summaryrefslogtreecommitdiff
path: root/RealtimeSync
diff options
context:
space:
mode:
Diffstat (limited to 'RealtimeSync')
-rw-r--r--RealtimeSync/RealtimeSync.cbp1
-rw-r--r--RealtimeSync/RealtimeSync.vcproj12
-rw-r--r--RealtimeSync/mainDialog.cpp4
-rw-r--r--RealtimeSync/makefile1
-rw-r--r--RealtimeSync/trayMenu.cpp198
-rw-r--r--RealtimeSync/watcher.cpp18
-rw-r--r--RealtimeSync/watcher.h3
-rw-r--r--RealtimeSync/xmlProcessing.cpp21
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);
}
bgstack15