diff options
Diffstat (limited to 'RealtimeSync')
-rw-r--r-- | RealtimeSync/RealtimeSync.cbp | 84 | ||||
-rw-r--r-- | RealtimeSync/RealtimeSync.vcxproj | 81 | ||||
-rw-r--r-- | RealtimeSync/application.cpp | 16 | ||||
-rw-r--r-- | RealtimeSync/functions.cpp | 10 | ||||
-rw-r--r-- | RealtimeSync/functions.h | 2 | ||||
-rw-r--r-- | RealtimeSync/gui_generated.cpp (renamed from RealtimeSync/guiGenerated.cpp) | 4 | ||||
-rw-r--r-- | RealtimeSync/gui_generated.h (renamed from RealtimeSync/guiGenerated.h) | 0 | ||||
-rw-r--r-- | RealtimeSync/main_dlg.cpp (renamed from RealtimeSync/mainDialog.cpp) | 76 | ||||
-rw-r--r-- | RealtimeSync/main_dlg.h (renamed from RealtimeSync/mainDialog.h) | 10 | ||||
-rw-r--r-- | RealtimeSync/makefile | 43 | ||||
-rw-r--r-- | RealtimeSync/notify.cpp | 268 | ||||
-rw-r--r-- | RealtimeSync/notify.h | 40 | ||||
-rw-r--r-- | RealtimeSync/pch.h | 6 | ||||
-rw-r--r-- | RealtimeSync/resources.cpp | 8 | ||||
-rw-r--r-- | RealtimeSync/tray_menu.cpp (renamed from RealtimeSync/trayMenu.cpp) | 52 | ||||
-rw-r--r-- | RealtimeSync/tray_menu.h (renamed from RealtimeSync/trayMenu.h) | 4 | ||||
-rw-r--r-- | RealtimeSync/watcher.cpp | 372 | ||||
-rw-r--r-- | RealtimeSync/watcher.h | 4 | ||||
-rw-r--r-- | RealtimeSync/xml_ffs.cpp (renamed from RealtimeSync/xmlFreeFileSync.cpp) | 34 | ||||
-rw-r--r-- | RealtimeSync/xml_ffs.h (renamed from RealtimeSync/xmlFreeFileSync.h) | 4 | ||||
-rw-r--r-- | RealtimeSync/xml_proc.cpp (renamed from RealtimeSync/xmlProcessing.cpp) | 4 | ||||
-rw-r--r-- | RealtimeSync/xml_proc.h (renamed from RealtimeSync/xmlProcessing.h) | 2 |
22 files changed, 643 insertions, 481 deletions
diff --git a/RealtimeSync/RealtimeSync.cbp b/RealtimeSync/RealtimeSync.cbp index dd803ecf..e423cbfb 100644 --- a/RealtimeSync/RealtimeSync.cbp +++ b/RealtimeSync/RealtimeSync.cbp @@ -8,7 +8,7 @@ <Option compiler="gcc" /> <Build> <Target title="Release"> - <Option output="..\BUILD\RealtimeSync" prefix_auto="1" extension_auto="1" /> + <Option output="..\BUILD\RealtimeSync_Win32" prefix_auto="1" extension_auto="1" /> <Option working_dir="..\BUILD" /> <Option object_output="..\OBJ\Release_RTS_GCC" /> <Option type="0" /> @@ -21,16 +21,18 @@ </Compiler> <Linker> <Add option="-s" /> + <Add option="-static" /> <Add library="libwxmsw28u_core.a" /> <Add library="libwxmsw28u_adv.a" /> <Add library="libwxbase28u.a" /> <Add library="libwxpng.a" /> <Add library="libwxzlib.a" /> + <Add library="libboost_thread-mgw45-mt-s-1_43.a" /> <Add directory="C:\Programme\C++\wxWidgets\lib\gcc_lib" /> </Linker> </Target> <Target title="Debug-DLL"> - <Option output="..\BUILD\RealtimeSync" prefix_auto="1" extension_auto="1" /> + <Option output="..\BUILD\RealtimeSync_Debug" prefix_auto="1" extension_auto="1" /> <Option working_dir="..\BUILD" /> <Option object_output="..\OBJ\Debug_RTS_GCC" /> <Option type="0" /> @@ -49,6 +51,7 @@ <Add library="libwxbase28ud.a" /> <Add library="libwxpngd.a" /> <Add library="libwxzlibd.a" /> + <Add library="libboost_thread-mgw45-mt-sd-1_43.a" /> <Add directory="C:\Program Files\C++\wxWidgets\lib\gcc_dll" /> </Linker> </Target> @@ -68,7 +71,7 @@ <Add option="-DZSTRING_WIDE_CHAR" /> <Add option="-DTIXML_USE_STL" /> <Add directory="C:\Programme\C++\wxWidgets\include" /> - <Add directory="..\shared\boost_1_x" /> + <Add directory="C:\Program Files\C++\Boost" /> </Compiler> <ResourceCompiler> <Add directory="C:\Programme\C++\wxWidgets\include" /> @@ -85,16 +88,20 @@ <Add library="liboleaut32.a" /> <Add library="libcomdlg32.a" /> <Add library="libws2_32.a" /> + <Add library="libwinspool.a" /> + <Add directory="C:\Program Files\C++\Boost\stage\lib" /> </Linker> <Unit filename="WxWizDialog.fbp" /> <Unit filename="application.cpp" /> <Unit filename="application.h" /> <Unit filename="functions.cpp" /> <Unit filename="functions.h" /> - <Unit filename="guiGenerated.cpp" /> - <Unit filename="guiGenerated.h" /> - <Unit filename="mainDialog.cpp" /> - <Unit filename="mainDialog.h" /> + <Unit filename="gui_generated.cpp" /> + <Unit filename="gui_generated.h" /> + <Unit filename="main_dlg.cpp" /> + <Unit filename="main_dlg.h" /> + <Unit filename="notify.cpp" /> + <Unit filename="notify.h" /> <Unit filename="pch.h"> <Option compile="1" /> <Option weight="0" /> @@ -105,49 +112,48 @@ </Unit> <Unit filename="resources.cpp" /> <Unit filename="resources.h" /> - <Unit filename="trayMenu.cpp" /> - <Unit filename="trayMenu.h" /> + <Unit filename="tray_menu.cpp" /> + <Unit filename="tray_menu.h" /> <Unit filename="watcher.cpp" /> <Unit filename="watcher.h" /> - <Unit filename="xmlFreeFileSync.cpp" /> - <Unit filename="xmlFreeFileSync.h" /> - <Unit filename="xmlProcessing.cpp" /> - <Unit filename="xmlProcessing.h" /> - <Unit filename="..\Shared\customButton.cpp" /> - <Unit filename="..\Shared\customButton.h" /> - <Unit filename="..\Shared\dragAndDrop.cpp" /> - <Unit filename="..\Shared\dragAndDrop.h" /> + <Unit filename="xml_ffs.cpp" /> + <Unit filename="xml_ffs.h" /> + <Unit filename="xml_proc.cpp" /> + <Unit filename="xml_proc.h" /> + <Unit filename="..\Shared\custom_button.cpp" /> + <Unit filename="..\Shared\custom_button.h" /> + <Unit filename="..\Shared\drag_n_drop.cpp" /> + <Unit filename="..\Shared\drag_n_drop.h" /> <Unit filename="..\Shared\zstring.cpp" /> <Unit filename="..\Shared\zstring.h" /> - <Unit filename="..\library\processXml.cpp" /> - <Unit filename="..\shared\checkExist.cpp" /> - <Unit filename="..\shared\dllLoader.cpp" /> - <Unit filename="..\shared\dllLoader.h" /> - <Unit filename="..\shared\fileError.h" /> - <Unit filename="..\shared\fileHandling.cpp" /> - <Unit filename="..\shared\fileHandling.h" /> - <Unit filename="..\shared\fileID.cpp" /> - <Unit filename="..\shared\fileIO.cpp" /> - <Unit filename="..\shared\fileTraverser.cpp" /> - <Unit filename="..\shared\globalFunctions.cpp" /> - <Unit filename="..\shared\globalFunctions.h" /> - <Unit filename="..\shared\helpProvider.cpp" /> + <Unit filename="..\library\process_xml.cpp" /> + <Unit filename="..\shared\check_exist.cpp" /> + <Unit filename="..\shared\dll_loader.cpp" /> + <Unit filename="..\shared\dll_loader.h" /> + <Unit filename="..\shared\file_error.h" /> + <Unit filename="..\shared\file_handling.cpp" /> + <Unit filename="..\shared\file_handling.h" /> + <Unit filename="..\shared\file_id.cpp" /> + <Unit filename="..\shared\file_io.cpp" /> + <Unit filename="..\shared\file_traverser.cpp" /> + <Unit filename="..\shared\global_func.cpp" /> + <Unit filename="..\shared\global_func.h" /> + <Unit filename="..\shared\help_provider.cpp" /> <Unit filename="..\shared\localization.cpp" /> <Unit filename="..\shared\localization.h" /> - <Unit filename="..\shared\longPathPrefix.cpp" /> - <Unit filename="..\shared\longPathPrefix.h" /> - <Unit filename="..\shared\parallelCall.cpp" /> + <Unit filename="..\shared\long_path_prefix.cpp" /> + <Unit filename="..\shared\long_path_prefix.h" /> <Unit filename="..\shared\shadow.cpp" /> - <Unit filename="..\shared\standardPaths.cpp" /> - <Unit filename="..\shared\standardPaths.h" /> - <Unit filename="..\shared\systemFunctions.cpp" /> - <Unit filename="..\shared\systemFunctions.h" /> + <Unit filename="..\shared\standard_paths.cpp" /> + <Unit filename="..\shared\standard_paths.h" /> + <Unit filename="..\shared\system_func.cpp" /> + <Unit filename="..\shared\system_func.h" /> <Unit filename="..\shared\tinyxml\tinystr.cpp" /> <Unit filename="..\shared\tinyxml\tinyxml.cpp" /> <Unit filename="..\shared\tinyxml\tinyxmlerror.cpp" /> <Unit filename="..\shared\tinyxml\tinyxmlparser.cpp" /> - <Unit filename="..\shared\xmlBase.cpp" /> - <Unit filename="..\shared\xmlBase.h" /> + <Unit filename="..\shared\xml_base.cpp" /> + <Unit filename="..\shared\xml_base.h" /> <Unit filename="..\structures.cpp" /> <Extensions> <code_completion /> diff --git a/RealtimeSync/RealtimeSync.vcxproj b/RealtimeSync/RealtimeSync.vcxproj index 04f1d7a8..4812a3d0 100644 --- a/RealtimeSync/RealtimeSync.vcxproj +++ b/RealtimeSync/RealtimeSync.vcxproj @@ -28,7 +28,7 @@ <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v100</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> @@ -41,7 +41,7 @@ <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v100</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> @@ -100,13 +100,13 @@ <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR</PreprocessorDefinitions> - <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets\include;C:\Programme\C++\wxWidgets\lib\vc_lib\mswud;..\shared\boost_1_x</AdditionalIncludeDirectories> - <PrecompiledHeaderFile>$(ProjectDir)../library/pch.h</PrecompiledHeaderFile> + <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets\include;C:\Programme\C++\wxWidgets\lib\vc_lib\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <PrecompiledHeaderFile>$(ProjectDir)/pch.h</PrecompiledHeaderFile> <DisableSpecificWarnings>4100</DisableSpecificWarnings> <MultiProcessorCompilation>false</MultiProcessorCompilation> <DisableLanguageExtensions>false</DisableLanguageExtensions> <PrecompiledHeaderOutputFile>$(IntDir)pch.obj</PrecompiledHeaderOutputFile> - <ForcedIncludeFiles>$(ProjectDir)../library/pch.h</ForcedIncludeFiles> + <ForcedIncludeFiles>$(ProjectDir)/pch.h</ForcedIncludeFiles> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> </ClCompile> <Link> @@ -115,7 +115,7 @@ <SuppressStartupBanner>true</SuppressStartupBanner> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalDependencies>wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxbase28ud.lib;wxpngd.lib;wxzlibd.lib;wxbase28ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets\lib\vc_lib</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets\lib\vc_lib;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> @@ -130,13 +130,13 @@ <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR</PreprocessorDefinitions> - <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets-x64\include;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud;..\shared\boost_1_x</AdditionalIncludeDirectories> - <PrecompiledHeaderFile>$(ProjectDir)../library/pch.h</PrecompiledHeaderFile> + <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets-x64\include;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <PrecompiledHeaderFile>$(ProjectDir)/pch.h</PrecompiledHeaderFile> <DisableSpecificWarnings>4100</DisableSpecificWarnings> <MultiProcessorCompilation>false</MultiProcessorCompilation> <DisableLanguageExtensions>false</DisableLanguageExtensions> <PrecompiledHeaderOutputFile>$(IntDir)pch.obj</PrecompiledHeaderOutputFile> - <ForcedIncludeFiles>$(ProjectDir)../library/pch.h</ForcedIncludeFiles> + <ForcedIncludeFiles>$(ProjectDir)/pch.h</ForcedIncludeFiles> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <SuppressStartupBanner>true</SuppressStartupBanner> </ClCompile> @@ -146,7 +146,7 @@ <SuppressStartupBanner>true</SuppressStartupBanner> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalDependencies>wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxbase28ud.lib;wxpngd.lib;wxzlibd.lib;wxbase28ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets-x64\lib\vc_lib</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets-x64\lib\vc_lib;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> @@ -163,9 +163,9 @@ <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>wxUSE_UNICODE;__WXMSW__;FFS_WIN;NDEBUG;TIXML_USE_STL;ZSTRING_WIDE_CHAR</PreprocessorDefinitions> - <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets\include;C:\Programme\C++\wxWidgets\lib\vc_lib\mswu;..\shared\boost_1_x</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets\include;C:\Programme\C++\wxWidgets\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <DisableLanguageExtensions>false</DisableLanguageExtensions> @@ -176,9 +176,9 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <SuppressStartupBanner>true</SuppressStartupBanner> - <AdditionalDependencies>wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets\lib\vc_lib</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets\lib\vc_lib;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> @@ -197,7 +197,7 @@ <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>wxUSE_UNICODE;__WXMSW__;FFS_WIN;NDEBUG;TIXML_USE_STL;ZSTRING_WIDE_CHAR</PreprocessorDefinitions> - <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets-x64\include;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu;..\shared\boost_1_x</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>C:\Programme\C++\wxWidgets-x64\include;C:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> @@ -211,9 +211,9 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <SuppressStartupBanner>true</SuppressStartupBanner> - <AdditionalDependencies>wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets-x64\lib\vc_lib</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>C:\Programme\C++\wxWidgets-x64\lib\vc_lib;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> @@ -225,44 +225,51 @@ </ResourceCompile> </ItemDefinitionGroup> <ItemGroup> - <ClCompile Include="..\library\processXml.cpp" /> - <ClCompile Include="..\shared\checkExist.cpp" /> - <ClCompile Include="..\shared\customButton.cpp" /> - <ClCompile Include="..\shared\dllLoader.cpp" /> - <ClCompile Include="..\shared\dragAndDrop.cpp" /> - <ClCompile Include="..\shared\fileHandling.cpp" /> - <ClCompile Include="..\shared\fileIO.cpp" /> - <ClCompile Include="..\shared\fileTraverser.cpp" /> - <ClCompile Include="..\shared\globalFunctions.cpp" /> - <ClCompile Include="..\shared\helpProvider.cpp" /> + <ClCompile Include="..\library\process_xml.cpp" /> + <ClCompile Include="..\shared\check_exist.cpp" /> + <ClCompile Include="..\shared\custom_button.cpp" /> + <ClCompile Include="..\shared\dll_loader.cpp" /> + <ClCompile Include="..\shared\drag_n_drop.cpp" /> + <ClCompile Include="..\shared\file_handling.cpp" /> + <ClCompile Include="..\shared\file_io.cpp" /> + <ClCompile Include="..\shared\file_traverser.cpp" /> + <ClCompile Include="..\shared\global_func.cpp" /> + <ClCompile Include="..\shared\help_provider.cpp" /> <ClCompile Include="..\shared\localization.cpp" /> - <ClCompile Include="..\shared\longPathPrefix.cpp" /> - <ClCompile Include="..\shared\parallelCall.cpp" /> + <ClCompile Include="..\shared\long_path_prefix.cpp" /> <ClCompile Include="..\shared\shadow.cpp" /> - <ClCompile Include="..\shared\standardPaths.cpp" /> - <ClCompile Include="..\shared\systemFunctions.cpp" /> + <ClCompile Include="..\shared\standard_paths.cpp" /> + <ClCompile Include="..\shared\system_func.cpp" /> <ClCompile Include="..\shared\tinyxml\tinyxml.cpp" /> <ClCompile Include="..\shared\tinyxml\tinyxmlerror.cpp" /> <ClCompile Include="..\shared\tinyxml\tinyxmlparser.cpp" /> - <ClCompile Include="..\shared\xmlBase.cpp" /> + <ClCompile Include="..\shared\xml_base.cpp" /> <ClCompile Include="..\shared\zstring.cpp" /> <ClCompile Include="..\structures.cpp" /> <ClCompile Include="application.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)/pch.h</PrecompiledHeaderFile> </ClCompile> <ClCompile Include="functions.cpp" /> - <ClCompile Include="guiGenerated.cpp" /> - <ClCompile Include="mainDialog.cpp" /> + <ClCompile Include="gui_generated.cpp" /> + <ClCompile Include="main_dlg.cpp" /> + <ClCompile Include="notify.cpp" /> <ClCompile Include="resources.cpp" /> - <ClCompile Include="trayMenu.cpp" /> + <ClCompile Include="tray_menu.cpp" /> <ClCompile Include="watcher.cpp" /> - <ClCompile Include="xmlFreeFileSync.cpp" /> - <ClCompile Include="xmlProcessing.cpp" /> + <ClCompile Include="xml_ffs.cpp" /> + <ClCompile Include="xml_proc.cpp" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="resource.rc" /> </ItemGroup> + <ItemGroup> + <None Include="WxWizDialog.fbp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="pch.h" /> + </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> diff --git a/RealtimeSync/application.cpp b/RealtimeSync/application.cpp index a48369b4..d3a1f0e0 100644 --- a/RealtimeSync/application.cpp +++ b/RealtimeSync/application.cpp @@ -5,15 +5,15 @@ // ************************************************************************** // #include "application.h" -#include "mainDialog.h" +#include "main_dlg.h" #include <wx/event.h> #include "resources.h" #include <wx/msgdlg.h> #include "../shared/localization.h" -#include "xmlFreeFileSync.h" -#include "../shared/standardPaths.h" +#include "xml_ffs.h" +#include "../shared/standard_paths.h" #include <wx/file.h> -#include "../shared/stringConv.h" +#include "../shared/string_conv.h" #ifdef FFS_LINUX #include <gtk/gtk.h> @@ -41,11 +41,11 @@ void Application::OnStartApplication(wxIdleEvent& event) SetAppName(wxT("FreeFileSync")); //use a different app name, to have "GetUserDataDir()" return the same directory as for FreeFileSync #ifdef FFS_LINUX - ::gtk_rc_parse(FreeFileSync::wxToZ(FreeFileSync::getResourceDir()) + "styles.rc"); //remove inner border from bitmap buttons + ::gtk_rc_parse(ffs3::wxToZ(ffs3::getResourceDir()) + "styles.rc"); //remove inner border from bitmap buttons #endif //set program language - FreeFileSync::CustomLocale::getInstance().setLanguage(RealtimeSync::getProgramLanguage()); + ffs3::CustomLocale::getInstance().setLanguage(rts::getProgramLanguage()); //try to set config/batch-filename set by %1 parameter wxString cfgFilename; @@ -89,10 +89,10 @@ int Application::OnRun() catch (const std::exception& e) //catch all STL exceptions { //unfortunately it's not always possible to display a message box in this erroneous situation, however (non-stream) file output always works! - wxFile safeOutput(FreeFileSync::getConfigDir() + wxT("LastError.txt"), wxFile::write); + wxFile safeOutput(ffs3::getConfigDir() + wxT("LastError.txt"), wxFile::write); safeOutput.Write(wxString::FromAscii(e.what())); - wxMessageBox(wxString::FromAscii(e.what()), _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString::FromAscii(e.what()), _("An exception occurred!"), wxOK | wxICON_ERROR); return -9; } diff --git a/RealtimeSync/functions.cpp b/RealtimeSync/functions.cpp index 15461cc4..f66db6b4 100644 --- a/RealtimeSync/functions.cpp +++ b/RealtimeSync/functions.cpp @@ -7,15 +7,15 @@ #include "functions.h" #include <wx/textctrl.h> #include <wx/filepicker.h> -#include "../shared/stringConv.h" -#include "../shared/fileHandling.h" +#include "../shared/string_conv.h" +#include "../shared/file_handling.h" -using namespace FreeFileSync; +using namespace ffs3; -void RealtimeSync::setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker) +void rts::setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker) { txtCtrl->SetValue(dirname); - const Zstring leftDirFormatted = FreeFileSync::getFormattedDirectoryName(wxToZ(dirname)); + const Zstring leftDirFormatted = ffs3::getFormattedDirectoryName(wxToZ(dirname)); if (dirExists(leftDirFormatted)) dirPicker->SetPath(zToWx(leftDirFormatted)); } diff --git a/RealtimeSync/functions.h b/RealtimeSync/functions.h index e8c03a93..5b20ee9e 100644 --- a/RealtimeSync/functions.h +++ b/RealtimeSync/functions.h @@ -13,7 +13,7 @@ class wxTextCtrl; class wxDirPickerCtrl; -namespace RealtimeSync +namespace rts { void setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker); } diff --git a/RealtimeSync/guiGenerated.cpp b/RealtimeSync/gui_generated.cpp index 4ee67bc9..5bdae20e 100644 --- a/RealtimeSync/guiGenerated.cpp +++ b/RealtimeSync/gui_generated.cpp @@ -5,9 +5,9 @@ // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "../shared/customButton.h" +#include "../shared/custom_button.h" -#include "guiGenerated.h" +#include "gui_generated.h" /////////////////////////////////////////////////////////////////////////// diff --git a/RealtimeSync/guiGenerated.h b/RealtimeSync/gui_generated.h index 7be541d4..7be541d4 100644 --- a/RealtimeSync/guiGenerated.h +++ b/RealtimeSync/gui_generated.h diff --git a/RealtimeSync/mainDialog.cpp b/RealtimeSync/main_dlg.cpp index a6bc7829..d1a30c48 100644 --- a/RealtimeSync/mainDialog.cpp +++ b/RealtimeSync/main_dlg.cpp @@ -4,26 +4,26 @@ // * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** // -#include "mainDialog.h" +#include "main_dlg.h" #include "resources.h" -#include "../shared/customButton.h" -#include "../shared/standardPaths.h" +#include "../shared/custom_button.h" +#include "../shared/standard_paths.h" #include "functions.h" #include <wx/msgdlg.h> #include <wx/wupdlock.h> #include "watcher.h" #include <wx/utils.h> -#include "xmlProcessing.h" -#include "trayMenu.h" -#include "../shared/fileHandling.h" -#include "xmlFreeFileSync.h" -#include "../shared/systemConstants.h" -#include "../shared/stringConv.h" -#include "../shared/staticAssert.h" -#include "../shared/buildInfo.h" -#include "../shared/helpProvider.h" +#include "xml_proc.h" +#include "tray_menu.h" +#include "../shared/file_handling.h" +#include "xml_ffs.h" +#include "../shared/system_constants.h" +#include "../shared/string_conv.h" +#include "../shared/assert_static.h" +#include "../shared/build_info.h" +#include "../shared/help_provider.h" -using namespace FreeFileSync; +using namespace ffs3; MainDialog::MainDialog(wxDialog *dlg, @@ -43,7 +43,7 @@ MainDialog::MainDialog(wxDialog *dlg, Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnKeyPressed), NULL, this); //prepare drag & drop - dragDropOnFolder.reset(new FreeFileSync::DragDropOnDlg(m_panelMainFolder, m_dirPickerMain, m_txtCtrlDirectoryMain)); + dragDropOnFolder.reset(new ffs3::DragDropOnDlg(m_panelMainFolder, m_dirPickerMain, m_txtCtrlDirectoryMain)); //load config values xmlAccess::XmlRealConfig newConfig; @@ -53,30 +53,30 @@ MainDialog::MainDialog(wxDialog *dlg, if (cfgFilename.empty()) try { - RealtimeSync::readRealOrBatchConfig(lastConfigFileName(), newConfig); + rts::readRealOrBatchConfig(lastConfigFileName(), newConfig); } catch (const xmlAccess::XmlError& error) { if (wxFileExists(lastConfigFileName())) //show error only if it's a parsing problem { if (error.getSeverity() == xmlAccess::XmlError::WARNING) - wxMessageBox(error.show(), _("Warning"), wxOK | wxICON_WARNING); + wxMessageBox(error.msg(), _("Warning"), wxOK | wxICON_WARNING); else - wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR); } } else try { - RealtimeSync::readRealOrBatchConfig(cfgFilename, newConfig); + rts::readRealOrBatchConfig(cfgFilename, newConfig); startWatchingImmediately = true; } catch (const xmlAccess::XmlError& error) { if (error.getSeverity() == xmlAccess::XmlError::WARNING) - wxMessageBox(error.show(), _("Warning"), wxOK | wxICON_WARNING); + wxMessageBox(error.msg(), _("Warning"), wxOK | wxICON_WARNING); else - wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR); } setConfiguration(newConfig); @@ -105,7 +105,7 @@ MainDialog::~MainDialog() } catch (const xmlAccess::XmlError& error) { - wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(error.msg().c_str(), _("Error"), wxOK | wxICON_ERROR); } } @@ -124,7 +124,7 @@ void MainDialog::OnQuit(wxCommandEvent &event) const wxString& MainDialog::lastConfigFileName() { - static wxString instance = FreeFileSync::getConfigDir() + wxT("LastRun.ffs_real"); + static wxString instance = ffs3::getConfigDir() + wxT("LastRun.ffs_real"); return instance; } @@ -132,9 +132,9 @@ const wxString& MainDialog::lastConfigFileName() void MainDialog::OnShowHelp(wxCommandEvent& event) { #ifdef FFS_WIN - FreeFileSync::displayHelpEntry(wxT("html\\advanced\\RealtimeSync.html")); + ffs3::displayHelpEntry(wxT("html\\advanced\\RealtimeSync.html")); #elif defined FFS_LINUX - FreeFileSync::displayHelpEntry(wxT("html/advanced/RealtimeSync.html")); + ffs3::displayHelpEntry(wxT("html/advanced/RealtimeSync.html")); #endif } @@ -150,11 +150,11 @@ void MainDialog::OnMenuAbout(wxCommandEvent& event) #endif //wxUSE_UNICODE //compile time info about 32/64-bit build - if (Utility::is64BitBuild) + if (util::is64BitBuild) build += wxT(" x64"); else build += wxT(" x86"); - assert_static(Utility::is32BitBuild || Utility::is64BitBuild); + assert_static(util::is32BitBuild || util::is64BitBuild); wxString buildFormatted = _("(Build: %x)"); buildFormatted.Replace(wxT("%x"), build); @@ -183,16 +183,16 @@ void MainDialog::OnStart(wxCommandEvent& event) wxWindowDisabler dummy; //avoid unwanted re-entrance in the following process - switch (RealtimeSync::startDirectoryMonitor(currentCfg)) + switch (rts::startDirectoryMonitor(currentCfg)) { - case RealtimeSync::QUIT: + case rts::QUIT: { Destroy(); return; } break; - case RealtimeSync::RESUME: + case rts::RESUME: break; } @@ -226,9 +226,9 @@ void MainDialog::OnSaveConfig(wxCommandEvent& event) { writeRealConfig(currentCfg, newFileName); } - catch (const FreeFileSync::FileError& error) + catch (const ffs3::FileError& error) { - wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(error.msg().c_str(), _("Error"), wxOK | wxICON_ERROR); } } } @@ -240,15 +240,15 @@ void MainDialog::loadConfig(const wxString& filename) try { - RealtimeSync::readRealOrBatchConfig(filename, newConfig); + rts::readRealOrBatchConfig(filename, newConfig); } catch (const xmlAccess::XmlError& error) { if (error.getSeverity() == xmlAccess::XmlError::WARNING) - wxMessageBox(error.show(), _("Warning"), wxOK | wxICON_WARNING); + wxMessageBox(error.msg(), _("Warning"), wxOK | wxICON_WARNING); else { - wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR); return; } } @@ -280,7 +280,7 @@ void MainDialog::setConfiguration(const xmlAccess::XmlRealConfig& cfg) //fill top folder m_txtCtrlDirectoryMain->SetValue(*cfg.directories.begin()); - const Zstring dirFormatted = FreeFileSync::getFormattedDirectoryName(wxToZ(*cfg.directories.begin())); + const Zstring dirFormatted = ffs3::getFormattedDirectoryName(wxToZ(*cfg.directories.begin())); if (dirExists(dirFormatted)) m_dirPickerMain->SetPath(zToWx(dirFormatted)); @@ -316,7 +316,7 @@ void MainDialog::OnAddFolder(wxCommandEvent& event) const wxString topFolder = m_txtCtrlDirectoryMain->GetValue(); //clear existing top folder first - RealtimeSync::setDirectoryName(wxEmptyString, m_txtCtrlDirectoryMain, m_dirPickerMain); + rts::setDirectoryName(wxEmptyString, m_txtCtrlDirectoryMain, m_dirPickerMain); std::vector<wxString> newFolders; newFolders.push_back(topFolder.c_str()); @@ -345,7 +345,7 @@ void MainDialog::OnRemoveTopFolder(wxCommandEvent& event) if (additionalFolders.size() > 0) { const wxString topDir = (*additionalFolders.begin())->m_txtCtrlDirectory->GetValue().c_str(); - RealtimeSync::setDirectoryName(topDir, m_txtCtrlDirectoryMain, m_dirPickerMain); + rts::setDirectoryName(topDir, m_txtCtrlDirectoryMain, m_dirPickerMain); removeAddFolder(0); //remove first of additional folders } @@ -391,7 +391,7 @@ void MainDialog::addFolder(const std::vector<wxString>& newFolders, bool addFron newFolder->m_bpButtonRemoveFolder->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolder), NULL, this ); //insert directory name - RealtimeSync::setDirectoryName(*i, newFolder->m_txtCtrlDirectory, newFolder->m_dirPicker); + rts::setDirectoryName(*i, newFolder->m_txtCtrlDirectory, newFolder->m_dirPicker); } //set size of scrolled window diff --git a/RealtimeSync/mainDialog.h b/RealtimeSync/main_dlg.h index 8b83b058..0f408f6d 100644 --- a/RealtimeSync/mainDialog.h +++ b/RealtimeSync/main_dlg.h @@ -7,10 +7,10 @@ #ifndef REALTIMESYNCMAIN_H #define REALTIMESYNCMAIN_H -#include "guiGenerated.h" +#include "gui_generated.h" #include <vector> #include <memory> -#include "../shared/dragAndDrop.h" +#include "../shared/drag_n_drop.h" namespace xmlAccess { @@ -23,11 +23,11 @@ class FolderPanel : public FolderGenerated public: FolderPanel(wxWindow* parent) : FolderGenerated(parent), - dragDropOnFolder(new FreeFileSync::DragDropOnDlg(this, m_dirPicker, m_txtCtrlDirectory)) {} + dragDropOnFolder(new ffs3::DragDropOnDlg(this, m_dirPicker, m_txtCtrlDirectory)) {} private: //support for drag and drop - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnFolder; + std::auto_ptr<ffs3::DragDropOnDlg> dragDropOnFolder; }; @@ -69,7 +69,7 @@ private: std::vector<FolderPanel*> additionalFolders; //additional pairs to the standard pair //support for drag and drop on main folder - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnFolder; + std::auto_ptr<ffs3::DragDropOnDlg> dragDropOnFolder; }; #endif // REALTIMESYNCMAIN_H diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile index 1b7018eb..764cb5f9 100644 --- a/RealtimeSync/makefile +++ b/RealtimeSync/makefile @@ -3,39 +3,38 @@ APPNAME = RealtimeSync prefix = /usr BINDIR = $(DESTDIR)$(prefix)/bin -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 -DZSTRING_CHAR -O3 -pthread -c -I../shared/boost_1_x -LINKFLAGS=`wx-config --libs --debug=no --unicode=yes` -O3 -pthread +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 -DZSTRING_CHAR -O3 -pthread -c +LINKFLAGS=`wx-config --libs --debug=no --unicode=yes` -lboost_thread -O3 -pthread FILE_LIST= #internal list of all *.cpp files needed for compilation FILE_LIST+=application.cpp FILE_LIST+=functions.cpp -FILE_LIST+=guiGenerated.cpp -FILE_LIST+=mainDialog.cpp +FILE_LIST+=gui_generated.cpp +FILE_LIST+=main_dlg.cpp FILE_LIST+=resources.cpp -FILE_LIST+=trayMenu.cpp +FILE_LIST+=tray_menu.cpp FILE_LIST+=watcher.cpp -FILE_LIST+=xmlProcessing.cpp -FILE_LIST+=xmlFreeFileSync.cpp -FILE_LIST+=../library/processXml.cpp +FILE_LIST+=xml_proc.cpp +FILE_LIST+=xml_ffs.cpp +FILE_LIST+=../library/process_xml.cpp FILE_LIST+=../structures.cpp -FILE_LIST+=../shared/checkExist.cpp -FILE_LIST+=../shared/parallelCall.cpp +FILE_LIST+=../shared/check_exist.cpp FILE_LIST+=../shared/localization_no_BOM.cpp FILE_LIST+=../shared/inotify/inotify-cxx.cpp FILE_LIST+=../shared/tinyxml/tinyxml.cpp FILE_LIST+=../shared/tinyxml/tinyxmlerror.cpp FILE_LIST+=../shared/tinyxml/tinyxmlparser.cpp -FILE_LIST+=../shared/globalFunctions.cpp -FILE_LIST+=../shared/systemFunctions.cpp -FILE_LIST+=../shared/dragAndDrop.cpp +FILE_LIST+=../shared/global_func.cpp +FILE_LIST+=../shared/system_func.cpp +FILE_LIST+=../shared/drag_n_drop.cpp FILE_LIST+=../shared/zstring.cpp -FILE_LIST+=../shared/xmlBase.cpp -FILE_LIST+=../shared/customButton.cpp -FILE_LIST+=../shared/fileHandling.cpp -FILE_LIST+=../shared/fileTraverser.cpp -FILE_LIST+=../shared/standardPaths.cpp -FILE_LIST+=../shared/helpProvider.cpp -FILE_LIST+=../shared/fileIO.cpp +FILE_LIST+=../shared/xml_base.cpp +FILE_LIST+=../shared/custom_button.cpp +FILE_LIST+=../shared/file_handling.cpp +FILE_LIST+=../shared/file_traverser.cpp +FILE_LIST+=../shared/standard_paths.cpp +FILE_LIST+=../shared/help_provider.cpp +FILE_LIST+=../shared/file_io.cpp #list of all *.o files OBJECT_LIST=$(foreach file, $(FILE_LIST), OBJ/$(subst .cpp,.o,$(notdir $(file)))) @@ -50,8 +49,8 @@ init: if [ ! -d OBJ ]; then mkdir OBJ; fi #remove byte ordering mark: needed by Visual C++ but an error with GCC -removeBOM: ../tools/removeBOM.cpp - g++ -o OBJ/removeBOM ../tools/removeBOM.cpp +removeBOM: ../tools/remove_BOM.cpp + g++ -o OBJ/removeBOM ../tools/remove_BOM.cpp ./OBJ/removeBOM ../shared/localization.cpp ../shared/localization_no_BOM.cpp %.dep : %.cpp diff --git a/RealtimeSync/notify.cpp b/RealtimeSync/notify.cpp new file mode 100644 index 00000000..fc9ac8cc --- /dev/null +++ b/RealtimeSync/notify.cpp @@ -0,0 +1,268 @@ +// ************************************************************************** +// * 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 "notify.h" +#include <set> +#include "../shared/system_func.h" +#include "../shared/Loki/ScopeGuard.h" +#include <algorithm> +#include <boost/bind.hpp> +#include <dbt.h> + +using namespace ffs3; + + +/* +//convert bitmask into "real" drive-letter +Zstring getDriveFromMask(ULONG unitmask) +{ + for (int i = 0; i < 26; ++i) + { + if (unitmask & 0x1) + return Zstring() + static_cast<DefaultChar>(DefaultChar('A') + i) + DefaultStr(":\\"); + unitmask >>= 1; + } + return Zstring(); +} +*/ + +namespace +{ +bool messageProviderConstructed = false; +} + + +class MessageProvider //administrates a single dummy window to receive messages +{ +public: + static MessageProvider& instance() //throw (FileError) + { + static MessageProvider inst; + messageProviderConstructed = true; + return inst; + } + + class Listener + { + public: + virtual ~Listener() {} + virtual void onMessage(UINT message, WPARAM wParam, LPARAM lParam) = 0; //throw()! + }; + void registerListener(Listener& l); + void unregisterListener(Listener& l); //don't unregister objects with static lifetime + + HWND getWnd() const; //get handle in order to register additional notifications + +private: + MessageProvider(); + ~MessageProvider(); + MessageProvider(const MessageProvider&); + MessageProvider& operator=(const MessageProvider&); + + static const wchar_t WINDOW_NAME[]; + + friend LRESULT CALLBACK topWndProc(HWND, UINT, WPARAM, LPARAM); + void processMessage(UINT message, WPARAM wParam, LPARAM lParam); + + const HINSTANCE process; + HWND windowHandle; + + std::set<Listener*> listener; +}; + + +const wchar_t MessageProvider::WINDOW_NAME[] = L"E6AD5EB1-527B-4EEF-AC75-27883B233380"; //random name + + +LRESULT CALLBACK topWndProc( + HWND hwnd, //handle to window + UINT uMsg, //message identifier + WPARAM wParam, //first message parameter + LPARAM lParam) //second message parameter +{ + if (messageProviderConstructed) //attention: this callback is triggered in the middle of singleton construction! It is a bad idea to to call back at this time! + try + { + MessageProvider::instance().processMessage(uMsg, wParam, lParam); //not supposed to throw + } + catch (...) {} + + return ::DefWindowProc(hwnd, uMsg, wParam, lParam); +} + + +MessageProvider::MessageProvider() : + process(::GetModuleHandle(NULL)), //get program's module handle + windowHandle(NULL) +{ + if (process == NULL) + throw ffs3::FileError(wxString(wxT("Could not start monitoring window notifications:")) + wxT("\n\n") + + ffs3::getLastErrorFormatted() + wxT(" (GetModuleHandle)")); + + //register the main window class + WNDCLASS wc = {}; + wc.lpfnWndProc = topWndProc; + wc.hInstance = process; + wc.lpszClassName = WINDOW_NAME; + + if (::RegisterClass(&wc) == 0) + throw ffs3::FileError(wxString(wxT("Could not start monitoring window notifications:")) + wxT("\n\n") + + ffs3::getLastErrorFormatted() + wxT(" (RegisterClass)")); + + Loki::ScopeGuard guardClass = Loki::MakeGuard(::UnregisterClass, WINDOW_NAME, process); + + //create dummy-window + windowHandle = ::CreateWindow( + WINDOW_NAME, //LPCTSTR lpClassName OR ATOM in low-order word! + NULL, //LPCTSTR lpWindowName, + 0, //DWORD dwStyle, + 0, //int x, + 0, //int y, + 0, //int nWidth, + 0, //int nHeight, + 0, //note: we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)! + NULL, //HMENU hMenu, + process, //HINSTANCE hInstance, + NULL); //LPVOID lpParam + if (windowHandle == NULL) + throw ffs3::FileError(wxString(wxT("Could not start monitoring window notifications:")) + wxT("\n\n") + + ffs3::getLastErrorFormatted() + wxT(" (CreateWindow)")); + + guardClass.Dismiss(); +} + + +MessageProvider::~MessageProvider() +{ + //clean-up in reverse order + ::DestroyWindow(windowHandle); + ::UnregisterClass(WINDOW_NAME, //LPCTSTR lpClassName OR ATOM in low-order word! + process); //HINSTANCE hInstance +} + + +inline +void MessageProvider::registerListener(Listener& l) +{ + listener.insert(&l); +} + + +inline +void MessageProvider::unregisterListener(Listener& l) //don't unregister objects with static lifetime +{ + listener.erase(&l); +} + + +inline +HWND MessageProvider::getWnd() const //get handle in order to register additional notifications +{ + return windowHandle; +} + + +void MessageProvider::processMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + std::for_each(listener.begin(), listener.end(), boost::bind(&Listener::onMessage, _1, message, wParam, lParam)); +} +//#################################################################################################### + + +class NotifyRequestDeviceRemoval::Pimpl : private MessageProvider::Listener +{ +public: + Pimpl(NotifyRequestDeviceRemoval& parent, const std::vector<HANDLE>& openHandles) : //throw (FileError) + parent_(parent) + { + MessageProvider::instance().registerListener(*this); //throw (FileError) + + //register handles to receive notifications + DEV_BROADCAST_HANDLE filter = {}; + filter.dbch_size = sizeof(filter); + filter.dbch_devicetype = DBT_DEVTYP_HANDLE; + + try + { + for (std::vector<HANDLE>::const_iterator i = openHandles.begin(); i != openHandles.end(); ++i) + { + filter.dbch_handle = *i; + + HDEVNOTIFY hNotfication = ::RegisterDeviceNotification( + MessageProvider::instance().getWnd(), //__in HANDLE hRecipient, + &filter, //__in LPVOID NotificationFilter, + DEVICE_NOTIFY_WINDOW_HANDLE); //__in DWORD Flags + if (hNotfication == NULL) + throw ffs3::FileError(wxString(wxT("Could not register device removal notifications:")) + wxT("\n\n") + ffs3::getLastErrorFormatted()); + + notifications.insert(hNotfication); + } + } + catch (...) + { + std::for_each(notifications.begin(), notifications.end(), ::UnregisterDeviceNotification); + MessageProvider::instance().unregisterListener(*this); //throw() in this case + throw; + } + } + + ~Pimpl() + { + std::for_each(notifications.begin(), notifications.end(), ::UnregisterDeviceNotification); + MessageProvider::instance().unregisterListener(*this); + } + +private: + virtual void onMessage(UINT message, WPARAM wParam, LPARAM lParam) //throw()! + { + //DBT_DEVICEQUERYREMOVE example: http://msdn.microsoft.com/en-us/library/aa363427(v=VS.85).aspx + if (message == WM_DEVICECHANGE) + { + if ( wParam == DBT_DEVICEQUERYREMOVE || + wParam == DBT_DEVICEQUERYREMOVEFAILED || + wParam == DBT_DEVICEREMOVECOMPLETE) + { + PDEV_BROADCAST_HDR header = reinterpret_cast<PDEV_BROADCAST_HDR>(lParam); + if (header->dbch_devicetype == DBT_DEVTYP_HANDLE) + { + PDEV_BROADCAST_HANDLE body = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lParam); + +#ifdef __MINGW32__ + const HDEVNOTIFY requestNotification = reinterpret_cast<HDEVNOTIFY>(body->dbch_hdevnotify); +#else + const HDEVNOTIFY requestNotification = body->dbch_hdevnotify; +#endif + if (notifications.find(requestNotification) != notifications.end()) //is it for one of our notifications we registered? + switch (wParam) + { + case DBT_DEVICEQUERYREMOVE: + parent_.onRequestRemoval(body->dbch_handle); + break; + case DBT_DEVICEQUERYREMOVEFAILED: + parent_.onRemovalFinished(body->dbch_handle, false); + break; + case DBT_DEVICEREMOVECOMPLETE: + parent_.onRemovalFinished(body->dbch_handle, true); + break; + } + } + } + } + } + + NotifyRequestDeviceRemoval& parent_; + std::set<HDEVNOTIFY> notifications; +}; +//#################################################################################################### + + +NotifyRequestDeviceRemoval::NotifyRequestDeviceRemoval(const std::vector<HANDLE>& openHandles) +{ + pimpl.reset(new Pimpl(*this, openHandles)); +} + + +NotifyRequestDeviceRemoval::~NotifyRequestDeviceRemoval() {} //make sure ~auto_ptr() works with complete type diff --git a/RealtimeSync/notify.h b/RealtimeSync/notify.h new file mode 100644 index 00000000..07d74f2a --- /dev/null +++ b/RealtimeSync/notify.h @@ -0,0 +1,40 @@ +// ************************************************************************** +// * 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 NOTIFY_H_INCLUDED +#define NOTIFY_H_INCLUDED + +#ifndef FFS_WIN +use in windows build only +#endif + +#include <wx/msw/wrapwin.h> //includes "windows.h" +#include "../shared/file_error.h" +#include <vector> +#include <memory> + +//handle (user-) request for device removal via template method pattern +//evaluate directly after processing window messages +class NotifyRequestDeviceRemoval +{ +public: + NotifyRequestDeviceRemoval(const std::vector<HANDLE>& openHandles); //throw (FileError) + virtual ~NotifyRequestDeviceRemoval(); + +private: + virtual void onRequestRemoval(HANDLE hnd) = 0; //throw()! + //NOTE: onRemovalFinished is NOT guaranteed to execute after onRequestRemoval()! but most likely will + virtual void onRemovalFinished(HANDLE hnd, bool successful) = 0; //throw()! + + NotifyRequestDeviceRemoval(NotifyRequestDeviceRemoval&); //no copying + void operator=(NotifyRequestDeviceRemoval&); // + + class Pimpl; + std::auto_ptr<Pimpl> pimpl; +}; + + +#endif // NOTIFY_H_INCLUDED diff --git a/RealtimeSync/pch.h b/RealtimeSync/pch.h index aaee9032..53076de8 100644 --- a/RealtimeSync/pch.h +++ b/RealtimeSync/pch.h @@ -4,8 +4,8 @@ // * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** // -#ifndef FFS_PRECOMPILED_HEADER -#define FFS_PRECOMPILED_HEADER +#ifndef RTS_PRECOMPILED_HEADER +#define RTS_PRECOMPILED_HEADER //pay attention when using this file: might cause issues! #ifndef __WXDEBUG__ @@ -100,4 +100,4 @@ do NOT use in release build! #endif //FFS_WIN //##################################################### -#endif //FFS_PRECOMPILED_HEADER +#endif //RTS_PRECOMPILED_HEADER
\ No newline at end of file diff --git a/RealtimeSync/resources.cpp b/RealtimeSync/resources.cpp index c2678878..b6e35c38 100644 --- a/RealtimeSync/resources.cpp +++ b/RealtimeSync/resources.cpp @@ -10,10 +10,10 @@ #include <wx/image.h> #include <wx/icon.h> #include <memory> -#include "../shared/standardPaths.h" -#include "../shared/systemConstants.h" +#include "../shared/standard_paths.h" +#include "../shared/system_constants.h" -using namespace FreeFileSync; +using namespace ffs3; const GlobalResources& GlobalResources::getInstance() @@ -42,7 +42,7 @@ GlobalResources::~GlobalResources() void GlobalResources::load() const { - wxFFileInputStream input(FreeFileSync::getResourceDir() + wxT("Resources.dat")); + wxFFileInputStream input(ffs3::getResourceDir() + wxT("Resources.dat")); if (input.IsOk()) //if not... we don't want to react too harsh here { //activate support for .png files diff --git a/RealtimeSync/trayMenu.cpp b/RealtimeSync/tray_menu.cpp index 4e82b5f7..1ea7416c 100644 --- a/RealtimeSync/trayMenu.cpp +++ b/RealtimeSync/tray_menu.cpp @@ -4,28 +4,28 @@ // * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** // -#include "trayMenu.h" +#include "tray_menu.h" #include <wx/msgdlg.h> #include <wx/taskbar.h> #include <wx/app.h> #include "resources.h" #include <algorithm> #include <iterator> -#include "../shared/stringConv.h" +#include "../shared/string_conv.h" #include <wx/utils.h> #include <wx/menu.h> #include "watcher.h" #include <wx/utils.h> #include <wx/log.h> -#include "../shared/staticAssert.h" -#include "../shared/buildInfo.h" +#include "../shared/assert_static.h" +#include "../shared/build_info.h" #include <wx/icon.h> //Linux needs this #include <wx/timer.h> -using namespace RealtimeSync; +using namespace rts; -class WaitCallbackImpl : private wxEvtHandler, public RealtimeSync::WaitCallback //keep this order: else VC++ generates wrong code +class WaitCallbackImpl : private wxEvtHandler, public rts::WaitCallback //keep this order: else VC++ generates wrong code { public: WaitCallbackImpl(); @@ -175,23 +175,23 @@ void WaitCallbackImpl::OnContextMenuSelection(wxCommandEvent& event) break; case CONTEXT_ABOUT: { - //build information - wxString build = __TDATE__; + //build information + wxString build = __TDATE__; #if wxUSE_UNICODE - build += wxT(" - Unicode"); + build += wxT(" - Unicode"); #else - build += wxT(" - ANSI"); + build += wxT(" - ANSI"); #endif //wxUSE_UNICODE - //compile time info about 32/64-bit build - if (Utility::is64BitBuild) - build += wxT(" x64"); - else - build += wxT(" x86"); - assert_static(Utility::is32BitBuild || Utility::is64BitBuild); + //compile time info about 32/64-bit build + if (util::is64BitBuild) + build += wxT(" x64"); + else + build += wxT(" x86"); + assert_static(util::is32BitBuild || util::is64BitBuild); -wxString buildFormatted = _("(Build: %x)"); -buildFormatted.Replace(wxT("%x"), build); + wxString buildFormatted = _("(Build: %x)"); + buildFormatted.Replace(wxT("%x"), build); wxMessageDialog aboutDlg(NULL, wxString(wxT("RealtimeSync")) + wxT("\n\n") + buildFormatted, _("About"), wxOK); aboutDlg.ShowModal(); @@ -218,15 +218,15 @@ namespace { std::vector<Zstring> convert(const std::vector<wxString>& dirList) { - std::vector<Zstring> output; + std::set<Zstring, LessFilename> output; std::transform(dirList.begin(), dirList.end(), - std::back_inserter(output), static_cast<Zstring (*)(const wxString&)>(FreeFileSync::wxToZ)); - return output; + std::inserter(output, output.end()), static_cast<Zstring (*)(const wxString&)>(ffs3::wxToZ)); + return std::vector<Zstring>(output.begin(), output.end()); } } -RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAccess::XmlRealConfig& config) +rts::MonitorResponse rts::startDirectoryMonitor(const xmlAccess::XmlRealConfig& config) { const std::vector<Zstring> dirList = convert(config.directories); @@ -235,7 +235,7 @@ RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAcces WaitCallbackImpl callback; if (config.commandline.empty()) - throw FreeFileSync::FileError(_("Command line is empty!")); + throw ffs3::FileError(_("Command line is empty!")); while (true) { @@ -264,7 +264,7 @@ RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAcces while (wxGetLocalTime() < nextExec) { callback.requestUiRefresh(); - wxMilliSleep(RealtimeSync::UI_UPDATE_INTERVAL); + wxMilliSleep(rts::UI_UPDATE_INTERVAL); } } } @@ -272,9 +272,9 @@ RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAcces { return ab.getCommand(); } - catch (const FreeFileSync::FileError& error) + catch (const ffs3::FileError& error) { - wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR); return RESUME; } diff --git a/RealtimeSync/trayMenu.h b/RealtimeSync/tray_menu.h index 8bf73a47..048fda60 100644 --- a/RealtimeSync/trayMenu.h +++ b/RealtimeSync/tray_menu.h @@ -8,10 +8,10 @@ #define TRAYMENU_H_INCLUDED #include "watcher.h" -#include "xmlProcessing.h" +#include "xml_proc.h" -namespace RealtimeSync +namespace rts { enum MonitorResponse { diff --git a/RealtimeSync/watcher.cpp b/RealtimeSync/watcher.cpp index 9af48783..89fc5e61 100644 --- a/RealtimeSync/watcher.cpp +++ b/RealtimeSync/watcher.cpp @@ -5,36 +5,35 @@ // ************************************************************************** // #include "watcher.h" -#include "../shared/systemFunctions.h" -//#include "functions.h" +#include "../shared/system_func.h" #include <wx/intl.h> -//#include <wx/filefn.h> -#include "../shared/stringConv.h" -#include "../shared/fileHandling.h" +#include "../shared/string_conv.h" +#include "../shared/file_handling.h" #include <stdexcept> #include <set> #include <wx/timer.h> #include <algorithm> #ifdef FFS_WIN +#include "notify.h" #include <wx/msw/wrapwin.h> //includes "windows.h" -#include "../shared/longPathPrefix.h" +#include "../shared/long_path_prefix.h" +#include <boost/shared_ptr.hpp> #elif defined FFS_LINUX -//#include <exception> #include "../shared/inotify/inotify-cxx.h" -#include "../shared/fileTraverser.h" +#include "../shared/file_traverser.h" #endif -using namespace FreeFileSync; +using namespace ffs3; -bool RealtimeSync::updateUiIsAllowed() +bool rts::updateUiIsAllowed() { static wxLongLong lastExec; const wxLongLong newExec = wxGetLocalTimeMillis(); - if (newExec - lastExec >= RealtimeSync::UI_UPDATE_INTERVAL) //perform ui updates not more often than necessary + if (newExec - lastExec >= rts::UI_UPDATE_INTERVAL) //perform ui updates not more often than necessary { lastExec = newExec; return true; @@ -42,238 +41,34 @@ bool RealtimeSync::updateUiIsAllowed() return false; } -#ifdef FFS_WIN -/* -template <class T> //have a disctinct static variable per class! -class InstanceCounter //exception safety!!!! use RAII for counter inc/dec! -{ -public: - InstanceCounter() - { - ++instanceCount; - //we're programming on global variables: only one instance of NotifyDeviceArrival allowed at a time! - if (instanceCount > 1) - throw std::logic_error("Only one instance of NotifyDeviceArrival allowed!"); - } - ~InstanceCounter() - { - --instanceCount; - } -private: - static size_t instanceCount; //this class needs to be a singleton but with variable lifetime! => count instances to check consistency -}; -template <class T> //we need a disctinct static variable per class! -size_t InstanceCounter<T>::instanceCount = 0; - - -std::set<Zstring> driveNamesArrived; //letters of newly arrived drive names - -//convert bitmask into "real" drive-letter -void notifyDriveFromMask (ULONG unitmask) -{ - for (wchar_t i = 0; i < 26; ++i) - { - if (unitmask & 0x1) - { - Zstring newDrivePath; - newDrivePath += DefaultChar('A') + i; - newDrivePath += DefaultStr(":\\"); - driveNamesArrived.insert(newDrivePath); - return; - } - unitmask = unitmask >> 1; - } -} - - -LRESULT CALLBACK MainWndProc( - HWND hwnd, // handle to window - UINT uMsg, // message identifier - WPARAM wParam, // first message parameter - LPARAM lParam) // second message parameter +#ifdef FFS_WIN +//shared_ptr custom deleter +void cleanUpChangeNotifications(const std::vector<HANDLE>* handles) { + for (std::vector<HANDLE>::const_iterator i = handles->begin(); i != handles->end(); ++i) + if (*i != INVALID_HANDLE_VALUE) + ::FindCloseChangeNotification(*i); - //detect device arrival: http://msdn.microsoft.com/en-us/library/aa363215(VS.85).aspx - if (uMsg == WM_DEVICECHANGE) - { - if (wParam == DBT_DEVICEARRIVAL) - { - PDEV_BROADCAST_HDR lpdb = reinterpret_cast<PDEV_BROADCAST_HDR>(lParam); - if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) - { - PDEV_BROADCAST_VOLUME lpdbv = reinterpret_cast<PDEV_BROADCAST_VOLUME>(lpdb); - //warning: lpdbv->dbcv_flags is 0 for USB-sticks! - - //insert drive name notification into global variable: - notifyDriveFromMask(lpdbv->dbcv_unitmask); - } - } - } - //default - return DefWindowProc(hwnd, uMsg, wParam, lParam); + delete handles; //don't forget!!! custom deleter needs to care for everything! } - -class NotifyDeviceArrival //e.g. insertion of USB-Stick -{ -public: - NotifyDeviceArrival() : - parentInstance(NULL), - registeredClass(NULL), - windowHandle(NULL) - { - //get program's module handle - parentInstance = GetModuleHandle(NULL); - if (parentInstance == NULL) - throw FreeFileSync::FileError(wxString(("Could not start monitoring for volume arrival:")) + wxT("\n\n") + - FreeFileSync::getLastErrorFormatted()+ wxT(" (GetModuleHandle)")); - - //register the main window class - WNDCLASS wc; - wc.style = 0; - wc.lpfnWndProc = MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = parentInstance; - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = wxT("DeviceArrivalWatcher"); - - registeredClass =:: RegisterClass(&wc); - if (registeredClass == 0) - throw FreeFileSync::FileError(wxString(("Could not start monitoring for volume arrival:")) + wxT("\n\n") + - FreeFileSync::getLastErrorFormatted()+ wxT(" (RegisterClass)")); - - //create dummy-window - windowHandle = ::CreateWindow( - reinterpret_cast<LPCTSTR>(registeredClass), //LPCTSTR lpClassName OR ATOM in low-order word! - 0, //LPCTSTR lpWindowName, - 0, //DWORD dwStyle, - 0, //int x, - 0, //int y, - 0, //int nWidth, - 0, //int nHeight, - 0, //note: we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)! - NULL, //HMENU hMenu, - parentInstance, //HINSTANCE hInstance, - NULL); //LPVOID lpParam - if (windowHandle == NULL) - throw FreeFileSync::FileError(wxString( ("Could not start monitoring for volume arrival:")) + wxT("\n\n") + - FreeFileSync::getLastErrorFormatted() + wxT(" (CreateWindow)")); - - //clear global variable - driveNamesArrived.clear(); - } - - ~NotifyDeviceArrival() - { - //clean-up in reverse order - if (windowHandle != NULL) - ::DestroyWindow(windowHandle); - - if (registeredClass != 0) - ::UnregisterClass(reinterpret_cast<LPCTSTR>(registeredClass), //LPCTSTR lpClassName OR ATOM in low-order word! - parentInstance); //HINSTANCE hInstance - } - - - //test if one of the notifications matches one of the directory paths specified - bool notificationsFound(const std::vector<Zstring>& dirList) const - { - //do NOT rely on string parsing! use (volume directory) file ids! - std::set<Utility::FileID> notifiedIds; - for (std::set<Zstring>::const_iterator j = driveNamesArrived.begin(); j != driveNamesArrived.end(); ++j) - { - const Utility::FileID notifiedVolId = Utility::retrieveFileID(*j); - if (notifiedVolId != Utility::FileID()) - notifiedIds.insert(notifiedVolId); - } - //clear global variable - driveNamesArrived.clear(); - - if (!notifiedIds.empty()) //minor optimization - { - for (std::vector<Zstring>::const_iterator i = dirList.begin(); i != dirList.end(); ++i) - { - //retrieve volume name - wchar_t volumeNameRaw[1000]; - if (::GetVolumePathName(i->c_str(), //__in LPCTSTR lpszFileName, - volumeNameRaw, //__out LPTSTR lpszVolumePathName, - 1000)) //__in DWORD cchBufferLength - { - const Utility::FileID monitoredId = Utility::retrieveFileID(volumeNameRaw); - if (monitoredId != Utility::FileID()) - { - if (notifiedIds.find(monitoredId) != notifiedIds.end()) - return true; - } - } - } - } - - return false; - } - -private: - HINSTANCE parentInstance; - ATOM registeredClass; - HWND windowHandle; - - //we're programming on global variables: only one instance of NotifyDeviceArrival allowed at a time! - InstanceCounter<NotifyDeviceArrival> dummy; //exception safety!!!! use RAII for counter inc/dec! -}; -*/ - - -//-------------------------------------------------------------------------------------------------------------- -class ChangeNotifications -{ -public: - ~ChangeNotifications() - { - for (std::vector<HANDLE>::const_iterator i = arrayHandle.begin(); i != arrayHandle.end(); ++i) - if (*i != INVALID_HANDLE_VALUE) - ::FindCloseChangeNotification(*i); - } - - void addHandle(HANDLE hndl) - { - arrayHandle.push_back(hndl); - } - - size_t getSize() const - { - return arrayHandle.size(); - } - - const HANDLE* getArray() - { - return &arrayHandle[0]; //client needs to check getSize() before calling this method! - } - -private: - std::vector<HANDLE> arrayHandle; -}; - #elif defined FFS_LINUX -class DirsOnlyTraverser : public FreeFileSync::TraverseCallback +class DirsOnlyTraverser : public ffs3::TraverseCallback { public: DirsOnlyTraverser(std::vector<std::string>& dirs) : m_dirs(dirs) {} virtual void onFile(const DefaultChar* shortName, const Zstring& fullName, const FileInfo& details) {} - virtual void onSymlink(const DefaultChar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} + virtual void onSymlink(const DefaultChar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} virtual ReturnValDir onDir(const DefaultChar* shortName, const Zstring& fullName) { m_dirs.push_back(fullName.c_str()); - return ReturnValDir(Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_CONTINUE>(), this); + return ReturnValDir(Loki::Int2Type<ReturnValDir::TRAVERSING_DIR_CONTINUE>(), this); } virtual void onError(const wxString& errorText) { - throw FreeFileSync::FileError(errorText); + throw ffs3::FileError(errorText); } private: @@ -285,7 +80,7 @@ private: class WatchDirectories //detect changes to directory availability { public: - WatchDirectories() : allExistingBuffer(true) {} + WatchDirectories() : allExisting_(true) {} //initialization void addForMonitoring(const Zstring& dirName) @@ -301,47 +96,48 @@ public: if (newExec - lastExec >= UPDATE_INTERVAL) { lastExec = newExec; - allExistingBuffer = std::find_if(dirList.begin(), dirList.end(), notExisting) == dirList.end(); + allExisting_ = std::find_if(dirList.begin(), dirList.end(), notExisting) == dirList.end(); } - return allExistingBuffer; + return allExisting_; } private: static bool notExisting(const Zstring& dirname) { - return !FreeFileSync::dirExists(dirname); + return !ffs3::dirExists(dirname); } mutable wxLongLong lastExec; - mutable bool allExistingBuffer; + mutable bool allExisting_; - std::set<Zstring> dirList; //save avail. directories, avoid double-entries + std::set<Zstring, LessFilename> dirList; //save avail. directories, avoid double-entries }; -RealtimeSync::WaitResult RealtimeSync::waitForChanges(const std::vector<Zstring>& dirNames, WaitCallback* statusHandler) //throw(FileError) +rts::WaitResult rts::waitForChanges(const std::vector<Zstring>& dirNames, WaitCallback* statusHandler) //throw(FileError) { if (dirNames.empty()) //pathological case, but check is needed nevertheless - throw FreeFileSync::FileError(_("At least one directory input field is empty.")); + throw ffs3::FileError(_("At least one directory input field is empty.")); //detect when volumes are removed/are not available anymore WatchDirectories dirWatcher; #ifdef FFS_WIN - ChangeNotifications notifications; + typedef boost::shared_ptr<std::vector<HANDLE> > ChangeNotifList; + ChangeNotifList changeNotifications(new std::vector<HANDLE>, ::cleanUpChangeNotifications); for (std::vector<Zstring>::const_iterator i = dirNames.begin(); i != dirNames.end(); ++i) { - const Zstring formattedDir = FreeFileSync::getFormattedDirectoryName(*i); + const Zstring formattedDir = ffs3::getFormattedDirectoryName(*i); if (formattedDir.empty()) - throw FreeFileSync::FileError(_("At least one directory input field is empty.")); + throw ffs3::FileError(_("At least one directory input field is empty.")); dirWatcher.addForMonitoring(formattedDir); const HANDLE rv = ::FindFirstChangeNotification( - FreeFileSync::applyLongPathPrefix(formattedDir).c_str(), //__in LPCTSTR lpPathName, + ffs3::applyLongPathPrefix(formattedDir).c_str(), //__in LPCTSTR lpPathName, true, //__in BOOL bWatchSubtree, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | @@ -354,34 +150,82 @@ RealtimeSync::WaitResult RealtimeSync::waitForChanges(const std::vector<Zstring> return CHANGE_DIR_MISSING; const wxString errorMessage = wxString(_("Could not initialize directory monitoring:")) + wxT("\n\"") + zToWx(*i) + wxT("\""); - throw FreeFileSync::FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted()); + throw ffs3::FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted()); } - notifications.addHandle(rv); + changeNotifications->push_back(rv); } + if (changeNotifications->size() == 0) + throw ffs3::FileError(_("At least one directory input field is empty.")); + + + //detect user request for device removal (e.g. usb stick) + class HandleVolumeRemoval : public NotifyRequestDeviceRemoval + { + public: + HandleVolumeRemoval(ChangeNotifList& openHandles) : + NotifyRequestDeviceRemoval(*openHandles), //throw (FileError) + removalRequested(false), + operationComplete(false), + openHandles_(openHandles) {} + + bool requestReceived() const + { + return removalRequested; + } + bool finished() const + { + return operationComplete; + } + + private: + virtual void onRequestRemoval(HANDLE hnd) //don't throw! + { + openHandles_.reset(); //free all handles + removalRequested = true; //and make sure they are not used anymore + } + virtual void onRemovalFinished(HANDLE hnd, bool successful) //throw()! + { + operationComplete = true; + } + + bool removalRequested; + bool operationComplete; + ChangeNotifList& openHandles_; + } removalRequest(changeNotifications); - if (notifications.getSize() == 0) - throw FreeFileSync::FileError(_("At least one directory input field is empty.")); while (true) { //check for changes within directories: - const DWORD rv = ::WaitForMultipleObjects( //NOTE: notifications.getArray() returns valid pointer, because it cannot be empty in this context - static_cast<DWORD>(notifications.getSize()), //__in DWORD nCount, - notifications.getArray(), //__in const HANDLE *lpHandles, - false, //__in BOOL bWaitAll, - UI_UPDATE_INTERVAL); //__in DWORD dwMilliseconds - if (WAIT_OBJECT_0 <= rv && rv < WAIT_OBJECT_0 + notifications.getSize()) + const DWORD rv = ::WaitForMultipleObjects( //NOTE: changeNotifications returns valid pointer, because it cannot be empty in this context + static_cast<DWORD>(changeNotifications->size()), //__in DWORD nCount, + &(*changeNotifications)[0], //__in const HANDLE *lpHandles, + false, //__in BOOL bWaitAll, + UI_UPDATE_INTERVAL); //__in DWORD dwMilliseconds + if (WAIT_OBJECT_0 <= rv && rv < WAIT_OBJECT_0 + changeNotifications->size()) return CHANGE_DETECTED; //directory change detected else if (rv == WAIT_FAILED) - throw FreeFileSync::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + FreeFileSync::getLastErrorFormatted()); + throw ffs3::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + ffs3::getLastErrorFormatted()); //else if (rv == WAIT_TIMEOUT) if (!dirWatcher.allExisting()) //check for removed devices: return CHANGE_DIR_MISSING; statusHandler->requestUiRefresh(); + + //handle device removal + if (removalRequest.requestReceived()) + { + const wxMilliClock_t maxwait = wxGetLocalTimeMillis() + 5000; //HandleVolumeRemoval::finished() not guaranteed! + while (!removalRequest.finished() && wxGetLocalTimeMillis() < maxwait) + { + wxMilliSleep(rts::UI_UPDATE_INTERVAL); + statusHandler->requestUiRefresh(); + } + return CHANGE_DIR_MISSING; + } } #elif defined FFS_LINUX @@ -390,10 +234,10 @@ RealtimeSync::WaitResult RealtimeSync::waitForChanges(const std::vector<Zstring> //add all subdirectories for (std::vector<Zstring>::const_iterator i = dirNames.begin(); i != dirNames.end(); ++i) { - const Zstring formattedDir = FreeFileSync::getFormattedDirectoryName(*i); + const Zstring formattedDir = ffs3::getFormattedDirectoryName(*i); if (formattedDir.empty()) - throw FreeFileSync::FileError(_("At least one directory input field is empty.")); + throw ffs3::FileError(_("At least one directory input field is empty.")); dirWatcher.addForMonitoring(formattedDir); @@ -403,11 +247,11 @@ RealtimeSync::WaitResult RealtimeSync::waitForChanges(const std::vector<Zstring> try //get all subdirectories { DirsOnlyTraverser traverser(fullDirList); - FreeFileSync::traverseFolder(formattedDir, false, &traverser); //don't traverse into symlinks (analog to windows build) + ffs3::traverseFolder(formattedDir, false, &traverser); //don't traverse into symlinks (analog to windows build) } - catch (const FreeFileSync::FileError&) + catch (const ffs3::FileError&) { - if (!FreeFileSync::dirExists(formattedDir)) //that's no good locking behavior, but better than nothing + if (!ffs3::dirExists(formattedDir)) //that's no good locking behavior, but better than nothing return CHANGE_DIR_MISSING; throw; @@ -438,17 +282,17 @@ RealtimeSync::WaitResult RealtimeSync::waitForChanges(const std::vector<Zstring> } catch (const InotifyException& e) { - if (!FreeFileSync::dirExists(i->c_str())) //that's no good locking behavior, but better than nothing + if (!ffs3::dirExists(i->c_str())) //that's no good locking behavior, but better than nothing return CHANGE_DIR_MISSING; const wxString errorMessage = wxString(_("Could not initialize directory monitoring:")) + wxT("\n\"") + zToWx(i->c_str()) + wxT("\""); - throw FreeFileSync::FileError(errorMessage + wxT("\n\n") + zToWx(e.GetMessage().c_str())); + throw ffs3::FileError(errorMessage + wxT("\n\n") + zToWx(e.GetMessage().c_str())); } } if (notifications.GetWatchCount() == 0) - throw FreeFileSync::FileError(_("At least one directory input field is empty.")); + throw ffs3::FileError(_("At least one directory input field is empty.")); while (true) { @@ -460,33 +304,33 @@ RealtimeSync::WaitResult RealtimeSync::waitForChanges(const std::vector<Zstring> if (!dirWatcher.allExisting()) //check for removed devices: return CHANGE_DIR_MISSING; - wxMilliSleep(RealtimeSync::UI_UPDATE_INTERVAL); + wxMilliSleep(rts::UI_UPDATE_INTERVAL); statusHandler->requestUiRefresh(); } } catch (const InotifyException& e) { - throw FreeFileSync::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + zToWx(e.GetMessage().c_str())); + throw ffs3::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + zToWx(e.GetMessage().c_str())); } catch (const std::exception& e) { - throw FreeFileSync::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + zToWx(e.what())); + throw ffs3::FileError(wxString(_("Error when monitoring directories.")) + wxT("\n\n") + zToWx(e.what())); } #endif } -void RealtimeSync::waitForMissingDirs(const std::vector<Zstring>& dirNames, WaitCallback* statusHandler) //throw(FileError) +void rts::waitForMissingDirs(const std::vector<Zstring>& dirNames, WaitCallback* statusHandler) //throw(FileError) { //new: support for monitoring newly connected directories volumes (e.g.: USB-sticks) WatchDirectories dirWatcher; for (std::vector<Zstring>::const_iterator i = dirNames.begin(); i != dirNames.end(); ++i) { - const Zstring formattedDir = FreeFileSync::getFormattedDirectoryName(*i); + const Zstring formattedDir = ffs3::getFormattedDirectoryName(*i); if (formattedDir.empty()) - throw FreeFileSync::FileError(_("At least one directory input field is empty.")); + throw ffs3::FileError(_("At least one directory input field is empty.")); dirWatcher.addForMonitoring(formattedDir); } @@ -496,7 +340,7 @@ void RealtimeSync::waitForMissingDirs(const std::vector<Zstring>& dirNames, Wait if (dirWatcher.allExisting()) //check for newly arrived devices: return; - wxMilliSleep(RealtimeSync::UI_UPDATE_INTERVAL); + wxMilliSleep(rts::UI_UPDATE_INTERVAL); statusHandler->requestUiRefresh(); } } diff --git a/RealtimeSync/watcher.h b/RealtimeSync/watcher.h index c0690c33..dc579edc 100644 --- a/RealtimeSync/watcher.h +++ b/RealtimeSync/watcher.h @@ -9,10 +9,10 @@ #include "../shared/zstring.h" #include <vector> -#include "../shared/fileError.h" +#include "../shared/file_error.h" -namespace RealtimeSync +namespace rts { const int UI_UPDATE_INTERVAL = 100; //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss diff --git a/RealtimeSync/xmlFreeFileSync.cpp b/RealtimeSync/xml_ffs.cpp index ac4c1e3a..3f87b20f 100644 --- a/RealtimeSync/xmlFreeFileSync.cpp +++ b/RealtimeSync/xml_ffs.cpp @@ -4,18 +4,18 @@ // * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** // -#include "xmlFreeFileSync.h" -#include "../shared/standardPaths.h" -#include "../shared/globalFunctions.h" +#include "xml_ffs.h" +#include "../shared/standard_paths.h" +#include "../shared/global_func.h" #include "../shared/zstring.h" #include "functions.h" -#include "../shared/xmlBase.h" -#include "../shared/stringConv.h" +#include "../shared/xml_base.h" +#include "../shared/string_conv.h" //include FreeFileSync xml headers -#include "../library/processXml.h" +#include "../library/process_xml.h" -using namespace FreeFileSync; +using namespace ffs3; #ifdef FFS_WIN @@ -44,7 +44,7 @@ xmlAccess::XmlRealConfig convertBatchToReal(const xmlAccess::XmlBatchConfig& bat uniqueFolders.insert(zToWx(batchCfg.mainCfg.firstPair.rightDirectory)); //additional folders - for (std::vector<FreeFileSync::FolderPairEnh>::const_iterator i = batchCfg.mainCfg.additionalPairs.begin(); + for (std::vector<ffs3::FolderPairEnh>::const_iterator i = batchCfg.mainCfg.additionalPairs.begin(); i != batchCfg.mainCfg.additionalPairs.end(); ++i) { uniqueFolders.insert(zToWx(i->leftDirectory)); @@ -53,7 +53,7 @@ xmlAccess::XmlRealConfig convertBatchToReal(const xmlAccess::XmlBatchConfig& bat output.directories.insert(output.directories.end(), uniqueFolders.begin(), uniqueFolders.end()); - output.commandline = FreeFileSync::getBinaryDir() + + output.commandline = ffs3::getBinaryDir() + #ifdef FFS_WIN wxT("FreeFileSync.exe") + #elif defined FFS_LINUX @@ -65,7 +65,7 @@ xmlAccess::XmlRealConfig convertBatchToReal(const xmlAccess::XmlBatchConfig& bat } -void RealtimeSync::readRealOrBatchConfig(const wxString& filename, xmlAccess::XmlRealConfig& config) //throw (xmlAccess::XmlError); +void rts::readRealOrBatchConfig(const wxString& filename, xmlAccess::XmlRealConfig& config) //throw (xmlAccess::XmlError); { if (xmlAccess::getXmlType(filename) != xmlAccess::XML_BATCH_CONFIG) { @@ -77,30 +77,28 @@ void RealtimeSync::readRealOrBatchConfig(const wxString& filename, xmlAccess::Xm xmlAccess::XmlBatchConfig batchCfg; try { - xmlAccess::readBatchConfig(filename, batchCfg); //throw (xmlAccess::XmlError); + xmlAccess::readConfig(filename, batchCfg); //throw (xmlAccess::XmlError); } catch (const xmlAccess::XmlError& e) { - if (e.getSeverity() != xmlAccess::XmlError::WARNING) - throw; + if (e.getSeverity() == xmlAccess::XmlError::WARNING) + config = convertBatchToReal(batchCfg, filename); //do work despite parsing errors, then re-throw - config = convertBatchToReal(batchCfg, filename); //do work despite parsing errors, then re-throw throw; // } config = convertBatchToReal(batchCfg, filename); } -int RealtimeSync::getProgramLanguage() +int rts::getProgramLanguage() { xmlAccess::XmlGlobalSettings settings; try { - xmlAccess::readGlobalSettings(settings); + xmlAccess::readConfig(settings); } - catch (const xmlAccess::XmlError&) - {} //user default language if error occured + catch (const xmlAccess::XmlError&) {} //user default language if error occured return settings.programLanguage; } diff --git a/RealtimeSync/xmlFreeFileSync.h b/RealtimeSync/xml_ffs.h index 8955ccf1..cef11c9f 100644 --- a/RealtimeSync/xmlFreeFileSync.h +++ b/RealtimeSync/xml_ffs.h @@ -7,12 +7,12 @@ #ifndef XMLFREEFILESYNC_H_INCLUDED #define XMLFREEFILESYNC_H_INCLUDED -#include "xmlProcessing.h" +#include "xml_proc.h" //reuse (some of) FreeFileSync's xml files -namespace RealtimeSync +namespace rts { void readRealOrBatchConfig(const wxString& filename, xmlAccess::XmlRealConfig& config); //throw (xmlAccess::XmlError); diff --git a/RealtimeSync/xmlProcessing.cpp b/RealtimeSync/xml_proc.cpp index e9420d1b..273a687f 100644 --- a/RealtimeSync/xmlProcessing.cpp +++ b/RealtimeSync/xml_proc.cpp @@ -4,7 +4,7 @@ // * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** // -#include "xmlProcessing.h" +#include "xml_proc.h" #include <wx/filefn.h> #include <wx/intl.h> @@ -35,7 +35,7 @@ void xmlAccess::readRealConfig(const wxString& filename, XmlRealConfig& config) RtsXmlParser parser(doc.RootElement()); parser.readXmlRealConfig(config); //read GUI layout configuration - if (parser.errorsOccured()) + if (parser.errorsOccurred()) throw XmlError(wxString(_("Error parsing configuration file:")) + wxT("\n\"") + filename + wxT("\"\n\n") + parser.getErrorMessageFormatted(), XmlError::WARNING); } diff --git a/RealtimeSync/xmlProcessing.h b/RealtimeSync/xml_proc.h index bcfcf8f2..bac42f1e 100644 --- a/RealtimeSync/xmlProcessing.h +++ b/RealtimeSync/xml_proc.h @@ -9,7 +9,7 @@ #include <vector> #include <wx/string.h> -#include "../shared/xmlBase.h" +#include "../shared/xml_base.h" namespace xmlAccess |