diff options
Diffstat (limited to 'RealtimeSync')
-rw-r--r-- | RealtimeSync/RealtimeSync.cbp | 1 | ||||
-rw-r--r-- | RealtimeSync/RealtimeSync.vcproj | 12 | ||||
-rw-r--r-- | RealtimeSync/mainDialog.cpp | 4 | ||||
-rw-r--r-- | RealtimeSync/makefile | 1 | ||||
-rw-r--r-- | RealtimeSync/trayMenu.cpp | 198 | ||||
-rw-r--r-- | RealtimeSync/watcher.cpp | 18 | ||||
-rw-r--r-- | RealtimeSync/watcher.h | 3 | ||||
-rw-r--r-- | RealtimeSync/xmlProcessing.cpp | 21 |
8 files changed, 141 insertions, 117 deletions
diff --git a/RealtimeSync/RealtimeSync.cbp b/RealtimeSync/RealtimeSync.cbp index 6d5760fd..9a5d9f93 100644 --- a/RealtimeSync/RealtimeSync.cbp +++ b/RealtimeSync/RealtimeSync.cbp @@ -129,6 +129,7 @@ <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" /> diff --git a/RealtimeSync/RealtimeSync.vcproj b/RealtimeSync/RealtimeSync.vcproj index d84e8525..8d60d6ba 100644 --- a/RealtimeSync/RealtimeSync.vcproj +++ b/RealtimeSync/RealtimeSync.vcproj @@ -50,10 +50,12 @@ MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" - UsePrecompiledHeader="0" + UsePrecompiledHeader="1" + PrecompiledHeaderThrough="$(ProjectDir)../library/pch.h" WarningLevel="4" DebugInformationFormat="4" DisableSpecificWarnings="4804;4100" + ForcedIncludeFiles="$(ProjectDir)../library/pch.h" /> <Tool Name="VCManagedResourceCompilerTool" @@ -134,10 +136,12 @@ MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" - UsePrecompiledHeader="0" + UsePrecompiledHeader="1" + PrecompiledHeaderThrough="$(ProjectDir)../library/pch.h" WarningLevel="4" DebugInformationFormat="3" DisableSpecificWarnings="4804;4100" + ForcedIncludeFiles="$(ProjectDir)../library/pch.h" /> <Tool Name="VCManagedResourceCompilerTool" @@ -388,6 +392,10 @@ > </File> <File + RelativePath="..\shared\fileIO.cpp" + > + </File> + <File RelativePath="..\shared\fileTraverser.cpp" > </File> diff --git a/RealtimeSync/mainDialog.cpp b/RealtimeSync/mainDialog.cpp index ec53cd02..72b19a35 100644 --- a/RealtimeSync/mainDialog.cpp +++ b/RealtimeSync/mainDialog.cpp @@ -37,7 +37,6 @@ MainDialog::MainDialog(wxDialog *dlg, m_bpButtonAddFolder->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("addFolderPair"))); m_bpButtonRemoveTopFolder->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("removeFolderPair"))); m_buttonStart->setBitmapFront(GlobalResources::getInstance().getImageByName(wxT("startRed"))); - m_buttonStart->SetFocus(); //register key event Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnKeyPressed), NULL, this); @@ -81,7 +80,6 @@ MainDialog::MainDialog(wxDialog *dlg, setConfiguration(newConfig); - m_buttonStart->SetFocus(); Fit(); Center(); @@ -90,6 +88,8 @@ MainDialog::MainDialog(wxDialog *dlg, wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); this->OnStart(dummy2); } + else + m_buttonStart->SetFocus(); //don't "steal" focus if program is running from sys-tray" } diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile index 59e4a25e..8f42e2e3 100644 --- a/RealtimeSync/makefile +++ b/RealtimeSync/makefile @@ -34,6 +34,7 @@ FILE_LIST+=../shared/fileTraverser.cpp FILE_LIST+=../shared/localization.cpp FILE_LIST+=../shared/standardPaths.cpp FILE_LIST+=../shared/helpProvider.cpp +FILE_LIST+=../shared/fileIO.cpp #list of all *.o files OBJECT_LIST=$(foreach file, $(FILE_LIST), OBJ/$(subst .cpp,.o,$(notdir $(file)))) diff --git a/RealtimeSync/trayMenu.cpp b/RealtimeSync/trayMenu.cpp index ff88a950..79076abd 100644 --- a/RealtimeSync/trayMenu.cpp +++ b/RealtimeSync/trayMenu.cpp @@ -9,24 +9,25 @@ #include <wx/taskbar.h> #include <wx/app.h> #include "resources.h" -#include <memory> +//#include <memory> #include <wx/utils.h> #include <wx/menu.h> #include "watcher.h" -#include <wx/timer.h> #include <wx/utils.h> #include <wx/log.h> #include "../shared/staticAssert.h" #include "../shared/buildInfo.h" #include <wx/icon.h> //Linux needs this +#include <wx/timer.h> -class RtsTrayIcon; +using namespace RealtimeSync; -class WaitCallbackImpl : public RealtimeSync::WaitCallback +class WaitCallbackImpl : private wxEvtHandler, public RealtimeSync::WaitCallback //keep this order: else VC++ generated wrong code { public: WaitCallbackImpl(); + ~WaitCallbackImpl(); virtual void requestUiRefresh(); @@ -35,156 +36,157 @@ public: m_abortRequested = true; } - void requestResume() + void OnRequestResume(wxCommandEvent& event) { m_resumeRequested = true; } + enum Selection + { + CONTEXT_ABORT, + CONTEXT_RESTORE, + CONTEXT_ABOUT + }; + + void OnContextMenuSelection(wxCommandEvent& event); + private: - std::auto_ptr<RtsTrayIcon> trayMenu; + class RtsTrayIcon; + RtsTrayIcon* trayMenu; + bool m_abortRequested; bool m_resumeRequested; }; -class RtsTrayIcon : public wxTaskBarIcon +//RtsTrayIcon shall be a dumb class whose sole purpose is to enable wxWidgets deferred deletion +class WaitCallbackImpl::RtsTrayIcon : public wxTaskBarIcon { public: - RtsTrayIcon(WaitCallbackImpl* callback) : - m_callback(callback) - { -#ifdef FFS_WIN - const wxIcon& realtimeIcon = *GlobalResources::getInstance().programIcon; -#elif defined FFS_LINUX - wxIcon realtimeIcon; - realtimeIcon.CopyFromBitmap(GlobalResources::getInstance().getImageByName(wxT("RTS_tray_linux.png"))); //use a 22x22 bitmap for perfect fit -#endif - wxTaskBarIcon::SetIcon(realtimeIcon, wxString(wxT("RealtimeSync")) + wxT(" - ") + _("Monitoring active...")); + RtsTrayIcon(WaitCallbackImpl* parent) : parent_(parent) {} - //register double-click - Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(RtsTrayIcon::resumeToMain), NULL, this); - } - - void updateSysTray() + void parentHasDied() //call before tray icon is marked for deferred deletion { - wxTheApp->Yield(); + parent_ = NULL; } private: - enum Selection - { - CONTEXT_ABORT, - CONTEXT_RESTORE, - CONTEXT_ABOUT - }; - virtual wxMenu* CreatePopupMenu() { + if (!parent_) + return NULL; + wxMenu* contextMenu = new wxMenu; contextMenu->Append(CONTEXT_RESTORE, _("&Restore")); contextMenu->Append(CONTEXT_ABOUT, _("&About...")); contextMenu->AppendSeparator(); contextMenu->Append(CONTEXT_ABORT, _("&Exit")); //event handling - contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RtsTrayIcon::OnContextMenuSelection), NULL, this); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WaitCallbackImpl::OnContextMenuSelection), NULL, parent_); - return contextMenu; //ownership transferred to library + return contextMenu; //ownership transferred to caller } - void OnContextMenuSelection(wxCommandEvent& event) - { - const int eventId = event.GetId(); - switch (static_cast<Selection>(eventId)) - { - case CONTEXT_ABORT: - m_callback->requestAbort(); - break; - case CONTEXT_ABOUT: - { - //build information - wxString build = wxString(wxT("(")) + _("Build:") + wxT(" ") + __TDATE__; -#if wxUSE_UNICODE - build += wxT(" - Unicode"); -#else - build += wxT(" - ANSI"); -#endif //wxUSE_UNICODE + WaitCallbackImpl* parent_; +}; +//############################################################################################################## - //compile time info about 32/64-bit build - if (Utility::is64BitBuild) - build += wxT(" x64)"); - else - build += wxT(" x86)"); - assert_static(Utility::is32BitBuild || Utility::is64BitBuild); - wxMessageDialog* aboutDlg = new wxMessageDialog(NULL, wxString(wxT("RealtimeSync")) + wxT("\n\n") + build, _("About"), wxOK); - aboutDlg->ShowModal(); - aboutDlg->Destroy(); - } - break; - case CONTEXT_RESTORE: - m_callback->requestResume(); - break; - } - } +class AbortThisProcess //exception class +{ +public: + AbortThisProcess(MonitorResponse command) : command_(command) {} - void resumeToMain(wxCommandEvent& event) + MonitorResponse getCommand() const { - m_callback->requestResume(); + return command_; } - WaitCallbackImpl* m_callback; +private: + MonitorResponse command_; }; +//############################################################################################################## -bool updateUiIsAllowed() +WaitCallbackImpl::WaitCallbackImpl() : + m_abortRequested(false), + m_resumeRequested(false) { - static wxLongLong lastExec = 0; - const wxLongLong newExec = wxGetLocalTimeMillis(); + trayMenu = new RtsTrayIcon(this); //not in initialization list: give it a valid parent object! - if (newExec - lastExec >= RealtimeSync::UI_UPDATE_INTERVAL) //perform ui updates not more often than necessary - { - lastExec = newExec; - return true; - } - return false; +#ifdef FFS_WIN + const wxIcon& realtimeIcon = *GlobalResources::getInstance().programIcon; +#elif defined FFS_LINUX + wxIcon realtimeIcon; + realtimeIcon.CopyFromBitmap(GlobalResources::getInstance().getImageByName(wxT("RTS_tray_linux.png"))); //use a 22x22 bitmap for perfect fit +#endif + trayMenu->SetIcon(realtimeIcon, wxString(wxT("RealtimeSync")) + wxT(" - ") + _("Monitoring active...")); + + //register double-click + trayMenu->Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(WaitCallbackImpl::OnRequestResume), NULL, this); } -class AbortThisProcess //exception class +WaitCallbackImpl::~WaitCallbackImpl() { -public: - AbortThisProcess(bool backToMain) : m_backToMain(backToMain) {} + trayMenu->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(WaitCallbackImpl::OnRequestResume), NULL, this); + trayMenu->RemoveIcon(); //(try to) hide icon until final deletion takes place + trayMenu->parentHasDied(); - bool backToMainMenu() const - { - return m_backToMain; - } + //use wxWidgets delayed destruction: delete during next idle loop iteration (handle late window messages, e.g. when double-clicking) + if (!wxPendingDelete.Member(trayMenu)) + wxPendingDelete.Append(trayMenu); +} -private: - bool m_backToMain; -}; +void WaitCallbackImpl::OnContextMenuSelection(wxCommandEvent& event) +{ + const int eventId = event.GetId(); + switch (static_cast<Selection>(eventId)) + { + case CONTEXT_ABORT: + requestAbort(); + break; + case CONTEXT_RESTORE: + OnRequestResume(event); //just remember: never throw exceptions through a C-Layer (GUI) ;) + break; + case CONTEXT_ABOUT: + { + //build information + wxString build = wxString(wxT("(")) + _("Build:") + wxT(" ") + __TDATE__; +#if wxUSE_UNICODE + build += wxT(" - Unicode"); +#else + 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); -WaitCallbackImpl::WaitCallbackImpl() : - m_abortRequested(false), - m_resumeRequested(false) -{ - trayMenu.reset(new RtsTrayIcon(this)); + wxMessageDialog aboutDlg(NULL, wxString(wxT("RealtimeSync")) + wxT("\n\n") + build, _("About"), wxOK); + aboutDlg.ShowModal(); + } + break; + } } void WaitCallbackImpl::requestUiRefresh() { if (updateUiIsAllowed()) - trayMenu->updateSysTray(); + wxTheApp->Yield(); if (m_abortRequested) - throw ::AbortThisProcess(false); + throw ::AbortThisProcess(QUIT); if (m_resumeRequested) - throw ::AbortThisProcess(true); + throw ::AbortThisProcess(RESUME); } +//############################################################################################################## RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAccess::XmlRealConfig& config) @@ -216,10 +218,7 @@ RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAcces } catch (const ::AbortThisProcess& ab) { - if (ab.backToMainMenu()) - return RESUME; - else - return QUIT; + return ab.getCommand(); } catch (const FreeFileSync::FileError& error) { @@ -229,4 +228,3 @@ RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAcces return RESUME; } - diff --git a/RealtimeSync/watcher.cpp b/RealtimeSync/watcher.cpp index 2bb91b8a..3aa40520 100644 --- a/RealtimeSync/watcher.cpp +++ b/RealtimeSync/watcher.cpp @@ -31,6 +31,19 @@ using namespace FreeFileSync; +bool RealtimeSync::updateUiIsAllowed() +{ + static wxLongLong lastExec = 0; + const wxLongLong newExec = wxGetLocalTimeMillis(); + + if (newExec - lastExec >= RealtimeSync::UI_UPDATE_INTERVAL) //perform ui updates not more often than necessary + { + lastExec = newExec; + return true; + } + return false; +} + #ifdef FFS_WIN /* template <class T> //have a disctinct static variable per class! @@ -216,6 +229,7 @@ private: }; */ + //-------------------------------------------------------------------------------------------------------------- class ChangeNotifications { @@ -232,7 +246,7 @@ public: arrayHandle.push_back(hndl); } - size_t getSize() + size_t getSize() const { return arrayHandle.size(); } @@ -307,7 +321,7 @@ public: } private: - std::map<Zstring, bool> availablility; //save avail. status for each directory + std::map<Zstring, bool> availablility; //save avail. status for each directory, avoid double-entries }; diff --git a/RealtimeSync/watcher.h b/RealtimeSync/watcher.h index 87edde86..58b20d99 100644 --- a/RealtimeSync/watcher.h +++ b/RealtimeSync/watcher.h @@ -16,6 +16,9 @@ namespace RealtimeSync { const int UI_UPDATE_INTERVAL = 100; //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss +bool updateUiIsAllowed(); + + class WaitCallback { public: diff --git a/RealtimeSync/xmlProcessing.cpp b/RealtimeSync/xmlProcessing.cpp index 7cf78c7a..e9420d1b 100644 --- a/RealtimeSync/xmlProcessing.cpp +++ b/RealtimeSync/xmlProcessing.cpp @@ -27,17 +27,16 @@ void xmlAccess::readRealConfig(const wxString& filename, XmlRealConfig& config) { //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_REAL_CONFIG, doc)) - throw XmlError(wxString(_("Error reading file:")) + wxT(" \"") + filename + wxT("\"")); + loadXmlDocument(filename, XML_REAL_CONFIG, doc); //throw (XmlError) RtsXmlParser parser(doc.RootElement()); parser.readXmlRealConfig(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); } @@ -48,10 +47,10 @@ void xmlAccess::writeRealConfig(const XmlRealConfig& outputCfg, const wxString& getDefaultXmlDocument(XML_REAL_CONFIG, doc); //populate and write XML tree - if ( !writeXmRealSettings(outputCfg, doc) || //add GUI layout configuration settings - !saveXmlDocument(filename, doc)) //save XML - throw XmlError(wxString(_("Error writing file:")) + wxT(" \"") + filename + wxT("\"")); - return; + if (!writeXmRealSettings(outputCfg, doc)) //add GUI layout configuration settings + throw XmlError(wxString(_("Error writing file:")) + wxT("\n\"") + filename + wxT("\"")); + + saveXmlDocument(filename, doc); //throw (XmlError) } //-------------------------------------------------------------------------------- @@ -60,15 +59,15 @@ void xmlAccess::writeRealConfig(const XmlRealConfig& outputCfg, const wxString& void RtsXmlParser::readXmlRealConfig(xmlAccess::XmlRealConfig& outputCfg) { //read directories for monitoring - const TiXmlElement* directoriesToWatch = TiXmlHandleConst(root).FirstChild("Directories").ToElement(); + const TiXmlElement* directoriesToWatch = TiXmlHandleConst(getRoot()).FirstChild("Directories").ToElement(); readXmlElementLogging("Folder", directoriesToWatch, outputCfg.directories); //commandline to execute - readXmlElementLogging("Commandline", root, outputCfg.commandline); + readXmlElementLogging("Commandline", getRoot(), outputCfg.commandline); //delay - readXmlElementLogging("Delay", root, outputCfg.delay); + readXmlElementLogging("Delay", getRoot(), outputCfg.delay); } |