1 /*
2 Copyright (C) 2013-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: WinprintFrame.wxc
12 */
13
14 /** @file WinprintFrame.cpp The WinprintFrame module.
15 */
16
17
18 #include "dk3conf.h"
19 #include <winprint/winprint.h>
20 #if 0
21 #include <libdk3c/dkt-version.h>
22 #endif
23 #include <libdk4wx/dk4verswx.h>
24 #include "gui-img/shared/toolbar/run-conversion.xpm"
25 #include "gui-img/shared/toolbar/exit-program.xpm"
26
27
28 #if !defined(__WXMSW__)
29 #include "gui-img/icons/winprint.xpm"
30 #endif
31
32
33
34
35
36
37
38 /* __CHANGE__ 017: Add further events. */
39 /* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
40
41 #if wxCHECK_VERSION(3,0,0)
42 wxBEGIN_EVENT_TABLE(WinprintFrame,wxFrame)
43 #else
44 BEGIN_EVENT_TABLE(WinprintFrame,wxFrame)
45 #endif
46 EVT_MENU(WinprintFrame_Quit, WinprintFrame::OnQuit)
47 EVT_MENU(WinprintFrame_Print, WinprintFrame::OnPrint)
48 EVT_MENU(WinprintFrame_Help_About, WinprintFrame::OnAbout)
49 EVT_MENU(WinprintFrame_Help_Contents, WinprintFrame::OnHelpContents)
50 EVT_IDLE(WinprintFrame::OnIdle)
51 #if wxCHECK_VERSION(3,0,0)
52 wxEND_EVENT_TABLE()
53 #else
54 END_EVENT_TABLE()
55 #endif
56
57
58
59 #if __GNUC__
60 #pragma GCC diagnostic push
61 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
62 #endif
63
64 static const wxCmdLineEntryDesc winprint_cmd_line_desc[] = {
65 {
66 wxCMD_LINE_OPTION,
67 wxT_2("P"),
68 wxT_2("printer"),
69 wxT_2("choose printer"),
70 wxCMD_LINE_VAL_STRING
71 },
72 {
73 wxCMD_LINE_SWITCH,
74 wxT_2("d"),
75 wxT_2("default"),
76 wxT_2("Use default printer")
77 },
78 {
79 wxCMD_LINE_PARAM,
80 NULL,
81 NULL,
82 wxT_2("input file"),
83 wxCMD_LINE_VAL_STRING,
84 wxCMD_LINE_PARAM_OPTIONAL
85 },
86 { wxCMD_LINE_NONE }
87 };
88
89 #if __GNUC__
90 #pragma GCC diagnostic pop
91 #endif
92
93
WinprintFrame(int wxid,DkWxAppHelper * applicationHelper,DkWxHelpController * hc,int argc,wxChar ** argv,wxChar const * const * localizedTexts,wxChar const * const * nlWx,dkChar const * const * nlDk,dk3_print_conf_t * pPrintConf,DK3_PCWXCHAR * printerNames,size_t numberOfPrinters,int defaultPrinterIndex)94 WinprintFrame::WinprintFrame(
95 int wxid,
96 DkWxAppHelper *applicationHelper,
97 DkWxHelpController *hc,
98 int argc,
99 wxChar **argv,
100 wxChar const * const *localizedTexts,
101 wxChar const * const *nlWx,
102 dkChar const * const *nlDk,
103 dk3_print_conf_t *pPrintConf,
104 DK3_PCWXCHAR *printerNames,
105 size_t numberOfPrinters,
106 int defaultPrinterIndex
107 ) : DkWxFrame(nlWx[0], applicationHelper, hc, wxid),
108 cBlack(0, 0, 0),
109 cGreen(0, 127, 0),
110 cRed(127, 0, 0)
111 {
112 /* __CHANGE__ 012: Add further local variables.
113 */
114 size_t i; /* Traverse pNames when creating wxsNames. */
115
116 /* __CHANGE__ 012: Initialize further local variables.
117 */
118 fdx = -1; fdy = -1;
119 pcx = -1; pcy = -1;
120 wxsNames = NULL;
121 pNames = printerNames;
122 nNames = numberOfPrinters;
123 nDefPrinter = defaultPrinterIndex;
124 pComm = NULL;
125 bCloseScheduled = false;
126 bAutostartWanted = false;
127 timeClose = (dk3_time_t)0UL;
128 sNamedFile = NULL;
129 sNamedPrinter = NULL;
130 bUseDefaultPrinter = false;
131 sTexts = localizedTexts;
132 sNlWx = nlWx;
133 sNlDk = nlDk;
134 pc = pPrintConf;
135 #if defined(__WXMSW__)
136 wxIcon winprint_icon(sNlWx[4]);
137 #else
138 wxIcon winprint_icon(winprint_xpm);
139 #endif
140 /* __CHANGE__ 011: Initialize further class members.
141 */
142 dkctGUILayoutOK = false;
143 dkctGUIContentsPanel = NULL;
144 mainSizer = NULL;
145 tbMain = NULL;
146 mbMain = NULL;
147 bRun = NULL;
148 bExit = NULL;
149 menuFile = NULL;
150 menuHelp = NULL;
151 miFilePrint = NULL;
152 miFileExit = NULL;
153 miHelpAbout = NULL;
154 miHelpContents = NULL;
155 verticalSizer = NULL;
156 contentsSizer = NULL;
157 tStatus = NULL;
158 dkctGUIContentsPanel = new wxPanel(this);
159 if(!(dkctGUIContentsPanel)) {
160 goto dkctGUILayoutFinished;
161 }
162 #if wxUSE_MENUS
163 mbMain = new wxMenuBar(
164 );
165 if(!(mbMain)) {
166 goto dkctGUILayoutFinished;
167 }
168 menuFile = new wxMenu(
169 );
170 if(!(menuFile)) {
171 goto dkctGUILayoutFinished;
172 }
173 miFilePrint = menuFile->Append(
174 WinprintFrame_Print,
175 sTexts[15],
176 sTexts[16]
177 );
178 if(!(miFilePrint)) {
179 goto dkctGUILayoutFinished;
180 }
181 miFileExit = menuFile->Append(
182 WinprintFrame_Quit,
183 sTexts[1],
184 sTexts[2]
185 );
186 if(!(miFileExit)) {
187 goto dkctGUILayoutFinished;
188 }
189 mbMain->Append(menuFile, sTexts[0]);
190 menuHelp = new wxMenu(
191 );
192 if(!(menuHelp)) {
193 goto dkctGUILayoutFinished;
194 }
195 miHelpAbout = menuHelp->Append(
196 WinprintFrame_Help_About,
197 sTexts[4],
198 sTexts[5]
199 );
200 if(!(miHelpAbout)) {
201 goto dkctGUILayoutFinished;
202 }
203 miHelpContents = menuHelp->Append(
204 WinprintFrame_Help_Contents,
205 sTexts[6],
206 sTexts[7]
207 );
208 if(!(miHelpContents)) {
209 goto dkctGUILayoutFinished;
210 }
211 mbMain->Append(menuHelp, sTexts[3]);
212 SetMenuBar(mbMain);
213 #endif
214 #if wxUSE_TOOLBAR
215 tbMain = new wxToolBar(
216 this,
217 wxID_ANY
218 );
219 if(!(tbMain)) {
220 goto dkctGUILayoutFinished;
221 }
222 bRun = tbMain->AddTool(
223 WinprintFrame_Print,
224 sTexts[15],
225 xpm_run_conversion,
226 wxNullBitmap,
227 wxITEM_NORMAL,
228 sTexts[16]
229 );
230 if(!(bRun)) {
231 goto dkctGUILayoutFinished;
232 }
233 bExit = tbMain->AddTool(
234 WinprintFrame_Quit,
235 sTexts[1],
236 xpm_exit_program,
237 wxNullBitmap,
238 wxITEM_NORMAL,
239 sTexts[2]
240 );
241 if(!(bExit)) {
242 goto dkctGUILayoutFinished;
243 }
244 tbMain->Realize();
245 SetToolBar(tbMain);
246 #endif
247 mainSizer = new wxBoxSizer(
248 wxHORIZONTAL
249 );
250 if(!(mainSizer)) {
251 goto dkctGUILayoutFinished;
252 }
253 mainSizer->Add(10, 10, 0);
254 verticalSizer = new wxBoxSizer(
255 wxVERTICAL
256 );
257 if(!(verticalSizer)) {
258 goto dkctGUILayoutFinished;
259 }
260 verticalSizer->Add(10, 10, 0);
261 contentsSizer = new wxGridBagSizer(
262 5, 5
263 );
264 if(!(contentsSizer)) {
265 goto dkctGUILayoutFinished;
266 }
267 tStatus = new wxStaticText(
268 dkctGUIContentsPanel,
269 wxID_ANY,
270 sTexts[13]
271 );
272 if(!(tStatus)) {
273 goto dkctGUILayoutFinished;
274 }
275 contentsSizer->Add(
276 tStatus,
277 wxGBPosition(0, 0),
278 wxGBSpan(1, 1),
279 wxALIGN_LEFT
280 );
281 verticalSizer->Add(
282 contentsSizer
283 );
284 verticalSizer->Add(10, 10, 0);
285 mainSizer->Add(
286 verticalSizer,
287 1,
288 wxGROW
289 );
290 mainSizer->Add(10, 10, 0);
291 dkctGUIContentsPanel->SetSizer(mainSizer);
292 SetIcon(winprint_icon);
293 dkctGUILayoutOK = true;
294 dkctGUILayoutFinished:
295 #if wxUSE_STATUSBAR
296 if(dkctGUILayoutOK) {
297 CreateStatusBar(1);
298 SetStatusText(sTexts[8]);
299 }
300 #endif
301 if(dkctGUILayoutOK) {
302 mainSizer->Fit(this);
303 mainSizer->SetSizeHints(this);
304 }
305 if(dkctGUILayoutOK) {
306 SetTitle(nlWx[0]);
307 }
308 if((pNames) && (nNames > 0)) {
309 wxsNames = new wxString[nNames];
310 if(wxsNames) {
311 for(i = 0; i < nNames; i++) {
312 wxsNames[i] = wxString(pNames[i]);
313 }
314 }
315 }
316 pComm = new DkWxCommunicator(
317 applicationHelper->getWxEncoding(),
318 applicationHelper->getDkEncoding()
319 );
320 if(argc > 1) {
321 bAutostartWanted = true;
322 {
323 wxChar const *ptr;
324 int res = -1;
325 wxCmdLineParser parser(winprint_cmd_line_desc, argc, argv);
326 {
327 wxLogNull log;
328 res = parser.Parse(false);
329 }
330 if(0 == res) {
331 wxString sPrinter(wxT(""));
332 if(pComm) {
333 pComm->autostartEnable(true);
334 }
335 if(parser.Found(wxT("d"))) {
336 /* Use default printer */
337 bUseDefaultPrinter = true;
338 } else {
339 if(parser.Found(wxT("P"), &sPrinter)) {
340 /* Use named printer */
341 wxCStrData printerstrdata = sPrinter.c_str();
342 ptr = (wxChar const *)printerstrdata;
343 if(ptr) {
344 if(sNamedPrinter) {
345 dk3_release(sNamedPrinter);
346 }
347 sNamedPrinter = dk3wxs_dup(ptr);
348 }
349 }
350 }
351 if(parser.GetParamCount() > 0) {
352 wxString cmdfn;
353 wxString fullPath;
354 /* Print named file(s) */
355 cmdfn = parser.GetParam(0);
356 wxFileName fn(cmdfn);
357 fn.Normalize(
358 wxPATH_NORM_LONG | wxPATH_NORM_DOTS
359 | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
360 );
361 fullPath = fn.GetFullPath();
362 wxCStrData fullpathstrdata = fullPath.c_str();
363 ptr = (wxChar const *)fullpathstrdata;
364 if(ptr) {
365 if(sNamedFile) {
366 dk3_release(sNamedFile);
367 }
368 sNamedFile = dk3wxs_dup(ptr);
369 }
370 }
371 }
372 }
373 }
374 }
375
376
377
378
379
380
~WinprintFrame()381 WinprintFrame::~WinprintFrame()
382 {
383 size_t i; /* Index of current string to delete. */
384 /* __CHANGE__ 011: Release resources allocated by further class members.
385 */
386 if(wxsNames) {
387 for(i = 0; i < nNames; i++) {
388 wxsNames[i] = wxString(wxT(""));
389 }
390 delete [] wxsNames;
391 }
392 dk3_cpp_release(pComm);
393 if(sNamedPrinter) {
394 dk3_release(sNamedPrinter);
395 sNamedPrinter = NULL;
396 }
397 if(sNamedFile) {
398 dk3_release(sNamedFile);
399 sNamedFile = NULL;
400 }
401 }
402
403
404
405 bool
canClose(bool isLast)406 WinprintFrame::canClose(bool isLast)
407 {
408 bool back = true;
409
410 /* __CHANGE__ 013: Check for unsaved data.
411 */
412
413 return back;
414 }
415
416
417 void
OnQuit(wxCommandEvent & event)418 WinprintFrame::OnQuit(wxCommandEvent & event)
419 {
420 Close();
421 }
422
423
424
425 void
OnAbout(wxCommandEvent & event)426 WinprintFrame::OnAbout(wxCommandEvent & event)
427 {
428 wxString text(wxT("")); /* Text to show. */
429 wxString title(wxT("")); /* Windows title. */
430
431 /* Construct message text. */
432 text.Append(sNlWx[0]);
433 text.Append(sNlWx[7]);
434 #if 0
435 text.Append(sNlWx[1]);
436 #else
437 text.Append( DKT_VERSION_WX );
438 #endif
439 text.Append(sNlWx[8]);
440 text.Append(sTexts[9]);
441 text.Append(sNlWx[2]);
442 text.Append(sNlWx[8]);
443 text.Append(sNlWx[8]);
444 text.Append(sTexts[11]);
445 text.Append(sNlWx[8]);
446 text.Append(sNlWx[9]);
447 text.Append(sNlWx[8]);
448 text.Append(sNlWx[8]);
449 text.Append(sTexts[12]);
450 text.Append(sNlWx[8]);
451 text.Append(sNlWx[10]);
452 text.Append(sNlWx[8]);
453 text.Append(sNlWx[11]);
454 text.Append(sNlWx[8]);
455 text.Append(sNlWx[12]);
456 text.Append(sNlWx[8]);
457 text.Append(sNlWx[13]);
458 text.Append(sNlWx[8]);
459 text.Append(sNlWx[14]);
460 text.Append(sNlWx[8]);
461 text.Append(sNlWx[15]);
462 text.Append(sNlWx[8]);
463
464 /* Construct dialog box title. */
465 title.Append(sTexts[10]);
466 title.Append(sNlWx[0]);
467
468 /* Show dialog box. */
469 wxMessageBox(text, title, wxOK, this);
470
471 /* __CHANGE__ 019: Create better about box.
472 */
473 }
474
475
476
477 void
OnHelpContents(wxCommandEvent & event)478 WinprintFrame::OnHelpContents(wxCommandEvent & event)
479 {
480 openHelp();
481 }
482
483 /* __CHANGE__ 017: Event handlers for further events.
484 */
485
486 void
OnPrint(wxCommandEvent & event)487 WinprintFrame::OnPrint(wxCommandEvent & event)
488 {
489 (void)runJob();
490 }
491
492
493 /* __CHANGE__ 014: Implementation of further methods.
494 */
495
496
497 /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
498 */
499
500 void
OnIdle(wxIdleEvent & event)501 WinprintFrame::OnIdle(wxIdleEvent & event)
502 {
503 static BOOL firstIdle = true; /* Flag: First idle event of application. */
504 dk3_time_t ct; /* Current time. */
505 int res; /* Operation result. */
506
507 /* __CHANGE__
508 */
509 if(firstIdle) {
510 firstIdle = false;
511 tStatus->SetLabel(wxT(""));
512 Refresh();
513 Update();
514 /* For autostart */
515 event.RequestMore();
516 } else {
517 if(!bCloseScheduled) {
518 if(pComm) {
519 if((bAutostartWanted) && (pComm->autostartCanRun())) {
520
521 res = runJob();
522 if(res > 0) {
523 event.RequestMore();
524 }
525 } else {
526 if(pComm->autostartIsFinished()) {
527 if(!(timeClose)) {
528 if(pComm->getLogLevel() > DK3_LL_WARNING) {
529 dk3sf_time(&timeClose);
530 event.RequestMore();
531 tStatus->SetLabel(sTexts[14]);
532 tStatus->SetForegroundColour(cGreen);
533 Refresh();
534 Update();
535 } else {
536 tStatus->SetLabel(pComm->getText());
537 tStatus->SetForegroundColour(cRed);
538 Refresh();
539 Update();
540 wxMessageBox(
541 pComm->getText(), sTexts[29], (wxICON_ERROR | wxOK), this
542 );
543 dk3sf_time(&timeClose);
544 event.RequestMore();
545 }
546 }
547 }
548 if(timeClose) {
549 dk3sf_time(&ct);
550 if(ct > (timeClose + (dk3_time_t)1UL)) {
551 timeClose = (dk3_time_t)0UL;
552 bCloseScheduled = true;
553 Show(false);
554 Close();
555 } else {
556 event.RequestMore();
557 }
558 }
559 }
560 } else {
561 /* ERROR: No communicator */
562 if(timeClose) {
563 dk3sf_time(&ct);
564 if(ct > (timeClose * (dk3_time_t)1UL)) {
565 timeClose = (dk3_time_t)0UL;
566 bCloseScheduled = true;
567 Show(false);
568 Close();
569 } else {
570 event.RequestMore();
571 }
572 }
573 }
574 } else {
575 }
576 }
577 event.Skip();
578
579 }
580
581
582
583 int
runFileNameJob(wxChar const * filename)584 WinprintFrame::runFileNameJob(wxChar const *filename)
585 {
586 wxChar prbuf[512]; /* Printer name system enc */
587 wxChar const *printername = NULL; /* Printer name */
588 int res = 0; /* Operation result */
589 int ok = 0; /* Flag: Success */
590 int back = 0; /* Function result */
591
592 if(filename) {
593 if(bUseDefaultPrinter) {
594 if(pc) {
595 if(pc->defPrinter) {
596 if((pc->defPrinter->name)) {
597 res = dk3wxs_from_dkstr(
598 prbuf,
599 DK3_SIZEOF(prbuf,wxChar),
600 pHelper->getWxEncoding(),
601 (pc->defPrinter)->name,
602 pHelper->getDkEncoding()
603 );
604 if(res) {
605 printername = prbuf;
606 } else {
607 /* ERROR: Failed to convert printer name! */
608 setErrorStatus(sTexts[24], filename);
609 }
610 } else {
611 /* ERROR: No default printer name */
612 setErrorStatus(sTexts[25], filename);
613 }
614 } else {
615 /* ERROR: No default printer */
616 setErrorStatus(sTexts[25], filename);
617 }
618 } else {
619 /* ERROR: No print configuration */
620 setErrorStatus(sTexts[26], filename);
621 }
622 } else {
623 if(sNamedPrinter) {
624 printername = sNamedPrinter;
625 } else {
626 if((pNames) && (wxsNames) && (nNames > 0)) {
627 WinprintChooserDialog dlg(this, sTexts[30], sTexts, wxsNames, nNames);
628 dlg.setCurrentPrinter(nDefPrinter);
629 pHelper->setRelatedPosition(this, &dlg, &pcx, &pcy);
630 if(wxID_OK == dlg.ShowModal()) {
631 nDefPrinter = dlg.getCurrentPrinter();
632 if((nDefPrinter >= 0) && (nDefPrinter < (int)nNames)) {
633 printername = pNames[nDefPrinter];
634 } else {
635 /* BUG: Illegal return value from dialog */
636 setErrorStatus(sTexts[26], filename);
637 }
638 } else {
639 /* ERROR: Aborted by user */
640 setErrorStatus(sTexts[19], filename);
641 }
642 dlg.GetPosition(&pcx, &pcy);
643 } else {
644 /* ERROR: No printer configuration */
645 setErrorStatus(sTexts[26], filename);
646 }
647 }
648 }
649 } else {
650 }
651 if((filename) && (printername)) {
652 /* wxMessageBox(filename, printername); */
653 if(pComm) {
654 DkWxProgressDialog *pd;
655 pComm->prepareRun();
656 pd = new DkWxProgressDialog(
657 (DkWxFrame *)this,
658 pComm,
659 NULL,
660 sTexts[20],
661 filename,
662 sTexts[21],
663 sTexts[22],
664 sTexts[23]
665 );
666 if(pd) {
667 WinprintThread *pt;
668 pt = new WinprintThread(
669 pComm, sTexts, pHelper, pc, filename, printername
670 );
671 if(pt) {
672 if(wxTHREAD_NO_ERROR == pt->Create()) {
673 pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
674 pt->Run();
675 pd->chooseModalPosition();
676 pd->ShowModal();
677 ok = 1;
678 if(pComm->getLogLevel() <= DK3_LL_WARNING) {
679 /* ERRORS occured */
680 tStatus->SetLabel(pComm->getText());
681 tStatus->SetForegroundColour(cRed);
682 } else {
683 /* Transfer succeeeded */
684 if(!(bAutostartWanted)) {
685 tStatus->SetLabel(sTexts[37]);
686 tStatus->SetForegroundColour(cGreen);
687 }
688 }
689 Refresh();
690 Update();
691 back = 1;
692 } else {
693 /* ERROR: Create method failed! */
694 setErrorStatus(sTexts[27], filename);
695 }
696 } else {
697 /* ERROR: Failed to create thread */
698 setErrorStatus(sTexts[27], filename);
699 }
700 pd->Destroy();
701 } else {
702 /* ERROR: Failed to create progress dialog */
703 setErrorStatus(sTexts[28], filename);
704 }
705 } else {
706 /* ###### ERROR: No communicator */
707 }
708 } else {
709 if(pComm) {
710 if(!(filename)) {
711 }
712 if(!(printername)) {
713 }
714 } else {
715 /* ##### ERROR: No communicator */
716 }
717 }
718
719 return back;
720 }
721
722
723
724 int
runJob(void)725 WinprintFrame::runJob(void)
726 {
727 wxString path; /* File path. */
728 wxChar const *filename = NULL; /* File name. */
729 int back = 0;
730
731 tStatus->SetLabel(sTexts[17]);
732 tStatus->SetForegroundColour(cBlack);
733 Refresh();
734 Update();
735 if(sNamedFile) {
736 filename = sNamedFile;
737 back = runFileNameJob(filename);
738 } else {
739 wxString s(wxT(""));
740 s.Append(wxT("Print files (*.prn)|*.prn"));
741 s.Append(wxT("|All files (*.*)|*.*"));
742 #if wxCHECK_VERSION(2, 9, 0)
743 wxFileDialog dlg(this, sTexts[18], wxT("."), wxT(""), s, wxFD_OPEN);
744 #else
745 wxFileDialog dlg(this, sTexts[18], wxT("."), wxT(""), s, wxOPEN);
746 #endif
747 pHelper->setRelatedPosition(this, &dlg, &fdx, &fdy);
748 if(wxID_OK == dlg.ShowModal()) {
749 path = dlg.GetPath();
750 wxCStrData pathstrdata = path.c_str();
751 filename = (wxChar const *)pathstrdata;
752 if (NULL != filename) {
753 back = runFileNameJob(filename);
754 }
755 } else {
756 /* Aborted by user */
757 setErrorStatus(sTexts[19], NULL);
758 }
759 dlg.GetPosition(&fdx, &fdy);
760 }
761
762 return back;
763 }
764
765
766
767 void
setErrorStatus(wxChar const * txt,wxChar const * filename)768 WinprintFrame::setErrorStatus(wxChar const *txt, wxChar const *filename)
769 {
770 if(pComm) {
771 pComm->prepareRun();
772 pComm->addWxText(txt);
773 pComm->setLogLevel(DK3_LL_ERROR);
774 pComm->setUpdates(((filename) ? filename : wxT("")), 1000);
775 pComm->setRunning(0);
776 }
777 tStatus->SetLabel(txt);
778 tStatus->SetForegroundColour(cRed);
779 Refresh();
780 Update();
781 }
782
783
784