%% options copyright owner = Dirk Krause copyright year = 2011 license = bsd %% wx-gui # . align = left top type = frame menu bar = mbMain contents = mainSizer tool bar = tbMain icon = dkicon_bitmap status bar = 1 sTexts[67] [wxToolBar tbMain] contents = bDir contents = bOptions contents = bRun contents = bExit [wxToolBarToolBase bDir] text = sTexts[17] bitmap = xpm_choose_dir id = DkWxTrace_ChooseDirectory tip = sTexts[21] [wxToolBarToolBase bOptions] text = sTexts[18] bitmap = xpm_set_options id = DkWxTrace_SetOptions tip = sTexts[22] [wxToolBarToolBase bRun] text = sTexts[19] bitmap = xpm_run_conversion id = DkWxTrace_Run tip = sTexts[23] [wxToolBarToolBase bExit] text = sTexts[20] bitmap = xpm_exit_program id = DkWxTrace_Quit tip = sTexts[24] [wxMenuBar mbMain] contents = menuFile contents = menuHelp [wxMenu menuFile] contents = miFileDir contents = miFileOptions contents = miFileRun contents = miFileExit text = sTexts[3] [wxMenu menuHelp] contents = miHelpContents contents = miHelpAbout text = sTexts[4] [wxMenuItem miFileDir] id = DkWxTrace_ChooseDirectory text = sTexts[12] tip = sTexts[13] [wxMenuItem miFileOptions] id = DkWxTrace_SetOptions text = sTexts[14] tip = sTexts[15] [wxMenuItem miFileRun] id = DkWxTrace_Run text = sTexts[64] tip = sTexts[65] [wxMenuItem miFileExit] id = DkWxTrace_Quit text = sTexts[5] tip = sTexts[7] [wxMenuItem miHelpContents] id = DkWxTrace_Help_Contents text = sTexts[9] tip = sTexts[10] [wxMenuItem miHelpAbout] id = DkWxTrace_About text = sTexts[6] tip = sTexts[8] [wxBoxSizer mainSizer] direction = horizontal contents = $space(10) contents = verticalSizer contents = $space(10) [wxBoxSizer verticalSizer] direction = vertical grow = yes proportion = 1 contents = $space(10) contents = contentsSizer left contents = $space(10) contents = tLogmessages left top contents = $space(10) contents = tStatus left contents = $space(10) [wxGridBagSizer contentsSizer] grid = 5 5 contents = lDirectory 0 0 1 1 right contents = tDirectory . 1 1 1 # contents = lLines +1 0 1 1 right # contents = tLines . 1 1 1 # contents = lDebug +1 0 1 1 right # contents = tDebug . 1 1 1 [wxStaticText lDirectory] text = sTexts[11] [wxStaticText tDirectory] text = ((sDirectory) ? sDirectory : sTexts[25]) [wxTextCtrl tLogmessages] grow = yes proportion = 1 size = 200 30 text style = readonly multiline left no-wrap selection [wxStaticText tStatus] text = sTexts[67] %% header start #include "dkct.h" %% class start /** Top level frame of the dkwxtrace program. */ class DkWxTraceFrame : public DkWxFrame { private: /** Event table. */ DECLARE_EVENT_TABLE() protected: /** Localized texts. */ wxChar const * const *sTexts; /** Localized dkChar texts. */ dkChar const * const *msg; /** Conversion options. */ DKCT_OPTION_SET options; /** Communication object for main thread and worker thread. */ DkWxCommunicator *pComm; /** Current directory. */ wxChar const *sDirectory; /** Color: Black. */ wxColour *cBlack; /** Color: Dark green. */ wxColour *cGreen; /** Color: Dark red. */ wxColour *cRed; /** Timestamp to close the application. */ dk3_time_t timeClose; /** Directory dialog x position. */ int ddx; /** Directory dialog y position. */ int ddy; /** Options dialog x position. */ int odx; /** Options dialog y position. */ int ody; /** Must save the current settings. */ bool bSaveSettings; /** Must save the current directory. */ bool bSaveDirectory; /** Timestamp for closing the application is scheduled. */ bool bCloseScheduled; /** GUI elements are active, not automatic closing. */ bool bGuiActive; /** The run was started automatically. */ bool bAutoStartRequested; %% class end public: /** Constructor. @param applicationName Application name. @param messageTexts Localized texts. @param ms Message texts as dkChar strings. @param applicationHelper Application helper. @param wxid Window ID. @param hc Help controller. @param argc Number of command line arguments. @param argv Command line arguments array. */ DkWxTraceFrame( wxChar const *applicationName, wxChar const * const *messageTexts, dkChar const * const *ms, DkWxAppHelper *applicationHelper, int wxid, DkWxHelpController *hc, int argc, wxChar **argv ); /** Destructor. */ ~DkWxTraceFrame(); /** Find index for splint special character. @param c Character to find index for. @return Index in range 0 to 17. */ int findSplintCharacterIndex(char c); /** Check whether we can close the window. @param isLast Flag: Last top level window. */ bool canClose(bool isLast); /** Menu event handler for File / Quit. @param event Event to process. */ void OnQuit(wxCommandEvent& event); /** Menu event handler for Help / About. */ void OnAbout(wxCommandEvent& event); /** Menu event handler for Help / Contents. */ void OnHelpContents(wxCommandEvent& event); /** Menu event handler for File / Directory. */ void OnChooseDirectory(wxCommandEvent& event); /** Menu event handler for File / Options. */ void OnSetOptions(wxCommandEvent& event); /** Menu event handler for File / Run. */ void OnRunConversion(wxCommandEvent& event); /** Handler for idle events. */ void OnIdle(wxIdleEvent & event); /** Run a conversion. */ void runConversion(); /** Check whether GUI elements are active. @return True if GUI elements can be used, false otherwise (autostart job running). */ bool isGuiActive(); protected: /** Retrieve stored preferences. */ void getData(void); }; %% header end %% module start #include "dkwxtrace.h" /* Icons and bitmaps */ #include "dkicon.xpm" #include "choose-dir.xpm" #include "exit-program.xpm" #include "run-conversion.xpm" #include "set-options.xpm" $!trace-include /** Version for the about dialog (program name). */ static wxChar const dkwxct_version[] = { wxT("wxdkct (part of dkt-") }; /** Version number for the about dialog (version number). */ static wxChar const dkwxct_versnumber[] = { DKT_WXCHAR_VERSION }; /** Version number for the about dialog (end). */ static wxChar const dkwxct_versend[] = { wxT(")") }; static wxChar const * const dkwxct_settings_names[] = { $!string-table macro=wxT # # 0: Make mode # wxdkct.make # # 1: Show line numbers # wxdkct.line-numbers # # 2: Debug (0=no 1=file 2=stdout) # wxdkct.debug # # 3: Include timestamp # wxdkct.debug.timestamp # # 4: Use trace keyword # wxdkct.debug.keyword # # 5: Wide character support. # wxdkct.debug.wide # # 6: Use splint # wxdkct.splint.use # # 7: Current string index # wxdkct.splint.selected $!end }; static wxChar const * dkwxct_string_settings_names[] = { $!string-table macro=wxT # # 0: Current directory # wxdkct.directory $!end }; /** Event table for the DkWxTraceFrame class. */ BEGIN_EVENT_TABLE(DkWxTraceFrame, wxFrame) EVT_MENU(DkWxTrace_Quit, DkWxTraceFrame::OnQuit) EVT_MENU(DkWxTrace_Help_Contents, DkWxTraceFrame::OnHelpContents) EVT_MENU(DkWxTrace_About, DkWxTraceFrame::OnAbout) EVT_MENU(DkWxTrace_ChooseDirectory, DkWxTraceFrame::OnChooseDirectory) EVT_MENU(DkWxTrace_SetOptions, DkWxTraceFrame::OnSetOptions) EVT_MENU(DkWxTrace_Run, DkWxTraceFrame::OnRunConversion) EVT_IDLE(DkWxTraceFrame::OnIdle) END_EVENT_TABLE() static const wxCmdLineEntryDesc wxdkctframe_cmd_line_desc[] = { { wxCMD_LINE_SWITCH, wxT_2("r"), wxT_2("run"), wxT_2("Run conversion") }, { wxCMD_LINE_SWITCH, wxT_2("R"), wxT_2("reset"), wxT_2("Reset all options") }, { wxCMD_LINE_SWITCH, wxT_2("m"), wxT_2("make"), wxT_2("Run in make mode") }, { wxCMD_LINE_SWITCH, wxT_2("l"), wxT_2("line-numbers"), wxT_2("Run conversion") }, { wxCMD_LINE_OPTION, wxT_2("b"), wxT_2("box"), wxT_2("Box width"), wxCMD_LINE_VAL_NUMBER }, { wxCMD_LINE_SWITCH, wxT_2("d"), wxT_2("debug"), wxT_2("Create debug output") }, { wxCMD_LINE_SWITCH, wxT_2("s"), wxT_2("debug-stdout"), wxT_2("Send debug output to standard output") }, { wxCMD_LINE_SWITCH, wxT_2("t"), wxT_2("time"), wxT_2("Include timestamps in debug output") }, { wxCMD_LINE_SWITCH, wxT_2("k"), wxT_2("keyword"), wxT_2("Include \"trace\" keyword in debug output") }, { wxCMD_LINE_SWITCH, wxT_2("w"), wxT_2("wide"), wxT_2("Allow wide character debug output") }, { wxCMD_LINE_PARAM, NULL, NULL, wxT_2("input file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE } }; %% constructor start DkWxTraceFrame::DkWxTraceFrame( wxChar const *applicationName, wxChar const * const *messageTexts, dkChar const * const *m, DkWxAppHelper *applicationHelper, int wxid, DkWxHelpController *hc, int argc, wxChar **argv ) : DkWxFrame(applicationName, applicationHelper, hc, wxid) { $? "+ constructor" ddx = -1; ddy = -1; odx = -1; ody = -1; bAutoStartRequested = false; pComm = NULL; cBlack = NULL; cGreen = NULL; cRed = NULL; sDirectory = NULL; sTexts = messageTexts; msg = m; bSaveSettings = true; bSaveDirectory = true; bCloseScheduled = false; bGuiActive = true; #if defined(__WXMSW__) wxIcon dkicon_bitmap(wxT("aaaaa")); /* from resource file */ #else wxIcon dkicon_bitmap(xpm_dkicon); /* from included xpm */ #endif options.deb = 0; options.deben = 1; options.lnn = 0; options.mak = 0; options.sty = 0; options.bw = 75; options.tkw = 0; options.ts = 0; options.win = 0; options.tip = 0; timeClose = (dk3_time_t)0UL; getData(); %% constructor end $? ". GUI finished" pComm = new DkWxCommunicator( applicationHelper->getWxEncoding(), applicationHelper->getDkEncoding() ); cBlack = new wxColour(0x00, 0x00, 0x00); cGreen = new wxColour(0x00, 0x7F, 0x00); cRed = new wxColour(0x7f, 0x00, 0x00); if(argc > 1) { int res = -1; long l = 0L; wxString cmdfn; wxCmdLineParser parser(wxdkctframe_cmd_line_desc, argc, argv); bSaveSettings = false; bSaveDirectory = false; { wxLogNull log; res = parser.Parse(false); } if(parser.Found(wxT("r"))) { if(pComm) { pComm->autostartEnable(true); bGuiActive = false; bAutoStartRequested = true; } } if(parser.Found(wxT("R"))) { options.deb = 0; options.deben = 1; options.lnn = 0; options.mak = 0; options.sty = 0; options.bw = 75; options.tkw = 0; options.ts = 0; options.win = 0; options.tip = 0; } if(parser.Found(wxT("d"))) { options.deb = 1; options.deben = 1; } if(parser.Found(wxT("s"))) { options.deb = 2; options.deben = 1; } if(parser.Found(wxT("l"))) { options.lnn = 1; } if(parser.Found(wxT("m"))) { options.mak = 1; } if(parser.Found(wxT("b"), &l)) { if((l > 20L) && (l < 128L)) { options.bw = (int)l; } } if(options.deb) { if(parser.Found(wxT("t"))) { options.ts = 1; } if(parser.Found(wxT("k"))) { options.tkw = 1; } if(parser.Found(wxT("w"))) { options.win = 1; } } if(parser.GetParamCount() > 0) { $? ". parameter" wxChar const *nd; cmdfn = parser.GetParam(0); $? ". parameter=\"%ls\"", cmdfn.c_str() wxFileName fn(cmdfn); fn.Normalize( wxPATH_NORM_LONG | wxPATH_NORM_DOTS | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE ); cmdfn = fn.GetFullPath(); $? ". full path = \"%ls\"", cmdfn.c_str() if(wxFileName::DirExists(cmdfn)) { $? ". is directory" nd = cmdfn.c_str(); if(nd) { $? ". text found" nd = dk3wxs_dup_app(nd, applicationHelper->getApp()); if(nd) { $? ". allocation ok" dk3_release(sDirectory); sDirectory = nd; if(tDirectory) { tDirectory->SetLabel(sDirectory); } } else { $? "! allocation" pComm->autostartEnable(false); bGuiActive = true; if(bAutoStartRequested) { tStatus->SetLabel(sTexts[71]); if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); } bAutoStartRequested = false; } } } else { $? "! bug" pComm->autostartEnable(false); bGuiActive = true; if(bAutoStartRequested) { tStatus->SetLabel(sTexts[71]); if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); } bAutoStartRequested = false; } } } else { $? "! not a directory" pComm->autostartEnable(false); bGuiActive = true; if(bAutoStartRequested) { tStatus->SetLabel(sTexts[71]); if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); } bAutoStartRequested = false; } } } else { pComm->autostartEnable(false); bGuiActive = true; if(bAutoStartRequested) { tStatus->SetLabel(sTexts[71]); if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); } bAutoStartRequested = false; } } } restorePosition(); $? "- constructor" } %% module end DkWxTraceFrame::~DkWxTraceFrame() { dk3_cpp_release(pComm); dk3_cpp_release(cBlack); dk3_cpp_release(cGreen); dk3_cpp_release(cRed); } void DkWxTraceFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { if(isGuiActive()) { bCloseScheduled = true; Close(); } } void DkWxTraceFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event)) { $? "+ OnHelpContents" openHelp(); $? "- OnHelpContents" } void DkWxTraceFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { $? "+ OnAbout" if(isGuiActive()) { wxString sVersion(dkwxct_version); sVersion.Append(dkwxct_versnumber); sVersion.Append(dkwxct_versend); sVersion.Append(sTexts[73]); sVersion.Append(wxT("Copyright (c) 2013 Dirk Krause")); sVersion.Append(sTexts[73]); sVersion.Append(sTexts[73]); sVersion.Append(sTexts[74]); sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.")); sVersion.Append(sTexts[73]); sVersion.Append(sTexts[73]); sVersion.Append(sTexts[75]); sVersion.Append(wxT("http://dktools.sourceforge.net\n")); sVersion.Append(wxT("http://www.wxwidgets.org\n")); sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n")); sVersion.Append(wxT("http://www.ijg.org\n")); sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n")); sVersion.Append(wxT("http://www.zlib.net\n")); wxMessageBox(sVersion, sTexts[66]); } $? "- OnAbout" } void DkWxTraceFrame::OnChooseDirectory(wxCommandEvent& WXUNUSED(event)) { wxChar const *ptr; wxChar const *np; $? "+ OnChooseDirectory" if(isGuiActive()) { wxDirDialog dd( this, sTexts[53], ((sDirectory) ? sDirectory : wxEmptyString), (wxDD_DIR_MUST_EXIST | wxDD_CHANGE_DIR) ); pHelper->setRelatedPosition(this, &dd, &ddx, &ddy); if(dd.ShowModal() == wxID_OK) { wxString path = dd.GetPath(); ptr = path.c_str(); if(ptr) { np = dk3wxs_dup_app(ptr, pHelper->getApp()); if(np) { dk3_release(sDirectory); sDirectory = np; if(tDirectory) { tDirectory->SetLabel(sDirectory); Refresh(); Update(); } } } } dd.GetPosition(&ddx, &ddy); } $? "- OnChooseDirectory" } void DkWxTraceFrame::OnSetOptions(wxCommandEvent& WXUNUSED(event)) { $? "+ OnSetOptions" if(isGuiActive()) { DkWxTraceOptionsDialog dlg( (DkWxTraceFrame *)this, sTexts[30], sTexts, &options ); dlg.dataIn(); pHelper->setRelatedPosition(this, &dlg, &odx, &ody); dlg.ShowModal(); dlg.GetPosition(&odx, &ody); } $? "- OnSetOptions" } void DkWxTraceFrame::runConversion() { DkWxProgressDialog *pd = NULL; DkWxTraceThread *pt = NULL; int ok = 0; $? "+ OnRunConversion" /* SetStatusText(sTexts[67]); */ tStatus->SetLabel(sTexts[67]); if(cBlack) { tStatus->SetForegroundColour(*cBlack); } if(pComm) { pComm->prepareRun(); pd = new DkWxProgressDialog( (DkWxFrame *)this, pComm, tLogmessages, sTexts[48], /* title */ sTexts[49], /* file name */ sTexts[50], /* button text */ sTexts[51], /* button tool tip */ sTexts[52] /* wait text */ ); if(pd) { pt = new DkWxTraceThread( pComm, sTexts, msg, sDirectory, pHelper, &options, pHelper->getWxEncoding(), pHelper->getDkEncoding() ); if(pt) { if(pt->Create() == wxTHREAD_NO_ERROR) { pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY); #if 0 if(iRunState == DK3_WX_RUN_STATE_START) { iRunState = DK3_WX_RUN_STATE_RUNNING; } #endif pt->Run(); pd->chooseModalPosition(); pd->ShowModal(); ok = 1; if(pComm->getLogLevel() <= DK3_LL_WARNING) { bGuiActive = true; } } else { delete(pt); /* ##### ERROR: Failed to create new thread! */ } } else { /* ##### ERROR: Failed to construct new thread! */ } pd->Destroy(); } else { /* ##### ERROR: Failed to construct new progress dialog! */ } if(tLogmessages) { pComm->getText(tLogmessages); } if(pComm->getLogLevel() > DK3_LL_WARNING) { /* SetStatusText(sTexts[68]); */ if(bAutoStartRequested) { tStatus->SetLabel(sTexts[72]); } else { tStatus->SetLabel(sTexts[68]); } if((cBlack) && (cGreen)) { tStatus->SetForegroundColour(*cGreen); } } else { if(pComm->getLogLevel() < DK3_LL_WARNING) { /* SetStatusText(sTexts[70]); */ tStatus->SetLabel(sTexts[70]); if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); } } else { /* SetStatusText(sTexts[69]); */ tStatus->SetLabel(sTexts[69]); if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); } } } Refresh(); Update(); } $? "- OnRunConversion" } void DkWxTraceFrame::OnRunConversion(wxCommandEvent& WXUNUSED(event)) { if(isGuiActive()) { runConversion(); } } bool DkWxTraceFrame::canClose(bool isLast) { bool back = true; int values_to_save[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if(isLast) { if(bSaveSettings) { values_to_save[0] = options.mak; values_to_save[1] = options.lnn; values_to_save[2] = options.deb; values_to_save[3] = options.ts; values_to_save[4] = options.tkw; values_to_save[5] = options.win; values_to_save[6] = (('\0' != options.spls) ? 1 : 0); values_to_save[7] = findSplintCharacterIndex(options.spls); pHelper->saveMultipleInts(dkwxct_settings_names, values_to_save); } if(bSaveDirectory) { if(sDirectory) { pHelper->saveString(dkwxct_string_settings_names[0], sDirectory); } } } dk3_cpp_release(pComm); dk3_release(sDirectory); return back; } void DkWxTraceFrame::getData() { int values_to_save[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; pHelper->retrieveMultipleInts(dkwxct_settings_names, values_to_save); options.mak = values_to_save[0]; options.lnn = values_to_save[1]; options.deb = values_to_save[2]; options.ts = values_to_save[3]; options.tkw = values_to_save[4]; options.win = values_to_save[5]; options.spls = '\0'; if ((values_to_save[6]) && ((0 <= values_to_save[7]) && (18 > values_to_save[7]))) { options.spls = (char)((sTexts[76 + values_to_save[7]])[0]); } sDirectory = pHelper->retrieveString(dkwxct_string_settings_names[0]); } void DkWxTraceFrame::OnIdle(wxIdleEvent & event) { dk3_time_t ct; $? "+ DkWxTraceFrame::OnIdle" if(!bCloseScheduled) { if(pComm) { if(pComm->autostartCanRun()) { $? ". start" runConversion(); } else { if(pComm->autostartIsFinished()) { $? ". close" if(!(timeClose)) { if(pComm->getLogLevel() > DK3_LL_WARNING) { dk3sf_time(&timeClose); event.RequestMore(); tStatus->SetLabel(sTexts[72]); if((cGreen) && (cBlack)) { tStatus->SetForegroundColour(*cGreen); } Refresh(); Update(); } } } } } if(timeClose) { dk3sf_time(&ct); if(ct > (timeClose + (dk3_time_t)1UL)) { timeClose = (dk3_time_t)0UL; bCloseScheduled = true; Show(false); Close(); } else { event.RequestMore(); } } } $? "- DkWxTraceFrame::OnIdle" event.Skip(); } bool DkWxTraceFrame::isGuiActive() { bool back = false; if(!(bCloseScheduled)) { back = bGuiActive; } return back; } int DkWxTraceFrame::findSplintCharacterIndex(char c) { int back = 0; int i; /* Traverse 0 to 17 */ bool found = false; /* Flag: Character was found */ for (i = 0; ((i < 18) && (!(found))); i++) { if (c == (sTexts[76 + i])[0]) { found = true; back = i; } } return back; }