diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/WxpqdicFrame.wxc |
Initial commit
Diffstat (limited to 'support/dktools/WxpqdicFrame.wxc')
-rw-r--r-- | support/dktools/WxpqdicFrame.wxc | 1540 |
1 files changed, 1540 insertions, 0 deletions
diff --git a/support/dktools/WxpqdicFrame.wxc b/support/dktools/WxpqdicFrame.wxc new file mode 100644 index 0000000000..9b28dae9ab --- /dev/null +++ b/support/dktools/WxpqdicFrame.wxc @@ -0,0 +1,1540 @@ +%% options + +copyright owner = Dirk Krause + +copyright year = 2016-xxxx + +license = bsd + + + +%% wx-gui + +type = frame +contents = mainSizer +icon = wxpqdic_icon +status bar = 1 sTexts[8] +menu bar = mbMain +tool bar = tbMain + +[wxMenuBar mbMain] +contents = menuFile +contents = menuView +contents = menuHelp + +[wxMenu menuFile] +text = sTexts[0] +contents = miFileExit + +[wxMenuItem miFileExit] +id = WxpqdicFrame_Quit +text = sTexts[1] +tip = sTexts[2] + +[wxMenu menuView] +text = sTexts[22] +contents = miViewUpdate + +[wxMenuItem miViewUpdate] +id = WxpqdicFrame_View_Update +text = sTexts[23] +tip = sTexts[24] + +[wxMenu menuHelp] +text = sTexts[3] +contents = miHelpAbout +contents = miHelpContents + +[wxMenuItem miHelpAbout] +id = WxpqdicFrame_Help_About +text = sTexts[4] +tip = sTexts[5] + +[wxMenuItem miHelpContents] +id = WxpqdicFrame_Help_Contents +text = sTexts[6] +tip = sTexts[7] + +[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 +contents = $space(10) + +[wxGridBagSizer contentsSizer] +grid = 2 2 +contents = lLimit 0 0 1 1 right +contents = tLimit . +1 1 1 +contents = lUsed +1 0 1 1 right +contents = tUsed . +1 1 1 +contents = $space(5) +1 0 1 1 +contents = lAccount +1 0 1 1 right +contents = tAccount . +1 1 1 +contents = $space(5) +1 0 1 1 +contents = lAllowed +1 0 1 1 right +contents = tAllowed . +1 1 1 +contents = $space(5) +1 0 1 1 +contents = lStatus +1 0 1 2 + +[wxStaticText lLimit] +text = sTexts[13] + +[wxStaticText tLimit] +text = sTexts[14] + +[wxStaticText lUsed] +text = sTexts[15] + +[wxStaticText tUsed] +text = sTexts[27] + +[wxStaticText lAccount] +text = sTexts[17] + +[wxStaticText tAccount] +text = sTexts[16] + +[wxStaticText lAllowed] +text = sTexts[18] + +[wxStaticText tAllowed] +text = sTexts[27] + +[wxStaticText lStatus] +text = sTexts[21] + + +[wxToolBar tbMain] +contents = bUpdate +contents = bExit + +[wxToolBarToolBase bUpdate] +text = sTexts[25] +tip = sTexts[24] +bitmap = xpm_run_conversion +id = WxpqdicFrame_View_Update + +[wxToolBarToolBase bExit] +text = sTexts[26] +tip = sTexts[2] +bitmap = xpm_exit_program +id = WxpqdicFrame_Quit + + +%% header start + + + +%% class start +class WxpqdicFrame : public Dk4WxFrame +{ + private: + + /** Event table for frame. + */ + DECLARE_EVENT_TABLE() + + protected: + + /** Buffer for response processing. + */ + char bResponse[32 * sizeof(dk4_um_t)]; + + /** Address pair, 0=remote, 1=local. + */ + dk4_sockaddr_storage_t aAddresses[2]; + + /** Remote host name as wxChar string. + */ + wxString sHostname; + + /** Queue name as wxChar string. + */ + wxString sQueuename; + + /** User name as wxChar string. + */ + wxString sUsername; + + /** Localized texts. + */ + wxChar const * const *sTexts; + + /** Non-localized texts. + */ + wxChar const * const *sNlWx; + + /** Non-localized texts. + */ + dkChar const * const *sNlDk; + + /** Copy of the command line arguments poiner. + */ + wxChar **copyArgv; + + /* __CHANGE__ 011: Add further member variables. + */ + + /** Critical section to protect socket and timer. + */ + wxCriticalSection csProtect; + + /** Black color for normal status text. + */ + wxColour cBlack; + + /** Red color for not allowed to print. + */ + wxColour cRed; + + /** Green color for allowed to print. + */ + wxColour cGreen; + + /** Timer for periodic updates. + */ + wxTimer timer; + + /** Error report from socket subsystem initialization. + */ + dk4_er_t sockerr; + + /** Host name to query. + */ + dkChar *pHostname; + + /** Print queue to check. + */ + char *pQueuename; + + /** User name to use in check. + */ + char *pUsername; + + /** Request to send to server. + */ + char *pRequest; + + /** Previous limit value. + */ + dk4_um_t uLimit; + + /** Previous used value. + */ + dk4_um_t uUsed; + + /** Previous account value. + */ + dk4_um_t uAccount; + + /** Length of request. + */ + size_t szRequest; + + /** Size of response buffer. + */ + size_t szResponse; + + /** Time last request was sended. + */ + dk4_time_t tRequestSended; + + /** Update interval in seconds. + */ + long lUpdateInterval; + + /** Timeout interval before complaining about missing response. + */ + long lWaitResponse; + + /** Previous summary value. + */ + int iSummary; + + /** Number of command line arguments. + */ + int copyArgc; + + /** Current state. + */ + int iState; + + /** Socket for data exchange + */ + dk4_socket_t sock; + + /** Port number on remote host. + */ + unsigned short usPortnumber; + + /** Local port number to use. + */ + unsigned short usLocalPort; + + /** Flag: Socket subsystem initialized. + */ + bool bSockInit; + + /** Flag: Remote host uses UTF-8 encoding (user name and queue name). + */ + bool bIsUtf8; + + /** Flag: This idle event is the first one (no idle events before). + */ + bool bFirstIdle; + + /** Flag: All components initialized completely. + */ + bool bIsInitialized; + + /** Flag: This is the first response. + */ + bool bFirstResponse; + +%% class end + + 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. + @param bSocketsInitialized Flag: Socket subsys initialized. + @param psockerr Error report from socket initialization. + */ + WxpqdicFrame( + int wxid, + Dk4WxApplicationHelper *applicationHelper, + Dk4WxHelpController *hc, + int argc, + wxChar **argv, + wxChar const * const *localizedTexts, + wxChar const * const *nlWx, + dkChar const * const *nlDk, + bool bSocketsInitialized, + dk4_er_t *psockerr + ); + + /** Destructor. + */ + ~WxpqdicFrame(); + + /** Check whether we can close the window. + @param isLast Flag: Last main window to close. + */ + bool + CanClose(bool isFinal); + + /** Handler for File/Exit. + @param event Event to process. + */ + void + OnQuit(wxCommandEvent & event); + + /** Handler for File/Update. + @param event Event to process. + */ + void + OnRun(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); + + /* __CHANGE__ 008: Remove OnIdle if no idle processing required. + */ + /** Handler for idle events. + */ + void + OnIdle(wxIdleEvent & event); + + /* __CHANGE__ 017: Event handlers for further events. + */ + + /** Handler for timer event. + @param event Timer event to process. + */ + void + OnTimer(wxTimerEvent & event); + + + /* __CHANGE__ 014: Add further methods. + */ + + private: + + /** Attempt to configure. + @param perrc Address of error code variable. + @return True if configuration failed and the application should + exit, false on success. + */ + bool + ConfigureAndCheckNeedToClose(int *perrc); + + /** Attempt to receive data, send request again if interval is over. + @return True if the windows requires an update, false otherwise. + */ + bool + DataExchangeWithServer(void); + + bool + RetrieveResponse(void); + + bool + ProcessResponse(bool & found); + + bool + SendRequest(bool force = false); + +}; + +%% header end + +%% module start + +#include "wxpqdic.h" +#include "dk4user.h" +#include "dk4enc.h" +#include "dk4strd.h" +#include "dk4rec.h" +#include "dk4str8.h" +#include "dk4strx.h" +#include "dk4recwx.h" +#include "dk4maasz.h" +#include "dk4mai8ddu.h" +#include "dk4mai8dii.h" +#include "dk4mao8d.h" +#include "dk4maowd.h" +#include "dk4numco.h" + + +#include "exit-program.xpm" +#include "run-conversion.xpm" + +#include "dk4verswx.h" + +#if !defined(__WXMSW__) +#include "dkicon.xpm" +#endif + + + +$!trace-include + + + +/* __CHANGE__ 017: Add further events. */ +/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */ +BEGIN_EVENT_TABLE(WxpqdicFrame, wxFrame) + EVT_MENU(WxpqdicFrame_View_Update, WxpqdicFrame::OnRun) + EVT_MENU(WxpqdicFrame_Quit, WxpqdicFrame::OnQuit) + EVT_MENU(WxpqdicFrame_Help_About, WxpqdicFrame::OnAbout) + EVT_MENU(WxpqdicFrame_Help_Contents, WxpqdicFrame::OnHelpContents) + EVT_TIMER(WxpqdicFrame_Timer, WxpqdicFrame::OnTimer) + EVT_IDLE(WxpqdicFrame::OnIdle) +END_EVENT_TABLE() + + + +static const wxChar versionNumber[] = { DKT_VERSION_WX }; + + + +static const wxCmdLineEntryDesc wxpqdic_cmd_line_entries[] = { + { + wxCMD_LINE_OPTION, + wxT_2("h"), + wxT_2("host"), + wxT_2("Host to connect to."), + wxCMD_LINE_VAL_STRING, + 0 + }, + { + wxCMD_LINE_OPTION, + wxT_2("p"), + wxT_2("port"), + wxT_2("Port number to connect to."), + wxCMD_LINE_VAL_NUMBER, + 0 + }, + { + wxCMD_LINE_OPTION, + wxT_2("l"), + wxT_2("local-port"), + wxT_2("Local port number to use."), + wxCMD_LINE_VAL_NUMBER, + 0 + }, + { + wxCMD_LINE_OPTION, + wxT_2("q"), + wxT_2("queue"), + wxT_2("Queue name to check."), + wxCMD_LINE_VAL_STRING, + 0 + }, + { + wxCMD_LINE_OPTION, + wxT_2("u"), + wxT_2("user"), + wxT_2("User name to check."), + wxCMD_LINE_VAL_STRING, + 0 + }, + { + wxCMD_LINE_OPTION, + wxT_2("i"), + wxT_2("interval"), + wxT_2("Time interval for automatic update."), + wxCMD_LINE_VAL_NUMBER, + 0 + }, + { + wxCMD_LINE_OPTION, + wxT_2("a"), + wxT_2("ascii"), + wxT_2("Remote host uses ASCII encoding, not UTF-8."), + wxCMD_LINE_VAL_NONE, + 0 + }, + { wxCMD_LINE_NONE } +}; + + + +/** Key names for preferences. +*/ +static const wxChar * const wxpqdic_pref_key_names[] = { +$!string-table macro=wxT +printqd.host +printqd.port +printqd.queue +printqd.interval +printqd.local +printqd.encoding +$!end +}; + + + +/** Constant 8-bit strings, not localized. +*/ +static const char * const wxpqdic_kw[] = { +$!string-table +# +# 0 newline +# +\n +# +# 1 space +# + +# +# 2 keyword info +# +info +$!end +}; + + +%% constructor start +WxpqdicFrame::WxpqdicFrame( + int wxid, + Dk4WxApplicationHelper *applicationHelper, + Dk4WxHelpController *hc, + int argc, + wxChar **argv, + wxChar const * const *localizedTexts, + wxChar const * const *nlWx, + dkChar const * const *nlDk, + bool bSocketsInitialized, + dk4_er_t *psockerr +) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid), + sHostname(wxT("")), + sQueuename(wxT("")), + sUsername(wxT("")), + cBlack(0, 0, 0), + cRed(127, 0, 0), + cGreen(0, 127, 0), + timer(this, WxpqdicFrame_Timer) + +{ + /* __CHANGE__ 012: Add further local variables. + */ + + /* __CHANGE__ 012: Initialize further local variables. + */ + + sTexts = localizedTexts; + sNlWx = nlWx; + sNlDk = nlDk; +#if defined(__WXMSW__) + wxIcon wxpqdic_icon(sNlWx[4]); +#else + wxIcon wxpqdic_icon(xpm_dkicon); +#endif + + /* __CHANGE__ 011: Initialize further class members. + */ + bSockInit = bSocketsInitialized; + DK4_MEMCPY(&sockerr, psockerr, sizeof(dk4_er_t)); + pHostname = NULL; + pQueuename = NULL; + pUsername = NULL; + pRequest = NULL; + szRequest = (size_t)0UL; + lUpdateInterval = 30L; + lWaitResponse = 1L; + usPortnumber = 9100; + usLocalPort = 9100; + bIsUtf8 = true; + bFirstIdle = true; + bFirstResponse = true; + bIsInitialized = false; + copyArgc = argc; + copyArgv = argv; + sock = INVALID_SOCKET; + iState = WXPQDIC_STATE_OK; + tRequestSended = (dk4_time_t)0UL; + szResponse = sizeof(bResponse); + DK4_MEMRES(&(aAddresses[0]), (2*sizeof(dk4_sockaddr_storage_t))); + +%% constructor end + if(dkctGUILayoutOK) { + SetTitle(nlWx[0]); + } + + + /* __CHANGE__ 012: Release resources allocated by local variables. + */ +} + +%% module end + + + +WxpqdicFrame::~WxpqdicFrame() +{ + + /* __CHANGE__ 011: Release resources allocated by further class members. + */ +} + + + +bool +WxpqdicFrame::CanClose(bool isLast) +{ + bool back = true; + + return back; +} + + +void +WxpqdicFrame::OnQuit(wxCommandEvent & event) +{ + { + wxCriticalSectionLocker lockCsProtect(csProtect); + if (bIsInitialized) { + timer.Stop(); + bIsInitialized = false; + } + } + if (INVALID_SOCKET != sock) { + dk4socket_close(sock, NULL); + sock = INVALID_SOCKET; + } + dk4mem_release(pUsername); + dk4mem_release(pQueuename); + dk4mem_release(pHostname); + dk4mem_release(pRequest); + Show(false); + /* !!!!! TODO: Release resources */ + Close(); +} + + + +void +WxpqdicFrame::OnAbout(wxCommandEvent & event) +{ + wxString text(wxT("")); + wxString title(wxT("")); + + /* Construct message text. */ + text.Append(sNlWx[0]); + text.Append(sNlWx[7]); +#if 0 + text.Append(sNlWx[1]); +#endif + text.Append(versionNumber); + 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); + +} + + + +void +WxpqdicFrame::OnHelpContents(wxCommandEvent & event) +{ + DisplayContents(); +} + +/* __CHANGE__ 017: Event handlers for further events. +*/ + +/* __CHANGE__ 014: Implementation of further methods. +*/ + + +bool +WxpqdicFrame::ConfigureAndCheckNeedToClose(int *perrc) +{ + + dkChar buf[1024]; + char c8b[1024]; + dk4_er_t er; + wxChar *pv[] = { NULL, NULL, NULL, NULL, NULL, NULL }; + const wxChar *cptr; + const size_t szbuf = DK4_SIZEOF(buf,dkChar); + const size_t szc8b = sizeof(c8b); + long l = 0L; + int res = 0; + bool back = true; + + /* Retrieve some fallback values from preferences. + */ + pAppHelp->GetMultiple(wxpqdic_pref_key_names, pv, 6); + $? ". host = \"%!ws\"", TR_WXSTR(pv[0]) + $? ". port = \"%!ws\"", TR_WXSTR(pv[1]) + $? ". queue = \"%!ws\"", TR_WXSTR(pv[2]) + $? ". interval = \"%!ws\"", TR_WXSTR(pv[3]) + $? ". local = \"%!ws\"", TR_WXSTR(pv[4]) + $? ". encoding = \"%!ws\"", TR_WXSTR(pv[5]) + + /* Check command line arguments + */ + { + wxLogNull log; + wxCmdLineParser parser(wxpqdic_cmd_line_entries, copyArgc, copyArgv); + res = parser.Parse(false); + /* + Check overall parsing of arguments + */ + if (0 != res) { $? "! failed to parse cmd line args" + /* ERROR: Failed to parse command line arguments */ + *perrc = WXPQDIC_FRAME_ERROR_PARSE; + goto finished; + } + /* + Option -a means the remote host wants ASCII data. + */ + if (parser.Found(wxT_2("a"))) { + bIsUtf8 = false; + } else { + if (NULL != pv[5]) { + if (0 != dk4strx_casecmp(pv[5], sNlWx[16])) { + if (0 != dk4strx_casecmp(pv[5], sNlWx[17])) { + bIsUtf8 = false; + } + } + } + } + /* + Try to obtain host name from arguments or from preferences. + */ + dk4error_init(&er); + cptr = NULL; + if (parser.Found(wxT_2("h"), &sHostname)) { + cptr = sHostname.c_str(); + } + else { + cptr = pv[0]; + } + if (NULL != cptr) { + if (pAppHelp->StringToDk(buf, szbuf, cptr, &er)) { + pHostname = dk4str_dup(buf, NULL); + if (NULL == pHostname) { $? ". pHostname = \"%!ds\"", pHostname + /* ERROR: Memory */ + *perrc = WXPQDIC_FRAME_ERROR_MEMORY; + goto finished; + } + } else { + /* ERROR: Failed to convert string */ + *perrc = WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME; + goto finished; + } + } + if (NULL == pHostname) { + /* ERROR: Missing host name */ + *perrc = WXPQDIC_FRAME_ERROR_HOSTNAME; + goto finished; + } + /* + Queue name is required. + */ + cptr = NULL; + if (parser.Found(wxT_2("q"), &sQueuename)) { + cptr = sQueuename.c_str(); + } + else { + cptr = pv[2]; + } + if (NULL != cptr) { + res = dk4recwx_wxchar_to_char( + c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)), + cptr, pAppHelp->GetWxEncoding(), NULL + ); + if (0 != res) { + pQueuename = dk4str8_dup(c8b, NULL); + if (NULL == pQueuename) { $? ". pQueuename = \"%!8s\"", pQueuename + /* ERROR: Memory */ + *perrc = WXPQDIC_FRAME_ERROR_MEMORY; + goto finished; + } + } else { + /* ERROR: String conversion failed */ + *perrc = WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME; + goto finished; + } + } + else { + /* ERROR: Missing queue name */ + *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME; + goto finished; + } + if (NULL == pQueuename) { + /* ERROR: Missing queue name */ + *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME; + goto finished; + } + /* + Port number is optional. + */ + { + bool portnoFound = false; + l = 0L; + if (parser.Found(wxT_2("p"), &l)) { + portnoFound = true; + } + else { + if (NULL != pv[1]) { + wxString s(pv[1]); + if (s.ToLong(&l, 0)) { + portnoFound = true; + } + } + } + if (portnoFound) { + if ((long)(USHRT_MAX) < l) { + /* ERROR: Port number out of range */ + *perrc = WXPQDIC_FRAME_ERROR_PORT_OOR; + goto finished; + } + if (0L == l) { + /* ERROR: Illegal port number 0 */ + *perrc = WXPQDIC_FRAME_ERROR_PORT_ZERO; + goto finished; + } + usPortnumber = (unsigned short)l; + } + } + /* + Local port number is optional. + */ + { + bool portnoFound = false; + l = 0L; + if (parser.Found(wxT_2("l"), &l)) { + portnoFound = true; + } + else { + if (NULL != pv[4]) { + wxString s(pv[4]); + if (s.ToLong(&l, 0)) { + portnoFound = true; + } + } + } + if (portnoFound) { + if ((long)(USHRT_MAX) < l) { + /* ERROR: Port number out of range */ + *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_OOR; + goto finished; + } + if (0L == l) { + /* ERROR: Illegal port number 0 */ + *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO; + goto finished; + } + usLocalPort = (unsigned short)l; + } + } + /* + User name is optional, use current user by default. + */ + if (parser.Found(wxT_2("u"), &sUsername)) { + res = dk4recwx_wxchar_to_char( + c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)), + sUsername.c_str(), pAppHelp->GetWxEncoding(), NULL + ); + if (0 != res) { + pUsername = dk4str8_dup(c8b, NULL); + if (NULL == pUsername) { + /* ERROR: Memory */ + *perrc = WXPQDIC_FRAME_ERROR_MEMORY; + goto finished; + } + } + else { + /* ERROR: Failed to convert user name */ + *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME; + goto finished; + } + } + else { + res = dk4user_get_logname(buf, szbuf, 0, NULL); + if (0 != res) { + res = dk4recode_dk_to_any( + c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)), + buf, pAppHelp->GetDkEncoding(), NULL + ); + if (0 != res) { + pUsername = dk4str8_dup(c8b, NULL); + if (NULL == pUsername) { + /* ERROR: Memory */ + *perrc = WXPQDIC_FRAME_ERROR_MEMORY; + goto finished; + } + } + else { + /* ERROR: Failed to convert user name */ + *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME; + goto finished; + } + } else { + /* ERROR: User name not found! */ + *perrc = WXPQDIC_FRAME_ERROR_USERNAME; + goto finished; + } + } + if (NULL == pUsername) { + /* ERROR: No user name */ + *perrc = WXPQDIC_FRAME_ERROR_USERNAME; + goto finished; + } + /* + Interval length is optional. + */ + { + bool intervalFound = false; + l = 0L; + if (parser.Found(wxT_2("p"), &l)) { + intervalFound = true; + } + else { + if (NULL != pv[3]) { + wxString s(pv[3]); + if (s.ToLong(&l, 0)) { + intervalFound = true; + } + } + } + if (intervalFound) { + if (5L <= l) { + lUpdateInterval = l; + } else { + lUpdateInterval = 5L; + } + } + } + /* + Now build request + */ + dk4error_init(&er); + szRequest = strlen(wxpqdic_kw[2]); + szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pQueuename), &er); + szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pUsername), &er); + szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(wxpqdic_kw[2]), &er); + szRequest = dk4ma_size_t_add(szRequest, 4, &er); + if (DK4_E_NONE == er.ec) { + pRequest = dk4mem_new(char,szRequest,NULL); + if (NULL != pRequest) { + if (0 == dk4str8_cpy_s(pRequest, szRequest, wxpqdic_kw[2], NULL)) { + /* ERROR: BUG */ + *perrc = WXPQDIC_FRAME_ERROR_BUG; + goto finished; + } + if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) { + /* ERROR: BUG */ + *perrc = WXPQDIC_FRAME_ERROR_BUG; + goto finished; + } + if (0 == dk4str8_cat_s(pRequest, szRequest, pQueuename, NULL)) { + /* ERROR: BUG */ + *perrc = WXPQDIC_FRAME_ERROR_BUG; + goto finished; + } + if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) { + /* ERROR: BUG */ + *perrc = WXPQDIC_FRAME_ERROR_BUG; + goto finished; + } + if (0 == dk4str8_cat_s(pRequest, szRequest, pUsername, NULL)) { + /* ERROR: BUG */ + *perrc = WXPQDIC_FRAME_ERROR_BUG; + goto finished; + } + if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[0], NULL)) { + /* ERROR: BUG */ + *perrc = WXPQDIC_FRAME_ERROR_BUG; + goto finished; + } + szRequest = dk4str8_len(pRequest); + $? ". request = \"%s\"", TR_8STR(pRequest) + } else { + /* ERROR: Memory */ + *perrc = WXPQDIC_FRAME_ERROR_MEMORY; + goto finished; + } + } else { + /* ERROR: Numeric overflow in size calculation */ + *perrc = WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW; + goto finished; + } + /* + Create socket. + */ + sock = dk4socket_udp_client_for_host( + aAddresses, pHostname, usPortnumber, usLocalPort, 1, NULL + ); + if (INVALID_SOCKET == sock) { + *perrc = WXPQDIC_FRAME_ERROR_SOCKET; + goto finished; + } + + } + + $? ". successfully completed setup" + + tLimit->SetLabel(sTexts[27]); + tUsed->SetLabel(sTexts[27]); + tAccount->SetLabel(sTexts[27]); + + /* Finally indicate success. + */ + timer.Start(500); + bIsInitialized = true; + back = false; + + /* Clean up at end and return result. + */ + finished: + pAppHelp->ReleaseWxcharStringArray(pv, 6); + if (back) { + if (INVALID_SOCKET != sock) { + dk4socket_close(sock, NULL); + sock = INVALID_SOCKET; + } + dk4mem_release(pUsername); + dk4mem_release(pQueuename); + dk4mem_release(pHostname); + dk4mem_release(pRequest); + } + return back; +} + + + +void +WxpqdicFrame::OnIdle(wxIdleEvent & event) +{ + int errorCode = WXPQDIC_FRAME_ERROR_NONE; + bool mustClose = false; + $? "+ OnIdle" + /* __CHANGE__ + */ + { + wxCriticalSectionLocker lockCsProtect(csProtect); + if (bFirstIdle) { + bFirstIdle = false; + mustClose = ConfigureAndCheckNeedToClose(&errorCode); + } + } + if (mustClose) { $? "! error in setup, must close window" + const wxChar *ti; + const wxChar *tx; + ti = sTexts[58]; tx = sTexts[59]; + switch (errorCode) { + case WXPQDIC_FRAME_ERROR_PARSE : { + ti = sTexts[30]; tx = sTexts[31]; + } break; + case WXPQDIC_FRAME_ERROR_MEMORY : { + ti = sTexts[32]; tx = sTexts[33]; + } break; + case WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME : { + ti = sTexts[34]; tx = sTexts[35]; + } break; + case WXPQDIC_FRAME_ERROR_HOSTNAME : { + ti = sTexts[36]; tx = sTexts[37]; + } break; + case WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME : { + ti = sTexts[38]; tx = sTexts[39]; + } break; + case WXPQDIC_FRAME_ERROR_QUEUENAME : { + ti = sTexts[40]; tx = sTexts[41]; + } break; + case WXPQDIC_FRAME_ERROR_PORT_OOR : { + ti = sTexts[42]; tx = sTexts[43]; + } break; + case WXPQDIC_FRAME_ERROR_PORT_ZERO : { + ti = sTexts[42]; tx = sTexts[44]; + } break; + case WXPQDIC_FRAME_ERROR_STRCONV_USERNAME : { + ti = sTexts[45]; tx = sTexts[46]; + } break; + case WXPQDIC_FRAME_ERROR_USERNAME : { + ti = sTexts[47]; tx = sTexts[48]; + } break; + case WXPQDIC_FRAME_ERROR_LOCALPORT_OOR : { + ti = sTexts[49]; tx = sTexts[50]; + } break; + case WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO : { + ti = sTexts[49]; tx = sTexts[51]; + } break; + case WXPQDIC_FRAME_ERROR_BUG : { + ti = sTexts[52]; tx = sTexts[53]; + } break; + case WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW : { + ti = sTexts[54]; tx = sTexts[55]; + } break; + case WXPQDIC_FRAME_ERROR_SOCKET : { + ti = sTexts[56]; tx = sTexts[57]; + } break; + } + wxMessageBox(tx, ti, (wxICON_ERROR | wxOK), this); + Show(false); + Close(); + } + + /* Allow idle handlers from the base class. + */ + $? "- OnIdle" + event.Skip(); +} + + +void +WxpqdicFrame::OnTimer(wxTimerEvent & event) +{ + bool mustUpdate = false; + $? "+ OnTimer" + { + wxCriticalSectionLocker lockCsProtect(csProtect); + $? ". entered critical section" + if (bIsInitialized) { $? ". already initialized" + mustUpdate = DataExchangeWithServer(); + } +#if TRACE_DEBUG + else { $? "! not yet initialized" + } +#endif + $? ". exiting critical section" + } + if (mustUpdate) { + Refresh(); + Update(); + } + $? "- OnTimer" +} + + + +bool +WxpqdicFrame::ProcessResponse(bool & found) +{ + wxChar wxb[16*sizeof(dk4_um_t)]; + char *tokens[8]; /* Tokens in the response */ + const char *ep; /* End part of text */ + dk4_um_t limit; /* Print limit */ + dk4_um_t used; /* Pages used with in limit */ + dk4_um_t account; /* Personal account */ + size_t sz; /* Number of tokens used */ + size_t szwxb; /* Size of wxb */ + int founddet; /* Details found. */ + int res; /* Text to number conversion result */ + int summary; /* Flag: Can print */ + bool force; /* Flag: Force use of values */ + bool back = false; + $? "+ ProcessResponse" + sz = dk4str8_tokenize(tokens, 8, bResponse, NULL, NULL); + if (4 == sz) { $? ". 4 tokens" + founddet = 0; + force = bFirstResponse; + switch (iState) { + case WXPQDIC_STATE_TIMEOUT : + case WXPQDIC_STATE_SEND_FAILED : + { + force = true; $? ". recover from error" + } break; + } $? ". force = %d", (force ? 1 : 0) + if (0 == dk4str8_cmp("-1", tokens[0])) { $? ". 0 = unlimited" + limit = DK4_UM_MAX; + founddet |= 1; + } else { + limit = (dk4_um_t)0UL; + ep = NULL; + res = dk4ma_input_c8_dec_dk4_um_t(&limit, tokens[0], &ep, 1, NULL); + if (0 != res) { $? ". 0 = %lu", (unsigned long)limit + founddet |= 1; + } +#if TRACE_DEBUG + else { $? "! 0 not a number" + } +#endif + } + used = (dk4_um_t)0UL; + ep = NULL; + res = dk4ma_input_c8_dec_dk4_um_t(&used, tokens[1], &ep, 1, NULL); + if (0 != res) { $? ". 1 = %lu", (unsigned long)used + founddet |= 2; + } +#if TRACE_DEBUG + else { $? "! 1 not a number" + } +#endif + account = (dk4_um_t)0UL; + ep = NULL; + res = dk4ma_input_c8_dec_dk4_um_t(&account, tokens[2], &ep, 1, NULL); + if (0 != res) { $? ". 2 = %lu", (unsigned long)account + founddet |= 4; + } +#if TRACE_DEBUG + else { $? "! 2 not a number" + } +#endif + summary = 0; + ep = NULL; + res = dk4ma_input_c8_dec_int(&summary, tokens[3], &ep, 1, NULL); + if (0 != res) { $? ". 3 = %d", summary + founddet |= 8; + } +#if TRACE_DEBUG + else { $? "! 3 not a number" + } +#endif + if (15 == (15 & founddet)) { $? ". processed successfully" + /* Renew text labels + */ +#if DK4_SIZEOF_WXCHAR > 1 + szwxb = DK4_SIZEOF(wxb,wxChar); + if ((force) || (limit != uLimit)) { + if (DK4_UM_MAX == limit) { + tLimit->SetLabel(sTexts[14]); + } else { + res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, limit, 0, NULL); + if (0 != res) { + wxString s(wxb); + tLimit->SetLabel(s); + } + } + back = true; + } + if ((force) || (used != uUsed)) { + res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, used, 0, NULL); + if (0 != res) { + wxString s(wxb); + tUsed->SetLabel(s); + } + back = true; + } + if ((force) || (account != uAccount)) { + res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, account, 0, NULL); + if (0 != res) { + wxString s(wxb); + tAccount->SetLabel(s); + } + back = true; + } +#else + if ((force) || (limit != uLimit)) { + if (DK4_UM_MAX == limit) { + tLimit->SetLabel(sTexts[14]); + } else { + wxString s(tokens[0]); + tLimit->SetLabel(s); + } + back = true; $? ". update for limit" + } + if ((force) || (used != uUsed)) { + wxString s(tokens[1]); + tUsed->SetLabel(s); + back = true; $? ". update for used" + } + if ((force) || (account != uAccount)) { + wxString s(tokens[2]); + tAccount->SetLabel(s); + back = true; $? ". update for account" + } +#endif + if ((force) || (summary != iSummary)) { + wxString s(sTexts[(0 != summary) ? 19 : 20]); + tAllowed->SetLabel(s); + if (0 != summary) { + tAllowed->SetForegroundColour(cGreen); + } else { + tAllowed->SetForegroundColour(cRed); + } + back = true; $? ". update for summary" + } + if (force) { + lStatus->SetLabel(sNlWx[5]); + switch (iState) { + case WXPQDIC_STATE_TIMEOUT : + case WXPQDIC_STATE_SEND_FAILED : + { + lStatus->SetForegroundColour(cBlack); + } break; + } + } + /* Save values for later comparisons + */ + uLimit = limit; + uUsed = used; + uAccount = account; + iSummary = summary; + bFirstResponse = false; + /* Change state + */ + iState = WXPQDIC_STATE_OK; + found = true; + } +#if TRACE_DEBUG + else { $? "! processing failed" + } +#endif + } +#if TRACE_DEBUG + else { $? "! not 4 tokens" + } +#endif + $? "- ProcessResponse %d", ((back) ? (1) : (0)) + return back; +} + + + +bool +WxpqdicFrame::RetrieveResponse(void) +{ + dk4_sockaddr_storage_t remaddr; /* Source address */ + size_t sz; /* Buffer size */ + size_t szrema; /* Address size */ + int res; /* Conversion result */ + bool back = false; + bool found = false; /* Flag: Found */ + $? "+ RetrieveResponse" + sz = szResponse; + szrema = sizeof(remaddr); + res = dk4socket_recvfrom( + sock, bResponse, &sz, 0, + (struct sockaddr *)(&remaddr), &szrema, + 0L, 10000L, NULL + ); + switch (res) { + case DK4_SOCKET_RESULT_SUCCESS : + case DK4_SOCKET_RESULT_IN_PROGRESS : + { $? ". data" + if (0 < sz) { $? ". data length" + bResponse[(szResponse > sz) ? (sz) : (szResponse - 1)] = '\0'; +#if TRACE_DEBUG + dk4str8_delnl(bResponse); $? ". response = \"%!8s\"", bResponse +#endif + if (1 /* ##### TODO: Compare addresses */ ) { $? ". addr ok" + back = ProcessResponse(found); + } +#if TRACE_DEBUG + else { $? "! addr mismatch" + } +#endif + } +#if TRACE_DEBUG + else { $? "! data length 0" + } +#endif + } break; + default : { $? ". no data" + } break; + } + if (!(found)) { + if (WXPQDIC_STATE_SENDED == iState) { + iState = WXPQDIC_STATE_TIMEOUT; + tLimit->SetLabel(sTexts[27]); + tUsed->SetLabel(sTexts[27]); + tAccount->SetLabel(sTexts[27]); + tAllowed->SetLabel(sTexts[27]); + tAllowed->SetForegroundColour(cBlack); + lStatus->SetLabel(sTexts[29]); + lStatus->SetForegroundColour(cRed); + back = true; + } + } + $? "- RetrieveResponse %d", ((back) ? (1) : (0)) + return back; +} + + + +bool +WxpqdicFrame::SendRequest(bool force) +{ + dk4_time_t currenttime = (dk4_time_t)0UL; + size_t sz = 0; + int res = 0; + bool mustsend = false; + bool back = false; + $? "+ SendRequest" + if ((dk4_time_t)0UL == tRequestSended) { + mustsend = true; + } else { + if (force) { + mustsend = true; + } else { + dk4time_get(¤ttime); + if ((tRequestSended + (dk4_time_t)lUpdateInterval) <= currenttime) { + mustsend = true; + } + } + } + if (mustsend) { $? ". must send" + sz = szRequest; + if ((dk4_um_t)0UL == currenttime) { + dk4time_get(¤ttime); + } + res = dk4socket_sendto( + sock, pRequest, &sz, 0, + (struct sockaddr *)(&(aAddresses[0])), sizeof(dk4_sockaddr_storage_t), + 0L, 0L, NULL + ); + tRequestSended = currenttime; + switch (res) { + case DK4_SOCKET_RESULT_SUCCESS : + case DK4_SOCKET_RESULT_IN_PROGRESS : + { $? ". success, sended" + switch (iState) { + case WXPQDIC_STATE_OK : { + iState = WXPQDIC_STATE_SENDED; + } break; + } + } break; + default : { $? "! send" + if (WXPQDIC_STATE_SEND_FAILED != iState) { + tLimit->SetLabel(sTexts[27]); + tUsed->SetLabel(sTexts[27]); + tAccount->SetLabel(sTexts[27]); + tAllowed->SetLabel(sTexts[27]); + lStatus->SetLabel(sTexts[28]); + lStatus->SetForegroundColour(cRed); + back = true; + } + iState = WXPQDIC_STATE_SEND_FAILED; + } break; + } + } +#if TRACE_DEBUG + else { $? ". no need to send" + } +#endif + $? "- SendRequest %d", ((back) ? (1) : (0)) + return back; +} + + + +void +WxpqdicFrame::OnRun(wxCommandEvent & event) +{ + bool mustUpdate = false; + $? "+ OnRun" + { + wxCriticalSectionLocker lockCsProtect(csProtect); + if (bIsInitialized) { + mustUpdate = SendRequest(true); + } + } + if (mustUpdate) { + Refresh(); + Update(); + } + $? "- OnRun" +} + + + +bool +WxpqdicFrame::DataExchangeWithServer(void) +{ + bool back = false; + $? "+ DataExchangeWithServer" + if (RetrieveResponse()) { + back = true; + } + if (SendRequest()) { + back = true; + } + $? "- DataExchangeWithServer %d", ((back) ? (1) : (0)) + return back; +} + |