%% options copyright owner = Dirk Krause copyright year = 2013 license = bsd %% wx-gui type = frame contents = mainSizer icon = wxdkclock_icon menu bar = mbMain [wxMenuBar mbMain] contents = menuFile contents = menuOptions contents = menuHelp [wxMenu menuFile] text = sTexts[0] contents = miFileExit [wxMenuItem miFileExit] id = DkClockFrame_Quit text = sTexts[1] tip = sTexts[2] [wxMenu menuOptions] text = sTexts[13] contents = miOptionsAlert contents = miOptionsHide contents = mOptionsColour [wxMenuItem miOptionsAlert] id = DkClockFrame_Edit_Options text = sTexts[14] tip = sTexts[15] [wxMenuItem miOptionsHide] id = DkClockFrame_Hide text = sTexts[28] tip = sTexts[29] menu item style = check [wxMenu mOptionsColour] text = sTexts[30] contents = miOptionsColourNormal contents = miOptionsColourAlert [wxMenuItem miOptionsColourNormal] id = DkClockFrame_NormalColour text = sTexts[31] tip = sTexts[32] [wxMenuItem miOptionsColourAlert] id = DkClockFrame_AlertColour text = sTexts[33] tip = sTexts[34] [wxMenu menuHelp] text = sTexts[3] contents = miHelpAbout contents = miHelpContents [wxMenuItem miHelpAbout] id = DkClockFrame_Help_About text = sTexts[4] tip = sTexts[5] [wxMenuItem miHelpContents] id = DkClockFrame_Help_Contents text = sTexts[6] tip = sTexts[7] [wxBoxSizer mainSizer] direction = horizontal contents = $space(1) contents = verticalSizer contents = $space(1) [wxBoxSizer verticalSizer] direction = vertical grow = yes proportion = 1 contents = $space(1) contents = clv contents = $space(1) [DkClockView clv] grow = yes proportion = 1 id = wxID_ANY constructor = &clockData %% header start %% class start class DkClockFrame : public DkWxFrame { private: /** Event table for frame. */ DECLARE_EVENT_TABLE() protected: /** Timer. */ wxTimer tiTenPerSecond; /** Controller for idle processing. */ DkWxProcessingIdleController pcIdle; /** Processing controller for timer events. */ DkWxProcessingController pcTimer; /* Clock data including timer settings and current time. */ DkClockData clockData; /** Keywords for configuration entries. */ static wxChar const * const kwConfInt[]; /** Colour preference keys. */ static dkChar const * const colPrefKeys[]; /** Localized texts. */ wxChar const * const *sTexts; /** Non-localized texts. */ wxChar const * const *sNlWx; /** Non-localized texts. */ dkChar const * const *sNlDk; /** Task bar icon. */ DkClockTaskbarIcon *iconTb; #if defined(__WXCOCOA__) /** Dock icon. */ DkClockTaskbarIcon *iconDock; #endif /** Last current time saved. */ dk3_time_t currentTime; /** Previous options dialog x position. */ int odx; /** Previous options dialog y position. */ int ody; /** Colour dialog x position. */ int cdx; /** Colour dialog y position. */ int cdy; /** Flag: Is first idle event. */ bool bIsFirstIdleEvent; /** Flag: First time iconized. */ bool bHaveBuffer; /** Flag: Application is hidden behind task bar icon. */ bool bIsHidden; /** Flag: Option -h specified to hide at startup. */ bool bShouldHide; %% class end protected: /** Save all settings. */ void saveSettings(void); public: /** Constructor. @param wxid Window ID. @param applicationHelper Application helper object. @param hc Help controller for online help. @param argc Number of command line arguments. @param argv Command line arguments array. @param localizedTexts Localized wxChar texts. @param nlWx Non-localized wxChar texts. @param nlDk Non-localized dkChar texts. */ DkClockFrame( int wxid, DkWxAppHelper *applicationHelper, DkWxHelpController *hc, int argc, wxChar **argv, wxChar const * const *localizedTexts, wxChar const * const *nlWx, dkChar const * const *nlDk ); /** Destructor. */ ~DkClockFrame(); /** Check whether we can close the window. @param isLast Flag: Last main window to close. */ bool canClose(bool isLast); /** Handler for File/Exit. @param event Event to process. */ void OnQuit(wxCommandEvent & event); /** Handler for Help/About. @param event Event to process. */ void OnAbout(wxCommandEvent & event); /** Handler for Help/Contents. @param event Event to process. */ void OnHelpContents(wxCommandEvent & event); /** Handler for Edit/Options. @param event Event to process. */ void OnEditOptions(wxCommandEvent & event); /** Handler for idle events. @param event Event to process. */ void OnIdle(wxIdleEvent & event); /** Handler for timer events. @param event Event to process. */ void OnTimer(wxTimerEvent & event); /** Handler for hide menu item. @param event Event to process. */ void OnHide(wxCommandEvent & event); /** Handler for normal colour menu item. @param event Event to process. */ void OnColourNormal(wxCommandEvent & event); /** Handler for alert colour menu item. @param event Event to process. */ void OnColourAlert(wxCommandEvent & event); /** Handler for iconize. @param event Event to process. */ void OnIconize(wxIconizeEvent & event); /** Notify window whether or not it is hidden. */ void SetHidden(bool b); }; %% header end %% module start #include "wxdkclock.h" #include "dkt-version.h" #if !defined(__WXMSW__) #include "dkclock.xpm" #endif $!trace-include BEGIN_EVENT_TABLE(DkClockFrame, wxFrame) EVT_MENU(DkClockFrame_Quit, DkClockFrame::OnQuit) EVT_MENU(DkClockFrame_Help_About, DkClockFrame::OnAbout) EVT_MENU(DkClockFrame_Help_Contents, DkClockFrame::OnHelpContents) EVT_MENU(DkClockFrame_Edit_Options, DkClockFrame::OnEditOptions) EVT_MENU(DkClockFrame_Hide, DkClockFrame::OnHide) EVT_MENU(DkClockFrame_NormalColour, DkClockFrame::OnColourNormal) EVT_MENU(DkClockFrame_AlertColour, DkClockFrame::OnColourAlert) EVT_TIMER(DkClockFrame_Timer, DkClockFrame::OnTimer) EVT_IDLE(DkClockFrame::OnIdle) EVT_ICONIZE(DkClockFrame::OnIconize) END_EVENT_TABLE() wxChar const * const DkClockFrame::kwConfInt[] = { /* 0 */ wxT("alert.enabled"), /* 1 */ wxT("alert.hour"), /* 2 */ wxT("alert.minute"), /* 3 */ wxT("colour.clock.red"), /* 4 */ wxT("colour.clock.green"), /* 5 */ wxT("colour.clock.blue"), /* 6 */ wxT("colour.alert.red"), /* 7 */ wxT("colour.alert.green"), /* 8 */ wxT("colour.alert.blue"), NULL }; dkChar const * const DkClockFrame::colPrefKeys[] = { /* 0 */ dkT("/colour/clock/red"), /* 1 */ dkT("/colour/clock/green"), /* 2 */ dkT("/colour/clock/blue"), /* 3 */ dkT("/colour/alert/red"), /* 4 */ dkT("/colour/alert/green"), /* 5 */ dkT("/colour/alert/blue"), NULL }; /** Allowed command line arguments. */ static const wxCmdLineEntryDesc dkclock_cmd_line_desc[] = { { wxCMD_LINE_SWITCH, wxT_2("t"), wxT_2("taskbar"), wxT_2("Hide behind task bar icon"), }, { wxCMD_LINE_NONE } }; %% constructor start DkClockFrame::DkClockFrame( int wxid, DkWxAppHelper *applicationHelper, DkWxHelpController *hc, int argc, wxChar **argv, wxChar const * const *localizedTexts, wxChar const * const *nlWx, dkChar const * const *nlDk ) : DkWxFrame(nlWx[0], applicationHelper, hc, wxid), tiTenPerSecond(this, DkClockFrame_Timer), pcIdle(), pcTimer(), clockData() { dk3_time_t ct; size_t szres; int alval[9]; int res = -1; $? "+ DkClockFrame::DkClockFrame" iconTb = NULL; #if defined(__WXCOCOA__) iconDock = NULL; #endif sTexts = localizedTexts; sNlWx = nlWx; sNlDk = nlDk; bIsFirstIdleEvent = true; currentTime = (dk3_time_t)0UL; bHaveBuffer = true; bIsHidden = false; bShouldHide = false; odx = ody = -1; cdx = cdy = -1; #if defined(__WXMSW__) wxIcon wxdkclock_icon(sNlWx[4]); #else wxIcon wxdkclock_icon(xpm_dkclock); #endif %% constructor end if(dkctGUILayoutOK) { miOptionsHide->Enable(false); SetTitle(nlWx[0]); restorePosition(); dk3sf_time(&ct); alval[0] = 0; alval[1] = 0; alval[2] = 0; /* When running for the first time, use defaults set by the system administrator. */ alval[3] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[0], 0); alval[4] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[1], 0); alval[5] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[2], 0); #if DK3_ON_WINDOWS alval[6] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[3], 127); #else alval[6] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[3], 191); #endif alval[7] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[4], 0); alval[8] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[5], 0); szres = pHelper->retrieveMultipleInts(kwConfInt, alval); if(3 <= szres) { $? ". retrieve" if(0 != alval[0]) { $? ". enabled" if((0 <= alval[1]) && (23 >= alval[1])) { $? ". hour ok" if((0 <= alval[2]) && (59 >= alval[2])) { $? ". min ok" clockData.setAlert(true, alval[1], alval[2]); } } } else { $? ". not enabled" } } else { $? "! retrieve" } clv->setNormal(alval[3], alval[4], alval[5]); clv->setAlert(alval[6], alval[7], alval[8]); clockData.setTime(&ct); clockData.endAlert(); clv->SetMustUpdate(); #if 0 if(wxTaskBarIcon::IsAvailable()) { #endif iconTb = new DkClockTaskbarIcon(this, sTexts); if(!(iconTb->SetIcon(wxdkclock_icon, sNlWx[0]))) { delete iconTb; iconTb = NULL; } if(iconTb) { miOptionsHide->Enable(true); } #if defined(__WXCOCOA__) if(iconTb) { iconDock = new DkClockTaskbarIcon(this, sTexts, wxTaskBarIcon::DOCK); } #endif #if 0 } #endif miOptionsHide->Check(false); { wxCmdLineParser parser(dkclock_cmd_line_desc, argc, argv); { wxLogNull log; res = parser.Parse(false); } if(0 == res) { if(parser.Found(wxT("t"))) { if(iconTb) { bShouldHide = true; miOptionsHide->Check(true); } } } } } $? "- DkClockFrame::DkClockFrame %d", ((dkctGUILayoutOK) ? 1 : 0) } %% module end DkClockFrame::~DkClockFrame() { $? "+ DkClockFrame::~DkClockFrame" if(iconTb) { delete iconTb; iconTb = NULL; } #if defined(__WXCOCOA__) if(iconDock) { delete iconDock; iconDock = NULL; } #endif $? "- DkClockFrame::~DkClockFrame" } void DkClockFrame::saveSettings(void) { int alval[9]; $? "+ DkClockFrame::saveSettings" alval[0] = alval[1] = alval[2] = 0; alval[3] = clv->getNormalRed(); alval[4] = clv->getNormalGreen(); alval[5] = clv->getNormalBlue(); alval[6] = clv->getAlertRed(); alval[7] = clv->getAlertGreen(); alval[8] = clv->getAlertBlue(); clockData.getAlertData(&(alval[0]), &(alval[1]), &(alval[2])); pHelper->saveMultipleInts(kwConfInt, alval); $? "- DkClockFrame::saveSettings" } bool DkClockFrame::canClose(bool isLast) { #if VERSION_BEFORE_20140410 int alval[9]; #endif bool back = true; $? "+ DkClockFrame::canClose" tiTenPerSecond.Stop(); #if VERSION_BEFORE_20140410 alval[0] = alval[1] = alval[2] = 0; alval[3] = clv->getNormalRed(); alval[4] = clv->getNormalGreen(); alval[5] = clv->getNormalBlue(); alval[6] = clv->getAlertRed(); alval[7] = clv->getAlertGreen(); alval[8] = clv->getAlertBlue(); clockData.getAlertData(&(alval[0]), &(alval[1]), &(alval[2])); pHelper->saveMultipleInts(kwConfInt, alval); #else saveSettings(); #endif $? "- DkClockFrame::canClose %d", ((back) ? 1 : 0) return back; } void DkClockFrame::OnQuit(wxCommandEvent & event) { $? "= DkClockFrame::OnQuit" Close(); } void DkClockFrame::OnAbout(wxCommandEvent & event) { wxString text(wxT("")); wxString title(wxT("")); $? "+ DkClockFrame::OnAbout" /* Construct message text. */ text.Append(sNlWx[0]); text.Append(sNlWx[7]); #if 0 text.Append(sNlWx[1]); #else text.Append( DKT_WXCHAR_VERSION ); #endif text.Append(sNlWx[8]); text.Append(sTexts[9]); text.Append(sNlWx[2]); text.Append(sNlWx[8]); text.Append(sNlWx[8]); text.Append(sTexts[11]); text.Append(sNlWx[8]); text.Append(sNlWx[9]); text.Append(sNlWx[8]); text.Append(sNlWx[8]); text.Append(sTexts[12]); text.Append(sNlWx[8]); text.Append(sNlWx[10]); text.Append(sNlWx[8]); text.Append(sNlWx[11]); text.Append(sNlWx[8]); text.Append(sNlWx[12]); text.Append(sNlWx[8]); text.Append(sNlWx[13]); text.Append(sNlWx[8]); text.Append(sNlWx[14]); text.Append(sNlWx[8]); text.Append(sNlWx[15]); text.Append(sNlWx[8]); /* Construct dialog box title. */ title.Append(sTexts[10]); title.Append(sNlWx[0]); /* Show dialog box. */ wxMessageBox(text, title); $? "- DkClockFrame::OnAbout" } void DkClockFrame::OnHelpContents(wxCommandEvent & event) { $? "+ DkClockFrame::OnHelpContents" openHelp(); $? "- DkClockFrame::OnHelpContents" } void DkClockFrame::OnEditOptions(wxCommandEvent & event) { $? "+ DkClockFrame::OnEditOptions" DkClockOptionsDialog dlg((DkWxFrame *)this, sTexts[16], sTexts, &clockData); pHelper->setRelatedPosition(this, &dlg, &odx, &ody); if(wxID_OK == dlg.ShowModal()) { saveSettings(); } dlg.GetPosition(&odx, &ody); $? "- DkClockFrame::OnEditOptions" } void DkClockFrame::OnIdle(wxIdleEvent & event) { $? "+ DkClockFrame::OnIdle" if(pcIdle.canBeginProcessing()) { if(bIsFirstIdleEvent) { bIsFirstIdleEvent = false; tiTenPerSecond.Start(100); if((NULL != iconTb) && (bShouldHide)) { bIsHidden = true; Show(false); } } pcIdle.endProcessing(); } event.Skip(); $? "- DkClockFrame::OnIdle" } void DkClockFrame::OnTimer(wxTimerEvent & event) { dk3_time_t newTime; int res; $? "+ DkClockFrame::OnTimer" if(pcTimer.canBeginProcessing()) { $? ". can begin processing" if(dk3sf_time(&newTime)) { $? ". time found" if(newTime > currentTime) { $? ". new second" currentTime = newTime; res = clockData.setTime(¤tTime); if(1 == res) { $? ". now in alert state" bHaveBuffer = true; bIsHidden = false; Show(true); Iconize(false); Maximize(true); Raise(); clv->SetMustUpdate(); clv->Refresh(); clv->Update(); } else { $? ". state unchanged" if((IsIconized()) || (bIsHidden)) { $? ". iconized" if(bHaveBuffer) { $? ". first time iconized" bHaveBuffer = false; clv->releaseBuffer(); } } else { $? ". not iconized" bHaveBuffer = true; $? ". refresh view" clv->SetMustUpdate(); clv->Refresh(); clv->Update(); } } } } pcTimer.endProcessing(); } $? "- DkClockFrame::OnTimer" } void DkClockFrame::OnHide(wxCommandEvent & event) { $? "+ DkClockFrame::OnHide" if(miOptionsHide->IsChecked()) { bShouldHide = true; bIsHidden = true; Show(false); } else { bShouldHide = false; } $? "- DkClockFrame::OnHide" } void DkClockFrame::OnColourNormal(wxCommandEvent & event) { wxColourData wxcd; wxcd.SetColour( wxColour( clv->getNormalRed(), clv->getNormalGreen(), clv->getNormalBlue() ) ); wxColourDialog dlg(this, &wxcd); pHelper->setRelatedPosition(this, &dlg, &cdx, &cdy); if(dlg.ShowModal() == wxID_OK) { wxColour c = dlg.GetColourData().GetColour(); clv->setNormal(c.Red(), c.Green(), c.Blue()); saveSettings(); } dlg.GetPosition(&cdx, &cdy); } void DkClockFrame::OnColourAlert(wxCommandEvent & event) { wxColourData wxcd; wxcd.SetColour( wxColour( clv->getAlertRed(), clv->getAlertGreen(), clv->getAlertBlue() ) ); wxColourDialog dlg(this, &wxcd); pHelper->setRelatedPosition(this, &dlg, &cdx, &cdy); if(dlg.ShowModal() == wxID_OK) { wxColour c = dlg.GetColourData().GetColour(); clv->setAlert(c.Red(), c.Green(), c.Blue()); saveSettings(); } dlg.GetPosition(&cdx, &cdy); } void DkClockFrame::SetHidden(bool b) { $? "+ DkClockFrame::SetHidden %d", ((b) ? 1 : 0) bIsHidden = b; $? "- DkClockFrame::SetHidden" } void DkClockFrame::OnIconize(wxIconizeEvent & event) { if(event.Iconized()) { if(bShouldHide) { if(NULL != iconTb) { bIsHidden = true; Show(false); } } } }