summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Application.cpp1
-rw-r--r--BUILD/Changelog.txt20
-rw-r--r--BUILD/Compare_Complete.wavbin0 -> 46 bytes
-rw-r--r--BUILD/FreeFileSync.chmbin139070 -> 168410 bytes
-rw-r--r--BUILD/Help/html/Features.html47
-rw-r--r--BUILD/Help/html/advanced/EnvironmentVariables.html14
-rw-r--r--BUILD/Help/html/advanced/RealtimeSync.html103
-rw-r--r--BUILD/Help/html/advanced/RealtimeSync_html_72dda21b.gifbin39593 -> 0 bytes
-rw-r--r--BUILD/Help/html/advanced/ScheduleBatch.html16
-rw-r--r--BUILD/Help/html/advanced/SendMail.html15
-rw-r--r--BUILD/Help/html/advanced/SymbolicLinks.html10
-rw-r--r--BUILD/Help/html/advanced/VariableDrive.html12
-rw-r--r--BUILD/Help/html/advanced/rts.pngbin0 -> 32069 bytes
-rw-r--r--BUILD/Help/html/advanced/rts23.pngbin0 -> 36157 bytes
-rw-r--r--BUILD/Languages/chinese_simple.lng70
-rw-r--r--BUILD/Languages/chinese_traditional.lng76
-rw-r--r--BUILD/Languages/czech.lng68
-rw-r--r--BUILD/Languages/dutch.lng72
-rw-r--r--BUILD/Languages/finnish.lng70
-rw-r--r--BUILD/Languages/french.lng70
-rw-r--r--BUILD/Languages/german.lng66
-rw-r--r--BUILD/Languages/hungarian.lng68
-rw-r--r--BUILD/Languages/italian.lng72
-rw-r--r--BUILD/Languages/japanese.lng70
-rw-r--r--BUILD/Languages/polish.lng72
-rw-r--r--BUILD/Languages/portuguese.lng70
-rw-r--r--BUILD/Languages/portuguese_br.lng74
-rw-r--r--BUILD/Languages/romanian.lng72
-rw-r--r--BUILD/Languages/russian.lng70
-rw-r--r--BUILD/Languages/slovenian.lng74
-rw-r--r--BUILD/Languages/spanish.lng660
-rw-r--r--BUILD/Languages/swedish.lng886
-rw-r--r--BUILD/Languages/turkish.lng70
-rw-r--r--BUILD/Resources.datbin283152 -> 275228 bytes
-rw-r--r--BUILD/Sync_Complete.wavbin58 -> 364076 bytes
-rw-r--r--BUILD/mingwm10.dllbin19763 -> 0 bytes
-rw-r--r--FreeFileSync.cbp9
-rw-r--r--FreeFileSync.vcproj33
-rw-r--r--Makefile1
-rw-r--r--RealtimeSync/RealtimeSync.cbp4
-rw-r--r--RealtimeSync/RealtimeSync.vcproj33
-rw-r--r--RealtimeSync/RealtimeSync.xpm312
-rw-r--r--RealtimeSync/application.cpp28
-rw-r--r--RealtimeSync/application.h4
-rw-r--r--RealtimeSync/functions.h2
-rw-r--r--RealtimeSync/guiGenerated.cpp38
-rw-r--r--RealtimeSync/guiGenerated.h9
-rw-r--r--RealtimeSync/mainDialog.cpp32
-rw-r--r--RealtimeSync/mainDialog.h6
-rw-r--r--RealtimeSync/resources.cpp27
-rw-r--r--RealtimeSync/resources.h4
-rw-r--r--RealtimeSync/trayMenu.cpp23
-rw-r--r--RealtimeSync/trayMenu.h12
-rw-r--r--RealtimeSync/watcher.cpp335
-rw-r--r--RealtimeSync/watcher.h16
-rw-r--r--RealtimeSync/xmlFreeFileSync.h4
-rw-r--r--RealtimeSync/xmlProcessing.h18
-rw-r--r--algorithm.cpp520
-rw-r--r--algorithm.h4
-rw-r--r--comparison.cpp106
-rw-r--r--comparison.h14
-rw-r--r--fileHierarchy.cpp26
-rw-r--r--fileHierarchy.h63
-rw-r--r--library/CustomGrid.cpp236
-rw-r--r--library/FreeFileSync.xpm425
-rw-r--r--library/Recycler/Recycler_Vista.vcproj409
-rw-r--r--library/Recycler/dllmain.cpp22
-rw-r--r--library/Recycler/recycler.cpp142
-rw-r--r--library/Recycler/recycler.h24
-rw-r--r--library/ShadowCopy/Shadow_2003.vcproj4
-rw-r--r--library/ShadowCopy/Shadow_XP.vcproj4
-rw-r--r--library/ShadowCopy/shadow.cpp1
-rw-r--r--library/detectRenaming.cpp279
-rw-r--r--library/detectRenaming.h20
-rw-r--r--library/filter.cpp22
-rw-r--r--library/filter.h54
-rw-r--r--library/iconBuffer.cpp145
-rw-r--r--library/iconBuffer.h8
-rw-r--r--library/processXml.cpp6
-rw-r--r--library/processXml.h11
-rw-r--r--library/resources.cpp177
-rw-r--r--library/resources.h159
-rw-r--r--library/statistics.cpp8
-rw-r--r--library/statistics.h2
-rw-r--r--shared/buildInfo.h12
-rw-r--r--shared/customButton.cpp6
-rw-r--r--shared/customComboBox.cpp4
-rw-r--r--shared/dllLoader.cpp45
-rw-r--r--shared/dllLoader.h13
-rw-r--r--shared/fileHandling.cpp239
-rw-r--r--shared/fileHandling.h6
-rw-r--r--shared/fileID.cpp82
-rw-r--r--shared/fileID.h194
-rw-r--r--shared/fileTraverser.cpp22
-rw-r--r--shared/localization.cpp13
-rw-r--r--shared/longPathPrefix.cpp95
-rw-r--r--shared/longPathPrefix.h27
-rw-r--r--shared/recycler.cpp128
-rw-r--r--shared/recycler.h21
-rw-r--r--shared/shadow.cpp122
-rw-r--r--shared/shadow.h3
-rw-r--r--shared/zstring.cpp123
-rw-r--r--shared/zstring.h24
-rw-r--r--structures.cpp23
-rw-r--r--structures.h3
-rw-r--r--synchronization.cpp170
-rw-r--r--synchronization.h11
-rw-r--r--ui/MainDialog.cpp239
-rw-r--r--ui/MainDialog.h6
-rw-r--r--ui/SmallDialogs.cpp96
-rw-r--r--ui/batchStatusHandler.cpp16
-rw-r--r--ui/checkVersion.cpp19
-rw-r--r--ui/folderPair.h12
-rw-r--r--ui/gridView.cpp29
-rw-r--r--ui/gridView.h4
-rw-r--r--ui/guiGenerated.cpp50
-rw-r--r--ui/guiGenerated.h16
-rw-r--r--ui/settingsDialog.cpp154
-rw-r--r--ui/settingsDialog.h2
-rw-r--r--ui/sorting.h27
-rw-r--r--ui/trayIcon.cpp87
-rw-r--r--ui/trayIcon.h2
-rw-r--r--version/version.h2
123 files changed, 5951 insertions, 3025 deletions
diff --git a/Application.cpp b/Application.cpp
index 04b687b8..6b17bc19 100644
--- a/Application.cpp
+++ b/Application.cpp
@@ -246,6 +246,7 @@ void Application::runBatchMode(const wxString& filename, xmlAccess::XmlGlobalSet
FreeFileSync::CompareProcess comparison(batchCfg.mainCfg.hidden.traverseDirectorySymlinks,
batchCfg.mainCfg.hidden.fileTimeTolerance,
globSettings.ignoreOneHourDiff,
+ globSettings.detectRenameThreshold,
globSettings.optDialogs,
statusHandler.get());
diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt
index efd4697e..5bc1a41b 100644
--- a/BUILD/Changelog.txt
+++ b/BUILD/Changelog.txt
@@ -2,6 +2,26 @@
|FreeFileSync|
--------------
+Changelog v3.3
+--------------
+New installer package for portable/local/32/64-bit versions
+Built-in support for very long filenames: apply \\?\-prefix automatically
+New button for synchonization preview: show equal files
+RealtimeSync: Respond to directory or volume arrival, e.g. USB stick insert
+Start comparison automatically when double-clicking on *.ffs_gui files
+Visual progress indicator for sys-tray icon
+Fixed string comparison for 'ß' and 'ss' (all Windows versions)
+Fixed general string comparison for Windows 2000
+Significantly faster file icon loading
+Applied new IFileOperation interface for recycle bin (Windows >= Vista)
+Patched <Automatic> mode to handle FAT32 2-second file time precision
+Play optional sound after comparison: "Compare_Complete.wav"
+Allow environment variables for logfile-directory
+Enhanced conflict reporting
+Added Swedish translation
+Updated translation files
+
+
Changelog v3.2
--------------
Native Windows 64-Bit version (including Volume Shadow Copy Service)
diff --git a/BUILD/Compare_Complete.wav b/BUILD/Compare_Complete.wav
new file mode 100644
index 00000000..f304e6d7
--- /dev/null
+++ b/BUILD/Compare_Complete.wav
Binary files differ
diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm
index 3cf06742..139df0e1 100644
--- a/BUILD/FreeFileSync.chm
+++ b/BUILD/FreeFileSync.chm
Binary files differ
diff --git a/BUILD/Help/html/Features.html b/BUILD/Help/html/Features.html
index 75aea41d..7a40fcdb 100644
--- a/BUILD/Help/html/Features.html
+++ b/BUILD/Help/html/Features.html
@@ -3,9 +3,9 @@
<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="GENERATOR" CONTENT="OpenOffice.org 3.1 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20091207;23033200">
+ <META NAME="CHANGED" CONTENT="20100124;542600">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
@@ -30,6 +30,9 @@
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">Built-in
+ support for very long filenames (more than MAX_PATH = 260
+ characters)</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Synchronization
database for propagation of deleted files and conflict detection</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support
@@ -42,11 +45,11 @@
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
+ <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
+ <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
+ <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
@@ -73,41 +76,39 @@
</OL>
</OL>
<OL START=14>
- <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Support
+ <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
+ <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
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Ignore
directories &quot;\RECYCLER&quot; and &quot;\System Volume
- Information&quot; with default Filter. (Windows only)</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Localized
+ Information&quot; 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
+ <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
+ <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
+ <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
+ <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
+ <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
+ <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
+ <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
+ <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
+ <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
+ <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
+ <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>
diff --git a/BUILD/Help/html/advanced/EnvironmentVariables.html b/BUILD/Help/html/advanced/EnvironmentVariables.html
index 2d4f6069..c3e80ce7 100644
--- a/BUILD/Help/html/advanced/EnvironmentVariables.html
+++ b/BUILD/Help/html/advanced/EnvironmentVariables.html
@@ -5,7 +5,7 @@
<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="CHANGED" CONTENT="20091217;17435700">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
@@ -34,15 +34,15 @@ character. Besides special macros handling time and date (see
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">
+ <P><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&nbsp;&nbsp;&nbsp;</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&nbsp;&nbsp;&nbsp;</FONT>expands to<FONT FACE="Courier New, monospace"><BR>C:\Documents
- and Settings\ZenJu\Application Data\FreeFileSync</FONT></FONT></P>
+ <FONT FACE="Tahoma, sans-serif"><FONT FACE="Courier New, monospace">%APPDATA%\FreeFileSync&nbsp;&nbsp;&nbsp;</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>
@@ -63,7 +63,7 @@ batch configuration file <FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batc
</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">
+ <P><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 &quot;C:\Program
@@ -78,7 +78,7 @@ batch configuration file <FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batc
<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><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 &quot;<FONT FACE="Courier New, monospace">set</FONT>&quot;
diff --git a/BUILD/Help/html/advanced/RealtimeSync.html b/BUILD/Help/html/advanced/RealtimeSync.html
index 7eac013c..156409ba 100644
--- a/BUILD/Help/html/advanced/RealtimeSync.html
+++ b/BUILD/Help/html/advanced/RealtimeSync.html
@@ -5,7 +5,7 @@
<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="CHANGED" CONTENT="20100125;20445600">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
@@ -21,7 +21,7 @@
-->
</STYLE>
</HEAD>
-<BODY LANG="de-DE" DIR="LTR">
+<BODY LANG="en-US" DIR="LTR">
<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">RealtimeSync</FONT></H3>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
@@ -30,41 +30,46 @@ 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>
+Whenever a file within these directories or subdirectories is
+modified OR the directory becomes available (e.g. insert of a
+USB-stick), RealtimeSync responds by executing the user-specified
+command line.</FONT></P>
<P STYLE="margin-bottom: 0cm"><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
+start up RealtimeSync.exe located in FreeFileSync's installation
+directory. Then specify all directories that shall be monitored.
+Instead of doing this manually you can simply import a </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT>
+<FONT FACE="Tahoma, sans-serif">file via </FONT><FONT FACE="Tahoma, sans-serif"><I>Menu
-&gt; File -&gt; 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>
+but also sets up the command-line to execute the </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT>
+<FONT FACE="Tahoma, sans-serif">file every time changes are detected.
+Now press &quot;</FONT><FONT FACE="Tahoma, sans-serif"><I>Start</I></FONT><FONT FACE="Tahoma, sans-serif">&quot;
+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>
+ <P STYLE="margin-bottom: 0cm"><IMG SRC="rts23.png" NAME="Grafik3" ALIGN=MIDDLE WIDTH=503 HEIGHT=429 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">
+ <P><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
+ restricted to starting FreeFileSync. It can also be used in 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>
+ by passing a RealtimeSync configuration file (<FONT FACE="Courier New, monospace">*.ffs_real</FONT>)
+ OR a FreeFileSync Batch file (<FONT FACE="Courier New, monospace">*.ffs_batch</FONT>)
+ as first command-line argument. This allows for integration with
+ your operating system's autostart facility:</FONT></P>
</UL>
</SPAN><BR CLEAR=LEFT>
</P>
@@ -72,13 +77,73 @@ monitoring.</FONT></P>
<P STYLE="margin-bottom: 0cm"><BR>
</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">&quot;C:\Program
+ Files\FreeFileSync\RealtimeSync.exe&quot;
+ &quot;C:\MyConfig.ffs_real&quot;<BR>&quot;C:\Program
+ Files\FreeFileSync\RealtimeSync.exe&quot; &quot;C:\SyncJob.ffs_batch&quot;</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>Example:</B></FONT>
+<FONT FACE="Tahoma, sans-serif">(Smart synchronization when USB
+sticks are inserted into your PC - in combination with FreeFileSync)</FONT></P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Assume
+you have multiple(!) USB sticks that contain data you want to
+automatically synchronize in two-way mode whenever you insert one of
+the sticks into the PC. In order to be on the safe side, you decide
+to setup FreeFileSync batch jobs (</FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT><FONT FACE="Tahoma, sans-serif">)
+using </FONT><FONT FACE="Tahoma, sans-serif"><I>&lt;Automatic&gt;</I></FONT>
+<FONT FACE="Tahoma, sans-serif">mode so that conflicts, for example
+files modified on both sides, are detected avoiding data loss. Save
+the relevant configuration on each USB stick's root directory to have
+it called when the stick is mounted. Then configure RealtimeSync
+analog to the following:</FONT></P>
+<UL>
+ <P><IMG SRC="rts.png" NAME="Grafik2" ALIGN=BOTTOM WIDTH=462 HEIGHT=411 BORDER=0></P>
+</UL>
+<P STYLE="margin-bottom: 0cm"><BR>
+</P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Whenever
+directory &quot;</FONT><FONT FACE="Courier New, monospace">H:\Data</FONT><FONT FACE="Tahoma, sans-serif">&quot;
+becomes available, the command-line executes and starts the batchjob
+whose configuration is located on the stick. Furthermore it also
+starts the batch job each time files are modified within &quot;</FONT><FONT FACE="Courier New, monospace">H:\Data</FONT><FONT FACE="Tahoma, sans-serif">&quot;.
+</FONT>
+</P>
+<P STYLE="margin-bottom: 0cm"><BR>
+</P>
+<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">For
+additional convenience it might be nice if the batch job remains
+silent if synchronization completes successfully, otherwise shows
+FreeFileSync's GUI dialog when errors occurred. Therefore create two
+configurations, one silent-mode batch to be called by default and one
+<FONT FACE="Courier New, monospace">*.ffs_gui</FONT> to be called
+when former fails. Then replace the command-line to simply execute a
+batch file similar to this one:</FONT></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>
+ <FONT COLOR="#808080"><FONT FACE="Courier New, monospace"><I><B>::first
+ check whether USB-stick contains a sync-configuration at all</B></I></FONT></FONT><FONT FACE="Courier New, monospace"><BR>@if
+ exist &quot;H:\Silent_Config.ffs_batch&quot; (<BR></FONT><FONT COLOR="#808080"><FONT FACE="Courier New, monospace"><I><B>::configuration
+ found, now execute the synchronization batch job</B></I></FONT></FONT><FONT FACE="Courier New, monospace"><BR>&quot;C:\Program
+ Files\FreeFileSync\FreeFileSync.exe&quot;
+ &quot;H:\Silent_Config.ffs_batch&quot;<BR>@if not errorlevel 0
+ (<BR></FONT><FONT COLOR="#808080"><FONT FACE="Courier New, monospace"><I><B>::if
+ something went wrong, start FreeFileSync in GUI
+ mode</B></I></FONT></FONT><FONT FACE="Courier New, monospace"><BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;<FONT FACE="Courier New, monospace">&quot;C:\Program
+ Files\FreeFileSync\FreeFileSync.exe&quot;
+ &quot;H:\GUI_Config.ffs_gui&quot;<BR>)<BR>)</FONT></P>
</SPAN><BR CLEAR=LEFT>
</P>
</UL>
+<P STYLE="margin-bottom: 0cm"><BR>
+</P>
</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
deleted file mode 100644
index 9da1bc3f..00000000
--- a/BUILD/Help/html/advanced/RealtimeSync_html_72dda21b.gif
+++ /dev/null
Binary files differ
diff --git a/BUILD/Help/html/advanced/ScheduleBatch.html b/BUILD/Help/html/advanced/ScheduleBatch.html
index 4d1f3de0..bb956401 100644
--- a/BUILD/Help/html/advanced/ScheduleBatch.html
+++ b/BUILD/Help/html/advanced/ScheduleBatch.html
@@ -5,7 +5,7 @@
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20091213;16291600">
+ <META NAME="CHANGED" CONTENT="20100118;18123600">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
@@ -19,23 +19,22 @@
</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>
+Job in Windows Task Planner <SPAN STYLE="font-weight: normal">(Windows
+XP)</SPAN></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-&gt;Advanced-&gt;Create batch job</I> and save
- it, for example, as <FONT FACE="Courier New, monospace">&quot;C:\SyncJob.ffs_batch</FONT>&quot;.</FONT></P>
- <P STYLE="margin-bottom: 0cm"></P>
+ it, for example, as &quot;<FONT FACE="Courier New, monospace">C:\SyncJob.ffs_
+ batch</FONT>&quot;.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Make
- sure you are using &quot;<I>silent mode</I>&quot; to prevent showing
- a status dialog at the end of the process.</FONT></P>
- <P STYLE="margin-bottom: 0cm"></P>
+ sure you enable checkbox &quot;<I>silent mode</I>&quot; to prevent
+ showing a status dialog at the end of the process.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start
Windows Task Scheduler: Go to <I>Start-&gt;Control Panel-&gt;Scheduled
Tasks</I> and select &quot;<I>Add Scheduled Task</I>&quot;.</FONT></P>
- <P STYLE="margin-bottom: 0cm"></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Follow
the wizard and choose &quot;<FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batch</FONT>&quot;
as program to run.</FONT></P>
@@ -45,7 +44,6 @@ Job in Windows Task Planner (Windows XP)</FONT></H3>
</FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> <FONT FACE="Tahoma, sans-serif">files
are automatically associated with the tool and field &quot;</FONT><FONT FACE="Tahoma, sans-serif"><I>Run:</I></FONT><FONT FACE="Tahoma, sans-serif">&quot;
can be filled with the filename directly:<BR>&quot;</FONT><FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batch</FONT><FONT FACE="Tahoma, sans-serif">&quot;<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>
&quot;<FONT FACE="Tahoma, sans-serif"><I>Run:</I></FONT><FONT FACE="Tahoma, sans-serif">&quot;
diff --git a/BUILD/Help/html/advanced/SendMail.html b/BUILD/Help/html/advanced/SendMail.html
index 10ea0e4a..0946de2b 100644
--- a/BUILD/Help/html/advanced/SendMail.html
+++ b/BUILD/Help/html/advanced/SendMail.html
@@ -3,9 +3,9 @@
<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="GENERATOR" CONTENT="OpenOffice.org 3.1 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20091213;15581500">
+ <META NAME="CHANGED" CONTENT="20091231;16373900">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
@@ -32,7 +32,7 @@ Batch Mode and send error notification via email</FONT></H3>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Set
error handling to &quot;<I>Exit with Returncode &lt; 0</I>&quot; or
&quot;<I>ignore errors</I>&quot; to avoid having a popup stop the
- program flow. In case errors occur FreeFileSync will abort with a
+ program flow. In case errors occur FreeFileSync will exit with a
returncode &lt; 0 which can be checked via the ERRORLEVEL batch
command.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create
@@ -41,11 +41,12 @@ Batch Mode and send error notification via email</FONT></H3>
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">
+ <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">C:\Program
- Files\FreeFileSync\FreeFileSync.exe C:\SyncJob.ffs_batch<BR>if not
- errorlevel 0 echo An error occured! &amp;&amp; pause</FONT></P>
+ <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Courier New, monospace">&quot;C:\Program
+ Files\FreeFileSync\FreeFileSync.exe&quot;
+ &quot;C:\SyncJob.ffs_batch&quot;<BR>@if not errorlevel 0
+ (<BR>&nbsp;&nbsp;&nbsp;&nbsp;echo An error occured!<BR>&nbsp;&nbsp;&nbsp;&nbsp;pause<BR>)</FONT></P>
</UL>
</SPAN><BR CLEAR=LEFT>
</P>
diff --git a/BUILD/Help/html/advanced/SymbolicLinks.html b/BUILD/Help/html/advanced/SymbolicLinks.html
index e3dd6ea2..b85c6bbd 100644
--- a/BUILD/Help/html/advanced/SymbolicLinks.html
+++ b/BUILD/Help/html/advanced/SymbolicLinks.html
@@ -5,7 +5,7 @@
<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="CHANGED" CONTENT="20091213;19145800">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
@@ -56,10 +56,10 @@ being copied instead.</FONT></P>
<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">&quot;<I>TraverseDirectorySymlinks</I>&quot;
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
+<I>true</I>, they are being traversed like regular 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">
diff --git a/BUILD/Help/html/advanced/VariableDrive.html b/BUILD/Help/html/advanced/VariableDrive.html
index e46bbaad..975995cf 100644
--- a/BUILD/Help/html/advanced/VariableDrive.html
+++ b/BUILD/Help/html/advanced/VariableDrive.html
@@ -5,7 +5,7 @@
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20091213;16011300">
+ <META NAME="CHANGED" CONTENT="20091213;19170300">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
@@ -37,9 +37,19 @@ the following workflow is possible:</FONT></P>
the absolute USB directory name in your configuration by a relative
one:<BR>E.g. &quot;<FONT FACE="Courier New, monospace">E:\SyncDir</FONT>&quot;
-&gt; &quot;<FONT FACE="Courier New, monospace">\SyncDir</FONT>&quot;</FONT></P>
+ <P STYLE="margin-bottom: 0cm"></P>
+ </OL>
+</UL>
+<UL>
+ <OL>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Save
and copy synchronization settings to the USB stick:
&quot;<FONT FACE="Courier New, monospace">E:\settings.ffs_gui</FONT>&quot;</FONT></P>
+ </OL>
+</UL>
+<UL>
+ <OL>
+ <P STYLE="margin-bottom: 0cm"></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start
FreeFileSync by double-clicking on &quot;</FONT><FONT FACE="Courier New, monospace">E:\settings.ffs_gui</FONT><FONT FACE="Tahoma, sans-serif">&quot;<BR>=&gt;
Working directory automatically is set to &quot;</FONT><FONT FACE="Courier New, monospace">E:\</FONT><FONT FACE="Tahoma, sans-serif">&quot;
diff --git a/BUILD/Help/html/advanced/rts.png b/BUILD/Help/html/advanced/rts.png
new file mode 100644
index 00000000..8462d0e0
--- /dev/null
+++ b/BUILD/Help/html/advanced/rts.png
Binary files differ
diff --git a/BUILD/Help/html/advanced/rts23.png b/BUILD/Help/html/advanced/rts23.png
new file mode 100644
index 00000000..9cda186d
--- /dev/null
+++ b/BUILD/Help/html/advanced/rts23.png
Binary files differ
diff --git a/BUILD/Languages/chinese_simple.lng b/BUILD/Languages/chinese_simple.lng
index d73d300c..1d7b11dc 100644
--- a/BUILD/Languages/chinese_simple.lng
+++ b/BUILD/Languages/chinese_simple.lng
@@ -46,6 +46,8 @@
å–消(&C)
&Check for new version
检查更新(&C)
+&Content
+内容(&C)
&Create batch job
创建批处ç†ä½œä¸š(&C)
&Default
@@ -88,6 +90,8 @@
是(&Y)
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(请注æ„åªæœ‰FAT/FAT32分区å—此问题影å“!\n在所有其他情况下你å¯ç¦ç”¨\"忽略一å°æ—¶å·®å¼‚\"这一选项.)
+(Requires an Internet connection!)
+(需è¦å› ç‰¹ç½‘连接!)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. 比较(&C)
1. Enter relative file or directory names separated by ';' or a new line.
1. 输入相对文件或文件夹å称,用';'或空行分隔.
+1. Select directories to monitor.
+1. 选择è¦ç›‘视的目录.
2. &Synchronize...
2. åŒæ­¥(&S)...
+2. Enter a command line.
+2. 输入一个命令行.
2. Use wildcard characters '*' and '?'.
2. 使用通é…符‘*’和‘?’.
3. Exclude files directly on main grid via context menu.
3. 通过å³é”®èœå•åœ¨ä¸»ç½‘格排除文件.
+3. Press 'Start'.
+3. 点击'开始'.
<Automatic>
自动
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
顾åæ€ä¹‰,两个相åŒæ–‡ä»¶å的文件当且仅当它们具有相åŒçš„内容时会被认为是相åŒçš„。\n此选项对于一致性检查比较有用,而ä¸æ˜¯å¤‡ä»½æ“作. å› æ­¤,文件时间没有被考虑到. \n\n通过此选项使决策树较å°:
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.
装é…一个批处ç†æ–‡ä»¶ç”¨äºŽè‡ªåŠ¨åŒæ­¥. è¦å¼€å§‹æ‰¹å¤„ç†æ¨¡å¼åªéœ€ç®€å•åœ°å°†æ‰¹å¤„ç†æ–‡ä»¶åä¼ é€ç»™FreeFileSyncå¯æ‰§è¡Œæ–‡ä»¶:FreeFileSync.exe <batchfile>. 这个也å¯ä»¥å®‰æŽ’在您的æ“作系统的计划任务中.
+At least one directory input field is empty.
+至少有一个目录输入字段是空的.
Auto-adjust columns
自动调整æ å®½
Automatic mode
@@ -192,20 +204,18 @@ Build:
å¼€å‘:
Cancel
å–消
-Cannot determine sync-direction: Changed filter settings!
-ä¸èƒ½ç¡®å®šåŒæ­¥æ–¹å‘: 过滤器设置已改å˜!
-Cannot determine sync-direction: No change since last synchronization!
-ä¸èƒ½ç¡®å®šåŒæ­¥æ–¹å‘: 在最åŽåŒæ­¥ä¹‹åŽæ²¡æœ‰æ”¹å˜!
+Cannot determine sync-direction:
+ä¸èƒ½æ£€æµ‹åŒæ­¥æ–¹å‘:
Category
分类
Change direction
改å˜æ–¹å‘
Comma separated list
逗å·åˆ†éš”的列表
-Commandline
+Command line
命令行
-Commandline is empty!
-命令行为空!
+Command line is empty!
+命令行是空的!
Compare
比较
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
从å³ä¾§å¤åˆ¶åˆ°å·¦ä¾§
Copy from right to left overwriting
从å³ä¾§å¤åˆ¶åˆ°å·¦ä¾§(覆盖模å¼)
+Copy locked files
+å¤åˆ¶è¢«é”定的文件
Copy new or updated files to right folder.
å¤åˆ¶æ–°çš„或修改过的文件到å³ä¾§æ–‡ä»¶å¤¹
+Copy shared or locked files using Volume Shadow Copy Service.
+使用å·å½±å¤åˆ¶æœåŠ¡æ¥å¤åˆ¶å…±äº«æˆ–é”定的文件.
Copy to clipboard\tCTRL+C
å¤åˆ¶åˆ°å‰ªè´´æ¿\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
ä¸èƒ½ç¡®å®šæ­¤æ–‡ä»¶çš„å·å称:
Could not initialize directory monitoring:
ä¸èƒ½åˆå§‹åŒ–目录监视:
+Could not load a required DLL:
+ä¸èƒ½åŠ è½½æ‰€éœ€çš„动æ€è¿žæŽ¥åº“:
Could not read values for the following XML nodes:
ä¸èƒ½ä»Žå¦‚下XML节点读å–数值:
Create a batch job
@@ -298,7 +314,7 @@ Date
日期
Delay
延时
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
在检测和执行命令行之间的延时秒数
Delete files/folders existing on left side only
删除仅在左侧存在的文件/文件夹
@@ -386,6 +402,8 @@ Error reading file:
读å–文件出错:
Error reading from synchronization database:
从åŒæ­¥æ•°æ®åº“中读å–时出错:
+Error resolving full path name:
+解决完整路径时出错:
Error resolving symbolic link:
解决符å·é“¾æŽ¥å‡ºé”™:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
过滤文件
Filter has been selected
过滤器已选择
+Filter settings have changed!
+过滤设置已改å˜!
Filter view
过滤查看
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
包括所有行
Include temporarily
暂时包括
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-包括: *.doc;*.zip;*.exe\n排除temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+包括: *.doc;*.zip;*.exe\n排除\\stuff\\temp\\*
Incompatible synchronization database format:
ä¸å…¼å®¹çš„åŒæ­¥æ•°æ®åº“æ ¼å¼:
Info
@@ -572,8 +592,6 @@ 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. :)
-åˆå§‹åŒ–回收站是ä¸å¤§å¯èƒ½äº†!\n\n估计你使用的ä¸æ˜¯Windows系统.\n如果你想包å«æ­¤ç‰¹æ€§,请è”系作者. :)
Leave as unresolved conflict
é—留为未解决的冲çª
Left
@@ -590,18 +608,22 @@ Log-messages:
日志信æ¯:
Logging
记录
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+ä¸æ”¯æŒåœ¨WOW64上使用å·å½±å¤åˆ¶. 请使用 FreeFileSync 64ä½ç‰ˆæœ¬.
Mirror ->>
é•œåƒ ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
左侧文件夹镜åƒå¤‡ä»½: åŒæ­¥åŽå³ä¾§æ–‡ä»¶å¤¹å°†è¢«è¦†ç›–并且完全匹é…左边的文件夹.
+Monitoring active...
+监视激活...
More than 50% of the total number of files will be copied or deleted!
超过总数 50% 以上的文件è¦è¢«å¤åˆ¶æˆ–删除!
Move column down
下移一行
Move column up
上移一行
-Move files to a user-defined directory.
-移动文件到用户定义的目录
+Move files into a time-stamped subdirectory.
+移动文件到时间标记å­ç›®å½•.
Moving %x to Recycle Bin
移动 %x 到回收站
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
移动文件夹 %x 到用户定义目录 %y
Multiple...
å€æ•°...
+No change since last synchronization!
+自从最åŽä¸€æ¬¡åŒæ­¥ä»¥æ¥æ²¡æœ‰å˜åŠ¨!
No filter selected
没有选定过滤器
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
æš‚åœ
Paused
已暂åœ
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-请å¤åˆ¶é€‚当的\"Shadow.dll\"(ä½äºŽ\"Shadow.zip\"压缩包中)到FreeFileSync安装目录以å¯ç”¨æ­¤ç‰¹æ€§.
-Please fill all empty directory fields.
-请填满所有空的目录区域.
Please run a Compare first before synchronizing!
åŒæ­¥ä¹‹å‰è¯·å…ˆè¿›è¡Œå¯¹æ¯”
+Processing folder pair:
+正在处ç†æˆå¯¹æ–‡ä»¶å¤¹:
Published under the GNU General Public License:
在GNU通用公共许å¯ä¸‹å‘布:
Question
@@ -670,6 +692,8 @@ Remove folder pair
删除文件夹对
Remove local filter settings
移除局部过滤器
+Renaming file %x to %y
+å°† %x é‡å‘½å为 %y
Report translation error
报告翻译错误
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
目标目录已ç»å­˜åœ¨!
Target file already existing!
目标文件已ç»å­˜åœ¨!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+命令行会被执行æ¯å½“:\n- 这些目录(或å­ç›®å½•)里é¢çš„文件有修改\n- 相应的盘符å˜æˆå¯ç”¨(æ’å…¥U盘)
The database file is not yet existing, but will be created during synchronization:
æ•°æ®åº“文件未存在, 但在åŒæ­¥æœŸé—´ä¼šè¢«åˆ›å»º:
The file does not contain a valid configuration:
@@ -816,12 +842,14 @@ Unable to create logfile!
无法创建日志!
Unable to initialize Recycle Bin!
无法åˆå§‹åŒ–回收站!
+Unresolved conflicts existing!
+存在ä¸å¯è§£å†³çš„冲çª!
Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
存在ä¸å¯è§£å†³çš„冲çª!\n\nä½ å¯å¿½ç•¥å†²çªå¹¶ç»§ç»­åŒæ­¥.
Update ->
å‡çº§ ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-用法: 选择è¦ç›‘视的目录并输入一命令行. æ¯æ¬¡ç›®å½•(或å­ç›®å½•)中的文件被修改时此命令行就会执行.
+Usage:
+用法:
Use Recycle Bin
使用回收站
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
警告:åŒæ­¥å¤±è´¥ %x (æŸäº›)项目:
When the comparison is started with this option set the following decision tree is processed:
当以此选项开始比较时以下决定树被处ç†:
+You can ignore conflicts and continue synchronization.
+ä½ å¯å¿½ç•¥å†²çªå¹¶ç»§ç»­åŒæ­¥.
You can ignore the error to consider not existing directories as empty.
您å¯å¿½ç•¥æ­¤é”™è¯¯è€Œå°†ä¸å­˜åœ¨çš„目录视为空.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/chinese_traditional.lng b/BUILD/Languages/chinese_traditional.lng
index cc9abc57..d4e4e7b1 100644
--- a/BUILD/Languages/chinese_traditional.lng
+++ b/BUILD/Languages/chinese_traditional.lng
@@ -46,6 +46,8 @@
å–消(&C)
&Check for new version
檢查更新(&C)
+&Content
+內容
&Create batch job
新建批次處ç†ä½œæ¥­(&C)
&Default
@@ -87,7 +89,9 @@
&Yes
是
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
-(請注æ„åªæœ‰ FAT/FAT32 ç£ç¢Ÿæ©Ÿæœƒå—到此å•é¡Œçš„影響ï¼\n在所有其他狀æ³ä¸‹ï¼Œå¯ä»¥é—œé–‰é€™å€‹è¨­å®š\"忽略1å°æ™‚的誤差"\。)
+(請注æ„åªæœ‰ FAT/FAT32 ç£ç¢Ÿæ©Ÿæœƒå—到此å•é¡Œçš„影響ï¼\n在所有其他狀æ³ä¸‹ï¼Œå¯ä»¥é—œé–‰é€™å€‹è¨­å®š\"忽略1å°æ™‚的誤差\"。)
+(Requires an Internet connection!)
+(需è¦é€£æŽ¥åˆ°ç¶²éš›ç¶²è·¯ï¼)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. 比å°(&C)
1. Enter relative file or directory names separated by ';' or a new line.
1. 輸入相å°æª”案或目錄å稱,使用';'或空行分隔。
+1. Select directories to monitor.
+1. é¸æ“‡è¦ç›£æ¸¬çš„目錄。
2. &Synchronize...
2. åŒæ­¥(&S)...
+2. Enter a command line.
+2. 輸入命令列。
2. Use wildcard characters '*' and '?'.
2. 使用è¬ç”¨å­—元‘*’和‘?’。
3. Exclude files directly on main grid via context menu.
3. 經由內容é¸å–®ç›´æŽ¥åœ¨ä¸»è¦ç¶²æ ¼æŽ’除檔案。
+3. Press 'Start'.
+3. 按下 '開始'。
<Automatic>
<自動>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
顧åæ€ç¾©ï¼Œå…©å€‹ç›¸åŒæª”å的檔案,åªæœ‰ç•¶ä»–們具有åŒæ¨£çš„内容時會被判斷是相åŒçš„。\næ­¤é¸é …å°æ–¼ä¸€è‡´æ€§æª¢æŸ¥æ¯”較有用,而ä¸æ˜¯å‚™ä»½æ“作。因此,檔案時間沒有列入考慮。\n\n啟用此é¸é …使決策樹較å°ï¼š
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.
組åˆä¸€å€‹ç”¨æ–¼è‡ªå‹•åŒæ­¥çš„批次檔。若è¦é–‹å§‹æ‰¹æ¬¡è™•ç†æ¨¡å¼ï¼Œåªéœ€ç°¡å–®çš„將批次檔å傳é€ç»™ FreeFileSync å¯åŸ·è¡Œæª”:FreeFileSync.exe <batchfile>。這個也å¯ä»¥å®‰æŽ’在你的作業系統的計畫任務中。
+At least one directory input field is empty.
+至少有一個目錄輸入欄ä½æ˜¯ç©ºçš„。
Auto-adjust columns
自動調整欄寬
Automatic mode
@@ -192,19 +204,17 @@ Build:
建立:
Cancel
å–消
-Cannot determine sync-direction: Changed filter settings!
-ä¸èƒ½åˆ¤æ–·åŒæ­¥æ–¹å‘:已更改篩é¸å™¨è¨­å®šï¼
-Cannot determine sync-direction: No change since last synchronization!
-ä¸èƒ½åˆ¤æ–·åŒæ­¥æ–¹å‘:自上次åŒæ­¥å¾Œï¼Œæ²’有更改éŽï¼
+Cannot determine sync-direction:
+無法判斷åŒæ­¥æ–¹å‘:
Category
分類
Change direction
改變方å‘
Comma separated list
逗號分隔清單
-Commandline
+Command line
命令列
-Commandline is empty!
+Command line is empty!
命令列是空的ï¼
Compare
比å°
@@ -260,8 +270,12 @@ Copy from right to left
從å³é‚Šè¤‡è£½åˆ°å·¦é‚Š
Copy from right to left overwriting
從å³é‚Šè¤‡è£½åˆ°å·¦é‚Šè¦†è“‹æª”案
+Copy locked files
+複製被鎖定的檔案
Copy new or updated files to right folder.
將新的或更新éŽçš„檔案複製到å³é‚Šçš„資料夾中。
+Copy shared or locked files using Volume Shadow Copy Service.
+使用å·å½±è¤‡è£½æœå‹™ä¾†è¤‡è£½å…±äº«æˆ–鎖定的檔案。
Copy to clipboard\tCTRL+C
複製到剪貼簿\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
無法判斷此檔案的å·æ¨™å稱:
Could not initialize directory monitoring:
無法åˆå§‹åŒ–目錄監測:
+Could not load a required DLL:
+無法載入一個所需的DLL:
Could not read values for the following XML nodes:
ç„¡æ³•è®€å– XML 之後節點的值:
Create a batch job
@@ -298,7 +314,7 @@ Date
日期
Delay
延é²
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
檢測更改和執行命令列的延é²æ™‚間,以秒為單ä½ã€‚
Delete files/folders existing on left side only
刪除åªå­˜åœ¨æ–¼å·¦é‚Šçš„檔案/資料夾
@@ -386,6 +402,8 @@ Error reading file:
讀å–檔案錯誤:
Error reading from synchronization database:
讀å–åŒæ­¥è³‡æ–™åº«éŒ¯èª¤ï¼š
+Error resolving full path name:
+完整路徑å稱解æžéŒ¯èª¤ï¼š
Error resolving symbolic link:
解决符號連çµéŒ¯èª¤ï¼š
Error starting Volume Shadow Copy Service!
@@ -393,7 +411,7 @@ Error starting Volume Shadow Copy Service!
Error traversing directory:
é歷目錄錯誤:
Error when monitoring directories.
-監測目錄錯誤:
+監測目錄錯誤。
Error writing file attributes:
寫入檔案屬性錯誤:
Error writing file:
@@ -466,6 +484,8 @@ Filter files
篩é¸æª”案
Filter has been selected
å·²é¸æ“‡ç¯©é¸å™¨
+Filter settings have changed!
+篩é¸å™¨è¨­å®šå·²æ›´æ”¹ï¼
Filter view
篩é¸æª¢è¦–
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
包括所有行
Include temporarily
暫時包括
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-包括:*.doc;*.zip;*.exe\n排除temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+包括:*.doc;*.zip;*.exe\n排除\\stuff\\temp\\*
Incompatible synchronization database format:
åŒæ­¥è³‡æ–™åº«æ ¼å¼ä¸ç›¸å®¹ï¼š
Info
@@ -569,11 +589,9 @@ Info
Information
訊æ¯
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. :)
-ä¸èƒ½åˆå§‹åŒ–資æºå›žæ”¶ç­’ï¼\n\nå¯èƒ½ä½ ä½¿ç”¨çš„ä¸æ˜¯ Windows 系統。\n如果你想包括此功能,請è¯ç¹«ä½œè€…。:)
Leave as unresolved conflict
ä¿ç•™çµ¦æœªè§£æ±ºçš„è¡çª
Left
@@ -590,18 +608,22 @@ Log-messages:
日誌訊æ¯ï¼š
Logging
日誌記錄
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+ä¸æ”¯æ´è£½ä½œ WOW64 上的å·å½±å‰¯æœ¬ã€‚請使用 FreeFileSync 64ä½å…ƒç‰ˆæœ¬ã€‚
Mirror ->>
é¡åƒ ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
-左邊資料夾的é¡åƒå‚™ä»½ï¼šåŒæ­¥ä¹‹å¾Œï¼Œå³é‚Šè³‡æ–™å¤¾å°‡è¢«è¦†è“‹ï¼Œå®Œå…¨å’Œå·¦é‚Šè³‡æ–™å¤¾ä¸€æ¨¡ä¸€æ¨£ã€‚
+左邊資料夾的é¡åƒå‚™ä»½ï¼š åŒæ­¥ä¹‹å¾Œï¼Œå³é‚Šè³‡æ–™å¤¾å°‡è¢«è¦†è“‹ï¼Œå®Œå…¨å’Œå·¦é‚Šè³‡æ–™å¤¾ä¸€æ¨¡ä¸€æ¨£ã€‚
+Monitoring active...
+監測活動...
More than 50% of the total number of files will be copied or deleted!
超éŽç¸½æ•¸ 50% 以上的檔案將被複製或刪除ï¼
Move column down
下移一行
Move column up
上移一行
-Move files to a user-defined directory.
-將檔案移動到自定義目錄。
+Move files into a time-stamped subdirectory.
+移動檔案到一個時間標記的å­ç›®éŒ„。
Moving %x to Recycle Bin
移動 %x 到資æºå›žæ”¶ç­’
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
移動資料夾 %x 到自定義資料夾 %y
Multiple...
多個...
+No change since last synchronization!
+自上次åŒæ­¥ä»¥ä¾†éƒ½æ²’有變更ï¼
No filter selected
沒有é¸æ“‡ç¯©é¸å™¨
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
æš«åœ
Paused
已暫åœ
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-請複製é©ç•¶çš„\"Shadow.dll\"(ä½æ–¼\"Shadow.zip\"壓縮檔)到 FreeFileSync 安è£ç›®éŒ„以啟用此功能。
-Please fill all empty directory fields.
-請填滿所有空白目錄欄ä½ã€‚
Please run a Compare first before synchronizing!
請執行åŒæ­¥å‰å…ˆæ¯”å°ï¼
+Processing folder pair:
+處ç†å…©å€‹è³‡æ–™å¤¾ï¼š
Published under the GNU General Public License:
在GNU通用公共許å¯è­‰ä¸‹ç™¼ä½ˆï¼š
Question
@@ -670,6 +692,8 @@ Remove folder pair
移除兩個資料夾
Remove local filter settings
移除局部性篩é¸å™¨è¨­å®š
+Renaming file %x to %y
+檔案é‡æ–°å‘½å %x 為 %y
Report translation error
回報翻譯錯誤
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
目標目錄已存在ï¼
Target file already existing!
目標檔案已存在ï¼
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+命令行æ¯æ¬¡åŸ·è¡Œæ™‚:\n- 檔案在這些目錄(或å­ç›®éŒ„)會被修改\n- å¯ä¾›ä½¿ç”¨ç›¸æ‡‰çš„ç£ç¢Ÿæ©Ÿä»£è™Ÿ(USBæ’å…¥)
The database file is not yet existing, but will be created during synchronization:
資料庫檔未存在,但會在åŒæ­¥éŽç¨‹ä¸­æ–°å»ºï¼š
The file does not contain a valid configuration:
@@ -816,12 +842,14 @@ Unable to create logfile!
無法新建日誌檔ï¼
Unable to initialize Recycle Bin!
無法åˆå§‹åŒ–資æºå›žæ”¶ç­’ï¼
+Unresolved conflicts existing!
+存在未解決的è¡çªï¼
Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
存在未解決的è¡çªï¼\n\nä½ å¯ä»¥å¿½ç•¥è¡çªï¼Œä¸¦ç¹¼çºŒåŒæ­¥ã€‚
Update ->
æ›´æ–° ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-用法:é¸æ“‡ç›£æ¸¬çš„目錄並輸入命令行。æ¯æ¬¡ç›®éŒ„(或å­ç›®éŒ„)中的檔案被修改時,此命令列就會執行。
+Usage:
+使用é‡ï¼š
Use Recycle Bin
使用資æºå›žæ”¶ç­’
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
警告:åŒæ­¥å¤±æ•—çš„å稱為 %x 項目:
When the comparison is started with this option set the following decision tree is processed:
當比å°é–‹å§‹ï¼Œä½¿ç”¨æ­¤é¸é …設定時,以下決策樹將被處ç†ï¼š
+You can ignore conflicts and continue synchronization.
+ä½ å¯ä»¥å¿½ç•¥è¡çªï¼Œä¸¦ç¹¼çºŒåŒæ­¥ã€‚
You can ignore the error to consider not existing directories as empty.
ä½ å¯ä»¥å¿½ç•¥è©²éŒ¯èª¤è€Œå°‡ä¸å­˜åœ¨çš„目錄視為空目錄。
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/czech.lng b/BUILD/Languages/czech.lng
index 8be657b4..56778c7b 100644
--- a/BUILD/Languages/czech.lng
+++ b/BUILD/Languages/czech.lng
@@ -46,6 +46,8 @@ souborů: %x;
&Zrušit
&Check for new version
Zkontrolovat &aktualizace
+&Content
+&Obsah
&Create batch job
&Vytvořit dávku
&Default
@@ -88,6 +90,8 @@ U&konÄit
&Ano
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Platí pouze pro souborové systémy FAT/FAT32. V ostatních případech můžete nastavení \"Ignorovat 1 hodinu rozdílu v Äase mezi soubory\" nechat vypnuté.)
+(Requires an Internet connection!)
+(Vyžaduje připojení k internetu!)
,
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@ soubor: 1;
1. &Porovnat
1. Enter relative file or directory names separated by ';' or a new line.
1. Můžete použít relativní cesty k souboru nebo adresáři oddělené ';' nebo řádkem.
+1. Select directories to monitor.
+1. Vyberte adresáře pro sledování.
2. &Synchronize...
2. &Synchronizovat...
+2. Enter a command line.
+2. Zadejte příkazovou řádku.
2. Use wildcard characters '*' and '?'.
2. Můžete použít zástupné znaky (wildcard) '*' a '?'.
3. Exclude files directly on main grid via context menu.
3. Můžete použít pro vynechávání souborů přímo kontextového menu.
+3. Press 'Start'.
+3. ZmáÄknÄ›te 'Start'
<Automatic>
<Automaticky>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Jak název napovídá, dva soubory mající stejné jméno jsou oznaÄeny za shodné jen a pouze pokud mají shodný obsah. Toto nastavení je vhodné spíše pro sledování konzistence než pro zálohování. Proto nejsou data zmÄ›n souborů brána vůbec v potaz.\n\nPokud vyberete toto nastavení bude schéma rozhodování kratší:
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.
Vytvoření dávkového souboru pro automatický provoz. Ke spuštění dávky jednoduše její jméno zadejte jako parametr při spuštění FreeFileSync: FreeFileSync.exe <batchfile>.
+At least one directory input field is empty.
+Alespoň jedno zadání adresáře je prázdné.
Auto-adjust columns
Automaticky přizpůsobit šířku
Automatic mode
@@ -192,19 +204,17 @@ Build:
Build:
Cancel
Zrušit
-Cannot determine sync-direction: Changed filter settings!
-Nelze urÄit smÄ›r synchronizace: Změňte nastavení filtru!
-Cannot determine sync-direction: No change since last synchronization!
-Nelze urÄit smÄ›r synchronizace: NedoÅ¡lo ke zmÄ›nám od poslední synchronizace!
+Cannot determine sync-direction:
+Nelze urÄit smÄ›r synchronizace:
Category
Kategorie
Change direction
Změnit akci
Comma separated list
Text oddÄ›lený Äárkami
-Commandline
+Command line
Příkazová řádka
-Commandline is empty!
+Command line is empty!
Příkazová řádka je prázdná!
Compare
Porovnat
@@ -260,8 +270,12 @@ Copy from right to left
Kopírovat z prava do leva
Copy from right to left overwriting
Kopírovat z prava do leva přepisem
+Copy locked files
+Kopírovat zamÄené soubory
Copy new or updated files to right folder.
Kopírovat nové nebo aktualizované soubory do adresáře vpravo.
+Copy shared or locked files using Volume Shadow Copy Service.
+Kopírovat sdílené nebo zamÄené soubory pomocí Volume Shadow Copy Service.
Copy to clipboard\tCTRL+C
Vložit do schránky\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Není možné zjistit jméno jednotky souboru:
Could not initialize directory monitoring:
Nelze nastavit monitorování adresáře:
+Could not load a required DLL:
+Nelze naÄíst požadovanou knihovnu DLL:
Could not read values for the following XML nodes:
Nelze naÄíst hodnoty následujících XML elementy:
Create a batch job
@@ -298,7 +314,7 @@ Date
Datum
Delay
Zpoždění
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Zpoždění detekce změn a spuštění příkazu v sekundách
Delete files/folders existing on left side only
Smazat soubory/adresáře existující pouze na levé straně
@@ -386,6 +402,8 @@ Error reading file:
Chyba Ätení souboru:
Error reading from synchronization database:
Chyba Ätení synchronizaÄní databáze:
+Error resolving full path name:
+Chyba názvu plné cesty:
Error resolving symbolic link:
Chyba odkazu zástupce:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtrovat soubory
Filter has been selected
Filtr je zapnut
+Filter settings have changed!
+Nastavení filtru bylo změněno!
Filter view
Filtrovat seznam
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Použít všechny řádky
Include temporarily
PÅ™idat doÄasnÄ›
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Přidat: *.doc;*.zip;*.exe\nVynechat: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Přidat: *.doc;*.zip;*.exe\nVynechat: \\stuff\\temp\\*
Incompatible synchronization database format:
Chyba formátu synchronizaÄní databáze:
Info
@@ -572,8 +592,6 @@ 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. :)
-Nebylo možné inicializovat Koš!\n\nPravděpodobně nepoužíváte Windows.\nPokud chcete tuto vlastnost využívat, kontaktujte autora. :)
Leave as unresolved conflict
Ponechat jako nevyřešený konflikt
Left
@@ -590,18 +608,22 @@ Log-messages:
Záznamy:
Logging
Zaznamenávání
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Vytváření stínových kopíí na WOW64 není podporováno. Prosím použijte 64 bitovou verzi FreeFileSync.
Mirror ->>
Zrcadlení ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Zrcadlení levého adresáře: Pravý adresář bude přepsán a po synchronizaci bude totožný s levým.
+Monitoring active...
+Sledování zapnuto...
More than 50% of the total number of files will be copied or deleted!
Více než 50% souborů bude kopírovaných nebo mazaných!
Move column down
Přesunout sloupec dolů
Move column up
Přesunout sloupec nahoru
-Move files to a user-defined directory.
-Přesunout soubory do uživatelem definovaného adresáře.
+Move files into a time-stamped subdirectory.
+PÅ™esunout soubory do ÄasovÄ› oznaÄeného podadresáře.
Moving %x to Recycle Bin
Přesouvání %x do Koše.
Moving file %x to user-defined directory %y
@@ -610,6 +632,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 change since last synchronization!
+Žádné změny od poslední synchronizace!
No filter selected
Není vybrán žádný filtr
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pauza
Paused
Pauza
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Prosím proveÄte nejdřív porovnání pÅ™ed synchronizací!
+Processing folder pair:
+Zpracovávání adresářové páru:
Published under the GNU General Public License:
Vydáno podl GNU General Public License (GPL):
Question
@@ -670,6 +692,8 @@ Remove folder pair
Odstranit dvojici adresářů
Remove local filter settings
Odstranit nastavení místního filtru
+Renaming file %x to %y
+Přejmenovávání souboru %x na %y
Report translation error
Hlásit chyby překladu
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Cílový adresář již existuje!
Target file already existing!
Cílový soubor již existuje!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+Příkazová řádka je spuštěna pokaždé když:\n- dojde ke změně souborů v adresáři (nebo podadresářích)\n- je připojen odpovídající disk (vložením USB disku)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
není možné vytvořit záznamový soubor!
Unable to initialize Recycle Bin!
Není možné použít Koš!
+Unresolved conflicts existing!
+Nevyřešené konflikty!
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 ->
Aktualizuj ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Použití: Vyberte adresáře, které mají být monitorovány a vložte příkaz. Pokaždé, když dojde ke změně v těchto adresářích (nebo podadresářích), bude příkaz spuštěn.
+Usage:
+Použití:
Use Recycle Bin
Použít Koš
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Varování: Synchronizace se nepovedla pro \"%x\" položek:
When the comparison is started with this option set the following decision tree is processed:
Když je zahájeno porovnávání s tímto nastavením, je použito následující schéma rozhodování:
+You can ignore conflicts and continue synchronization.
+Je možné konflikt ignorovat a pokraÄovat v synchronizaci.
You can ignore the error to consider not existing directories as empty.
Pro považování neexistujících adresářů jako prázdných můžete chybu ignorovat.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/dutch.lng b/BUILD/Languages/dutch.lng
index c17049ba..0aaf8f61 100644
--- a/BUILD/Languages/dutch.lng
+++ b/BUILD/Languages/dutch.lng
@@ -46,6 +46,8 @@
&Annuleren
&Check for new version
&Controleer op nieuwe versie
+&Content
+&Help artikelen
&Create batch job
&Creëer batchjob
&Default
@@ -88,6 +90,8 @@
&Ja
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Alleen FAT/FAT32 schijven hebben last van dit probleem!\nIn alle andere gevallen kunt u deze instelling uitschakelen \"negeer 1-uur tijdsverschil\".)
+(Requires an Internet connection!)
+(Vereist een internetverbinding)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Vergelijk
1. Enter relative file or directory names separated by ';' or a new line.
1. Vul de relatieve bestandsnaam of map in, gescheiden bij ';' of een nieuwe regel.
+1. Select directories to monitor.
+1. Selecteer mappen om te observeren.
2. &Synchronize...
2. &Synchroniseer...
+2. Enter a command line.
+2. Geef een opdrachtregel in.
2. Use wildcard characters '*' and '?'.
2. U kunt gebruik maken van wildcard karakters zoals '*' en '?'.
3. Exclude files directly on main grid via context menu.
3. Sluit bestanden direct uit in het hoofscherm via een contextmenu
+3. Press 'Start'.
+3. Klik op 'Start'.
<Automatic>
<Automatisch>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Zoals de naam suggereert, worden twee bestanden met dezelfde naam alleen gemarkeerd als gelijk, als ze precies dezelfde inhoud hebben. Deze optie is handig voor een consistentiecontrole in plaats van back-up handelingen. Daarom worden de tijdstempels niet bekeken.\n\n Met deze optie aan is de beslissingsboom korter:
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.
Assembleer een batchbestand voor automatische synchronisatie. Om te starten in batchmodus is het voldoende om de bestandsnaam achter de FreeFileSync toepassing te zetten: FreeFileSync.exe <batchbestand>. Het is mogelijk dit in te plannen in de systeemplanner.
+At least one directory input field is empty.
+Er is minimaal één locatie-veld leeg.
Auto-adjust columns
Kolommen automatisch aanpassen
Automatic mode
@@ -192,19 +204,17 @@ Build:
Gebouwd:
Cancel
Annuleren
-Cannot determine sync-direction: Changed filter settings!
-Kan de synchronisatie-richting niet bepalen: verandering in
-Cannot determine sync-direction: No change since last synchronization!
-Kan de synchronisatie-richting niet bepalen: geen verandering sinds de laatste synchronisatie!
+Cannot determine sync-direction:
+Kan de synchronisatie-richting niet bepalen:
Category
Categorie
Change direction
Zijdes omwisselen
Comma separated list
Komma gescheiden lijst
-Commandline
+Command line
Opdrachtregel
-Commandline is empty!
+Command line is empty!
Opdrachtregel is leeg!
Compare
Vergelijk
@@ -260,8 +270,12 @@ Copy from right to left
Kopieer van rechts naar links
Copy from right to left overwriting
Kopieer en overschrijf van rechts naar links
+Copy locked files
+Kopieer 'alleen lezen' bestanden
Copy new or updated files to right folder.
Kopieer nieuwe of geupdate bestanden naar de rechter map.
+Copy shared or locked files using Volume Shadow Copy Service.
+Kopieer gedeelde of alleen-lezen bestanden met Volume Shadow Copy Service.
Copy to clipboard\tCTRL+C
Kopieer naar het klembord\tCTRL+C
Copying file %x to %y
@@ -271,7 +285,9 @@ Aan het overschrijven van bestand %x naar %y
Could not determine volume name for file:
Kon de schijfnaam niet vaststellen van bestand:
Could not initialize directory monitoring:
-Initaliseren van locatie-controle niet mogelijk:
+Initaliseren van locatie-observatie niet mogelijk:
+Could not load a required DLL:
+Kon een benodigde DLL niet laden:
Could not read values for the following XML nodes:
Kon geen waarden inlezen voor de volgende XML punten:
Create a batch job
@@ -298,7 +314,7 @@ Date
Datum
Delay
Vertraging
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Vertraging tussen detecteren van veranderingen en uitvoering van de opdrachtregel in seconden
Delete files/folders existing on left side only
Verwijder bestanden/folders die alleen links bestaan
@@ -386,6 +402,8 @@ Error reading file:
Er is een fout opgetreden bij het lezen van het bestand:
Error reading from synchronization database:
Er is een fout opgetreden bij het lezen van de synchronisatie-database:
+Error resolving full path name:
+Er is een fout opgetreden bij het ophalen van de locatie van bestand:
Error resolving symbolic link:
Er is een fout opgetreden bij het ophalen van een symbolische koppeling:
Error starting Volume Shadow Copy Service!
@@ -393,7 +411,7 @@ Er is een fout opgetreden bij het starten van de Volume Schadow Copy Service!
Error traversing directory:
Er is een fout opgetreden bij het doorzoeken van map:
Error when monitoring directories.
-Er is een fout opgetreden bij het controleren van locaties.
+Er is een fout opgetreden bij het observeren van locaties.
Error writing file attributes:
Er is een fout opgetreden bij het schrijven van de bestands-eigenschappen:
Error writing file:
@@ -466,6 +484,8 @@ Filter files
Filter bestanden
Filter has been selected
Filter is geselecteerd
+Filter settings have changed!
+Filter instellingen opgeslagen!
Filter view
Bekijk het filter
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Alle rijen gebruiken
Include temporarily
Tijdelijk bijsluiten
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Bijsluiten: *.doc;*.zip;*.exe\nUitsluiten: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Bijsluiten: *.doc;*.zip;*.exe\nUitsluiten: \\stuff\\temp\\*
Incompatible synchronization database format:
Opmaak van synchronisatie-database komt niet overeen:
Info
@@ -572,8 +592,6 @@ 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. :)
-Het was niet mogelijk de prullenbak te initialiseren!\n\nHet is waarschijnlijk dat u niet Windows gebruikt.\nAls u deze optie wel wilt, neem dan alstublieft contact op met de auteur. :)
Leave as unresolved conflict
Beschouwen als onopgelost conflict
Left
@@ -590,18 +608,22 @@ Log-messages:
Logberichten:
Logging
Loggen
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Schaduw kopieen op WOW64 worden niet ondersteund. Gebruik alstublieft de 64-bit versie van FreeFileSync.
Mirror ->>
Spiegelen ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Spiegel backup van de linkerkant: de rechterkant wordt overschreven en komt na synchronisatie exact overeen met de linkerkant.
+Monitoring active...
+Observeren actief...
More than 50% of the total number of files will be copied or deleted!
Meer dan 50% van alle bestanden zal worden gekopieerd of verwijderd!
Move column down
Verplaats kolom naar beneden
Move column up
Verplaats kolom naar boven
-Move files to a user-defined directory.
-Verplaats bestanden naar een door de gebruiker te definiëren map.
+Move files into a time-stamped subdirectory.
+Verplaats de bestanden in een tijd-gemarkeerde sublocatie.
Moving %x to Recycle Bin
%x aan het verplaatsen naar de Prullenbak
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Verplaatsen map %x naar een door de gebruiker gedefinieerde locatie %y
Multiple...
Meerdere...
+No change since last synchronization!
+Geen veranderingen sinds de laatste synchronisatie!
No filter selected
Geen filter geselecteerd
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pause
Paused
Gepauseerd
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Voer eerst een Vergelijking uit voordat u synchroniseerd.
+Processing folder pair:
+Verwerken van gekoppelde folder:
Published under the GNU General Public License:
Gepubliceerd onder de GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Verwijder 1 paar gekoppelde mappen
Remove local filter settings
Verwijder lokale filter instellingen
+Renaming file %x to %y
+Hernoemen van bestand %x naar %y
Report translation error
Rapporteer een fout in de vertaling
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Doellocatie bestaal al!
Target file already existing!
Doelbestand bestaat al!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+De opdrachtregel wordt elke keer uitgevoerd als:\n- Bestanden in deze folders (of subfolders) zijn gewijzigd\n- De gekoppelde schijf beschikbaar wordt (USB-invoegen)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Niet mogelijk om een logbestand aan te maken!
Unable to initialize Recycle Bin!
De prullenbak kon niet worden geïnitialiseerd!
+Unresolved conflicts existing!
+Er bestaan onopgeloste conflicten!
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 ->
Overschrijven ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Uitleg: Selecteer locaties om te controleren en type een opdrachtregel. Elke keer dat bestanden worden aangepast binnen die locaties (en/of sublocaties) wordt de opdrachtregel uitgevoerd.
+Usage:
+Gebruik:
Use Recycle Bin
Gebruik de prullenbak
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Let op: %x item(s) konden niet worden gesynchroniseerd:
When the comparison is started with this option set the following decision tree is processed:
Wanneer met deze optie aan de vergelijking wordt gestart zal de volgende vergelijkingsboom worden gebruikt:
+You can ignore conflicts and continue synchronization.
+U kunt de conflicten negeren en doorgaan met synchroniseren.
You can ignore the error to consider not existing directories as empty.
U kunt de fout negeren om niet bestaande locaties als leeg te beschouwen.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/finnish.lng b/BUILD/Languages/finnish.lng
index d4b45c04..f988eed6 100644
--- a/BUILD/Languages/finnish.lng
+++ b/BUILD/Languages/finnish.lng
@@ -46,6 +46,8 @@
&Lopeta
&Check for new version
Etsi &uusi versio
+&Content
+
&Create batch job
&Tee eräajo
&Default
@@ -88,6 +90,8 @@ Asetusten &lataus
&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\".)
+(Requires an Internet connection!)
+
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@ Asetusten &lataus
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
+1. Select directories to monitor.
+
2. &Synchronize...
2. &Täsmäytä...
+2. Enter a command line.
+
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.
+3. Press 'Start'.
+
<Automatic>
<- Automaattinen ->
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
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.
+At least one directory input field is empty.
+
Auto-adjust columns
Säädä sarakeleveys automaattisesti
Automatic mode
@@ -192,20 +204,18 @@ 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ä!
+Cannot determine sync-direction:
+
Category
Luokka
Change direction
Vaihda suunta
Comma separated list
CSV-muotoinen lista
-Commandline
+Command line
Komentokehote
-Commandline is empty!
-Tyhjä komentokehote!
+Command line is empty!
+
Compare
Vertaile
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
Kopioidaan oikea -> vasen
Copy from right to left overwriting
Kopioidaan oikea -> vasen ylikirjoittaen
+Copy locked files
+
Copy new or updated files to right folder.
Kopioidaan uudet tai muuttuneet tiedostot oikeaan hakemistoon.
+Copy shared or locked files using Volume Shadow Copy Service.
+
Copy to clipboard\tCTRL+C
Kopioi Leikepöydälle\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Levyasemaa ei tunnistettu tiedostolle:
Could not initialize directory monitoring:
Ei voitu käynnistää hakemiston tarkkailua:
+Could not load a required DLL:
+
Could not read values for the following XML nodes:
Tietoja lukeminen epäonnistui, XML jäsen:
Create a batch job
@@ -298,7 +314,7 @@ Date
Päiväys
Delay
Viive
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Viive sekunneissa havaitun muutoksen ja komentokehotteen suorittamisen välillä
Delete files/folders existing on left side only
Poista vain tiedostoja/hakemistoja vasemmalta
@@ -386,6 +402,8 @@ Error reading file:
Virhe lukiessa tiedostoa:
Error reading from synchronization database:
Virhe lukiessa täsmäytyksen tietokantaa:
+Error resolving full path name:
+
Error resolving symbolic link:
Virhe selvittäessä symbolista linkkiä:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Suodata tiedostoja
Filter has been selected
Suodin valittu
+Filter settings have changed!
+
Filter view
Näytä suodattimet
Filtering is deactivated
@@ -560,8 +580,8 @@ 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\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Sisällytä: *.doc;*.zip;*.exe\nSulje pois: \\stuff\\temp\\*
Incompatible synchronization database format:
Täsmäytyksen tietokannan muoto on virheellinen:
Info
@@ -572,8 +592,6 @@ 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
@@ -590,18 +608,22 @@ Log-messages:
Lokin viestit:
Logging
Kirjaa
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+
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.
+Monitoring active...
+
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
+Move files into a time-stamped subdirectory.
+
Moving %x to Recycle Bin
Siirrä %x Roskakoriin
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Siirrä hakemisto %x valittuun hakemistoon %y
Multiple...
Moninkertainen...
+No change since last synchronization!
+
No filter selected
Suodin valitsematta
Not enough free disk space available in:
@@ -642,12 +666,10 @@ 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ä.
+Processing folder pair:
+
Published under the GNU General Public License:
Julkaistu lisenssillä GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Poista hakemistopari
Remove local filter settings
Poista paikalliset suotimet
+Renaming file %x to %y
+
Report translation error
Ilmoita käännösvirheestä
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Haluttu tiedosto on jo olemassa!
Target file already existing!
Kohde tiedosto on jo olemassa!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Lokitiedostoa ei pystytä luomaan!
Unable to initialize Recycle Bin!
Roskakorin initialisointi ei onnistu!
+Unresolved conflicts existing!
+
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.
+Usage:
+
Use Recycle Bin
Käytä Roskakoria
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ 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 conflicts and continue synchronization.
+
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.
diff --git a/BUILD/Languages/french.lng b/BUILD/Languages/french.lng
index ad91f136..bae3af5d 100644
--- a/BUILD/Languages/french.lng
+++ b/BUILD/Languages/french.lng
@@ -46,6 +46,8 @@
&Annuler
&Check for new version
&Rechercher une nouvelle version
+&Content
+&Contenu
&Create batch job
&Créer un fichier de commandes
&Default
@@ -88,6 +90,8 @@
&Oui
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Notez que seuls les lecteurs FAT/FAT32 sont touchées par ce problème ! \ NDans les autres cas, vous pouvez désactiver le paramètre \ "ignorer la différence d'une heure \".)
+(Requires an Internet connection!)
+(Nécessite une connexion internet)
,
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Comparer
1. Enter relative file or directory names separated by ';' or a new line.
1. Entrez les noms relatifs des fichiers ou des répertoires séparés par un ';' ou par un passage à la ligne.
+1. Select directories to monitor.
+1. Sélectionner les répertoires à surveiller.
2. &Synchronize...
2. &Synchroniser...
+2. Enter a command line.
+2. Entrez une ligne de commande.
2. Use wildcard characters '*' and '?'.
2. Les caractères génériques '*' et '?' sont acceptés.
3. Exclude files directly on main grid via context menu.
3. Exclure les fichiers directement sur le tableau principal à l'aide du menu contextuel.
+3. Press 'Start'.
+3. Cliquez sur 'Démarrer'.
<Automatic>
<Automatique>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Comme le nom le suggère, deux fichiers qui ont le même nom sont considérés comme identiques si, et seulement si, leur contenu est identique. Cette option est utile pour les contrôles de cohérence plutôt que pour les opérations de sauvegarde. Toutefois, les dates et heures ne sont pas du tout prises en compte.\n\nAvec cette option, l'arbre de décision est plus simple :
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.
Créer un fichier de commandespour une synchronisation automatique. Pour démarrer en mode batch, indiquer le nom du fichier à l'exécutable FreeFileSync : freefilesync.exe <fichier de commandes>. Ceci peut aussi être programmé dans le plannificateur de tâches.
+At least one directory input field is empty.
+Au moins un champ répertoire est vide.
Auto-adjust columns
Auto-ajustement des colonnes
Automatic mode
@@ -192,20 +204,18 @@ Build:
Créé le :
Cancel
Annuler
-Cannot determine sync-direction: Changed filter settings!
-Impossible de déterminer le sens de la synchro : la configuration a été modifiée !
-Cannot determine sync-direction: No change since last synchronization!
-Impossible de déterminer le sens de la synchro : Aucune modification depuis la dernière synchro !
+Cannot determine sync-direction:
+Impossible de déterminer le sens de la synchro :
Category
Catégorie
Change direction
Changer la direction
Comma separated list
Liste d'éléments séparés par une virgule
-Commandline
+Command line
Ligne de commande
-Commandline is empty!
-ligne de commande vide
+Command line is empty!
+La ligne de commande est vide !
Compare
Comparer
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
Copie de droite à gauche
Copy from right to left overwriting
Copie de droite à gauche avec remplacement
+Copy locked files
+Copier les fichiers verrouilés
Copy new or updated files to right folder.
Copie de fichiers nouveaux ou modifiés dans le dossier de droite.
+Copy shared or locked files using Volume Shadow Copy Service.
+Copier les fichiers partagés ou verrouilés en utilisant le service Volume Shadow Copy
Copy to clipboard\tCTRL+C
Copier dans le presse-papiers\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Impossible de trouver le nom de volume pour le fichier :
Could not initialize directory monitoring:
Impossible d'initialiser la surveillance des dossiers:
+Could not load a required DLL:
+Impossible de charger une DLL :
Could not read values for the following XML nodes:
Impossible de lire les valeurs des noeuds XML suivants :
Create a batch job
@@ -298,7 +314,7 @@ Date
Date
Delay
délai
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Intervalle entre la détection des changements et l'exécution de la ligne de commande en secondes
Delete files/folders existing on left side only
Suppression des fichiers/répertoires n'existant que sur le côté gauche
@@ -386,6 +402,8 @@ Error reading file:
Erreur lors de la lecture du fichier :
Error reading from synchronization database:
Erreur lors de la lecture de la base de données de synchro :
+Error resolving full path name:
+Erreur lors de la résolution du chemin :
Error resolving symbolic link:
Erreur lors de la résolution du lien symbolique :
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtrage des fichiers
Filter has been selected
Le filtre a été sélectionné
+Filter settings have changed!
+La configuration du filtre a changé !
Filter view
Filtrage de la vue
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Inclure toutes les lignes
Include temporarily
Inclure temporairement
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Inclure : *.doc;*.zip;*.exe\nExclure : temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Inclure : *.doc;*.zip;*.exe\nExclure : \\stuff\\temp\\*
Incompatible synchronization database format:
Format de la base de données de synchro incompatible :
Info
@@ -572,8 +592,6 @@ 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. :)
-Impossible d'accéder à la corbeille !\n\nIl est probable que vous n'utilisez pas Windows.\nSi vous désirez utilisee cette fonctionnalité, veuillez contacter l'auteur. :)
Leave as unresolved conflict
Abandonner en tant que conflit non résolu
Left
@@ -590,18 +608,22 @@ Log-messages:
Messages log :
Logging
Connexion
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+La copie en tâche de fond sur WOW64 n'est pas possible. Utilisez pour cela la version 64 bits de FreeFileSync.
Mirror ->>
Mirroir ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Sauvegarde miroir du répertoire de gauche : Le répertoire de droite sera écrasé et exactement identique au répertoire de gauche après la synchronisation.
+Monitoring active...
+Surveillance en cours...
More than 50% of the total number of files will be copied or deleted!
Plus de 50% des fichiers seront copiés ou détruits !
Move column down
Déplacer la colonne vers le bas
Move column up
Déplacer la colonne vers le haut
-Move files to a user-defined directory.
-Déplacer les fichiers vers un répertoire défini par l'utilisateur.
+Move files into a time-stamped subdirectory.
+Déplacer les fichiers vers un sous-répertoire daté.
Moving %x to Recycle Bin
Déplacement de %x vers la Corbeille
Moving file %x to user-defined directory %y
@@ -610,6 +632,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 change since last synchronization!
+Aucun changement depuis la dernière synchronisation !
No filter selected
Aucun filtre sélectionné
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pause
Paused
En pause
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Veuillez cliquer sur "Compareré avant de lancer la synchronisation !
+Processing folder pair:
+Traitement de la paire de dossiers :
Published under the GNU General Public License:
Publié sous la licence GNU General Public :
Question
@@ -670,6 +692,8 @@ Remove folder pair
Supprimer le couple de dossiers
Remove local filter settings
Supprimer la configuration du filtre local
+Renaming file %x to %y
+Renommage des fichiers %x en %y
Report translation error
Etat d'erreurs de transfert
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Le répertoire de destination existe déjà !
Target file already existing!
Le fichier de destination existe déjà !
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+La ligne de commande est exécutée chque fois que :\n- Les fichiers de ces répertoires (ou sous-répertoires sont modifiés\n- La lettre correspondant au disque devient accessible (insertion USB)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Impossible de créer un fichier log !
Unable to initialize Recycle Bin!
Impossible d'initialiser la corbeille !
+Unresolved conflicts existing!
+Il y a des conflits non résolus !
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 ->
Mise à Jour ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Utilisation : Choisir un dossier et entrer une ligne de commande. A chaque fois qu'un fichier est modifié dans ces dossiers (ou sous-dossiers), la ligne de commande est éxécutée.
+Usage:
+Utilisation :
Use Recycle Bin
Utilisation de la corbeille
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Attention : La synchronisation a échouée pour %x élément(s) :
When the comparison is started with this option set the following decision tree is processed:
Lorsque la comparaison démarre avec cette option, l'arbre de décision suivant est exécuté :
+You can ignore conflicts and continue synchronization.
+Vous pouvez ignorer ces conflits et continuer la synchronisation.
You can ignore the error to consider not existing directories as empty.
Vous pouvez ignorer l'erreur considérant qu'un dossier inexistant est vide.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/german.lng b/BUILD/Languages/german.lng
index 552019ed..cc82a8ad 100644
--- a/BUILD/Languages/german.lng
+++ b/BUILD/Languages/german.lng
@@ -90,6 +90,8 @@ Konfiguration &laden
&Ja
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Achtung: Nur FAT/FAT32 Laufwerke sind von diesem Problem betroffen!\nIn allen anderen Fällen kann die Einstellung \"Zeitunterschied von einer Stunde ignorieren\" deaktiviert werden.)
+(Requires an Internet connection!)
+(Eine Internetverbindung wird benötigt!)
,
.
- Other side's counterpart to %dir
@@ -134,12 +136,18 @@ Konfiguration &laden
1. &Vergleichen
1. Enter relative file or directory names separated by ';' or a new line.
1. Relative Datei- oder Verzeichnisnamen getrennt durch ';' oder eine Neuzeile eingeben.
+1. Select directories to monitor.
+1. Zu überwachende Verzeichnisse wählen.
2. &Synchronize...
2. &Synchronisieren...
+2. Enter a command line.
+2. Eine Befehlszeile angeben.
2. Use wildcard characters '*' and '?'.
2. Die Platzhalter '*' und '?' werden unterstützt.
3. Exclude files directly on main grid via context menu.
3. Dateien können direkt über das Kontextmenü im Hauptfenster ausgeschlossen werden.
+3. Press 'Start'.
+3. 'Start' drücken.
<Automatic>
<Automatik>
<Directory>
@@ -174,8 +182,10 @@ As the name suggests, two files which share the same name are marked as equal if
Wie der Name andeutet, werden zwei Dateien mit gleichem Namen genau dann als gleich angesehen, wenn sie den gleichen Dateiinhalt haben. Diese Einstellung ist eher für Konsistenzprüfungen geeignet als für Backup-Operationen. Aus diesem Grund wird der Zeitpunkt der letzten Änderung der Dateien nicht berücksichtigt.\n\nDer Entscheidungsbaum ist in diesem Fall kleiner:
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.
Erzeuge eine Batchdatei für die automatisierte Synchronisation. Um den Batch-Modus zu starten, muss nur der Dateiname an die Programmdatei übergeben werden: FreeFileSync.exe <Batchdatei>. Dies kann auch in den Taskplaner des Betriebssystems eingetragen werden.
+At least one directory input field is empty.
+Mindestens ein Verzeichniseingabefeld ist leer.
Auto-adjust columns
-Spalten automatisch anpassen
+Spalten automatisch ausrichten
Automatic mode
Automatik Modus
Batch execution
@@ -194,19 +204,17 @@ Build:
Build:
Cancel
Abbrechen
-Cannot determine sync-direction: Changed filter settings!
-Synchronisationsrichtung konnte nicht bestimmt werden: Filtereinstellungen wurden geändert!
-Cannot determine sync-direction: No change since last synchronization!
-Synchronisationsrichtung konnte nicht bestimmt werden: Keine Änderungen seit der letzten Synchronisation!
+Cannot determine sync-direction:
+Die Synchronisationsrichtung konnte nicht bestimmt werden:
Category
Kategorie
Change direction
Richtung ändern
Comma separated list
Kommagetrennte Liste
-Commandline
+Command line
Befehlszeile
-Commandline is empty!
+Command line is empty!
Die Befehlszeile ist leer!
Compare
Vergleichen
@@ -266,6 +274,8 @@ 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 shared or locked files using Volume Shadow Copy Service.
+Gesperrte oder gemeinsam verwendete Dateien mit Hilfe des Volume Shadow Copy Service kopieren.
Copy to clipboard\tCTRL+C
In die Zwischenablage kopieren\tCTRL+C
Copying file %x to %y
@@ -304,7 +314,7 @@ Date
Datum
Delay
Verzögerung
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
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
@@ -392,6 +402,8 @@ Error reading file:
Fehler beim Lesen der Datei:
Error reading from synchronization database:
Fehler beim Lesen der Synchronisationsdatenbank:
+Error resolving full path name:
+Fehler beim Ermitteln des vollen Pfadnamens:
Error resolving symbolic link:
Fehler beim Auflösen des Symbolischen Links:
Error starting Volume Shadow Copy Service!
@@ -472,6 +484,8 @@ Filter files
Dateien filtern
Filter has been selected
Filter ist ausgewählt
+Filter settings have changed!
+Die Filtereinstellungen wurden geändert!
Filter view
Ansicht filtern
Filtering is deactivated
@@ -566,8 +580,8 @@ Include all rows
Alle Zeilen einschließen
Include temporarily
Temporär einschließen
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Einschließen: *.doc;*.zip;*.exe\nAusschließen: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Einschließen: *.doc;*.zip;*.exe\nAusschließen: \\stuff\\temp\\*
Incompatible synchronization database format:
Inkompatibles Datenbankformat:
Info
@@ -578,8 +592,6 @@ 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. :)
-Die Papierkorbfunktion steht nicht zur Verfügung!\n\nWahrscheinlich benutzen Sie nicht Microsoft Windows.\nWenn Sie diese Funktion wirklich benötigen, kontaktieren Sie bitte den Autor. :)
Leave as unresolved conflict
Als unbehandelten Konflikt belassen
Left
@@ -596,18 +608,22 @@ Log-messages:
Protokollmeldungen:
Logging
Protokoll
+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.
Mirror ->>
Spiegeln ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Spiegelkopie des linken Verzeichnisses erstellen: Das rechte Verzeichnis wird dabei überschrieben und nach der Synchronisation dem linken exakt entsprechen.
+Monitoring active...
+Ãœberwachung aktiv...
More than 50% of the total number of files will be copied or deleted!
Mehr als 50% aller Dateien werden kopiert oder gelöscht!
Move column down
Spalte nach unten verschieben
Move column up
Spalte nach oben verschieben
-Move files to a user-defined directory.
-Verschiebe Dateien in benutzerdefiniertes Verzeichnis
+Move files into a time-stamped subdirectory.
+Verschiebe Dateien in ein Unterverzeichnis mit Zeitstempel.
Moving %x to Recycle Bin
Verschiebe %x in den Papierkorb
Moving file %x to user-defined directory %y
@@ -616,6 +632,8 @@ Moving folder %x to user-defined directory %y
Verschiebe Ordner %x in benutzerdefiniertes Verzeichnis %y
Multiple...
Verschiedene...
+No change since last synchronization!
+Keine Änderungen seit der letzten Synchronisation!
No filter selected
Kein Filter ausgewählt
Not enough free disk space available in:
@@ -648,10 +666,10 @@ Pause
Pause
Paused
Angehalten
-Please fill all empty directory fields.
-Bitte die leeren Verzeichnisfelder füllen.
Please run a Compare first before synchronizing!
Vor der Synchronisation bitte zuerst einen Vergleich ausführen!
+Processing folder pair:
+Verarbeite Verzeichnispaar:
Published under the GNU General Public License:
Veröffentlicht unter der GNU General Public License:
Question
@@ -674,6 +692,8 @@ Remove folder pair
Verzeichnispaar entfernen
Remove local filter settings
Lokale Filtereinstellungen entfernen
+Renaming file %x to %y
+Benenne Datei %x um nach %y
Report translation error
Ãœbersetzungsfehler melden
Reset
@@ -682,8 +702,6 @@ 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
@@ -792,6 +810,8 @@ Target directory already existing!
Zielverzeichnis existiert bereits!
Target file already existing!
Die Zieldatei existiert bereits!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+Die Befehlszeile wird ausgeführt wenn:\n- Dateien innerhalb dieser Verzeichnisse (oder Unterverzeichnisse) geändert werden\n- der zugehörige Laufwerksbuchstabe verfügbar wird (USB-Anschluss)
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:
@@ -822,18 +842,18 @@ Unable to create logfile!
Die Protokolldatei konnte nicht erstellt werden!
Unable to initialize Recycle Bin!
Der Papierkorb konnte nicht initialisiert werden!
+Unresolved conflicts existing!
+Es existieren ungelöste Konflikte!
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 Befehlszeile angeben. Jedesmal wenn Dateien innerhalb dieser Verzeichnisse (oder Unterverzeichnisse) verändert werden, wird die Befehlszeile ausgeführt.
+Usage:
+Verwendung:
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!
@@ -850,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Warnung: Synchronisation fehlgeschlagen für %x Element(e):
When the comparison is started with this option set the following decision tree is processed:
Wenn der Vergleich mit dieser Option gestartet wurde, wird folgender Entscheidungsbaum abgearbeitet:
+You can ignore conflicts and continue synchronization.
+Die Konflikte können ignoriert und die Synchronisation fortgesetzt werden.
You can ignore the error to consider not existing directories as empty.
Dieser Fehler kann ignoriert werden, um nicht existierende Verzeichnisse als leer anzusehen.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/hungarian.lng b/BUILD/Languages/hungarian.lng
index ea6fccaa..b2d32ead 100644
--- a/BUILD/Languages/hungarian.lng
+++ b/BUILD/Languages/hungarian.lng
@@ -46,6 +46,8 @@ A(z) %x nem megfelelő FreeFileSync kötegelt feladat fájl!
&Mégsem
&Check for new version
&Új verzió keresése
+&Content
+&Tartalom
&Create batch job
&Kötegelt feladat létrehozása
&Default
@@ -88,6 +90,8 @@ A(z) %x nem megfelelő FreeFileSync kötegelt feladat fájl!
&Igen
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Megjegyzés: Csak a FAT/FAT32 meghajtókat érinti ez a probléma!\nMinden más esetben ki lehet kapcsolni az \"1 órás különbség figyelmen kívül hagyása\" beállítást.)
+(Requires an Internet connection!)
+(Internetkapcsolat szükséges!)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@ A(z) %x nem megfelelő FreeFileSync kötegelt feladat fájl!
1. &Összehasonlítás
1. Enter relative file or directory names separated by ';' or a new line.
1. A relatív fájl- és mappanevek megadása pontosvesszővel elválasztva vagy új sorban.
+1. Select directories to monitor.
+1. Válaszd ki a figyelendő mappákat.
2. &Synchronize...
2. &Szinkronizálás
+2. Enter a command line.
+2. Add meg a parancssort.
2. Use wildcard characters '*' and '?'.
2. A csillag ('*') és a kérdőjel ('?') helyettesítő karakterek megengedettek.
3. Exclude files directly on main grid via context menu.
3. Fájlok közvetlen kizárása a fő listából helyi menü segítségével.
+3. Press 'Start'.
+3. Nyomd meg a Start gombot.
<Automatic>
<Automatikus>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Ahogy a neve is mutatja, két fájl, melyeknek ugyanaz a nevük, akkor és csakis akkor lesz egyezÅ‘ként jelölve, ha a tartalmuk megegyezik. Ez az opció leginkább a konzisztencia-viszgálatokhoz jó, mintsem a biztonsági mentésekhez. Ãgy a fájlok dátuma nem számít semmit.\n\nEnnek az opciónak az engedélyezésével a döntési fa kisebb lesz:
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.
Egy kötegelt feladat fájl létrehozása az automatizált szinkronizációhoz. Kötegelt feladat módban való indításhoz egyszerűen meg kell adni a fájl nevét a FreeFileSync.exe-nek: FreeFileSync.exe <kötegelt feladat fájl>. Ezt ütemezni is lehet az operációs rendszer feladatkezelőjével.
+At least one directory input field is empty.
+Legalább az egyik mappa beviteli mező üres.
Auto-adjust columns
Oszlopok automatikus igazítása
Automatic mode
@@ -192,19 +204,17 @@ Build:
Build:
Cancel
Mégsem
-Cannot determine sync-direction: Changed filter settings!
-Nem lehet meghatározni a szinkronizáció irányát: A szűrőbeállítások megváltoztak!
-Cannot determine sync-direction: No change since last synchronization!
-Nem lehet meghatározni a szinkronizáció irányát: Nem volt változás az utolsó szinkronizáció óta!
+Cannot determine sync-direction:
+Nem lehet meghatározni a szinkronizáció irányát:
Category
Kategória
Change direction
Irány megváltoztatása
Comma separated list
Comma separated values
-Commandline
+Command line
Parancssor
-Commandline is empty!
+Command line is empty!
A parancssor üres!
Compare
Összehasonlítás
@@ -260,8 +270,12 @@ Copy from right to left
Másolás a jobb oldalról a bal oldalra
Copy from right to left overwriting
Másolás a jobb oldalról a bal oldalra felülírással
+Copy locked files
+Zárolt fájlok másolása
Copy new or updated files to right folder.
Új vagy frissített fájlok másolása a jobb oldali mappába.
+Copy shared or locked files using Volume Shadow Copy Service.
+Megosztott vagy zárolt fájlok másolása a Volume Shadow Copy Service segítségével.
Copy to clipboard\tCTRL+C
Másolás a vágólapra\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
A következő fájlnak nem lehet meghatározni a kötetnevét:
Could not initialize directory monitoring:
A mappafigyelés inicializálása sikertelen:
+Could not load a required DLL:
+A szükséges DLL betöltése sikertelen:
Could not read values for the following XML nodes:
A következő XML-csomópontok értékének beolvasása sikertelen:
Create a batch job
@@ -298,7 +314,7 @@ Date
Dátum
Delay
Várakozás
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
A változások észlelése és a parancssor meghívása közötti várakozás másodpercben
Delete files/folders existing on left side only
Csak a bal oldalon létező fájlok/mappák törlése
@@ -386,6 +402,8 @@ Error reading file:
A fájl olvasása sikertelen:
Error reading from synchronization database:
Hiba történt a szinkronizációs adatbázis olvasása közben:
+Error resolving full path name:
+A teljes útvonal feloldása sikertelen:
Error resolving symbolic link:
A szimbolikus link feloldása sikertelen:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Fájlok szűrése
Filter has been selected
Szűrő kiválasztva
+Filter settings have changed!
+A szűrőbeállítások megváltoztak!
Filter view
Szűrő nézet
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Minden sort csatolni
Include temporarily
Ideiglenesen csatolni
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Csatol: *.doc;*.zip;*.exe\nKizár: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Csatol: *.doc;*.zip;*.exe\nKizár: \\stuff\\temp\\*
Incompatible synchronization database format:
Inkompatibilis szinkronizációs adatbázis formátum:
Info
@@ -572,8 +592,6 @@ 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. :)
-Lehetetlen a Lomtár (Recycle Bin) inicializálása!\n\nValószínűleg azért, mert nem Windost használ.\nHa szeretné ezt a funkciót használni, kérjük, lépjen kapcsolatba a szerzővel. :)
Leave as unresolved conflict
Feloldatlan ütközésként hagyni
Left
@@ -590,18 +608,22 @@ Log-messages:
Naplóbejegyzések:
Logging
Naplózás
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+A Shadow Copy a WOW64-en nem támogatott. Kérjük, használja a 64-bites FreeFileSync-et.
Mirror ->>
Tükrözés ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
A bal oldali mappa tükrözött másolata: A jobb oldali mappa felülíródik és pontosan megegyezik majd a bal oldalival a szinkronizálás után.
+Monitoring active...
+Figyelés aktív...
More than 50% of the total number of files will be copied or deleted!
Az összes fájl több mint 50%-a másolva vagy törölve lesz!
Move column down
Oszlop mozgatása lefelé
Move column up
Oszlop mozgatása felfelé
-Move files to a user-defined directory.
-Fájlok mozgatása a felhasználó által megadott mappába.
+Move files into a time-stamped subdirectory.
+Fájlok másolása időbélyeggel ellátott almappába.
Moving %x to Recycle Bin
%x mozgatása a Lomtárba
Moving file %x to user-defined directory %y
@@ -610,6 +632,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 change since last synchronization!
+Az utolsó szinkronizálás után nem történt változás.
No filter selected
Nincs szűrő kiválasztva
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Szünet
Paused
Szüneteltetve
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Kérjük, futtass le egy összehasonlítást mielőtt szinkronizálnál!
+Processing folder pair:
+Mappapár feldolgozása:
Published under the GNU General Public License:
Kiadva a GNU General Public License alatt:
Question
@@ -670,6 +692,8 @@ 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
+Renaming file %x to %y
+%x fájl átnevezése %y névre
Report translation error
Fordítói hiba bejelentése
Reset
@@ -786,6 +810,8 @@ 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 command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+A parancssor minden egyes alkalommal végrehajtódik, ha:\n- a megadott mappákban (vagy almappákban) lévő fájlok megváltoznak\n- a megfelelő meghajtójel elérhetővé válik (USB-csatolás)
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:
@@ -816,12 +842,14 @@ 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)!
+Unresolved conflicts existing!
+Feloldatlan ütközések vannak!
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 ->
Frissítés ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Használat: Válassza ki a figyelendő mappákat és adjon meg egy parancssort. Minden alkalommal, amikor az adott mappákon (vagy almappákon) belül megváltoznak a fájlok, a parancssor végrehajtásra kerül.
+Usage:
+Használat:
Use Recycle Bin
Lomtár (Recycle Bin) használata
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Figyelem: A következő %x elem szinkronizálása sikertelen:
When the comparison is started with this option set the following decision tree is processed:
Ha az összehasonlítás ezekkel a beállításokkal lesz elindítva, akkor a következő döntési fa érvényesül:
+You can ignore conflicts and continue synchronization.
+Figyelmen kívül hagyhatod az ütközéseket és folytathatod a szinkronizálást.
You can ignore the error to consider not existing directories as empty.
Figyelmen kívül hagyhatja a hibákat a nem létező mappákat üresnek tekintve.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/italian.lng b/BUILD/Languages/italian.lng
index 22e85097..df56ba46 100644
--- a/BUILD/Languages/italian.lng
+++ b/BUILD/Languages/italian.lng
@@ -46,6 +46,8 @@
&Annulla
&Check for new version
&Controlla la presenza di nuove versioni
+&Content
+&Contenuto
&Create batch job
&Crea un job in batch
&Default
@@ -88,6 +90,8 @@
&Si
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Solo volumi con file-system FAT/FAT32 risentono di questo problema!\nIn tutti gli altri casi puoi disabilitare l'impostazione \"ignora differenze di 1 ora\".)
+(Requires an Internet connection!)
+(Richiede una connessione Internet!)
,
,
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Compara
1. Enter relative file or directory names separated by ';' or a new line.
1. Inserisci i nomi relativi di file o directory separati da ';' o su una nuova riga.
+1. Select directories to monitor.
+1. Seleziona cartelle da monitorare.
2. &Synchronize...
2. &Sincronizza...
+2. Enter a command line.
+2. Inserisci linea di comando.
2. Use wildcard characters '*' and '?'.
2. Sono ammessi i caratteri generici '*' e '?'.
3. Exclude files directly on main grid via context menu.
3. Escludi i file direttamente sulla griglia principale tramite il menu contestuale.
+3. Press 'Start'.
+3. Premi 'Start'.
<Automatic>
<Automatico>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Come suggerisce il nome, due file con lo stesso nome sono considerati come identici se, e solamente se, il loro contenuto è identico. Questa opzione è utile sia per i contrlli di coerenza che per le operazioni di backup. Tuttavia, data e ora vengono ignorate.\n\nAbilitando questa opzione l'albero delle decisioni è semplificato:
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.
Componi un file batch per la sincronia automatica. Per partire in modalità batch fai semplicemente seguire il nome del file all'eseguibile di FreeFileSync: FreeFileSync.exe <nomefilebatch>. Puoi anche schedulare l'operazione nelle operazioni pianificate del sistema operativo.
+At least one directory input field is empty.
+Almeno un campo di inserimento cartella e' vuoto.
Auto-adjust columns
Larghezza automatica colonne
Automatic mode
@@ -192,20 +204,18 @@ Build:
Build:
Cancel
Annulla
-Cannot determine sync-direction: Changed filter settings!
-Impossibile determinare direzione di sincronia: Impostazioni filtro cambiate!
-Cannot determine sync-direction: No change since last synchronization!
-Impossibile determinare direzione di sincronia: Nessuna modifica dall'ultima sincronizzazione!
+Cannot determine sync-direction:
+Impossibile determinare direzione di sincronia:
Category
Categoria
Change direction
Cambia direzione
Comma separated list
Lista di elementi separati da virgola
-Commandline
+Command line
Linea di comando
-Commandline is empty!
-La linea di comando è vuota!
+Command line is empty!
+Linea di comando e' vuota!
Compare
Compara
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
Copia da destra a sinistra
Copy from right to left overwriting
Copia da destra a sinistra sovrascrivendo
+Copy locked files
+Copia file bloccati
Copy new or updated files to right folder.
Copia file nuovi o aggiornati nella cartella di destra.
+Copy shared or locked files using Volume Shadow Copy Service.
+Copia file condivisi o bloccati usando il servizio Volume Shadow Copy
Copy to clipboard\tCTRL+C
Copia nella clipboard\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Impossibile determinare il nome volume per il file:
Could not initialize directory monitoring:
Monitoraggio directory non inizializzabile:
+Could not load a required DLL:
+Impossibile caricare una DLL richiesta:
Could not read values for the following XML nodes:
Impossibile leggere i valori per i seguenti nodi XML:
Create a batch job
@@ -298,8 +314,8 @@ Date
Data
Delay
Ritardo
-Delay between detection of changes and execution of commandline in seconds
-Ritardo in secondi tra rilevazione cambiamenti ed esecuzione della commandline
+Delay between detection of changes and execution of command line in seconds
+Ritardo in secondi tra rilevazione cambiamenti ed esecuzione della command line
Delete files/folders existing on left side only
Elimina files/cartelle esistenti solo a sinistra
Delete files/folders existing on right side only
@@ -386,6 +402,8 @@ Error reading file:
Errore durante la lettura del file:
Error reading from synchronization database:
Errore in lettura dal database di sincronizzione:
+Error resolving full path name:
+Errore nella risoluzione del nome di percorso completo:
Error resolving symbolic link:
Errore nella risoluzione di collegamento simbolico:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtro dei files
Filter has been selected
Filtro selezionato
+Filter settings have changed!
+Le impostazioni del filtro sono cambiate!
Filter view
Filtro della vista
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Includi tutte le righe
Include temporarily
Includi temporaneamente
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Includi: *.doc;*.zip;*.exe\nEscludi: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Includi: *.doc;*.zip;*.exe\nEscludi: \\stuff\\temp\\*
Incompatible synchronization database format:
Formato database di sincronizzazione incompatibile:
Info
@@ -572,8 +592,6 @@ 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. :)
-Impossibile inizializzare il Cestino!\n\nE'probabile che non si stia utilizzando Windows.\nSe si vuole usare questa funzionalità, contattare l'autore. :)
Leave as unresolved conflict
Lascia come conflitti irrisolti
Left
@@ -590,18 +608,22 @@ Log-messages:
Log-messages:
Logging
Logging
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+La creazione di copie shadow su WOW64 non e' supportata. Utilizzare FreeFileSync in versione 64-bit.
Mirror ->>
Mirror ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Mirror backup della cartella di sinistra: La cartella di destra sarà sovrascritta e resa identica alla cartella di sinistra dopo la sincronizzazione.
+Monitoring active...
+Monitoraggio attivo...
More than 50% of the total number of files will be copied or deleted!
Piu' del 50% del totale dei files saranno copiati o cancellati!
Move column down
Sposta colonna giu'
Move column up
Sposta colonna su'
-Move files to a user-defined directory.
-Sposta i file in una directory personalizzata.
+Move files into a time-stamped subdirectory.
+Sposta file in una sotto-cartella datata.
Moving %x to Recycle Bin
Spostamento di %x nel Cestino
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Spostamento di cartella %x nella directory personalizzata %y
Multiple...
Multiplo...
+No change since last synchronization!
+Nessun cambiamento dall'ultima sincronizzazione!
No filter selected
Nessun filtro selezionato
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pausa
Paused
In pausa
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Prima di sincronizzare effettua una Comparazione!
+Processing folder pair:
+Elaborazione coppia di cartelle:
Published under the GNU General Public License:
Pubblicato sotto licenza GNU General Public:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Elimina la coppia di cartelle
Remove local filter settings
Rimuovi impostazioni di filtro locale
+Renaming file %x to %y
+Rinomina file %x in %y
Report translation error
Segnala errori di traduzione
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Directory di destinazione già esistente!
Target file already existing!
File destinazione già esistente!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+La linea di comando e' eseguita ogni volta che:\n- I file in queste cartelle (o sottocartelle) sono modificati\n- La corrispondente unita' disco e' disponibile (inserimento USB)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Impossibile creaer il file di log!
Unable to initialize Recycle Bin!
Impossibile inizializzare il Cestino!
+Unresolved conflicts existing!
+Sono presenti conflitti irrisolti!
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 ->
Aggiorna ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Uso: Seleziona le directory da monitorare e inserisci una linea di comando. Ogni volta che i file vengono modificati in queste directory (o sotto-directory) la linea di comando verrà eseguita.
+Usage:
+Uso:
Use Recycle Bin
Usa il Cestino
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Attenzione: Sincronizzazione fallita per %x elementi:
When the comparison is started with this option set the following decision tree is processed:
Quando questo set di opzioni viene selezionato per la comparazione viene processato il seguente albero di decisioni:
+You can ignore conflicts and continue synchronization.
+Puoi ignorare i conflitti e continuare la sincronizzazione.
You can ignore the error to consider not existing directories as empty.
Puoi ignorare l'errore per considerare directory inesistenti come vuote.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/japanese.lng b/BUILD/Languages/japanese.lng
index ff52cff2..f6a81d65 100644
--- a/BUILD/Languages/japanese.lng
+++ b/BUILD/Languages/japanese.lng
@@ -46,6 +46,8 @@
キャンセル(&C)
&Check for new version
ãƒãƒ¼ã‚¸ãƒ§ãƒ³æ›´æ–°ã®ç¢ºèª(&C)
+&Content
+トピック(&C)
&Create batch job
一括ジョブを作æˆ(&C)
&Default
@@ -88,6 +90,8 @@
ã¯ã„(&Y)
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(注æ„: FAT/FAT32 ドライブã®ã¿ã“ã®å½±éŸ¿ã‚’å—ã‘ã¾ã™! \n ãã®ä»–ã®ã‚±ãƒ¼ã‚¹ã§ã¯è¨­å®šã‚’無効ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"1 時間ã®å·®ç•°ã¯ç„¡è¦–" )
+(Requires an Internet connection!)
+(インターãƒãƒƒãƒˆæŽ¥ç¶šã‚’å¿…è¦ã¨ã—ã¾ã™!)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. 比較(&C)
1. Enter relative file or directory names separated by ';' or a new line.
1. 相対ファイルã€ã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’ ';' ã¾ãŸã¯ 改行ã§åŒºåˆ‡ã£ã¦å…¥åŠ›
+1. Select directories to monitor.
+1. 監視ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠž
2. &Synchronize...
2. åŒæœŸå‡¦ç†(&S)...
+2. Enter a command line.
+2. コマンドラインを入力
2. Use wildcard characters '*' and '?'.
2. ワイルドカード㫠' * ' 㨠' ? ' を使用出æ¥ã¾ã™ã€‚
3. Exclude files directly on main grid via context menu.
3. コンテキストメニューã‹ã‚‰ç›´æŽ¥ãƒ•ã‚¡ã‚¤ãƒ«ã‚’除外出æ¥ã¾ã™ã€‚
+3. Press 'Start'.
+3. 'スタート'をクリック
<Automatic>
<自動>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
ã“ã®ã‚ªãƒ—ションã§ã¯ã€åŒã˜åå‰ã‚’共有ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã§å†…容ãŒåŒã˜å ´åˆã¯ã€åŒä¸€ã¨ã—ã¦æ‰±ã‚ã‚Œã¾ã™ã€‚ ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—æ“作よりã€ã‚€ã—ã‚æ•´åˆæ€§ã®ãƒã‚§ãƒƒã‚¯ã‚’è¡Œã†æ™‚ã«å½¹ç«‹ã¤ã‚ªãƒ—ションã§ã™ã€‚ 従ã£ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã®æ—¥æ™‚ã«ã¤ã„ã¦ã¯å…¨ã考慮ã•ã‚Œã¦ã„ã¾ã›ã‚“。\n\n設定ãŒæœ‰åŠ¹ãªæ™‚ã¯ã€ãƒ„リー表示ãŒå°ã•ããªã‚Šã¾ã™ã€‚
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.
一括ã§åŒæœŸå‡¦ç†ã‚’è¡Œã†ãŸã‚ã®ãƒãƒƒãƒãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã—ã¾ã™ã€‚ 一括モードを開始ã™ã‚‹ã¨ãã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒ‘スåを実行ファイル\n< FreeFileSync.exe> \nã«ãƒãƒƒãƒãƒ•ã‚¡ã‚¤ãƒ«ã§æ¸¡ã™ã ã‘ã§ã™ã€‚ ã¾ãŸã€ã“ã®æ“作ã¯OSã®ã‚¿ã‚¹ã‚¯ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ©ã‹ã‚‰å®Ÿè¡Œã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+At least one directory input field is empty.
+å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„
Auto-adjust columns
列ã®è‡ªå‹•èª¿æ•´
Automatic mode
@@ -192,19 +204,17 @@ Build:
ビルド:
Cancel
中止
-Cannot determine sync-direction: Changed filter settings!
-åŒæœŸæ–¹å‘を決定ã§ãã¾ã›ã‚“: フィルター設定ãŒå¤‰æ›´ã•ã‚Œã¦ã„ã¾ã™!
-Cannot determine sync-direction: No change since last synchronization!
-åŒæœŸæ–¹å‘を決定ã§ãã¾ã›ã‚“: å‰å›žæœ€å¾Œã®åŒæœŸå‡¦ç†ä»¥é™ã€å¤‰æ›´ã¯ã‚ã‚Šã¾ã›ã‚“
+Cannot determine sync-direction:
+åŒæœŸæ–¹å‘ãŒæ±ºå®šã•ã‚Œã¦ã„ã¾ã›ã‚“:
Category
カテゴリ
Change direction
æ–¹å‘を変更
Comma separated list
カンマ区切り
-Commandline
+Command line
コマンドライン
-Commandline is empty!
+Command line is empty!
コマンドラインãŒç©ºç™½ã§ã™!
Compare
比較
@@ -260,8 +270,12 @@ Copy from right to left
å³ã‹ã‚‰å·¦ã«ã‚³ãƒ”ー
Copy from right to left overwriting
å³ã‹ã‚‰å·¦ã«ä¸Šæ›¸ãコピー
+Copy locked files
+ロックã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’コピー
Copy new or updated files to right folder.
æ–°ã—ã„(æ›´æ–°)ファイルをå³ãƒ•ã‚©ãƒ«ãƒ€ã«ã‚³ãƒ”ー
+Copy shared or locked files using Volume Shadow Copy Service.
+共有ã€ã¾ãŸã¯ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚·ãƒ£ãƒ‰ã‚¦ã‚³ãƒ”ーã§ãƒ­ãƒƒã‚¯ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’コピー
Copy to clipboard\tCTRL+C
クリップボードã«ã‚³ãƒ”ー\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
ファイルã®ãƒœãƒªãƒ¥ãƒ¼ãƒ åãŒæ±ºå®šã•ã‚Œã¦ã„ã¾ã›ã‚“:
Could not initialize directory monitoring:
監視ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“:
+Could not load a required DLL:
+å¿…è¦ãªDLLを読ã¿è¾¼ã‚ã¾ã›ã‚“:
Could not read values for the following XML nodes:
以下㮠XMLノードã®å€¤ã‚’読ã¿è¾¼ã‚€ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“:
Create a batch job
@@ -298,7 +314,7 @@ Date
データ
Delay
é…延時間
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
変更ã®æ¤œå‡ºã¨ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å®Ÿè¡Œé–“ã®é…延(秒)
Delete files/folders existing on left side only
å·¦å´ã®ã¿ã«å­˜åœ¨ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«/フォルダを削除
@@ -386,6 +402,8 @@ Error reading file:
ファイル読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼:
Error reading from synchronization database:
åŒæœŸãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‹ã‚‰ã®èª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼:
+Error resolving full path name:
+フルパスåã®è§£æ±ºã‚¨ãƒ©ãƒ¼:
Error resolving symbolic link:
シンボリックリンクã®è§£æ±ºã«å¤±æ•—:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
ファイルフィルター
Filter has been selected
フィルターã¯é¸æŠžæ¸ˆã¿ã§ã™
+Filter settings have changed!
+フィルター設定ã¯å¤‰æ›´ã•ã‚Œã¦ã„ã¾ã™!
Filter view
表示フィルター
Filtering is deactivated
@@ -541,7 +561,7 @@ 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
@@ -560,8 +580,8 @@ Include all rows
ã™ã¹ã¦ã®è¡Œã‚’å«ã‚ã‚‹
Include temporarily
一時フォルダをå«ã‚ã‚‹
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-å«ã‚ã‚‹: *.doc;*.zip;*.exe\n除外: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+å«ã‚ã‚‹: *.doc;*.zip;*.exe\n除外: \\stuff\\temp\\*
Incompatible synchronization database format:
åŒæœŸãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ›¸å¼ã«äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“:
Info
@@ -572,8 +592,6 @@ 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. :)
-ゴミ箱をåˆæœŸåŒ–ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸ!\n\n使用ã—ã¦ã„ã‚‹ OS ãŒã€Windows 以外㮠OS ã§ã™ã€‚\nã“ã®æ©Ÿèƒ½ã‚’使用ã—ãŸã„å ´åˆã¯ã€ä½œè€…ã¾ã§ã”連絡ãã ã•ã„ :)
Leave as unresolved conflict
未解決ã®ç«¶åˆã‚’残ã™
Left
@@ -590,18 +608,22 @@ Log-messages:
ログメッセージ:
Logging
ログ
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+WOW64 ã§ã¯ã€ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚·ãƒ£ãƒ‰ã‚¦ã‚³ãƒ”ーã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“ã€FreeFileSync 64-bit 版をãŠè©¦ã—ãã ã•ã„。
Mirror ->>
ミラー >>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
å·¦å´ãƒ•ã‚©ãƒ«ãƒ€ã‚’ミラーリングãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—: åŒæœŸå®Œäº†å¾Œã¯ã€å·¦å´ãƒ•ã‚©ãƒ«ãƒ€ã«åˆã‚ã›ã¦å³å´ãƒ•ã‚©ãƒ«ãƒ€ã¯ä¸Šæ›¸ãã•ã‚Œã¾ã™ã€‚
+Monitoring active...
+監視を開始ã—ã¾ã™...
More than 50% of the total number of files will be copied or deleted!
ファイルåˆè¨ˆç·æ•°ã® 50% 以上ãŒå‰Šé™¤ã€ã¾ãŸã¯ã‚³ãƒ”ーã•ã‚Œã¾ã™
Move column down
列を下ã«ç§»å‹•
Move column up
列を上ã«ç§»å‹•
-Move files to a user-defined directory.
-ユーザ定義ディレクトリã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’移動
+Move files into a time-stamped subdirectory.
+ファイルをタイムスタンプåã®ã‚µãƒ–フォルダã«ç§»å‹•
Moving %x to Recycle Bin
%x をゴミ箱ã«ç§»å‹•ä¸­
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
フォルダ %x をユーザ定義ディレクトリ %y ã«ç§»å‹•
Multiple...
複数処ç†...
+No change since last synchronization!
+å‰å›žã®åŒæœŸä»¥é™ã€å¤‰æ›´ã¯ã‚ã‚Šã¾ã›ã‚“!
No filter selected
フィルターé¸æŠžãªã—
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
一時åœæ­¢
Paused
一時åœæ­¢ä¸­
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
- \"Shadow.dll\" (\"Shadow.zip\" アーカイブ内) ã‚’ã€FreeFileSync インストールフォルダã«ã‚³ãƒ”ーã™ã‚‹ã“ã¨ã§ã€ã“ã®æ©Ÿèƒ½ã‚’利用ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
-Please fill all empty directory fields.
-アイテムãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“!
Please run a Compare first before synchronizing!
åŒæœŸå‡¦ç†ã‚’実行ã™ã‚‹å‰ã«æ¯”較を行ã£ã¦ãã ã•ã„!
+Processing folder pair:
+フォルダペアを処ç†ä¸­:
Published under the GNU General Public License:
Published under the GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
フォルダペアを除去
Remove local filter settings
ローカルフィルター設定を除去
+Renaming file %x to %y
+ファイル %x ã‚’ %y ã«ãƒªãƒãƒ¼ãƒ ä¸­
Report translation error
翻訳エラーã®è©³ç´°
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
対象ディレクトリã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™!
Target file already existing!
対象ファイルã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+ã“ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã¯é€æ¬¡å®Ÿè¡Œã•ã‚Œã¾ã™:\n- ã“れらã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª(サブディレクトリ)内ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯å¤‰æ›´ã•ã‚Œã¦ã„ã¾ã™ã€‚\n- 対応ã™ã‚‹ãƒ‰ãƒ©ã‚¤ãƒ–レターã¯ã€USB 挿入時ã«æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚
The database file is not yet existing, but will be created during synchronization:
ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã€ã¾ã å­˜åœ¨ã—ã¾ã›ã‚“ãŒã€åŒæœŸå‡¦ç†ã®å®Ÿè¡Œä¸­ã«ä½œæˆã•ã‚Œã¾ã™:
The file does not contain a valid configuration:
@@ -816,12 +842,14 @@ Unable to create logfile!
ログファイルを作æˆå‡ºæ¥ã¾ã›ã‚“!
Unable to initialize Recycle Bin!
ゴミ箱ã®åˆæœŸåŒ–ãŒå‡ºæ¥ã¾ã›ã‚“!
+Unresolved conflicts existing!
+未解決ã®ä¸ä¸€è‡´ãŒã‚ã‚Šã¾ã™!
Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
未解決ã®ä¸ä¸€è‡´ãŒã‚ã‚Šã¾ã™! \n\nã“ã®ä¸ä¸€è‡´ã‚’無視ã—ã¦åŒæœŸã‚’続行ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚
Update ->
æ›´æ–° ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-使用方法: 監視ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠžã—ã¦ã€ã‚³ãƒžãƒ³ãƒ‰ã‚’入力ã—ã¾ã™ã€‚ é¸æŠžã•ã‚ŒãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª(サブディレクトリ)内ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒå¤‰æ›´ã•ã‚Œã‚‹åº¦ã«ã€å…¥åŠ›ã—ãŸã‚³ãƒžãƒ³ãƒ‰ãŒå®Ÿè¡Œã•ã‚Œã¾ã™ã€‚
+Usage:
+使用方法:
Use Recycle Bin
ゴミ箱を使用
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
警告: %x アイテムã®åŒæœŸã«å¤±æ•—ã—ã¾ã—ãŸ:
When the comparison is started with this option set the following decision tree is processed:
ã“ã®ã‚ªãƒ—ションã§æ¯”較を開始ã—ãŸå ´åˆã¯ã€ä»¥ä¸‹ã®ãƒ„リーã«å¾“ã£ã¦å‡¦ç†ãŒè¡Œã‚ã‚Œã¾ã™:
+You can ignore conflicts and continue synchronization.
+ã“ã®ä¸ä¸€è‡´ã‚’無視ã—ã¦åŒæœŸã‚’続行ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚
You can ignore the error to consider not existing directories as empty.
既存ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒç©ºã§ã¯ãªã„ã¨ã„ã†ã‚¨ãƒ©ãƒ¼ã¯ç„¡è¦–ã§ãã¾ã™ã€‚
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/polish.lng b/BUILD/Languages/polish.lng
index fc554eca..90499bee 100644
--- a/BUILD/Languages/polish.lng
+++ b/BUILD/Languages/polish.lng
@@ -46,6 +46,8 @@
&Anuluj
&Check for new version
&Aktualizuj
+&Content
+&Zawartość
&Create batch job
&Twórz plik wsadowy
&Default
@@ -88,6 +90,8 @@
&Tak
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Pamiętaj, że ten problem dotyczy tylko FAT/FAT32!\nW każdym innym przypadku możesz wyłączyć opcję \"Ignoruj 1-godzinną różnicę\".)
+(Requires an Internet connection!)
+(Wymaga połączenia z Internetem!)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Porównaj
1. Enter relative file or directory names separated by ';' or a new line.
1. Wprowdź relatywne scieżki do plików lub katalogów oddzielone ';' lub nową linią.
+1. Select directories to monitor.
+1. Wprowadź katalogi do nadzorowania
2. &Synchronize...
2. &Synchronizuj...
+2. Enter a command line.
+2. Wprowadź komendę.
2. Use wildcard characters '*' and '?'.
2. Użyj wieloznacznika (wildcard) '*' i '?'.
3. Exclude files directly on main grid via context menu.
3. Wyklucz pliki i foldery używając prawego przycisku myszki.
+3. Press 'Start'.
+3. Wciśnij 'Start'.
<Automatic>
<Automatycznie>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Jak wskazuje nazwa, dwa pliki o tej samej nazwie są równe tylko i wyłącznie jeżeli ich zawartość jest jednakowa. Czas modyfikacji nie jest brany pod uwagę. Ta opcja jest raczej użyteczna do sprawdzania spójności plików niż zadań kopii zapasowej.\n\nDrzewko decyzyjne dla tej opcji jest mniejsze:
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.
Twórz plik wsadowy dla automatyzacji procesu. By rozpocząć prace w tym trybie zwyczajnie uruchom plik klikając dwa razy lub dodaj go do zadań zaplanowanych Twojego systemu. Plik wsadowy może być również przekazywany jako parametr do programu w postaci: FreeFileSync.exe <plikwsadowy>.
+At least one directory input field is empty.
+Przynajmniej jedno pole jest puste.
Auto-adjust columns
Autodopasowanie kolumn
Automatic mode
@@ -192,20 +204,18 @@ Build:
Buduj:
Cancel
Anuluj
-Cannot determine sync-direction: Changed filter settings!
-Nie można określik kierunku synchronizacji: Zmieniono ustawienia filtra!
-Cannot determine sync-direction: No change since last synchronization!
-Nie można określik kierunku synchronizacji: Brak zmian od ostatniej synchronizacji!
+Cannot determine sync-direction:
+Nie można określić kierunku synchronizacji:
Category
Kategoria
Change direction
Zmień kierunek
Comma separated list
Lista oddzielona przecinkami
-Commandline
-Wiersz poleceń
-Commandline is empty!
-Wiersz poleceń jest pusty!
+Command line
+Linia komend
+Command line is empty!
+Linia komend jest pusta!
Compare
Porównaj
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
Kopiuj z prawej do lewej
Copy from right to left overwriting
Kopiuj z prawej do lewej nadpisujÄ…c
+Copy locked files
+Kopiuj zablokowane pliki
Copy new or updated files to right folder.
Kopiuj nowe lub aktualniejsze pliki na prawÄ… stronÄ™.
+Copy shared or locked files using Volume Shadow Copy Service.
+Kopiuj współdzielone lub zablokowane pliki używając Volume Shadow Copy Service.
Copy to clipboard\tCTRL+C
Kopiuj do pamięci\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Nie można określić nazwy dysku dla pliku:
Could not initialize directory monitoring:
Nie można uruchomić monitora katalogów:
+Could not load a required DLL:
+Nie można załadować wymaganej biblioteki DLL:
Could not read values for the following XML nodes:
Nie można odczytać wartości dla danych gałęzi XML:
Create a batch job
@@ -298,7 +314,7 @@ Date
Data
Delay
Opóźnienie
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Opóźnienie pomiędzy wykryciem zmian, a wykonaniem komendy w sekundach
Delete files/folders existing on left side only
Usuń pliki/foldery istniejące tylko po lewej stronie
@@ -386,6 +402,8 @@ Error reading file:
BÅ‚Ä…d odczytu pliku:
Error reading from synchronization database:
BÅ‚Ä…d odczytu z bazy danych synchronizacji:
+Error resolving full path name:
+Bład odczytu pełnej nazwy dla ścieżki:
Error resolving symbolic link:
BÅ‚Ä…d odczytu dowiÄ…zania symbolicznego:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtruj pliki
Filter has been selected
Filtr został zaznaczony
+Filter settings have changed!
+Ustawienia filtra uległy zmianie!
Filter view
Filtr podglÄ…du
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Dołącz wszystkie rzędy
Include temporarily
Dołącz tymczasowo
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Dołącz: *.doc;*.zip;*.exe\nWyklucz: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Dołącz: *.doc;*.zip;*.exe\nWyklucz: \\stuff\\temp\\*
Incompatible synchronization database format:
Niepoprawny format bazy danych dla synchronizacji:
Info
@@ -572,8 +592,6 @@ 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. :)
-Inicjalizacja Kosza nie była możliwa!\n\nPrawdopodobnie nie używasz Windowsa.\nJeżeli chcesz dołączyć tą cechę, skontaktuj się z autorem. :)
Leave as unresolved conflict
Zostaw jako nierozwiÄ…zany konflikt
Left
@@ -590,18 +608,22 @@ Log-messages:
Logi:
Logging
Tworzenie logów
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Tworzenie Shadow Copies dla WOW64 nie jest obsługiwane. Zainstaluj 64 bitową wersję FreeFileSync.
Mirror ->>
Lustrzana ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Kopia lustrzana lewego folderu: Prawy folder będzie nadpisany zawartością lewego folderu.
+Monitoring active...
+Monitorowanie aktywne...
More than 50% of the total number of files will be copied or deleted!
Ponad 50% plików zostanie skopiowanych lub usuniętych!
Move column down
Przesuń kolumnę w dół
Move column up
Przesuń kolumnę do góry
-Move files to a user-defined directory.
-Przenieś pliki do katalogu użytkownika.
+Move files into a time-stamped subdirectory.
+PrzenieÅ› pliki do oznaczonego podkatalogu.
Moving %x to Recycle Bin
Przenoszenie %x do kosza.
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Przenoszenie folderu %x do katalogu użytkownika %y
Multiple...
Wiele...
+No change since last synchronization!
+Brak zmian od ostatniej synchronizacji!
No filter selected
Nie wybrano żadnego filtra
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pauza
Paused
Pauza
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Przed synchronizacją należy uruchomić Porównaj!
+Processing folder pair:
+Przetwarzanie folderów:
Published under the GNU General Public License:
Udostępnione na zasadach licencji GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Usuń parę folderów
Remove local filter settings
Usuń ustawienia lokalnego filtra
+Renaming file %x to %y
+Zmiana nazwy pliku %X na %Y
Report translation error
Zgłoś błąd w tłumaczeniu
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Katalog docelowy już istnieje!
Target file already existing!
Plik docelowy już istnieje!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+Komenda ta jest wykonywana za każdym razem gdy:\n- Pliki w tych katalogach (lub podkatalogach) są modyfikowane\n- Odpowiednia litera dysku jest aktywna (Podłączenie USB)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Nie można utworzyć pliku z logami!
Unable to initialize Recycle Bin!
Nie można zainicjalizować Kosz!
+Unresolved conflicts existing!
+IstniejÄ… nierozwiÄ…zane konflikty!
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 ->
Uaktualnij ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Użycie: Wybierz katalogi do monitorowania i wprowadź komendę. Gdy któryś z plików zostanie zmodyfikowany, w obrębie katalogów, zostanie uruchomiona podana komenda.
+Usage:
+Użycie:
Use Recycle Bin
Użyj kosza
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Uwaga: Błąd synchronizacji dla \"%x\" elementów:
When the comparison is started with this option set the following decision tree is processed:
Gdy porównywanie z zaznaczoną opcją jest w toku, podejmowane są następujące dezyje:
+You can ignore conflicts and continue synchronization.
+Możesz je zignorować i kontynułować synchronizację.
You can ignore the error to consider not existing directories as empty.
Możesz zignorować ten błąd i uznać nieistniejący katalog za pusty.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/portuguese.lng b/BUILD/Languages/portuguese.lng
index 83518934..09acd77e 100644
--- a/BUILD/Languages/portuguese.lng
+++ b/BUILD/Languages/portuguese.lng
@@ -46,6 +46,8 @@
&Cancelar
&Check for new version
&Procurar actualizações
+&Content
+
&Create batch job
&Criar um ficheiro batch
&Default
@@ -88,6 +90,8 @@
&Sim
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Apenas as drives FAT/FAT32 são afectadas por este problema! \nPara todas as outras situações pode desactivar a opção \"ignorar diferença de 1 hora\".)
+(Requires an Internet connection!)
+
,
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Comparar
1. Enter relative file or directory names separated by ';' or a new line.
1. Inserir caminho(s) do(s) ficheiro(s) ou pasta(s) separados por ';' ou numa nova linha.
+1. Select directories to monitor.
+
2. &Synchronize...
2. &Sincronizar...
+2. Enter a command line.
+
2. Use wildcard characters '*' and '?'.
2. Usar '*' e '?' como caracteres de procura.
3. Exclude files directly on main grid via context menu.
3. Excluir ficheiros directamente da grelha através do menu de contexto.
+3. Press 'Start'.
+
<Automatic>
<Automático>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Como o nome sugere, dois ficheiros com o mesmo nome são assinalados iguais se e só se o seu conteúdo for idêntico. Esta opção é útil para controles de consistência mais do que para efeitos de backup. Portanto, a data dos ficheiros não é tomada em conta.\n\nCom esta opção, a arvoré de decisão é menor:
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.
Criar um batch para sincronização automática. Para iniciar o modo batch, passar o nome do ficheiro para o executável do FreeFileSync: FreeFileSync.exe <ficheiro batch>. Também pode ser calendarizado no programador de tarefas.
+At least one directory input field is empty.
+
Auto-adjust columns
Auto ajustar colunas
Automatic mode
@@ -192,20 +204,18 @@ Build:
Criado:
Cancel
Cancelar
-Cannot determine sync-direction: Changed filter settings!
-Não é possível determinar a direcção de sincronização: Alterações na configuração do filtro!
-Cannot determine sync-direction: No change since last synchronization!
-Não é possível determinar a direcção de sincronização: Não há alterações desde a última sincronização!
+Cannot determine sync-direction:
+
Category
Categoria
Change direction
Mudar direcção
Comma separated list
Lista de itens separados por virgula
-Commandline
+Command line
Linha de comandos
-Commandline is empty!
-Linha de comandos vazia!
+Command line is empty!
+
Compare
Comparar
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
Copiar da direita para a esquerda
Copy from right to left overwriting
Copiar da direita para a esquerda com sobreposição
+Copy locked files
+
Copy new or updated files to right folder.
Copiar ficheiros novos ou actualizados para a direita
+Copy shared or locked files using Volume Shadow Copy Service.
+
Copy to clipboard\tCTRL+C
Copiar para a Ãrea de transferência\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Não é possível determinar o nome do volume para o ficheiro:
Could not initialize directory monitoring:
Não é possível iniciar monitorização do directório:
+Could not load a required DLL:
+
Could not read values for the following XML nodes:
Não foi possível ler os valores dos seguintes nós XML:
Create a batch job
@@ -298,7 +314,7 @@ Date
Data
Delay
Atraso
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Atraso entre a detecção de diferenças e a execuçao dos comandos em segundos
Delete files/folders existing on left side only
Eliminar itens existentes apenas no lado esquerdo
@@ -386,6 +402,8 @@ Error reading file:
Erro de leitura de ficheiro:
Error reading from synchronization database:
Erro ao ler a base de dados de sincronização:
+Error resolving full path name:
+
Error resolving symbolic link:
Erro na resolução do link simbólico:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtrar ficheiros
Filter has been selected
+Filter settings have changed!
+
Filter view
Filtrar vista
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Include temporarily
Incluir temporariamente
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Incluir: *.doc;*.zip;*.exe\nExcluir: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Incluir: *.doc;*.zip;*.exe\nExcluir: \\stuff\\temp\\*
Incompatible synchronization database format:
Formato de base de dados de sincronização incompatível:
Info
@@ -572,8 +592,6 @@ 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. :)
-Não é possível aceder à Reciclagem!\n\nÉ possível que não esteja a utilizar Windows.\nSe desejar esta opção incluída, é favor contactar o autor. :)
Leave as unresolved conflict
Deixar como conflito
Left
@@ -590,18 +608,22 @@ Log-messages:
Log de mensagens:
Logging
A escrever em log
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+
Mirror ->>
Espelhar ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Espelhar pasta da esquerda: A pasta da direita vai ser sobreposta e uma cópia exacta da pasta esquerda após sincronização.
+Monitoring active...
+
More than 50% of the total number of files will be copied or deleted!
Mais de 50% dos ficheiros vai ser copiado ou apagado!
Move column down
Mover coluna para baixo
Move column up
Mover coluna para cima
-Move files to a user-defined directory.
-Mover ficheiros para um directório definido pelo utilizador.
+Move files into a time-stamped subdirectory.
+
Moving %x to Recycle Bin
A mover %x para a Reciclagem
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
A mover pasta %x para o directório %y
Multiple...
Multiplo...
+No change since last synchronization!
+
No filter selected
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pausa
Paused
Em pausa
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
+Processing folder pair:
+
Published under the GNU General Public License:
Publicado sobre GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Remover o par de pastas
Remove local filter settings
+Renaming file %x to %y
+
Report translation error
Informar um erro de tradução
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Directório de destino já existe!
Target file already existing!
Ficheiro de destino já existe!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+
The database file is not yet existing, but will be created during synchronization:
The file does not contain a valid configuration:
@@ -816,12 +842,14 @@ Unable to create logfile!
Não é possível criar ficheiro log!
Unable to initialize Recycle Bin!
Não é possível iniciar a Reciclagem!
+Unresolved conflicts existing!
+
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 ->
Actualizar ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Uso: Selecionar directórios a monitorizar e escrever uma linha de comando. Cada vez que um ficheiro for alterado nestes directórios (ou subdirectórios) a linha de comando será executada.
+Usage:
+
Use Recycle Bin
Utilizar Reciclagem
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Atenção: A sincronização falhou para %x item(s):
When the comparison is started with this option set the following decision tree is processed:
Usar a seguinte árvore de decisão quando inicia com estas opções de comparação:
+You can ignore conflicts and continue synchronization.
+
You can ignore the error to consider not existing directories as empty.
Pode ignorar o erro para considerar directórios não existentes como vazios.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/portuguese_br.lng b/BUILD/Languages/portuguese_br.lng
index 081e1b96..7783f823 100644
--- a/BUILD/Languages/portuguese_br.lng
+++ b/BUILD/Languages/portuguese_br.lng
@@ -46,6 +46,8 @@
&Cancelar
&Check for new version
&Procurar novas versões
+&Content
+Conteúdo
&Create batch job
&Criar um arquivo batch
&Default
@@ -88,6 +90,8 @@
&Sim
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Note que apenas discos FAT/FAT32 são afetados por este problema!\nEm todos os outros casos pode-se desabilitar esta opção \"ignorar diferença de 1 hora\".)
+(Requires an Internet connection!)
+(Requer conexão com a Internet!)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Comparar
1. Enter relative file or directory names separated by ';' or a new line.
1. Entre os nomes dos arquivos ou diretórios relativos separados por ';' ou uma nova linha.
+1. Select directories to monitor.
+1. Selecione os diretórios para monitorar.
2. &Synchronize...
2. &Sincronizar...
+2. Enter a command line.
+2. Entre uma linha de comando.
2. Use wildcard characters '*' and '?'.
2. Usar '*' e '?' como caracteres coringa.
3. Exclude files directly on main grid via context menu.
3. Excluir arquivos diretamente do grid principal através do menu de contexto.
+3. Press 'Start'.
+3. Pressione 'Iniciar'.
<Automatic>
<Automático>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Como o nome sugere, dois arquivos com o mesmo nome são assinalados como iguais se e somente se eles tiverem o mesmo conteúdo. Esta opção é útil para controles de consistência mais do que para efeitos de backup. Portanto, a data dos arquivos não é levada em consideração.\n\nCom esta opção, a árvore de decisão é menor:
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.
Monta um arquivo batch para sincronização automatizada. Para iniciar o modo batch, passar o nome do arquivo para o executável do FreeFileSync: FreeFileSync.exe <arquivo batch>. Também pode ser programado no Agendador de Tarefas do sistema operacional.
+At least one directory input field is empty.
+Pelo menos um dos campos de entrada de diretório está vazio.
Auto-adjust columns
Autoajustar colunas
Automatic mode
@@ -192,20 +204,18 @@ Build:
Criado:
Cancel
Cancelar
-Cannot determine sync-direction: Changed filter settings!
-Não foi possível determinar a direção de sicronização: Configurações do filtro alteradas!
-Cannot determine sync-direction: No change since last synchronization!
-Não foi possível determinar a direção de sicronização: Nenhuma alteração desde a última sincronização!
+Cannot determine sync-direction:
+Não foi possível determinar a direção de sincronização:
Category
Categoria
Change direction
Inverter sentido
Comma separated list
Lista de itens separada por vírgula
-Commandline
+Command line
Linha de comando
-Commandline is empty!
-A linha de comando está vazia!
+Command line is empty!
+Linha de comando está vazia!
Compare
Comparar
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
Copiar da direita para a esquerda
Copy from right to left overwriting
Copiar da direita para a esquerda com sobreposição
+Copy locked files
+Copiar arquivos bloqueados (em uso)
Copy new or updated files to right folder.
Copiar arquivos novos ou atualizados para a pasta da direita
+Copy shared or locked files using Volume Shadow Copy Service.
+Copiar arquivos compartilhados ou bloqueados usando o Serviço de Cópias de Sombra de Volume.
Copy to clipboard\tCTRL+C
Copiar para a Ãrea de transferência\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Não foi possível determinar o nome do volume para o arquivo:
Could not initialize directory monitoring:
Não foi possível inicializar o monitoramento de diretórios:
+Could not load a required DLL:
+Não foi possível carregar uma DLL requerida:
Could not read values for the following XML nodes:
Não foi possível ler os valores para os seguintes nós XML:
Create a batch job
@@ -298,7 +314,7 @@ Date
Data
Delay
Atraso
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Atraso entre detecção de mudanças e execução de linha de comando em segundos
Delete files/folders existing on left side only
Apagar arquivos/pastas existentes apenas no lado esquerdo
@@ -386,6 +402,8 @@ Error reading file:
Erro ao ler arquivo:
Error reading from synchronization database:
Erro ao ler do banco de dados de sincronização:
+Error resolving full path name:
+Erro na resolução do caminho completo:
Error resolving symbolic link:
Erro na resolução de link simbólico:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtrar arquivos
Filter has been selected
Filtro foi selecionado
+Filter settings have changed!
+As configurações do filtro foram alteradas!
Filter view
Filtrar vista
Filtering is deactivated
@@ -541,11 +561,11 @@ 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.
+Identificar e propagar mudanças em ambos os lados utilizando um 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
-Ignorar diferença de tempo de 1 hora
+Ignorar diferenças de 1 hora nos arquivos
Ignore errors
Ignorar erros
Ignore subsequent errors
@@ -560,8 +580,8 @@ Include all rows
Incluir todas as linhas
Include temporarily
Incluir temporariamente
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Incluir: *.doc;*.zip;*.exe\nExcluir: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Incluir: *.doc;*.zip;*.exe\nExcluir: \\stuff\\temp\\*
Incompatible synchronization database format:
Formato de banco de dados de sincronização incompatível:
Info
@@ -572,8 +592,6 @@ 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. :)
-Não foi possível acessar a Lixeira!\n\nÉ possível que não esteja utilizando Windows.\nSe desejar esta opção incluída, favor contatar o autor. :)
Leave as unresolved conflict
Deixar como conflito não resolvido
Left
@@ -590,18 +608,22 @@ Log-messages:
Log de mensagens:
Logging
Gravando log
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Cópias de sombra no WOW64 não são suportadas. Por favor use a versão 64-bits do FreeFileSync.
Mirror ->>
Espelhar ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Espelhar pasta da esquerda: A pasta da direita vai ser sobreposta e será feita uma cópia exata da pasta da esquerda após a sincronização.
+Monitoring active...
+Monitoramento ativo...
More than 50% of the total number of files will be copied or deleted!
Mais de 50% do número total de arquivos será copiado ou apagado!
Move column down
Mover coluna para baixo
Move column up
Mover coluna para cima
-Move files to a user-defined directory.
-Mover arquivos para um diretório especificado.
+Move files into a time-stamped subdirectory.
+Mover arquivos para um subdiretório com carimbo de tempo.
Moving %x to Recycle Bin
Movendo %x para a Lixeira
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Movendo pasta %x para o diretório especificado
Multiple...
Múltiplos...
+No change since last synchronization!
+Nenhuma mudança desde a última sincronização!
No filter selected
Nenhum filtro selecionado
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pausa
Paused
Pausado
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Por favor execute primeiro a Comparação antes de sincronizar!
+Processing folder pair:
+Processando par de pastas:
Published under the GNU General Public License:
Publicado sobre a GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Remover par de pastas
Remove local filter settings
Remover configurações locais de filtro
+Renaming file %x to %y
+Renomeando arquivo %x para %y
Report translation error
Reportar erro de tradução
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Diretório de destino já existe!
Target file already existing!
Arquivo de destino já existe!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+A linha de comando é executada cada vez que:\n- Arquivos dentro desses diretórios (ou subdiretórios) são modificados\n- A letra correspondente do disco se torna disponível (inserção de USB)
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:
@@ -816,12 +842,14 @@ 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!
+Unresolved conflicts existing!
+Conflitos não resolvidos existentes!
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 ->
Atualizar ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Uso: Selecionar diretórios para monitoração e entrar com linha de comando. Cada vez que os arquivos são modificados nesses diretórios (ou subdiretórios) a linha de comando é executada.
+Usage:
+Uso:
Use Recycle Bin
Utilizar Lixeira
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Atenção: A sincronização falhou para %x item(s):
When the comparison is started with this option set the following decision tree is processed:
Quando a comparação é iniciada com esta opção, a seguinte árvore de decisão é processada:
+You can ignore conflicts and continue synchronization.
+Você pode ignorar os conflitos e continuar a sincronização.
You can ignore the error to consider not existing directories as empty.
Você pode ignorar o erro para considerar diretórios não existente como vazios.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/romanian.lng b/BUILD/Languages/romanian.lng
index 8bdf1247..52f715a6 100644
--- a/BUILD/Languages/romanian.lng
+++ b/BUILD/Languages/romanian.lng
@@ -46,6 +46,8 @@
&Anulează
&Check for new version
&Caută Versiune Nouă
+&Content
+&Conținut
&Create batch job
&Creează o Sarcină Lot
&Default
@@ -88,12 +90,14 @@
&Da
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Doar dispozitivele FAT/FAT32 sînt afectate de această problemă!\nÎn celelalte cazuri, puteți dezactiva setarea \"ignoră diferența de 1-oră\".)
+(Requires an Internet connection!)
+(Necesită o conexiune la internet!)
,
.
- Other side's counterpart to %dir
-- Corespondentul din partea opusă al lui %dir
+- corespondentul din partea opusă al lui %dir
- Other side's counterpart to %name
-- Corespondentul din partea opusă al lui %name
+- corespondentul din partea opusă al lui %name
- conflict
- conflict
- conflict (same date, different size)
@@ -132,12 +136,18 @@
1. &Compară
1. Enter relative file or directory names separated by ';' or a new line.
1. Introduceți numele relative ale fișierelor sau dosarelor, separate de semnul ';' sau de un rînd nou.
+1. Select directories to monitor.
+1. Selectați dosarele de monitorizat.
2. &Synchronize...
2. &Sincronizează...
+2. Enter a command line.
+2. Introduceți calea.
2. Use wildcard characters '*' and '?'.
2. Folosiți metacaracterele '*' și '?' (asterisc și semn de întrebare).
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.
+3. Press 'Start'.
+3. Apăsați 'Start'.
<Automatic>
<Sincronizare Inteligentă>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
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 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].
+At least one directory input field is empty.
+Cel puțin un cîmp de introducere a dosarului este gol.
Auto-adjust columns
Autoajustează Coloanele
Automatic mode
@@ -192,19 +204,17 @@ Build:
Compilat la:
Cancel
Anulează
-Cannot determine sync-direction: Changed filter settings!
-Nu se poate determina sensul de sincronizare: Setările filtrului s-au schimbat!
-Cannot determine sync-direction: No change since last synchronization!
-Nu se poate determina sensul de sincronizare: Nici o modificare de la ultima sincronizare!
+Cannot determine sync-direction:
+Nu se poate determina sensul de sincronizare:
Category
Categorie
Change direction
Schimbă în Sensul Iconiței
Comma separated list
Listă de elemente separate prin virgulă
-Commandline
+Command line
Linie de comandă
-Commandline is empty!
+Command line is empty!
Linia de comandă este goală!
Compare
Compară
@@ -260,8 +270,12 @@ Copy from right to left
Copiază de la Dreapta la Stînga
Copy from right to left overwriting
Copiază de la Dreapta la Stînga cu Suprascriere
+Copy locked files
+Copiază fișierele zăvorîte [locked]
Copy new or updated files to right folder.
Copiere în dosarul din dreapta a fișierelor actualizate sau noi.
+Copy shared or locked files using Volume Shadow Copy Service.
+Copiază fișierele partajate sau zăvorîte folosind serviciul de salvgardare din Windows.
Copy to clipboard\tCTRL+C
Copiază în Cliplanșetă\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Nu pot determina numele volumului pentru fișierul:
Could not initialize directory monitoring:
Nu pot inițializa monitorizarea dosarelor:
+Could not load a required DLL:
+Nu pot încărca un fișier DLL necesar:
Could not read values for the following XML nodes:
Nu pot citi valorile pentru următoarele noduri XML:
Create a batch job
@@ -298,7 +314,7 @@ Date
Dată
Delay
Întîrziere
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Întîrziere în secunde între detectarea modificărilor și executarea liniei de comandă
Delete files/folders existing on left side only
Șterge Itemul din Stînga
@@ -386,6 +402,8 @@ Error reading file:
Eroare la citirea fișierului:
Error reading from synchronization database:
Eroare la citirea din baza de date a sincronizării:
+Error resolving full path name:
+Eroare la rezolvarea numelui căii complete:
Error resolving symbolic link:
Eroare la rezolvarea legăturii simbolice:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtrează Fișierele
Filter has been selected
Filtrul a fost selectat
+Filter settings have changed!
+Setările filtrului au fost schimbate!
Filter view
Filtru de Vedere
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Include Toate Rîndurile
Include temporarily
Include Temporar
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Incluse: *.doc;*.zip;*.exe\nExcluse: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Incluse: *.doc;*.zip;*.exe\nExcluse: \\stuff\\temp\\*
Incompatible synchronization database format:
Format incompatibil al bazei de date a sincronizării:
Info
@@ -572,8 +592,6 @@ 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 Conflict Nerezolvat
Left
@@ -590,18 +608,22 @@ Log-messages:
Mesaje de jurnalizare:
Logging
Jurnalizez
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Realizarea de copii de rezervă prin sistemul WOW64 nu este suportată. Folosiți versiunea pe 64-biți a FreeFileSync.
Mirror ->>
Clonare =>>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Salvgardare [backup] prin clonare a dosarului stîng: dosarul din dreapta va fi suprascris și va fi identic după sincronizare cu dosarul din stînga.
+Monitoring active...
+Monitorizare activă...
More than 50% of the total number of files will be copied or deleted!
Peste 50% din numărul total de fișiere vor fi copiate sau distruse!
Move column down
Mută coloana în jos
Move column up
Mută coloana în sus
-Move files to a user-defined directory.
-Fișierele sînt mutate într-un dosar ales de utilizator.
+Move files into a time-stamped subdirectory.
+Mută fișierele într-un subdosar cu marcaj de timp.
Moving %x to Recycle Bin
Mut %x în Reciclator
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Mut dosarul %x în dosarul %y ales de utilizator
Multiple...
Multiplu...
+No change since last synchronization!
+Nu sînt schimbări de la ultima sincronizare!
No filter selected
Nu a fost selectat nici un filtru
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Pauză
Paused
Pauzat
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
Rulați compararea înainte de a sincroniza!
+Processing folder pair:
+Procesez perechea de dosare:
Published under the GNU General Public License:
Publicat sub licența GNU GPL:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Înlătură Perechea de Dosare
Remove local filter settings
Înlătură Configurația Filtrului Local
+Renaming file %x to %y
+Redenumesc fișierul %x în %y
Report translation error
Raportarea erorilor de traducere
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Dosarul țintă există deja!
Target file already existing!
Fișierul țintă există deja!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+Linia de comandă este executată de fiecare dată:\n- Fișierele din aceste dosare (sau subdosare) sînt modificate\n- Litera corespunzătoare a dispozitivului devine disponibilă (introducere-USB)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Fișierul jurnal nu poate fi creat!
Unable to initialize Recycle Bin!
Reciclatorul nu poate fi inițializat!
+Unresolved conflicts existing!
+Există conflicte nerezolvate!
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 ->
Actualizare =>
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Utilizare: Selectați dosarele de sincronizat și introduceți o linie de comandă. De fiecare dată cînd un fișier este modificat în aceste dosare (sau subdosare), este executată linia de comandă.
+Usage:
+Utilizare:
Use Recycle Bin
Mută în reciclator
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
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 conflicts and continue synchronization.
+Puteți ignora conflictele pentru a continua cu sincronizarea.
You can ignore the error to consider not existing directories as empty.
Puteți ignora eroarea care consideră că un dosar inexistent este gol.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/russian.lng b/BUILD/Languages/russian.lng
index f2dd49ef..fc461c2e 100644
--- a/BUILD/Languages/russian.lng
+++ b/BUILD/Languages/russian.lng
@@ -46,6 +46,8 @@
&Отмена
&Check for new version
&Проверить наличие новой верÑии
+&Content
+&Справка
&Create batch job
&Создать задание...
&Default
@@ -88,6 +90,8 @@
&Да
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Помните, что только диÑки FAT/FAT32 Ñтрадают от Ñтой проблемы!\nВо вÑех оÑтальных ÑлучаÑÑ… вы можете отключить параметр \"игнорировать 1-чаÑовую разницу\".)
+(Requires an Internet connection!)
+(ТребуетÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ к Интернету!)
,
.
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@
1. &Сравнить
1. Enter relative file or directory names separated by ';' or a new line.
1. Введите имена файлов или папок, разделÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼ ';' или Ñ Ð½Ð¾Ð²Ð¾Ð¹ Ñтроки.
+1. Select directories to monitor.
+1. Выберите папки Ð´Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ð°;
2. &Synchronize...
2. &Синхронизировать
+2. Enter a command line.
+2. Введите командную Ñтроку;
2. Use wildcard characters '*' and '?'.
2. ИÑпользуйте Ñимволы '*' и '?' Ð´Ð»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ‹ неизвеÑтных.
3. Exclude files directly on main grid via context menu.
3. ИÑключите файлы прÑмо в главном окне через контекÑтное меню.
+3. Press 'Start'.
+3. Ðажмите 'Старт'.
<Automatic>
<ÐвтоматичеÑкий>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
Как напиÑано в названии, два файла Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼ именем отмечаютÑÑ Ñ€Ð°Ð²Ð½Ñ‹Ð¼Ð¸, только еÑли они имеют то же Ñамое Ñодержание. Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð° Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ ÑоглаÑованноÑти, а не операции резервного копированиÑ. ПоÑтому даты файлов не учитываютÑÑ Ð²Ð¾Ð¾Ð±Ñ‰Ðµ.\n\nС Ñтой опцией алгоритм короче:
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.
Создайте файл Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ð¹ Ñинхронизации. Чтобы запуÑтить программу в Ñтом режиме проÑто передайте название файла на выполнение FreeFileSync: FreeFileSync.exe <batchfile>. Это также может быть запиÑано в планировщике задач Вашей операционной ÑиÑтемы.
+At least one directory input field is empty.
+По крайней мере, одно поле путей папок не заполнено.
Auto-adjust columns
Ðвтовыравнивание ширины колонок
Automatic mode
@@ -192,19 +204,17 @@ Build:
Сборка:
Cancel
Отмена
-Cannot determine sync-direction: Changed filter settings!
-Ðевозможно определить направление Ñинхронизации: Изменены наÑтройки фильтра!
-Cannot determine sync-direction: No change since last synchronization!
-Ðевозможно определить направление Ñинхронизации: Ðикаких изменений поÑле поÑледней Ñинхронизации!
+Cannot determine sync-direction:
+Ðевозможно определить направление Ñинхронизации:
Category
КатегориÑ
Change direction
ПоменÑÑ‚ÑŒ направление
Comma separated list
СпиÑок, разделÑемый запÑтыми
-Commandline
+Command line
ÐšÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока
-Commandline is empty!
+Command line is empty!
ÐšÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока пуÑта!
Compare
Сравнить
@@ -260,8 +270,12 @@ Copy from right to left
Скопировать Ñправа налево
Copy from right to left overwriting
Скопировать Ñправа налево Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿Ð¸Ñью
+Copy locked files
+Копировать заблокированные файлы
Copy new or updated files to right folder.
Копировать новые или обновлÑÑ‚ÑŒ файлы на правой Ñтороне.
+Copy shared or locked files using Volume Shadow Copy Service.
+Копировать общие или заблокированные файлы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Службы Теневого ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¢Ð¾Ð¼Ð°.
Copy to clipboard\tCTRL+C
Копировать в буфер обмена\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Ðе удалоÑÑŒ определить название тома Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð°:
Could not initialize directory monitoring:
Ðе удалоÑÑŒ инициализировать папку Ð´Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ð°:
+Could not load a required DLL:
+Ðе удалоÑÑŒ загрузить необходимые DLL:
Could not read values for the following XML nodes:
Ðе удалоÑÑŒ прочитать Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñледующих XML запиÑей:
Create a batch job
@@ -298,7 +314,7 @@ Date
Дата
Delay
Задержка
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Задержка между обнаружением изменений и выполнением командной Ñтроки в Ñекундах
Delete files/folders existing on left side only
УдалÑÑ‚ÑŒ файлы/папки, ÑущеÑтвующие только на левой Ñтороне
@@ -386,6 +402,8 @@ Error reading file:
Ошибка при чтении файла:
Error reading from synchronization database:
Ошибка при чтении из базы данных Ñинхронизации:
+Error resolving full path name:
+Ошибка при воÑÑтановлении абÑолютного пути из отноÑительного:
Error resolving symbolic link:
Ошибка при решении ÑимволичеÑкой ÑÑылки:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Фильтр файлов
Filter has been selected
Фильтр уÑтановлен
+Filter settings have changed!
+ÐаÑтройки фильтра были изменены!
Filter view
Вид фильтра
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ñе Ñтроки
Include temporarily
Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ðµ
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-ВключаÑ: *.doc;*.zip;*.exe\nИÑключаÑ: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+ВключаÑ: *.doc;*.zip;*.exe\nИÑключаÑ: \\stuff\\temp\\*
Incompatible synchronization database format:
ÐеÑовмеÑтимый формат базы данных Ñинхронизации:
Info
@@ -572,8 +592,6 @@ 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. :)
-Ðевозможно инициализировать "Корзину"!\n\nВероÑтно, что Ð’Ñ‹ не иÑпользуете Windows.\nЕÑли Ð’Ñ‹ хотите, чтобы Ñта Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð±Ñ‹Ð»Ð°, пожалуйÑта ÑвÑжитеÑÑŒ Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼. :)
Leave as unresolved conflict
ОÑтавить как нерешенный конфликт
Left
@@ -590,18 +608,22 @@ Log-messages:
Лог-ÑообщениÑ:
Logging
Лог-файлы
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Создание теневых копий на WOW64 не поддерживаетÑÑ. ПожалуйÑта, иÑпользуйте FreeFileSync 64-разрÑдной верÑии.
Mirror ->>
Зеркало ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Ð ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð»ÐµÐ²Ð¾Ð¹ папки: Ð¿Ñ€Ð°Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° будет перезапиÑана и поÑле Ñинхронизации будет точно ÑоответÑтвовать левой папке.
+Monitoring active...
+Мониторинг включен...
More than 50% of the total number of files will be copied or deleted!
Более 50% общего количеÑтва файлов будет Ñкопировано или удалено!
Move column down
ПеремеÑтить вниз
Move column up
ПеремеÑтить вверх
-Move files to a user-defined directory.
-ПеремеÑтить файлы в заданную пользователем папку
+Move files into a time-stamped subdirectory.
+ПеремеÑтить файлы во временно-отмеченную подпапку.
Moving %x to Recycle Bin
Отправка %x в "Корзину"
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Перемещение папки %x в заданную пользователем папку %y
Multiple...
Различные варианты Ñинхронизации
+No change since last synchronization!
+Ðикаких изменений Ñ Ð¿Ð¾Ñледней Ñинхронизации!
No filter selected
Ðи один фильтр не выбран
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Пауза
Paused
Пауза
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-ПожалуйÑта, Ñкопируйте ÑоответÑтвующий \"Shadow.dll\" (находÑщийÑÑ Ð² архиве \"Shadow.zip\") в папку уÑтановки FreeFileSync Ð´Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñтой функции.
-Please fill all empty directory fields.
-ПожалуйÑта, заполните вÑе пуÑтые Ð¿Ð¾Ð»Ñ Ð¿Ð°Ð¿Ð¾Ðº
Please run a Compare first before synchronizing!
ПожалуйÑта, запуÑтите Ñравнение перед Ñинхронизацией!
+Processing folder pair:
+Обработка пары папок:
Published under the GNU General Public License:
ИздаетÑÑ Ð¿Ð¾Ð´ GNU General Public License:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Удалить пару папок
Remove local filter settings
Удалить наÑтройки локального фильтра
+Renaming file %x to %y
+Переименование файла %x в %y
Report translation error
Сообщить об ошибке перевода
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° уже ÑущеÑтвует!
Target file already existing!
Конечный файл уже ÑущеÑтвует!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+ÐšÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока выполнÑетÑÑ ÐºÐ¾Ð³Ð´Ð°:\n- Файлы в Ñтих папках (или подпапках) были изменены\n- СоответÑÑ‚Ð²ÑƒÑŽÑ‰Ð°Ñ Ð±ÑƒÐºÐ²Ð° диÑка ÑтановитÑÑ Ð´Ð¾Ñтупной (добавление USB уÑтройÑтва)
The database file is not yet existing, but will be created during synchronization:
Файл базы данных еще не ÑущеÑтвует, но будет Ñоздан во Ð²Ñ€ÐµÐ¼Ñ Ñинхронизации:
The file does not contain a valid configuration:
@@ -816,12 +842,14 @@ Unable to create logfile!
Ðевозможно Ñоздать лог!
Unable to initialize Recycle Bin!
Ðевозможно инициализировать "Корзину"!
+Unresolved conflicts existing!
+СущеÑтвуют нерешенные конфликты
Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
-СущеÑтвуют нерешенные конфликты \n\nÐ’Ñ‹ можете проигнорировать их и продолжить Ñинхронизацию.
+СущеÑтвуют нерешенные конфликты! \n\nÐ’Ñ‹ можете проигнорировать их и продолжить Ñинхронизацию.
Update ->
Обновить ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Выберите папки Ð´Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ð° и введите командную Ñтроку. Каждый раз при обновлении Ñтих папок (или их подпапок) ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока будет выполнÑÑ‚ÑŒÑÑ.
+Usage:
+ИнÑтрукциÑ:
Use Recycle Bin
ИÑпользовать "Корзину"
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Внимание: Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾Ð²Ð°Ð»ÐµÐ½Ð° Ð´Ð»Ñ %x
When the comparison is started with this option set the following decision tree is processed:
Когда Ñравнение запущено Ñ Ñтими критериÑми, алгоритм Ñледующий:
+You can ignore conflicts and continue synchronization.
+Ð’Ñ‹ можете проигнорировать их и продолжить Ñинхронизацию.
You can ignore the error to consider not existing directories as empty.
Ð’Ñ‹ можете проигнорировать ошибку, принÑв неÑущеÑтвующие папки за пуÑтые.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/slovenian.lng b/BUILD/Languages/slovenian.lng
index 1dab4ba0..59daefa7 100644
--- a/BUILD/Languages/slovenian.lng
+++ b/BUILD/Languages/slovenian.lng
@@ -46,6 +46,8 @@
&PrekliÄi
&Check for new version
&Preveri za novo razliÄico
+&Content
+&Vsebina
&Create batch job
&Ustvari batch opravilo
&Default
@@ -75,7 +77,7 @@ Na&loži konfiguracijo
&OK
&V redu
&Pause
-&Pavza
+&Premor
&Quit
&Zapri
&Restore
@@ -88,6 +90,8 @@ Na&loži konfiguracijo
&Da
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Vedite, da samo na pogonih s FAT/FAT32 lahko pride do teh težav!\nV vseh drugih primerih lahko onemogoÄite nastavitev \"prezri 1-urno razliko\".)
+(Requires an Internet connection!)
+(Zahteva povezavo z Internetom!)
,
,
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@ Duplikat z druge strani od %name
1. &Primerjaj
1. Enter relative file or directory names separated by ';' or a new line.
1. Vnesite relativna imena datotek ali imenikov loÄenih z ';' ali novo vrstico.
+1. Select directories to monitor.
+1. Izberite imenike za nadziranje
2. &Synchronize...
2. &Sinhroniziraj...
+2. Enter a command line.
+2. Vnesite ukazno-vrstico.
2. Use wildcard characters '*' and '?'.
2. Uporabite lahko tudi znake '*' in '?'.
3. Exclude files directly on main grid via context menu.
3. IzkljuÄite datoteke neposredno na glavni mreži s kontekstnim menujem.
+3. Press 'Start'.
+3. Pritisnite 'ZaÄni'.
<Automatic>
<Samodejno>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
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 batch datoteke k FreeFileSync izvrÅ¡ilni datoteki: FreeFileSync.exe <imedatotekebatch>. To se lahko nastavi tudi v urniku opravil vaÅ¡ega operacijskega sistema.
+At least one directory input field is empty.
+Vsaj eno vnosno polje za vpis imenika je prazno.
Auto-adjust columns
Samo-prilagodi stolpce
Automatic mode
@@ -192,19 +204,17 @@ Build:
Izgradnja:
Cancel
PrekliÄi
-Cannot determine sync-direction: Changed filter settings!
-Ne morem doloÄiti smeri sinhronizacije: Spremenite nastavitve filtra!
-Cannot determine sync-direction: No change since last synchronization!
-Ne morem doloÄiti smeri sinhronizacije: Ni bilo sprememb od zadnje sinhronizacije!
+Cannot determine sync-direction:
+Ne morem doloÄiti sinhronizacijske smeri.
Category
Kategorija
Change direction
Spremeni smer
Comma separated list
Seznam loÄen z vejico
-Commandline
+Command line
Ukazna vrstica
-Commandline is empty!
+Command line is empty!
Ukazna vrstica je prazna!
Compare
Primerjaj
@@ -260,8 +270,12 @@ Copy from right to left
Kopiraj iz desne na levo
Copy from right to left overwriting
Kopiraj iz desne na levo s prepisovanjem
+Copy locked files
+Kopiraj zaklenjene datoteke
Copy new or updated files to right folder.
Kopiraj nove ali posodobljene datoteke v desno mapo.
+Copy shared or locked files using Volume Shadow Copy Service.
+Kopiraj deljene ali zaklenjene datoteke z uporabo servisa Volume Shadow Copy.
Copy to clipboard\tCTRL+C
Kopiraj v odložiÅ¡Äe\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Ne morem doloÄiti imena volumna za datoteko:
Could not initialize directory monitoring:
Ne morem zaÄeti nadzorovanja imenikov:
+Could not load a required DLL:
+Ne morem naložiti zahtevano DLL:
Could not read values for the following XML nodes:
Ne morem brati vrednosti za naslednja XML vozliÅ¡Äa:
Create a batch job
@@ -298,7 +314,7 @@ Date
Datum
Delay
Zakasnitev
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Zakasnitev med zaznavo sprememb in izvršitvijo ukazov v sekundah
Delete files/folders existing on left side only
Izbriši datoteke/mape, ki obstajajo samo na levi strani
@@ -386,6 +402,8 @@ Error reading file:
Napaka pri branju datoteke:
Error reading from synchronization database:
Napaka pri branju iz sinhronizacijske podatkovne baze:
+Error resolving full path name:
+Napaka pri razreševanju polnega imena poti:
Error resolving symbolic link:
Napaka pri razreÅ¡evanju simboliÄne povezave:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Filtriraj datoteke
Filter has been selected
Filter je bil izbran
+Filter settings have changed!
+Nastavitve filtra so bile spremenjene!
Filter view
Filtriran pogled
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
VkljuÄi se vrstice
Include temporarily
Trenutno vkljuÄi
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-VkljuÄi: *.doc;*.zip;*.exe\nIzkljuÄi: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+VkljuÄi: *.doc;*.zip;*.exe\nIzkljuÄi: \\stuff\\temp\\*
Incompatible synchronization database format:
Nekompatibilen format sinhronizacijske podatkovne baze:
Info
@@ -572,8 +592,6 @@ 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. :)
-Ni bilo mogoÄe inicializirati KoÅ¡a!\n\nZgleda, da ne uporabljate Windowsov.\nÄŒe želite imeti vkljuÄeno to lastnost, prosimo kontaktirajte avtorja. :)
Leave as unresolved conflict
Pusti kot nerešeni spor
Left
@@ -590,18 +608,22 @@ Log-messages:
SporoÄila beleženja:
Logging
Beležim
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Ustvarjanje senÄnih kopij na WOW63 ni podprto. Prosimo uporabite 64-bitno FreeFileSync razliÄico.
Mirror ->>
Zrcalno ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Zrcalna kopija leve mape: Desna mapa bo prepisana in se bo natanÄno ujemala z levo mapo po sinhronizaciji.
+Monitoring active...
+Nadziranje aktivno...
More than 50% of the total number of files will be copied or deleted!
VeÄ kot 50% od celotnega Å¡tevila datotek bo kopiranih ali izbrisanih!
Move column down
Premakni stolpec dol
Move column up
Premakni stolpec gor
-Move files to a user-defined directory.
-Premakne datoteke v uporabniÅ¡ko-doloÄen imenik.
+Move files into a time-stamped subdirectory.
+Premakni datoteke v Äasovno-oznaÄen podimenik.
Moving %x to Recycle Bin
Premikam %x v Koš
Moving file %x to user-defined directory %y
@@ -610,6 +632,8 @@ Moving folder %x to user-defined directory %y
Premikam mapo %x v uporabniÅ¡ko-doloÄen imenik %y
Multiple...
VeÄkratno...
+No change since last synchronization!
+Ni sprememb od zadnje sinhronizacije!
No filter selected
Noben filter ni izbran
Not enough free disk space available in:
@@ -639,15 +663,13 @@ Operacija:
Overview
Pregled
Pause
-Pavza
+Premor
Paused
-Na pavzi
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
+Na premoru
Please run a Compare first before synchronizing!
Prosim najprej zaženite Primerjaj preden sinhronizirate!
+Processing folder pair:
+Obdelujem par map:
Published under the GNU General Public License:
Objavljeno pod licenco GNU General Public:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Odstrani par imenikov
Remove local filter settings
Odstrani nastavitve lokalnega filtra
+Renaming file %x to %y
+Preimenujem datoteko %x v %y
Report translation error
PoroÄaj o napaki prevoda
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Ciljni imenik že obstaja!
Target file already existing!
Ciljna datoteka že obstaja!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+Ta ukazna-vrstica se izvede vsakiÄ:\n- Datoteke znotraj teh imenikov (ali podimenikov) so spremenjene\n- Ustrezna Ärka pogona postane na razpolago (vstavitev USB-ja)
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:
@@ -816,12 +842,14 @@ Unable to create logfile!
Ne morem ustvariti datoteko za beleženje!
Unable to initialize Recycle Bin!
Ne morem inicializirati Koša!
+Unresolved conflicts existing!
+Obstajajo nerešeni spori!
Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
Obstajajo nerešeni spori! \n\nLahko ignorirate spore in nadaljujete s sinhronizacijo.
Update ->
Posodobi ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Uporaba: Izberite imenike za nadzorovanje in vnesite ukazno vrstico. VsakiÄ ko se spremenijo datoteke znotraj teh imenikov (ali podimenikov) se izvrÅ¡i ukazna vrstica.
+Usage:
+Uporaba:
Use Recycle Bin
Uporabi Koš
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Pozor: Sinhronizacija ni uspela za %x predmetov:
When the comparison is started with this option set the following decision tree is processed:
Ko se primerjava zažene s tem setom možnosti, se obdela naslednje drevo odloÄitev:
+You can ignore conflicts and continue synchronization.
+Lahko ignorirate spore in nadaljujete s sinhronizacijo.
You can ignore the error to consider not existing directories as empty.
Ignoriraj napako za smatranje neobstojeÄih imenikv kot praznih.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Languages/spanish.lng b/BUILD/Languages/spanish.lng
index 466161c8..0c33f4bd 100644
--- a/BUILD/Languages/spanish.lng
+++ b/BUILD/Languages/spanish.lng
@@ -11,33 +11,33 @@
TB
TB
day(s)
-
+ dia(s)
hour(s)
-
+ hora(s)
kB
kB
min
-
+ min
sec
-
+ seg
%x / %y objects deleted successfully
-
+%x / %y objetos borrados satisfactoriamente
%x Percent
-
+%x Por ciento
%x directories
%x directorios
%x files,
-%x ficheros,
+%x archivos,
%x is not a valid FreeFileSync batch file!
-
+%x no es un archivo batch de FreeFileSync válido!
%x of %y rows in view
-%x de %y ficheros
+%x de %y filas en vista
%x of 1 row in view
-%x de 1 línea
+%x de 1 fila en vista
&Abort
&Abortar
&About...
-&Sobre...
+&Acerca de...
&Advanced
&Avanzado
&Apply
@@ -45,17 +45,19 @@
&Cancel
&Cancelar
&Check for new version
-&Buscar versión nueva
+&Comprobar si existe una nueva versión
+&Content
+&Contenido
&Create batch job
-&Crear un fichero batch
+&Crear un archivo batch
&Default
-&Config. por defecto
+&Configuración por defecto
&Exit
-
+&Salir
&Export file list
-&Exportar lista de ficheros
+&Exportar lista de archivos
&File
-&Fichero
+&Archivo
&Global settings
&Opciones globales
&Help
@@ -69,9 +71,9 @@
&Load configuration
&Cargar configuración
&New
-
+&Nuevo
+&No
&No
-
&OK
&OK
&Pause
@@ -79,15 +81,17 @@
&Quit
&Salir
&Restore
-
+&Restaurar
&Retry
&Reintentar
&Save
&Guardar
&Yes
-
+&Yes
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
-
+(Tenga en cuenta que sólo las unidades FAT/FAT32 se ven afectadas por este problema!\nEn los demás casos puede deshabilitar la opción \"ignorar 1-hora de diferencia\".)
+(Requires an Internet connection!)
+(¡Conexión a Internet necesaria!)
,
,
- Other side's counterpart to %dir
@@ -95,139 +99,145 @@
- Other side's counterpart to %name
- conflict
-
+- conflicto
- conflict (same date, different size)
-
+- conflicto (misma fecha, distinto tamaño)
- different
-- ficheros diferentes
+- diferentes
- directory part only
-
+- sólo parte del directorio
- equal
-- ficheros iguales
+- iguales
- exists left only
- existe sólo en la izquierda
- exists right only
- existe sólo en la derecha
- full file or directory name
-
+- archivo completo o nombre del directorio
- left
- izquierda
- left newer
-- el más nuevo en la izquierda
+- más reciente en la izquierda
- right
- derecha
- right newer
-- el más nuevo en la derecha
+- más reciente en la derecha
-Open-Source file synchronization-
--Sincronización de ficheros Open-Source-
+-Sincronización de archivos Open-Source-
+.
.
-,
/sec
-
+/seg
1 directory
1 directorio
1 file,
-1 fichero,
+1 archivo,
1. &Compare
1. &Comparar
1. Enter relative file or directory names separated by ';' or a new line.
-
+1. Introduzca los nombres de los archivos o directorios relativos separados por ';' o una nueva línea.
+1. Select directories to monitor.
+1. Seleccione los directorios a visualizar.
2. &Synchronize...
2. &Sincronizar...
+2. Enter a command line.
+2. Introduzca una línea de comando.
2. Use wildcard characters '*' and '?'.
-2. Usar '*' y '?' como caracteres comodín.
+2. Usar los caracteres comodín '*' y '?'.
3. Exclude files directly on main grid via context menu.
-3. Excluir directamente ficheros sobre la rejilla a través del menu de contexto.
+3. Excluir directamente archivos sobre las celdas a través del menú de contexto.
+3. Press 'Start'.
+3. Presione 'Inicio'.
<Automatic>
-
+<Automático>
<Directory>
<Directorio>
<Last session>
<Última sesión>
<multiple selection>
-<Selección múltiple>
+<selección múltiple>
A newer version of FreeFileSync is available:
-
+Una nueva versión de FreeFileSync está disponible:
Abort requested: Waiting for current operation to finish...
-Abortar pedido: Esperar a que la actual operación finalice...
+Solicitud de aborto: Esperando a que la operación actual finalice...
Aborted
Abortado
About
-Sobre
+Acerca de
Action
Acción
Activate filter
-
+Activar filtro
Add folder
-
+Añadir carpeta
Add folder pair
Añadir un par de carpetas
All directories in sync!
-
+¡Todos los directorios en sincronización!
An exception occured!
-¡Ha ocurrido una excepción!
+¡Se ha producido una excepción!
As a result the files are separated into the following categories:
-Como resultado, los ficheros son separados en las siguientes categorías:
+Como resultado, los archivos están separados en las siguientes categorías:
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:
-Como el nombre sugiere, dos ficheros que comparten el mismo nombre son marcados como iguales sólo si tienen el mismo contenido. Esta opción es útil para los chequeos de consistencia más que en operaciones de "backup". Por tanto, las fechas de los ficheros no se tienen en cuenta de ningún modo.\n\nCon esta opción habilitada el árbol de decisiones es más pequeño:
+Como el título sugiere, dos archivos que comparten el mismo nombre son marcados como iguales sólo si tienen el mismo contenido. Esta opción es útil para las comprobaciones de consistencia más que en operaciones de "backup". Por lo tanto, las fechas de los archivos no se tienen en cuenta.\n\nCon esta opción habilitada el árbol de decisiones se reduce a:
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.
-Crear un fichero "batch" para una sincronización automática. Para empezar en modo "batch" simplemente pasar el nombre del fichero al ejecutable FreeFileSyinc en la ventana de comandos (CMD): FreeFileSync.exe <nombre de fichero batch>. También puede ser planificada en el Administrador de Tareas programadas.
+Crear un archivo batch para una sincronización automática. Para empezar en modo batch simplemente pasar el nombre del archivo por el ejecutable FreeFileSync en la ventana de comandos (CMD): FreeFileSync.exe <archivo batch>. También se puede planificar en el Administrador de Tareas de su Sistema Operativo.
+At least one directory input field is empty.
+Almenos un campo de entrada del directorio está vacío.
Auto-adjust columns
-
+Ajustar automáticamente las columnas
Automatic mode
-
+Modo automático
Batch execution
-Ejecución del "batch"
+Ejecución batch
Batch file created successfully!
-¡El fichero "batch" ha sido creado correctamente!
+¡El archivo batch ha sido creado correctamente!
Batch job
-Tarea Batch
+Tarea batch
Big thanks for localizing FreeFileSync goes out to:
Agradecimientos por la traducción de FreeFileSync a:
Both sides have changed since last synchronization!
-
+¡Ambos lados han cambiado desde la última sincronizacion!
Browse
-
+Navegar
Build:
-Construído:
+Realizado:
Cancel
Cancelar
-Cannot determine sync-direction: Changed filter settings!
-
-Cannot determine sync-direction: No change since last synchronization!
-
+Cannot determine sync-direction:
+No se puede determinar la dirección de la sincronización:
Category
-
+Categoría
Change direction
-
+Cambiar dirección
Comma separated list
-Lista de "items" separados por coma
-Commandline
-
-Commandline is empty!
-
+Lista separada por comas
+Command line
+Línea de comandos
+Command line is empty!
+¡La línea de comandos está vacía!
Compare
-
+Comparar
Compare both sides
Comparar ambos lados
Compare by \"File content\"
-Comparar por \"Contenido de fichero\"
+Comparar por \"Contenido del archivo\"
Compare by \"File size and date\"
-Comparar por \"Tamaño y fecha de fichero\"
+Comparar por \"Tamaño y fecha del archivo\"
Compare by...
Comparar por...
Comparing content
-Comparación de contenido
+Comparación del contenido
Comparing content of files %x
-Comparación del contenido de %x ficheros
+Comparación del contenido de %x archivos
Comparing content...
-
+Comparando el contenido...
Comparing files by content failed.
-
+La comparación de archivos por el contenido ha fallado.
Comparison Result
-
+Resultado de la comparación
Comparison settings
-
+Opciones de comparación
Completed
Terminado
Configuration
@@ -235,23 +245,23 @@ Configuración
Configuration loaded!
¡Configuración cargada!
Configuration overview:
-Parámetros de configuración:
+Visión global de la configuración:
Configuration saved!
¡Configuración guardada!
Configure filter
Configurar filtro
Configure your own synchronization rules.
-Configure sus propias reglas de sincronización.
+Configuración de sus propias reglas de sincronización.
Confirm
Confirmar
Conflict detected:
-
+Conflicto detectado:
Conflicts/files that cannot be categorized
-
+Conflictos/archivos que no pueden ser categorizados
Continue
Continuar
Conversion error:
-Erro de conversión:
+Error de conversión:
Copy from left to right
Copiar de izquierda a derecha
Copy from left to right overwriting
@@ -260,22 +270,28 @@ Copy from right to left
Copiar de derecha a izquierda
Copy from right to left overwriting
Copiar de derecha a izquierda con sobreescritura
+Copy locked files
+Copiar archivos bloqueados
Copy new or updated files to right folder.
-Copiar ficheros nuevos o actualizados a la carpeta de la derecha.
+Copiar archivos nuevos o actualizados a la carpeta de la derecha.
+Copy shared or locked files using Volume Shadow Copy Service.
+Copiar archivos compartidos o bloqueados usando el servicio "Volume Shadow Copy".
Copy to clipboard\tCTRL+C
Copiar al Portapapeles\tCTRL+C
Copying file %x to %y
-Copiar fichero %x a %y
+Copiar archivo %x a %y
Copying file %x to %y overwriting target
-
+Copiar archivo %x a %y sobreescribiendo el objetivo
Could not determine volume name for file:
-
+No se ha podido determinar el nombre del volumen para el archivo:
Could not initialize directory monitoring:
-
+No se ha podido inicializar la visualización de directorios:
+Could not load a required DLL:
+No se ha podido cargar el DLL solicitado:
Could not read values for the following XML nodes:
-
+No se ha podido leer los valores para los siguientes nodos XML:
Create a batch job
-Crear una tarea "batch"
+Crear una tarea batch
Creating folder %x
Creando la carpeta %x
Current operation:
@@ -285,71 +301,71 @@ Personalizado
Customize columns
Personalizar columnas
Customize...
-
+Personalizar...
+D-Click
D-Click
-
DECISION TREE
ÃRBOL DE DECISIÓN
Data remaining:
Datos que faltan:
Data verification error: Source and target file have different content!
-
+Error de verificación de datos: Los archivos origen y objetivo tienen un contenido diferente!
Date
Fecha
Delay
-
-Delay between detection of changes and execution of commandline in seconds
-
+Retardo
+Delay between detection of changes and execution of command line in seconds
+Retardo entre la detección de cambios y la ejecución de la línea de comandos en segundos
Delete files/folders existing on left side only
-Eliminar sólo ficheros/carpetas existentes en el lado izquierdo
+Borrar sólo archivos/carpetas existentes en el lado izquierdo
Delete files/folders existing on right side only
-Eliminar sólo ficheros/carpetas existentes en el lado derecho
+Borrar sólo archivos/carpetas existentes en el lado derecho
Delete files\tDEL
-Eliminar ficheros\tDEL
+Borrar archivos\tDEL
Delete on both sides
-Eliminar en ambos lados lados
+Borrar en ambos lados
Delete on both sides even if the file is selected on one side only
-Eliminar en ambos lados incluso si el fichero es seleccionado en un solo lado
+Borrar en ambos lados incluso si el archivo está seleccionado en un solo lado
Delete or overwrite files permanently.
-
+Borrar o sobreescribir archivos permanentemente.
Delete permanently
-
+Borrar permanentemente
Deleting file %x
-Borrar fichero %x
+Borrar archivo %x
Deleting folder %x
Borrar carpeta %x
Deletion handling
-
+Gestión de eliminación
Description
-
+Descripción
Directories are dependent! Be careful when setting up synchronization rules:
¡Los directorios son dependientes! Cuidado al establecer las reglas de sincronización:
Directories to watch
-
+Directorios a visualizar
Directory
-
+Directorio
Directory does not exist:
El directorio no existe:
Do not show this dialog again
-
+No volver a mostrar este diálogo
Do nothing
No hacer nada
Do you really want to delete the following objects(s)?
¿Está seguro de querer borrar el/los siguiente(s) objeto(s)?
Do you really want to move the following objects(s) to the Recycle Bin?
-¿Está seguro de querer mover el/los siguiente(s) objeto(s) a la Papelera?
+¿Está seguro de querer mover el/los siguiente(s) objeto(s) a la Papelera de Reciclaje?
Do you want FreeFileSync to automatically check for updates every week?
-
+¿Quiere que FreeFileSync detecte automáticamente nuevas actualizaciones cada semana?
Donate with PayPal
-Donar usando PayPal
+Donar a través de PayPal
Download now?
¿Descargar ahora?
Drag && drop
-Arrastrar
+Arrastrar && Soltar
Email
Email
Enable filter to exclude files from synchronization
-
+Activar filtro para excluir archivos de la sincronización
Endless loop when traversing directory:
Error
@@ -357,199 +373,203 @@ Error
Error changing modification time:
Error al modificar hora:
Error copying file:
-Erro al copiar fichero:
+Error al copiar archivo:
Error copying locked file %x!
-
+¡Error al copiar archivo bloqueado %x!
Error creating directory:
Error al crear directorio:
Error deleting directory:
Error al borrar directorio:
Error deleting file:
-Error al eliminar fichero:
+Error al borrar archivo:
Error handling
-Controlador de errores
+Gestión de errores
Error loading library function:
-Error al descargar función de biblioteca:
+Error al cargar la función de biblioteca:
Error moving directory:
-
+Error al mover directorio:
Error moving file:
-
+Error al mover archivo:
Error moving to Recycle Bin:
-Error al mover a la Papelera:
+Error al mover a la Papelera de Reciclaje:
Error opening file:
-Error al abrir fichero:
+Error al abrir archivo:
Error parsing configuration file:
-Error en el análisis sintáctico del fichero de configuración:
+Error en el análisis sintáctico del archivo de configuración:
Error reading file attributes:
-Error al leer atributos del fichero:
+Error al leer atributos del archivo:
Error reading file:
-Error al leer el fichero:
+Error al leer el archivo:
Error reading from synchronization database:
-
+Error al leer de la base de datos de sincronización:
+Error resolving full path name:
+Error al resolver el nombre completo de ruta:
Error resolving symbolic link:
Error al resolver enlace simbólico:
Error starting Volume Shadow Copy Service!
-
+¡Error al iniciar el servicio "Volume Shadow Copy"!
Error traversing directory:
-Error al trasladar directorio:
-Error when monitoring directories.
+Error when monitoring directories.
+Error al visualizar los directorios.
Error writing file attributes:
-Error al escribir atributos del fichero:
+Error al escribir atributos del archivos:
Error writing file:
-Error al escribir fichero:
+Error al escribir archivo:
Error writing to synchronization database:
-
+Error al escribir en la base de datos de sincronización:
Example
Ejemplo
Exclude
Excluir
Exclude all rows
-
+Excluir todas las columnas
Exclude temporarily
Excluir temporalmente
Exclude via filter:
-Excluir por filtro:
+Excluir a través del filtro:
Exit immediately and set returncode < 0
-Salir inmediatamente y enviar el código < 0
+Salir inmediatamente y establecer el código de retorno < 0
Exit with RC < 0
-Salir com RC < 0
+Salir con RC < 0
External applications
-
+Aplicaciones externas
Fatal Error
-
+Error fatal
Feedback and suggestions are welcome at:
-Los comentarios y sugerencias será bienvenidos en:
+Comentarios y sugerencias son bienvenidos en:
File %x has an invalid date!
-
+¡Archivo %x tiene una fecha inválida!
File already exists. Overwrite?
-El fichero ya existe. ¿Sustituir?
+El archivo ya existe. ¿Sobreescribir?
File content
-Contenido del fichero
+Contenido del archivo
File does not exist:
-El fichero no existe:
+El archivo no existe:
File list exported!
-Lista de ficheros exportada!
+¡Lista de archivos exportada!
File size and date
-Fecha y tamaño del fichero
+Fecha y tamaño del archivo
Filename
-Nombre del fichero
+Nombre del archivo
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.
-
+Los archivos %x tienen un archivo de tiempo diferente o menor que una hora!\n\nNo es seguro decidir cual de ellos es más reciente por cuestiones con el horario de verano.
Files %x have the same date but a different size!
-
+¡Los archivos %x tienen la misma fecha pero un tamaño diferente!
Files are found equal if\n - file content\nis the same.
-Los ficheros serán considerados iguales si\n - el contenido del fichero\nes el mismo.
+Los archivos serán considerados iguales si\n - el contenido del archivo\nes el mismo.
Files are found equal if\n - filesize\n - last write time and date\nare the same.
-Los ficheros serán considerados iguales si\n - la hora y fecha de la última escritura\nson iguales.
+Los archivos serán considerados iguales si\n - tamaño del archivo\n - la hora y fecha de la última escritura\nson iguales.
Files remaining:
-Ficheros restantes:
+Archivos restantes:
Files that are equal on both sides
-
+Archivos que son iguales en ambos lados
Files that exist on both sides and have different content
-Ficheros que existen en ambos lados y tienen contenidos diferentes
+Archivos que existen en ambos lados y tienen contenido diferente
Files that exist on both sides, left one is newer
-Ficheros que existen en ambos lados, el de la izquierda es más reciente
+Archivos que existen en ambos lados, el de la izquierda es más reciente
Files that exist on both sides, right one is newer
-Ficheros que existen en ambos lados, el de la derecha es más reciente
+Archivos que existen en ambos lados, el de la derecha es más reciente
Files/folders found:
-
+Archivos/carpetas encontrados:
Files/folders remaining:
-Ficheros/carpetas restantes:
+Archivos/carpetas restantes:
Files/folders that exist on left side only
-Ficheros/carpetas que existen sólo en el lado izquierdo
+Archivos/carpetas que existen sólo en el lado izquierdo
Files/folders that exist on right side only
-Ficheros/carpetas que existen sólo en el lado derecho
+Archivos/carpetas que existen sólo en el lado derecho
Filter
-
+Filtro
Filter files
-Filtrar ficheros
+Filtrar archivos
Filter has been selected
-
+El filtro ha sido seleccionado
+Filter settings have changed!
+¡Las opciones de filtrado han cambiado!
Filter view
Vista de filtros
Filtering is deactivated
-
+Filtrado desactivado
Folder Comparison and Synchronization
-Carpeta de Comparación y Sincronización
+Comparación y Sincronización de carpetas
Free disk space available:
-
+Espacio de disco libre disponible:
FreeFileSync - Folder Comparison and Synchronization
FreeFileSync - Comparación y Sincronización de carpetas
FreeFileSync Batch Job
-FreeFileSync Tarea "Batch"
+FreeFileSync Tarea Batch
FreeFileSync at Sourceforge
FreeFileSync en Sourceforge
FreeFileSync batch file
-FreeFileSync fichero batch
+FreeFileSync archivo batch
FreeFileSync configuration
FreeFileSync configuración
FreeFileSync is up to date!
-FreeFileSync está actualizado
+¡FreeFileSync está actualizado!
Full path
-
+Ruta completa
Generating database...
-
+Generando base de datos...
Generating file list...
-Generando lista de ficheros...
+Generando lista de archivos...
Global filter
-
+Filtro global
Global settings
Opciones globales
Help
Ayuda
Hidden dialogs:
-
+Diálogos ocultos:
Hide all error and warning messages
Ocultar todos los mensajes de error y aviso
Hide conflicts
-
+Ocultar conflictos
Hide excluded items
-
+Ocultar elementos excluidos
Hide files that are different
-Ocultar ficheros diferentes
+Ocultar archivos diferentes
Hide files that are equal
-Ocultar ficheros iguales
+Ocultar archivos iguales
Hide files that are newer on left
-Ocultar ficheros más recientes en la izquierda
+Ocultar archivos más recientes en la izquierda
Hide files that are newer on right
-Ocultar ficheros más recientes en la derecha
+Ocultar archivos más recientes en la derecha
Hide files that exist on left side only
-Ocultar los ficheros que existen sólo en el lado izquierdo
+Ocultar archivos que existen sólo en el lado izquierdo
Hide files that exist on right side only
-Ocultar los ficheros que existen sólo en el lado derecho
+Ocultar archivos que existen sólo en el lado derecho
Hide files that will be created on the left side
-
+Ocultar archivos que serán creados en el lado izquierdo
Hide files that will be created on the right side
-
+Ocultar archivos que serán creados en el lado derecho
Hide files that will be deleted on the left side
-
+Ocultar archivos que serán eliminados en el lado izquierdo
Hide files that will be deleted on the right side
-
+Ocultar archivos que serán eliminados en el lado derecho
Hide files that will be overwritten on left side
-
+Ocultar archivos que serán sobreescritos en el lado izquierdo
Hide files that will be overwritten on right side
-
+Ocultar archivos que serán sobreescritos en el lado derecho
Hide files that won't be copied
-
+Ocultar archivos que no serán copiados
Hide filtered or temporarily excluded files
-
+Ocultar archivos filtrados o temporalmente excluidos
Hide further error messages during the current process
-Ocultar próximos mensajes de error durante este processo
+Ocultar próximos mensajes de error durante el proceso actual
Hints:
Consejos:
Homepage
-Homepage
+Página de inicio
Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically.
-
+Identificar y aplicar cambios en ambos lados usando una base de datos. Los borrados y conflictos son detectados automáticamente.
If you like FFS
Si te gusta FFS
Ignore 1-hour file time difference
-
+Ignorar el archivo de 1-hora de tiempo de diferencia
Ignore errors
Ignorar errores
Ignore subsequent errors
-Ignorar errores siguientes
+Ignorar errores posteriores
Ignore this error, retry or abort synchronization?
¿Ignorar este error, reintentar o abortar sincronización?
Ignore this error, retry or abort?
@@ -557,135 +577,139 @@ Ignore this error, retry or abort?
Include
Incluir
Include all rows
-
+Incluir todas las filas
Include temporarily
Incluir temporalmente
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Incluir: *.doc;*.zip;*.exe\nExcluir: \\stuff\\temp\\*
Incompatible synchronization database format:
-
+Formato de sincronización de base de datos incompatible:
Info
Info
Information
Información
Initial synchronization:
-
+Sincronización inicial:
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. :)
-¡No fue posible iniciar la Papelera!\n\nEs probable que no esté usando Windows.\nSi quiere que este hecho sea considerado, por favor, contactate con el autor :)
+Integrar aplicaciones externas en el menú de contexto. Las siguientes macros están disponibles:
Leave as unresolved conflict
-
+Dejar como conflicto sin resolver
Left
-
+Izquierda
Legend
-
+Leyenda
Load configuration from file
-Cargar configuración desde fichero
+Cargar configuración desde archivo
Load configuration history (press DEL to delete items)
-Cargar histórico de configuración (presionar DEL para borrar elementos)
+Cargar historial de configuración (presionar DEL para borrar elementos)
Local filter
-
+Filtro local
Log-messages:
-Log de mensajes:
+Registro de mensajes:
Logging
-
+Iniciando sesión
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+La realización de copias shadow en WOW64 no está soportado. Por favor, use la versión de 64-bit de FreeFileSync.
Mirror ->>
Espejo ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Backup espejo de la carpeta de la izquierda: La carpeta de la derecha será sustituída y coincidirá exactamente con la carpeta de la izquierda después de la sincronización.
+Monitoring active...
+Visualización activa...
More than 50% of the total number of files will be copied or deleted!
-
+¡Más del 50% del número total de archivos serán copiados o borrados!
Move column down
Mover columna abajo
Move column up
Mover columna arriba
-Move files to a user-defined directory.
-
+Move files into a time-stamped subdirectory.
+Mover archivos a un subdirectorio con marca de tiempo.
Moving %x to Recycle Bin
-
+Mover %x a la Papelera de Reciclaje
Moving file %x to user-defined directory %y
-
+Mover el archivo %x al directorio definido por el usuario %y.
Moving folder %x to user-defined directory %y
-
+Mover la carpeta %x al directorio definido por el usuario %y.
Multiple...
-
+Múltiple...
+No change since last synchronization!
+¡Ningún cambio desde la última sincronización!
No filter selected
-
+Ningún filtro seleccionado
Not enough free disk space available in:
-
+Espacio en disco disponible insuficiente en:
Nothing to synchronize according to configuration!
-¡No hay nada que sincronizar de acuerdo con la configuración!
+¡Nada que sincronizar de acuerdo con la configuración!
Number of files and directories that will be created
-Número de elementos que serán creados
+Número de archivos y directorios que serán creados
Number of files and directories that will be deleted
-Número de elementos que serán borrados
+Número de archivos y directorios que serán borrados
Number of files that will be overwritten
-Número de ficheros que serán sustituídos
+Número de archivos que serán sobreescritos
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.
-
+Sólo los archivos/directorios que pasen el filtrado serán seleccionados para la sincronización. El filtro será aplicado al nombre relativo(!) a la base de directorios de sincronización.
Open directly
-
+Abrir directamente
Open with Explorer
-
+Abrir con Explorer
Open with Konqueror
-
+Abrir con Konqueror
Operation aborted!
-Operación abortada!
+¡Operación abortada!
Operation:
Operación:
Overview
-
+Visión global
Pause
Pausa
Paused
-
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-
-Please fill all empty directory fields.
-Por favor, rellene todos los campos del directorio vacíos.
+Pausado
Please run a Compare first before synchronizing!
-
+¡Por favor, ejecute la comparación antes de la sincronización!
+Processing folder pair:
+Procesar un par de carpetas:
Published under the GNU General Public License:
Publicado bajo "GNU General Public License":
Question
-
+Pregunta
Quit
Salir
Re-enable all hidden dialogs?
-
+¿Reactivar todos los diálogos ocultos?
RealtimeSync - Automated Synchronization
-
+Sincronización automática de RealtimeSync
RealtimeSync configuration
-
+Configuración de RealtimeSync
Relative path
-Camino relativo
+Ruta relativa
Remove alternate settings
-
+Eliminar opciones alternativas
Remove folder
-
+Eliminar carpeta
Remove folder pair
-Eliminar par de carpetas
+Eliminar un par de carpetas
Remove local filter settings
-
+Eliminar las opciones locales de filtrado
+Renaming file %x to %y
+Renombrando archivo %x a %y
Report translation error
-
+Informar de errores de traducción
Reset
Reiniciar
Right
-
+Derecha
Run minimized and write status information to a logfile
-
+Ejecutar minimizado y escribir información del estado en un archivo de registro
S&ave configuration
G&uardar configuración
S&witch view
-
+C&ambiar vista
Save changes to current configuration?
-
+¿Guardar los cambios de la configuración actual?
Save current configuration to file
-Guardar la configuración actual en un fichero
+Guardar la configuración actual en un archivo
Scanning...
Analizando...
Scanning:
@@ -693,117 +717,119 @@ Analizar:
Select a folder
Seleccione una carpeta
Select alternate synchronization settings
-
+Seleccione opciones alternativas de sincronización
Select logfile directory:
-
+Seleccione directorio del archivo de registro:
Select variant:
-Sleccione una variante:
+Seleccione un tipo:
Setting default synchronization directions. Please check whether they are appropriate for you.
-
+Configurar direcciones de sincronización por defecto. Por favor, compruebe que son correctas.
Show conflicts
-
+Mostrar conflictos
Show file icons
-
+Mostrar icono de los archivos
Show files that are different
-Mostrar los ficheros diferentes
+Mostrar archivos diferentes
Show files that are equal
-Mostrar los ficheros iguales
+Mostrar archivos iguales
Show files that are newer on left
-Mostrar ficheros recientes a la izquierda
+Mostrar archivos más recientes a la izquierda
Show files that are newer on right
-Mostrar ficheros recientes a la derecha
+Mostrar archivos más recientes a la derecha
Show files that exist on left side only
-Mostrar ficheros existentes en la izquierda sólamente
+Mostrar sólo archivos existentes en la izquierda
Show files that exist on right side only
-Mostrar ficheros existentes en la derecha sólamente
+Mostrar sólo archivos existentes en la derecha
Show files that will be created on the left side
-
+Mostrar archivos que serán creados en el lado izquierdo
Show files that will be created on the right side
-
+Mostrar archivos que serán creados en el lado derecho
Show files that will be deleted on the left side
-
+Mostrar archivos que serán eliminados en el lado izquierdo
Show files that will be deleted on the right side
-
+Mostrar archivos que serán eliminados en el lado derecho
Show files that will be overwritten on left side
-
+Mostrar archivos que serán sobreescritos en el lado izquierdo
Show files that will be overwritten on right side
-
+Mostrar archivos que serán sobreescritos en el lado derecho
Show files that won't be copied
-
+Mostrar archivos que no serán copiados
Show hidden dialogs
-
+Mostrar diálogos ocultos
Show popup
-Mostrar "popups"
+Mostrar popup
Show popup on errors or warnings
-Mostrar "popup" de errores o avisos
+Mostrar popup de errores o avisos
Significant difference detected:
-
+Diferencia significante detectada:
Silent mode
Modo silencioso
Size
Tamaño
Source code written completely in C++ utilizing:
-Código fuente escrito en C++ utilizando:
+Código fuente escrito completamente en C++ utilizando:
Source directory does not exist anymore:
-El directorio origen no existe ya:
+El directorio origen ya no existe:
Speed:
-
+Velocidad:
Start
Iniciar
Start synchronization
-Iniciar a sincronización
+Iniciar sincronización
Statistics
-
+Estadística
Stop
-Parar
+Detener
Swap sides
-
+Intercambiar lados
Synchronization Preview
-
+Previsualización de la sincronización
Synchronization aborted!
-Sincronización abortada!
+¡Sincronización abortada!
Synchronization completed successfully!
¡Sincronización completada con éxito!
Synchronization completed with errors!
¡Sincronización completada con errores!
Synchronization settings
-Parámetros de sincronización
+Opciones de sincronización
Synchronization status
Estado de la sincronización
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
-
+Sincronizar todos los archivos .doc, .zip and .exe excepto el contenido de la subcarpeta \"temp\".
Synchronize both sides simultaneously: Copy new or updated files in both directions.
-Sincronizar ambos lados simultáneamente: Copiar ficheros nuevos o actualizados en ambas direcciones.
+Sincronizar ambos lados simultáneamente: Copiar archivos nuevos o actualizados en ambas direcciones.
Synchronize both sides using a database. Deletions are detected automatically.
-
+Sincronizar ambos lados usando una base de datos. Los borrados son detectados automáticamente.
Synchronize...
-
+Sincronizar...
Synchronizing...
Sincronizando...
System out of memory!
-Sistema sin memoria!
+¡Sistema sin memoria!
Target directory already existing!
-
+¡El directorio objetivo ya existe!
Target file already existing!
-¡El fichero objetivo existe ya!
+¡El archivo objetivo ya existe!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+La línea de comandos es ejecutada cada vez:\n- Archivos con estos directorios (o subdirectorios) son modificados\n- La letra de la unidad correspondiente se muestra disponible (inserción USB)
The database file is not yet existing, but will be created during synchronization:
-
+El archivo de base de datos no existe aún pero será creado durante la sincronización:
The file does not contain a valid configuration:
-El fichero no contiene una configuración válida:
+El archivo no contiene una configuración válida:
The required database entry is not yet existing, but will be created during synchronization:
-
+La entrada a la base de datos no existe aún pero será creada durante la sincronizació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.
-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.
+Este tipo evalúa dos archivos con el mismo nombre como iguales cuando tienen el mismo tamaño de archivo y la misma fecha de modificación.
Time
Hora
Time elapsed:
Tiempo transcurrido:
Time remaining:
-
+Tiempo restante:
Total amount of data that will be transferred
Cantidad total de datos que serán transferidos
Total required free disk space:
-
+Espacio total de disco necesario:
Total time:
Tiempo 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.
@@ -811,46 +837,50 @@ Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as
Two way <->
Doble sentido <->
Unable to connect to sourceforge.net!
-Permitir conectar con sourceforge.net
+¡Incapaz de conectar con sourceforge.net!
Unable to create logfile!
-Permitir crear logfile
+¡Incapaz de crear un archivo de registro!
Unable to initialize Recycle Bin!
-Permitir iniciar la Papelera
+¡Incapaz de iniciar la Papelera de Reciclaje!
+Unresolved conflicts existing!
+¡Existen conflictos sin resolver!
Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
Update ->
Actualizar ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-
+Usage:
+Uso:
Use Recycle Bin
-Utilizar la Papelera
+Utilizar Papelera de Reciclaje
Use Recycle Bin when deleting or overwriting files.
-
+Utilitzar Papelera de Reciclaje al borrar o sobreescribir archivos.
User-defined directory
-
+Directorio definido por el usuario
User-defined directory for deletion was not specified!
-
+¡El directorio definido por el usuario para el borrado no ha sido indicado!
Variant
-
+Tipo
Verifying file %x
-
+Verificación del archivo %x
Volume name %x not part of filename %y!
-
+El nombre del volumen %x no es una parte del nombre del archivo %y
Warning
Atención
Warning: Synchronization failed for %x item(s):
Atención: La sincronización falló para %x item(s):
When the comparison is started with this option set the following decision tree is processed:
-Cuando la comparación se inicia con este conjunto de opciones, se procesa el siguiente árbol de decisiones:
+Cuando la comparación se inicia con este conjunto de opciones se procesa el siguiente árbol de decisiones:
+You can ignore conflicts and continue synchronization.
+Puede ignorar conflictos y continuar con la sincronización.
You can ignore the error to consider not existing directories as empty.
-
+Puede ignorar el error al considerar que no existen directorios como vacíos.
You can ignore the error to skip current folder pair.
-
+Puede ignorar el error omitiendo el par de carpetas actuales.
You may try to synchronize remaining items again (WITHOUT having to re-compare)!
-Puede intentar sincronizar los elementos restantes otra vez (SIN tener que volver a comparar)
+¡Puede intentar sincronizar los elementos restantes otra vez (SIN tener que volver a comparar)!
different
-ficheros diferentes
+diferentes
file exists on both sides
-el fichero existe en ambos lados
+el archivo existe en ambos lados
on one side only
-fichero sólo en un lado
+sólo en un lado
diff --git a/BUILD/Languages/swedish.lng b/BUILD/Languages/swedish.lng
new file mode 100644
index 00000000..9211ce99
--- /dev/null
+++ b/BUILD/Languages/swedish.lng
@@ -0,0 +1,886 @@
+ 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
+ Byte
+ GB
+ GB
+ MB
+ MB
+ PB
+ PB
+ TB
+ TB
+ day(s)
+ dag(ar)
+ hour(s)
+ timma(r)
+ kB
+ kB
+ min
+ min.
+ sec
+ sek.
+%x / %y objects deleted successfully
+%x / %y objekt borttagna
+%x Percent
+%x Procent
+%x directories
+%x kataloger
+%x files,
+%x filer,
+%x is not a valid FreeFileSync batch file!
+%x är ingen giltig FreeFileSync batch-fil!
+%x of %y rows in view
+%x rader av %y i vyn
+%x of 1 row in view
+%x av 1 rad i vyn
+&Abort
+&Avbryt
+&About...
+&Om...
+&Advanced
+&Avancerat
+&Apply
+&Verkställ
+&Cancel
+&Avbryt
+&Check for new version
+&Sök efter uppdatering
+&Content
+&Innehåll
+&Create batch job
+&Skapa batch-jobb
+&Default
+&Standard
+&Exit
+&Avsluta
+&Export file list
+&Exportera fillista
+&File
+&Arkiv
+&Global settings
+&Allmäna inställningar
+&Help
+&Hjälp
+&Ignore
+&Ignorera
+&Language
+&Språk
+&Load
+&Läs från fil
+&Load configuration
+&Hämta inställningar från fil
+&New
+&Nytt
+&No
+&Nej
+&OK
+&OK
+&Pause
+&Paus
+&Quit
+&Sluta
+&Restore
+&Återställ
+&Retry
+&Försök igen
+&Save
+&Spara
+&Yes
+&Ja
+(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
+(Notera att endast FAT/FAT32-formaterade diskar berörs av detta problem!\nI alla andra fall kan du inaktivera alternativet \"Ignorera sommartid\".)
+(Requires an Internet connection!)
+(Kräver Internetuppkoppling!)
+,
+.
+- Other side's counterpart to %dir
+- Andra sidans motsvarighet till %dir
+- Other side's counterpart to %name
+- Andra sidans motsvarighet till %name
+- conflict
+- konflikt
+- conflict (same date, different size)
+- konflikt (samma datum, olika storlek)
+- different
+- olika
+- directory part only
+- Endast fil-/katalognamn
+- equal
+- lika
+- exists left only
+- finns endast till vänster
+- exists right only
+- finns endast till höger
+- full file or directory name
+- Full sökväg
+- left
+- vänster
+- left newer
+- vänster nyare
+- right
+- höger
+- right newer
+- höger nyare
+-Open-Source file synchronization-
+-Öppen källkod filsynkronisering-
+.
+,
+/sec
+/s
+1 directory
+1 katalog
+1 file,
+1 fil,
+1. &Compare
+1. &Jämför
+1. Enter relative file or directory names separated by ';' or a new line.
+1. Ange fil- eller katalognamn avgränsade med "," eller en ny rad
+1. Select directories to monitor.
+1. Välj kataloger att övervaka.
+2. &Synchronize...
+2. &Synkronisera...
+2. Enter a command line.
+2. Mata in ett kommando.
+2. Use wildcard characters '*' and '?'.
+2. Använd wildcard-tecknen '*' och '?' .
+3. Exclude files directly on main grid via context menu.
+3. Undanta filer direkt i huvudfönstret, via högerklicksmenyn.
+3. Press 'Start'.
+3. Tryck 'Start'.
+<Automatic>
+<Automatisk>
+<Directory>
+<Katalog>
+<Last session>
+<Senaste session>
+<multiple selection>
+<flerval>
+A newer version of FreeFileSync is available:
+En nyare version av FreeFileSync finns tillgänglig:
+Abort requested: Waiting for current operation to finish...
+Avbryter: Väntar på att aktuell process skall slutföras...
+Aborted
+Användaren avbröt
+About
+Om
+Action
+Aktivitet
+Activate filter
+Aktivera filter
+Add folder
+Lägg till katalog
+Add folder pair
+Lägg till katalogpar
+All directories in sync!
+Alla kataloger synkade!
+An exception occured!
+Ett undantag inträffade!
+As a result the files are separated into the following categories:
+Som ett resultat blir filerna separerade i följande kategorier:
+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:
+Som namnet antyder, två filer med samma namn beräknas som lika, endast om dom har samma innehåll. Den här funktionen är mer användbar för konsistenskontroll, snarare än säkerhetskopiering. Därför tas inte tidsattributen med i beräkningen.\n\nMed det här alternativet aktiverat, blir beslutsträdet mindre:
+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.
+Montera en batch-fil för automatisk synkronisering. För att starta i batch-läge, lägg till filnamnet i startkommandot: FreeFileSync.exe <batch-fil>. Det kan också schemaläggas i Windows Schemaläggaren.
+At least one directory input field is empty.
+Minst 1 adressfält är tomt.
+Auto-adjust columns
+Autojustera kollumner
+Automatic mode
+Autoläge
+Batch execution
+Batch-körning
+Batch file created successfully!
+Batch-filen skapades korrekt!
+Batch job
+Batch-jobb
+Big thanks for localizing FreeFileSync goes out to:
+Stort tack för översättningen av FreeFileSync går till:
+Both sides have changed since last synchronization!
+Båda sidor har ändrats sedan senaste synkroniseringen!
+Browse
+Bläddra
+Build:
+Bygg:
+Cancel
+Avbryt
+Cannot determine sync-direction:
+Kan inte bestämma synk-riktning:
+Category
+Kategori
+Change direction
+Ändra riktning
+Comma separated list
+Komma-separerad lista
+Command line
+Kommandofält
+Command line is empty!
+Kommandofältet är tomt
+Compare
+Jämför
+Compare both sides
+Jämför båda sidor
+Compare by \"File content\"
+Jämför: \"Filinnehåll\"
+Compare by \"File size and date\"
+Jämför: \"Filstorlek och datum\"
+Compare by...
+Jämför...
+Comparing content
+Jämför innehåll
+Comparing content of files %x
+Jämför filinnehåll för %x
+Comparing content...
+Jämför innehåll...
+Comparing files by content failed.
+Kunde inte jämföra filinnehåll.
+Comparison Result
+Jämförelseresultat
+Comparison settings
+Jämförelseinställningar
+Completed
+Klar
+Configuration
+Inställningar
+Configuration loaded!
+Inställningar inlästa!
+Configuration overview:
+Översikt:
+Configuration saved!
+Inställningar sparade!
+Configure filter
+Filterinställningar
+Configure your own synchronization rules.
+Konfigurera dina egna synkroniseringsregler.
+Confirm
+Bekräfta
+Conflict detected:
+Konflikt upptäckt:
+Conflicts/files that cannot be categorized
+Konflikter/filer som inte kan kategoriseras
+Continue
+Fortsätt
+Conversion error:
+Konversionsfel:
+Copy from left to right
+Kopiera från vänster till höger
+Copy from left to right overwriting
+Kopiera från vänster till höger och skriv över målet
+Copy from right to left
+Kopiera från höger till vänster
+Copy from right to left overwriting
+Kopiera från höger till vänster och skriv över målet
+Copy locked files
+Kopiera låsta filer
+Copy new or updated files to right folder.
+Kopiera nya och uppdaterade filer till höger katalog.
+Copy shared or locked files using Volume Shadow Copy Service.
+Använd Volume Shadow Copy Service för att kopiera låsta eller delade filer.
+Copy to clipboard\tCTRL+C
+Kopiera till urklipp\tCTRL+C
+Copying file %x to %y
+Kopierar fil %x till %y
+Copying file %x to %y overwriting target
+Kopierar fil %x till %y skriver över målet
+Could not determine volume name for file:
+Kan inte bestämma volym för fil:
+Could not initialize directory monitoring:
+Kan inte initiera katalogskanner:
+Could not load a required DLL:
+Kan inte läsa in nödvändig DLL:
+Could not read values for the following XML nodes:
+Kan inte läsa värden för följande XML-noder:
+Create a batch job
+Skapa ett batch-jobb
+Creating folder %x
+Skapar katalog %x
+Current operation:
+Aktuell uppgift:
+Custom
+Anpassat
+Customize columns
+Anpassa kollumner
+Customize...
+Anpassar...
+D-Click
+HÃ¥ll ner D
+DECISION TREE
+BESLUTSTRÄD
+Data remaining:
+Återstående data:
+Data verification error: Source and target file have different content!
+Verifikationsfel: Källfil och målfil har olika innehåll!
+Date
+Datum
+Delay
+Fördröjning
+Delay between detection of changes and execution of command line in seconds
+Fördröjning mellan ändringars upptäckt och åtgärd i sekunder
+Delete files/folders existing on left side only
+Ta bort filer/kataloger som endast finns på vänster sida
+Delete files/folders existing on right side only
+Ta bort filer/kataloger som endast finns på höger sida
+Delete files\tDEL
+Ta bort filer\tDEL
+Delete on both sides
+Ta bort på båda sidor
+Delete on both sides even if the file is selected on one side only
+Ta bort på båda sidor, även om filen är markerad på endast en sida
+Delete or overwrite files permanently.
+Ta bort eller skriv över permanent
+Delete permanently
+Ta bort permanent
+Deleting file %x
+Tar bort filen %x
+Deleting folder %x
+Tar bort katalogen %x
+Deletion handling
+Borttagning
+Description
+Beskrivning
+Directories are dependent! Be careful when setting up synchronization rules:
+Kataloger är beroende! Var försiktig när du sätter upp synkroniseringsregler:
+Directories to watch
+Kataloger att övervaka
+Directory
+Katalog
+Directory does not exist:
+Katalogen finns inte:
+Do not show this dialog again
+Visa inte den här dialogrutan igen
+Do nothing
+Gör ingenting
+Do you really want to delete the following objects(s)?
+Vill du verkligen ta bort följande objekt?
+Do you really want to move the following objects(s) to the Recycle Bin?
+Vill du verkligen flytta följande objekt till papperskorgen?
+Do you want FreeFileSync to automatically check for updates every week?
+Vill du att FreeFileSync skall söka efter uppdateringar varje vecka?
+Donate with PayPal
+Donera via PayPal
+Download now?
+Ladda ner nu?
+Drag && drop
+Dra && släpp
+Email
+e-post
+Enable filter to exclude files from synchronization
+Aktivera filter för att undanta filer från synkronisering
+Endless loop when traversing directory:
+Oändlig loop vid accessförsök på katalog:
+Error
+Fel
+Error changing modification time:
+Kan inte modifiera tidsstämpel:
+Error copying file:
+Kan inte kopiera fil:
+Error copying locked file %x!
+Kan inte kopiera låst fil %x!
+Error creating directory:
+Kan inte skapa katalog:
+Error deleting directory:
+Kan inte ta bort katalog:
+Error deleting file:
+Kan inte ta bort fil:
+Error handling
+Felhantering
+Error loading library function:
+Kan inte starta biblioteksfunktion:
+Error moving directory:
+Kan inte flytta katalog:
+Error moving file:
+Kan inte flytta fil:
+Error moving to Recycle Bin:
+Kan inte flytta till papperskorgen:
+Error opening file:
+Kan inte öppna fil:
+Error parsing configuration file:
+Kan inte läsa in konfigurationsfil:
+Error reading file attributes:
+Kan inte läsa filattribut:
+Error reading file:
+Kan inte läsa fil:
+Error reading from synchronization database:
+Kan inte läsa från databasen:
+Error resolving full path name:
+Kan inte läsa in full sökväg:
+Error resolving symbolic link:
+Kan inte tyda symbolisk länk:
+Error starting Volume Shadow Copy Service!
+Kan inte starta 'Volume Shadow Copy Service'!
+Error traversing directory:
+Accessfel på katalog:
+Error when monitoring directories.
+Fel vid övervakning av kataloger.
+Error writing file attributes:
+Kan inte skriva filattribut:
+Error writing file:
+Kan inte skriva fil:
+Error writing to synchronization database:
+Kan inte skriva till databas:
+Example
+Exempel
+Exclude
+Undanta
+Exclude all rows
+Undanta alla rader
+Exclude temporarily
+Undanta tillfälligt
+Exclude via filter:
+Lägg till i undantag:
+Exit immediately and set returncode < 0
+Avsluta omedelbart och sätt returkod < 0
+Exit with RC < 0
+Avsluta med RC < 0
+External applications
+Externa program
+Fatal Error
+Allvarligt fel
+Feedback and suggestions are welcome at:
+Feedback och förslag är välkommna här:
+File %x has an invalid date!
+Filen %x har ett ogiltigt datum!
+File already exists. Overwrite?
+Filen finns redan. Vill du skriva över:
+File content
+Filinnehåll
+File does not exist:
+Filen finns inte:
+File list exported!
+Fillista exporterad!
+File size and date
+Filstorlek och datum
+Filename
+Filnamn
+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.
+Filerna %x har en tidsstämpling som skiljer mindre än en timme!\n\nDet är inte helt säkert att avgöra vilken som är nyast, p.g.a sommartids-problem.
+Files %x have the same date but a different size!
+Filerna %x har samma datum men olika storlek!
+Files are found equal if\n - file content\nis the same.
+Filerna betecknas som lika om, \n - filinnehållet\när lika.
+Files are found equal if\n - filesize\n - last write time and date\nare the same.
+Filerna betecknas som lika om, \n - filstorlek\n - 'senast använd' och datum\när lika.
+Files remaining:
+Filer kvar:
+Files that are equal on both sides
+Filer som är lika på båda sidor
+Files that exist on both sides and have different content
+Filer som finns på båda sidor och har olika innehåll
+Files that exist on both sides, left one is newer
+Filer som finns på båda sidor, vänster är nyare
+Files that exist on both sides, right one is newer
+Filer som finns på båda sidor, höger är nyare
+Files/folders found:
+Funna filer/kataloger:
+Files/folders remaining:
+Filer/kataloger kvar:
+Files/folders that exist on left side only
+Filer/kataloger som finns på vänster sida enbart
+Files/folders that exist on right side only
+Filer/kataloger som finns på höger sida enbart
+Filter
+Filter
+Filter files
+Undantag
+Filter has been selected
+Filter aktiverat
+Filter settings have changed!
+Filterinställningar har ändrats!
+Filter view
+Filtervy
+Filtering is deactivated
+Filter inaktiverat
+Folder Comparison and Synchronization
+Katalogjämförelse och synkronisering
+Free disk space available:
+Ledigt diskutrymme:
+FreeFileSync - Folder Comparison and Synchronization
+FreeFileSync - Jämför och Synkronisera
+FreeFileSync Batch Job
+FreeFileSync Batch-jobb
+FreeFileSync at Sourceforge
+FreeFileSync på Sourceforge
+FreeFileSync batch file
+FreeFileSync batch-fil
+FreeFileSync configuration
+FreeFileSync konfiguration
+FreeFileSync is up to date!
+FreeFileSync är uppdaterad!
+Full path
+Fullständig sökväg
+Generating database...
+Skapar databas...
+Generating file list...
+Skapar fillista...
+Global filter
+Allmänt filter
+Global settings
+Allmäna inställningar
+Help
+Hjälp
+Hidden dialogs:
+Dolda meddelanden:
+Hide all error and warning messages
+Visa inte fel- och varningsmeddelanden
+Hide conflicts
+Visa inte konflikter
+Hide excluded items
+Visa inte undantagna objekt
+Hide files that are different
+Visa inte filer som är olika
+Hide files that are equal
+Visa inte filer som är lika
+Hide files that are newer on left
+Visa inte filer som är nyare till vänster
+Hide files that are newer on right
+Visa inte filer som är nyare till höger
+Hide files that exist on left side only
+Visa inte filer som endast finns till vänster
+Hide files that exist on right side only
+Visa inte filer som endast finns till höger
+Hide files that will be created on the left side
+Visa inte filer som kommer att skapas på vänster sida
+Hide files that will be created on the right side
+Visa inte filer som kommer att skapas på höger sida
+Hide files that will be deleted on the left side
+Visa inte filer som kommer att tas bort på vänster sida
+Hide files that will be deleted on the right side
+Visa inte filer som kommer att tas bort på höger sida
+Hide files that will be overwritten on left side
+Visa inte filer som kommer att skrivas över på vänster sida
+Hide files that will be overwritten on right side
+Visa inte filer som kommer att skrivas över på höger sida
+Hide files that won't be copied
+Visa inte filer som som inte kopieras
+Hide filtered or temporarily excluded files
+Visa inte filtrerade eller temporärt undantagna filer
+Hide further error messages during the current process
+Dölj vidare felmeddelanden under aktuell process
+Hints:
+Ledtråd:
+Homepage
+Hemsida
+Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically.
+Identifiera och visa förändringar på båda sidor via databas. Borttagningar och konflikter upptäcks automatiskt.
+If you like FFS
+Om du gillar FFS
+Ignore 1-hour file time difference
+Ignorera sommartid
+Ignore errors
+Ignorera fel
+Ignore subsequent errors
+Ignorera följdfel
+Ignore this error, retry or abort synchronization?
+Ignorera felet, försök igen eller avbryt synkroniseringen?
+Ignore this error, retry or abort?
+Ignorera felet, försök igen eller avbryt?
+Include
+Inkludera
+Include all rows
+Inkludera alla rader
+Include temporarily
+Inkludera tillfälligt
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Inkludera: *.doc;*.zip;*.exe\nUndanta: \\stuff\\temp\\*
+Incompatible synchronization database format:
+Inkompatibelt databasformat:
+Info
+Info
+Information
+Information
+Initial synchronization:
+Initial synkronisering:
+Integrate external applications into context menu. The following macros are available:
+Integrera externa program i högerklicksmeny. Följande variabler finns tillgängliga:
+Leave as unresolved conflict
+Ignorera konflikt
+Left
+Vänster
+Legend
+Förklaring
+Load configuration from file
+Hämta inställningar från fil
+Load configuration history (press DEL to delete items)
+Konfigurationshistoria (Tryck DEL för att ta bort objekt)
+Local filter
+Lokalt filter
+Log-messages:
+Log-meddelanden:
+Logging
+Loggar
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+Skuggkopior av wow64 stöds ej. Använd FreeFileSync x64 istället!
+Mirror ->>
+Spegla ->>
+Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
+Speglad kopia av vänster sida: Höger sida kommer att skrivas över med en exakt kopia av vänster sida.
+Monitoring active...
+Övervakning aktiverad...
+More than 50% of the total number of files will be copied or deleted!
+mer än 50% av totalt filantal kommer att kopieras eller tas bort!
+Move column down
+Flytta ner kollumn
+Move column up
+Flytta upp kollumn
+Move files into a time-stamped subdirectory.
+Flytta filer till en tidsstämplad underkatalog
+Moving %x to Recycle Bin
+Flyttar %x till papperskorgen
+Moving file %x to user-defined directory %y
+Flyttar %x till %y
+Moving folder %x to user-defined directory %y
+Flyttar %x till %y
+Multiple...
+Multipla...
+No change since last synchronization!
+Inga ändringar sedan senaste synkronisering!
+No filter selected
+Inga filter aktiverade
+Not enough free disk space available in:
+Ej tillräckligt ledigt diskutrymme på:
+Nothing to synchronize according to configuration!
+Inget att synkronisera enligt aktuella inställningar!
+Number of files and directories that will be created
+Antal filer och kataloger som kommer att skapas
+Number of files and directories that will be deleted
+Antal filer och kataloger som kommer att tas bort
+Number of files that will be overwritten
+Antal filer som kommer att skrivas över
+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.
+Endast filer/kataloger som kvarstår efter filtrering, kommer att markeras för synkronisering.
+Open directly
+Öppna fil
+Open with Explorer
+Öppna katalog
+Open with Konqueror
+Öppna med Konqueror
+Operation aborted!
+Processen avbruten!
+Operation:
+Arbetsuppgift:
+Overview
+Översikt
+Pause
+Paus
+Paused
+Pausad
+Please run a Compare first before synchronizing!
+Du måste trycka \"Jämför\" innan du kan synkronisera.
+Processing folder pair:
+Processar katalogpar:
+Published under the GNU General Public License:
+Publiserad under GNU General Public License:
+Question
+Fråga
+Quit
+Avsluta
+Re-enable all hidden dialogs?
+Ã…teraktivera alla dolda meddelanden?
+RealtimeSync - Automated Synchronization
+RealtimeSync - Automatiserad synkronisering
+RealtimeSync configuration
+RealtimeSync konfiguration
+Relative path
+Sökväg
+Remove alternate settings
+Ta bort alternativa inställningar
+Remove folder
+Ta bort katalog
+Remove folder pair
+Ta bort katalogpar
+Remove local filter settings
+Ta bort lokala filterinställningar
+Renaming file %x to %y
+Byter namn på %x till %y
+Report translation error
+Rapportera översättningsfel
+Reset
+Återställ
+Right
+Höger
+Run minimized and write status information to a logfile
+Kör minimerad och skriv statusinformation till loggfil
+S&ave configuration
+S&para inställningar
+S&witch view
+B&yt sida
+Save changes to current configuration?
+Vill du spara ändringarna i aktuella inställningar?
+Save current configuration to file
+Spara aktuella inställningar till fil
+Scanning...
+Skannar...
+Scanning:
+Skannar:
+Select a folder
+Markera en katalog
+Select alternate synchronization settings
+Välj alternativa synkroniseringsinställningar
+Select logfile directory:
+Välj loggfilsdestination:
+Select variant:
+Välj variant:
+Setting default synchronization directions. Please check whether they are appropriate for you.
+Kontrollera om standard synkroniseringskataloger passar dina önskemål.
+Show conflicts
+Visa konflikter
+Show file icons
+Visa filikoner
+Show files that are different
+Visa filer som är olika
+Show files that are equal
+Visa filer som är lika
+Show files that are newer on left
+Visa filer som är nyare till vänster
+Show files that are newer on right
+Visa filer som är nyare till höger
+Show files that exist on left side only
+Visa filer som endast finns till vänster
+Show files that exist on right side only
+Visa filer som endast finns till höger
+Show files that will be created on the left side
+Visa filer som kommer att skapas till vänster
+Show files that will be created on the right side
+Visa filer som kommer att skapas till höger
+Show files that will be deleted on the left side
+Visa filer som kommer att tas bort till vänster
+Show files that will be deleted on the right side
+Visa filer som kommer att tas bort till höger
+Show files that will be overwritten on left side
+Visa filer som skrivas över till vänster
+Show files that will be overwritten on right side
+Visa filer som skrivas över till höger
+Show files that won't be copied
+Visa filer som inte kommer att kopieras
+Show hidden dialogs
+Visa dolda meddelanden
+Show popup
+Visa popups
+Show popup on errors or warnings
+Visa popup vid fel eller varningar
+Significant difference detected:
+Betydande skillnad upptäckt:
+Silent mode
+Tyst läge
+Size
+Storlek
+Source code written completely in C++ utilizing:
+Source code written completely in C++ utilizing:
+Source directory does not exist anymore:
+Källkatalogen finns inte längre:
+Speed:
+Hastighet:
+Start
+Start
+Start synchronization
+Starta synkronisering
+Statistics
+Statistik
+Stop
+Stopp
+Swap sides
+Byt sida
+Synchronization Preview
+Förhandsvisning
+Synchronization aborted!
+Synkronisering avbruten!
+Synchronization completed successfully!
+Synkronisering slutförd!
+Synchronization completed with errors!
+Synkronisering slutförd med fel!
+Synchronization settings
+Synkroniseringsinställningar
+Synchronization status
+Synkroniseringsstatus
+Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
+Synkronisera alla filer, .doc, .zip och .exe men inga undermappar \"temp\".
+Synchronize both sides simultaneously: Copy new or updated files in both directions.
+Synkronisera båda sidor simultant: Kopiera nya eller uppdaterade filer i bägge riktningar.
+Synchronize both sides using a database. Deletions are detected automatically.
+Synkronisera båda sidor med hjälp av databas. Borttagningar upptäcks automatiskt.
+Synchronize...
+Synkronisera
+Synchronizing...
+Synkroniserar...
+System out of memory!
+Systemminnet är fullt!
+Target directory already existing!
+MÃ¥lkatalogen finns redan!
+Target file already existing!
+Filen finns redan!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+Kommandot kommer att exekveras varje gång:\n- Innehållet i dessa kataloger (eller underkataloger) ändras\n- Enheten med aktuell enhetsbokstav ansluts (USB-anslutning)
+The database file is not yet existing, but will be created during synchronization:
+Databasfilen finns inte ännu, men kommer att skapas under synkroniseringen.
+The file does not contain a valid configuration:
+Filen är ingen giltig konfigureringsfil:
+The required database entry is not yet existing, but will be created during synchronization:
+Databasobjektet finns inte ännu, men kommer att skapas under synkroniseringen:
+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.
+Denna variant betecknar 2 filer med samma namn som lika, när dom har samma storlek OCH samma tidsstämpling.
+Time
+Tid
+Time elapsed:
+Förfluten tid:
+Time remaining:
+Kvarvarande tid:
+Total amount of data that will be transferred
+Total mängd data som kommer att överföras
+Total required free disk space:
+Ledigt diskutrymme som krävs:
+Total time:
+Total tid:
+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.
+Betrakta tidsstämplar som skiljer exakt +/- 1 timme som lika, och mindre än 1 timme som konflikt, för att hantera sommartid.
+Two way <->
+Bägge riktningar <->
+Unable to connect to sourceforge.net!
+Kan inte ansluta sourceforge.net!
+Unable to create logfile!
+Kan inte skapa loggfil!
+Unable to initialize Recycle Bin!
+Kan inte initiera papperskorgen!
+Unresolved conflicts existing!
+Obehandlad konflikt upptäckt!
+Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization.
+Obehandlad konflikt upptäckt! \n\nDu kan ignorera konflikter och fortsätta synkroniseringen.
+Update ->
+Uppdatera ->
+Usage:
+Användning:
+Use Recycle Bin
+Använd papperskorgen
+Use Recycle Bin when deleting or overwriting files.
+Use Volume Shadow Copy Service to copy locked or shared files.
+User-defined directory
+Användardefinierad katalog
+User-defined directory for deletion was not specified!
+Katalog för borttagning ej specifiserad!
+Variant
+Variant
+Verifying file %x
+Verifierar %x
+Volume name %x not part of filename %y!
+Volymnamn %x saknas i filnamn %y!
+Warning
+Varning
+Warning: Synchronization failed for %x item(s):
+Varning: Synkronisering misslyckades för %x objekt:
+When the comparison is started with this option set the following decision tree is processed:
+När jämförelse startas med detta alternativ aktiverat, processas följande beslutsträd:
+You can ignore conflicts and continue synchronization.
+Du kan ignorera konflikter och fortsätta synkroniseringen.
+You can ignore the error to consider not existing directories as empty.
+Du kan ignorera felet att inte betrakta befintliga kataloger som tomma.
+You can ignore the error to skip current folder pair.
+Du kan ignorera felet att hoppa över aktuellt katalogpar.
+You may try to synchronize remaining items again (WITHOUT having to re-compare)!
+Du kan försöka synkronisera återstående objekt igen (utan att trycka \"Jämför\")!
+different
+olika
+file exists on both sides
+Filen finns på båda sidor
+on one side only
+endast på en sida
diff --git a/BUILD/Languages/turkish.lng b/BUILD/Languages/turkish.lng
index 8b548066..3bc006f1 100644
--- a/BUILD/Languages/turkish.lng
+++ b/BUILD/Languages/turkish.lng
@@ -46,6 +46,8 @@ Va&zgeç
&Ä°ptal
&Check for new version
&Yeni sürüm kontrolü yap
+&Content
+
&Create batch job
&Komut (batch) görevi oluştur
&Default
@@ -88,6 +90,8 @@ Ge&ri yükle
&Evet
(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)
(Not: Sadece FAT/FAT32 olarak biçimlendirilmiş sürücüler bu problemden etkilenir!\nDiğer durumlarda, \"1-saat'lik zaman farkını yoksay\" ayarı devre dışı bırakılabilir.)
+(Requires an Internet connection!)
+
,
,
- Other side's counterpart to %dir
@@ -132,12 +136,18 @@ Ge&ri yükle
1. &Karşılaştır
1. Enter relative file or directory names separated by ';' or a new line.
1. ';' ile ayırarak veya herbiri yeni satırda olacak şekilde göreceli (relatif) dosya veya dizin adlarını girin.
+1. Select directories to monitor.
+
2. &Synchronize...
2. &Senkronize et...
+2. Enter a command line.
+
2. Use wildcard characters '*' and '?'.
2. Joker karakter olan '*' ve '?' kullan.
3. Exclude files directly on main grid via context menu.
3. Sağ fare tuşu ile açılan menüden ana listedeki dosyaları direk olarak hariç tutun.
+3. Press 'Start'.
+
<Automatic>
<Otomatik>
<Directory>
@@ -172,6 +182,8 @@ As the name suggests, two files which share the same name are marked as equal if
İsmindende anlaşılacağı gibi, aynı isme sahip iki dosya sadece ve sadece aynı içeriğe sahipse eşit olarak işaretlenir. Bu seçenek yedekleme işlemlerinden daha ziyade uyuşma kontrolü için faydalıdır. Bu yüzden dosya tarihleri hiç bir zaman dikkate alınmaz.\n\nBu seçenek etkinleştirildiğinde karar şeması küçülür:
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.
Otomatik senkronizasyon için bir komut (batch) dosyası oluşturun. Komut modunda başlamak için, komut dosyasını parametre olarak tanımlayarak FreeFileSync'i çalıştırın: FreeFileSync.exe <Komut Dosyası Adı>. Bu komut dosyası, istenirse, işletim sistemindeki görev zamanlayıcı ile istenilen zamanlarda çalıştırılabilir.
+At least one directory input field is empty.
+
Auto-adjust columns
Kolonları otomatik olarak hizala
Automatic mode
@@ -192,20 +204,18 @@ Build:
Derleme:
Cancel
Ä°ptal
-Cannot determine sync-direction: Changed filter settings!
-Senkronizasyon yönü belirlenemiyor: Filtre ayarlarý deðiþmiþ!
-Cannot determine sync-direction: No change since last synchronization!
-Senkronizasyon yönü belirlenemiyor: En son senkronizasyondan beri deðiþiklik yok!
+Cannot determine sync-direction:
+
Category
Kategori
Change direction
Yönü değiştir
Comma separated list
Virgül ile ayrılmış liste
-Commandline
+Command line
Komut satırı
-Commandline is empty!
-Komut satırı boş!
+Command line is empty!
+
Compare
Karşılaştır
Compare both sides
@@ -260,8 +270,12 @@ Copy from right to left
SaÄŸdan sola kopyala
Copy from right to left overwriting
Sağdan sola üzerine yazmaya izin vererek kopyala
+Copy locked files
+
Copy new or updated files to right folder.
Yeni veya güncellenmiş dosyaları sağdaki klasöre kopyala.
+Copy shared or locked files using Volume Shadow Copy Service.
+
Copy to clipboard\tCTRL+C
Hafızaya kopyala\tCTRL+C
Copying file %x to %y
@@ -272,6 +286,8 @@ Could not determine volume name for file:
Belirtilen dosya için birim adı belirlenemedi:
Could not initialize directory monitoring:
Dizin izlemesi başlatılamadı:
+Could not load a required DLL:
+
Could not read values for the following XML nodes:
Takibeden XML başlığındaki değerler okunamadı:
Create a batch job
@@ -298,7 +314,7 @@ Date
Tarih
Delay
Gecikme
-Delay between detection of changes and execution of commandline in seconds
+Delay between detection of changes and execution of command line in seconds
Saniye olarak, değişikliklerin tespiti ile komut satırının çalıştırılması arasındaki boşluk süresi
Delete files/folders existing on left side only
Sadece sol tarafta olan dosyaları/klasörleri sil
@@ -386,6 +402,8 @@ Error reading file:
Dosyayı okurken hata:
Error reading from synchronization database:
Senkronizasyon veri tabanýndan okuma hatasý:
+Error resolving full path name:
+
Error resolving symbolic link:
Sembolik bağlantıyı çözümlerken hata:
Error starting Volume Shadow Copy Service!
@@ -466,6 +484,8 @@ Filter files
Fltre dosyaları
Filter has been selected
+Filter settings have changed!
+
Filter view
Filtre görünümü
Filtering is deactivated
@@ -560,8 +580,8 @@ Include all rows
Include temporarily
Geçici olarak dahil et
-Include: *.doc;*.zip;*.exe\nExclude: temp\\*
-Dahil et: *.doc;*.zip;*.exe\nHariç tut: temp\\*
+Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
+Dahil et: *.doc;*.zip;*.exe\nHariç tut: \\stuff\\temp\\*
Incompatible synchronization database format:
Uyumsuz senkronizasyon veritabaný formatý:
Info
@@ -572,8 +592,6 @@ 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. :)
-Geri dönüşüm kutusunu başlatmak mümkün olmadı!\n\nMuhtemelen Microsoft Windows kullanmıyorsunuz.\nEğer bu özelliğin eklenmesini istiyorsanız, lütfen program yazarı ile temasa geçin. :)
Leave as unresolved conflict
Çözülmemiş tutarsızlık olarak bırak
Left
@@ -590,18 +608,22 @@ Log-messages:
Kayıt mesajları:
Logging
Kayıt tutma
+Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
+
Mirror ->>
Yedekleme ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
Sol klasörün yedeklemesi: Senkronizasyondan sonra sol klasör ile tam olarak eşleşen sağ klasörün üzerine yazılacak.
+Monitoring active...
+
More than 50% of the total number of files will be copied or deleted!
%50’den fazla dosya kopyalanacak veya silinecek!
Move column down
Kolonu aşağı taşı
Move column up
Kolonu yukarı taşı
-Move files to a user-defined directory.
-Dosyaları kullanıcı tanımlı bir dizine taşı.
+Move files into a time-stamped subdirectory.
+
Moving %x to Recycle Bin
%x geri dönüşüm kutusuna taşınıyor
Moving file %x to user-defined directory %y
@@ -610,6 +632,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 change since last synchronization!
+
No filter selected
Not enough free disk space available in:
@@ -642,12 +666,10 @@ Pause
Duraklat
Paused
Duraklatıldı
-Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.
-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.
Please run a Compare first before synchronizing!
+Processing folder pair:
+
Published under the GNU General Public License:
“GNU General Public Licenseâ€a uygun olarak yayımlanmıştır:
Question
@@ -670,6 +692,8 @@ Remove folder pair
Klasör çiftini kaldır
Remove local filter settings
+Renaming file %x to %y
+
Report translation error
Çeviri hatasını bildir
Reset
@@ -786,6 +810,8 @@ Target directory already existing!
Hedef dizin zaten mevcut!
Target file already existing!
Hedef dosya zaten mevcut!
+The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)
+
The database file is not yet existing, but will be created during synchronization:
The file does not contain a valid configuration:
@@ -816,12 +842,14 @@ Unable to create logfile!
Kayıt dosyası yaratılamıyor!
Unable to initialize Recycle Bin!
Geri dönüşüm kutusu başlatılamıyor!
+Unresolved conflicts existing!
+
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 ->
Güncelle ->
-Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed.
-Kullanım: İzleme için dizinleri seç ve bir komut satırı ver. Bu dizinlerdeki (veya alt dizinlerdeki) dosyalar değişikliğe her uğradığında, girilen komut satırı çalıştırılacaktır.
+Usage:
+
Use Recycle Bin
Geri dönüşüm kutusunu kullan
Use Recycle Bin when deleting or overwriting files.
@@ -842,6 +870,8 @@ Warning: Synchronization failed for %x item(s):
Uyarı: %x kadar öğe için senkronizasyon başarısız oldu:
When the comparison is started with this option set the following decision tree is processed:
Bu opsiyonla karşılaştırma başlatıldığı zaman, takibeden karar şemasının işleme konacağını tanımla:
+You can ignore conflicts and continue synchronization.
+
You can ignore the error to consider not existing directories as empty.
Var olamayan dizinleri boş olarak tanımlama hatasını yoksay.
You can ignore the error to skip current folder pair.
diff --git a/BUILD/Resources.dat b/BUILD/Resources.dat
index 481a9f0f..ff81f194 100644
--- a/BUILD/Resources.dat
+++ b/BUILD/Resources.dat
Binary files differ
diff --git a/BUILD/Sync_Complete.wav b/BUILD/Sync_Complete.wav
index a6a9cc84..f166cc4b 100644
--- a/BUILD/Sync_Complete.wav
+++ b/BUILD/Sync_Complete.wav
Binary files differ
diff --git a/BUILD/mingwm10.dll b/BUILD/mingwm10.dll
deleted file mode 100644
index 9e609264..00000000
--- a/BUILD/mingwm10.dll
+++ /dev/null
Binary files differ
diff --git a/FreeFileSync.cbp b/FreeFileSync.cbp
index cad9426e..fc06b084 100644
--- a/FreeFileSync.cbp
+++ b/FreeFileSync.cbp
@@ -147,6 +147,7 @@
<Unit filename="library\customGrid.h">
<Option target="&lt;{~None~}&gt;" />
</Unit>
+ <Unit filename="library\detectRenaming.h" />
<Unit filename="library\errorLogging.cpp">
<Option target="Debug" />
<Option target="Release" />
@@ -230,6 +231,7 @@
<Option target="Debug" />
<Option target="Release" />
</Unit>
+ <Unit filename="shared\Recycler.h" />
<Unit filename="shared\appMain.cpp">
<Option target="Debug" />
<Option target="Release" />
@@ -238,6 +240,7 @@
<Option target="Debug" />
<Option target="Release" />
</Unit>
+ <Unit filename="shared\buildInfo.h" />
<Unit filename="shared\customButton.cpp">
<Option target="Debug" />
<Option target="Release" />
@@ -269,6 +272,8 @@
<Unit filename="shared\fileError.h" />
<Unit filename="shared\fileHandling.cpp" />
<Unit filename="shared\fileHandling.h" />
+ <Unit filename="shared\fileID.cpp" />
+ <Unit filename="shared\fileID.h" />
<Unit filename="shared\fileTraverser.cpp" />
<Unit filename="shared\fileTraverser.h" />
<Unit filename="shared\globalFunctions.cpp" />
@@ -277,6 +282,10 @@
<Unit filename="shared\guid.h" />
<Unit filename="shared\localization.cpp" />
<Unit filename="shared\localization.h" />
+ <Unit filename="shared\longPathPrefix.cpp" />
+ <Unit filename="shared\longPathPrefix.h" />
+ <Unit filename="shared\recycler.cpp" />
+ <Unit filename="shared\recycler.h" />
<Unit filename="shared\serialize.cpp" />
<Unit filename="shared\serialize.h" />
<Unit filename="shared\shadow.cpp" />
diff --git a/FreeFileSync.vcproj b/FreeFileSync.vcproj
index 6bf06d87..9af3ce87 100644
--- a/FreeFileSync.vcproj
+++ b/FreeFileSync.vcproj
@@ -70,7 +70,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28ud_adv.lib &#x0A;wxmsw28ud_core.lib &#x0A;wxbase28ud.lib &#x0A;wxpngd.lib&#x0A; wxzlibd.lib &#x0A;wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib winmm.lib"
- OutputFile="BUILD\$(ProjectName).exe"
+ OutputFile="BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets\lib\vc_lib"
GenerateManifest="true"
@@ -130,7 +130,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="&quot;D:\Programme\C++\wxWidgets-x64\include&quot;;&quot;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud&quot;;.\shared\boost_1_x"
+ AdditionalIncludeDirectories="&quot;C:\Programme\C++\wxWidgets-x64\include&quot;;&quot;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud&quot;;.\shared\boost_1_x"
PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -147,7 +147,7 @@
<Tool
Name="VCResourceCompilerTool"
Culture="0"
- AdditionalIncludeDirectories="D:\Programme\C++\wxWidgets-x64\include;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud"
+ AdditionalIncludeDirectories="C:\Programme\C++\wxWidgets-x64\include;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud"
/>
<Tool
Name="VCPreLinkEventTool"
@@ -155,9 +155,9 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28ud_adv.lib &#x0A;wxmsw28ud_core.lib &#x0A;wxbase28ud.lib &#x0A;wxpngd.lib&#x0A; wxzlibd.lib &#x0A;wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib winmm.lib"
- OutputFile="BUILD\$(ProjectName).exe"
+ OutputFile="BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="2"
- AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib"
+ AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets-x64\lib\vc_lib"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="2"
@@ -239,7 +239,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28u_adv.lib &#x0A;wxmsw28u_core.lib &#x0A;wxbase28u.lib &#x0A;wxpng.lib &#x0A;wxzlib.lib &#x0A;wxbase28u_net.lib comctl32.lib ws2_32.lib winmm.lib"
- OutputFile="BUILD\$(ProjectName).exe"
+ OutputFile="BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets\lib\vc_lib"
GenerateDebugInformation="false"
@@ -300,12 +300,13 @@
Optimization="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
- AdditionalIncludeDirectories="&quot;D:\Programme\C++\wxWidgets-x64\include&quot;;&quot;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;;.\shared\boost_1_x"
+ AdditionalIncludeDirectories="&quot;C:\Programme\C++\wxWidgets-x64\include&quot;;&quot;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;;.\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"
+ SuppressStartupBanner="false"
DebugInformationFormat="3"
DisableSpecificWarnings="4804;4100"
/>
@@ -315,7 +316,7 @@
<Tool
Name="VCResourceCompilerTool"
Culture="1033"
- AdditionalIncludeDirectories="&quot;D:\Programme\C++\wxWidgets-x64\include&quot;;&quot;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;"
+ AdditionalIncludeDirectories="&quot;C:\Programme\C++\wxWidgets-x64\include&quot;;&quot;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;"
/>
<Tool
Name="VCPreLinkEventTool"
@@ -323,9 +324,9 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28u_adv.lib &#x0A;wxmsw28u_core.lib &#x0A;wxbase28u.lib &#x0A;wxpng.lib &#x0A;wxzlib.lib &#x0A;wxbase28u_net.lib comctl32.lib ws2_32.lib winmm.lib"
- OutputFile="BUILD\$(ProjectName).exe"
+ OutputFile="BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="1"
- AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib"
+ AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets-x64\lib\vc_lib"
GenerateDebugInformation="false"
SubSystem="2"
OptimizeReferences="2"
@@ -425,6 +426,10 @@
>
</File>
<File
+ RelativePath=".\shared\fileID.cpp"
+ >
+ </File>
+ <File
RelativePath=".\shared\fileTraverser.cpp"
>
</File>
@@ -461,6 +466,10 @@
>
</File>
<File
+ RelativePath=".\shared\longPathPrefix.cpp"
+ >
+ </File>
+ <File
RelativePath=".\ui\mainDialog.cpp"
>
</File>
@@ -469,6 +478,10 @@
>
</File>
<File
+ RelativePath=".\shared\recycler.cpp"
+ >
+ </File>
+ <File
RelativePath=".\library\resources.cpp"
>
</File>
diff --git a/Makefile b/Makefile
index 9fbfeef6..71c01a52 100644
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@ FILE_LIST+=shared/customButton.cpp
FILE_LIST+=shared/toggleButton.cpp
FILE_LIST+=shared/customComboBox.cpp
FILE_LIST+=shared/serialize.cpp
+FILE_LIST+=shared/fileID.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 d15a5ab2..76eccb5e 100644
--- a/RealtimeSync/RealtimeSync.cbp
+++ b/RealtimeSync/RealtimeSync.cbp
@@ -128,11 +128,15 @@
<Unit filename="..\shared\fileError.h" />
<Unit filename="..\shared\fileHandling.cpp" />
<Unit filename="..\shared\fileHandling.h" />
+ <Unit filename="..\shared\fileID.cpp" />
<Unit filename="..\shared\fileTraverser.cpp" />
<Unit filename="..\shared\globalFunctions.cpp" />
<Unit filename="..\shared\globalFunctions.h" />
<Unit filename="..\shared\localization.cpp" />
<Unit filename="..\shared\localization.h" />
+ <Unit filename="..\shared\longPathPrefix.cpp" />
+ <Unit filename="..\shared\longPathPrefix.h" />
+ <Unit filename="..\shared\recycler.cpp" />
<Unit filename="..\shared\shadow.cpp" />
<Unit filename="..\shared\standardPaths.cpp" />
<Unit filename="..\shared\standardPaths.h" />
diff --git a/RealtimeSync/RealtimeSync.vcproj b/RealtimeSync/RealtimeSync.vcproj
index f3501a17..ddf293ea 100644
--- a/RealtimeSync/RealtimeSync.vcproj
+++ b/RealtimeSync/RealtimeSync.vcproj
@@ -69,7 +69,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28ud_adv.lib &#x0A;wxmsw28ud_core.lib &#x0A;wxbase28ud.lib &#x0A;wxpngd.lib&#x0A; wxzlibd.lib &#x0A;wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib"
- OutputFile="..\BUILD\$(ProjectName).exe"
+ OutputFile="..\BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets\lib\vc_lib"
GenerateManifest="true"
@@ -129,7 +129,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="&quot;D:\Programme\C++\wxWidgets-x64\include&quot;;&quot;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud&quot;;..\shared\boost_1_x"
+ AdditionalIncludeDirectories="&quot;C:\Programme\C++\wxWidgets-x64\include&quot;;&quot;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud&quot;;..\shared\boost_1_x"
PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -145,7 +145,7 @@
<Tool
Name="VCResourceCompilerTool"
Culture="0"
- AdditionalIncludeDirectories="D:\Programme\C++\wxWidgets-x64\include;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud"
+ AdditionalIncludeDirectories="C:\Programme\C++\wxWidgets-x64\include;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud"
/>
<Tool
Name="VCPreLinkEventTool"
@@ -153,9 +153,9 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28ud_adv.lib &#x0A;wxmsw28ud_core.lib &#x0A;wxbase28ud.lib &#x0A;wxpngd.lib&#x0A; wxzlibd.lib &#x0A;wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib"
- OutputFile="..\BUILD\$(ProjectName).exe"
+ OutputFile="..\BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="2"
- AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib"
+ AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets-x64\lib\vc_lib"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="2"
@@ -237,7 +237,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28u_adv.lib &#x0A;wxmsw28u_core.lib &#x0A;wxbase28u.lib &#x0A;wxpng.lib &#x0A;wxzlib.lib &#x0A;wxbase28u_net.lib comctl32.lib ws2_32.lib"
- OutputFile="..\BUILD\$(ProjectName).exe"
+ OutputFile="..\BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets\lib\vc_lib"
GenerateDebugInformation="false"
@@ -298,12 +298,13 @@
Optimization="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
- AdditionalIncludeDirectories="&quot;D:\Programme\C++\wxWidgets-x64\include&quot;;&quot;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;;..\shared\boost_1_x"
+ AdditionalIncludeDirectories="&quot;C:\Programme\C++\wxWidgets-x64\include&quot;;&quot;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;;..\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"
+ SuppressStartupBanner="false"
DebugInformationFormat="3"
DisableSpecificWarnings="4804"
/>
@@ -313,7 +314,7 @@
<Tool
Name="VCResourceCompilerTool"
Culture="1033"
- AdditionalIncludeDirectories="&quot;D:\Programme\C++\wxWidgets-x64\include&quot;;&quot;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;"
+ AdditionalIncludeDirectories="&quot;C:\Programme\C++\wxWidgets-x64\include&quot;;&quot;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu&quot;"
/>
<Tool
Name="VCPreLinkEventTool"
@@ -321,9 +322,9 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wxmsw28u_adv.lib &#x0A;wxmsw28u_core.lib &#x0A;wxbase28u.lib &#x0A;wxpng.lib &#x0A;wxzlib.lib &#x0A;wxbase28u_net.lib comctl32.lib ws2_32.lib"
- OutputFile="..\BUILD\$(ProjectName).exe"
+ OutputFile="..\BUILD\$(ProjectName)_$(PlatformName).exe"
LinkIncremental="1"
- AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib"
+ AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets-x64\lib\vc_lib"
GenerateDebugInformation="false"
SubSystem="2"
OptimizeReferences="2"
@@ -383,6 +384,10 @@
>
</File>
<File
+ RelativePath="..\shared\fileID.cpp"
+ >
+ </File>
+ <File
RelativePath="..\shared\fileTraverser.cpp"
>
</File>
@@ -403,6 +408,10 @@
>
</File>
<File
+ RelativePath="..\shared\longPathPrefix.cpp"
+ >
+ </File>
+ <File
RelativePath=".\mainDialog.cpp"
>
</File>
@@ -411,6 +420,10 @@
>
</File>
<File
+ RelativePath="..\shared\recycler.cpp"
+ >
+ </File>
+ <File
RelativePath=".\resources.cpp"
>
</File>
diff --git a/RealtimeSync/RealtimeSync.xpm b/RealtimeSync/RealtimeSync.xpm
deleted file mode 100644
index 557ef973..00000000
--- a/RealtimeSync/RealtimeSync.xpm
+++ /dev/null
@@ -1,312 +0,0 @@
-/* XPM */
-static const char* RealtimeSync_xpm[] = {
-"32 32 277 2",
-" c None",
-"! c black",
-"# c #2A0404",
-"$ c #330505",
-"% c #3D0707",
-"& c #360606",
-"' c #340606",
-"( c #500909",
-") c #630B0B",
-"* c #890F0F",
-"+ c #AC1414",
-", c #AB1414",
-"- c #9F1212",
-". c #820F0F",
-"0 c #510909",
-"1 c #2F0505",
-"2 c #530A0A",
-"3 c #8B1010",
-"4 c #E83E3E",
-"5 c #F39494",
-"6 c #F6ADAD",
-"7 c #F49B9B",
-"8 c #F07E7E",
-"9 c #EC5C5C",
-": c #E73636",
-"; c #D71818",
-"< c #AD1414",
-"= c #7C0E0E",
-"> c #410707",
-"? c #E73232",
-"@ c #FACECE",
-"A c #FCDFDF",
-"B c #F7B8B8",
-"C c #F39090",
-"D c #EF6E6E",
-"E c #EA4D4D",
-"F c #E72D2D",
-"G c #E41E1E",
-"H c #E31F1F",
-"I c #E52121",
-"J c #E31C1C",
-"K c #670C0C",
-"L c #380606",
-"M c #420808",
-"N c #6D0C0C",
-"O c #F07777",
-"P c #FEEEEE",
-"Q c #F9C6C6",
-"R c #F49D9D",
-"S c #EC5D5D",
-"T c #E83C3C",
-"U c #E62121",
-"V c #E41A1A",
-"W c #E41D1D",
-"X c #E21E1E",
-"Y c #E41C1C",
-"Z c #E51C1C",
-"[ c #C71717",
-"] c #720C0C",
-"^ c #330606",
-"_ c #640C0C",
-"` c #EF7171",
-"a c #FCE3E3",
-"b c #F6AFAF",
-"c c #F28D8D",
-"d c #E72E2E",
-"e c #E62020",
-"f c #E51A1A",
-"g c #E51F1F",
-"h c #CA1818",
-"i c #680C0C",
-"j c #260404",
-"k c #4F0909",
-"l c #540A0A",
-"m c #520909",
-"n c #E72F2F",
-"o c #FAD3D3",
-"p c #F4A0A0",
-"q c #F17E7E",
-"r c #ED5E5E",
-"s c #E93E3E",
-"t c #E62525",
-"u c #E51B1B",
-"v c #BD1616",
-"w c #941111",
-"x c #810E0E",
-"y c #830F0F",
-"z c #991111",
-"{ c #E21A1A",
-"| c #B41515",
-"} c #420707",
-"~ c #8C1010",
-" ! c #E62323",
-"!! c #C91717",
-"#! c #B21515",
-"$! c #EB5050",
-"%! c #E73030",
-"&! c #DC1919",
-"'! c #250404",
-"(! c #550A0A",
-")! c #7B0E0E",
-"*! c #BC1616",
-"+! c #860F0F",
-",! c #310505",
-"-! c #3F0707",
-".! c #F07676",
-"0! c #EB5656",
-"1! c #E62727",
-"2! c #E62424",
-"3! c #E21D1D",
-"4! c #DE1919",
-"5! c #7A0E0E",
-"6! c #470808",
-"7! c #350606",
-"8! c #5B0A0A",
-"9! c #971111",
-":! c #DF1919",
-";! c #BF1616",
-"<! c #951111",
-"=! c #EA4E4E",
-">! c #E61F1F",
-"?! c #E41B1B",
-"@! c #E31A1A",
-"A! c #D41919",
-"B! c #8D1010",
-"C! c #5D0B0B",
-"D! c #390606",
-"E! c #1F0303",
-"F! c #4E0909",
-"G! c #D61818",
-"H! c #750D0D",
-"I! c #270404",
-"J! c #6A0C0C",
-"K! c #E62222",
-"L! c #C81717",
-"M! c #790D0D",
-"N! c #290404",
-"O! c #460808",
-"P! c #770D0D",
-"Q! c #D81818",
-"R! c #A21212",
-"S! c #E52020",
-"T! c #931111",
-"U! c #7D0E0E",
-"V! c #A61313",
-"W! c #450808",
-"X! c #3A0606",
-"Y! c #570A0A",
-"Z! c #2E0505",
-"[! c #440808",
-"]! c #580A0A",
-"^! c #630C0C",
-"_! c #BA1616",
-"`! c #D51818",
-"a! c #180202",
-"b! c #EC5959",
-"c! c #F39292",
-"d! c #3C0707",
-"e! c #DF1A1A",
-"f! c #6C0C0C",
-"g! c #300505",
-"h! c #D11818",
-"i! c #FFFEFE",
-"j! c white",
-"k! c #FCDDDD",
-"l! c #8A1010",
-"m! c #D41818",
-"n! c #A91313",
-"o! c #730D0D",
-"p! c #1D0303",
-"q! c #4B0909",
-"r! c #AF1414",
-"s! c #F39797",
-"t! c #FFFBFB",
-"u! c #FFFAFA",
-"v! c #FDEBEB",
-"w! c #FCDEDE",
-"x! c #FBD4D4",
-"y! c #FBDADA",
-"z! c #EB4E4E",
-"{! c #880F0F",
-"|! c #200303",
-"}! c #600B0B",
-"~! c #F9CBCB",
-" # c #FBD7D7",
-"!# c #F8BEBE",
-"## c #F5A5A5",
-"$# c #F49C9C",
-"%# c #F39191",
-"&# c #F28989",
-"'# c #F07B7B",
-"(# c #A71313",
-")# c #700D0D",
-"*# c #140202",
-"+# c #E73333",
-",# c #F5A8A8",
-"-# c #F39393",
-".# c #F18282",
-"0# c #F07878",
-"1# c #EE6C6C",
-"2# c #ED6262",
-"3# c #EC5757",
-"4# c #E94242",
-"5# c #E94141",
-"6# c #DA1919",
-"7# c #F38E8E",
-"8# c #690C0C",
-"9# c #760D0D",
-":# c #EC5A5A",
-";# c #EA4949",
-"<# c #E93F3F",
-"=# c #E62626",
-"># c #DD1919",
-"?# c #6F0C0C",
-"@# c #2C0505",
-"A# c #FEEBEB",
-"B# c #F07D7D",
-"C# c #6B0C0C",
-"D# c #911010",
-"E# c #D21818",
-"F# c #E31B1B",
-"G# c #E11D1D",
-"H# c #400707",
-"I# c #EE6666",
-"J# c #7F0E0E",
-"K# c #5C0B0B",
-"L# c #E62828",
-"M# c #B11414",
-"N# c #F39A9A",
-"O# c #ED6565",
-"P# c #A31313",
-"Q# c #370606",
-"R# c #840F0F",
-"S# c #E21B1B",
-"T# c #E31D1D",
-"U# c #B61515",
-"V# c #ED6161",
-"W# c #EB5555",
-"X# c #490808",
-"Y# c #3B0707",
-"Z# c #650C0C",
-"[# c #9E1212",
-"]# c #E41F1F",
-"^# c #E51D1D",
-"_# c #800E0E",
-"`# c #921111",
-"a# c #4A0808",
-"b# c #320505",
-"c# c #E73535",
-"d# c #E72A2A",
-"e# c #E72B2B",
-"f# c #E42020",
-"g# c #B11515",
-"h# c #E51E1E",
-"i# c #E31E1E",
-"j# c #530909",
-"k# c #E42121",
-"l# c #610B0B",
-"m# c #4D0909",
-"n# c #DB1A1A",
-"o# c #AA1414",
-"p# c #620B0B",
-"q# c #720D0D",
-"r# c #B31515",
-"s# c #E11919",
-"t# c #C61717",
-"u# c #5A0A0A",
-"v# c #BB1616",
-"w# c #CC1818",
-"x# c #C11717",
-"y# c #850F0F",
-"z# c #1E0303",
-"{# c #2B0505",
-"|# c #560A0A",
-"}# c #5F0B0B",
-"~# c #210303",
-" $ c #170202",
-" ",
-" # $ % & # ",
-" ' ( ) * + , - . ) 0 $ ",
-" 1 2 3 4 5 6 7 8 9 : ; < = 2 # ",
-" > ) ? @ A B C D E F G H I J < K L ",
-" M N O P Q R 8 S T U V W X Y Z I [ ] & ",
-" ^ _ ` a b c D E d e G f Y g e W Y f h i j ",
-" k l l m 2 n o p q r s t u v w x y z v { f f f | 2 ",
-"} ~ d !!!#!q C ` $!%!g &!~ 0 1 '!j L (!)!*!f f f +!,! ",
-"-!*!.!0!4 1!Y 2!d 2!3!4!5!6! 7!8!9!:!f ;!2 ",
-"% <!=!: >!?!V @!{ V W A!B!C!D! E!F!x G!f H!E! ",
-"I!J!e K!?!f ?!u ?!J f f f L!M!N! O!P!Q!R!1 ",
-" l < S!f ?!u ?!J f f f f f T!# } U!V!W! ",
-" X!= V Z u ?!J f f f f f + Y! Z![!]!^!]! ",
-" 8!_!I ?!J f f f f `!T!0 a! ,!Y!#!b!c!;!l ",
-" d!P!e!Z f f f 4!+ f!X! g!]!h!R i!j!j!k!l!& ",
-" 2 +!{ f m!n!o!W!p! q!r!s!t!u!v!w!x!y!z!Y! ",
-" O!]!x {!_ > |! }!F ~! #!#b ##$#%#&#'#~ X! ",
-" & (#)#6!*# 8!+#,#-#.#0#1#2#3#=!4#5#;!(! ",
-" '!6#7#8#Z! 9#S :#;#<#: F =#I Z 3!Y >#?#@# ",
-" U!A#B#C#X! m D#E#X F#G#V G#F#J Y 3!Y T!H# ",
-" ( 2#y!I#J#O! W!K#v L#Y J f f f f f f M#0 ",
-" ,!r!$#N#O#P#]!Q# W!R#S#U T#?!T#X ?!V f f U#Y! ",
-" 8!? 1#V#W#h!y C!X#Y#q!Z#[#S#]#W G ^#G ?!* _#`#w P!a# ",
-" b#J#? c#d#e#f#h g#+ | `!g h#Y Y i#Y f V!j#^ & D!' ",
-" 6!l!J h#J W k#U K!U ]#Y ?!f f f f U#l#g! ",
-" m#{!n#e h#i#J u f f f f f f f o#p#X! ",
-" W!q#r#s#f f f f f f f f t#{!u#b# ",
-" Z!2 P!- v#w#G!h!x#o#y#p#O!z# ",
-" {#> |#}#p#}!8!m#X!~# ",
-" $ $ ",
-" "}; \ No newline at end of file
diff --git a/RealtimeSync/application.cpp b/RealtimeSync/application.cpp
index b974fb89..68cebae0 100644
--- a/RealtimeSync/application.cpp
+++ b/RealtimeSync/application.cpp
@@ -13,6 +13,7 @@
#include "../shared/localization.h"
#include "xmlFreeFileSync.h"
#include "../shared/standardPaths.h"
+#include <wx/file.h>
#ifdef FFS_LINUX
#include <gtk/gtk.h>
@@ -80,3 +81,30 @@ void Application::OnStartApplication(wxIdleEvent& event)
frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon
frame->Show();
}
+
+
+bool Application::OnExceptionInMainLoop()
+{
+ throw; //just re-throw exception and avoid display of additional exception messagebox: it will be caught in OnRun()
+}
+
+
+int Application::OnRun()
+{
+ try
+ {
+ wxApp::OnRun();
+ }
+ catch (const std::exception& e) //catch all STL exceptions
+ {
+ //unfortunately it's not always possible to display a message box in this erroneous situation, however (non-stream) file output always works!
+ wxFile safeOutput(FreeFileSync::getLastErrorTxtFile(), wxFile::write);
+ safeOutput.Write(wxString::FromAscii(e.what()));
+
+ wxMessageBox(wxString::FromAscii(e.what()), _("An exception occured!"), wxOK | wxICON_ERROR);
+ return -9;
+ }
+
+ return 0; //program's return value
+}
+
diff --git a/RealtimeSync/application.h b/RealtimeSync/application.h
index e7116156b..d95cb3b4 100644
--- a/RealtimeSync/application.h
+++ b/RealtimeSync/application.h
@@ -16,11 +16,13 @@ class Application : public wxApp
{
public:
virtual bool OnInit();
+ virtual int OnRun();
+ virtual bool OnExceptionInMainLoop();
private:
void OnStartApplication(wxIdleEvent& event);
- std::auto_ptr<wxHelpController> helpController; //global help controller
+ std::auto_ptr<wxHelpController> helpController; //global help controller
};
#endif // REALTIMESYNCAPP_H
diff --git a/RealtimeSync/functions.h b/RealtimeSync/functions.h
index 3d7d522f..0001a7ec 100644
--- a/RealtimeSync/functions.h
+++ b/RealtimeSync/functions.h
@@ -9,7 +9,7 @@ class wxDirPickerCtrl;
namespace RealtimeSync
{
- void setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker);
+void setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker);
}
#endif // FUNCTIONS_H_INCLUDED
diff --git a/RealtimeSync/guiGenerated.cpp b/RealtimeSync/guiGenerated.cpp
index 7e705927..aa4a8261 100644
--- a/RealtimeSync/guiGenerated.cpp
+++ b/RealtimeSync/guiGenerated.cpp
@@ -13,7 +13,7 @@
MainDlgGenerated::MainDlgGenerated( 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->SetSizeHints( wxSize( 420,440 ), wxDefaultSize );
m_menubar1 = new wxMenuBar( 0 );
m_menuFile = new wxMenu();
@@ -56,9 +56,35 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr
bSizer1->Add( 0, 10, 0, 0, 5 );
- m_staticText2 = new wxStaticText( m_panelMain, wxID_ANY, _("Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed."), wxDefaultPosition, wxDefaultSize, 0|wxDOUBLE_BORDER );
- m_staticText2->Wrap( 350 );
- bSizer1->Add( m_staticText2, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 40 );
+ wxStaticBoxSizer* sbSizer41;
+ sbSizer41 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, wxEmptyString ), wxVERTICAL );
+
+ m_staticText2 = new wxStaticText( m_panelMain, wxID_ANY, _("Usage:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText2->Wrap( -1 );
+ m_staticText2->SetFont( wxFont( 10, 74, 90, 90, true, wxT("Tahoma") ) );
+
+ sbSizer41->Add( m_staticText2, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+
+ m_staticText3 = new wxStaticText( m_panelMain, wxID_ANY, _("1. Select directories to monitor."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText3->Wrap( -1 );
+ sbSizer41->Add( m_staticText3, 0, wxLEFT, 10 );
+
+ m_staticText4 = new wxStaticText( m_panelMain, wxID_ANY, _("2. Enter a command line."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText4->Wrap( -1 );
+ sbSizer41->Add( m_staticText4, 0, wxLEFT, 10 );
+
+ m_staticText5 = new wxStaticText( m_panelMain, wxID_ANY, _("3. Press 'Start'."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText5->Wrap( -1 );
+ sbSizer41->Add( m_staticText5, 0, wxLEFT, 10 );
+
+ m_staticline3 = new wxStaticLine( m_panelMain, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ sbSizer41->Add( m_staticline3, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
+
+ m_staticText21 = new wxStaticText( m_panelMain, wxID_ANY, _("The command line is executed each time:\n- Files within these directories (or subdirectories) are modified\n- The corresponding drive letter becomes available (USB-insert)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText21->Wrap( -1 );
+ sbSizer41->Add( m_staticText21, 0, wxRIGHT|wxLEFT|wxEXPAND, 5 );
+
+ bSizer1->Add( sbSizer41, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxEXPAND, 40 );
m_staticline2 = new wxStaticLine( m_panelMain, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizer1->Add( m_staticline2, 0, wxTOP|wxBOTTOM|wxEXPAND, 10 );
@@ -119,7 +145,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr
bSizer1->Add( bSizer8, 1, wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer3;
- sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Commandline") ), wxVERTICAL );
+ sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Command line") ), wxVERTICAL );
m_textCtrlCommand = new wxTextCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
sbSizer3->Add( m_textCtrlCommand, 0, wxEXPAND|wxBOTTOM, 5 );
@@ -133,7 +159,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr
sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Delay") ), wxVERTICAL );
m_spinCtrlDelay = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 0, 2000000000, 0 );
- m_spinCtrlDelay->SetToolTip( _("Delay between detection of changes and execution of commandline in seconds") );
+ m_spinCtrlDelay->SetToolTip( _("Delay between detection of changes and execution of command line in seconds") );
sbSizer4->Add( m_spinCtrlDelay, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 5 );
diff --git a/RealtimeSync/guiGenerated.h b/RealtimeSync/guiGenerated.h
index 91669af8..7be541d4 100644
--- a/RealtimeSync/guiGenerated.h
+++ b/RealtimeSync/guiGenerated.h
@@ -23,14 +23,14 @@ class wxButtonWithImage;
#include <wx/settings.h>
#include <wx/stattext.h>
#include <wx/statline.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
#include <wx/bmpbuttn.h>
#include <wx/button.h>
-#include <wx/sizer.h>
#include <wx/textctrl.h>
#include <wx/filepicker.h>
#include <wx/panel.h>
#include <wx/scrolwin.h>
-#include <wx/statbox.h>
#include <wx/spinctrl.h>
#include <wx/frame.h>
@@ -52,6 +52,11 @@ class MainDlgGenerated : public wxFrame
wxPanel* m_panelMain;
wxStaticText* m_staticText2;
+ wxStaticText* m_staticText3;
+ wxStaticText* m_staticText4;
+ wxStaticText* m_staticText5;
+ wxStaticLine* m_staticline3;
+ wxStaticText* m_staticText21;
wxStaticLine* m_staticline2;
wxPanel* m_panelMainFolder;
wxBitmapButton* m_bpButtonAddFolder;
diff --git a/RealtimeSync/mainDialog.cpp b/RealtimeSync/mainDialog.cpp
index 8d9c7d7a..81af1ce0 100644
--- a/RealtimeSync/mainDialog.cpp
+++ b/RealtimeSync/mainDialog.cpp
@@ -2,7 +2,6 @@
#include "resources.h"
#include "../shared/customButton.h"
#include "../shared/standardPaths.h"
-//#include "../shared/globalFunctions.h"
#include <wx/msgdlg.h>
#include <wx/wupdlock.h>
#include "watcher.h"
@@ -13,6 +12,8 @@
#include "xmlFreeFileSync.h"
#include "../shared/systemConstants.h"
#include "../shared/stringConv.h"
+#include "../shared/staticAssert.h"
+#include "../shared/buildInfo.h"
using namespace FreeFileSync;
@@ -20,17 +21,17 @@ using namespace FreeFileSync;
MainDialog::MainDialog(wxDialog *dlg,
const wxString& cfgFilename,
wxHelpController& helpController)
- : MainDlgGenerated(dlg),
- helpController_(helpController)
+ : MainDlgGenerated(dlg),
+ helpController_(helpController)
{
wxWindowUpdateLocker dummy(this); //avoid display distortion
m_bpButtonRemoveTopFolder->Hide();
m_panelMainFolder->Layout();
- m_bpButtonAddFolder->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
- m_bpButtonRemoveTopFolder->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
- m_buttonStart->setBitmapFront(*GlobalResources::getInstance().bitmapStart);
+ m_bpButtonAddFolder->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("addFolderPair")));
+ m_bpButtonRemoveTopFolder->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("removeFolderPair")));
+ m_buttonStart->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("startRed")));
m_buttonStart->SetFocus();
//register key event
@@ -126,11 +127,11 @@ const wxString& MainDialog::lastConfigFileName()
void MainDialog::OnShowHelp(wxCommandEvent& event)
{
- #ifdef FFS_WIN
+#ifdef FFS_WIN
helpController_.DisplaySection(wxT("html\\advanced\\RealtimeSync.html"));
- #elif defined FFS_LINUX
+#elif defined FFS_LINUX
helpController_.DisplaySection(wxT("html/advanced/RealtimeSync.html"));
- #endif
+#endif
}
@@ -139,11 +140,18 @@ void MainDialog::OnMenuAbout(wxCommandEvent& event)
//build information
wxString build = wxString(wxT("(")) + _("Build:") + wxT(" ") + __TDATE__;
#if wxUSE_UNICODE
- build += wxT(" - Unicode)");
+ build += wxT(" - Unicode");
#else
- build += wxT(" - ANSI)");
+ build += wxT(" - ANSI");
#endif //wxUSE_UNICODE
+ //compile time info about 32/64-bit build
+ if (Utility::is64BitBuild)
+ build += wxT(" x64)");
+ else
+ build += wxT(" x86)");
+ assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
+
wxMessageDialog* aboutDlg = new wxMessageDialog(this, wxString(wxT("RealtimeSync")) + wxT("\n\n") + build, _("About"), wxOK);
aboutDlg->ShowModal();
}
@@ -356,7 +364,7 @@ void MainDialog::addFolder(const std::vector<wxString>& newFolders, bool addFron
{
//add new folder pair
FolderPanel* newFolder = new FolderPanel(m_scrolledWinFolders);
- newFolder->m_bpButtonRemoveFolder->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
+ newFolder->m_bpButtonRemoveFolder->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("removeFolderPair")));
//get size of scrolled window
folderHeight = newFolder->GetSize().GetHeight();
diff --git a/RealtimeSync/mainDialog.h b/RealtimeSync/mainDialog.h
index 8447d269..8a5e87bf 100644
--- a/RealtimeSync/mainDialog.h
+++ b/RealtimeSync/mainDialog.h
@@ -16,7 +16,7 @@
namespace xmlAccess
{
- struct XmlRealConfig;
+struct XmlRealConfig;
}
@@ -24,8 +24,8 @@ class FolderPanel : public FolderGenerated
{
public:
FolderPanel(wxWindow* parent) :
- FolderGenerated(parent),
- dragDropOnFolder(new FreeFileSync::DragDropOnDlg(this, m_dirPicker, m_txtCtrlDirectory)) {}
+ FolderGenerated(parent),
+ dragDropOnFolder(new FreeFileSync::DragDropOnDlg(this, m_dirPicker, m_txtCtrlDirectory)) {}
private:
//support for drag and drop
diff --git a/RealtimeSync/resources.cpp b/RealtimeSync/resources.cpp
index fe2a5ced..eeb89563 100644
--- a/RealtimeSync/resources.cpp
+++ b/RealtimeSync/resources.cpp
@@ -19,12 +19,7 @@ const GlobalResources& GlobalResources::getInstance()
GlobalResources::GlobalResources()
{
- //map, allocate and initialize pictures
- bitmapResource[wxT("start red.png")] = (bitmapStart = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("add pair.png")] = (bitmapAddFolderPair = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("remove pair.png")] = (bitmapRemoveFolderPair = new wxBitmap(wxNullBitmap));
-
- programIcon = new wxIcon(wxNullIcon);
+ programIcon = new wxIcon(wxNullIcon);
}
@@ -49,7 +44,6 @@ void GlobalResources::load() const
wxZipInputStream resourceFile(input);
- std::map<wxString, wxBitmap*>::iterator bmp;
while (true)
{
std::auto_ptr<wxZipEntry> entry(resourceFile.GetNextEntry());
@@ -58,24 +52,31 @@ void GlobalResources::load() const
const wxString name = entry->GetName();
- //search if entry is available in map
- if ((bmp = bitmapResource.find(name)) != bitmapResource.end())
- *(bmp->second) = wxBitmap(wxImage(resourceFile, wxBITMAP_TYPE_PNG));
+ //generic image loading
+ if (name.EndsWith(wxT(".png")))
+ {
+ if (bitmapResource.find(name) == bitmapResource.end()) //avoid duplicate entry: prevent memory leak!
+ bitmapResource[name] = new wxBitmap(wxImage(resourceFile, wxBITMAP_TYPE_PNG));
+ }
}
}
#ifdef FFS_WIN
+ //for compatibility it seems we need to stick with a "real" icon
*programIcon = wxIcon(wxT("A_PROGRAM_ICON"));
#else
-#include "RealtimeSync.xpm"
- *programIcon = wxIcon(RealtimeSync_xpm);
+ //use big logo bitmap for better quality
+ programIcon->CopyFromBitmap(getImageByName(wxT("RealtimeSync.png")));
#endif
}
const wxBitmap& GlobalResources::getImageByName(const wxString& imageName) const
{
- std::map<wxString, wxBitmap*>::const_iterator bmp = bitmapResource.find(imageName);
+ const std::map<wxString, wxBitmap*>::const_iterator bmp = imageName.Find(wxChar('.')) == wxNOT_FOUND ? //assume .png ending if nothing else specified
+ bitmapResource.find(imageName + wxT(".png")) :
+ bitmapResource.find(imageName);
+
if (bmp != bitmapResource.end())
return *bmp->second;
else
diff --git a/RealtimeSync/resources.h b/RealtimeSync/resources.h
index 3a0cde7b..6a6cd976 100644
--- a/RealtimeSync/resources.h
+++ b/RealtimeSync/resources.h
@@ -14,10 +14,6 @@ public:
const wxBitmap& getImageByName(const wxString& imageName) const;
//image resource objects
- wxBitmap* bitmapStart;
- wxBitmap* bitmapAddFolderPair;
- wxBitmap* bitmapRemoveFolderPair;
-
wxIcon* programIcon;
void load() const; //loads bitmap resources on program startup: logical const!
diff --git a/RealtimeSync/trayMenu.cpp b/RealtimeSync/trayMenu.cpp
index 5d9d2430..01bcda48 100644
--- a/RealtimeSync/trayMenu.cpp
+++ b/RealtimeSync/trayMenu.cpp
@@ -10,6 +10,8 @@
#include <wx/timer.h>
#include <wx/utils.h>
#include <wx/log.h>
+#include "../shared/staticAssert.h"
+#include "../shared/buildInfo.h"
class RtsTrayIcon;
@@ -42,9 +44,9 @@ class RtsTrayIcon : public wxTaskBarIcon
{
public:
RtsTrayIcon(WaitCallbackImpl* callback) :
- m_callback(callback)
+ m_callback(callback)
{
- wxTaskBarIcon::SetIcon(*GlobalResources::getInstance().programIcon, wxT("RealtimeSync"));
+ wxTaskBarIcon::SetIcon(*GlobalResources::getInstance().programIcon, wxString(wxT("RealtimeSync")) + wxT(" - ") + _("Monitoring active..."));
//register double-click
Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(RtsTrayIcon::resumeToMain), NULL, this);
@@ -89,11 +91,18 @@ private:
//build information
wxString build = wxString(wxT("(")) + _("Build:") + wxT(" ") + __TDATE__;
#if wxUSE_UNICODE
- build += wxT(" - Unicode)");
+ build += wxT(" - Unicode");
#else
- build += wxT(" - ANSI)");
+ build += wxT(" - ANSI");
#endif //wxUSE_UNICODE
+ //compile time info about 32/64-bit build
+ if (Utility::is64BitBuild)
+ build += wxT(" x64)");
+ else
+ build += wxT(" x86)");
+ assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
+
wxMessageDialog* aboutDlg = new wxMessageDialog(NULL, wxString(wxT("RealtimeSync")) + wxT("\n\n") + build, _("About"), wxOK);
aboutDlg->ShowModal();
aboutDlg->Destroy();
@@ -145,8 +154,8 @@ private:
WaitCallbackImpl::WaitCallbackImpl() :
- m_abortRequested(false),
- m_resumeRequested(false)
+ m_abortRequested(false),
+ m_resumeRequested(false)
{
trayMenu.reset(new RtsTrayIcon(this));
}
@@ -172,7 +181,7 @@ RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAcces
WaitCallbackImpl callback;
if (config.commandline.empty())
- throw FreeFileSync::FileError(_("Commandline is empty!"));
+ throw FreeFileSync::FileError(_("Command line is empty!"));
long lastExec = 0;
while (true)
diff --git a/RealtimeSync/trayMenu.h b/RealtimeSync/trayMenu.h
index 04b07f8a..99f2f90a 100644
--- a/RealtimeSync/trayMenu.h
+++ b/RealtimeSync/trayMenu.h
@@ -7,13 +7,13 @@
namespace RealtimeSync
{
- enum MonitorResponse
- {
- RESUME,
- QUIT
- };
+enum MonitorResponse
+{
+ RESUME,
+ QUIT
+};
- MonitorResponse startDirectoryMonitor(const xmlAccess::XmlRealConfig& config);
+MonitorResponse startDirectoryMonitor(const xmlAccess::XmlRealConfig& config);
}
diff --git a/RealtimeSync/watcher.cpp b/RealtimeSync/watcher.cpp
index 97471397..67dae521 100644
--- a/RealtimeSync/watcher.cpp
+++ b/RealtimeSync/watcher.cpp
@@ -5,9 +5,15 @@
#include <wx/filefn.h>
#include "../shared/fileHandling.h"
#include "../shared/stringConv.h"
+#include <stdexcept>
+#include <map>
+#include <wx/timer.h>
#ifdef FFS_WIN
+//#include "../shared/fileId.h"
+//#include "Dbt.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "../shared/longPathPrefix.h"
#elif defined FFS_LINUX
#include <wx/timer.h>
@@ -20,6 +26,191 @@ using namespace FreeFileSync;
#ifdef FFS_WIN
+/*
+template <class T> //have a disctinct static variable per class!
+class InstanceCounter //exception safety!!!! use RAII for counter inc/dec!
+{
+public:
+ InstanceCounter()
+ {
+ ++instanceCount;
+ //we're programming on global variables: only one instance of NotifyDeviceArrival allowed at a time!
+ if (instanceCount > 1)
+ throw std::logic_error("Only one instance of NotifyDeviceArrival allowed!");
+ }
+ ~InstanceCounter()
+ {
+ --instanceCount;
+ }
+private:
+ static size_t instanceCount; //this class needs to be a singleton but with variable lifetime! => count instances to check consistency
+};
+template <class T> //we need a disctinct static variable per class!
+size_t InstanceCounter<T>::instanceCount = 0;
+
+
+std::set<Zstring> driveNamesArrived; //letters of newly arrived drive names
+
+
+//convert bitmask into "real" drive-letter
+void notifyDriveFromMask (ULONG unitmask)
+{
+ for (wchar_t i = 0; i < 26; ++i)
+ {
+ if (unitmask & 0x1)
+ {
+ Zstring newDrivePath;
+ newDrivePath += DefaultChar('A') + i;
+ newDrivePath += DefaultStr(":\\");
+ driveNamesArrived.insert(newDrivePath);
+ return;
+ }
+ unitmask = unitmask >> 1;
+ }
+}
+
+
+LRESULT CALLBACK MainWndProc(
+ HWND hwnd, // handle to window
+ UINT uMsg, // message identifier
+ WPARAM wParam, // first message parameter
+ LPARAM lParam) // second message parameter
+{
+
+ //detect device arrival: http://msdn.microsoft.com/en-us/library/aa363215(VS.85).aspx
+ if (uMsg == WM_DEVICECHANGE)
+ {
+ if (wParam == DBT_DEVICEARRIVAL)
+ {
+ PDEV_BROADCAST_HDR lpdb = reinterpret_cast<PDEV_BROADCAST_HDR>(lParam);
+ if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
+ {
+ PDEV_BROADCAST_VOLUME lpdbv = reinterpret_cast<PDEV_BROADCAST_VOLUME>(lpdb);
+ //warning: lpdbv->dbcv_flags is 0 for USB-sticks!
+
+ //insert drive name notification into global variable:
+ notifyDriveFromMask(lpdbv->dbcv_unitmask);
+ }
+ }
+ }
+ //default
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+
+class NotifyDeviceArrival //e.g. insertion of USB-Stick
+{
+public:
+ NotifyDeviceArrival() :
+ parentInstance(NULL),
+ registeredClass(NULL),
+ windowHandle(NULL)
+ {
+ //get program's module handle
+ parentInstance = GetModuleHandle(NULL);
+ if (parentInstance == NULL)
+ throw FreeFileSync::FileError(wxString(("Could not start monitoring for volume arrival:")) + wxT("\n\n") +
+ FreeFileSync::getLastErrorFormatted()+ wxT(" (GetModuleHandle)"));
+
+ //register the main window class
+ WNDCLASS wc;
+ wc.style = 0;
+ wc.lpfnWndProc = MainWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = parentInstance;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = wxT("DeviceArrivalWatcher");
+
+ registeredClass =:: RegisterClass(&wc);
+ if (registeredClass == 0)
+ throw FreeFileSync::FileError(wxString(("Could not start monitoring for volume arrival:")) + wxT("\n\n") +
+ FreeFileSync::getLastErrorFormatted()+ wxT(" (RegisterClass)"));
+
+ //create dummy-window
+ windowHandle = ::CreateWindow(
+ reinterpret_cast<LPCTSTR>(registeredClass), //LPCTSTR lpClassName OR ATOM in low-order word!
+ 0, //LPCTSTR lpWindowName,
+ 0, //DWORD dwStyle,
+ 0, //int x,
+ 0, //int y,
+ 0, //int nWidth,
+ 0, //int nHeight,
+ 0, //note: we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)!
+ NULL, //HMENU hMenu,
+ parentInstance, //HINSTANCE hInstance,
+ NULL); //LPVOID lpParam
+ if (windowHandle == NULL)
+ throw FreeFileSync::FileError(wxString( ("Could not start monitoring for volume arrival:")) + wxT("\n\n") +
+ FreeFileSync::getLastErrorFormatted() + wxT(" (CreateWindow)"));
+
+ //clear global variable
+ driveNamesArrived.clear();
+ }
+
+ ~NotifyDeviceArrival()
+ {
+ //clean-up in reverse order
+ if (windowHandle != NULL)
+ ::DestroyWindow(windowHandle);
+
+ if (registeredClass != 0)
+ ::UnregisterClass(reinterpret_cast<LPCTSTR>(registeredClass), //LPCTSTR lpClassName OR ATOM in low-order word!
+ parentInstance); //HINSTANCE hInstance
+ }
+
+
+ //test if one of the notifications matches one of the directory paths specified
+ bool notificationsFound(const std::vector<Zstring>& dirList) const
+ {
+ //do NOT rely on string parsing! use (volume directory) file ids!
+ std::set<Utility::FileID> notifiedIds;
+ for (std::set<Zstring>::const_iterator j = driveNamesArrived.begin(); j != driveNamesArrived.end(); ++j)
+ {
+ const Utility::FileID notifiedVolId = Utility::retrieveFileID(*j);
+ if (notifiedVolId != Utility::FileID())
+ notifiedIds.insert(notifiedVolId);
+ }
+ //clear global variable
+ driveNamesArrived.clear();
+
+ if (!notifiedIds.empty()) //minor optimization
+ {
+ for (std::vector<Zstring>::const_iterator i = dirList.begin(); i != dirList.end(); ++i)
+ {
+ //retrieve volume name
+ wchar_t volumeNameRaw[1000];
+ if (::GetVolumePathName(i->c_str(), //__in LPCTSTR lpszFileName,
+ volumeNameRaw, //__out LPTSTR lpszVolumePathName,
+ 1000)) //__in DWORD cchBufferLength
+ {
+ const Utility::FileID monitoredId = Utility::retrieveFileID(volumeNameRaw);
+ if (monitoredId != Utility::FileID())
+ {
+ if (notifiedIds.find(monitoredId) != notifiedIds.end())
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+private:
+ HINSTANCE parentInstance;
+ ATOM registeredClass;
+ HWND windowHandle;
+
+ //we're programming on global variables: only one instance of NotifyDeviceArrival allowed at a time!
+ InstanceCounter<NotifyDeviceArrival> dummy; //exception safety!!!! use RAII for counter inc/dec!
+};
+*/
+
+//--------------------------------------------------------------------------------------------------------------
class ChangeNotifications
{
public:
@@ -75,11 +266,53 @@ private:
#endif
+class NotifyDirectoryArrival //detect changes to directory availability
+{
+public:
+ //initialization
+ void addForMonitoring(const Zstring& dirName, bool isExisting) //dir-existence already checked by calling method, avoid double-checking -> consistency!
+ {
+ availablility[dirName] = isExisting;
+ }
+
+ //detection
+ bool changeDetected() //polling explicitly allowed!
+ {
+ const int UPDATE_INTERVAL = 1000; //1 second interval
+
+ static wxLongLong lastExec = 0;
+ const wxLongLong newExec = wxGetLocalTimeMillis();
+
+ if (newExec - lastExec >= UPDATE_INTERVAL)
+ {
+ lastExec = newExec;
+
+ for (std::map<Zstring, bool>::iterator i = availablility.begin(); i != availablility.end(); ++i)
+ if (FreeFileSync::dirExists(i->first) != i->second) //change in availability
+ {
+ if (i->second) //directory doesn't exist anymore: no reason to trigger the commandline! (sometimes triggered by ChangeNotifications anyway...)
+ i->second = false; //update value, so that dir-arrival will be detected next time
+ else //directory arrival: trigger commandline!
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+private:
+ std::map<Zstring, bool> availablility; //save avail. status for each directory
+};
+
+
void RealtimeSync::waitForChanges(const std::vector<wxString>& dirNames, WaitCallback* statusHandler)
{
if (dirNames.empty()) //pathological case, but check is needed later
return;
+ //new: support for monitoring newly connected directories volumes (e.g.: USB-sticks)
+ NotifyDirectoryArrival monitorAvailability;
+
#ifdef FFS_WIN
ChangeNotifications notifications;
@@ -88,47 +321,58 @@ void RealtimeSync::waitForChanges(const std::vector<wxString>& dirNames, WaitCal
const Zstring formattedDir = FreeFileSync::getFormattedDirectoryName(i->c_str());
if (formattedDir.empty())
- throw FreeFileSync::FileError(_("Please fill all empty directory fields."));
- else if (!FreeFileSync::dirExists(formattedDir))
- throw FreeFileSync::FileError(wxString(_("Directory does not exist:")) + wxT("\n") +
- wxT("\"") + zToWx(formattedDir) + wxT("\"") + wxT("\n\n") +
- FreeFileSync::getLastErrorFormatted());
-
- const HANDLE rv = ::FindFirstChangeNotification(
- formattedDir.c_str(), //__in LPCTSTR lpPathName,
- true, //__in BOOL bWatchSubtree,
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_SIZE |
- FILE_NOTIFY_CHANGE_LAST_WRITE); //__in DWORD dwNotifyFilter
-
- if (rv == INVALID_HANDLE_VALUE)
+ throw FreeFileSync::FileError(_("At least one directory input field is empty."));
+
+ const bool isExisting = FreeFileSync::dirExists(formattedDir);
+ if (isExisting)
{
- const wxString errorMessage = wxString(_("Could not initialize directory monitoring:")) + wxT("\n\"") + *i + wxT("\"");
- throw FreeFileSync::FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ const HANDLE rv = ::FindFirstChangeNotification(
+ FreeFileSync::applyLongPathPrefix(formattedDir).c_str(), //__in LPCTSTR lpPathName,
+ true, //__in BOOL bWatchSubtree,
+ FILE_NOTIFY_CHANGE_FILE_NAME |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE); //__in DWORD dwNotifyFilter
+
+ if (rv == INVALID_HANDLE_VALUE)
+ {
+ const wxString errorMessage = wxString(_("Could not initialize directory monitoring:")) + wxT("\n\"") + *i + wxT("\"");
+ throw FreeFileSync::FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ }
+
+ notifications.addHandle(rv);
}
+ //else: we silently ignore this error: it may be that the directory becomes available later, e.g. if it is a USB-stick
- notifications.addHandle(rv);
+ monitorAvailability.addForMonitoring(formattedDir, isExisting); //all directories (including not yet existing) are relevant
}
while (true)
{
- const DWORD rv = ::WaitForMultipleObjects( //NOTE: notifications.getArray() returns valid pointer, because it cannot be empty in this context
- notifications.getSize(), //__in DWORD nCount,
- notifications.getArray(), //__in const HANDLE *lpHandles,
- false, //__in BOOL bWaitAll,
- UI_UPDATE_INTERVAL); //__in DWORD dwMilliseconds
- if (WAIT_OBJECT_0 <= rv && rv < WAIT_OBJECT_0 + notifications.getSize())
- return; //directory change detected
- else if (rv == WAIT_FAILED)
- throw FreeFileSync::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
- else if (rv == WAIT_TIMEOUT)
- statusHandler->requestUiRefresh();
+ //check for changes within directories:
+ if (notifications.getSize() > 0)
+ {
+ const DWORD rv = ::WaitForMultipleObjects( //NOTE: notifications.getArray() returns valid pointer, because it cannot be empty in this context
+ notifications.getSize(), //__in DWORD nCount,
+ notifications.getArray(), //__in const HANDLE *lpHandles,
+ false, //__in BOOL bWaitAll,
+ UI_UPDATE_INTERVAL); //__in DWORD dwMilliseconds
+ if (WAIT_OBJECT_0 <= rv && rv < WAIT_OBJECT_0 + notifications.getSize())
+ return; //directory change detected
+ else if (rv == WAIT_FAILED)
+ throw FreeFileSync::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ //else if (rv == WAIT_TIMEOUT)
+ }
+
+ if (monitorAvailability.changeDetected()) //check for newly arrived devices:
+ return;
+
+ statusHandler->requestUiRefresh();
}
#elif defined FFS_LINUX
- std::vector<std::string> fullDirList;
+ std::vector<std::string> fullDirList; //including subdirectories!
//add all subdirectories
for (std::vector<wxString>::const_iterator i = dirNames.begin(); i != dirNames.end(); ++i)
@@ -136,17 +380,19 @@ void RealtimeSync::waitForChanges(const std::vector<wxString>& dirNames, WaitCal
const Zstring formattedDir = FreeFileSync::getFormattedDirectoryName(wxToZ(*i));
if (formattedDir.empty())
- throw FreeFileSync::FileError(_("Please fill all empty directory fields."));
+ throw FreeFileSync::FileError(_("At least one directory input field is empty."));
- else if (!FreeFileSync::dirExists(formattedDir))
- throw FreeFileSync::FileError(wxString(_("Directory does not exist:")) + wxT("\n") +
- wxT("\"") + zToWx(formattedDir) + wxT("\"") + wxT("\n\n") +
- FreeFileSync::getLastErrorFormatted());
+ const bool isExisting = FreeFileSync::dirExists(formattedDir);
+ if (isExisting)
+ {
+ fullDirList.push_back(formattedDir.c_str());
+ //get all subdirectories
+ DirsOnlyTraverser traverser(fullDirList);
+ FreeFileSync::traverseFolder(formattedDir, false, &traverser); //don't traverse into symlinks (analog to windows build)
+ }
+ //else: we silently ignore this error: it may be that the directory becomes available later, e.g. if it is a USB-stick
- fullDirList.push_back(formattedDir.c_str());
- //get all subdirectories
- DirsOnlyTraverser traverser(fullDirList);
- FreeFileSync::traverseFolder(formattedDir, false, &traverser); //don't traverse into symlinks (analog to windows build)
+ monitorAvailability.addForMonitoring(formattedDir, isExisting); //all directories (including not yet existing) are relevant
}
try
@@ -178,6 +424,7 @@ void RealtimeSync::waitForChanges(const std::vector<wxString>& dirNames, WaitCal
}
}
+
while (true)
{
notifications.WaitForEvents(); //called in non-blocking mode
@@ -185,6 +432,9 @@ void RealtimeSync::waitForChanges(const std::vector<wxString>& dirNames, WaitCal
if (notifications.GetEventCount() > 0)
return; //directory change detected
+ if (monitorAvailability.changeDetected()) //check for newly arrived devices:
+ return;
+
wxMilliSleep(RealtimeSync::UI_UPDATE_INTERVAL);
statusHandler->requestUiRefresh();
}
@@ -199,3 +449,10 @@ void RealtimeSync::waitForChanges(const std::vector<wxString>& dirNames, WaitCal
}
#endif
}
+
+
+
+
+
+
+
diff --git a/RealtimeSync/watcher.h b/RealtimeSync/watcher.h
index 1655eebf..2f3990c2 100644
--- a/RealtimeSync/watcher.h
+++ b/RealtimeSync/watcher.h
@@ -8,16 +8,16 @@
namespace RealtimeSync
{
- const int UI_UPDATE_INTERVAL = 100; //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss
+const int UI_UPDATE_INTERVAL = 100; //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss
- class WaitCallback
- {
- public:
- virtual ~WaitCallback() {}
- virtual void requestUiRefresh() = 0; //opportunity to abort must be implemented in a frequently executed method like requestUiRefresh()
- };
+class WaitCallback
+{
+public:
+ virtual ~WaitCallback() {}
+ virtual void requestUiRefresh() = 0; //opportunity to abort must be implemented in a frequently executed method like requestUiRefresh()
+};
- void waitForChanges(const std::vector<wxString>& dirNames, WaitCallback* statusHandler); //throw(FreeFileSync::FileError);
+void waitForChanges(const std::vector<wxString>& dirNames, WaitCallback* statusHandler); //throw(FreeFileSync::FileError);
}
#endif // WATCHER_H_INCLUDED
diff --git a/RealtimeSync/xmlFreeFileSync.h b/RealtimeSync/xmlFreeFileSync.h
index 8de9af08..55687d93 100644
--- a/RealtimeSync/xmlFreeFileSync.h
+++ b/RealtimeSync/xmlFreeFileSync.h
@@ -8,9 +8,9 @@
namespace RealtimeSync
{
- void readRealOrBatchConfig(const wxString& filename, xmlAccess::XmlRealConfig& config); //throw (xmlAccess::XmlError);
+void readRealOrBatchConfig(const wxString& filename, xmlAccess::XmlRealConfig& config); //throw (xmlAccess::XmlError);
- int getProgramLanguage();
+int getProgramLanguage();
}
#endif // XMLFREEFILESYNC_H_INCLUDED
diff --git a/RealtimeSync/xmlProcessing.h b/RealtimeSync/xmlProcessing.h
index 90842abf..b8207973 100644
--- a/RealtimeSync/xmlProcessing.h
+++ b/RealtimeSync/xmlProcessing.h
@@ -8,16 +8,16 @@
namespace xmlAccess
{
- struct XmlRealConfig
- {
- XmlRealConfig() : delay(5) {}
- std::vector<wxString> directories;
- wxString commandline;
- unsigned int delay;
- };
+struct XmlRealConfig
+{
+ XmlRealConfig() : delay(5) {}
+ std::vector<wxString> directories;
+ wxString commandline;
+ unsigned int delay;
+};
- void readRealConfig(const wxString& filename, XmlRealConfig& config); //throw (xmlAccess::XmlError);
- void writeRealConfig(const XmlRealConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError);
+void readRealConfig(const wxString& filename, XmlRealConfig& config); //throw (xmlAccess::XmlError);
+void writeRealConfig(const XmlRealConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError);
}
#endif // XMLPROCESSING_H_INCLUDED
diff --git a/algorithm.cpp b/algorithm.cpp
index 566bae27..0940674d 100644
--- a/algorithm.cpp
+++ b/algorithm.cpp
@@ -10,7 +10,7 @@
#include "shared/stringConv.h"
#include "shared/globalFunctions.h"
#include "shared/loki/TypeManip.h"
-#include "shared/loki/NullType.h"
+//#include "shared/loki/NullType.h"
using namespace FreeFileSync;
@@ -135,180 +135,149 @@ bool FreeFileSync::allElementsEqual(const FolderComparison& folderCmp)
}
//---------------------------------------------------------------------------------------------------------------
-enum Answer
+inline
+bool sameFileTime(const wxLongLong& a, const wxLongLong& b, const unsigned int tolerance)
{
- CHANGE_DETECTED,
- NO_CHANGE,
- CANT_SAY_FILTERING_CHANGED
-};
-
+ if (a < b)
+ return b - a <= tolerance;
+ else
+ return a - b <= tolerance;
+}
+//---------------------------------------------------------------------------------------------------------------
-template <bool respectFiltering>
-class DetectChanges
+class DataSetFile
{
public:
- DetectChanges(const DirContainer* dirCont, //DirContainer in sense of a HierarchyObject
- const FilterProcess::FilterRef& dbFilter);
-
- DetectChanges(const DirContainer* dirCont); //DirContainer in sense of a HierarchyObject
-
- template <SelectedSide side>
- Answer detectFileChange(const FileMapping& fileObj) const;
-
- struct DirAnswer
+ DataSetFile(const FileMapping& fileObj, Loki::Int2Type<LEFT_SIDE>) :
+ lastWriteTime_(NULL),
+ fileSize_(NULL)
{
- DirAnswer(Answer status, const DetectChanges instance) : dirStatus(status), subDirInstance(instance) {}
- Answer dirStatus;
- DetectChanges subDirInstance; //not valid if dirStatus == CANT_SAY_FILTERING_CHANGED
- };
- template <SelectedSide side>
- DirAnswer detectDirChange(const DirMapping& dirObj) const;
-
-private:
- const DirContainer* const dirCont_; //if NULL: did not exist during db creation
- 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::FilterRef& dbFilter) :
- dirCont_(dirCont),
- dbFilter_(dbFilter) {}
-
-
-template <>
-inline
-DetectChanges<false>::DetectChanges(const DirContainer* dirCont) : //DirContainer in sense of a HierarchyObject
- dirCont_(dirCont) {}
+ if (!fileObj.isEmpty<LEFT_SIDE>())
+ {
+ lastWriteTime_ = &fileObj.getLastWriteTime<LEFT_SIDE>();
+ fileSize_ = &fileObj.getFileSize<LEFT_SIDE>();
+ }
+ }
+ DataSetFile(const FileMapping& fileObj, Loki::Int2Type<RIGHT_SIDE>) :
+ lastWriteTime_(NULL),
+ fileSize_(NULL)
+ {
+ if (!fileObj.isEmpty<RIGHT_SIDE>())
+ {
+ lastWriteTime_ = &fileObj.getLastWriteTime<RIGHT_SIDE>();
+ fileSize_ = &fileObj.getFileSize<RIGHT_SIDE>();
+ }
+ }
-template <SelectedSide side>
-Answer detectFileChangeSub(const FileMapping& fileObj, const DirContainer* dbDirectory)
-{
- if (dbDirectory)
+ DataSetFile(const FileContainer* fileCont) :
+ lastWriteTime_(NULL),
+ fileSize_(NULL)
{
- DirContainer::SubFileList::const_iterator j = dbDirectory->getSubFiles().find(fileObj.getObjShortName());
- if (j == dbDirectory->getSubFiles().end())
+ if (fileCont)
{
- if (fileObj.isEmpty<side>())
- return NO_CHANGE;
- else
- return CHANGE_DETECTED; //->create
+ const FileDescriptor& dbData = fileCont->getData();
+ lastWriteTime_ = &dbData.lastWriteTimeRaw;
+ fileSize_ = &dbData.fileSize;
}
+ }
+
+ bool operator==(const DataSetFile& other) const
+ {
+ if (lastWriteTime_ == NULL)
+ return other.lastWriteTime_ == NULL;
else
{
- if (fileObj.isEmpty<side>())
- return CHANGE_DETECTED; //->delete
+ if (other.lastWriteTime_ == NULL)
+ return false;
else
{
- const FileDescriptor& dbData = j->second.getData();
- if ( fileObj.getLastWriteTime<side>() == dbData.lastWriteTimeRaw &&
- fileObj.getFileSize<side>() == dbData.fileSize)
- return NO_CHANGE;
- else
- return CHANGE_DETECTED; //->update
+ //respect 2 second FAT/FAT32 precision! copying a file to a FAT32 drive changes it's modification date by up to 2 seconds
+ return ::sameFileTime(*lastWriteTime_, *other.lastWriteTime_, 2) &&
+ *fileSize_ == *other.fileSize_;
}
}
}
- else
+
+ template <class T>
+ bool operator!=(const T& other) const
{
- if (fileObj.isEmpty<side>())
- return NO_CHANGE;
- else
- return CHANGE_DETECTED; //->create
+ return !(*this == other);
}
-}
-
-template <>
-template <SelectedSide side>
-inline
-Answer DetectChanges<false>::detectFileChange(const FileMapping& fileObj) const
-{
- return detectFileChangeSub<side>(fileObj, dirCont_);
-}
+private:
+ const wxLongLong* lastWriteTime_; //optional
+ const wxULongLong* fileSize_; //optional
+};
-template <>
-template <SelectedSide side>
-inline
-Answer DetectChanges<true>::detectFileChange(const FileMapping& fileObj) const
+//-----------------------------------
+class DataSetDir
{
- //if filtering would have excluded file during database creation, then we can't say anything about its former state
- if (!dbFilter_->passFileFilter(fileObj.getObjShortName()))
- return CANT_SAY_FILTERING_CHANGED;
+public:
+ DataSetDir(const DirMapping& dirObj, Loki::Int2Type<LEFT_SIDE>) :
+ existing(!dirObj.isEmpty<LEFT_SIDE>()) {}
- return detectFileChangeSub<side>(fileObj, dirCont_);
-}
+ DataSetDir(const DirMapping& dirObj, Loki::Int2Type<RIGHT_SIDE>) :
+ existing(!dirObj.isEmpty<RIGHT_SIDE>()) {}
+ DataSetDir(bool isExising) :
+ existing(isExising) {}
-template <SelectedSide side>
-Answer detectDirChangeSub(const DirMapping& dirObj, const DirContainer* dbDirectory, const DirContainer*& dbSubDirectory)
-{
- if (dbDirectory)
+ bool operator==(const DataSetDir& other) const
{
- DirContainer::SubDirList::const_iterator j = dbDirectory->getSubDirs().find(dirObj.getObjShortName());
- if (j == dbDirectory->getSubDirs().end())
- {
- if (dirObj.isEmpty<side>())
- return NO_CHANGE;
- else
- return CHANGE_DETECTED; //->create
- }
- else
- {
- dbSubDirectory = &j->second;
- if (dirObj.isEmpty<side>())
- return CHANGE_DETECTED; //->delete
- else
- return NO_CHANGE;
- }
+ return existing == other.existing;
}
- else
+
+ template <class T>
+ bool operator!=(const T& other) const
{
- if (dirObj.isEmpty<side>())
- return NO_CHANGE;
- else
- return CHANGE_DETECTED; //->create
+ return !(*this == other);
}
-}
+private:
+ bool existing;
+};
-template <>
-template <SelectedSide side>
-DetectChanges<false>::DirAnswer DetectChanges<false>::detectDirChange(const DirMapping& dirObj) const
+
+//--------------------------------------------------------------------------------------------------------
+DataSetFile retrieveDataSetFile(const Zstring& objShortName, const DirContainer* dbDirectory)
{
- const DirContainer* dbSubDir = NULL;
- const Answer answer = detectDirChangeSub<side>(dirObj, dirCont_, dbSubDir);
+ if (dbDirectory)
+ {
+ const DirContainer::SubFileList& fileList = dbDirectory->getSubFiles();
+ const DirContainer::SubFileList::const_iterator j = fileList.find(objShortName);
+ if (j != fileList.end())
+ return DataSetFile(&j->second);
+ }
- return DirAnswer(answer, DetectChanges<false>(dbSubDir));
+ //object not found
+ return DataSetFile(NULL);
}
-template <>
-template <SelectedSide side>
-DetectChanges<true>::DirAnswer DetectChanges<true>::detectDirChange(const DirMapping& dirObj) const
+std::pair<DataSetDir, const DirContainer*> retrieveDataSetDir(const Zstring& objShortName, const DirContainer* dbDirectory)
{
- //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))
- return DirAnswer(CANT_SAY_FILTERING_CHANGED, DetectChanges<true>(NULL, dbFilter_));
-
- const DirContainer* dbSubDir = NULL;
- const Answer answer = detectDirChangeSub<side>(dirObj, dirCont_, dbSubDir);
+ if (dbDirectory)
+ {
+ const DirContainer::SubDirList& dirList = dbDirectory->getSubDirs();
+ const DirContainer::SubDirList::const_iterator j = dirList.find(objShortName);
+ if (j != dirList.end())
+ return std::make_pair(DataSetDir(true), &j->second);
+ }
- return DirAnswer(answer, DetectChanges<true>(dbSubDir, dbFilter_));
+ //object not found
+ return std::make_pair(DataSetDir(false), static_cast<const DirContainer*>(NULL));
}
-//----------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------------
class SetDirChangedFilter
{
public:
SetDirChangedFilter() :
- txtFilterChanged(_("Cannot determine sync-direction: Changed filter settings!")) {}
+ txtFilterChanged(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("Filter settings have changed!")) {}
void execute(HierarchyObject& hierObj) const
{
@@ -361,8 +330,11 @@ public:
RedetermineAuto(BaseDirMapping& baseDirectory,
DeterminationProblem* handler) :
txtBothSidesChanged(_("Both sides have changed since last synchronization!")),
- txtNoSideChanged(_("Cannot determine sync-direction: No change since last synchronization!")),
- txtFilterChanged(_("Cannot determine sync-direction: Changed filter settings!")),
+ txtNoSideChanged(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("No change since last synchronization!")),
+ txtFilterChanged(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("Filter settings have changed!")),
+ txtLastSyncFail(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("Last synchronization not completed!")),
+ dbFilterLeft(NULL),
+ dbFilterRight(NULL),
handler_(handler)
{
if (AllElementsEqual()(baseDirectory)) //nothing to do: abort and don't show any nag-screens
@@ -383,33 +355,16 @@ public:
const DirInformation& dirInfoLeft = *dirInfo.first;
const DirInformation& dirInfoRight = *dirInfo.second;
- if ( respectFiltering(baseDirectory, dirInfoLeft) &&
- respectFiltering(baseDirectory, dirInfoRight))
- {
- execute(baseDirectory,
- 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, dirInfoRight.filter));
- }
- else if ( respectFiltering( baseDirectory, dirInfoLeft) &&
- !respectFiltering(baseDirectory, dirInfoRight))
- {
- execute(baseDirectory,
- DetectChanges<true>( &dirInfoLeft.baseDirContainer, dirInfoLeft.filter),
- DetectChanges<false>(&dirInfoRight.baseDirContainer));
- }
- else
- {
- execute(baseDirectory,
- DetectChanges<false>(&dirInfoLeft.baseDirContainer),
- DetectChanges<false>(&dirInfoRight.baseDirContainer));
- }
+ //save db filter (if it needs to be considered only):
+ if (respectFiltering(baseDirectory, dirInfoLeft))
+ dbFilterLeft = dirInfoLeft.filter.get();
+
+ if (respectFiltering(baseDirectory, dirInfoRight))
+ dbFilterRight = dirInfoRight.filter.get();
+
+ execute(baseDirectory,
+ &dirInfoLeft.baseDirContainer,
+ &dirInfoRight.baseDirContainer);
}
@@ -422,6 +377,7 @@ private:
return !dirInfo.filter->isNull() && *dirInfo.filter != *baseDirectory.getFilter();
}
+
std::pair<DirInfoPtr, DirInfoPtr> loadDBFile(const BaseDirMapping& baseDirectory) //return NULL on failure
{
try
@@ -436,36 +392,49 @@ private:
return std::pair<DirInfoPtr, DirInfoPtr>(); //NULL
}
+
+ bool filterConflictFound(const FileMapping& fileObj) const
+ {
+ //if filtering would have excluded file during database creation, then we can't say anything about its former state
+ return (dbFilterLeft && !dbFilterLeft ->passFileFilter(fileObj.getObjShortName())) ||
+ (dbFilterRight && !dbFilterRight->passFileFilter(fileObj.getObjShortName()));
+ }
+
+
+ bool filterConflictFound(const DirMapping& dirObj) const
+ {
+ //if filtering would have excluded directory during database creation, then we can't say anything about its former state
+ return (dbFilterLeft && !dbFilterLeft ->passDirFilter(dirObj.getObjShortName(), NULL)) ||
+ (dbFilterRight && !dbFilterRight->passDirFilter(dirObj.getObjShortName(), NULL));
+ }
+
+
template<typename Iterator, typename Function>
friend Function std::for_each(Iterator, Iterator, Function);
- template <bool dbLeftFilterActive, bool dbRightFilterActive>
+
void execute(HierarchyObject& hierObj,
- const DetectChanges<dbLeftFilterActive>& dbLeft,
- const DetectChanges<dbRightFilterActive>& dbRight)
+ const DirContainer* dbDirectoryLeft,
+ const DirContainer* dbDirectoryRight)
{
//process files
std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(),
- boost::bind(&RedetermineAuto::processFile<dbLeftFilterActive, dbRightFilterActive>, this, _1, boost::ref(dbLeft), boost::ref(dbRight)));
+ boost::bind(&RedetermineAuto::processFile, this, _1, dbDirectoryLeft, dbDirectoryRight));
//process directories
std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(),
- boost::bind(&RedetermineAuto::processDir<dbLeftFilterActive, dbRightFilterActive>, this, _1, boost::ref(dbLeft), boost::ref(dbRight)));
+ boost::bind(&RedetermineAuto::processDir, this, _1, dbDirectoryLeft, dbDirectoryRight));
}
- template <bool dbLeftFilterActive, bool dbRightFilterActive>
+
void processFile(FileMapping& fileObj,
- const DetectChanges<dbLeftFilterActive>& dbLeft,
- const DetectChanges<dbRightFilterActive>& dbRight)
+ const DirContainer* dbDirectoryLeft,
+ const DirContainer* dbDirectoryRight)
{
const CompareFilesResult cat = fileObj.getCategory();
if (cat == FILE_EQUAL)
return;
- const Answer statusLeft = dbLeft. template detectFileChange<LEFT_SIDE>(fileObj);
- const Answer statusRight = dbRight.template detectFileChange<RIGHT_SIDE>(fileObj);
-
- if ( statusLeft == CANT_SAY_FILTERING_CHANGED ||
- statusRight == CANT_SAY_FILTERING_CHANGED)
+ if (filterConflictFound(fileObj))
{
if (cat == FILE_LEFT_SIDE_ONLY)
fileObj.setSyncDir(SYNC_DIR_RIGHT);
@@ -476,96 +445,155 @@ private:
return;
}
+ //determine datasets for change detection
+ const DataSetFile dataDbLeft = retrieveDataSetFile(fileObj.getObjShortName(), dbDirectoryLeft);
+ const DataSetFile dataDbRight = retrieveDataSetFile(fileObj.getObjShortName(), dbDirectoryRight);
- if ( statusLeft == CHANGE_DETECTED &&
- statusRight == NO_CHANGE)
- fileObj.setSyncDir(SYNC_DIR_RIGHT);
-
- else if ( statusLeft == NO_CHANGE &&
- statusRight == CHANGE_DETECTED)
- fileObj.setSyncDir(SYNC_DIR_LEFT);
+ const DataSetFile dataCurrentLeft( fileObj, Loki::Int2Type<LEFT_SIDE>());
+ const DataSetFile dataCurrentRight(fileObj, Loki::Int2Type<RIGHT_SIDE>());
- else if ( statusLeft == CHANGE_DETECTED &&
- statusRight == CHANGE_DETECTED)
- fileObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ //evaluation
+ const bool changeOnLeft = dataDbLeft != dataCurrentLeft;
+ const bool changeOnRight = dataDbRight != dataCurrentRight;
- else if ( statusLeft == NO_CHANGE &&
- statusRight == NO_CHANGE)
+ if (dataDbLeft == dataDbRight) //last sync seems to have been successful
{
- if (cat == FILE_LEFT_SIDE_ONLY)
- fileObj.setSyncDir(SYNC_DIR_RIGHT);
- else if (cat == FILE_RIGHT_SIDE_ONLY)
- fileObj.setSyncDir(SYNC_DIR_LEFT);
+ if (changeOnLeft)
+ {
+ if (changeOnRight)
+ fileObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ else
+ fileObj.setSyncDir(SYNC_DIR_RIGHT);
+ }
else
- fileObj.setSyncDirConflict(txtNoSideChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ {
+ if (changeOnRight)
+ fileObj.setSyncDir(SYNC_DIR_LEFT);
+ else
+ {
+ if (cat == FILE_LEFT_SIDE_ONLY)
+ fileObj.setSyncDir(SYNC_DIR_RIGHT);
+ else if (cat == FILE_RIGHT_SIDE_ONLY)
+ fileObj.setSyncDir(SYNC_DIR_LEFT);
+ else
+ fileObj.setSyncDirConflict(txtNoSideChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ }
+ }
+ }
+ else //object did not complete last sync
+ {
+ if (changeOnLeft && changeOnRight)
+ fileObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ else
+ {
+ if (cat == FILE_LEFT_SIDE_ONLY)
+ fileObj.setSyncDir(SYNC_DIR_RIGHT);
+ else if (cat == FILE_RIGHT_SIDE_ONLY)
+ fileObj.setSyncDir(SYNC_DIR_LEFT);
+ else
+ fileObj.setSyncDirConflict(txtLastSyncFail); //set syncDir = SYNC_DIR_INT_CONFLICT
+ }
}
}
- template <bool dbLeftFilterActive, bool dbRightFilterActive>
void processDir(DirMapping& dirObj,
- const DetectChanges<dbLeftFilterActive>& dbLeft,
- const DetectChanges<dbRightFilterActive>& dbRight)
+ const DirContainer* dbDirectoryLeft,
+ const DirContainer* dbDirectoryRight)
{
- const typename DetectChanges<dbLeftFilterActive> ::DirAnswer statusLeft = dbLeft. template detectDirChange<LEFT_SIDE>(dirObj);
- const typename DetectChanges<dbRightFilterActive>::DirAnswer statusRight = dbRight.template detectDirChange<RIGHT_SIDE>(dirObj);
-
const CompareDirResult cat = dirObj.getDirCategory();
- if (cat != DIR_EQUAL)
+
+ if (filterConflictFound(dirObj))
{
- if ( (statusLeft.dirStatus == CANT_SAY_FILTERING_CHANGED ||
- statusRight.dirStatus == CANT_SAY_FILTERING_CHANGED))
+ switch (cat)
{
- switch (cat)
- {
- case DIR_LEFT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_RIGHT);
- break;
- case DIR_RIGHT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_LEFT);
- break;
- case DIR_EQUAL:
- assert(false);
- }
-
- SetDirChangedFilter().execute(dirObj); //filter issue for this directory => treat subfiles/-dirs the same
- return;
- }
- else if ( statusLeft.dirStatus == CHANGE_DETECTED &&
- statusRight.dirStatus == NO_CHANGE)
+ case DIR_LEFT_SIDE_ONLY:
dirObj.setSyncDir(SYNC_DIR_RIGHT);
-
- else if ( statusLeft.dirStatus == NO_CHANGE &&
- statusRight.dirStatus == CHANGE_DETECTED)
+ break;
+ case DIR_RIGHT_SIDE_ONLY:
dirObj.setSyncDir(SYNC_DIR_LEFT);
+ break;
+ case DIR_EQUAL:
+ assert(false);
+ }
- else if ( statusLeft.dirStatus == CHANGE_DETECTED &&
- statusRight.dirStatus == CHANGE_DETECTED)
- dirObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ SetDirChangedFilter().execute(dirObj); //filter issue for this directory => treat subfiles/-dirs the same
+ return;
+ }
+
+ //determine datasets for change detection
+ const std::pair<DataSetDir, const DirContainer*> dataDbLeftStuff = retrieveDataSetDir(dirObj.getObjShortName(), dbDirectoryLeft);
+ const std::pair<DataSetDir, const DirContainer*> dataDbRightStuff = retrieveDataSetDir(dirObj.getObjShortName(), dbDirectoryRight);
+
+ const DataSetDir dataCurrentLeft( dirObj, Loki::Int2Type<LEFT_SIDE>());
+ const DataSetDir dataCurrentRight(dirObj, Loki::Int2Type<RIGHT_SIDE>());
- else if ( statusLeft.dirStatus == NO_CHANGE &&
- statusRight.dirStatus == NO_CHANGE)
+ //evaluation
+ const bool changeOnLeft = dataDbLeftStuff.first != dataCurrentLeft;
+ const bool changeOnRight = dataDbRightStuff.first != dataCurrentRight;
+
+ if (cat != DIR_EQUAL)
+ {
+ if (dataDbLeftStuff.first == dataDbRightStuff.first) //last sync seems to have been successful
{
- switch (cat)
+ if (changeOnLeft)
{
- case DIR_LEFT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_RIGHT);
- break;
- case DIR_RIGHT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_LEFT);
- break;
- case DIR_EQUAL:
- assert(false);
+ if (changeOnRight)
+ dirObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ else
+ dirObj.setSyncDir(SYNC_DIR_RIGHT);
+ }
+ else
+ {
+ if (changeOnRight)
+ dirObj.setSyncDir(SYNC_DIR_LEFT);
+ else
+ {
+ switch (cat)
+ {
+ case DIR_LEFT_SIDE_ONLY:
+ dirObj.setSyncDir(SYNC_DIR_RIGHT);
+ break;
+ case DIR_RIGHT_SIDE_ONLY:
+ dirObj.setSyncDir(SYNC_DIR_LEFT);
+ break;
+ case DIR_EQUAL:
+ assert(false);
+ }
+ }
+ }
+ }
+ else //object did not complete last sync
+ {
+ if (changeOnLeft && changeOnRight)
+ dirObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
+ else
+ {
+ switch (cat)
+ {
+ case DIR_LEFT_SIDE_ONLY:
+ dirObj.setSyncDir(SYNC_DIR_RIGHT);
+ break;
+ case DIR_RIGHT_SIDE_ONLY:
+ dirObj.setSyncDir(SYNC_DIR_LEFT);
+ break;
+ case DIR_EQUAL:
+ assert(false);
+ }
}
}
}
- execute(dirObj, statusLeft.subDirInstance, statusRight.subDirInstance); //recursion
+ execute(dirObj, dataDbLeftStuff.second, dataDbRightStuff.second); //recursion
}
const wxString txtBothSidesChanged;
const wxString txtNoSideChanged;
const wxString txtFilterChanged;
+ const wxString txtLastSyncFail;
+
+ const BaseFilter* dbFilterLeft; //optional
+ const BaseFilter* dbFilterRight; //optional
DeterminationProblem* const handler_;
};
@@ -624,12 +652,14 @@ private:
void operator()(FileMapping& fileObj) const
{
- fileObj.setSyncDir(newDirection_);
+ if (fileObj.getCategory() != FILE_EQUAL)
+ fileObj.setSyncDir(newDirection_);
}
void operator()(DirMapping& dirObj) const
{
- dirObj.setSyncDir(newDirection_);
+ if (dirObj.getDirCategory() != DIR_EQUAL)
+ dirObj.setSyncDir(newDirection_);
execute(dirObj); //recursion
}
@@ -639,7 +669,8 @@ private:
void FreeFileSync::setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj)
{
- fsObj.setSyncDir(newDirection);
+ if (fsObj.getCategory() != FILE_EQUAL)
+ fsObj.setSyncDir(newDirection);
DirMapping* dirObj = dynamic_cast<DirMapping*>(&fsObj);
if (dirObj) //process subdirectories also!
@@ -708,7 +739,7 @@ void FreeFileSync::setActiveStatus(bool newStatus, FreeFileSync::FileSystemObjec
class FilterData
{
public:
- FilterData(const FilterProcess& filterProcIn) : filterProc(filterProcIn) {}
+ FilterData(const BaseFilter& filterProcIn) : filterProc(filterProcIn) {}
void execute(FreeFileSync::HierarchyObject& hierObj)
{
@@ -740,11 +771,11 @@ private:
InOrExcludeAllRows<false>().execute(dirObj); //exclude all files dirs in subfolders
}
- const FilterProcess& filterProc;
+ const BaseFilter& filterProc;
};
-void FreeFileSync::applyFiltering(const FilterProcess& filter, FreeFileSync::BaseDirMapping& baseDirectory)
+void FreeFileSync::applyFiltering(const BaseFilter& filter, FreeFileSync::BaseDirMapping& baseDirectory)
{
FilterData(filter).execute(baseDirectory);
}
@@ -766,14 +797,14 @@ void FreeFileSync::applyFiltering(const MainConfiguration& currentMainCfg, Folde
currentMainCfg.additionalPairs.end());
- const FilterProcess::FilterRef globalFilter(new NameFilter(currentMainCfg.includeFilter, currentMainCfg.excludeFilter));
+ const BaseFilter::FilterRef globalFilter(new NameFilter(currentMainCfg.includeFilter, currentMainCfg.excludeFilter));
for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i)
{
BaseDirMapping& baseDirectory = folderCmp[i - allPairs.begin()];
applyFiltering(*combineFilters(globalFilter,
- FilterProcess::FilterRef(new NameFilter(
+ BaseFilter::FilterRef(new NameFilter(
i->localFilter.includeFilter,
i->localFilter.excludeFilter))),
baseDirectory);
@@ -916,7 +947,7 @@ private:
};
-void FreeFileSync::deleteFromGridAndHD(FolderComparison& folderCmp, //attention: rows will be physically deleted!
+void FreeFileSync::deleteFromGridAndHD(FolderComparison& folderCmp, //attention: rows will be physically deleted!
std::vector<FileSystemObject*>& rowsToDeleteOnLeft, //refresh GUI grid after deletion to remove invalid rows
std::vector<FileSystemObject*>& rowsToDeleteOnRight, //all pointers need to be bound!
const bool deleteOnBothSides,
@@ -1116,3 +1147,12 @@ void FreeFileSync::checkForDSTChange(const FileCompareResult& gridData,
*/
+
+
+
+
+
+
+
+
+
diff --git a/algorithm.h b/algorithm.h
index 580ad2dd..dbe5dd35 100644
--- a/algorithm.h
+++ b/algorithm.h
@@ -6,7 +6,7 @@
namespace FreeFileSync
{
-class FilterProcess;
+class BaseFilter;
void swapGrids(const MainConfiguration& config, FolderComparison& folderCmp);
@@ -24,7 +24,7 @@ bool allElementsEqual(const FolderComparison& folderCmp);
//filtering
void applyFiltering(const MainConfiguration& currentMainCfg, FolderComparison& folderCmp);
-void applyFiltering(const FilterProcess& filter, BaseDirMapping& baseDirectory);
+void applyFiltering(const BaseFilter& 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!
diff --git a/comparison.cpp b/comparison.cpp
index 79105801..120a96c3 100644
--- a/comparison.cpp
+++ b/comparison.cpp
@@ -21,6 +21,10 @@
#include <boost/bind.hpp>
#include <boost/scoped_array.hpp>
+#ifdef FFS_WIN
+#include "shared/longPathPrefix.h"
+#endif
+
using namespace FreeFileSync;
@@ -33,7 +37,7 @@ std::vector<FreeFileSync::FolderPairCfg> FreeFileSync::extractCompareCfg(const M
mainCfg.additionalPairs.begin(), //add additional pairs
mainCfg.additionalPairs.end());
- const FilterProcess::FilterRef globalFilter(new NameFilter(mainCfg.includeFilter, mainCfg.excludeFilter));
+ const BaseFilter::FilterRef globalFilter(new NameFilter(mainCfg.includeFilter, mainCfg.excludeFilter));
std::vector<FolderPairCfg> output;
for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i)
@@ -43,11 +47,11 @@ std::vector<FreeFileSync::FolderPairCfg> FreeFileSync::extractCompareCfg(const M
mainCfg.filterIsActive ?
combineFilters(globalFilter,
- FilterProcess::FilterRef(
+ BaseFilter::FilterRef(
new NameFilter(
i->localFilter.includeFilter,
i->localFilter.excludeFilter))) :
- FilterProcess::FilterRef(new NullFilter),
+ BaseFilter::FilterRef(new NullFilter),
i->altSyncConfig.get() ? i->altSyncConfig->syncConfiguration : mainCfg.syncConfiguration));
@@ -89,9 +93,13 @@ class BaseDirCallback : public DirCallback
{
friend class DirCallback;
public:
- BaseDirCallback(DirContainer& output, const FilterProcess::FilterRef& filter, StatusHandler* handler) :
+ BaseDirCallback(DirContainer& output,
+ const BaseFilter::FilterRef& filter,
+ unsigned int detectRenameThreshold,
+ StatusHandler* handler) :
DirCallback(this, Zstring(), output, handler),
textScanning(wxToZ(wxString(_("Scanning:")) + wxT(" \n"))),
+ detectRenameThreshold_(detectRenameThreshold),
filterInstance(filter) {}
virtual TraverseCallback::ReturnValue onFile(const DefaultChar* shortName, const Zstring& fullName, const TraverseCallback::FileInfo& details);
@@ -102,7 +110,8 @@ private:
const Zstring textScanning;
std::vector<CallbackPointer> callBackBox; //collection of callback pointers to handle ownership
- const FilterProcess::FilterRef filterInstance; //always bound!
+ const unsigned int detectRenameThreshold_;
+ const BaseFilter::FilterRef filterInstance; //always bound!
};
@@ -126,6 +135,16 @@ TraverseCallback::ReturnValue DirCallback::onFile(const DefaultChar* shortName,
return TRAVERSING_CONTINUE;
}
+ //warning: for windows retrieveFileID is slow as hell! approximately 3 * 10^-4 s per file!
+ //therefore only large files (that take advantage of detection of renaming when synchronizing) should be evaluated!
+ //testcase: scanning only files larger than 1 MB results in performance loss of 6%
+
+//#warning this call is NOT acceptable for Linux!
+// //Linux: retrieveFileID takes about 50% longer in VM! (avoidable because of redundant stat() call!)
+// const Utility::FileID fileIdentifier = details.fileSize >= baseCallback_->detectRenameThreshold_ ?
+// Utility::retrieveFileID(fullName) :
+// Utility::FileID();
+
output_.addSubFile(shortName, FileDescriptor(details.lastWriteTimeRaw, details.fileSize));
//add 1 element to the progress indicator
@@ -212,7 +231,7 @@ TraverseCallback::ReturnValue BaseDirCallback::onFile(
const Zstring& fullName,
const TraverseCallback::FileInfo& details)
{
- //do not scan the database file
+ //do not list the database file sync.ffs_db
#ifdef FFS_WIN
if (getSyncDBFilename().CmpNoCase(shortName) == 0)
#elif defined FFS_LINUX
@@ -228,14 +247,14 @@ TraverseCallback::ReturnValue BaseDirCallback::onFile(
struct DirBufferKey
{
DirBufferKey(const Zstring& dirname,
- const FilterProcess::FilterRef& filterIn) : //filter interface: always bound by design!
+ const BaseFilter::FilterRef& filterIn) : //filter interface: always bound by design!
directoryName(dirname),
filter(filterIn->isNull() ? //some optimization of "Null" filter
- FilterProcess::FilterRef(new NullFilter) :
+ BaseFilter::FilterRef(new NullFilter) :
filterIn) {}
const Zstring directoryName;
- const FilterProcess::FilterRef filter; //buffering has to consider filtering!
+ const BaseFilter::FilterRef filter; //buffering has to consider filtering!
bool operator < (const DirBufferKey& b) const
{
@@ -256,11 +275,14 @@ struct DirBufferKey
class CompareProcess::DirectoryBuffer //buffer multiple scans of the same directories
{
public:
- DirectoryBuffer(const bool traverseDirectorySymlinks, StatusHandler* statusUpdater) :
+ DirectoryBuffer(const bool traverseDirectorySymlinks,
+ const unsigned int detectRenameThreshold,
+ StatusHandler* statusUpdater) :
m_traverseDirectorySymlinks(traverseDirectorySymlinks),
+ detectRenameThreshold_(detectRenameThreshold),
m_statusUpdater(statusUpdater) {}
- const DirContainer& getDirectoryDescription(const Zstring& directoryPostfixed, const FilterProcess::FilterRef& filter);
+ const DirContainer& getDirectoryDescription(const Zstring& directoryPostfixed, const BaseFilter::FilterRef& filter);
private:
typedef boost::shared_ptr<DirContainer> DirBufferValue; //exception safety: avoid memory leak
@@ -271,6 +293,7 @@ private:
BufferType buffer;
const bool m_traverseDirectorySymlinks;
+ const unsigned int detectRenameThreshold_;
StatusHandler* m_statusUpdater;
};
//------------------------------------------------------------------------------------------
@@ -282,10 +305,15 @@ 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(new BaseDirCallback(*baseContainer, newKey.filter, m_statusUpdater));
+ std::auto_ptr<TraverseCallback> traverser(new BaseDirCallback(*baseContainer,
+ newKey.filter,
+ detectRenameThreshold_,
+ m_statusUpdater));
//get all files and folders from directoryPostfixed (and subdirectories)
- traverseFolder(newKey.directoryName, m_traverseDirectorySymlinks, traverser.get()); //exceptions may be thrown!
+ traverseFolder(newKey.directoryName,
+ m_traverseDirectorySymlinks,
+ traverser.get()); //exceptions may be thrown!
}
return *baseContainer.get();
}
@@ -293,7 +321,7 @@ DirContainer& CompareProcess::DirectoryBuffer::insertIntoBuffer(const DirBufferK
const DirContainer& CompareProcess::DirectoryBuffer::getDirectoryDescription(
const Zstring& directoryPostfixed,
- const FilterProcess::FilterRef& filter)
+ const BaseFilter::FilterRef& filter)
{
const DirBufferKey searchKey(directoryPostfixed, filter);
@@ -321,14 +349,14 @@ void foldersAreValidForComparison(const std::vector<FolderPairCfg>& folderPairsF
checkEmptyDirnameActive = false;
while (true)
{
- const ErrorHandler::Response rv = statusUpdater->reportError(wxString(_("Please fill all empty directory fields.")) + wxT(" \n\n") +
+ const ErrorHandler::Response rv = statusUpdater->reportError(wxString(_("At least one directory input field is empty.")) + wxT(" \n\n") +
+ wxT("(") + additionalInfo + wxT(")"));
if (rv == ErrorHandler::IGNORE_ERROR)
break;
else if (rv == ErrorHandler::RETRY)
; //continue with loop
else
- throw std::logic_error("Programming Error: Unknown return value!");
+ throw std::logic_error("Programming Error: Unknown return value! (1)");
}
}
}
@@ -339,13 +367,13 @@ void foldersAreValidForComparison(const std::vector<FolderPairCfg>& folderPairsF
{
ErrorHandler::Response rv = statusUpdater->reportError(wxString(_("Directory does not exist:")) + wxT(" \n") +
wxT("\"") + zToWx(i->leftDirectory) + wxT("\"") + wxT("\n\n") +
- FreeFileSync::getLastErrorFormatted() + wxT(" ") + additionalInfo);
+ additionalInfo + wxT(" ") + FreeFileSync::getLastErrorFormatted());
if (rv == ErrorHandler::IGNORE_ERROR)
break;
else if (rv == ErrorHandler::RETRY)
; //continue with loop
else
- throw std::logic_error("Programming Error: Unknown return value!");
+ throw std::logic_error("Programming Error: Unknown return value! (2)");
}
if (!i->rightDirectory.empty())
@@ -353,13 +381,13 @@ void foldersAreValidForComparison(const std::vector<FolderPairCfg>& folderPairsF
{
ErrorHandler::Response rv = statusUpdater->reportError(wxString(_("Directory does not exist:")) + wxT("\n") +
wxT("\"") + zToWx(i->rightDirectory) + wxT("\"") + wxT("\n\n") +
- FreeFileSync::getLastErrorFormatted() + wxT(" ") + additionalInfo);
+ additionalInfo + wxT(" ") + FreeFileSync::getLastErrorFormatted());
if (rv == ErrorHandler::IGNORE_ERROR)
break;
else if (rv == ErrorHandler::RETRY)
; //continue with loop
else
- throw std::logic_error("Programming Error: Unknown return value!");
+ throw std::logic_error("Programming Error: Unknown return value! (3)");
}
}
}
@@ -372,8 +400,8 @@ bool dependencyExists(const std::set<Zstring>& folders, const Zstring& newFolder
Zstring newFolderFmt = newFolder;
Zstring refFolderFmt = *i;
#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case
- newFolderFmt.MakeLower();
- refFolderFmt.MakeLower();
+ newFolderFmt.MakeUpper();
+ refFolderFmt.MakeUpper();
#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case
//nothing to do here
#endif
@@ -419,6 +447,7 @@ bool foldersHaveDependencies(const std::vector<FolderPairCfg>& folderPairsFrom,
CompareProcess::CompareProcess(const bool traverseSymLinks,
const unsigned int fileTimeTol,
const bool ignoreOneHourDiff,
+ const unsigned int detectRenameThreshold,
xmlAccess::OptionalDialogs& warnings,
StatusHandler* handler) :
fileTimeTolerance(fileTimeTol),
@@ -427,7 +456,7 @@ CompareProcess::CompareProcess(const bool traverseSymLinks,
statusUpdater(handler),
txtComparingContentOfFiles(wxToZ(_("Comparing content of files %x")).Replace(DefaultStr("%x"), DefaultStr("\n\"%x\""), false))
{
- directoryBuffer.reset(new DirectoryBuffer(traverseSymLinks, handler));
+ directoryBuffer.reset(new DirectoryBuffer(traverseSymLinks, detectRenameThreshold, handler));
}
@@ -447,7 +476,7 @@ bool filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, Co
static boost::scoped_array<unsigned char> memory2(new unsigned char[BUFFER_SIZE]);
#ifdef FFS_WIN
- wxFFile file1(filename1.c_str(), DefaultStr("rb"));
+ wxFFile file1(FreeFileSync::applyLongPathPrefix(filename1).c_str(), DefaultStr("rb"));
#elif defined FFS_LINUX
wxFFile file1(::fopen(filename1.c_str(), DefaultStr("rb"))); //utilize UTF-8 filename
#endif
@@ -455,7 +484,7 @@ bool filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, Co
throw FileError(wxString(_("Error opening file:")) + wxT(" \"") + zToWx(filename1) + wxT("\""));
#ifdef FFS_WIN
- wxFFile file2(filename2.c_str(), DefaultStr("rb"));
+ wxFFile file2(FreeFileSync::applyLongPathPrefix(filename2).c_str(), DefaultStr("rb"));
#elif defined FFS_LINUX
wxFFile file2(::fopen(filename2.c_str(), DefaultStr("rb"))); //utilize UTF-8 filename
#endif
@@ -551,7 +580,7 @@ struct ToBeRemoved
class RemoveFilteredDirs
{
public:
- RemoveFilteredDirs(const FilterProcess& filterProc) :
+ RemoveFilteredDirs(const BaseFilter& filterProc) :
filterProc_(filterProc) {}
void execute(HierarchyObject& hierObj)
@@ -573,7 +602,7 @@ private:
execute(dirObj);
}
- const FilterProcess& filterProc_;
+ const BaseFilter& filterProc_;
};
@@ -695,15 +724,25 @@ wxString getConflictInvalidDate(const Zstring& fileNameFull, const wxLongLong& u
}
+namespace
+{
+inline
+void makeSameLength(wxString& first, wxString& second)
+{
+ const size_t maxPref = std::max(first.length(), second.length());
+ first.Pad(maxPref - first.length(), wxT(' '), true);
+ second.Pad(maxPref - second.length(), wxT(' '), true);
+}
+}
+
+
//check for changed files with same modification date
wxString getConflictSameDateDiffSize(const FileMapping& fileObj)
{
//some beautification...
wxString left = wxString(_("Left")) + wxT(": ");
wxString right = wxString(_("Right")) + wxT(": ");
- const size_t maxPref = std::max(left.length(), right.length());
- left.Pad(maxPref - left.length(), wxT(' '), true);
- right.Pad(maxPref - right.length(), wxT(' '), true);
+ makeSameLength(left, right);
wxString msg = _("Files %x have the same date but a different size!");
msg.Replace(wxT("%x"), wxString(wxT("\"")) + zToWx(fileObj.getRelativeName<LEFT_SIDE>()) + wxT("\""));
@@ -722,9 +761,7 @@ wxString getConflictChangeWithinHour(const FileMapping& fileObj)
//some beautification...
wxString left = wxString(_("Left")) + wxT(": ");
wxString right = wxString(_("Right")) + wxT(": ");
- const size_t maxPref = std::max(left.length(), right.length());
- left.Pad(maxPref - left.length(), wxT(' '), true);
- right.Pad(maxPref - right.length(), wxT(' '), true);
+ makeSameLength(left, right);
wxString msg = _("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.");
msg += wxString(wxT("\n")) + _("(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".)");
@@ -880,7 +917,7 @@ void CompareProcess::compareByContent(const std::vector<FolderPairCfg>& director
- const size_t objectsTotal = filesToCompareBytewise.size() * 2;
+ const size_t objectsTotal = filesToCompareBytewise.size() * 2;
const wxULongLong bytesTotal = getBytesToCompare(filesToCompareBytewise);
statusUpdater->initNewProcess(objectsTotal,
@@ -1060,4 +1097,3 @@ void CompareProcess::performBaseComparison(BaseDirMapping& output, std::vector<F
MergeSides(appendUndefined).execute(directoryLeft, directoryRight, output);
}
-
diff --git a/comparison.h b/comparison.h
index 3a7492c6..59ee582c 100644
--- a/comparison.h
+++ b/comparison.h
@@ -13,7 +13,7 @@ struct FolderPairCfg
{
FolderPairCfg(const Zstring& leftDir,
const Zstring& rightDir,
- const FilterProcess::FilterRef& filterIn,
+ const BaseFilter::FilterRef& filterIn,
const SyncConfiguration& syncCfg) :
leftDirectory(leftDir),
rightDirectory(rightDir),
@@ -23,7 +23,7 @@ struct FolderPairCfg
Zstring leftDirectory;
Zstring rightDirectory;
- FilterProcess::FilterRef filter; //filter interface: always bound by design!
+ BaseFilter::FilterRef filter; //filter interface: always bound by design!
SyncConfiguration syncConfiguration;
};
@@ -34,9 +34,13 @@ std::vector<FolderPairCfg> extractCompareCfg(const MainConfiguration& mainCfg);
class CompareProcess
{
public:
- CompareProcess(const bool traverseSymLinks,
- const unsigned int fileTimeTol,
- const bool ignoreOneHourDiff,
+ CompareProcess(bool traverseSymLinks,
+ unsigned int fileTimeTol,
+ bool ignoreOneHourDiff,
+#ifndef _MSC_VER
+#warning remove threshold, if not used!
+#endif
+ unsigned int detectRenameThreshold,
xmlAccess::OptionalDialogs& warnings,
StatusHandler* handler);
diff --git a/fileHierarchy.cpp b/fileHierarchy.cpp
index e27d9421..6316edf9 100644
--- a/fileHierarchy.cpp
+++ b/fileHierarchy.cpp
@@ -8,9 +8,11 @@
#include "shared/fileHandling.h"
#include <wx/mstream.h>
#include "shared/serialize.h"
+#include "shared/buildInfo.h"
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "shared/longPathPrefix.h"
#endif
using namespace FreeFileSync;
@@ -110,7 +112,10 @@ SyncOperation FileSystemObject::getSyncOperation(const CompareFilesResult cmpRes
const bool selectedForSynchronization,
const SyncDirectionIntern syncDir)
{
- if (!selectedForSynchronization) return SO_DO_NOTHING;
+ if (!selectedForSynchronization)
+ return cmpResult == FILE_EQUAL ?
+ SO_EQUAL :
+ SO_DO_NOTHING;
switch (cmpResult)
{
@@ -173,7 +178,7 @@ SyncOperation FileSystemObject::getSyncOperation(const CompareFilesResult cmpRes
case FILE_EQUAL:
assert(syncDir == SYNC_DIR_INT_NONE);
- return SO_DO_NOTHING;
+ return SO_EQUAL;
}
return SO_DO_NOTHING; //dummy
@@ -194,7 +199,7 @@ const Zstring& FreeFileSync::getSyncDBFilename()
//-------------------------------------------------------------------------------------------------------------------------------
const char FILE_FORMAT_DESCR[] = "FreeFileSync";
-const int FILE_FORMAT_VER = 3;
+const int FILE_FORMAT_VER = Utility::is64BitBuild ? -3 : 3; //32 and 64 bit builds are binary incompatible! So give them different IDs
//-------------------------------------------------------------------------------------------------------------------------------
@@ -204,7 +209,7 @@ public:
ReadDirInfo(wxInputStream& stream, const wxString& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName)
{
//read filter settings
- dirInfo.filter = FilterProcess::loadFilter(stream_);
+ dirInfo.filter = BaseFilter::loadFilter(stream_);
check();
//start recursion
@@ -234,8 +239,12 @@ private:
const unsigned long sizeHigh = readNumberC<unsigned long>();
const unsigned long sizeLow = readNumberC<unsigned long>();
+ //const Utility::FileID fileIdentifier(stream_);
+ //check();
+
dirCont.addSubFile(shortName,
- FileDescriptor(wxLongLong(modHigh, modLow), wxULongLong(sizeHigh, sizeLow)));
+ FileDescriptor(wxLongLong(modHigh, modLow),
+ wxULongLong(sizeHigh, sizeLow)));
}
void readSubDirectory(DirContainer& dirCont)
@@ -400,6 +409,9 @@ private:
writeNumberC<unsigned long>(fileMap.getLastWriteTime<side>().GetLo()); //
writeNumberC<unsigned long>(fileMap.getFileSize<side>().GetHi()); //filesize
writeNumberC<unsigned long>(fileMap.getFileSize<side>().GetLo()); //
+
+ //fileMap.getFileID<side>().toStream(stream_); //unique file identifier
+ //check();
}
}
@@ -464,7 +476,7 @@ void saveFile(const DbStreamData& dbStream, const Zstring& filename) //throw (Fi
//(try to) hide database file
#ifdef FFS_WIN
output.Close();
- ::SetFileAttributes(filename.c_str(), FILE_ATTRIBUTE_HIDDEN);
+ ::SetFileAttributes(FreeFileSync::applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_HIDDEN);
#endif
}
@@ -533,7 +545,6 @@ void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileEr
removeFile(baseMapping.getDBFilename<RIGHT_SIDE>(), false);
renameFile(fileNameLeftTmp, baseMapping.getDBFilename<LEFT_SIDE>()); //throw (FileError);
renameFile(fileNameRightTmp, baseMapping.getDBFilename<RIGHT_SIDE>()); //throw (FileError);
-
}
catch (...)
{
@@ -548,3 +559,4 @@ void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileEr
}
}
+
diff --git a/fileHierarchy.h b/fileHierarchy.h
index d26d527e..ca029354 100644
--- a/fileHierarchy.h
+++ b/fileHierarchy.h
@@ -11,6 +11,7 @@
#include <boost/shared_ptr.hpp>
#include "shared/guid.h"
#include "library/filter.h"
+#include "shared/fileID.h"
class DirectoryBuffer;
@@ -19,11 +20,16 @@ namespace FreeFileSync
{
struct FileDescriptor
{
- FileDescriptor(const wxLongLong& lastWriteTimeRawIn, const wxULongLong& fileSizeIn) :
+ FileDescriptor(const wxLongLong& lastWriteTimeRawIn,
+ const wxULongLong& fileSizeIn) :
+ //const Utility::FileID fileId) :
lastWriteTimeRaw(lastWriteTimeRawIn),
fileSize(fileSizeIn) {}
- wxLongLong lastWriteTimeRaw; //number of seconds since Jan. 1st 1970 UTC, same semantics like time_t (== signed long)
+ wxLongLong lastWriteTimeRaw; //number of seconds since Jan. 1st 1970 UTC, same semantics like time_t (== signed long)
wxULongLong fileSize;
+
+ //#warning: what about memory consumption?? (assume large comparisons!!?)
+ //Utility::FileID fileIdentifier; //unique file identifier, optional: may be NULL!
};
@@ -96,7 +102,7 @@ private:
struct DirInformation
{
//filter settings (used when retrieving directory data)
- FilterProcess::FilterRef filter;
+ BaseFilter::FilterRef filter;
//hierarchical directory information
DirContainer baseDirContainer;
@@ -198,7 +204,7 @@ class FileSystemObject
public:
const Zstring getParentRelativeName() const; //get name relative to base sync dir without FILE_NAME_SEPARATOR postfix
const Zstring getObjRelativeName() const; //same as getRelativeName() but also returns value if either side is empty
- const Zstring& getObjShortName() const; //same as getShortName() but also returns value if either side is empty
+ const Zstring& getObjShortName() const; //same as getShortName() but also returns value if either side is empty
template <SelectedSide side> bool isEmpty() const;
template <SelectedSide side> const Zstring& getShortName() const;
template <SelectedSide side> const Zstring getRelativeName() const; //get name relative to base sync dir without FILE_NAME_SEPARATOR prefix
@@ -310,6 +316,7 @@ class FileMapping : public FileSystemObject
public:
template <SelectedSide side> const wxLongLong& getLastWriteTime() const;
template <SelectedSide side> const wxULongLong& getFileSize() const;
+ //template <SelectedSide side> const Utility::FileID& getFileID() const;
virtual CompareFilesResult getCategory() const;
virtual const wxString& getCatConflict() const;
@@ -367,16 +374,16 @@ class BaseDirMapping : public HierarchyObject //synchronization base directory
public:
BaseDirMapping(const Zstring& dirPostfixedLeft,
const Zstring& dirPostfixedRight,
- const FilterProcess::FilterRef& filterIn) :
+ const BaseFilter::FilterRef& filterIn) :
HierarchyObject(dirPostfixedLeft, dirPostfixedRight),
filter(filterIn) {}
- const FilterProcess::FilterRef& getFilter() const;
+ const BaseFilter::FilterRef& getFilter() const;
template <SelectedSide side> Zstring getDBFilename() const;
virtual void swap();
private:
- FilterProcess::FilterRef filter;
+ BaseFilter::FilterRef filter;
};
@@ -384,8 +391,9 @@ typedef std::vector<BaseDirMapping> FolderComparison;
//------------------------------------------------------------------
-
-
+//convenience methods
+//test whether FileSystemObject is a DirMapping
+bool isDirectoryMapping(const FileSystemObject& fsObj);
@@ -819,7 +827,7 @@ void DirMapping::copyToR()
inline
-const FilterProcess::FilterRef& BaseDirMapping::getFilter() const
+const BaseFilter::FilterRef& BaseDirMapping::getFilter() const
{
return filter;
}
@@ -888,7 +896,7 @@ inline
void FileMapping::removeObjectL()
{
cmpResult = FILE_RIGHT_SIDE_ONLY;
- dataLeft = FileDescriptor(0, 0);
+ dataLeft = FileDescriptor(0, 0);
}
@@ -904,7 +912,9 @@ inline
void FileMapping::copyToL()
{
cmpResult = FILE_EQUAL;
- dataLeft = dataRight;
+ dataLeft = FileDescriptor(dataRight.lastWriteTimeRaw,
+ dataRight.fileSize);
+ //Utility::FileID()); //attention! do not copy FileID! It is retained on file renaming only!
}
@@ -912,7 +922,9 @@ inline
void FileMapping::copyToR()
{
cmpResult = FILE_EQUAL;
- dataRight = dataLeft;
+ dataRight = FileDescriptor(dataLeft.lastWriteTimeRaw,
+ dataLeft.fileSize);
+ //Utility::FileID()); //attention! do not copy FileID! It is retained on file renaming only!
}
@@ -946,6 +958,31 @@ const wxULongLong& FileMapping::getFileSize<RIGHT_SIDE>() const
{
return dataRight.fileSize;
}
+
+
+//template <>
+//inline
+//const Utility::FileID& FileMapping::getFileID<LEFT_SIDE>() const
+//{
+// return dataLeft.fileIdentifier;
+//}
+//
+//
+//template <>
+//inline
+//const Utility::FileID& FileMapping::getFileID<RIGHT_SIDE>() const
+//{
+// return dataRight.fileIdentifier;
+//}
+
+inline
+bool isDirectoryMapping(const FileSystemObject& fsObj)
+{
+ return dynamic_cast<const DirMapping*>(&fsObj) != NULL;
+}
+
}
#endif // FILEHIERARCHY_H_INCLUDED
+
+
diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp
index 6c72859c..cba76f57 100644
--- a/library/CustomGrid.cpp
+++ b/library/CustomGrid.cpp
@@ -242,7 +242,7 @@ public:
}
//get filename in order to retrieve the icon from it
- virtual Zstring getIconFile(const unsigned int row) const = 0;
+ virtual Zstring getIconFile(const unsigned int row) const = 0; //return "folder" if row points to a folder
protected:
template <SelectedSide side>
@@ -311,7 +311,7 @@ private:
if (!fsObj->isActive())
return COLOR_BLUE;
//mark directories
- else if (dynamic_cast<const DirMapping*>(fsObj) != NULL)
+ else if (isDirectoryMapping(*fsObj))
return COLOR_GREY;
else
return *wxWHITE;
@@ -332,13 +332,18 @@ public:
return CustomGridTableRim::GetValueSub<LEFT_SIDE>(row, col);
}
- virtual Zstring getIconFile(const unsigned int row) const
+ virtual Zstring getIconFile(const unsigned int row) const //return "folder" if row points to a folder
{
const FileSystemObject* fsObj = getRawData(row);
if (fsObj && !fsObj->isEmpty<LEFT_SIDE>())
- return fsObj->getFullName<LEFT_SIDE>();
- else
- return Zstring();
+ {
+ if (isDirectoryMapping(*fsObj)) //it's a directory icon
+ return DefaultStr("folder");
+ else
+ return fsObj->getFullName<LEFT_SIDE>();
+ }
+
+ return Zstring();
}
};
@@ -351,20 +356,25 @@ public:
return CustomGridTableRim::GetValueSub<RIGHT_SIDE>(row, col);
}
- virtual Zstring getIconFile(const unsigned int row) const
+ virtual Zstring getIconFile(const unsigned int row) const //return "folder" if row points to a folder
{
const FileSystemObject* fsObj = getRawData(row);
if (fsObj && !fsObj->isEmpty<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>();
+ if (isDirectoryMapping(*fsObj)) //it's a directory icon
+ return DefaultStr("folder");
else
- 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();
+
+ return Zstring();
}
};
@@ -435,6 +445,7 @@ private:
case SO_UNRESOLVED_CONFLICT:
return COLOR_YELLOW;
case SO_DO_NOTHING:
+ case SO_EQUAL:
return *wxWHITE;
}
}
@@ -873,9 +884,9 @@ void CustomGrid::DrawColLabel(wxDC& dc, int col)
if (col == m_marker.first)
{
if (m_marker.second == ASCENDING)
- dc.DrawBitmap(*GlobalResources::getInstance().bitmapSmallUp, GetColRight(col) - 16 - 2, 2, true); //respect 2-pixel border
+ dc.DrawBitmap(GlobalResources::getInstance().getImageByName(wxT("smallUp")), GetColRight(col) - 16 - 2, 2, true); //respect 2-pixel border
else
- dc.DrawBitmap(*GlobalResources::getInstance().bitmapSmallDown, GetColRight(col) - 16 - 2, 2, true); //respect 2-pixel border
+ dc.DrawBitmap(GlobalResources::getInstance().getImageByName(wxT("smallDown")), GetColRight(col) - 16 - 2, 2, true); //respect 2-pixel border
}
}
@@ -980,39 +991,48 @@ public:
const Zstring fileName = m_gridDataTable->getIconFile(row);
if (!fileName.empty())
{
- wxIcon icon;
- bool iconDrawnFully = false;
- const bool iconLoaded = IconBuffer::getInstance().requestIcon(fileName, &icon); //returns false if icon is not in buffer
- if (iconLoaded)
+ //first check if it is a directory icon:
+ if (fileName == DefaultStr("folder"))
{
- dc.DrawIcon(icon, rectShrinked.GetX() + LEFT_BORDER, rectShrinked.GetY());
+ dc.DrawIcon(IconBuffer::getDirectoryIcon(), rectShrinked.GetX() + LEFT_BORDER, rectShrinked.GetY());
+ m_loadIconSuccess[row] = true; //save status of last icon load -> used for async. icon loading
+ }
+ else //retrieve file icon
+ {
+ wxIcon icon;
+ bool iconDrawnFully = false;
+ const bool iconLoaded = IconBuffer::getInstance().requestFileIcon(fileName, &icon); //returns false if icon is not in buffer
+ if (iconLoaded)
+ {
+ dc.DrawIcon(icon, rectShrinked.GetX() + LEFT_BORDER, rectShrinked.GetY());
- //-----------------------------------------------------------------------------------------------
- //only mark as successful if icon was drawn fully!
- //(attention: when scrolling, rows get partially updated, which can result in the upper half being blank!)
+ //-----------------------------------------------------------------------------------------------
+ //only mark as successful if icon was drawn fully!
+ //(attention: when scrolling, rows get partially updated, which can result in the upper half being blank!)
- //rect where icon was placed
- wxRect iconRect(rect); //unscrolled
- iconRect.x += LEFT_BORDER;
- iconRect.SetWidth(IconBuffer::ICON_SIZE);
+ //rect where icon was placed
+ wxRect iconRect(rect); //unscrolled
+ iconRect.x += LEFT_BORDER;
+ iconRect.SetWidth(IconBuffer::ICON_SIZE);
- //convert to scrolled coordinates
- grid.CalcScrolledPosition(iconRect.x, iconRect.y, &iconRect.x, &iconRect.y);
+ //convert to scrolled coordinates
+ grid.CalcScrolledPosition(iconRect.x, iconRect.y, &iconRect.x, &iconRect.y);
- wxRegionIterator regionsInv(grid.GetGridWindow()->GetUpdateRegion());
- while (regionsInv)
- {
- if (regionsInv.GetRect().Contains(iconRect))
+ wxRegionIterator regionsInv(grid.GetGridWindow()->GetUpdateRegion());
+ while (regionsInv)
{
- iconDrawnFully = true;
- break;
+ if (regionsInv.GetRect().Contains(iconRect))
+ {
+ iconDrawnFully = true;
+ break;
+ }
+ ++regionsInv;
}
- ++regionsInv;
}
+ //-----------------------------------------------------------------------------------------------
+ //save status of last icon load -> used for async. icon loading
+ m_loadIconSuccess[row] = iconLoaded && iconDrawnFully;
}
- //-----------------------------------------------------------------------------------------------
- //save status of last icon load -> used for async. icon loading
- m_loadIconSuccess[row] = iconLoaded && iconDrawnFully;
}
}
return;
@@ -1364,7 +1384,7 @@ void CustomGridRim::getIconsToBeLoaded(std::vector<Zstring>& newLoad) //loads al
if (!fileName.empty())
{
//test if they are already loaded in buffer:
- if (FreeFileSync::IconBuffer::getInstance().requestIcon(fileName))
+ if (FreeFileSync::IconBuffer::getInstance().requestFileIcon(fileName))
{
//exists in buffer: refresh Row
for (int k = 0; k < totalCols; ++k)
@@ -1644,28 +1664,31 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
switch (syncOp)
{
case SO_CREATE_NEW_LEFT:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncCreateLeftAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncCreateLeftAct")));
break;
case SO_CREATE_NEW_RIGHT:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncCreateRightAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncCreateRightAct")));
break;
case SO_DELETE_LEFT:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncDeleteLeftAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDeleteLeftAct")));
break;
case SO_DELETE_RIGHT:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncDeleteRightAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDeleteRightAct")));
break;
case SO_OVERWRITE_LEFT:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncDirLeftAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDirLeftAct")));
break;
case SO_OVERWRITE_RIGHT:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncDirRightAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDirRightAct")));
break;
case SO_DO_NOTHING:
- toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncDirNoneAct);
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDirNoneAct")));
+ break;
+ case SO_EQUAL:
+ toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("equalAct")));
break;
case SO_UNRESOLVED_CONFLICT:
- toolTip->show(fsObj->getSyncOpConflict(), pos, GlobalResources::getInstance().bitmapConflictAct);
+ toolTip->show(fsObj->getSyncOpConflict(), pos, &GlobalResources::getInstance().getImageByName(wxT("conflictAct")));
break;
};
}
@@ -1675,25 +1698,25 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
switch (cmpRes)
{
case FILE_LEFT_SIDE_ONLY:
- toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapLeftOnlyAct);
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("leftOnlyAct")));
break;
case FILE_RIGHT_SIDE_ONLY:
- toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapRightOnlyAct);
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("rightOnlyAct")));
break;
case FILE_LEFT_NEWER:
- toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapLeftNewerAct);
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("leftNewerAct")));
break;
case FILE_RIGHT_NEWER:
- toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapRightNewerAct);
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("rightNewerAct")));
break;
case FILE_DIFFERENT:
- toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapDifferentAct);
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("differentAct")));
break;
case FILE_EQUAL:
- toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapEqualAct);
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("equalAct")));
break;
case FILE_CONFLICT:
- toolTip->show(fsObj->getCatConflict(), pos, GlobalResources::getInstance().bitmapConflictAct);
+ toolTip->show(fsObj->getCatConflict(), pos, &GlobalResources::getInstance().getImageByName(wxT("conflictAct")));
break;
}
}
@@ -1767,26 +1790,32 @@ int CustomGridMiddle::mousePosToRow(const wxPoint pos, BlockPosition* block)
if (block)
{
*block = BLOCKPOS_CHECK_BOX; //default
- if (gridDataTable->syncPreviewIsActive() &&
- row >= 0)
- {
- // cell:
- // ----------------------------------
- // | checkbox | left | middle | right|
- // ----------------------------------
- const wxRect rect = CellToRect(row, 0);
- if (rect.GetWidth() > CHECK_BOX_WIDTH)
+ if (row >= 0)
+ {
+ const FileSystemObject* const fsObj = gridDataTable->getRawData(row);
+ if ( fsObj != NULL && //if valid row...
+ gridDataTable->syncPreviewIsActive() &&
+ fsObj->getSyncOperation() != SO_EQUAL) //in sync-preview equal files shall be treated as in cmp result, i.e. as full checkbox
{
- const double blockWidth = (rect.GetWidth() - CHECK_BOX_WIDTH) / 3.0;
- if (rect.GetX() + CHECK_BOX_WIDTH <= x && x < rect.GetX() + rect.GetWidth())
+ // cell:
+ // ----------------------------------
+ // | checkbox | left | middle | right|
+ // ----------------------------------
+
+ const wxRect rect = CellToRect(row, 0);
+ if (rect.GetWidth() > CHECK_BOX_WIDTH)
{
- if (x - (rect.GetX() + CHECK_BOX_WIDTH) < blockWidth)
- *block = BLOCKPOS_LEFT;
- else if (x - (rect.GetX() + CHECK_BOX_WIDTH) < 2 * blockWidth)
- *block = BLOCKPOS_MIDDLE;
- else
- *block = BLOCKPOS_RIGHT;
+ const double blockWidth = (rect.GetWidth() - CHECK_BOX_WIDTH) / 3.0;
+ if (rect.GetX() + CHECK_BOX_WIDTH <= x && x < rect.GetX() + rect.GetWidth())
+ {
+ if (x - (rect.GetX() + CHECK_BOX_WIDTH) < blockWidth)
+ *block = BLOCKPOS_LEFT;
+ else if (x - (rect.GetX() + CHECK_BOX_WIDTH) < 2 * blockWidth)
+ *block = BLOCKPOS_MIDDLE;
+ else
+ *block = BLOCKPOS_RIGHT;
+ }
}
}
}
@@ -1831,22 +1860,23 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
rectShrinked.SetWidth(CHECK_BOX_WIDTH);
wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
- //print image into first block
+ //print checkbox into first block
rectShrinked.SetX(rect.GetX() + 1);
- //HIGHLIGHTNING:
- if (rowIsHighlighted && m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ //HIGHLIGHTNING (checkbox):
+ if ( rowIsHighlighted &&
+ m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
{
if (fsObj->isActive())
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxTrueFocus, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("checkboxTrueFocus")), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
else
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxFalseFocus, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("checkboxFalseFocus")), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
}
//default
else if (fsObj->isActive())
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxTrue, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("checkboxTrue")), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
else
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxFalse, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("checkboxFalse")), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
//clean remaining block of rect that will receive image of checkbox/directions
rectShrinked.SetWidth(rect.GetWidth() - CHECK_BOX_WIDTH);
@@ -1858,8 +1888,9 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
{
//print sync direction into second block
- //HIGHLIGHTNING:
- if (rowIsHighlighted && m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ //HIGHLIGHTNING (sync direction):
+ if ( rowIsHighlighted &&
+ m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX) //don't allow changing direction for "=="-files
switch (m_gridMiddle->highlightedPos)
{
case CustomGridMiddle::BLOCKPOS_CHECK_BOX:
@@ -1885,25 +1916,25 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
switch (fsObj->getCategory())
{
case FILE_LEFT_SIDE_ONLY:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapLeftOnlySmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("leftOnlySmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_RIGHT_SIDE_ONLY:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapRightOnlySmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("rightOnlySmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_LEFT_NEWER:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapLeftNewerSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("leftNewerSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_RIGHT_NEWER:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapRightNewerSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("rightNewerSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_DIFFERENT:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapDifferentSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("differentSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_EQUAL:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapEqualSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("equalSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_CONFLICT:
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapConflictSmall, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("conflictSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
}
}
@@ -1935,9 +1966,9 @@ void CustomGridMiddle::DrawColLabel(wxDC& dc, int col)
const wxRect rect(GetColLeft(col), 0, GetColWidth(col), GetColLabelSize());
if (gridDataTable->syncPreviewIsActive())
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapSyncViewSmall, rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("syncViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
else
- dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCmpViewSmall, rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("cmpViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
}
@@ -1946,21 +1977,23 @@ const wxBitmap& FreeFileSync::getSyncOpImage(SyncOperation syncOp)
switch (syncOp) //evaluate comparison result and sync direction
{
case SO_CREATE_NEW_LEFT:
- return *GlobalResources::getInstance().bitmapCreateLeftSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("createLeftSmall"));
case SO_CREATE_NEW_RIGHT:
- return *GlobalResources::getInstance().bitmapCreateRightSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("createRightSmall"));
case SO_DELETE_LEFT:
- return *GlobalResources::getInstance().bitmapDeleteLeftSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("deleteLeftSmall"));
case SO_DELETE_RIGHT:
- return *GlobalResources::getInstance().bitmapDeleteRightSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("deleteRightSmall"));
case SO_OVERWRITE_RIGHT:
- return *GlobalResources::getInstance().bitmapSyncDirRightSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("syncDirRightSmall"));
case SO_OVERWRITE_LEFT:
- return *GlobalResources::getInstance().bitmapSyncDirLeftSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("syncDirLeftSmall"));
case SO_DO_NOTHING:
- return *GlobalResources::getInstance().bitmapSyncDirNoneSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("syncDirNoneSmall"));
+ case SO_EQUAL:
+ return GlobalResources::getInstance().getImageByName(wxT("equalSmall"));
case SO_UNRESOLVED_CONFLICT:
- return *GlobalResources::getInstance().bitmapConflictSmall;
+ return GlobalResources::getInstance().getImageByName(wxT("conflictSmall"));
}
return wxNullBitmap; //dummy
@@ -1970,3 +2003,8 @@ const wxBitmap& FreeFileSync::getSyncOpImage(SyncOperation syncOp)
+
+
+
+
+
diff --git a/library/FreeFileSync.xpm b/library/FreeFileSync.xpm
deleted file mode 100644
index 339ccccb..00000000
--- a/library/FreeFileSync.xpm
+++ /dev/null
@@ -1,425 +0,0 @@
-/* XPM */
-static const char * FreeFileSync_xpm[] = {
-"32 32 390 2",
-" c None",
-". c #005927",
-"+ c #046A38",
-"@ c #1B7E4B",
-"# c #318F5A",
-"$ c #308F56",
-"% c #258C4D",
-"& c #128040",
-"* c #036C36",
-"= c #005A31",
-"- c #005D28",
-"; c #1F7D4E",
-"> c #76B08F",
-", c #ADD9B7",
-"' c #B9EABB",
-") c #A5E9A5",
-"! c #8BE38A",
-"~ c #6DDB6D",
-"{ c #4DD04E",
-"] c #2FC136",
-"^ c #19A82F",
-"/ c #078433",
-"( c #005D33",
-"_ c #036B35",
-": c #6FAA8C",
-"< c #D9EEDE",
-"[ c #E0FDDD",
-"} c #BDF3BB",
-"| c #9BE89A",
-"1 c #7DE07C",
-"2 c #5FD85F",
-"3 c #44D143",
-"4 c #32D131",
-"5 c #2AD929",
-"6 c #25E422",
-"7 c #1CE31C",
-"8 c #0CB522",
-"9 c #017235",
-"0 c #0B6F3B",
-"a c #9EC8B0",
-"b c #EEFFEC",
-"c c #CAF5C9",
-"d c #A7EAA7",
-"e c #8AE38A",
-"f c #6EDB6E",
-"g c #51D351",
-"h c #39CF38",
-"i c #2CD32B",
-"j c #26DB26",
-"k c #20E11F",
-"l c #19E719",
-"m c #13EF12",
-"n c #0CFE08",
-"o c #03DB0F",
-"p c #007F31",
-"q c #056B36",
-"r c #98C7AA",
-"s c #E3FEE0",
-"t c #B8EEB7",
-"u c #99E699",
-"v c #7DDF7D",
-"w c #60D760",
-"x c #45D144",
-"y c #33D530",
-"z c #2ADA28",
-"A c #23DC23",
-"B c #1CE41C",
-"C c #16F113",
-"D c #0FF90C",
-"E c #08FA07",
-"F c #02FE02",
-"G c #00FF00",
-"H c #00E20A",
-"I c #007434",
-"J c #005E2F",
-"K c #005E30",
-"L c #005B2E",
-"M c #005D2E",
-"N c #6BAB87",
-"O c #D5FAD2",
-"P c #AAEAAA",
-"Q c #8CE28C",
-"R c #70DB70",
-"S c #53D453",
-"T c #3BD13A",
-"U c #2DD42C",
-"V c #1CB72C",
-"W c #0D9830",
-"X c #078931",
-"Y c #068D2F",
-"Z c #06A527",
-"` c #04CF14",
-" . c #00FC02",
-".. c #00C914",
-"+. c #1A8347",
-"@. c #5ABA6B",
-"#. c #4FBA60",
-"$. c #36AA4A",
-"%. c #299E42",
-"&. c #8FDF92",
-"*. c #81DE81",
-"=. c #65D665",
-"-. c #47D047",
-";. c #33D232",
-">. c #27CE2A",
-",. c #0D8F30",
-"'. c #005A2F",
-"). c #005F33",
-"!. c #008A2C",
-"~. c #00D210",
-"{. c #009629",
-"]. c #369C56",
-"^. c #81E87D",
-"/. c #66DE63",
-"(. c #50D94D",
-"_. c #3BD538",
-":. c #2CD52B",
-"<. c #2DDD2D",
-"[. c #34E034",
-"}. c #2FDB2F",
-"|. c #29D728",
-"1. c #25D228",
-"2. c #098033",
-"3. c #00502E",
-"4. c #006536",
-"5. c #00A820",
-"6. c #00F802",
-"7. c #00D510",
-"8. c #005D31",
-"9. c #1D8945",
-"0. c #60D860",
-"a. c #4AD34A",
-"b. c #36CF36",
-"c. c #2BD42B",
-"d. c #22DC22",
-"e. c #19E419",
-"f. c #0FED0F",
-"g. c #08F608",
-"h. c #05FE03",
-"i. c #05E80B",
-"j. c #009E21",
-"k. c #006832",
-"l. c #005734",
-"m. c #009029",
-"n. c #00EF05",
-"o. c #00832D",
-"p. c #057238",
-"q. c #40C646",
-"r. c #38D137",
-"s. c #1BE41B",
-"t. c #13ED13",
-"u. c #0AF50A",
-"v. c #02FD02",
-"w. c #00DF0C",
-"x. c #008730",
-"y. c #004F30",
-"z. c #00852C",
-"A. c #00F105",
-"B. c #00B41F",
-"C. c #005E32",
-"D. c #1DA434",
-"E. c #2EDA2B",
-"F. c #00A426",
-"G. c #008C27",
-"H. c #00B91B",
-"I. c #098234",
-"J. c #23DB23",
-"K. c #1CE61B",
-"L. c #00C019",
-"M. c #006131",
-"N. c #006233",
-"O. c #006E2B",
-"P. c #00622F",
-"Q. c #006535",
-"R. c #12BD23",
-"S. c #14F511",
-"T. c #00EE07",
-"U. c #00A424",
-"V. c #00612F",
-"W. c #3A8D63",
-"X. c #8ABBA3",
-"Y. c #B3D1C2",
-"Z. c #468F6D",
-"`. c #005E2A",
-" + c #038230",
-".+ c #0AEF0C",
-"++ c #03FF02",
-"@+ c #00F703",
-"#+ c #007931",
-"$+ c #006230",
-"%+ c #509A75",
-"&+ c #BBD6C9",
-"*+ c #FEFEFF",
-"=+ c #FFFFFF",
-"-+ c #E6F2EB",
-";+ c #1F7C4D",
-">+ c #005D35",
-",+ c #009624",
-"'+ c #00FC01",
-")+ c #00ED07",
-"!+ c #00BC1A",
-"~+ c #00812F",
-"{+ c #004E2E",
-"]+ c #378C60",
-"^+ c #B5D5C3",
-"/+ c #FAFFFA",
-"(+ c #FBFFF9",
-"_+ c #ECFCEB",
-":+ c #E1F8E1",
-"<+ c #D8F6D8",
-"[+ c #DBFCD8",
-"}+ c #7BBE8F",
-"|+ c #009022",
-"1+ c #009823",
-"2+ c #007030",
-"3+ c #00492B",
-"4+ c #046734",
-"5+ c #65AE81",
-"6+ c #D0F3D1",
-"7+ c #D8FBD6",
-"8+ c #C3F2C3",
-"9+ c #B7EEB7",
-"0+ c #AEECAE",
-"a+ c #A5EAA5",
-"b+ c #9CE79C",
-"c+ c #94E694",
-"d+ c #89E189",
-"e+ c #198446",
-"f+ c #31895D",
-"g+ c #116C44",
-"h+ c #00502A",
-"i+ c #036230",
-"j+ c #62B878",
-"k+ c #AEF1AC",
-"l+ c #9DE99C",
-"m+ c #8FE38F",
-"n+ c #86E186",
-"o+ c #7CDE7C",
-"p+ c #73DC73",
-"q+ c #6AD96A",
-"r+ c #61D761",
-"s+ c #57D457",
-"t+ c #53D951",
-"u+ c #2CA941",
-"v+ c #005F31",
-"w+ c #549F7A",
-"x+ c #B0D0C1",
-"y+ c #0B6A38",
-"z+ c #0D773D",
-"A+ c #6EDB6F",
-"B+ c #6BDF67",
-"C+ c #5DD65D",
-"D+ c #55D355",
-"E+ c #4BD24B",
-"F+ c #43D143",
-"G+ c #3BD13B",
-"H+ c #34D234",
-"I+ c #2DD42D",
-"J+ c #27D827",
-"K+ c #22DF21",
-"L+ c #1BDB1E",
-"M+ c #027A34",
-"N+ c #167646",
-"O+ c #EDFBEE",
-"P+ c #9FCDAF",
-"Q+ c #0A6E39",
-"R+ c #168C3B",
-"S+ c #2BC034",
-"T+ c #28D828",
-"U+ c #21DD21",
-"V+ c #1EE01E",
-"W+ c #1AE41A",
-"X+ c #15E915",
-"Y+ c #10EE10",
-"Z+ c #0CF30C",
-"`+ c #08F808",
-" @ c #05FB04",
-".@ c #03FE02",
-"+@ c #01A323",
-"@@ c #00592A",
-"#@ c #88C79A",
-"$@ c #DBFFD5",
-"%@ c #88CB97",
-"&@ c #157942",
-"*@ c #006732",
-"=@ c #1FB431",
-"-@ c #24EC22",
-";@ c #0CF40C",
-">@ c #00C515",
-",@ c #005A33",
-"'@ c #309358",
-")@ c #A4ECA3",
-"!@ c #A3EDA0",
-"~@ c #7DD584",
-"{@ c #288E4B",
-"]@ c #006232",
-"^@ c #0F8535",
-"/@ c #36C739",
-"(@ c #35D334",
-"_@ c #29D729",
-":@ c #0FF10F",
-"<@ c #05FB05",
-"[@ c #01FE01",
-"}@ c #00FE00",
-"|@ c #00CB13",
-"1@ c #006135",
-"2@ c #016432",
-"3@ c #5ABF68",
-"4@ c #7AE377",
-"5@ c #71DF6F",
-"6@ c #66DB65",
-"7@ c #39B04A",
-"8@ c #11823A",
-"9@ c #026633",
-"0@ c #00522D",
-"a@ c #036E34",
-"b@ c #129E2E",
-"c@ c #25D826",
-"d@ c #22E221",
-"e@ c #1DE41D",
-"f@ c #19E919",
-"g@ c #15ED15",
-"h@ c #11F210",
-"i@ c #039626",
-"j@ c #008F2A",
-"k@ c #00A323",
-"l@ c #00A522",
-"m@ c #008530",
-"n@ c #00532D",
-"o@ c #0F7F3D",
-"p@ c #4BCE4E",
-"q@ c #49D547",
-"r@ c #41D040",
-"s@ c #3ED63B",
-"t@ c #33D133",
-"u@ c #23BF2E",
-"v@ c #17AF2C",
-"w@ c #12AE2B",
-"x@ c #11B826",
-"y@ c #17D71E",
-"z@ c #18EF15",
-"A@ c #12F211",
-"B@ c #05FC05",
-"C@ c #00B919",
-"D@ c #005C35",
-"E@ c #0F8C35",
-"F@ c #2AD52A",
-"G@ c #27DE25",
-"H@ c #21DE22",
-"I@ c #1EE41D",
-"J@ c #1BEC19",
-"K@ c #17F314",
-"L@ c #12F90F",
-"M@ c #0DFD0A",
-"N@ c #08FD06",
-"O@ c #03FD03",
-"P@ c #00CB12",
-"Q@ c #006C37",
-"R@ c #00562F",
-"S@ c #07912F",
-"T@ c #12E316",
-"U@ c #0DFC0A",
-"V@ c #09FA09",
-"W@ c #01FF01",
-"X@ c #00BE18",
-"Y@ c #006D37",
-"Z@ c #008030",
-"`@ c #00C814",
-" # c #00FA02",
-".# c #00DD0C",
-"+# c #009827",
-"@# c #006437",
-"## c #00852E",
-"$# c #00B11E",
-"%# c #00D111",
-"&# c #00E40A",
-"*# c #00EF06",
-"=# c #00E908",
-"-# c #00D80E",
-";# c #00BD18",
-"># c #009528",
-",# c #006D35",
-"'# c #004F2E",
-")# c #00492C",
-"!# c #006032",
-"~# c #006A32",
-"{# c #006D31",
-"]# c #006B31",
-"^# c #006533",
-"/# c #005631",
-" ",
-" ",
-" . + @ # $ % & * = ",
-" - ; > , ' ) ! ~ { ] ^ / ( ",
-" _ : < [ } | 1 2 3 4 5 6 7 8 9 ",
-" 0 a b c d e f g h i j k l m n o p ",
-" q r s t u v w x y z A B C D E F G H I ",
-" J K L M N O P Q R S T U V W X Y Z ` .G G G ..( ",
-" +.@.#.$.%.&.| *.=.-.;.>.,.'. ).!.~.G G G {. ",
-" ].^./.(._.:.<.[.}.|.1.2.3. 4.5.6.G 7.8. ",
-" 9.0.a.b.c.d.e.f.g.h.i.j.k. l.m.n.G o. ",
-" p.q.r.c.A s.t.u.v.G G G w.x. y.z.A.B. ",
-" C.D.E.A s.t.u.v.G G G G G F. G.H. ",
-" I.J.K.t.u.v.G G G G G L.M. N.O.P. ",
-" Q.R.S.u.v.G G G G T.U.= V.W.X.Y.Z.`. ",
-" +.+++G G G @+L.#+ $+%+&+*+=+=+-+;+ ",
-" >+,+'+G )+!+~+{+ ]+^+/+(+_+:+<+[+}+V. ",
-" N.|+1+2+3+ 4+5+6+7+8+9+0+a+b+c+d+e+ ",
-" f+g+h+ i+j+k+l+m+n+o+p+q+r+s+t+u+v+ ",
-" w+x+y+ z+A+B+C+D+E+F+G+H+I+J+K+L+M+ ",
-" N+O+P+Q+ L R+S+T+U+V+W+X+Y+Z+`+ @.@+@ ",
-" @@#@$@%@&@ *@=@-@;@v.G G G G G G >@,@ ",
-" '@)@!@~@{@]@ ^@/@(@_@s.:@<@[@}@G G |@1@ ",
-" 2@3@4@5@6@7@8@9@0@ a@b@c@d@e@f@g@h@u.i@j@k@l@m@n@ ",
-" o@p@q@r@s@t@u@v@w@x@y@z@A@;@`+B@F G C@D@ ",
-" E@F@G@H@I@J@K@L@M@N@O@[@G G G G P@Q@ ",
-" R@S@T@U@V@B@v.W@G G G G G G G X@Y@ ",
-" Z@`@ #G G G G G G G G .#+#@# ",
-" ( ##$#%#&#*#=#-#;#>#,#'# ",
-" )#!#~#{#]#^#/# ",
-" ",
-" "};
diff --git a/library/Recycler/Recycler_Vista.vcproj b/library/Recycler/Recycler_Vista.vcproj
new file mode 100644
index 00000000..65ab6609
--- /dev/null
+++ b/library/Recycler/Recycler_Vista.vcproj
@@ -0,0 +1,409 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="Vista Recycler"
+ 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;RECYCLER_DLL_EXPORTS"
+ 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="Recycler_$(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;RECYCLER_DLL_EXPORTS"
+ 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="Recycler_$(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;RECYCLER_DLL_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="Recycler_$(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;RECYCLER_DLL_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="Recycler_$(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>
+ </Filter>
+ <Filter
+ Name="Headerdateien"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\recycler.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\recycler.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/library/Recycler/dllmain.cpp b/library/Recycler/dllmain.cpp
new file mode 100644
index 00000000..834b4f88
--- /dev/null
+++ b/library/Recycler/dllmain.cpp
@@ -0,0 +1,22 @@
+// dllmain.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
diff --git a/library/Recycler/recycler.cpp b/library/Recycler/recycler.cpp
new file mode 100644
index 00000000..b551d4d0
--- /dev/null
+++ b/library/Recycler/recycler.cpp
@@ -0,0 +1,142 @@
+#include "recycler.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#include <Shellapi.h> // Included for shell constants such as FO_* values
+#include <shobjidl.h> // Required for necessary shell dependencies
+
+#include <algorithm>
+#include <string>
+#include <cstdio>
+#include <comdef.h>
+
+
+void writeString(const wchar_t* input, wchar_t* output, size_t outputBufferLen)
+{
+ const size_t newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination
+ memcpy(output, input, newSize * sizeof(wchar_t));
+ output[newSize-1] = 0; //if output buffer is too small...
+}
+
+
+std::wstring numberToHexString(const long number)
+{
+ wchar_t result[100];
+ swprintf(result, 100, L"0x%08x", number);
+ return std::wstring(result);
+}
+
+
+void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, size_t outputBufferLen)
+{
+ std::wstring formattedMsg(input);
+ formattedMsg += L" (";
+ formattedMsg += numberToHexString(hr);
+ formattedMsg += L": ";
+ formattedMsg += _com_error(hr).ErrorMessage();
+ formattedMsg += L")";
+
+ writeString(formattedMsg.c_str(), output, outputBufferLen);
+}
+
+
+//IShellItem resource management
+template <class T>
+class ReleaseAtExit
+{
+public:
+ ReleaseAtExit(T*& item) : item_(item) {}
+ ~ReleaseAtExit()
+ {
+ if (item_ != NULL)
+ item_->Release();
+ }
+private:
+ T*& item_;
+};
+
+
+bool Utility::moveToRecycleBin(const wchar_t* fileNames[],
+ size_t fileNo, //size of fileNames array
+ wchar_t* errorMessage,
+ size_t errorBufferLen)
+{
+ HRESULT hr;
+
+ // Create the IFileOperation interface
+ IFileOperation* pfo = NULL;
+ ReleaseAtExit<IFileOperation> dummy(pfo);
+ hr = CoCreateInstance(CLSID_FileOperation,
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(&pfo));
+ if (FAILED(hr))
+ {
+ writeErrorMsg(L"Error calling \"CoCreateInstance\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
+
+ // Set the operation flags. Turn off all UI
+ // from being shown to the user during the
+ // operation. This includes error, confirmation
+ // and progress dialogs.
+ hr = pfo->SetOperationFlags(FOF_ALLOWUNDO |
+ FOF_NOCONFIRMATION |
+ FOF_SILENT |
+ FOF_NOERRORUI);
+ if (FAILED(hr))
+ {
+ writeErrorMsg(L"Error calling \"SetOperationFlags\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
+
+ for (size_t i = 0; i < fileNo; ++i)
+ {
+ //create file/folder item object
+ IShellItem* psiFile = NULL;
+ ReleaseAtExit<IShellItem> dummy2(psiFile);
+ hr = SHCreateItemFromParsingName(fileNames[i],
+ NULL,
+ IID_PPV_ARGS(&psiFile));
+ if (FAILED(hr))
+ {
+ std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file ");
+ message += std::wstring(L"\"") + fileNames[i] + L"\".";
+ writeErrorMsg(message.c_str(), hr, errorMessage, errorBufferLen);
+ return false;
+ }
+
+ hr = pfo->DeleteItem(psiFile, NULL);
+ if (FAILED(hr))
+ {
+ writeErrorMsg(L"Error calling \"DeleteItem\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
+ }
+
+ //perform actual operations
+ hr = pfo->PerformOperations();
+ if (FAILED(hr))
+ {
+ writeErrorMsg(L"Error calling \"PerformOperations\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
+
+ //check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors!
+ BOOL pfAnyOperationsAborted = FALSE;
+ hr = pfo->GetAnyOperationsAborted(&pfAnyOperationsAborted);
+ if (FAILED(hr))
+ {
+ writeErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
+
+
+ if (pfAnyOperationsAborted == TRUE)
+ {
+ writeString(L"Operation did not complete successfully.", errorMessage, errorBufferLen);
+ return false;
+ }
+
+ return true;
+}
diff --git a/library/Recycler/recycler.h b/library/Recycler/recycler.h
new file mode 100644
index 00000000..59bec9dc
--- /dev/null
+++ b/library/Recycler/recycler.h
@@ -0,0 +1,24 @@
+#ifndef RECYCLER_DLL_H
+#define RECYCLER_DLL_H
+
+#ifdef RECYCLER_DLL_EXPORTS
+#define RECYCLER_DLL_API extern "C" __declspec(dllexport)
+#else
+#define RECYCLER_DLL_API extern "C" __declspec(dllimport)
+#endif
+
+
+namespace Utility
+{
+//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
+
+RECYCLER_DLL_API
+bool moveToRecycleBin(const wchar_t* fileNames[],
+ size_t fileNo, //size of fileNames array
+ wchar_t* errorMessage,
+ size_t errorBufferLen);
+}
+
+
+
+#endif //RECYCLER_DLL_H
diff --git a/library/ShadowCopy/Shadow_2003.vcproj b/library/ShadowCopy/Shadow_2003.vcproj
index 560deb8d..49730440 100644
--- a/library/ShadowCopy/Shadow_2003.vcproj
+++ b/library/ShadowCopy/Shadow_2003.vcproj
@@ -205,7 +205,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003"
- RuntimeLibrary="2"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -287,7 +287,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003"
- RuntimeLibrary="2"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
diff --git a/library/ShadowCopy/Shadow_XP.vcproj b/library/ShadowCopy/Shadow_XP.vcproj
index 6c1cbaaa..74b231de 100644
--- a/library/ShadowCopy/Shadow_XP.vcproj
+++ b/library/ShadowCopy/Shadow_XP.vcproj
@@ -205,7 +205,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP"
- RuntimeLibrary="2"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -287,7 +287,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP"
- RuntimeLibrary="2"
+ RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
diff --git a/library/ShadowCopy/shadow.cpp b/library/ShadowCopy/shadow.cpp
index cbc4b085..0693815f 100644
--- a/library/ShadowCopy/shadow.cpp
+++ b/library/ShadowCopy/shadow.cpp
@@ -28,6 +28,7 @@ void writeString(const wchar_t* input, wchar_t* output, unsigned int outputBuffe
{
const size_t newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination
memcpy(output, input, newSize * sizeof(wchar_t));
+ output[newSize-1] = 0; //if output buffer is too small...
}
diff --git a/library/detectRenaming.cpp b/library/detectRenaming.cpp
new file mode 100644
index 00000000..d2b4a62c
--- /dev/null
+++ b/library/detectRenaming.cpp
@@ -0,0 +1,279 @@
+#include "detectRenaming.h"
+#include <map>
+#include <vector>
+#include <boost/bind.hpp>
+
+using namespace FreeFileSync;
+
+/*detect renamed files:
+Example:
+ X -> |_| Create right
+|_| -> Y Delete right
+
+is detected as:
+
+Rename Y to X on right
+
+Algorithm:
+----------
+DB-file left ---filename, Metadata(=:MD)---> DB-file right
+ /|\ |
+ | fileID, MD
+ fileID, MD |
+ | \|/
+ X Y
+
+*/
+
+
+class FindDBAssoc
+{
+ /*
+ load and associate db-files by filename and metadata(size, date)
+ fileID, MD |-> fileID
+ */
+public:
+ struct AssocKey
+ {
+ AssocKey(const Utility::FileID& fileId,
+ const wxLongLong& lastWriteTimeRaw,
+ const wxULongLong& fileSize);
+
+ bool operator<(const AssocKey& other) const;
+
+ Utility::FileID fileId_;
+ wxLongLong lastWriteTimeRaw_;
+ wxULongLong fileSize_;
+ };
+
+ FindDBAssoc(const FreeFileSync::BaseDirMapping& baseMapping,
+ std::map<AssocKey, Utility::FileID>& assocDBLeftToRight);
+
+private:
+ void recurse(const DirContainer& leftSide, const DirContainer& rightSide);
+
+ std::map<AssocKey, Utility::FileID>& assocDBLeftToRight_; //-->
+};
+
+
+inline
+FindDBAssoc::AssocKey::AssocKey(const Utility::FileID& fileId,
+ const wxLongLong& lastWriteTimeRaw,
+ const wxULongLong& fileSize) :
+ fileId_(fileId),
+ lastWriteTimeRaw_(lastWriteTimeRaw),
+ fileSize_(fileSize) {}
+
+
+inline
+bool FindDBAssoc::AssocKey::operator<(const AssocKey& other) const
+{
+ if (fileId_ != other.fileId_)
+ return fileId_ < other.fileId_;
+
+ if (lastWriteTimeRaw_ != other.lastWriteTimeRaw_)
+ return lastWriteTimeRaw_ < other.lastWriteTimeRaw_;
+
+ return fileSize_ < other.fileSize_;
+}
+
+
+FindDBAssoc::FindDBAssoc(const FreeFileSync::BaseDirMapping& baseMapping,
+ std::map<AssocKey, Utility::FileID>& assocDBLeftToRight) : assocDBLeftToRight_(assocDBLeftToRight)
+{
+ try
+ {
+ std::pair<FreeFileSync::DirInfoPtr, FreeFileSync::DirInfoPtr> dbInfo =
+ FreeFileSync::loadFromDisk(baseMapping); //throw (FileError)
+
+ recurse(dbInfo.first->baseDirContainer,
+ dbInfo.second->baseDirContainer);
+ }
+ catch (...) {} //swallow...
+}
+
+
+void FindDBAssoc::recurse(const DirContainer& leftSide, const DirContainer& rightSide)
+{
+ for (DirContainer::SubFileList::const_iterator i = leftSide.getSubFiles().begin(); i != leftSide.getSubFiles().end(); ++i)
+ {
+ const FileDescriptor& fileDescrI = i->second.getData();
+ if (!fileDescrI.fileIdentifier.isNull()) //fileIdentifier may be NULL
+ {
+ const DirContainer::SubFileList::const_iterator j = rightSide.getSubFiles().find(i->first);
+
+ //find files that exist on left and right
+ if (j != rightSide.getSubFiles().end())
+ {
+ const FileDescriptor& fileDescrJ = j->second.getData();
+ if (!fileDescrJ.fileIdentifier.isNull()) //fileIdentifier may be NULL
+ {
+ if ( fileDescrI.lastWriteTimeRaw == fileDescrJ.lastWriteTimeRaw &&
+ fileDescrI.fileSize == fileDescrJ.fileSize)
+ {
+ assocDBLeftToRight_[AssocKey(fileDescrI.fileIdentifier,
+ fileDescrI.lastWriteTimeRaw,
+ fileDescrI.fileSize)] = fileDescrJ.fileIdentifier;
+ }
+ }
+ }
+ }
+ }
+
+//-----------------------------------------------------------------------------------------------
+ for (DirContainer::SubDirList::const_iterator i = leftSide.getSubDirs().begin(); i != leftSide.getSubDirs().end(); ++i)
+ {
+ const DirContainer::SubDirList::const_iterator j = rightSide.getSubDirs().find(i->first);
+
+ //directories that exist on both sides
+ if (j != rightSide.getSubDirs().end())
+ {
+ recurse(i->second, j->second); //recurse into subdirectories
+ }
+ }
+}
+
+
+
+class FindRenameCandidates
+{
+public:
+ FindRenameCandidates(FreeFileSync::BaseDirMapping& baseMapping)
+ {
+ FindDBAssoc(baseMapping,
+ assocDBLeftToRight);
+
+ if (!assocDBLeftToRight.empty())
+ recurse(baseMapping);
+ }
+
+ void getRenameCandidates(std::vector<std::pair<FileMapping*, FileMapping*> >& renameOnLeft,
+ std::vector<std::pair<FileMapping*, FileMapping*> >& renameOnRight);
+
+private:
+ void recurse(HierarchyObject& hierObj)
+ {
+ //files
+ std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(),
+ boost::bind(&FindRenameCandidates::processFile, this, _1));
+
+ //directories
+ std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(),
+ boost::bind(&FindRenameCandidates::recurse, this, _1));//recursion
+ }
+
+ void processFile(FileMapping& fileObj)
+ {
+ switch (fileObj.getSyncOperation()) //evaluate comparison result and sync direction
+ {
+ case SO_CREATE_NEW_LEFT:
+ if (!fileObj.getFileID<RIGHT_SIDE>().isNull()) //fileIdentifier may be NULL
+ createLeft[FindDBAssoc::AssocKey(fileObj.getFileID<RIGHT_SIDE>(),
+ fileObj.getLastWriteTime<RIGHT_SIDE>(),
+ fileObj.getFileSize<RIGHT_SIDE>())] = &fileObj;
+ break;
+
+ case SO_CREATE_NEW_RIGHT:
+ if (!fileObj.getFileID<LEFT_SIDE>().isNull()) //fileIdentifier may be NULL
+ createRight.push_back(&fileObj);
+ break;
+
+ case SO_DELETE_LEFT:
+ if (!fileObj.getFileID<LEFT_SIDE>().isNull()) //fileIdentifier may be NULL
+ deleteLeft.push_back(&fileObj);
+ break;
+
+ case SO_DELETE_RIGHT:
+ if (!fileObj.getFileID<RIGHT_SIDE>().isNull()) //fileIdentifier may be NULL
+ deleteRight[FindDBAssoc::AssocKey(fileObj.getFileID<RIGHT_SIDE>(),
+ fileObj.getLastWriteTime<RIGHT_SIDE>(),
+ fileObj.getFileSize<RIGHT_SIDE>())] = &fileObj;
+ break;
+
+ case SO_OVERWRITE_RIGHT:
+ case SO_OVERWRITE_LEFT:
+ case SO_DO_NOTHING:
+ case SO_UNRESOLVED_CONFLICT:
+ break;
+ }
+
+ }
+
+
+ std::vector<FileMapping*> createRight; //pointer always bound!
+ std::vector<FileMapping*> deleteLeft; //
+// |
+// \|/
+ std::map<FindDBAssoc::AssocKey, Utility::FileID> assocDBLeftToRight;
+// |
+// \|/
+ std::map<FindDBAssoc::AssocKey, FileMapping*> deleteRight; //pointer always bound!
+ std::map<FindDBAssoc::AssocKey, FileMapping*> createLeft; //
+
+};
+
+
+
+void FindRenameCandidates::getRenameCandidates(
+ std::vector<std::pair<FileMapping*, FileMapping*> >& renameOnLeft,
+ std::vector<std::pair<FileMapping*, FileMapping*> >& renameOnRight)
+{
+ for (std::vector<FileMapping*>::const_iterator crRightIter = createRight.begin();
+ crRightIter != createRight.end();
+ ++crRightIter)
+ {
+ const FindDBAssoc::AssocKey assocDbKey((*crRightIter)->getFileID<LEFT_SIDE>(),
+ (*crRightIter)->getLastWriteTime<LEFT_SIDE>(),
+ (*crRightIter)->getFileSize<LEFT_SIDE>());
+
+ const std::map<FindDBAssoc::AssocKey, Utility::FileID>::const_iterator assocDBIter =
+ assocDBLeftToRight.find(assocDbKey);
+
+ if (assocDBIter != assocDBLeftToRight.end())
+ {
+ std::map<FindDBAssoc::AssocKey, FileMapping*>::const_iterator delRightIter =
+ deleteRight.find(FindDBAssoc::AssocKey(assocDBIter->second, //FileID of right side
+ assocDbKey.lastWriteTimeRaw_,
+ assocDbKey.fileSize_));
+
+ if (delRightIter != deleteRight.end())
+ {
+ renameOnRight.push_back(std::make_pair(*crRightIter, delRightIter->second));
+ }
+ }
+ }
+ //------------------------------------------------------------------------------------------------
+ for (std::vector<FileMapping*>::const_iterator delLeftIter = deleteLeft.begin();
+ delLeftIter != deleteLeft.end();
+ ++delLeftIter)
+ {
+ const FindDBAssoc::AssocKey assocDbKey((*delLeftIter)->getFileID<LEFT_SIDE>(),
+ (*delLeftIter)->getLastWriteTime<LEFT_SIDE>(),
+ (*delLeftIter)->getFileSize<LEFT_SIDE>());
+
+ const std::map<FindDBAssoc::AssocKey, Utility::FileID>::const_iterator assocDBIter =
+ assocDBLeftToRight.find(assocDbKey);
+
+ if (assocDBIter != assocDBLeftToRight.end())
+ {
+ std::map<FindDBAssoc::AssocKey, FileMapping*>::const_iterator createLeftIter =
+ createLeft.find(FindDBAssoc::AssocKey(assocDBIter->second, //FileID of right side
+ assocDbKey.lastWriteTimeRaw_,
+ assocDbKey.fileSize_));
+
+ if (createLeftIter != createLeft.end())
+ {
+ renameOnLeft.push_back(std::make_pair(createLeftIter->second, *delLeftIter));
+ }
+ }
+ }
+}
+
+
+void FreeFileSync::getRenameCandidates(FreeFileSync::BaseDirMapping& baseMapping, //in
+ std::vector<std::pair<CreateOnLeft, DeleteOnLeft> >& renameOnLeft, //out
+ std::vector<std::pair<CreateOnRight, DeleteOnRight> >& renameOnRight) //out throw()!
+{
+ FindRenameCandidates(baseMapping).getRenameCandidates(renameOnLeft, renameOnRight);
+}
+
diff --git a/library/detectRenaming.h b/library/detectRenaming.h
new file mode 100644
index 00000000..82cb543e
--- /dev/null
+++ b/library/detectRenaming.h
@@ -0,0 +1,20 @@
+#ifndef DETECTRENAMING_H_INCLUDED
+#define DETECTRENAMING_H_INCLUDED
+
+#include "../fileHierarchy.h"
+
+
+//identify a file "create and delete"-operation as a file renaming!
+
+namespace FreeFileSync
+{
+typedef FileMapping* CreateOnLeft;
+typedef FileMapping* DeleteOnLeft;
+typedef FileMapping* CreateOnRight;
+typedef FileMapping* DeleteOnRight;
+void getRenameCandidates(FreeFileSync::BaseDirMapping& baseMapping, //in
+ std::vector<std::pair<CreateOnLeft, DeleteOnLeft> >& renameOnLeft, //out
+ std::vector<std::pair<CreateOnRight, DeleteOnRight> >& renameOnRight); //out throw()!
+}
+
+#endif // DETECTRENAMING_H_INCLUDED
diff --git a/library/filter.cpp b/library/filter.cpp
index 6565da2e..25877513 100644
--- a/library/filter.cpp
+++ b/library/filter.cpp
@@ -10,24 +10,24 @@
#include "../shared/loki/LokiTypeInfo.h"
#include "../shared/serialize.h"
-using FreeFileSync::FilterProcess;
+using FreeFileSync::BaseFilter;
using FreeFileSync::NameFilter;
//--------------------------------------------------------------------------------------------------
-bool FilterProcess::operator==(const FilterProcess& other) const
+bool BaseFilter::operator==(const BaseFilter& other) const
{
return !(*this < other) && !(other < *this);
}
-bool FilterProcess::operator!=(const FilterProcess& other) const
+bool BaseFilter::operator!=(const BaseFilter& other) const
{
return !(*this == other);
}
-bool FilterProcess::operator<(const FilterProcess& other) const
+bool BaseFilter::operator<(const BaseFilter& other) const
{
if (Loki::TypeInfo(typeid(*this)) != typeid(other))
return Loki::TypeInfo(typeid(*this)) < typeid(other);
@@ -37,7 +37,7 @@ bool FilterProcess::operator<(const FilterProcess& other) const
}
-void FilterProcess::saveFilter(wxOutputStream& stream) const //serialize derived object
+void BaseFilter::saveFilter(wxOutputStream& stream) const //serialize derived object
{
//save type information
Utility::writeString(stream, uniqueClassIdentifier());
@@ -47,7 +47,7 @@ void FilterProcess::saveFilter(wxOutputStream& stream) const //serialize derived
}
-FilterProcess::FilterRef FilterProcess::loadFilter(wxInputStream& stream)
+BaseFilter::FilterRef BaseFilter::loadFilter(wxInputStream& stream)
{
//read type information
const Zstring uniqueClassId = Utility::readString(stream);
@@ -72,7 +72,7 @@ void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, st
#ifdef FFS_WIN
//Windows does NOT distinguish between upper/lower-case
- filterFormatted.MakeLower();
+ filterFormatted.MakeUpper();
#elif defined FFS_LINUX
//Linux DOES distinguish between upper/lower-case: nothing to do here
#endif
@@ -140,7 +140,7 @@ bool matchesFilter(const DefaultChar* name, const std::set<Zstring>& filter)
{
#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case
Zstring nameFormatted = name;
- nameFormatted.MakeLower();
+ nameFormatted.MakeUpper();
#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case
const DefaultChar* const nameFormatted = name; //nothing to do here
#endif
@@ -180,7 +180,7 @@ bool matchesFilterBegin(const DefaultChar* name, const std::set<Zstring>& filter
{
#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case
Zstring nameFormatted = name;
- nameFormatted.MakeLower();
+ nameFormatted.MakeUpper();
#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case
const DefaultChar* const nameFormatted = name; //nothing to do here
#endif
@@ -265,7 +265,7 @@ bool NameFilter::isNull() const
}
-bool NameFilter::cmpLessSameType(const FilterProcess& other) const
+bool NameFilter::cmpLessSameType(const BaseFilter& other) const
{
//typeid(*this) == typeid(other) in this context!
assert(typeid(*this) == typeid(other));
@@ -300,7 +300,7 @@ void NameFilter::save(wxOutputStream& stream) const
}
-FilterProcess::FilterRef NameFilter::load(wxInputStream& stream) //"constructor"
+BaseFilter::FilterRef NameFilter::load(wxInputStream& stream) //"constructor"
{
const Zstring include = Utility::readString(stream);
const Zstring exclude = Utility::readString(stream);
diff --git a/library/filter.h b/library/filter.h
index efdb01fd..ea725291 100644
--- a/library/filter.h
+++ b/library/filter.h
@@ -11,17 +11,23 @@ namespace FreeFileSync
//------------------------------------------------------------------
/* class hierarchy:
- FilterProcess (interface)
+ BaseFilter (interface)
/|\
_________|_____________
| | |
NullFilter NameFilter CombinedFilter
*/
-class FilterProcess //interface for filtering
+/*
+Semantics of BaseFilter:
+1. using it creates a NEW folder hierarchy! -> must be respected by <Automatic>-mode!
+2. it applies equally to both sides => it always matches either both sides or none! => can be used while traversing a single folder!
+*/
+
+class BaseFilter //interface for filtering
{
public:
- virtual ~FilterProcess() {}
+ virtual ~BaseFilter() {}
//filtering
virtual bool passFileFilter(const DefaultChar* relFilename) const = 0;
@@ -32,11 +38,11 @@ public:
virtual bool isNull() const = 0; //filter is equivalent to NullFilter, but may be technically slower
//comparison
- bool operator<(const FilterProcess& other) const;
- bool operator==(const FilterProcess& other) const;
- bool operator!=(const FilterProcess& other) const;
+ bool operator<(const BaseFilter& other) const;
+ bool operator==(const BaseFilter& other) const;
+ bool operator!=(const BaseFilter& other) const;
- typedef boost::shared_ptr<const FilterProcess> FilterRef; //always bound by design!
+ typedef boost::shared_ptr<const BaseFilter> FilterRef; //always bound by design!
//serialization
void saveFilter(wxOutputStream& stream) const; //serialize derived object
@@ -45,11 +51,11 @@ public:
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!
+ virtual bool cmpLessSameType(const BaseFilter& other) const = 0; //typeid(*this) == typeid(other) in this context!
};
-class NullFilter : public FilterProcess //no filtering at all
+class NullFilter : public BaseFilter //no filtering at all
{
public:
static FilterRef load(wxInputStream& stream); //"serial constructor"
@@ -60,11 +66,11 @@ public:
private:
virtual Zstring uniqueClassIdentifier() const;
virtual void save(wxOutputStream& stream) const {}
- virtual bool cmpLessSameType(const FilterProcess& other) const;
+ virtual bool cmpLessSameType(const BaseFilter& other) const;
};
-class NameFilter : public FilterProcess //standard filter by filename
+class NameFilter : public BaseFilter //standard filter by filename
{
public:
NameFilter(const Zstring& includeFilter, const Zstring& excludeFilter);
@@ -77,7 +83,7 @@ public:
private:
virtual Zstring uniqueClassIdentifier() const;
virtual void save(wxOutputStream& stream) const;
- virtual bool cmpLessSameType(const FilterProcess& other) const;
+ virtual bool cmpLessSameType(const BaseFilter& other) const;
std::set<Zstring> filterFileIn;
std::set<Zstring> filterFolderIn;
@@ -89,7 +95,7 @@ private:
};
-class CombinedFilter : public FilterProcess //combine two filters to match if and only if both match
+class CombinedFilter : public BaseFilter //combine two filters to match if and only if both match
{
public:
CombinedFilter(const FilterRef& first, const FilterRef& second) : first_(first), second_(second) {}
@@ -102,7 +108,7 @@ public:
private:
virtual Zstring uniqueClassIdentifier() const;
virtual void save(wxOutputStream& stream) const;
- virtual bool cmpLessSameType(const FilterProcess& other) const;
+ virtual bool cmpLessSameType(const BaseFilter& other) const;
const FilterRef first_;
const FilterRef second_;
@@ -110,8 +116,8 @@ private:
//small helper method: remove Null-filters
-FilterProcess::FilterRef combineFilters(const FilterProcess::FilterRef& first,
- const FilterProcess::FilterRef& second);
+BaseFilter::FilterRef combineFilters(const BaseFilter::FilterRef& first,
+ const BaseFilter::FilterRef& second);
@@ -132,7 +138,7 @@ FilterProcess::FilterRef combineFilters(const FilterProcess::FilterRef& first,
//---------------Inline Implementation---------------------------------------------------
inline
-FilterProcess::FilterRef NullFilter::load(wxInputStream& stream) //"serial constructor"
+BaseFilter::FilterRef NullFilter::load(wxInputStream& stream) //"serial constructor"
{
return FilterRef(new NullFilter);
}
@@ -161,7 +167,7 @@ bool NullFilter::isNull() const
inline
-bool NullFilter::cmpLessSameType(const FilterProcess& other) const
+bool NullFilter::cmpLessSameType(const BaseFilter& other) const
{
//typeid(*this) == typeid(other) in this context!
assert(typeid(*this) == typeid(other));
@@ -200,7 +206,7 @@ bool CombinedFilter::isNull() const
inline
-bool CombinedFilter::cmpLessSameType(const FilterProcess& other) const
+bool CombinedFilter::cmpLessSameType(const BaseFilter& other) const
{
//typeid(*this) == typeid(other) in this context!
assert(typeid(*this) == typeid(other));
@@ -229,7 +235,7 @@ void CombinedFilter::save(wxOutputStream& stream) const
inline
-FilterProcess::FilterRef CombinedFilter::load(wxInputStream& stream) //"constructor"
+BaseFilter::FilterRef CombinedFilter::load(wxInputStream& stream) //"constructor"
{
FilterRef first = loadFilter(stream);
FilterRef second = loadFilter(stream);
@@ -239,13 +245,13 @@ FilterProcess::FilterRef CombinedFilter::load(wxInputStream& stream) //"construc
inline
-FilterProcess::FilterRef combineFilters(const FilterProcess::FilterRef& first,
- const FilterProcess::FilterRef& second)
+BaseFilter::FilterRef combineFilters(const BaseFilter::FilterRef& first,
+ const BaseFilter::FilterRef& second)
{
if (first->isNull())
{
if (second->isNull())
- return FilterProcess::FilterRef(new NullFilter);
+ return BaseFilter::FilterRef(new NullFilter);
else
return second;
}
@@ -254,7 +260,7 @@ FilterProcess::FilterRef combineFilters(const FilterProcess::FilterRef& first,
if (second->isNull())
return first;
else
- return FilterProcess::FilterRef(new CombinedFilter(first, second));
+ return BaseFilter::FilterRef(new CombinedFilter(first, second));
}
}
diff --git a/library/iconBuffer.cpp b/library/iconBuffer.cpp
index d386c85a..21f85372 100644
--- a/library/iconBuffer.cpp
+++ b/library/iconBuffer.cpp
@@ -7,10 +7,82 @@
#include <map>
#include <queue>
#include <stdexcept>
+#include <set>
using FreeFileSync::IconBuffer;
+const wxIcon& IconBuffer::getDirectoryIcon() //one folder icon should be sufficient...
+{
+ static wxIcon folderIcon;
+
+ static bool isInitalized = false;
+ if (!isInitalized)
+ {
+ isInitalized = true;
+
+ SHFILEINFO fileInfo;
+ fileInfo.hIcon = 0; //initialize hIcon
+
+ //NOTE: CoInitializeEx()/CoUninitialize() implicitly called by wxWidgets on program startup!
+ if (::SHGetFileInfo(DefaultStr("dummy"), //Windows Seven doesn't like this parameter to be an empty string
+ FILE_ATTRIBUTE_DIRECTORY,
+ &fileInfo,
+ sizeof(fileInfo),
+ SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES) &&
+
+ fileInfo.hIcon != 0) //fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!!
+ {
+ folderIcon.SetHICON(fileInfo.hIcon);
+ folderIcon.SetSize(IconBuffer::ICON_SIZE, IconBuffer::ICON_SIZE);
+ }
+ }
+ return folderIcon;
+}
+
+namespace
+{
+Zstring getFileExtension(const Zstring& filename)
+{
+ const Zstring shortName = filename.AfterLast(DefaultChar('\\')); //Zstring::AfterLast() returns the whole string if ch not found
+ const size_t pos = shortName.Find(DefaultChar('.'), true);
+ return pos == Zstring::npos ?
+ Zstring() :
+ Zstring(shortName.c_str() + pos + 1);
+}
+
+
+struct CmpFilenameWin
+{
+ bool operator()(const Zstring& a, const Zstring& b) const
+ {
+ return a.CmpNoCase(b) < 0;
+ }
+};
+
+
+//test for extension for icons that physically have to be retrieved from disc
+bool isPriceyExtension(const Zstring& extension)
+{
+ static std::set<Zstring, CmpFilenameWin> exceptions;
+ static bool isInitalized = false;
+ if (!isInitalized)
+ {
+ isInitalized = true;
+ exceptions.insert(DefaultStr("exe"));
+ exceptions.insert(DefaultStr("lnk"));
+ exceptions.insert(DefaultStr("ico"));
+ exceptions.insert(DefaultStr("ani"));
+ exceptions.insert(DefaultStr("cur"));
+ exceptions.insert(DefaultStr("url"));
+ exceptions.insert(DefaultStr("msc"));
+ exceptions.insert(DefaultStr("scr"));
+ }
+ return exceptions.find(extension) != exceptions.end();
+}
+}
+//################################################################################################################################################
+
typedef std::vector<DefaultChar> BasicString; //simple thread safe string class: std::vector is guaranteed to not use reference counting, Effective STL, item 13
@@ -112,7 +184,7 @@ wxThread::ExitCode WorkerThread::Entry()
if (threadExitIsRequested) //no mutex here: atomicity is not prob for a bool, but visibility (e.g. caching in registers)
return 0; //shouldn't be a problem nevertheless because of implicit memory barrier caused by mutex.Lock() in .Wait()
- //do work: get the file icon.
+ //do work: get the file icons
doWork();
}
}
@@ -139,29 +211,25 @@ void WorkerThread::doWork()
workload.pop_back();
}
- if (iconBuffer->requestIcon(Zstring(&fileName[0]))) //thread safety: Zstring okay, won't be reference-counted in requestIcon(), fileName is NOT empty
- break; //icon already in buffer: enter waiting state
+ if (iconBuffer->requestFileIcon(Zstring(&fileName[0]))) //thread safety: Zstring okay, won't be reference-counted in requestIcon(), fileName is NOT empty
+ continue; //icon already in buffer: skip
//despite what docu says about SHGetFileInfo() it can't handle all relative filenames, e.g. "\DirName"
- const unsigned int MAX_SIZE = 10000;
- DefaultChar fullName[MAX_SIZE];
- const DWORD rv = ::GetFullPathName(
- &fileName[0], //__in LPCTSTR lpFileName,
- MAX_SIZE, //__in DWORD nBufferLength,
- fullName, //__out LPTSTR lpBuffer,
- NULL); //__out LPTSTR *lpFilePart
- if (rv < MAX_SIZE && rv != 0)
- {
- //load icon
- SHFILEINFO fileInfo;
- fileInfo.hIcon = 0; //initialize hIcon
+ //but no problem, directory formatting takes care that filenames are always absolute!
- if (::SHGetFileInfo(fullName, //NOTE: CoInitializeEx()/CoUninitialize() implicitly called by wxWidgets on program startup!
+ //load icon
+ SHFILEINFO fileInfo;
+ fileInfo.hIcon = 0; //initialize hIcon
+
+ const Zstring extension = getFileExtension(&fileName[0]); //thread-safe: no sharing!
+ if (isPriceyExtension(extension)) //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension
+ {
+ //NOTE: CoInitializeEx()/CoUninitialize() implicitly called by wxWidgets on program startup!
+ if (::SHGetFileInfo(&fileName[0], //FreeFileSync::removeLongPathPrefix(&fileName[0]), //::SHGetFileInfo() can't handle \\?\-prefix!
0,
&fileInfo,
sizeof(fileInfo),
SHGFI_ICON | SHGFI_SMALLICON) &&
-
fileInfo.hIcon != 0) //fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!!
{
//bug report: https://sourceforge.net/tracker/?func=detail&aid=2768004&group_id=234430&atid=1093080
@@ -170,7 +238,8 @@ void WorkerThread::doWork()
newIcon.SetHICON(fileInfo.hIcon);
newIcon.SetSize(IconBuffer::ICON_SIZE, IconBuffer::ICON_SIZE);
- iconBuffer->insertIntoBuffer(&fileName[0], newIcon); //thread safety: icon may be deleted only within insertIntoBuffer()
+ iconBuffer->insertIntoBuffer(&fileName[0], newIcon); //thread safety: icon buffer is written by this thread and this call only, so
+ //newIcon can safely go out of scope without race-condition because of ref-counting
//freeing of icon handle seems to happen somewhere beyond wxIcon destructor
//if (!DestroyIcon(fileInfo.hIcon))
@@ -178,16 +247,32 @@ void WorkerThread::doWork()
continue;
}
}
+ else //no read-access to disk! determine icon by extension
+ {
+ if (::SHGetFileInfo((Zstring(DefaultStr("dummy.")) + extension).c_str(), //Windows Seven doesn't like this parameter to be without short name
+ FILE_ATTRIBUTE_NORMAL,
+ &fileInfo,
+ sizeof(fileInfo),
+ SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES) &&
+ fileInfo.hIcon != 0) //fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!!
+ {
+ wxIcon newIcon; //attention: wxIcon uses reference counting!
+ newIcon.SetHICON(fileInfo.hIcon);
+ newIcon.SetSize(IconBuffer::ICON_SIZE, IconBuffer::ICON_SIZE);
+
+ iconBuffer->insertIntoBuffer(extension.c_str(), newIcon); //thread safety: icon buffer is written by this thread and this call only, so
+ continue;
+ }
+ }
+
//if loading of icon fails for whatever reason, just save a dummy icon to avoid re-loading
iconBuffer->insertIntoBuffer(&fileName[0], wxNullIcon);
}
}
//---------------------------------------------------------------------------------------------------
-
-typedef Zstring FileName;
-class IconDB : public std::map<FileName, wxIcon> {};
-class IconDbSequence : public std::queue<FileName> {};
+class IconDB : public std::map<Zstring, wxIcon> {}; // entryName/icon
+class IconDbSequence : public std::queue<Zstring> {}; // entryName
//---------------------------------------------------------------------------------------------------
@@ -213,11 +298,16 @@ IconBuffer::~IconBuffer()
}
-bool IconBuffer::requestIcon(const Zstring& fileName, wxIcon* icon)
+bool IconBuffer::requestFileIcon(const Zstring& fileName, wxIcon* icon)
{
+ const Zstring extension = getFileExtension(fileName);
+
wxCriticalSectionLocker dummy(*lockIconDB);
- IconDB::const_iterator i = buffer->find(fileName);
+ IconDB::const_iterator i = buffer->find( //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension
+ isPriceyExtension(extension) ?
+ fileName :
+ extension);
if (i != buffer->end())
{
if (icon != NULL)
@@ -235,13 +325,13 @@ void IconBuffer::setWorkload(const std::vector<Zstring>& load)
}
-void IconBuffer::insertIntoBuffer(const DefaultChar* fileName, const wxIcon& icon) //called by worker thread
+void IconBuffer::insertIntoBuffer(const DefaultChar* entryName, const wxIcon& icon) //called by worker thread
{
if (icon.IsOk()) //this check won't hurt
{
wxCriticalSectionLocker dummy(*lockIconDB);
- const Zstring fileNameZ = fileName;
+ const Zstring fileNameZ = entryName;
const std::pair<IconDB::iterator, bool> rc = buffer->insert(IconDB::value_type(fileNameZ, icon));
@@ -260,3 +350,6 @@ void IconBuffer::insertIntoBuffer(const DefaultChar* fileName, const wxIcon& ico
}
}
+
+
+
diff --git a/library/iconBuffer.h b/library/iconBuffer.h
index e6d2bcaf..703f7eb7 100644
--- a/library/iconBuffer.h
+++ b/library/iconBuffer.h
@@ -25,10 +25,12 @@ class IconBuffer
public:
static IconBuffer& getInstance();
- bool requestIcon(const Zstring& fileName, wxIcon* icon = NULL); //returns false if icon is not in buffer
+ static const wxIcon& getDirectoryIcon(); //one folder icon should be sufficient...
+
+ bool requestFileIcon(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:
@@ -36,7 +38,7 @@ private:
~IconBuffer();
//methods used by worker thread
- void insertIntoBuffer(const DefaultChar* fileName, const wxIcon& icon);
+ void insertIntoBuffer(const DefaultChar* entryName, const wxIcon& icon);
//---------------------- Shared Data -------------------------
std::auto_ptr<wxCriticalSection> lockIconDB;
diff --git a/library/processXml.cpp b/library/processXml.cpp
index af16f91e..4773fb72 100644
--- a/library/processXml.cpp
+++ b/library/processXml.cpp
@@ -416,6 +416,9 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//last update check
readXmlElementLogging("LastCheckForUpdates", global, outputCfg.lastUpdateCheck);
+ //minimum size (in bytes) for files to be considered for rename-detection
+ readXmlElementLogging("DetectRenameThreshold", global, outputCfg.detectRenameThreshold);
+
const TiXmlElement* optionalDialogs = TiXmlHandleConst(root).FirstChild("Shared").FirstChild("ShowOptionalDialogs").ToElement();
@@ -814,6 +817,9 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD
//last update check
addXmlElement("LastCheckForUpdates", inputCfg.lastUpdateCheck, global);
+ //minimum size (in bytes) for files to be considered for rename-detection
+ addXmlElement("DetectRenameThreshold", inputCfg.detectRenameThreshold, global);
+
//optional dialogs
TiXmlElement* optionalDialogs = new TiXmlElement("ShowOptionalDialogs");
diff --git a/library/processXml.h b/library/processXml.h
index 80db71a3..9cb920d9 100644
--- a/library/processXml.h
+++ b/library/processXml.h
@@ -109,12 +109,15 @@ struct XmlGlobalSettings
programLanguage(retrieveSystemLanguage()),
ignoreOneHourDiff(false),
copyLockedFiles(true),
- lastUpdateCheck(0) {}
+ detectRenameThreshold(1024 *1024),
+ lastUpdateCheck(0)
+ {}
int programLanguage;
- bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change
- bool copyLockedFiles; //VSS usage
- long lastUpdateCheck; //time of last update check
+ bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change
+ bool copyLockedFiles; //VSS usage
+ unsigned int detectRenameThreshold; //minimum size (in bytes) for files to be considered for rename-detection
+ long lastUpdateCheck; //time of last update check
OptionalDialogs optDialogs;
diff --git a/library/resources.cpp b/library/resources.cpp
index 02f5d701..3b44a361 100644
--- a/library/resources.cpp
+++ b/library/resources.cpp
@@ -21,164 +21,6 @@ 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));
- bitmapResource[wxT("right arrow create.png")] = (bitmapArrowRightCr = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("no arrow.png")] = (bitmapArrowNone = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("start sync.png")] = (bitmapStartSync = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("start sync dis.png")] = (bitmapStartSyncDis = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("left delete.png")] = (bitmapDeleteLeft = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("right delete.png")] = (bitmapDeleteRight = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("email.png")] = (bitmapEmail = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("about.png")] = (bitmapAbout = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("about_small.png")] = (bitmapAboutSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("website.png")] = (bitmapWebsite = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("exit.png")] = (bitmapExit = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("compare.png")] = (bitmapCompare = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("compare disabled.png")] = (bitmapCompareDisabled = new wxBitmap(wxNullBitmap));
- 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("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));
- bitmapResource[wxT("leftOnlyDeact.png")] = (bitmapLeftOnlyDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightOnly.png")] = (bitmapRightOnly = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightOnlyAct.png")] = (bitmapRightOnlyAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightOnlyDeact.png")] = (bitmapRightOnlyDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("leftNewer.png")] = (bitmapLeftNewer = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("leftNewerAct.png")] = (bitmapLeftNewerAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("leftNewerDeact.png")] = (bitmapLeftNewerDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightNewer.png")] = (bitmapRightNewer = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightNewerAct.png")] = (bitmapRightNewerAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightNewerDeact.png")] = (bitmapRightNewerDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("different.png")] = (bitmapDifferent = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("differentAct.png")] = (bitmapDifferentAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("differentDeact.png")] = (bitmapDifferentDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("equal.png")] = (bitmapEqual = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("equalAct.png")] = (bitmapEqualAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("equalDeact.png")] = (bitmapEqualDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("conflict.png")] = (bitmapConflict = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("conflictGrey.png")] = (bitmapConflictGrey = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("conflictAct.png")] = (bitmapConflictAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("conflictDeact.png")] = (bitmapConflictDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("include.png")] = (bitmapInclude = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("exclude.png")] = (bitmapExclude = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("filter active.png")] = (bitmapFilterOn = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("filter not active.png")] = (bitmapFilterOff = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("filter_small.png")] = (bitmapFilterSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("filterSmallGrey.png")] = (bitmapFilterSmallGrey = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("warning.png")] = (bitmapWarning = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("warningSmall.png")] = (bitmapWarningSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("error.png")] = (bitmapError = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("small arrow up.png"]) = (bitmapSmallUp = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("small arrow down.png")] = (bitmapSmallDown = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("save.png")] = (bitmapSave = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("load.png")] = (bitmapLoad = new wxBitmap(wxNullBitmap));
- 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("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));
- bitmapResource[wxT("statusError.png")] = (bitmapStatusError = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("statusSuccess.png")] = (bitmapStatusSuccess = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("statusWarning.png")] = (bitmapStatusWarning = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("statusScanning.png")] = (bitmapStatusScanning = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("statusBinaryCompare.png")]= (bitmapStatusBinCompare = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("statusSyncing.png")] = (bitmapStatusSyncing = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("logo.png")] = (bitmapLogo = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("statusEdge.png")] = (bitmapStatusEdge = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("add pair.png")] = (bitmapAddFolderPair = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("remove pair.png")] = (bitmapRemoveFolderPair = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("remove pair disabl.png")] = (bitmapRemoveFolderPairD = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("link.png")] = (bitmapLink = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("background.png")] = (bitmapBackground = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("compare_small.png")] = (bitmapCompareSmall = new wxBitmap(wxNullBitmap));
- 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("batch.png")] = (bitmapBatch = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("batch_small.png")] = (bitmapBatchSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("move up.png")] = (bitmapMoveUp = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("move down.png")] = (bitmapMoveDown = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("checkbox_true.png")] = (bitmapCheckBoxTrue = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("checkbox_true_focus.png")] = (bitmapCheckBoxTrueFocus = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("checkbox_false.png")] = (bitmapCheckBoxFalse = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("checkbox_false_focus.png")] = (bitmapCheckBoxFalseFocus = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("settings.png")] = (bitmapSettings = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("settings_small.png")] = (bitmapSettingsSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("recycler.png")] = (bitmapRecycler = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("shift.png")] = (bitmapShift = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncConfig.png")] = (bitmapSyncCfg = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncConfigSmall.png")] = (bitmapSyncCfgSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncConfigSmallGrey.png")] = (bitmapSyncCfgSmallGrey = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("cmpConfig.png")] = (bitmapCmpCfg = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncPreview.png")] = (bitmapPreview = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncPreviewDisabl.png")] = (bitmapPreviewDisabled = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("question.png")] = (bitmapQuestion = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("czechRep.png")] = (bitmapCzechRep = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("china.png")] = (bitmapChina = new wxBitmap(wxNullBitmap));
- 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));
- bitmapResource[wxT("taiwan.png")] = (bitmapTaiwan = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("turkey.png")] = (bitmapTurkey = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("italy.png")] = (bitmapItaly = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("japan.png")] = (bitmapJapan = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("poland.png")] = (bitmapPoland = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("portugal.png")] = (bitmapPortugal = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("brazil.png")] = (bitmapBrazil = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("slovakia.png")] = (bitmapSlovakia = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("spain.png")] = (bitmapSpain = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("russia.png")] = (bitmapRussia = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncCreateLeftAct.png")] = (bitmapSyncCreateLeftAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncCreateLeftDeact.png")] = (bitmapSyncCreateLeftDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncCreateRightAct.png")] = (bitmapSyncCreateRightAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncCreateRightDeact.png")] = (bitmapSyncCreateRightDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDeleteLeftAct.png")] = (bitmapSyncDeleteLeftAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDeleteLeftDeact.png")] = (bitmapSyncDeleteLeftDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDeleteRightAct.png")] = (bitmapSyncDeleteRightAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDeleteRightDeact.png")] = (bitmapSyncDeleteRightDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirLeftAct.png")] = (bitmapSyncDirLeftAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirLeftDeact.png")] = (bitmapSyncDirLeftDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirRightAct.png")] = (bitmapSyncDirRightAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirRightDeact.png")] = (bitmapSyncDirRightDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirNoneAct.png")] = (bitmapSyncDirNoneAct = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirNoneDeact.png")] = (bitmapSyncDirNoneDeact = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirLeftSmall.png")] = (bitmapSyncDirLeftSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirRightSmall.png")] = (bitmapSyncDirRightSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncDirNoneSmall.png")] = (bitmapSyncDirNoneSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("createLeftSmall.png")] = (bitmapCreateLeftSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("createRightSmall.png")] = (bitmapCreateRightSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("deleteLeftSmall.png")] = (bitmapDeleteLeftSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("deleteRightSmall.png")] = (bitmapDeleteRightSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("leftOnlySmall.png")] = (bitmapLeftOnlySmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightOnlySmall.png")] = (bitmapRightOnlySmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("leftNewerSmall.png")] = (bitmapLeftNewerSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("rightNewerSmall.png")] = (bitmapRightNewerSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("equalSmall.png")] = (bitmapEqualSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("differentSmall.png")] = (bitmapDifferentSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("conflictSmall.png")] = (bitmapConflictSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("create.png")] = (bitmapCreate = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("update.png")] = (bitmapUpdate = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("delete.png")] = (bitmapDelete = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("data.png")] = (bitmapData = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("cmpViewSmall.png")] = (bitmapCmpViewSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("syncViewSmall.png")] = (bitmapSyncViewSmall = new wxBitmap(wxNullBitmap));
- bitmapResource[wxT("toggleViewSmall.png")] = (bitmapSwitchViewSmall = new wxBitmap(wxNullBitmap));
-
-
//init all the other resource files
animationMoney = new wxAnimation(wxNullAnimation);
animationSync = new wxAnimation(wxNullAnimation);
@@ -227,7 +69,6 @@ void GlobalResources::load() const
wxZipInputStream resourceFile(input);
- std::map<wxString, wxBitmap*>::iterator bmp;
while (true)
{
std::auto_ptr<wxZipEntry> entry(resourceFile.GetNextEntry());
@@ -236,9 +77,12 @@ void GlobalResources::load() const
const wxString name = entry->GetName();
- //search if entry is available in map
- if ((bmp = bitmapResource.find(name)) != bitmapResource.end())
- *(bmp->second) = wxBitmap(wxImage(resourceFile, wxBITMAP_TYPE_PNG));
+ //generic image loading
+ if (name.EndsWith(wxT(".png")))
+ {
+ if (bitmapResource.find(name) == bitmapResource.end()) //avoid duplicate entry: prevent memory leak!
+ bitmapResource[name] = new wxBitmap(wxImage(resourceFile, wxBITMAP_TYPE_PNG));
+ }
else if (name == wxT("money.gif"))
loadAnimFromZip(resourceFile, animationMoney);
else if (name == wxT("working.gif"))
@@ -253,15 +97,18 @@ void GlobalResources::load() const
//#include "FreeFileSync.xpm"
//*programIcon = wxIcon(FreeFileSync_xpm);
- //use big FFS logo bitmap for better quality
- programIcon->CopyFromBitmap(*bitmapFFS);
+ //use big logo bitmap for better quality
+ programIcon->CopyFromBitmap(getImageByName(wxT("FreeFileSync.png")));
#endif
}
const wxBitmap& GlobalResources::getImageByName(const wxString& imageName) const
{
- std::map<wxString, wxBitmap*>::const_iterator bmp = bitmapResource.find(imageName);
+ const std::map<wxString, wxBitmap*>::const_iterator bmp = imageName.Find(wxChar('.')) == wxNOT_FOUND ? //assume .png ending if nothing else specified
+ bitmapResource.find(imageName + wxT(".png")) :
+ bitmapResource.find(imageName);
+
if (bmp != bitmapResource.end())
return *bmp->second;
else
diff --git a/library/resources.h b/library/resources.h
index 512d7ed9..c6424dbb 100644
--- a/library/resources.h
+++ b/library/resources.h
@@ -14,166 +14,9 @@ public:
const wxBitmap& getImageByName(const wxString& imageName) const;
- //image resource objects
- wxBitmap* bitmapCmpByTime;
- wxBitmap* bitmapCmpByContent;
- wxBitmap* bitmapArrowLeft;
- wxBitmap* bitmapArrowRight;
- wxBitmap* bitmapArrowLeftCr;
- wxBitmap* bitmapArrowRightCr;
- wxBitmap* bitmapArrowNone;
- wxBitmap* bitmapStartSync;
- wxBitmap* bitmapStartSyncDis;
- wxBitmap* bitmapDeleteLeft;
- wxBitmap* bitmapDeleteRight;
- wxBitmap* bitmapEmail;
- wxBitmap* bitmapAbout;
- wxBitmap* bitmapAboutSmall;
- wxBitmap* bitmapWebsite;
- wxBitmap* bitmapExit;
- wxBitmap* bitmapCompare;
- wxBitmap* bitmapCompareDisabled;
- wxBitmap* bitmapSync;
- wxBitmap* bitmapSyncDisabled;
- wxBitmap* bitmapSwap;
- wxBitmap* bitmapSwapSlim;
- wxBitmap* bitmapHelp;
- wxBitmap* bitmapLeftOnly;
- wxBitmap* bitmapLeftOnlyAct;
- wxBitmap* bitmapLeftOnlyDeact;
- wxBitmap* bitmapRightOnly;
- wxBitmap* bitmapRightOnlyAct;
- wxBitmap* bitmapRightOnlyDeact;
- wxBitmap* bitmapLeftNewer;
- wxBitmap* bitmapLeftNewerAct;
- wxBitmap* bitmapLeftNewerDeact;
- wxBitmap* bitmapRightNewer;
- wxBitmap* bitmapRightNewerAct;
- wxBitmap* bitmapRightNewerDeact;
- wxBitmap* bitmapEqual;
- wxBitmap* bitmapEqualAct;
- wxBitmap* bitmapEqualDeact;
- wxBitmap* bitmapDifferent;
- wxBitmap* bitmapDifferentAct;
- wxBitmap* bitmapDifferentDeact;
- wxBitmap* bitmapConflict;
- wxBitmap* bitmapConflictGrey;
- wxBitmap* bitmapConflictAct;
- wxBitmap* bitmapConflictDeact;
- wxBitmap* bitmapInclude;
- wxBitmap* bitmapExclude;
- wxBitmap* bitmapFilterOn;
- wxBitmap* bitmapFilterOff;
- wxBitmap* bitmapFilterSmall;
- wxBitmap* bitmapFilterSmallGrey;
- wxBitmap* bitmapWarning;
- wxBitmap* bitmapWarningSmall;
- wxBitmap* bitmapError;
- wxBitmap* bitmapSmallUp;
- wxBitmap* bitmapSmallDown;
- wxBitmap* bitmapSave;
- wxBitmap* bitmapLoad;
- wxBitmap* bitmapSaveSmall;
- wxBitmap* bitmapLoadSmall;
- wxBitmap* bitmapNewSmall;
- wxBitmap* bitmapFFS;
- wxBitmap* bitmapDeleteFile;
- wxBitmap* bitmapGPL;
- wxBitmap* bitmapStatusPause;
- wxBitmap* bitmapStatusError;
- wxBitmap* bitmapStatusSuccess;
- wxBitmap* bitmapStatusWarning;
- wxBitmap* bitmapStatusScanning;
- wxBitmap* bitmapStatusBinCompare;
- wxBitmap* bitmapStatusSyncing;
- wxBitmap* bitmapLogo;
- wxBitmap* bitmapStatusEdge;
- wxBitmap* bitmapAddFolderPair;
- wxBitmap* bitmapRemoveFolderPair;
- wxBitmap* bitmapRemoveFolderPairD;
- wxBitmap* bitmapLink;
- wxBitmap* bitmapBackground;
- wxBitmap* bitmapCompareSmall;
- wxBitmap* bitmapSyncSmall;
- wxBitmap* bitmapClockSmall;
- wxBitmap* bitmapClock;
- wxBitmap* bitmapBatch;
- wxBitmap* bitmapBatchSmall;
- wxBitmap* bitmapMoveUp;
- wxBitmap* bitmapMoveDown;
- wxBitmap* bitmapCheckBoxTrue;
- wxBitmap* bitmapCheckBoxTrueFocus;
- wxBitmap* bitmapCheckBoxFalse;
- wxBitmap* bitmapCheckBoxFalseFocus;
- wxBitmap* bitmapSettings;
- wxBitmap* bitmapSettingsSmall;
- wxBitmap* bitmapRecycler;
- wxBitmap* bitmapShift;
- wxBitmap* bitmapSyncCfg;
- wxBitmap* bitmapSyncCfgSmall;
- wxBitmap* bitmapSyncCfgSmallGrey;
- wxBitmap* bitmapCmpCfg;
- wxBitmap* bitmapPreview;
- wxBitmap* bitmapPreviewDisabled;
- wxBitmap* bitmapQuestion;
- wxBitmap* bitmapCzechRep;
- wxBitmap* bitmapChina;
- wxBitmap* bitmapHolland;
- wxBitmap* bitmapEngland;
- wxBitmap* bitmapFrance;
- wxBitmap* bitmapFinland;
- wxBitmap* bitmapGermany;
- wxBitmap* bitmapHungary;
- wxBitmap* bitmapRomania;
- wxBitmap* bitmapTaiwan;
- wxBitmap* bitmapTurkey;
- wxBitmap* bitmapItaly;
- wxBitmap* bitmapJapan;
- wxBitmap* bitmapPoland;
- wxBitmap* bitmapPortugal;
- wxBitmap* bitmapBrazil;
- wxBitmap* bitmapSlovakia;
- wxBitmap* bitmapSpain;
- wxBitmap* bitmapRussia;
- wxBitmap* bitmapSyncCreateLeftAct;
- wxBitmap* bitmapSyncCreateLeftDeact;
- wxBitmap* bitmapSyncCreateRightAct;
- wxBitmap* bitmapSyncCreateRightDeact;
- wxBitmap* bitmapSyncDeleteLeftAct;
- wxBitmap* bitmapSyncDeleteLeftDeact;
- wxBitmap* bitmapSyncDeleteRightAct;
- wxBitmap* bitmapSyncDeleteRightDeact;
- wxBitmap* bitmapSyncDirLeftAct;
- wxBitmap* bitmapSyncDirLeftDeact;
- wxBitmap* bitmapSyncDirRightAct;
- wxBitmap* bitmapSyncDirRightDeact;
- wxBitmap* bitmapSyncDirNoneAct;
- wxBitmap* bitmapSyncDirNoneDeact;
- wxBitmap* bitmapSyncDirLeftSmall;
- wxBitmap* bitmapSyncDirRightSmall;
- wxBitmap* bitmapSyncDirNoneSmall;
- wxBitmap* bitmapCreateLeftSmall;
- wxBitmap* bitmapCreateRightSmall;
- wxBitmap* bitmapDeleteLeftSmall;
- wxBitmap* bitmapDeleteRightSmall;
- wxBitmap* bitmapLeftOnlySmall;
- wxBitmap* bitmapRightOnlySmall;
- wxBitmap* bitmapLeftNewerSmall;
- wxBitmap* bitmapRightNewerSmall;
- wxBitmap* bitmapEqualSmall;
- wxBitmap* bitmapDifferentSmall;
- wxBitmap* bitmapConflictSmall;
- wxBitmap* bitmapCreate;
- wxBitmap* bitmapUpdate;
- wxBitmap* bitmapDelete;
- wxBitmap* bitmapData;
- wxBitmap* bitmapCmpViewSmall;
- wxBitmap* bitmapSyncViewSmall;
- wxBitmap* bitmapSwitchViewSmall;
-
+ //global image resource objects
wxAnimation* animationMoney;
wxAnimation* animationSync;
-
wxIcon* programIcon;
void load() const; //loads bitmap resources on program startup: logical const!
diff --git a/library/statistics.cpp b/library/statistics.cpp
index 53a75fce..f4319686 100644
--- a/library/statistics.cpp
+++ b/library/statistics.cpp
@@ -113,10 +113,10 @@ Statistics::Statistics(const int totalObjectCount,
remainingTimeLast(256*256*256*100), //something "big"
timer(new wxStopWatch) {}
- Statistics::~Statistics()
- {
- delete timer;
- }
+Statistics::~Statistics()
+{
+ delete timer;
+}
void Statistics::addMeasurement(const int objectsCurrent, const double dataCurrent)
{
diff --git a/library/statistics.h b/library/statistics.h
index d1b8b98b..a8aa140f 100644
--- a/library/statistics.h
+++ b/library/statistics.h
@@ -39,7 +39,7 @@ public:
const unsigned windowSizeRemainingTime, //time in ms
const unsigned windowSizeBytesPerSecond); //time in ms
- ~Statistics();
+ ~Statistics();
void addMeasurement(const int objectsCurrent, const double dataCurrent);
wxString getRemainingTime() const; //returns the remaining time in milliseconds
diff --git a/shared/buildInfo.h b/shared/buildInfo.h
new file mode 100644
index 00000000..1c14caa5
--- /dev/null
+++ b/shared/buildInfo.h
@@ -0,0 +1,12 @@
+#ifndef BUILDINFO_H_INCLUDED
+#define BUILDINFO_H_INCLUDED
+
+namespace Utility
+{
+//determine build info
+//seems to be safer than checking for _WIN64 (defined on windows for 64-bit compilations only) while _WIN32 is always defined
+static const bool is32BitBuild = sizeof(void*) == 4;
+static const bool is64BitBuild = sizeof(void*) == 8;
+}
+
+#endif // BUILDINFO_H_INCLUDED
diff --git a/shared/customButton.cpp b/shared/customButton.cpp
index 40c0397f..73b9d1ee 100644
--- a/shared/customButton.cpp
+++ b/shared/customButton.cpp
@@ -277,17 +277,17 @@ void wxButtonWithImage::refreshButtonLabel()
//wxDC::DrawLabel() unfortunately isn't working for transparent images on Linux, so we need to use custom image-concatenation
if (bitmapFront.IsOk())
- writeToImage(wxImage(bitmapFront.ConvertToImage()),
+ writeToImage(bitmapFront.ConvertToImage(),
wxPoint(0, (transparentImage.GetHeight() - bitmapFront.GetHeight()) / 2),
transparentImage);
if (bitmapText.IsOk())
- writeToImage(wxImage(bitmapText.ConvertToImage()),
+ writeToImage(bitmapText.ConvertToImage(),
wxPoint(bitmapFront.GetWidth() + m_spaceAfter, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2),
transparentImage);
if (bitmapBack.IsOk())
- writeToImage(wxImage(bitmapBack.ConvertToImage()),
+ writeToImage(bitmapBack.ConvertToImage(),
wxPoint(bitmapFront.GetWidth() + m_spaceAfter + bitmapText.GetWidth() + m_spaceBefore, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2),
transparentImage);
diff --git a/shared/customComboBox.cpp b/shared/customComboBox.cpp
index f2eec7a9..e21e915c 100644
--- a/shared/customComboBox.cpp
+++ b/shared/customComboBox.cpp
@@ -50,6 +50,10 @@ void CustomComboBox::OnKeyEvent(wxKeyEvent& event)
void CustomComboBox::addPairToFolderHistory(const wxString& newFolder, unsigned int maxHistSize)
{
+ //don't add empty directories
+ if (newFolder.empty())
+ return;
+
const wxString oldVal = this->GetValue();
//insert new folder or put it to the front if already existing
diff --git a/shared/dllLoader.cpp b/shared/dllLoader.cpp
index e37ded54..fbfa5b11 100644
--- a/shared/dllLoader.cpp
+++ b/shared/dllLoader.cpp
@@ -1,44 +1,55 @@
#include "dllLoader.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include <map>
+#include <assert.h>
namespace
{
-class KernelDllHandler //dynamically load "kernel32.dll"
+class DllHandler //dynamically load "kernel32.dll"
{
public:
- static const KernelDllHandler& getInstance()
+ static DllHandler& getInstance()
{
- static KernelDllHandler instance;
+ static DllHandler instance;
return instance;
}
- HINSTANCE getHandle() const
+ HINSTANCE getHandle(const std::wstring& libraryName)
{
- return hKernel;
+ HandleMap::const_iterator foundEntry = handles.find(libraryName);
+ if (foundEntry == handles.end())
+ {
+ HINSTANCE newHandle = ::LoadLibrary(libraryName.c_str());
+ handles.insert(std::make_pair(libraryName, newHandle));
+
+ assert(handles.find(libraryName) != handles.end());
+ return newHandle;
+ }
+ else
+ return foundEntry->second;
}
private:
- KernelDllHandler() :
- hKernel(NULL)
- {
- //get a handle to the DLL module containing required functionality
- hKernel = ::LoadLibrary(L"kernel32.dll");
- }
+ DllHandler() {}
- ~KernelDllHandler()
+ ~DllHandler()
{
- if (hKernel) ::FreeLibrary(hKernel);
+ for (HandleMap::const_iterator i = handles.begin(); i != handles.end(); ++i)
+ if (i->second != NULL) ::FreeLibrary(i->second);
}
- HINSTANCE hKernel;
+ typedef std::map<std::wstring, HINSTANCE> HandleMap;
+ HandleMap handles;
};
}
-void* Utility::loadSymbolKernel(const std::string& functionName)
+void* Utility::loadSymbol(const std::wstring& libraryName, const std::string& functionName)
{
- if (KernelDllHandler::getInstance().getHandle() != NULL)
- return reinterpret_cast<void*>(::GetProcAddress(KernelDllHandler::getInstance().getHandle(), functionName.c_str()));
+ const HINSTANCE libHandle = DllHandler::getInstance().getHandle(libraryName);
+
+ if (libHandle != NULL)
+ return reinterpret_cast<void*>(::GetProcAddress(libHandle, functionName.c_str()));
else
return NULL;
}
diff --git a/shared/dllLoader.h b/shared/dllLoader.h
index bf62b542..5b561c5a 100644
--- a/shared/dllLoader.h
+++ b/shared/dllLoader.h
@@ -5,10 +5,11 @@
namespace Utility
{
- //load kernel dll functions
-template <typename FunctionType>
-FunctionType loadDllFunKernel(const std::string& functionName);
+//load function from a DLL library, e.g. from kernel32.dll
+//NOTE: you're allowed to take a static reference to the return value to optimize performance! :)
+template <typename FunctionType>
+FunctionType loadDllFunction(const std::wstring& libraryName, const std::string& functionName);
@@ -22,13 +23,13 @@ FunctionType loadDllFunKernel(const std::string& functionName);
//---------------Inline Implementation---------------------------------------------------
-void* loadSymbolKernel(const std::string& functionName);
+void* loadSymbol(const std::wstring& libraryName, const std::string& functionName);
template <typename FunctionType>
inline
-FunctionType loadDllFunKernel(const std::string& functionName)
+FunctionType loadDllFunction(const std::wstring& libraryName, const std::string& functionName)
{
- return reinterpret_cast<FunctionType>(loadSymbolKernel(functionName));
+ return reinterpret_cast<FunctionType>(loadSymbol(libraryName, functionName));
}
#ifndef FFS_WIN
diff --git a/shared/fileHandling.cpp b/shared/fileHandling.cpp
index 4b9901e0..ef1d3e6c 100644
--- a/shared/fileHandling.cpp
+++ b/shared/fileHandling.cpp
@@ -14,9 +14,11 @@
#include <wx/utils.h>
#ifdef FFS_WIN
+#include "recycler.h"
#include "dllLoader.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include "shadow.h"
+#include "longPathPrefix.h"
#elif defined FFS_LINUX
#include <sys/stat.h>
@@ -104,83 +106,48 @@ Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname)
if (dirnameTmp.empty()) //an empty string is interpreted as "\"; this is not desired
return Zstring();
- if (!dirnameTmp.EndsWith(zToWx(globalFunctions::FILE_NAME_SEPARATOR)))
- dirnameTmp += zToWx(globalFunctions::FILE_NAME_SEPARATOR);
-
//replace macros
expandMacros(dirnameTmp);
+#ifdef FFS_WIN
+ /*
+ resolve relative names; required by:
+ - \\?\-prefix which needs absolute names
+ - Volume Shadow Copy: volume name needs to be part of each filename
+ - file icon buffer (at least for extensions that are acutally read from disk, e.g. "exe")
+ - detection of dependent directories, e.g. "\" and "C:\test"
+ */
+ dirnameTmp = resolveRelativePath(dirnameTmp.c_str()).c_str();
+#endif
+
+ if (!dirnameTmp.EndsWith(zToWx(globalFunctions::FILE_NAME_SEPARATOR)))
+ dirnameTmp += zToWx(globalFunctions::FILE_NAME_SEPARATOR);
+
return wxToZ(dirnameTmp);
}
-class RecycleBin
+bool FreeFileSync::recycleBinExists()
{
-public:
- static const RecycleBin& getInstance()
- {
- static RecycleBin instance; //lazy creation of RecycleBin
- return instance;
- }
-
- bool recycleBinExists() const
- {
- return recycleBinAvailable;
- }
-
- bool moveToRecycleBin(const Zstring& filename) const; //throw (std::logic_error)
-
-private:
- RecycleBin() :
- recycleBinAvailable(false)
- {
#ifdef FFS_WIN
- recycleBinAvailable = true;
+ return true;
+#else
+ return false;
#endif // FFS_WIN
- }
-
- ~RecycleBin() {}
-
-private:
- bool recycleBinAvailable;
-};
+}
-bool RecycleBin::moveToRecycleBin(const Zstring& filename) const //throw (std::logic_error)
+inline
+void moveToRecycleBin(const Zstring& filename) //throw (std::logic_error), throw (FileError)
{
- if (!recycleBinAvailable) //this method should ONLY be called if recycle bin is available
+ if (!FreeFileSync::recycleBinExists()) //this method should ONLY be called if recycle bin is available
throw std::logic_error("Initialization of Recycle Bin failed!");
#ifdef FFS_WIN
- Zstring filenameDoubleNull = filename + wxChar(0);
-
- SHFILEOPSTRUCT fileOp;
- fileOp.hwnd = NULL;
- fileOp.wFunc = FO_DELETE;
- fileOp.pFrom = filenameDoubleNull.c_str();
- fileOp.pTo = NULL;
- fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
- fileOp.fAnyOperationsAborted = false;
- fileOp.hNameMappings = NULL;
- fileOp.lpszProgressTitle = NULL;
-
- if (SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) return false;
+ FreeFileSync::moveToWindowsRecycler(filename); //throw (FileError)
+#else
+ throw std::logic_error("No Recycler for Linux available at the moment!");
#endif
-
- return true;
-}
-
-
-bool FreeFileSync::recycleBinExists()
-{
- return RecycleBin::getInstance().recycleBinExists();
-}
-
-
-inline
-bool moveToRecycleBin(const Zstring& filename) //throw (std::logic_error)
-{
- return RecycleBin::getInstance().moveToRecycleBin(filename);
}
@@ -190,7 +157,7 @@ bool FreeFileSync::fileExists(const DefaultChar* filename)
#ifdef FFS_WIN
// we must use GetFileAttributes() instead of the ANSI C functions because
// it can cope with network (UNC) paths unlike them
- const DWORD ret = ::GetFileAttributes(filename);
+ const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(filename).c_str());
return (ret != INVALID_FILE_ATTRIBUTES) && !(ret & FILE_ATTRIBUTE_DIRECTORY); //returns true for (file-)symlinks also
@@ -208,7 +175,7 @@ bool FreeFileSync::dirExists(const DefaultChar* dirname)
#ifdef FFS_WIN
// we must use GetFileAttributes() instead of the ANSI C functions because
// it can cope with network (UNC) paths unlike them
- const DWORD ret = ::GetFileAttributes(dirname);
+ const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(dirname).c_str());
return (ret != INVALID_FILE_ATTRIBUTES) && (ret & FILE_ATTRIBUTE_DIRECTORY); //returns true for (dir-)symlinks also
@@ -223,7 +190,7 @@ bool FreeFileSync::dirExists(const DefaultChar* dirname)
bool FreeFileSync::symlinkExists(const DefaultChar* objname)
{
#ifdef FFS_WIN
- const DWORD ret = ::GetFileAttributes(objname);
+ const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(objname).c_str());
return (ret != INVALID_FILE_ATTRIBUTES) && (ret & FILE_ATTRIBUTE_REPARSE_POINT);
#elif defined FFS_LINUX
@@ -263,8 +230,8 @@ bool FreeFileSync::isMovable(const Zstring& pathFrom, const Zstring& pathTo)
const bool result =
//try to move the file
#ifdef FFS_WIN
- ::MoveFileEx(dummyFileSource.c_str(), //__in LPCTSTR lpExistingFileName,
- dummyFileTarget.c_str(), //__in_opt LPCTSTR lpNewFileName,
+ ::MoveFileEx(applyLongPathPrefix(dummyFileSource).c_str(), //__in LPCTSTR lpExistingFileName,
+ applyLongPathPrefix(dummyFileTarget).c_str(), //__in_opt LPCTSTR lpNewFileName,
0) != 0; //__in DWORD dwFlags
#elif defined FFS_LINUX
::rename(dummyFileSource.c_str(), dummyFileTarget.c_str()) == 0;
@@ -285,7 +252,9 @@ void FreeFileSync::removeFile(const Zstring& filename, const bool useRecycleBin)
{
//no error situation if file is not existing! manual deletion relies on it!
#ifdef FFS_WIN
- if (::GetFileAttributes(filename.c_str()) == INVALID_FILE_ATTRIBUTES)
+
+ const Zstring filenameFmt = applyLongPathPrefix(filename);
+ if (::GetFileAttributes(filenameFmt.c_str()) == INVALID_FILE_ATTRIBUTES)
return; //neither file nor any other object with that name existing
#elif defined FFS_LINUX
@@ -296,15 +265,14 @@ void FreeFileSync::removeFile(const Zstring& filename, const bool useRecycleBin)
if (useRecycleBin)
{
- if (!moveToRecycleBin(filename))
- throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + zToWx(filename) + wxT("\""));
+ ::moveToRecycleBin(filename);
return;
}
#ifdef FFS_WIN
//initialize file attributes
if (!::SetFileAttributes(
- filename.c_str(), //address of filename
+ filenameFmt.c_str(), //address of filename
FILE_ATTRIBUTE_NORMAL)) //attributes to set
{
wxString errorMessage = wxString(_("Error deleting file:")) + wxT("\n\"") + zToWx(filename) + wxT("\"");
@@ -312,7 +280,7 @@ void FreeFileSync::removeFile(const Zstring& filename, const bool useRecycleBin)
}
//remove file, support for \\?\-prefix
- if (!::DeleteFile(filename.c_str()))
+ if (!::DeleteFile(filenameFmt.c_str()))
{
wxString errorMessage = wxString(_("Error deleting file:")) + wxT("\n\"") + zToWx(filename) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
@@ -331,9 +299,9 @@ void FreeFileSync::removeFile(const Zstring& filename, const bool useRecycleBin)
void FreeFileSync::renameFile(const Zstring& oldName, const Zstring& newName) //throw (FileError);
{
#ifdef FFS_WIN
- if (!::MoveFileEx(oldName.c_str(), //__in LPCTSTR lpExistingFileName,
- newName.c_str(), //__in_opt LPCTSTR lpNewFileName,
- 0)) //__in DWORD dwFlags
+ if (!::MoveFileEx(applyLongPathPrefix(oldName).c_str(), //__in LPCTSTR lpExistingFileName,
+ applyLongPathPrefix(newName).c_str(), //__in_opt LPCTSTR lpNewFileName,
+ 0)) //__in DWORD dwFlags
{
const wxString errorMessage = wxString(_("Error moving file:")) + wxT("\n\"") + zToWx(oldName) + wxT("\" ->\n\"") + zToWx(newName) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
@@ -388,8 +356,8 @@ void FreeFileSync::moveFile(const Zstring& sourceFile, const Zstring& targetFile
#ifdef FFS_WIN
//first try to move the file directly without copying
- if (::MoveFileEx(sourceFile.c_str(), //__in LPCTSTR lpExistingFileName,
- targetFile.c_str(), //__in_opt LPCTSTR lpNewFileName,
+ if (::MoveFileEx(applyLongPathPrefix(sourceFile).c_str(), //__in LPCTSTR lpExistingFileName,
+ applyLongPathPrefix(targetFile).c_str(), //__in_opt LPCTSTR lpNewFileName,
0)) //__in DWORD dwFlags
return;
@@ -494,8 +462,8 @@ void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool
{
//first try to move the directory directly without copying
#ifdef FFS_WIN
- if (::MoveFileEx(sourceDir.c_str(), //__in LPCTSTR lpExistingFileName,
- targetDir.c_str(), //__in_opt LPCTSTR lpNewFileName,
+ if (::MoveFileEx(applyLongPathPrefix(sourceDir).c_str(), //__in LPCTSTR lpExistingFileName,
+ applyLongPathPrefix(targetDir).c_str(), //__in_opt LPCTSTR lpNewFileName,
0)) //__in DWORD dwFlags
return;
@@ -615,7 +583,9 @@ void FreeFileSync::removeDirectory(const Zstring& directory, const bool useRecyc
{
//no error situation if directory is not existing! manual deletion relies on it!
#ifdef FFS_WIN
- const DWORD dirAttr = GetFileAttributes(directory.c_str()); //name of a file or directory
+ const Zstring directoryFmt = applyLongPathPrefix(directory); //support for \\?\-prefix
+
+ const DWORD dirAttr = ::GetFileAttributes(directoryFmt.c_str()); //name of a file or directory
if (dirAttr == INVALID_FILE_ATTRIBUTES)
return; //neither directory nor any other object with that name existing
@@ -627,8 +597,7 @@ void FreeFileSync::removeDirectory(const Zstring& directory, const bool useRecyc
if (useRecycleBin)
{
- if (!moveToRecycleBin(directory))
- throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + zToWx(directory) + wxT("\""));
+ ::moveToRecycleBin(directory);
return;
}
@@ -636,7 +605,7 @@ void FreeFileSync::removeDirectory(const Zstring& directory, const bool useRecyc
#ifdef FFS_WIN
//initialize file attributes
if (!::SetFileAttributes( // initialize file attributes: actually NEEDED for symbolic links also!
- directory.c_str(), // address of directory name
+ directoryFmt.c_str(), // address of directory name
FILE_ATTRIBUTE_NORMAL)) // attributes to set
{
wxString errorMessage = wxString(_("Error deleting directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
@@ -645,9 +614,9 @@ void FreeFileSync::removeDirectory(const Zstring& directory, const bool useRecyc
//attention: check if directory is a symlink! Do NOT traverse into it deleting contained files!!!
- if (dirAttr & FILE_ATTRIBUTE_REPARSE_POINT) //remove symlink directly, support for \\?\-prefix
+ if (dirAttr & FILE_ATTRIBUTE_REPARSE_POINT) //remove symlink directly
{
- if (!::RemoveDirectory(directory.c_str()))
+ if (!::RemoveDirectory(directoryFmt.c_str()))
{
wxString errorMessage = wxString(_("Error deleting directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
@@ -683,7 +652,7 @@ void FreeFileSync::removeDirectory(const Zstring& directory, const bool useRecyc
//parent directory is deleted last
#ifdef FFS_WIN
//remove directory, support for \\?\-prefix
- if (!::RemoveDirectory(directory.c_str()))
+ if (!::RemoveDirectory(directoryFmt.c_str()))
#else
if (::rmdir(directory.c_str()) != 0)
#endif
@@ -718,7 +687,7 @@ void FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target
return;
#ifdef FFS_WIN
- HANDLE hDirRead = ::CreateFile(sourceDir.c_str(),
+ HANDLE hDirRead = ::CreateFile(applyLongPathPrefix(sourceDir).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -737,7 +706,7 @@ void FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target
&accessTime,
&lastWriteTime))
{
- HANDLE hDirWrite = ::CreateFile(targetDir.c_str(),
+ HANDLE hDirWrite = ::CreateFile(applyLongPathPrefix(targetDir).c_str(),
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -776,13 +745,13 @@ void FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target
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);
+ const HANDLE hDir = ::CreateFile(FreeFileSync::applyLongPathPrefix(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();
@@ -799,7 +768,7 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
DWORD cchFilePath,
DWORD dwFlags);
static const GetFinalPathNameByHandleWFunc getFinalPathNameByHandle =
- Utility::loadDllFunKernel<GetFinalPathNameByHandleWFunc>("GetFinalPathNameByHandleW");
+ Utility::loadDllFunction<GetFinalPathNameByHandleWFunc>(L"kernel32.dll", "GetFinalPathNameByHandleW");
if (getFinalPathNameByHandle == NULL)
throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\""));
@@ -885,10 +854,10 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
//now creation should be possible
#ifdef FFS_WIN
- const DWORD templateAttr = ::GetFileAttributes(templateDir.c_str()); //replaces wxDirExists(): also returns successful for broken symlinks
+ const DWORD templateAttr = ::GetFileAttributes(applyLongPathPrefix(templateDir).c_str()); //replaces wxDirExists(): also returns successful for broken symlinks
if (templateAttr == INVALID_FILE_ATTRIBUTES) //fallback
{
- if (!::CreateDirectory(directory.c_str(), // pointer to a directory path string
+ if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
NULL) && level == 0)
{
const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
@@ -910,8 +879,8 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
else
{
if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
- linkPath.c_str(), // pointer to path string of template directory
- directory.c_str(), // pointer to a directory path string
+ applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
+ applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
NULL) && level == 0)
{
const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
@@ -924,12 +893,16 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
}
else //in all other cases
{
- if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
- templateDir.c_str(), // pointer to path string of template directory
- directory.c_str(), // pointer to a directory path string
+ if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
+ applyLongPathPrefix(templateDir).c_str(), // pointer to path string of template directory
+ applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
NULL) && level == 0)
{
- const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
+ const wxString errorMessage = templateAttr & FILE_ATTRIBUTE_REPARSE_POINT ?
+ //give a more meaningful errormessage if copying a symbolic link failed, e.g. "C:\Users\ZenJu\Application Data"
+ (wxString(_("Error copying symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\" ->\n\"") + directory.c_str() + wxT("\"")) :
+
+ (wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\""));
throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
}
@@ -960,7 +933,7 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
if (symlink(buffer, directory.c_str()) != 0)
{
- wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
+ const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + zToWx(templateDir) + wxT("\" ->\n\"") + zToWx(directory) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
}
return; //symlink created successfully
@@ -1022,7 +995,7 @@ Zstring createTempName(const Zstring& filename)
{
//if it's not unique, add a postfix number
int postfix = 1;
- while (FreeFileSync::fileExists(output + DefaultChar('_') + numberToZstring(postfix)))
+ while (FreeFileSync::fileExists(output + DefaultStr("_") + numberToZstring(postfix)))
++postfix;
output += Zstring(DefaultStr("_")) + numberToZstring(postfix);
@@ -1107,9 +1080,10 @@ bool supportForNonEncryptedDestination()
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- //symbolic links are supported starting with Vista
+ //encrypted destination is not supported with Windows 2000
if (GetVersionEx(&osvi))
- return osvi.dwMajorVersion >= 5 && osvi.dwMinorVersion >= 1; //XP has majorVersion == 5, minorVersion == 1, Vista majorVersion == 6
+ return osvi.dwMajorVersion > 5 ||
+ (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 0); //2000 has majorVersion == 5, minorVersion == 0
//overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
return false;
}
@@ -1121,6 +1095,10 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
FreeFileSync::ShadowCopy* shadowCopyHandler,
FreeFileSync::CopyFileCallback* callback)
{
+ //FreeFileSync::fileExists(targetFile.c_str()) -> avoid this call, performance;
+ //if target exists (very unlikely, because sync-algorithm deletes it) renaming below will fail!
+
+
DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS;
//copy symbolic links instead of the files pointed at
@@ -1133,11 +1111,11 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
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(),
- temporary.c_str(),
+ applyLongPathPrefix(sourceFile).c_str(),
+ applyLongPathPrefix(temporary).c_str(),
copyCallbackInternal,
callback,
NULL,
@@ -1152,6 +1130,7 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
(lastError == ERROR_SHARING_VIOLATION ||
lastError == ERROR_LOCK_VIOLATION))
{
+ //shadowFilename already contains prefix: E.g. "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Program Files\FFS\sample.dat"
const Zstring shadowFilename(shadowCopyHandler->makeShadowCopy(sourceFile));
copyFile(shadowFilename, //transferred bytes is automatically reset when new file is copied
targetFile,
@@ -1161,12 +1140,33 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
return;
}
- const wxString errorMessage = wxString(_("Error copying file:")) + wxT("\n\"") + sourceFile.c_str() + wxT("\" ->\n\"") + targetFile.c_str() + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted(lastError));
+ //assemble error message...
+ const wxString errorMessage = wxString(_("Error copying file:")) + wxT("\n\"") + sourceFile.c_str() + wxT("\" ->\n\"") + targetFile.c_str() + wxT("\"") +
+ wxT("\n\n") + FreeFileSync::getLastErrorFormatted(lastError);
+
+ throw FileError(errorMessage);
}
- //rename temporary file
- FreeFileSync::renameFile(temporary, targetFile);
+ try
+ {
+ //rename temporary file
+ FreeFileSync::renameFile(temporary, targetFile);
+ }
+ catch (...) //if renaming temporary failed: cleanup
+ {
+ try
+ {
+ removeFile(temporary, false); //throw (FileError, std::logic_error);
+ }
+ catch(...) {}
+
+ //this can only happen in very obscure situations: while scanning, target didn't exist, but while sync'ing it suddenly does (e.g. network drop?)
+ if (FreeFileSync::fileExists(targetFile.c_str()))
+ throw FileError(wxString(_("Error copying file:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") + zToWx(targetFile) + wxT("\"\n\n")
+ + _("Target file already existing!"));
+
+ throw;
+ }
//copy creation date (last modification date is redundantly written, too)
copyFileTimes(sourceFile, targetFile); //throw()
@@ -1230,7 +1230,7 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
if (symlink(buffer, targetFile.c_str()) != 0)
{
- const wxString errorMessage = wxString(_("Error writing file:")) + wxT("\n\"") + zToWx(targetFile) + wxT("\"");
+ const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") + zToWx(targetFile) + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
}
@@ -1254,12 +1254,12 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
//create targetFile and open it for writing
const Zstring temporary = createTempName(targetFile); //use temporary file until a correct date has been set
- std::ofstream fileOut(temporary.c_str(), std::ios_base::binary);
- if (fileOut.fail())
- throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(targetFile) + wxT("\""));
-
try
{
+ std::ofstream fileOut(temporary.c_str(), std::ios_base::binary);
+ if (fileOut.fail())
+ throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(targetFile) + wxT("\""));
+
//copy contents of sourceFile to targetFile
wxULongLong totalBytesTransferred;
static MemoryAllocator memory;
@@ -1326,8 +1326,11 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
catch (...)
{
//try to delete target file if error occured, or exception was thrown in callback function
+ //no data-loss, because of "fileExists(targetFile))" check at the beginning!
if (FreeFileSync::fileExists(targetFile))
::unlink(targetFile); //don't handle error situations!
+
+ //clean-up temporary
if (FreeFileSync::fileExists(temporary))
::unlink(temporary); //don't handle error situations!
diff --git a/shared/fileHandling.h b/shared/fileHandling.h
index b12f6f03..95d8fddd 100644
--- a/shared/fileHandling.h
+++ b/shared/fileHandling.h
@@ -1,5 +1,5 @@
-#ifndef RECYCLER_H_INCLUDED
-#define RECYCLER_H_INCLUDED
+#ifndef RECYCLER2_H_INCLUDED
+#define RECYCLER2_H_INCLUDED
#include "zstring.h"
#include "fileError.h"
@@ -83,4 +83,4 @@ void copyFile(const Zstring& sourceFile,
}
-#endif // RECYCLER_H_INCLUDED
+#endif // RECYCLER2_H_INCLUDED
diff --git a/shared/fileID.cpp b/shared/fileID.cpp
new file mode 100644
index 00000000..005707dc
--- /dev/null
+++ b/shared/fileID.cpp
@@ -0,0 +1,82 @@
+#include "fileID.h"
+
+#ifdef FFS_WIN
+#include "staticAssert.h"
+#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "longPathPrefix.h"
+
+#elif defined FFS_LINUX
+
+#endif
+
+
+
+#ifdef FFS_WIN
+class CloseHandleOnExit
+{
+public:
+ CloseHandleOnExit(HANDLE fileHandle) : fileHandle_(fileHandle) {}
+
+ ~CloseHandleOnExit()
+ {
+ ::CloseHandle(fileHandle_);
+ }
+
+private:
+ HANDLE fileHandle_;
+};
+
+
+Utility::FileID Utility::retrieveFileID(const Zstring& filename)
+{
+ //ensure our DWORD_FFS really is the same as DWORD
+ assert_static(sizeof(Utility::FileID::DWORD_FFS) == sizeof(DWORD));
+
+//WARNING: CreateFile() is SLOW, while GetFileInformationByHandle() is quite cheap!
+//http://msdn.microsoft.com/en-us/library/aa363788(VS.85).aspx
+
+ const HANDLE hFile = ::CreateFile(FreeFileSync::applyLongPathPrefix(filename).c_str(),
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, //FILE_FLAG_BACKUP_SEMANTICS needed to open directories
+ NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ CloseHandleOnExit dummy(hFile);
+
+ BY_HANDLE_FILE_INFORMATION info;
+ if (::GetFileInformationByHandle(hFile, &info))
+ {
+ return Utility::FileID(info.dwVolumeSerialNumber,
+ info.nFileIndexHigh,
+ info.nFileIndexLow);
+ }
+ }
+ return Utility::FileID(); //empty ID
+}
+
+
+#elif defined FFS_LINUX
+Utility::FileID Utility::retrieveFileID(const Zstring& filename)
+{
+ struct stat fileInfo;
+ if (::lstat(filename.c_str(), &fileInfo) == 0) //lstat() does not resolve symlinks
+ return Utility::FileID(fileInfo.st_dev, fileInfo.st_ino);
+
+ return Utility::FileID(); //empty ID
+}
+#endif
+
+
+bool Utility::sameFileSpecified(const Zstring& file1, const Zstring& file2)
+{
+ const Utility::FileID id1 = retrieveFileID(file1);
+ const Utility::FileID id2 = retrieveFileID(file2);
+
+ if (id1 != FileID() && id2 != FileID())
+ return id1 == id2;
+
+ return false;
+}
diff --git a/shared/fileID.h b/shared/fileID.h
new file mode 100644
index 00000000..7944b368
--- /dev/null
+++ b/shared/fileID.h
@@ -0,0 +1,194 @@
+#ifndef FILEID_H_INCLUDED
+#define FILEID_H_INCLUDED
+
+#include <wx/stream.h>
+#include "zstring.h"
+
+#ifdef FFS_WIN
+#elif defined FFS_LINUX
+#include <sys/stat.h>
+#endif
+
+
+//unique file identifier
+namespace Utility
+{
+class FileID
+{
+public:
+ //standard copy constructor and assignment operator are okay!
+
+ FileID(wxInputStream& stream); //read
+ void toStream(wxOutputStream& stream) const; //write
+
+ bool isNull() const;
+ bool operator==(const FileID& rhs) const;
+ bool operator!=(const FileID& rhs) const;
+ bool operator<(const FileID& rhs) const;
+
+ FileID();
+#ifdef FFS_WIN
+ typedef unsigned long DWORD_FFS; //we don't want do include "windows.h" or "<wx/msw/wrapwin.h>" here, do we?
+
+ FileID(DWORD_FFS dwVolumeSN,
+ DWORD_FFS fileIndexHi,
+ DWORD_FFS fileIndexLo);
+#elif defined FFS_LINUX
+ FileID(dev_t devId,
+ ino_t inId);
+#endif
+private:
+#ifdef FFS_WIN
+ DWORD_FFS dwVolumeSerialNumber;
+ DWORD_FFS nFileIndexHigh;
+ DWORD_FFS nFileIndexLow;
+#elif defined FFS_LINUX
+ dev_t deviceId;
+ ino_t inodeId;
+#endif
+};
+
+//get unique file id (symbolic link handling: opens the link!!!)
+//error condition: returns FileID ()
+FileID retrieveFileID(const Zstring& filename);
+
+//test whether two distinct paths point to the same file or directory:
+// true: paths point to same files/dirs
+// false: error occured OR point to different files/dirs
+bool sameFileSpecified(const Zstring& file1, const Zstring& file2);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//---------------Inline Implementation---------------------------------------------------
+#ifdef FFS_WIN
+inline
+Utility::FileID::FileID() :
+ dwVolumeSerialNumber(0),
+ nFileIndexHigh(0),
+ nFileIndexLow(0) {}
+
+inline
+Utility::FileID::FileID(DWORD_FFS dwVolumeSN,
+ DWORD_FFS fileIndexHi,
+ DWORD_FFS fileIndexLo) :
+ dwVolumeSerialNumber(dwVolumeSN),
+ nFileIndexHigh(fileIndexHi),
+ nFileIndexLow(fileIndexLo) {}
+
+inline
+bool Utility::FileID::isNull() const
+{
+ return dwVolumeSerialNumber == 0 &&
+ nFileIndexHigh == 0 &&
+ nFileIndexLow == 0;
+}
+
+inline
+bool Utility::FileID::operator==(const FileID& rhs) const
+{
+ return dwVolumeSerialNumber == rhs.dwVolumeSerialNumber &&
+ nFileIndexHigh == rhs.nFileIndexHigh &&
+ nFileIndexLow == rhs.nFileIndexLow;
+}
+
+inline
+bool Utility::FileID::operator<(const FileID& rhs) const
+{
+ if (dwVolumeSerialNumber != rhs.dwVolumeSerialNumber)
+ return dwVolumeSerialNumber < rhs.dwVolumeSerialNumber;
+
+ if (nFileIndexHigh != rhs.nFileIndexHigh)
+ return nFileIndexHigh < rhs.nFileIndexHigh;
+
+ return nFileIndexLow < rhs.nFileIndexLow;
+}
+
+inline
+Utility::FileID::FileID(wxInputStream& stream) //read
+{
+ stream.Read(&dwVolumeSerialNumber, sizeof(dwVolumeSerialNumber));
+ stream.Read(&nFileIndexHigh, sizeof(nFileIndexHigh));
+ stream.Read(&nFileIndexLow, sizeof(nFileIndexLow));
+}
+
+inline
+void Utility::FileID::toStream(wxOutputStream& stream) const //write
+{
+ stream.Write(&dwVolumeSerialNumber, sizeof(dwVolumeSerialNumber));
+ stream.Write(&nFileIndexHigh, sizeof(nFileIndexHigh));
+ stream.Write(&nFileIndexLow, sizeof(nFileIndexLow));
+}
+
+#elif defined FFS_LINUX
+inline
+Utility::FileID::FileID() :
+ deviceId(0),
+ inodeId(0) {}
+
+inline
+Utility::FileID::FileID(dev_t devId,
+ ino_t inId) :
+ deviceId(devId),
+ inodeId(inId) {}
+
+inline
+bool Utility::FileID::isNull() const
+{
+ return deviceId == 0 &&
+ inodeId == 0;
+}
+
+inline
+bool Utility::FileID::operator==(const FileID& rhs) const
+{
+ return deviceId == rhs.deviceId &&
+ inodeId == rhs.inodeId;
+}
+
+inline
+bool Utility::FileID::operator<(const FileID& rhs) const
+{
+ if (deviceId != rhs.deviceId)
+ return deviceId < rhs.deviceId;
+
+ return inodeId < rhs.inodeId;
+}
+
+inline
+Utility::FileID::FileID(wxInputStream& stream) //read
+{
+ stream.Read(&deviceId, sizeof(deviceId));
+ stream.Read(&inodeId, sizeof(inodeId));
+}
+
+inline
+void Utility::FileID::toStream(wxOutputStream& stream) const //write
+{
+ stream.Write(&deviceId, sizeof(deviceId));
+ stream.Write(&inodeId, sizeof(inodeId));
+}
+#endif
+inline
+bool Utility::FileID::operator!=(const FileID& rhs) const
+{
+ return !(*this == rhs);
+}
+
+#endif // FILEID_H_INCLUDED
diff --git a/shared/fileTraverser.cpp b/shared/fileTraverser.cpp
index c323f1a3..7d2615bf 100644
--- a/shared/fileTraverser.cpp
+++ b/shared/fileTraverser.cpp
@@ -6,6 +6,7 @@
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "longPathPrefix.h"
#elif defined FFS_LINUX
#include <sys/stat.h>
@@ -22,7 +23,7 @@ public:
~CloseHandleOnExit()
{
- CloseHandle(fileHandle_);
+ ::CloseHandle(fileHandle_);
}
private:
@@ -65,7 +66,7 @@ inline
bool setWin32FileInformationFromSymlink(const Zstring linkName, FreeFileSync::TraverseCallback::FileInfo& output)
{
//open handle to target of symbolic link
- HANDLE hFile = ::CreateFile(linkName.c_str(),
+ HANDLE hFile = ::CreateFile(FreeFileSync::applyLongPathPrefix(linkName).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -129,8 +130,8 @@ bool traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
directory + globalFunctions::FILE_NAME_SEPARATOR;
WIN32_FIND_DATA fileMetaData;
- HANDLE searchHandle = FindFirstFile((directoryFormatted + DefaultChar('*')).c_str(), //__in LPCTSTR lpFileName
- &fileMetaData); //__out LPWIN32_FIND_DATA lpFindFileData
+ HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(directoryFormatted + DefaultChar('*')).c_str(), //__in LPCTSTR lpFileName
+ &fileMetaData); //__out LPWIN32_FIND_DATA lpFindFileData
//no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH
if (searchHandle == INVALID_HANDLE_VALUE)
@@ -140,8 +141,10 @@ bool traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
return true;
//else: we have a problem... report it:
- const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- switch (sink->onError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted(lastError)))
+ const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") + wxT("\n\n") +
+ FreeFileSync::getLastErrorFormatted(lastError);
+
+ switch (sink->onError(errorMessage))
{
case TraverseCallback::TRAVERSING_STOP:
return false;
@@ -205,8 +208,8 @@ bool traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
}
}
}
- while (FindNextFile(searchHandle, // handle to search
- &fileMetaData)); // pointer to structure for data on found file
+ while (::FindNextFile(searchHandle, // handle to search
+ &fileMetaData)); // pointer to structure for data on found file
const DWORD lastError = ::GetLastError();
if (lastError == ERROR_NO_MORE_FILES)
@@ -362,3 +365,6 @@ void FreeFileSync::traverseFolder(const Zstring& directory,
else
traverseDirectory<false>(directoryFormatted, sink, 0);
}
+
+
+
diff --git a/shared/localization.cpp b/shared/localization.cpp
index ad3cbb99..5f017989 100644
--- a/shared/localization.cpp
+++ b/shared/localization.cpp
@@ -53,7 +53,7 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageID = wxLANGUAGE_SPANISH;
newEntry.languageName = wxT("Español");
newEntry.languageFile = wxT("spanish.lng");
- newEntry.translatorName = wxT("David Rodríguez");
+ newEntry.translatorName = wxT("Alexis Martínez");
newEntry.languageFlag = wxT("spain.png");
locMapping.push_back(newEntry);
@@ -134,6 +134,13 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageFlag = wxT("finland.png");
locMapping.push_back(newEntry);
+ newEntry.languageID = wxLANGUAGE_SWEDISH;
+ newEntry.languageName = wxT("Svenska");
+ newEntry.languageFile = wxT("swedish.lng");
+ newEntry.translatorName = wxT("Ã…ke Engelbrektson");
+ newEntry.languageFlag = wxT("sweden.png");
+ locMapping.push_back(newEntry);
+
newEntry.languageID = wxLANGUAGE_TURKISH;
newEntry.languageName = wxT("Türkçe");
newEntry.languageFile = wxT("turkish.lng");
@@ -230,6 +237,10 @@ int mapLanguageDialect(const int language)
case wxLANGUAGE_SPANISH_VENEZUELA:
return wxLANGUAGE_SPANISH;
+ //variants of wxLANGUAGE_SWEDISH
+ case wxLANGUAGE_SWEDISH_FINLAND:
+ return wxLANGUAGE_SWEDISH;
+
//case wxLANGUAGE_CZECH:
//case wxLANGUAGE_FINNISH:
//case wxLANGUAGE_JAPANESE:
diff --git a/shared/longPathPrefix.cpp b/shared/longPathPrefix.cpp
new file mode 100644
index 00000000..9ce74c8b
--- /dev/null
+++ b/shared/longPathPrefix.cpp
@@ -0,0 +1,95 @@
+#include "longPathPrefix.h"
+#include <boost/scoped_array.hpp>
+#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "fileError.h"
+#include "systemFunctions.h"
+#include "stringConv.h"
+#include <wx/intl.h>
+
+namespace
+{
+Zstring getFullPathName(const Zstring& relativeName, size_t proposedBufferSize = 1000)
+{
+ using namespace FreeFileSync;
+
+ boost::scoped_array<DefaultChar> fullPath(new DefaultChar[proposedBufferSize]);
+ const DWORD rv = ::GetFullPathName(
+ relativeName.c_str(), //__in LPCTSTR lpFileName,
+ proposedBufferSize, //__in DWORD nBufferLength,
+ fullPath.get(), //__out LPTSTR lpBuffer,
+ NULL); //__out LPTSTR *lpFilePart
+ if (rv == 0 || rv == proposedBufferSize)
+ throw FileError(wxString(_("Error resolving full path name:")) + wxT("\n\"") + zToWx(relativeName) + wxT("\"") +
+ wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ if (rv > proposedBufferSize)
+ return getFullPathName(relativeName, rv);
+
+ return fullPath.get();
+}
+}
+
+
+Zstring FreeFileSync::resolveRelativePath(const Zstring& path) //throw()
+{
+ try
+ {
+ return getFullPathName(path);
+ }
+ catch (...)
+ {
+ return path;
+ }
+}
+
+
+//there are two flavors of long path prefix: one for UNC paths, one for regular paths
+const Zstring LONG_PATH_PREFIX = DefaultStr("\\\\?\\");
+const Zstring LONG_PATH_PREFIX_UNC = DefaultStr("\\\\?\\UNC");
+
+template <size_t max_path>
+inline
+Zstring applyLongPathPrefixImpl(const Zstring& path)
+{
+ if ( path.length() >= max_path && //maximum allowed path length without prefix is (MAX_PATH - 1)
+ !path.StartsWith(LONG_PATH_PREFIX))
+ {
+ if (path.StartsWith(DefaultStr("\\\\"))) //UNC-name, e.g. \\zenju-pc\Users
+ return LONG_PATH_PREFIX_UNC + path.AfterFirst(DefaultChar('\\')); //convert to \\?\UNC\zenju-pc\Users
+ else
+ return LONG_PATH_PREFIX + path; //prepend \\?\ prefix
+ }
+
+ //fallback
+ return path;
+}
+
+
+Zstring FreeFileSync::applyLongPathPrefix(const Zstring& path)
+{
+ return applyLongPathPrefixImpl<MAX_PATH>(path);
+}
+
+
+Zstring FreeFileSync::applyLongPathPrefixCreateDir(const Zstring& path) //throw()
+{
+ //special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold
+ return applyLongPathPrefixImpl<MAX_PATH - 12>(path);
+}
+
+
+Zstring FreeFileSync::removeLongPathPrefix(const Zstring& path) //throw()
+{
+ if (path.StartsWith(LONG_PATH_PREFIX))
+ {
+ Zstring finalPath = path;
+ if (path.StartsWith(LONG_PATH_PREFIX_UNC)) //UNC-name
+ finalPath.Replace(LONG_PATH_PREFIX_UNC, DefaultStr("\\"), false);
+ else
+ finalPath.Replace(LONG_PATH_PREFIX, DefaultStr(""), false);
+ return finalPath;
+ }
+
+ //fallback
+ return path;
+}
+
diff --git a/shared/longPathPrefix.h b/shared/longPathPrefix.h
new file mode 100644
index 00000000..e4834184
--- /dev/null
+++ b/shared/longPathPrefix.h
@@ -0,0 +1,27 @@
+#ifndef LONGPATHPREFIX_H_INCLUDED
+#define LONGPATHPREFIX_H_INCLUDED
+
+#ifndef FFS_WIN
+use in windows build only!
+#endif
+
+#include "zstring.h"
+
+namespace FreeFileSync
+{
+
+Zstring resolveRelativePath(const Zstring& path); //throw()
+
+//handle filenames longer-equal 260 (== MAX_PATH) characters by applying \\?\-prefix (Reference: http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath)
+/*
+1. path must be absolute
+2. if path is smaller than MAX_PATH nothing is changed!
+3. path may already contain \\?\-prefix
+*/
+Zstring applyLongPathPrefix(const Zstring& path); //throw()
+Zstring applyLongPathPrefixCreateDir(const Zstring& path); //throw() -> special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold
+
+Zstring removeLongPathPrefix(const Zstring& path); //throw()
+}
+
+#endif // LONGPATHPREFIX_H_INCLUDED
diff --git a/shared/recycler.cpp b/shared/recycler.cpp
new file mode 100644
index 00000000..b3bb87dd
--- /dev/null
+++ b/shared/recycler.cpp
@@ -0,0 +1,128 @@
+#include "recycler.h"
+#include "dllLoader.h"
+#include <wx/intl.h>
+#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "buildInfo.h"
+#include "staticAssert.h"
+#include <algorithm>
+#include <functional>
+//#include "../shared/longPathPrefix.h"
+
+const std::wstring& getRecyclerDllName()
+{
+ static const std::wstring filename(
+ Utility::is64BitBuild ?
+ L"Recycler_x64.dll":
+ L"Recycler_Win32.dll");
+
+ assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
+
+ return filename;
+}
+
+
+bool vistaOrLater()
+{
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ //IFileOperation is supported with Vista and later
+ if (GetVersionEx(&osvi))
+ return osvi.dwMajorVersion > 5;
+ //XP has majorVersion == 5, minorVersion == 1
+ //Vista has majorVersion == 6, minorVersion == 0
+ //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
+ return false;
+}
+
+/*
+Performance test: delete 1000 files
+------------------------------------
+SHFileOperation - single file 33s
+SHFileOperation - multiple files 2,1s
+IFileOperation - single file 33s
+IFileOperation - multiple files 2,1s
+
+=> SHFileOperation and IFileOperation have nearly IDENTICAL performance characteristics!
+
+Nevertheless, let's use IFileOperation for better error reporting!
+*/
+
+void FreeFileSync::moveToWindowsRecycler(const Zstring& fileToDelete) //throw (FileError)
+{
+ std::vector<Zstring> fileNames;
+ fileNames.push_back(fileToDelete);
+ moveToWindowsRecycler(fileNames); //throw (FileError)
+}
+
+
+void FreeFileSync::moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (FileError)
+{
+ if (filesToDelete.empty())
+ return;
+
+ static const bool useIFileOperation = vistaOrLater();
+
+ if (useIFileOperation) //new recycle bin usage: available since Vista
+ {
+ typedef bool (*MoveToRecycleBinFunc)(
+ const wchar_t* fileNames[],
+ size_t fileNo, //size of fileNames array
+ wchar_t* errorMessage,
+ size_t errorBufferLen);
+
+ static const MoveToRecycleBinFunc moveToRecycler =
+ Utility::loadDllFunction<MoveToRecycleBinFunc>(getRecyclerDllName().c_str(), "moveToRecycleBin");
+
+ if (moveToRecycler == NULL)
+ throw FileError(wxString(_("Could not load a required DLL:")) + wxT(" \"") + getRecyclerDllName().c_str() + wxT("\""));
+
+ //#warning moving long file paths to recycler does not work! clarify!
+// std::vector<Zstring> temp;
+// std::transform(filesToDelete.begin(), filesToDelete.end(),
+// std::back_inserter(temp), std::ptr_fun(FreeFileSync::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix!
+
+ std::vector<const wchar_t*> fileNames;
+ std::transform(filesToDelete.begin(), filesToDelete.end(),
+ std::back_inserter(fileNames), std::mem_fun_ref(&Zstring::c_str));
+
+ wchar_t errorMessage[2000];
+ if (!(*moveToRecycler)(&fileNames[0], //array must not be empty
+ fileNames.size(),
+ errorMessage,
+ 2000))
+ {
+ throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + fileNames[0] + wxT("\"") + //report first file only... better than nothing
+ + wxT("\n\n") +
+ wxT("(") + errorMessage + wxT(")"));
+ }
+ }
+ else //regular recycle bin usage: available since XP
+ {
+ Zstring filenameDoubleNull;
+ for (std::vector<Zstring>::const_iterator i = filesToDelete.begin(); i != filesToDelete.end(); ++i)
+ {
+ //#warning moving long file paths to recycler does not work! clarify!
+ //filenameDoubleNull += removeLongPathPrefix(*i); //::SHFileOperation() can't handle \\?\-prefix!
+ filenameDoubleNull += *i; //::SHFileOperation() can't handle \\?\-prefix!
+ filenameDoubleNull += DefaultChar(0);
+ }
+
+ SHFILEOPSTRUCT fileOp;
+ fileOp.hwnd = NULL;
+ fileOp.wFunc = FO_DELETE;
+ fileOp.pFrom = filenameDoubleNull.c_str();
+ fileOp.pTo = NULL;
+ fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
+ fileOp.fAnyOperationsAborted = false;
+ fileOp.hNameMappings = NULL;
+ fileOp.lpszProgressTitle = NULL;
+
+ if (SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted)
+ {
+ throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + filenameDoubleNull.c_str() + wxT("\"")); //report first file only... better than nothing
+ }
+ }
+}
+
diff --git a/shared/recycler.h b/shared/recycler.h
new file mode 100644
index 00000000..14aff4c0
--- /dev/null
+++ b/shared/recycler.h
@@ -0,0 +1,21 @@
+#ifndef RECYCLER_H_INCLUDED
+#define RECYCLER_H_INCLUDED
+
+#include "fileError.h"
+#include "zstring.h"
+#include <vector>
+
+#ifndef FFS_WIN
+use in windows build only!
+#endif
+
+
+namespace FreeFileSync
+{
+//single-file processing
+void moveToWindowsRecycler(const Zstring& fileToDelete); //throw (FileError)
+//multi-file processing: about a factor of 15 faster than single-file
+void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete); //throw (FileError) -> on error reports about first file only!
+}
+
+#endif // RECYCLER_H_INCLUDED
diff --git a/shared/shadow.cpp b/shared/shadow.cpp
index 29eec53b..7e3b34c0 100644
--- a/shared/shadow.cpp
+++ b/shared/shadow.cpp
@@ -2,6 +2,10 @@
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include <wx/intl.h>
#include "systemConstants.h"
+#include "dllLoader.h"
+#include <stdexcept>
+#include "staticAssert.h"
+#include "buildInfo.h"
using FreeFileSync::ShadowCopy;
@@ -12,7 +16,6 @@ bool newerThanXP()
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) ;
@@ -42,93 +45,78 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
}
-class ShadowCopy::ShadowlDllHandler //dynamically load windows API functions
+const wxString& getShadowDllName()
{
- typedef bool (*CreateShadowCopyFct)( //volumeName must end with "\", while shadowVolName does not end with "\"
- const wchar_t* volumeName,
- wchar_t* shadowVolName,
- unsigned int shadowBufferLen,
- void** backupHandle,
- wchar_t* errorMessage,
- unsigned int errorBufferLen);
+ /*
+ 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
+ */
- typedef void (*ReleaseShadowCopyFct)(void* backupHandle);
+ static const wxString filename(
+ Utility::is64BitBuild ?
+ (newerThanXP() ?
+ wxT("Shadow_Server2003_x64.dll") :
+ wxT("Shadow_XP_x64.dll")) :
-public:
- static const wxString& getShadowDllName()
- {
- /*
- 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;
- }
+ (newerThanXP() ?
+ wxT("Shadow_Server2003_Win32.dll") :
+ wxT("Shadow_XP_Win32.dll")));
- ShadowlDllHandler() :
- createShadowCopy(NULL),
- releaseShadowCopy(NULL),
- hShadow(NULL)
- {
- //get a handle to the DLL module containing the required functionality
- hShadow = ::LoadLibrary(getShadowDllName().c_str());
- if (hShadow)
- {
- createShadowCopy = reinterpret_cast<CreateShadowCopyFct>(::GetProcAddress(hShadow, "createShadowCopy"));
- releaseShadowCopy = reinterpret_cast<ReleaseShadowCopyFct>(::GetProcAddress(hShadow, "releaseShadowCopy"));
- }
- }
+ assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
- ~ShadowlDllHandler()
- {
- if (hShadow) ::FreeLibrary(hShadow);
- }
-
- CreateShadowCopyFct createShadowCopy;
- ReleaseShadowCopyFct releaseShadowCopy;
+ return filename;
+}
-private:
- HINSTANCE hShadow;
-};
//#############################################################################################################
ShadowCopy::ShadowCopy() :
- backupHandle(NULL)
-{
- shadowDll = new ShadowlDllHandler;
-}
+ backupHandle(NULL) {}
ShadowCopy::~ShadowCopy()
{
if (backupHandle != NULL)
- shadowDll->releaseShadowCopy(backupHandle);
+ {
+ typedef void (*ReleaseShadowCopyFct)(void* backupHandle);
+ static const ReleaseShadowCopyFct releaseShadowCopy =
+ Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), "releaseShadowCopy");
+
+ if (releaseShadowCopy == NULL)
+ throw std::logic_error("Could not load \"releaseShadowCopy\"!"); //shouldn't arrive here!
- delete shadowDll;
+ releaseShadowCopy(backupHandle);
+ }
}
Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
{
+ typedef bool (*CreateShadowCopyFct)( //volumeName must end with "\", while shadowVolName does not end with "\"
+ const wchar_t* volumeName,
+ wchar_t* shadowVolName,
+ unsigned int shadowBufferLen,
+ void** backupHandle,
+ wchar_t* errorMessage,
+ unsigned int errorBufferLen);
+ static const CreateShadowCopyFct createShadowCopy =
+ Utility::loadDllFunction<CreateShadowCopyFct>(getShadowDllName().c_str(), "createShadowCopy");
+
+
+ typedef void (*ReleaseShadowCopyFct)(void* backupHandle);
+ static const ReleaseShadowCopyFct releaseShadowCopy =
+ Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), "releaseShadowCopy");
+
+
+
//check if shadow copy dll was loaded correctly
- if ( shadowDll->createShadowCopy == NULL ||
- shadowDll->releaseShadowCopy == NULL)
+ if ( createShadowCopy == NULL ||
+ 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") +
- _("Could not load a required DLL:") + wxT(" \"") + ShadowlDllHandler::getShadowDllName() + wxT("\""));
+ _("Could not load a required DLL:") + wxT(" \"") + getShadowDllName() + wxT("\""));
}
//VSS does not support running under WOW64 except for Windows XP and Windows Server 2003
@@ -146,7 +134,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
//---------------------------------------------------------------------------------------------------------
wchar_t volumeNameRaw[1000];
- if (!GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName,
+ if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName,
volumeNameRaw, //__out LPTSTR lpszVolumePathName,
1000)) //__in DWORD cchBufferLength
{
@@ -164,7 +152,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
//release old shadow copy
if (backupHandle != NULL)
{
- shadowDll->releaseShadowCopy(backupHandle);
+ releaseShadowCopy(backupHandle);
backupHandle = NULL;
}
realVolumeLast.clear(); //...if next call fails...
@@ -175,7 +163,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
void* backupHandleTmp = NULL;
wchar_t errorMessage[1000];
- if (!shadowDll->createShadowCopy(
+ if (!createShadowCopy(
volumeNameFormatted.c_str(),
shadowVolName,
1000,
@@ -194,7 +182,8 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
backupHandle = backupHandleTmp;
}
- const size_t pos = inputFile.find(volumeNameFormatted);
+ //input file is always absolute! directory formatting takes care of this! Therefore volume name can always be found.
+ const size_t pos = inputFile.find(volumeNameFormatted); //inputFile needs NOT to begin with volumeNameFormatted: consider for example \\?\ prefix!
if (pos == Zstring::npos)
{
wxString errorMsg = _("Error copying locked file %x!");
@@ -209,4 +198,3 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
return shadowVolumeLast + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
}
-
diff --git a/shared/shadow.h b/shared/shadow.h
index 79e0e59c..78100f78 100644
--- a/shared/shadow.h
+++ b/shared/shadow.h
@@ -23,9 +23,6 @@ private:
ShadowCopy(const ShadowCopy&);
ShadowCopy& operator=(const ShadowCopy&);
- class ShadowlDllHandler;
- const ShadowlDllHandler* shadowDll;
-
Zstring realVolumeLast; //buffer last volume name
Zstring shadowVolumeLast; //buffer last created shadow volume
void* backupHandle;
diff --git a/shared/zstring.cpp b/shared/zstring.cpp
index cb288ea2..c3d5ba8e 100644
--- a/shared/zstring.cpp
+++ b/shared/zstring.cpp
@@ -4,6 +4,7 @@
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include "dllLoader.h"
+#include <boost/scoped_array.hpp>
#endif //FFS_WIN
#ifdef __WXDEBUG__
@@ -45,60 +46,122 @@ AllocationCount& AllocationCount::getInstance()
}
#endif
-
#ifdef FFS_WIN
+bool hasInvariantLocale()
+{
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ //invariant locale has been introduced with XP
+ if (GetVersionEx(&osvi))
+ return osvi.dwMajorVersion > 5 ||
+ (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion >= 1); //XP has majorVersion == 5, minorVersion == 1
+ //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
+ return false;
+}
#ifndef LOCALE_INVARIANT
#define LOCALE_INVARIANT 0x007f
#endif
+//warning: LOCALE_INVARIANT is NOT available with Windows 2000, so we have to make yet another distinction...
+namespace
+{
+const LCID invariantLocale = hasInvariantLocale() ?
+ LOCALE_INVARIANT :
+ MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); //see: http://msdn.microsoft.com/en-us/goglobal/bb688122.aspx
+}
+
inline
-int compareStringsWin32(const wchar_t* a, const wchar_t* b, const int aCount = -1, const int bCount = -1)
+int compareFilenamesWin32(const wchar_t* a, const wchar_t* b, size_t sizeA, size_t sizeB)
{
- //try to call "CompareStringOrdinal" first for low-level string comparison: unfortunately available not before Windows Vista!
+ //try to call "CompareStringOrdinal" for low-level string comparison: unfortunately available not before Windows Vista!
+ //by a factor ~3 faster than old string comparison using "LCMapString"
typedef int (WINAPI *CompareStringOrdinalFunc)(
LPCWSTR lpString1,
int cchCount1,
LPCWSTR lpString2,
int cchCount2,
BOOL bIgnoreCase);
- static const CompareStringOrdinalFunc ordinalCompare = Utility::loadDllFunKernel<CompareStringOrdinalFunc>("CompareStringOrdinal");
+ static const CompareStringOrdinalFunc ordinalCompare = Utility::loadDllFunction<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal");
-
- //we're lucky here! This additional test for "CompareStringOrdinal" has no noticeable performance impact!!
- if (ordinalCompare != NULL)
+ if (ordinalCompare != NULL) //this additional test has no noticeable performance impact
{
const int rv = (*ordinalCompare)(
a, //pointer to first string
- aCount, //size, in bytes or characters, of first string
+ sizeA, //size, in bytes or characters, of first string
b, //pointer to second string
- bCount, //size, in bytes or characters, of second string
+ sizeB, //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"!!!
+ else //fallback
{
- //DON'T use lstrcmpi() here! It uses word sort and is locale dependent!
- //Use CompareString() with "SORT_STRINGSORT" instead!!!
+//do NOT use "CompareString"; this function is NOT accurate (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!!
+//the only reliable way to compare filenames (with XP) is to call "CharUpper" or "LCMapString":
- const int 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
+ const size_t minSize = std::min(sizeA, sizeB);
- if (rv == 0)
- throw std::runtime_error("Error comparing strings!");
- else
- return rv - 2; //convert to C-style string compare result
+ if (minSize == 0) //LCMapString does not allow input sizes of 0!
+ return sizeA - sizeB;
+
+ int rv = 0; //always initialize...
+ if (minSize <= 5000) //performance optimization: stack
+ {
+ wchar_t bufferA[5000];
+ wchar_t bufferB[5000];
+
+ if (::LCMapString( //faster than CharUpperBuff + wmemcpy or CharUpper + wmemcpy and same speed like ::CompareString()
+ invariantLocale, //__in LCID Locale,
+ LCMAP_UPPERCASE, //__in DWORD dwMapFlags,
+ a, //__in LPCTSTR lpSrcStr,
+ minSize, //__in int cchSrc,
+ bufferA, //__out LPTSTR lpDestStr,
+ 5000 //__in int cchDest
+ ) == 0)
+ throw std::runtime_error("Error comparing strings! (LCMapString)");
+
+ if (::LCMapString(invariantLocale, LCMAP_UPPERCASE, b, minSize, bufferB, 5000) == 0)
+ throw std::runtime_error("Error comparing strings! (LCMapString)");
+
+ rv = ::wmemcmp(bufferA, bufferB, minSize);
+ }
+ else //use freestore
+ {
+ boost::scoped_array<wchar_t> bufferA(new wchar_t[minSize]);
+ boost::scoped_array<wchar_t> bufferB(new wchar_t[minSize]);
+
+ if (::LCMapString(invariantLocale, LCMAP_UPPERCASE, a, minSize, bufferA.get(), minSize) == 0)
+ throw std::runtime_error("Error comparing strings! (LCMapString: FS)");
+
+ if (::LCMapString(invariantLocale, LCMAP_UPPERCASE, b, minSize, bufferB.get(), minSize) == 0)
+ throw std::runtime_error("Error comparing strings! (LCMapString: FS)");
+
+ rv = ::wmemcmp(bufferA.get(), bufferB.get(), minSize);
+ }
+
+ return rv == 0 ?
+ sizeA - sizeB :
+ rv;
}
+
+// const int rv = CompareString(
+// invariantLocale, //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
@@ -106,13 +169,13 @@ int compareStringsWin32(const wchar_t* a, const wchar_t* b, const int aCount = -
#ifdef FFS_WIN
int Zstring::CmpNoCase(const DefaultChar* other) const
{
- return ::compareStringsWin32(c_str(), other); //way faster than wxString::CmpNoCase()!!
+ return ::compareFilenamesWin32(c_str(), other, length(), ::wcslen(other)); //way faster than wxString::CmpNoCase()
}
int Zstring::CmpNoCase(const Zstring& other) const
{
- return ::compareStringsWin32(c_str(), other.c_str(), length(), other.length()); //way faster than wxString::CmpNoCase()!!
+ return ::compareFilenamesWin32(c_str(), other.c_str(), length(), other.length()); //way faster than wxString::CmpNoCase()
}
#endif
@@ -277,14 +340,17 @@ std::vector<Zstring> Zstring::Tokenize(const DefaultChar delimiter) const
#ifdef FFS_WIN
-Zstring& Zstring::MakeLower()
+Zstring& Zstring::MakeUpper()
{
const size_t thisLen = length();
if (thisLen == 0)
return *this;
reserve(thisLen); //make unshared
- ::CharLower(data()); //use Windows' lower case conversion
+
+ //use Windows' upper case conversion: faster than ::CharUpper()
+ if (::LCMapString(invariantLocale, LCMAP_UPPERCASE, data(), thisLen, data(), thisLen) == 0)
+ throw std::runtime_error("Error converting to upper case! (LCMapString)");
return *this;
}
@@ -484,3 +550,4 @@ void Zstring::reserve(size_t capacityNeeded) //make unshared and check capacity
descr->capacity = newCapacity;
}
}
+
diff --git a/shared/zstring.h b/shared/zstring.h
index d0be30bf..cb047e15 100644
--- a/shared/zstring.h
+++ b/shared/zstring.h
@@ -52,7 +52,7 @@ public:
#ifdef FFS_WIN
int CmpNoCase(const DefaultChar* other) const;
int CmpNoCase(const Zstring& other) const;
- Zstring& MakeLower();
+ Zstring& MakeUpper();
#endif
int Cmp(const DefaultChar* other) const;
int Cmp(const Zstring& other) const;
@@ -134,6 +134,28 @@ template <class T>
Zstring numberToZstring(const T& number); //convert number to Zstring
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
//#######################################################################################
//begin of implementation
diff --git a/structures.cpp b/structures.cpp
index 8653f43a..4cf6b335 100644
--- a/structures.cpp
+++ b/structures.cpp
@@ -64,13 +64,13 @@ SyncConfiguration::Variant SyncConfiguration::getVariant() const
conflict == SYNC_DIR_NONE)
return UPDATE; //Update ->
- else if (exLeftSideOnly == SYNC_DIR_RIGHT &&
- exRightSideOnly == SYNC_DIR_LEFT &&
- leftNewer == SYNC_DIR_RIGHT &&
- rightNewer == SYNC_DIR_LEFT &&
- different == SYNC_DIR_NONE &&
- conflict == SYNC_DIR_NONE)
- return TWOWAY; //two way <->
+// else if (exLeftSideOnly == SYNC_DIR_RIGHT && -> variant "twoway" is not selectable via gui anymore
+// exRightSideOnly == SYNC_DIR_LEFT &&
+// leftNewer == SYNC_DIR_RIGHT &&
+// rightNewer == SYNC_DIR_LEFT &&
+// different == SYNC_DIR_NONE &&
+// conflict == SYNC_DIR_NONE)
+// return TWOWAY; //two way <->
else
return CUSTOM; //other
}
@@ -127,8 +127,7 @@ wxString SyncConfiguration::getVariantName() const
return _("Mirror ->>");
case SyncConfiguration::UPDATE:
return _("Update ->");
- case SyncConfiguration::TWOWAY:
- return _("Two way <->");
+ case SyncConfiguration::TWOWAY: //variant "twoway" is not selectable via gui anymore
case SyncConfiguration::CUSTOM:
return _("Custom");
}
@@ -230,6 +229,8 @@ wxString FreeFileSync::getDescription(SyncOperation op)
return _("Copy from left to right overwriting");
case SO_DO_NOTHING:
return _("Do nothing");
+ case SO_EQUAL:
+ return _("Files that are equal on both sides");
case SO_UNRESOLVED_CONFLICT:
return _("Conflicts/files that cannot be categorized");
};
@@ -257,6 +258,8 @@ wxString FreeFileSync::getSymbol(SyncOperation op)
return wxT("->");
case SO_DO_NOTHING:
return wxT("-");
+ case SO_EQUAL:
+ return wxT("'=="); //added quotation mark to avoid error in Excel cell when exporting to *.cvs
case SO_UNRESOLVED_CONFLICT:
return wxT("\\/\\->");
};
@@ -264,5 +267,3 @@ wxString FreeFileSync::getSymbol(SyncOperation op)
assert(false);
return wxEmptyString;
}
-
-
diff --git a/structures.h b/structures.h
index ba9c3ada..212f9557 100644
--- a/structures.h
+++ b/structures.h
@@ -277,7 +277,8 @@ enum SyncOperation
SO_DELETE_RIGHT,
SO_OVERWRITE_LEFT,
SO_OVERWRITE_RIGHT,
- SO_DO_NOTHING,
+ SO_DO_NOTHING, //= both sides differ, but nothing will be synced
+ SO_EQUAL, //= both sides are equal, so nothing will be synced
SO_UNRESOLVED_CONFLICT
};
diff --git a/synchronization.cpp b/synchronization.cpp
index fac3d9a4..b00d35b7 100644
--- a/synchronization.cpp
+++ b/synchronization.cpp
@@ -13,9 +13,11 @@
#include "shared/globalFunctions.h"
#include <boost/scoped_array.hpp>
#include <memory>
+//#include "library/detectRenaming.h"
#ifdef FFS_WIN
#include "shared/shadow.h"
+#include "shared/longPathPrefix.h"
#endif
using namespace FreeFileSync;
@@ -74,6 +76,10 @@ int SyncStatistics::getConflict() const
return conflict;
}
+const SyncStatistics::ConflictTexts& SyncStatistics::getFirstConflicts() const //get first few sync conflicts
+{
+ return firstConflicts;
+}
wxULongLong SyncStatistics::getDataToProcess() const
{
@@ -100,9 +106,6 @@ void SyncStatistics::getNumbersRecursively(const HierarchyObject& hierObj)
rowsTotal += hierObj.subDirs.size();
rowsTotal += hierObj.subFiles.size();
-
- //recurse into sub-dirs
- std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), boost::bind(&SyncStatistics::getNumbersRecursively, this, _1));
}
@@ -140,10 +143,13 @@ void SyncStatistics::getFileNumbers(const FileMapping& fileObj)
break;
case SO_DO_NOTHING:
+ case SO_EQUAL:
break;
case SO_UNRESOLVED_CONFLICT:
++conflict;
+ if (firstConflicts.size() < 3) //save the first 3 conflict texts
+ firstConflicts.push_back(std::make_pair(fileObj.getObjRelativeName(), fileObj.getSyncOpConflict()));
break;
}
}
@@ -177,8 +183,12 @@ void SyncStatistics::getDirNumbers(const DirMapping& dirObj)
break;
case SO_DO_NOTHING:
+ case SO_EQUAL:
break;
}
+
+ //recurse into sub-dirs
+ getNumbersRecursively(dirObj);
}
@@ -256,6 +266,7 @@ private:
break;
case SO_DO_NOTHING:
+ case SO_EQUAL:
case SO_UNRESOLVED_CONFLICT:
break;
}
@@ -437,16 +448,16 @@ bool deletionImminent(const FileSystemObject& fsObj)
class RemoveInvalid
{
public:
- RemoveInvalid(HierarchyObject& hierObj) :
- hierObj_(hierObj) {}
+ RemoveInvalid(BaseDirMapping& baseDir) :
+ baseDir_(baseDir) {}
~RemoveInvalid()
{
- FileSystemObject::removeEmptyNonRec(hierObj_);
+ FileSystemObject::removeEmpty(baseDir_);
}
private:
- HierarchyObject& hierObj_;
+ BaseDirMapping& baseDir_;
};
@@ -477,9 +488,6 @@ public:
template <bool deleteOnly> //"true" if files deletion shall happen only
void execute(HierarchyObject& hierObj)
{
- //enforce removal of invalid entries (where both sides are empty)
- RemoveInvalid dummy(hierObj); //non-recursive
-
//synchronize files:
for (HierarchyObject::SubFileMapping::iterator i = hierObj.subFiles.begin(); i != hierObj.subFiles.end(); ++i)
{
@@ -516,7 +524,8 @@ public:
case SO_DELETE_LEFT:
case SO_DELETE_RIGHT:
case SO_DO_NOTHING:
- ;
+ case SO_EQUAL:
+ break;
}
}
}
@@ -680,6 +689,8 @@ void SyncRecursively::synchronizeFile(FileMapping& fileObj) const
break;
case SO_OVERWRITE_RIGHT:
+ target = fileObj.getBaseDirPf<RIGHT_SIDE>() + fileObj.getRelativeName<LEFT_SIDE>();
+
statusText = txtOverwritingFile;
statusText.Replace(DefaultStr("%x"), fileObj.getShortName<LEFT_SIDE>(), false);
statusText.Replace(DefaultStr("%y"), fileObj.getFullName<RIGHT_SIDE>().BeforeLast(globalFunctions::FILE_NAME_SEPARATOR), false);
@@ -687,10 +698,14 @@ void SyncRecursively::synchronizeFile(FileMapping& fileObj) const
statusUpdater_.requestUiRefresh(); //trigger display refresh
removeFile<RIGHT_SIDE>(fileObj, false);
- copyFileUpdating(fileObj.getFullName<LEFT_SIDE>(), fileObj.getFullName<RIGHT_SIDE>(), fileObj.getFileSize<LEFT_SIDE>());
+ fileObj.removeObject<RIGHT_SIDE>(); //remove file from FileMapping, to keep in sync (if subsequent copying fails!!)
+
+ copyFileUpdating(fileObj.getFullName<LEFT_SIDE>(), target, fileObj.getFileSize<LEFT_SIDE>());
break;
case SO_OVERWRITE_LEFT:
+ target = fileObj.getBaseDirPf<LEFT_SIDE>() + fileObj.getRelativeName<RIGHT_SIDE>();
+
statusText = txtOverwritingFile;
statusText.Replace(DefaultStr("%x"), fileObj.getShortName<RIGHT_SIDE>(), false);
statusText.Replace(DefaultStr("%y"), fileObj.getFullName<LEFT_SIDE>().BeforeLast(globalFunctions::FILE_NAME_SEPARATOR), false);
@@ -698,10 +713,13 @@ void SyncRecursively::synchronizeFile(FileMapping& fileObj) const
statusUpdater_.requestUiRefresh(); //trigger display refresh
removeFile<LEFT_SIDE>(fileObj, false);
- copyFileUpdating(fileObj.getFullName<RIGHT_SIDE>(), fileObj.getFullName<LEFT_SIDE>(), fileObj.getFileSize<RIGHT_SIDE>());
+ fileObj.removeObject<LEFT_SIDE>(); //remove file from FileMapping, to keep in sync (if subsequent copying fails!!)
+
+ copyFileUpdating(fileObj.getFullName<RIGHT_SIDE>(), target, fileObj.getFileSize<RIGHT_SIDE>());
break;
case SO_DO_NOTHING:
+ case SO_EQUAL:
case SO_UNRESOLVED_CONFLICT:
return; //no update on processed data!
}
@@ -715,6 +733,72 @@ void SyncRecursively::synchronizeFile(FileMapping& fileObj) const
}
+//class DetectRenamedFiles
+//{
+//public:
+// static void execute(BaseDirMapping& baseMap, StatusHandler& statusUpdater)
+// {
+// DetectRenamedFiles(baseMap, statusUpdater);
+// }
+//
+//private:
+// DetectRenamedFiles(BaseDirMapping& baseMap, StatusHandler& statusUpdater);
+//
+// template <SelectedSide renameOnSide>
+// void renameFile(FileMapping& fileObjCreate, FileMapping& fileObjDelete) const;
+//
+// const Zstring txtRenamingFile;
+// StatusHandler& statusUpdater_;
+//};
+
+
+//DetectRenamedFiles::DetectRenamedFiles(BaseDirMapping& baseMap, StatusHandler& statusUpdater) :
+// txtRenamingFile(wxToZ(_("Renaming file %x to %y")).Replace(DefaultStr("%x"), DefaultStr("\"%x\""), false).Replace(DefaultStr("%y"), DefaultStr("\n\"%y\""), false)),
+// statusUpdater_(statusUpdater)
+//{
+// typedef std::vector<std::pair<CreateOnLeft, DeleteOnLeft> > RenameList;
+// RenameList renameOnLeft;
+// RenameList renameOnRight;
+// FreeFileSync::getRenameCandidates(baseMap, renameOnLeft, renameOnRight); //throw()!
+//
+// for (RenameList::const_iterator i = renameOnLeft.begin(); i != renameOnLeft.end(); ++i)
+// tryReportingError(statusUpdater_, boost::bind(&DetectRenamedFiles::renameFile<LEFT_SIDE>, this, boost::ref(*i->first), boost::ref(*i->second)));
+//
+// for (RenameList::const_iterator i = renameOnRight.begin(); i != renameOnRight.end(); ++i)
+// tryReportingError(statusUpdater_, boost::bind(&DetectRenamedFiles::renameFile<RIGHT_SIDE>, this, boost::ref(*i->first), boost::ref(*i->second)));
+//}
+
+
+//template <SelectedSide renameOnSide>
+//void DetectRenamedFiles::renameFile(FileMapping& fileObjCreate, FileMapping& fileObjDelete) const
+//{
+// const SelectedSide sourceSide = renameOnSide == LEFT_SIDE ? RIGHT_SIDE : LEFT_SIDE;
+//
+// Zstring statusText = txtRenamingFile;
+// statusText.Replace(DefaultStr("%x"), fileObjDelete.getFullName<renameOnSide>(), false);
+// statusText.Replace(DefaultStr("%y"), fileObjCreate.getRelativeName<sourceSide>(), false);
+// statusUpdater_.updateStatusText(statusText);
+// statusUpdater_.requestUiRefresh(); //trigger display refresh
+//
+// FreeFileSync::renameFile(fileObjDelete.getFullName<renameOnSide>(),
+// fileObjDelete.getBaseDirPf<renameOnSide>() + fileObjCreate.getRelativeName<sourceSide>()); //throw (FileError);
+//
+// //update FileMapping
+// fileObjCreate.synchronizeSides();
+// fileObjDelete.synchronizeSides();
+//
+//#ifndef _MSC_VER
+//#warning set FileID!
+//#warning Test: zweimaliger rename sollte dann klappen
+//
+//#warning allgemein: FileID nach jedem kopieren neu bestimmen?
+//#endif
+// //progress indicator update
+// //indicator is updated only if file is sync'ed correctly (and if some sync was done)!
+// statusUpdater_.updateProcessedData(2, globalFunctions::convertToSigned(fileObjCreate.getFileSize<sourceSide>()));
+//}
+
+
template <FreeFileSync::SelectedSide side>
inline
void SyncRecursively::removeFolder(const DirMapping& dirObj) const
@@ -838,6 +922,7 @@ void SyncRecursively::synchronizeFolder(DirMapping& dirObj) const
case SO_UNRESOLVED_CONFLICT:
assert(false);
case SO_DO_NOTHING:
+ case SO_EQUAL:
return; //no update on processed data!
}
@@ -879,6 +964,16 @@ bool dataLossPossible(const Zstring& dirName, const SyncStatistics& folderPairSt
!dirName.empty() && !FreeFileSync::dirExists(dirName);
}
+namespace
+{
+void makeSameLength(wxString& first, wxString& second)
+{
+ const size_t maxPref = std::max(first.length(), second.length());
+ first.Pad(maxPref - first.length(), wxT(' '), true);
+ second.Pad(maxPref - second.length(), wxT(' '), true);
+}
+}
+
void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCfg>& syncConfig, FolderComparison& folderCmp)
{
@@ -978,8 +1073,24 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf
//check if unresolved conflicts exist
if (statisticsTotal.getConflict() > 0)
- statusUpdater.reportWarning(_("Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization."),
- m_warnings.warningUnresolvedConflicts);
+ {
+ //show the first few conflicts in warning message also:
+ wxString warningMessage = wxString(_("Unresolved conflicts existing!")) +
+ wxT(" (") + globalFunctions::numberToWxString(statisticsTotal.getConflict()) + wxT(")\n\n");
+
+ const SyncStatistics::ConflictTexts& firstConflicts = statisticsTotal.getFirstConflicts(); //get first few sync conflicts
+ for (SyncStatistics::ConflictTexts::const_iterator i = firstConflicts.begin(); i != firstConflicts.end(); ++i)
+ warningMessage += wxString(wxT("\"")) + zToWx(i->first) + wxT("\": \t") + i->second + wxT("\n");
+
+ if (statisticsTotal.getConflict() > static_cast<int>(firstConflicts.size()))
+ warningMessage += wxT("[...]\n");
+ else
+ warningMessage += wxT("\n");
+
+ warningMessage += _("You can ignore conflicts and continue synchronization.");
+
+ statusUpdater.reportWarning(warningMessage, m_warnings.warningUnresolvedConflicts);
+ }
//-------------------end of basic checks------------------------------------------
@@ -996,6 +1107,17 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf
{
const FolderPairSyncCfg& folderPairCfg = syncConfig[j - folderCmp.begin()];
+//------------------------------------------------------------------------------------------
+ //info about folder pair to be processed (useful for logfile)
+ wxString left = wxString(_("Left")) + wxT(": ");
+ wxString right = wxString(_("Right")) + wxT(": ");
+ makeSameLength(left, right);
+ const wxString statusTxt = wxString(_("Processing folder pair:")) + wxT(" \n") +
+ wxT("\t") + left + wxT("\"") + zToWx(j->getBaseDir<LEFT_SIDE>()) + wxT("\"")+ wxT(" \n") +
+ wxT("\t") + right + wxT("\"") + zToWx(j->getBaseDir<RIGHT_SIDE>()) + wxT("\"");
+ statusUpdater.updateStatusText(wxToZ(statusTxt));
+//------------------------------------------------------------------------------------------
+
//generate name of alternate deletion directory (unique for session AND folder pair)
const DeletionHandling currentDelHandling(folderPairCfg.handleDeletion, folderPairCfg.custDelFolder);
@@ -1005,6 +1127,13 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf
//------------------------------------------------------------------------------------------
//execute synchronization recursively
+ //enforce removal of invalid entries (where both sides are empty)
+ RemoveInvalid dummy(*j);
+
+ //detect renamed files: currently in automatic mode only
+ // if (folderPairCfg.inAutomaticMode)
+ // DetectRenamedFiles::execute(*j, statusUpdater);
+
//loop through all files twice; reason: first delete, then copy
SyncRecursively( *this,
#ifdef FFS_WIN
@@ -1019,7 +1148,7 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf
//------------------------------------------------------------------------------------------
//update synchronization database (automatic sync only)
- if (folderPairCfg.updateSyncDB)
+ if (folderPairCfg.inAutomaticMode)
{
UpdateDatabase syncDB(*j, statusUpdater);
statusUpdater.updateStatusText(wxToZ(_("Generating database...")));
@@ -1133,7 +1262,7 @@ void verifyFiles(const Zstring& source, const Zstring& target, VerifyCallback* c
static boost::scoped_array<unsigned char> memory2(new unsigned char[BUFFER_SIZE]);
#ifdef FFS_WIN
- wxFile file1(source.c_str(), wxFile::read); //don't use buffered file input for verification!
+ wxFile file1(FreeFileSync::applyLongPathPrefix(source).c_str(), wxFile::read); //don't use buffered file input for verification!
#elif defined FFS_LINUX
wxFile file1(::open(source.c_str(), O_RDONLY)); //utilize UTF-8 filename
#endif
@@ -1141,7 +1270,7 @@ void verifyFiles(const Zstring& source, const Zstring& target, VerifyCallback* c
throw FileError(wxString(_("Error opening file:")) + wxT(" \"") + zToWx(source) + wxT("\""));
#ifdef FFS_WIN
- wxFile file2(target.c_str(), wxFile::read); //don't use buffered file input for verification!
+ wxFile file2(FreeFileSync::applyLongPathPrefix(target).c_str(), wxFile::read); //don't use buffered file input for verification!
#elif defined FFS_LINUX
wxFile file2(::open(target.c_str(), O_RDONLY)); //utilize UTF-8 filename
#endif
@@ -1216,3 +1345,8 @@ void SyncRecursively::verifyFileCopy(const Zstring& source, const Zstring& targe
}
+
+
+
+
+
diff --git a/synchronization.h b/synchronization.h
index 53b17091..9db4d112 100644
--- a/synchronization.h
+++ b/synchronization.h
@@ -20,6 +20,10 @@ public:
int getOverwrite(bool inclLeft = true, bool inclRight = true) const;
int getDelete( bool inclLeft = true, bool inclRight = true) const;
int getConflict() const;
+
+ typedef std::vector<std::pair<Zstring, wxString> > ConflictTexts; // Pair(filename/conflict text)
+ const ConflictTexts& getFirstConflicts() const; //get first few sync conflicts
+
wxULongLong getDataToProcess() const;
int getRowCount() const;
@@ -35,6 +39,7 @@ private:
int overwriteLeft, overwriteRight;
int deleteLeft, deleteRight;
int conflict;
+ ConflictTexts firstConflicts; //save the first few conflict texts to display as a warning message
wxULongLong dataToProcess;
int rowsTotal;
};
@@ -45,14 +50,14 @@ class SyncRecursively;
struct FolderPairSyncCfg
{
- FolderPairSyncCfg(bool inAutomaticMode,
+ FolderPairSyncCfg(bool automaticMode,
const DeletionPolicy handleDel,
const Zstring& custDelDir) :
- updateSyncDB(inAutomaticMode),
+ inAutomaticMode(automaticMode),
handleDeletion(handleDel),
custDelFolder(custDelDir) {}
- bool updateSyncDB; //update database if in automatic mode
+ bool inAutomaticMode; //update database if in automatic mode
DeletionPolicy handleDeletion;
Zstring custDelFolder;
};
diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp
index 0d203453..4d255950 100644
--- a/ui/MainDialog.cpp
+++ b/ui/MainDialog.cpp
@@ -228,6 +228,16 @@ private:
};
+struct DirNotFound
+{
+ bool operator()(const FolderPairEnh& fp) const
+ {
+ return !dirExists(FreeFileSync::getFormattedDirectoryName(fp.leftDirectory)) ||
+ !dirExists(FreeFileSync::getFormattedDirectoryName(fp.rightDirectory));
+ }
+};
+
+
//##################################################################################################################################
MainDialog::MainDialog(wxFrame* frame,
const wxString& cfgFileName,
@@ -256,42 +266,43 @@ MainDialog::MainDialog(wxFrame* frame,
//initialize and load configuration
readGlobalSettings();
+ bool loadCfgSuccess = false;
if (cfgFileName.empty())
- readConfigurationFromXml(lastConfigFileName(), true);
+ loadCfgSuccess = readConfigurationFromXml(lastConfigFileName(), true);
else
- readConfigurationFromXml(cfgFileName, true);
+ loadCfgSuccess = readConfigurationFromXml(cfgFileName, true);
//set icons for this dialog
- m_bpButton10->SetBitmapLabel(*GlobalResources::getInstance().bitmapExit);
- m_buttonCompare->setBitmapFront(*GlobalResources::getInstance().bitmapCompare);
- m_bpButtonSyncConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfg);
- m_bpButtonCmpConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapCmpCfg);
- m_bpButtonSave->SetBitmapLabel(*GlobalResources::getInstance().bitmapSave);
- m_bpButtonLoad->SetBitmapLabel(*GlobalResources::getInstance().bitmapLoad);
- m_bpButtonAddPair->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
- m_bitmap15->SetBitmap(*GlobalResources::getInstance().bitmapStatusEdge);
-
- m_bitmapCreate->SetBitmap(*GlobalResources::getInstance().bitmapCreate);
- m_bitmapUpdate->SetBitmap(*GlobalResources::getInstance().bitmapUpdate);
- m_bitmapDelete->SetBitmap(*GlobalResources::getInstance().bitmapDelete);
- m_bitmapData->SetBitmap(*GlobalResources::getInstance().bitmapData);
+ m_bpButton10->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("exit")));
+ m_buttonCompare->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("compare")));
+ m_bpButtonSyncConfig->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("syncConfig")));
+ m_bpButtonCmpConfig->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("cmpConfig")));
+ m_bpButtonSave->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("save")));
+ m_bpButtonLoad->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("load")));
+ m_bpButtonAddPair->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("addFolderPair")));
+ m_bitmap15->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusEdge")));
+
+ m_bitmapCreate->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("create")));
+ m_bitmapUpdate->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("update")));
+ m_bitmapDelete->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("delete")));
+ m_bitmapData->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("data")));
bSizer6->Layout(); //wxButtonWithImage size might have changed
//menu icons: workaround for wxWidgets: small hack to update menu items: actually this is a wxWidgets bug (affects Windows- and Linux-build)
MenuItemUpdater updateMenuFile(m_menuFile);
- updateMenuFile.addForUpdate(m_menuItem10, *GlobalResources::getInstance().bitmapCompareSmall);
- updateMenuFile.addForUpdate(m_menuItem11, *GlobalResources::getInstance().bitmapSyncSmall);
- updateMenuFile.addForUpdate(m_menuItemNew, *GlobalResources::getInstance().bitmapNewSmall);
- updateMenuFile.addForUpdate(m_menuItemSave, *GlobalResources::getInstance().bitmapSaveSmall);
- updateMenuFile.addForUpdate(m_menuItemLoad, *GlobalResources::getInstance().bitmapLoadSmall);
+ updateMenuFile.addForUpdate(m_menuItem10, GlobalResources::getInstance().getImageByName(wxT("compareSmall")));
+ updateMenuFile.addForUpdate(m_menuItem11, GlobalResources::getInstance().getImageByName(wxT("syncSmall")));
+ updateMenuFile.addForUpdate(m_menuItemNew, GlobalResources::getInstance().getImageByName(wxT("newSmall")));
+ updateMenuFile.addForUpdate(m_menuItemSave, GlobalResources::getInstance().getImageByName(wxT("saveSmall")));
+ updateMenuFile.addForUpdate(m_menuItemLoad, GlobalResources::getInstance().getImageByName(wxT("loadSmall")));
MenuItemUpdater updateMenuAdv(m_menuAdvanced);
- updateMenuAdv.addForUpdate(m_menuItemGlobSett, *GlobalResources::getInstance().bitmapSettingsSmall);
- updateMenuAdv.addForUpdate(m_menuItem7, *GlobalResources::getInstance().bitmapBatchSmall);
+ updateMenuAdv.addForUpdate(m_menuItemGlobSett, GlobalResources::getInstance().getImageByName(wxT("settingsSmall")));
+ updateMenuAdv.addForUpdate(m_menuItem7, GlobalResources::getInstance().getImageByName(wxT("batchSmall")));
MenuItemUpdater updateMenuHelp(m_menuHelp);
- updateMenuHelp.addForUpdate(m_menuItemAbout, *GlobalResources::getInstance().bitmapAboutSmall);
+ updateMenuHelp.addForUpdate(m_menuItemAbout, GlobalResources::getInstance().getImageByName(wxT("aboutSmall")));
//create language selection menu
@@ -353,6 +364,22 @@ MainDialog::MainDialog(wxFrame* frame,
//asynchronous call to wxWindow::Layout(): fix superfluous frame on right and bottom when FFS is started in fullscreen mode
Connect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), NULL, this);
+
+//----------------------------------------------------------------------------------------------------------------------------------------------------------------
+ //some convenience: if FFS is started with a *.ffs_gui file as commandline parameter AND all directories contained exist, comparison shall be started right off
+ if (!cfgFileName.empty() && loadCfgSuccess)
+ {
+ const FreeFileSync::MainConfiguration currMainCfg = getCurrentConfiguration().mainCfg;
+ const bool allFoldersExist = !DirNotFound()(currMainCfg.firstPair) &&
+ std::find_if(currMainCfg.additionalPairs.begin(), currMainCfg.additionalPairs.end(),
+ DirNotFound()) == currMainCfg.additionalPairs.end();
+ if (allFoldersExist)
+ {
+ wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED);
+ m_buttonCompare->AddPendingEvent(dummy2); //simulate button click on "compare"
+ }
+ }
+//----------------------------------------------------------------------------------------------------------------------------------------------------------------
}
@@ -735,20 +762,15 @@ void exstractNames(const FileSystemObject& fsObj, wxString& name, wxString& dir)
{
if (!fsObj.isEmpty<side>())
{
- const FileMapping* fileObj = dynamic_cast<const FileMapping*>(&fsObj);
- if (fileObj != NULL)
+ if (isDirectoryMapping(fsObj))
{
name = zToWx(fsObj.getFullName<side>());
- dir = zToWx(fsObj.getFullName<side>().BeforeLast(globalFunctions::FILE_NAME_SEPARATOR));
+ dir = name;
}
else
{
- const DirMapping* dirObj = dynamic_cast<const DirMapping*>(&fsObj);
- if (dirObj != NULL)
- {
- name = zToWx(fsObj.getFullName<side>());
- dir = name;
- }
+ name = zToWx(fsObj.getFullName<side>());
+ dir = zToWx(fsObj.getFullName<side>().BeforeLast(globalFunctions::FILE_NAME_SEPARATOR));
}
}
else
@@ -1190,9 +1212,10 @@ void MainDialog::OnContextRim(wxGridEvent& event)
//re-create context menu
contextMenu.reset(new wxMenu);
- if (syncPreview.previewIsEnabled())
+ if (syncPreview.previewIsEnabled() &&
+ fsObj && fsObj->getSyncOperation() != SO_EQUAL)
{
- if (fsObj && (selectionLeft.size() + selectionRight.size() > 0))
+ if (selectionLeft.size() + selectionRight.size() > 0)
{
//CONTEXT_SYNC_DIR_LEFT
wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, wxString(_("Change direction")) + wxT("\tALT + LEFT"));
@@ -1220,13 +1243,13 @@ void MainDialog::OnContextRim(wxGridEvent& event)
if (fsObj->isActive())
{
wxMenuItem* menuItemExclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, wxString(_("Exclude temporarily")) + wxT("\tSPACE"));
- menuItemExclTemp->SetBitmap(*GlobalResources::getInstance().bitmapCheckBoxFalse);
+ menuItemExclTemp->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("checkboxFalse")));
contextMenu->Append(menuItemExclTemp);
}
else
{
wxMenuItem* menuItemInclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, wxString(_("Include temporarily")) + wxT("\tSPACE"));
- menuItemInclTemp->SetBitmap(*GlobalResources::getInstance().bitmapCheckBoxTrue);
+ menuItemInclTemp->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("checkboxTrue")));
contextMenu->Append(menuItemInclTemp);
}
}
@@ -1244,16 +1267,14 @@ void MainDialog::OnContextRim(wxGridEvent& event)
const FileSystemObject* currObj = gridDataView->getObject(*i);
if (currObj && !currObj->isEmpty<LEFT_SIDE>())
exFilterCandidateObj.push_back(
- FilterObject(currObj->getRelativeName<LEFT_SIDE>(),
- dynamic_cast<const DirMapping*>(currObj) != NULL));
+ FilterObject(currObj->getRelativeName<LEFT_SIDE>(), isDirectoryMapping(*currObj)));
}
for (std::set<unsigned int>::const_iterator i = selectionRight.begin(); i != selectionRight.end(); ++i)
{
const FileSystemObject* currObj = gridDataView->getObject(*i);
if (currObj && !currObj->isEmpty<RIGHT_SIDE>())
exFilterCandidateObj.push_back(
- FilterObject(currObj->getRelativeName<RIGHT_SIDE>(),
- dynamic_cast<const DirMapping*>(currObj) != NULL));
+ FilterObject(currObj->getRelativeName<RIGHT_SIDE>(), isDirectoryMapping(*currObj)));
}
//###############################################################################################
@@ -1267,7 +1288,7 @@ void MainDialog::OnContextRim(wxGridEvent& event)
//add context menu item
wxMenuItem* menuItemExclExt = new wxMenuItem(contextMenu.get(), CONTEXT_EXCLUDE_EXT, wxString(_("Exclude via filter:")) + wxT(" ") + wxT("*.") + zToWx(extension));
- menuItemExclExt->SetBitmap(*GlobalResources::getInstance().bitmapFilterSmall);
+ menuItemExclExt->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("filterSmall")));
contextMenu->Append(menuItemExclExt);
//connect event
@@ -1289,7 +1310,7 @@ void MainDialog::OnContextRim(wxGridEvent& event)
if (menuItemExclObj != NULL)
{
- menuItemExclObj->SetBitmap(*GlobalResources::getInstance().bitmapFilterSmall);
+ menuItemExclObj->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("filterSmall")));
contextMenu->Append(menuItemExclObj);
//connect event
@@ -1603,9 +1624,9 @@ void MainDialog::OnContextMiddleLabel(wxGridEvent& event)
wxMenuItem* itemCmpResult = new wxMenuItem(contextMenu.get(), CONTEXT_COMPARISON_RESULT, _("Comparison Result"));
if (syncPreview.previewIsEnabled())
- itemSyncPreview->SetBitmap(*GlobalResources::getInstance().bitmapSyncViewSmall);
+ itemSyncPreview->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("syncViewSmall")));
else
- itemCmpResult->SetBitmap(*GlobalResources::getInstance().bitmapCmpViewSmall);
+ itemCmpResult->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("cmpViewSmall")));
contextMenu->Append(itemCmpResult);
contextMenu->Append(itemSyncPreview);
@@ -1667,44 +1688,19 @@ wxString getFormattedHistoryElement(const wxString& filename)
}
-wxString getFullFilename(const wxString& name)
-{
- //resolve relative names to avoid problems after working directory is changed
- wxFileName filename(name);
- if (!filename.Normalize())
- return name; //fallback
-
- return filename.GetFullPath();
-}
-
-
-//tests if the same filenames are specified, even if they are relative to the current working directory
-inline
-bool sameFileSpecified(const wxString& file1, const wxString& file2)
-{
- const wxString file1Full = getFullFilename(file1);
- const wxString file2Full = getFullFilename(file2);
-
-#ifdef FFS_WIN //don't respect case in windows build
- return file1Full.CmpNoCase(file2Full) == 0;
-#elif defined FFS_LINUX
- return file1Full == file2Full;
-#endif
-}
-
-
+//tests if the same filenames are specified, even if they are relative to the current working directory/include symlinks or \\?\ prefix
class FindDuplicates
{
public:
- FindDuplicates(const wxString& name) : m_name(name) {}
+ FindDuplicates(const Zstring& name) : m_name(name) {}
bool operator()(const wxString& other) const
{
- return sameFileSpecified(m_name, other);
+ return Utility::sameFileSpecified(m_name, wxToZ(other));
}
private:
- const wxString& m_name;
+ const Zstring& m_name;
};
@@ -1714,7 +1710,7 @@ void MainDialog::addFileToCfgHistory(const wxString& filename)
if (!wxFileExists(filename))
return;
- std::vector<wxString>::const_iterator i = find_if(cfgFileNames.begin(), cfgFileNames.end(), FindDuplicates(filename));
+ std::vector<wxString>::const_iterator i = find_if(cfgFileNames.begin(), cfgFileNames.end(), FindDuplicates(wxToZ(filename)));
if (i != cfgFileNames.end())
{
//if entry is in the list, then jump to element
@@ -1725,7 +1721,7 @@ void MainDialog::addFileToCfgHistory(const wxString& filename)
cfgFileNames.insert(cfgFileNames.begin(), filename);
//the default config file should receive another name on GUI
- if (sameFileSpecified(lastConfigFileName(), filename))
+ if (Utility::sameFileSpecified(wxToZ(lastConfigFileName()), wxToZ(filename)))
m_choiceHistory->Insert(_("<Last session>"), 0); //insert at beginning of list
else
m_choiceHistory->Insert(getFormattedHistoryElement(filename), 0); //insert at beginning of list
@@ -1763,7 +1759,11 @@ void MainDialog::OnSaveConfig(wxCommandEvent& event)
bool MainDialog::trySaveConfig() //return true if saved successfully
{
- const wxString defaultFileName = currentConfigFileName.empty() ? wxT("SyncSettings.ffs_gui") : currentConfigFileName;
+ wxString defaultFileName = currentConfigFileName.empty() ? wxT("SyncSettings.ffs_gui") : currentConfigFileName;
+ //attention: currentConfigFileName may be an imported *.ffs_batch file! We don't want to overwrite it with a GUI config!
+ if (defaultFileName.EndsWith(wxT(".ffs_batch")))
+ defaultFileName.Replace(wxT(".ffs_batch"), wxT(".ffs_gui"), false);
+
wxFileDialog* filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, defaultFileName, wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui)|*.ffs_gui"), wxFD_SAVE);
if (filePicker->ShowModal() == wxID_OK)
@@ -1937,7 +1937,7 @@ void MainDialog::OnSetSyncDirection(FFSSyncDirectionEvent& event)
if (fsObj)
{
setSyncDirectionRec(event.direction, *fsObj); //set new direction (recursively)
- FreeFileSync::setActiveStatus(true, *fsObj); //works recursively for directories
+ FreeFileSync::setActiveStatus(true, *fsObj); //works recursively for directories
}
}
@@ -2291,75 +2291,75 @@ void MainDialog::OnSyncDirNone(wxCommandEvent& event)
void MainDialog::initViewFilterButtons()
{
//compare result buttons
- m_bpButtonLeftOnly->init(*GlobalResources::getInstance().bitmapLeftOnlyAct,
+ m_bpButtonLeftOnly->init(GlobalResources::getInstance().getImageByName(wxT("leftOnlyAct")),
_("Hide files that exist on left side only"),
- *GlobalResources::getInstance().bitmapLeftOnlyDeact,
+ GlobalResources::getInstance().getImageByName(wxT("leftOnlyDeact")),
_("Show files that exist on left side only"));
- m_bpButtonRightOnly->init(*GlobalResources::getInstance().bitmapRightOnlyAct,
+ m_bpButtonRightOnly->init(GlobalResources::getInstance().getImageByName(wxT("rightOnlyAct")),
_("Hide files that exist on right side only"),
- *GlobalResources::getInstance().bitmapRightOnlyDeact,
+ GlobalResources::getInstance().getImageByName(wxT("rightOnlyDeact")),
_("Show files that exist on right side only"));
- m_bpButtonLeftNewer->init(*GlobalResources::getInstance().bitmapLeftNewerAct,
+ m_bpButtonLeftNewer->init(GlobalResources::getInstance().getImageByName(wxT("leftNewerAct")),
_("Hide files that are newer on left"),
- *GlobalResources::getInstance().bitmapLeftNewerDeact,
+ GlobalResources::getInstance().getImageByName(wxT("leftNewerDeact")),
_("Show files that are newer on left"));
- m_bpButtonRightNewer->init(*GlobalResources::getInstance().bitmapRightNewerAct,
+ m_bpButtonRightNewer->init(GlobalResources::getInstance().getImageByName(wxT("rightNewerAct")),
_("Hide files that are newer on right"),
- *GlobalResources::getInstance().bitmapRightNewerDeact,
+ GlobalResources::getInstance().getImageByName(wxT("rightNewerDeact")),
_("Show files that are newer on right"));
- m_bpButtonEqual->init(*GlobalResources::getInstance().bitmapEqualAct,
+ m_bpButtonEqual->init(GlobalResources::getInstance().getImageByName(wxT("equalAct")),
_("Hide files that are equal"),
- *GlobalResources::getInstance().bitmapEqualDeact,
+ GlobalResources::getInstance().getImageByName(wxT("equalDeact")),
_("Show files that are equal"));
- m_bpButtonDifferent->init(*GlobalResources::getInstance().bitmapDifferentAct,
+ m_bpButtonDifferent->init(GlobalResources::getInstance().getImageByName(wxT("differentAct")),
_("Hide files that are different"),
- *GlobalResources::getInstance().bitmapDifferentDeact,
+ GlobalResources::getInstance().getImageByName(wxT("differentDeact")),
_("Show files that are different"));
- m_bpButtonConflict->init(*GlobalResources::getInstance().bitmapConflictAct,
+ m_bpButtonConflict->init(GlobalResources::getInstance().getImageByName(wxT("conflictAct")),
_("Hide conflicts"),
- *GlobalResources::getInstance().bitmapConflictDeact,
+ GlobalResources::getInstance().getImageByName(wxT("conflictDeact")),
_("Show conflicts"));
//sync preview buttons
- m_bpButtonSyncCreateLeft->init(*GlobalResources::getInstance().bitmapSyncCreateLeftAct,
+ m_bpButtonSyncCreateLeft->init(GlobalResources::getInstance().getImageByName(wxT("syncCreateLeftAct")),
_("Hide files that will be created on the left side"),
- *GlobalResources::getInstance().bitmapSyncCreateLeftDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncCreateLeftDeact")),
_("Show files that will be created on the left side"));
- m_bpButtonSyncCreateRight->init(*GlobalResources::getInstance().bitmapSyncCreateRightAct,
+ m_bpButtonSyncCreateRight->init(GlobalResources::getInstance().getImageByName(wxT("syncCreateRightAct")),
_("Hide files that will be created on the right side"),
- *GlobalResources::getInstance().bitmapSyncCreateRightDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncCreateRightDeact")),
_("Show files that will be created on the right side"));
- m_bpButtonSyncDeleteLeft->init(*GlobalResources::getInstance().bitmapSyncDeleteLeftAct,
+ m_bpButtonSyncDeleteLeft->init(GlobalResources::getInstance().getImageByName(wxT("syncDeleteLeftAct")),
_("Hide files that will be deleted on the left side"),
- *GlobalResources::getInstance().bitmapSyncDeleteLeftDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncDeleteLeftDeact")),
_("Show files that will be deleted on the left side"));
- m_bpButtonSyncDeleteRight->init(*GlobalResources::getInstance().bitmapSyncDeleteRightAct,
+ m_bpButtonSyncDeleteRight->init(GlobalResources::getInstance().getImageByName(wxT("syncDeleteRightAct")),
_("Hide files that will be deleted on the right side"),
- *GlobalResources::getInstance().bitmapSyncDeleteRightDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncDeleteRightDeact")),
_("Show files that will be deleted on the right side"));
- m_bpButtonSyncDirOverwLeft->init(*GlobalResources::getInstance().bitmapSyncDirLeftAct,
+ m_bpButtonSyncDirOverwLeft->init(GlobalResources::getInstance().getImageByName(wxT("syncDirLeftAct")),
_("Hide files that will be overwritten on left side"),
- *GlobalResources::getInstance().bitmapSyncDirLeftDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncDirLeftDeact")),
_("Show files that will be overwritten on left side"));
- m_bpButtonSyncDirOverwRight->init(*GlobalResources::getInstance().bitmapSyncDirRightAct,
+ m_bpButtonSyncDirOverwRight->init(GlobalResources::getInstance().getImageByName(wxT("syncDirRightAct")),
_("Hide files that will be overwritten on right side"),
- *GlobalResources::getInstance().bitmapSyncDirRightDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncDirRightDeact")),
_("Show files that will be overwritten on right side"));
- m_bpButtonSyncDirNone->init(*GlobalResources::getInstance().bitmapSyncDirNoneAct,
+ m_bpButtonSyncDirNone->init(GlobalResources::getInstance().getImageByName(wxT("syncDirNoneAct")),
_("Hide files that won't be copied"),
- *GlobalResources::getInstance().bitmapSyncDirNoneDeact,
+ GlobalResources::getInstance().getImageByName(wxT("syncDirNoneDeact")),
_("Show files that won't be copied"));
//compare result buttons
@@ -2388,8 +2388,8 @@ void MainDialog::updateFilterButtons()
if (m_notebookBottomLeft->GetImageList() == NULL)
{
wxImageList* panelIcons = new wxImageList(16, 16);
- panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmall));
- panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmallGrey));
+ panelIcons->Add(wxBitmap(GlobalResources::getInstance().getImageByName(wxT("filterSmall"))));
+ panelIcons->Add(wxBitmap(GlobalResources::getInstance().getImageByName(wxT("filterSmallGrey"))));
m_notebookBottomLeft->AssignImageList(panelIcons); //pass ownership
}
@@ -2400,7 +2400,7 @@ void MainDialog::updateFilterButtons()
const bool isNullFilter = NameFilter(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter).isNull();
if (isNullFilter)
{
- m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff);
+ m_bpButtonFilter->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("filterOff")));
m_bpButtonFilter->SetToolTip(_("No filter selected"));
//additional filter icon
@@ -2408,7 +2408,7 @@ void MainDialog::updateFilterButtons()
}
else
{
- m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOn);
+ m_bpButtonFilter->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("filterOn")));
m_bpButtonFilter->SetToolTip(_("Filter has been selected"));
//show filter icon
@@ -2417,7 +2417,7 @@ void MainDialog::updateFilterButtons()
}
else
{
- m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff);
+ m_bpButtonFilter->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("filterOff")));
m_bpButtonFilter->SetToolTip(_("Filtering is deactivated"));
//additional filter icon
@@ -2457,6 +2457,7 @@ void MainDialog::OnCompare(wxCommandEvent &event)
FreeFileSync::CompareProcess comparison(currentCfg.mainCfg.hidden.traverseDirectorySymlinks,
currentCfg.mainCfg.hidden.fileTimeTolerance,
globalSettings.ignoreOneHourDiff,
+ globalSettings.detectRenameThreshold,
globalSettings.optDialogs,
&statusHandler);
@@ -2469,6 +2470,11 @@ void MainDialog::OnCompare(wxCommandEvent &event)
newCompareData);
gridDataView->setData(newCompareData); //newCompareData is invalidated after this call
+
+ //play (optional) sound notification after sync has completed (GUI and batch mode)
+ const wxString soundFile = FreeFileSync::getInstallationDir() + wxT("Compare_Complete.wav");
+ if (fileExists(wxToZ(soundFile)))
+ wxSound::Play(soundFile, wxSOUND_ASYNC);
}
catch (AbortThisProcess&)
{
@@ -2932,6 +2938,7 @@ void MainDialog::updateGridViewData()
m_bpButtonSyncDirOverwLeft-> isActive(),
m_bpButtonSyncDirOverwRight->isActive(),
m_bpButtonSyncDirNone-> isActive(),
+ m_bpButtonEqual-> isActive(),
m_bpButtonConflict-> isActive());
filesOnLeftView = result.filesOnLeftView;
@@ -2950,6 +2957,7 @@ void MainDialog::updateGridViewData()
m_bpButtonSyncDirOverwLeft-> Show(result.existsSyncDirLeft);
m_bpButtonSyncDirOverwRight->Show(result.existsSyncDirRight);
m_bpButtonSyncDirNone-> Show(result.existsSyncDirNone);
+ m_bpButtonEqual-> Show(result.existsSyncEqual);
m_bpButtonConflict-> Show(result.existsConflict);
if ( m_bpButtonSyncCreateLeft-> IsShown() ||
@@ -2959,6 +2967,7 @@ void MainDialog::updateGridViewData()
m_bpButtonSyncDirOverwLeft-> IsShown() ||
m_bpButtonSyncDirOverwRight->IsShown() ||
m_bpButtonSyncDirNone-> IsShown() ||
+ m_bpButtonEqual-> IsShown() ||
m_bpButtonConflict-> IsShown())
{
m_panel112->Show();
@@ -3269,14 +3278,14 @@ void MainDialog::updateGuiForFolderPair()
m_bpButtonLocalFilter->Hide();
m_bpButtonAltSyncCfg->Hide();
- m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwap);
+ m_bpButtonSwapSides->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("swap")));
}
else
{
m_bpButtonLocalFilter->Show();
m_bpButtonAltSyncCfg->Show();
- m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwapSlim);
+ m_bpButtonSwapSides->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("swapSlim")));
}
m_panelTopMiddle->Layout();
@@ -3427,6 +3436,7 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event)
exportString += wxString(wxT("\"")) + getDescription(SO_OVERWRITE_LEFT) + wxT("\";") + getSymbol(SO_OVERWRITE_LEFT) + wxT('\n');
exportString += wxString(wxT("\"")) + getDescription(SO_OVERWRITE_RIGHT) + wxT("\";") + getSymbol(SO_OVERWRITE_RIGHT) + wxT('\n');
exportString += wxString(wxT("\"")) + getDescription(SO_DO_NOTHING) + wxT("\";") + getSymbol(SO_DO_NOTHING) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_DO_NOTHING) + wxT("\";") + getSymbol(SO_EQUAL) + wxT('\n');
exportString += wxString(wxT("\"")) + getDescription(SO_UNRESOLVED_CONFLICT) + wxT("\";") + getSymbol(SO_UNRESOLVED_CONFLICT) + wxT('\n');
}
else
@@ -3644,13 +3654,13 @@ void MainDialog::SyncPreview::enableSynchronization(bool value)
{
synchronizationEnabled = true;
mainDlg_->m_buttonStartSync->SetForegroundColour(*wxBLACK);
- mainDlg_->m_buttonStartSync->setBitmapFront(*GlobalResources::getInstance().bitmapSync);
+ mainDlg_->m_buttonStartSync->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("sync")));
}
else
{
synchronizationEnabled = false;
mainDlg_->m_buttonStartSync->SetForegroundColour(wxColor(128, 128, 128)); //Some colors seem to have problems with 16Bit color depth, well this one hasn't!
- mainDlg_->m_buttonStartSync->setBitmapFront(*GlobalResources::getInstance().bitmapSyncDisabled);
+ mainDlg_->m_buttonStartSync->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("syncDisabled")));
}
}
@@ -3663,3 +3673,4 @@ bool MainDialog::SyncPreview::synchronizationIsEnabled() const
+
diff --git a/ui/MainDialog.h b/ui/MainDialog.h
index 61f1537f..ff9fee09 100644
--- a/ui/MainDialog.h
+++ b/ui/MainDialog.h
@@ -82,7 +82,7 @@ public:
MainDialog(wxFrame* frame,
const wxString& cfgFileName,
xmlAccess::XmlGlobalSettings& settings,
- wxHelpController& helpController);
+ wxHelpController& helpController);
~MainDialog();
@@ -116,7 +116,7 @@ private:
void removeAddFolderPair(const unsigned int pos);
void clearAddFolderPairs();
-void updateGuiForFolderPair(); //helper method: add usability by showing/hiding buttons related to folder pairs
+ 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();
@@ -267,7 +267,7 @@ void updateGuiForFolderPair(); //helper method: add usability by showing/hiding
xmlAccess::XmlGuiConfig currentCfg;
//folder pairs:
- std::auto_ptr<FirstFolderPairCfg> firstFolderPair; //always bound!!!
+ std::auto_ptr<FirstFolderPairCfg> firstFolderPair; //always bound!!!
std::vector<FolderPairPanel*> additionalFolderPairs; //additional pairs to the first pair
//gui settings
diff --git a/ui/SmallDialogs.cpp b/ui/SmallDialogs.cpp
index 74678244..cab26472 100644
--- a/ui/SmallDialogs.cpp
+++ b/ui/SmallDialogs.cpp
@@ -14,16 +14,18 @@
#include <wx/wupdlock.h>
#include "../shared/globalFunctions.h"
#include "trayIcon.h"
+#include "../shared/staticAssert.h"
+#include "../shared/buildInfo.h"
using namespace FreeFileSync;
AboutDlg::AboutDlg(wxWindow* window) : AboutDlgGenerated(window)
{
- m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapWebsite);
- m_bitmap10->SetBitmap(*GlobalResources::getInstance().bitmapEmail);
- m_bitmap11->SetBitmap(*GlobalResources::getInstance().bitmapLogo);
- m_bitmap13->SetBitmap(*GlobalResources::getInstance().bitmapGPL);
+ m_bitmap9->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("website")));
+ m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("email")));
+ m_bitmap11->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("logo")));
+ m_bitmap13->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("gpl")));
//create language credits
for (std::vector<LocInfoLine>::const_iterator i = LocalizationInfo::getMapping().begin(); i != LocalizationInfo::getMapping().end(); ++i)
@@ -49,10 +51,19 @@ AboutDlg::AboutDlg(wxWindow* window) : AboutDlgGenerated(window)
//build information
wxString build = wxString(wxT("(")) + _("Build:") + wxT(" ") + __TDATE__;
#if wxUSE_UNICODE
- build += wxT(" - Unicode)");
+ build += wxT(" - Unicode");
#else
- build += wxT(" - ANSI)");
+ build += wxT(" - ANSI");
#endif //wxUSE_UNICODE
+
+ //compile time info about 32/64-bit build
+ if (Utility::is64BitBuild)
+ build += wxT(" x64)");
+ else
+ build += wxT(" x86)");
+ assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
+
+
m_build->SetLabel(build);
m_animationControl1->SetAnimation(*GlobalResources::getInstance().animationMoney);
@@ -80,7 +91,7 @@ HelpDlg::HelpDlg(wxWindow* window) : HelpDlgGenerated(window)
{
m_notebook1->SetFocus();
- m_bitmap25->SetBitmap(*GlobalResources::getInstance().bitmapHelp);
+ m_bitmap25->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("help")));
//populate decision trees: "compare by date"
wxTreeItemId treeRoot = m_treeCtrl1->AddRoot(_("DECISION TREE"));
@@ -137,10 +148,10 @@ FilterDlg::FilterDlg(wxWindow* window,
includeFilter(filterIncl),
excludeFilter(filterExcl)
{
- m_bitmap8->SetBitmap(*GlobalResources::getInstance().bitmapInclude);
- m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapExclude);
- m_bitmap26->SetBitmap(*GlobalResources::getInstance().bitmapFilterOn);
- m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp);
+ m_bitmap8->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("include")));
+ m_bitmap9->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("exclude")));
+ m_bitmap26->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("filterOn")));
+ m_bpButtonHelp->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("help")));
m_textCtrlInclude->SetValue(zToWx(includeFilter));
m_textCtrlExclude->SetValue(zToWx(excludeFilter));
@@ -243,12 +254,12 @@ void DeleteDialog::updateTexts()
if (m_checkBoxUseRecycler->GetValue())
{
m_staticTextHeader->SetLabel(_("Do you really want to move the following objects(s) to the Recycle Bin?"));
- m_bitmap12->SetBitmap(*GlobalResources::getInstance().bitmapRecycler);
+ m_bitmap12->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("recycler")));
}
else
{
m_staticTextHeader->SetLabel(_("Do you really want to delete the following objects(s)?"));
- m_bitmap12->SetBitmap(*GlobalResources::getInstance().bitmapDeleteFile);
+ m_bitmap12->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("deleteFile")));
}
const std::pair<wxString, int> delInfo = FreeFileSync::deleteFromGridAndHDPreview(
@@ -292,7 +303,7 @@ void DeleteDialog::OnUseRecycler(wxCommandEvent& event)
{
if (!FreeFileSync::recycleBinExists())
{
- wxMessageBox(_("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. :)"), _("Error") , wxOK | wxICON_ERROR);
+ wxMessageBox(_("Unable to initialize Recycle Bin!"), _("Error") , wxOK | wxICON_ERROR);
m_checkBoxUseRecycler->SetValue(false);
}
}
@@ -307,7 +318,7 @@ ErrorDlg::ErrorDlg(wxWindow* parentWindow, const int activeButtons, const wxStri
ErrorDlgGenerated(parentWindow),
ignoreErrors(ignoreNextErrors)
{
- m_bitmap10->SetBitmap(*GlobalResources::getInstance().bitmapError);
+ m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("error")));
m_textCtrl8->SetValue(messageText);
m_checkBoxIgnoreErrors->SetValue(ignoreNextErrors);
@@ -368,7 +379,7 @@ WarningDlg::WarningDlg(wxWindow* parentWindow, int activeButtons, const wxStrin
WarningDlgGenerated(parentWindow),
dontShowAgain(dontShowDlgAgain)
{
- m_bitmap10->SetBitmap(*GlobalResources::getInstance().bitmapWarning);
+ m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("warning")));
m_textCtrl8->SetValue(messageText);
m_checkBoxDontShowAgain->SetValue(dontShowAgain);
@@ -418,7 +429,7 @@ QuestionDlg::QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxStri
QuestionDlgGenerated(parentWindow),
dontShowAgain(dontShowDlgAgain)
{
- m_bitmap10->SetBitmap(*GlobalResources::getInstance().bitmapQuestion);
+ m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("question")));
m_textCtrl8->SetValue(messageText);
if (dontShowAgain)
m_checkBoxDontAskAgain->SetValue(*dontShowAgain);
@@ -485,8 +496,8 @@ CustomizeColsDlg::CustomizeColsDlg(wxWindow* window, xmlAccess::ColumnAttributes
output(attr),
m_showFileIcons(showFileIcons)
{
- m_bpButton29->SetBitmapLabel(*GlobalResources::getInstance().bitmapMoveUp);
- m_bpButton30->SetBitmapLabel(*GlobalResources::getInstance().bitmapMoveDown);
+ m_bpButton29->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("moveUp")));
+ m_bpButton30->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("moveDown")));
xmlAccess::ColumnAttributes columnSettings = attr;
@@ -604,12 +615,11 @@ SyncPreviewDlg::SyncPreviewDlg(wxWindow* parentWindow,
using FreeFileSync::includeNumberSeparator;
using globalFunctions::numberToWxString;
- //m_bitmapPreview->SetBitmap(*GlobalResources::getInstance().bitmapSync);
- m_buttonStartSync->setBitmapFront(*GlobalResources::getInstance().bitmapStartSync);
- m_bitmapCreate->SetBitmap(*GlobalResources::getInstance().bitmapCreate);
- m_bitmapUpdate->SetBitmap(*GlobalResources::getInstance().bitmapUpdate);
- m_bitmapDelete->SetBitmap(*GlobalResources::getInstance().bitmapDelete);
- m_bitmapData->SetBitmap(*GlobalResources::getInstance().bitmapData);
+ m_buttonStartSync->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("startSync")));
+ m_bitmapCreate->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("create")));
+ m_bitmapUpdate->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("update")));
+ m_bitmapDelete->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("delete")));
+ m_bitmapData->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("data")));
m_staticTextVariant->SetLabel(variantName);
m_textCtrlData->SetValue(FreeFileSync::formatFilesizeToShortString(statistics.getDataToProcess()));
@@ -657,9 +667,9 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& positi
//move dialog up so that compare-config button and first config-variant are on same level
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);
+ m_bpButtonHelp->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("help")));
+ m_bitmapByTime->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("cmpByTime")));
+ m_bitmapByContent->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("cmpByContent")));
switch (cmpVar)
{
@@ -714,17 +724,17 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSetti
GlobalSettingsDlgGenerated(window),
settings(globalSettings)
{
- m_bitmapSettings->SetBitmap(*GlobalResources::getInstance().bitmapSettings);
- m_buttonResetDialogs->setBitmapFront(*GlobalResources::getInstance().bitmapWarningSmall, 5);
- m_bpButtonAddRow->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
- m_bpButtonRemoveRow->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
+ m_bitmapSettings->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("settings")));
+ m_buttonResetDialogs->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("warningSmall")), 5);
+ m_bpButtonAddRow->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("addFolderPair")));
+ m_bpButtonRemoveRow->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("removeFolderPair")));
m_checkBoxIgnoreOneHour->SetValue(globalSettings.ignoreOneHourDiff);
m_checkBoxCopyLocked->SetValue(globalSettings.copyLockedFiles);
#ifndef FFS_WIN
-m_staticTextCopyLocked->Hide();
-m_checkBoxCopyLocked->Hide();
+ m_staticTextCopyLocked->Hide();
+ m_checkBoxCopyLocked->Hide();
#endif
set(globalSettings.gui.externelApplications);
@@ -1130,11 +1140,11 @@ void SyncStatus::updateStatusDialogNow()
break;
case COMPARING_CONTENT:
minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Comparing content...")) + wxT(" ") +
- fromatPercentage(currentData, totalData));
+ fromatPercentage(currentData, totalData), currentData.ToDouble() * 100 / totalData.ToDouble());
break;
case SYNCHRONIZING:
minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Synchronizing...")) + wxT(" ") +
- fromatPercentage(currentData, totalData));
+ fromatPercentage(currentData, totalData), currentData.ToDouble() * 100 / totalData.ToDouble());
break;
case ABORTED:
case FINISHED_WITH_SUCCESS:
@@ -1230,37 +1240,37 @@ void SyncStatus::setCurrentStatus(SyncStatusID id)
switch (id)
{
case ABORTED:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusError);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusError")));
m_staticTextStatus->SetLabel(_("Aborted"));
break;
case FINISHED_WITH_SUCCESS:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusSuccess);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusSuccess")));
m_staticTextStatus->SetLabel(_("Completed"));
break;
case FINISHED_WITH_ERROR:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusWarning);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusWarning")));
m_staticTextStatus->SetLabel(_("Completed"));
break;
case PAUSE:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusPause);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusPause")));
m_staticTextStatus->SetLabel(_("Paused"));
break;
case SCANNING:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusScanning);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusScanning")));
m_staticTextStatus->SetLabel(_("Scanning..."));
break;
case COMPARING_CONTENT:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusBinCompare);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusBinaryCompare")));
m_staticTextStatus->SetLabel(_("Comparing content..."));
break;
case SYNCHRONIZING:
- m_bitmapStatus->SetBitmap(*GlobalResources::getInstance().bitmapStatusSyncing);
+ m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusSyncing")));
m_staticTextStatus->SetLabel(_("Synchronizing..."));
break;
}
diff --git a/ui/batchStatusHandler.cpp b/ui/batchStatusHandler.cpp
index 43e818ee..793f18fd 100644
--- a/ui/batchStatusHandler.cpp
+++ b/ui/batchStatusHandler.cpp
@@ -63,14 +63,18 @@ private:
using namespace globalFunctions;
//create logfile directory
- const wxString logfileDir = logfileDirectory.empty() ? FreeFileSync::getDefaultLogDirectory() : logfileDirectory;
- if (!FreeFileSync::dirExists(wxToZ(logfileDir)))
- FreeFileSync::createDirectory(wxToZ(logfileDir)); //create recursively if necessary: may throw (FileError&)
+ Zstring logfileDir = logfileDirectory.empty() ?
+ wxToZ(FreeFileSync::getDefaultLogDirectory()) :
+ FreeFileSync::getFormattedDirectoryName(wxToZ(logfileDirectory));
+
+ if (!FreeFileSync::dirExists(logfileDir))
+ FreeFileSync::createDirectory(logfileDir); //create recursively if necessary: may throw (FileError&)
//assemble logfile name
- wxString logfileName = logfileDir;
- if (!logfileName.empty() && logfileName.Last() != FILE_NAME_SEPARATOR)
- logfileName += FILE_NAME_SEPARATOR;
+ if (!logfileDir.EndsWith(FILE_NAME_SEPARATOR))
+ logfileDir += FILE_NAME_SEPARATOR;
+
+ wxString logfileName = zToWx(logfileDir);
wxString timeNow = wxDateTime::Now().FormatISOTime();
timeNow.Replace(wxT(":"), wxT("-"));
diff --git a/ui/checkVersion.cpp b/ui/checkVersion.cpp
index 2fb57ec6..9ecb8876 100644
--- a/ui/checkVersion.cpp
+++ b/ui/checkVersion.cpp
@@ -1,12 +1,12 @@
#include "checkVersion.h"
-
+#include <wx/msgdlg.h>
#include <wx/protocol/http.h>
#include <wx/sstream.h>
#include "../version/version.h"
-#include <wx/msgdlg.h>
#include <wx/utils.h>
#include <wx/timer.h>
#include "../shared/globalFunctions.h"
+#include "smallDialogs.h"
class CloseConnectionOnExit
@@ -112,9 +112,15 @@ void FreeFileSync::checkForUpdatePeriodically(long& lastUpdateCheck)
{
if (lastUpdateCheck == 0)
{
- const int rv = wxMessageBox(_("Do you want FreeFileSync to automatically check for updates every week?"), _("Information"), wxYES_NO | wxICON_QUESTION);
- if (rv == wxYES)
- {
+ QuestionDlg* const messageDlg = new QuestionDlg(NULL,
+ QuestionDlg::BUTTON_YES | QuestionDlg::BUTTON_CANCEL,
+ wxString(_("Do you want FreeFileSync to automatically check for updates every week?")) + wxT("\n") +
+ _("(Requires an Internet connection!)"));
+
+ const bool checkRegularly = messageDlg->ShowModal() == QuestionDlg::BUTTON_YES;
+ messageDlg->Destroy();
+ if (checkRegularly)
+ {
lastUpdateCheck = 123; //some old date (few seconds after 1970)
checkForUpdatePeriodically(lastUpdateCheck); //check for updates now
@@ -140,6 +146,3 @@ void FreeFileSync::checkForUpdatePeriodically(long& lastUpdateCheck)
}
}
-
-
-
diff --git a/ui/folderPair.h b/ui/folderPair.h
index 557f3cc6..a67e5078 100644
--- a/ui/folderPair.h
+++ b/ui/folderPair.h
@@ -60,13 +60,13 @@ public:
{
if (altSyncConfig.get())
{
- basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmall);
+ basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("syncConfigSmall")));
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->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("syncConfigSmallGrey")));
basicPanel_.m_bpButtonAltSyncCfg->SetToolTip(_("Select alternate synchronization settings"));
}
@@ -77,18 +77,18 @@ public:
const bool isNullFilter = NameFilter(localFilter.includeFilter, localFilter.excludeFilter).isNull();
if (isNullFilter)
{
- basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey);
+ basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("filterSmallGrey")));
basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("No filter selected"));
}
else
{
- basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmall);
+ basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("filterSmall")));
basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filter has been selected"));
}
}
else
{
- basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey);
+ basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("filterSmallGrey")));
basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filtering is deactivated"));
}
}
@@ -104,7 +104,7 @@ protected:
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);
+ basicPanel_.m_bpButtonRemovePair->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("removeFolderPair")));
}
virtual void OnLocalFilterCfgRemoveConfirm(wxCommandEvent& event)
diff --git a/ui/gridView.cpp b/ui/gridView.cpp
index 8a3929fb..9b841e56 100644
--- a/ui/gridView.cpp
+++ b/ui/gridView.cpp
@@ -92,15 +92,11 @@ GridView::StatusCmpResult GridView::updateCmpResult(bool hideFiltered, //maps so
}
else
{
- const DirMapping* dirObj = dynamic_cast<const DirMapping*>(fsObj);
- if (dirObj)
- {
- if (!dirObj->isEmpty<LEFT_SIDE>())
+ if (!fsObj->isEmpty<LEFT_SIDE>())
++output.foldersOnLeftView;
- if (!dirObj->isEmpty<RIGHT_SIDE>())
+ if (!fsObj->isEmpty<RIGHT_SIDE>())
++output.foldersOnRightView;
- }
}
viewRef.push_back(*j);
@@ -119,6 +115,7 @@ GridView::StatusSyncPreview::StatusSyncPreview() :
existsSyncDirLeft(false),
existsSyncDirRight(false),
existsSyncDirNone(false),
+ existsSyncEqual(false),
existsConflict(false),
filesOnLeftView(0),
@@ -135,6 +132,7 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map
bool syncDirOverwLeftActive,
bool syncDirOverwRightActive,
bool syncDirNoneActive,
+ bool syncEqualActive,
bool conflictFilesActive)
{
StatusSyncPreview output;
@@ -146,13 +144,6 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map
const FileSystemObject* fsObj = getReferencedRow(*j);
if (fsObj)
{
- //synchronization preview
-
- //exclude result "=="
-//#warning na dann consider mal!
- if (fsObj->getCategory() == FILE_EQUAL) //note: consider "objectsTotal"
- continue;
-
//hide filtered row, if corresponding option is set
if (hideFiltered && !fsObj->isActive())
continue;
@@ -188,6 +179,10 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map
output.existsSyncDirNone = true;
if (!syncDirNoneActive) continue;
break;
+ case SO_EQUAL:
+ output.existsSyncEqual = true;
+ if (!syncEqualActive) continue;
+ break;
case SO_UNRESOLVED_CONFLICT:
output.existsConflict = true;
if (!conflictFilesActive) continue;
@@ -211,15 +206,11 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map
}
else
{
- const DirMapping* dirObj = dynamic_cast<const DirMapping*>(fsObj);
- if (dirObj)
- {
- if (!dirObj->isEmpty<LEFT_SIDE>())
+ if (!fsObj->isEmpty<LEFT_SIDE>())
++output.foldersOnLeftView;
- if (!dirObj->isEmpty<RIGHT_SIDE>())
+ if (!fsObj->isEmpty<RIGHT_SIDE>())
++output.foldersOnRightView;
- }
}
viewRef.push_back(*j);
diff --git a/ui/gridView.h b/ui/gridView.h
index 5ab28a44..eaa8ad8c 100644
--- a/ui/gridView.h
+++ b/ui/gridView.h
@@ -61,6 +61,7 @@ public:
bool existsSyncDirLeft;
bool existsSyncDirRight;
bool existsSyncDirNone;
+ bool existsSyncEqual;
bool existsConflict;
unsigned int filesOnLeftView;
@@ -81,6 +82,7 @@ public:
bool syncDirOverwLeftActive,
bool syncDirOverwRightActive,
bool syncDirNoneActive,
+ bool syncEqualActive,
bool conflictFilesActive);
@@ -125,7 +127,7 @@ private:
// |
// | (update...)
// \|/
- std::vector<RefIndex> sortedRef; //equivalent to folerCmp, but may be sorted
+ std::vector<RefIndex> sortedRef; //equivalent to folderCmp, but may be sorted
// |
// | (setData)
// \|/
diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp
index 9670c775..c522ccff 100644
--- a/ui/guiGenerated.cpp
+++ b/ui/guiGenerated.cpp
@@ -492,6 +492,15 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
sbSizer31->Add( 0, 0, 1, wxEXPAND, 5 );
+ m_bpButtonSyncCreateLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ sbSizer31->Add( m_bpButtonSyncCreateLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_bpButtonSyncDirOverwLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ sbSizer31->Add( m_bpButtonSyncDirOverwLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_bpButtonSyncDeleteLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ sbSizer31->Add( m_bpButtonSyncDeleteLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
m_bpButtonLeftOnly = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonLeftOnly, 0, wxALIGN_CENTER_VERTICAL, 5 );
@@ -504,24 +513,15 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
m_bpButtonDifferent = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonDifferent, 0, wxALIGN_CENTER_VERTICAL, 5 );
+ m_bpButtonSyncDirNone = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ sbSizer31->Add( m_bpButtonSyncDirNone, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
m_bpButtonRightNewer = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonRightNewer, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_bpButtonRightOnly = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonRightOnly, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncCreateLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
- sbSizer31->Add( m_bpButtonSyncCreateLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- m_bpButtonSyncDirOverwLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
- sbSizer31->Add( m_bpButtonSyncDirOverwLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- m_bpButtonSyncDeleteLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
- sbSizer31->Add( m_bpButtonSyncDeleteLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
- m_bpButtonSyncDirNone = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
- sbSizer31->Add( m_bpButtonSyncDirNone, 0, wxALIGN_CENTER_VERTICAL, 5 );
-
m_bpButtonSyncDeleteRight = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonSyncDeleteRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
@@ -756,16 +756,16 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
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_bpButtonSyncCreateLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateLeft ), NULL, this );
+ m_bpButtonSyncDirOverwLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
+ m_bpButtonSyncDeleteLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteLeft ), 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 );
m_bpButtonEqual->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnEqualFiles ), NULL, this );
m_bpButtonDifferent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnDifferentFiles ), NULL, this );
+ m_bpButtonSyncDirNone->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirNone ), NULL, this );
m_bpButtonRightNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightNewerFiles ), NULL, this );
m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightOnlyFiles ), NULL, this );
- m_bpButtonSyncCreateLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateLeft ), NULL, this );
- m_bpButtonSyncDirOverwLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
- m_bpButtonSyncDeleteLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteLeft ), NULL, this );
- m_bpButtonSyncDirNone->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirNone ), NULL, this );
m_bpButtonSyncDeleteRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteRight ), NULL, this );
m_bpButtonSyncDirOverwRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirRight ), NULL, this );
m_bpButtonSyncCreateRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateRight ), NULL, this );
@@ -817,16 +817,16 @@ MainDialogGenerated::~MainDialogGenerated()
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_bpButtonSyncCreateLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateLeft ), NULL, this );
+ m_bpButtonSyncDirOverwLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
+ m_bpButtonSyncDeleteLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteLeft ), 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 );
m_bpButtonEqual->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnEqualFiles ), NULL, this );
m_bpButtonDifferent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnDifferentFiles ), NULL, this );
+ m_bpButtonSyncDirNone->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirNone ), NULL, this );
m_bpButtonRightNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightNewerFiles ), NULL, this );
m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightOnlyFiles ), NULL, this );
- m_bpButtonSyncCreateLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateLeft ), NULL, this );
- m_bpButtonSyncDirOverwLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
- m_bpButtonSyncDeleteLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteLeft ), NULL, this );
- m_bpButtonSyncDirNone->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirNone ), NULL, this );
m_bpButtonSyncDeleteRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteRight ), NULL, this );
m_bpButtonSyncDirOverwRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirRight ), NULL, this );
m_bpButtonSyncCreateRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateRight ), NULL, this );
@@ -1309,7 +1309,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
wxBoxSizer* bSizer1151;
bSizer1151 = new wxBoxSizer( wxHORIZONTAL );
- m_textCtrlCustomDelFolder = new wxTextCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_RIGHT );
+ m_textCtrlCustomDelFolder = new wxTextCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_textCtrlCustomDelFolder->SetMinSize( wxSize( 160,-1 ) );
bSizer1151->Add( m_textCtrlCustomDelFolder, 1, wxALIGN_CENTER_VERTICAL, 5 );
@@ -3322,7 +3322,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w
wxBoxSizer* bSizer66;
bSizer66 = new wxBoxSizer( wxHORIZONTAL );
- m_staticText181 = new wxStaticText( m_panel13, wxID_ANY, _("Include: *.doc;*.zip;*.exe\nExclude: temp\\*"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText181 = new wxStaticText( m_panel13, wxID_ANY, _("Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText181->Wrap( -1 );
bSizer66->Add( m_staticText181, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
@@ -3600,7 +3600,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
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.") );
+ m_staticTextCopyLocked->SetToolTip( _("Copy shared or locked files using Volume Shadow Copy Service.") );
bSizer1201->Add( m_staticTextCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -3609,7 +3609,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
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.") );
+ m_checkBoxCopyLocked->SetToolTip( _("Copy shared or locked files using Volume Shadow Copy Service.") );
bSizer1201->Add( m_checkBoxCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -3663,7 +3663,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
m_gridCustomCommand->EnableDragColSize( true );
m_gridCustomCommand->SetColLabelSize( 20 );
m_gridCustomCommand->SetColLabelValue( 0, _("Description") );
- m_gridCustomCommand->SetColLabelValue( 1, _("Commandline") );
+ m_gridCustomCommand->SetColLabelValue( 1, _("Command line") );
m_gridCustomCommand->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h
index 70cce976..ab4d3c12 100644
--- a/ui/guiGenerated.h
+++ b/ui/guiGenerated.h
@@ -118,16 +118,16 @@ class MainDialogGenerated : public wxFrame
wxCheckBox* m_checkBoxHideFilt;
wxPanel* m_panel112;
+ ToggleButton* m_bpButtonSyncCreateLeft;
+ ToggleButton* m_bpButtonSyncDirOverwLeft;
+ ToggleButton* m_bpButtonSyncDeleteLeft;
ToggleButton* m_bpButtonLeftOnly;
ToggleButton* m_bpButtonLeftNewer;
ToggleButton* m_bpButtonEqual;
ToggleButton* m_bpButtonDifferent;
+ ToggleButton* m_bpButtonSyncDirNone;
ToggleButton* m_bpButtonRightNewer;
ToggleButton* m_bpButtonRightOnly;
- ToggleButton* m_bpButtonSyncCreateLeft;
- ToggleButton* m_bpButtonSyncDirOverwLeft;
- ToggleButton* m_bpButtonSyncDeleteLeft;
- ToggleButton* m_bpButtonSyncDirNone;
ToggleButton* m_bpButtonSyncDeleteRight;
ToggleButton* m_bpButtonSyncDirOverwRight;
ToggleButton* m_bpButtonSyncCreateRight;
@@ -195,16 +195,16 @@ class MainDialogGenerated : public wxFrame
virtual void OnConfigureFilter( wxCommandEvent& event ){ event.Skip(); }
virtual void OnFilterButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnHideFilteredButton( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnSyncCreateLeft( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnSyncDirLeft( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnSyncDeleteLeft( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftOnlyFiles( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftNewerFiles( wxCommandEvent& event ){ event.Skip(); }
virtual void OnEqualFiles( wxCommandEvent& event ){ event.Skip(); }
virtual void OnDifferentFiles( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnSyncDirNone( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightNewerFiles( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightOnlyFiles( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnSyncCreateLeft( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnSyncDirLeft( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnSyncDeleteLeft( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnSyncDirNone( wxCommandEvent& event ){ event.Skip(); }
virtual void OnSyncDeleteRight( wxCommandEvent& event ){ event.Skip(); }
virtual void OnSyncDirRight( wxCommandEvent& event ){ event.Skip(); }
virtual void OnSyncCreateRight( wxCommandEvent& event ){ event.Skip(); }
diff --git a/ui/settingsDialog.cpp b/ui/settingsDialog.cpp
index 230d187d..fe037322 100644
--- a/ui/settingsDialog.cpp
+++ b/ui/settingsDialog.cpp
@@ -48,12 +48,12 @@ SyncCfgDialog::SyncCfgDialog(wxWindow* window,
updateConfigIcons(cmpVariant, localSyncConfiguration);
//set icons for this dialog
- m_bitmapLeftOnly->SetBitmap(*GlobalResources::getInstance().bitmapLeftOnly);
- m_bitmapRightOnly->SetBitmap(*GlobalResources::getInstance().bitmapRightOnly);
- m_bitmapLeftNewer->SetBitmap(*GlobalResources::getInstance().bitmapLeftNewer);
- m_bitmapRightNewer->SetBitmap(*GlobalResources::getInstance().bitmapRightNewer);
- m_bitmapDifferent->SetBitmap(*GlobalResources::getInstance().bitmapDifferent);
- m_bitmapConflict->SetBitmap(*GlobalResources::getInstance().bitmapConflictGrey);
+ m_bitmapLeftOnly->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("leftOnly")));
+ m_bitmapRightOnly->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("rightOnly")));
+ m_bitmapLeftNewer->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("leftNewer")));
+ m_bitmapRightNewer->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("rightNewer")));
+ m_bitmapDifferent->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("different")));
+ m_bitmapConflict->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("conflictGrey")));
bSizer201->Layout(); //wxButtonWithImage size might have changed
@@ -175,15 +175,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
switch (syncConfig.exLeftSideOnly)
{
case SYNC_DIR_RIGHT:
- buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRightCr);
+ buttonLeftOnly->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowRightCr")));
buttonLeftOnly->SetToolTip(getDescription(SO_CREATE_NEW_RIGHT));
break;
case SYNC_DIR_LEFT:
- buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapDeleteLeft);
+ buttonLeftOnly->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("deleteLeft")));
buttonLeftOnly->SetToolTip(getDescription(SO_DELETE_LEFT));
break;
case SYNC_DIR_NONE:
- buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
+ buttonLeftOnly->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowNone")));
buttonLeftOnly->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -191,15 +191,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
switch (syncConfig.exRightSideOnly)
{
case SYNC_DIR_RIGHT:
- buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapDeleteRight);
+ buttonRightOnly->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("deleteRight")));
buttonRightOnly->SetToolTip(getDescription(SO_DELETE_RIGHT));
break;
case SYNC_DIR_LEFT:
- buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeftCr);
+ buttonRightOnly->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowLeftCr")));
buttonRightOnly->SetToolTip(getDescription(SO_CREATE_NEW_LEFT));
break;
case SYNC_DIR_NONE:
- buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
+ buttonRightOnly->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowNone")));
buttonRightOnly->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -207,15 +207,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
switch (syncConfig.leftNewer)
{
case SYNC_DIR_RIGHT:
- buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
+ buttonLeftNewer->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowRight")));
buttonLeftNewer->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
- buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
+ buttonLeftNewer->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowLeft")));
buttonLeftNewer->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
- buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
+ buttonLeftNewer->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowNone")));
buttonLeftNewer->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -223,15 +223,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
switch (syncConfig.rightNewer)
{
case SYNC_DIR_RIGHT:
- buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
+ buttonRightNewer->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowRight")));
buttonRightNewer->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
- buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
+ buttonRightNewer->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowLeft")));
buttonRightNewer->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
- buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
+ buttonRightNewer->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowNone")));
buttonRightNewer->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -239,15 +239,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
switch (syncConfig.different)
{
case SYNC_DIR_RIGHT:
- buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
+ buttonDifferent->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowRight")));
buttonDifferent->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
- buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
+ buttonDifferent->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowLeft")));
buttonDifferent->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
- buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
+ buttonDifferent->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowNone")));
buttonDifferent->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -255,15 +255,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
switch (syncConfig.conflict)
{
case SYNC_DIR_RIGHT:
- buttonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
+ buttonConflict->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowRight")));
buttonConflict->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
- buttonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
+ buttonConflict->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("arrowLeft")));
buttonConflict->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
- buttonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapConflict);
+ buttonConflict->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("conflict")));
buttonConflict->SetToolTip(_("Leave as unresolved conflict"));
break;
}
@@ -350,7 +350,7 @@ void updateToolTipDeletionHandling(wxChoice* choiceHandleError, wxPanel* customD
break;
case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY:
- choiceHandleError->SetToolTip(_("Move files to a user-defined directory."));
+ choiceHandleError->SetToolTip(_("Move files into a time-stamped subdirectory."));
customDir->Enable();
break;
}
@@ -637,16 +637,16 @@ void BatchDialog::init()
//set icons for this dialog
- m_bpButtonAddPair->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
- m_bitmapLeftOnly->SetBitmap(*GlobalResources::getInstance().bitmapLeftOnly);
- m_bitmapRightOnly->SetBitmap(*GlobalResources::getInstance().bitmapRightOnly);
- m_bitmapLeftNewer->SetBitmap(*GlobalResources::getInstance().bitmapLeftNewer);
- m_bitmapRightNewer->SetBitmap(*GlobalResources::getInstance().bitmapRightNewer);
- m_bitmapDifferent->SetBitmap(*GlobalResources::getInstance().bitmapDifferent);
- m_bitmapConflict->SetBitmap(*GlobalResources::getInstance().bitmapConflictGrey);
- m_bitmap8->SetBitmap(*GlobalResources::getInstance().bitmapInclude);
- m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapExclude);
- m_bitmap27->SetBitmap(*GlobalResources::getInstance().bitmapBatch);
+ m_bpButtonAddPair->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("addFolderPair")));
+ m_bitmapLeftOnly->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("leftOnly")));
+ m_bitmapRightOnly->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("rightOnly")));
+ m_bitmapLeftNewer->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("leftNewer")));
+ m_bitmapRightNewer->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("rightNewer")));
+ m_bitmapDifferent->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("different")));
+ m_bitmapConflict->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("conflictGrey")));
+ m_bitmap8->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("include")));
+ m_bitmap9->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("exclude")));
+ m_bitmap27->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("batch")));
m_buttonSave->SetFocus();
}
@@ -1143,11 +1143,11 @@ void BatchDialog::OnAddFolderPair(wxCommandEvent& event)
addFolderPair(newPairs, true); //add pair in front of additonal pairs
//clear first pair
- const FolderPairEnh cfgEmpty;
- firstFolderPair->setValues(cfgEmpty.leftDirectory,
- cfgEmpty.rightDirectory,
- cfgEmpty.altSyncConfig,
- cfgEmpty.localFilter);
+ const FolderPairEnh cfgEmpty;
+ firstFolderPair->setValues(cfgEmpty.leftDirectory,
+ cfgEmpty.rightDirectory,
+ cfgEmpty.altSyncConfig,
+ cfgEmpty.localFilter);
}
@@ -1220,48 +1220,48 @@ void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>&
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);
-
- if (addFront)
+ //add folder pairs
+ int pairHeight = 0;
+ for (std::vector<FreeFileSync::FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i)
{
- bSizerAddFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5);
- additionalFolderPairs.insert(additionalFolderPairs.begin(), newPair);
- }
- else
- {
- bSizerAddFolderPairs->Add(newPair, 0, wxEXPAND, 5);
- additionalFolderPairs.push_back(newPair);
- }
+ BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6, *this);
- //get size of scrolled window
- pairHeight = newPair->GetSize().GetHeight();
+ 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);
+ }
- //register events
- newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::OnRemoveFolderPair), NULL, this );
+ //get size of scrolled window
+ pairHeight = newPair->GetSize().GetHeight();
- //set alternate configuration
- 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
- m_scrolledWindow6->SetMinSize(wxSize( -1, pairHeight * visiblePairs));
+ //register events
+ newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::OnRemoveFolderPair), NULL, this );
- //update controls
- m_scrolledWindow6->Fit(); //adjust scrolled window size
- m_panelOverview->Layout(); //adjust stuff inside scrolled window
- Fit(); //adapt dialog size
+ //set alternate configuration
+ 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
+ m_scrolledWindow6->SetMinSize(wxSize( -1, pairHeight * visiblePairs));
- //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();
-}
+ //update controls
+ m_scrolledWindow6->Fit(); //adjust scrolled window size
+ m_panelOverview->Layout(); //adjust stuff inside scrolled window
+ Fit(); //adapt dialog size
+
+ //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();
}
@@ -1269,7 +1269,7 @@ void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>&
void BatchDialog::removeAddFolderPair(const int pos)
{
- wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion
+ wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion
if (0 <= pos && pos < static_cast<int>(additionalFolderPairs.size()))
{
@@ -1296,7 +1296,7 @@ void BatchDialog::removeAddFolderPair(const int pos)
m_bpButtonLeftOnly->SetFocus();
}
- updateGuiForFolderPair();
+ updateGuiForFolderPair();
}
diff --git a/ui/settingsDialog.h b/ui/settingsDialog.h
index 0864cf92..15d880f4 100644
--- a/ui/settingsDialog.h
+++ b/ui/settingsDialog.h
@@ -137,7 +137,7 @@ private:
void removeAddFolderPair(const int pos);
void clearAddFolderPairs();
-void updateGuiForFolderPair();
+ void updateGuiForFolderPair();
FreeFileSync::CompareVariant getCurrentCompareVar() const;
diff --git a/ui/sorting.h b/ui/sorting.h
index 04ecc171..5771d7db 100644
--- a/ui/sorting.h
+++ b/ui/sorting.h
@@ -60,16 +60,16 @@ bool sortByFileName(const FileSystemObject& a, const FileSystemObject& b)
return true; //empty rows always last
- if (dynamic_cast<const DirMapping*>(&a)) //sort directories by relative name
+ if (isDirectoryMapping(a)) //sort directories by relative name
{
- if (dynamic_cast<const DirMapping*>(&b))
+ if (isDirectoryMapping(b))
return stringSmallerThan(a.getRelativeName<side>(), b.getRelativeName<side>());
else
return false;
}
else
{
- if (dynamic_cast<const DirMapping*>(&b))
+ if (isDirectoryMapping(b))
return true;
else
return Compare<ascending>().isSmallerThan(
@@ -86,15 +86,16 @@ bool sortByRelativeName(const FileSystemObject& a, const FileSystemObject& b)
else if (b.isEmpty<side>())
return true; //empty rows always last
- const FileMapping* fileObjA = dynamic_cast<const FileMapping*>(&a);
- const Zstring relDirNameA = fileObjA != NULL ?
- a.getParentRelativeName() : //file
- a.getRelativeName<side>(); //directory
+ const bool isDirectoryA = isDirectoryMapping(a);
+ const Zstring relDirNameA = isDirectoryA ?
+ a.getRelativeName<side>() : //directory
+ a.getParentRelativeName(); //file
+
+ const bool isDirectoryB = isDirectoryMapping(b);
+ const Zstring relDirNameB = isDirectoryB ?
+ b.getRelativeName<side>() : //directory
+ b.getParentRelativeName(); //file
- const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b);
- const Zstring relDirNameB = fileObjB != NULL ?
- b.getParentRelativeName() : //file
- b.getRelativeName<side>(); //directory
//compare relative names without filenames first
const int rv = compareString(relDirNameA, relDirNameB);
@@ -102,9 +103,9 @@ bool sortByRelativeName(const FileSystemObject& a, const FileSystemObject& b)
return Compare<ascending>().isSmallerThan(rv, 0);
else //compare the filenames
{
- if (fileObjB == NULL) //directories shall appear before files
+ if (isDirectoryB) //directories shall appear before files
return false;
- else if (fileObjA == NULL)
+ else if (isDirectoryA)
return true;
return stringSmallerThan(a.getShortName<side>(), b.getShortName<side>());
diff --git a/ui/trayIcon.cpp b/ui/trayIcon.cpp
index 478d135a..921fe79f 100644
--- a/ui/trayIcon.cpp
+++ b/ui/trayIcon.cpp
@@ -1,8 +1,8 @@
#include "trayIcon.h"
#include "../library/resources.h"
#include "smallDialogs.h"
-//#include "../library/statusHandler.h"
#include <wx/taskbar.h>
+#include <cmath>
enum Selection
@@ -89,10 +89,90 @@ void MinimizeToTray::resumeFromTray() //remove trayIcon and restore windows: Mi
}
-void MinimizeToTray::setToolTip(const wxString& toolTipText)
+namespace
+{
+inline
+int roundNum(double d) //little rounding function
+{
+ return static_cast<int>(d < 0 ? d - .5 : d + .5);
+}
+
+
+wxIcon generateIcon(size_t percent) //generate icon with progress indicator
+{
+ percent = std::min(percent, static_cast<size_t>(100u)); //handle invalid input
+
+#ifdef FFS_WIN
+ static const wxBitmap trayIcon = GlobalResources::getInstance().getImageByName(wxT("FFS_tray_win.png"));
+#elif defined FFS_LINUX
+ static const wxBitmap trayIcon = GlobalResources::getInstance().getImageByName(wxT("FFS_tray_linux.png"));
+#endif
+
+ const int indicatorHeight = roundNum((trayIcon.GetHeight() * percent) / 100.0);
+
+ //minor optimization
+ static std::pair<int, wxIcon> buffer = std::make_pair(-1, wxNullIcon);
+ if (buffer.first == indicatorHeight)
+ return buffer.second;
+
+ if ( trayIcon.GetWidth() > 0 &&
+ trayIcon.GetHeight() > 0)
+ {
+ static const int indicatorWidth = trayIcon.GetWidth() * .25;
+ const int indicatorXBegin = ceil((trayIcon.GetWidth() - indicatorWidth) / 2.0);
+ const int indicatorYBegin = trayIcon.GetHeight() - indicatorHeight;
+
+ wxImage genImage(trayIcon.ConvertToImage());
+
+ //draw progress indicator: do NOT use wxDC::DrawRectangle! Doesn't respect alpha in Windows, but does in Linux!
+ //We need a simple, working solution:
+ unsigned char* const data = genImage.GetData();
+ for (int row = indicatorYBegin; row < genImage.GetHeight(); ++row)
+ {
+ for (int col = indicatorXBegin; col < indicatorXBegin + indicatorWidth; ++col)
+ {
+ unsigned char* const pixelBegin = data + (row * genImage.GetWidth() + col) * 3;
+ pixelBegin[0] = 255; //red
+ pixelBegin[1] = 255; //green
+ pixelBegin[2] = 0; //blue
+ }
+ }
+
+ if (genImage.HasAlpha())
+ {
+ unsigned char* const alpha = genImage.GetAlpha();
+ //make progress indicator fully opaque:
+ for (int row = indicatorYBegin; row < genImage.GetHeight(); ++row)
+ ::memset(alpha + row * genImage.GetWidth() + indicatorXBegin, wxIMAGE_ALPHA_OPAQUE, indicatorWidth);
+ }
+
+ wxIcon genIcon;
+ genIcon.CopyFromBitmap(wxBitmap(genImage));
+
+ //fill buffer
+ buffer.first = indicatorHeight;
+ buffer.second = genIcon;
+
+ return genIcon;
+ }
+
+ //fallback
+ wxIcon defaultIcon;
+ defaultIcon.CopyFromBitmap(trayIcon);
+
+ //fill buffer
+ buffer.first = indicatorHeight;
+ buffer.second = defaultIcon;
+
+ return defaultIcon;
+}
+}
+
+
+void MinimizeToTray::setToolTip(const wxString& toolTipText, size_t percent)
{
if (trayIcon)
- trayIcon->SetIcon(*GlobalResources::getInstance().programIcon, toolTipText);
+ trayIcon->SetIcon(generateIcon(percent), toolTipText);
}
@@ -125,3 +205,4 @@ void MinimizeToTray::OnDoubleClick(wxCommandEvent& event)
{
resumeFromTray();
}
+
diff --git a/ui/trayIcon.h b/ui/trayIcon.h
index 94e75518..8c8797d4 100644
--- a/ui/trayIcon.h
+++ b/ui/trayIcon.h
@@ -11,7 +11,7 @@ public:
MinimizeToTray(wxTopLevelWindow* callerWnd, wxWindow* secondWnd = NULL); //ensure callerWind has longer lifetime!
~MinimizeToTray(); //show windows again
- void setToolTip(const wxString& toolTipText);
+ void setToolTip(const wxString& toolTipText, size_t percent = 0); //percent (optional), number between [0, 100], for small progress indicator
void keepHidden(); //do not show windows again: avoid window flashing shortly before it is destroyed
private:
diff --git a/version/version.h b/version/version.h
index 647be5ba..6f9095ce 100644
--- a/version/version.h
+++ b/version/version.h
@@ -2,5 +2,5 @@
namespace FreeFileSync
{
- static const wxString currentVersion = wxT("3.2"); //internal linkage!
+ static const wxString currentVersion = wxT("3.3"); //internal linkage!
}
bgstack15