Added the OPJViewer Module (/OPJViewer), developed by Giuseppe Baruffa of the Univers...
[openjpeg.git] / OPJViewer / source / OPJViewer.cpp
1 /*\r
2  * Copyright (c) 2007, Digital Signal Processing Laboratory, Universit� degli studi di Perugia (UPG), Italy\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  * 1. Redistributions of source code must retain the above copyright\r
9  *    notice, this list of conditions and the following disclaimer.\r
10  * 2. Redistributions in binary form must reproduce the above copyright\r
11  *    notice, this list of conditions and the following disclaimer in the\r
12  *    documentation and/or other materials provided with the distribution.\r
13  *\r
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
24  * POSSIBILITY OF SUCH DAMAGE.\r
25  */\r
26 /////////////////////////////////////////////////////////////////////////////\r
27 // Name:        sashtest.cpp\r
28 // Purpose:     Layout/sash sample\r
29 // Author:      Julian Smart\r
30 // Modified by:\r
31 // Created:     04/01/98\r
32 // RCS-ID:      $Id: sashtest.cpp,v 1.18 2005/08/23 15:54:35 ABX Exp $\r
33 // Copyright:   (c) Julian Smart\r
34 // Licence:     wxWindows license\r
35 /////////////////////////////////////////////////////////////////////////////\r
36 /////////////////////////////////////////////////////////////////////////////\r
37 // Name:        treetest.cpp\r
38 // Purpose:     wxTreeCtrl sample\r
39 // Author:      Julian Smart\r
40 // Modified by:\r
41 // Created:     04/01/98\r
42 // RCS-ID:      $Id: treetest.cpp,v 1.110 2006/11/04 11:26:51 VZ Exp $\r
43 // Copyright:   (c) Julian Smart\r
44 // Licence:     wxWindows license\r
45 /////////////////////////////////////////////////////////////////////////////\r
46 /////////////////////////////////////////////////////////////////////////////\r
47 // Name:        dialogs.cpp\r
48 // Purpose:     Common dialogs demo\r
49 // Author:      Julian Smart\r
50 // Modified by: ABX (2004) - adjustements for conditional building + new menu\r
51 // Created:     04/01/98\r
52 // RCS-ID:      $Id: dialogs.cpp,v 1.163 2006/11/04 10:57:24 VZ Exp $\r
53 // Copyright:   (c) Julian Smart\r
54 // Licence:     wxWindows license\r
55 /////////////////////////////////////////////////////////////////////////////\r
56 /////////////////////////////////////////////////////////////////////////////\r
57 // Name:        thread.cpp\r
58 // Purpose:     wxWidgets thread sample\r
59 // Author:      Guilhem Lavaux, Vadim Zeitlin\r
60 // Modified by:\r
61 // Created:     06/16/98\r
62 // RCS-ID:      $Id: thread.cpp,v 1.26 2006/10/02 05:36:28 PC Exp $\r
63 // Copyright:   (c) 1998-2002 wxWidgets team\r
64 // Licence:     wxWindows license\r
65 /////////////////////////////////////////////////////////////////////////////\r
66 ///////////////////////////////////////////////////////////////////////////////\r
67 // Name:        samples/image/image.cpp\r
68 // Purpose:     sample showing operations with wxImage\r
69 // Author:      Robert Roebling\r
70 // Modified by:\r
71 // Created:     1998\r
72 // RCS-ID:      $Id: image.cpp,v 1.120 2006/12/06 17:13:11 VZ Exp $\r
73 // Copyright:   (c) 1998-2005 Robert Roebling\r
74 // License:     wxWindows licence\r
75 ///////////////////////////////////////////////////////////////////////////////\r
76 /////////////////////////////////////////////////////////////////////////////\r
77 // Name:        samples/console/console.cpp\r
78 // Purpose:     A sample console (as opposed to GUI) program using wxWidgets\r
79 // Author:      Vadim Zeitlin\r
80 // Modified by:\r
81 // Created:     04.10.99\r
82 // RCS-ID:      $Id: console.cpp,v 1.206 2006/11/12 19:55:19 VZ Exp $\r
83 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>\r
84 // Licence:     wxWindows license\r
85 /////////////////////////////////////////////////////////////////////////////\r
86 /////////////////////////////////////////////////////////////////////////////\r
87 // Name:        samples/notebook/notebook.cpp\r
88 // Purpose:     a sample demonstrating notebook usage\r
89 // Author:      Julian Smart\r
90 // Modified by: Dimitri Schoolwerth\r
91 // Created:     26/10/98\r
92 // RCS-ID:      $Id: notebook.cpp,v 1.49 2006/11/04 18:24:07 RR Exp $\r
93 // Copyright:   (c) 1998-2002 wxWidgets team\r
94 // License:     wxWindows license\r
95 /////////////////////////////////////////////////////////////////////////////\r
96 #include "OPJViewer.h"\r
97 \r
98 OPJFrame *frame = NULL;\r
99 wxList my_children;\r
100 \r
101 IMPLEMENT_APP(OPJViewerApp)\r
102 \r
103 // For drawing lines in a canvas\r
104 long xpos = -1;\r
105 long ypos = -1;\r
106 \r
107 int winNumber = 1;\r
108 \r
109 // Initialise this in OnInit, not statically\r
110 bool OPJViewerApp::OnInit(void)\r
111 {\r
112 #if wxUSE_UNICODE\r
113     wxChar **wxArgv = new wxChar *[argc + 1];\r
114 \r
115     {\r
116         int n;\r
117 \r
118         for (n = 0; n < argc; n++ )\r
119         {\r
120             wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);\r
121             wxArgv[n] = wxStrdup(warg);\r
122         }\r
123 \r
124         wxArgv[n] = NULL;\r
125     }\r
126 #else // !wxUSE_UNICODE\r
127     #define wxArgv argv\r
128 #endif // wxUSE_UNICODE/!wxUSE_UNICODE\r
129 \r
130 #if wxUSE_CMDLINE_PARSER\r
131     static const wxCmdLineEntryDesc cmdLineDesc[] =\r
132     {\r
133         { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),\r
134             wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },\r
135         /*{ wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },\r
136         { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"),   _T("be quiet") },\r
137 \r
138         { wxCMD_LINE_OPTION, _T("o"), _T("output"),  _T("output file") },\r
139         { wxCMD_LINE_OPTION, _T("i"), _T("input"),   _T("input dir") },\r
140         { wxCMD_LINE_OPTION, _T("s"), _T("size"),    _T("output block size"),\r
141             wxCMD_LINE_VAL_NUMBER },\r
142         { wxCMD_LINE_OPTION, _T("d"), _T("date"),    _T("output file date"),\r
143             wxCMD_LINE_VAL_DATE },*/\r
144 \r
145         { wxCMD_LINE_PARAM,  NULL, NULL, _T("input file"),\r
146             wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE },\r
147 \r
148         { wxCMD_LINE_NONE }\r
149     };\r
150 \r
151     wxCmdLineParser parser(cmdLineDesc, argc, wxArgv);\r
152 \r
153     /*parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),\r
154                      wxCMD_LINE_VAL_STRING,\r
155                      wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);*/\r
156 \r
157     switch ( parser.Parse() )\r
158     {\r
159         case -1:\r
160             wxLogMessage(_T("Help was given, terminating."));\r
161             break;\r
162 \r
163         case 0:\r
164             ShowCmdLine(parser);\r
165             break;\r
166 \r
167         default:\r
168             wxLogMessage(_T("Syntax error detected."));\r
169             break;\r
170     }\r
171 #endif // wxUSE_CMDLINE_PARSER\r
172 \r
173     //wxInitAllImageHandlers();\r
174 #if wxUSE_LIBJPEG\r
175   wxImage::AddHandler( new wxJPEGHandler );\r
176 #endif\r
177 #if wxUSE_LIBOPENJPEG\r
178   wxImage::AddHandler( new wxJ2KHandler );\r
179   wxImage::AddHandler( new wxJP2Handler );\r
180   wxImage::AddHandler( new wxMJ2Handler );\r
181 #endif\r
182 \r
183 \r
184         // Create the main frame window\r
185 \r
186   frame = new OPJFrame(NULL, wxID_ANY, OPJ_APPLICATION_TITLEBAR, wxDefaultPosition, wxSize(800, 600),\r
187                       wxDEFAULT_FRAME_STYLE |\r
188                       wxNO_FULL_REPAINT_ON_RESIZE |\r
189                       wxHSCROLL | wxVSCROLL);\r
190 \r
191   // Give it an icon (this is ignored in MDI mode: uses resources)\r
192 #ifdef __WXMSW__\r
193   frame->SetIcon(wxIcon(_T("OPJViewer16")));\r
194 #endif\r
195 \r
196   frame->Show(true);\r
197 \r
198   SetTopWindow(frame);\r
199 \r
200   return true;\r
201 }\r
202 \r
203 void OPJViewerApp::ShowCmdLine(const wxCmdLineParser& parser)\r
204 {\r
205     wxString s = _T("Command line parsed successfully:\nInput files: ");\r
206 \r
207     size_t count = parser.GetParamCount();\r
208     for ( size_t param = 0; param < count; param++ )\r
209     {\r
210         s << parser.GetParam(param) << ';';\r
211 \r
212                 m_filelist.Add(parser.GetParam(param));\r
213     }\r
214 \r
215     /*s << '\n'\r
216       << _T("Verbose:\t") << (parser.Found(_T("v")) ? _T("yes") : _T("no")) << '\n'\r
217       << _T("Quiet:\t") << (parser.Found(_T("q")) ? _T("yes") : _T("no")) << '\n';\r
218 \r
219     wxString strVal;\r
220     long lVal;\r
221     wxDateTime dt;\r
222     if ( parser.Found(_T("o"), &strVal) )\r
223         s << _T("Output file:\t") << strVal << '\n';\r
224     if ( parser.Found(_T("i"), &strVal) )\r
225         s << _T("Input dir:\t") << strVal << '\n';\r
226     if ( parser.Found(_T("s"), &lVal) )\r
227         s << _T("Size:\t") << lVal << '\n';\r
228     if ( parser.Found(_T("d"), &dt) )\r
229         s << _T("Date:\t") << dt.FormatISODate() << '\n';\r
230     if ( parser.Found(_T("project_name"), &strVal) )\r
231         s << _T("Project:\t") << strVal << '\n';*/\r
232 \r
233     //wxLogMessage(s);\r
234 }\r
235 \r
236 // OPJFrame events\r
237 BEGIN_EVENT_TABLE(OPJFrame, wxMDIParentFrame)\r
238     EVT_MENU(SASHTEST_ABOUT, OPJFrame::OnAbout)\r
239     EVT_MENU(SASHTEST_NEW_WINDOW, OPJFrame::OnFileOpen)\r
240     EVT_SIZE(OPJFrame::OnSize)\r
241     EVT_MENU(SASHTEST_QUIT, OPJFrame::OnQuit)\r
242     EVT_MENU(SASHTEST_TOGGLE_WINDOW, OPJFrame::OnToggleWindow)\r
243     EVT_SASH_DRAGGED_RANGE(ID_WINDOW_TOP, ID_WINDOW_BOTTOM, OPJFrame::OnSashDrag)\r
244     EVT_NOTEBOOK_PAGE_CHANGED(LEFT_NOTEBOOK_ID, OPJFrame::OnNotebook)\r
245 END_EVENT_TABLE()\r
246 \r
247 // this is the frame constructor\r
248 OPJFrame::OPJFrame(wxWindow *parent, const wxWindowID id, const wxString& title,\r
249                                    const wxPoint& pos, const wxSize& size, const long style)\r
250                 : wxMDIParentFrame(parent, id, title, pos, size, style)\r
251 {\r
252         // file menu and its items\r
253         wxMenu *file_menu = new wxMenu;\r
254 \r
255         file_menu->Append(SASHTEST_NEW_WINDOW, wxT("&Open\tCtrl+O"));\r
256         file_menu->SetHelpString(SASHTEST_NEW_WINDOW, wxT("Open one or more files"));\r
257 \r
258         file_menu->Append(SASHTEST_TOGGLE_WINDOW, wxT("&Toggle browser\tCtrl+T"));\r
259         file_menu->SetHelpString(SASHTEST_TOGGLE_WINDOW, wxT("Toggle the left browsing pane"));\r
260 \r
261         file_menu->Append(SASHTEST_QUIT, wxT("&Exit\tCtrl+Q"));\r
262         file_menu->SetHelpString(SASHTEST_QUIT, wxT("Quit this program"));\r
263 \r
264         // help menu and its items\r
265         wxMenu *help_menu = new wxMenu;\r
266 \r
267         help_menu->Append(SASHTEST_ABOUT, wxT("&About\tF1"));\r
268         help_menu->SetHelpString(SASHTEST_ABOUT, wxT("Basic info on the program"));\r
269 \r
270         // the whole menubar\r
271         wxMenuBar *menu_bar = new wxMenuBar;\r
272         menu_bar->Append(file_menu, wxT("&File"));\r
273         menu_bar->Append(help_menu, wxT("&Help"));\r
274 \r
275         // Associate the menu bar with the frame\r
276         SetMenuBar(menu_bar);\r
277 \r
278         // the status bar\r
279         CreateStatusBar();\r
280 \r
281         // the logging window\r
282         loggingWindow = new wxSashLayoutWindow(this, ID_WINDOW_BOTTOM,\r
283                                                                                         wxDefaultPosition, wxSize(400, 130),\r
284                                                                                         wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN\r
285                                                                                         );\r
286         loggingWindow->SetDefaultSize(wxSize(1000, 130));\r
287         loggingWindow->SetOrientation(wxLAYOUT_HORIZONTAL);\r
288         loggingWindow->SetAlignment(wxLAYOUT_BOTTOM);\r
289         //loggingWindow->SetBackgroundColour(wxColour(0, 0, 255));\r
290         loggingWindow->SetSashVisible(wxSASH_TOP, true);\r
291 \r
292         // create the bottom notebook\r
293         m_bookCtrlbottom = new wxNotebook(loggingWindow, BOTTOM_NOTEBOOK_ID,\r
294                                                                 wxDefaultPosition, wxDefaultSize,\r
295                                                                 wxBK_LEFT);\r
296 \r
297         // create the text control of the logger\r
298         m_textCtrl = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""),\r
299                                                                 wxDefaultPosition, wxDefaultSize,\r
300                                                                 wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY \r
301                                                                 );\r
302         m_textCtrl->SetValue(_T("Logging window\n"));\r
303 \r
304         // add it to the notebook\r
305         m_bookCtrlbottom->AddPage(m_textCtrl, wxT("Log"));\r
306 \r
307         // create the text control of the browser\r
308         m_textCtrlbrowse = new wxTextCtrl(m_bookCtrlbottom, wxID_ANY, wxT(""),\r
309                                                                 wxDefaultPosition, wxDefaultSize,\r
310                                                                 wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY \r
311                                                                 );\r
312         m_textCtrlbrowse->SetValue(_T("Browsing window\n"));\r
313 \r
314         // add it the notebook\r
315         m_bookCtrlbottom->AddPage(m_textCtrlbrowse, wxT("Peek"));\r
316 \r
317         // the browser window\r
318         markerTreeWindow = new wxSashLayoutWindow(this, ID_WINDOW_LEFT1,\r
319                                                                                           wxDefaultPosition, wxSize(300, 30),\r
320                                                                                           wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN\r
321                                                                                           );\r
322         markerTreeWindow->SetDefaultSize(wxSize(300, 1000));\r
323         markerTreeWindow->SetOrientation(wxLAYOUT_VERTICAL);\r
324         markerTreeWindow->SetAlignment(wxLAYOUT_LEFT);\r
325         //markerTreeWindow->SetBackgroundColour(wxColour(0, 255, 0));\r
326         markerTreeWindow->SetSashVisible(wxSASH_RIGHT, true);\r
327         markerTreeWindow->SetExtraBorderSize(0);\r
328 \r
329         // create the browser notebook\r
330         m_bookCtrl = new wxNotebook(markerTreeWindow, LEFT_NOTEBOOK_ID,\r
331                                                                 wxDefaultPosition, wxDefaultSize,\r
332                                                                 wxBK_TOP);\r
333 \r
334 \r
335 #if wxUSE_LOG\r
336 #ifdef __WXMOTIF__\r
337         // For some reason, we get a memcpy crash in wxLogStream::DoLogStream\r
338         // on gcc/wxMotif, if we use wxLogTextCtl. Maybe it's just gcc?\r
339         delete wxLog::SetActiveTarget(new wxLogStderr);\r
340 #else\r
341         // set our text control as the log target\r
342         wxLogTextCtrl *logWindow = new wxLogTextCtrl(m_textCtrl);\r
343         delete wxLog::SetActiveTarget(logWindow);\r
344 #endif\r
345 #endif // wxUSE_LOG\r
346 \r
347         // if there are files on the command line, open them\r
348         /*if (!wxGetApp().m_filelist.IsEmpty()) {\r
349         wxLogMessage(wxT("Habemus files!!!"));\r
350         wxArrayString paths, filenames;\r
351         for (int f = 0; f < wxGetApp().m_filelist.GetCount(); f++) {\r
352         paths.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullPath());\r
353         filenames.Add(wxFileName(wxGetApp().m_filelist[f]).GetFullName());\r
354         }\r
355         OpenFiles(paths, filenames);\r
356         }*/\r
357 }\r
358 \r
359 // this is the frame destructor\r
360 OPJFrame::~OPJFrame(void)\r
361 {\r
362         // delete all possible things\r
363         delete m_bookCtrl;\r
364         m_bookCtrl = NULL;\r
365 \r
366         delete markerTreeWindow;\r
367         markerTreeWindow = NULL;\r
368 \r
369         delete m_textCtrl;\r
370         m_textCtrl = NULL;\r
371 \r
372         delete m_bookCtrlbottom;\r
373         m_bookCtrlbottom = NULL;\r
374 \r
375         delete loggingWindow;\r
376         loggingWindow = NULL;\r
377 }\r
378 \r
379 void OPJFrame::OnNotebook(wxNotebookEvent& event)\r
380 {\r
381         int sel = event.GetSelection();\r
382         long childnum;\r
383 \r
384         m_bookCtrl->GetPageText(sel).ToLong(&childnum);\r
385 \r
386         m_childhash[childnum]->Activate();\r
387 \r
388         wxLogMessage(wxString::Format(wxT("Selection changed (now %d --> %d)"), childnum, m_childhash[childnum]->m_winnumber));\r
389 \r
390 }\r
391 \r
392 \r
393 void OPJFrame::Resize(int number)\r
394 {\r
395         wxSize size = GetClientSize();\r
396 }\r
397 \r
398 void OPJFrame::OnQuit(wxCommandEvent& WXUNUSED(event))\r
399 {\r
400         Close(true);\r
401 }\r
402 \r
403 // about window for the frame\r
404 void OPJFrame::OnAbout(wxCommandEvent& WXUNUSED(event))\r
405 {\r
406         wxMessageBox(wxString::Format(OPJ_APPLICATION_TITLEBAR\r
407                                                                   wxT("\n\n")\r
408                                                                   wxT("Built with %s and OpenJPEG ")\r
409                                                                   wxT(OPENJPEG_VERSION)\r
410                                                                   wxT("\non ") wxT(__DATE__) wxT(", ") wxT(__TIME__)\r
411                                                                   wxT("\nRunning under %s\n\n")\r
412                                                                   OPJ_APPLICATION_COPYRIGHT,\r
413                                                                   wxVERSION_STRING,\r
414                                                                   wxGetOsDescription().c_str()\r
415                                                                   ),\r
416                                  wxT("About ") OPJ_APPLICATION_NAME,\r
417                                  wxOK | wxICON_INFORMATION,\r
418                                  this\r
419                                  );\r
420 }\r
421 \r
422 void OPJFrame::OnToggleWindow(wxCommandEvent& WXUNUSED(event))\r
423 {\r
424     if (markerTreeWindow->IsShown())\r
425     {\r
426         markerTreeWindow->Show(false);\r
427     }\r
428     else\r
429     {\r
430         markerTreeWindow->Show(true);\r
431     }\r
432 #if wxUSE_MDI_ARCHITECTURE\r
433     wxLayoutAlgorithm layout;\r
434     layout.LayoutMDIFrame(this);\r
435 #endif // wxUSE_MDI_ARCHITECTURE\r
436 }\r
437 \r
438 void OPJFrame::OnSashDrag(wxSashEvent& event)\r
439 {\r
440     if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE)\r
441         return;\r
442 \r
443     switch (event.GetId())\r
444     {\r
445         case ID_WINDOW_LEFT1:\r
446         {\r
447             markerTreeWindow->SetDefaultSize(wxSize(event.GetDragRect().width, 1000));\r
448             break;\r
449         }\r
450         case ID_WINDOW_BOTTOM:\r
451         {\r
452             loggingWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height));\r
453             break;\r
454         }\r
455     }\r
456 \r
457 #if wxUSE_MDI_ARCHITECTURE\r
458     wxLayoutAlgorithm layout;\r
459     layout.LayoutMDIFrame(this);\r
460 #endif // wxUSE_MDI_ARCHITECTURE\r
461 \r
462     // Leaves bits of itself behind sometimes\r
463     GetClientWindow()->Refresh();\r
464 }\r
465 \r
466 // physically open the files\r
467 void OPJFrame::OpenFiles(wxArrayString paths, wxArrayString filenames)\r
468 {\r
469 \r
470         size_t count = paths.GetCount();\r
471         for ( size_t n = 0; n < count; n++ )\r
472         {\r
473                         wxString msg, s;\r
474             s.Printf(_T("File %d: %s (%s)\n"),\r
475                      (int)n, paths[n].c_str(), filenames[n].c_str());\r
476 \r
477             msg += s;\r
478                         //s.Printf(_T("Filter index: %d"), dialog.GetFilterIndex());\r
479                         msg += s;\r
480 \r
481                         /*wxMessageDialog dialog2(this, msg, _T("Selected files"));\r
482                         dialog2.ShowModal();*/\r
483 \r
484                         // Make another frame, containing a canvas\r
485                           OPJChildFrame *subframe = new OPJChildFrame(frame,\r
486                                                                                           paths[n],\r
487                                                                                           winNumber,\r
488                                                                                           _T("Canvas Frame"),\r
489                                                                                           wxDefaultPosition, wxSize(300, 300),\r
490                                                                                           wxDEFAULT_FRAME_STYLE |\r
491                                                                                           wxNO_FULL_REPAINT_ON_RESIZE);\r
492                           m_childhash[winNumber] = subframe;\r
493 \r
494                                   // create own marker tree\r
495                                 long tstyle = wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER | \r
496                         #ifndef NO_VARIABLE_HEIGHT\r
497                                                          wxTR_HAS_VARIABLE_ROW_HEIGHT /*|*/\r
498                         #endif\r
499                                                          /*wxTR_EDIT_LABELS*/;\r
500 \r
501                                 m_treehash[winNumber] = new OPJMarkerTree(m_bookCtrl, paths[n], wxT("Parsing..."), TreeTest_Ctrl,\r
502                                                                                         wxDefaultPosition, wxDefaultSize,\r
503                                                                                         tstyle);\r
504 \r
505                                 m_bookCtrl->AddPage(m_treehash[winNumber],\r
506                                                                                 wxString::Format(wxT("%u"), winNumber), false);\r
507 \r
508                                 for (int p = 0; p < m_bookCtrl->GetPageCount(); p++) {\r
509 \r
510                                         if (m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), winNumber)) {\r
511                                                 m_bookCtrl->ChangeSelection(p);\r
512                                                 break;\r
513                                         }\r
514 \r
515                                 }\r
516 \r
517                           winNumber++;\r
518                 \r
519                 }\r
520 \r
521 \r
522 }\r
523 \r
524 void OPJFrame::OnFileOpen(wxCommandEvent& WXUNUSED(event))\r
525 {\r
526     wxString wildcards =\r
527 #ifdef __WXMOTIF__\r
528         wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.*j*2*");\r
529 #else\r
530         wxT("JPEG 2000 files (*.jp2,*.j2k,*.j2c,*.mj2)|*.jp2;*.j2k;*.j2c;*.mj2|JPEG files (*.jpg)|*.jpg|All files|*");\r
531 #endif\r
532     wxFileDialog dialog(this, _T("Open JPEG 2000 file(s)"),\r
533                         wxEmptyString, wxEmptyString, wildcards,\r
534                         wxFD_OPEN|wxFD_MULTIPLE);\r
535 \r
536     if (dialog.ShowModal() == wxID_OK)\r
537     {\r
538         wxArrayString paths, filenames;\r
539 \r
540         dialog.GetPaths(paths);\r
541         dialog.GetFilenames(filenames);\r
542 \r
543                 OpenFiles(paths, filenames);\r
544 \r
545     }\r
546 \r
547 }\r
548 \r
549 BEGIN_EVENT_TABLE(OPJCanvas, wxScrolledWindow)\r
550     EVT_MOUSE_EVENTS(OPJCanvas::OnEvent)\r
551 END_EVENT_TABLE()\r
552 \r
553 // Define a constructor for my canvas\r
554 OPJCanvas::OPJCanvas(wxFileName fname, wxWindow *parent, const wxPoint& pos, const wxSize& size)\r
555         : wxScrolledWindow(parent, wxID_ANY, pos, size,\r
556                            wxSUNKEN_BORDER | wxNO_FULL_REPAINT_ON_RESIZE)\r
557 {\r
558     SetBackgroundColour(OPJ_CANVAS_COLOUR);\r
559 \r
560         m_fname = fname;\r
561 \r
562     OPJDecoThread *dthread = CreateDecoThread();\r
563 \r
564     if (dthread->Run() != wxTHREAD_NO_ERROR)\r
565         wxLogMessage(wxT("Can't start deco thread!"));\r
566     else\r
567                 wxLogMessage(_T("New deco thread started."));\r
568 \r
569 }\r
570 \r
571 OPJDecoThread *OPJCanvas::CreateDecoThread(void)\r
572 {\r
573     OPJDecoThread *dthread = new OPJDecoThread(this);\r
574 \r
575     if (dthread->Create() != wxTHREAD_NO_ERROR)\r
576                 wxLogError(wxT("Can't create deco thread!"));\r
577 \r
578     wxCriticalSectionLocker enter(wxGetApp().m_deco_critsect);\r
579     wxGetApp().m_deco_threads.Add(dthread);\r
580 \r
581     return dthread;\r
582 }\r
583 \r
584 // Define the repainting behaviour\r
585 void OPJCanvas::OnDraw(wxDC& dc)\r
586 {\r
587     /*dc.SetFont(*wxSWISS_FONT);\r
588     dc.SetPen(*wxBLACK_PEN);\r
589     dc.DrawText(_T("Image drawing canvas"), 10, 10);\r
590     dc.DrawLine(8, 22, 300, 22);*/\r
591         if (m_image.Ok()) {\r
592                 dc.DrawBitmap(m_image, OPJ_CANVAS_BORDER, OPJ_CANVAS_BORDER);\r
593         } else {\r
594                 dc.SetFont(*wxSWISS_FONT);\r
595                 dc.SetPen(*wxBLACK_PEN);\r
596                 dc.DrawText(_T("Decoding image, please wait..."), 40, 50);\r
597         }\r
598 \r
599     /*dc.SetFont(*wxSWISS_FONT);\r
600     dc.SetPen(*wxGREEN_PEN);\r
601     dc.DrawLine(0, 0, 200, 200);\r
602     dc.DrawLine(200, 0, 0, 200);\r
603 \r
604     dc.SetBrush(*wxCYAN_BRUSH);\r
605     dc.SetPen(*wxRED_PEN);\r
606     dc.DrawRectangle(100, 100, 100, 50);\r
607     dc.DrawRoundedRectangle(150, 150, 100, 50, 20);\r
608 \r
609     dc.DrawEllipse(250, 250, 100, 50);\r
610 #if wxUSE_SPLINES\r
611     dc.DrawSpline(50, 200, 50, 100, 200, 10);\r
612 #endif // wxUSE_SPLINES\r
613     dc.DrawLine(50, 230, 200, 230);\r
614     dc.DrawText(_T("This is a test string"), 50, 230);\r
615 \r
616     wxPoint points[3];\r
617     points[0].x = 200; points[0].y = 300;\r
618     points[1].x = 100; points[1].y = 400;\r
619     points[2].x = 300; points[2].y = 400;\r
620 \r
621     dc.DrawPolygon(3, points);*/\r
622 }\r
623 \r
624 // This implements a tiny doodling program! Drag the mouse using\r
625 // the left button.\r
626 void OPJCanvas::OnEvent(wxMouseEvent& event)\r
627 {\r
628   wxClientDC dc(this);\r
629   PrepareDC(dc);\r
630 \r
631   wxPoint pt(event.GetLogicalPosition(dc));\r
632 \r
633   if (xpos > -1 && ypos > -1 && event.Dragging())\r
634   {\r
635     dc.SetPen(*wxBLACK_PEN);\r
636     dc.DrawLine(xpos, ypos, pt.x, pt.y);\r
637   }\r
638   xpos = pt.x;\r
639   ypos = pt.y;\r
640 }\r
641 \r
642 void OPJFrame::OnSize(wxSizeEvent& WXUNUSED(event))\r
643 {\r
644 #if wxUSE_MDI_ARCHITECTURE\r
645     wxLayoutAlgorithm layout;\r
646     layout.LayoutMDIFrame(this);\r
647 #endif // wxUSE_MDI_ARCHITECTURE\r
648 }\r
649 \r
650 // Note that SASHTEST_NEW_WINDOW and SASHTEST_ABOUT commands get passed\r
651 // to the parent window for processing, so no need to\r
652 // duplicate event handlers here.\r
653 \r
654 BEGIN_EVENT_TABLE(OPJChildFrame, wxMDIChildFrame)\r
655   /*EVT_MENU(SASHTEST_CHILD_QUIT, OPJChildFrame::OnQuit)*/\r
656   EVT_CLOSE(OPJChildFrame::OnClose)\r
657   EVT_SET_FOCUS(OPJChildFrame::OnGotFocus)\r
658   /*EVT_KILL_FOCUS(OPJChildFrame::OnLostFocus)*/\r
659 END_EVENT_TABLE()\r
660 \r
661 OPJChildFrame::OPJChildFrame(OPJFrame *parent, wxFileName fname, int winnumber, const wxString& title, const wxPoint& pos, const wxSize& size,\r
662 const long style):\r
663   wxMDIChildFrame(parent, wxID_ANY, title, pos, size, style)\r
664 {\r
665   m_frame = (OPJFrame  *) parent;\r
666   m_canvas = NULL;\r
667   my_children.Append(this);\r
668   m_fname = fname;\r
669   m_winnumber = winnumber;\r
670         SetTitle(wxString::Format(_T("%d: "), m_winnumber) + m_fname.GetFullName());\r
671 \r
672 \r
673           // Give it an icon (this is ignored in MDI mode: uses resources)\r
674 #ifdef __WXMSW__\r
675           SetIcon(wxIcon(_T("sashtest_icn")));\r
676 #endif\r
677 \r
678 #if wxUSE_STATUSBAR\r
679           // Give it a status line\r
680           //CreateStatusBar();\r
681 #endif // wxUSE_STATUSBAR\r
682 \r
683           // Make a menubar\r
684           /*wxMenu *file_menu = new wxMenu;\r
685 \r
686           file_menu->Append(SASHTEST_NEW_WINDOW, _T("&Open\tCtrl+O"));\r
687           file_menu->Append(SASHTEST_CHILD_QUIT, _T("&Close\tCtrl+C"));\r
688           file_menu->Append(SASHTEST_QUIT, _T("&Exit\tCtrl+Q"));\r
689 \r
690           wxMenu *option_menu = new wxMenu;\r
691 \r
692           // Dummy option\r
693           option_menu->Append(SASHTEST_REFRESH, _T("&Refresh picture"));\r
694 \r
695           wxMenu *help_menu = new wxMenu;\r
696           help_menu->Append(SASHTEST_ABOUT, _T("&About\tF1"));\r
697 \r
698           wxMenuBar *menu_bar = new wxMenuBar;\r
699 \r
700           menu_bar->Append(file_menu, _T("&File"));\r
701           menu_bar->Append(option_menu, _T("&Options"));\r
702           menu_bar->Append(help_menu, _T("&Help"));\r
703 \r
704           // Associate the menu bar with the frame\r
705           SetMenuBar(menu_bar);*/\r
706 \r
707 \r
708           int width, height;\r
709           GetClientSize(&width, &height);\r
710 \r
711           OPJCanvas *canvas = new OPJCanvas(fname, this, wxPoint(0, 0), wxSize(width, height));\r
712           canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));\r
713           m_canvas = canvas;\r
714 \r
715           // Give it scrollbars\r
716           canvas->SetScrollbars(20, 20, 5, 5);\r
717 \r
718           Show(true);\r
719           Maximize(true);\r
720 \r
721 \r
722     /*wxSize gsize = m_frame->m_bookCtrl->GetClientSize();\r
723     m_frame->m_treehash[m_winnumber]->SetSize(0, 0, gsize.x, gsize.y);*/\r
724 \r
725     /*m_frame->Resize(m_winnumber);*/\r
726         /*m_frame->m_treehash[0]->Show(false);\r
727         m_frame->m_treehash[m_winnumber]->Show(true);*/\r
728     /*m_frame->Resize(m_winnumber);*/\r
729 \r
730         /*wxLogError(wxString::Format(wxT("Created tree %d (0x%x)"), m_winnumber, m_frame->m_treehash[m_winnumber]));*/\r
731 \r
732 }\r
733 \r
734 OPJChildFrame::~OPJChildFrame(void)\r
735 {\r
736   my_children.DeleteObject(this);\r
737 }\r
738 \r
739 /*void OPJChildFrame::OnQuit(wxCommandEvent& WXUNUSED(event))\r
740 {\r
741         for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {\r
742 \r
743                 if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {\r
744                         m_frame->m_bookCtrl->DeletePage(p);;\r
745                         break;\r
746                 }\r
747 \r
748         }\r
749 \r
750         Close(true);\r
751 }*/\r
752 \r
753 void OPJChildFrame::OnClose(wxCloseEvent& event)\r
754 {\r
755         for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {\r
756 \r
757                 if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {\r
758                         m_frame->m_bookCtrl->DeletePage(p);\r
759                         break;\r
760                 }\r
761 \r
762         }\r
763         Destroy();\r
764 \r
765         wxLogMessage(wxString::Format(wxT("Closed: %d"), m_winnumber));\r
766 \r
767 }\r
768 \r
769 void OPJChildFrame::OnActivate(wxActivateEvent& event)\r
770 {\r
771   /*if (event.GetActive() && m_canvas)\r
772     m_canvas->SetFocus();*/\r
773 }\r
774 \r
775 void OPJChildFrame::OnGotFocus(wxFocusEvent& event)\r
776 {\r
777         // we need to check if the notebook is being destroyed or not\r
778         if (!m_frame->m_bookCtrl)\r
779                 return;\r
780 \r
781         for (int p = 0; p < m_frame->m_bookCtrl->GetPageCount(); p++) {\r
782 \r
783                 if (m_frame->m_bookCtrl->GetPageText(p) == wxString::Format(wxT("%u"), m_winnumber)) {\r
784                         m_frame->m_bookCtrl->ChangeSelection(p);\r
785                         break;\r
786                 }\r
787 \r
788         }\r
789 \r
790         wxLogMessage(wxString::Format(wxT("Got focus: %d (%x)"), m_winnumber, event.GetWindow()));\r
791 }\r
792 \r
793 /*void OPJChildFrame::OnLostFocus(wxFocusEvent& event)\r
794 {\r
795         wxLogMessage(wxString::Format(wxT("Lost focus: %d (%x)"), m_winnumber, event.GetWindow()));\r
796 \r
797 }*/\r
798 \r
799 #if USE_GENERIC_TREECTRL\r
800 BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl)\r
801 #else\r
802 BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl)\r
803 #endif\r
804     /*EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginDrag)\r
805     EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginRDrag)\r
806     EVT_TREE_END_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnEndDrag)*/\r
807     /*EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnBeginLabelEdit)\r
808     EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnEndLabelEdit)*/\r
809     /*EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, OPJMarkerTree::OnDeleteItem)*/\r
810 #if 0       // there are so many of those that logging them causes flicker\r
811     /*EVT_TREE_GET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnGetInfo)*/\r
812 #endif\r
813     /*EVT_TREE_SET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnSetInfo)\r
814     EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanded)*/\r
815     EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanding)\r
816     /*EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsed)\r
817     EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsing)*/\r
818 \r
819     EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, OPJMarkerTree::OnSelChanged)\r
820     /*EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, OPJMarkerTree::OnSelChanging)*/\r
821     /*EVT_TREE_KEY_DOWN(TreeTest_Ctrl, OPJMarkerTree::OnTreeKeyDown)*/\r
822     /*EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, OPJMarkerTree::OnItemActivated)*/\r
823 \r
824     // so many differents ways to handle right mouse button clicks...\r
825     /*EVT_CONTEXT_MENU(OPJMarkerTree::OnContextMenu)*/\r
826     // EVT_TREE_ITEM_MENU is the preferred event for creating context menus\r
827     // on a tree control, because it includes the point of the click or item,\r
828     // meaning that no additional placement calculations are required.\r
829     /*EVT_TREE_ITEM_MENU(TreeTest_Ctrl, OPJMarkerTree::OnItemMenu)*/\r
830     /*EVT_TREE_ITEM_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/\r
831 \r
832     /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown)\r
833     EVT_RIGHT_UP(OPJMarkerTree::OnRMouseUp)\r
834     EVT_RIGHT_DCLICK(OPJMarkerTree::OnRMouseDClick)*/\r
835 END_EVENT_TABLE()\r
836 \r
837 // OPJMarkerTree implementation\r
838 #if USE_GENERIC_TREECTRL\r
839 IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl)\r
840 #else\r
841 IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl)\r
842 #endif\r
843 \r
844 OPJMarkerTree::OPJMarkerTree(wxWindow *parent, wxFileName fname, wxString name, const wxWindowID id,\r
845                        const wxPoint& pos, const wxSize& size,\r
846                        long style)\r
847           : wxTreeCtrl(parent, id, pos, size, style)\r
848 {\r
849     m_reverseSort = false;\r
850         m_fname = fname;\r
851 \r
852         m_peektextCtrl = ((OPJFrame *) (parent->GetParent()->GetParent()))->m_textCtrlbrowse;\r
853     CreateImageList();\r
854 \r
855     // Add some items to the tree\r
856     //AddTestItemsToTree(5, 5);\r
857     int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1;\r
858     wxTreeItemId rootId = AddRoot(name,\r
859                                   image, image,\r
860                                   new OPJMarkerData(name));\r
861 \r
862     OPJParseThread *pthread = CreateParseThread();\r
863     if (pthread->Run() != wxTHREAD_NO_ERROR)\r
864         wxLogMessage(wxT("Can't start parse thread!"));\r
865     else\r
866                 wxLogMessage(_T("New parse thread started."));\r
867 }\r
868 \r
869 void OPJMarkerTree::CreateImageList(int size)\r
870 {\r
871     if ( size == -1 )\r
872     {\r
873         SetImageList(NULL);\r
874         return;\r
875     }\r
876     if ( size == 0 )\r
877         size = m_imageSize;\r
878     else\r
879         m_imageSize = size;\r
880 \r
881     // Make an image list containing small icons\r
882     wxImageList *images = new wxImageList(size, size, true);\r
883 \r
884     // should correspond to TreeCtrlIcon_xxx enum\r
885     wxBusyCursor wait;\r
886     wxIcon icons[5];\r
887     icons[0] = wxIcon(icon1_xpm);\r
888     icons[1] = wxIcon(icon2_xpm);\r
889     icons[2] = wxIcon(icon3_xpm);\r
890     icons[3] = wxIcon(icon4_xpm);\r
891     icons[4] = wxIcon(icon5_xpm);\r
892 \r
893     int sizeOrig = icons[0].GetWidth();\r
894     for ( size_t i = 0; i < WXSIZEOF(icons); i++ )\r
895     {\r
896         if ( size == sizeOrig )\r
897         {\r
898             images->Add(icons[i]);\r
899         }\r
900         else\r
901         {\r
902             images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));\r
903         }\r
904     }\r
905 \r
906     AssignImageList(images);\r
907 }\r
908 \r
909 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)\r
910 void OPJMarkerTree::CreateButtonsImageList(int size)\r
911 {\r
912     if ( size == -1 )\r
913     {\r
914         SetButtonsImageList(NULL);\r
915         return;\r
916     }\r
917 \r
918     // Make an image list containing small icons\r
919     wxImageList *images = new wxImageList(size, size, true);\r
920 \r
921     // should correspond to TreeCtrlIcon_xxx enum\r
922     wxBusyCursor wait;\r
923     wxIcon icons[4];\r
924     icons[0] = wxIcon(icon3_xpm);   // closed\r
925     icons[1] = wxIcon(icon3_xpm);   // closed, selected\r
926     icons[2] = wxIcon(icon5_xpm);   // open\r
927     icons[3] = wxIcon(icon5_xpm);   // open, selected\r
928 \r
929     for ( size_t i = 0; i < WXSIZEOF(icons); i++ )\r
930     {\r
931         int sizeOrig = icons[i].GetWidth();\r
932         if ( size == sizeOrig )\r
933         {\r
934             images->Add(icons[i]);\r
935         }\r
936         else\r
937         {\r
938             images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));\r
939         }\r
940     }\r
941 \r
942     AssignButtonsImageList(images);\r
943 #else\r
944 void OPJMarkerTree::CreateButtonsImageList(int WXUNUSED(size))\r
945 {\r
946 #endif\r
947 }\r
948 \r
949 void OPJParseThread::LoadFile(wxFileName fname)\r
950 {\r
951         wxTreeItemId rootid;\r
952 \r
953         // this is the root node\r
954         int image = wxGetApp().ShowImages() ? m_tree->TreeCtrlIcon_Folder : -1;\r
955 \r
956         if (this->m_parentid) {\r
957                 // leaf of a tree\r
958                 rootid = m_parentid;\r
959                 m_tree->SetItemText(rootid, wxT("Parsing..."));\r
960 \r
961         } else {\r
962 \r
963                 // delete the existing tree hierarchy\r
964                 m_tree->DeleteAllItems();\r
965 \r
966                 // new tree\r
967                 rootid = m_tree->AddRoot(wxT("Parsing..."),\r
968                         image,\r
969                         image,\r
970                         new OPJMarkerData(fname.GetFullPath())\r
971                         );\r
972                 //m_tree->SetItemFont(rootid, *wxITALIC_FONT);\r
973                 m_tree->SetItemBold(rootid);\r
974         }\r
975 \r
976         // open the file\r
977         wxFile m_file(fname.GetFullPath().c_str(), wxFile::read);\r
978 \r
979         // what is the extension?\r
980         if ((fname.GetExt() == wxT("j2k")) || (fname.GetExt() == wxT("j2c"))) {\r
981 \r
982                 // parse the file\r
983                 ParseJ2KFile(&m_file, 0, m_file.Length(), rootid);\r
984 \r
985         } else if ((fname.GetExt() == wxT("jp2")) || (fname.GetExt() == wxT("mj2"))) {\r
986 \r
987                 // parse the file\r
988                 if (this->m_parentid) {\r
989                         //WriteText(wxT("Only a subsection of jp2"));\r
990                         OPJMarkerData *data = (OPJMarkerData *) m_tree->GetItemData(rootid);\r
991                         ParseJ2KFile(&m_file, data->m_start, data->m_length, rootid);\r
992                         m_tree->Expand(rootid);\r
993 \r
994                 } else\r
995                         // as usual\r
996                         ParseJP2File(&m_file, 0, m_file.Length(), rootid);\r
997 \r
998         } else {\r
999 \r
1000                 // unknown extension\r
1001                 WriteText(wxT("Unknown file format!"));\r
1002 \r
1003         }\r
1004 \r
1005         // close the file\r
1006         m_file.Close();\r
1007 \r
1008         // this is the root node\r
1009         if (this->m_parentid)\r
1010                 m_tree->SetItemText(rootid, wxT("Codestream"));\r
1011         else\r
1012                 m_tree->SetItemText(rootid, fname.GetFullName());\r
1013         \r
1014         WriteText(wxT("Parsing finished!"));\r
1015 }\r
1016 \r
1017 /*int OPJMarkerTree::OnCompareItems(const wxTreeItemId& item1,\r
1018                                const wxTreeItemId& item2)\r
1019 {\r
1020     if ( m_reverseSort )\r
1021     {\r
1022         // just exchange 1st and 2nd items\r
1023         return wxTreeCtrl::OnCompareItems(item2, item1);\r
1024     }\r
1025     else\r
1026     {\r
1027         return wxTreeCtrl::OnCompareItems(item1, item2);\r
1028     }\r
1029 }*/\r
1030 \r
1031 /*void OPJMarkerTree::AddItemsRecursively(const wxTreeItemId& idParent,\r
1032                                      size_t numChildren,\r
1033                                      size_t depth,\r
1034                                      size_t folder)\r
1035 {\r
1036     if ( depth > 0 )\r
1037     {\r
1038         bool hasChildren = depth > 1;\r
1039 \r
1040         wxString str;\r
1041         for ( size_t n = 0; n < numChildren; n++ )\r
1042         {\r
1043             // at depth 1 elements won't have any more children\r
1044             if ( hasChildren )\r
1045                 str.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n + 1));\r
1046             else\r
1047                 str.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder), unsigned(n + 1));\r
1048 \r
1049             // here we pass to AppendItem() normal and selected item images (we\r
1050             // suppose that selected image follows the normal one in the enum)\r
1051             int image, imageSel;\r
1052             if ( wxGetApp().ShowImages() )\r
1053             {\r
1054                 image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;\r
1055                 imageSel = image + 1;\r
1056             }\r
1057             else\r
1058             {\r
1059                 image = imageSel = -1;\r
1060             }\r
1061             wxTreeItemId id = AppendItem(idParent, str, image, imageSel,\r
1062                                          new OPJMarkerData(str));\r
1063 \r
1064             // and now we also set the expanded one (only for the folders)\r
1065             if ( hasChildren && wxGetApp().ShowImages() )\r
1066             {\r
1067                 SetItemImage(id, TreeCtrlIcon_FolderOpened,\r
1068                              wxTreeItemIcon_Expanded);\r
1069             }\r
1070 \r
1071             // remember the last child for OnEnsureVisible()\r
1072             if ( !hasChildren && n == numChildren - 1 )\r
1073             {\r
1074                 m_lastItem = id;\r
1075             }\r
1076 \r
1077             AddItemsRecursively(id, numChildren, depth - 1, n + 1);\r
1078         }\r
1079     }\r
1080     //else: done!\r
1081 }*/\r
1082 \r
1083 /*void OPJMarkerTree::AddTestItemsToTree(size_t numChildren,\r
1084                                     size_t depth)\r
1085 {\r
1086     int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1;\r
1087     wxTreeItemId rootId = AddRoot(wxT("Root"),\r
1088                                   image, image,\r
1089                                   new OPJMarkerData(wxT("Root item")));\r
1090     if ( image != -1 )\r
1091     {\r
1092         SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded);\r
1093     }\r
1094 \r
1095     AddItemsRecursively(rootId, numChildren, depth, 0);\r
1096 \r
1097     // set some colours/fonts for testing\r
1098     SetItemFont(rootId, *wxITALIC_FONT);\r
1099 \r
1100     wxTreeItemIdValue cookie;\r
1101     wxTreeItemId id = GetFirstChild(rootId, cookie);\r
1102     SetItemTextColour(id, *wxBLUE);\r
1103 \r
1104     id = GetNextChild(rootId, cookie);\r
1105     id = GetNextChild(rootId, cookie);\r
1106     SetItemTextColour(id, *wxRED);\r
1107     SetItemBackgroundColour(id, *wxLIGHT_GREY);\r
1108 }*/\r
1109 \r
1110 /*void OPJMarkerTree::GetItemsRecursively(const wxTreeItemId& idParent,\r
1111                                      wxTreeItemIdValue cookie)\r
1112 {\r
1113     wxTreeItemId id;\r
1114 \r
1115     if ( !cookie )\r
1116         id = GetFirstChild(idParent, cookie);\r
1117     else\r
1118         id = GetNextChild(idParent, cookie);\r
1119 \r
1120     if ( !id.IsOk() )\r
1121         return;\r
1122 \r
1123     wxString text = GetItemText(id);\r
1124     wxLogMessage(text);\r
1125 \r
1126     if (ItemHasChildren(id))\r
1127         GetItemsRecursively(id);\r
1128 \r
1129     GetItemsRecursively(idParent, cookie);\r
1130 }*/\r
1131 \r
1132 /*void OPJMarkerTree::DoToggleIcon(const wxTreeItemId& item)\r
1133 {\r
1134     int image = (GetItemImage(item) == TreeCtrlIcon_Folder)\r
1135                     ? TreeCtrlIcon_File\r
1136                     : TreeCtrlIcon_Folder;\r
1137     SetItemImage(item, image, wxTreeItemIcon_Normal);\r
1138 \r
1139     image = (GetItemImage(item) == TreeCtrlIcon_FolderSelected)\r
1140                     ? TreeCtrlIcon_FileSelected\r
1141                     : TreeCtrlIcon_FolderSelected;\r
1142     SetItemImage(item, image, wxTreeItemIcon_Selected);\r
1143 }*/\r
1144 \r
1145 void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event)\r
1146 {\r
1147     wxTreeItemId item = event.GetItem();\r
1148     wxString text;\r
1149     if ( item.IsOk() )\r
1150         text << _T('"') << GetItemText(item).c_str() << _T('"');\r
1151     else\r
1152         text = _T("invalid item");\r
1153     wxLogMessage(wxT("%s(%s)"), name, text.c_str());\r
1154 }\r
1155 \r
1156 OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid)\r
1157 {\r
1158     OPJParseThread *pthread = new OPJParseThread(this, parentid);\r
1159 \r
1160     if (pthread->Create() != wxTHREAD_NO_ERROR)\r
1161                 wxLogError(wxT("Can't create parse thread!"));\r
1162 \r
1163     wxCriticalSectionLocker enter(wxGetApp().m_parse_critsect);\r
1164     wxGetApp().m_parse_threads.Add(pthread);\r
1165 \r
1166     return pthread;\r
1167 }\r
1168 \r
1169 \r
1170 /*// avoid repetition\r
1171 #define TREE_EVENT_HANDLER(name)                                 \\r
1172 void OPJMarkerTree::name(wxTreeEvent& event)                        \\r
1173 {                                                                \\r
1174     LogEvent(_T(#name), event);                                  \\r
1175     SetLastItem(wxTreeItemId());                                 \\r
1176     event.Skip();                                                \\r
1177 }*/\r
1178 \r
1179 /*TREE_EVENT_HANDLER(OnBeginRDrag)*/\r
1180 /*TREE_EVENT_HANDLER(OnDeleteItem)*/\r
1181 /*TREE_EVENT_HANDLER(OnGetInfo)\r
1182 TREE_EVENT_HANDLER(OnSetInfo)*/\r
1183 /*TREE_EVENT_HANDLER(OnItemExpanded)\r
1184 TREE_EVENT_HANDLER(OnItemExpanding)*/\r
1185 /*TREE_EVENT_HANDLER(OnItemCollapsed)*/\r
1186 /*TREE_EVENT_HANDLER(OnSelChanged)\r
1187 TREE_EVENT_HANDLER(OnSelChanging)*/\r
1188 \r
1189 /*#undef TREE_EVENT_HANDLER*/\r
1190 \r
1191 void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event)\r
1192 {\r
1193         wxTreeItemId item = event.GetItem();\r
1194         OPJMarkerData* data = (OPJMarkerData *) GetItemData(item);\r
1195         wxString text;\r
1196 \r
1197         if (item.IsOk())\r
1198                 text << wxT('"') << GetItemText(item).c_str() << wxT('"');\r
1199         else\r
1200                 text = wxT("invalid item");\r
1201 \r
1202         if (strcmp(data->GetDesc1(), wxT("INFO-CSTREAM")))\r
1203                 return;\r
1204 \r
1205         wxLogMessage(wxT("Expanding... (%s -> %s, %s, %d, %d)"),\r
1206                 text.c_str(), data->GetDesc1(), data->GetDesc2(),\r
1207                 data->m_start, data->m_length);\r
1208 \r
1209         // the codestream box is being asked for expansion\r
1210         wxTreeItemIdValue cookie;\r
1211         if (!GetFirstChild(item, cookie).IsOk()) {\r
1212                 OPJParseThread *pthread = CreateParseThread(item);\r
1213                 if (pthread->Run() != wxTHREAD_NO_ERROR)\r
1214                         wxLogMessage(wxT("Can't start parse thread!"));\r
1215                 else\r
1216                         wxLogMessage(wxT("New parse thread started."));\r
1217         }\r
1218 }\r
1219 \r
1220 void OPJMarkerTree::OnSelChanged(wxTreeEvent& event)\r
1221 {\r
1222 #define BUNCH_LINESIZE  24\r
1223 #define BUNCH_NUMLINES  6\r
1224 \r
1225         wxTreeItemId item = event.GetItem();\r
1226         OPJMarkerData* data = (OPJMarkerData *) GetItemData(item);\r
1227         wxString text;\r
1228         int l, c, pos = 0, pre_pos;\r
1229         unsigned char buffer[BUNCH_LINESIZE * BUNCH_NUMLINES];\r
1230 \r
1231         m_peektextCtrl->Clear();\r
1232 \r
1233         /*wxTextAttr myattr = m_peektextCtrl->GetDefaultStyle();\r
1234         myattr.SetFont(wxFont(10, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));\r
1235         m_peektextCtrl->SetDefaultStyle(myattr);*/\r
1236 \r
1237         text << wxString::Format(wxT("Selected... (%s -> %s, %s, %d, %d)"),\r
1238                 text.c_str(), data->GetDesc1(), data->GetDesc2(),\r
1239                 data->m_start, data->m_length) << wxT("\n");\r
1240 \r
1241         // open the file and browse a little\r
1242         wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read);\r
1243 \r
1244         // go to position claimed\r
1245         fp->Seek(data->m_start, wxFromStart);\r
1246 \r
1247         // read a bunch\r
1248         int max_read = wxMin(WXSIZEOF(buffer), data->m_length - data->m_start + 1);\r
1249         fp->Read(buffer, max_read);\r
1250 \r
1251         pos = 0;\r
1252         for (l = 0; l < BUNCH_NUMLINES; l++) {\r
1253 \r
1254                 text << wxString::Format(wxT("%08d:"), data->m_start + pos);\r
1255 \r
1256                 pre_pos = pos;\r
1257 \r
1258                 // add hex browsing text\r
1259                 for (c = 0; c < BUNCH_LINESIZE; c++) {\r
1260 \r
1261                         if (!(c % 8))\r
1262                                 text << wxT(" ");\r
1263 \r
1264                         if (pos < max_read) {\r
1265                                 text << wxString::Format(wxT("%02X "), wxT(buffer[pos]));\r
1266                         } else\r
1267                                 text << wxT("   ");\r
1268                         pos++;\r
1269                 }\r
1270 \r
1271                 text << wxT("    ");\r
1272 \r
1273                 // add char browsing text\r
1274                 for (c = 0; c < BUNCH_LINESIZE; c++) {\r
1275 \r
1276                         if (pre_pos < max_read) {\r
1277                                 if ((buffer[pre_pos] == '\n') || (buffer[pre_pos] == '\t'))\r
1278                                         buffer[pre_pos] = ' ';\r
1279                                 text << wxString::Format(wxT("%c."), wxChar(buffer[pre_pos]));\r
1280                         } else\r
1281                                 text << wxT("  ");\r
1282                         pre_pos++;\r
1283                 }\r
1284 \r
1285                 text << wxT("\n");\r
1286 \r
1287         }\r
1288 \r
1289         // close the file\r
1290         fp->Close();\r
1291 \r
1292         m_peektextCtrl->WriteText(text);\r
1293 }\r
1294 \r
1295 /*void LogKeyEvent(const wxChar *name, const wxKeyEvent& event)\r
1296 {\r
1297     wxString key;\r
1298     long keycode = event.GetKeyCode();\r
1299     {\r
1300         switch ( keycode )\r
1301         {\r
1302             case WXK_BACK: key = wxT("BACK"); break;\r
1303             case WXK_TAB: key = wxT("TAB"); break;\r
1304             case WXK_RETURN: key = wxT("RETURN"); break;\r
1305             case WXK_ESCAPE: key = wxT("ESCAPE"); break;\r
1306             case WXK_SPACE: key = wxT("SPACE"); break;\r
1307             case WXK_DELETE: key = wxT("DELETE"); break;\r
1308             case WXK_START: key = wxT("START"); break;\r
1309             case WXK_LBUTTON: key = wxT("LBUTTON"); break;\r
1310             case WXK_RBUTTON: key = wxT("RBUTTON"); break;\r
1311             case WXK_CANCEL: key = wxT("CANCEL"); break;\r
1312             case WXK_MBUTTON: key = wxT("MBUTTON"); break;\r
1313             case WXK_CLEAR: key = wxT("CLEAR"); break;\r
1314             case WXK_SHIFT: key = wxT("SHIFT"); break;\r
1315             case WXK_ALT: key = wxT("ALT"); break;\r
1316             case WXK_CONTROL: key = wxT("CONTROL"); break;\r
1317             case WXK_MENU: key = wxT("MENU"); break;\r
1318             case WXK_PAUSE: key = wxT("PAUSE"); break;\r
1319             case WXK_CAPITAL: key = wxT("CAPITAL"); break;\r
1320             case WXK_END: key = wxT("END"); break;\r
1321             case WXK_HOME: key = wxT("HOME"); break;\r
1322             case WXK_LEFT: key = wxT("LEFT"); break;\r
1323             case WXK_UP: key = wxT("UP"); break;\r
1324             case WXK_RIGHT: key = wxT("RIGHT"); break;\r
1325             case WXK_DOWN: key = wxT("DOWN"); break;\r
1326             case WXK_SELECT: key = wxT("SELECT"); break;\r
1327             case WXK_PRINT: key = wxT("PRINT"); break;\r
1328             case WXK_EXECUTE: key = wxT("EXECUTE"); break;\r
1329             case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break;\r
1330             case WXK_INSERT: key = wxT("INSERT"); break;\r
1331             case WXK_HELP: key = wxT("HELP"); break;\r
1332             case WXK_NUMPAD0: key = wxT("NUMPAD0"); break;\r
1333             case WXK_NUMPAD1: key = wxT("NUMPAD1"); break;\r
1334             case WXK_NUMPAD2: key = wxT("NUMPAD2"); break;\r
1335             case WXK_NUMPAD3: key = wxT("NUMPAD3"); break;\r
1336             case WXK_NUMPAD4: key = wxT("NUMPAD4"); break;\r
1337             case WXK_NUMPAD5: key = wxT("NUMPAD5"); break;\r
1338             case WXK_NUMPAD6: key = wxT("NUMPAD6"); break;\r
1339             case WXK_NUMPAD7: key = wxT("NUMPAD7"); break;\r
1340             case WXK_NUMPAD8: key = wxT("NUMPAD8"); break;\r
1341             case WXK_NUMPAD9: key = wxT("NUMPAD9"); break;\r
1342             case WXK_MULTIPLY: key = wxT("MULTIPLY"); break;\r
1343             case WXK_ADD: key = wxT("ADD"); break;\r
1344             case WXK_SEPARATOR: key = wxT("SEPARATOR"); break;\r
1345             case WXK_SUBTRACT: key = wxT("SUBTRACT"); break;\r
1346             case WXK_DECIMAL: key = wxT("DECIMAL"); break;\r
1347             case WXK_DIVIDE: key = wxT("DIVIDE"); break;\r
1348             case WXK_F1: key = wxT("F1"); break;\r
1349             case WXK_F2: key = wxT("F2"); break;\r
1350             case WXK_F3: key = wxT("F3"); break;\r
1351             case WXK_F4: key = wxT("F4"); break;\r
1352             case WXK_F5: key = wxT("F5"); break;\r
1353             case WXK_F6: key = wxT("F6"); break;\r
1354             case WXK_F7: key = wxT("F7"); break;\r
1355             case WXK_F8: key = wxT("F8"); break;\r
1356             case WXK_F9: key = wxT("F9"); break;\r
1357             case WXK_F10: key = wxT("F10"); break;\r
1358             case WXK_F11: key = wxT("F11"); break;\r
1359             case WXK_F12: key = wxT("F12"); break;\r
1360             case WXK_F13: key = wxT("F13"); break;\r
1361             case WXK_F14: key = wxT("F14"); break;\r
1362             case WXK_F15: key = wxT("F15"); break;\r
1363             case WXK_F16: key = wxT("F16"); break;\r
1364             case WXK_F17: key = wxT("F17"); break;\r
1365             case WXK_F18: key = wxT("F18"); break;\r
1366             case WXK_F19: key = wxT("F19"); break;\r
1367             case WXK_F20: key = wxT("F20"); break;\r
1368             case WXK_F21: key = wxT("F21"); break;\r
1369             case WXK_F22: key = wxT("F22"); break;\r
1370             case WXK_F23: key = wxT("F23"); break;\r
1371             case WXK_F24: key = wxT("F24"); break;\r
1372             case WXK_NUMLOCK: key = wxT("NUMLOCK"); break;\r
1373             case WXK_SCROLL: key = wxT("SCROLL"); break;\r
1374             case WXK_PAGEUP: key = wxT("PAGEUP"); break;\r
1375             case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break;\r
1376             case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break;\r
1377             case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break;\r
1378             case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break;\r
1379             case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break;\r
1380             case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break;\r
1381             case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break;\r
1382             case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break;\r
1383             case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break;\r
1384             case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break;\r
1385             case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break;\r
1386             case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break;\r
1387             case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break;\r
1388             case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break;\r
1389             case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break;\r
1390             case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break;\r
1391             case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break;\r
1392             case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break;\r
1393             case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break;\r
1394             case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break;\r
1395             case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break;\r
1396             case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break;\r
1397             case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break;\r
1398             case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break;\r
1399             case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break;\r
1400 \r
1401             default:\r
1402             {\r
1403                if ( keycode < 128 && wxIsprint((int)keycode) )\r
1404                    key.Printf(wxT("'%c'"), (char)keycode);\r
1405                else if ( keycode > 0 && keycode < 27 )\r
1406                    key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1);\r
1407                else\r
1408                    key.Printf(wxT("unknown (%ld)"), keycode);\r
1409             }\r
1410         }\r
1411     }\r
1412 \r
1413     wxLogMessage( wxT("%s event: %s (flags = %c%c%c%c)"),\r
1414                   name,\r
1415                   key.c_str(),\r
1416                   event.ControlDown() ? wxT('C') : wxT('-'),\r
1417                   event.AltDown() ? wxT('A') : wxT('-'),\r
1418                   event.ShiftDown() ? wxT('S') : wxT('-'),\r
1419                   event.MetaDown() ? wxT('M') : wxT('-'));\r
1420 }\r
1421 \r
1422 void OPJMarkerTree::OnTreeKeyDown(wxTreeEvent& event)\r
1423 {\r
1424     LogKeyEvent(wxT("Tree key down "), event.GetKeyEvent());\r
1425 \r
1426     event.Skip();\r
1427 }*/\r
1428 \r
1429 /*void OPJMarkerTree::OnBeginDrag(wxTreeEvent& event)\r
1430 {\r
1431     // need to explicitly allow drag\r
1432     if ( event.GetItem() != GetRootItem() )\r
1433     {\r
1434         m_draggedItem = event.GetItem();\r
1435 \r
1436         wxLogMessage(wxT("OnBeginDrag: started dragging %s"),\r
1437                      GetItemText(m_draggedItem).c_str());\r
1438 \r
1439         event.Allow();\r
1440     }\r
1441     else\r
1442     {\r
1443         wxLogMessage(wxT("OnBeginDrag: this item can't be dragged."));\r
1444     }\r
1445 }\r
1446 \r
1447 void OPJMarkerTree::OnEndDrag(wxTreeEvent& event)\r
1448 {\r
1449     wxTreeItemId itemSrc = m_draggedItem,\r
1450                  itemDst = event.GetItem();\r
1451     m_draggedItem = (wxTreeItemId)0l;\r
1452 \r
1453     // where to copy the item?\r
1454     if ( itemDst.IsOk() && !ItemHasChildren(itemDst) )\r
1455     {\r
1456         // copy to the parent then\r
1457         itemDst = GetItemParent(itemDst);\r
1458     }\r
1459 \r
1460     if ( !itemDst.IsOk() )\r
1461     {\r
1462         wxLogMessage(wxT("OnEndDrag: can't drop here."));\r
1463 \r
1464         return;\r
1465     }\r
1466 \r
1467     wxString text = GetItemText(itemSrc);\r
1468     wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."),\r
1469                  text.c_str(), GetItemText(itemDst).c_str());\r
1470 \r
1471     // just do append here - we could also insert it just before/after the item\r
1472     // on which it was dropped, but this requires slightly more work... we also\r
1473     // completely ignore the client data and icon of the old item but could\r
1474     // copy them as well.\r
1475     //\r
1476     // Finally, we only copy one item here but we might copy the entire tree if\r
1477     // we were dragging a folder.\r
1478     int image = wxGetApp().ShowImages() ? TreeCtrlIcon_File : -1;\r
1479     AppendItem(itemDst, text, image);\r
1480 }*/\r
1481 \r
1482 /*void OPJMarkerTree::OnBeginLabelEdit(wxTreeEvent& event)\r
1483 {\r
1484     wxLogMessage(wxT("OnBeginLabelEdit"));\r
1485 \r
1486     // for testing, prevent this item's label editing\r
1487     wxTreeItemId itemId = event.GetItem();\r
1488     if ( IsTestItem(itemId) )\r
1489     {\r
1490         wxMessageBox(wxT("You can't edit this item."));\r
1491 \r
1492         event.Veto();\r
1493     }\r
1494     else if ( itemId == GetRootItem() )\r
1495     {\r
1496         // test that it is possible to change the text of the item being edited\r
1497         SetItemText(itemId, _T("Editing root item"));\r
1498     }\r
1499 }\r
1500 \r
1501 void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event)\r
1502 {\r
1503     wxLogMessage(wxT("OnEndLabelEdit"));\r
1504 \r
1505     // don't allow anything except letters in the labels\r
1506     if ( !event.GetLabel().IsWord() )\r
1507     {\r
1508         wxMessageBox(wxT("The new label should be a single word."));\r
1509 \r
1510         event.Veto();\r
1511     }\r
1512 }*/\r
1513 \r
1514 /*void OPJMarkerTree::OnItemCollapsing(wxTreeEvent& event)\r
1515 {\r
1516     wxLogMessage(wxT("OnItemCollapsing"));\r
1517 \r
1518     // for testing, prevent the user from collapsing the first child folder\r
1519     wxTreeItemId itemId = event.GetItem();\r
1520     if ( IsTestItem(itemId) )\r
1521     {\r
1522         wxMessageBox(wxT("You can't collapse this item."));\r
1523 \r
1524         event.Veto();\r
1525     }\r
1526 }*/\r
1527 \r
1528 /*void OPJMarkerTree::OnItemActivated(wxTreeEvent& event)\r
1529 {\r
1530     // show some info about this item\r
1531     wxTreeItemId itemId = event.GetItem();\r
1532     OPJMarkerData *item = (OPJMarkerData *)GetItemData(itemId);\r
1533 \r
1534     if ( item != NULL )\r
1535     {\r
1536         item->ShowInfo(this);\r
1537     }\r
1538 \r
1539     wxLogMessage(wxT("OnItemActivated"));\r
1540 }*/\r
1541 \r
1542 /*void OPJMarkerTree::OnItemMenu(wxTreeEvent& event)\r
1543 {\r
1544     wxTreeItemId itemId = event.GetItem();\r
1545     OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId)\r
1546                                          : NULL;\r
1547 \r
1548     wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc()\r
1549                                                          : _T(""));\r
1550 \r
1551     event.Skip();\r
1552 }*/\r
1553 \r
1554 /*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event)\r
1555 {\r
1556     wxPoint pt = event.GetPosition();\r
1557     wxTreeItemId item;\r
1558     wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y);\r
1559 \r
1560     // check if event was generated by keyboard (MSW-specific?)\r
1561     if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it)\r
1562     {\r
1563         if ( !HasFlag(wxTR_MULTIPLE) )\r
1564             item = GetSelection();\r
1565 \r
1566         // attempt to guess where to show the menu\r
1567         if ( item.IsOk() )\r
1568         {\r
1569             // if an item was clicked, show menu to the right of it\r
1570             wxRect rect;\r
1571             GetBoundingRect(item, rect, true );// only the label\r
1572             pt = wxPoint(rect.GetRight(), rect.GetTop());\r
1573         }\r
1574         else\r
1575         {\r
1576             pt = wxPoint(0, 0);\r
1577         }\r
1578     }\r
1579     else // event was generated by mouse, use supplied coords\r
1580     {\r
1581         pt = ScreenToClient(pt);\r
1582         item = HitTest(pt);\r
1583     }\r
1584 \r
1585     ShowMenu(item, pt);\r
1586 }*/\r
1587 \r
1588 /*void OPJMarkerTree::ShowMenu(wxTreeItemId id, const wxPoint& pt)\r
1589 {\r
1590     wxString title;\r
1591     if ( id.IsOk() )\r
1592     {\r
1593         title << wxT("Menu for ") << GetItemText(id);\r
1594     }\r
1595     else\r
1596     {\r
1597         title = wxT("Menu for no particular item");\r
1598     }\r
1599 \r
1600 #if wxUSE_MENUS\r
1601     wxMenu menu(title);\r
1602     menu.Append(TreeTest_About, wxT("&About..."));\r
1603     menu.AppendSeparator();\r
1604     menu.Append(TreeTest_Highlight, wxT("&Highlight item"));\r
1605     menu.Append(TreeTest_Dump, wxT("&Dump"));\r
1606 \r
1607     PopupMenu(&menu, pt);\r
1608 #endif // wxUSE_MENUS\r
1609 }*/\r
1610 \r
1611 /*void OPJMarkerTree::OnItemRClick(wxTreeEvent& event)\r
1612 {\r
1613     wxTreeItemId itemId = event.GetItem();\r
1614     OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId)\r
1615                                          : NULL;\r
1616 \r
1617     wxLogMessage(wxT("Item \"%s\" right clicked"), item ? item->GetDesc()\r
1618                                                         : _T(""));\r
1619 \r
1620     event.Skip();\r
1621 }*/\r
1622 \r
1623 /*\r
1624 void OPJMarkerTree::OnRMouseDown(wxMouseEvent& event)\r
1625 {\r
1626     wxLogMessage(wxT("Right mouse button down"));\r
1627 \r
1628     event.Skip();\r
1629 }\r
1630 \r
1631 void OPJMarkerTree::OnRMouseUp(wxMouseEvent& event)\r
1632 {\r
1633     wxLogMessage(wxT("Right mouse button up"));\r
1634 \r
1635     event.Skip();\r
1636 }\r
1637 \r
1638 void OPJMarkerTree::OnRMouseDClick(wxMouseEvent& event)\r
1639 {\r
1640     wxTreeItemId id = HitTest(event.GetPosition());\r
1641     if ( !id )\r
1642         wxLogMessage(wxT("No item under mouse"));\r
1643     else\r
1644     {\r
1645         OPJMarkerData *item = (OPJMarkerData *)GetItemData(id);\r
1646         if ( item )\r
1647             wxLogMessage(wxT("Item '%s' under mouse"), item->GetDesc());\r
1648     }\r
1649 \r
1650     event.Skip();\r
1651 }\r
1652 */\r
1653 \r
1654 static inline const wxChar *Bool2String(bool b)\r
1655 {\r
1656     return b ? wxT("") : wxT("not ");\r
1657 }\r
1658 \r
1659 void OPJMarkerData::ShowInfo(wxTreeCtrl *tree)\r
1660 {\r
1661     wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n")\r
1662                  wxT("%u children (%u immediately under this item)."),\r
1663                  m_desc.c_str(),\r
1664                  Bool2String(tree->IsSelected(GetId())),\r
1665                  Bool2String(tree->IsExpanded(GetId())),\r
1666                  Bool2String(tree->IsBold(GetId())),\r
1667                  unsigned(tree->GetChildrenCount(GetId())),\r
1668                  unsigned(tree->GetChildrenCount(GetId(), false)));\r
1669 }\r
1670 \r
1671 /////////////////////////////////////////////////////////////////////\r
1672 // Decoding thread class\r
1673 /////////////////////////////////////////////////////////////////////\r
1674 \r
1675 OPJDecoThread::OPJDecoThread(OPJCanvas *canvas)\r
1676         : wxThread()\r
1677 {\r
1678     m_count = 0;\r
1679     m_canvas = canvas;\r
1680 }\r
1681 \r
1682 void OPJDecoThread::WriteText(const wxString& text)\r
1683 {\r
1684     wxString msg;\r
1685 \r
1686     // before doing any GUI calls we must ensure that this thread is the only\r
1687     // one doing it!\r
1688 \r
1689     wxMutexGuiEnter();\r
1690 \r
1691     msg << text;\r
1692     m_canvas->WriteText(msg);\r
1693 \r
1694     wxMutexGuiLeave();\r
1695 }\r
1696 \r
1697 void OPJDecoThread::OnExit()\r
1698 {\r
1699     wxCriticalSectionLocker locker(wxGetApp().m_deco_critsect);\r
1700 \r
1701     wxArrayThread& dthreads = wxGetApp().m_deco_threads;\r
1702     dthreads.Remove(this);\r
1703 \r
1704     if (dthreads.IsEmpty() )\r
1705     {\r
1706         // signal the main thread that there are no more threads left if it is\r
1707         // waiting for us\r
1708         if (wxGetApp().m_deco_waitingUntilAllDone) {\r
1709             wxGetApp().m_deco_waitingUntilAllDone = false;\r
1710             wxGetApp().m_deco_semAllDone.Post();\r
1711         }\r
1712     }\r
1713 }\r
1714 \r
1715 void *OPJDecoThread::Entry()\r
1716 {\r
1717 \r
1718     wxString text;\r
1719 \r
1720         srand(GetId());\r
1721         int m_countnum = rand() % 9;\r
1722     text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."),\r
1723                 GetId(), GetPriority(), m_countnum);\r
1724     WriteText(text);\r
1725     // wxLogMessage(text); -- test wxLog thread safeness\r
1726 \r
1727         //wxBusyCursor wait;\r
1728         //wxBusyInfo wait(wxT("Decoding image ..."));\r
1729 \r
1730 \r
1731     /*for (m_count = 0; m_count < m_countnum; m_count++) {\r
1732         // check if we were asked to exit\r
1733         if ( TestDestroy() )\r
1734             break;\r
1735 \r
1736         text.Printf(wxT("[%u] Deco thread 0x%lx here."), m_count, GetId());\r
1737         WriteText(text);\r
1738 \r
1739         // wxSleep() can't be called from non-GUI thread!\r
1740         wxThread::Sleep(10);\r
1741     }*/\r
1742 \r
1743     wxBitmap bitmap( 100, 100 );\r
1744     wxImage image = bitmap.ConvertToImage();\r
1745     image.Destroy();\r
1746 \r
1747         WriteText(m_canvas->m_fname.GetFullPath());\r
1748 \r
1749     if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY), 0) {\r
1750         wxLogError(wxT("Can't load image"));\r
1751                 return NULL;\r
1752         }\r
1753 \r
1754     m_canvas->m_image = wxBitmap(image);\r
1755         m_canvas->Refresh();\r
1756         m_canvas->SetScrollbars(20, 20, (int)(0.5 + (double) image.GetWidth() / 20.0), (int)(0.5 + (double) image.GetHeight() / 20.0));\r
1757 \r
1758     text.Printf(wxT("Deco thread 0x%lx finished."), GetId());\r
1759     WriteText(text);\r
1760     // wxLogMessage(text); -- test wxLog thread safeness\r
1761 \r
1762     return NULL;\r
1763 }\r
1764 \r
1765 /////////////////////////////////////////////////////////////////////\r
1766 // Parsing thread class\r
1767 /////////////////////////////////////////////////////////////////////\r
1768 \r
1769 OPJParseThread::OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid)\r
1770         : wxThread()\r
1771 {\r
1772     m_count = 0;\r
1773     m_tree = tree;\r
1774         m_parentid = parentid;\r
1775 }\r
1776 \r
1777 void OPJParseThread::WriteText(const wxString& text)\r
1778 {\r
1779     wxString msg;\r
1780 \r
1781     // before doing any GUI calls we must ensure that this thread is the only\r
1782     // one doing it!\r
1783 \r
1784     wxMutexGuiEnter();\r
1785 \r
1786     msg << text;\r
1787     m_tree->WriteText(msg);\r
1788 \r
1789     wxMutexGuiLeave();\r
1790 }\r
1791 \r
1792 void OPJParseThread::OnExit()\r
1793 {\r
1794     wxCriticalSectionLocker locker(wxGetApp().m_parse_critsect);\r
1795 \r
1796     wxArrayThread& threads = wxGetApp().m_parse_threads;\r
1797     threads.Remove(this);\r
1798 \r
1799     if ( threads.IsEmpty() )\r
1800     {\r
1801         // signal the main thread that there are no more threads left if it is\r
1802         // waiting for us\r
1803         if ( wxGetApp().m_parse_waitingUntilAllDone )\r
1804         {\r
1805             wxGetApp().m_parse_waitingUntilAllDone = false;\r
1806 \r
1807             wxGetApp().m_parse_semAllDone.Post();\r
1808         }\r
1809     }\r
1810 }\r
1811 \r
1812 void *OPJParseThread::Entry()\r
1813 {\r
1814 \r
1815     wxString text;\r
1816 \r
1817         srand( GetId() );\r
1818         int m_countnum = rand() % 9;\r
1819     text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."),\r
1820                 GetId(), GetPriority(), m_countnum);\r
1821     WriteText(text);\r
1822     // wxLogMessage(text); -- test wxLog thread safeness\r
1823 \r
1824         //wxBusyCursor wait;\r
1825         //wxBusyInfo wait(wxT("Decoding image ..."));\r
1826 \r
1827 \r
1828     /*for ( m_count = 0; m_count < m_countnum; m_count++ )\r
1829     {\r
1830         // check if we were asked to exit\r
1831         if ( TestDestroy() )\r
1832             break;\r
1833 \r
1834         text.Printf(wxT("[%u] Parse thread 0x%lx here."), m_count, GetId());\r
1835         WriteText(text);\r
1836 \r
1837         // wxSleep() can't be called from non-GUI thread!\r
1838         wxThread::Sleep(10);\r
1839     }*/\r
1840 \r
1841 \r
1842     LoadFile(m_tree->m_fname);\r
1843 \r
1844     text.Printf(wxT("Parse thread 0x%lx finished."), GetId());\r
1845     WriteText(text);\r
1846     // wxLogMessage(text); -- test wxLog thread safeness\r
1847 \r
1848     return NULL;\r
1849 }\r