summaryrefslogtreecommitdiff
path: root/RealtimeSync/trayMenu.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:17 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:17 +0200
commitfd0853d2623dd278b08288331ed42e3be59252fb (patch)
treea7645daeaef8bdbed064faf4eb88e72cee58726c /RealtimeSync/trayMenu.cpp
parent2.1 (diff)
downloadFreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.tar.gz
FreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.tar.bz2
FreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.zip
2.2
Diffstat (limited to 'RealtimeSync/trayMenu.cpp')
-rw-r--r--RealtimeSync/trayMenu.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/RealtimeSync/trayMenu.cpp b/RealtimeSync/trayMenu.cpp
new file mode 100644
index 00000000..5d9d2430
--- /dev/null
+++ b/RealtimeSync/trayMenu.cpp
@@ -0,0 +1,209 @@
+#include "trayMenu.h"
+#include <wx/msgdlg.h>
+#include <wx/taskbar.h>
+#include <wx/app.h>
+#include "resources.h"
+#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>
+
+class RtsTrayIcon;
+
+
+class WaitCallbackImpl : public RealtimeSync::WaitCallback
+{
+public:
+ WaitCallbackImpl();
+
+ virtual void requestUiRefresh();
+
+ void requestAbort()
+ {
+ m_abortRequested = true;
+ }
+
+ void requestResume()
+ {
+ m_resumeRequested = true;
+ }
+
+private:
+ std::auto_ptr<RtsTrayIcon> trayMenu;
+ bool m_abortRequested;
+ bool m_resumeRequested;
+};
+
+
+class RtsTrayIcon : public wxTaskBarIcon
+{
+public:
+ RtsTrayIcon(WaitCallbackImpl* callback) :
+ m_callback(callback)
+ {
+ wxTaskBarIcon::SetIcon(*GlobalResources::getInstance().programIcon, wxT("RealtimeSync"));
+
+ //register double-click
+ Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(RtsTrayIcon::resumeToMain), NULL, this);
+ }
+
+ void updateSysTray()
+ {
+ wxTheApp->Yield();
+ }
+
+private:
+ enum Selection
+ {
+ CONTEXT_ABORT,
+ CONTEXT_RESTORE,
+ CONTEXT_ABOUT
+ };
+
+ virtual wxMenu* CreatePopupMenu()
+ {
+ 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);
+
+ return contextMenu; //ownership transferred to library
+ }
+
+ 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
+
+ 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;
+ }
+ }
+
+ void resumeToMain(wxCommandEvent& event)
+ {
+ m_callback->requestResume();
+ }
+
+ WaitCallbackImpl* m_callback;
+};
+
+
+bool 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;
+}
+
+
+class AbortThisProcess //exception class
+{
+public:
+ AbortThisProcess(bool backToMain) : m_backToMain(backToMain) {}
+
+ bool backToMainMenu() const
+ {
+ return m_backToMain;
+ }
+
+private:
+ bool m_backToMain;
+};
+
+
+
+WaitCallbackImpl::WaitCallbackImpl() :
+ m_abortRequested(false),
+ m_resumeRequested(false)
+{
+ trayMenu.reset(new RtsTrayIcon(this));
+}
+
+
+void WaitCallbackImpl::requestUiRefresh()
+{
+ if (updateUiIsAllowed())
+ trayMenu->updateSysTray();
+
+ if (m_abortRequested)
+ throw ::AbortThisProcess(false);
+
+ if (m_resumeRequested)
+ throw ::AbortThisProcess(true);
+}
+
+
+RealtimeSync::MonitorResponse RealtimeSync::startDirectoryMonitor(const xmlAccess::XmlRealConfig& config)
+{
+ try
+ {
+ WaitCallbackImpl callback;
+
+ if (config.commandline.empty())
+ throw FreeFileSync::FileError(_("Commandline is empty!"));
+
+ long lastExec = 0;
+ while (true)
+ {
+ wxExecute(config.commandline, wxEXEC_SYNC); //execute command
+ wxLog::FlushActive(); //show wxWidgets error messages (if any)
+
+ //wait
+ waitForChanges(config.directories, &callback);
+ lastExec = wxGetLocalTime();
+
+ //some delay
+ while (wxGetLocalTime() - lastExec < static_cast<long>(config.delay))
+ {
+ callback.requestUiRefresh();
+ wxMilliSleep(RealtimeSync::UI_UPDATE_INTERVAL);
+ }
+ }
+ }
+ catch (const ::AbortThisProcess& ab)
+ {
+ if (ab.backToMainMenu())
+ return RESUME;
+ else
+ return QUIT;
+ }
+ catch (const FreeFileSync::FileError& error)
+ {
+ wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR);
+ return RESUME;
+ }
+
+ return RESUME;
+}
bgstack15