summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Application.cpp38
-rw-r--r--BUILD/Changelog.txt23
-rw-r--r--BUILD/FreeFileSync.chmbin377174 -> 377164 bytes
-rw-r--r--BUILD/Help/html/Features.html21
-rw-r--r--BUILD/Help/html/advanced/ExcludeSubfolder.html6
-rw-r--r--BUILD/Help/html/advanced/RealtimeSync.html17
-rw-r--r--BUILD/Help/html/advanced/ScheduleBatch.html27
-rw-r--r--BUILD/Help/html/advanced/SymbolicLinks.html2
-rw-r--r--BUILD/Languages/chinese_simple.lng14
-rw-r--r--BUILD/Languages/chinese_traditional.lng14
-rw-r--r--BUILD/Languages/czech.lng14
-rw-r--r--BUILD/Languages/dutch.lng148
-rw-r--r--BUILD/Languages/english_uk.lng14
-rw-r--r--BUILD/Languages/finnish.lng20
-rw-r--r--BUILD/Languages/french.lng14
-rw-r--r--BUILD/Languages/german.lng18
-rw-r--r--BUILD/Languages/hebrew.lng14
-rw-r--r--BUILD/Languages/hungarian.lng30
-rw-r--r--BUILD/Languages/italian.lng14
-rw-r--r--BUILD/Languages/japanese.lng14
-rw-r--r--BUILD/Languages/polish.lng14
-rw-r--r--BUILD/Languages/portuguese.lng12
-rw-r--r--BUILD/Languages/portuguese_br.lng14
-rw-r--r--BUILD/Languages/romanian.lng36
-rw-r--r--BUILD/Languages/russian.lng18
-rw-r--r--BUILD/Languages/slovenian.lng14
-rw-r--r--BUILD/Languages/spanish.lng14
-rw-r--r--BUILD/Languages/swedish.lng18
-rw-r--r--BUILD/Languages/turkish.lng684
-rw-r--r--BUILD/Resources.datbin294245 -> 294369 bytes
-rw-r--r--FreeFileSync.cbp7
-rw-r--r--Makefile34
-rw-r--r--RealtimeSync/RealtimeSync.cbp4
-rw-r--r--RealtimeSync/makefile16
-rw-r--r--RealtimeSync/notify.cpp3
-rw-r--r--RealtimeSync/watcher.cpp11
-rw-r--r--algorithm.cpp114
-rw-r--r--algorithm.h3
-rw-r--r--comparison.cpp87
-rw-r--r--file_hierarchy.h6
-rw-r--r--library/binary.cpp10
-rw-r--r--library/custom_grid.cpp293
-rw-r--r--library/custom_grid.h72
-rw-r--r--library/db_file.cpp2
-rw-r--r--library/dir_lock.cpp79
-rw-r--r--library/pch.h14
-rw-r--r--shared/IFileOperation/file_op.cpp1
-rw-r--r--shared/com_ptr.h23
-rw-r--r--shared/custom_combo_box.cpp39
-rw-r--r--shared/custom_combo_box.h7
-rw-r--r--shared/custom_tooltip.cpp3
-rw-r--r--shared/dir_name.cpp2
-rw-r--r--shared/file_handling.cpp178
-rw-r--r--shared/file_io.cpp2
-rw-r--r--shared/file_traverser.cpp144
-rw-r--r--shared/global_func.h2
-rw-r--r--shared/localization.cpp29
-rw-r--r--shared/localization.h2
-rw-r--r--shared/recycler.cpp10
-rw-r--r--shared/serialize.cpp2
-rw-r--r--shared/serialize.h5
-rw-r--r--shared/signal_processing.h166
-rw-r--r--shared/symlink_target.h146
-rw-r--r--shared/system_func.cpp17
-rw-r--r--shared/zbase.h20
-rw-r--r--synchronization.cpp9
-rw-r--r--ui/batch_status_handler.cpp26
-rw-r--r--ui/batch_status_handler.h2
-rw-r--r--ui/check_version.cpp17
-rw-r--r--ui/gui_generated.cpp23
-rw-r--r--ui/gui_generated.h41
-rw-r--r--ui/gui_status_handler.cpp7
-rw-r--r--ui/gui_status_handler.h2
-rw-r--r--ui/main_dlg.cpp126
-rw-r--r--ui/main_dlg.h4
-rw-r--r--ui/progress_indicator.cpp24
-rw-r--r--ui/progress_indicator.h3
-rw-r--r--ui/small_dlgs.cpp6
-rw-r--r--version/version.h2
-rw-r--r--version/version.rc4
80 files changed, 1764 insertions, 1371 deletions
diff --git a/Application.cpp b/Application.cpp
index af111a65..d8b7c760 100644
--- a/Application.cpp
+++ b/Application.cpp
@@ -102,13 +102,10 @@ void Application::OnStartApplication(wxIdleEvent&)
GlobalResources::getInstance().load(); //loads bitmap resources on program startup
-#ifndef _MSC_VER
-#warning wxWidgets 2.9
+#if wxCHECK_VERSION(2, 9, 1)
+ wxToolTip::SetMaxWidth(-1); //disable tooltip wrapping
+ wxToolTip::SetAutoPop(7000); //tooltip visibilty in ms, 5s seems to be default for Windows
#endif
- /*
- wxToolTip::SetMaxWidth(-1); //disable tooltip wrapping
- wxToolTip::SetAutoPop(7000); //tooltip visibilty in ms, 5s seems to be default for Windows
- */
try //load global settings from XML
@@ -236,9 +233,9 @@ void Application::runBatchMode(const wxString& filename, xmlAccess::XmlGlobalSet
//class handling status updates and error messages
std::auto_ptr<BatchStatusHandler> statusHandler; //delete object automatically
if (batchCfg.silent)
- statusHandler.reset(new BatchStatusHandler(true, filename, &batchCfg.logFileDirectory, batchCfg.handleError, switchBatchToGui, returnValue));
+ statusHandler.reset(new BatchStatusHandler(true, ffs3::extractJobName(filename), &batchCfg.logFileDirectory, batchCfg.handleError, switchBatchToGui, returnValue));
else
- statusHandler.reset(new BatchStatusHandler(false, filename, NULL, batchCfg.handleError, switchBatchToGui, returnValue));
+ statusHandler.reset(new BatchStatusHandler(false, ffs3::extractJobName(filename), NULL, batchCfg.handleError, switchBatchToGui, returnValue));
//COMPARE DIRECTORIES
ffs3::FolderComparison folderCmp;
@@ -251,13 +248,6 @@ void Application::runBatchMode(const wxString& filename, xmlAccess::XmlGlobalSet
batchCfg.mainCfg.compareVar,
folderCmp);
- //check if there are files/folders to be sync'ed at all
- if (!synchronizationNeeded(folderCmp))
- {
- statusHandler->logInfo(_("Nothing to synchronize according to configuration!")); //inform about this special case
- //return; -> disabled: <automatic> mode requires database to be written in any case
- }
-
//START SYNCHRONIZATION
ffs3::SyncProcess synchronization(
globSettings.optDialogs,
@@ -271,10 +261,20 @@ void Application::runBatchMode(const wxString& filename, xmlAccess::XmlGlobalSet
synchronization.startSynchronizationProcess(syncProcessCfg, folderCmp);
- //play (optional) sound notification after sync has completed (GUI and batch mode)
- const wxString soundFile = ffs3::getResourceDir() + wxT("Sync_Complete.wav");
- if (ffs3::fileExists(ffs3::wxToZ(soundFile)))
- wxSound::Play(soundFile, wxSOUND_ASYNC);
+ //check if there are files/folders to be sync'ed at all
+ if (!synchronizationNeeded(folderCmp))
+ {
+ statusHandler->logInfo(_("Nothing to synchronize according to configuration!")); //inform about this special case
+ //return; -> disabled: <automatic> mode requires database to be written in any case
+ }
+
+ //play (optional) sound notification after sync has completed
+ if (!batchCfg.silent)
+ {
+ const wxString soundFile = ffs3::getResourceDir() + wxT("Sync_Complete.wav");
+ if (ffs3::fileExists(ffs3::wxToZ(soundFile)))
+ wxSound::Play(soundFile, wxSOUND_ASYNC);
+ }
}
catch (ffs3::AbortThisProcess&) //exit used by statusHandler
{
diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt
index 5cc1db55..dc7dd689 100644
--- a/BUILD/Changelog.txt
+++ b/BUILD/Changelog.txt
@@ -2,6 +2,29 @@
|FreeFileSync|
--------------
+Changelog v3.12
+---------------
+Allow empty folder pairs without complaining
+Automatically exclude database and lock files from all (sub-)directories (not only from base)
+Resize grid columns on both sides in parallel
+Fixed tooltip foreground text color (Linux)
+Search via CTRL + F and F3 now as global hotkeys
+Fully portable use of directory locking (Windows/Linux, 32/64 bit)
+RealtimeSync: Treat missing network path the same as missing local path
+Show current job name during synchronization (batch/gui)
+Allow copying dereferenced (=followed) directory Symlinks over network share
+Fail to copy Symlinks (=direct) over network share instead of silently creating empty folder (Windows XP)
+Copy NTFS junctions as Symlinks (avoiding permission checks)
+RealtimeSync: ignore request for device removal on network mapped drives
+Support for copying SELinux security contexts
+Fixed moving buttons in synchronization dialog
+Allow deleting currently selected item from list of last used folders (not before wxWidgets 2.9.1)
+Avoid losing focus after manually deleting a file
+Preserve custom changes to sync directions after manually deleting a file
+Handle empty tooltips correctly (Linux)
+Updated translation files
+
+
Changelog v3.11
---------------
Fixed migration issue: reasonable default value for number of folder pairs
diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm
index 381fc7ca..6a48eef9 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 0bf33088..c5665a7d 100644
--- a/BUILD/Help/html/Features.html
+++ b/BUILD/Help/html/Features.html
@@ -5,7 +5,7 @@
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20100807;20464900">
+ <META NAME="CHANGED" CONTENT="20101013;18402500">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
@@ -33,7 +33,7 @@
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>
+ 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
@@ -70,8 +70,8 @@
superfluous/temporary files directly on main grid.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Right-click
context menu.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Status
- information and error reporting</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Comprehensive
+ status information and error reporting</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Sort
file-lists by name, size or date.</FONT></P>
</OL>
@@ -93,13 +93,10 @@
requiring a re-compare!).</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Include/exclude
specific files from synchronization temporarily.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create
- sync jobs via GUI to synchronize automatically (can be scheduled or
- executed via double-click).</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Handle
- daylight saving time changes on FAT/FAT32 volumes correctly.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Automatically
+ handle daylight saving time changes on FAT/FAT32 volumes.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Portable
- version available.</FONT></P>
+ version available (selectable via installer).</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Native
64-Bit version.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Check
@@ -110,10 +107,10 @@
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create
regular backups with macros %time%, %date% within directory names</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy
- file and folder create/access/modification times when synchronizing</FONT></P>
+ file and folder create/access/modification times when synchronizing.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Advanced
locking strategy to allow multiple synchronization processes (e.g.
- multiple writers, same network share)</FONT></P>
+ multiple writers, same network share).</FONT></P>
</OL>
</BODY>
</HTML> \ No newline at end of file
diff --git a/BUILD/Help/html/advanced/ExcludeSubfolder.html b/BUILD/Help/html/advanced/ExcludeSubfolder.html
index 239d88b9..eff2c465 100644
--- a/BUILD/Help/html/advanced/ExcludeSubfolder.html
+++ b/BUILD/Help/html/advanced/ExcludeSubfolder.html
@@ -5,7 +5,7 @@
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20100711;12255900">
+ <META NAME="CHANGED" CONTENT="20101114;14355300">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
@@ -94,9 +94,9 @@ character, which is interpreted as the end of a directory name.</FONT></P>
<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen4" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff">
<P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm">
<FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>In most cases
- specifying a filter phrase manually is not necessary! You can
+ manually specifying a filter phrase is not necessary! You can
exclude files, directories and even whole lists of both directly on
- main dialog via right-click context menu.</FONT></P>
+ main grid via context menu.</FONT></P>
</SPAN><BR CLEAR=LEFT><BR>
</P>
</BODY>
diff --git a/BUILD/Help/html/advanced/RealtimeSync.html b/BUILD/Help/html/advanced/RealtimeSync.html
index 692a1b36..635b86d1 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.2 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20100902;19164200">
+ <META NAME="CHANGED" CONTENT="20101016;14325500">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
@@ -48,7 +48,7 @@ Instead of doing this manually you can simply import a </FONT><FONT FACE="Courie
-&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 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.
+<FONT FACE="Tahoma, sans-serif">file each 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>
@@ -61,17 +61,16 @@ to begin monitoring.</FONT></P>
<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">The settings dialog can be skipped
+ by passing a RealtimeSync configuration file (<FONT FACE="Courier New, monospace">*.ffs_real</FONT>)
+ OR a FreeFileSync Batch file (<FONT FACE="Courier New, monospace">*.ffs_batch</FONT>)
+ as first command-line argument. This enables integration with your
+ operating system's auto start facility:</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 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 (<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. Latter is implicitly converted to
- a *.ffs_real file with default settings. This allows for
- integration with your operating system's auto start facility:</FONT></P>
</UL>
</SPAN><BR CLEAR=LEFT>
</P>
diff --git a/BUILD/Help/html/advanced/ScheduleBatch.html b/BUILD/Help/html/advanced/ScheduleBatch.html
index a155b3e6..c7b163c9 100644
--- a/BUILD/Help/html/advanced/ScheduleBatch.html
+++ b/BUILD/Help/html/advanced/ScheduleBatch.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.2 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20100323;21404100">
+ <META NAME="CHANGED" CONTENT="20101128;12534500">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
@@ -13,6 +13,7 @@
H3 { margin-bottom: 0.21cm }
H3.western { font-family: "Arial", sans-serif }
H3.cjk { font-family: "MS Mincho" }
+ H3.ctl { font-family: "Mangal" }
A:link { so-language: zxx }
-->
</STYLE>
@@ -27,8 +28,7 @@ XP)</SPAN></FONT></H3>
<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 &quot;<FONT FACE="Courier New, monospace">C:\SyncJob.ffs_
- batch</FONT>&quot;.</FONT></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 enable checkbox &quot;<I>Silent mode</I>&quot; to prevent
showing a status dialog at the end of the process.</FONT></P>
@@ -42,21 +42,34 @@ XP)</SPAN></FONT></H3>
<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>
- <P STYLE="margin-bottom: 0cm"></P>
<UL>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If
you are using the locally installed version of FreeFileSync,
</FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> <FONT FACE="Tahoma, sans-serif">files
are automatically associated with the tool and field &quot;</FONT><FONT FACE="Tahoma, sans-serif"><I>Run:</I></FONT><FONT FACE="Tahoma, sans-serif">&quot;
can be directly filled with the filename:<BR>&quot;</FONT><FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batch</FONT><FONT FACE="Tahoma, sans-serif">&quot;<BR><IMG SRC="ScheduleBatch_html_372f0f3.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 installation),</FONT>
&quot;<FONT FACE="Tahoma, sans-serif"><I>Run:</I></FONT><FONT FACE="Tahoma, sans-serif">&quot;
has to be prefixed with the
- executable:<BR>&quot;D</FONT><FONT FACE="Courier New, monospace">:\FreeFileSync\FreeFileSync.exe&quot;
+ executable:<BR>&quot;</FONT><FONT FACE="Courier New, monospace">D:\FreeFileSync\FreeFileSync.exe&quot;
&quot;C:\SyncJob.ffs_batch</FONT><FONT FACE="Tahoma, sans-serif">&quot;<BR><IMG SRC="ScheduleBatch_html_m10bf0d36.gif" NAME="Grafik2" ALIGN=BOTTOM WIDTH=406 HEIGHT=455 BORDER=0></FONT></P>
</UL>
</OL>
+<P STYLE="margin-bottom: 0cm"><BR>
+</P>
+<P STYLE="margin-bottom: 0cm"><BR>
+</P>
+<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff">
+ <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm">
+ <FONT FACE="Tahoma, sans-serif"><B>Note:</B></FONT><FONT FACE="Tahoma, sans-serif"><BR>Beginning
+ with Windows Vista, the command always needs to be prefixed with the
+ executable even if file associations are set:<BR></FONT>&rarr;
+ <FONT FACE="Tahoma, sans-serif">&quot;</FONT><FONT FACE="Courier New, monospace">D:\FreeFileSync\FreeFileSync.exe&quot;
+ &quot;C:\SyncJob.ffs_batch<BR></FONT><FONT FACE="Tahoma, sans-serif">Else
+ the task will return with error code 0xC1, &quot;%1 is not a valid
+ Win32 application&quot;.</FONT></P>
+</SPAN><BR CLEAR=LEFT><BR>
+</P>
</BODY>
</HTML> \ No newline at end of file
diff --git a/BUILD/Help/html/advanced/SymbolicLinks.html b/BUILD/Help/html/advanced/SymbolicLinks.html
index 6efe1eb9..1914f953 100644
--- a/BUILD/Help/html/advanced/SymbolicLinks.html
+++ b/BUILD/Help/html/advanced/SymbolicLinks.html
@@ -50,7 +50,7 @@ Links (also called Symlinks or Soft Links):</FONT></P>
</UL>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
-<P STYLE="margin-bottom: 0cm"><IMG SRC="CmpSettings.png" NAME="Grafik1" ALIGN=BOTTOM WIDTH=343 HEIGHT=261 BORDER=0></P>
+<P STYLE="margin-bottom: 0cm"><IMG SRC="CmpSettings.png" NAME="Grafik1" ALIGN=BOTTOM BORDER=0></P>
<P STYLE="margin-bottom: 0cm"><BR>
</P>
<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff">
diff --git a/BUILD/Languages/chinese_simple.lng b/BUILD/Languages/chinese_simple.lng
index c5645a85..eaae2c4a 100644
--- a/BUILD/Languages/chinese_simple.lng
+++ b/BUILD/Languages/chinese_simple.lng
@@ -76,6 +76,8 @@
确定(&O)
&Pause
暂停(&P)
+&Program
+程序(&P)
&Quit
退出(&Q)
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
剩余的元素:
Email
邮箱
+Encoding extended time information: %x
+正在编码扩展时间信息:%x
Endless loop when traversing directory:
遍历目录时出现无限循环:
Error
@@ -400,6 +404,8 @@ Error reading file:
读取文件出错:
Error reading from synchronization database:
从同步数据库中读取时出错:
+Error reading security context:
+读取安全上下文时出错:
Error resolving symbolic link:
解决符号链接出错:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
监视目录时出错.
Error writing file:
写入文件出错:
+Error writing security context:
+写入安全上下文时出错:
Error writing to synchronization database:
向同步数据库中写入时出错:
Example
@@ -702,8 +710,6 @@ Reset
重置
Right
右侧
-Run minimized and write status information to a logfile
-最小化运行并将状态信息写到一个记录文件中
S&ave configuration...
保存配置(&A)...
S&witch view
@@ -776,6 +782,8 @@ Speed:
速度:
Start
开始
+Start minimized and write status information to a logfile
+以最小化开始运行并将信息写到日志文件
Start synchronization
开始同步
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
同步已完成但有错误.
Synchronization settings
同步设置
-Synchronization status
-同步状态
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
同步所有 .doc, .zip和 .exe 文件, 除了\"temp\"中的一切.
Synchronize...
diff --git a/BUILD/Languages/chinese_traditional.lng b/BUILD/Languages/chinese_traditional.lng
index d8a23a7a..a8a019a2 100644
--- a/BUILD/Languages/chinese_traditional.lng
+++ b/BUILD/Languages/chinese_traditional.lng
@@ -76,6 +76,8 @@
確定(&O)
&Pause
暫停(&P)
+&Program
+程式(&P)
&Quit
離開(&Q)
&Restore
@@ -360,8 +362,8 @@ Elements remaining:
剩餘要素:
Email
信箱
-Encode extended time information: %x
-
+Encoding extended time information: %x
+編碼延長時間資訊:%x
Endless loop when traversing directory:
當遍歷目錄時無限循環:
Error
@@ -402,6 +404,8 @@ Error reading file:
讀取檔案錯誤:
Error reading from synchronization database:
讀取同步資料庫錯誤:
+Error reading security context:
+讀取安全內文錯誤:
Error resolving symbolic link:
解决符號連結錯誤:
Error setting directory lock:
@@ -416,6 +420,8 @@ Error when monitoring directories.
監測目錄錯誤。
Error writing file:
寫入檔案錯誤:
+Error writing security context:
+寫入安全上內文錯誤:
Error writing to synchronization database:
寫入同步資料庫錯誤:
Example
@@ -704,8 +710,6 @@ Reset
重置
Right
右邊
-Run minimized and write status information to a logfile
-執行最小化和狀態資訊寫入到日誌檔
S&ave configuration...
儲存配置(&A)...
S&witch view
@@ -778,6 +782,8 @@ Speed:
速度:
Start
開始
+Start minimized and write status information to a logfile
+啟動最小化和寫入狀態資訊到日誌檔
Start synchronization
開始同步
Statistics
diff --git a/BUILD/Languages/czech.lng b/BUILD/Languages/czech.lng
index 976d32ce..4e9def42 100644
--- a/BUILD/Languages/czech.lng
+++ b/BUILD/Languages/czech.lng
@@ -76,6 +76,8 @@ Zkontrolovat &aktualizace
&OK
&Pause
&Pauza
+&Program
+&Nástroje
&Quit
U&končit
&Restore
@@ -360,8 +362,8 @@ Elements remaining:
Zbývá položek:
Email
Email
-Encode extended time information: %x
-
+Encoding extended time information: %x
+Zpracování rozšířené informace o čase: %x
Endless loop when traversing directory:
Zacyklení při procházení adresáře:
Error
@@ -402,6 +404,8 @@ Error reading file:
Chyba čtení souboru:
Error reading from synchronization database:
Chyba čtení synchronizační databáze:
+Error reading security context:
+Chyba při čtení přístupových práv:
Error resolving symbolic link:
Chyba odkazu zástupce:
Error setting directory lock:
@@ -416,6 +420,8 @@ Error when monitoring directories.
Chyba při sledování adresářů.
Error writing file:
Chyba zápisu souboru:
+Error writing security context:
+Chyba při zápisu přístupových práv:
Error writing to synchronization database:
Chyba zápisu synchronizační databáze:
Example
@@ -704,8 +710,6 @@ Reset
Resetovat
Right
Pravý
-Run minimized and write status information to a logfile
-Spustit minimalizovaný a zapisovat informace do souboru
S&ave configuration...
&Uložení konfigurace...
S&witch view
@@ -778,6 +782,8 @@ Speed:
Rychlost:
Start
Start
+Start minimized and write status information to a logfile
+Spustit minimalizovaný a zapisovat informace do souboru
Start synchronization
Start synchronizace
Statistics
diff --git a/BUILD/Languages/dutch.lng b/BUILD/Languages/dutch.lng
index ee674596..5e1d3499 100644
--- a/BUILD/Languages/dutch.lng
+++ b/BUILD/Languages/dutch.lng
@@ -3,35 +3,35 @@
%x / %y objects deleted successfully
%x / %y objecten succesvol verwijderd
%x Byte
-
+%x Byte
+%x GB
%x GB
-
%x MB
-
+%x MB
+%x PB
%x PB
-
%x TB
-
+%x TB
%x day(s)
-
+%x dag(en)
%x directories
%x paden
%x files
%x bestanden
%x hour(s)
-
+%x uur/uren
+%x kB
%x kB
-
%x min
-
+%x min
%x of %y rows in view
%x van de %y rijen in zicht
%x of 1 row in view
%x van 1 rij in zicht
%x sec
-
+%x sec
+%x%
%x%
-
&Abort
&Afbreken
&About...
@@ -55,7 +55,7 @@
&File
&Bestand
&Find next
-
+&Vind volgende
&Global settings...
&Algemene instellingen...
&Help
@@ -76,6 +76,8 @@
&OK
&Pause
&Pause
+&Program
+&Programma
&Quit
&Afsluiten
&Restore
@@ -85,11 +87,11 @@
&Save
&Opslaan
&Switch
-
+&Verander
&Yes
&Ja
(Build: %x)
-
+(Build: %x)
(Requires an Internet connection!)
(Vereist een internetverbinding)
- Other side's counterpart to %dir
@@ -149,7 +151,7 @@
<Last session>
<Laatste sessie>
<Symlink>
-
+<Symlink>
<multiple selection>
<veelvoudige selectie>
A newer version of FreeFileSync is available:
@@ -157,7 +159,7 @@ Een nieuwe versie van FreeFileSync is beschikbaar:
Abort requested: Waiting for current operation to finish...
Bezig met afbreken: wachten op beëindigen huidige handeling...
Abort synchronization immediately
-
+Stop synchronistatie onmiddelijk
Aborted
Afgebroken
About
@@ -195,15 +197,15 @@ Beide zijden zijn veranderd sinds de laatste synchronisatie!
Browse
Map opzoeken
Browse directory
-
+Doorzoek map
Cannot determine sync-direction:
Kan de synchronisatie-richting niet bepalen:
Cannot find %x
-
+Kan %x niet vinden
Category
Categorie
Clear filter settings
-
+Leeg filter instellingen
Comma separated list
Komma gescheiden lijst
Command line
@@ -255,7 +257,7 @@ Doorgaan
Conversion error:
Fout bij het converteren:
Copy filesystem permissions
-
+Kopieer bestandsmachtigingen
Copy from left to right
Kopieer van links naar rechts
Copy from left to right overwriting
@@ -269,13 +271,13 @@ 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\n(Requires Administrator rights)
-
+Kopieer gedeelde of beveiligde bestanden met Volume Shadow Copy Service\n(Heeft administrator rechten nodig)
Copy to clipboard\tCTRL+C
Kopieer naar het klembord\tCTRL+C
Copying new Symbolic Link %x to %y
-
+Kopieer nieuw symbolische link van %x naar %y
Copying new file %x to %y
-
+Kopieer nieuw bestand van %x naar %y
Could not determine volume name for file:
Kon de schijfnaam niet vaststellen van bestand:
Could not initialize directory monitoring:
@@ -317,7 +319,7 @@ Verwijder of overschrijf bestanden onomkeerbaar
Delete permanently
Verwijder onomkeerbaar
Deleting Symbolic Link %x
-
+Verwijderen symbolische link %x
Deleting file %x
Bestand %x wordt verwijderd
Deleting folder %x
@@ -327,7 +329,7 @@ Verwijder-afhandeling
Description
Beschrijving
Direct
-
+Direct
Directories are dependent! Be careful when setting up synchronization rules:
Mappen zijn afhankelijk van elkaar! Wees voorzichtig met het maken van synchronisatieregels:
Directories to watch
@@ -353,13 +355,15 @@ Nu downloaden?
Drag && drop
Drag en drop
Elements found:
-
+Elementen gevonden:
Elements processed:
-
+Elementen verwerkt:
Elements remaining:
-
+Elementen te gaaan:
Email
E-mail
+Encoding extended time information: %x
+Coderen uitgebreide tijd informatie: %x
Endless loop when traversing directory:
Oneindige lus bij het nalopen van locatie:
Error
@@ -367,13 +371,13 @@ Fout
Error changing modification time:
Er is een fout opgetreden bij het aanpassen van de bestandstijd:
Error copying file permissions:
-
+Error kopieren van bestandspremissies:
Error copying file:
Er is een fout opgetreden bij het kopiëren van bestand:
Error copying locked file %x!
Er is een fout opgetreden bij het kopiëren van %x omdat het bestand in gebruik is!
Error copying symbolic link:
-
+Error kopieren symbolische link:
Error creating directory:
Er is een fout opgetreden bij het aanmaken van pad:
Error deleting directory:
@@ -400,12 +404,14 @@ 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 reading security context:
+Error bij lezen van de beveiliging:
Error resolving symbolic link:
Er is een fout opgetreden bij het ophalen van een symbolische koppeling:
Error setting directory lock:
-
+Error instelling van map slot:
Error setting privilege:
-
+Error instelling van premissies:
Error starting Volume Shadow Copy Service!
Er is een fout opgetreden bij het starten van de Volume Schadow Copy Service!
Error traversing directory:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Er is een fout opgetreden bij het observeren van locaties.
Error writing file:
Er is een fout opgetreden bij het schrijven naar bestand:
+Error writing security context:
+Error met het schrijven van de beveiliging:
Error writing to synchronization database:
Er is een fout opgetreden bij het schrijven naar de synchronisatie-database:
Example
@@ -427,9 +435,9 @@ Tijdelijk uitsluiten
Exclude via filter:
Uitsluiten door filter:
Exit instantly
-
+Sluit gelijk af
Extension
-
+Extensie
External applications
Externe applicaties
Fatal Error
@@ -463,7 +471,7 @@ Bestanden die aan beide kanten bestaan, maar waarvan de linkerkant nieuwer is
Files that exist on both sides, right one is newer
Bestanden die aan beide kanten bestaan, maar waarvan de rechterkant nieuwer is
Files that have different content
-
+Bestanden dat andere inhoud hebben
Files/folders that exist on left side only
Bestanden/mappen die alleen aan de linkerkant bestaan
Files/folders that exist on right side only
@@ -471,23 +479,23 @@ Bestanden/mappen die alleen aan de rechterkant bestaan
Filter files
Filter bestanden
Filter is active
-
+Filer is actief
Filter settings have changed!
Filter instellingen opgeslagen!
Filter view
Bekijk het filter
Filter: All pairs
-
+Filter: Alle paren
Filter: Single pair
-
+Filter: Enkel paar
Find
-
+Vind
Find what:
-
+Vind wat:
Folder Comparison and Synchronization
Mappen vergelijken en synchroniseren
Follow
-
+Volg
Free disk space available:
Beschikbare vrije schijfruimte :
FreeFileSync Batch Job
@@ -555,11 +563,11 @@ Homepage
Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically.
Identificeer en verwerk verandereringen aan beide kanten dmv een database. Verschillen en conflicten worden automatisch gedecteerd.
Idle time between detection of last change and execution of command line in seconds
-
+Inactieve tijd tussen de detectie van de laatste verandering en het uitvoeren van een command in seconden
If you like FFS
-Als het programma u bevalt
+Als het programma FreeFileSync u bevalt
Ignore
-
+Negeer
Ignore errors
Negeer foutmeldingen
Ignore subsequent errors
@@ -583,7 +591,7 @@ 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:
Invalid FreeFileSync config file!
-
+FreeFileSync config bestand klopt niet!
Leave as unresolved conflict
Beschouwen als onopgelost conflict
Left
@@ -601,9 +609,9 @@ 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.
Match case
-
+Hoofdlettergevoelig
Minimum Idle Time
-
+Minimale Inactieve Tijd
Mirror ->>
Spiegelen ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
@@ -621,7 +629,7 @@ Verplaats de bestanden in een tijd-gemarkeerde sublocatie
Moving %x to Recycle Bin
%x aan het verplaatsen naar de Prullenbak
Moving Symbolic Link %x to user-defined directory %y
-
+Verplaatsen symbolische link %x naar map %y
Moving file %x to user-defined directory %y
Verplaatsen bestand %x naar een door de gebruiker gedefinieerde locatie %y
Moving folder %x to user-defined directory %y
@@ -643,15 +651,15 @@ Aantal mappen en bestanden die zullen worden verwijderd
Number of files that will be overwritten
Aantal bestanden dat zal worden overschreven
One of the FreeFileSync database entries within the following file is not yet existing:
-
+Een van de FreeFileSync databasegegevens met dit bestand bestaat nog niet:
One of the FreeFileSync database files is not yet existing:
-
+Een van de FreeFileSync database bestanden bestaat nog niet:
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.
Alleen bestanden /locatie die niet worden gefilterd zullen worden gesynchroniseerd. Het filter word toegepast op de relatieve(!) naam van de basislocatie van de synchronisatie.
Open with Explorer
Openen met Explorer
Open with default application
-
+Open met standaardapplicatie
Operation aborted!
Operatie afgebroken!
Operation:
@@ -659,19 +667,19 @@ Voortgang:
Overview
Overzicht
Overwriting Symbolic Link %x in %y
-
+Overschrijven van symbolische link %x over %y
Overwriting file %x in %y
-
+Overschrijven bestand %x over %y
Pause
Pause
Paused
Gepauseerd
Planned directory deletion is in conflict with its subdirectories and -files!
-
+Geplande map verwijdering heeft een conflict veroorzaakt met de bestanden en submappen
Please run a Compare first before synchronizing!
Voer eerst een Vergelijking uit voordat u synchroniseerd.
Press \"Switch\" to open FreeFileSync GUI mode.
-
+Druk op \"Switch\" om FreeFilySync GUI mode te gebruiken.
Processing folder pair:
Verwerken van gekoppelde folder:
Published under the GNU General Public License:
@@ -687,7 +695,7 @@ RealtimeSync - Automatische Synchronisatie
RealtimeSync configuration
RealtimeSync configuratie
Recycle Bin not yet supported for this system!
-
+Prullenbak werkt (nog) niet op dit systeem!
Relative path
Relatieve pad
Remove alternate settings
@@ -702,8 +710,6 @@ Reset
Reset
Right
Rechts
-Run minimized and write status information to a logfile
-Tijdens het synchroniseren het venster minimaliseren en alle informatie opslaan in een log-bestand
S&ave configuration...
S&la de instellingen op...
S&witch view
@@ -725,9 +731,9 @@ Selecteer een map voor het logbestand:
Select variant:
Selecteer een variant:
Set direction:
-
+Selecteer map:
Setting default synchronization directions: Old files will be overwritten with newer files.
-
+Instellingen worden veranderd naar standaard instellingen: Oude bestanden worden overschreven naar nieuwere bestanden.
Show conflicts
Geef conflicten weer
Show files that are different
@@ -776,22 +782,24 @@ Speed:
Snelheid:
Start
Start
+Start minimized and write status information to a logfile
+Start geminimaliseerd en schrijf status informatie in een logbestand
Start synchronization
Start synchroniseren
Statistics
Statistieken
Status feedback
-
+Status feedback
Stop
Stop
Swap sides
Wissel zijdes
Switching to FreeFileSync GUI mode...
-
+Veranderen naar FreeFileSync GUI mode...
Symbolic Link handling
-
+Symbolische Link handeling
Symlinks %x have the same date but a different target!
-
+Symbolische links %x heeft dezelfde datum maar een ander doel!
Synchronization Preview
Synchronisatie voorbeeldweergave
Synchronization aborted!
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Synchronisatie afgerond. Er zijn fouten opgetreden.
Synchronization settings
Synchronisatie instellingen
-Synchronization status
-Synchronisatie: status
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Synchroniseer alle .doc, .zip en .exe bestanden uitgezonderd alles in submap \"temp\"
Synchronize...
@@ -817,11 +823,11 @@ Doellocatie bestaal al!
Target file already existing!
Doelbestand bestaat al!
The command line is executed each time:\n- all directories become available (e.g. USB stick insert)\n- files within these directories or subdirectories are modified
-
+De command lijn is uitgevoerd elke tijd:\n- alle mappen worden beschikbaar (bijvoorbeeld via een USB stick)\n- bestanden binnen deze mappen of submappen zijn bewerkt.
The file does not contain a valid configuration:
Het bestand bevat geen geldige configuratie:
The file was not processed by last synchronization!
-
+Het bestand werd niet verwerkt door de laatste synchronisatie!
This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time.
Deze variant ziet twee gelijknamige bestanden als gelijk wanneer ze dezelfde bestandsgrootte EN tijdstempel hebben.
Time
@@ -837,7 +843,7 @@ Benodigde hoeveelheid vrije schijfruimte:
Total time:
Totale tijd:
Transfer file and directory permissions\n(Requires Administrator rights)
-
+Overdracht van bestanden en mappen permissies\n (Vereist Administrator rechten)
Unable to connect to sourceforge.net!
Niet in staat verbinding te maken met sourceforge.net!
Unable to create logfile!
@@ -863,9 +869,9 @@ Verifiëren bestand %x
Volume name %x not part of filename %y!
Volume naam %x maakt niet deel uit van bestandsnaam %y!
Waiting for all directories to become available...
-
+Wachten op alle mappen....
Waiting while directory is locked (%x)...
-
+Wachten totdat map is beveiligd (%x)...
Warning
Attentie
Warning: Synchronization failed for %x item(s):
diff --git a/BUILD/Languages/english_uk.lng b/BUILD/Languages/english_uk.lng
index eab1c880..60b3f04c 100644
--- a/BUILD/Languages/english_uk.lng
+++ b/BUILD/Languages/english_uk.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Pause
+&Program
+&Program
&Quit
&Quit
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Elements remaining:
Email
E-mail
+Encoding extended time information: %x
+Encoding extended time information: %x
Endless loop when traversing directory:
Endless loop when traversing directory:
Error
@@ -400,6 +404,8 @@ Error reading file:
Error reading file:
Error reading from synchronization database:
Error reading from synchronisation database:
+Error reading security context:
+Error reading security context:
Error resolving symbolic link:
Error resolving symbolic link:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Error when monitoring directories.
Error writing file:
Error writing file:
+Error writing security context:
+Error writing security context:
Error writing to synchronization database:
Error writing to synchronisation database:
Example
@@ -702,8 +710,6 @@ Reset
Reset
Right
Right
-Run minimized and write status information to a logfile
-Run minimised and write status information to a logfile
S&ave configuration...
S&ave configuration...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Speed:
Start
Start
+Start minimized and write status information to a logfile
+Start minimized and write status information to a logfile
Start synchronization
Start synchronisation
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Synchronisation completed with errors!
Synchronization settings
Synchronisation settings
-Synchronization status
-Synchronisation status
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Synchronise all .doc, .zip and .exe files except everything in subfolder \"temp\".
Synchronize...
diff --git a/BUILD/Languages/finnish.lng b/BUILD/Languages/finnish.lng
index 77c39c55..ca642e15 100644
--- a/BUILD/Languages/finnish.lng
+++ b/BUILD/Languages/finnish.lng
@@ -19,7 +19,7 @@
%x files
%x tiedostoista
%x hour(s)
-% tunteja
+%x tunti(a)
%x kB
%x kB
%x min
@@ -76,6 +76,8 @@ Asetusten &lataus...
&OK
&Pause
&Keskeytä
+&Program
+&Ohjelma
&Quit
&Lopeta
&Restore
@@ -153,9 +155,9 @@ Asetusten &lataus...
<multiple selection>
<monivalinta>
A newer version of FreeFileSync is available:
-FreeFileSync:n uusi versio on olemassa:
+FreeFileSync:n uusi versio on saatavilla:
Abort requested: Waiting for current operation to finish...
-Ohjelma on lopetettava: Odotetaan toiminnon lopettamista...
+Ohjelma on lopetettava: Odotetaan toiminnon loppumista...
Abort synchronization immediately
Lopeta täsmäytys välittömästi
Aborted
@@ -360,6 +362,8 @@ Elements remaining:
Osia jäljellä:
Email
S-posti
+Encoding extended time information: %x
+Tulkitaan laajennettua aikatietoa: %x
Endless loop when traversing directory:
Suorita hakemiston läpikulku jatkuvana:
Error
@@ -400,6 +404,8 @@ Error reading file:
Virhe lukiessa tiedostoa:
Error reading from synchronization database:
Virhe lukiessa täsmäytyksen tietokantaa:
+Error reading security context:
+Virhe lukiessa tuvatietoja:
Error resolving symbolic link:
Virhe selvittäessä symbolista linkkiä:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Virhe seuratessa hakemistoa.
Error writing file:
Virhe kirjottaessa tiedosto:
+Error writing security context:
+Virhe kirjottaessa tuvatietoja:
Error writing to synchronization database:
Virhe kirjottaessa täsmäytyksen tietokantaa:
Example
@@ -702,8 +710,6 @@ Reset
Palauta
Right
Oikea
-Run minimized and write status information to a logfile
-Suorita pienenettynä vie status tiedot lokiin
S&ave configuration...
Asetukset t&allennetaan...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Nopeus:
Start
Käynnistä
+Start minimized and write status information to a logfile
+Käynnistä minimoituna ja kirjoita statukset lokiin
Start synchronization
Käynnistä täsmäytys
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Täsmäytys päättyi virheisiin!
Synchronization settings
Täsmäytyksen asetukset
-Synchronization status
-Täsmäytyksen status
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Täsmäytä kaikki .doc, .zip und .exe tiedostot paitsi hakemistossa \"temp\" oleva.
Synchronize...
diff --git a/BUILD/Languages/french.lng b/BUILD/Languages/french.lng
index 9d47b8e7..7703cbe5 100644
--- a/BUILD/Languages/french.lng
+++ b/BUILD/Languages/french.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Pause
+&Program
+&Actions
&Quit
&Quitter
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Elements restants :
Email
Email
+Encoding extended time information: %x
+Codage de l'heure au format étendu : %x
Endless loop when traversing directory:
Boucle sans fin lors du parcours du répertoire :
Error
@@ -400,6 +404,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 reading security context:
+Erreur de lecture du contexte de sécurité:
Error resolving symbolic link:
Erreur lors de la résolution du lien symbolique :
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Erreur lors de la surveillance des répertoires.
Error writing file:
Erreur lors de l'écriture du fichier :
+Error writing security context:
+Erreur d'écriture du contexte de sécurité:
Error writing to synchronization database:
Erreur lors de l'écriture de la base de données de synchro :
Example
@@ -702,8 +710,6 @@ Reset
Réinitialiser
Right
Droite
-Run minimized and write status information to a logfile
-Exécution en mode réduit. Les informations d'état sont enregistrées dans un fichier .log
S&ave configuration...
S&auvegarder la configuration...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Vitesse :
Start
Démarrer
+Start minimized and write status information to a logfile
+Démarrage en mode réduit et écriture des informations d'état dans un fichier log
Start synchronization
Démarrer la synchronisation
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Synchronisation terminée avec des erreurs !
Synchronization settings
Paramétrage de la synchronisation
-Synchronization status
-Etat de la synchronisation
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Synchroniser tous les fichiers .doc, .zip et .exe sauf ceux du dossier \"temp\".
Synchronize...
diff --git a/BUILD/Languages/german.lng b/BUILD/Languages/german.lng
index 105b302e..20e752ae 100644
--- a/BUILD/Languages/german.lng
+++ b/BUILD/Languages/german.lng
@@ -76,6 +76,8 @@ Konfiguration &laden...
&OK
&Pause
&Pause
+&Program
+&Programm
&Quit
&Beenden
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Verbleibende Elemente:
Email
Email
+Encoding extended time information: %x
+Speichere erweiterte Zeitinformation: %x
Endless loop when traversing directory:
Endlosschleife beim Lesen des Verzeichnisses:
Error
@@ -400,6 +404,8 @@ Error reading file:
Fehler beim Lesen der Datei:
Error reading from synchronization database:
Fehler beim Lesen der Synchronisationsdatenbank:
+Error reading security context:
+Fehler beim Lesen des Sicherheitskontextes:
Error resolving symbolic link:
Fehler beim Auflösen des Symbolischen Links:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Fehler beim Überwachen der Verzeichnisse.
Error writing file:
Fehler beim Schreiben der Datei:
+Error writing security context:
+Fehler beim Schreiben des Sicherheitskontextes:
Error writing to synchronization database:
Fehler beim Schreiben der Synchronisationsdatenbank:
Example
@@ -451,7 +459,7 @@ Dateigröße und -datum
Filename
Dateiname
Files %x have the same date but a different size!
-Die Dateien %x haben dasselbe Datum, aber eine unterschiedliche Größe!
+Die Dateien %x haben dasselbe Datum, aber unterschiedliche Größen!
Files are found equal if\n - file content\nis the same
Dateien gelten als gleich, wenn\n - der Inhalt\ngleich ist
Files are found equal if\n - filesize\n - last write time and date\nare the same
@@ -702,8 +710,6 @@ Reset
Zurücksetzen
Right
Rechts
-Run minimized and write status information to a logfile
-Minimiert ausführen und Statusinformationen in eine Logdatei schreiben
S&ave configuration...
Konfiguration s&peichern...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Geschwindigkeit:
Start
Start
+Start minimized and write status information to a logfile
+Minimiert starten und Statusinformationen in eine Logdatei schreiben
Start synchronization
Synchronisation starten
Statistics
@@ -789,7 +797,7 @@ Seiten vertauschen
Switching to FreeFileSync GUI mode...
Wechsle in die graphische Ansicht...
Symbolic Link handling
-Verwendung Symbolischer Links
+Behandlung Symbolischer Links
Symlinks %x have the same date but a different target!
Die Symbolischen Links %x haben dasselbe Datum, aber ein unterschiedliches Ziel!
Synchronization Preview
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Synchronisation mit Fehlern abgeschlossen!
Synchronization settings
Synchronisationseinstellungen
-Synchronization status
-Synchronisationsstatus
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Alle .doc, .zip und .exe Dateien mit Ausnahme des Verzeichnisses \"temp\" werden synchronisiert.
Synchronize...
diff --git a/BUILD/Languages/hebrew.lng b/BUILD/Languages/hebrew.lng
index 3c487fc7..dd1621b2 100644
--- a/BUILD/Languages/hebrew.lng
+++ b/BUILD/Languages/hebrew.lng
@@ -76,6 +76,8 @@
&אשר
&Pause
&עצור
+&Program
+
&Quit
&יציאה
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
אלמנתים נותרו:
Email
:דוא"ל
+Encoding extended time information: %x
+
Endless loop when traversing directory:
נוצרת לולאה אינסופית בחצית מחיצות
Error
@@ -400,6 +404,8 @@ Error reading file:
טעות בקריאת קובץ:
Error reading from synchronization database:
טעות בקריאה מבסיס הנתונים של הסנכרון:
+Error reading security context:
+
Error resolving symbolic link:
טעות בפענוח מראה מקום סימלי (Symbolic Link)
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
טעות בניתור מחיצות.
Error writing file:
טעות בכתיבת קובת:
+Error writing security context:
+
Error writing to synchronization database:
טעות ברישום לבסיס נתוני סנכרון:
Example
@@ -702,8 +710,6 @@ Reset
אפס
Right
ימין
-Run minimized and write status information to a logfile
-הפעל ניסתר ורשום ליומן פעילות
S&ave configuration...
שמ&ןר תצורה...
S&witch view
@@ -776,6 +782,8 @@ Speed:
מהירות:
Start
התחל
+Start minimized and write status information to a logfile
+
Start synchronization
התחל סנכרון
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
סנכרון הושלם עם שגיאות!
Synchronization settings
משתני סנכרון
-Synchronization status
-סטטוס סנכרון
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
סנכרן .doc, .zip und .exe כל הקבצים בתיקית משנה \"temp\".
Synchronize...
diff --git a/BUILD/Languages/hungarian.lng b/BUILD/Languages/hungarian.lng
index 79cbd932..838fe79a 100644
--- a/BUILD/Languages/hungarian.lng
+++ b/BUILD/Languages/hungarian.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Szünet
+&Program
+&Program
&Quit
&Kilépés
&Restore
@@ -273,9 +275,9 @@ A megosztott vagy zárolt fájlok másolása a Volume Shadow Copy szolgáltatás
Copy to clipboard\tCTRL+C
Másolás a vágólapra\tCTRL+C
Copying new Symbolic Link %x to %y
-
+A(z) %x új symlink másolása a(z) %y symlinkbe
Copying new file %x to %y
-
+A(z) %x új fájl másolása a(z) %y fájlba
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:
@@ -360,6 +362,8 @@ Elements remaining:
Hátralévő elemek száma:
Email
E-mail
+Encoding extended time information: %x
+Kibővített időinformációk kódolása: %x
Endless loop when traversing directory:
Végtelen hurok a mappák bejárásakor:
Error
@@ -400,10 +404,12 @@ 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 reading security context:
+A biztonsági címke olvasása sikertelen:
Error resolving symbolic link:
A szimbolikus link feloldása sikertelen:
Error setting directory lock:
-
+Hiba történt a mappa zárolása közben:
Error setting privilege:
Hiba történt a jogok beállítása közben:
Error starting Volume Shadow Copy Service!
@@ -414,6 +420,8 @@ Error when monitoring directories.
Hiba történt a mappák figyelése közben.
Error writing file:
A fájl írása sikertelen:
+Error writing security context:
+A biztonsági címke írása sikertelen:
Error writing to synchronization database:
Hiba történt a szinkronizációs adatbázis írása közben:
Example
@@ -555,7 +563,7 @@ Honlap
Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically.
Mindkét oldal változásainak azonosítása és tárolása adatbázis segítségével. A törlések és ütközések automatikusan észlelődnek.
Idle time between detection of last change and execution of command line in seconds
-
+A tétlenség hossza másodpercekben az utolsó változás észlelése és a parancssor végrehajtása között.
If you like FFS
FFS támogatása
Ignore
@@ -603,7 +611,7 @@ A Shadow Copy a WOW64-en nem támogatott. Kérjük, használja a 64-bites FreeFi
Match case
Kis-/nagybetű egyezés
Minimum Idle Time
-
+Minimális tétleségi idő
Mirror ->>
Tükrözés ->>
Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization.
@@ -659,9 +667,9 @@ Művelet:
Overview
Összefoglaló
Overwriting Symbolic Link %x in %y
-
+A(z) %x symlink fölülírása a(z) %y mappában
Overwriting file %x in %y
-
+A(z) %x fájl fölülírása a(z) %y mappában
Pause
Szünet
Paused
@@ -702,8 +710,6 @@ Reset
Helyreállítás
Right
Jobb oldal
-Run minimized and write status information to a logfile
-Futtatás lekicsinyítve és a státuszinformációk mentése naplófájlba
S&ave configuration...
Beállítások mentés&e...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Sebesség:
Start
Indítás
+Start minimized and write status information to a logfile
+Indítás lekicsinyítve és a státuszinformációk mentése naplófájlba
Start synchronization
Szinkronizáció indítása
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
A szinkronizáció befejeződött, de akadtak hibák!
Synchronization settings
Szinkronizáció beállításai
-Synchronization status
-Szinkronizáció állapota
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Minden .doc, .zip és .exe fájl szinkronizálása a \"temp\" almappában találhatók kivételével.
Synchronize...
@@ -865,7 +871,7 @@ A(z) %x kötetnevet nem tartalmazza a(z) %y fájlnév!
Waiting for all directories to become available...
Várakozás az összes mappa elérhetővé válására...
Waiting while directory is locked (%x)...
-
+Várakozás a mappa zárolásának a feloldására (%x)...
Warning
Figyelem
Warning: Synchronization failed for %x item(s):
diff --git a/BUILD/Languages/italian.lng b/BUILD/Languages/italian.lng
index 6f71202a..e9570526 100644
--- a/BUILD/Languages/italian.lng
+++ b/BUILD/Languages/italian.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Pausa
+&Program
+&Programma
&Quit
&Esci
&Restore
@@ -360,8 +362,8 @@ Elements remaining:
Elementi rimanenti:
Email
Email
-Encode extended time information: %x
-
+Encoding extended time information: %x
+Codifica estesa informazioni orario: %x
Endless loop when traversing directory:
Loop senza fine attraverso le directory:
Error
@@ -402,6 +404,8 @@ Error reading file:
Errore durante la lettura del file:
Error reading from synchronization database:
Errore in lettura dal database di sincronizzione:
+Error reading security context:
+Errore in lettura del contesto di sicurezza:
Error resolving symbolic link:
Errore nella risoluzione di collegamento simbolico:
Error setting directory lock:
@@ -416,6 +420,8 @@ Error when monitoring directories.
Errore durante il monitoraggio directory.
Error writing file:
Errore durante la scrittura del file:
+Error writing security context:
+Errore in scrittura del contesto di sicurezza:
Error writing to synchronization database:
Errore in scrittura sul database di sincronizzazione:
Example
@@ -704,8 +710,6 @@ Reset
Reset
Right
Destra
-Run minimized and write status information to a logfile
-Lancia minimizzato e scrivi informazioni di stato in un log
S&ave configuration...
S&alva la configurazione...
S&witch view
@@ -778,6 +782,8 @@ Speed:
Velocita':
Start
Avvia
+Start minimized and write status information to a logfile
+Lancia minimizzato e scrivi informazioni di stato in un file log
Start synchronization
Avvia sincronizzazione
Statistics
diff --git a/BUILD/Languages/japanese.lng b/BUILD/Languages/japanese.lng
index 443cca07..4a79eba1 100644
--- a/BUILD/Languages/japanese.lng
+++ b/BUILD/Languages/japanese.lng
@@ -76,6 +76,8 @@
&OK
&Pause
一時停止(&P)
+&Program
+プログラム(&P)
&Quit
終了(&Q)
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
残りの要素:
Email
E-メール
+Encoding extended time information: %x
+拡張された時間情報のエンコーディング: %x
Endless loop when traversing directory:
ディレクトリ移動中に無限ループが発生:
Error
@@ -400,6 +404,8 @@ Error reading file:
ファイル読み込みエラー:
Error reading from synchronization database:
同期データベースからの読み込みエラー:
+Error reading security context:
+セキュリティ・コンテキストの読み取りエラー:
Error resolving symbolic link:
シンボリックリンクの解決に失敗:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
ディレクトリの監視エラー
Error writing file:
ファイル書き込みエラー:
+Error writing security context:
+セキュリティ・コンテキストの書き込みエラー:
Error writing to synchronization database:
同期データベースへの書き込みエラー:
Example
@@ -702,8 +710,6 @@ Reset
リセット
Right
右側
-Run minimized and write status information to a logfile
-最小化で起動して、ステータス情報をログに書き込む
S&ave configuration...
構成設定を保存(&A)...
S&witch view
@@ -776,6 +782,8 @@ Speed:
速度:
Start
開始
+Start minimized and write status information to a logfile
+最小化状態で起動して、ステータス情報をログファイルに書き出す
Start synchronization
同期の開始
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
同期処理は、エラーで終了しています!
Synchronization settings
同期処理設定
-Synchronization status
-同期処理: ステータス
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
\"temp\" のサブフォルダを除いて、すべての.doc、.zip、および.exeファイルを同期
Synchronize...
diff --git a/BUILD/Languages/polish.lng b/BUILD/Languages/polish.lng
index a7e9f143..a8120869 100644
--- a/BUILD/Languages/polish.lng
+++ b/BUILD/Languages/polish.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Pauza
+&Program
+
&Quit
&Zamknij
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Pozostałe elementy:
Email
Poczta
+Encoding extended time information: %x
+
Endless loop when traversing directory:
Zapętlenie podczas przeglądania katalogu:
Error
@@ -400,6 +404,8 @@ Error reading file:
Błąd odczytu pliku:
Error reading from synchronization database:
Błąd odczytu z bazy danych synchronizacji:
+Error reading security context:
+
Error resolving symbolic link:
Błąd odczytu dowiązania symbolicznego:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Błąd podczas monitorowania katalogów.
Error writing file:
Błąd zapisu pliku:
+Error writing security context:
+
Error writing to synchronization database:
Błąd zapisu do bazy danych synchronizacji:
Example
@@ -702,8 +710,6 @@ Reset
Resetuj
Right
Prawy
-Run minimized and write status information to a logfile
-Uruchom w trybie ukrytym i zapisz informacje w logu
S&ave configuration...
Z&apisz konfigurację...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Prędkość:
Start
Rozpocznij
+Start minimized and write status information to a logfile
+
Start synchronization
Rozpocznij synchronizację
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Synchronizacja zakończona z błędami.
Synchronization settings
Ustawienia synchronizacji
-Synchronization status
-Status synchronizacji
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Synchronizuj wszystkie pliki .doc, .zip i exe z wyjątkiem folderu \"temp\"
Synchronize...
diff --git a/BUILD/Languages/portuguese.lng b/BUILD/Languages/portuguese.lng
index da9f53b3..d82bc6f7 100644
--- a/BUILD/Languages/portuguese.lng
+++ b/BUILD/Languages/portuguese.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Pausa
+&Program
+&Programa
&Quit
&Sair
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Elementos restantes:
Email
Email
+Encoding extended time information: %x
+A codificar dados temporais extendidos: %x
Endless loop when traversing directory:
Loop infinito ao percorrer directório:
Error
@@ -400,6 +404,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 reading security context:
+Erro ao ler contexto de segurança:
Error resolving symbolic link:
Erro na resolução do link simbólico:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Erro ao monitorizar os directórios.
Error writing file:
Erro de escrita no ficheiro:
+Error writing security context:
+Erro de escrita no contexto de segurança:
Error writing to synchronization database:
Erro na escrita da base de dados de sincronização:
Example
@@ -702,8 +710,6 @@ Reset
Reiniciar
Right
Direita
-Run minimized and write status information to a logfile
-Minimizar o programa e enviar status para um ficheiro log
S&ave configuration...
G&uardar a configuração...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Velocidade:
Start
Iniciar
+Start minimized and write status information to a logfile
+Iniciar minimizado e escrever info de estado para o log
Start synchronization
Iniciar a sincronização
Statistics
diff --git a/BUILD/Languages/portuguese_br.lng b/BUILD/Languages/portuguese_br.lng
index 994028eb..0cb7eb56 100644
--- a/BUILD/Languages/portuguese_br.lng
+++ b/BUILD/Languages/portuguese_br.lng
@@ -76,6 +76,8 @@ C&riar um arquivo batch...
&OK
&Pause
&Pausa
+&Program
+&Programa
&Quit
&Sair
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Elementos faltantes:
Email
Email
+Encoding extended time information: %x
+Codificando informações adicionais de tempo: %x
Endless loop when traversing directory:
Loop infinito quando percorrendo diretório:
Error
@@ -400,6 +404,8 @@ Error reading file:
Erro ao ler arquivo:
Error reading from synchronization database:
Erro ao ler do banco de dados de sincronização:
+Error reading security context:
+Erro ao ler contexto de segurança:
Error resolving symbolic link:
Erro na resolução de link simbólico:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Erro monitorando diretórios.
Error writing file:
Erro ao escrever arquivo:
+Error writing security context:
+Erro ao escrever contexto de segurança:
Error writing to synchronization database:
Erro ao escrever no banco de dados de sincronização:
Example
@@ -702,8 +710,6 @@ Reset
Reiniciar
Right
Direita
-Run minimized and write status information to a logfile
-Executar minimizado e escrever informações de status em um arquivo log
S&ave configuration...
S&alvar configuração...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Velocidade:
Start
Iniciar
+Start minimized and write status information to a logfile
+Iniciar minimizado e escrever informação de status em um arquivo de log
Start synchronization
Iniciar sincronização
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Sincronização finalizada com erros!
Synchronization settings
Parâmetros de sincronização
-Synchronization status
-Estado da sincronização
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Sincronizar todos arquivos .doc, .zip e .exe exceto tudo que estiver na subpasta \"temp\".
Synchronize...
diff --git a/BUILD/Languages/romanian.lng b/BUILD/Languages/romanian.lng
index a5f860af..23b51f86 100644
--- a/BUILD/Languages/romanian.lng
+++ b/BUILD/Languages/romanian.lng
@@ -41,7 +41,7 @@
&Cancel
&Anulează
&Check for new version
-&Caută Versiune Nouă
+&Caută Versiune Nouă a Softului
&Content
&Conținut
&Create batch job...
@@ -69,13 +69,15 @@
&Load configuration...
&Deschide Configurația...
&New
-&Nouă
+Configurație &Nouă
&No
&Nu
&OK
&OK
&Pause
&Pauzează
+&Program
+&Program
&Quit
&Ieși
&Restore
@@ -101,11 +103,11 @@
- conflict (same date, different size)
- conflict (aceeași dată, mărime diferită)
- different
-- diferit
+- diferite
- directory part only
- doar dosarele
- equal
-- identic
+- identice
- exists left only
- există doar în stînga
- exists right only
@@ -115,11 +117,11 @@
- left
- stînga
- left newer
-- cel mai nou e în stînga
+- cea mai nouă e în stînga
- right
- dreapta
- right newer
-- cel mai nou e în dreapta
+- cea mai nouă e în dreapta
/sec
/sec
1 directory
@@ -147,7 +149,7 @@
<Directory>
<Dosar>
<Last session>
-<Ultima sesiune>
+<Ultima Sesiune>
<Symlink>
<Simlegătură>
<multiple selection>
@@ -275,7 +277,7 @@ Copiază în Cliplanșetă\tCTRL+C
Copying new Symbolic Link %x to %y
Copiez noua Legătură Simbolică %x în %y
Copying new file %x to %y
-Copiez noua filă %x în %y
+Copiez fila nouă %x în %y
Could not determine volume name for file:
Nu pot determina numele volumului pentru fila:
Could not initialize directory monitoring:
@@ -360,6 +362,8 @@ Elements remaining:
Elemente Rămase:
Email
E-mail
+Encoding extended time information: %x
+Codarea informațiilor timpului extins: %x
Endless loop when traversing directory:
Buclă infinită la parcurgerea dosarului:
Error
@@ -400,6 +404,8 @@ Error reading file:
Eroare la citirea filei:
Error reading from synchronization database:
Eroare la citirea din baza de date a sincronizării:
+Error reading security context:
+Eroare la citirea contextului de securitate:
Error resolving symbolic link:
Eroare la rezolvarea legăturii simbolice:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Eroare la monitorizarea dosarelor.
Error writing file:
Eroare la scrierea filei:
+Error writing security context:
+Eroare la scrierea contextului de securitate:
Error writing to synchronization database:
Eroare la scrierea în baza de date a sincronizării:
Example
@@ -441,13 +449,13 @@ Fila %x are o dată nevalidă !
File already exists. Overwrite?
Fila există deja. Dorești s-o suprascrii?
File content
-Conținutul Filei
+Conținutul Filelor
File does not exist:
Fila nu există:
File list exported!
Lista de file a fost exportată!
File size and date
-Mărimea și Data Filei
+Mărimea și Data Filelor
Filename
Numele Filei
Files %x have the same date but a different size!
@@ -575,7 +583,7 @@ Incluse: *.doc;*.zip;*.exe\nExcluse: \\chestii\\temp\\*
Incompatible synchronization database format:
Format incompatibil al bazei de date a sincronizării:
Info
-Info
+Informații
Information
Informații
Initial synchronization:
@@ -702,8 +710,6 @@ Reset
Resetează
Right
Dreapta
-Run minimized and write status information to a logfile
-Rulează minimizat și scrie informațiile de stare într-un jurnal
S&ave configuration...
S&alvează Configurația...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Viteză:
Start
Pornește
+Start minimized and write status information to a logfile
+Pornește minimizat și scrie informațiile de stare într-un jurnal
Start synchronization
Pornește Sincronizarea
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Sincronizare terminată cu erori!
Synchronization settings
Setările Sincronizării
-Synchronization status
-Starea Sincronizării
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Sincronizează filele .doc, .zip și .exe, cu excepția celor din dosarul \"temp\".
Synchronize...
diff --git a/BUILD/Languages/russian.lng b/BUILD/Languages/russian.lng
index 99c85a1c..6ff42818 100644
--- a/BUILD/Languages/russian.lng
+++ b/BUILD/Languages/russian.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Пауза
+&Program
+&Программа
&Quit
&Выход
&Restore
@@ -360,8 +362,8 @@ Elements remaining:
Элементов осталось:
Email
Почта
-Encode extended time information: %x
-
+Encoding extended time information: %x
+Кодирование расширенной информации о времени: %x
Endless loop when traversing directory:
Зацикливание при встрече пересекающихся путей:
Error
@@ -402,6 +404,8 @@ Error reading file:
Ошибка при чтении файла:
Error reading from synchronization database:
Ошибка при чтении из базы данных синхронизации:
+Error reading security context:
+Ошибка при чтении контекста безобасности:
Error resolving symbolic link:
Ошибка при решении символической ссылки:
Error setting directory lock:
@@ -416,6 +420,8 @@ Error when monitoring directories.
Ошибка при мониторинге папок.
Error writing file:
Ошибка при записи файла:
+Error writing security context:
+Ошибка при записи контекста безобасности:
Error writing to synchronization database:
Ошибка при записи в базу данных синхронизации:
Example
@@ -677,7 +683,7 @@ Press \"Switch\" to open FreeFileSync GUI mode.
Processing folder pair:
Обработка пары папок:
Published under the GNU General Public License:
-Издается под GNU General Public License:
+Издается под лицензией GNU General Public License:
Question
Вопрос
Quit
@@ -704,8 +710,6 @@ Reset
Сбросить
Right
Справа
-Run minimized and write status information to a logfile
-Запустить свернутым и писать информацию по статусу в лог-файл
S&ave configuration...
Сохранить конфигурацию...
S&witch view
@@ -778,6 +782,8 @@ Speed:
Скорость:
Start
Старт
+Start minimized and write status information to a logfile
+Запускать свернутым и писать информацию о состоянии в лог-файл
Start synchronization
Начать синхронизацию
Statistics
@@ -841,7 +847,7 @@ Transfer file and directory permissions\n(Requires Administrator rights)
Unable to connect to sourceforge.net!
Невозможно соединиться с sourceforge.net!
Unable to create logfile!
-Невозможно создать лог!
+Невозможно создать лог-файл!
Unresolved conflicts existing!
Существуют нерешенные конфликты
Update ->
diff --git a/BUILD/Languages/slovenian.lng b/BUILD/Languages/slovenian.lng
index 4fc220d8..84c725e8 100644
--- a/BUILD/Languages/slovenian.lng
+++ b/BUILD/Languages/slovenian.lng
@@ -76,6 +76,8 @@ Na&loži konfiguracijo...
&V redu
&Pause
&Premor
+&Program
+&Program
&Quit
&Zapri
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Preostalih elementov:
Email
Email
+Encoding extended time information: %x
+Podrobne informacije o času enkodiranja: %x
Endless loop when traversing directory:
Neskončna zanka pri prehodu imenika:
Error
@@ -400,6 +404,8 @@ Error reading file:
Napaka pri branju datoteke:
Error reading from synchronization database:
Napaka pri branju iz sinhronizacijske podatkovne baze:
+Error reading security context:
+Napaka pri branju varnostne skladnosti:
Error resolving symbolic link:
Napaka pri razreševanju simbolične povezave:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Napaka pri nadzorovanju imenikov.
Error writing file:
Napaka pri pisanju datoteke:
+Error writing security context:
+Napaka pri pisanju varnostne skladnosti:
Error writing to synchronization database:
Napaka pri pisanju v sinhronizacijsko podatkovno bazo:
Example
@@ -702,8 +710,6 @@ Reset
Ponastavi
Right
Desno
-Run minimized and write status information to a logfile
-Poženi minimizirano in zapisuj statusne informacije v dnevniško datoteko
S&ave configuration...
Shr&ani konfiguracijo...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Hitrost:
Start
Začni
+Start minimized and write status information to a logfile
+Zaženi pomanjšano in piši statusne informacije v datoteko za beleženje
Start synchronization
Začni sinhronizacijo
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
Sinhronizacija se je končala z napakami!
Synchronization settings
Nastavitve sinhronizacije
-Synchronization status
-Status sinhronizacije
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
Sinhroniziraj vse .doc, .zip in .exe datoteke, razen iz podmape \"temp\".
Synchronize...
diff --git a/BUILD/Languages/spanish.lng b/BUILD/Languages/spanish.lng
index 9243158f..15a25781 100644
--- a/BUILD/Languages/spanish.lng
+++ b/BUILD/Languages/spanish.lng
@@ -76,6 +76,8 @@
&OK
&Pause
&Pausa
+&Program
+&Programa
&Quit
&Salir
&Restore
@@ -360,6 +362,8 @@ Elements remaining:
Elementos restantes:
Email
Correo electrónico
+Encoding extended time information: %x
+Información temporal extendida de la codificación: %x
Endless loop when traversing directory:
Bucle infinito al buscar en el directorio:
Error
@@ -400,6 +404,8 @@ Error reading file:
Error al leer archivo:
Error reading from synchronization database:
Error al leer de la base de datos de sincronización:
+Error reading security context:
+Error al leer en contexto de seguridad:
Error resolving symbolic link:
Error al resolver enlace simbólico:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Error al visualizar los directorios.
Error writing file:
Error al escribir archivo:
+Error writing security context:
+Error al escribir en contexto de seguridad:
Error writing to synchronization database:
Error al escribir en la base de datos de sincronización:
Example
@@ -702,8 +710,6 @@ Reset
Reiniciar
Right
Derecha
-Run minimized and write status information to a logfile
-Ejecución minimizada y escritura de información del estado en un archivo de registro
S&ave configuration...
G&uardar configuración...
S&witch view
@@ -776,6 +782,8 @@ Speed:
Velocidad:
Start
Iniciar
+Start minimized and write status information to a logfile
+Iniciar minimizado y escribir información de estado en un registro
Start synchronization
Iniciar sincronización
Statistics
@@ -802,8 +810,6 @@ Synchronization completed with errors!
¡Sincronización completada con errores!
Synchronization settings
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 y .exe excepto el contenido de la subcarpeta \"temp\".
Synchronize...
diff --git a/BUILD/Languages/swedish.lng b/BUILD/Languages/swedish.lng
index 6462f5c3..93f0fbdb 100644
--- a/BUILD/Languages/swedish.lng
+++ b/BUILD/Languages/swedish.lng
@@ -76,8 +76,10 @@
&OK
&Pause
&Paus
+&Program
+&Program
&Quit
-&Sluta
+&Avsluta
&Restore
&Återställ
&Retry
@@ -231,7 +233,7 @@ Jämförelseresultat
Comparison settings
Jämförelseinställningar
Completed
-Klar
+Slutförd
Configuration
Inställningar
Configuration loaded!
@@ -360,6 +362,8 @@ Elements remaining:
Återstående poster:
Email
e-post
+Encoding extended time information: %x
+Kodar utökad tidsinformation: %x
Endless loop when traversing directory:
Oändlig loop vid accessförsök på katalog:
Error
@@ -400,6 +404,8 @@ Error reading file:
Kan inte läsa fil:
Error reading from synchronization database:
Kan inte läsa från databasen:
+Error reading security context:
+Kan inte läsa säkerhetskontext:
Error resolving symbolic link:
Kan inte tyda symbolisk länk:
Error setting directory lock:
@@ -414,6 +420,8 @@ Error when monitoring directories.
Fel vid övervakning av kataloger.
Error writing file:
Kan inte skriva fil:
+Error writing security context:
+Kan inte skriva säkerhetskontext:
Error writing to synchronization database:
Kan inte skriva till databas:
Example
@@ -702,8 +710,6 @@ 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
@@ -776,6 +782,8 @@ Speed:
Hastighet:
Start
Start
+Start minimized and write status information to a logfile
+Starta minimerad och skriv statusinformation till en loggfil
Start synchronization
Starta synkronisering
Statistics
@@ -802,8 +810,6 @@ 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...
diff --git a/BUILD/Languages/turkish.lng b/BUILD/Languages/turkish.lng
index ad8d7c19..9b5d89f9 100644
--- a/BUILD/Languages/turkish.lng
+++ b/BUILD/Languages/turkish.lng
@@ -1,61 +1,61 @@
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
%x / %y objects deleted successfully
-%x / %y obje başarıyla silindi
+%y ögeden %x tanesi sorunsuz silindi
%x Byte
-
+%x Bayt
+%x GB
%x GB
-
%x MB
-
+%x MB
+%x PB
%x PB
-
%x TB
-
+%x TB
%x day(s)
-
+%x gün
%x directories
-%x dizin
+%x klasör
%x files
%x dosya
%x hour(s)
-
+%x saat
+%x kB
%x kB
-
%x min
-
+%x dakika
%x of %y rows in view
-%y satırdan %x'i görüntüleniyor
+%y satırın %x tanesi görüntüleniyor
%x of 1 row in view
-1 satırdan %x'i görüntüleniyor
+1 satırın %x tanesi görüntüleniyor
%x sec
-
+%x saniye
+%x%
%x%
-
&Abort
-Va&zgeç
+V&azgeç
&About...
-&Hakkında...
+H&akkında...
&Advanced
&Gelişmiş
&Cancel
-&İptal
+İ&ptal
&Check for new version
-&Yeni sürüm kontrolü yap
+Yeni &sürüm denetimi
&Content
-
+İçe&rik
&Create batch job...
-&Komut (batch) görevi oluştur...
+&Toplu komut işi oluştur...
&Default
&Varsayılan
&Exit
Çı&kış
&Export file list...
-Dosya list&esini dışarı aktar...
+Dosya list&esini ver...
&File
&Dosya
&Find next
-
+&Sonrakini bul
&Global settings...
&Genel ayarlar...
&Help
@@ -63,21 +63,23 @@ Dosya list&esini dışarı aktar...
&Ignore
&Yoksay
&Language
-&Dil
+Di&l
&Load
-&Yükle
+Yük&le
&Load configuration...
-Konfigürasyon &yükle...
+Yapılandırmayı a&l...
&New
-&Yeni
+Ye&ni
&No
&Hayır
&OK
&Tamam
&Pause
&Duraklat
+&Program
+
&Quit
-&Çık
+Çı&k
&Restore
Ge&ri yükle
&Retry
@@ -85,33 +87,33 @@ Ge&ri yükle
&Save
&Kaydet
&Switch
-
+&Değiştir
&Yes
&Evet
(Build: %x)
-
+(Yapım: %x)
(Requires an Internet connection!)
-
+(İnternet bağlantısı gereklidir!)
- Other side's counterpart to %dir
-- %dir'e diğer tarafın karşılığı
+- %dir klasörünün diğer taraftaki karşılığı
- Other side's counterpart to %name
-- %name'e diğer tarafın karşılığı
+- %name diğer taraftaki karşılığı
- conflict
- tutarsızlık
- conflict (same date, different size)
-- tutarsızlık (aynı tarih, farklı ebat)
+- tutarsızlık (aynı tarih, farklı boyut)
- different
- farklı
- directory part only
-- sadece kısmi dizin
+- Yalnız klasör kısmı
- equal
- eşit
- exists left only
-- sadece solda olan
+- yalnız solda olan
- exists right only
-- sadece sağda olan
+- yalnız sağda olan
- full file or directory name
-- tam dosya veya dizin adı
+- tam dosya ya da klasör adı
- left
- sol
- left newer
@@ -123,41 +125,41 @@ Ge&ri yükle
/sec
/san
1 directory
-1 dizin
+1 klasör
1 file
1 dosya
1. &Compare
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. Bağıl dosya ya da klasör adlarını ';' ile ayırarak ya da ayrı satırlar şeklinde yazın.
1. Select directories to monitor.
-
+1. İzlenecek klasörleri seçin.
2. &Synchronize...
-2. &Senkronize et...
+2. &Eşleştir...
2. Enter a command line.
-
+2. Bir komut satırı yazın.
2. Use wildcard characters '*' and '?'.
-2. Joker karakter olan '*' ve '?' kullan.
+2. '*' ve '?' jokerleri kullanılabilsin.
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. Ana listedeki dosyaları sağ fare tuşu menüsüyle doğrudan dışla.
3. Press 'Start'.
-
+3. 'Başlat'a Tıklayın.
<Automatic>
-<Otomatik>
+<Kendiliğinden>
<Directory>
-<Dizin>
+<Klasör>
<Last session>
<Önceki oturum>
<Symlink>
-
+<Symlink>
<multiple selection>
-<Çoklu seçim>
+<çoklu seçim>
A newer version of FreeFileSync is available:
-FreeFileSync'in yeni bir sürümü var:
+FreeFileSync programının yeni bir sürümü yayınlanmış:
Abort requested: Waiting for current operation to finish...
-Vazgeçildi: Devam eden işlemin bitmesi bekleniyor...
+Vazgeçildi: Yürürlükteki işlemin bitmesi bekleniyor...
Abort synchronization immediately
-
+Eşleştirmeyi hemen bırak
Aborted
Vazgeçildi
About
@@ -169,63 +171,63 @@ Klasör ekle
Add folder pair
Klasör çifti ekle
All directories in sync!
-
+Tüm klasörler eş!
An exception occurred!
Olağan dışı bir durum oluştu!
As a result the files are separated into the following categories:
-Sonuç olarak dosyalar takibeden katagorilere göre ayrıldı:
+Sonuç olarak dosyalar şu kategorilere göre ayrılır:
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:
-İ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:
+Bu seçenekte, yalnızca aynı ada sahip iki dosyanın içeriği aynıysa eşit olarak kabul edilirler. Bu seçenek yedekleme işlemlerinden daha çok, uyuşma denetimi için yararlıdır. Bu yüzden dosya tarihleri hiç bir zaman dikkate alınmaz.\n\nBu seçenekle karşılaştırma yapıldığında, şu karar ağacı işlenir:
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.
+Kendiliğinden eşleştirme için bir toplu komut dosyası oluşturabilirsiniz. Programı toplu komut kipinde başlatmak için, komut dosyasını FreeFileSync çalışan dosyasına parametre olarak şu şekilde ekleyerek çalıştırın: FreeFileSync.exe <Komut Dosyası Adı>. Ayrıca bu komut dosyasını işletim sistemindeki görev zamanlayıcı ile istediğiniz zamanlarda da çalıştırabilirsiniz.
At least one directory input field is empty.
-
+En az bir klasör giriş alanı boş.
Auto-adjust columns
-Kolonları otomatik olarak hizala
+Sütunları kendiliğinden hizala
Batch execution
-Komut (batch) çalıştırılması
+Toplu komut yürütme
Batch file created successfully!
-Komut (batch) dosyası başarıyla oluşturuldu!
+Toplu komut dosyası sorunsuz oluşturuldu!
Batch job
-Komut (batch) görevi
+Toplu komut işi
Big thanks for localizing FreeFileSync goes out to:
-FreeFileSync'in çevirisinden dolayı çok teşekkürler:
+FreeFileSync çevirisinden dolayı çok teşekkürler:
Both sides have changed since last synchronization!
-En son senkronizasyondan sonra her iki tarafta deðiþmiþ bulunuyor!
+Son eşleştirmeden bu yana iki yanın içeriği de değişmiş!
Browse
-Araştır
+Gözat
Browse directory
-
+Klasöre gözat
Cannot determine sync-direction:
-
+Eşleştirme yönü belirlenemedi:
Cannot find %x
-
+%x bulunamadı
Category
Kategori
Clear filter settings
-
+Süzgeç ayarlarını temizle
Comma separated list
Virgül ile ayrılmış liste
Command line
Komut satırı
Command line is empty!
-
+Komut satırı boş!
Compare
Karşılaştır
Compare both sides
-İki tarafıda karşılaştır
+İki tarafı da karşılaştır
Compare by \"File content\"
-\"Dosya içeriği\" ile karşılaştır
+\"Dosya içeriği\"ne göre karşılaştırma
Compare by \"File size and date\"
-\"Dosya ebadı ve tarihi\" ile karşılaştır
+\"Dosya boyutu ve tarihi\"ne göre karşılaştırma
Compare by...
-ile karşılaştır...
+Karşılaştırmayı yaparken şunu kullan:
Comparing content of files %x
-%x dosyasının içeriği karşılaştırılıyor
+%x dosyalarının içeriği karşılaştırılıyor
Comparing content...
İçerik karşılaştırılıyor...
Comparing files by content failed.
-Dosyaların içerik ile karşılaştırılması başarısız oldu.
+Dosyaların içerikleri karşılaştırılamadı.
Comparison Result
Karşılaştırma sonucu
Comparison settings
@@ -233,277 +235,283 @@ Karşılaştırma ayarları
Completed
Tamamlandı
Configuration
-Konfigürasyon
+Yapılandırma
Configuration loaded!
-Konfigürasyon yüklendi!
+Yapılandırma yüklendi!
Configuration overview:
-Konfigürasyon özeti:
+Yapılandırma özeti:
Configuration saved!
-Konfigürasyon kaydedildi!
+Yapılandırma kaydedildi!
Configure filter
-Filtrelemeyi ayarla
+Yapılandırma süzgeci
Configure your own synchronization rules.
-Kendi senkronizasyon kurallarınızı ayarlayın.
+Buradan kendi eşleştirme kurallarınızı yapılandırabilirsiniz.
Confirm
Doğrula
Conflict detected:
-Tutarsızlık saptandı:
+Çelişki bulundu:
Conflicts/files that cannot be categorized
-Katagorize edilemeyen tutarsızlıklar/dosyalar
+Kategorize edilemeyen tutarsızlıklar/dosyalar
Continue
Devam et
Conversion error:
Dönüştürme hatası:
Copy filesystem permissions
-
+Dosya sistemi izinlerini de kopyala
Copy from left to right
Soldan sağa kopyala
Copy from left to right overwriting
-Soldan sağa üzerine yazmaya izin vererek kopyala
+Soldan sağa üzerine yazarak kopyala
Copy from right to left
Sağdan sola kopyala
Copy from right to left overwriting
-Sağdan sola üzerine yazmaya izin vererek kopyala
+Sağdan sola üzerine yazarak kopyala
Copy locked files
-
+Kilitli dosyaları da kopyala
Copy new or updated files to right folder.
-Yeni veya güncellenmiş dosyaları sağdaki klasöre kopyala.
+Soldan sağa yalnız yeni ya da güncellenmiş dosyalar kopyalanır.
Copy shared or locked files using Volume Shadow Copy Service\n(Requires Administrator rights)
-
+Paylaşılmış ya da kilitli dosyaları Birim Gölge Kopya Hizmetini\n kullanarak kopyala (Yönetici izinlerine gerek duyar)
Copy to clipboard\tCTRL+C
-Hafızaya kopyala\tCTRL+C
+Panoya kopyala\tCTRL+C
Copying new Symbolic Link %x to %y
-
+Yeni sembolik bağlantı %x %y üzerine kopyalanıyor
Copying new file %x to %y
-
+Yeni dosya %x %y üzerine kopyalanıyor
Could not determine volume name for file:
-Belirtilen dosya için birim adı belirlenemedi:
+Şu dosya için birim adı belirlenemedi:
Could not initialize directory monitoring:
-Dizin izlemesi başlatılamadı:
+Klasör izlemesi başlatılamadı:
Could not load a required DLL:
-
+Gerekli bir DLL yüklenemedi:
Could not read values for the following XML nodes:
-Takibeden XML başlığındaki değerler okunamadı:
+Şu XML düğümlerindeki değerler okunamadı:
Create a batch job
-Komut (batch) görevi oluştur
+Toplu komut işi oluştur
Creating folder %x
%x klasörü oluşturuluyor
Custom
Özel
Customize columns
-Kolonları özelleştir
+Sütunları özelleştir
Customize...
Özelleştir...
D-Click
D-Tuşu
DECISION TREE
-Karar Şeması
+KARAR AĞACI
Data verification error: Source and target file have different content!
Veri doğrulama hatası: Kaynak ve hedef dosyası içeriği farklı!
Date
Tarih
Delete files/folders existing on left side only
-Sadece sol tarafta olan dosyaları/klasörleri sil
+Yalnız sol tarafta olan dosyaları/klasörleri sil
Delete files/folders existing on right side only
-Sadece sağ tarafta olan dosyaları/klasörleri sil
+Yalnız sağ tarafta olan dosyaları/klasörleri sil
Delete files\tDEL
Dosyaları sil\tDEL
Delete on both sides
-Her iki taraftakini sil
+Her iki yandakini de sil
Delete on both sides even if the file is selected on one side only
-Dosya sadece bir tarafta seçili olsa bile her iki taraftakini de sil
+Dosya yalnız bir tarafta seçili olsa bile her iki yandakini de sil
Delete or overwrite files permanently
-Kalıcı olarak üzerine yaz veya sil
+Kalıcı olarak üzerine yaz ya da sil
Delete permanently
Kalıcı olarak sil
Deleting Symbolic Link %x
-
+%z sembolik bağlantısı siliniyor
Deleting file %x
%x dosyası siliniyor
Deleting folder %x
%x klasörü siliniyor
Deletion handling
-Silme işleminin idaresi
+Silme eyleminde:
Description
Açıklama
Direct
-
+Doğrudan
Directories are dependent! Be careful when setting up synchronization rules:
-Dizinler bağımlı! Senkronizasyon kurallarını koyarken dikkatli olun:
+Klasörler bağımlı! Eşleştirme kurallarını koyarken dikkatli olun:
Directories to watch
-İzlenecek dizinler
+İzlenecek klasörler
Directory
-Dizin
+Klasör
Directory does not exist:
-Dizin mevcut değil:
+Klasör bulunamadı:
Do not show this dialog again
-Bu iletiyi tekrar gösterme
+Bu iletiyi yeniden gösterme
Do nothing
Hiçbir şey yapma
Do you really want to delete the following object(s)?
-Gerçekten şu objeleri silmek istiyormusunuz?
+Gerçekten şu ögeleri silmek istiyor musunuz?
Do you really want to move the following object(s) to the Recycle Bin?
-Gerçekten şu objeleri geri dönüşüm kutusuna taşımak istiyormusunuz?
+Gerçekten şu ögeleri Geri Dönüşüm Kutusu'na atmak istiyor musunuz?
Do you want FreeFileSync to automatically check for updates every week?
-Her hafta FreeFileSync'in güncellemeleri denetlemesini istermisiniz?
+FreeFileSync güncellemelerinin her hafta denetlenmesini ister misiniz?
Donate with PayPal
PayPal ile bağış yapın
Download now?
-Şimdi indirilsinmi?
+Şimdi indir?
Drag && drop
-Sürükle bırak
+Klasör ya da dosyaları sürükleyip buraya bırakabilirsiniz
Elements found:
-
+Bulunan bileşenler:
Elements processed:
-
+İşlenen bileşenler:
Elements remaining:
-
+Kalan bileşenler:
Email
-Eposta
+E-posta
+Encoding extended time information: %x
+
Endless loop when traversing directory:
-Dizin işleminde sonsuz döngü:
+Klasörlerde dolaşırken sonsuz döngü:
Error
Hata
Error changing modification time:
Değişiklik tarihini değiştirirken hata:
Error copying file permissions:
-
+Dosya izinleri kopyalanırken hata:
Error copying file:
-Dosya kopyalarken hata:
+Dosya kopyalanırken hata:
Error copying locked file %x!
-Kilitli dosya %x'i kopyalarken hata!
+Kilitli dosya %x kopyalanırken hata!
Error copying symbolic link:
-
+Sembolik bağlantı kopyalanırken hata:
Error creating directory:
-Dizin oluştururken hata:
+Klasör oluşturulurken hata:
Error deleting directory:
-Dizin silerken hata:
+Klasör silinirken hata:
Error deleting file:
-Dosya silerken hata:
+Dosya silinirken hata:
Error handling
-Hataları ele alma
+Hata olduğunda:
Error loading library function:
-Kütüphaneden fonksiyon yüklerken hata:
+Kütüphane işlevi yüklenirken hata:
Error moving directory:
-Dizin taşırken hata:
+Klasör taşınırken hata:
Error moving file:
-Dosya taşırken hata:
+Dosya taşınırken hata:
Error moving to Recycle Bin:
-Geri dönüşüm kutusuna taşırken hata:
+Geri Dönüşüm Kutusu'na atılırken hata:
Error opening file:
-Dosya açarken hata:
+Dosya açılırken hata:
Error parsing configuration file:
-Konfigürasyon dosyasını çözümlerken hata:
+Yapılandırma dosyası çözümlenirken hata:
Error reading file attributes:
-Dosya özniteliklerini okurken hata:
+Dosya öznitelikleri okunurken hata:
Error reading file:
-Dosyayı okurken hata:
+Dosya okunurken hata:
Error reading from synchronization database:
-Senkronizasyon veri tabanýndan okuma hatasý:
+Eşleştirme veri tabanı okunurken hata:
+Error reading security context:
+
Error resolving symbolic link:
-Sembolik bağlantıyı çözümlerken hata:
+Sembolik bağlantı çözümlenirken hata:
Error setting directory lock:
-
+Klasör kilitlenirken hata:
Error setting privilege:
-
+İzinler ayarlanırken hata:
Error starting Volume Shadow Copy Service!
-'Volume shadow copy' servisini başlatırken hata!
+Birim Gölge Kopya hizmeti başlatılırken hata!
Error traversing directory:
-Dizini okurken hata:
+Klasörde dolaşırken hata:
Error when monitoring directories.
-Dizinler izlenirken hata.
+Klasörler izlenirken hata.
Error writing file:
-Dosya yazarken hata:
+Dosya yazılırken hata:
+Error writing security context:
+
Error writing to synchronization database:
-Senkronizasyon veri tabanýna yazma hatasý:
+Eşleştirme veri tabanına yazılırken hata:
Example
Örnek
Exclude
-Dışarda bırak
+Dışlanacaklar:
Exclude all rows
-
+Tüm satırları dışla
Exclude temporarily
-Geçici olarak dışarda bırak
+Geçici olarak dışla
Exclude via filter:
-Filtrelemeyle dışarda bırak:
+Süzerek dışarda bırak:
Exit instantly
-
+Hemen çık
Extension
-
+Uzantı
External applications
-Harici uygulamalar
+Dış uygulamalar
Fatal Error
-
+Ölümcül Hata
Feedback and suggestions are welcome at:
-Geri bildirim ve öneriler için:
+Geri bildirim ve önerileriniz için:
File %x has an invalid date!
-%x dosyası geçersiz bir tarihe sahip!
+%x dosyasının tarihi geçersiz!
File already exists. Overwrite?
-Dosya zaten mevcut. Üzerine yazılsınmı?
+Dosya zaten var. Üzerine yazılsın mı?
File content
Dosya içeriği
File does not exist:
-Dosya mevcut değil:
+Dosya bulunamadı:
File list exported!
-Dosya listesi karışmış!
+Dosya listesi verilmiş!
File size and date
-Dosya ebatı ve tarihi
+Dosya boyutu ve tarihi
Filename
Dosya adı
Files %x have the same date but a different size!
-%x dosyalarının tarihleri aynı fakat ebatları farklı!
+%x dosyalarının tarihleri aynı fakat boyutları farklı!
Files are found equal if\n - file content\nis the same
-\n - dosya içeriği\naynı ise dosyalar eşit kabul edilir
+Eşit dosyaları bulurken\n - dosya içeriği\naynı olanlara bakılır
Files are found equal if\n - filesize\n - last write time and date\nare the same
-\n - dosya ebadı\n - son değişiklik tarihi\naynı ise dosyalar eşit kabul edilir
+Eşit dosyaları bulurken\n - dosya boyutu\n - son yazma zamanı ve tarihi\naynı olanlara bakılır
Files that are equal on both sides
-Her iki tarafta eşit olan dosyalar
+Her iki yanda da eşit olan dosyalar
Files that exist on both sides, left one is newer
-Her iki tarafta mevcut olup solda olanı yeni olan dosyalar
+Her iki yanda da varolup, solda daha yeni olan dosyalar
Files that exist on both sides, right one is newer
-Her iki tarafta mevcut olup sağda olanı yeni olan dosyalar
+Her iki yanda da varolup, sağda daha yeni olan dosyalar
Files that have different content
-
+Farklı içeriğe sahip dosyalar
Files/folders that exist on left side only
-Sadece sol tarafta mevcut olan dosyalar/klasörler
+Yalnız sol yanda bulunan dosyalar/klasörler
Files/folders that exist on right side only
-Sadece sağ tarafta mevcut olan dosyalar/klasörler
+Yalnız sağ yanda bulunan dosyalar/klasörler
Filter files
-Fltre dosyaları
+Dosya süzgeci
Filter is active
-
+Etkin süzgeç
Filter settings have changed!
-
+Süzgeç ayarları değiştirildi!
Filter view
-Filtre görünümü
+Görünümü süz
Filter: All pairs
-
+Süzgeç: Tüm çiftler
Filter: Single pair
-
+Süzgeç: Tek çift
Find
-
+Bul
Find what:
-
+Aranacak:
Folder Comparison and Synchronization
-Klasör Karşılaştırması ve Senkronizasyonu
+Klasör Karşılaştırma ve Eşleştirme
Follow
-
+İzle
Free disk space available:
-Boşta kullanılabilir disk alanı:
+Kullanılabilir disk alanı:
FreeFileSync Batch Job
-FreeFileSync Komut (Batch) Görevi
+FreeFileSync Toplu Komut İşi
FreeFileSync at Sourceforge
-Sourceforge'da FreeFileSync
+Sourceforge sitesinde FreeFileSync
FreeFileSync batch file
-FreeFileSync komut (batch) dosyası
+FreeFileSync toplu komut dosyası
FreeFileSync configuration
-FreeFileSync konfigürasyonu
+FreeFileSync yapılandırması
FreeFileSync is up to date!
FreeFileSync güncel!
Full path
-Tam dizin
+Tam yol
Generating database...
-Veri tabaný yaratýlýyor...
+Veri tabanı oluşturuluyor...
Generating file list...
Dosya listesi oluşturuluyor...
Global settings
@@ -511,225 +519,223 @@ Genel ayarlar
Help
Yardım
Hidden dialogs:
-Gösterilmemiş iletiler:
+Gizlenmiş iletiler:
Hide all error and warning messages
-Hata ve uyarı mesajlarını gösterme
+Tüm hata ve uyarı iletilerini gizler
Hide conflicts
-Tutarsızlıkları gösterme
+Çelişkileri gizle
Hide excluded items
-
+Dışlanan ögeleri gizle
Hide files that are different
-Farklı olan dosyaları gösterme
+Farklı olan dosyaları gizle
Hide files that are equal
-Eşit olan dosyaları gösterme
+Eşit olan dosyaları gizle
Hide files that are newer on left
-Solda daha yeni olan dosyaları gösterme
+Solda daha yeni olan dosyaları gizle
Hide files that are newer on right
-Sağda daha yeni olan dosyaları gösterme
+Sağda daha yeni olan dosyaları gizle
Hide files that exist on left side only
-Sadece sol tarafta mevcut olan dosyaları gösterme
+Yalnız sol yanda bulunan dosyaları gizle
Hide files that exist on right side only
-Sadece sağ tarafta mevcut olan dosyaları gösterme
+Yalnız sağ yanda bulunan dosyaları gizle
Hide files that will be created on the left side
-Sol tarafta yaratılacak dosyaları gösterme
+Sol yanda oluşturulacak dosyaları gizle
Hide files that will be created on the right side
-Sağ tarafta yaratılacak dosyaları gösterme
+Sağ yanda oluşturulacak dosyaları gizle
Hide files that will be deleted on the left side
-Sol tarafta silinecek dosyaları gösterme
+Sol yanda silinecek dosyaları gizle
Hide files that will be deleted on the right side
-Sağ tarafta silinecek dosyaları gösterme
+Sağ yanda silinecek dosyaları gizle
Hide files that will be overwritten on left side
-Sol tarafta üzerine yazılacak dosyaları gösterme
+Sol yanda üzerine yazılacak dosyaları gizle
Hide files that will be overwritten on right side
-Sağ tarafta üzerine yazılacak dosyaları gösterme
+Sağ yanda üzerine yazılacak dosyaları gizle
Hide files that won't be copied
-Kopyalanmayacak dosyaları gösterme
+Kopyalanmayacak dosyaları gizle
Hide filtered or temporarily excluded files
-
+Süzülmüş ya da geçici olarak dışlanmış dosyaları gizle
Hide further error messages during the current process
-Devam eden işlem süresince daha fazla hata mesajı gösterme
+Yürürlükteki işlem boyunca başka hata iletisi gösterme
Hints:
İpuçları:
Homepage
Ana sayfa
Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically.
-
+Bir veritabanı kullanarak iki yandaki değişiklikleri belirler ve günceller. Silinme ve tutarsızlıklar kendiliğinden algılanır.
Idle time between detection of last change and execution of command line in seconds
-
+Son değişikliğin algılanması ile komut satırının yürütülmesi arasındaki bekleme süresi
If you like FFS
-Eğer FFS’i sevdiyseniz
+FFS’i beğendiyseniz
Ignore
-
+Yoksay
Ignore errors
Hataları yoksay
Ignore subsequent errors
-Takibeden hataları yoksay
+Sonraki hataları yoksay
Include
-Dahil et
+Katılacaklar:
Include all rows
-
+Tüm satırları kat
Include temporarily
-Geçici olarak dahil et
+Geçici olarak kat
Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*
-Dahil et: *.doc;*.zip;*.exe\nHariç tut: \\stuff\\temp\\*
+Kat: *.doc;*.zip;*.exe\nDışla: \\stuff\\temp\\*
Incompatible synchronization database format:
-Uyumsuz senkronizasyon veritabaný formatý:
+Uyumsuz eşleştirme veritabanı biçimi:
Info
Bilgi
Information
Bilgi
Initial synchronization:
-Baþlangýç senkronizasyonu:
+Başlangıç eşleştirmesi:
Integrate external applications into context menu. The following macros are available:
-Harici uygulamaları içerik menüsüne ekle. Şu makro’lar temin edilebilir:
+Dış uygulamaları sağ tuş menüsüne ekle. Şu makrolar kullanılabilir:
Invalid FreeFileSync config file!
-
+Geçersiz FreeFileSync yapılandırma dosyası!
Leave as unresolved conflict
Çözülmemiş tutarsızlık olarak bırak
Left
Sol
Legend
-Lejant
+Gösterge
Load configuration from file
-Dosyadan konfigürasyonu yükle
+Yapılandırmayı dosyadan yükle
Load configuration history (press DEL to delete items)
-Konfigürasyon geçmişini yükle (Öğeleri silmek için DEL’e basın)
+Geçmişteki yapılandırmalardan yükle (Listedeki öğeleri silmek için DEL’e basın)
Log-messages:
-Kayıt mesajları:
+Günlük iletileri:
Logging
-Kayıt tutma
+Günlükleme
Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.
-
+WOW64 üzerinde gölge kopyalama desteklenmiyor. FreeFileSync 64-bit sürümünü kullanın
Match case
-
+Büyük/küçük harf uydur
Minimum Idle Time
-
+En Az Boşluk Süresi
Mirror ->>
-Yedekleme ->>
+Yansı ->>
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.
+Sol klasörü yansıtır. Sol klasör tam olarak sağ klasörün üzerine yazılır ve klasörler tümüyle eşit olur.
Monitoring active...
-
+İzleme etkin...
More than 50% of the total number of files will be copied or deleted!
-%50’den fazla dosya kopyalanacak veya silinecek!
+Dosyaların yarıdan fazlası kopyalanacak ya da silinecek!
Move column down
-Kolonu aşağı taşı
+Sütunu aşağı taşı
Move column up
-Kolonu yukarı taşı
+Sütunu yukarı taşı
Move files into a time-stamped subdirectory
-
+Dosyaları zaman damgalı bir alt klasöre taşı
Moving %x to Recycle Bin
-%x geri dönüşüm kutusuna taşınıyor
+%x Geri Dönüşüm Kutusu'na atılıyor
Moving Symbolic Link %x to user-defined directory %y
-
+%x sembolik bağlantısı kullanıcının belirttiği %y klasörüne taşınıyor
Moving file %x to user-defined directory %y
-%x dosyası kullanıcı tanımlı dizin %y’e taşınıyor
+%x dosyası kullanıcının tanımladığı %y klasörüne taşınıyor
Moving folder %x to user-defined directory %y
-%x klasörü kullanıcı tanımlı dizin %y’e taşınıyor
+%x klasörü kullanıcının tanımladığı %y klasörüne taşınıyor
Multiple...
Çoklu...
No change since last synchronization!
-
+Son eşleştirmeden bu yana değişik olmamış!
No filter selected
-
+Hiç süzgeç seçilmedi
Not enough free disk space available in:
-Yeterli disk alanı yok :
+Şurada yeterli disk alanı yok :
Nothing to synchronize according to configuration!
-Konfigürasyona göre senkronize edecek bir şey yok!
+Yapılandırmaya göre eşleştirilecek bir şey yok!
Number of files and directories that will be created
-Oluşturulacak dosya ve dizinlerin sayısı
+Oluşturulacak dosya ve klasör sayısı
Number of files and directories that will be deleted
-Silinecek dosya ve dizinlerin sayısı
+Silinecek dosya ve klasör sayısı
Number of files that will be overwritten
-Üzerine yazılacak dosyaların sayısı
+Üzerine yazılacak dosya sayısı
One of the FreeFileSync database entries within the following file is not yet existing:
-
+Şu dosyadaki FreeFileSync veritabanı kayıtlarından biri henüz yok:
One of the FreeFileSync database files is not yet existing:
-
+FreeFileSync veritabanı dosyalarından biri henüz yok:
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.
-Senkronizasyon için sadece filtrelenmiş dosyalar/dizinler seçilecek. Senkronizasyon taban dizinlerine göreceli isimlere filtereleme uygulanacaktır.
+Yalnız süzgeçten geçen dosyalar/klasörler eşleştirme için seçilir. Süzgeç, temel eşleştirme klasörlerine, adlara göre uygulanır.
Open with Explorer
Gezgin ile aç
Open with default application
-
+Varsayılan uygulama ile aç
Operation aborted!
İşlemden vazgeçildi!
Operation:
İşlem:
Overview
-Değerlendirme
+Özet
Overwriting Symbolic Link %x in %y
-
+%y içindeki %x sembolik bağlantısının üzerine yazılıyor
Overwriting file %x in %y
-
+%y içindeki %x dosyasının üzerine yazılıyor
Pause
Duraklat
Paused
Duraklatıldı
Planned directory deletion is in conflict with its subdirectories and -files!
-
+Planlanmış klasörün silinmesi alt klasör ve dosyalarıyla çelişiyor!
Please run a Compare first before synchronizing!
-
+Lütfen eşleştirmeden önce karşılaştırma yapın!
Press \"Switch\" to open FreeFileSync GUI mode.
-
+FreeFileSync grafik kullanıcı arayüzünü açmak için \"Geç\" düğmesine tıklayın
Processing folder pair:
-
+İşlenen klasör çifti:
Published under the GNU General Public License:
-“GNU General Public License”a uygun olarak yayımlanmıştır:
+GNU Genel Kamu Lisansına şartları altında yayınlanmıştır:
Question
Soru
Quit
Çık
Re-enable all hidden dialogs?
-Gösterilmeyen iletilerin görünmesini istermisiniz?
+Tüm gizlenmiş iletiler yeniden görünür olsun mu?
RealtimeSync - Automated Synchronization
-RealtimeSync - Otomatik senkronizasyon
+RealtimeSync - Kendiliğinden Eşleştirme
RealtimeSync configuration
-RealtimeSync Konfigürasyon
+RealtimeSync yapılandırması
Recycle Bin not yet supported for this system!
-
+Geri Dönüşüm Kutusu bu sistemde desteklenmiyor!
Relative path
-Göreceli dizin yolu
+Bağıl klasör yolu
Remove alternate settings
-Alternatif ayarları kaldır
+Alternatif ayarları sil
Remove folder
-Klasörü kaldır
+Klasörü sil
Remove folder pair
-Klasör çiftini kaldır
+Klasör çiftini sil
Report translation error
Çeviri hatasını bildir
Reset
Sıfırla
Right
Sağ
-Run minimized and write status information to a logfile
-
S&ave configuration...
-Konfigürasyonu &kaydet...
+Y&apılandırmayı kaydet...
S&witch view
-Görünümü &değiştir
+Orta görünümü &değiştir
Save changes to current configuration?
-Değişiklikleri aktif konfigürasyona kaydetmek istermisiniz?
+Değişiklikleri şu anki yapılandırmaya kaydetmek ister misiniz?
Save current configuration to file
-Aktif konfigürasyonu dosyaya kaydet
+Kullanımdaki yapılandırmayı dosyaya kaydet
Scanning...
Taranıyor...
Scanning:
Taranıyor:
Select a folder
-Bir klasör seç
+Bir klasör seçin
Select alternate synchronization settings
-Alternatif senkronizasyon ayarı seç
+Alternatif eşleştirme ayarlarını seçin
Select logfile directory:
-Kayıt dosyası dizinini seç:
+Kayıt dosyası klasörünü seçin:
Select variant:
-Değişkeni seç:
+Değişkeni seçin:
Set direction:
-
+Yönü seçin:
Setting default synchronization directions: Old files will be overwritten with newer files.
-
+Varsayılan eşleştirme yönleri ayarlanıyor: Yeni dosyalar eski dosyaların üzerine yazılacak.
Show conflicts
-Tutarsızlıkları göster
+Çelişkileri göster
Show files that are different
Farklı olan dosyaları göster
Show files that are equal
@@ -739,91 +745,91 @@ Solda daha yeni olan dosyaları göster
Show files that are newer on right
Sağda daha yeni olan dosyaları göster
Show files that exist on left side only
-Sadece sol tarafta var olan dosyaları göster
+Yalnız sol tarafta bulunan dosyaları göster
Show files that exist on right side only
-Sadece sağ tarafta var olan dosyaları göster
+Yalnız sağ tarafta bulunan dosyaları göster
Show files that will be created on the left side
-Sadece sol tarafta yaratılacak dosyaları göster
+Yalnız sol tarafta oluşturulacak dosyaları göster
Show files that will be created on the right side
-Sadece sağ tarafta yaratılacak dosyaları göster
+Yalnız sağ tarafta oluşturulacak dosyaları göster
Show files that will be deleted on the left side
-Sadece sol tarafta silinecek dosyaları göster
+Yalnız sol tarafta silinecek dosyaları göster
Show files that will be deleted on the right side
-Sadece sağ tarafta silinecek dosyaları göster
+Yalnız sağ tarafta silinecek dosyaları göster
Show files that will be overwritten on left side
-Sadece sol tarafta üzerine yazılacak dosyaları göster
+Yalnız sol tarafta üzerine yazılacak dosyaları göster
Show files that will be overwritten on right side
-Sadece sağ tarafta üzerine yazılacak dosyaları göster
+Yalnız sağ tarafta üzerine yazılacak dosyaları göster
Show files that won't be copied
Kopyalanmayacak dosyaları göster
Show hidden dialogs
-Gösterilmemiş diyalogları göster
+Gizlenmiş iletileri göster
Show popup
-açılır bildirimleri göster
+Açılır pencerede göster
Show popup on errors or warnings
-Hata ve uyarılarda açılır bildirimi göster
+Hata ve uyarılarda açılır bir pencere gösterir
Significant difference detected:
Önemli fark saptandı:
Silent mode
-Sessiz mod
+Sessiz kip
Size
-Ebat
+Boyut
Source code written completely in C++ utilizing:
-Kaynak kod tümüyle C++ ile yazıldı:
+Kaynak kod tümüyle C++ kullanılarak yazıldı:
Source directory does not exist anymore:
-Kaynak dizin artık mevcut değil:
+Kaynak klasör artık yok:
Speed:
Hız:
Start
Başla
+Start minimized and write status information to a logfile
+
Start synchronization
-Senkronizasyonu başlat
+Eşleştirmeyi başlat
Statistics
-İstatistik
+İstatistikler
Status feedback
-
+Durum geri bildirimi
Stop
Durdur
Swap sides
-Tarafları ters çevir
+Sağ ve sol yanı değiştir
Switching to FreeFileSync GUI mode...
-
+FreeFileSync grafik kullanıcı arayüzüne geçiliyor...
Symbolic Link handling
-
+Sembolik bağlantı işleme
Symlinks %x have the same date but a different target!
-
+Sembolik bağlantılar %x aynı tarihli fakat hedefleri farklı!
Synchronization Preview
-Senkronizasyon Önizlemesi
+Eşleştirme önizlemesi
Synchronization aborted!
-Senkronizasyon durduruldu!
+Eşleştirme durduruldu!
Synchronization completed successfully!
-Senkronizasyon başarı ile tamamlandı!
+Eşleştirme sorunsuz tamamlandı!
Synchronization completed with errors!
-Senkronizasyon hatalı olarak tamamlandı!
+Eşleştirme hatalarla tamamlandı!
Synchronization settings
-Senkronizasyon ayarları
-Synchronization status
-Senkronizasyon durumu
+Eşleştirme ayarları
Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\".
-\"temp\" alt klasöründeki herşey hariç, tüm .doc, .zip ve .exe dosyalarını senkronize et.
+\"temp\" alt klasöründeki herşey hariç, tüm .doc, .zip ve .exe dosyalarını eşleştir.
Synchronize...
-Senkronize et...
+Eşleştir...
Synchronizing...
-Senkronize ediliyor...
+Eşleştiriliyor...
System out of memory!
-Sistem hafızası yetersiz!
+Sistem belleği yetersiz!
Target directory already existing!
-Hedef dizin zaten mevcut!
+Hedef klasör zaten var!
Target file already existing!
-Hedef dosya zaten mevcut!
+Hedef dosya zaten var!
The command line is executed each time:\n- all directories become available (e.g. USB stick insert)\n- files within these directories or subdirectories are modified
-
+Her seferinde çalıştırılacak komut satırı:\n- tüm klasörler geçerli (örneğin USB bellek takıldığında)\n- bu klasörlerin ya da alt klasörlerin içindeki dosyalar değiştirildiğinde
The file does not contain a valid configuration:
-Dosya geçerli bir konfigürasyon içermiyor:
+Dosya geçerli bir yapılandırma içermiyor:
The file was not processed by last synchronization!
-
+Dosya son eşleştirmede işlenmemiş!
This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time.
-Bu değişken, aynı isimli iki dosyanın, aynı ebata ve aynı son değişikik tarihine sahip olması durumunda eşit olması anlamına gelir.
+Bu seçenek, aynı adlı iki dosyanın, aynı boyuta ve aynı son değişiklik tarihine sahip olması durumunda eşit olması anlamına gelir.
Time
Zaman
Time elapsed:
@@ -831,56 +837,56 @@ Geçen zaman:
Time remaining:
Kalan zaman:
Total amount of data that will be transferred
-Transfer edilecek toplam veri miktarı
+Aktarılacak toplam veri miktarı
Total required free disk space:
-Toplam gerekli boş disk alanı:
+Toplam gereken boş disk alanı:
Total time:
Toplam zaman:
Transfer file and directory permissions\n(Requires Administrator rights)
-
+Dosya ve klasör izinlerini de aktar\n(Yönetici izinlerine gerek duyar)
Unable to connect to sourceforge.net!
-sourceforge.net’e bağlanılamıyor!
+sourceforge.net sitesine bağlanılamıyor!
Unable to create logfile!
-Kayıt dosyası yaratılamıyor!
+Günlük dosyası oluşturulamıyor!
Unresolved conflicts existing!
-
+Çözülmemiş tutarsızlıklar var!
Update ->
Güncelle ->
Usage:
-
+Kullanım:
Use Recycle Bin
-Geri dönüşüm kutusunu kullan
+Geri Dönüşüm Kutusu'nu kullan
Use Recycle Bin when deleting or overwriting files
-Silme ve üzerine yazma sırasında geri dönüşüm kutusunu kullan
+Dosyaları silerken ve üzerine yazarken Geri Dönüşüm Kutusu'nu kullan
User-defined directory
-Kullanıcı tanımlı dizin
+Kullanıcının belirttiği klasöre taşı
User-defined directory for deletion was not specified!
-Silme için kulllanıcı tanımlı dizin belirtilmemiş!
+Silme için kullanıcının belirttiği dizin belirtilmemiş!
Variant
Değişken
Verifying file %x
%x dosyası doğrulanıyor
Volume name %x not part of filename %y!
-%x birim adı, %y dosya adının bölümü değil!
+%x birim adı, %y dosya adının parçası değil!
Waiting for all directories to become available...
-
+Tüm klasörlerlerin hazır olması bekleniyor...
Waiting while directory is locked (%x)...
-
+Klasör kilitli olduğundan bekleniyor (%x)...
Warning
Uyarı
Warning: Synchronization failed for %x item(s):
-Uyarı: %x kadar öğe için senkronizasyon başarısız oldu:
+Uyarı: %x öğe için eşleştirme yapılamadı:
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:
+Bu seçenekle karşılaştırma yapıldığında, şu karar ağacı işlenir:
You can ignore conflicts and continue synchronization.
-
+Çelişkileri yoksayıp eşleştirmeyi sürdürebilirsiniz.
You can ignore the error to consider not existing directories as empty.
-Var olamayan dizinleri boş olarak tanımlama hatasını yoksay.
+Bulunamayan klasörleri boş olarak kabul ederek hatayı yoksayabilirsiniz.
You may try to synchronize remaining items again (WITHOUT having to re-compare)!
-Kalan öğeleri tekrar senkronize etmeyi deneyebilirsiniz (Tekrar kaşılaştırma yapmadan)!
+Kalan öğeleri yeniden eşleştirmeyi deneyebilirsiniz (Tekrar kaşılaştırma yapmadan)!
different
farklı
file exists on both sides
-Dosya her iki tarafta da mevcut
+Dosya her iki yanda da var
on one side only
-sadece tek tarafta
+yalnız tek yanda
diff --git a/BUILD/Resources.dat b/BUILD/Resources.dat
index e4594b68..b2bd5570 100644
--- a/BUILD/Resources.dat
+++ b/BUILD/Resources.dat
Binary files differ
diff --git a/FreeFileSync.cbp b/FreeFileSync.cbp
index d7a6c432..47bb0408 100644
--- a/FreeFileSync.cbp
+++ b/FreeFileSync.cbp
@@ -28,7 +28,7 @@
<Add library="libwxpng.a" />
<Add library="libwxzlib.a" />
<Add library="libwxbase28u_net.a" />
- <Add library="libboost_thread-mgw45-mt-s-1_44.a" />
+ <Add library="libboost_thread-mgw45-mt-s-1_45.a" />
<Add directory="C:\Programme\C++\wxWidgets\lib\gcc_lib" />
</Linker>
</Target>
@@ -54,7 +54,7 @@
<Add library="libwxbase28ud.a" />
<Add library="libwxpngd.a" />
<Add library="libwxzlibd.a" />
- <Add library="libboost_thread-mgw45-mt-sd-1_44.a" />
+ <Add library="libboost_thread-mgw45-mt-sd-1_45.a" />
<Add directory="C:\Programme\C++\wxWidgets\lib\gcc_dll" />
</Linker>
</Target>
@@ -77,7 +77,7 @@
<Add library="libwxmsw28ud_core.a" />
<Add library="libwxbase28ud.a" />
<Add library="libwxbase28ud_net.a" />
- <Add library="libboost_thread-mgw45-mt-sd-1_44.a" />
+ <Add library="libboost_thread-mgw45-mt-sd-1_45.a" />
<Add directory="C:\Programme\C++\wxWidgets\lib\gcc_dll" />
</Linker>
</Target>
@@ -302,6 +302,7 @@
<Unit filename="shared\standard_paths.cpp" />
<Unit filename="shared\standard_paths.h" />
<Unit filename="shared\string_conv.h" />
+ <Unit filename="shared\symlink_target.h" />
<Unit filename="shared\system_constants.h" />
<Unit filename="shared\system_func.cpp" />
<Unit filename="shared\system_func.h" />
diff --git a/Makefile b/Makefile
index 172690f2..d9f9e3e3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,33 @@
-APPNAME = FreeFileSync
-
-prefix = /usr
-BINDIR = $(DESTDIR)$(prefix)/bin
-SHAREDIR = $(DESTDIR)$(prefix)/share
+APPNAME = FreeFileSync
+prefix = /usr
+BINDIR = $(DESTDIR)$(prefix)/bin
+SHAREDIR = $(DESTDIR)$(prefix)/share
APPSHAREDIR = $(SHAREDIR)/$(APPNAME)
-FFS_CPPFLAGS=-Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes --static=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -O3 -pthread
-LINKFLAGS=`wx-config --libs --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a -O3 -pthread
+#default build
+FFS_CPPFLAGS = -Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -O3 -pthread
+LINKFLAGS = `wx-config --libs --debug=no --unicode=yes` -lboost_thread -O3 -pthread
+
+#static build used for precompiled release
+ifeq ($(BUILD),release)
+FFS_CPPFLAGS = -Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes --static=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -O3 -pthread
+LINKFLAGS = `wx-config --libs --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a -O3 -pthread
+endif
+#####################################################################################################
+
#support for GTKMM
FFS_CPPFLAGS+=`pkg-config --cflags gtkmm-2.4`
LINKFLAGS+=`pkg-config --libs gtkmm-2.4`
+#support for SELinux (optional)
+ifeq ($(BUILD),release)
+SELINUX_EXISTING=$(shell pkg-config --exists libselinux && echo YES)
+ifeq ($(SELINUX_EXISTING),YES)
+FFS_CPPFLAGS += -DHAVE_SELINUX
+endif
+endif
+
FILE_LIST= #internal list of all *.cpp files needed for compilation
FILE_LIST+=structures.cpp
FILE_LIST+=algorithm.cpp
@@ -81,9 +97,7 @@ all: FreeFileSync
init:
if [ ! -d OBJ ]; then mkdir OBJ; fi
-
#remove byte ordering mark: needed by Visual C++ but an error with GCC
-removeBOM: tools/remove_BOM.cpp
g++ -o OBJ/removeBOM tools/remove_BOM.cpp
./OBJ/removeBOM shared/localization.cpp shared/localization_no_BOM.cpp
@@ -91,7 +105,7 @@ removeBOM: tools/remove_BOM.cpp
#strip path information
g++ $(FFS_CPPFLAGS) -c $< -o OBJ/$(subst .cpp,.o,$(notdir $<))
-FreeFileSync: init removeBOM $(DEP_LIST)
+FreeFileSync: init $(DEP_LIST)
#respect linker order: wxWidgets libraries last
g++ -o ./BUILD/$(APPNAME) $(OBJECT_LIST) $(LINKFLAGS)
diff --git a/RealtimeSync/RealtimeSync.cbp b/RealtimeSync/RealtimeSync.cbp
index 701e8c9c..4dd1addb 100644
--- a/RealtimeSync/RealtimeSync.cbp
+++ b/RealtimeSync/RealtimeSync.cbp
@@ -27,7 +27,7 @@
<Add library="libwxbase28u.a" />
<Add library="libwxpng.a" />
<Add library="libwxzlib.a" />
- <Add library="libboost_thread-mgw45-mt-s-1_44.a" />
+ <Add library="libboost_thread-mgw45-mt-s-1_45.a" />
<Add directory="C:\Programme\C++\wxWidgets\lib\gcc_lib" />
</Linker>
</Target>
@@ -51,7 +51,7 @@
<Add library="libwxbase28ud.a" />
<Add library="libwxpngd.a" />
<Add library="libwxzlibd.a" />
- <Add library="libboost_thread-mgw45-mt-sd-1_44.a" />
+ <Add library="libboost_thread-mgw45-mt-sd-1_45.a" />
<Add directory="C:\Program Files\C++\wxWidgets\lib\gcc_dll" />
</Linker>
</Target>
diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile
index cf7aca36..e60ca3bf 100644
--- a/RealtimeSync/makefile
+++ b/RealtimeSync/makefile
@@ -1,10 +1,16 @@
APPNAME = RealtimeSync
-
prefix = /usr
BINDIR = $(DESTDIR)$(prefix)/bin
-FFS_CPPFLAGS=-Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes --static=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -O3 -pthread
-LINKFLAGS=`wx-config --libs --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a -O3 -pthread
+#default build
+FFS_CPPFLAGS = -Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -O3 -pthread
+LINKFLAGS = `wx-config --libs --debug=no --unicode=yes` -lboost_thread -O3 -pthread
+
+#static build used for precompiled release
+ifeq ($(BUILD),static)
+FFS_CPPFLAGS = -Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes --static=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -O3 -pthread
+LINKFLAGS = `wx-config --libs --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a -O3 -pthread
+endif
FILE_LIST= #internal list of all *.cpp files needed for compilation
FILE_LIST+=application.cpp
@@ -46,9 +52,7 @@ all: RealtimeSync
init:
if [ ! -d OBJ ]; then mkdir OBJ; fi
-
#remove byte ordering mark: needed by Visual C++ but an error with GCC
-removeBOM: ../tools/remove_BOM.cpp
g++ -o OBJ/removeBOM ../tools/remove_BOM.cpp
./OBJ/removeBOM ../shared/localization.cpp ../shared/localization_no_BOM.cpp
@@ -56,7 +60,7 @@ removeBOM: ../tools/remove_BOM.cpp
#strip path information
g++ $(FFS_CPPFLAGS) -c $< -o OBJ/$(subst .cpp,.o,$(notdir $<))
-RealtimeSync: init removeBOM $(DEP_LIST)
+RealtimeSync: init $(DEP_LIST)
#respect linker order: wxWidgets libraries last
g++ -o ../BUILD/$(APPNAME) $(OBJECT_LIST) $(LINKFLAGS)
diff --git a/RealtimeSync/notify.cpp b/RealtimeSync/notify.cpp
index 599259e6..c87c15fc 100644
--- a/RealtimeSync/notify.cpp
+++ b/RealtimeSync/notify.cpp
@@ -198,7 +198,8 @@ public:
if (hNotfication == NULL)
{
const DWORD lastError = ::GetLastError();
- if (lastError != ERROR_CALL_NOT_IMPLEMENTED) //fail on SAMBA share: this shouldn't be a showstopper!
+ if (lastError != ERROR_CALL_NOT_IMPLEMENTED && //fail on SAMBA share: this shouldn't be a showstopper!
+ lastError != ERROR_SERVICE_SPECIFIC_ERROR) //neither should be fail for "Pogoplug" mapped network drives
throw ffs3::FileError(wxString(wxT("Could not register device removal notifications:")) + wxT("\n\n") + ffs3::getLastErrorFormatted(lastError));
}
else
diff --git a/RealtimeSync/watcher.cpp b/RealtimeSync/watcher.cpp
index e9793545..d03c98b8 100644
--- a/RealtimeSync/watcher.cpp
+++ b/RealtimeSync/watcher.cpp
@@ -96,18 +96,13 @@ public:
if (newExec - lastExec >= UPDATE_INTERVAL)
{
lastExec = newExec;
- allExisting_ = std::find_if(dirList.begin(), dirList.end(), notExisting) == dirList.end();
+ allExisting_ = std::find_if(dirList.begin(), dirList.end(), std::not1(std::ptr_fun(&ffs3::dirExists))) == dirList.end();
}
return allExisting_;
}
private:
- static bool notExisting(const Zstring& dirname)
- {
- return !ffs3::dirExists(dirname);
- }
-
mutable wxLongLong lastExec;
mutable bool allExisting_;
@@ -146,7 +141,9 @@ rts::WaitResult rts::waitForChanges(const std::vector<Zstring>& dirNames, WaitCa
if (rv == INVALID_HANDLE_VALUE)
{
- if (::GetLastError() == ERROR_FILE_NOT_FOUND) //no need to check this condition any earlier!
+ const DWORD lastError = ::GetLastError();
+ if ( lastError == ERROR_FILE_NOT_FOUND || //no need to check this condition any earlier!
+ lastError == ERROR_BAD_NETPATH) //
return CHANGE_DIR_MISSING;
const wxString errorMessage = wxString(_("Could not initialize directory monitoring:")) + wxT("\n\"") + zToWx(*i) + wxT("\"");
diff --git a/algorithm.cpp b/algorithm.cpp
index 5e6b2b66..93aacf40 100644
--- a/algorithm.cpp
+++ b/algorithm.cpp
@@ -23,6 +23,16 @@
using namespace ffs3;
+wxString ffs3::extractJobName(const wxString& configFilename)
+{
+ using namespace common;
+
+ const wxString shortName = configFilename.AfterLast(FILE_NAME_SEPARATOR); //returns the whole string if seperator not found
+ const wxString jobName = shortName.BeforeLast(wxChar('.')); //returns empty string if seperator not found
+ return jobName.IsEmpty() ? shortName : jobName;
+}
+
+
void ffs3::swapGrids(const MainConfiguration& config, FolderComparison& folderCmp)
{
std::for_each(folderCmp.begin(), folderCmp.end(), boost::bind(&BaseDirMapping::swap, _1));
@@ -42,9 +52,40 @@ public:
std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), prx); //process files
std::for_each(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), prx); //process links
- std::for_each(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), prx); //process directories
+ std::for_each(hierObj.useSubDirs(). begin(), hierObj.useSubDirs(). end(), prx); //process directories
}
+ /*
+ void execute2(FileSystemObject& fsObj) const
+ {
+ struct RedetermineObject : public FSObjectVisitor
+ {
+ RedetermineObject(const Redetermine& parent,
+ FileSystemObject& fsObject) : parent_(parent), fsObj_(fsObject) {}
+
+ virtual void visit(const FileMapping& fileObj)
+ {
+ parent_(static_cast<FileMapping&>(fsObj_));
+ }
+
+ virtual void visit(const SymLinkMapping& linkObj)
+ {
+ parent_(static_cast<SymLinkMapping&>(fsObj_));
+ }
+
+ virtual void visit(const DirMapping& dirObj)
+ {
+ parent_(static_cast<DirMapping&>(fsObj_));
+ }
+
+ private:
+ const Redetermine& parent_;
+ FileSystemObject& fsObj_; //hack
+ } redetObj(*this, fsObj);
+ fsObj.accept(redetObj);
+ }
+ */
+
private:
friend class util::ProxyForEach<const Redetermine>; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
@@ -896,20 +937,7 @@ void ffs3::redetermineSyncDirection(const MainConfiguration& currentMainCfg, Fol
class SetNewDirection
{
public:
- SetNewDirection(SyncDirection newDirection) :
- newDirection_(newDirection) {}
-
- void execute(HierarchyObject& hierObj) const
- {
- util::ProxyForEach<const SetNewDirection> prx(*this); //grant std::for_each access to private parts of this class
-
- std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), prx); //process files
- std::for_each(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), prx); //process links
- std::for_each(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), prx); //process directories
- }
-
-private:
- friend class util::ProxyForEach<const SetNewDirection>; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
+ SetNewDirection(SyncDirection newDirection) : newDirection_(newDirection) {}
void operator()(FileMapping& fileObj) const
{
@@ -930,28 +958,45 @@ private:
execute(dirObj); //recursion
}
+private:
+ friend class util::ProxyForEach<const SetNewDirection>; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
+
+ void execute(HierarchyObject& hierObj) const
+ {
+ util::ProxyForEach<const SetNewDirection> prx(*this); //grant std::for_each access to private parts of this class
+
+ std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), prx); //process files
+ std::for_each(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), prx); //process links
+ std::for_each(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), prx); //process directories
+ }
+
const SyncDirection newDirection_;
};
void ffs3::setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj)
{
- if (fsObj.getCategory() != FILE_EQUAL)
- fsObj.setSyncDir(newDirection);
+ SetNewDirection dirSetter(newDirection);
//process subdirectories also!
struct Recurse: public FSObjectVisitor
{
- Recurse(SyncDirection newDirect) : newDirection_(newDirect) {}
- virtual void visit(const FileMapping& fileObj) {}
- virtual void visit(const SymLinkMapping& linkObj) {}
+ Recurse(const SetNewDirection& ds) : dirSetter_(ds) {}
+ virtual void visit(const FileMapping& fileObj)
+ {
+ dirSetter_(const_cast<FileMapping&>(fileObj)); //phyiscal object is not const in this method anyway
+ }
+ virtual void visit(const SymLinkMapping& linkObj)
+ {
+ dirSetter_(const_cast<SymLinkMapping&>(linkObj)); //phyiscal object is not const in this method anyway
+ }
virtual void visit(const DirMapping& dirObj)
{
- SetNewDirection(newDirection_).execute(const_cast<DirMapping&>(dirObj)); //phyiscal object is not const in this method anyway
+ dirSetter_(const_cast<DirMapping&>(dirObj)); //phyiscal object is not const in this method anyway
}
private:
- const SyncDirection newDirection_;
- } recurse(newDirection);
+ const SetNewDirection& dirSetter_;
+ } recurse(dirSetter);
fsObj.accept(recurse);
}
@@ -1224,6 +1269,7 @@ private:
};
}
+
template <SelectedSide side>
void deleteFromGridAndHDOneSide(std::vector<FileSystemObject*>& rowsToDeleteOneSide,
const bool useRecycleBin,
@@ -1279,6 +1325,12 @@ void deleteFromGridAndHDOneSide(std::vector<FileSystemObject*>& rowsToDeleteOneS
}
fsObj->removeObject<side>(); //if directory: removes recursively!
+
+ //update sync direction: as this is a synchronization tool, the user most likely wants to delete the other side, too!
+ if (side == LEFT_SIDE)
+ setSyncDirectionRec(SYNC_DIR_RIGHT, *fsObj); //set new direction (recursively)
+ else
+ setSyncDirectionRec(SYNC_DIR_LEFT, *fsObj);
}
statusHandler.deletionSuccessful(1); //notify successful file/folder deletion
@@ -1304,19 +1356,17 @@ void deleteFromGridAndHDOneSide(std::vector<FileSystemObject*>& rowsToDeleteOneS
class FinalizeDeletion
{
public:
- FinalizeDeletion(FolderComparison& folderCmp, const MainConfiguration& mainConfig) :
- folderCmp_(folderCmp),
- mainConfig_(mainConfig) {}
+ FinalizeDeletion(FolderComparison& folderCmp) : folderCmp_(folderCmp) {}
~FinalizeDeletion()
{
std::for_each(folderCmp_.begin(), folderCmp_.end(), FileSystemObject::removeEmpty);
- redetermineSyncDirection(mainConfig_, folderCmp_, NULL);
+
+ //redetermineSyncDirection(mainConfig_, folderCmp_, NULL);
}
private:
FolderComparison& folderCmp_;
- const MainConfiguration& mainConfig_;
};
@@ -1325,15 +1375,9 @@ void ffs3::deleteFromGridAndHD(FolderComparison& folderCmp,
std::vector<FileSystemObject*>& rowsToDeleteOnRight, //all pointers need to be bound!
const bool deleteOnBothSides,
const bool useRecycleBin,
- const MainConfiguration& mainConfig,
DeleteFilesHandler& statusHandler)
{
- if (folderCmp.size() == 0)
- return;
- else if (folderCmp.size() != mainConfig.additionalPairs.size() + 1)
- throw std::logic_error("Programming Error: Contract violation!");
-
- FinalizeDeletion dummy(folderCmp, mainConfig); //ensure cleanup: redetermination of sync-directions and removal of invalid rows
+ FinalizeDeletion dummy(folderCmp); //ensure cleanup: redetermination of sync-directions and removal of invalid rows
if (deleteOnBothSides)
diff --git a/algorithm.h b/algorithm.h
index 7280ed7d..c1acec9e 100644
--- a/algorithm.h
+++ b/algorithm.h
@@ -14,6 +14,8 @@ namespace ffs3
{
class BaseFilter;
+ wxString extractJobName(const wxString& configFilename);
+
void swapGrids(const MainConfiguration& config, FolderComparison& folderCmp);
struct DeterminationProblem //callback
@@ -64,7 +66,6 @@ void deleteFromGridAndHD(FolderComparison& folderCmp, //a
std::vector<FileSystemObject*>& rowsToDeleteOnRight, //all pointers need to be bound!
const bool deleteOnBothSides,
const bool useRecycleBin,
- const MainConfiguration& mainConfig,
DeleteFilesHandler& statusHandler);
}
diff --git a/comparison.cpp b/comparison.cpp
index 9071664a..db56ea54 100644
--- a/comparison.cpp
+++ b/comparison.cpp
@@ -122,6 +122,20 @@ private:
void DirCallback::onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details)
{
+ //do not list the database file(s) sync.ffs_db, sync.x64.ffs_db, etc. or lock files
+ const Zstring fileNameShort(shortName);
+ const size_t pos = fileNameShort.rfind(Zchar('.'));
+ if (pos != Zstring::npos)
+ {
+ const Zchar* ending = shortName + pos + 1; //(returns the whole string if ch not found)
+ // if ( EqualFilename()(ending, SYNC_DB_FILE_ENDING) ||
+ // EqualFilename()(ending, LOCK_FILE_ENDING)) //let's hope this premature performance optimization doesn't bite back!
+ if ( ending == SYNC_DB_FILE_ENDING || //
+ ending == LOCK_FILE_ENDING)
+ return;
+ }
+
+
//assemble status message (performance optimized) = textScanning + wxT("\"") + fullName + wxT("\"")
Zstring statusText = baseCallback_->textScanning;
statusText.reserve(statusText.length() + fullName.length() + 2);
@@ -134,7 +148,7 @@ void DirCallback::onFile(const Zchar* shortName, const Zstring& fullName, const
//------------------------------------------------------------------------------------
//apply filter before processing (use relative name!)
- if (!baseCallback_->filterInstance->passFileFilter(relNameParentPf_ + shortName))
+ if (!baseCallback_->filterInstance->passFileFilter(relNameParentPf_ + fileNameShort))
{
statusHandler->requestUiRefresh();
return;
@@ -150,7 +164,7 @@ void DirCallback::onFile(const Zchar* shortName, const Zstring& fullName, const
// util::retrieveFileID(fullName) :
// util::FileID();
- output_.addSubFile(shortName, FileDescriptor(details.lastWriteTimeRaw, details.fileSize));
+ output_.addSubFile(fileNameShort, FileDescriptor(details.lastWriteTimeRaw, details.fileSize));
//add 1 element to the progress indicator
statusHandler->updateProcessedData(1, 0); //NO performance issue at all
@@ -251,17 +265,6 @@ void DirCallback::onError(const wxString& errorText)
void BaseDirCallback::onFile(const Zchar* shortName, const Zstring& fullName, const TraverseCallback::FileInfo& details)
{
- //do not list the database file(s) sync.ffs_db, sync.x64.ffs_db, etc. or lock files
- const Zstring fileName(shortName);
- const size_t pos = fileName.rfind(Zchar('.'));
- if (pos != Zstring::npos)
- {
- const Zstring ending(shortName + pos + 1); //(returns the whole string if ch not found)
- if ( EqualFilename()(ending, SYNC_DB_FILE_ENDING) ||
- EqualFilename()(ending, LOCK_FILE_ENDING))
- return;
- }
-
DirCallback::onFile(shortName, fullName, details);
}
@@ -319,7 +322,7 @@ class DstHackCallbackImpl : public DstHackCallback
{
public:
DstHackCallbackImpl(StatusHandler& statusUpdater) :
- textApplyingDstHack(wxToZ(_("Encode extended time information: %x")).Replace(Zstr("%x"), Zstr("\n\"%x\""))),
+ textApplyingDstHack(wxToZ(_("Encoding extended time information: %x")).Replace(Zstr("%x"), Zstr("\n\"%x\""))),
statusUpdater_(statusUpdater) {}
private:
@@ -394,30 +397,19 @@ namespace
{
void foldersAreValidForComparison(const std::vector<FolderPairCfg>& folderPairsForm, StatusHandler* statusUpdater)
{
- bool checkEmptyDirnameActive = true; //check for empty dirs just once
+ bool nonEmptyPairFound = false; //check if user entered at least one folder pair
+ bool partiallyFilledPairFound = false;
+
const wxString additionalInfo = _("You can ignore the error to consider not existing directories as empty.");
for (std::vector<FolderPairCfg>::const_iterator i = folderPairsForm.begin(); i != folderPairsForm.end(); ++i)
{
- //check if folder name is empty
- if (i->leftDirectory.empty() || i->rightDirectory.empty())
- {
- if (checkEmptyDirnameActive)
- {
- checkEmptyDirnameActive = false;
- while (true)
- {
- 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! (1)");
- }
- }
- }
+ if (!i->leftDirectory.empty() || !i->rightDirectory.empty()) //may be partially filled though
+ nonEmptyPairFound = true;
+
+ if ( (i->leftDirectory.empty() && !i->rightDirectory.empty()) ||
+ (!i->leftDirectory.empty() && i->rightDirectory.empty()))
+ partiallyFilledPairFound = true;
//check if folders exist
if (!i->leftDirectory.empty())
@@ -448,6 +440,22 @@ void foldersAreValidForComparison(const std::vector<FolderPairCfg>& folderPairsF
throw std::logic_error("Programming Error: Unknown return value! (3)");
}
}
+
+ //check for empty entries
+ if (!nonEmptyPairFound || partiallyFilledPairFound)
+ {
+ while (true)
+ {
+ 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! (1)");
+ }
+ }
}
@@ -635,7 +643,7 @@ void CompareProcess::startCompareProcess(const std::vector<FolderPairCfg>& direc
#endif
// #ifdef FFS_WIN
-// PERF_START;
+ //PERF_START;
// #endif
//init process: keep at beginning so that all gui elements are initialized properly
@@ -789,9 +797,12 @@ void makeSameLength(wxString& first, wxString& second)
wxString getConflictSameDateDiffSize(const FileMapping& fileObj)
{
//some beautification...
- wxString left = wxString(_("Left")) + wxT(": ");
- wxString right = wxString(_("Right")) + wxT(": ");
- makeSameLength(left, right);
+// wxString left = wxString(_("Left")) + wxT(": ");
+// wxString right = wxString(_("Right")) + wxT(": ");
+// makeSameLength(left, right);
+
+ const wxString left = wxT("<-- ");
+ const wxString right = wxT("--> ");
wxString msg = _("Files %x have the same date but a different size!");
msg.Replace(wxT("%x"), wxString(wxT("\"")) + zToWx(fileObj.getRelativeName<LEFT_SIDE>()) + wxT("\""));
diff --git a/file_hierarchy.h b/file_hierarchy.h
index d03184a1..2cbbb7ca 100644
--- a/file_hierarchy.h
+++ b/file_hierarchy.h
@@ -333,10 +333,10 @@ public:
void setActive(bool active);
void synchronizeSides(); //copy one side to the other (NOT recursive!!!)
- template <SelectedSide side> void removeObject(); //removes file or directory (recursively!): used by manual deletion
+ template <SelectedSide side> void removeObject(); //removes file or directory (recursively!) without physically removing the element: used by manual deletion
bool isEmpty() const; //true, if both sides are empty
- static void removeEmpty(BaseDirMapping& baseDir); //remove all invalid entries (where both sides are empty) recursively
- static void removeEmptyNonRec(HierarchyObject& hierObj); //remove all invalid entries (where both sides are empty) non-recursively
+ static void removeEmpty(BaseDirMapping& baseDir); //physically remove all invalid entries (where both sides are empty) recursively
+ static void removeEmptyNonRec(HierarchyObject& hierObj); //physically remove all invalid entries (where both sides are empty) non-recursively
protected:
FileSystemObject(bool existsLeft, bool existsRight, const Zstring& shortName, const HierarchyObject& parent) :
diff --git a/library/binary.cpp b/library/binary.cpp
index d4d35e92..cbcef238 100644
--- a/library/binary.cpp
+++ b/library/binary.cpp
@@ -106,16 +106,6 @@ bool ffs3::filesHaveSameContent(const Zstring& filename1, const Zstring& filenam
}
//------------------------------------------------------------------------------------------------
-//#warning
-// static wxLongLong blorg = wxGetLocalTimeMillis();
-// if (wxGetLocalTimeMillis() - blorg > 5000)
-// {
-// blorg = wxGetLocalTimeMillis();
-// wxMessageBox(numberToZstring<size_t>(bufferSize).c_str());
-// }
-
-
-
if (length1 != length2 || ::memcmp(&memory1[0], &memory2[0], length1) != 0)
return false;
diff --git a/library/custom_grid.cpp b/library/custom_grid.cpp
index b510717f..e7a724a0 100644
--- a/library/custom_grid.cpp
+++ b/library/custom_grid.cpp
@@ -599,9 +599,6 @@ void CustomGrid::initSettings(CustomGridLeft* gridLeft,
m_gridRight = gridRight;
m_gridMiddle = gridMiddle;
- //set underlying grid data
- setGridDataTable(gridDataView);
-
//enhance grid functionality; identify leading grid by keyboard input or scroll action
Connect(wxEVT_KEY_DOWN, wxEventHandler(CustomGrid::onGridAccess), NULL, this);
Connect(wxEVT_SCROLLWIN_TOP, wxEventHandler(CustomGrid::onGridAccess), NULL, this);
@@ -626,7 +623,8 @@ void CustomGrid::initSettings(CustomGridLeft* gridLeft,
void CustomGrid::release() //release connection to ffs3::GridView
{
- setGridDataTable(NULL);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(NULL); //kind of "disable" griddatatable; don't delete it with SetTable(NULL)! May be used by wxGridCellStringRenderer
}
@@ -955,6 +953,13 @@ void CustomGrid::adjustGridHeights(wxEvent& event)
}
+void CustomGrid::updateGridSizes()
+{
+ if(getGridDataTable())
+ getGridDataTable()->updateGridSizes();
+}
+
+
void CustomGrid::setSortMarker(SortMarker marker)
{
m_marker = marker;
@@ -1175,7 +1180,48 @@ CustomGridRim::CustomGridRim(wxWindow *parent,
const wxSize& size,
long style,
const wxString& name) :
- CustomGrid(parent, id, pos, size, style, name), fileIconsAreEnabled(false) {}
+ CustomGrid(parent, id, pos, size, style, name), fileIconsAreEnabled(false), otherGrid(NULL)
+{
+ Connect(wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler(CustomGridRim::OnResizeColumn), NULL, this); //row-based tooltip
+}
+
+
+void CustomGridRim::setOtherGrid(CustomGridRim* other) //call during initialization!
+{
+ otherGrid = other;
+}
+
+
+void CustomGridRim::OnResizeColumn(wxGridSizeEvent& event)
+{
+ //Resize columns on both sides in parallel
+ const int thisCol = event.GetRowOrCol();
+
+ if (!otherGrid || thisCol < 0 || thisCol >= GetNumberCols()) return;
+
+ const xmlAccess::ColumnTypes thisColType = getTypeAtPos(thisCol);
+
+ for (int i = 0; i < otherGrid->GetNumberCols(); ++i)
+ if (otherGrid->getTypeAtPos(i) == thisColType)
+ {
+ otherGrid->SetColSize(i, GetColSize(thisCol));
+ otherGrid->ForceRefresh();
+ break;
+ }
+}
+
+
+//this method is called when grid view changes: useful for parallel updating of multiple grids
+void CustomGridRim::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight)
+{
+ if (!otherGrid) return;
+
+ int x = 0;
+ int y = 0;
+ GetViewStart(&x, &y);
+ gridMiddle->Scroll(-1, y);
+ otherGrid->Scroll(x, y);
+}
template <SelectedSide side>
@@ -1217,21 +1263,25 @@ void CustomGridRim::setTooltip(const wxMouseEvent& event)
}
}
- wxToolTip* tt = GetGridWindow()->GetToolTip();
- if (!tt)
- //wxWidgets bug: tooltip multiline property is defined by first tooltip text containing newlines or not (same is true for maximum width)
- GetGridWindow()->SetToolTip(new wxToolTip(wxT("a b\n\
- a b"))); //ugly, but is working (on Windows)
- tt = GetGridWindow()->GetToolTip(); //should be bound by now
- if (tt && tt->GetTip() != toolTip)
- tt->SetTip(toolTip);
-}
+ wxToolTip* tt = GetGridWindow()->GetToolTip();
-void CustomGridRim::updateGridSizes()
-{
- assert(getGridDataTable());
- getGridDataTable()->updateGridSizes();
+ const wxString currentTip = tt ? tt->GetTip() : wxString();
+ if (toolTip != currentTip)
+ {
+ if (toolTip.IsEmpty())
+ GetGridWindow()->SetToolTip(NULL); //wxGTK doesn't allow wxToolTip with empty text!
+ else
+ {
+ //wxWidgets bug: tooltip multiline property is defined by first tooltip text containing newlines or not (same is true for maximum width)
+ if (!tt)
+ GetGridWindow()->SetToolTip(new wxToolTip(wxT("a b\n\
+ a b"))); //ugly, but is working (on Windows)
+ tt = GetGridWindow()->GetToolTip(); //should be bound by now
+ if (tt)
+ tt->SetTip(toolTip);
+ }
+ }
}
@@ -1353,8 +1403,8 @@ void CustomGridRim::setColumnAttributes(const xmlAccess::ColumnAttributes& attr)
newPositions.push_back(columnSettings[i].type);
//set column positions
- assert(getGridDataTable());
- getGridDataTable()->setupColumns(newPositions);
+ if (getGridDataTableRim())
+ getGridDataTableRim()->setupColumns(newPositions);
//set column width (set them after setupColumns!)
for (size_t i = 0; i < newPositions.size(); ++i)
@@ -1379,8 +1429,10 @@ void CustomGridRim::setColumnAttributes(const xmlAccess::ColumnAttributes& attr)
xmlAccess::ColumnTypes CustomGridRim::getTypeAtPos(size_t pos) const
{
- assert(getGridDataTable());
- return getGridDataTable()->getTypeAtPos(pos);
+ if (getGridDataTableRim())
+ return getGridDataTableRim()->getTypeAtPos(pos);
+ else
+ return xmlAccess::DIRECTORY;
}
@@ -1408,13 +1460,6 @@ wxString CustomGridRim::getTypeName(xmlAccess::ColumnTypes colType)
}
-CustomGridTableRim* CustomGridRim::getGridDataTable()
-{
- //let the non-const call the const version: see Meyers Effective C++
- return const_cast<CustomGridTableRim*>(static_cast<const CustomGridRim*>(this)->getGridDataTable());
-}
-
-
void CustomGridRim::autoSizeColumns() //performance optimized column resizer (analog to wxGrid::AutoSizeColumns()
{
for (int col = 0; col < GetNumberCols(); ++col)
@@ -1474,9 +1519,9 @@ void CustomGridRim::enableFileIcons(const bool value)
fileIconsAreEnabled = value;
if (value)
- SetDefaultRenderer(new GridCellRenderer<true>(loadIconSuccess, getGridDataTable())); //SetDefaultRenderer takes ownership!
+ SetDefaultRenderer(new GridCellRenderer<true>(loadIconSuccess, getGridDataTableRim())); //SetDefaultRenderer takes ownership!
else
- SetDefaultRenderer(new GridCellRenderer<false>(loadIconSuccess, getGridDataTable()));
+ SetDefaultRenderer(new GridCellRenderer<false>(loadIconSuccess, getGridDataTableRim()));
Refresh();
}
@@ -1504,13 +1549,22 @@ CustomGridRim::VisibleRowRange CustomGridRim::getVisibleRows()
}
+inline
+CustomGridTableRim* CustomGridRim::getGridDataTableRim() const
+{
+ return dynamic_cast<CustomGridTableRim*>(getGridDataTable()); //I'm tempted to use a static cast here...
+}
+
+
void CustomGridRim::getIconsToBeLoaded(std::vector<Zstring>& newLoad) //loads all (not yet) drawn icons
{
newLoad.clear();
if (fileIconsAreEnabled) //don't check too often! give worker thread some time to fetch data
{
- const CustomGridTableRim* gridDataTable = getGridDataTable();
+ const CustomGridTableRim* gridDataTable = getGridDataTableRim();
+ if (!gridDataTable) return;
+
const VisibleRowRange rowsOnScreen = getVisibleRows();
const int totalCols = const_cast<CustomGridTableRim*>(gridDataTable)->GetNumberCols();
const int totalRows = const_cast<CustomGridTableRim*>(gridDataTable)->GetNumberRows();
@@ -1596,54 +1650,46 @@ CustomGridLeft::CustomGridLeft(wxWindow *parent,
const wxSize& size,
long style,
const wxString& name) :
- CustomGridRim(parent, id, pos, size, style, name),
- gridDataTable(NULL)
+ CustomGridRim(parent, id, pos, size, style, name)
{
GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridLeft::OnMouseMovement), NULL, this); //row-based tooltip
}
-void CustomGridLeft::OnMouseMovement(wxMouseEvent& event)
-{
- CustomGridRim::setTooltip<LEFT_SIDE>(event);
- event.Skip();
-}
-
-
bool CustomGridLeft::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode)
{
//use custom wxGridTableBase class for management of large sets of formatted data.
//This is done in CreateGrid instead of SetTable method since source code is generated and wxFormbuilder invokes CreatedGrid by default.
- gridDataTable = new CustomGridTableLeft;
- SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
-
+ SetTable(new CustomGridTableLeft, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
return true;
}
-void CustomGridLeft::setGridDataTable(const GridView* gridDataView)
+void CustomGridLeft::initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView)
{
//set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(gridDataView);
+
+ CustomGridRim::setOtherGrid(gridRight);
+
+ CustomGridRim::initSettings(gridLeft, gridMiddle, gridRight, gridDataView);
}
-const CustomGridTableRim* CustomGridLeft::getGridDataTable() const
+void CustomGridLeft::OnMouseMovement(wxMouseEvent& event)
{
- return gridDataTable;
+ CustomGridRim::setTooltip<LEFT_SIDE>(event);
+ event.Skip();
}
-//this method is called when grid view changes: useful for parallel updating of multiple grids
-void CustomGridLeft::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight)
+CustomGridTable* CustomGridLeft::getGridDataTable() const
{
- int x = 0;
- int y = 0;
- GetViewStart(&x, &y);
-
- gridMiddle->Scroll(-1, y); //scroll in y-direction only
- gridRight->Scroll(x, y);
+ return static_cast<CustomGridTable*>(GetTable()); //one of the few cases where no dynamic_cast is required!
}
@@ -1654,51 +1700,44 @@ CustomGridRight::CustomGridRight(wxWindow *parent,
const wxSize& size,
long style,
const wxString& name) :
- CustomGridRim(parent, id, pos, size, style, name),
- gridDataTable(NULL)
+ CustomGridRim(parent, id, pos, size, style, name)
{
GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridRight::OnMouseMovement), NULL, this); //row-based tooltip
}
-void CustomGridRight::OnMouseMovement(wxMouseEvent& event)
-{
- CustomGridRim::setTooltip<RIGHT_SIDE>(event);
- event.Skip();
-}
-
-
bool CustomGridRight::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode)
{
- gridDataTable = new CustomGridTableRight;
- SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
-
+ SetTable(new CustomGridTableRight, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
return true;
}
-void CustomGridRight::setGridDataTable(const GridView* gridDataView)
+void CustomGridRight::initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView)
{
//set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(gridDataView);
+
+ CustomGridRim::setOtherGrid(gridLeft);
+
+ CustomGridRim::initSettings(gridLeft, gridMiddle, gridRight, gridDataView);
}
-const CustomGridTableRim* CustomGridRight::getGridDataTable() const
+void CustomGridRight::OnMouseMovement(wxMouseEvent& event)
{
- return gridDataTable;
+ CustomGridRim::setTooltip<RIGHT_SIDE>(event);
+ event.Skip();
}
-//this method is called when grid view changes: useful for parallel updating of multiple grids
-void CustomGridRight::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight)
+CustomGridTable* CustomGridRight::getGridDataTable() const
{
- int x = 0;
- int y = 0;
- GetViewStart(&x, &y);
- gridLeft->Scroll(x, y);
- gridMiddle->Scroll(-1, y);
+ return static_cast<CustomGridTable*>(GetTable()); //one of the few cases where no dynamic_cast is required!
}
@@ -1706,7 +1745,7 @@ void CustomGridRight::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMidd
class GridCellRendererMiddle : public wxGridCellStringRenderer
{
public:
- GridCellRendererMiddle(const CustomGridMiddle* middleGrid) : m_gridMiddle(middleGrid) {};
+ GridCellRendererMiddle(const CustomGridMiddle& middleGrid) : m_gridMiddle(middleGrid) {};
virtual void Draw(wxGrid& grid,
wxGridCellAttr& attr,
@@ -1716,7 +1755,7 @@ public:
bool isSelected);
private:
- const CustomGridMiddle* const m_gridMiddle;
+ const CustomGridMiddle& m_gridMiddle;
};
@@ -1744,7 +1783,6 @@ CustomGridMiddle::CustomGridMiddle(wxWindow *parent,
selectionPos(BLOCKPOS_CHECK_BOX),
highlightedRow(-1),
highlightedPos(BLOCKPOS_CHECK_BOX),
- gridDataTable(NULL),
toolTip(new CustomTooltip)
{
SetLayoutDirection(wxLayout_LeftToRight); //
@@ -1765,38 +1803,55 @@ CustomGridMiddle::~CustomGridMiddle() {} //non-inline destructor for std::auto_p
bool CustomGridMiddle::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode)
{
- gridDataTable = new CustomGridTableMiddle;
- SetTable(gridDataTable, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
+ SetTable(new CustomGridTableMiddle, true, wxGrid::wxGridSelectRows); //give ownership to wxGrid: gridDataTable is deleted automatically in wxGrid destructor
//display checkboxes (representing bool values) if row is enabled for synchronization
- SetDefaultRenderer(new GridCellRendererMiddle(this)); //SetDefaultRenderer takes ownership!
+ SetDefaultRenderer(new GridCellRendererMiddle(*this)); //SetDefaultRenderer takes ownership!
return true;
}
-#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
-void CustomGridMiddle::SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh)
-{
- wxWindow::SetScrollbar(orientation, 0, 0, 0, refresh);
-}
-#endif
-
-
-void CustomGridMiddle::setGridDataTable(const GridView* gridDataView) //called once on startup
+void CustomGridMiddle::initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView)
{
//set underlying grid data
- assert(gridDataTable);
- gridDataTable->setGridDataTable(gridDataView);
+ assert(getGridDataTable());
+ getGridDataTable()->setGridDataTable(gridDataView);
#ifdef FFS_LINUX //get rid of scrollbars; Linux: change policy for GtkScrolledWindow
GtkWidget* gridWidget = wxWindow::m_widget;
GtkScrolledWindow* scrolledWindow = GTK_SCROLLED_WINDOW(gridWidget);
gtk_scrolled_window_set_policy(scrolledWindow, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
#endif
+
+ CustomGrid::initSettings(gridLeft, gridMiddle, gridRight, gridDataView);
}
+CustomGridTable* CustomGridMiddle::getGridDataTable() const
+{
+ return static_cast<CustomGridTable*>(GetTable()); //one of the few cases where no dynamic_cast is required!
+}
+
+
+inline
+CustomGridTableMiddle* CustomGridMiddle::getGridDataTableMiddle() const
+{
+ return static_cast<CustomGridTableMiddle*>(getGridDataTable());
+}
+
+
+#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
+void CustomGridMiddle::SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh)
+{
+ wxWindow::SetScrollbar(orientation, 0, 0, 0, refresh);
+}
+#endif
+
+
void CustomGridMiddle::OnMouseMovement(wxMouseEvent& event)
{
const int rowOld = highlightedRow;
@@ -1836,14 +1891,17 @@ void CustomGridMiddle::OnLeaveWindow(wxMouseEvent& event)
void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
{
- const FileSystemObject* const fsObj = gridDataTable->getRawData(rowNumber);
+ if (!getGridDataTableMiddle())
+ return;
+
+ const FileSystemObject* const fsObj = getGridDataTableMiddle()->getRawData(rowNumber);
if (fsObj == NULL) //if invalid row...
{
toolTip->hide();
return;
}
- if (gridDataTable->syncPreviewIsActive()) //synchronization preview
+ if (getGridDataTableMiddle()->syncPreviewIsActive()) //synchronization preview
{
const SyncOperation syncOp = fsObj->getSyncOperation();
switch (syncOp)
@@ -1963,6 +2021,9 @@ void CustomGridMiddle::OnLeftMouseUp(wxMouseEvent& event)
int CustomGridMiddle::mousePosToRow(wxPoint pos, BlockPosition* block)
{
+ if (!getGridDataTableMiddle())
+ return 0;
+
int row = -1;
int x = -1;
int y = -1;
@@ -1978,9 +2039,9 @@ int CustomGridMiddle::mousePosToRow(wxPoint pos, BlockPosition* block)
if (row >= 0)
{
- const FileSystemObject* const fsObj = gridDataTable->getRawData(row);
+ const FileSystemObject* const fsObj = getGridDataTableMiddle()->getRawData(row);
if ( fsObj != NULL && //if valid row...
- gridDataTable->syncPreviewIsActive() &&
+ getGridDataTableMiddle()->syncPreviewIsActive() &&
fsObj->getSyncOperation() != SO_EQUAL) //in sync-preview equal files shall be treated as in cmp result, i.e. as full checkbox
{
// cell:
@@ -2012,8 +2073,8 @@ int CustomGridMiddle::mousePosToRow(wxPoint pos, BlockPosition* block)
void CustomGridMiddle::enableSyncPreview(bool value)
{
- assert(gridDataTable);
- gridDataTable->enableSyncPreview(value);
+ assert(getGridDataTableMiddle());
+ getGridDataTableMiddle()->enableSyncPreview(value);
if (value)
GetGridColLabelWindow()->SetToolTip(_("Synchronization Preview"));
@@ -2022,13 +2083,6 @@ void CustomGridMiddle::enableSyncPreview(bool value)
}
-void CustomGridMiddle::updateGridSizes()
-{
- assert(gridDataTable);
- gridDataTable->updateGridSizes();
-}
-
-
void GridCellRendererMiddle::Draw(wxGrid& grid,
wxGridCellAttr& attr,
wxDC& dc,
@@ -2037,12 +2091,12 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
bool isSelected)
{
//retrieve grid data
- const FileSystemObject* const fsObj = m_gridMiddle->gridDataTable->getRawData(row);
+ const FileSystemObject* const fsObj = m_gridMiddle.getGridDataTableMiddle() ? m_gridMiddle.getGridDataTableMiddle()->getRawData(row) : NULL;
if (fsObj != NULL) //if valid row...
{
if (rect.GetWidth() > CHECK_BOX_WIDTH)
{
- const bool rowIsHighlighted = row == m_gridMiddle->highlightedRow;
+ const bool rowIsHighlighted = row == m_gridMiddle.highlightedRow;
wxRect rectShrinked(rect);
@@ -2055,7 +2109,7 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
//HIGHLIGHTNING (checkbox):
if ( rowIsHighlighted &&
- m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
+ m_gridMiddle.highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX)
{
if (fsObj->isActive())
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("checkboxTrueFocus")), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
@@ -2074,14 +2128,14 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
wxGridCellRenderer::Draw(grid, attr, dc, rectShrinked, row, col, isSelected);
//print remaining block
- if (m_gridMiddle->gridDataTable->syncPreviewIsActive()) //synchronization preview
+ if (m_gridMiddle.getGridDataTableMiddle()->syncPreviewIsActive()) //synchronization preview
{
//print sync direction into second block
//HIGHLIGHTNING (sync direction):
if ( rowIsHighlighted &&
- m_gridMiddle->highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX) //don't allow changing direction for "=="-files
- switch (m_gridMiddle->highlightedPos)
+ m_gridMiddle.highlightedPos != CustomGridMiddle::BLOCKPOS_CHECK_BOX) //don't allow changing direction for "=="-files
+ switch (m_gridMiddle.highlightedPos)
{
case CustomGridMiddle::BLOCKPOS_CHECK_BOX:
break;
@@ -2153,9 +2207,12 @@ void CustomGridMiddle::DrawColLabel(wxDC& dc, int col)
{
CustomGrid::DrawColLabel(dc, col);
+ if (!getGridDataTableMiddle())
+ return;
+
const wxRect rect(GetColLeft(col), 0, GetColWidth(col), GetColLabelSize());
- if (gridDataTable->syncPreviewIsActive())
+ if (getGridDataTableMiddle()->syncPreviewIsActive())
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("syncViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
else
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("cmpViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
diff --git a/library/custom_grid.h b/library/custom_grid.h
index 206841dd..193b403d 100644
--- a/library/custom_grid.h
+++ b/library/custom_grid.h
@@ -16,6 +16,7 @@
#include "../file_hierarchy.h"
+class CustomGridTable;
class CustomGridTableRim;
class CustomGridTableLeft;
class CustomGridTableRight;
@@ -62,10 +63,10 @@ public:
virtual ~CustomGrid() {}
- void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
- CustomGridMiddle* gridMiddle,
- CustomGridRight* gridRight,
- const ffs3::GridView* gridDataView);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
void release(); //release connection to ffs3::GridView
@@ -80,6 +81,9 @@ public:
DESCENDING
};
+ //notify wxGrid that underlying table size has changed
+ void updateGridSizes();
+
typedef std::pair<SortColumn, SortDirection> SortMarker;
void setSortMarker(SortMarker marker);
@@ -90,9 +94,9 @@ protected:
virtual void DrawColLabel(wxDC& dc, int col);
std::pair<int, int> mousePosToCell(wxPoint pos); //returns (row/column) pair
-private:
- virtual void setGridDataTable(const ffs3::GridView* gridDataView) = 0;
+ virtual CustomGridTable* getGridDataTable() const = 0;
+private:
//this method is called when grid view changes: useful for parallel updating of multiple grids
void OnPaintGrid(wxEvent& event);
@@ -147,9 +151,6 @@ public:
long style,
const wxString& name);
- //notify wxGrid that underlying table size has changed
- void updateGridSizes();
-
//set visibility, position and width of columns
static xmlAccess::ColumnAttributes getDefaultColumnAttributes();
xmlAccess::ColumnAttributes getColumnAttributes();
@@ -159,7 +160,6 @@ public:
static wxString getTypeName(xmlAccess::ColumnTypes colType);
void autoSizeColumns(); //performance optimized column resizer
- void autoSizeColumns(int col, bool doRefresh = true); //
void enableFileIcons(const bool value);
@@ -167,9 +167,15 @@ protected:
template <ffs3::SelectedSide side>
void setTooltip(const wxMouseEvent& event);
+void setOtherGrid(CustomGridRim* other); //call during initialization!
+
private:
- CustomGridTableRim* getGridDataTable();
- virtual const CustomGridTableRim* getGridDataTable() const = 0;
+ CustomGridTableRim* getGridDataTableRim() const;
+
+void OnResizeColumn(wxGridSizeEvent& event);
+
+ //this method is called when grid view changes: useful for parallel updating of multiple grids
+ virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
//asynchronous icon loading
void getIconsToBeLoaded(std::vector<Zstring>& newLoad); //loads all (not yet) drawn icons
@@ -188,6 +194,7 @@ private:
bool fileIconsAreEnabled;
xmlAccess::ColumnAttributes columnSettings; //set visibility, position and width of columns
+ CustomGridRim* otherGrid; //sibling grid on other side
};
@@ -203,15 +210,14 @@ public:
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
+
private:
void OnMouseMovement(wxMouseEvent& event);
- virtual void setGridDataTable(const ffs3::GridView* gridDataView);
- virtual const CustomGridTableRim* getGridDataTable() const;
-
- //this method is called when grid view changes: useful for parallel updating of multiple grids
- virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
-
- CustomGridTableLeft* gridDataTable;
+ virtual CustomGridTable* getGridDataTable() const;
};
@@ -227,15 +233,14 @@ public:
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
+
private:
void OnMouseMovement(wxMouseEvent& event);
- virtual void setGridDataTable(const ffs3::GridView* gridDataView);
- virtual const CustomGridTableRim* getGridDataTable() const;
-
- //this method is called when grid view changes: useful for parallel updating of multiple grids
- virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
-
- CustomGridTableRight* gridDataTable;
+ virtual CustomGridTable* getGridDataTable() const;
};
@@ -255,18 +260,21 @@ public:
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
- void enableSyncPreview(bool value);
+ virtual void initSettings(CustomGridLeft* gridLeft, //create connection with ffs3::GridView
+ CustomGridMiddle* gridMiddle,
+ CustomGridRight* gridRight,
+ const ffs3::GridView* gridDataView);
- //notify wxGrid that underlying table size has changed
- void updateGridSizes();
+ void enableSyncPreview(bool value);
private:
+ virtual CustomGridTable* getGridDataTable() const;
+ CustomGridTableMiddle* getGridDataTableMiddle() const;
+
#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
virtual void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh = true);
#endif
- virtual void setGridDataTable(const ffs3::GridView* gridDataView);
-
//this method is called when grid view changes: useful for parallel updating of multiple grids
virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
@@ -297,8 +305,6 @@ private:
int highlightedRow;
BlockPosition highlightedPos;
- CustomGridTableMiddle* gridDataTable;
-
std::auto_ptr<CustomTooltip> toolTip;
};
diff --git a/library/db_file.cpp b/library/db_file.cpp
index 195d7df6..a0f5099c 100644
--- a/library/db_file.cpp
+++ b/library/db_file.cpp
@@ -33,8 +33,6 @@ const int FILE_FORMAT_VER = 4;
//-------------------------------------------------------------------------------------------------------------------------------
-//yet another layer of indirection: Since 32/64 bit builds are binary incompatible, we want them to write into "distinct parts" of the db-file
-//just like we were actually accessing different files
class FileInputStreamDB : public FileInputStream
{
public:
diff --git a/library/dir_lock.cpp b/library/dir_lock.cpp
index 54ae8636..f4ed8e07 100644
--- a/library/dir_lock.cpp
+++ b/library/dir_lock.cpp
@@ -12,8 +12,11 @@
#include "../shared/system_constants.h"
#include "../shared/guid.h"
#include "../shared/file_io.h"
+#include "../shared/assert_static.h"
#include <utility>
#include "../shared/serialize.h"
+#include <boost/cstdint.hpp>
+#include "../shared/build_info.h"
#ifdef FFS_WIN
#include <tlhelp32.h>
@@ -205,20 +208,37 @@ Zstring deleteAbandonedLockName(const Zstring& lockfilename)
namespace
{
inline
-wxString readString(wxInputStream& stream) //read string from file stream
+std::string readString(wxInputStream& stream) //read string from file stream
{
- const size_t strLength = util::readNumber<size_t>(stream);
- boost::scoped_array<wxChar> buffer(new wxChar[strLength]);
- stream.Read(buffer.get(), sizeof(wxChar) * strLength);
- return wxString(buffer.get(), strLength);
+ const boost::uint32_t strLength = util::readNumber<boost::uint32_t>(stream);
+ std::string output;
+ if (strLength > 0)
+ {
+ output.resize(strLength);
+ stream.Read(&output[0], strLength);
+ }
+ return output;
}
inline
-void writeString(wxOutputStream& stream, const wxString& str) //write string to filestream
+void writeString(wxOutputStream& stream, const std::string& str) //write string to filestream
+{
+ const boost::uint32_t strLength = static_cast<boost::uint32_t>(str.length());
+ util::writeNumber<boost::uint32_t>(stream, strLength);
+ stream.Write(str.c_str(), strLength);
+}
+
+
+std::string getComputerId() //returns empty string on error
{
- util::writeNumber<size_t>(stream, str.length());
- stream.Write(str.c_str(), sizeof(wxChar) * str.length());
+ const wxString fhn = ::wxGetFullHostName();
+ if (fhn.empty()) return std::string();
+#ifdef FFS_WIN
+ return "Windows " + std::string(fhn.ToUTF8());
+#elif defined FFS_LINUX
+ return "Linux " + std::string(fhn.ToUTF8());
+#endif
}
@@ -227,36 +247,42 @@ struct LockInformation
LockInformation()
{
#ifdef FFS_WIN
- processId = ::GetCurrentProcessId();
+ procDescr.processId = ::GetCurrentProcessId();
#elif defined FFS_LINUX
- processId = ::getpid();
+ procDescr.processId = ::getpid();
#endif
- computerId = ::wxGetFullHostName();
+ procDescr.computerId = getComputerId();
}
LockInformation(wxInputStream& stream) : //read
lockId(util::UniqueId(stream))
{
- processId = util::readNumber<ProcessId>(stream);
- computerId = readString(stream);
+ procDescr.processId = static_cast<ProcessId>(util::readNumber<boost::uint64_t>(stream)); //possible loss of precision (32/64 bit process) covered by buildId
+ procDescr.computerId = readString(stream);
}
void toStream(wxOutputStream& stream) const //write
{
+ assert_static(sizeof(ProcessId) <= sizeof(boost::uint64_t)); //ensure portability
+
lockId.toStream(stream);
- util::writeNumber<ProcessId>(stream, processId);
- writeString(stream, computerId);
+ util::writeNumber<boost::uint64_t>(stream, procDescr.processId);
+ writeString(stream, procDescr.computerId);
}
#ifdef FFS_WIN
- typedef DWORD ProcessId;
+ typedef DWORD ProcessId; //same size on 32 and 64 bit windows!
#elif defined FFS_LINUX
typedef pid_t ProcessId;
#endif
- util::UniqueId lockId;
- ProcessId processId;
- wxString computerId;
+ util::UniqueId lockId; //16 byte portable construct
+
+ struct ProcessDescription
+ {
+ ProcessId processId;
+ std::string computerId;
+ } procDescr;
};
@@ -267,16 +293,17 @@ enum ProcessStatus
PROC_STATUS_RUNNING,
PROC_STATUS_NO_IDEA
};
-ProcessStatus getProcessStatus(LockInformation::ProcessId procId, const wxString& computerId)
+ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDescr)
{
- if (::wxGetFullHostName() != computerId || computerId.empty())
+ if ( procDescr.computerId != getComputerId() ||
+ procDescr.computerId.empty()) //both names are empty
return PROC_STATUS_NO_IDEA; //lock owned by different computer
#ifdef FFS_WIN
//note: ::OpenProcess() is no option as it may successfully return for crashed processes!
HANDLE snapshot = ::CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, //__in DWORD dwFlags,
- procId); //__in DWORD th32ProcessID
+ 0); //__in DWORD th32ProcessID
if (snapshot == INVALID_HANDLE_VALUE)
return PROC_STATUS_NO_IDEA;
boost::shared_ptr<void> dummy(snapshot, ::CloseHandle);
@@ -290,7 +317,7 @@ ProcessStatus getProcessStatus(LockInformation::ProcessId procId, const wxString
do
{
- if (processEntry.th32ProcessID == procId)
+ if (processEntry.th32ProcessID == procDescr.processId)
return PROC_STATUS_RUNNING; //process still running
}
while(::Process32Next(snapshot, &processEntry));
@@ -298,10 +325,10 @@ ProcessStatus getProcessStatus(LockInformation::ProcessId procId, const wxString
return PROC_STATUS_NOT_RUNNING;
#elif defined FFS_LINUX
- if (procId <= 0 || procId >= 65536)
+ if (procDescr.processId <= 0 || procDescr.processId >= 65536)
return PROC_STATUS_NO_IDEA; //invalid process id
- return ffs3::dirExists(Zstr("/proc/") + Zstring::fromNumber(procId)) ? PROC_STATUS_RUNNING : PROC_STATUS_NOT_RUNNING;
+ return ffs3::dirExists(Zstr("/proc/") + Zstring::fromNumber(procDescr.processId)) ? PROC_STATUS_RUNNING : PROC_STATUS_NOT_RUNNING;
#endif
}
@@ -339,7 +366,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
try
{
const LockInformation lockInfo = retrieveLockInfo(lockfilename); //throw (FileError, ErrorNotExisting)
- const bool lockOwnderDead = getProcessStatus(lockInfo.processId, lockInfo.computerId) == PROC_STATUS_NOT_RUNNING; //convenience optimization: if we know the owning process crashed, we needn't wait DETECT_EXITUS_INTERVAL sec
+ const bool lockOwnderDead = getProcessStatus(lockInfo.procDescr) == PROC_STATUS_NOT_RUNNING; //convenience optimization: if we know the owning process crashed, we needn't wait DETECT_EXITUS_INTERVAL sec
wxULongLong fileSizeOld;
wxLongLong lockSilentStart = wxGetLocalTimeMillis();
diff --git a/library/pch.h b/library/pch.h
index 798319c7..f7ff59ab 100644
--- a/library/pch.h
+++ b/library/pch.h
@@ -29,16 +29,24 @@ do NOT use in release build!
//STL headers
#include <string>
-#include <algorithm>
#include <vector>
-#include <queue>
-#include <stack>
#include <set>
#include <map>
+#include <queue>
+#include <deque>
+#include <stack>
+#include <list>
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <numeric>
#include <memory>
+#include <utility>
#include <fstream>
+#include <iostream>
#include <sstream>
#include <new>
+#include <stdexcept>
//other wxWidgets headers
#include <wx/log.h>
diff --git a/shared/IFileOperation/file_op.cpp b/shared/IFileOperation/file_op.cpp
index 6180a561..cc8c58bc 100644
--- a/shared/IFileOperation/file_op.cpp
+++ b/shared/IFileOperation/file_op.cpp
@@ -53,6 +53,7 @@ bool fileop::moveToRecycleBin(const wchar_t* fileNames[],
hr = fileOp->SetOperationFlags(FOF_ALLOWUNDO |
FOF_NOCONFIRMATION |
FOF_SILENT |
+ FOFX_EARLYFAILURE |
FOF_NOERRORUI);
if (FAILED(hr))
{
diff --git a/shared/com_ptr.h b/shared/com_ptr.h
index 1ce7eae6..52a072fa 100644
--- a/shared/com_ptr.h
+++ b/shared/com_ptr.h
@@ -12,7 +12,7 @@
namespace util
{
-/*
+/*
ComPtr: RAII class handling COM objects
Example:
@@ -39,13 +39,20 @@ public:
~ComPtr();
T** init(); //get pointer for use with ::CoCreateInstance()
T* get() const;
- T* release();
+ T* release(); //throw()
void swap(ComPtr& rhs); //throw()
T* operator->() const;
- operator bool() const;
private:
T* ptr;
+
+ struct ConversionToBool
+ {
+ int dummy;
+ };
+
+public:
+ operator int ConversionToBool::*() const; //use member pointer as implicit conversion to bool (C++ Templates - Vandevoorde/Josuttis; chapter 20)
};
@@ -162,12 +169,22 @@ T* ComPtr<T>::operator->() const
}
+/*
template <class T>
inline
ComPtr<T>::operator bool() const
{
return ptr != NULL;
}
+*/
+
+
+template <class T>
+inline
+ComPtr<T>::operator int ComPtr<T>::ConversionToBool::*() const
+{
+ return ptr != NULL ? &ConversionToBool::dummy : NULL;
+}
template <class S, class T>
diff --git a/shared/custom_combo_box.cpp b/shared/custom_combo_box.cpp
index 3c2a118c..18adb38a 100644
--- a/shared/custom_combo_box.cpp
+++ b/shared/custom_combo_box.cpp
@@ -18,12 +18,36 @@ CustomComboBox::CustomComboBox(wxWindow* parent,
const wxValidator& validator,
const wxString& name) :
wxComboBox(parent, id, value, pos, size, n, choices, style, validator, name)
+#if wxCHECK_VERSION(2, 9, 1)
+ , dropDownShown(false)
+#endif
{
//register key event to enable item deletion
this->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CustomComboBox::OnKeyEvent), NULL, this );
+
+#if wxCHECK_VERSION(2, 9, 1)
+ this->Connect(wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEventHandler(CustomComboBox::OnShowDropDown), NULL, this );
+ this->Connect(wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEventHandler(CustomComboBox::OnHideDropDown), NULL, this );
+#endif
+}
+
+
+#if wxCHECK_VERSION(2, 9, 1)
+void CustomComboBox::OnShowDropDown(wxCommandEvent& event)
+{
+ dropDownShown = true;
+ event.Skip();
}
+void CustomComboBox::OnHideDropDown(wxCommandEvent& event)
+{
+ dropDownShown = false;
+ event.Skip();
+}
+#endif
+
+
void CustomComboBox::OnKeyEvent(wxKeyEvent& event)
{
const int keyCode = event.GetKeyCode();
@@ -32,11 +56,16 @@ void CustomComboBox::OnKeyEvent(wxKeyEvent& event)
//try to delete the currently selected config history item
const int selectedItem = this->GetCurrentSelection();
if (0 <= selectedItem && selectedItem < static_cast<int>(this->GetCount()) &&
- (GetValue() != GetString(selectedItem) || //avoid problems when a character shall be deleted instead of list item
- GetValue() == wxEmptyString)) //exception: always allow removing empty entry
- {
- //save old (selected) value: deletion seems to have influence on this
- const wxString currentVal = this->GetValue();
+#if wxCHECK_VERSION(2, 9, 1)
+ dropDownShown)
+#else
+ //what a mess...:
+ (GetValue() != GetString(selectedItem) || //avoid problems when a character shall be deleted instead of list item
+ GetValue() == wxEmptyString)) //exception: always allow removing empty entry
+#endif
+ {
+ //save old (selected) value: deletion seems to have influence on this
+ const wxString currentVal = this->GetValue();
this->SetSelection(wxNOT_FOUND);
//delete selected row
diff --git a/shared/custom_combo_box.h b/shared/custom_combo_box.h
index 7db8cecf..28361a30 100644
--- a/shared/custom_combo_box.h
+++ b/shared/custom_combo_box.h
@@ -29,6 +29,13 @@ public:
private:
void OnKeyEvent(wxKeyEvent& event);
+
+#if wxCHECK_VERSION(2, 9, 1)
+ void OnShowDropDown(wxCommandEvent& event);
+ void OnHideDropDown(wxCommandEvent& event);
+
+ bool dropDownShown;
+#endif
};
diff --git a/shared/custom_tooltip.cpp b/shared/custom_tooltip.cpp
index be2d11b5..5b4e5e40 100644
--- a/shared/custom_tooltip.cpp
+++ b/shared/custom_tooltip.cpp
@@ -34,7 +34,8 @@ CustomTooltip::PopupFrameGenerated::PopupFrameGenerated(
long style ) : wxFrame(parent, id, title, pos, size, style)
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
- this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK));
+ this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); //both required: on Ubuntu background is black, foreground white!
+ this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); //
wxBoxSizer* bSizer158;
bSizer158 = new wxBoxSizer( wxHORIZONTAL );
diff --git a/shared/dir_name.cpp b/shared/dir_name.cpp
index 40e840f5..28c1c413 100644
--- a/shared/dir_name.cpp
+++ b/shared/dir_name.cpp
@@ -52,7 +52,7 @@ void setDirectoryNameImpl(const wxString& dirname, wxDirPickerCtrl* dirPicker, w
const wxString dirFormatted = zToWx(getFormattedDirectoryName(wxToZ(dirname)));
- tooltipWnd.SetToolTip(dirFormatted);
+ tooltipWnd.SetToolTip(dirFormatted); //wxComboBox bug: the edit control is not updated... hope this will be fixed: http://trac.wxwidgets.org/ticket/12659
if (staticBox)
{
diff --git a/shared/file_handling.cpp b/shared/file_handling.cpp
index 5c6ce856..b05b9cf8 100644
--- a/shared/file_handling.cpp
+++ b/shared/file_handling.cpp
@@ -21,6 +21,7 @@
#include "loki/TypeManip.h"
#include "loki/ScopeGuard.h"
#include <map>
+#include "symlink_target.h"
#ifdef FFS_WIN
#include "dll_loader.h"
@@ -36,6 +37,10 @@
#include <utime.h>
#include <cerrno>
#include <sys/time.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
#endif
using ffs3::FileError;
@@ -1129,7 +1134,7 @@ void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, boo
namespace
{
#ifdef FFS_WIN
-Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory
+Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory; throw (FileError)
{
//open handle to target of symbolic link
const HANDLE hDir = ::CreateFile(ffs3::applyLongPathPrefix(dirLinkName).c_str(),
@@ -1140,7 +1145,10 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
FILE_FLAG_BACKUP_SEMANTICS, //needed to open a directory
NULL);
if (hDir == INVALID_HANDLE_VALUE)
- return Zstring();
+ {
+ wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + ffs3::zToWx(dirLinkName) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
boost::shared_ptr<void> dummy(hDir, ::CloseHandle);
@@ -1159,13 +1167,17 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
if (getFinalPathNameByHandle == NULL)
throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\""));
- const DWORD rv = (*getFinalPathNameByHandle)(
+ const DWORD rv = getFinalPathNameByHandle(
hDir, //__in HANDLE hFile,
targetPath, //__out LPTSTR lpszFilePath,
BUFFER_SIZE,//__in DWORD cchFilePath,
0); //__in DWORD dwFlags
if (rv >= BUFFER_SIZE || rv == 0)
- return Zstring();
+ {
+ wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + ffs3::zToWx(dirLinkName) + wxT("\"");
+ if (rv == 0) errorMessage += wxT("\n\n") + ffs3::getLastErrorFormatted();
+ throw FileError(errorMessage);
+ }
return targetPath;
}
@@ -1351,6 +1363,58 @@ void Privileges::setPrivilege(LPCTSTR privilege, bool enable) //throw FileError(
}
+#ifdef HAVE_SELINUX
+//copy SELinux security context
+void copySecurityContext(const Zstring& source, const Zstring& target, bool derefSymlinks) //throw FileError()
+{
+ using ffs3::zToWx;
+
+ security_context_t contextSource = NULL;
+ const int rv = derefSymlinks ?
+ ::getfilecon (source.c_str(), &contextSource) :
+ ::lgetfilecon(source.c_str(), &contextSource);
+ if (rv < 0)
+ {
+ if ( errno == ENODATA || //no security context (allegedly) is not an error condition on SELinux
+ errno == EOPNOTSUPP) //extended attributes are not supported by the filesystem
+ return;
+
+ wxString errorMessage = wxString(_("Error reading security context:")) + wxT("\n\"") + zToWx(source) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+ boost::shared_ptr<char> dummy1(contextSource, ::freecon);
+
+ {
+ security_context_t contextTarget = NULL;
+ const int rv2 = derefSymlinks ?
+ ::getfilecon (target.c_str(), &contextTarget) :
+ ::lgetfilecon(target.c_str(), &contextTarget);
+ if (rv2 < 0)
+ {
+ if (errno == EOPNOTSUPP)
+ return;
+ //else: still try to set security context
+ }
+ else
+ {
+ boost::shared_ptr<char> dummy2(contextTarget, ::freecon);
+ if (::strcmp(contextSource, contextTarget) == 0) //nothing to do
+ return;
+ }
+ }
+
+ const int rv3 = derefSymlinks ?
+ ::setfilecon (target.c_str(), contextSource) :
+ ::lsetfilecon(target.c_str(), contextSource);
+ if (rv3 < 0)
+ {
+ wxString errorMessage = wxString(_("Error writing security context:")) + wxT("\n\"") + zToWx(target) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+}
+#endif //HAVE_SELINUX
+
+
//copy permissions for files, directories or symbolic links
void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, bool derefSymlinks) //throw FileError(); probably requires admin rights
{
@@ -1379,8 +1443,10 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
FILE_FLAG_BACKUP_SEMANTICS | (derefSymlinks ? 0 : FILE_FLAG_OPEN_REPARSE_POINT), //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory
NULL);
if (hSource == INVALID_HANDLE_VALUE)
- throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(source) + wxT("\"") +
- wxT("\n\n") + ffs3::getLastErrorFormatted());
+ {
+ const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (OR)"));
+ }
boost::shared_ptr<void> dummy(hSource, ::CloseHandle);
// DWORD rc = ::GetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(source).c_str()), -> does NOT dereference symlinks!
@@ -1396,7 +1462,7 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
if (rc != ERROR_SUCCESS)
{
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
- throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc));
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc) + wxT(" (R)"));
}
boost::shared_ptr<void> dummy2(buffer, ::LocalFree);
@@ -1413,7 +1479,7 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
resetAttributes.Dismiss();
- HANDLE hTarget = ::CreateFile( targetFmt.c_str(), // lpFileName
+ const HANDLE hTarget = ::CreateFile( targetFmt.c_str(), // lpFileName
FILE_GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY, // dwDesiredAccess: all four seem to be required!!!
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // dwShareMode
NULL, // lpSecurityAttributes
@@ -1421,8 +1487,10 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
FILE_FLAG_BACKUP_SEMANTICS | (derefSymlinks ? 0 : FILE_FLAG_OPEN_REPARSE_POINT), // dwFlagsAndAttributes
NULL); // hTemplateFile
if (hTarget == INVALID_HANDLE_VALUE)
- throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(target) + wxT("\"") +
- wxT("\n\n") + ffs3::getLastErrorFormatted());
+ {
+ const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (OW)"));
+ }
boost::shared_ptr<void> dummy3(hTarget, ::CloseHandle);
// rc = ::SetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(target).c_str()), //__in LPTSTR pObjectName, -> does NOT dereference symlinks!
@@ -1438,10 +1506,15 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
if (rc != ERROR_SUCCESS)
{
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
- throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc));
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc) + wxT(" (W)"));
}
#elif defined FFS_LINUX
+
+#ifdef HAVE_SELINUX //copy SELinux security context
+ copySecurityContext(source, target, derefSymlinks); //throw FileError()
+#endif
+
if (derefSymlinks)
{
struct stat fileInfo;
@@ -1450,7 +1523,7 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
::chmod(target.c_str(), fileInfo.st_mode) != 0)
{
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
- throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (R)"));
}
}
else
@@ -1461,7 +1534,7 @@ void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, b
(!symlinkExists(target) && ::chmod(target.c_str(), fileInfo.st_mode) != 0)) //setting access permissions doesn't make sense for symlinks on Linux: there is no lchmod()
{
const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
- throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted() + wxT(" (W)"));
}
}
#endif
@@ -1518,39 +1591,74 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
const bool isSymlink = (templateAttr & FILE_ATTRIBUTE_REPARSE_POINT) != 0; //syntax required to shut MSVC up
//symbolic link handling
- if (!copyDirectorySymLinks && isSymlink) //create directory based on target of symbolic link
+ if (isSymlink)
{
- //get target directory of symbolic link
- const Zstring linkPath = resolveDirectorySymlink(templateDir);
- if (linkPath.empty())
+ if (!copyDirectorySymLinks) //create directory based on target of symbolic link
{
- if (level != 0) return;
- throw FileError(wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\""));
- }
+ //get target directory of symbolic link
+ Zstring linkPath;
+ try
+ {
+ linkPath = resolveDirectorySymlink(templateDir); //throw (FileError)
+ }
+ catch (FileError&)
+ {
+ //dereferencing a symbolic link usually fails if it is located on network drive or client is XP: NOT really an error...
+ if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
+ NULL))
+ {
+ if (level != 0) return;
+ const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+ return;
+ }
- if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
- applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
- applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL))
+ if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
+ applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
+ applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
+ NULL))
+ {
+ if (level != 0) return;
+ const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+ }
+ else //copy symbolic link
{
- if (level != 0) return;
- const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ const Zstring linkPath = getSymlinkRawTargetString(templateDir); //accept broken symlinks; throw (FileError)
+
+ //dynamically load windows API function
+ typedef BOOLEAN (WINAPI *CreateSymbolicLinkFunc)(
+ LPCTSTR lpSymlinkFileName,
+ LPCTSTR lpTargetFileName,
+ DWORD dwFlags);
+ static const CreateSymbolicLinkFunc createSymbolicLink = util::getDllFun<CreateSymbolicLinkFunc>(L"kernel32.dll", "CreateSymbolicLinkW");
+ if (createSymbolicLink == NULL)
+ throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("CreateSymbolicLinkW") + wxT("\""));
+
+ if (!createSymbolicLink( //seems no long path prefix is required...
+ directory.c_str(), //__in LPTSTR lpSymlinkFileName,
+ linkPath.c_str(), //__in LPTSTR lpTargetFileName,
+ SYMBOLIC_LINK_FLAG_DIRECTORY)) //__in DWORD dwFlags
+ {
+ //if (level != 0) return;
+ const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\" ->\n\"") + directory.c_str() + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
}
}
- else //in all other cases
+ else //no symbolic link
{
- if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
+ //automatically copies symbolic links if encountered: unfortunately it doesn't copy symlinks over network shares but silently creates empty folders instead (on XP)!
+ //also it isn't able to copy most junctions because of missing permissions (although target path can be retrieved!)
+ if (!::CreateDirectoryEx(
applyLongPathPrefix(templateDir).c_str(), // pointer to path string of template directory
applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
NULL))
{
if (level != 0) return;
- const wxString errorMessage = isSymlink ?
- //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("\""));
+ const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
@@ -1868,7 +1976,6 @@ void ffs3::copyFile(const Zstring& sourceFile,
//invoke callback method to update progress indicators
if (callback != NULL)
- {
switch (callback->updateCopyStatus(totalBytesTransferred))
{
case CopyFileCallback::CONTINUE:
@@ -1878,7 +1985,6 @@ void ffs3::copyFile(const Zstring& sourceFile,
throw FileError(wxString(_("Error copying file:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\" ->\n\"") +
zToWx(targetFile) + wxT("\"\n\n") + _("Operation aborted!"));
}
- }
}
while (!fileIn.eof());
diff --git a/shared/file_io.cpp b/shared/file_io.cpp
index 95c14c49..78796bbe 100644
--- a/shared/file_io.cpp
+++ b/shared/file_io.cpp
@@ -12,7 +12,7 @@
#ifdef FFS_WIN
#include "long_path_prefix.h"
#elif defined FFS_LINUX
-#include <errno.h>
+#include <cerrno>
#endif
using namespace ffs3;
diff --git a/shared/file_traverser.cpp b/shared/file_traverser.cpp
index 5d3f75f4..f2b531e9 100644
--- a/shared/file_traverser.cpp
+++ b/shared/file_traverser.cpp
@@ -5,18 +5,16 @@
// **************************************************************************
//
#include "file_traverser.h"
+#include <limits>
#include "system_constants.h"
#include "system_func.h"
#include <wx/intl.h>
#include "string_conv.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/scoped_array.hpp>
#include "assert_static.h"
-#include <limits>
+#include "symlink_target.h"
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include "WinIoCtl.h"
#include "long_path_prefix.h"
#include "dst_hack.h"
@@ -27,130 +25,6 @@
#endif
-//Note: this class is superfluous for 64 bit applications!
-//class DisableWow64Redirection
-//{
-//public:
-// DisableWow64Redirection() :
-// wow64DisableWow64FsRedirection(util::getDllFun<Wow64DisableWow64FsRedirectionFunc>(L"kernel32.dll", "Wow64DisableWow64FsRedirection")),
-// wow64RevertWow64FsRedirection(util::getDllFun<Wow64RevertWow64FsRedirectionFunc>(L"kernel32.dll", "Wow64RevertWow64FsRedirection")),
-// oldValue(NULL)
-// {
-// if ( wow64DisableWow64FsRedirection &&
-// wow64RevertWow64FsRedirection)
-// (*wow64DisableWow64FsRedirection)(&oldValue); //__out PVOID *OldValue
-// }
-//
-// ~DisableWow64Redirection()
-// {
-// if ( wow64DisableWow64FsRedirection &&
-// wow64RevertWow64FsRedirection)
-// (*wow64RevertWow64FsRedirection)(oldValue); //__in PVOID OldValue
-// }
-//
-//private:
-// typedef BOOL (WINAPI *Wow64DisableWow64FsRedirectionFunc)(PVOID* OldValue);
-// typedef BOOL (WINAPI *Wow64RevertWow64FsRedirectionFunc)(PVOID OldValue);
-//
-// const Wow64DisableWow64FsRedirectionFunc wow64DisableWow64FsRedirection;
-// const Wow64RevertWow64FsRedirectionFunc wow64RevertWow64FsRedirection;
-//
-// PVOID oldValue;
-//};
-
-#ifdef _MSC_VER //I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structures and cross fingers...
-typedef struct _REPARSE_DATA_BUFFER
-{
- ULONG ReparseTag;
- USHORT ReparseDataLength;
- USHORT Reserved;
- union
- {
- struct
- {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- ULONG Flags;
- WCHAR PathBuffer[1];
- } SymbolicLinkReparseBuffer;
- struct
- {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- WCHAR PathBuffer[1];
- } MountPointReparseBuffer;
- struct
- {
- UCHAR DataBuffer[1];
- } GenericReparseBuffer;
- };
-} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
-#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
-#endif
-
-
-Zstring getSymlinkTarget(const Zstring& linkPath) //throw(); returns empty string on error
-{
-#ifdef FFS_WIN
-//FSCTL_GET_REPARSE_POINT: http://msdn.microsoft.com/en-us/library/aa364571(VS.85).aspx
-
- const HANDLE hLink = ::CreateFile(linkPath.c_str(),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
- NULL);
- if (hLink == INVALID_HANDLE_VALUE)
- return Zstring();
-
- boost::shared_ptr<void> dummy(hLink, ::CloseHandle);
-
- //respect alignment issues...
- const size_t bufferSize = REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
- boost::scoped_array<char> buffer(new char[bufferSize]);
-
- DWORD bytesReturned; //dummy value required by FSCTL_GET_REPARSE_POINT!
- if (!::DeviceIoControl(hLink, //__in HANDLE hDevice,
- FSCTL_GET_REPARSE_POINT, //__in DWORD dwIoControlCode,
- NULL, //__in_opt LPVOID lpInBuffer,
- 0, //__in DWORD nInBufferSize,
- buffer.get(), //__out_opt LPVOID lpOutBuffer,
- bufferSize, //__in DWORD nOutBufferSize,
- &bytesReturned, //__out_opt LPDWORD lpBytesReturned,
- NULL)) //__inout_opt LPOVERLAPPED lpOverlapped
- return Zstring();
-
- REPARSE_DATA_BUFFER& reparseData = *reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer.get()); //REPARSE_DATA_BUFFER needs to be artificially enlarged!
-
- if (reparseData.ReparseTag == IO_REPARSE_TAG_SYMLINK)
- return Zstring(reparseData.SymbolicLinkReparseBuffer.PathBuffer + reparseData.SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
- reparseData.SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR));
- else if (reparseData.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
- return Zstring(reparseData.MountPointReparseBuffer.PathBuffer + reparseData.MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
- reparseData.MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR));
- else
- return Zstring(); //unknown reparse point
-
-#elif defined FFS_LINUX
- const int BUFFER_SIZE = 10000;
- char buffer[BUFFER_SIZE];
-
- const int bytesWritten = ::readlink(linkPath.c_str(), buffer, BUFFER_SIZE);
- if (bytesWritten < 0 || bytesWritten >= BUFFER_SIZE)
- return Zstring(); //error
-
- buffer[bytesWritten] = 0; //set null-terminating char
-
- return buffer;
-#endif
-}
-
-
#ifdef FFS_WIN
inline
wxLongLong getWin32TimeInformation(const FILETIME& lastWriteTime)
@@ -292,8 +166,13 @@ private:
if (isSymbolicLink && !followSymlinks) //evaluate symlink directly
{
TraverseCallback::SymlinkInfo details;
+ try
+ {
+ details.targetPath = getSymlinkRawTargetString(fullName); //throw (FileError)
+ }
+ catch (FileError&) {}
+
details.lastWriteTimeRaw = getWin32TimeInformation(fileMetaData.ftLastWriteTime);
- details.targetPath = getSymlinkTarget(fullName); //throw(); returns empty string on error
details.dirLink = (fileMetaData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; //directory symlinks have this flag on Windows
sink.onSymlink(shortName, fullName, details);
}
@@ -418,8 +297,13 @@ private:
else //evaluate symlink directly
{
TraverseCallback::SymlinkInfo details;
+ try
+ {
+ details.targetPath = getSymlinkRawTargetString(fullName); //throw (FileError)
+ }
+ catch (FileError&) {}
+
details.lastWriteTimeRaw = fileInfo.st_mtime; //UTC time(ANSI C format); unit: 1 second
- details.targetPath = getSymlinkTarget(fullName); //throw(); returns empty string on error
details.dirLink = ::stat(fullName.c_str(), &fileInfo) == 0 && S_ISDIR(fileInfo.st_mode); //S_ISDIR and S_ISLNK are mutually exclusive on Linux => need to follow link
sink.onSymlink(shortName, fullName, details);
continue;
diff --git a/shared/global_func.h b/shared/global_func.h
index c3994ca0..20221f63 100644
--- a/shared/global_func.h
+++ b/shared/global_func.h
@@ -192,7 +192,7 @@ template <class ForwardIterator, class T, typename Compare>
inline
ForwardIterator common::custom_binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp)
{
- first = lower_bound(first, last, value, comp);
+ first = std::lower_bound(first, last, value, comp);
if (first != last && !comp(value, *first))
return first;
else
diff --git a/shared/localization.cpp b/shared/localization.cpp
index ef3e02d2..ae9b5143 100644
--- a/shared/localization.cpp
+++ b/shared/localization.cpp
@@ -48,7 +48,7 @@ const std::vector<ffs3::LocInfoLine>& LocalizationInfo::getMapping()
namespace
{
-struct CompareByName
+ struct CompareByName : public std::binary_function<ffs3::LocInfoLine, ffs3::LocInfoLine, bool>
{
bool operator()(const ffs3::LocInfoLine& lhs, const ffs3::LocInfoLine& rhs) const
{
@@ -121,7 +121,7 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageID = wxLANGUAGE_DUTCH;
newEntry.languageName = wxT("Nederlands");
newEntry.languageFile = wxT("dutch.lng");
- newEntry.translatorName = wxT("Mikhail Frolov");
+ newEntry.translatorName = wxT("Dion van Lieshout");
newEntry.languageFlag = wxT("holland.png");
locMapping.push_back(newEntry);
@@ -184,7 +184,7 @@ LocalizationInfo::LocalizationInfo()
newEntry.languageID = wxLANGUAGE_TURKISH;
newEntry.languageName = wxT("Türkçe");
newEntry.languageFile = wxT("turkish.lng");
- newEntry.translatorName = wxT("H.Barbaros BIÇAKCI");
+ newEntry.translatorName = wxT("Kaya Zeren");
newEntry.languageFlag = wxT("turkey.png");
locMapping.push_back(newEntry);
@@ -481,7 +481,7 @@ private:
};
-void CustomLocale::setLanguage(const int language)
+void CustomLocale::setLanguage(int language)
{
currentLanguage = language;
@@ -544,3 +544,24 @@ const wxChar* CustomLocale::GetString(const wxChar* szOrigString, const wxChar*
//fallback
return szOrigString;
}
+
+
+
+/*
+
+wxWidgets 2.9.1:
+
+class CustomTranslation : public wxTranslations
+{
+ virtual const wxString& GetString(const wxString& origString,
+ const wxString& domain = wxEmptyString) const
+ {
+ static const wxString blah = "map origString to translation by some arbitrary means";
+ return blah;
+ }
+
+ wxTranslations::Set(new CustomTranslation);
+
+};
+
+*/
diff --git a/shared/localization.h b/shared/localization.h
index 1c1773e9..9435030d 100644
--- a/shared/localization.h
+++ b/shared/localization.h
@@ -49,7 +49,7 @@ class CustomLocale : public wxLocale
public:
static CustomLocale& getInstance();
- void setLanguage(const int language);
+ void setLanguage(int language);
int getLanguage() const
{
diff --git a/shared/recycler.cpp b/shared/recycler.cpp
index 31257a65..2ee23462 100644
--- a/shared/recycler.cpp
+++ b/shared/recycler.cpp
@@ -88,11 +88,13 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (
using namespace fileop;
- static const MoveToRecycleBinFct moveToRecycler =
- util::getDllFun<MoveToRecycleBinFct>(getRecyclerDllName().c_str(), moveToRecycleBinFctName);
+ static MoveToRecycleBinFct moveToRecycler = NULL;
+ if (!moveToRecycler)
+ moveToRecycler = util::getDllFun<MoveToRecycleBinFct>(getRecyclerDllName().c_str(), moveToRecycleBinFctName);
- static const GetLastErrorFct getLastError =
- util::getDllFun<GetLastErrorFct>(getRecyclerDllName().c_str(), getLastErrorFctName);
+ static GetLastErrorFct getLastError = NULL;
+ if (!getLastError)
+ getLastError = util::getDllFun<GetLastErrorFct>(getRecyclerDllName().c_str(), getLastErrorFctName);
if (moveToRecycler == NULL || getLastError == NULL)
throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + fileNames[0] + wxT("\"\n\n") + //report first file only... better than nothing
diff --git a/shared/serialize.cpp b/shared/serialize.cpp
index cf6d96b1..f5765d3d 100644
--- a/shared/serialize.cpp
+++ b/shared/serialize.cpp
@@ -51,5 +51,3 @@ void WriteOutputStream::writeArrayC(const std::vector<char>& buffer) const
throwWriteError();
}
}
-
-
diff --git a/shared/serialize.h b/shared/serialize.h
index 7c4fcd5e..5f1d5fbf 100644
--- a/shared/serialize.h
+++ b/shared/serialize.h
@@ -12,6 +12,7 @@
#include "file_error.h"
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/cstdint.hpp>
namespace util
{
@@ -126,7 +127,7 @@ void writeNumber(wxOutputStream& stream, T number)
inline
-Zstring readString(wxInputStream& stream) //read string from file stream
+Zstring readString(wxInputStream& stream)
{
const size_t strLength = readNumber<size_t>(stream);
if (strLength <= 1000)
@@ -145,7 +146,7 @@ Zstring readString(wxInputStream& stream) //read string from file stream
inline
-void writeString(wxOutputStream& stream, const Zstring& str) //write string to filestream
+void writeString(wxOutputStream& stream, const Zstring& str)
{
writeNumber<size_t>(stream, str.length());
stream.Write(str.c_str(), sizeof(Zchar) * str.length());
diff --git a/shared/signal_processing.h b/shared/signal_processing.h
deleted file mode 100644
index 857d0b12..00000000
--- a/shared/signal_processing.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
-// **************************************************************************
-//
-#include <algorithm>
-#include <limits>
-#include <numeric>
-
-
-namespace util
-{
-template <class T>
-T abs(T value);
-
-int round(double d); //little rounding function
-
-template <class T>
-bool isNull(T number);
-
-//----------------------------------------------------------------------------------
-// smoothen data ranges through a window around each data point |
-//----------------------------------------------------------------------------------
-template <class InputIterator, class OutputIterator>
-void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize); //default implementation: averaging
-
-template <class InputIterator, class OutputIterator, class DataProcessor>
-void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize, DataProcessor proc);
-/*
-DataProcessor is an abstraction for data evaluation. A valid implementation needs to support three properties:
-- add data entry at window front: operator+=(ValueType value)
-- remove data entry at window back: operator-=(ValueType value)
-- evaluate smoothed middle value: ValueType operator()(size_t windowSize)
-*/
-//----------------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//################# inline implementation #########################
-template <class T>
-inline
-T abs(T value)
-{
- return value < 0 ? -value : value;
-}
-
-
-template <class T>
-inline
-bool isNull(T value)
-{
- return abs(number) <= std::numeric_limits<T>::epsilon(); //epsilon == 0 for integer types, therefore less-equal(!)
-}
-
-
-inline
-int round(double d)
-{
- return static_cast<int>(d < 0 ? d - .5 : d + .5);
-}
-
-
-template <class InputIterator, class OutputIterator, class DataProcessor>
-inline
-void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize, DataProcessor proc)
-{
- windowSize = std::min(windowSize, static_cast<size_t>(last - first)); //std::distance() not used to enforce random access iterator requirement
-
- if (windowSize <= 1)
- {
- std::copy(first, last, result);
- return;
- }
-
- const size_t firstHalf = windowSize / 2;
- const size_t secondHalf = windowSize - firstHalf;
-
- //preparation
- for (InputIterator i = first; i != first + secondHalf; ++i)
- proc += *i;
-
- //beginning
- for (InputIterator i = first; i != first + firstHalf; ++i)
- {
- *result++ = proc(i - first + secondHalf);
- proc += *(i + secondHalf);
- }
-
- //main
- for (InputIterator i = first + firstHalf; i != last - secondHalf; ++i)
- {
- *result++ = proc(windowSize);
- proc += *(i + secondHalf);
- proc -= *(i - firstHalf);
- }
-
- //ending
- for (InputIterator i = last - secondHalf; i != last; ++i)
- {
- *result++ = proc(windowSize - (i - last + secondHalf));
- proc -= *(i - firstHalf);
- }
-}
-
-
-template <class ValueType>
-class ProcessorAverage
-{
-public:
- ProcessorAverage() : valueAcc() {}
-
- //add front data entry
- ProcessorAverage& operator+=(ValueType value)
- {
- valueAcc += value;
- return *this;
- }
-
- //remove rear data entry
- ProcessorAverage& operator-=(ValueType value)
- {
- valueAcc -= value;
- return *this;
- }
-
- //evaluate smoothed value
- ValueType operator()(size_t windowSize) const
- {
- return valueAcc / windowSize;
- }
-
-private:
- ValueType valueAcc; //accumulated values
-};
-
-
-
-template <class InputIterator, class OutputIterator>
-inline
-void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize)
-{
- typedef typename std::iterator_traits<InputIterator>::value_type ValueType;
- smoothen(first, last, result, windowSize, ProcessorAverage<ValueType>());
-}
-
-} \ No newline at end of file
diff --git a/shared/symlink_target.h b/shared/symlink_target.h
new file mode 100644
index 00000000..c68d5229
--- /dev/null
+++ b/shared/symlink_target.h
@@ -0,0 +1,146 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef SYMLINK_WIN_H_INCLUDED
+#define SYMLINK_WIN_H_INCLUDED
+
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_array.hpp>
+#include "system_func.h"
+#include <wx/intl.h>
+#include "string_conv.h"
+#include "file_error.h"
+
+#ifdef FFS_WIN
+#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "WinIoCtl.h"
+#include "long_path_prefix.h"
+
+#elif defined FFS_LINUX
+#include <unistd.h>
+#endif
+
+
+#ifdef _MSC_VER //I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structures and cross fingers...
+typedef struct _REPARSE_DATA_BUFFER
+{
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union
+ {
+ struct
+ {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct
+ {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct
+ {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
+#endif
+
+namespace
+{
+ //retrieve raw target data of symlink or junction
+Zstring getSymlinkRawTargetString(const Zstring& linkPath) //throw (FileError)
+{
+ using ffs3::zToWx;
+ using ffs3::FileError;
+#ifdef FFS_WIN
+//FSCTL_GET_REPARSE_POINT: http://msdn.microsoft.com/en-us/library/aa364571(VS.85).aspx
+
+ const HANDLE hLink = ::CreateFile(ffs3::applyLongPathPrefix(linkPath).c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
+ NULL);
+ if (hLink == INVALID_HANDLE_VALUE)
+ {
+ wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + ffs3::zToWx(linkPath) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+ boost::shared_ptr<void> dummy(hLink, ::CloseHandle);
+
+ //respect alignment issues...
+ const size_t bufferSize = REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
+ boost::scoped_array<char> buffer(new char[bufferSize]);
+
+ DWORD bytesReturned; //dummy value required by FSCTL_GET_REPARSE_POINT!
+ if (!::DeviceIoControl(hLink, //__in HANDLE hDevice,
+ FSCTL_GET_REPARSE_POINT, //__in DWORD dwIoControlCode,
+ NULL, //__in_opt LPVOID lpInBuffer,
+ 0, //__in DWORD nInBufferSize,
+ buffer.get(), //__out_opt LPVOID lpOutBuffer,
+ bufferSize, //__in DWORD nOutBufferSize,
+ &bytesReturned, //__out_opt LPDWORD lpBytesReturned,
+ NULL)) //__inout_opt LPOVERLAPPED lpOverlapped
+ {
+ wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + ffs3::zToWx(linkPath) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+
+ REPARSE_DATA_BUFFER& reparseData = *reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer.get()); //REPARSE_DATA_BUFFER needs to be artificially enlarged!
+
+ Zstring output;
+ if (reparseData.ReparseTag == IO_REPARSE_TAG_SYMLINK)
+ {
+ output = Zstring(reparseData.SymbolicLinkReparseBuffer.PathBuffer + reparseData.SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
+ reparseData.SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR));
+ }
+ else if (reparseData.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
+ {
+ output = Zstring(reparseData.MountPointReparseBuffer.PathBuffer + reparseData.MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
+ reparseData.MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR));
+ }
+ else
+ {
+ wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + ffs3::zToWx(linkPath) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + wxT("Not a symbolic link or junction!"));
+ }
+
+ //absolute symlinks and junctions technically start with \??\ while relative ones do not
+ if (output.StartsWith(Zstr("\\??\\")))
+ output = Zstring(output.c_str() + 4, output.length() - 4);
+
+ return output;
+
+#elif defined FFS_LINUX
+ const int BUFFER_SIZE = 10000;
+ char buffer[BUFFER_SIZE];
+
+ const int bytesWritten = ::readlink(linkPath.c_str(), buffer, BUFFER_SIZE);
+ if (bytesWritten < 0 || bytesWritten >= BUFFER_SIZE)
+ {
+ wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + zToWx(linkPath) + wxT("\"");
+ if (bytesWritten < 0) errorMessage += wxString(wxT("\n\n")) + ffs3::getLastErrorFormatted();
+ throw FileError(errorMessage);
+ }
+ buffer[bytesWritten] = 0; //set null-terminating char
+
+ return buffer;
+#endif
+}
+}
+
+#endif // SYMLINK_WIN_H_INCLUDED
diff --git a/shared/system_func.cpp b/shared/system_func.cpp
index 71335d71..4f60f724 100644
--- a/shared/system_func.cpp
+++ b/shared/system_func.cpp
@@ -25,11 +25,20 @@ wxString ffs3::getLastErrorFormatted(unsigned long lastError) //try to get addit
wxString output = wxString(wxT("Windows Error Code ")) + wxString::Format(wxT("%u"), lastError);
- WCHAR buffer[1001];
- if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0, lastError, 0, buffer, 1001, NULL) != 0)
- output += wxString(wxT(": ")) + buffer;
+ LPWSTR buffer = NULL;
+ if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK |
+ FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders
+ FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastError, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL) != 0)
+ {
+ if (buffer) //just to be sure
+ {
+ output += wxString(wxT(": ")) + buffer;
+ ::LocalFree(buffer);
+ }
+ }
+ ::SetLastError(lastError); //restore last error
- ::SetLastError(lastError); //restore last error
return output;
}
diff --git a/shared/zbase.h b/shared/zbase.h
index efaa103c..1caf0e44 100644
--- a/shared/zbase.h
+++ b/shared/zbase.h
@@ -289,22 +289,22 @@ private:
};
template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> bool operator==(const T* lhs, const Zbase<T, SP, AP>& rhs);
+template <class T, template <class, class> class SP, class AP> bool operator==(const Zbase<T, SP, AP>& lhs, const T* rhs);
+template <class T, template <class, class> class SP, class AP> bool operator==(const T* lhs, const Zbase<T, SP, AP>& rhs);
template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> bool operator!=(const T* lhs, const Zbase<T, SP, AP>& rhs);
+template <class T, template <class, class> class SP, class AP> bool operator!=(const Zbase<T, SP, AP>& lhs, const T* rhs);
+template <class T, template <class, class> class SP, class AP> bool operator!=(const T* lhs, const Zbase<T, SP, AP>& rhs);
template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> bool operator< (const T* lhs, const Zbase<T, SP, AP>& rhs);
+template <class T, template <class, class> class SP, class AP> bool operator< (const Zbase<T, SP, AP>& lhs, const T* rhs);
+template <class T, template <class, class> class SP, class AP> bool operator< (const T* lhs, const Zbase<T, SP, AP>& rhs);
template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const T* rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const T* lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+( T lhs, const Zbase<T, SP, AP>& rhs);
-template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, T rhs);
+template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, const T* rhs);
+template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const T* lhs, const Zbase<T, SP, AP>& rhs);
+template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+( T lhs, const Zbase<T, SP, AP>& rhs);
+template <class T, template <class, class> class SP, class AP> const Zbase<T, SP, AP> operator+(const Zbase<T, SP, AP>& lhs, T rhs);
diff --git a/synchronization.cpp b/synchronization.cpp
index a64952b3..493bf077 100644
--- a/synchronization.cpp
+++ b/synchronization.cpp
@@ -1421,15 +1421,13 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf
for (SyncStatistics::ConflictTexts::const_iterator i = firstConflicts.begin(); i != firstConflicts.end(); ++i)
{
wxString conflictDescription = i->second;
- conflictDescription.Replace(wxT("\n"), wxT(" ")); //remove line-breaks
+ //conflictDescription.Replace(wxT("\n"), wxT(" ")); //remove line-breaks
- warningMessage += wxString(wxT("\"")) + zToWx(i->first) + wxT("\": ") + conflictDescription + wxT("\n");
+ warningMessage += wxString(wxT("\"")) + zToWx(i->first) + wxT("\": ") + conflictDescription + wxT("\n\n");
}
if (statisticsTotal.getConflict() > static_cast<int>(firstConflicts.size()))
- warningMessage += wxT("[...]\n");
- else
- warningMessage += wxT("\n");
+ warningMessage += wxT("[...]\n\n");
warningMessage += _("You can ignore conflicts and continue synchronization.");
@@ -1475,6 +1473,7 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf
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("\"");
diff --git a/ui/batch_status_handler.cpp b/ui/batch_status_handler.cpp
index c3dfc8df..1bcc4b33 100644
--- a/ui/batch_status_handler.cpp
+++ b/ui/batch_status_handler.cpp
@@ -22,9 +22,9 @@ using namespace ffs3;
class LogFile
{
public:
- LogFile(const wxString& logfileDirectory, const wxString& batchFilename) //throw (FileError&)
+ LogFile(const wxString& logfileDirectory, const wxString& jobName) //throw (FileError&)
{
- const wxString logfileName = findUniqueLogname(logfileDirectory, batchFilename);
+ const wxString logfileName = findUniqueLogname(logfileDirectory, jobName);
logFile.Open(logfileName, wxT("w"));
if (!logFile.IsOpened())
@@ -66,17 +66,7 @@ public:
}
private:
- static wxString extractJobName(const wxString& batchFilename)
- {
- using namespace common;
-
- const wxString shortName = batchFilename.AfterLast(FILE_NAME_SEPARATOR); //returns the whole string if seperator not found
- const wxString jobName = shortName.BeforeLast(wxChar('.')); //returns empty string if seperator not found
- return jobName.IsEmpty() ? shortName : jobName;
- }
-
-
- static wxString findUniqueLogname(const wxString& logfileDirectory, const wxString& batchFilename)
+ static wxString findUniqueLogname(const wxString& logfileDirectory, const wxString& jobName)
{
using namespace common;
@@ -95,7 +85,7 @@ private:
wxString logfileName = zToWx(logfileDir);
//add prefix
- logfileName += extractJobName(batchFilename) + wxT(" ");
+ logfileName += jobName + wxT(" ");
//add timestamp
wxString timeNow = wxDateTime::Now().FormatISOTime();
@@ -118,7 +108,7 @@ private:
//##############################################################################################################################
BatchStatusHandler::BatchStatusHandler(bool runSilent,
- const wxString& batchFilename,
+ const wxString& jobName,
const wxString* logfileDirectory,
const xmlAccess::OnError handleError,
const SwitchToGui& switchBatchToGui, //functionality to change from batch mode to GUI mode
@@ -129,13 +119,13 @@ BatchStatusHandler::BatchStatusHandler(bool runSilent,
handleError_(handleError),
currentProcess(StatusHandler::PROCESS_NONE),
returnValue(returnVal),
- syncStatusFrame(*this, NULL, runSilent)
+ syncStatusFrame(*this, NULL, runSilent, jobName)
{
if (logfileDirectory)
{
try
{
- logFile.reset(new LogFile(*logfileDirectory, batchFilename));
+ logFile.reset(new LogFile(*logfileDirectory, jobName));
}
catch (ffs3::FileError& error)
{
@@ -216,7 +206,7 @@ inline
void BatchStatusHandler::reportInfo(const Zstring& text)
{
if (currentProcess == StatusHandler::PROCESS_SYNCHRONIZING && logFile.get()) //write file transfer information to log
- errorLog.logInfo(zToWx(text));
+ errorLog.logInfo(zToWx(text)); //avoid spamming with file copy info: visually identifying warning messages has priority! however when saving to a log file wee need this info
syncStatusFrame.setStatusText_NoUpdate(text);
}
diff --git a/ui/batch_status_handler.h b/ui/batch_status_handler.h
index bc4c5bde..ca32aa81 100644
--- a/ui/batch_status_handler.h
+++ b/ui/batch_status_handler.h
@@ -21,7 +21,7 @@ class BatchStatusHandler : public StatusHandler
{
public:
BatchStatusHandler(bool runSilent, //defines: -start minimized and -quit immediately when finished
- const wxString& batchFilename,
+ const wxString& jobName,
const wxString* logfileDirectory, //optional: enable logging if available
const xmlAccess::OnError handleError,
const ffs3::SwitchToGui& switchBatchToGui, //functionality to change from batch mode to GUI mode
diff --git a/ui/check_version.cpp b/ui/check_version.cpp
index d9f892d9..cd1d4c48 100644
--- a/ui/check_version.cpp
+++ b/ui/check_version.cpp
@@ -95,15 +95,8 @@ bool newerVersionExists(const wxString& onlineVersion)
if (online.empty() || online[0] == 0) //onlineVersion may be "This website has been moved..." In this case better check for an update
return true;
- current.resize(std::max(current.size(), online.size()));
- online. resize(std::max(current.size(), online.size()));
-
- typedef std::vector<size_t>::const_iterator VerIter;
- const std::pair<VerIter, VerIter> mm = std::mismatch (current.begin(), current.end(),
- online.begin());
-
- return mm.first == current.end() ? false : //both versions match
- *mm.first < *mm.second;
+ return std::lexicographical_compare(current.begin(), current.end(),
+ online.begin(), online.end());
}
@@ -120,7 +113,7 @@ void ffs3::checkForUpdateNow()
{
const int rv = wxMessageBox(wxString(_("A newer version of FreeFileSync is available:")) + wxT(" v") + onlineVersion + wxT(". ") + _("Download now?"), _("Information"), wxYES_NO | wxICON_QUESTION);
if (rv == wxYES)
- wxLaunchDefaultBrowser(wxT("http://sourceforge.net/project/showfiles.php?group_id=234430"));
+ wxLaunchDefaultBrowser(wxT("http://sourceforge.net/projects/freefilesync/files/"));
}
else
wxMessageBox(_("FreeFileSync is up to date!"), _("Information"), wxICON_INFORMATION);
@@ -139,7 +132,7 @@ void ffs3::checkForUpdatePeriodically(long& lastUpdateCheck)
if (lastUpdateCheck == 0)
{
QuestionDlg* const messageDlg = new QuestionDlg(NULL,
- QuestionDlg::BUTTON_YES | QuestionDlg::BUTTON_CANCEL,
+ QuestionDlg::BUTTON_YES | QuestionDlg::BUTTON_NO,
wxString(_("Do you want FreeFileSync to automatically check for updates every week?")) + wxT("\n") +
_("(Requires an Internet connection!)"));
@@ -166,7 +159,7 @@ void ffs3::checkForUpdatePeriodically(long& lastUpdateCheck)
{
const int rv = wxMessageBox(wxString(_("A newer version of FreeFileSync is available:")) + wxT(" v") + onlineVersion + wxT(". ") + _("Download now?"), _("Information"), wxYES_NO | wxICON_QUESTION);
if (rv == wxYES)
- wxLaunchDefaultBrowser(wxT("http://sourceforge.net/project/showfiles.php?group_id=234430"));
+ wxLaunchDefaultBrowser(wxT("http://sourceforge.net/projects/freefilesync/files/"));
}
}
}
diff --git a/ui/gui_generated.cpp b/ui/gui_generated.cpp
index e39d8705..b830b0be 100644
--- a/ui/gui_generated.cpp
+++ b/ui/gui_generated.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Sep 8 2010)
+// C++ code generated with wxFormBuilder (version Nov 17 2010)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@@ -51,7 +51,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
m_menuItem4 = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("&Quit") ) + wxT('\t') + wxT("CTRL-Q"), wxEmptyString, wxITEM_NORMAL );
m_menuFile->Append( m_menuItem4 );
- m_menubar1->Append( m_menuFile, _("&File") );
+ m_menubar1->Append( m_menuFile, _("&Program") );
m_menuAdvanced = new wxMenu();
m_menuLanguages = new wxMenu();
@@ -1317,7 +1317,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
sbSizer24->Add( 0, 0, 1, wxEXPAND, 5 );
m_checkBoxSilent = new wxCheckBox( m_panelOverview, wxID_ANY, _("Silent mode"), wxDefaultPosition, wxDefaultSize, 0 );
- m_checkBoxSilent->SetToolTip( _("Run minimized and write status information to a logfile") );
+ m_checkBoxSilent->SetToolTip( _("Start minimized and write status information to a logfile") );
sbSizer24->Add( m_checkBoxSilent, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 14 );
@@ -2101,7 +2101,9 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id,
bSizer42->Add( m_staticTextStatus, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
- m_animationControl1 = new wxAnimationCtrl(this, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxSize( 45,45 ));
+ m_animationControl1 = new wxAnimationCtrl( this, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxDefaultSize, wxAC_DEFAULT_STYLE );
+ m_animationControl1->SetMinSize( wxSize( 45,45 ) );
+
bSizer42->Add( m_animationControl1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
@@ -2230,7 +2232,10 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id,
bSizerSpeed->Add( m_staticTextSpeed, 0, wxLEFT|wxALIGN_BOTTOM, 5 );
- bSizer28->Add( bSizerSpeed, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+ bSizerSpeed->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 );
+
+ bSizer28->Add( bSizerSpeed, 1, wxALIGN_CENTER_VERTICAL, 5 );
bSizer28->Add( 0, 0, 1, 0, 5 );
@@ -2257,6 +2262,9 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id,
bSizerRemTime = new wxBoxSizer( wxHORIZONTAL );
+
+ bSizerRemTime->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 );
+
m_staticText21 = new wxStaticText( this, wxID_ANY, _("Time remaining:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText21->Wrap( -1 );
m_staticText21->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) );
@@ -2269,7 +2277,7 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id,
bSizerRemTime->Add( m_staticTextTimeRemaining, 0, wxLEFT|wxALIGN_BOTTOM, 5 );
- bSizer28->Add( bSizerRemTime, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+ bSizer28->Add( bSizerRemTime, 1, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
bSizer27->Add( bSizer28, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxALL, 5 );
@@ -2627,8 +2635,9 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
bSizer108->Add( 30, 0, 1, wxEXPAND, 5 );
- m_animationControl1 = new wxAnimationCtrl(this, wxID_ANY, wxNullAnimation);
+ m_animationControl1 = new wxAnimationCtrl( this, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxSize( -1,-1 ), wxAC_DEFAULT_STYLE );
m_animationControl1->SetToolTip( _("Donate with PayPal") );
+ m_animationControl1->SetMinSize( wxSize( 48,48 ) );
bSizer108->Add( m_animationControl1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
diff --git a/ui/gui_generated.h b/ui/gui_generated.h
index 22bddfb1..cbcce489 100644
--- a/ui/gui_generated.h
+++ b/ui/gui_generated.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Sep 8 2010)
+// C++ code generated with wxFormBuilder (version Nov 17 2010)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@@ -228,6 +228,7 @@ class MainDialogGenerated : public wxFrame
wxPanel* m_panelRight;
MainDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 933,612 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
+
~MainDialogGenerated();
};
@@ -257,7 +258,7 @@ class FolderPairGenerated : public wxPanel
wxTextCtrl* m_directoryRight;
wxDirPickerCtrl* m_dirPickerRight;
- FolderPairGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
+ FolderPairGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
~FolderPairGenerated();
};
@@ -286,7 +287,7 @@ class BatchFolderPairGenerated : public wxPanel
wxDirPickerCtrl* m_dirPickerRight;
wxBitmapButton* m_bpButtonAltSyncCfg;
- BatchFolderPairGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
+ BatchFolderPairGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
~BatchFolderPairGenerated();
};
@@ -368,7 +369,7 @@ class BatchDlgGenerated : public wxDialog
wxDirPickerCtrl* m_dirPickerRight;
wxBitmapButton* m_bpButtonAltSyncCfg;
- BatchDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Create a batch job"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ BatchDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Create a batch job"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~BatchDlgGenerated();
};
@@ -408,7 +409,7 @@ class CompareStatusGenerated : public wxPanel
public:
- CompareStatusGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
+ CompareStatusGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
~CompareStatusGenerated();
};
@@ -492,7 +493,7 @@ class SyncCfgDlgGenerated : public wxDialog
public:
- SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Synchronization settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
+ SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Synchronization settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
~SyncCfgDlgGenerated();
};
@@ -530,7 +531,7 @@ class CmpCfgDlgGenerated : public wxDialog
public:
- CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Comparison settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
+ CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Comparison settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~CmpCfgDlgGenerated();
};
@@ -571,11 +572,13 @@ class SyncStatusDlgGenerated : public wxFrame
wxStaticText* m_staticText108;
wxStaticText* m_staticTextSpeed;
+
wxButton* m_buttonOK;
wxButton* m_buttonPause;
wxButton* m_buttonAbort;
wxBoxSizer* bSizerRemTime;
+
wxStaticText* m_staticText21;
wxStaticText* m_staticTextTimeRemaining;
@@ -592,6 +595,7 @@ class SyncStatusDlgGenerated : public wxFrame
wxGauge* m_gauge1;
SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 638,350 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
+
~SyncStatusDlgGenerated();
};
@@ -642,7 +646,7 @@ class HelpDlgGenerated : public wxDialog
public:
- HelpDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 579,543 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ HelpDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 579,543 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~HelpDlgGenerated();
};
@@ -696,7 +700,7 @@ class AboutDlgGenerated : public wxDialog
public:
- AboutDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
+ AboutDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
~AboutDlgGenerated();
};
@@ -728,7 +732,7 @@ class ErrorDlgGenerated : public wxDialog
public:
- ErrorDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Error"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 421,228 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ErrorDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Error"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 460,250 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
~ErrorDlgGenerated();
};
@@ -760,7 +764,7 @@ class WarningDlgGenerated : public wxDialog
public:
wxStaticBitmap* m_bitmap10;
- WarningDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Warning"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 421,231 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ WarningDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Warning"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 460,250 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
~WarningDlgGenerated();
};
@@ -792,7 +796,7 @@ class QuestionDlgGenerated : public wxDialog
public:
- QuestionDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Question"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 420,198 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ QuestionDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Question"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 420,198 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
~QuestionDlgGenerated();
};
@@ -827,7 +831,7 @@ class DeleteDlgGenerated : public wxDialog
public:
- DeleteDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Confirm"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 553,336 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ DeleteDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Confirm"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 553,336 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER );
~DeleteDlgGenerated();
};
@@ -879,7 +883,7 @@ class FilterDlgGenerated : public wxDialog
public:
- FilterDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Configure filter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ FilterDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Configure filter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~FilterDlgGenerated();
};
@@ -911,7 +915,7 @@ class CustomizeColsDlgGenerated : public wxDialog
public:
- CustomizeColsDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Customize columns"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
+ CustomizeColsDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Customize columns"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~CustomizeColsDlgGenerated();
};
@@ -958,7 +962,7 @@ class GlobalSettingsDlgGenerated : public wxDialog
public:
- GlobalSettingsDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Global settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ GlobalSettingsDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Global settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~GlobalSettingsDlgGenerated();
};
@@ -1005,7 +1009,7 @@ class SyncPreviewDlgGenerated : public wxDialog
public:
- SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Synchronization Preview"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
+ SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Synchronization Preview"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~SyncPreviewDlgGenerated();
};
@@ -1024,6 +1028,7 @@ class PopupFrameGenerated1 : public wxFrame
wxStaticText* m_staticTextMain;
PopupFrameGenerated1( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxFRAME_NO_TASKBAR|wxSTAY_ON_TOP|wxSTATIC_BORDER );
+
~PopupFrameGenerated1();
};
@@ -1052,7 +1057,7 @@ class SearchDialogGenerated : public wxDialog
public:
- SearchDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
+ SearchDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE );
~SearchDialogGenerated();
};
diff --git a/ui/gui_status_handler.cpp b/ui/gui_status_handler.cpp
index 81f4de6e..218f5cdc 100644
--- a/ui/gui_status_handler.cpp
+++ b/ui/gui_status_handler.cpp
@@ -222,8 +222,8 @@ void CompareStatusHandler::abortThisProcess()
//########################################################################################################
-SyncStatusHandler::SyncStatusHandler(wxTopLevelWindow* parentDlg, bool ignoreAllErrors) :
- syncStatusFrame(*this, parentDlg, false),
+SyncStatusHandler::SyncStatusHandler(wxTopLevelWindow* parentDlg, bool ignoreAllErrors, const wxString& jobName) :
+ syncStatusFrame(*this, parentDlg, false, jobName),
ignoreErrors(ignoreAllErrors) {}
@@ -269,6 +269,9 @@ SyncStatusHandler::~SyncStatusHandler()
inline
void SyncStatusHandler::reportInfo(const Zstring& text)
{
+ //if (currentProcess == StatusHandler::PROCESS_SYNCHRONIZING)
+ //errorLog.logInfo(zToWx(text)); -> don't spam with file copy info: visually identifying warning messages has priority!
+
syncStatusFrame.setStatusText_NoUpdate(text);
}
diff --git a/ui/gui_status_handler.h b/ui/gui_status_handler.h
index d6c03399..c44e257b 100644
--- a/ui/gui_status_handler.h
+++ b/ui/gui_status_handler.h
@@ -48,7 +48,7 @@ private:
class SyncStatusHandler : public StatusHandler
{
public:
- SyncStatusHandler(wxTopLevelWindow* parentDlg, bool ignoreAllErrors);
+ SyncStatusHandler(wxTopLevelWindow* parentDlg, bool ignoreAllErrors, const wxString& jobName);
~SyncStatusHandler();
virtual void initNewProcess(int objectsTotal, wxLongLong dataTotal, Process processID);
diff --git a/ui/main_dlg.cpp b/ui/main_dlg.cpp
index 0f2c83b5..5fa6aee7 100644
--- a/ui/main_dlg.cpp
+++ b/ui/main_dlg.cpp
@@ -51,6 +51,9 @@
#include "batch_config.h"
#include "../shared/check_exist.h"
#include <wx/display.h>
+#include <wx/app.h>
+#include <boost/bind.hpp>
+
using namespace ffs3;
using ffs3::CustomLocale;
@@ -492,6 +495,9 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig guiCfg,
m_gridRight->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridRightButtonEvent), NULL, this);
m_gridMiddle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridMiddleButtonEvent), NULL, this);
+ //register global hotkeys (without explicit menu entry)
+ wxTheApp->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), NULL, this);
+
Connect(wxEVT_IDLE, wxEventHandler(MainDialog::OnIdleEvent), NULL, this);
Connect(wxEVT_SIZE, wxSizeEventHandler(MainDialog::OnResize), NULL, this);
Connect(wxEVT_MOVE, wxSizeEventHandler(MainDialog::OnResize), NULL, this);
@@ -598,20 +604,17 @@ void MainDialog::readGlobalSettings()
m_gridRight->setColumnAttributes(globalSettings->gui.columnAttribRight);
//load list of last used configuration files (in reverse order)
- for (std::vector<wxString>::reverse_iterator i = globalSettings->gui.cfgFileHistory.rbegin();
- i != globalSettings->gui.cfgFileHistory.rend();
- ++i)
- addFileToCfgHistory(*i);
+ std::for_each(globalSettings->gui.cfgFileHistory.rbegin(), globalSettings->gui.cfgFileHistory.rend(),
+ boost::bind(&MainDialog::addFileToCfgHistory, this, _1));
//load list of last used folders
- for (std::vector<wxString>::reverse_iterator i = globalSettings->gui.folderHistoryLeft.rbegin();
- i != globalSettings->gui.folderHistoryLeft.rend();
- ++i)
- addLeftFolderToHistory(*i);
- for (std::vector<wxString>::reverse_iterator i = globalSettings->gui.folderHistoryRight.rbegin();
- i != globalSettings->gui.folderHistoryRight.rend();
- ++i)
- addRightFolderToHistory(*i);
+ std::for_each(globalSettings->gui.folderHistoryLeft.rbegin(),
+ globalSettings->gui.folderHistoryLeft.rend(),
+ boost::bind(&MainDialog::addLeftFolderToHistory, this, _1));
+
+ std::for_each(globalSettings->gui.folderHistoryRight.rbegin(),
+ globalSettings->gui.folderHistoryRight.rend(),
+ boost::bind(&MainDialog::addRightFolderToHistory, this, _1));
//show/hide file icons
m_gridLeft->enableFileIcons(globalSettings->gui.showFileIconsLeft);
@@ -856,6 +859,7 @@ private:
}
MainDialog* const mainDlg;
+
const size_t totalObjToDelete;
bool abortRequested;
@@ -881,6 +885,7 @@ void MainDialog::deleteSelectedFiles()
int totalDeleteCount = 0;
+ wxWindow* oldFocus = wxWindow::FindFocus();
if (ffs3::showDeleteDialog(compRefLeft,
compRefRight,
@@ -904,12 +909,11 @@ void MainDialog::deleteSelectedFiles()
compRefRight,
globalSettings->gui.deleteOnBothSides,
globalSettings->gui.useRecyclerForManualDeletion,
- getCurrentConfiguration().mainCfg,
statusHandler);
}
catch (ffs3::AbortThisProcess&) {}
- //remove rows that empty: just a beautification, invalid rows shouldn't cause issues
+ //remove rows that are empty: just a beautification, invalid rows shouldn't cause issues
gridDataView->removeInvalidRows();
//redraw grid neccessary to update new dimensions and for UI-Backend data linkage
@@ -919,6 +923,9 @@ void MainDialog::deleteSelectedFiles()
m_gridMiddle->ClearSelection();
m_gridRight-> ClearSelection();
}
+
+ if (oldFocus)
+ oldFocus->SetFocus(); //restore focus before deletion
}
}
@@ -1171,19 +1178,15 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event)
case 'C':
case WXK_INSERT: //CTRL + C || CTRL + INS
copySelectionToClipboard(m_gridLeft);
- break;
+ return; // -> swallow event! don't allow default grid commands!
case 'A': //CTRL + A
m_gridLeft->SelectAll();
- break;
-
- case 'F': //CTRL + F
- ffs3::startFind(*this, *m_gridLeft, *m_gridRight, globalSettings->gui.textSearchRespectCase);
- break;
+ return;
case WXK_NUMPAD_ADD: //CTRL + '+'
m_gridLeft->autoSizeColumns();
- break;
+ return;
}
else if (event.AltDown())
@@ -1194,14 +1197,14 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event)
wxCommandEvent dummy;
OnContextSyncDirLeft(dummy);
}
- break;
+ return;
case WXK_RIGHT: //ALT + ->
{
wxCommandEvent dummy;
OnContextSyncDirRight(dummy);
}
- break;
+ return;
case WXK_UP: /* ALT + /|\ */
case WXK_DOWN: /* ALT + \|/ */
@@ -1209,7 +1212,7 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event)
wxCommandEvent dummy;
OnContextSyncDirNone(dummy);
}
- break;
+ return;
}
else
@@ -1218,14 +1221,14 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event)
case WXK_DELETE:
case WXK_NUMPAD_DELETE:
deleteSelectedFiles();
- break;
+ return;
case WXK_SPACE:
{
wxCommandEvent dummy;
OnContextFilterTemp(dummy);
}
- break;
+ return;
case WXK_RETURN:
case WXK_NUMPAD_ENTER:
@@ -1233,15 +1236,10 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event)
wxCommandEvent dummy(wxEVT_NULL, externalAppIDFirst); //open with first external application
OnContextOpenWith(dummy);
}
- break;
-
- case WXK_F3: //F3
- case WXK_NUMPAD_F3: //
- ffs3::findNext(*this, *m_gridLeft, *m_gridRight, globalSettings->gui.textSearchRespectCase);
- break;
+ return;
}
- //event.Skip(); -> swallow event! don't allow default grid commands!
+ event.Skip(); //unknown keypress: propagate
}
@@ -1250,12 +1248,15 @@ void MainDialog::onGridMiddleButtonEvent(wxKeyEvent& event)
const int keyCode = event.GetKeyCode();
if (event.ControlDown())
- {
- if (keyCode == 67 || keyCode == WXK_INSERT) //CTRL + C || CTRL + INS
+ switch (keyCode)
+ {
+ case 'C':
+ case WXK_INSERT: //CTRL + C || CTRL + INS
copySelectionToClipboard(m_gridMiddle);
- }
+ return;
+ }
- //event.Skip(); -> swallow event! don't allow default grid commands!
+ event.Skip(); //unknown keypress: propagate
}
@@ -1269,19 +1270,15 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event)
case 'C':
case WXK_INSERT: //CTRL + C || CTRL + INS
copySelectionToClipboard(m_gridRight);
- break;
+ return;
case 'A': //CTRL + A
m_gridRight->SelectAll();
- break;
-
- case 'F': //CTRL + F
- ffs3::startFind(*this, *m_gridLeft, *m_gridRight, globalSettings->gui.textSearchRespectCase);
- break;
+ return;
case WXK_NUMPAD_ADD: //CTRL + '+'
m_gridRight->autoSizeColumns();
- break;
+ return;
}
else if (event.AltDown())
@@ -1292,14 +1289,14 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event)
wxCommandEvent dummy;
OnContextSyncDirLeft(dummy);
}
- break;
+ return;
case WXK_RIGHT: //ALT + ->
{
wxCommandEvent dummy;
OnContextSyncDirRight(dummy);
}
- break;
+ return;
case WXK_UP: /* ALT + /|\ */
case WXK_DOWN: /* ALT + \|/ */
@@ -1307,7 +1304,7 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event)
wxCommandEvent dummy;
OnContextSyncDirNone(dummy);
}
- break;
+ return;
}
else
@@ -1316,14 +1313,14 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event)
case WXK_DELETE:
case WXK_NUMPAD_DELETE:
deleteSelectedFiles();
- break;
+ return;
case WXK_SPACE:
{
wxCommandEvent dummy;
OnContextFilterTemp(dummy);
}
- break;
+ return;
case WXK_RETURN:
case WXK_NUMPAD_ENTER:
@@ -1331,19 +1328,39 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event)
wxCommandEvent dummy(wxEVT_NULL, externalAppIDFirst); //open with first external application
OnContextOpenWith(dummy);
}
- break;
+ return;
+ }
+
+ event.Skip(); //unknown keypress: propagate
+}
+
+void MainDialog::OnGlobalKeyEvent(wxKeyEvent& event) //process key events without explicit menu entry :)
+{
+ const int keyCode = event.GetKeyCode();
+
+ if (event.ControlDown())
+ switch (keyCode)
+ {
+ case 'F': //CTRL + F
+ ffs3::startFind(*this, *m_gridLeft, *m_gridRight, globalSettings->gui.textSearchRespectCase);
+ return; //-> swallow event!
+ }
+ else if (event.AltDown())
+ ;
+ else
+ switch (keyCode)
+ {
case WXK_F3: //F3
case WXK_NUMPAD_F3: //
ffs3::findNext(*this, *m_gridLeft, *m_gridRight, globalSettings->gui.textSearchRespectCase);
- break;
+ return; //-> swallow event!
}
- //event.Skip(); -> swallow event! don't allow default grid commands!
+ event.Skip();
}
-
//------------------------------------------------------------
//temporal variables used by exclude via context menu
struct SelectedExtension : public wxObject
@@ -2890,7 +2907,7 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
//PERF_START;
//class handling status updates and error messages
- SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors);
+ SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors, ffs3::extractJobName(currentConfigFileName));
//check if there are files/folders to be sync'ed at all
if (!synchronizationNeeded(gridDataView->getDataTentative()))
@@ -3891,3 +3908,4 @@ bool MainDialog::SyncPreview::synchronizationIsEnabled() const
{
return synchronizationEnabled;
}
+
diff --git a/ui/main_dlg.h b/ui/main_dlg.h
index 34a1fdb2..68310065 100644
--- a/ui/main_dlg.h
+++ b/ui/main_dlg.h
@@ -14,13 +14,10 @@
#include <map>
#include <set>
-class CompareStatusHandler;
-class DirectoryNameMainImpl;
class CustomGrid;
class FFSCheckRowsEvent;
class FFSSyncDirectionEvent;
class IconUpdater;
-class ManualDeletionHandler;
class DirectoryPair;
class DirectoryPairFirst;
class CompareStatus;
@@ -159,6 +156,7 @@ private:
void OnContextRimLabelRight( wxGridEvent& event);
void OnContextMiddle( wxGridEvent& event);
void OnContextMiddleLabel( wxGridEvent& event);
+ void OnGlobalKeyEvent( wxKeyEvent& event);
//context menu handler methods
void OnContextFilterTemp(wxCommandEvent& event);
diff --git a/ui/progress_indicator.cpp b/ui/progress_indicator.cpp
index 346403ee..e5cfa879 100644
--- a/ui/progress_indicator.cpp
+++ b/ui/progress_indicator.cpp
@@ -384,7 +384,7 @@ void CompareStatus::CompareStatusImpl::updateStatusPanelNow()
class SyncStatus::SyncStatusImpl : public SyncStatusDlgGenerated
{
public:
- SyncStatusImpl(StatusHandler& updater, wxTopLevelWindow* parentWindow);
+ SyncStatusImpl(StatusHandler& updater, wxTopLevelWindow* parentWindow, const wxString& jobName);
~SyncStatusImpl();
void resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess);
@@ -410,6 +410,7 @@ private:
bool currentProcessIsRunning();
void showProgressExternally(const wxString& progressText, float percent = 0); //percent may already be included in progressText
+ const wxString jobName_;
wxStopWatch timeElapsed;
StatusHandler* processStatusHandler;
@@ -445,8 +446,8 @@ private:
//redirect to implementation
-SyncStatus::SyncStatus(StatusHandler& updater, wxTopLevelWindow* parentWindow, bool startSilent) :
- pimpl(new SyncStatusImpl(updater, parentWindow))
+SyncStatus::SyncStatus(StatusHandler& updater, wxTopLevelWindow* parentWindow, bool startSilent, const wxString& jobName) :
+ pimpl(new SyncStatusImpl(updater, parentWindow, jobName))
{
if (startSilent)
pimpl->minimizeToTray();
@@ -509,7 +510,7 @@ void SyncStatus::processHasFinished(SyncStatusID id, const wxString& finalMessag
//########################################################################################
-SyncStatus::SyncStatusImpl::SyncStatusImpl(StatusHandler& updater, wxTopLevelWindow* parentWindow) :
+SyncStatus::SyncStatusImpl::SyncStatusImpl(StatusHandler& updater, wxTopLevelWindow* parentWindow, const wxString& jobName) :
SyncStatusDlgGenerated(parentWindow,
wxID_ANY,
parentWindow ? wxString(wxEmptyString) : (wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization")),
@@ -517,6 +518,7 @@ SyncStatus::SyncStatusImpl::SyncStatusImpl(StatusHandler& updater, wxTopLevelWin
parentWindow ?
wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT : //wxTAB_TRAVERSAL is needed for standard button handling: wxID_OK/wxID_CANCEL
wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL),
+ jobName_(jobName),
processStatusHandler(&updater),
mainDialog(parentWindow),
totalObjects(0),
@@ -702,26 +704,28 @@ void SyncStatus::SyncStatusImpl::updateStatusDialogNow()
const float percent = totalData == 0 ? 0 : currentData.ToDouble() * 100 / totalData.ToDouble();
//write status information to systray, taskbar, parent title ect.
+
+ const wxString postFix = jobName_.empty() ? wxString() : (wxT(" - \"") + jobName_ + wxT("\""));
switch (currentStatus)
{
case SyncStatus::SCANNING:
- showProgressExternally(numberToStringSep(scannedObjects) + wxT(" - ") + _("Scanning..."));
+ showProgressExternally(numberToStringSep(scannedObjects) + wxT(" - ") + _("Scanning...") + postFix);
break;
case SyncStatus::COMPARING_CONTENT:
- showProgressExternally(formatPercentage(currentData, totalData) + wxT(" - ") + _("Comparing content..."), percent);
+ showProgressExternally(formatPercentage(currentData, totalData) + wxT(" - ") + _("Comparing content...") + postFix, percent);
break;
case SyncStatus::SYNCHRONIZING:
- showProgressExternally(formatPercentage(currentData, totalData) + wxT(" - ") + _("Synchronizing..."), percent);
+ showProgressExternally(formatPercentage(currentData, totalData) + wxT(" - ") + _("Synchronizing...") + postFix, percent);
break;
case SyncStatus::PAUSE:
- showProgressExternally((totalData != 0 ? formatPercentage(currentData, totalData) + wxT(" - ") : wxString()) + _("Paused"), percent);
+ showProgressExternally((totalData != 0 ? formatPercentage(currentData, totalData) + wxT(" - ") : wxString()) + _("Paused") + postFix, percent);
break;
case SyncStatus::ABORTED:
- showProgressExternally(_("Aborted"), percent);
+ showProgressExternally(_("Aborted") + postFix, percent);
break;
case SyncStatus::FINISHED_WITH_SUCCESS:
case SyncStatus::FINISHED_WITH_ERROR:
- showProgressExternally(_("Completed"), percent);
+ showProgressExternally(_("Completed") + postFix, percent);
break;
}
diff --git a/ui/progress_indicator.h b/ui/progress_indicator.h
index 4bd9861b..bb5a287c 100644
--- a/ui/progress_indicator.h
+++ b/ui/progress_indicator.h
@@ -40,7 +40,8 @@ class SyncStatus
public:
SyncStatus(StatusHandler& updater,
wxTopLevelWindow* parentWindow, //may be NULL
- bool startSilent);
+ bool startSilent,
+ const wxString& jobName);
~SyncStatus();
wxWindow* getAsWindow(); //convenience! don't abuse!
diff --git a/ui/small_dlgs.cpp b/ui/small_dlgs.cpp
index 3d63db47..e582142c 100644
--- a/ui/small_dlgs.cpp
+++ b/ui/small_dlgs.cpp
@@ -451,16 +451,14 @@ DefaultReturnCode::Response ffs3::showDeleteDialog(const std::vector<ffs3::FileS
{
DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL;
- DeleteDialog* confirmDeletion = new DeleteDialog(NULL,
+ DeleteDialog confirmDeletion(NULL,
rowsOnLeft,
rowsOnRight,
deleteOnBothSides,
useRecycleBin,
totalDeleteCount);
- if (confirmDeletion->ShowModal() == DeleteDialog::BUTTON_OKAY)
+ if (confirmDeletion.ShowModal() == DeleteDialog::BUTTON_OKAY)
rv = DefaultReturnCode::BUTTON_OKAY;
-
- confirmDeletion->Destroy();
return rv;
}
//########################################################################################
diff --git a/version/version.h b/version/version.h
index 0fae15a7..b1d104bd 100644
--- a/version/version.h
+++ b/version/version.h
@@ -2,5 +2,5 @@
namespace ffs3
{
- const wxString currentVersion = wxT("3.11"); //internal linkage!
+ const wxString currentVersion = wxT("3.12"); //internal linkage!
}
diff --git a/version/version.rc b/version/version.rc
index f0065a5c..e9dcc18a 100644
--- a/version/version.rc
+++ b/version/version.rc
@@ -1,2 +1,2 @@
-#define VER_FREEFILESYNC 3,11,0,0
-#define VER_FREEFILESYNC_STR "3.11\0"
+#define VER_FREEFILESYNC 3,12,0,0
+#define VER_FREEFILESYNC_STR "3.12\0"
bgstack15