summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/CustomGrid.cpp10
-rw-r--r--library/CustomGrid.h2
-rw-r--r--library/Taskbar_Seven/Taskbar_Seven.vcproj409
-rw-r--r--library/Taskbar_Seven/dllmain.cpp27
-rw-r--r--library/Taskbar_Seven/taskbar.cpp160
-rw-r--r--library/Taskbar_Seven/taskbar.h62
-rw-r--r--library/binary.cpp99
-rw-r--r--library/binary.h2
-rw-r--r--library/dbFile.cpp419
-rw-r--r--library/dbFile.h20
-rw-r--r--library/filter.cpp4
-rw-r--r--library/filter.h17
-rw-r--r--library/processXml.cpp81
-rw-r--r--library/processXml.h10
-rw-r--r--library/softFilter.cpp10
-rw-r--r--library/softFilter.h79
-rw-r--r--library/statistics.cpp10
17 files changed, 1259 insertions, 162 deletions
diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp
index a04548a3..e9fe9eb6 100644
--- a/library/CustomGrid.cpp
+++ b/library/CustomGrid.cpp
@@ -8,7 +8,7 @@
#include "../shared/systemConstants.h"
#include "resources.h"
#include <wx/dc.h>
-#include "../ui/util.h"
+#include "../shared/util.h"
#include "../shared/stringConv.h"
#include "resources.h"
#include <typeinfo>
@@ -296,7 +296,7 @@ protected:
case xmlAccess::DIRECTORY:
return zToWx(fileObj->getBaseDirPf<side>());
case xmlAccess::SIZE: //file size
- return FreeFileSync::includeNumberSeparator(fileObj->getFileSize<side>().ToString());
+ return FreeFileSync::numberToWxString(fileObj->getFileSize<side>(), true);
case xmlAccess::DATE: //date
return FreeFileSync::utcTimeToLocalString(fileObj->getLastWriteTime<side>(), fileObj->getFullName<side>());
case xmlAccess::EXTENSION: //file extension
@@ -896,14 +896,14 @@ void CustomGrid::DrawColLabel(wxDC& dc, int col)
}
-std::set<unsigned int> CustomGrid::getAllSelectedRows() const
+std::set<size_t> CustomGrid::getAllSelectedRows() const
{
- std::set<unsigned int> output;
+ std::set<size_t> output;
const wxArrayInt selectedRows = this->GetSelectedRows();
if (!selectedRows.IsEmpty())
{
- for (unsigned int i = 0; i < selectedRows.GetCount(); ++i)
+ for (size_t i = 0; i < selectedRows.GetCount(); ++i)
output.insert(selectedRows[i]);
}
diff --git a/library/CustomGrid.h b/library/CustomGrid.h
index 7a0d1b10..35915811 100644
--- a/library/CustomGrid.h
+++ b/library/CustomGrid.h
@@ -65,7 +65,7 @@ public:
CustomGridRight* gridRight,
const FreeFileSync::GridView* gridDataView);
- std::set<unsigned int> getAllSelectedRows() const;
+ std::set<size_t> getAllSelectedRows() const;
//set sort direction indicator on UI
typedef int SortColumn;
diff --git a/library/Taskbar_Seven/Taskbar_Seven.vcproj b/library/Taskbar_Seven/Taskbar_Seven.vcproj
new file mode 100644
index 00000000..bf8e0993
--- /dev/null
+++ b/library/Taskbar_Seven/Taskbar_Seven.vcproj
@@ -0,0 +1,409 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="Taskbar_Seven"
+ ProjectGUID="{70394AEF-5897-4911-AFA1-82EAF0581EFA}"
+ RootNamespace="ShadowDll"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ ConfigurationType="2"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\Build.html"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="Taskbar7_$(PlatformName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(IntDir)$(TargetName).pdb"
+ SubSystem="2"
+ ProfileGuidedDatabase=""
+ ImportLibrary="$(IntDir)$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ ConfigurationType="2"
+ CharacterSet="1"
+ BuildLogFile="$(IntDir)\Build.html"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="Taskbar7_$(PlatformName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(IntDir)$(TargetName).pdb"
+ SubSystem="2"
+ ProfileGuidedDatabase=""
+ ImportLibrary="$(IntDir)$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ BuildLogFile="$(IntDir)\Build.html"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="Taskbar7_$(PlatformName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="false"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ ProfileGuidedDatabase=""
+ ImportLibrary="$(IntDir)$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ BuildLogFile="$(IntDir)\Build.html"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="Taskbar7_$(PlatformName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="false"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ ProfileGuidedDatabase=""
+ ImportLibrary="$(IntDir)$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Quelldateien"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\dllmain.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ CompileAsManaged="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ CompileAsManaged="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ CompileAsManaged="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ CompileAsManaged="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\taskbar.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Headerdateien"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\taskbar.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/library/Taskbar_Seven/dllmain.cpp b/library/Taskbar_Seven/dllmain.cpp
new file mode 100644
index 00000000..7db39bff
--- /dev/null
+++ b/library/Taskbar_Seven/dllmain.cpp
@@ -0,0 +1,27 @@
+// **************************************************************************
+// * 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) *
+// **************************************************************************
+//
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
diff --git a/library/Taskbar_Seven/taskbar.cpp b/library/Taskbar_Seven/taskbar.cpp
new file mode 100644
index 00000000..4baf2392
--- /dev/null
+++ b/library/Taskbar_Seven/taskbar.cpp
@@ -0,0 +1,160 @@
+// **************************************************************************
+// * 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 "taskbar.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#include <ShObjIdl.h>
+
+#include <map>
+#include <string>
+#include <comdef.h>
+
+
+namespace
+{
+void writeString(const std::wstring& input, wchar_t* output, size_t outputBufferLen)
+{
+ const size_t newSize = min(input.length() + 1, outputBufferLen); //including null-termination
+ memcpy(output, input.c_str(), newSize * sizeof(wchar_t));
+ output[newSize-1] = 0; //if output buffer is too small...
+}
+
+
+std::wstring numberToHexString(const long number)
+{
+ wchar_t result[100];
+ swprintf(result, 100, L"0x%08x", number);
+ return std::wstring(result);
+}
+
+
+std::wstring writeErrorMsg(const wchar_t* input, HRESULT hr)
+{
+ std::wstring output(input);
+ output += L" (";
+ output += numberToHexString(hr);
+ output += L": ";
+ output += _com_error(hr).ErrorMessage();
+ output += L")";
+ return output;
+}
+
+
+using TaskbarSeven::TBHandle;
+typedef std::map<TBHandle, ITaskbarList3*> TaskBarHandleMap;
+
+TaskbarSeven::TBHandle generateHandle()
+{
+ static TBHandle handle = 0;
+ return ++handle; //don't return 0! 0 is reserved for indicating failure
+}
+
+TaskBarHandleMap taskBarHandles;
+
+std::wstring lastErrorMessage;
+}
+//##################################################################################################
+
+
+TaskbarSeven::TBHandle TaskbarSeven::init() //call on app initializaiton; returns handle
+{
+ ITaskbarList3* pto = NULL;
+ HRESULT hr = CoCreateInstance(CLSID_TaskbarList,
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(&pto));
+ if (FAILED(hr))
+ {
+ lastErrorMessage = writeErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
+ return 0;
+ }
+
+ TBHandle newHandle = ::generateHandle();
+ taskBarHandles[newHandle] = pto;
+ return newHandle;
+}
+
+
+void TaskbarSeven::release(TBHandle handle) //release handle on app exit
+{
+ TaskBarHandleMap::const_iterator iter = taskBarHandles.find(handle);
+ if (iter != taskBarHandles.end())
+ {
+ if (iter->second != NULL)
+ iter->second->Release();
+ taskBarHandles.erase(iter);
+ }
+}
+
+
+bool TaskbarSeven::setStatus(TBHandle handle,
+ void* hwnd, //HWND: window assciated to the taskbar icon
+ TaskBarStatus status)
+{
+ TBPFLAG flag = TBPF_NORMAL;
+ switch (status)
+ {
+ case STATUS_NOPROGRESS:
+ flag = TBPF_NOPROGRESS;
+ break;
+ case STATUS_INDETERMINATE:
+ flag = TBPF_INDETERMINATE;
+ break;
+ case STATUS_NORMAL:
+ flag = TBPF_NORMAL;
+ break;
+ case STATUS_ERROR:
+ flag = TBPF_ERROR;
+ break;
+ case STATUS_PAUSED:
+ flag = TBPF_PAUSED;
+ break;
+ }
+
+ ITaskbarList3* pto = taskBarHandles[handle];
+ if (pto)
+ {
+ HRESULT hr = pto->SetProgressState(static_cast<HWND>(hwnd), //[in] HWND hwnd,
+ flag); //[in] TBPFLAG tbpFlags
+ if (FAILED(hr))
+ {
+ lastErrorMessage = writeErrorMsg(L"Error calling \"SetProgressState\".", hr);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+bool TaskbarSeven::setProgress(TBHandle handle,
+ void* hwnd, //HWND: window assciated to the taskbar icon
+ size_t current,
+ size_t total)
+{
+ ITaskbarList3* pto = taskBarHandles[handle];
+
+ if (pto)
+ {
+ HRESULT hr = pto->SetProgressValue(
+ static_cast<HWND>(hwnd), //[in] HWND hwnd,
+ current, //[in] ULONGLONG ullCompleted,
+ total); //[in] ULONGLONG ullTotal
+ if (FAILED(hr))
+ {
+ lastErrorMessage = writeErrorMsg(L"Error calling \"SetProgressValue\".", hr);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void TaskbarSeven::getLastError(wchar_t* errorMessage, size_t errorBufferLen)
+{
+ writeString(lastErrorMessage, errorMessage, errorBufferLen);
+}
diff --git a/library/Taskbar_Seven/taskbar.h b/library/Taskbar_Seven/taskbar.h
new file mode 100644
index 00000000..835f02ec
--- /dev/null
+++ b/library/Taskbar_Seven/taskbar.h
@@ -0,0 +1,62 @@
+// **************************************************************************
+// * 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 TASKBAR_SEVEN_DLL_H
+#define TASKBAR_SEVEN_DLL_H
+
+#ifdef TASKBAR_SEVEN_DLL_EXPORTS
+#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllexport)
+#else
+#define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllimport)
+#endif
+
+
+namespace TaskbarSeven
+{
+enum TaskBarStatus
+{
+ STATUS_NOPROGRESS,
+ STATUS_INDETERMINATE,
+ STATUS_NORMAL,
+ STATUS_ERROR,
+ STATUS_PAUSED
+};
+
+typedef size_t TBHandle;
+
+
+//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
+DLL_FUNCTION_DECLARATION
+TBHandle init(); //returns handle; 0 on failure
+
+DLL_FUNCTION_DECLARATION
+void release(TBHandle handle); //release taskbar handle
+
+DLL_FUNCTION_DECLARATION
+bool setStatus(TBHandle handle,
+ void* hwnd, //HWND: window assciated to the taskbar icon
+ TaskBarStatus status);
+
+
+DLL_FUNCTION_DECLARATION
+bool setProgress(TBHandle handle,
+ void* hwnd, //HWND: window assciated to the taskbar icon
+ size_t current,
+ size_t total);
+
+//if any of the functions above returns 'false', this message returns last error
+void getLastError(wchar_t* errorMessage, size_t errorBufferLen);
+
+
+//function typedefs
+typedef TBHandle (*initFct)();
+typedef void (*releaseFct)(TBHandle handle);
+typedef bool (*setStatusFct)(TBHandle handle, void* hwnd, TaskBarStatus status);
+typedef bool (*setProgressFct)(TBHandle handle, void* hwnd, size_t current, size_t total);
+typedef void (*getLastErrorFct)(wchar_t* errorMessage, size_t errorBufferLen);
+}
+
+#endif //TASKBAR_SEVEN_DLL_H \ No newline at end of file
diff --git a/library/binary.cpp b/library/binary.cpp
index bc5ba814..409b024a 100644
--- a/library/binary.cpp
+++ b/library/binary.cpp
@@ -6,103 +6,23 @@
//
#include "binary.h"
#include <boost/scoped_array.hpp>
-#include <wx/intl.h>
-#include "../shared/stringConv.h"
+#include "../shared/fileIO.h"
-#ifdef FFS_WIN
-#include "../shared/longPathPrefix.h"
-#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include <boost/shared_ptr.hpp>
-#elif defined FFS_LINUX
-#include <wx/ffile.h>
-#endif
-
-
-bool FreeFileSync::filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback* callback)
+bool FreeFileSync::filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback& callback)
{
const size_t BUFFER_SIZE = 512 * 1024; //512 kb seems to be the perfect buffer size
static boost::scoped_array<unsigned char> memory1(new unsigned char[BUFFER_SIZE]);
static boost::scoped_array<unsigned char> memory2(new unsigned char[BUFFER_SIZE]);
-#ifdef FFS_WIN
- const HANDLE hFile1 = ::CreateFile(FreeFileSync::applyLongPathPrefix(filename1).c_str(),
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (hFile1 == INVALID_HANDLE_VALUE)
- throw FileError(wxString(_("Error opening file:")) + wxT(" \"") + zToWx(filename1) + wxT("\""));
-
- boost::shared_ptr<void> dummy1(hFile1, &::CloseHandle);
-
- const HANDLE hFile2 = ::CreateFile(FreeFileSync::applyLongPathPrefix(filename2).c_str(),
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (hFile2 == INVALID_HANDLE_VALUE)
- throw FileError(wxString(_("Error opening file:")) + wxT(" \"") + zToWx(filename2) + wxT("\""));
-
- boost::shared_ptr<void> dummy2(hFile2, &::CloseHandle);
-
- wxLongLong bytesCompared;
- DWORD length1 = 0;
- do
- {
- if (!::ReadFile(
- hFile1, //__in HANDLE hFile,
- memory1.get(), //__out LPVOID lpBuffer,
- BUFFER_SIZE, //__in DWORD nNumberOfBytesToRead,
- &length1, //__out_opt LPDWORD lpNumberOfBytesRead,
- NULL)) //__inout_opt LPOVERLAPPED lpOverlapped
- throw FileError(wxString(_("Error reading file:")) + wxT(" \"") + zToWx(filename1) + wxT("\""));
-
- DWORD length2 = 0;
- if (!::ReadFile(
- hFile2, //__in HANDLE hFile,
- memory2.get(), //__out LPVOID lpBuffer,
- BUFFER_SIZE, //__in DWORD nNumberOfBytesToRead,
- &length2, //__out_opt LPDWORD lpNumberOfBytesRead,
- NULL)) //__inout_opt LPOVERLAPPED lpOverlapped
- throw FileError(wxString(_("Error reading file:")) + wxT(" \"") + zToWx(filename2) + wxT("\""));
-
- if (length1 != length2 || ::memcmp(memory1.get(), memory2.get(), length1) != 0)
- return false;
-
- bytesCompared += length1 * 2;
-
- //send progress updates
- callback->updateCompareStatus(bytesCompared);
- }
- while (length1 == BUFFER_SIZE);
-
- return true;
-
-
-#elif defined FFS_LINUX
- wxFFile file1(::fopen(filename1.c_str(), DefaultStr("rb,type=record,noseek"))); //utilize UTF-8 filename
- if (!file1.IsOpened())
- throw FileError(wxString(_("Error opening file:")) + wxT(" \"") + zToWx(filename1) + wxT("\""));
-
- wxFFile file2(::fopen(filename2.c_str(), DefaultStr("rb,type=record,noseek"))); //utilize UTF-8 filename
- if (!file2.IsOpened())
- throw FileError(wxString(_("Error opening file:")) + wxT(" \"") + zToWx(filename2) + wxT("\""));
+ FileInput file1(filename1); //throw FileError()
+ FileInput file2(filename2); //throw FileError()
wxLongLong bytesCompared;
do
{
- const size_t length1 = file1.Read(memory1.get(), BUFFER_SIZE);
- if (file1.Error())
- throw FileError(wxString(_("Error reading file:")) + wxT(" \"") + zToWx(filename1) + wxT("\""));
-
- const size_t length2 = file2.Read(memory2.get(), BUFFER_SIZE);
- if (file2.Error())
- throw FileError(wxString(_("Error reading file:")) + wxT(" \"") + zToWx(filename2) + wxT("\""));
+ const size_t length1 = file1.read(memory1.get(), BUFFER_SIZE); //returns actual number of bytes read; throw FileError()
+ const size_t length2 = file2.read(memory2.get(), BUFFER_SIZE); //
if (length1 != length2 || ::memcmp(memory1.get(), memory2.get(), length1) != 0)
return false;
@@ -110,13 +30,12 @@ bool FreeFileSync::filesHaveSameContent(const Zstring& filename1, const Zstring&
bytesCompared += length1 * 2;
//send progress updates
- callback->updateCompareStatus(bytesCompared);
+ callback.updateCompareStatus(bytesCompared);
}
- while (!file1.Eof());
+ while (!file1.eof());
- if (!file2.Eof()) //highly unlikely, but theoretically possible! (but then again, not in this context where both files have same size...)
+ if (!file1.eof()) //highly unlikely, but theoretically possible! (but then again, not in this context where both files have same size...)
return false;
return true;
-#endif
}
diff --git a/library/binary.h b/library/binary.h
index c4e9c928..e33e46bf 100644
--- a/library/binary.h
+++ b/library/binary.h
@@ -22,7 +22,7 @@ public:
virtual void updateCompareStatus(const wxLongLong& totalBytesTransferred) = 0;
};
-bool filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback* callback); //throw FileError
+bool filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback& callback); //throw FileError
}
#endif // BINARY_H_INCLUDED
diff --git a/library/dbFile.cpp b/library/dbFile.cpp
new file mode 100644
index 00000000..c08c8ae8
--- /dev/null
+++ b/library/dbFile.cpp
@@ -0,0 +1,419 @@
+// **************************************************************************
+// * 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 "dbFile.h"
+#include <wx/wfstream.h>
+#include <wx/zstream.h>
+#include "../shared/globalFunctions.h"
+#include "../shared/fileError.h"
+#include <wx/intl.h>
+#include "../shared/stringConv.h"
+#include "../shared/fileHandling.h"
+#include <wx/mstream.h>
+#include "../shared/serialize.h"
+#include "../shared/fileIO.h"
+
+#ifdef FFS_WIN
+#include <wx/msw/wrapwin.h> //includes "windows.h"
+#include "../shared/longPathPrefix.h"
+#endif
+
+using namespace FreeFileSync;
+
+
+namespace
+{
+//-------------------------------------------------------------------------------------------------------------------------------
+const char FILE_FORMAT_DESCR[] = "FreeFileSync";
+const int FILE_FORMAT_VER = 3;
+//-------------------------------------------------------------------------------------------------------------------------------
+
+
+//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:
+ FileInputStreamDB(const Zstring& filename) : //throw FileError()
+ FileInputStream(filename)
+ {
+ //read FreeFileSync file identifier
+ char formatDescr[sizeof(FILE_FORMAT_DESCR)];
+ Read(formatDescr, sizeof(formatDescr)); //throw (FileError)
+ formatDescr[sizeof(formatDescr) - 1] = 0;
+
+ if (std::string(formatDescr) != FILE_FORMAT_DESCR)
+ throw FileError(wxString(_("Incompatible synchronization database format:")) + wxT(" \n") + wxT("\"") + zToWx(filename) + wxT("\""));
+ }
+
+private:
+};
+
+
+class FileOutputStreamDB : public FileOutputStream
+{
+public:
+ FileOutputStreamDB(const Zstring& filename) : //throw FileError()
+ FileOutputStream(filename)
+ {
+ //write FreeFileSync file identifier
+ Write(FILE_FORMAT_DESCR, sizeof(FILE_FORMAT_DESCR)); //throw (FileError)
+ }
+
+private:
+};
+}
+//#######################################################################################################################################
+
+
+
+
+class ReadDirInfo : public Utility::ReadInputStream
+{
+public:
+ ReadDirInfo(wxInputStream& stream, const wxString& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName)
+ {
+ //read filter settings
+ dirInfo.filter = BaseFilter::loadFilter(getStream());
+ check();
+
+ //start recursion
+ execute(dirInfo.baseDirContainer);
+ }
+
+private:
+ void execute(DirContainer& dirCont)
+ {
+ unsigned int fileCount = readNumberC<unsigned int>();
+ while (fileCount-- != 0)
+ readSubFile(dirCont);
+
+ unsigned int dirCount = readNumberC<unsigned int>();
+ while (dirCount-- != 0)
+ readSubDirectory(dirCont);
+ }
+
+ void readSubFile(DirContainer& dirCont)
+ {
+ //attention: order of function argument evaluation is undefined! So do it one after the other...
+ const Zstring shortName = readStringC(); //file name
+
+ const long modHigh = readNumberC<long>();
+ const unsigned long modLow = readNumberC<unsigned long>();
+
+ const unsigned long sizeHigh = readNumberC<unsigned long>();
+ const unsigned long sizeLow = readNumberC<unsigned long>();
+
+ //const Utility::FileID fileIdentifier(stream_);
+ //check();
+
+ dirCont.addSubFile(shortName,
+ FileDescriptor(wxLongLong(modHigh, modLow),
+ wxULongLong(sizeHigh, sizeLow)));
+ }
+
+ void readSubDirectory(DirContainer& dirCont)
+ {
+ const Zstring shortName = readStringC(); //directory name
+ DirContainer& subDir = dirCont.addSubDir(shortName);
+ execute(subDir); //recurse
+ }
+};
+
+
+typedef boost::shared_ptr<std::vector<char> > MemoryStreamPtr; //byte stream representing DirInformation
+typedef std::map<Utility::UniqueId, MemoryStreamPtr> DirectoryTOC; //list of streams ordered by a UUID pointing to their partner database
+typedef std::pair<Utility::UniqueId, DirectoryTOC> DbStreamData; //header data: UUID representing this database, item data: list of dir-streams
+/* Example
+left side right side
+--------- ----------
+DB-ID 123 <-\ /-> DB-ID 567
+ \/
+Partner-ID 111 /\ Partner-ID 222
+Partner-ID 567 _/ \_ Partner-ID 123
+ ... ...
+*/
+
+class ReadFileStream : public Utility::ReadInputStream
+{
+public:
+ ReadFileStream(wxInputStream& stream, const wxString& filename, DbStreamData& output) : ReadInputStream(stream, filename)
+ {
+ if (readNumberC<int>() != FILE_FORMAT_VER) //read file format version
+ throw FileError(wxString(_("Incompatible synchronization database format:")) + wxT(" \n") + wxT("\"") + filename + wxT("\""));
+
+ //read DB id
+ output.first = Utility::UniqueId(getStream());
+ check();
+
+ DirectoryTOC& dbList = output.second;
+ dbList.clear();
+
+ size_t dbCount = readNumberC<size_t>(); //number of databases: one for each sync-pair
+ while (dbCount-- != 0)
+ {
+ const Utility::UniqueId partnerID(getStream()); //DB id of partner databases
+ check();
+
+ CharArray buffer = readArrayC(); //read db-entry stream (containing DirInformation)
+
+ dbList.insert(std::make_pair(partnerID, buffer));
+ }
+ }
+};
+
+
+DbStreamData loadFile(const Zstring& filename) //throw (FileError)
+{
+ if (!FreeFileSync::fileExists(filename))
+ throw FileError(wxString(_("Initial synchronization:")) + wxT(" \n\n") +
+ _("One of the FreeFileSync database files is not yet existing:") + wxT(" \n") +
+ wxT("\"") + zToWx(filename) + wxT("\""));
+
+
+ //read format description (uncompressed)
+ FileInputStreamDB uncompressed(filename); //throw (FileError)
+
+ wxZlibInputStream input(uncompressed, wxZLIB_ZLIB);
+
+ DbStreamData output;
+ ReadFileStream(input, zToWx(filename), output);
+ return output;
+}
+
+
+std::pair<DirInfoPtr, DirInfoPtr> FreeFileSync::loadFromDisk(const BaseDirMapping& baseMapping) //throw (FileError)
+{
+ const Zstring fileNameLeft = baseMapping.getDBFilename<LEFT_SIDE>();
+ const Zstring fileNameRight = baseMapping.getDBFilename<RIGHT_SIDE>();
+
+ //read file data: db ID + mapping of partner-ID/DirInfo-stream
+ const DbStreamData dbEntriesLeft = ::loadFile(fileNameLeft);
+ const DbStreamData dbEntriesRight = ::loadFile(fileNameRight);
+
+ //find associated DirInfo-streams
+ DirectoryTOC::const_iterator dbLeft = dbEntriesLeft.second.find(dbEntriesRight.first); //find left db-entry that corresponds to right database
+ if (dbLeft == dbEntriesLeft.second.end())
+ throw FileError(wxString(_("Initial synchronization:")) + wxT(" \n\n") +
+ _("One of the FreeFileSync database entries within the following file is not yet existing:") + wxT(" \n") +
+ wxT("\"") + zToWx(fileNameLeft) + wxT("\""));
+
+ DirectoryTOC::const_iterator dbRight = dbEntriesRight.second.find(dbEntriesLeft.first); //find left db-entry that corresponds to right database
+ if (dbRight == dbEntriesRight.second.end())
+ throw FileError(wxString(_("Initial synchronization:")) + wxT(" \n\n") +
+ _("One of the FreeFileSync database entries within the following file is not yet existing:") + wxT(" \n") +
+ wxT("\"") + zToWx(fileNameRight) + wxT("\""));
+
+ //read streams into DirInfo
+ boost::shared_ptr<DirInformation> dirInfoLeft(new DirInformation);
+ wxMemoryInputStream buffer(&(*dbLeft->second)[0], dbLeft->second->size()); //convert char-array to inputstream: no copying, ownership not transferred
+ ReadDirInfo(buffer, zToWx(fileNameLeft), *dirInfoLeft); //read file/dir information
+
+ boost::shared_ptr<DirInformation> dirInfoRight(new DirInformation);
+ wxMemoryInputStream buffer2(&(*dbRight->second)[0], dbRight->second->size()); //convert char-array to inputstream: no copying, ownership not transferred
+ ReadDirInfo(buffer2, zToWx(fileNameRight), *dirInfoRight); //read file/dir information
+
+ return std::make_pair(dirInfoLeft, dirInfoRight);
+}
+
+
+//-------------------------------------------------------------------------------------------------------------------------
+
+template <SelectedSide side>
+struct IsNonEmpty
+{
+ bool operator()(const FileSystemObject& fsObj) const
+ {
+ return !fsObj.isEmpty<side>();
+ }
+};
+
+
+template <SelectedSide side>
+class SaveDirInfo : public Utility::WriteOutputStream
+{
+public:
+ SaveDirInfo(const BaseDirMapping& baseMapping, const wxString& errorObjName, wxOutputStream& stream) : WriteOutputStream(errorObjName, stream)
+ {
+ //save filter settings
+ baseMapping.getFilter()->saveFilter(getStream());
+ check();
+
+ //start recursion
+ execute(baseMapping);
+ }
+
+private:
+ template<typename Iterator, typename Function>
+ friend Function std::for_each(Iterator, Iterator, Function);
+
+ void execute(const HierarchyObject& hierObj)
+ {
+ writeNumberC<unsigned int>(std::count_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), IsNonEmpty<side>())); //number of (existing) files
+ std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), *this);
+
+ writeNumberC<unsigned int>(std::count_if(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), IsNonEmpty<side>())); //number of (existing) directories
+ std::for_each(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), *this);
+ }
+
+ void operator()(const FileMapping& fileMap)
+ {
+ if (!fileMap.isEmpty<side>())
+ {
+ writeStringC(fileMap.getObjShortName()); //file name
+ writeNumberC<long>( fileMap.getLastWriteTime<side>().GetHi()); //last modification time
+ writeNumberC<unsigned long>(fileMap.getLastWriteTime<side>().GetLo()); //
+ writeNumberC<unsigned long>(fileMap.getFileSize<side>().GetHi()); //filesize
+ writeNumberC<unsigned long>(fileMap.getFileSize<side>().GetLo()); //
+
+ //fileMap.getFileID<side>().toStream(stream_); //unique file identifier
+ //check();
+ }
+ }
+
+ void operator()(const DirMapping& dirMap)
+ {
+ if (!dirMap.isEmpty<side>())
+ {
+ writeStringC(dirMap.getObjShortName()); //directory name
+ execute(dirMap); //recurse
+ }
+ }
+};
+
+
+class WriteFileStream : public Utility::WriteOutputStream
+{
+public:
+ WriteFileStream(const DbStreamData& input, const wxString& filename, wxOutputStream& stream) : WriteOutputStream(filename, stream)
+ {
+ //save file format version
+ writeNumberC<int>(FILE_FORMAT_VER);
+
+ //write DB id
+ input.first.toStream(getStream());
+ check();
+
+ const DirectoryTOC& dbList = input.second;
+
+ writeNumberC<size_t>(dbList.size()); //number of database records: one for each sync-pair
+
+ for (DirectoryTOC::const_iterator i = dbList.begin(); i != dbList.end(); ++i)
+ {
+ i->first.toStream(getStream()); //DB id of partner database
+ check();
+
+ writeArrayC(*(i->second)); //write DirInformation stream
+ }
+ }
+};
+
+
+//save/load DirContainer
+void saveFile(const DbStreamData& dbStream, const Zstring& filename) //throw (FileError)
+{
+ {
+ //write format description (uncompressed)
+ FileOutputStreamDB uncompressed(filename); //throw (FileError)
+
+ wxZlibOutputStream output(uncompressed, 4, wxZLIB_ZLIB);
+ /* 4 - best compromise between speed and compression: (scanning 200.000 objects)
+ 0 (uncompressed) 8,95 MB - 422 ms
+ 2 2,07 MB - 470 ms
+ 4 1,87 MB - 500 ms
+ 6 1,77 MB - 613 ms
+ 9 (maximal compression) 1,74 MB - 3330 ms */
+
+ WriteFileStream(dbStream, zToWx(filename), output);
+ }
+ //(try to) hide database file
+#ifdef FFS_WIN
+ ::SetFileAttributes(FreeFileSync::applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_HIDDEN);
+#endif
+}
+
+
+void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileError)
+{
+ //transactional behaviour! write to tmp files first
+ const Zstring fileNameLeftTmp = baseMapping.getDBFilename<LEFT_SIDE>() + DefaultStr(".tmp");
+ const Zstring fileNameRightTmp = baseMapping.getDBFilename<RIGHT_SIDE>() + DefaultStr(".tmp");;
+
+ //delete old tmp file, if necessary -> throws if deletion fails!
+ removeFile(fileNameLeftTmp);
+ removeFile(fileNameRightTmp);
+
+ try
+ {
+ //load old database files...
+
+ //read file data: db ID + mapping of partner-ID/DirInfo-stream: may throw!
+ DbStreamData dbEntriesLeft;
+ if (FreeFileSync::fileExists(baseMapping.getDBFilename<LEFT_SIDE>()))
+ try
+ {
+ dbEntriesLeft = ::loadFile(baseMapping.getDBFilename<LEFT_SIDE>());
+ }
+ catch(FileError&) {} //if error occurs: just overwrite old file! User is informed about issues right after comparing!
+ //else -> dbEntriesLeft has empty mapping, but already a DB-ID!
+
+ //read file data: db ID + mapping of partner-ID/DirInfo-stream: may throw!
+ DbStreamData dbEntriesRight;
+ if (FreeFileSync::fileExists(baseMapping.getDBFilename<RIGHT_SIDE>()))
+ try
+ {
+ dbEntriesRight = ::loadFile(baseMapping.getDBFilename<RIGHT_SIDE>());
+ }
+ catch(FileError&) {} //if error occurs: just overwrite old file! User is informed about issues right after comparing!
+
+ //create new database entries
+ MemoryStreamPtr dbEntryLeft(new std::vector<char>);
+ {
+ wxMemoryOutputStream buffer;
+ SaveDirInfo<LEFT_SIDE>(baseMapping, zToWx(baseMapping.getDBFilename<LEFT_SIDE>()), buffer);
+ dbEntryLeft->resize(buffer.GetSize()); //convert output stream to char-array
+ buffer.CopyTo(&(*dbEntryLeft)[0], buffer.GetSize()); //
+ }
+
+ MemoryStreamPtr dbEntryRight(new std::vector<char>);
+ {
+ wxMemoryOutputStream buffer;
+ SaveDirInfo<RIGHT_SIDE>(baseMapping, zToWx(baseMapping.getDBFilename<RIGHT_SIDE>()), buffer);
+ dbEntryRight->resize(buffer.GetSize()); //convert output stream to char-array
+ buffer.CopyTo(&(*dbEntryRight)[0], buffer.GetSize()); //
+ }
+
+ //create/update DirInfo-streams
+ dbEntriesLeft.second[dbEntriesRight.first] = dbEntryLeft;
+ dbEntriesRight.second[dbEntriesLeft.first] = dbEntryRight;
+
+ //write (temp-) files...
+ saveFile(dbEntriesLeft, fileNameLeftTmp); //throw (FileError)
+ saveFile(dbEntriesRight, fileNameRightTmp); //throw (FileError)
+
+ //operation finished: rename temp files -> this should work transactionally:
+ //if there were no write access, creation of temp files would have failed
+ removeFile(baseMapping.getDBFilename<LEFT_SIDE>());
+ removeFile(baseMapping.getDBFilename<RIGHT_SIDE>());
+ renameFile(fileNameLeftTmp, baseMapping.getDBFilename<LEFT_SIDE>()); //throw (FileError);
+ renameFile(fileNameRightTmp, baseMapping.getDBFilename<RIGHT_SIDE>()); //throw (FileError);
+ }
+ catch (...)
+ {
+ try //clean up: (try to) delete old tmp files
+ {
+ removeFile(fileNameLeftTmp);
+ }
+ catch (...) {}
+ try
+ {
+ removeFile(fileNameRightTmp);
+ }
+ catch (...) {}
+
+ throw;
+ }
+}
diff --git a/library/dbFile.h b/library/dbFile.h
new file mode 100644
index 00000000..e7db0393
--- /dev/null
+++ b/library/dbFile.h
@@ -0,0 +1,20 @@
+// **************************************************************************
+// * 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 DBFILE_H_INCLUDED
+#define DBFILE_H_INCLUDED
+
+#include "../fileHierarchy.h"
+
+namespace FreeFileSync
+{
+void saveToDisk(const BaseDirMapping& baseMapping); //throw (FileError)
+
+typedef boost::shared_ptr<const DirInformation> DirInfoPtr;
+std::pair<DirInfoPtr, DirInfoPtr> loadFromDisk(const BaseDirMapping& baseMapping); //throw (FileError) -> return value always bound!
+}
+
+#endif // DBFILE_H_INCLUDED
diff --git a/library/filter.cpp b/library/filter.cpp
index b1b67b86..d7f12bec 100644
--- a/library/filter.cpp
+++ b/library/filter.cpp
@@ -273,8 +273,8 @@ bool NameFilter::isNull() const
bool NameFilter::cmpLessSameType(const BaseFilter& other) const
{
- //typeid(*this) == typeid(other) in this context!
- assert(typeid(*this) == typeid(other));
+ assert(typeid(*this) == typeid(other)); //always given in this context!
+
const NameFilter& otherNameFilt = static_cast<const NameFilter&>(other);
if (filterFileIn != otherNameFilt.filterFileIn)
diff --git a/library/filter.h b/library/filter.h
index 6ec5a3d5..5df74997 100644
--- a/library/filter.h
+++ b/library/filter.h
@@ -55,7 +55,7 @@ public:
static FilterRef loadFilter(wxInputStream& stream); //CAVEAT!!! adapt this method for each new derivation!!!
private:
- virtual Zstring uniqueClassIdentifier() const = 0; //get identifier, used for serialization
+ virtual Zstring uniqueClassIdentifier() const = 0; //get identifier, used for serialization
virtual void save(wxOutputStream& stream) const = 0; //serialization
virtual bool cmpLessSameType(const BaseFilter& other) const = 0; //typeid(*this) == typeid(other) in this context!
};
@@ -91,10 +91,10 @@ private:
virtual void save(wxOutputStream& stream) const;
virtual bool cmpLessSameType(const BaseFilter& other) const;
- std::set<Zstring> filterFileIn;
- std::set<Zstring> filterFolderIn;
- std::set<Zstring> filterFileEx;
- std::set<Zstring> filterFolderEx;
+ std::set<Zstring> filterFileIn; //upper case (windows)
+ std::set<Zstring> filterFolderIn; //
+ std::set<Zstring> filterFileEx; //
+ std::set<Zstring> filterFolderEx; //
const Zstring includeFilterTmp; //save constructor arguments for serialization
const Zstring excludeFilterTmp; //
@@ -175,8 +175,7 @@ bool NullFilter::isNull() const
inline
bool NullFilter::cmpLessSameType(const BaseFilter& other) const
{
- //typeid(*this) == typeid(other) in this context!
- assert(typeid(*this) == typeid(other));
+ assert(typeid(*this) == typeid(other)); //always given in this context!
return false;
}
@@ -214,8 +213,8 @@ bool CombinedFilter::isNull() const
inline
bool CombinedFilter::cmpLessSameType(const BaseFilter& other) const
{
- //typeid(*this) == typeid(other) in this context!
- assert(typeid(*this) == typeid(other));
+ assert(typeid(*this) == typeid(other)); //always given in this context!
+
const CombinedFilter& otherCombFilt = static_cast<const CombinedFilter&>(other);
if (*first_ != *otherCombFilt.first_)
diff --git a/library/processXml.cpp b/library/processXml.cpp
index 69cf8baf..1cc279b0 100644
--- a/library/processXml.cpp
+++ b/library/processXml.cpp
@@ -6,16 +6,12 @@
//
#include "processXml.h"
#include "../shared/xmlBase.h"
-#include <wx/filefn.h>
#include <wx/intl.h>
+#include <wx/filefn.h>
#include "../shared/globalFunctions.h"
#include "../shared/standardPaths.h"
#include "../shared/stringConv.h"
-#ifdef FFS_WIN
-#include <wx/msw/wrapwin.h> //includes "windows.h"
-#endif
-
using namespace FreeFileSync;
using namespace xmlAccess; //functionally needed!!!
@@ -57,17 +53,16 @@ void xmlAccess::readGuiConfig(const wxString& filename, xmlAccess::XmlGuiConfig&
{
//load XML
if (!wxFileExists(filename))
- throw XmlError(wxString(_("File does not exist:")) + wxT(" \"") + filename + wxT("\""));
+ throw XmlError(wxString(_("File does not exist:")) + wxT("\n\"") + filename + wxT("\""));
TiXmlDocument doc;
- if (!loadXmlDocument(filename, XML_GUI_CONFIG, doc))
- throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + filename + wxT("\""));
+ loadXmlDocument(filename, XML_GUI_CONFIG, doc); //throw (XmlError)
FfsXmlParser parser(doc.RootElement());
parser.readXmlGuiConfig(config); //read GUI layout configuration
if (parser.errorsOccured())
- throw XmlError(wxString(_("Error parsing configuration file:")) + wxT(" \"") + filename + wxT("\"\n\n") +
+ throw XmlError(wxString(_("Error parsing configuration file:")) + wxT("\n\"") + filename + wxT("\"\n\n") +
parser.getErrorMessageFormatted(), XmlError::WARNING);
}
@@ -76,17 +71,16 @@ void xmlAccess::readBatchConfig(const wxString& filename, xmlAccess::XmlBatchCon
{
//load XML
if (!wxFileExists(filename))
- throw XmlError(wxString(_("File does not exist:")) + wxT(" \"") + filename + wxT("\""));
+ throw XmlError(wxString(_("File does not exist:")) + wxT("\n\"") + filename + wxT("\""));
TiXmlDocument doc;
- if (!loadXmlDocument(filename, XML_BATCH_CONFIG, doc))
- throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + filename + wxT("\""));
+ loadXmlDocument(filename, XML_BATCH_CONFIG, doc); //throw (XmlError)
FfsXmlParser parser(doc.RootElement());
parser.readXmlBatchConfig(config); //read GUI layout configuration
if (parser.errorsOccured())
- throw XmlError(wxString(_("Error parsing configuration file:")) + wxT(" \"") + filename + wxT("\"\n\n") +
+ throw XmlError(wxString(_("Error parsing configuration file:")) + wxT("\n\"") + filename + wxT("\"\n\n") +
parser.getErrorMessageFormatted(), XmlError::WARNING);
}
@@ -95,17 +89,16 @@ void xmlAccess::readGlobalSettings(xmlAccess::XmlGlobalSettings& config)
{
//load XML
if (!wxFileExists(getGlobalConfigFile()))
- throw XmlError(wxString(_("File does not exist:")) + wxT(" \"") + getGlobalConfigFile() + wxT("\""));
+ throw XmlError(wxString(_("File does not exist:")) + wxT("\n\"") + getGlobalConfigFile() + wxT("\""));
TiXmlDocument doc;
- if (!loadXmlDocument(getGlobalConfigFile(), XML_GLOBAL_SETTINGS, doc))
- throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + getGlobalConfigFile() + wxT("\""));
+ loadXmlDocument(getGlobalConfigFile(), XML_GLOBAL_SETTINGS, doc); //throw (XmlError)
FfsXmlParser parser(doc.RootElement());
parser.readXmlGlobalSettings(config); //read GUI layout configuration
if (parser.errorsOccured())
- throw XmlError(wxString(_("Error parsing configuration file:")) + wxT(" \"") + getGlobalConfigFile() + wxT("\"\n\n") +
+ throw XmlError(wxString(_("Error parsing configuration file:")) + wxT("\n\"") + getGlobalConfigFile() + wxT("\"\n\n") +
parser.getErrorMessageFormatted(), XmlError::WARNING);
}
@@ -116,10 +109,10 @@ void xmlAccess::writeGuiConfig(const XmlGuiConfig& outputCfg, const wxString& fi
getDefaultXmlDocument(XML_GUI_CONFIG, doc);
//populate and write XML tree
- if ( !writeXmlGuiConfig(outputCfg, doc) || //add GUI layout configuration settings
- !saveXmlDocument(filename, doc)) //save XML
- throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + filename + wxT("\""));
- return;
+ if (!writeXmlGuiConfig(outputCfg, doc)) //add GUI layout configuration settings
+ throw XmlError(wxString(_("Error writing file:")) + wxT("\n\"") + filename + wxT("\""));
+
+ saveXmlDocument(filename, doc); //throw (XmlError)
}
@@ -129,10 +122,10 @@ void xmlAccess::writeBatchConfig(const XmlBatchConfig& outputCfg, const wxString
getDefaultXmlDocument(XML_BATCH_CONFIG, doc);
//populate and write XML tree
- if ( !writeXmlBatchConfig(outputCfg, doc) || //add batch configuration settings
- !saveXmlDocument(filename, doc)) //save XML
- throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + filename + wxT("\""));
- return;
+ if (!writeXmlBatchConfig(outputCfg, doc)) //add batch configuration settings
+ throw XmlError(wxString(_("Error writing file:")) + wxT("\n\"") + filename + wxT("\""));
+
+ saveXmlDocument(filename, doc); //throw (XmlError)
}
@@ -142,10 +135,10 @@ void xmlAccess::writeGlobalSettings(const XmlGlobalSettings& outputCfg)
getDefaultXmlDocument(XML_GLOBAL_SETTINGS, doc);
//populate and write XML tree
- if ( !writeXmlGlobalSettings(outputCfg, doc) || //add GUI layout configuration settings
- !saveXmlDocument(getGlobalConfigFile(), doc)) //save XML
- throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + getGlobalConfigFile() + wxT("\""));
- return;
+ if (!writeXmlGlobalSettings(outputCfg, doc)) //add GUI layout configuration settings
+ throw XmlError(wxString(_("Error writing file:")) + wxT("\n\"") + getGlobalConfigFile() + wxT("\""));
+
+ saveXmlDocument(getGlobalConfigFile(), doc); //throw (XmlError)
}
@@ -298,7 +291,7 @@ void FfsXmlParser::readXmlLocalConfig(const TiXmlElement& folderPair, FolderPair
void FfsXmlParser::readXmlMainConfig(MainConfiguration& mainCfg)
{
- TiXmlHandleConst hRoot(root); //custom const handle: TiXml API seems broken in this regard
+ TiXmlHandleConst hRoot(getRoot()); //custom const handle: TiXml API seems broken in this regard
//###########################################################
const TiXmlElement* cmpSettings = hRoot.FirstChild("MainConfig").FirstChild("Comparison").ToElement();
@@ -378,7 +371,7 @@ void FfsXmlParser::readXmlGuiConfig(xmlAccess::XmlGuiConfig& outputCfg)
readXmlMainConfig(outputCfg.mainCfg);
//read GUI specific config data
- const TiXmlElement* guiConfig = TiXmlHandleConst(root).FirstChild("GuiConfig").ToElement();
+ const TiXmlElement* guiConfig = TiXmlHandleConst(getRoot()).FirstChild("GuiConfig").ToElement();
readXmlElementLogging("HideFiltered", guiConfig, outputCfg.hideFilteredElements);
@@ -396,7 +389,7 @@ void FfsXmlParser::readXmlBatchConfig(xmlAccess::XmlBatchConfig& outputCfg)
readXmlMainConfig(outputCfg.mainCfg);
//read batch specific config
- const TiXmlElement* batchConfig = TiXmlHandleConst(root).FirstChild("BatchConfig").ToElement();
+ const TiXmlElement* batchConfig = TiXmlHandleConst(getRoot()).FirstChild("BatchConfig").ToElement();
readXmlElementLogging("Silent", batchConfig, outputCfg.silent);
readXmlElementLogging("LogfileDirectory", batchConfig, outputCfg.logFileDirectory);
@@ -407,7 +400,7 @@ void FfsXmlParser::readXmlBatchConfig(xmlAccess::XmlBatchConfig& outputCfg)
void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg)
{
//read global settings
- const TiXmlElement* global = TiXmlHandleConst(root).FirstChild("Shared").ToElement();
+ const TiXmlElement* global = TiXmlHandleConst(getRoot()).FirstChild("Shared").ToElement();
//try to read program language setting
readXmlElementLogging("Language", global, outputCfg.programLanguage);
@@ -418,11 +411,8 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//copy locked files using VSS
readXmlElementLogging("CopyLockedFiles", global, outputCfg.copyLockedFiles);
- //last update check
- readXmlElementLogging("LastCheckForUpdates", global, outputCfg.lastUpdateCheck);
-
- const TiXmlElement* optionalDialogs = TiXmlHandleConst(root).FirstChild("Shared").FirstChild("ShowOptionalDialogs").ToElement();
+ const TiXmlElement* optionalDialogs = TiXmlHandleConst(getRoot()).FirstChild("Shared").FirstChild("ShowOptionalDialogs").ToElement();
//folder dependency check
readXmlElementLogging("CheckForDependentFolders", optionalDialogs, outputCfg.optDialogs.warningDependentFolders);
@@ -441,7 +431,8 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//gui specific global settings (optional)
- const TiXmlElement* mainWindow = TiXmlHandleConst(root).FirstChild("Gui").FirstChild("Windows").FirstChild("Main").ToElement();
+ const TiXmlElement* gui = TiXmlHandleConst(getRoot()).FirstChild("Gui").ToElement();
+ const TiXmlElement* mainWindow = TiXmlHandleConst(gui).FirstChild("Windows").FirstChild("Main").ToElement();
//read application window size and position
readXmlElementLogging("Width", mainWindow, outputCfg.gui.widthNotMaximized);
@@ -509,8 +500,6 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
readXmlElementLogging("SelectedTabBottomLeft", mainWindow, outputCfg.gui.selectedTabBottomLeft);
- const TiXmlElement* gui = TiXmlHandleConst(root).FirstChild("Gui").ToElement();
-
//external applications
const TiXmlElement* extApps = TiXmlHandleConst(gui).FirstChild("ExternalApplications").FirstChild("Commandline").ToElement();
if (extApps)
@@ -530,7 +519,7 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
}
}
//load config file history
- const TiXmlElement* cfgHistory = TiXmlHandleConst(root).FirstChild("Gui").FirstChild("ConfigHistory").ToElement();
+ const TiXmlElement* cfgHistory = TiXmlHandleConst(gui).FirstChild("ConfigHistory").ToElement();
//load max. history size
readXmlAttributeLogging("MaximumSize", cfgHistory, outputCfg.gui.cfgHistoryMax);
@@ -538,6 +527,9 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//load config history elements
readXmlElementLogging("File", cfgHistory, outputCfg.gui.cfgFileHistory);
+ //last update check
+ readXmlElementLogging("LastUpdateCheck", gui, outputCfg.gui.lastUpdateCheck);
+
//batch specific global settings
//const TiXmlElement* batch = TiXmlHandleConst(root).FirstChild("Batch").ToElement();
@@ -818,9 +810,6 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD
//copy locked files using VSS
addXmlElement("CopyLockedFiles", inputCfg.copyLockedFiles, global);
- //last update check
- addXmlElement("LastCheckForUpdates", inputCfg.lastUpdateCheck, global);
-
//optional dialogs
TiXmlElement* optionalDialogs = new TiXmlElement("ShowOptionalDialogs");
@@ -943,6 +932,10 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD
addXmlAttribute("MaximumSize", inputCfg.gui.cfgHistoryMax, cfgHistory);
addXmlElement("File", inputCfg.gui.cfgFileHistory, cfgHistory);
+
+ //last update check
+ addXmlElement("LastUpdateCheck", inputCfg.gui.lastUpdateCheck, gui);
+
//###################################################################
//write global batch settings
diff --git a/library/processXml.h b/library/processXml.h
index ad8465ff..13282de9 100644
--- a/library/processXml.h
+++ b/library/processXml.h
@@ -8,7 +8,6 @@
#define PROCESSXML_H_INCLUDED
#include "../structures.h"
-#include <wx/intl.h>
namespace xmlAccess
{
@@ -116,14 +115,12 @@ struct XmlGlobalSettings
XmlGlobalSettings() :
programLanguage(retrieveSystemLanguage()),
ignoreOneHourDiff(false),
- copyLockedFiles(true),
- lastUpdateCheck(0)
+ copyLockedFiles(true)
{}
int programLanguage;
bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change
bool copyLockedFiles; //VSS usage
- long lastUpdateCheck; //time of last update check
OptionalDialogs optDialogs;
@@ -150,7 +147,8 @@ struct XmlGlobalSettings
textSearchRespectCase(true),
#endif
showFileIconsLeft(true),
- showFileIconsRight(true)
+ showFileIconsRight(true),
+ lastUpdateCheck(0)
{
//default external apps will be translated "on the fly"!!!
#ifdef FFS_WIN
@@ -194,6 +192,8 @@ struct XmlGlobalSettings
bool textSearchRespectCase;
bool showFileIconsLeft;
bool showFileIconsRight;
+
+ long lastUpdateCheck; //time of last update check
} gui;
//---------------------------------------------------------------------
diff --git a/library/softFilter.cpp b/library/softFilter.cpp
new file mode 100644
index 00000000..496c185e
--- /dev/null
+++ b/library/softFilter.cpp
@@ -0,0 +1,10 @@
+// **************************************************************************
+// * 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 "softFilter.h"
+
+
+
diff --git a/library/softFilter.h b/library/softFilter.h
new file mode 100644
index 00000000..e4735e38
--- /dev/null
+++ b/library/softFilter.h
@@ -0,0 +1,79 @@
+// **************************************************************************
+// * 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 SOFTFILTER_H_INCLUDED
+#define SOFTFILTER_H_INCLUDED
+
+#include "../fileHierarchy.h"
+#include <wx/timer.h>
+/*
+Semantics of SoftFilter:
+1. It potentially can match only one side => it MUST NOT be applied while traversing a single folder to avoid mismatches
+2. => it is applied after traversing and just marks rows, (NO deletions after comparison are allowed)
+3. => not relevant for <Automatic>-mode! ;)
+
+-> SoftFilter is equivalent to a user temporarily (de-)selecting rows
+*/
+
+namespace FreeFileSync
+{
+
+class SoftFilter
+{
+public:
+ SoftFilter(size_t timeWindow) :
+ timeWindow_(timeWindow),
+ currentTime(wxGetUTCTime()) {}
+
+ bool passFilter(const FileMapping& fileMap) const;
+ bool passFilter(const DirMapping& dirMap) const;
+
+private:
+ const size_t timeWindow_; //point in time from "now" (in seconds) for oldest modification date to be allowed
+ const long currentTime; //number of seconds since GMT 00:00:00 Jan 1st 1970.
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//---------------Inline Implementation---------------------------------------------------
+inline
+bool SoftFilter::passFilter(const FileMapping& fileMap) const
+{
+ return (!fileMap.isEmpty<LEFT_SIDE>() &&
+ currentTime <= fileMap.getLastWriteTime<LEFT_SIDE>() + timeWindow_) ||
+ (!fileMap.isEmpty<RIGHT_SIDE>() &&
+ currentTime <= fileMap.getLastWriteTime<RIGHT_SIDE>() + timeWindow_);
+}
+
+
+inline
+bool SoftFilter::passFilter(const DirMapping& dirMap) const
+{
+ return false;
+}
+}
+
+#endif // SOFTFILTER_H_INCLUDED
diff --git a/library/statistics.cpp b/library/statistics.cpp
index ac968d1f..6e64be1c 100644
--- a/library/statistics.cpp
+++ b/library/statistics.cpp
@@ -10,7 +10,7 @@
#include "../shared/globalFunctions.h"
#include "statusHandler.h"
//#include "../algorithm.h"
-#include "../ui/util.h"
+#include "../shared/util.h"
#include <wx/intl.h>
#include <limits>
#include <wx/stopwatch.h>
@@ -31,11 +31,11 @@ RetrieveStatistics::~RetrieveStatistics()
for (std::vector<statEntry>::const_iterator i = data.begin(); i != data.end(); ++i)
{
- outputFile.Write(globalFunctions::numberToWxString(int(i->time)));
+ outputFile.Write(FreeFileSync::numberToWxString(static_cast<int>(i->time), false));
outputFile.Write(wxT(";"));
- outputFile.Write(globalFunctions::numberToWxString(i->objects));
+ outputFile.Write(FreeFileSync::numberToWxString(i->objects, false));
outputFile.Write(wxT(";"));
- outputFile.Write(globalFunctions::numberToWxString(float(i->value)));
+ outputFile.Write(FreeFileSync::numberToWxString(static_cast<int>(i->value), false));
outputFile.Write(wxT("\n"));
}
}
@@ -104,7 +104,7 @@ wxString Statistics::formatRemainingTime(const double timeInMs) const
}
remainingTimeLast = formattedTime;
- return globalFunctions::numberToWxString(formattedTime) + unit;
+ return FreeFileSync::numberToWxString(formattedTime, false) + unit;
//+ wxT("(") + globalFunctions::numberToWxString(globalFunctions::round(timeInMs / 1000)) + wxT(")");
}
bgstack15