[2.0] Backport all changes since r2798 (included) from trunk
[openjpeg.git] / src / bin / wx / OPJViewer / source / OPJViewer.cpp
1 /*
2  * The copyright in this software is being made available under the 2-clauses 
3  * BSD License, included below. This software may be subject to other third 
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita' degli studi di Perugia (UPG), Italy
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /////////////////////////////////////////////////////////////////////////////
32 // Name:        sashtest.cpp
33 // Purpose:     Layout/sash sample
34 // Author:      Julian Smart
35 // Modified by:
36 // Created:     04/01/98
37 // RCS-ID:      $Id: sashtest.cpp,v 1.18 2005/08/23 15:54:35 ABX Exp $
38 // Copyright:   (c) Julian Smart
39 // Licence:     wxWindows license
40 /////////////////////////////////////////////////////////////////////////////
41 /////////////////////////////////////////////////////////////////////////////
42 // Name:        treetest.cpp
43 // Purpose:     wxTreeCtrl sample
44 // Author:      Julian Smart
45 // Modified by:
46 // Created:     04/01/98
47 // RCS-ID:      $Id: treetest.cpp,v 1.110 2006/11/04 11:26:51 VZ Exp $
48 // Copyright:   (c) Julian Smart
49 // Licence:     wxWindows license
50 /////////////////////////////////////////////////////////////////////////////
51 /////////////////////////////////////////////////////////////////////////////
52 // Name:        dialogs.cpp
53 // Purpose:     Common dialogs demo
54 // Author:      Julian Smart
55 // Modified by: ABX (2004) - adjustements for conditional building + new menu
56 // Created:     04/01/98
57 // RCS-ID:      $Id: dialogs.cpp,v 1.163 2006/11/04 10:57:24 VZ Exp $
58 // Copyright:   (c) Julian Smart
59 // Licence:     wxWindows license
60 /////////////////////////////////////////////////////////////////////////////
61 /////////////////////////////////////////////////////////////////////////////
62 // Name:        thread.cpp
63 // Purpose:     wxWidgets thread sample
64 // Author:      Guilhem Lavaux, Vadim Zeitlin
65 // Modified by:
66 // Created:     06/16/98
67 // RCS-ID:      $Id: thread.cpp,v 1.26 2006/10/02 05:36:28 PC Exp $
68 // Copyright:   (c) 1998-2002 wxWidgets team
69 // Licence:     wxWindows license
70 /////////////////////////////////////////////////////////////////////////////
71 ///////////////////////////////////////////////////////////////////////////////
72 // Name:        samples/image/image.cpp
73 // Purpose:     sample showing operations with wxImage
74 // Author:      Robert Roebling
75 // Modified by:
76 // Created:     1998
77 // RCS-ID:      $Id: image.cpp,v 1.120 2006/12/06 17:13:11 VZ Exp $
78 // Copyright:   (c) 1998-2005 Robert Roebling
79 // License:     wxWindows licence
80 ///////////////////////////////////////////////////////////////////////////////
81 /////////////////////////////////////////////////////////////////////////////
82 // Name:        samples/console/console.cpp
83 // Purpose:     A sample console (as opposed to GUI) program using wxWidgets
84 // Author:      Vadim Zeitlin
85 // Modified by:
86 // Created:     04.10.99
87 // RCS-ID:      $Id: console.cpp,v 1.206 2006/11/12 19:55:19 VZ Exp $
88 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
89 // Licence:     wxWindows license
90 /////////////////////////////////////////////////////////////////////////////
91 /////////////////////////////////////////////////////////////////////////////
92 // Name:        samples/notebook/notebook.cpp
93 // Purpose:     a sample demonstrating notebook usage
94 // Author:      Julian Smart
95 // Modified by: Dimitri Schoolwerth
96 // Created:     26/10/98
97 // RCS-ID:      $Id: notebook.cpp,v 1.49 2006/11/04 18:24:07 RR Exp $
98 // Copyright:   (c) 1998-2002 wxWidgets team
99 // License:     wxWindows license
100 /////////////////////////////////////////////////////////////////////////////
101 /////////////////////////////////////////////////////////////////////////////
102 // Name:        dialogs.cpp
103 // Purpose:     Common dialogs demo
104 // Author:      Julian Smart
105 // Modified by: ABX (2004) - adjustements for conditional building + new menu
106 // Created:     04/01/98
107 // RCS-ID:      $Id: dialogs.cpp,v 1.163 2006/11/04 10:57:24 VZ Exp $
108 // Copyright:   (c) Julian Smart
109 // Licence:     wxWindows license
110 /////////////////////////////////////////////////////////////////////////////
111 /////////////////////////////////////////////////////////////////////////////
112 // Name:        dnd.cpp
113 // Purpose:     Drag and drop sample
114 // Author:      Vadim Zeitlin
115 // Modified by:
116 // Created:     04/01/98
117 // RCS-ID:      $Id: dnd.cpp,v 1.107 2006/10/30 20:23:41 VZ Exp $
118 // Copyright:
119 // Licence:     wxWindows licence
120 /////////////////////////////////////////////////////////////////////////////
121 /////////////////////////////////////////////////////////////////////////////
122 // Name:        test.cpp
123 // Purpose:     wxHtml testing example
124 /////////////////////////////////////////////////////////////////////////////
125
126
127 #include "OPJViewer.h"
128
129 IMPLEMENT_APP(OPJViewerApp)
130
131 // For drawing lines in a canvas
132 long xpos = -1;
133 long ypos = -1;
134
135 int winNumber = 1;
136
137 // Initialise this in OnInit, not statically
138 bool OPJViewerApp::OnInit(void)
139 {
140         int n;
141 #if wxUSE_UNICODE
142
143     wxChar **wxArgv = new wxChar *[argc + 1];
144
145     for (n = 0; n < argc; n++ ) {
146         wxMB2WXbuf warg = wxConvertMB2WX((char *) argv[n]);
147         wxArgv[n] = wxStrdup(warg);
148     }
149
150     wxArgv[n] = NULL;
151
152 #else // !wxUSE_UNICODE
153
154     #define wxArgv argv
155
156 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
157
158 #if wxUSE_CMDLINE_PARSER
159
160     static const wxCmdLineEntryDesc cmdLineDesc[] =
161     {
162         { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
163             wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
164
165         { wxCMD_LINE_PARAM,  NULL, NULL, _T("input file"),
166             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },
167
168         { wxCMD_LINE_NONE }
169     };
170
171     wxCmdLineParser parser(cmdLineDesc, argc, wxArgv);
172
173     switch (parser.Parse()) {
174     case -1:
175         wxLogMessage(wxT("Help was given, terminating."));
176         break;
177
178     case 0:
179         ShowCmdLine(parser);
180         break;
181
182     default:
183         wxLogMessage(wxT("Syntax error detected."));
184         break;
185     }
186
187 #endif // wxUSE_CMDLINE_PARSER
188
189     //wxInitAllImageHandlers();
190 #if wxUSE_LIBJPEG
191   wxImage::AddHandler( new wxJPEGHandler );
192 #endif
193 #if wxUSE_LIBOPENJPEG
194   wxImage::AddHandler( new wxJPEG2000Handler );
195 #endif
196 #if USE_MXF
197   wxImage::AddHandler( new wxMXFHandler );
198 #endif // USE_MXF
199 #if OPJ_MANYFORMATS
200   wxImage::AddHandler( new wxBMPHandler );
201   wxImage::AddHandler( new wxPNGHandler );
202   wxImage::AddHandler( new wxGIFHandler );
203   wxImage::AddHandler( new wxPNMHandler );
204   wxImage::AddHandler( new wxTIFFHandler );
205 #endif
206     // we use a XPM image in our HTML page
207     wxImage::AddHandler(new wxXPMHandler);
208
209         // memory file system
210     wxFileSystem::AddHandler(new wxMemoryFSHandler);
211
212 #ifdef OPJ_INICONFIG
213         //load decoding engine parameters
214         OPJconfig = new wxConfig(OPJ_APPLICATION, OPJ_APPLICATION_VENDOR);
215
216         OPJconfig->Read(wxT("decode/enabledeco"), &m_enabledeco, (bool) true);
217         OPJconfig->Read(wxT("decode/enableparse"), &m_enableparse, (bool) true);
218         OPJconfig->Read(wxT("decode/resizemethod"), &m_resizemethod, (long) 0);
219         OPJconfig->Read(wxT("decode/xxxreducefactor"), &m_reducefactor, (long) 0);
220         OPJconfig->Read(wxT("decode/xxxqualitylayers"), &m_qualitylayers, (long) 0);
221         OPJconfig->Read(wxT("decode/xxxcomponents"), &m_components, (long) 0);
222         OPJconfig->Read(wxT("decode/xxxframenum"), &m_framenum, (long) 0);
223 #ifdef USE_JPWL
224         OPJconfig->Read(wxT("decode/enablejpwl"), &m_enablejpwl, (bool) true);
225         OPJconfig->Read(wxT("decode/expcomps"), &m_expcomps, (long) JPWL_EXPECTED_COMPONENTS);
226         OPJconfig->Read(wxT("decode/maxtiles"), &m_maxtiles, (long) JPWL_MAXIMUM_TILES);
227 #endif // USE_JPWL
228
229         OPJconfig->Write(wxT("teststring"), wxT("This is a test value"));
230         OPJconfig->Write(wxT("testbool"), (bool) true);
231         OPJconfig->Write(wxT("testlong"), (long) 245);
232
233         OPJconfig->Read(wxT("showtoolbar"), &m_showtoolbar, (bool) true);
234         OPJconfig->Read(wxT("showbrowser"), &m_showbrowser, (bool) true);
235         OPJconfig->Read(wxT("showpeeker"), &m_showpeeker, (bool) true);
236         OPJconfig->Read(wxT("browserwidth"), &m_browserwidth, (long) OPJ_BROWSER_WIDTH);
237         OPJconfig->Read(wxT("peekerheight"), &m_peekerheight, (long) OPJ_PEEKER_HEIGHT);
238         OPJconfig->Read(wxT("framewidth"), &m_framewidth, (long) OPJ_FRAME_WIDTH);
239         OPJconfig->Read(wxT("frameheight"), &m_frameheight, (long) OPJ_FRAME_HEIGHT);
240
241         // load encoding engine parameters
242         OPJconfig->Read(wxT("encode/subsampling"), &m_subsampling, (wxString) wxT("1,1"));
243         OPJconfig->Read(wxT("encode/origin"), &m_origin, (wxString) wxT("0,0"));
244         OPJconfig->Read(wxT("encode/rates"), &m_rates, (wxString) wxT("20,10,5"));
245         OPJconfig->Read(wxT("encode/quality"), &m_quality, (wxString) wxT("30,35,40"));
246         OPJconfig->Read(wxT("encode/enablequality"), &m_enablequality, (bool) false);
247         OPJconfig->Read(wxT("encode/multicomp"), &m_multicomp, (bool) false);   
248         OPJconfig->Read(wxT("encode/irreversible"), &m_irreversible, (bool) false);     
249         OPJconfig->Read(wxT("encode/resolutions"), &m_resolutions, (int) 6);    
250         OPJconfig->Read(wxT("encode/progression"), &m_progression, (int) 0);    
251         OPJconfig->Read(wxT("encode/cbsize"), &m_cbsize, (wxString) wxT("32,32"));
252         OPJconfig->Read(wxT("encode/prsize"), &m_prsize, (wxString) wxT("[128,128],[128,128]"));
253         OPJconfig->Read(wxT("encode/tsize"), &m_tsize, (wxString) wxT(""));
254         OPJconfig->Read(wxT("encode/torigin"), &m_torigin, (wxString) wxT("0,0"));
255         OPJconfig->Read(wxT("encode/enablesop"), &m_enablesop, (bool) false);   
256         OPJconfig->Read(wxT("encode/enableeph"), &m_enableeph, (bool) false);   
257         OPJconfig->Read(wxT("encode/enablebypass"), &m_enablebypass, (bool) false);     
258         OPJconfig->Read(wxT("encode/enablereset"), &m_enablereset, (bool) false);       
259         OPJconfig->Read(wxT("encode/enablerestart"), &m_enablerestart, (bool) false);   
260         OPJconfig->Read(wxT("encode/enablevsc"), &m_enablevsc, (bool) false);   
261         OPJconfig->Read(wxT("encode/enableerterm"), &m_enableerterm, (bool) false);     
262         OPJconfig->Read(wxT("encode/enablesegmark"), &m_enablesegmark, (bool) false);   
263         OPJconfig->Read(wxT("encode/enablecomm"), &m_enablecomm, (bool) true);  
264         OPJconfig->Read(wxT("encode/enablepoc"), &m_enablepoc, (bool) false);   
265         OPJconfig->Read(wxT("encode/comment"), &m_comment, (wxString) wxT(""));
266         OPJconfig->Read(wxT("encode/poc"), &m_poc, (wxString) wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL"));
267         OPJconfig->Read(wxT("encode/enableidx"), &m_enableidx, (bool) false);   
268         OPJconfig->Read(wxT("encode/index"), &m_index, (wxString) wxT("index.txt"));
269 #ifdef USE_JPWL
270         OPJconfig->Read(wxT("encode/enablejpwl"), &m_enablejpwle, (bool) true);
271         for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) {
272                 OPJconfig->Read(wxT("encode/jpwl/hprotsel") + wxString::Format(wxT("%02d"), n), &m_hprotsel[n], 0);
273                 OPJconfig->Read(wxT("encode/jpwl/htileval") + wxString::Format(wxT("%02d"), n), &m_htileval[n], 0);
274                 OPJconfig->Read(wxT("encode/jpwl/pprotsel") + wxString::Format(wxT("%02d"), n), &m_pprotsel[n], 0);
275                 OPJconfig->Read(wxT("encode/jpwl/ptileval") + wxString::Format(wxT("%02d"), n), &m_ptileval[n], 0);
276                 OPJconfig->Read(wxT("encode/jpwl/ppackval") + wxString::Format(wxT("%02d"), n), &m_ppackval[n], 0);
277                 OPJconfig->Read(wxT("encode/jpwl/sensisel") + wxString::Format(wxT("%02d"), n), &m_sensisel[n], 0);
278                 OPJconfig->Read(wxT("encode/jpwl/stileval") + wxString::Format(wxT("%02d"), n), &m_stileval[n], 0);
279         }
280 #endif // USE_JPWL
281
282 #else
283         // set decoding engine parameters
284         m_enabledeco = true;
285         m_enableparse = true;
286         m_resizemethod = 0;
287         m_reducefactor = 0;
288         m_qualitylayers = 0;
289         m_components = 0;
290         m_framenum = 0;
291 #ifdef USE_JPWL
292         m_enablejpwl = true;
293         m_expcomps = JPWL_EXPECTED_COMPONENTS;
294         m_maxtiles = JPWL_MAXIMUM_TILES;
295 #endif // USE_JPWL
296         m_showtoolbar = true;
297         m_showbrowser = true;
298         m_showpeeker = true;
299         m_browserwidth = OPJ_BROWSER_WIDTH;
300         m_peekerheight = OPJ_PEEKER_HEIGHT;
301         m_framewidth = OPJ_FRAME_WIDTH;
302         m_frameheight = OPJ_FRAME_HEIGHT;
303
304         // set encoding engine parameters
305         m_subsampling = wxT("1,1");
306         m_origin = wxT("0,0");
307         m_rates = wxT("20,10,5");
308         m_quality = wxT("30,35,40");
309         m_enablequality = false;
310         m_multicomp = false;
311         m_irreversible = false;
312         m_resolutions = 6;
313         m_progression = 0;
314         m_cbsize= wxT("32,32");
315         m_prsize= wxT("[128,128],[128,128]");
316         m_tsize = wxT("");
317         m_torigin = wxT("0,0");
318         m_enablesop = false;
319         m_enableeph = false;
320         m_enablebypass = false;
321         m_enablereset = false;
322         m_enablerestart = false;
323         m_enablevsc = false;
324         m_enableerterm = false;
325         m_enablesegmark = false;
326         m_enableidx = false;
327         m_index = wxT("index.txt");
328         m_enablecomm = true;
329         m_comment = wxT("");
330         m_enablepoc = false;
331         m_poc = wxT("T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL");
332 #ifdef USE_JPWL
333         m_enablejpwle = true;
334         for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) {
335                 m_hprotsel[n] = 0;
336                 m_htileval[n] = 0;
337                 m_pprotsel[n] = 0;
338                 m_ptileval[n] = 0;
339                 m_sensisel[n] = 0;
340                 m_stileval[n] = 0;
341         }
342 #endif // USE_JPWL
343
344 #endif // OPJ_INICONFIG
345
346         if (m_comment == wxT("")) {
347 #if defined __WXMSW__
348                 m_comment = wxT("Created by OPJViewer Win32 - OpenJPEG  version ");
349 #elif defined __WXGTK__
350                 m_comment = wxT("Created by OPJViewer Lin32 - OpenJPEG version ");
351 #else
352                 m_comment = wxT("Created by OPJViewer - OpenJPEG version ");
353 #endif
354
355 #ifdef USE_JPWL
356                 m_comment += wxString::Format(wxT("%s with JPWL"), (char *) opj_version());
357 #else
358                 m_comment += wxString::Format(wxT("%s"), (char *) opj_version());
359 #endif
360         }
361
362         // Create the main frame window
363   OPJFrame *frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR,
364                                           wxDefaultPosition, wxSize(wxGetApp().m_framewidth, wxGetApp().m_frameheight),
365                       wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE |
366                       wxHSCROLL | wxVSCROLL);
367
368   // Give it an icon (this is ignored in MDI mode: uses resources)
369 #ifdef __WXMSW__
370   frame->SetIcon(wxIcon(wxT("OPJViewer16")));
371 #endif
372
373   frame->Show(true);
374
375   SetTopWindow(frame);
376
377         // if there are files on the command line, open them
378         if (!(m_filelist.IsEmpty())) {
379                 //wxLogMessage(wxT("Habemus files!!!"));
380                 wxArrayString paths, filenames;
381                 for (unsigned int f = 0; f < wxGetApp().m_filelist.GetCount(); f++) {
382                         paths.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullPath());
383                         filenames.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullName());
384                 }
385                 //wxLogMessage(paths[0]);
386                 frame->OpenFiles(paths, filenames);
387         }
388
389   return true;
390 }
391
392 int OPJViewerApp::OnExit()
393 {
394         int n;
395
396 #ifdef OPJ_INICONFIG
397         OPJconfig->Write(wxT("decode/enabledeco"), m_enabledeco);
398         OPJconfig->Write(wxT("decode/enableparse"), m_enableparse);
399         OPJconfig->Write(wxT("decode/resizemethod"), m_resizemethod);
400         OPJconfig->Write(wxT("decode/reducefactor"), m_reducefactor);
401         OPJconfig->Write(wxT("decode/qualitylayers"), m_qualitylayers);
402         OPJconfig->Write(wxT("decode/components"), m_components);
403         OPJconfig->Write(wxT("decode/framenum"), m_framenum);
404 #ifdef USE_JPWL
405         OPJconfig->Write(wxT("decode/enablejpwl"), m_enablejpwl);
406         OPJconfig->Write(wxT("decode/expcomps"), m_expcomps);
407         OPJconfig->Write(wxT("decode/maxtiles"), m_maxtiles);
408 #endif // USE_JPWL
409         OPJconfig->Write(wxT("showtoolbar"), m_showtoolbar);
410         OPJconfig->Write(wxT("showbrowser"), m_showbrowser);
411         OPJconfig->Write(wxT("showpeeker"), m_showpeeker);
412         OPJconfig->Write(wxT("browserwidth"), m_browserwidth);
413         OPJconfig->Write(wxT("peekerheight"), m_peekerheight);
414         OPJconfig->Write(wxT("framewidth"), m_framewidth);
415         OPJconfig->Write(wxT("frameheight"), m_frameheight);
416
417         OPJconfig->Write(wxT("encode/subsampling"), m_subsampling);
418         OPJconfig->Write(wxT("encode/origin"), m_origin);
419         OPJconfig->Write(wxT("encode/rates"), m_rates);
420         OPJconfig->Write(wxT("encode/quality"), m_quality);
421         OPJconfig->Write(wxT("encode/enablequality"), m_enablequality);
422         OPJconfig->Write(wxT("encode/multicomp"), m_multicomp);
423         OPJconfig->Write(wxT("encode/irreversible"), m_irreversible);
424         OPJconfig->Write(wxT("encode/resolutions"), m_resolutions);
425         OPJconfig->Write(wxT("encode/progression"), m_progression);
426         OPJconfig->Write(wxT("encode/cbsize"), m_cbsize);
427         OPJconfig->Write(wxT("encode/prsize"), m_prsize);
428         OPJconfig->Write(wxT("encode/tiles"), m_tsize);
429         OPJconfig->Write(wxT("encode/torigin"), m_torigin);
430         OPJconfig->Write(wxT("encode/enablesop"), m_enablesop);
431         OPJconfig->Write(wxT("encode/enableeph"), m_enableeph);
432         OPJconfig->Write(wxT("encode/enablebypass"), m_enablebypass);
433         OPJconfig->Write(wxT("encode/enablereset"), m_enablereset);
434         OPJconfig->Write(wxT("encode/enablerestart"), m_enablerestart);
435         OPJconfig->Write(wxT("encode/enablevsc"), m_enablevsc);
436         OPJconfig->Write(wxT("encode/enableerterm"), m_enableerterm);
437         OPJconfig->Write(wxT("encode/enablesegmark"), m_enablesegmark);
438         OPJconfig->Write(wxT("encode/enableidx"), m_enableidx);
439         OPJconfig->Write(wxT("encode/index"), m_index);
440         OPJconfig->Write(wxT("encode/enablecomm"), m_enablecomm);
441         OPJconfig->Write(wxT("encode/comment"), m_comment);
442         OPJconfig->Write(wxT("encode/enablepoc"), m_enablepoc);
443         OPJconfig->Write(wxT("encode/poc"), m_poc);
444 #ifdef USE_JPWL
445         OPJconfig->Write(wxT("encode/enablejpwl"), m_enablejpwle);
446         for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) {
447                 OPJconfig->Write(wxT("encode/jpwl/hprotsel") + wxString::Format(wxT("%02d"), n), m_hprotsel[n]);
448                 OPJconfig->Write(wxT("encode/jpwl/htileval") + wxString::Format(wxT("%02d"), n), m_htileval[n]);
449                 OPJconfig->Write(wxT("encode/jpwl/pprotsel") + wxString::Format(wxT("%02d"), n), m_pprotsel[n]);
450                 OPJconfig->Write(wxT("encode/jpwl/ptileval") + wxString::Format(wxT("%02d"), n), m_ptileval[n]);
451                 OPJconfig->Write(wxT("encode/jpwl/ppackval") + wxString::Format(wxT("%02d"), n), m_ppackval[n]);
452                 OPJconfig->Write(wxT("encode/jpwl/sensisel") + wxString::Format(wxT("%02d"), n), m_sensisel[n]);
453                 OPJconfig->Write(wxT("encode/jpwl/stileval") + wxString::Format(wxT("%02d"), n), m_stileval[n]);
454         }
455 #endif // USE_JPWL
456
457 #endif // OPJ_INICONFIG
458
459         return 1;
460 }
461
462 void OPJViewerApp::ShowCmdLine(const wxCmdLineParser& parser)
463 {
464     wxString s = wxT("Command line parsed successfully:\nInput files: ");
465
466     size_t count = parser.GetParamCount();
467     for (size_t param = 0; param < count; param++) {
468         s << parser.GetParam(param) << ';';
469                 m_filelist.Add(parser.GetParam(param));
470     }
471
472     //wxLogMessage(s);
473 }
474
475 // OPJFrame events
476
477 // Event class for sending text messages between worker and GUI threads
478 BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame)
479     EVT_MENU(OPJFRAME_HELPABOUT, OPJFrame::OnAbout)
480     EVT_MENU(OPJFRAME_FILEOPEN, OPJFrame::OnFileOpen)
481     EVT_MENU(OPJFRAME_FILESAVEAS, OPJFrame::OnFileSaveAs)
482     EVT_MENU(OPJFRAME_MEMORYOPEN, OPJFrame::OnMemoryOpen)
483     EVT_SIZE(OPJFrame::OnSize)
484     EVT_MENU(OPJFRAME_FILEEXIT, OPJFrame::OnQuit)
485     EVT_MENU(OPJFRAME_FILECLOSE, OPJFrame::OnClose)
486     EVT_MENU(OPJFRAME_VIEWZOOM, OPJFrame::OnZoom)
487     EVT_MENU(OPJFRAME_VIEWFIT, OPJFrame::OnFit)
488     EVT_MENU(OPJFRAME_VIEWRELOAD, OPJFrame::OnReload)
489     EVT_MENU(OPJFRAME_VIEWPREVFRAME, OPJFrame::OnPrevFrame)
490     EVT_MENU(OPJFRAME_VIEWHOMEFRAME, OPJFrame::OnHomeFrame)
491     EVT_MENU(OPJFRAME_VIEWNEXTFRAME, OPJFrame::OnNextFrame)
492     EVT_MENU(OPJFRAME_VIEWLESSLAYERS, OPJFrame::OnLessLayers)
493     EVT_MENU(OPJFRAME_VIEWALLLAYERS, OPJFrame::OnAllLayers)
494     EVT_MENU(OPJFRAME_VIEWMORELAYERS, OPJFrame::OnMoreLayers)
495     EVT_MENU(OPJFRAME_VIEWLESSRES, OPJFrame::OnLessRes)
496     EVT_MENU(OPJFRAME_VIEWFULLRES, OPJFrame::OnFullRes)
497     EVT_MENU(OPJFRAME_VIEWMORERES, OPJFrame::OnMoreRes)
498     EVT_MENU(OPJFRAME_VIEWPREVCOMP, OPJFrame::OnPrevComp)
499     EVT_MENU(OPJFRAME_VIEWALLCOMPS, OPJFrame::OnAllComps)
500     EVT_MENU(OPJFRAME_VIEWNEXTCOMP, OPJFrame::OnNextComp)
501     EVT_MENU(OPJFRAME_FILETOGGLEB, OPJFrame::OnToggleBrowser)
502     EVT_MENU(OPJFRAME_FILETOGGLEP, OPJFrame::OnTogglePeeker)
503     EVT_MENU(OPJFRAME_FILETOGGLET, OPJFrame::OnToggleToolbar)
504     EVT_MENU(OPJFRAME_SETSENCO, OPJFrame::OnSetsEnco)
505     EVT_MENU(OPJFRAME_SETSDECO, OPJFrame::OnSetsDeco)
506     EVT_SASH_DRAGGED_RANGE(OPJFRAME_BROWSEWIN, OPJFRAME_LOGWIN, OPJFrame::OnSashDrag)
507     EVT_NOTEBOOK_PAGE_CHANGED(LEFT_NOTEBOOK_ID, OPJFrame::OnNotebook)
508     EVT_MENU(OPJFRAME_THREADLOGMSG, OPJFrame::OnThreadLogmsg)
509 END_EVENT_TABLE()
510
511 // this is the frame constructor
512 OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title,
513                                    const wxPoint& pos, const wxSize& size, const long style)
514                 : wxMDIParentFrame(parent, id, title, pos, size, style)
515 {
516         // file menu and its items
517         wxMenu *file_menu = new wxMenu;
518
519         file_menu->Append(OPJFRAME_FILEOPEN, wxT("&Open\tCtrl+O"));
520         file_menu->SetHelpString(OPJFRAME_FILEOPEN, wxT("Open one or more files"));
521
522         file_menu->Append(OPJFRAME_MEMORYOPEN, wxT("&Memory\tCtrl+M"));
523         file_menu->SetHelpString(OPJFRAME_MEMORYOPEN, wxT("Open a memory buffer"));
524
525         file_menu->Append(OPJFRAME_FILECLOSE, wxT("&Close\tCtrl+C"));
526         file_menu->SetHelpString(OPJFRAME_FILECLOSE, wxT("Close current image"));
527
528         file_menu->AppendSeparator();
529
530         file_menu->Append(OPJFRAME_FILESAVEAS, wxT("&Save as\tCtrl+S"));
531         file_menu->SetHelpString(OPJFRAME_FILESAVEAS, wxT("Save the current image"));
532         //file_menu->Enable(OPJFRAME_FILESAVEAS, false);
533
534         file_menu->AppendSeparator();
535
536         file_menu->Append(OPJFRAME_FILETOGGLEB, wxT("Toggle &browser\tCtrl+B"));
537         file_menu->SetHelpString(OPJFRAME_FILETOGGLEB, wxT("Toggle the left browsing pane"));
538
539         file_menu->Append(OPJFRAME_FILETOGGLEP, wxT("Toggle &peeker\tCtrl+P"));
540         file_menu->SetHelpString(OPJFRAME_FILETOGGLEP, wxT("Toggle the bottom peeking pane"));
541
542         file_menu->Append(OPJFRAME_FILETOGGLET, wxT("Toggle &toolbar\tCtrl+T"));
543         file_menu->SetHelpString(OPJFRAME_FILETOGGLET, wxT("Toggle the toolbar"));
544
545         file_menu->AppendSeparator();
546
547         file_menu->Append(OPJFRAME_FILEEXIT, wxT("&Exit\tCtrl+Q"));
548         file_menu->SetHelpString(OPJFRAME_FILEEXIT, wxT("Quit this program"));
549
550         // view menu and its items
551         wxMenu *view_menu = new wxMenu;
552
553         view_menu->Append(OPJFRAME_VIEWZOOM, wxT("&Zoom\tCtrl+Z"));
554         view_menu->SetHelpString(OPJFRAME_VIEWZOOM, wxT("Rescale the image"));
555
556         view_menu->Append(OPJFRAME_VIEWFIT, wxT("Zoom to &fit\tCtrl+F"));
557         view_menu->SetHelpString(OPJFRAME_VIEWFIT, wxT("Fit the image in canvas"));
558
559         view_menu->Append(OPJFRAME_VIEWRELOAD, wxT("&Reload image\tCtrl+R"));
560         view_menu->SetHelpString(OPJFRAME_VIEWRELOAD, wxT("Reload the current image"));
561
562         view_menu->AppendSeparator();
563
564         view_menu->Append(OPJFRAME_VIEWPREVFRAME, wxT("&Prev frame\tLeft"));
565         view_menu->SetHelpString(OPJFRAME_VIEWPREVFRAME, wxT("View previous frame"));
566
567         view_menu->Append(OPJFRAME_VIEWHOMEFRAME, wxT("&Start frame\tHome"));
568         view_menu->SetHelpString(OPJFRAME_VIEWHOMEFRAME, wxT("View starting frame"));
569
570         view_menu->Append(OPJFRAME_VIEWNEXTFRAME, wxT("&Next frame\tRight"));
571         view_menu->SetHelpString(OPJFRAME_VIEWNEXTFRAME, wxT("View next frame"));
572
573         view_menu->AppendSeparator();
574
575         view_menu->Append(OPJFRAME_VIEWLESSLAYERS, wxT("&Less layers\t-"));
576         view_menu->SetHelpString(OPJFRAME_VIEWLESSLAYERS, wxT("Remove a layer"));
577
578         view_menu->Append(OPJFRAME_VIEWALLLAYERS, wxT("&All layers\t0"));
579         view_menu->SetHelpString(OPJFRAME_VIEWALLLAYERS, wxT("Show all layers"));
580
581         view_menu->Append(OPJFRAME_VIEWMORELAYERS, wxT("&More layers\t+"));
582         view_menu->SetHelpString(OPJFRAME_VIEWMORELAYERS, wxT("Add a layer"));
583
584         view_menu->AppendSeparator();
585
586         view_menu->Append(OPJFRAME_VIEWLESSRES, wxT("&Less resolution\t<"));
587         view_menu->SetHelpString(OPJFRAME_VIEWLESSRES, wxT("Reduce the resolution"));
588
589         view_menu->Append(OPJFRAME_VIEWFULLRES, wxT("&Full resolution\tf"));
590         view_menu->SetHelpString(OPJFRAME_VIEWFULLRES, wxT("Full resolution"));
591
592         view_menu->Append(OPJFRAME_VIEWMORERES, wxT("&More resolution\t>"));
593         view_menu->SetHelpString(OPJFRAME_VIEWMORERES, wxT("Increase the resolution"));
594
595         view_menu->AppendSeparator();
596
597         view_menu->Append(OPJFRAME_VIEWPREVCOMP, wxT("&Prev component\tDown"));
598         view_menu->SetHelpString(OPJFRAME_VIEWPREVCOMP, wxT("View previous component"));
599
600         view_menu->Append(OPJFRAME_VIEWALLCOMPS, wxT("&All components\ta"));
601         view_menu->SetHelpString(OPJFRAME_VIEWALLCOMPS, wxT("View all components"));
602
603         view_menu->Append(OPJFRAME_VIEWNEXTCOMP, wxT("&Next component\tUp"));
604         view_menu->SetHelpString(OPJFRAME_VIEWNEXTCOMP, wxT("View next component"));
605
606
607         // settings menu and its items
608         wxMenu *sets_menu = new wxMenu;
609
610         sets_menu->Append(OPJFRAME_SETSENCO, wxT("&Encoder\tCtrl+E"));
611         sets_menu->SetHelpString(OPJFRAME_SETSENCO, wxT("Encoder settings"));
612
613         sets_menu->Append(OPJFRAME_SETSDECO, wxT("&Decoder\tCtrl+D"));
614         sets_menu->SetHelpString(OPJFRAME_SETSDECO, wxT("Decoder settings"));
615
616         // help menu and its items
617         wxMenu *help_menu = new wxMenu;
618
619         help_menu->Append(OPJFRAME_HELPABOUT, wxT("&About\tF1"));
620         help_menu->SetHelpString(OPJFRAME_HELPABOUT, wxT("Basic info on the program"));
621
622         // the whole menubar
623         wxMenuBar *menu_bar = new wxMenuBar;
624         menu_bar->Append(file_menu, wxT("&File"));
625         menu_bar->Append(view_menu, wxT("&View"));
626         menu_bar->Append(sets_menu, wxT("&Settings"));
627         menu_bar->Append(help_menu, wxT("&Help"));
628
629         // Associate the menu bar with the frame
630         SetMenuBar(menu_bar);
631
632         // the status bar
633         CreateStatusBar();
634
635         // the toolbar
636         tool_bar = new wxToolBar(this, OPJFRAME_TOOLBAR,
637                                                                 wxDefaultPosition, wxDefaultSize,
638                                                                 wxTB_HORIZONTAL | wxNO_BORDER);
639         wxBitmap bmpOpen = wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR,
640                                                                                                 wxDefaultSize);
641         wxBitmap bmpSaveAs = wxArtProvider::GetBitmap(wxART_FILE_SAVE_AS, wxART_TOOLBAR,
642                                                                                                 wxDefaultSize);
643         wxBitmap bmpZoom = wxArtProvider::GetBitmap(wxART_FIND, wxART_TOOLBAR,
644                                                                                                 wxDefaultSize);
645         wxBitmap bmpFit = wxArtProvider::GetBitmap(wxART_FIND_AND_REPLACE, wxART_TOOLBAR,
646                                                                                                 wxDefaultSize);
647         wxBitmap bmpReload = wxArtProvider::GetBitmap(wxART_EXECUTABLE_FILE, wxART_TOOLBAR,
648                                                                                                 wxDefaultSize);
649         wxBitmap bmpDecosettings = wxArtProvider::GetBitmap(wxART_REPORT_VIEW, wxART_TOOLBAR,
650                                                                                                 wxDefaultSize);
651         wxBitmap bmpEncosettings = wxArtProvider::GetBitmap(wxART_LIST_VIEW, wxART_TOOLBAR,
652                                                                                                 wxDefaultSize);
653         wxBitmap bmpPrevframe = wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR,
654                                                                                                 wxDefaultSize);
655         wxBitmap bmpHomeframe = wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_TOOLBAR,
656                                                                                                 wxDefaultSize);
657         wxBitmap bmpNextframe = wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR,
658                                                                                                 wxDefaultSize);
659         wxBitmap bmpLesslayers = bmpPrevframe;
660         wxBitmap bmpAlllayers = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR,
661                                                                                                 wxDefaultSize);
662         wxBitmap bmpMorelayers = bmpNextframe;
663         wxBitmap bmpLessres = bmpPrevframe;
664         wxBitmap bmpFullres = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR,
665                                                                                                 wxDefaultSize);
666         wxBitmap bmpMoreres = bmpNextframe;
667         wxBitmap bmpPrevcomp = bmpPrevframe;
668         wxBitmap bmpAllcomps = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR,
669                                                                                                 wxDefaultSize);
670         wxBitmap bmpNextcomp = bmpNextframe;
671
672         tool_bar->AddTool(OPJFRAME_FILEOPEN, bmpOpen, wxT("Open"));
673         tool_bar->AddTool(OPJFRAME_FILESAVEAS, bmpSaveAs, wxT("Save as "));
674         //tool_bar->EnableTool(OPJFRAME_FILESAVEAS, false);
675         tool_bar->AddSeparator();
676         tool_bar->AddTool(OPJFRAME_VIEWZOOM, bmpZoom, wxT("Zoom"));
677         tool_bar->AddTool(OPJFRAME_VIEWFIT, bmpFit, wxT("Zoom to fit"));
678         tool_bar->AddTool(OPJFRAME_VIEWRELOAD, bmpReload, wxT("Reload"));
679         tool_bar->AddSeparator();
680         tool_bar->AddTool(OPJFRAME_SETSDECO, bmpDecosettings, wxT("Decoder settings"));
681         tool_bar->AddTool(OPJFRAME_SETSENCO, bmpEncosettings, wxT("Encoder settings"));
682         tool_bar->AddSeparator();
683         tool_bar->AddTool(OPJFRAME_VIEWPREVFRAME, bmpPrevframe, wxT("Previous frame"));
684         tool_bar->AddTool(OPJFRAME_VIEWHOMEFRAME, bmpHomeframe, wxT("Starting frame"));
685         tool_bar->AddTool(OPJFRAME_VIEWNEXTFRAME, bmpNextframe, wxT("Next frame"));
686         tool_bar->AddSeparator();
687         tool_bar->AddTool(OPJFRAME_VIEWLESSLAYERS, bmpLesslayers, wxT("Remove a layer"));
688         tool_bar->AddTool(OPJFRAME_VIEWALLLAYERS, bmpAlllayers, wxT("Show all layers"));
689         tool_bar->AddTool(OPJFRAME_VIEWMORELAYERS, bmpMorelayers, wxT("Add a layer"));
690         tool_bar->AddSeparator();
691         tool_bar->AddTool(OPJFRAME_VIEWLESSRES, bmpLessres, wxT("Reduce the resolution"));
692         tool_bar->AddTool(OPJFRAME_VIEWFULLRES, bmpFullres, wxT("Full resolution"));
693         tool_bar->AddTool(OPJFRAME_VIEWMORERES, bmpMoreres, wxT("Increase the resolution"));
694         tool_bar->AddSeparator();
695         tool_bar->AddTool(OPJFRAME_VIEWPREVCOMP, bmpPrevcomp, wxT("Previous component"));
696         tool_bar->AddTool(OPJFRAME_VIEWALLCOMPS, bmpAllcomps, wxT("All components"));
697         tool_bar->AddTool(OPJFRAME_VIEWNEXTCOMP, bmpNextcomp, wxT("Next component"));
698         tool_bar->Realize();
699         
700         // associate the toolbar with the frame
701         SetToolBar(tool_bar);
702
703         // show the toolbar?
704         if (!wxGetApp().m_showtoolbar)
705                 tool_bar->Show(false);
706         else
707                 tool_bar->Show(true);
708
709         // the logging window
710         loggingWindow = new wxSashLayoutWindow(this, OPJFRAME_LOGWIN,
711                                                                                         wxDefaultPosition, wxSize(400, wxGetApp().m_peekerheight),
712                                                                                         wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN
713                                                                                         );
714         loggingWindow->SetDefaultSize(wxSize(1000, wxGetApp().m_peekerheight));
715         loggingWindow->SetOrientation(wxLAYOUT_HORIZONTAL);
716         loggingWindow->SetAlignment(wxLAYOUT_BOTTOM);
717         //loggingWindow->SetBackgroundColour(wxColour(0, 0, 255));
718         loggingWindow->SetSashVisible(wxSASH_TOP, true);
719
720         // show the logging?
721         if (!wxGetApp().m_showpeeker)
722                 loggingWindow->Show(false);
723         else
724                 loggingWindow->Show(true);
725
726         // create the bottom notebook
727         m_bookCtrlbottom = new wxNotebook(loggingWindow, BOTTOM_NOTEBOOK_ID,
728                                                                 wxDefaultPosition, wxDefaultSize,
729                                                                 wxBK_LEFT);
730
731         // create the text control of the logger
732         m_textCtrl = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""),
733                                                                 wxDefaultPosition, wxDefaultSize,
734                                                                 wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY
735                                                                 );
736         m_textCtrl->SetValue(_T("Logging window\n"));
737
738         // add it to the notebook
739         m_bookCtrlbottom->AddPage(m_textCtrl, wxT("Log"));
740
741         // create the text control of the browser
742         m_textCtrlbrowse = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""),
743                                                                 wxDefaultPosition, wxDefaultSize,
744                                                                 wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH
745                                                                 );
746         wxFont *browsefont = new wxFont(wxNORMAL_FONT->GetPointSize(),
747                 wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
748     m_textCtrlbrowse->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, *browsefont));
749         m_textCtrlbrowse->AppendText(wxT("Browsing window\n"));
750
751         // add it the notebook
752         m_bookCtrlbottom->AddPage(m_textCtrlbrowse, wxT("Peek"), false);
753
754         // the browser window
755         markerTreeWindow = new wxSashLayoutWindow(this, OPJFRAME_BROWSEWIN,
756                                                                                           wxDefaultPosition, wxSize(wxGetApp().m_browserwidth, 30),
757                                                                                           wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN
758                                                                                           );
759         markerTreeWindow->SetDefaultSize(wxSize(wxGetApp().m_browserwidth, 1000));
760         markerTreeWindow->SetOrientation(wxLAYOUT_VERTICAL);
761         markerTreeWindow->SetAlignment(wxLAYOUT_LEFT);
762         //markerTreeWindow->SetBackgroundColour(wxColour(0, 255, 0));
763         markerTreeWindow->SetSashVisible(wxSASH_RIGHT, true);
764         markerTreeWindow->SetExtraBorderSize(0);
765
766         // create the browser notebook
767         m_bookCtrl = new wxNotebook(markerTreeWindow, LEFT_NOTEBOOK_ID,
768                                                                 wxDefaultPosition, wxDefaultSize,
769                                                                 wxBK_TOP);
770
771         // show the browser?
772         if (!wxGetApp().m_showbrowser)
773                 markerTreeWindow->Show(false);
774         else
775                 markerTreeWindow->Show(true);
776
777 #ifdef __WXMOTIF__
778         // For some reason, we get a memcpy crash in wxLogStream::DoLogStream
779         // on gcc/wxMotif, if we use wxLogTextCtl. Maybe it's just gcc?
780         delete wxLog::SetActiveTarget(new wxLogStderr);
781 #else
782         // set our text control as the log target
783         wxLogTextCtrl *logWindow = new wxLogTextCtrl(m_textCtrl);
784         delete wxLog::SetActiveTarget(logWindow);
785 #endif
786
787         // associate drop targets with the controls
788         SetDropTarget(new OPJDnDFile(this));
789
790 }
791
792 // this is the frame destructor
793 OPJFrame::~OPJFrame(void)
794 {
795         // save size settings
796         GetSize(&(wxGetApp().m_framewidth), &(wxGetApp().m_frameheight));
797
798         // delete all possible things
799         delete m_bookCtrl;
800         m_bookCtrl = NULL;
801
802         delete markerTreeWindow;
803         markerTreeWindow = NULL;
804
805         delete m_textCtrl;
806         m_textCtrl = NULL;
807
808         delete m_bookCtrlbottom;
809         m_bookCtrlbottom = NULL;
810
811         delete loggingWindow;
812         loggingWindow = NULL;
813 }
814
815 void OPJFrame::OnNotebook(wxNotebookEvent& event)
816 {
817         int sel = event.GetSelection();
818         long childnum;
819
820         m_bookCtrl->GetPageText(sel).ToLong(&childnum);
821
822         if (m_childhash[childnum])
823                 m_childhash[childnum]->Activate();
824
825         //wxLogMessage(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber);
826
827 }
828
829
830 void OPJFrame::Resize(int number)
831 {
832         wxSize size = GetClientSize();
833 }
834
835 void OPJFrame::OnSetsEnco(wxCommandEvent& event)
836 {
837         int n;
838
839     OPJEncoderDialog dialog(this, event.GetId());
840
841     if (dialog.ShowModal() == wxID_OK) {
842
843                 // load settings
844                 wxGetApp().m_subsampling = dialog.m_subsamplingCtrl->GetValue();
845                 wxGetApp().m_origin = dialog.m_originCtrl->GetValue();
846                 wxGetApp().m_rates = dialog.m_rateCtrl->GetValue();
847                 wxGetApp().m_quality = dialog.m_qualityCtrl->GetValue();
848                 wxGetApp().m_enablequality = dialog.m_qualityRadio->GetValue();
849                 wxGetApp().m_multicomp = dialog.m_mctCheck->GetValue();
850                 wxGetApp().m_irreversible = dialog.m_irrevCheck->GetValue();
851                 wxGetApp().m_resolutions = dialog.m_resolutionsCtrl->GetValue();
852                 wxGetApp().m_cbsize = dialog.m_cbsizeCtrl->GetValue();
853                 wxGetApp().m_prsize = dialog.m_prsizeCtrl->GetValue();
854                 wxGetApp().m_tsize = dialog.m_tsizeCtrl->GetValue();
855                 wxGetApp().m_torigin = dialog.m_toriginCtrl->GetValue();
856                 wxGetApp().m_progression = dialog.progressionBox->GetSelection();
857                 wxGetApp().m_enablesop = dialog.m_sopCheck->GetValue();
858                 wxGetApp().m_enableeph = dialog.m_ephCheck->GetValue();
859                 wxGetApp().m_enablebypass = dialog.m_enablebypassCheck->GetValue();
860                 wxGetApp().m_enablereset = dialog.m_enableresetCheck->GetValue();
861                 wxGetApp().m_enablerestart = dialog.m_enablerestartCheck->GetValue();
862                 wxGetApp().m_enablevsc = dialog.m_enablevscCheck->GetValue();
863                 wxGetApp().m_enableerterm = dialog.m_enableertermCheck->GetValue();
864                 wxGetApp().m_enablesegmark = dialog.m_enablesegmarkCheck->GetValue();
865                 wxGetApp().m_enableidx = dialog.m_enableidxCheck->GetValue();
866                 wxGetApp().m_index = dialog.m_indexCtrl->GetValue();
867                 wxGetApp().m_enablecomm = dialog.m_enablecommCheck->GetValue();
868                 wxGetApp().m_comment = dialog.m_commentCtrl->GetValue();
869                 wxGetApp().m_enablepoc = dialog.m_enablepocCheck->GetValue();
870                 wxGetApp().m_poc = dialog.m_pocCtrl->GetValue();
871 #ifdef USE_JPWL
872                 wxGetApp().m_enablejpwle = dialog.m_enablejpwlCheck->GetValue();
873                 for (n = 0; n < MYJPWL_MAX_NO_TILESPECS; n++) {
874                         wxGetApp().m_hprotsel[n] = dialog.m_hprotChoice[n]->GetSelection();
875                         wxGetApp().m_htileval[n] = dialog.m_htileCtrl[n]->GetValue();
876                         wxGetApp().m_pprotsel[n] = dialog.m_pprotChoice[n]->GetSelection();
877                         wxGetApp().m_ptileval[n] = dialog.m_ptileCtrl[n]->GetValue();
878                         wxGetApp().m_ppackval[n] = dialog.m_ppackCtrl[n]->GetValue();
879                         wxGetApp().m_sensisel[n] = dialog.m_sensiChoice[n]->GetSelection();
880                         wxGetApp().m_stileval[n] = dialog.m_stileCtrl[n]->GetValue();
881                 }
882 #endif // USE_JPWL
883         };
884 }
885
886 void OPJFrame::OnSetsDeco(wxCommandEvent& event)
887 {
888     OPJDecoderDialog dialog(this, event.GetId());
889
890     if (dialog.ShowModal() == wxID_OK) {
891
892                 // load settings
893                 wxGetApp().m_enabledeco = dialog.m_enabledecoCheck->GetValue();
894                 wxGetApp().m_enableparse = dialog.m_enableparseCheck->GetValue();
895                 wxGetApp().m_resizemethod = dialog.m_resizeBox->GetSelection() - 1;
896                 wxGetApp().m_reducefactor = dialog.m_reduceCtrl->GetValue();
897                 wxGetApp().m_qualitylayers = dialog.m_layerCtrl->GetValue();
898                 wxGetApp().m_components = dialog.m_numcompsCtrl->GetValue();
899                 wxGetApp().m_framenum = dialog.m_framenumCtrl->GetValue();
900 #ifdef USE_JPWL
901                 wxGetApp().m_enablejpwl = dialog.m_enablejpwlCheck->GetValue();
902                 wxGetApp().m_expcomps = dialog.m_expcompsCtrl->GetValue();
903                 wxGetApp().m_maxtiles = dialog.m_maxtilesCtrl->GetValue();
904 #endif // USE_JPWL
905
906         };
907 }
908
909 void OPJFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
910 {
911         Close(true);
912 }
913
914 void OPJFrame::OnClose(wxCommandEvent& WXUNUSED(event))
915 {
916         // current frame
917         OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild();
918
919         if (!currframe)
920                 return;
921
922         wxCloseEvent e;
923         currframe->OnClose(e);
924 }
925
926 void OPJFrame::OnFit(wxCommandEvent& event)
927 {
928         OPJChildFrame *currchild;
929         wxString eventstring = event.GetString();
930
931         //wxLogMessage(wxT("OnFit:%d:%s"), event.GetInt(), eventstring);
932
933         // current child
934         if (event.GetInt() >= 1) {
935                 currchild = m_childhash[event.GetInt()];
936         } else {
937                 currchild = (OPJChildFrame *) GetActiveChild();
938         }
939
940         // problems
941         if (!currchild)
942                 return;
943
944         // current canvas
945         OPJCanvas *currcanvas = currchild->m_canvas;
946
947         // find a fit-to-width zoom
948         /*int zooml, wzooml, hzooml;
949         wxSize clientsize = currcanvas->GetClientSize();
950         wzooml = (int) ceil(100.0 * (double) (clientsize.GetWidth() - 2 * OPJ_CANVAS_BORDER) / (double) (currcanvas->m_image100.GetWidth()));
951         hzooml = (int) ceil(100.0 * (double) (clientsize.GetHeight() - 2 * OPJ_CANVAS_BORDER) / (double) (currcanvas->m_image100.GetHeight()));
952         zooml = wxMin(100, wxMin(wzooml, hzooml));*/
953
954         // fit to width
955         Rescale(-1, currchild);
956 }
957
958 void OPJFrame::OnZoom(wxCommandEvent& WXUNUSED(event))
959 {
960         // current frame
961         OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild();
962
963         if (!currframe)
964                 return;
965
966         // get the preferred zoom
967         long zooml = wxGetNumberFromUser(wxT("Choose a scale between 5% and 300%"),
968                 wxT("Zoom (%)"),
969                 wxT("Image scale"),
970                 currframe->m_canvas->m_zooml, 5, 300, NULL, wxDefaultPosition);
971
972         // rescale current frame image if necessary
973         if (zooml >= 5) {
974                 Rescale(zooml, currframe);
975                 wxLogMessage(wxT("zoom to %d%%"), zooml);
976         }
977 }
978
979 void OPJFrame::Rescale(int zooml, OPJChildFrame *currframe)
980 {
981         wxImage new_image = currframe->m_canvas->m_image100.ConvertToImage();
982
983         // resizing enabled?
984         if (wxGetApp().m_resizemethod == -1) {
985
986                 zooml = 100;
987
988         } else {
989
990                 if (zooml < 0) {
991                         // find a fit-to-width zoom
992                         int wzooml, hzooml;
993                         //wxSize clientsize = currframe->m_canvas->GetClientSize();
994                         wxSize clientsize = currframe->m_frame->GetActiveChild()->GetClientSize();
995                         wzooml = (int) floor(100.0 * (double) clientsize.GetWidth() / (double) (2 * OPJ_CANVAS_BORDER + currframe->m_canvas->m_image100.GetWidth()));
996                         hzooml = (int) floor(100.0 * (double) clientsize.GetHeight() / (double) (2 * OPJ_CANVAS_BORDER + currframe->m_canvas->m_image100.GetHeight()));
997                         zooml = wxMin(100, wxMin(wzooml, hzooml));
998                 }
999         }
1000
1001         if (zooml != 100)
1002                 new_image.Rescale((int) ((double) zooml * (double) new_image.GetWidth() / 100.0),
1003                         (int) ((double) zooml * (double) new_image.GetHeight() / 100.0),
1004                         wxGetApp().m_resizemethod ? wxIMAGE_QUALITY_HIGH : wxIMAGE_QUALITY_NORMAL);
1005         currframe->m_canvas->m_image = wxBitmap(new_image);
1006         currframe->m_canvas->SetScrollbars(20,
1007                                                                                 20,
1008                                                                                 (int)(0.5 + (double) new_image.GetWidth() / 20.0),
1009                                                                                 (int)(0.5 + (double) new_image.GetHeight() / 20.0)
1010                                                                                 );
1011
1012         currframe->m_canvas->Refresh();
1013
1014         wxLogMessage(wxT("Rescale said %d%%"), zooml);
1015
1016         // update zoom
1017         currframe->m_canvas->m_zooml = zooml;
1018 }
1019
1020
1021 void OPJFrame::OnReload(wxCommandEvent& event)
1022 {
1023         OPJChildFrame *currframe = (OPJChildFrame *) GetActiveChild();
1024
1025         if (currframe) {
1026                 OPJDecoThread *dthread = currframe->m_canvas->CreateDecoThread();
1027
1028                 if (dthread->Run() != wxTHREAD_NO_ERROR)
1029                         wxLogMessage(wxT("Can't start deco thread!"));
1030                 else
1031                         wxLogMessage(wxT("New deco thread started."));
1032
1033                 currframe->m_canvas->Refresh();
1034
1035                 // update zoom
1036                 //currframe->m_canvas->m_zooml = zooml;
1037         }
1038 }
1039
1040 void OPJFrame::OnPrevFrame(wxCommandEvent& event)
1041 {
1042         if (--wxGetApp().m_framenum < 0)
1043                 wxGetApp().m_framenum = 0;
1044
1045         wxCommandEvent e;
1046         OnReload(e);
1047 }
1048
1049 void OPJFrame::OnHomeFrame(wxCommandEvent& event)
1050 {
1051         wxGetApp().m_framenum = 0;
1052
1053         wxCommandEvent e;
1054         OnReload(e);
1055 }
1056
1057 void OPJFrame::OnNextFrame(wxCommandEvent& event)
1058 {
1059         ++wxGetApp().m_framenum;
1060
1061         wxCommandEvent e;
1062         OnReload(e);
1063 }
1064
1065 void OPJFrame::OnLessLayers(wxCommandEvent& event)
1066 {
1067         if (--wxGetApp().m_qualitylayers < 1)
1068                 wxGetApp().m_qualitylayers = 1;
1069
1070         wxCommandEvent e;
1071         OnReload(e);
1072 }
1073
1074 void OPJFrame::OnAllLayers(wxCommandEvent& event)
1075 {
1076         wxGetApp().m_qualitylayers = 0;
1077
1078         wxCommandEvent e;
1079         OnReload(e);
1080 }
1081
1082 void OPJFrame::OnMoreLayers(wxCommandEvent& event)
1083 {
1084         ++wxGetApp().m_qualitylayers;
1085
1086         wxCommandEvent e;
1087         OnReload(e);
1088 }
1089
1090 void OPJFrame::OnLessRes(wxCommandEvent& event)
1091 {
1092         ++wxGetApp().m_reducefactor;
1093
1094         wxCommandEvent e;
1095         OnReload(e);
1096 }
1097
1098 void OPJFrame::OnFullRes(wxCommandEvent& event)
1099 {
1100         wxGetApp().m_reducefactor = 0;
1101
1102         wxCommandEvent e;
1103         OnReload(e);
1104 }
1105
1106 void OPJFrame::OnMoreRes(wxCommandEvent& event)
1107 {
1108         if (--wxGetApp().m_reducefactor < 0)
1109                 wxGetApp().m_reducefactor = 0;
1110
1111         wxCommandEvent e;
1112         OnReload(e);
1113 }
1114
1115 void OPJFrame::OnPrevComp(wxCommandEvent& event)
1116 {
1117         if (--wxGetApp().m_components < 1)
1118                 wxGetApp().m_components = 1;
1119
1120         wxCommandEvent e;
1121         OnReload(e);
1122 }
1123
1124 void OPJFrame::OnAllComps(wxCommandEvent& event)
1125 {
1126         wxGetApp().m_components = 0;
1127
1128         wxCommandEvent e;
1129         OnReload(e);
1130 }
1131
1132 void OPJFrame::OnNextComp(wxCommandEvent& event)
1133 {
1134         ++wxGetApp().m_components;
1135
1136         wxCommandEvent e;
1137         OnReload(e);
1138 }
1139
1140 void OPJFrame::OnToggleBrowser(wxCommandEvent& WXUNUSED(event))
1141 {
1142     if (markerTreeWindow->IsShown())
1143         markerTreeWindow->Show(false);
1144     else
1145         markerTreeWindow->Show(true);
1146
1147     wxLayoutAlgorithm layout;
1148     layout.LayoutMDIFrame(this);
1149
1150         wxGetApp().m_showbrowser = markerTreeWindow->IsShown();
1151
1152     // Leaves bits of itself behind sometimes
1153     GetClientWindow()->Refresh();
1154 }
1155
1156 void OPJFrame::OnTogglePeeker(wxCommandEvent& WXUNUSED(event))
1157 {
1158     if (loggingWindow->IsShown())
1159         loggingWindow->Show(false);
1160     else
1161         loggingWindow->Show(true);
1162
1163     wxLayoutAlgorithm layout;
1164     layout.LayoutMDIFrame(this);
1165
1166         wxGetApp().m_showpeeker = loggingWindow->IsShown();
1167
1168     // Leaves bits of itself behind sometimes
1169     GetClientWindow()->Refresh();
1170 }
1171
1172 void OPJFrame::OnToggleToolbar(wxCommandEvent& WXUNUSED(event))
1173 {
1174     if (tool_bar->IsShown())
1175         tool_bar->Show(false);
1176     else
1177         tool_bar->Show(true);
1178
1179     wxLayoutAlgorithm layout;
1180     layout.LayoutMDIFrame(this);
1181
1182         wxGetApp().m_showtoolbar = tool_bar->IsShown();
1183
1184     // Leaves bits of itself behind sometimes
1185     GetClientWindow()->Refresh();
1186 }
1187
1188 void OPJFrame::OnSashDrag(wxSashEvent& event)
1189 {
1190         int wid, hei;
1191
1192     if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE)
1193         return;
1194
1195     switch (event.GetId()) {
1196                 case OPJFRAME_BROWSEWIN:
1197                 {
1198                         markerTreeWindow->SetDefaultSize(wxSize(event.GetDragRect().width, 1000));
1199                         break;
1200                 }
1201                 case OPJFRAME_LOGWIN:
1202                 {
1203                         loggingWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height));
1204                         break;
1205                 }
1206     }
1207
1208     wxLayoutAlgorithm layout;
1209     layout.LayoutMDIFrame(this);
1210
1211     // Leaves bits of itself behind sometimes
1212     GetClientWindow()->Refresh();
1213
1214         // update dimensions
1215         markerTreeWindow->GetSize(&wid, &hei);
1216         wxGetApp().m_browserwidth = wid;
1217
1218         loggingWindow->GetSize(&wid, &hei);
1219         wxGetApp().m_peekerheight = hei;
1220
1221 }
1222
1223 void OPJFrame::OnThreadLogmsg(wxCommandEvent& event)
1224 {
1225 #if 1
1226     wxLogMessage(wxT("Frame got message from worker thread: %d"), event.GetInt());
1227     wxLogMessage(event.GetString());
1228 #else
1229     int n = event.GetInt();
1230     if ( n == -1 )
1231     {
1232         m_dlgProgress->Destroy();
1233         m_dlgProgress = (wxProgressDialog *)NULL;
1234
1235         // the dialog is aborted because the event came from another thread, so
1236         // we may need to wake up the main event loop for the dialog to be
1237         // really closed
1238         wxWakeUpIdle();
1239     }
1240     else
1241     {
1242         if ( !m_dlgProgress->Update(n) )
1243         {
1244             wxCriticalSectionLocker lock(m_critsectWork);
1245
1246             m_cancelled = true;
1247         }
1248     }
1249 #endif
1250 }
1251
1252
1253 // physically save the file
1254 void OPJFrame::SaveFile(wxArrayString paths, wxArrayString filenames)
1255 {
1256         size_t count = paths.GetCount();
1257         wxString msg, s;
1258
1259         if (wxFile::Exists(paths[0].c_str())) {
1260
1261                 s.Printf(wxT("File %s already exists. Do you want to overwrite it?\n"), filenames[0].c_str());
1262                 wxMessageDialog dialog3(this, s, _T("File exists"), wxYES_NO);
1263                 if (dialog3.ShowModal() == wxID_NO)
1264                         return;
1265         }
1266
1267         /*s.Printf(_T("File %d: %s (%s)\n"), (int)0, paths[0].c_str(), filenames[0].c_str());
1268         msg += s;
1269
1270         wxMessageDialog dialog2(this, msg, _T("Selected files"));
1271         dialog2.ShowModal();*/
1272
1273         if (!GetActiveChild())
1274                 return;
1275
1276         ((OPJChildFrame *) GetActiveChild())->m_canvas->m_savename = paths[0];
1277
1278         OPJEncoThread *ethread = ((OPJChildFrame *) GetActiveChild())->m_canvas->CreateEncoThread();
1279
1280     if (ethread->Run() != wxTHREAD_NO_ERROR)
1281         wxLogMessage(wxT("Can't start enco thread!"));
1282     else
1283                 wxLogMessage(wxT("New enco thread started."));
1284
1285
1286 }
1287
1288 // physically open the files
1289 void OPJFrame::OpenFiles(wxArrayString paths, wxArrayString filenames)
1290 {
1291
1292         size_t count = paths.GetCount();
1293         for (size_t n = 0; n < count; n++) {
1294
1295                 wxString msg, s;
1296                 s.Printf(_T("File %d: %s (%s)\n"), (int)n, paths[n].c_str(), filenames[n].c_str());
1297
1298                 msg += s;
1299
1300                 /*wxMessageDialog dialog2(this, msg, _T("Selected files"));
1301                 dialog2.ShowModal();*/
1302
1303                 // Make another frame, containing a canvas
1304                 OPJChildFrame *subframe = new OPJChildFrame(this,
1305                                                                                                         paths[n],
1306                                                                                                         winNumber,
1307                                                                                                         wxT("Canvas Frame"),
1308                                                                                                         wxDefaultPosition, wxSize(300, 300),
1309                                                                                                         wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE
1310                                                                                                         );
1311                 m_childhash[winNumber] = subframe;
1312
1313                 // create own marker tree
1314                 m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, subframe, paths[n], wxT("Parsing..."), TreeTest_Ctrl,
1315                                                                                                   wxDefaultPosition, wxDefaultSize,
1316                                                                                                   wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER
1317                                                                                                   );
1318
1319                 m_bookCtrl->AddPage(m_treehash[winNumber], wxString::Format(wxT("%u"), winNumber), false);
1320
1321                 for (unsigned int p = 0; p < m_bookCtrl->GetPageCount(); p++) {
1322                         if (m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), winNumber)) {
1323                                 m_bookCtrl->ChangeSelection(p);
1324                                 break;
1325                         }
1326                 }
1327
1328                 winNumber++;
1329         }
1330 }
1331
1332 void OPJFrame::OnFileOpen(wxCommandEvent& WXUNUSED(event))
1333 {
1334     wxString wildcards =
1335 #ifdef __WXMOTIF__
1336         wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.*j*2*");
1337 #else
1338 #if wxUSE_LIBOPENJPEG
1339         wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.jp2;*.j2k;*.j2c;*.mj2")
1340 #endif
1341 #if USE_MXF
1342         wxT("|MXF JPEG 2000 video (*.mxf)|*.mxf")
1343 #endif // USE_MXF
1344 #if wxUSE_LIBJPEG
1345                 wxT("|JPEG files (*.jpg)|*.jpg")
1346 #endif
1347 #if OPJ_MANYFORMATS
1348                 wxT("|BMP files (*.bmp)|*.bmp")
1349                 wxT("|PNG files (*.png)|*.png")
1350                 wxT("|GIF files (*.gif)|*.gif")
1351                 wxT("|PNM files (*.pnm)|*.pnm")
1352                 wxT("|TIFF files (*.tif,*.tiff)|*.tif*")
1353 #endif
1354                 wxT("|All files|*");
1355 #endif
1356     wxFileDialog dialog(this, _T("Open image file(s)"),
1357                         wxEmptyString, wxEmptyString, wildcards,
1358                         wxFD_OPEN|wxFD_MULTIPLE);
1359
1360     if (dialog.ShowModal() == wxID_OK) {
1361         wxArrayString paths, filenames;
1362
1363         dialog.GetPaths(paths);
1364         dialog.GetFilenames(filenames);
1365
1366                 OpenFiles(paths, filenames);
1367     }
1368
1369 }
1370
1371 void OPJFrame::OnFileSaveAs(wxCommandEvent& WXUNUSED(event))
1372 {
1373     wxString wildcards =
1374 #ifdef wxUSE_LIBOPENJPEG
1375 #ifdef __WXMOTIF__
1376         wxT("JPEG 2000 codestream (*.j2k)|*.*j*2*");
1377 #else
1378         wxT("JPEG 2000 codestream (*.j2k)|*.j2k")
1379         wxT("|JPEG 2000 file format (*.jp2)|*.jp2");
1380 #endif
1381 #else
1382         wxT("Houston we have a problem");
1383 #endif
1384
1385     wxFileDialog dialog(this, _T("Save image file"),
1386                         wxEmptyString, wxEmptyString, wildcards,
1387                         wxFD_SAVE);
1388
1389     if (dialog.ShowModal() == wxID_OK) {
1390         wxArrayString paths, filenames;
1391
1392         dialog.GetPaths(paths);
1393         dialog.GetFilenames(filenames);
1394
1395                 SaveFile(paths, filenames);
1396     }
1397
1398
1399 }
1400
1401 void OPJFrame::OnMemoryOpen(wxCommandEvent& WXUNUSED(event))
1402 {
1403         // do nothing
1404         return;
1405         
1406         wxTextEntryDialog dialog(this, wxT("Memory HEX address range: start_address-stop_address"),
1407                                                         wxT("Decode a memory buffer"),
1408                                                         wxT("0x-0x"),
1409                                                         wxOK | wxCANCEL | wxCENTRE,
1410                                                         wxDefaultPosition);
1411
1412         if (dialog.ShowModal() == wxID_OK) {
1413
1414         }
1415
1416 }
1417
1418 BEGIN_EVENT_TABLE(OPJCanvas, wxScrolledWindow)
1419     EVT_MOUSE_EVENTS(OPJCanvas::OnEvent)
1420     EVT_MENU(OPJCANVAS_THREADSIGNAL, OPJCanvas::OnThreadSignal)
1421 END_EVENT_TABLE()
1422
1423 // Define a constructor for my canvas
1424 OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size)
1425         : wxScrolledWindow(parent, wxID_ANY, pos, size,
1426                            wxSUNKEN_BORDER | wxNO_FULL_REPAINT_ON_RESIZE)
1427 {
1428     SetBackgroundColour(OPJ_CANVAS_COLOUR);
1429
1430         m_fname = fname;
1431         m_childframe = (OPJChildFrame *) parent;
1432         // 100% zoom
1433         m_zooml = 100;
1434
1435
1436     OPJDecoThread *dthread = CreateDecoThread();
1437
1438     if (dthread->Run() != wxTHREAD_NO_ERROR)
1439         wxLogMessage(wxT("Can't start deco thread!"));
1440     else
1441                 wxLogMessage(wxT("New deco thread started."));
1442
1443         // 100% zoom
1444         //m_zooml = 100;
1445
1446 }
1447
1448 OPJDecoThread *OPJCanvas::CreateDecoThread(void)
1449 {
1450     OPJDecoThread *dthread = new OPJDecoThread(this);
1451
1452     if (dthread->Create() != wxTHREAD_NO_ERROR)
1453                 wxLogError(wxT("Can't create deco thread!"));
1454
1455     wxCriticalSectionLocker enter(wxGetApp().m_deco_critsect);
1456     wxGetApp().m_deco_threads.Add(dthread);
1457
1458     return dthread;
1459 }
1460
1461 OPJEncoThread *OPJCanvas::CreateEncoThread(void)
1462 {
1463     OPJEncoThread *ethread = new OPJEncoThread(this);
1464
1465     if (ethread->Create() != wxTHREAD_NO_ERROR)
1466                 wxLogError(wxT("Can't create enco thread!"));
1467
1468     wxCriticalSectionLocker enter(wxGetApp().m_enco_critsect);
1469     wxGetApp().m_enco_threads.Add(ethread);
1470
1471     return ethread;
1472 }
1473
1474 #define activeoverlay 0
1475 // Define the repainting behaviour
1476 void OPJCanvas::OnDraw(wxDC& dc)
1477 {
1478         if (m_image.Ok()) {
1479                 dc.DrawBitmap(m_image, OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER);
1480
1481                 if (activeoverlay) {
1482                         dc.SetPen(*wxRED_PEN);
1483                         dc.SetBrush(*wxTRANSPARENT_BRUSH);
1484                         //int tw, th;
1485                         dc.DrawRectangle(OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER,
1486                                 (unsigned long int) (0.5 + (double) m_zooml * (double) m_childframe->m_twidth / 100.0),
1487                                 (unsigned long int) (0.5 + (double) m_zooml * (double) m_childframe->m_theight / 100.0));
1488                 }
1489
1490         } else {
1491                 dc.SetFont(*wxSWISS_FONT);
1492                 dc.SetPen(*wxBLACK_PEN);
1493 #ifdef __WXGTK__
1494                 dc.DrawText(_T("Decoding image, please wait... (press \"Zoom to Fit\" to show the image)"), 40, 50);
1495 #else
1496                 dc.DrawText(_T("Decoding image, please wait..."), 40, 50);
1497 #endif
1498         }
1499 }
1500
1501 // This implements a tiny doodling program! Drag the mouse using
1502 // the left button.
1503 void OPJCanvas::OnEvent(wxMouseEvent& event)
1504 {
1505 #if USE_PENCIL_ON_CANVAS
1506   wxClientDC dc(this);
1507   PrepareDC(dc);
1508
1509   wxPoint pt(event.GetLogicalPosition(dc));
1510
1511   if ((xpos > -1) && (ypos > -1) && event.Dragging()) {
1512     dc.SetPen(*wxRED_PEN);
1513     dc.DrawLine(xpos, ypos, pt.x, pt.y);
1514   }
1515   xpos = pt.x;
1516   ypos = pt.y;
1517 #endif
1518 }
1519
1520 void OPJFrame::OnSize(wxSizeEvent& WXUNUSED(event))
1521 {
1522     wxLayoutAlgorithm layout;
1523     layout.LayoutMDIFrame(this);
1524 }
1525
1526 void OPJCanvas::OnThreadSignal(wxCommandEvent& event)
1527 {
1528 #if 1
1529     wxLogMessage(wxT("Canvas got signal from deco thread: %d"), event.GetInt());
1530     wxLogMessage(event.GetString());
1531 #else
1532     int n = event.GetInt();
1533     if ( n == -1 )
1534     {
1535         m_dlgProgress->Destroy();
1536         m_dlgProgress = (wxProgressDialog *)NULL;
1537
1538         // the dialog is aborted because the event came from another thread, so
1539         // we may need to wake up the main event loop for the dialog to be
1540         // really closed
1541         wxWakeUpIdle();
1542     }
1543     else
1544     {
1545         if ( !m_dlgProgress->Update(n) )
1546         {
1547             wxCriticalSectionLocker lock(m_critsectWork);
1548
1549             m_cancelled = true;
1550         }
1551     }
1552 #endif
1553 }
1554
1555
1556 // Note that OPJFRAME_FILEOPEN and OPJFRAME_HELPABOUT commands get passed
1557 // to the parent window for processing, so no need to
1558 // duplicate event handlers here.
1559
1560 BEGIN_EVENT_TABLE(OPJChildFrame, wxMDIChildFrame)
1561   /*EVT_MENU(SASHTEST_CHILD_QUIT, OPJChildFrame::OnQuit)*/
1562   EVT_CLOSE(OPJChildFrame::OnClose)
1563   EVT_SET_FOCUS(OPJChildFrame::OnGotFocus)
1564   EVT_KILL_FOCUS(OPJChildFrame::OnLostFocus)
1565 END_EVENT_TABLE()
1566
1567 OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size,
1568 const long style):
1569   wxMDIChildFrame(parent, wxID_ANY, title, pos, size, style)
1570 {
1571         m_frame = (OPJFrame  *) parent;
1572         m_canvas = NULL;
1573         //my_children.Append(this);
1574         m_fname = fname;
1575         m_winnumber = winnumber;
1576         SetTitle(wxString::Format(_T("%d: "), m_winnumber) + m_fname.GetFullName());
1577
1578           // Give it an icon (this is ignored in MDI mode: uses resources)
1579 #ifdef __WXMSW__
1580         SetIcon(wxIcon(wxT("OPJChild16")));
1581 #endif
1582
1583         // Give it a status line
1584         /*CreateStatusBar();*/
1585
1586         int width, height;
1587         GetClientSize(&width, &height);
1588
1589         OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height));
1590 #if USE_PENCIL_ON_CANVAS
1591         canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
1592 #endif
1593         m_canvas = canvas;
1594
1595         // Give it scrollbars
1596         canvas->SetScrollbars(20, 20, 5, 5);
1597
1598         Show(true);
1599         Maximize(true);
1600
1601         /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/
1602
1603 }
1604
1605 OPJChildFrame::~OPJChildFrame(void)
1606 {
1607   //my_children.DeleteObject(this);
1608 }
1609
1610
1611 void OPJChildFrame::OnClose(wxCloseEvent& event)
1612 {
1613         for (unsigned int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {
1614                 if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {
1615                         m_frame->m_bookCtrl->DeletePage(p);
1616                         break;
1617                 }
1618         }
1619         Destroy();
1620
1621         wxLogMessage(wxT("Closed: %d"), m_winnumber);
1622 }
1623
1624 void OPJChildFrame::OnActivate(wxActivateEvent& event)
1625 {
1626   /*if (event.GetActive() && m_canvas)
1627     m_canvas->SetFocus();*/
1628 }
1629
1630 void OPJChildFrame::OnGotFocus(wxFocusEvent& event)
1631 {
1632         // we need to check if the notebook is being destroyed or not
1633         if (!m_frame->m_bookCtrl)
1634                 return;
1635
1636         for (unsigned int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {
1637
1638                 if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {
1639                         m_frame->m_bookCtrl->ChangeSelection(p);
1640                         break;
1641                 }
1642
1643         }
1644
1645         //wxLogMessage(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow());
1646 }
1647
1648 void OPJChildFrame::OnLostFocus(wxFocusEvent& event)
1649 {
1650         //wxLogMessage(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow());
1651 }
1652
1653
1654 ////////////////////////////////
1655 // drag and drop 
1656 ////////////////////////////////
1657
1658 bool OPJDnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames)
1659 {
1660     /*size_t nFiles = filenames.GetCount();
1661     wxString str;
1662     str.Printf( _T("%d files dropped\n"), (int)nFiles);
1663     for ( size_t n = 0; n < nFiles; n++ ) {
1664         str << filenames[n] << wxT("\n");
1665     }
1666     wxLogMessage(str);*/
1667         m_pOwner->OpenFiles(filenames, filenames);
1668
1669     return true;
1670 }
1671