1%%	options
2
3copyright owner	=	Dirk Krause
4
5copyright year	=	2016-xxxx
6
7SPDX-License-Identifier:	BSD-3-Clause
8
9
10
11%%	wx-gui
12
13type		= 	frame
14contents	=	mainSizer
15icon		=	wxpqdic_icon
16status bar	=	1 sTexts[8]
17menu bar	=	mbMain
18tool bar	=	tbMain
19
20[wxMenuBar mbMain]
21contents	=	menuFile
22contents	=	menuView
23contents	=	menuHelp
24
25[wxMenu menuFile]
26text		=	sTexts[0]
27contents	=	miFileExit
28
29[wxMenuItem miFileExit]
30id		=	WxpqdicFrame_Quit
31text		=	sTexts[1]
32tip		=	sTexts[2]
33
34[wxMenu menuView]
35text		=	sTexts[22]
36contents	=	miViewUpdate
37
38[wxMenuItem miViewUpdate]
39id		=	WxpqdicFrame_View_Update
40text		=	sTexts[23]
41tip		=	sTexts[24]
42
43[wxMenu menuHelp]
44text		=	sTexts[3]
45contents	=	miHelpAbout
46contents	=	miHelpContents
47
48[wxMenuItem miHelpAbout]
49id		=	WxpqdicFrame_Help_About
50text		=	sTexts[4]
51tip		=	sTexts[5]
52
53[wxMenuItem miHelpContents]
54id		=	WxpqdicFrame_Help_Contents
55text		=	sTexts[6]
56tip		=	sTexts[7]
57
58[wxBoxSizer mainSizer]
59direction	=	horizontal
60contents	=	$space(10)
61contents	=	verticalSizer
62contents	=	$space(10)
63
64[wxBoxSizer verticalSizer]
65direction	=	vertical
66grow		=	yes
67proportion	=	1
68contents	=	$space(10)
69contents	=	contentsSizer
70contents	=	$space(10)
71
72[wxGridBagSizer contentsSizer]
73grid		=	2 2
74contents	=	lLimit		  0  0  1  1  right
75contents	=	tLimit		  . +1  1  1
76contents	=	lUsed		 +1  0  1  1  right
77contents	=	tUsed		  . +1  1  1
78contents	=	$space(5)	 +1  0  1  1
79contents	=	lAccount	 +1  0  1  1  right
80contents	=	tAccount	  . +1  1  1
81contents	=	$space(5)	 +1  0  1  1
82contents	=	lAllowed	 +1  0  1  1  right
83contents	=	tAllowed	  . +1  1  1
84contents	=	$space(5)	 +1  0  1  1
85contents	=	lStatus		 +1  0  1  2
86
87[wxStaticText lLimit]
88text		=	sTexts[13]
89
90[wxStaticText tLimit]
91text		=	sTexts[14]
92
93[wxStaticText lUsed]
94text		=	sTexts[15]
95
96[wxStaticText tUsed]
97text		=	sTexts[27]
98
99[wxStaticText lAccount]
100text		=	sTexts[17]
101
102[wxStaticText tAccount]
103text		=	sTexts[16]
104
105[wxStaticText lAllowed]
106text		=	sTexts[18]
107
108[wxStaticText tAllowed]
109text		=	sTexts[27]
110
111[wxStaticText lStatus]
112text		=	sTexts[21]
113
114
115[wxToolBar tbMain]
116contents	=	bUpdate
117contents	=	bExit
118
119[wxToolBarToolBase bUpdate]
120text		=	sTexts[25]
121tip		=	sTexts[24]
122bitmap		=	xpm_run_conversion
123id		=	WxpqdicFrame_View_Update
124
125[wxToolBarToolBase bExit]
126text		=	sTexts[26]
127tip		=	sTexts[2]
128bitmap		=	xpm_exit_program
129id		=	WxpqdicFrame_Quit
130
131
132%%	header start
133
134
135
136%%	class start
137class WxpqdicFrame : public Dk4WxFrame
138{
139  private:
140
141    /**	Event table for frame.
142    */
143#if	wxCHECK_VERSION(3,0,0)
144    wxDECLARE_EVENT_TABLE();
145#else
146    DECLARE_EVENT_TABLE()
147#endif
148
149  protected:
150
151    /**	Buffer for response processing.
152    */
153    char			 bResponse[32 * sizeof(dk4_um_t)];
154
155    /**	Address pair, 0=remote, 1=local.
156    */
157    dk4_sockaddr_storage_t	 aAddresses[2];
158
159    /**	Remote host name as wxChar string.
160    */
161    wxString			 sHostname;
162
163    /**	Queue name as wxChar string.
164    */
165    wxString			 sQueuename;
166
167    /**	User name as wxChar string.
168    */
169    wxString			 sUsername;
170
171    /**	Localized texts.
172    */
173    wxChar const * const	*sTexts;
174
175    /**	Non-localized texts.
176    */
177    wxChar const * const	*sNlWx;
178
179    /**	Non-localized texts.
180    */
181    dkChar const * const	*sNlDk;
182
183    /**	Copy of the command line arguments poiner.
184    */
185    wxChar			**copyArgv;
186
187    /*	__CHANGE__ 011:	Add further member variables.
188    */
189
190    /**	Critical section to protect socket and timer.
191    */
192    wxCriticalSection		 csProtect;
193
194    /**	Black color for normal status text.
195    */
196    wxColour			 cBlack;
197
198    /**	Red color for not allowed to print.
199    */
200    wxColour			 cRed;
201
202    /**	Green color for allowed to print.
203    */
204    wxColour			 cGreen;
205
206    /**	Timer for periodic updates.
207    */
208    wxTimer			 timer;
209
210    /**	Error report from socket subsystem initialization.
211    */
212    dk4_er_t			 sockerr;
213
214    /**	Host name to query.
215    */
216    dkChar			*pHostname;
217
218    /**	Print queue to check.
219    */
220    char			*pQueuename;
221
222    /**	User name to use in check.
223    */
224    char			*pUsername;
225
226    /**	Request to send to server.
227    */
228    char			*pRequest;
229
230    /**	Previous limit value.
231    */
232    dk4_um_t			uLimit;
233
234    /**	Previous used value.
235    */
236    dk4_um_t			uUsed;
237
238    /**	Previous account value.
239    */
240    dk4_um_t			uAccount;
241
242    /**	Length of request.
243    */
244    size_t			 szRequest;
245
246    /**	Size of response buffer.
247    */
248    size_t			 szResponse;
249
250    /**	Time last request was sended.
251    */
252    dk4_time_t			 tRequestSended;
253
254    /**	Update interval in seconds.
255    */
256    long			 lUpdateInterval;
257
258    /**	Timeout interval before complaining about missing response.
259    */
260    long			 lWaitResponse;
261
262    /**	Previous summary value.
263    */
264    int				 iSummary;
265
266    /**	Number of command line arguments.
267    */
268    int				 copyArgc;
269
270    /**	Current state.
271    */
272    int				 iState;
273
274    /**	Socket for data exchange
275    */
276    dk4_socket_t		 sock;
277
278    /**	Port number on remote host.
279    */
280    unsigned short		 usPortnumber;
281
282    /**	Local port number to  use.
283    */
284    unsigned short		 usLocalPort;
285
286    /**	Flag: Socket subsystem initialized.
287    */
288    bool			 bSockInit;
289
290    /**	Flag: Remote host uses UTF-8 encoding (user name and queue name).
291    */
292    bool			 bIsUtf8;
293
294    /**	Flag: This idle event is the first one (no idle events before).
295    */
296    bool			 bFirstIdle;
297
298    /**	Flag: All components initialized completely.
299    */
300    bool			 bIsInitialized;
301
302    /**	Flag: This is the first response.
303    */
304    bool			 bFirstResponse;
305
306%%	class end
307
308  public:
309
310    /**	Constructor.
311	@param	wxid			Window ID.
312	@param	applicationHelper	Application helper object.
313	@param	hc			Help controller for online help.
314	@param	argc			Number of command line arguments.
315	@param	argv			Command line arguments array.
316	@param	localizedTexts		Localized wxChar texts.
317	@param	nlWx			Non-localized wxChar texts.
318	@param	nlDk			Non-localized dkChar texts.
319	@param	bSocketsInitialized	Flag: Socket subsys initialized.
320	@param	psockerr		Error report from socket initialization.
321    */
322    WxpqdicFrame(
323      int			  wxid,
324      Dk4WxApplicationHelper	 *applicationHelper,
325      Dk4WxHelpController	 *hc,
326      int			  argc,
327      wxChar			**argv,
328      wxChar const * const	 *localizedTexts,
329      wxChar const * const	 *nlWx,
330      dkChar const * const	 *nlDk,
331      bool			  bSocketsInitialized,
332      dk4_er_t		 	 *psockerr
333    );
334
335    /**	Destructor.
336    */
337    ~WxpqdicFrame();
338
339    /**	Check whether we can close the window.
340    	@param	isLast	Flag: Last main window to close.
341    */
342    bool
343    CanClose(bool isFinal);
344
345    /**	Handler for File/Exit.
346    	@param	event	Event to process.
347    */
348    void
349    OnQuit(wxCommandEvent & event);
350
351    /**	Handler for File/Update.
352    	@param	event	Event to process.
353    */
354    void
355    OnRun(wxCommandEvent & event);
356
357    /**	Handler for Help/About.
358    	@param	event	Event to process.
359    */
360    void
361    OnAbout(wxCommandEvent & event);
362
363    /**	Handler for Help/Contents.
364    	@param	event	Event to process.
365    */
366    void
367    OnHelpContents(wxCommandEvent & event);
368
369    /*	__CHANGE__ 008:	Remove OnIdle if no idle processing required.
370    */
371    /**	Handler for idle events.
372    */
373    void
374    OnIdle(wxIdleEvent & event);
375
376    /*	__CHANGE__ 017:	Event handlers for further events.
377    */
378
379    /** Handler for timer event.
380        @param  event   Timer event to process.
381    */
382    void
383    OnTimer(wxTimerEvent & event);
384
385
386    /*	__CHANGE__ 014:	Add further methods.
387    */
388
389  private:
390
391    /**	Attempt to configure.
392	@param	perrc	Address of error code variable.
393	@return	True if configuration failed and the application should
394	exit, false on success.
395    */
396    bool
397    ConfigureAndCheckNeedToClose(int *perrc);
398
399    /**	Attempt to receive data, send request again if interval is over.
400	@return	True if the windows requires an update, false otherwise.
401    */
402    bool
403    DataExchangeWithServer(void);
404
405    bool
406    RetrieveResponse(void);
407
408    bool
409    ProcessResponse(bool & found);
410
411    bool
412    SendRequest(bool force = false);
413
414};
415
416%%	header end
417
418%%	module start
419
420#include "dk4conf.h"
421
422#ifndef	DK4_SIZEOF_WXCHAR
423#ifndef	DK4WXCS_H_INCLUDED
424#include "dk4wxcs.h"
425#endif
426#endif
427
428#include <wxpqdic/wxpqdic.h>
429#include <libdk4c/dk4user.h>
430#include <libdk4c/dk4enc.h>
431#include <libdk4base/dk4strd.h>
432#include <libdk4c/dk4rec.h>
433#include <libdk4base/dk4str8.h>
434#include <libdk4wx/dk4strx.h>
435#include <libdk4wx/dk4recwx.h>
436#include <libdk4ma/dk4maasz.h>
437#include <libdk4maio8d/dk4mai8ddu.h>
438#include <libdk4maio8d/dk4mai8dii.h>
439#include <libdk4maio8d/dk4mao8d.h>
440#include <libdk4maiowd/dk4maowd.h>
441#include <libdk4base/dk4numco.h>
442
443
444#include "gui-img/shared/toolbar/exit-program.xpm"
445#include "gui-img/shared/toolbar/run-conversion.xpm"
446
447#include <libdk4wx/dk4verswx.h>
448
449#if !defined(__WXMSW__)
450#include "gui-img/icons/dkicon.xpm"
451#endif
452
453
454
455$!trace-include
456
457
458
459/*	__CHANGE__ 017: Add further events. */
460/*	__CHANGE__ 008: Remove OnIdle if no idle processing required. */
461
462#if	wxCHECK_VERSION(3,0,0)
463wxBEGIN_EVENT_TABLE(WxpqdicFrame,wxFrame)
464#else
465BEGIN_EVENT_TABLE(WxpqdicFrame,wxFrame)
466#endif
467	EVT_MENU(WxpqdicFrame_View_Update, WxpqdicFrame::OnRun)
468	EVT_MENU(WxpqdicFrame_Quit, WxpqdicFrame::OnQuit)
469	EVT_MENU(WxpqdicFrame_Help_About, WxpqdicFrame::OnAbout)
470	EVT_MENU(WxpqdicFrame_Help_Contents, WxpqdicFrame::OnHelpContents)
471	EVT_TIMER(WxpqdicFrame_Timer, WxpqdicFrame::OnTimer)
472	EVT_IDLE(WxpqdicFrame::OnIdle)
473#if	wxCHECK_VERSION(3,0,0)
474wxEND_EVENT_TABLE()
475#else
476END_EVENT_TABLE()
477#endif
478
479
480
481static const wxChar versionNumber[] = { DKT_VERSION_WX };
482
483
484
485#if __GNUC__
486#pragma GCC diagnostic push
487#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
488#endif
489
490static const wxCmdLineEntryDesc wxpqdic_cmd_line_entries[] = {
491  {
492    wxCMD_LINE_OPTION,
493    wxT_2("h"),
494    wxT_2("host"),
495    wxT_2("Host to connect to."),
496    wxCMD_LINE_VAL_STRING,
497    0
498  },
499  {
500    wxCMD_LINE_OPTION,
501    wxT_2("p"),
502    wxT_2("port"),
503    wxT_2("Port number to connect to."),
504    wxCMD_LINE_VAL_NUMBER,
505    0
506  },
507  {
508    wxCMD_LINE_OPTION,
509    wxT_2("l"),
510    wxT_2("local-port"),
511    wxT_2("Local port number to use."),
512    wxCMD_LINE_VAL_NUMBER,
513    0
514  },
515  {
516    wxCMD_LINE_OPTION,
517    wxT_2("q"),
518    wxT_2("queue"),
519    wxT_2("Queue name to check."),
520    wxCMD_LINE_VAL_STRING,
521    0
522  },
523  {
524    wxCMD_LINE_OPTION,
525    wxT_2("u"),
526    wxT_2("user"),
527    wxT_2("User name to check."),
528    wxCMD_LINE_VAL_STRING,
529    0
530  },
531  {
532    wxCMD_LINE_OPTION,
533    wxT_2("i"),
534    wxT_2("interval"),
535    wxT_2("Time interval for automatic update."),
536    wxCMD_LINE_VAL_NUMBER,
537    0
538  },
539  {
540    wxCMD_LINE_OPTION,
541    wxT_2("a"),
542    wxT_2("ascii"),
543    wxT_2("Remote host uses ASCII encoding, not UTF-8."),
544    wxCMD_LINE_VAL_NONE,
545    0
546  },
547  { wxCMD_LINE_NONE }
548};
549
550#if __GNUC__
551#pragma GCC diagnostic pop
552#endif
553
554
555/**	Key names for preferences.
556*/
557static	const wxChar * const	wxpqdic_pref_key_names[] = {
558$!string-table	macro=wxT
559printqd.host
560printqd.port
561printqd.queue
562printqd.interval
563printqd.local
564printqd.encoding
565$!end
566};
567
568
569
570/**	Constant 8-bit strings, not localized.
571*/
572static	const char * const	wxpqdic_kw[] = {
573$!string-table
574#
575#	0	newline
576#
577\n
578#
579#	1	space
580#
581
582#
583#	2	keyword info
584#
585info
586$!end
587};
588
589
590%%	constructor start
591WxpqdicFrame::WxpqdicFrame(
592  int			  wxid,
593  Dk4WxApplicationHelper *applicationHelper,
594  Dk4WxHelpController	 *hc,
595  int			  argc,
596  wxChar		**argv,
597  wxChar const * const	 *localizedTexts,
598  wxChar const * const	 *nlWx,
599  dkChar const * const	 *nlDk,
600  bool			  bSocketsInitialized,
601  dk4_er_t		 *psockerr
602) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid),
603    sHostname(wxT("")),
604    sQueuename(wxT("")),
605    sUsername(wxT("")),
606    cBlack(0, 0, 0),
607    cRed(127, 0, 0),
608    cGreen(0, 127, 0),
609    timer(this, WxpqdicFrame_Timer)
610
611{
612  /*	__CHANGE__ 012:	Add further local variables.
613  */
614
615  /*	__CHANGE__ 012: Initialize further local variables.
616  */
617
618  sTexts = localizedTexts;
619  sNlWx  = nlWx;
620  sNlDk  = nlDk;
621#if defined(__WXMSW__)
622  wxIcon	wxpqdic_icon(sNlWx[4]);
623#else
624  wxIcon	wxpqdic_icon(xpm_dkicon);
625#endif
626
627  /*	__CHANGE__ 011:	Initialize further class members.
628  */
629  bSockInit		= bSocketsInitialized;
630  DK4_MEMCPY(&sockerr, psockerr, sizeof(dk4_er_t));
631  pHostname		= NULL;
632  pQueuename		= NULL;
633  pUsername		= NULL;
634  pRequest		= NULL;
635  szRequest		= (size_t)0UL;
636  lUpdateInterval	= 30L;
637  lWaitResponse		= 1L;
638  usPortnumber		= 9100;
639  usLocalPort		= 9100;
640  bIsUtf8		= true;
641  bFirstIdle		= true;
642  bFirstResponse	= true;
643  bIsInitialized	= false;
644  copyArgc		= argc;
645  copyArgv		= argv;
646  sock			= INVALID_SOCKET;
647  iState		= WXPQDIC_STATE_OK;
648  tRequestSended	= (dk4_time_t)0UL;
649  szResponse		= sizeof(bResponse);
650  DK4_MEMRES(&(aAddresses[0]), (2*sizeof(dk4_sockaddr_storage_t)));
651
652%%	constructor end
653  if(dkctGUILayoutOK) {
654    SetTitle(nlWx[0]);
655  }
656
657
658  /*	__CHANGE__ 012:	Release resources allocated by local variables.
659  */
660}
661
662%%	module end
663
664
665
666WxpqdicFrame::~WxpqdicFrame()
667{
668
669  /*	__CHANGE__ 011:	Release resources allocated by further class members.
670  */
671}
672
673
674
675bool
676WxpqdicFrame::CanClose(bool WXUNUSED(isLast))
677{
678  bool		back	= true;
679
680  return back;
681}
682
683
684void
685WxpqdicFrame::OnQuit(wxCommandEvent & WXUNUSED(event))
686{
687  {
688    wxCriticalSectionLocker	lockCsProtect(csProtect);
689    if (bIsInitialized) {
690      timer.Stop();
691      bIsInitialized = false;
692    }
693  }
694  if (INVALID_SOCKET != sock) {
695    dk4socket_close(sock, NULL);
696    sock = INVALID_SOCKET;
697  }
698  dk4mem_release(pUsername);
699  dk4mem_release(pQueuename);
700  dk4mem_release(pHostname);
701  dk4mem_release(pRequest);
702  Show(false);
703  /*	!!!!! TODO: Release resources */
704  Close();
705}
706
707
708
709void
710WxpqdicFrame::OnAbout(wxCommandEvent & WXUNUSED(event))
711{
712  wxString	text(wxT(""));
713  wxString	title(wxT(""));
714
715  /* Construct message text. */
716  text.Append(sNlWx[0]);
717  text.Append(sNlWx[7]);
718#if 0
719  text.Append(sNlWx[1]);
720#endif
721  text.Append(versionNumber);
722  text.Append(sNlWx[8]);
723  text.Append(sTexts[9]);
724  text.Append(sNlWx[2]);
725  text.Append(sNlWx[8]);
726  text.Append(sNlWx[8]);
727  text.Append(sTexts[11]);
728  text.Append(sNlWx[8]);
729  text.Append(sNlWx[9]);
730  text.Append(sNlWx[8]);
731  text.Append(sNlWx[8]);
732  text.Append(sTexts[12]);
733  text.Append(sNlWx[8]);
734  text.Append(sNlWx[10]);
735  text.Append(sNlWx[8]);
736  text.Append(sNlWx[11]);
737  text.Append(sNlWx[8]);
738  text.Append(sNlWx[12]);
739  text.Append(sNlWx[8]);
740  text.Append(sNlWx[13]);
741  text.Append(sNlWx[8]);
742  text.Append(sNlWx[14]);
743  text.Append(sNlWx[8]);
744  text.Append(sNlWx[15]);
745  text.Append(sNlWx[8]);
746
747  /* Construct dialog box title. */
748  title.Append(sTexts[10]);
749  title.Append(sNlWx[0]);
750
751  /* Show dialog box. */
752  wxMessageBox(text, title);
753
754}
755
756
757
758void
759WxpqdicFrame::OnHelpContents(wxCommandEvent & WXUNUSED(event))
760{
761  DisplayContents();
762}
763
764/*	__CHANGE__ 017:	Event handlers for further events.
765*/
766
767/*	__CHANGE__ 014:	Implementation of further methods.
768*/
769
770
771bool
772WxpqdicFrame::ConfigureAndCheckNeedToClose(int *perrc)
773{
774  wxString		 dummy(wxT(""));
775  dkChar		 buf[1024];
776  char			 c8b[1024];
777  dk4_er_t		 er;
778  wxChar		*pv[] = { NULL, NULL, NULL, NULL, NULL, NULL };
779  wxCStrData		 hnstrdata = dummy.c_str();
780  wxCStrData		 qnstrdata = dummy.c_str();
781  wxCStrData		 unstrdata = dummy.c_str();
782  const wxChar		*cptr;
783  const size_t		 szbuf			= DK4_SIZEOF(buf,dkChar);
784  const size_t		 szc8b			= sizeof(c8b);
785  long		 	 l			= 0L;
786  int		 	 res			= 0;
787  bool			 back			= true;
788
789  /*	Retrieve some fallback values from preferences.
790  */
791  pAppHelp->GetMultiple(wxpqdic_pref_key_names, pv, 6);
792  $? ". host     = \"%!ws\"", TR_WXSTR(pv[0])
793  $? ". port     = \"%!ws\"", TR_WXSTR(pv[1])
794  $? ". queue    = \"%!ws\"", TR_WXSTR(pv[2])
795  $? ". interval = \"%!ws\"", TR_WXSTR(pv[3])
796  $? ". local    = \"%!ws\"", TR_WXSTR(pv[4])
797  $? ". encoding = \"%!ws\"", TR_WXSTR(pv[5])
798
799  /*	Check command line arguments
800  */
801  {
802    wxLogNull log;
803    wxCmdLineParser 	 parser(wxpqdic_cmd_line_entries, copyArgc, copyArgv);
804    res = parser.Parse(false);
805    /*
806	Check overall parsing of arguments
807    */
808    if (0 != res) {		$? "! failed to parse cmd line args"
809      /* ERROR: Failed to parse command line arguments */
810      *perrc = WXPQDIC_FRAME_ERROR_PARSE;
811      goto finished;
812    }
813    /*
814	Option -a means the remote host wants ASCII data.
815    */
816    if (parser.Found(wxT_2("a"))) {
817      bIsUtf8 = false;
818    } else {
819      if (NULL != pv[5]) {
820        if (0 != dk4strx_casecmp(pv[5], sNlWx[16])) {
821	  if (0 != dk4strx_casecmp(pv[5], sNlWx[17])) {
822	    bIsUtf8 = false;
823	  }
824	}
825      }
826    }
827    /*
828	Try to obtain host name from arguments or from preferences.
829    */
830    dk4error_init(&er);
831    cptr = NULL;
832    if (parser.Found(wxT_2("h"), &sHostname)) {
833      hnstrdata = sHostname.c_str();
834      cptr = (wxChar const *)hnstrdata;
835    }
836    else {
837      cptr = pv[0];
838    }
839    if (NULL != cptr) {
840      if (pAppHelp->StringToDk(buf, szbuf, cptr, &er)) {
841        pHostname = dk4str_dup(buf, NULL);
842	if (NULL == pHostname) { $? ". pHostname = \"%!ds\"", pHostname
843	  /* ERROR: Memory */
844	  *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
845	  goto finished;
846	}
847      } else {
848        /* ERROR: Failed to convert string */
849	*perrc = WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME;
850	goto finished;
851      }
852    }
853    if (NULL == pHostname) {
854      /* ERROR: Missing host name */
855      *perrc = WXPQDIC_FRAME_ERROR_HOSTNAME;
856      goto finished;
857    }
858    /*
859	Queue name is required.
860    */
861    cptr = NULL;
862    if (parser.Found(wxT_2("q"), &sQueuename)) {
863      qnstrdata = sQueuename.c_str();
864      cptr = (wxChar const *)qnstrdata;
865    }
866    else {
867      cptr = pv[2];
868    }
869    if (NULL != cptr) {
870      res = dk4recwx_wxchar_to_char(
871        c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_PLAIN)),
872	cptr, pAppHelp->GetWxEncoding(), NULL
873      );
874      if (0 != res) {
875        pQueuename = dk4str8_dup(c8b, NULL);
876	if (NULL == pQueuename) {	$? ". pQueuename = \"%!8s\"", pQueuename
877	  /* ERROR: Memory */
878	  *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
879	  goto finished;
880	}
881      } else {
882        /* ERROR: String conversion failed */
883	*perrc = WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME;
884	goto finished;
885      }
886    }
887    else {
888      /* ERROR: Missing queue name */
889      *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME;
890      goto finished;
891    }
892    if (NULL == pQueuename) {
893      /* ERROR: Missing queue name */
894      *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME;
895      goto finished;
896    }
897    /*
898	Port number is optional.
899    */
900    {
901      bool	portnoFound	= false;
902      l = 0L;
903      if (parser.Found(wxT_2("p"), &l)) {
904        portnoFound = true;
905      }
906      else {
907        if (NULL != pv[1]) {
908	  wxString s(pv[1]);
909	  if (s.ToLong(&l, 0)) {
910	    portnoFound = true;
911	  }
912	}
913      }
914      if (portnoFound) {
915	if ((long)(USHRT_MAX) < l) {
916	  /* ERROR: Port number out of range */
917	  *perrc = WXPQDIC_FRAME_ERROR_PORT_OOR;
918	  goto finished;
919	}
920	if (0L == l) {
921	  /* ERROR: Illegal port number 0 */
922	  *perrc = WXPQDIC_FRAME_ERROR_PORT_ZERO;
923	  goto finished;
924	}
925	usPortnumber = (unsigned short)l;
926      }
927    }
928    /*
929	Local port number is optional.
930    */
931    {
932      bool	portnoFound	= false;
933      l = 0L;
934      if (parser.Found(wxT_2("l"), &l)) {
935        portnoFound = true;
936      }
937      else {
938        if (NULL != pv[4]) {
939	  wxString s(pv[4]);
940	  if (s.ToLong(&l, 0)) {
941	    portnoFound = true;
942	  }
943	}
944      }
945      if (portnoFound) {
946	if ((long)(USHRT_MAX) < l) {
947	  /* ERROR: Port number out of range */
948	  *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_OOR;
949	  goto finished;
950	}
951	if (0L == l) {
952	  /* ERROR: Illegal port number 0 */
953	  *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO;
954	  goto finished;
955	}
956	usLocalPort = (unsigned short)l;
957      }
958    }
959    /*
960	User name is optional, use current user by default.
961    */
962    if (parser.Found(wxT_2("u"), &sUsername)) {
963      unstrdata = sUsername.c_str();
964      res = dk4recwx_wxchar_to_char(
965        c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_PLAIN)),
966	(wxChar const *)unstrdata, pAppHelp->GetWxEncoding(), NULL
967      );
968      if (0 != res) {
969        pUsername = dk4str8_dup(c8b, NULL);
970	if (NULL == pUsername) {
971	  /* ERROR: Memory */
972	  *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
973	  goto finished;
974	}
975      }
976      else {
977        /* ERROR: Failed to convert user name */
978	*perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME;
979	goto finished;
980      }
981    }
982    else {
983      res = dk4user_get_logname(buf, szbuf, 0, NULL);
984      if (0 != res) {
985        res = dk4recode_dk_to_any(
986	  c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_PLAIN)),
987	  buf, pAppHelp->GetDkEncoding(), NULL
988	);
989	if (0 != res) {
990	  pUsername = dk4str8_dup(c8b, NULL);
991	  if (NULL == pUsername) {
992	    /* ERROR: Memory */
993	    *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
994	    goto finished;
995	  }
996	}
997	else {
998	  /* ERROR: Failed to convert user name */
999	  *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME;
1000	  goto finished;
1001	}
1002      } else {
1003        /* ERROR: User name not found! */
1004	*perrc = WXPQDIC_FRAME_ERROR_USERNAME;
1005	goto finished;
1006      }
1007    }
1008    if (NULL == pUsername) {
1009      /* ERROR: No user name */
1010      *perrc = WXPQDIC_FRAME_ERROR_USERNAME;
1011      goto finished;
1012    }
1013    /*
1014	Interval length is optional.
1015    */
1016    {
1017      bool	intervalFound	= false;
1018      l = 0L;
1019      if (parser.Found(wxT_2("p"), &l)) {
1020        intervalFound = true;
1021      }
1022      else {
1023        if (NULL != pv[3]) {
1024	  wxString s(pv[3]);
1025	  if (s.ToLong(&l, 0)) {
1026	    intervalFound = true;
1027	  }
1028	}
1029      }
1030      if (intervalFound) {
1031        if (5L <= l) {
1032	  lUpdateInterval = l;
1033	} else {
1034	  lUpdateInterval = 5L;
1035	}
1036      }
1037    }
1038    /*
1039	Now build request
1040    */
1041    dk4error_init(&er);
1042    szRequest = strlen(wxpqdic_kw[2]);
1043    szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pQueuename), &er);
1044    szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pUsername), &er);
1045    szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(wxpqdic_kw[2]), &er);
1046    szRequest = dk4ma_size_t_add(szRequest, 4, &er);
1047    if (DK4_E_NONE == er.ec) {
1048      pRequest = dk4mem_new(char,szRequest,NULL);
1049      if (NULL != pRequest) {
1050        if (0 == dk4str8_cpy_s(pRequest, szRequest, wxpqdic_kw[2], NULL)) {
1051	  /* ERROR: BUG */
1052	  *perrc = WXPQDIC_FRAME_ERROR_BUG;
1053	  goto finished;
1054	}
1055	if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) {
1056	  /* ERROR: BUG */
1057	  *perrc = WXPQDIC_FRAME_ERROR_BUG;
1058	  goto finished;
1059	}
1060	if (0 == dk4str8_cat_s(pRequest, szRequest, pQueuename, NULL)) {
1061	  /* ERROR: BUG */
1062	  *perrc = WXPQDIC_FRAME_ERROR_BUG;
1063	  goto finished;
1064	}
1065	if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) {
1066	  /* ERROR: BUG */
1067	  *perrc = WXPQDIC_FRAME_ERROR_BUG;
1068	  goto finished;
1069	}
1070	if (0 == dk4str8_cat_s(pRequest, szRequest, pUsername, NULL)) {
1071	  /* ERROR: BUG */
1072	  *perrc = WXPQDIC_FRAME_ERROR_BUG;
1073	  goto finished;
1074	}
1075	if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[0], NULL)) {
1076	  /* ERROR: BUG */
1077	  *perrc = WXPQDIC_FRAME_ERROR_BUG;
1078	  goto finished;
1079	}
1080	szRequest = dk4str8_len(pRequest);
1081	$? ". request = \"%s\"", TR_8STR(pRequest)
1082      } else {
1083        /* ERROR: Memory */
1084	*perrc = WXPQDIC_FRAME_ERROR_MEMORY;
1085	goto finished;
1086      }
1087    } else {
1088      /* ERROR: Numeric overflow in size calculation */
1089      *perrc = WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW;
1090      goto finished;
1091    }
1092    /*
1093	Create socket.
1094    */
1095    sock = dk4socket_udp_client_for_host(
1096      aAddresses, pHostname, usPortnumber, usLocalPort, 1, NULL
1097    );
1098    if (INVALID_SOCKET == sock) {
1099      *perrc = WXPQDIC_FRAME_ERROR_SOCKET;
1100      goto finished;
1101    }
1102
1103  }
1104
1105  $? ". successfully completed setup"
1106
1107  tLimit->SetLabel(sTexts[27]);
1108  tUsed->SetLabel(sTexts[27]);
1109  tAccount->SetLabel(sTexts[27]);
1110
1111  /*	Finally indicate success.
1112  */
1113  timer.Start(500);
1114  bIsInitialized = true;
1115  back = false;
1116
1117  /*	Clean up at end and return result.
1118  */
1119  finished:
1120  pAppHelp->ReleaseWxcharStringArray(pv, 6);
1121  if (back) {
1122    if (INVALID_SOCKET != sock) {
1123      dk4socket_close(sock, NULL);
1124      sock = INVALID_SOCKET;
1125    }
1126    dk4mem_release(pUsername);
1127    dk4mem_release(pQueuename);
1128    dk4mem_release(pHostname);
1129    dk4mem_release(pRequest);
1130  }
1131  return back;
1132}
1133
1134
1135
1136void
1137WxpqdicFrame::OnIdle(wxIdleEvent & event)
1138{
1139  int			 errorCode		= WXPQDIC_FRAME_ERROR_NONE;
1140  bool			 mustClose		= false;
1141  $? "+ OnIdle"
1142  /* __CHANGE__
1143  */
1144  {
1145    wxCriticalSectionLocker	lockCsProtect(csProtect);
1146    if (bFirstIdle) {
1147      bFirstIdle = false;
1148      mustClose = ConfigureAndCheckNeedToClose(&errorCode);
1149    }
1150  }
1151  if (mustClose) {		$? "! error in setup, must close window"
1152    const wxChar *ti;
1153    const wxChar *tx;
1154    ti = sTexts[58]; tx = sTexts[59];
1155    switch (errorCode) {
1156      case WXPQDIC_FRAME_ERROR_PARSE : {
1157        ti = sTexts[30]; tx = sTexts[31];
1158      } break;
1159      case WXPQDIC_FRAME_ERROR_MEMORY : {
1160        ti = sTexts[32]; tx = sTexts[33];
1161      } break;
1162      case WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME : {
1163        ti = sTexts[34]; tx = sTexts[35];
1164      } break;
1165      case WXPQDIC_FRAME_ERROR_HOSTNAME : {
1166        ti = sTexts[36]; tx = sTexts[37];
1167      } break;
1168      case WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME : {
1169        ti = sTexts[38]; tx = sTexts[39];
1170      } break;
1171      case WXPQDIC_FRAME_ERROR_QUEUENAME : {
1172        ti = sTexts[40]; tx = sTexts[41];
1173      } break;
1174      case WXPQDIC_FRAME_ERROR_PORT_OOR : {
1175        ti = sTexts[42]; tx = sTexts[43];
1176      } break;
1177      case WXPQDIC_FRAME_ERROR_PORT_ZERO : {
1178        ti = sTexts[42]; tx = sTexts[44];
1179      } break;
1180      case WXPQDIC_FRAME_ERROR_STRCONV_USERNAME : {
1181        ti = sTexts[45]; tx = sTexts[46];
1182      } break;
1183      case WXPQDIC_FRAME_ERROR_USERNAME : {
1184        ti = sTexts[47]; tx = sTexts[48];
1185      } break;
1186      case WXPQDIC_FRAME_ERROR_LOCALPORT_OOR : {
1187        ti = sTexts[49]; tx = sTexts[50];
1188      } break;
1189      case WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO : {
1190        ti = sTexts[49]; tx = sTexts[51];
1191      } break;
1192      case WXPQDIC_FRAME_ERROR_BUG : {
1193        ti = sTexts[52]; tx = sTexts[53];
1194      } break;
1195      case WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW : {
1196        ti = sTexts[54]; tx = sTexts[55];
1197      } break;
1198      case WXPQDIC_FRAME_ERROR_SOCKET : {
1199        ti = sTexts[56]; tx = sTexts[57];
1200      } break;
1201    }
1202    wxMessageBox(tx, ti, (wxICON_ERROR | wxOK), this);
1203    Show(false);
1204    Close();
1205  }
1206
1207  /*	Allow idle handlers from the base class.
1208  */
1209  $? "- OnIdle"
1210  event.Skip();
1211}
1212
1213
1214void
1215WxpqdicFrame::OnTimer(wxTimerEvent & WXUNUSED(event))
1216{
1217  bool	mustUpdate	= false;
1218  $? "+ OnTimer"
1219  {
1220    wxCriticalSectionLocker	lockCsProtect(csProtect);
1221    $? ". entered critical section"
1222    if (bIsInitialized) {	$? ". already initialized"
1223      mustUpdate = DataExchangeWithServer();
1224    }
1225#if TRACE_DEBUG
1226    else {			$? "! not yet initialized"
1227    }
1228#endif
1229    $? ". exiting critical section"
1230  }
1231  if (mustUpdate) {
1232    Refresh();
1233    Update();
1234  }
1235  $? "- OnTimer"
1236}
1237
1238
1239
1240bool
1241WxpqdicFrame::ProcessResponse(bool & found)
1242{
1243  wxChar	 wxb[16*sizeof(dk4_um_t)];
1244  char		*tokens[8];		/* Tokens in the response */
1245  const char	*ep;			/* End part of text */
1246  dk4_um_t	 limit;			/* Print limit */
1247  dk4_um_t	 used;			/* Pages used with in limit */
1248  dk4_um_t	 account;		/* Personal account */
1249  size_t	 sz;			/* Number of tokens used */
1250  size_t	 szwxb;			/* Size of wxb */
1251  int		 founddet;		/* Details found. */
1252  int		 res;			/* Text to number conversion result */
1253  int		 summary;		/* Flag: Can print */
1254  bool		 force;			/* Flag: Force use of values */
1255  bool		 back	= false;
1256  $? "+ ProcessResponse"
1257  sz = dk4str8_tokenize(tokens, 8, bResponse, NULL, NULL);
1258  if (4 == sz) {				$? ". 4 tokens"
1259    founddet = 0;
1260    force = bFirstResponse;
1261    switch (iState) {
1262      case WXPQDIC_STATE_TIMEOUT :
1263      case WXPQDIC_STATE_SEND_FAILED :
1264      {
1265        force = true;			$? ". recover from error"
1266      } break;
1267    }					$? ". force = %d", (force ? 1 : 0)
1268    if (0 == dk4str8_cmp("-1", tokens[0])) {	$? ". 0 = unlimited"
1269      limit = DK4_UM_MAX;
1270      founddet |= 1;
1271    } else {
1272      limit = (dk4_um_t)0UL;
1273      ep = NULL;
1274      res = dk4ma_input_c8_dec_dk4_um_t(&limit, tokens[0], &ep, 1, NULL);
1275      if (0 != res) {				$? ". 0 = %lu", (unsigned long)limit
1276        founddet |= 1;
1277      }
1278#if TRACE_DEBUG
1279      else {					$? "! 0 not a number"
1280      }
1281#endif
1282    }
1283    used = (dk4_um_t)0UL;
1284    ep = NULL;
1285    res = dk4ma_input_c8_dec_dk4_um_t(&used, tokens[1], &ep, 1, NULL);
1286    if (0 != res) {				$? ". 1 = %lu", (unsigned long)used
1287      founddet |= 2;
1288    }
1289#if TRACE_DEBUG
1290    else {					$? "! 1 not a number"
1291    }
1292#endif
1293    account = (dk4_um_t)0UL;
1294    ep = NULL;
1295    res = dk4ma_input_c8_dec_dk4_um_t(&account, tokens[2], &ep, 1, NULL);
1296    if (0 != res) {				$? ". 2 = %lu", (unsigned long)account
1297      founddet |= 4;
1298    }
1299#if TRACE_DEBUG
1300    else {					$? "! 2 not a number"
1301    }
1302#endif
1303    summary = 0;
1304    ep = NULL;
1305    res = dk4ma_input_c8_dec_int(&summary, tokens[3], &ep, 1, NULL);
1306    if (0 != res) {				$? ". 3 = %d", summary
1307      founddet |= 8;
1308    }
1309#if TRACE_DEBUG
1310    else {					$? "! 3 not a number"
1311    }
1312#endif
1313    if (15 == (15 & founddet)) {		$? ". processed successfully"
1314      /*	Renew text labels
1315      */
1316#if DK4_SIZEOF_WXCHAR > 1
1317      szwxb = DK4_SIZEOF(wxb,wxChar);
1318      if ((force) || (limit != uLimit)) {
1319        if (DK4_UM_MAX == limit) {
1320	  tLimit->SetLabel(sTexts[14]);
1321	} else {
1322	  res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, limit, 0, NULL);
1323	  if (0 != res) {
1324	    wxString s(wxb);
1325	    tLimit->SetLabel(s);
1326	  }
1327	}
1328        back = true;
1329      }
1330      if ((force) || (used != uUsed)) {
1331        res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, used, 0, NULL);
1332	if (0 != res) {
1333	  wxString s(wxb);
1334	  tUsed->SetLabel(s);
1335	}
1336        back = true;
1337      }
1338      if ((force) || (account != uAccount)) {
1339        res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, account, 0, NULL);
1340	if (0 != res) {
1341	  wxString s(wxb);
1342	  tAccount->SetLabel(s);
1343	}
1344        back = true;
1345      }
1346#else
1347      if ((force) || (limit != uLimit)) {
1348        if (DK4_UM_MAX == limit) {
1349	  tLimit->SetLabel(sTexts[14]);
1350	} else {
1351	  wxString s(tokens[0]);
1352	  tLimit->SetLabel(s);
1353	}
1354	back = true;				$? ". update for limit"
1355      }
1356      if ((force) || (used != uUsed)) {
1357        wxString s(tokens[1]);
1358	tUsed->SetLabel(s);
1359        back = true;				$? ". update for used"
1360      }
1361      if ((force) || (account != uAccount)) {
1362        wxString s(tokens[2]);
1363	tAccount->SetLabel(s);
1364        back = true;				$? ". update for account"
1365      }
1366#endif
1367      if ((force) || (summary != iSummary)) {
1368        wxString s(sTexts[(0 != summary) ? 19 : 20]);
1369	tAllowed->SetLabel(s);
1370	if (0 != summary) {
1371	  tAllowed->SetForegroundColour(cGreen);
1372	} else {
1373	  tAllowed->SetForegroundColour(cRed);
1374	}
1375        back = true;				$? ". update for summary"
1376      }
1377      if (force) {
1378	lStatus->SetLabel(sNlWx[5]);
1379        switch (iState) {
1380          case WXPQDIC_STATE_TIMEOUT :
1381          case WXPQDIC_STATE_SEND_FAILED :
1382          {
1383            lStatus->SetForegroundColour(cBlack);
1384          } break;
1385        }
1386      }
1387      /*	Save values for later comparisons
1388      */
1389      uLimit   = limit;
1390      uUsed    = used;
1391      uAccount = account;
1392      iSummary = summary;
1393      bFirstResponse = false;
1394      /*	Change state
1395      */
1396      iState = WXPQDIC_STATE_OK;
1397      found = true;
1398    }
1399#if TRACE_DEBUG
1400    else {					$? "! processing failed"
1401    }
1402#endif
1403  }
1404#if TRACE_DEBUG
1405  else {				$? "! not 4 tokens"
1406  }
1407#endif
1408  $? "- ProcessResponse %d", ((back) ? (1) : (0))
1409  return back;
1410}
1411
1412
1413
1414bool
1415WxpqdicFrame::RetrieveResponse(void)
1416{
1417  dk4_sockaddr_storage_t	 remaddr;		/* Source address */
1418  size_t	 		 sz;			/* Buffer size */
1419  size_t	 		 szrema;		/* Address size */
1420  int				 res;			/* Conversion result */
1421  bool				 back	= false;
1422  bool				 found	= false;	/* Flag: Found */
1423  $? "+ RetrieveResponse"
1424  sz = szResponse;
1425  szrema = sizeof(remaddr);
1426  res = dk4socket_recvfrom(
1427    sock, bResponse, &sz, 0,
1428    (struct sockaddr *)(&remaddr), &szrema,
1429    0L, 10000L, NULL
1430  );
1431  switch (res) {
1432    case DK4_SOCKET_RESULT_SUCCESS :
1433    case DK4_SOCKET_RESULT_IN_PROGRESS :
1434    {					$? ". data"
1435      if (0 < sz) {				$? ". data length"
1436	bResponse[(szResponse > sz) ? (sz) : (szResponse - 1)] = '\0';
1437#if TRACE_DEBUG
1438	dk4str8_delnl(bResponse);	$? ". response = \"%!8s\"", bResponse
1439#endif
1440	if (1 /* ##### TODO: Compare addresses */ ) { $? ". addr ok"
1441	  back = ProcessResponse(found);
1442	}
1443#if TRACE_DEBUG
1444	else {				$? "! addr mismatch"
1445	}
1446#endif
1447      }
1448#if TRACE_DEBUG
1449      else {				$? "! data length 0"
1450      }
1451#endif
1452    } break;
1453    default : {				$? ". no data"
1454    } break;
1455  }
1456  if (!(found)) {
1457    if (WXPQDIC_STATE_SENDED == iState) {
1458      iState = WXPQDIC_STATE_TIMEOUT;
1459      tLimit->SetLabel(sTexts[27]);
1460      tUsed->SetLabel(sTexts[27]);
1461      tAccount->SetLabel(sTexts[27]);
1462      tAllowed->SetLabel(sTexts[27]);
1463      tAllowed->SetForegroundColour(cBlack);
1464      lStatus->SetLabel(sTexts[29]);
1465      lStatus->SetForegroundColour(cRed);
1466      back = true;
1467    }
1468  }
1469  $? "- RetrieveResponse %d", ((back) ? (1) : (0))
1470  return back;
1471}
1472
1473
1474
1475bool
1476WxpqdicFrame::SendRequest(bool force)
1477{
1478  dk4_time_t	 currenttime	= (dk4_time_t)0UL;
1479  size_t	 sz		= 0;
1480  int		 res		= 0;
1481  bool		 mustsend	= false;
1482  bool		 back		= false;
1483  $? "+ SendRequest"
1484  if ((dk4_time_t)0UL == tRequestSended) {
1485    mustsend = true;
1486  } else {
1487    if (force) {
1488      mustsend = true;
1489    } else {
1490      dk4time_get(&currenttime);
1491      if ((tRequestSended + (dk4_time_t)lUpdateInterval) <= currenttime) {
1492        mustsend = true;
1493      }
1494    }
1495  }
1496  if (mustsend) {					$? ". must send"
1497    sz = szRequest;
1498    if ((dk4_um_t)0UL == currenttime) {
1499      dk4time_get(&currenttime);
1500    }
1501    res = dk4socket_sendto(
1502      sock, pRequest, &sz, 0,
1503      (struct sockaddr *)(&(aAddresses[0])), sizeof(dk4_sockaddr_storage_t),
1504      0L, 0L, NULL
1505    );
1506    tRequestSended = currenttime;
1507    switch (res) {
1508      case DK4_SOCKET_RESULT_SUCCESS :
1509      case DK4_SOCKET_RESULT_IN_PROGRESS :
1510      {							$? ". success, sended"
1511        switch (iState) {
1512	  case WXPQDIC_STATE_OK : {
1513	    iState = WXPQDIC_STATE_SENDED;
1514	  } break;
1515	}
1516      } break;
1517      default : {					$? "! send"
1518        if (WXPQDIC_STATE_SEND_FAILED != iState) {
1519          tLimit->SetLabel(sTexts[27]);
1520	  tUsed->SetLabel(sTexts[27]);
1521	  tAccount->SetLabel(sTexts[27]);
1522	  tAllowed->SetLabel(sTexts[27]);
1523	  lStatus->SetLabel(sTexts[28]);
1524	  lStatus->SetForegroundColour(cRed);
1525	  back = true;
1526	}
1527        iState = WXPQDIC_STATE_SEND_FAILED;
1528      } break;
1529    }
1530  }
1531#if TRACE_DEBUG
1532  else {						$? ". no need to send"
1533  }
1534#endif
1535  $? "- SendRequest %d", ((back) ? (1) : (0))
1536  return back;
1537}
1538
1539
1540
1541void
1542WxpqdicFrame::OnRun(wxCommandEvent & WXUNUSED(event))
1543{
1544  bool	mustUpdate	= false;
1545  $? "+ OnRun"
1546  {
1547    wxCriticalSectionLocker	lockCsProtect(csProtect);
1548    if (bIsInitialized) {
1549      mustUpdate = SendRequest(true);
1550    }
1551  }
1552  if (mustUpdate) {
1553    Refresh();
1554    Update();
1555  }
1556  $? "- OnRun"
1557}
1558
1559
1560
1561bool
1562WxpqdicFrame::DataExchangeWithServer(void)
1563{
1564  bool		 back	=  false;
1565  $? "+ DataExchangeWithServer"
1566  if (RetrieveResponse()) {
1567    back = true;
1568  }
1569  if (SendRequest()) {
1570    back = true;
1571  }
1572  $? "- DataExchangeWithServer %d", ((back) ? (1) : (0))
1573  return back;
1574}
1575
1576