1 /*
2 Copyright (C) 2019-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: WximgszFrame.wxc
12 */
13
14 /** @file WximgszFrame.cpp The WximgszFrame module.
15 */
16
17
18 #include <wximgsz/wximgsz.h>
19
20
21 #if !defined(__WXMSW__)
22 #include "gui-img/icons/dkicon.xpm"
23 #endif
24
25
26 #include "gui-img/shared/toolbar/run-conversion.xpm"
27
28
29
30
31
32
33 /* __CHANGE__ 017: Add further events. */
34
35 /* Hint: Window IDs for main frame members are defined in an enum
36 in the frame class.
37 IDs defined in this enum should have WximgszFrame:: prepended
38 for an optical distinction from predefined window IDs (i.e. from
39 wxWidgets).
40 */
41
42 /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
43 When removing the table entry here, remove the entire OnIdle() method.
44 */
45
46 #if wxCHECK_VERSION(3,0,0)
47 wxBEGIN_EVENT_TABLE(WximgszFrame,wxFrame)
48 #else
49 BEGIN_EVENT_TABLE(WximgszFrame,wxFrame)
50 #endif
51 EVT_MENU(\
52 wxID_OPEN,\
53 WximgszFrame::OnFileOpen\
54 )
55 EVT_MENU(\
56 wxID_EXIT,\
57 WximgszFrame::OnQuit\
58 )
59 EVT_MENU(\
60 WximgszFrame::ID_HELP_ABOUT,\
61 WximgszFrame::OnAbout\
62 )
63 EVT_MENU(\
64 WximgszFrame::ID_HELP_TOC,\
65 WximgszFrame::OnHelpContents\
66 )
67 EVT_BUTTON(\
68 WximgszFrame::ID_BUTTON_RUN,\
69 WximgszFrame::OnButtonRun\
70 )
71 EVT_CHOICE(\
72 WximgszFrame::ID_CHOICE_OP,\
73 WximgszFrame::OnChoiceOperation\
74 )
75 EVT_IDLE(\
76 WximgszFrame::OnIdle\
77 )
78 #if wxCHECK_VERSION(3,0,0)
79 wxEND_EVENT_TABLE()
80 #else
81 END_EVENT_TABLE()
82 #endif
83
84
85
86 /** Image file types we can handle.
87 */
88 static wxChar const image_files_to_open[] = {
89 wxT("All files (*.*)|*.*")
90 #if wxUSE_LIBPNG
91 wxT("|PNG files (*.png)|*.png")
92 #endif
93 #if wxUSE_LIBJPEG
94 wxT("|JPEG files (*.jpeg)|*.jpeg")
95 wxT("|JPEG files (*.jpg)|*.jpg")
96 #endif
97 #if wxUSE_LIBTIFF
98 wxT("|TIFF files (*.tiff)|*.tiff")
99 wxT("|TIFF files (*.tif)|*.tif")
100 #endif
101 #if wxUSE_GIF
102 wxT("|GIF files (*.gif)|*.gif")
103 #endif
104 #if wxUSE_PCX
105 wxT("|PCX files (*.pcx)|*.pcx")
106 #endif
107 wxT("|BMP files (*.bmp)|*.bmp")
108 #if wxUSE_ICO_CUR
109 wxT("|ICO files (*.ico)|*.ico")
110 wxT("|CUR files (*.cur)|*.cur")
111 #endif
112 #if wxUSE_XPM
113 wxT("|XPM files (*.xpm)|*.xpm")
114 wxT("|XBM files (*.xbm)|*.xbm")
115 #endif
116 #if wxUSE_TGA
117 wxT("|TGA files (*.tga)|*.tga")
118 #endif
119 #if wxUSE_IFF
120 wxT("|IFF files (*.iff)|*.iff")
121 #endif
122 wxT("|ANI files (*.ani)|*.ani")
123 #if wxUSE_PNM
124 wxT("|NetPBM files (*.pam)|*.pam")
125 wxT("|NetPBM files (*.pnm)|*.pnm")
126 wxT("|NetPBM files (*.ppm)|*.ppm")
127 wxT("|NetPBM files (*.pgm)|*.pgm")
128 wxT("|NetPBM files (*.pbm)|*.pbm")
129 #endif
130 };
131
132
133 /** Suffix and bitmap type relationship.
134 */
135 typedef struct {
136 wxChar const *s; /**< File name suffix. */
137 wxBitmapType t; /**< Bitmap type. */
138 } Suffix_and_type_t;
139
140
141
142 /** Array to assign file name suffixes to file types.
143 */
144 Suffix_and_type_t suffix_and_type[] = {
145 #if wxUSE_LIBPNG
146 { wxT(".png"), wxBITMAP_TYPE_PNG },
147 #endif
148 #if wxUSE_LIBJPEG
149 { wxT(".jpeg"), wxBITMAP_TYPE_JPEG },
150 { wxT(".jpg"), wxBITMAP_TYPE_JPEG },
151 #endif
152 #if wxUSE_LIBTIFF
153 { wxT(".tiff"), wxBITMAP_TYPE_TIFF },
154 { wxT(".tif"), wxBITMAP_TYPE_TIF },
155 #endif
156 #if wxUSE_PNM
157 { wxT(".pam"), wxBITMAP_TYPE_PNM },
158 { wxT(".pnm"), wxBITMAP_TYPE_PNM },
159 { wxT(".ppm"), wxBITMAP_TYPE_PNM },
160 { wxT(".pgm"), wxBITMAP_TYPE_PNM },
161 { wxT(".pbm"), wxBITMAP_TYPE_PNM },
162 #endif
163 #if wxUSE_XPM
164 { wxT(".xpm"), wxBITMAP_TYPE_XPM },
165 { wxT(".xbm"), wxBITMAP_TYPE_XBM },
166 #endif
167 #if wxUSE_ICO_CUR
168 { wxT(".ico"), wxBITMAP_TYPE_ICO },
169 { wxT(".cur"), wxBITMAP_TYPE_CUR },
170 #endif
171 #if wxUSE_GIF
172 { wxT(".gif"), wxBITMAP_TYPE_GIF },
173 #endif
174 #if wxUSE_PCX
175 { wxT(".pcx"), wxBITMAP_TYPE_PCX },
176 #endif
177 { wxT(".bmp"), wxBITMAP_TYPE_BMP },
178 #if wxUSE_TGA
179 { wxT(".tga"), wxBITMAP_TYPE_TGA },
180 #endif
181 #if wxUSE_IFF
182 { wxT(".iff"), wxBITMAP_TYPE_IFF },
183 #endif
184 { wxT(".ani"), wxBITMAP_TYPE_ANI },
185 { NULL, wxBITMAP_TYPE_INVALID }
186 };
187
188
189
190 static
191 wxBitmapType
bitmap_type_for_name(wxString & fn)192 bitmap_type_for_name(wxString & fn)
193 {
194 wxChar const *ptr = NULL;
195 Suffix_and_type_t *sat = NULL;
196 wxBitmapType back = wxBITMAP_TYPE_INVALID;
197 wxCStrData strdata = fn.c_str();
198 ptr = (wxChar const *)strdata;
199 if (NULL != ptr) {
200 ptr = dk4strx_get_path_suffix(ptr, NULL);
201 if (NULL != ptr) {
202 sat = suffix_and_type;
203 while((NULL != sat->s) && (wxBITMAP_TYPE_INVALID == back)) {
204 if (0 == dk4strx_casecmp(sat->s, ptr)) {
205 back = sat->t;
206 }
207 else {
208 sat++;
209 }
210 }
211 }
212 }
213 return back;
214 }
215
216
217
WximgszFrame(int wxid,Dk4WxApplicationHelper * applicationHelper,Dk4WxHelpController * hc,int argc,wxChar ** argv,wxChar const * const * localizedTexts,wxChar const * const * nlWx,dkChar const * const * nlDk)218 WximgszFrame::WximgszFrame(
219 int wxid,
220 Dk4WxApplicationHelper *applicationHelper,
221 Dk4WxHelpController *hc,
222 int argc,
223 wxChar **argv,
224 wxChar const * const *localizedTexts,
225 wxChar const * const *nlWx,
226 dkChar const * const *nlDk
227 ) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid),
228 cas(),
229 cLabelRed(127, 0, 0),
230 cRed(255, 91, 91),
231 cGreen(127, 255, 127),
232 cYellow(255, 255, 0),
233 cBlack(0, 0, 0),
234 sImageFileName((1 < argc)?(argv[1]):(wxT(""))),
235 sDirectory(wxEmptyString)
236 {
237 wxString saOperation[] = {
238 wxString(localizedTexts[21]),
239 wxString(localizedTexts[22]),
240 wxString(localizedTexts[23])
241 };
242
243 /* __CHANGE__ 012: Add further local variables.
244 */
245
246 /* __CHANGE__ 012: Initialize further local variables.
247 */
248
249 sTexts = localizedTexts;
250 sNlWx = nlWx;
251 sNlDk = nlDk;
252 #if defined(__WXMSW__)
253 wxIcon wximgsz_icon(sNlWx[4]);
254 #else
255 wxIcon wximgsz_icon(xpm_dkicon);
256 #endif
257
258 /* __CHANGE__ 011: Initialize further class members.
259 */
260 maxpass = MAXPASS;
261 bActive = false;
262 bImageFileName = false;
263 if (1 < argc) {
264 bImageFileName = true;
265 cas.SetAutoStart();
266 }
267
268 dkctGUILayoutOK = false;
269 dkctGUIContentsPanel = NULL;
270 mainSizer = NULL;
271 mbMain = NULL;
272 menuFile = NULL;
273 menuHelp = NULL;
274 miFileOpen = NULL;
275 miFileExit = NULL;
276 miHelpAbout = NULL;
277 miHelpContents = NULL;
278 verticalSizer = NULL;
279 contentsSizer = NULL;
280 inputSizer = NULL;
281 runButtonSizer = NULL;
282 resultSizer = NULL;
283 lInput = NULL;
284 lInputWidth = NULL;
285 spInputWidth = NULL;
286 lInputHeight = NULL;
287 spInputHeight = NULL;
288 lChange = NULL;
289 lOperation = NULL;
290 cbOperation = NULL;
291 lOperationMin = NULL;
292 spOperationMin = NULL;
293 lOperationMax = NULL;
294 spOperationMax = NULL;
295 bRun = NULL;
296 lResults = NULL;
297 tResult = NULL;
298 dkctGUIContentsPanel = new wxPanel(this);
299 if(!(dkctGUIContentsPanel)) {
300 goto dkctGUILayoutFinished;
301 }
302 #if wxUSE_MENUS
303 mbMain = new wxMenuBar(
304 );
305 if(!(mbMain)) {
306 goto dkctGUILayoutFinished;
307 }
308 menuFile = new wxMenu(
309 );
310 if(!(menuFile)) {
311 goto dkctGUILayoutFinished;
312 }
313 miFileOpen = menuFile->Append(
314 wxID_OPEN,
315 sTexts[40],
316 sTexts[41]
317 );
318 if(!(miFileOpen)) {
319 goto dkctGUILayoutFinished;
320 }
321 miFileExit = menuFile->Append(
322 wxID_EXIT,
323 sTexts[1],
324 sTexts[2]
325 );
326 if(!(miFileExit)) {
327 goto dkctGUILayoutFinished;
328 }
329 mbMain->Append(menuFile, sTexts[0]);
330 menuHelp = new wxMenu(
331 );
332 if(!(menuHelp)) {
333 goto dkctGUILayoutFinished;
334 }
335 miHelpAbout = menuHelp->Append(
336 WximgszFrame::ID_HELP_ABOUT,
337 sTexts[4],
338 sTexts[5]
339 );
340 if(!(miHelpAbout)) {
341 goto dkctGUILayoutFinished;
342 }
343 miHelpContents = menuHelp->Append(
344 WximgszFrame::ID_HELP_TOC,
345 sTexts[6],
346 sTexts[7]
347 );
348 if(!(miHelpContents)) {
349 goto dkctGUILayoutFinished;
350 }
351 mbMain->Append(menuHelp, sTexts[3]);
352 SetMenuBar(mbMain);
353 #endif
354 mainSizer = new wxBoxSizer(
355 wxHORIZONTAL
356 );
357 if(!(mainSizer)) {
358 goto dkctGUILayoutFinished;
359 }
360 mainSizer->Add(10, 10, 0);
361 verticalSizer = new wxBoxSizer(
362 wxVERTICAL
363 );
364 if(!(verticalSizer)) {
365 goto dkctGUILayoutFinished;
366 }
367 verticalSizer->Add(10, 10, 0);
368 contentsSizer = new wxBoxSizer(
369 wxHORIZONTAL
370 );
371 if(!(contentsSizer)) {
372 goto dkctGUILayoutFinished;
373 }
374 inputSizer = new wxGridBagSizer(
375 5, 5
376 );
377 if(!(inputSizer)) {
378 goto dkctGUILayoutFinished;
379 }
380 lInput = new wxStaticText(
381 dkctGUIContentsPanel,
382 wxID_ANY,
383 sTexts[13]
384 );
385 if(!(lInput)) {
386 goto dkctGUILayoutFinished;
387 }
388 inputSizer->Add(
389 lInput,
390 wxGBPosition(0, 0),
391 wxGBSpan(1, 2),
392 wxALIGN_LEFT
393 );
394 lInputWidth = new wxStaticText(
395 dkctGUIContentsPanel,
396 wxID_ANY,
397 sTexts[14]
398 );
399 if(!(lInputWidth)) {
400 goto dkctGUILayoutFinished;
401 }
402 inputSizer->Add(
403 lInputWidth,
404 wxGBPosition(1, 0),
405 wxGBSpan(1, 1),
406 wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
407 );
408 spInputWidth = new wxSpinCtrl(
409 dkctGUIContentsPanel,
410 wxID_ANY,
411 wxEmptyString,
412 wxDefaultPosition,
413 wxDefaultSize,
414 0,
415 1,
416 65535,
417 1
418 );
419 if(!(spInputWidth)) {
420 goto dkctGUILayoutFinished;
421 }
422 spInputWidth->SetToolTip(sTexts[16]);
423 inputSizer->Add(
424 spInputWidth,
425 wxGBPosition(1, 1),
426 wxGBSpan(1, 1),
427 wxALIGN_CENTER_VERTICAL
428 );
429 lInputHeight = new wxStaticText(
430 dkctGUIContentsPanel,
431 wxID_ANY,
432 sTexts[15]
433 );
434 if(!(lInputHeight)) {
435 goto dkctGUILayoutFinished;
436 }
437 inputSizer->Add(
438 lInputHeight,
439 wxGBPosition(2, 0),
440 wxGBSpan(1, 1),
441 wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
442 );
443 spInputHeight = new wxSpinCtrl(
444 dkctGUIContentsPanel,
445 wxID_ANY,
446 wxEmptyString,
447 wxDefaultPosition,
448 wxDefaultSize,
449 0,
450 1,
451 65535,
452 1
453 );
454 if(!(spInputHeight)) {
455 goto dkctGUILayoutFinished;
456 }
457 spInputHeight->SetToolTip(sTexts[17]);
458 inputSizer->Add(
459 spInputHeight,
460 wxGBPosition(2, 1),
461 wxGBSpan(1, 1),
462 wxALIGN_CENTER_VERTICAL
463 );
464 inputSizer->Add(10, 10, wxGBPosition(3, 0), wxGBSpan(1, 1));
465 lChange = new wxStaticText(
466 dkctGUIContentsPanel,
467 wxID_ANY,
468 sTexts[18]
469 );
470 if(!(lChange)) {
471 goto dkctGUILayoutFinished;
472 }
473 inputSizer->Add(
474 lChange,
475 wxGBPosition(4, 0),
476 wxGBSpan(1, 2),
477 wxALIGN_LEFT
478 );
479 lOperation = new wxStaticText(
480 dkctGUIContentsPanel,
481 wxID_ANY,
482 sTexts[19]
483 );
484 if(!(lOperation)) {
485 goto dkctGUILayoutFinished;
486 }
487 inputSizer->Add(
488 lOperation,
489 wxGBPosition(5, 0),
490 wxGBSpan(1, 1),
491 wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
492 );
493 cbOperation = new wxChoice(
494 dkctGUIContentsPanel,
495 ID_CHOICE_OP,
496 wxDefaultPosition,
497 wxDefaultSize,
498 3,
499 saOperation
500 );
501 if(!(cbOperation)) {
502 goto dkctGUILayoutFinished;
503 }
504 cbOperation->SetToolTip(sTexts[20]);
505 inputSizer->Add(
506 cbOperation,
507 wxGBPosition(5, 1),
508 wxGBSpan(1, 1),
509 wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
510 );
511 lOperationMin = new wxStaticText(
512 dkctGUIContentsPanel,
513 wxID_ANY,
514 sTexts[24]
515 );
516 if(!(lOperationMin)) {
517 goto dkctGUILayoutFinished;
518 }
519 inputSizer->Add(
520 lOperationMin,
521 wxGBPosition(6, 0),
522 wxGBSpan(1, 1),
523 wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
524 );
525 spOperationMin = new wxSpinCtrl(
526 dkctGUIContentsPanel,
527 wxID_ANY,
528 wxEmptyString,
529 wxDefaultPosition,
530 wxDefaultSize,
531 0,
532 1,
533 65535,
534 1
535 );
536 if(!(spOperationMin)) {
537 goto dkctGUILayoutFinished;
538 }
539 spOperationMin->SetToolTip(sTexts[26]);
540 inputSizer->Add(
541 spOperationMin,
542 wxGBPosition(6, 1),
543 wxGBSpan(1, 1),
544 wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
545 );
546 lOperationMax = new wxStaticText(
547 dkctGUIContentsPanel,
548 wxID_ANY,
549 sTexts[25]
550 );
551 if(!(lOperationMax)) {
552 goto dkctGUILayoutFinished;
553 }
554 inputSizer->Add(
555 lOperationMax,
556 wxGBPosition(7, 0),
557 wxGBSpan(1, 1),
558 wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
559 );
560 spOperationMax = new wxSpinCtrl(
561 dkctGUIContentsPanel,
562 wxID_ANY,
563 wxEmptyString,
564 wxDefaultPosition,
565 wxDefaultSize,
566 0,
567 1,
568 65535,
569 1
570 );
571 if(!(spOperationMax)) {
572 goto dkctGUILayoutFinished;
573 }
574 spOperationMax->SetToolTip(sTexts[27]);
575 inputSizer->Add(
576 spOperationMax,
577 wxGBPosition(7, 1),
578 wxGBSpan(1, 1),
579 wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
580 );
581 contentsSizer->Add(
582 inputSizer
583 );
584 contentsSizer->Add(20, 20, 0);
585 runButtonSizer = new wxBoxSizer(
586 wxVERTICAL
587 );
588 if(!(runButtonSizer)) {
589 goto dkctGUILayoutFinished;
590 }
591 runButtonSizer->Add(10, 10, 1);
592 bRun = new wxBitmapButton(
593 dkctGUIContentsPanel,
594 ID_BUTTON_RUN,
595 xpm_run_conversion
596 );
597 if(!(bRun)) {
598 goto dkctGUILayoutFinished;
599 }
600 bRun->SetToolTip(sTexts[29]);
601 runButtonSizer->Add(
602 bRun
603 );
604 runButtonSizer->Add(10, 10, 1);
605 contentsSizer->Add(
606 runButtonSizer,
607 0,
608 wxGROW
609 );
610 contentsSizer->Add(20, 20, 0);
611 resultSizer = new wxBoxSizer(
612 wxVERTICAL
613 );
614 if(!(resultSizer)) {
615 goto dkctGUILayoutFinished;
616 }
617 lResults = new wxStaticText(
618 dkctGUIContentsPanel,
619 wxID_ANY,
620 sTexts[28]
621 );
622 if(!(lResults)) {
623 goto dkctGUILayoutFinished;
624 }
625 resultSizer->Add(
626 lResults,
627 0,
628 wxALIGN_LEFT
629 );
630 tResult = new wxGrid(
631 dkctGUIContentsPanel,
632 wxID_ANY
633 );
634 if(!(tResult)) {
635 goto dkctGUILayoutFinished;
636 }
637 tResult->CreateGrid(4, 4);
638 tResult->SetColLabelValue(0, sTexts[30]);
639 tResult->SetColLabelValue(1, sTexts[31]);
640 tResult->SetColLabelValue(2, sTexts[32]);
641 tResult->SetColLabelValue(3, sTexts[33]);
642 tResult->EnableEditing(false);
643 resultSizer->Add(
644 tResult,
645 1,
646 wxALIGN_LEFT|wxGROW
647 );
648 contentsSizer->Add(
649 resultSizer,
650 1,
651 wxGROW
652 );
653 verticalSizer->Add(
654 contentsSizer,
655 1,
656 wxGROW
657 );
658 verticalSizer->Add(10, 10, 0);
659 mainSizer->Add(
660 verticalSizer,
661 1,
662 wxGROW
663 );
664 mainSizer->Add(10, 10, 0);
665 dkctGUIContentsPanel->SetSizer(mainSizer);
666 SetIcon(wximgsz_icon);
667 dkctGUILayoutOK = true;
668 dkctGUILayoutFinished:
669 #if wxUSE_STATUSBAR
670 if(dkctGUILayoutOK) {
671 CreateStatusBar(1);
672 SetStatusText(sTexts[8]);
673 }
674 #endif
675 if(dkctGUILayoutOK) {
676 mainSizer->Fit(this);
677 mainSizer->SetSizeHints(this);
678 }
679 if(dkctGUILayoutOK) {
680 lInput->SetForegroundColour(cLabelRed);
681 lChange->SetForegroundColour(cLabelRed);
682 lResults->SetForegroundColour(cLabelRed);
683 #if 0
684 spInputWidth->SetRange(1, INT_MAX);
685 spInputHeight->SetRange(1, INT_MAX);
686 spOperationMin->SetRange(1, INT_MAX);
687 spOperationMax->SetRange(1, INT_MAX);
688 inputSizer->Fit(spInputWidth);
689 inputSizer->Fit(spInputHeight);
690 inputSizer->Fit(spOperationMin);
691 inputSizer->Fit(spOperationMax);
692 mainSizer->Layout();
693 #endif
694 cbOperation->SetSelection(0);
695 spOperationMin->Enable(false);
696 spOperationMax->Enable(false);
697 SetTitle(nlWx[0]);
698 #if 0
699 RestorePosition();
700 #endif
701 }
702
703 /* __CHANGE__ 012: Release resources allocated by local variables.
704 */
705
706
707 }
708
709
710
711
~WximgszFrame()712 WximgszFrame::~WximgszFrame()
713 {
714
715
716 /* __CHANGE__ 011: Release resources allocated by further class members.
717 */
718
719
720 }
721
722
723
724 bool
CanClose(bool WXUNUSED (isLast))725 WximgszFrame::CanClose(bool WXUNUSED(isLast))
726 {
727 bool back = true;
728
729
730 /* __CHANGE__ 013: Check for unsaved data.
731 And probably change parameter to "bool WXUNUSED(isLast)"
732 */
733
734
735 return back;
736 }
737
738
739
740 void
OnFileOpen(wxCommandEvent & WXUNUSED (event))741 WximgszFrame::OnFileOpen(wxCommandEvent & WXUNUSED(event))
742 {
743 dkChar buf[DK4_MAX_PATH];
744 dk4_bif_t *pbif;
745 const wxChar *ptrFilePath;
746 bool success = false;
747 int dke;
748 int wxe;
749 int res;
750 #if wxCHECK_VERSION(2, 9, 0)
751 wxFileDialog dlg(
752 this, sTexts[42], sDirectory, wxEmptyString,
753 image_files_to_open, (wxFD_OPEN | wxFD_FILE_MUST_EXIST)
754 );
755 #else
756 wxFileDialog dlg(
757 this, sTexts[42], sDirectory, wxEmptyString,
758 image_files_to_open, wxOPEN
759 );
760 #endif
761
762 if(wxID_OK == dlg.ShowModal()) {
763 wxString pa = dlg.GetPath();
764 wxFileName wxfn(pa);
765 if (wxfn.FileExists() && wxfn.IsFileReadable()) {
766 sDirectory = dlg.GetDirectory();
767 {
768 wxCStrData sFilePath = pa.c_str();
769 ptrFilePath = (wxChar const *)sFilePath;
770 if (NULL != ptrFilePath) {
771 dke = pAppHelp->GetDkEncoding();
772 wxe = pAppHelp->GetWxEncoding();
773 res = dk4recwx_wxchar_to_dkchar(
774 buf, DK4_SIZEOF(buf,dkChar), dke, ptrFilePath, wxe, NULL
775 );
776 if (0 != res) {
777 pbif = dk4bif_open(buf, 1, NULL, NULL);
778 if (NULL != pbif) {
779 dk4_bif_dim_t w = dk4bif_get_width(pbif);
780 dk4_bif_dim_t h = dk4bif_get_height(pbif);
781 if (
782 ((dk4_im_t)0L < (dk4_im_t)w)
783 && ((dk4_im_t)0L < (dk4_im_t)h)
784 && ((dk4_im_t)(MAXIMGDIM) >= (dk4_im_t)w)
785 && ((dk4_im_t)(MAXIMGDIM) >= (dk4_im_t)h)
786 ) {
787 spInputWidth->SetValue((int)w);
788 spInputHeight->SetValue((int)h);
789 success = true;
790 }
791 dk4bif_close(pbif);
792 }
793 }
794 }
795 }
796 if (!(success)) {
797 wxBitmapType t = bitmap_type_for_name(pa);
798 if (wxBITMAP_TYPE_INVALID != t) {
799 wxBitmap bm(pa, t);
800 if (bm.IsOk()) {
801 int w = bm.GetWidth();
802 int h = bm.GetHeight();
803 if ((0 < w) && (0 < h)) {
804 spInputWidth->SetValue(w);
805 spInputHeight->SetValue(h);
806 success = true;
807 }
808 else {
809 wxMessageBox(
810 sTexts[44], sTexts[43],
811 (wxOK | wxCENTRE | wxICON_ERROR)
812 );
813 }
814 }
815 else {
816 wxMessageBox(
817 sTexts[44], sTexts[43],
818 (wxOK | wxCENTRE | wxICON_ERROR)
819 );
820 }
821 }
822 else {
823 wxString s(sTexts[49]);
824 s.Append(pa);
825 s.Append(sTexts[50]);
826 wxMessageBox(
827 s, wxString(sTexts[43]), (wxOK | wxCENTRE | wxICON_ERROR)
828 );
829 }
830 }
831 if(success) {
832 Calculations();
833 }
834 }
835 else {
836 if (!(wxfn.FileExists())) {
837 wxString s(sTexts[45]);
838 s.Append(pa);
839 s.Append(sTexts[46]);
840 wxMessageBox(
841 s, wxString(sTexts[43]), (wxOK | wxCENTRE | wxICON_ERROR)
842 );
843 }
844 else {
845 if (!(wxfn.IsFileReadable())) {
846 wxString s(sTexts[47]);
847 s.Append(pa);
848 s.Append(sTexts[48]);
849 wxMessageBox(
850 s,wxString(sTexts[43]),(wxOK | wxCENTRE | wxICON_ERROR)
851 );
852 }
853 }
854 }
855 }
856
857 Refresh();
858 Update();
859 }
860
861
862 void
OnQuit(wxCommandEvent & WXUNUSED (event))863 WximgszFrame::OnQuit(wxCommandEvent & WXUNUSED(event))
864 {
865
866 bActive = false;
867
868 Close();
869 }
870
871
872
873 void
OnAbout(wxCommandEvent & WXUNUSED (event))874 WximgszFrame::OnAbout(wxCommandEvent & WXUNUSED(event))
875 {
876 wxString text(wxT(""));
877 wxString title(wxT(""));
878
879 /* Construct message text. */
880 text.Append(sNlWx[0]);
881 text.Append(sNlWx[7]);
882 #if 0
883 text.Append(sNlWx[1]);
884 #endif
885 text.Append(DKT_VERSION_WX);
886 text.Append(sNlWx[8]);
887 text.Append(sTexts[9]);
888 text.Append(sNlWx[2]);
889 text.Append(sNlWx[8]);
890 text.Append(sNlWx[8]);
891 text.Append(sTexts[11]);
892 text.Append(sNlWx[8]);
893 text.Append(sNlWx[9]);
894 text.Append(sNlWx[8]);
895 text.Append(sNlWx[8]);
896 text.Append(sTexts[12]);
897 text.Append(sNlWx[8]);
898 text.Append(sNlWx[10]);
899 text.Append(sNlWx[8]);
900 text.Append(sNlWx[11]);
901 text.Append(sNlWx[8]);
902 text.Append(sNlWx[12]);
903 text.Append(sNlWx[8]);
904 text.Append(sNlWx[13]);
905 text.Append(sNlWx[8]);
906 text.Append(sNlWx[14]);
907 text.Append(sNlWx[8]);
908 text.Append(sNlWx[15]);
909 text.Append(sNlWx[8]);
910
911 /* Construct dialog box title. */
912 title.Append(sTexts[10]);
913 title.Append(sNlWx[0]);
914
915 /* Show dialog box. */
916 wxMessageBox(text, title);
917
918 /* __CHANGE__ 019: Create better about box.
919 */
920
921 }
922
923
924
925 void
OnHelpContents(wxCommandEvent & WXUNUSED (event))926 WximgszFrame::OnHelpContents(wxCommandEvent & WXUNUSED(event))
927 {
928
929 DisplayContents();
930
931 }
932
933
934
935 static
936 int
bits_in_int(int x)937 bits_in_int(int x)
938 {
939 int back = 0;
940 int test = 1;
941 int done = 0;
942
943 while (0 == done) {
944 if (0 != (x & test)) {
945 if (1 < ++back) {
946 done = 1;
947 }
948 }
949 if ((INT_MAX / 2) >= test) {
950 test = test * 2;
951 if (test > x) {
952 done = 1;
953 }
954 }
955 else {
956 done = 1;
957 }
958 }
959 return back;
960 }
961
962
963 static
964 int
is_power_of_2(int x)965 is_power_of_2(int x)
966 {
967 int back = 0;
968 if (1 == bits_in_int(x)) {
969 back = 1;
970 }
971 return back;
972 }
973
974
975
976 static
977 int
quality_for_fraction(int counter,int denom)978 quality_for_fraction(int counter, int denom)
979 {
980 int back = 0;
981 if (1 == denom) {
982 back = 1;
983 if (0 != is_power_of_2(counter)) {
984 back = 2;
985 }
986 }
987 else {
988 if (1 == counter) {
989 back = 1;
990 if (0 != is_power_of_2(denom)) {
991 back = 2;
992 }
993 }
994 }
995 return back;
996 }
997
998
999
1000 static
1001 int
gcd(int a,int b)1002 gcd(int a, int b)
1003 {
1004 int h;
1005
1006 while (0 < b) {
1007 h = a % b;
1008 a = b;
1009 b = h;
1010 }
1011 return a;
1012 }
1013
1014
1015 /* __CHANGE__ 017: Event handlers for further events.
1016 */
1017
1018 void
Calculations(void)1019 WximgszFrame::Calculations(void)
1020 {
1021 wxString s1; /* Width */
1022 wxString s2; /* Height */
1023 wxString s3; /* Factor */
1024 wxString m2(sTexts[36]);
1025 wxString m1(sTexts[35]);
1026 wxString m0(sTexts[34]);
1027 int w_ori; /* Original width */
1028 int h_ori; /* Original height */
1029 int w_min; /* Minimum width */
1030 int h_min; /* Minimum height */
1031 int gcd_ori; /* Greatest common divisor original width height */
1032 int min; /* Destination range minimum */
1033 int max; /* Destination range maximum */
1034 int opsel; /* Operation selection */
1035 int f_min; /* Minimum factor */
1036 int f_max; /* Maximum factor */
1037 int nrows; /* Number of table rows */
1038 int passno; /* Current pass number (table row index) */
1039 int f; /* Current factor */
1040 int w; /* Current width */
1041 int h; /* Current height */
1042 int counter; /* Fraction counter */
1043 int denom; /* Fraction denominator */
1044 int gcd_fr; /* Fraction greatest common divisor */
1045 int q; /* Fraction quality */
1046 int i; /* Walk through the columns */
1047 bool bDidSkip; /* Flag: Restricted output to 2000 columns */
1048
1049 bDidSkip = false;
1050 w_ori = spInputWidth->GetValue();
1051 h_ori = spInputHeight->GetValue();
1052 min = spOperationMin->GetValue();
1053 max = spOperationMax->GetValue();
1054 opsel = cbOperation->GetSelection();
1055 if (0 >= w_ori) { w_ori = 1; }
1056 if (0 >= h_ori) { h_ori = 1; }
1057 if (0 >= min) { min = 1; }
1058 if (0 >= max) { max = 1; }
1059 gcd_ori = gcd(w_ori, h_ori);
1060 w_min = w_ori / gcd_ori;
1061 h_min = h_ori / gcd_ori;
1062 f_min = 1;
1063 f_max = gcd_ori;
1064 switch (opsel) {
1065 case 1: {
1066 f_min = min / w_min;
1067 f_max = max / w_min;
1068 if (0 >= f_min) { f_min = 1; }
1069 if (0 >= f_max) { f_max = 1; }
1070 } break;
1071 case 2: {
1072 f_min = min / h_min;
1073 f_max = max / h_min;
1074 if (0 >= f_min) { f_min = 1; }
1075 if (0 >= f_max) { f_max = 1; }
1076 } break;
1077 }
1078 nrows = f_max - f_min + 1;
1079 if (nrows > maxpass) { nrows = maxpass; bDidSkip = true; }
1080 /*
1081 Delete old table columns, allocate new columns
1082 */
1083 passno = tResult->GetNumberRows();
1084 tResult->DeleteRows(0, passno);
1085 tResult->AppendRows(nrows);
1086 /*
1087 Fill table
1088 */
1089 passno = 0;
1090 f = f_min;
1091 while (passno < nrows) {
1092 w = f * w_min;
1093 h = f * h_min;
1094 gcd_fr = gcd(f, gcd_ori);
1095 counter = f / gcd_fr;
1096 denom = gcd_ori / gcd_fr;
1097 q = quality_for_fraction(counter, denom);
1098 s1.Printf(wxT("%d"), w);
1099 s2.Printf(wxT("%d"), h);
1100 if (1 == denom) {
1101 s3.Printf(wxT("%d"), counter);
1102 }
1103 else {
1104 s3.Printf(wxT("%d / %d"), counter, denom);
1105 }
1106 for (i = 0; i < 4; i++) {
1107 tResult->SetCellTextColour(passno, i, cBlack);
1108 }
1109 tResult->SetCellValue(passno, 0, s1);
1110 tResult->SetCellValue(passno, 1, s2);
1111 tResult->SetCellValue(passno, 2, s3);
1112 switch (q) {
1113 case 2: {
1114 tResult->SetCellValue(passno, 3, m2);
1115 for (i = 0; i < 4; i++) {
1116 tResult->SetCellBackgroundColour(
1117 passno, i, cGreen
1118 );
1119 }
1120 } break;
1121 case 1: {
1122 tResult->SetCellValue(passno, 3, m1);
1123 for (i = 0; i < 4; i++) {
1124 tResult->SetCellBackgroundColour(
1125 passno, i, cYellow
1126 );
1127 }
1128 } break;
1129 case 0: {
1130 tResult->SetCellValue(passno, 3, m0);
1131 for (i = 0; i < 4; i++) {
1132 tResult->SetCellBackgroundColour(
1133 passno, i, cRed
1134 );
1135 }
1136 } break;
1137 }
1138 tResult->SetCellAlignment(passno, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
1139 tResult->SetCellAlignment(passno, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
1140 tResult->SetCellAlignment(passno, 2, wxALIGN_CENTRE, wxALIGN_CENTRE);
1141 tResult->SetCellAlignment(passno, 3, wxALIGN_CENTRE, wxALIGN_CENTRE);
1142 passno++;
1143 f++;
1144 }
1145 tResult->AutoSizeColumns();
1146 tResult->EnableDragColSize(true);
1147 if (bDidSkip) {
1148 wxMessageBox( sTexts[39], sTexts[38], (wxOK | wxCENTRE | wxICON_ERROR));
1149 }
1150
1151 }
1152
1153
1154
1155 void
OnButtonRun(wxCommandEvent & WXUNUSED (event))1156 WximgszFrame::OnButtonRun(wxCommandEvent & WXUNUSED(event))
1157 {
1158
1159 Calculations();
1160
1161 Refresh();
1162 Update();
1163 }
1164
1165
1166
1167 void
OnChoiceOperation(wxCommandEvent & WXUNUSED (event))1168 WximgszFrame::OnChoiceOperation(wxCommandEvent & WXUNUSED(event))
1169 {
1170
1171 switch (cbOperation->GetSelection()) {
1172 case 2 : case 1 : {
1173 spOperationMin->Enable();
1174 spOperationMax->Enable();
1175 } break;
1176 default : {
1177 spOperationMin->Enable(false);
1178 spOperationMax->Enable(false);
1179 } break;
1180 }
1181
1182 Refresh();
1183 Update();
1184 }
1185
1186
1187 /* __CHANGE__ 014: Implementation of further methods.
1188 */
1189
1190
1191 void
ActivateIdleProcessing(bool fl)1192 WximgszFrame::ActivateIdleProcessing(bool fl)
1193 {
1194 bActive = fl;
1195 }
1196
1197
1198 void
ProcessSpecifiedFileName(void)1199 WximgszFrame::ProcessSpecifiedFileName(void)
1200 {
1201 dkChar buf[DK4_MAX_PATH];
1202 wxChar const *ptrImageFileName;
1203 dk4_bif_t *pbif;
1204 int dke;
1205 int wxe;
1206 int res;
1207 bool success;
1208
1209 success = false;
1210 wxFileName wxfn(sImageFileName);
1211 if (wxfn.FileExists() && wxfn.IsFileReadable()) {
1212 wxCStrData csImageFileName = sImageFileName.c_str();
1213 ptrImageFileName = (wxChar const *)csImageFileName;
1214 if (NULL != ptrImageFileName) {
1215 dke = pAppHelp->GetDkEncoding();
1216 wxe = pAppHelp->GetWxEncoding();
1217 res = dk4recwx_wxchar_to_dkchar(
1218 buf, DK4_SIZEOF(buf,dkChar), dke, ptrImageFileName, wxe, NULL
1219 );
1220 if (0 != res) {
1221 pbif = dk4bif_open(buf, 1, NULL, NULL);
1222 if (NULL != pbif) {
1223 dk4_bif_dim_t w = dk4bif_get_width(pbif);
1224 dk4_bif_dim_t h = dk4bif_get_height(pbif);
1225 if (
1226 ((dk4_im_t)0L < (dk4_im_t)w)
1227 && ((dk4_im_t)0L < (dk4_im_t)h)
1228 && ((dk4_im_t)(MAXIMGDIM) >= (dk4_im_t)w)
1229 && ((dk4_im_t)(MAXIMGDIM) >= (dk4_im_t)h)
1230 ) {
1231 spInputWidth->SetValue((int)w);
1232 spInputHeight->SetValue((int)h);
1233 success = true;
1234 }
1235 #if TRACE_DEBUG
1236 else {
1237 }
1238 #endif
1239 dk4bif_close(pbif);
1240 }
1241 #if TRACE_DEBUG
1242 else {
1243 }
1244 #endif
1245 }
1246 #if TRACE_DEBUG
1247 else {
1248 }
1249 #endif
1250 }
1251 #if TRACE_DEBUG
1252 else {
1253 }
1254 #endif
1255 if (!(success)) {
1256 wxBitmapType t = bitmap_type_for_name(sImageFileName);
1257 if (wxBITMAP_TYPE_INVALID != t) {
1258 wxBitmap bm(sImageFileName, t);
1259 if (bm.IsOk()) {
1260 int w = bm.GetWidth();
1261 int h = bm.GetHeight();
1262 if ((0 < w) && (0 < h)) {
1263 spInputWidth->SetValue(w);
1264 spInputHeight->SetValue(h);
1265 success = true;
1266 }
1267 else {
1268 #if 0
1269 wxMessageBox(
1270 sTexts[44], sTexts[43],
1271 (wxOK | wxCENTRE | wxICON_ERROR)
1272 );
1273 #endif
1274 }
1275 }
1276 else {
1277 #if 0
1278 wxMessageBox(
1279 sTexts[44],sTexts[43],(wxOK | wxCENTRE | wxICON_ERROR)
1280 );
1281 #endif
1282 }
1283 }
1284 else {
1285 #if 0
1286 wxString s(sTexts[49]);
1287 s.Append(sImageFileName);
1288 s.Append(sTexts[50]);
1289 wxMessageBox(
1290 s, wxString(sTexts[43]), (wxOK | wxCENTRE | wxICON_ERROR)
1291 );
1292 #endif
1293 }
1294 }
1295 if (success) {
1296 Calculations();
1297 }
1298 }
1299 else {
1300 if (!(wxfn.FileExists())) {
1301 #if 0
1302 wxString s(sTexts[45]);
1303 s.Append(sImageFileName);
1304 s.Append(sTexts[46]);
1305 wxMessageBox(
1306 s, wxString(sTexts[43]), (wxOK | wxCENTRE | wxICON_ERROR)
1307 );
1308 #endif
1309 }
1310 else {
1311 if (!(wxfn.IsFileReadable())) {
1312 #if 0
1313 wxString s(sTexts[47]);
1314 s.Append(sImageFileName);
1315 s.Append(sTexts[48]);
1316 wxMessageBox(
1317 s, wxString(sTexts[43]), (wxOK | wxCENTRE | wxICON_ERROR)
1318 );
1319 #endif
1320 }
1321 }
1322 }
1323
1324 }
1325
1326 /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
1327 */
1328
1329 /* __CHANGE__ 008: Remove the request for more events if not needed.
1330 */
1331
1332 /* __CHANGE__ 008: Decide about Skip() call.
1333 The function name is irritating: Skip() or Skip(true) will continue to
1334 process the event, calling default handlers.
1335 Skip(false) or handlers without Skip() will skip further processing of the
1336 event.
1337
1338 From the wxWidgets documenation: Skip() should be called for all
1339 non-command events to allow the default handling to take place.
1340 The command events are, however, normally not skipped as usually a single
1341 command such as a button click or menu item selection must only be
1342 processed by one handler.
1343
1344 So my recommendation is to have a Skip() call in the idle event handler.
1345 */
1346
1347 void
OnIdle(wxIdleEvent & event)1348 WximgszFrame::OnIdle(wxIdleEvent & event)
1349 {
1350 bool rqm = false;
1351
1352 /* __CHANGE__
1353 */
1354 if (bActive) {
1355 switch (cas.GetReaction()) {
1356 case Dk4WxAutostartController::REACTION_START : {
1357 cas.StartProcessing();
1358 ProcessSpecifiedFileName();
1359 cas.EndProcessing();
1360 Refresh();
1361 Update();
1362 } break;
1363 }
1364 if (rqm) { event.RequestMore(); }
1365 }
1366
1367 event.Skip();
1368 }
1369
1370
1371 /* vim: set ai sw=4 ts=4 : */
1372