From 88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:20:07 +0200 Subject: 5.4 --- RealtimeSync/RealtimeSync.cbp | 2 +- RealtimeSync/application.cpp | 8 ++-- RealtimeSync/gui_generated.cpp | 103 ++++++++++++++++++++++++----------------- RealtimeSync/gui_generated.h | 10 ++-- RealtimeSync/main_dlg.cpp | 16 ++----- RealtimeSync/makefile | 2 +- RealtimeSync/tray_menu.cpp | 25 +++++----- RealtimeSync/watcher.cpp | 25 +++++----- RealtimeSync/watcher.h | 4 +- RealtimeSync/xml_proc.cpp | 3 -- 10 files changed, 106 insertions(+), 92 deletions(-) (limited to 'RealtimeSync') diff --git a/RealtimeSync/RealtimeSync.cbp b/RealtimeSync/RealtimeSync.cbp index 1a9469a8..97ce1a5b 100644 --- a/RealtimeSync/RealtimeSync.cbp +++ b/RealtimeSync/RealtimeSync.cbp @@ -127,7 +127,7 @@ - + diff --git a/RealtimeSync/application.cpp b/RealtimeSync/application.cpp index 4c477ce0..e756675e 100644 --- a/RealtimeSync/application.cpp +++ b/RealtimeSync/application.cpp @@ -52,7 +52,7 @@ void Application::OnStartApplication(wxIdleEvent& event) ::SetErrorMode(SEM_FAILCRITICALERRORS); #elif defined FFS_LINUX - ::gtk_rc_parse((zen::utf8CvrtTo(zen::getResourceDir()) + "styles.rc").c_str()); //remove inner border from bitmap buttons + ::gtk_rc_parse((zen::getResourceDir() + "styles.rc").c_str()); //remove inner border from bitmap buttons #endif //set program language @@ -105,9 +105,9 @@ int Application::OnRun() { //it's not always possible to display a message box, e.g. corrupted stack, however (non-stream) file output works! wxFile safeOutput(toWx(getConfigDir()) + L"LastError.txt", wxFile::write); - safeOutput.Write(utf8CvrtTo(e.what())); + safeOutput.Write(utfCvrtTo(e.what())); - wxSafeShowMessage(_("An exception occurred!") + L" - RTS", utf8CvrtTo(e.what())); + wxSafeShowMessage(_("An exception occurred!") + L" - RTS", utfCvrtTo(e.what())); return -9; } catch (...) //catch the rest @@ -121,6 +121,6 @@ int Application::OnRun() return -9; } - return 0; //program's return value + return 0; //program's return code } diff --git a/RealtimeSync/gui_generated.cpp b/RealtimeSync/gui_generated.cpp index 9bcbda52..8d656e74 100644 --- a/RealtimeSync/gui_generated.cpp +++ b/RealtimeSync/gui_generated.cpp @@ -11,25 +11,25 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxSize( 420,440 ), wxDefaultSize ); + this->SetSizeHints( wxSize( 420,350 ), wxDefaultSize ); m_menubar1 = new wxMenuBar( 0 ); m_menuFile = new wxMenu(); - wxMenuItem* m_menuItem14; - m_menuItem14 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("S&ave configuration...") ) + wxT('\t') + wxT("CTRL+S"), wxEmptyString, wxITEM_NORMAL ); - m_menuFile->Append( m_menuItem14 ); - wxMenuItem* m_menuItem13; - m_menuItem13 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration...") ) + wxT('\t') + wxT("CTRL+L"), wxEmptyString, wxITEM_NORMAL ); + m_menuItem13 = new wxMenuItem( m_menuFile, wxID_OPEN, wxString( _("&Open...") ) + wxT('\t') + wxT("CTRL+O"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItem13 ); + wxMenuItem* m_menuItem14; + m_menuItem14 = new wxMenuItem( m_menuFile, wxID_SAVE, wxString( _("&Save...") ) + wxT('\t') + wxT("CTRL+S"), wxEmptyString, wxITEM_NORMAL ); + m_menuFile->Append( m_menuItem14 ); + m_menuFile->AppendSeparator(); wxMenuItem* m_menuItem4; - m_menuItem4 = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("&Quit") ) + wxT('\t') + wxT("CTRL+Q"), wxEmptyString, wxITEM_NORMAL ); + m_menuItem4 = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("&Quit") ) , wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItem4 ); - m_menubar1->Append( m_menuFile, _("&File") ); + m_menubar1->Append( m_menuFile, _("&Program") ); m_menuHelp = new wxMenu(); wxMenuItem* m_menuItemContent; @@ -38,7 +38,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_menuHelp->AppendSeparator(); - m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("SHIFT+F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About") ) + wxT('\t') + wxT("SHIFT+F1"), wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); m_menubar1->Append( m_menuHelp, _("&Help") ); @@ -51,13 +51,13 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr wxBoxSizer* bSizer1; bSizer1 = new wxBoxSizer( wxVERTICAL ); - - bSizer1->Add( 0, 5, 0, 0, 5 ); + wxBoxSizer* bSizer13; + bSizer13 = new wxBoxSizer( wxVERTICAL ); wxStaticBoxSizer* sbSizer41; sbSizer41 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Usage:") ), wxVERTICAL ); - m_staticText3 = new wxStaticText( m_panelMain, wxID_ANY, _("1. Select directories to monitor."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText3 = new wxStaticText( m_panelMain, wxID_ANY, _("1. Select folders to watch."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText3->Wrap( -1 ); sbSizer41->Add( m_staticText3, 0, wxLEFT, 10 ); @@ -70,19 +70,21 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr sbSizer41->Add( m_staticText5, 0, wxLEFT, 10 ); - sbSizer41->Add( 0, 15, 0, 0, 5 ); + bSizer13->Add( sbSizer41, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxBOTTOM, 5 ); - m_staticText21 = new wxStaticText( m_panelMain, wxID_ANY, _("The command line is executed each time:\n- all directories become available (e.g. USB stick insert)\n- files within these directories or subdirectories are modified"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText21->Wrap( -1 ); - sbSizer41->Add( m_staticText21, 0, wxRIGHT|wxLEFT|wxEXPAND, 5 ); + m_staticText811 = new wxStaticText( m_panelMain, wxID_ANY, _("To get started just import a .ffs_batch file."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText811->Wrap( -1 ); + m_staticText811->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); + bSizer13->Add( m_staticText811, 0, wxLEFT, 20 ); - bSizer1->Add( sbSizer41, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 20 ); + + bSizer1->Add( bSizer13, 0, wxEXPAND|wxRIGHT|wxLEFT, 20 ); m_staticline2 = new wxStaticLine( m_panelMain, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer1->Add( m_staticline2, 0, wxTOP|wxBOTTOM|wxEXPAND, 10 ); + bSizer1->Add( m_staticline2, 0, wxEXPAND|wxTOP|wxBOTTOM, 10 ); - sbSizerDirToWatch2 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Directories to watch") ), wxVERTICAL ); + sbSizerDirToWatch2 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Folders to watch") ), wxVERTICAL ); m_panelMainFolder = new wxPanel( m_panelMain, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer10; @@ -144,26 +146,28 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr bSizer1->Add( sbSizerDirToWatch2, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - wxStaticBoxSizer* sbSizer3; - sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Command line") ), wxVERTICAL ); - - m_textCtrlCommand = new wxTextCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - sbSizer3->Add( m_textCtrlCommand, 0, wxEXPAND|wxBOTTOM, 5 ); - - - bSizer1->Add( sbSizer3, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - wxStaticBoxSizer* sbSizer4; - sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Minimum Idle Time [seconds]") ), wxVERTICAL ); + sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Delay [seconds]") ), wxVERTICAL ); m_spinCtrlDelay = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 2000000000, 0 ); - m_spinCtrlDelay->SetToolTip( _("Idle time between detection of last change and execution of command line in seconds") ); + m_spinCtrlDelay->SetToolTip( _("Idle time between last detected change and execution of command") ); sbSizer4->Add( m_spinCtrlDelay, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizer1->Add( sbSizer4, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + wxStaticBoxSizer* sbSizer3; + sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panelMain, wxID_ANY, _("Command line") ), wxVERTICAL ); + + m_textCtrlCommand = new wxTextCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlCommand->SetToolTip( _("The command is triggered if:\n- files or subfolders change\n- new folders arrive (e.g. USB stick insert)") ); + + sbSizer3->Add( m_textCtrlCommand, 0, wxEXPAND, 5 ); + + + bSizer1->Add( sbSizer3, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + m_buttonStart = new zen::BitmapButton( m_panelMain, wxID_OK, _("Start"), wxDefaultPosition, wxSize( -1,40 ), 0 ); m_buttonStart->SetDefault(); m_buttonStart->SetFont( wxFont( 14, 74, 90, 92, false, wxT("Arial Black") ) ); @@ -186,8 +190,8 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainDlgGenerated::OnClose ) ); - this->Connect( m_menuItem14->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); this->Connect( m_menuItem13->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnLoadConfig ) ); + this->Connect( m_menuItem14->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); this->Connect( m_menuItem4->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnQuit ) ); this->Connect( m_menuItemContent->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnShowHelp ) ); this->Connect( m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnMenuAbout ) ); @@ -201,8 +205,8 @@ MainDlgGenerated::~MainDlgGenerated() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainDlgGenerated::OnClose ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnLoadConfig ) ); + this->Disconnect( wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnLoadConfig ) ); + this->Disconnect( wxID_SAVE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); this->Disconnect( wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnQuit ) ); this->Disconnect( wxID_HELP, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnShowHelp ) ); this->Disconnect( wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnMenuAbout ) ); @@ -250,6 +254,7 @@ FolderGenerated::~FolderGenerated() ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { this->SetSizeHints( wxSize( 300,160 ), wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); wxBoxSizer* bSizer24; bSizer24 = new wxBoxSizer( wxVERTICAL ); @@ -260,37 +265,51 @@ ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxS wxBoxSizer* bSizer26; bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - m_bitmap10 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 ); - bSizer26->Add( m_bitmap10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + m_bitmap10 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer26->Add( m_bitmap10, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE|wxTE_READONLY ); - m_textCtrl8->SetBackgroundColour( wxColour( 224, 224, 224 ) ); - - bSizer26->Add( m_textCtrl8, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 400,150 ), wxTE_MULTILINE|wxTE_READONLY|wxNO_BORDER ); + bSizer26->Add( m_textCtrl8, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); bSizer24->Add( bSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer24->Add( m_staticline2, 0, wxEXPAND|wxTOP, 5 ); + + m_panel3 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel3->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + wxBoxSizer* bSizer13; + bSizer13 = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer* bSizer25; bSizer25 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonRetry = new wxButton( this, wxID_RETRY, _("&Retry"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonRetry = new wxButton( m_panel3, wxID_RETRY, _("&Retry"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_buttonRetry->SetDefault(); m_buttonRetry->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); bSizer25->Add( m_buttonRetry, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - m_buttonAbort = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonAbort = new wxButton( m_panel3, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_buttonAbort->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); bSizer25->Add( m_buttonAbort, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - bSizer24->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer13->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + + m_panel3->SetSizer( bSizer13 ); + m_panel3->Layout(); + bSizer13->Fit( m_panel3 ); + bSizer24->Add( m_panel3, 0, wxEXPAND, 5 ); this->SetSizer( bSizer24 ); this->Layout(); + bSizer24->Fit( this ); this->Centre( wxBOTH ); diff --git a/RealtimeSync/gui_generated.h b/RealtimeSync/gui_generated.h index 1989653f..50ffea2b 100644 --- a/RealtimeSync/gui_generated.h +++ b/RealtimeSync/gui_generated.h @@ -58,7 +58,7 @@ protected: wxStaticText* m_staticText3; wxStaticText* m_staticText4; wxStaticText* m_staticText5; - wxStaticText* m_staticText21; + wxStaticText* m_staticText811; wxStaticLine* m_staticline2; wxStaticBoxSizer* sbSizerDirToWatch2; wxPanel* m_panelMainFolder; @@ -68,15 +68,15 @@ protected: wxTextCtrl* m_txtCtrlDirectoryMain; wxScrolledWindow* m_scrolledWinFolders; wxBoxSizer* bSizerFolders; - wxTextCtrl* m_textCtrlCommand; wxSpinCtrl* m_spinCtrlDelay; + wxTextCtrl* m_textCtrlCommand; zen::BitmapButton* m_buttonStart; wxButton* m_buttonCancel; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnSaveConfig( wxCommandEvent& event ) { event.Skip(); } virtual void OnLoadConfig( wxCommandEvent& event ) { event.Skip(); } + virtual void OnSaveConfig( wxCommandEvent& event ) { event.Skip(); } virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); } virtual void OnShowHelp( wxCommandEvent& event ) { event.Skip(); } virtual void OnMenuAbout( wxCommandEvent& event ) { event.Skip(); } @@ -123,6 +123,8 @@ private: protected: wxStaticBitmap* m_bitmap10; wxTextCtrl* m_textCtrl8; + wxStaticLine* m_staticline2; + wxPanel* m_panel3; wxButton* m_buttonRetry; wxButton* m_buttonAbort; @@ -134,7 +136,7 @@ protected: public: - ErrorDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Error"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 460,250 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); + ErrorDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Error"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); ~ErrorDlgGenerated(); }; diff --git a/RealtimeSync/main_dlg.cpp b/RealtimeSync/main_dlg.cpp index dfb1a85e..40852056 100644 --- a/RealtimeSync/main_dlg.cpp +++ b/RealtimeSync/main_dlg.cpp @@ -44,12 +44,10 @@ MainDialog::MainDialog(wxDialog* dlg, const wxString& cfgFileName) //prepare drag & drop dirNameFirst.reset(new DirectoryName(*m_panelMainFolder, *m_dirPickerMain, *m_txtCtrlDirectoryMain, m_staticTextFinalPath)); - #ifdef FFS_WIN new MouseMoveWindow(*this); //ownership passed to "this" #endif - //--------------------------- load config values ------------------------------------ xmlAccess::XmlRealConfig newConfig; @@ -120,11 +118,7 @@ const wxString& MainDialog::lastConfigFileName() void MainDialog::OnShowHelp(wxCommandEvent& event) { -#ifdef FFS_WIN - zen::displayHelpEntry(wxT("html\\RealtimeSync.html")); -#elif defined FFS_LINUX - zen::displayHelpEntry(wxT("html/RealtimeSync.html")); -#endif + zen::displayHelpEntry(L"html/RealtimeSync.html"); } @@ -166,7 +160,7 @@ void MainDialog::OnStart(wxCommandEvent& event) Hide(); - switch (rts::startDirectoryMonitor(currentCfg, xmlAccess::extractJobName(currentConfigFileName))) + switch (rts::startDirectoryMonitor(currentCfg, xmlAccess::extractJobName(utfCvrtTo(currentConfigFileName)))) { case rts::EXIT_APP: Close(); @@ -188,8 +182,8 @@ void MainDialog::OnSaveConfig(wxCommandEvent& event) wxFileDialog filePicker(this, wxEmptyString, wxEmptyString, defaultFileName, - _("RealtimeSync configuration") + L" (*.ffs_real)|*.ffs_real", - wxFD_SAVE /*| wxFD_OVERWRITE_PROMPT*/); + wxString(L"RealtimeSync (*.ffs_real)|*.ffs_real") + L"|" +_("All files") + L" (*.*)|*", + wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (filePicker.ShowModal() != wxID_OK) return; @@ -252,7 +246,7 @@ void MainDialog::setLastUsedConfig(const wxString& filename) void MainDialog::OnLoadConfig(wxCommandEvent& event) { wxFileDialog filePicker(this, wxEmptyString, wxEmptyString, wxEmptyString, - _("RealtimeSync configuration") + L" (*.ffs_real;*.ffs_batch)|*.ffs_real;*.ffs_batch", + wxString(L"RealtimeSync (*.ffs_real;*.ffs_batch)|*.ffs_real;*.ffs_batch") + L"|" +_("All files") + L" (*.*)|*", wxFD_OPEN); if (filePicker.ShowModal() == wxID_OK) loadConfig(filePicker.GetPath()); diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile index c92e2052..9f0ae16a 100644 --- a/RealtimeSync/makefile +++ b/RealtimeSync/makefile @@ -3,7 +3,7 @@ prefix = /usr BINDIR = $(DESTDIR)$(prefix)/bin COMMON_COMPILE_FLAGS = -Wall -pipe -O3 -pthread -std=gnu++0x -DNDEBUG -DwxUSE_UNICODE -DFFS_LINUX -DZEN_PLATFORM_OTHER -DWXINTL_NO_GETTEXT_MACRO -I.. -include "../zen/i18n.h" -COMMON_LINK_FLAGS = -pthread +COMMON_LINK_FLAGS = -pthread -lrt #default build CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes` diff --git a/RealtimeSync/tray_menu.cpp b/RealtimeSync/tray_menu.cpp index 4afef5e4..942a6100 100644 --- a/RealtimeSync/tray_menu.cpp +++ b/RealtimeSync/tray_menu.cpp @@ -66,7 +66,7 @@ private: wxMenu* contextMenu = new wxMenu; contextMenu->Append(CONTEXT_RESTORE, _("&Restore")); - contextMenu->Append(CONTEXT_ABOUT, _("&About...")); + contextMenu->Append(CONTEXT_ABOUT, _("&About")); contextMenu->AppendSeparator(); contextMenu->Append(CONTEXT_ABORT, _("&Exit")); //event handling @@ -206,7 +206,7 @@ public: void clearSchedule() { nextSyncStart_ = std::numeric_limits::max(); } //implement WaitCallback - virtual void requestUiRefresh() //throw StartSyncNowException, AbortMonitoring + virtual void requestUiRefresh(bool readyForSync) //throw StartSyncNowException, AbortMonitoring { if (resumeRequested) throw AbortMonitoring(SHOW_GUI); @@ -214,8 +214,9 @@ public: if (abortRequested) throw AbortMonitoring(EXIT_APP); - if (nextSyncStart_ <= wxGetLocalTime()) - throw StartSyncNowException(); //abort wait and start sync + if (readyForSync) + if (nextSyncStart_ <= wxGetLocalTime()) + throw StartSyncNowException(); //abort wait and start sync if (updateUiIsAllowed()) trayIcon.doUiRefreshNow(); @@ -252,6 +253,8 @@ public: timer.Connect(wxEVT_TIMER, wxEventHandler(ErrorDlgWithTimeout::OnTimerEvent), nullptr, this); timer.Start(1000); //timer interval in ms updateButtonLabel(); + + Fit(); //child-element widths have changed: image was set } enum ButtonPressed @@ -325,12 +328,12 @@ rts::AbortReason rts::startDirectoryMonitor(const xmlAccess::XmlRealConfig& conf if (cmdLine.empty()) { - wxMessageBox(replaceCpy(_("Invalid command line: %x"), L"%x", L"\"\""), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(_("Invalid command line:") + L" \"\"", _("Error"), wxOK | wxICON_ERROR); return SHOW_GUI; } if (dirList.empty() || std::any_of(dirList.begin(), dirList.end(), [](Zstring str) -> bool { trim(str); return str.empty(); })) { - wxMessageBox(_("A directory input field is empty."), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(_("An input folder name is empty."), _("Error"), wxOK | wxICON_ERROR); return SHOW_GUI; } @@ -341,13 +344,12 @@ rts::AbortReason rts::startDirectoryMonitor(const xmlAccess::XmlRealConfig& conf auto execMonitoring = [&] //throw FileError, AbortMonitoring { - callback.clearSchedule(); - callback.notifyDirectoryMissing(); + callback.clearSchedule(); waitForMissingDirs(dirList, callback); //throw FileError, StartSyncNowException(not scheduled yet), AbortMonitoring callback.notifyAllDirectoriesExist(); - //schedule initial execution only AFTER waitForMissingDirs(), else StartSyncNowException might be thrown while directory checking hangs + //schedule initial execution (*after* all directories have arrived, which could take some time which we don't want to include) callback.scheduleNextSync(wxGetLocalTime() + static_cast(config.delay)); while (true) @@ -361,9 +363,8 @@ rts::AbortReason rts::startDirectoryMonitor(const xmlAccess::XmlRealConfig& conf switch (res.type) { case CHANGE_DIR_MISSING: //don't execute the commandline before all directories are available! - callback.clearSchedule(); - callback.notifyDirectoryMissing(); + callback.clearSchedule(); waitForMissingDirs(dirList, callback); //throw FileError, StartSyncNowException(not scheduled yet), AbortMonitoring callback.notifyAllDirectoriesExist(); break; @@ -377,7 +378,7 @@ rts::AbortReason rts::startDirectoryMonitor(const xmlAccess::XmlRealConfig& conf } catch (StartSyncNowException&) {} - ::wxSetEnv(L"changed_file", utf8CvrtTo(lastFileChanged)); //some way to output what file changed to the user + ::wxSetEnv(L"changed_file", utfCvrtTo(lastFileChanged)); //some way to output what file changed to the user lastFileChanged.clear(); //make sure old name is not shown again after a directory reappears //execute command diff --git a/RealtimeSync/watcher.cpp b/RealtimeSync/watcher.cpp index ee56bc7c..301c9c64 100644 --- a/RealtimeSync/watcher.cpp +++ b/RealtimeSync/watcher.cpp @@ -12,14 +12,15 @@ #include #include #include +#include #include -#include #include "../lib/resolve_path.h" //#include "../library/db_file.h" //SYNC_DB_FILE_ENDING -> complete file too much of a dependency; file ending too little to decouple into single header //#include "../library/lock_holder.h" //LOCK_FILE_ENDING using namespace zen; + namespace { const std::int64_t TICKS_UPDATE_INTERVAL = rts::UI_UPDATE_INTERVAL* ticksPerSec() / 1000; @@ -40,7 +41,7 @@ bool rts::updateUiIsAllowed() namespace { -const int CHECK_DIR_INTERVAL = 1000; //1 second interval +const int CHECK_DIR_INTERVAL = 1; //unit: [s] std::vector getFormattedDirs(const std::vector& dirs) //throw FileError @@ -59,7 +60,7 @@ rts::WaitResult rts::waitForChanges(const std::vector& dirNamesNonFmt, { const std::vector dirNamesFmt = getFormattedDirs(dirNamesNonFmt); //throw FileError if (dirNamesFmt.empty()) //pathological case, but check is needed nevertheless - throw zen::FileError(_("A directory input field is empty.")); //should have been checked by caller! + throw zen::FileError(_("An input folder name is empty.")); //should have been checked by caller! //detect when volumes are removed/are not available anymore std::vector>> watches; @@ -76,7 +77,6 @@ rts::WaitResult rts::waitForChanges(const std::vector& dirNamesNonFmt, if (!ftDirExists.get()) return WaitResult(CHANGE_DIR_MISSING, dirnameFmt); - watches.push_back(std::make_pair(dirnameFmt, std::make_shared(dirnameFmt))); //throw FileError, ErrorNotExisting } catch (ErrorNotExisting&) //nice atomic behavior: *no* second directory existence check!!! @@ -91,15 +91,16 @@ rts::WaitResult rts::waitForChanges(const std::vector& dirNamesNonFmt, } } - wxLongLong lastCheck; + const std::int64_t TICKS_DIR_CHECK_INTERVAL = CHECK_DIR_INTERVAL * ticksPerSec(); //0 on error + TickVal lastCheck = getTicks(); //0 on error while (true) { - const bool checkDirExistNow = [&lastCheck]() -> bool //checking once per sec should suffice + const bool checkDirExistNow = [&]() -> bool //checking once per sec should suffice { - const wxLongLong current = wxGetLocalTimeMillis(); - if (current - lastCheck >= CHECK_DIR_INTERVAL) + const TickVal now = getTicks(); //0 on error + if (now - lastCheck >= TICKS_DIR_CHECK_INTERVAL) { - lastCheck = current; + lastCheck = now; return true; } return false; @@ -151,7 +152,7 @@ rts::WaitResult rts::waitForChanges(const std::vector& dirNamesNonFmt, } boost::this_thread::sleep(boost::posix_time::milliseconds(rts::UI_UPDATE_INTERVAL)); - statusHandler.requestUiRefresh(); + statusHandler.requestUiRefresh(true); //throw ?: may start sync at this presumably idle time } } @@ -190,8 +191,8 @@ void rts::waitForMissingDirs(const std::vector& dirNamesNonFmt, WaitCal return; //wait some time... - assert_static(CHECK_DIR_INTERVAL % UI_UPDATE_INTERVAL == 0); - for (int i = 0; i < CHECK_DIR_INTERVAL / UI_UPDATE_INTERVAL; ++i) + assert_static(1000 * CHECK_DIR_INTERVAL % UI_UPDATE_INTERVAL == 0); + for (int i = 0; i < 1000 * CHECK_DIR_INTERVAL / UI_UPDATE_INTERVAL; ++i) { boost::this_thread::sleep(boost::posix_time::milliseconds(UI_UPDATE_INTERVAL)); statusHandler.requestUiRefresh(); diff --git a/RealtimeSync/watcher.h b/RealtimeSync/watcher.h index 17252535..6d68d5be 100644 --- a/RealtimeSync/watcher.h +++ b/RealtimeSync/watcher.h @@ -22,7 +22,7 @@ class WaitCallback { public: virtual ~WaitCallback() {} - virtual void requestUiRefresh() = 0; //opportunity to abort must be implemented in a frequently executed method like requestUiRefresh() + virtual void requestUiRefresh(bool readyForSync = false) = 0; //opportunity to abort must be implemented in a frequently executed method like requestUiRefresh() }; @@ -45,7 +45,7 @@ WaitResult waitForChanges(const std::vector& dirNamesNonFmt, //non-formatted dirnames that yet require call to getFormattedDirectoryName(); empty directories must be checked by caller! WaitCallback& statusHandler); //throw FileError -//wait until all directories become available (again) +//wait until all directories become available (again) + logs in network share void waitForMissingDirs(const std::vector& dirNamesNonFmt, WaitCallback& statusHandler); //throw FileError } diff --git a/RealtimeSync/xml_proc.cpp b/RealtimeSync/xml_proc.cpp index 891cb2df..b804ba72 100644 --- a/RealtimeSync/xml_proc.cpp +++ b/RealtimeSync/xml_proc.cpp @@ -38,9 +38,6 @@ bool isXmlTypeRTS(const XmlDoc& doc) //throw() void xmlAccess::readRealConfig(const Zstring& filename, XmlRealConfig& config) { - if (!fileExists(filename)) - throw FfsXmlError(replaceCpy(_("Cannot find file %x."), L"%x", fmtFileName(filename))); - XmlDoc doc; loadXmlDocument(filename, doc); //throw FfsXmlError -- cgit