update j2k_lib with new opj type
[openjpeg.git] / applications / OPJViewer / source / OPJThreads.cpp
1 /*
2  * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita'� degli studi di Perugia (UPG), Italy
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include "OPJViewer.h"
27
28
29 /////////////////////////////////////////////////////////////////////
30 // Encoding thread class
31 /////////////////////////////////////////////////////////////////////
32
33 OPJEncoThread::OPJEncoThread(OPJCanvas *canvas)
34         : wxThread()
35 {
36     m_count = 0;
37     m_canvas = canvas;
38 }
39
40 void OPJEncoThread::WriteText(const wxString& text)
41 {
42     wxString msg;
43
44     // before doing any GUI calls we must ensure that this thread is the only
45     // one doing it!
46
47 #ifndef __WXGTK__ 
48     wxMutexGuiEnter();
49 #endif // __WXGTK__
50
51     msg << text;
52     m_canvas->WriteText(msg);
53
54 #ifndef __WXGTK__ 
55     wxMutexGuiLeave();
56 #endif // __WXGTK__
57 }
58
59 void OPJEncoThread::OnExit()
60 {
61     wxCriticalSectionLocker locker(wxGetApp().m_enco_critsect);
62
63     wxArrayThread& ethreads = wxGetApp().m_enco_threads;
64     ethreads.Remove(this);
65
66     if (ethreads.IsEmpty() )
67     {
68         // signal the main thread that there are no more threads left if it is
69         // waiting for us
70         if (wxGetApp().m_enco_waitingUntilAllDone) {
71             wxGetApp().m_enco_waitingUntilAllDone = false;
72             wxGetApp().m_enco_semAllDone.Post();
73         }
74     }
75 }
76
77 void *OPJEncoThread::Entry()
78 {
79     wxString text;
80
81         srand(GetId());
82         //int m_countnum = rand() % 9;
83     //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."),
84     //            GetId(), GetPriority(), m_countnum);
85     text.Printf(wxT("Enco thread %d started"), m_canvas->m_childframe->m_winnumber);
86     WriteText(text);
87
88         // set handler properties
89         wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000);
90         jpeg2000handler->m_subsampling = wxGetApp().m_subsampling;
91         jpeg2000handler->m_origin = wxGetApp().m_origin;
92         jpeg2000handler->m_rates = wxGetApp().m_rates;
93         jpeg2000handler->m_quality = wxGetApp().m_quality;
94         jpeg2000handler->m_enablequality = wxGetApp().m_enablequality;
95         jpeg2000handler->m_multicomp = wxGetApp().m_multicomp;
96         jpeg2000handler->m_irreversible = wxGetApp().m_irreversible;
97         jpeg2000handler->m_resolutions = wxGetApp().m_resolutions;
98         jpeg2000handler->m_progression = wxGetApp().m_progression;
99         jpeg2000handler->m_cbsize = wxGetApp().m_cbsize;
100         jpeg2000handler->m_prsize = wxGetApp().m_prsize;
101         jpeg2000handler->m_tsize = wxGetApp().m_tsize;
102         jpeg2000handler->m_torigin = wxGetApp().m_torigin;
103         jpeg2000handler->m_enablesop = wxGetApp().m_enablesop;
104         jpeg2000handler->m_enableeph = wxGetApp().m_enableeph;
105         jpeg2000handler->m_enablebypass = wxGetApp().m_enablebypass;
106         jpeg2000handler->m_enablerestart = wxGetApp().m_enablerestart;
107         jpeg2000handler->m_enablereset = wxGetApp().m_enablereset;
108         jpeg2000handler->m_enablesegmark = wxGetApp().m_enablesegmark;
109         jpeg2000handler->m_enableerterm = wxGetApp().m_enableerterm;
110         jpeg2000handler->m_enablevsc = wxGetApp().m_enablevsc;
111         jpeg2000handler->m_enableidx = wxGetApp().m_enableidx;
112         jpeg2000handler->m_index = m_canvas->m_savename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxGetApp().m_index;
113         jpeg2000handler->m_enablecomm = wxGetApp().m_enablecomm;
114         jpeg2000handler->m_comment = wxGetApp().m_comment;
115         jpeg2000handler->m_enablepoc = wxGetApp().m_enablepoc;
116         jpeg2000handler->m_poc = wxGetApp().m_poc;
117
118         // save the file
119         if (!m_canvas->m_image100.SaveFile(m_canvas->m_savename.GetFullPath(), (wxBitmapType) wxBITMAP_TYPE_JPEG2000)) {
120                 WriteText(wxT("Can't save image"));
121                 return NULL;
122         }
123
124     text.Printf(wxT("Enco thread %d finished"), m_canvas->m_childframe->m_winnumber);
125     WriteText(text);
126     return NULL;
127 }
128
129
130 /////////////////////////////////////////////////////////////////////
131 // Decoding thread class
132 /////////////////////////////////////////////////////////////////////
133 OPJDecoThread::OPJDecoThread(OPJCanvas *canvas)
134         : wxThread()
135 {
136     m_count = 0;
137     m_canvas = canvas;
138 }
139
140 void OPJDecoThread::WriteText(const wxString& text)
141 {
142     wxString msg;
143         
144         // we use a fake event and post it for inter-thread gui communication
145     wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG);
146     event.SetInt(-1); 
147         msg << text;
148         event.SetString(msg);
149     wxPostEvent(this->m_canvas->m_childframe->m_frame, event);
150
151 /*
152     // before doing any GUI calls we must ensure that this thread is the only
153     // one doing it!
154
155 #ifndef __WXGTK__ 
156     wxMutexGuiEnter();
157 #endif // __WXGTK__
158
159     msg << text;
160     m_canvas->WriteText(msg);
161
162 #ifndef __WXGTK__ 
163     wxMutexGuiLeave();
164 #endif // __WXGTK__
165 */
166 }
167
168 void OPJDecoThread::OnExit()
169 {
170     wxCriticalSectionLocker locker(wxGetApp().m_deco_critsect);
171
172     wxArrayThread& dthreads = wxGetApp().m_deco_threads;
173     dthreads.Remove(this);
174
175     if (dthreads.IsEmpty() )
176     {
177         // signal the main thread that there are no more threads left if it is
178         // waiting for us
179         if (wxGetApp().m_deco_waitingUntilAllDone) {
180             wxGetApp().m_deco_waitingUntilAllDone = false;
181             wxGetApp().m_deco_semAllDone.Post();
182         }
183     }
184 }
185
186 void *OPJDecoThread::Entry()
187 {
188
189     wxString text;
190
191         //srand(GetId());
192         //int m_countnum = rand() % 9;
193     //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."),
194     //            GetId(), GetPriority(), m_countnum);
195
196         // we have started
197     text.Printf(wxT("Deco thread %d started"), m_canvas->m_childframe->m_winnumber);
198     WriteText(text);
199
200         // prepare dummy wximage
201     wxBitmap bitmap(100, 100);
202     wxImage image(100, 100, true); //= bitmap.ConvertToImage();
203     image.Destroy();
204
205         // show image full name
206         WriteText(m_canvas->m_fname.GetFullPath());
207
208         // set handler properties
209         wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000);
210         jpeg2000handler->m_reducefactor = wxGetApp().m_reducefactor;
211         jpeg2000handler->m_qualitylayers = wxGetApp().m_qualitylayers;
212         jpeg2000handler->m_components = wxGetApp().m_components;
213         jpeg2000handler->m_framenum = wxGetApp().m_framenum;
214 #ifdef USE_JPWL
215         jpeg2000handler->m_enablejpwl = wxGetApp().m_enablejpwl;
216         jpeg2000handler->m_expcomps = wxGetApp().m_expcomps;
217         jpeg2000handler->m_maxtiles = wxGetApp().m_maxtiles;
218 #endif // USE_JPWL
219
220 #ifdef USE_MXF
221         wxMXFHandler *mxfffhandler = (wxMXFHandler *) wxImage::FindHandler(wxBITMAP_TYPE_MXF);
222         mxfffhandler->m_reducefactor = wxGetApp().m_reducefactor;
223         mxfffhandler->m_qualitylayers = wxGetApp().m_qualitylayers;
224         mxfffhandler->m_components = wxGetApp().m_components;
225         mxfffhandler->m_framenum = wxGetApp().m_framenum;
226         mxfffhandler->m_filename = m_canvas->m_fname;
227 #ifdef USE_JPWL
228         mxfffhandler->m_enablejpwl = wxGetApp().m_enablejpwl;
229         mxfffhandler->m_expcomps = wxGetApp().m_expcomps;
230         mxfffhandler->m_maxtiles = wxGetApp().m_maxtiles;
231 #endif // USE_JPWL
232 #endif // USE_MXF
233
234         // if decoding is enabled...
235         if (wxGetApp().m_enabledeco) {
236
237                 // load the file
238                 if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY, 0)) {
239                         WriteText(wxT("Can't load image!"));
240                         return NULL;
241                 }
242
243         } else {
244
245                 // display a warning
246                 if (!image.Create(300, 5, false)) {
247                         WriteText(wxT("Can't create image!"));
248                         return NULL;
249                 }
250
251         }
252
253         // assign 100% image
254     m_canvas->m_image100 = wxBitmap(image);
255
256         // signal the frame to refresh the canvas
257     wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_VIEWFIT);
258         event.SetString(wxT("Fit me"));
259     event.SetInt(m_canvas->m_childframe->m_winnumber); 
260     wxPostEvent(m_canvas->m_childframe->m_frame, event);
261
262         // find a fit-to-width zoom
263         /*int zooml, wzooml, hzooml;
264         wxSize clientsize = m_canvas->GetClientSize();
265         wzooml = (int) floor(100.0 * (double) clientsize.GetWidth() / (double) (2 * OPJ_CANVAS_BORDER + image.GetWidth()));
266         hzooml = (int) floor(100.0 * (double) clientsize.GetHeight() / (double) (2 * OPJ_CANVAS_BORDER + image.GetHeight()));
267         zooml = wxMin(100, wxMin(wzooml, hzooml));*/
268
269         // fit to width
270 #ifndef __WXGTK__
271         //m_canvas->m_childframe->m_frame->Rescale(zooml, m_canvas->m_childframe);
272 #endif // __WXGTK__
273
274         //m_canvas->m_image = m_canvas->m_image100;
275         //m_canvas->Refresh();
276         //m_canvas->SetScrollbars(20, 20, (int)(0.5 + (double) image.GetWidth() / 20.0), (int)(0.5 + (double) image.GetHeight() / 20.0));
277
278     //text.Printf(wxT("Deco thread 0x%lx finished."), GetId());
279     text.Printf(wxT("Deco thread %d finished"), m_canvas->m_childframe->m_winnumber);
280     WriteText(text);
281     return NULL;
282
283 }
284
285 /////////////////////////////////////////////////////////////////////
286 // Parsing thread class
287 /////////////////////////////////////////////////////////////////////
288
289 OPJParseThread::OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid)
290         : wxThread()
291 {
292     m_count = 0;
293     m_tree = tree;
294         m_parentid = parentid;
295 }
296
297 void OPJParseThread::WriteText(const wxString& text)
298 {
299     wxString msg;
300         
301         // we use a fake event and post it for inter-thread gui communication
302     wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG);
303     event.SetInt(-1); 
304         msg << text;
305         event.SetString(msg);
306     wxPostEvent(this->m_tree->m_childframe->m_frame, event);
307
308 /*    // before doing any GUI calls we must ensure that this thread is the only
309     // one doing it!
310
311 #ifndef __WXGTK__ 
312     wxMutexGuiEnter();
313 #endif // __WXGTK
314
315     msg << text;
316     m_tree->WriteText(msg);
317
318 #ifndef __WXGTK__ 
319     wxMutexGuiLeave();
320 #endif // __WXGTK*/
321 }
322
323 void OPJParseThread::OnExit()
324 {
325     wxCriticalSectionLocker locker(wxGetApp().m_parse_critsect);
326
327     wxArrayThread& threads = wxGetApp().m_parse_threads;
328     threads.Remove(this);
329
330     if (threads.IsEmpty()) {
331         // signal the main thread that there are no more threads left if it is
332         // waiting for us
333         if (wxGetApp().m_parse_waitingUntilAllDone) {
334             wxGetApp().m_parse_waitingUntilAllDone = false;
335             wxGetApp().m_parse_semAllDone.Post();
336         }
337     }
338 }
339
340 void *OPJParseThread::Entry()
341 {
342
343         printf("Entering\n\n");
344
345     wxString text;
346
347         srand(GetId());
348         int m_countnum = rand() % 9;
349     text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."),
350             GetId(), GetPriority(), m_countnum);
351     WriteText(text);
352     LoadFile(m_tree->m_fname);
353     text.Printf(wxT("Parse thread 0x%lx finished."), GetId());
354     WriteText(text);
355
356
357     //wxLogMessage(wxT("Entering\n")); //test wxLog thread safeness
358
359         //wxBusyCursor wait;
360         //wxBusyInfo wait(wxT("Decoding image ..."));
361
362
363     /*for ( m_count = 0; m_count < m_countnum; m_count++ )
364     {
365         // check if we were asked to exit
366         if ( TestDestroy() )
367             break;
368
369         text.Printf(wxT("[%u] Parse thread 0x%lx here."), m_count, GetId());
370         WriteText(text);
371
372         // wxSleep() can't be called from non-GUI thread!
373         wxThread::Sleep(10);
374     }*/
375
376     // wxLogMessage(text); -- test wxLog thread safeness
377
378         printf("Exiting\n\n");
379
380     return NULL;
381 }
382
383
384 ///////////////////////////////////////////
385 // Parsing hread and related
386 ///////////////////////////////////////////
387
388 #if USE_GENERIC_TREECTRL
389 BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl)
390 #else
391 BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl)
392 #endif
393     /*EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginDrag)
394     EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginRDrag)
395     EVT_TREE_END_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnEndDrag)*/
396     /*EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnBeginLabelEdit)
397     EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnEndLabelEdit)*/
398     /*EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, OPJMarkerTree::OnDeleteItem)*/
399 #if 0       // there are so many of those that logging them causes flicker
400     /*EVT_TREE_GET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnGetInfo)*/
401 #endif
402     /*EVT_TREE_SET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnSetInfo)
403     EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanded)*/
404     EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanding)
405     /*EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsed)
406     EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsing)*/
407
408     EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, OPJMarkerTree::OnSelChanged)
409     /*EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, OPJMarkerTree::OnSelChanging)*/
410     /*EVT_TREE_KEY_DOWN(TreeTest_Ctrl, OPJMarkerTree::OnTreeKeyDown)*/
411     /*EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, OPJMarkerTree::OnItemActivated)*/
412
413     // so many differents ways to handle right mouse button clicks...
414     /*EVT_CONTEXT_MENU(OPJMarkerTree::OnContextMenu)*/
415     // EVT_TREE_ITEM_MENU is the preferred event for creating context menus
416     // on a tree control, because it includes the point of the click or item,
417     // meaning that no additional placement calculations are required.
418     EVT_TREE_ITEM_MENU(TreeTest_Ctrl, OPJMarkerTree::OnItemMenu)
419     /*EVT_TREE_ITEM_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/
420
421     /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown)
422     EVT_RIGHT_UP(OPJMarkerTree::OnRMouseUp)
423     EVT_RIGHT_DCLICK(OPJMarkerTree::OnRMouseDClick)*/
424 END_EVENT_TABLE()
425
426 // OPJMarkerTree implementation
427 #if USE_GENERIC_TREECTRL
428 IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl)
429 #else
430 IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl)
431 #endif
432
433 OPJMarkerTree::OPJMarkerTree(wxWindow *parent, OPJChildFrame *subframe, wxFileName fname, wxString name, const wxWindowID id,
434            const wxPoint& pos, const wxSize& size, long style)
435           : wxTreeCtrl(parent, id, pos, size, style)
436 {
437     m_reverseSort = false;
438         m_fname = fname;
439
440         m_peektextCtrl = ((OPJFrame *) (parent->GetParent()->GetParent()))->m_textCtrlbrowse;
441     CreateImageList();
442
443     // Add some items to the tree
444     //AddTestItemsToTree(5, 5);
445     int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1;
446     wxTreeItemId rootId = AddRoot(name,
447                                   image, image,
448                                   new OPJMarkerData(name));
449
450     OPJParseThread *pthread = CreateParseThread(0x00, subframe);
451     if (pthread->Run() != wxTHREAD_NO_ERROR)
452         wxLogMessage(wxT("Can't start parse thread!"));
453     else
454                 wxLogMessage(wxT("New parse thread started."));
455
456         m_childframe = subframe;
457 }
458
459 void OPJMarkerTree::CreateImageList(int size)
460 {
461     if (size == -1) {
462         SetImageList(NULL);
463         return;
464     }
465     if (size == 0)
466         size = m_imageSize;
467     else
468         m_imageSize = size;
469
470     // Make an image list containing small icons
471     wxImageList *images = new wxImageList(size, size, true);
472
473     // should correspond to TreeCtrlIcon_xxx enum
474     wxBusyCursor wait;
475     wxIcon icons[5];
476     icons[0] = wxIcon(icon1_xpm);
477     icons[1] = wxIcon(icon2_xpm);
478     icons[2] = wxIcon(icon3_xpm);
479     icons[3] = wxIcon(icon4_xpm);
480     icons[4] = wxIcon(icon5_xpm);
481
482     int sizeOrig = icons[0].GetWidth();
483     for (size_t i = 0; i < WXSIZEOF(icons); i++) {
484         if (size == sizeOrig) {
485             images->Add(icons[i]);
486         } else {
487             images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
488         }
489     }
490
491     AssignImageList(images);
492 }
493
494 #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
495 void OPJMarkerTree::CreateButtonsImageList(int size)
496 {
497     if ( size == -1 ) {
498         SetButtonsImageList(NULL);
499         return;
500     }
501
502     // Make an image list containing small icons
503     wxImageList *images = new wxImageList(size, size, true);
504
505     // should correspond to TreeCtrlIcon_xxx enum
506     wxBusyCursor wait;
507     wxIcon icons[4];
508     icons[0] = wxIcon(icon3_xpm);   // closed
509     icons[1] = wxIcon(icon3_xpm);   // closed, selected
510     icons[2] = wxIcon(icon5_xpm);   // open
511     icons[3] = wxIcon(icon5_xpm);   // open, selected
512
513     for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) {
514         int sizeOrig = icons[i].GetWidth();
515         if ( size == sizeOrig ) {
516             images->Add(icons[i]);
517         } else {
518             images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size)));
519         }
520     }
521
522     AssignButtonsImageList(images);
523 #else
524 void OPJMarkerTree::CreateButtonsImageList(int WXUNUSED(size))
525 {
526 #endif
527 }
528
529 void OPJParseThread::LoadFile(wxFileName fname)
530 {
531         wxTreeItemId rootid;
532
533         // this is the root node
534         int image = wxGetApp().ShowImages() ? m_tree->TreeCtrlIcon_Folder : -1;
535
536         if (this->m_parentid) {
537                 // leaf of a tree
538                 rootid = m_parentid;
539                 m_tree->SetItemText(rootid, wxT("Parsing..."));
540
541         } else {
542
543                 // delete the existing tree hierarchy
544                 m_tree->DeleteAllItems();
545
546                 // new tree
547                 rootid = m_tree->AddRoot(wxT("Parsing..."),
548                         image,
549                         image,
550                         new OPJMarkerData(fname.GetFullPath())
551                         );
552                 //m_tree->SetItemFont(rootid, *wxITALIC_FONT);
553                 m_tree->SetItemBold(rootid);
554         }
555
556         // open the file
557         wxFile m_file(fname.GetFullPath().c_str(), wxFile::read);
558
559         // parsing enabled?
560         if (wxGetApp().m_enableparse) {
561
562                 // what is the extension?
563                 if ((fname.GetExt() == wxT("j2k")) || (fname.GetExt() == wxT("j2c"))) {
564
565                         // parse the file
566                         ParseJ2KFile(&m_file, 0, m_file.Length(), rootid);
567
568                 } else if ((fname.GetExt() == wxT("jp2")) || (fname.GetExt() == wxT("mj2"))) {
569
570                         // parse the file
571                         if (this->m_parentid) {
572                                 //WriteText(wxT("Only a subsection of jp2"));
573                                 OPJMarkerData *data = (OPJMarkerData *) m_tree->GetItemData(rootid);
574                                 ParseJ2KFile(&m_file, data->m_start, data->m_length, rootid);
575                                 m_tree->Expand(rootid);
576
577                         } else {
578                                 // as usual
579                                 ParseJP2File(&m_file, 0, m_file.Length(), rootid);
580                         }
581
582                 } else {
583
584                         // unknown extension
585                         WriteText(wxT("Unknown file format!"));
586
587                 }
588
589         }
590
591         // this is the root node
592         if (this->m_parentid)
593                 m_tree->SetItemText(rootid, wxT("Codestream"));
594         else
595                 //m_tree->SetItemText(rootid, wxString::Format(wxT("%s (%d B)"), fname.GetFullName(), m_file.Length()));
596                 m_tree->SetItemText(rootid, fname.GetFullName());
597
598         // close the file
599         m_file.Close();
600
601         WriteText(wxT("Parsing finished!"));
602 }
603
604 /*int OPJMarkerTree::OnCompareItems(const wxTreeItemId& item1,
605                                const wxTreeItemId& item2)
606 {
607     if ( m_reverseSort )
608     {
609         // just exchange 1st and 2nd items
610         return wxTreeCtrl::OnCompareItems(item2, item1);
611     }
612     else
613     {
614         return wxTreeCtrl::OnCompareItems(item1, item2);
615     }
616 }*/
617
618 /*void OPJMarkerTree::AddItemsRecursively(const wxTreeItemId& idParent,
619                                      size_t numChildren,
620                                      size_t depth,
621                                      size_t folder)
622 {
623     if ( depth > 0 )
624     {
625         bool hasChildren = depth > 1;
626
627         wxString str;
628         for ( size_t n = 0; n < numChildren; n++ )
629         {
630             // at depth 1 elements won't have any more children
631             if ( hasChildren )
632                 str.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n + 1));
633             else
634                 str.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder), unsigned(n + 1));
635
636             // here we pass to AppendItem() normal and selected item images (we
637             // suppose that selected image follows the normal one in the enum)
638             int image, imageSel;
639             if ( wxGetApp().ShowImages() )
640             {
641                 image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
642                 imageSel = image + 1;
643             }
644             else
645             {
646                 image = imageSel = -1;
647             }
648             wxTreeItemId id = AppendItem(idParent, str, image, imageSel,
649                                          new OPJMarkerData(str));
650
651             // and now we also set the expanded one (only for the folders)
652             if ( hasChildren && wxGetApp().ShowImages() )
653             {
654                 SetItemImage(id, TreeCtrlIcon_FolderOpened,
655                              wxTreeItemIcon_Expanded);
656             }
657
658             // remember the last child for OnEnsureVisible()
659             if ( !hasChildren && n == numChildren - 1 )
660             {
661                 m_lastItem = id;
662             }
663
664             AddItemsRecursively(id, numChildren, depth - 1, n + 1);
665         }
666     }
667     //else: done!
668 }*/
669
670 /*void OPJMarkerTree::AddTestItemsToTree(size_t numChildren,
671                                     size_t depth)
672 {
673     int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1;
674     wxTreeItemId rootId = AddRoot(wxT("Root"),
675                                   image, image,
676                                   new OPJMarkerData(wxT("Root item")));
677     if ( image != -1 )
678     {
679         SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded);
680     }
681
682     AddItemsRecursively(rootId, numChildren, depth, 0);
683
684     // set some colours/fonts for testing
685     SetItemFont(rootId, *wxITALIC_FONT);
686
687     wxTreeItemIdValue cookie;
688     wxTreeItemId id = GetFirstChild(rootId, cookie);
689     SetItemTextColour(id, *wxBLUE);
690
691     id = GetNextChild(rootId, cookie);
692     id = GetNextChild(rootId, cookie);
693     SetItemTextColour(id, *wxRED);
694     SetItemBackgroundColour(id, *wxLIGHT_GREY);
695 }*/
696
697 /*void OPJMarkerTree::GetItemsRecursively(const wxTreeItemId& idParent,
698                                      wxTreeItemIdValue cookie)
699 {
700     wxTreeItemId id;
701
702     if ( !cookie )
703         id = GetFirstChild(idParent, cookie);
704     else
705         id = GetNextChild(idParent, cookie);
706
707     if ( !id.IsOk() )
708         return;
709
710     wxString text = GetItemText(id);
711     wxLogMessage(text);
712
713     if (ItemHasChildren(id))
714         GetItemsRecursively(id);
715
716     GetItemsRecursively(idParent, cookie);
717 }*/
718
719 /*void OPJMarkerTree::DoToggleIcon(const wxTreeItemId& item)
720 {
721     int image = (GetItemImage(item) == TreeCtrlIcon_Folder)
722                     ? TreeCtrlIcon_File
723                     : TreeCtrlIcon_Folder;
724     SetItemImage(item, image, wxTreeItemIcon_Normal);
725
726     image = (GetItemImage(item) == TreeCtrlIcon_FolderSelected)
727                     ? TreeCtrlIcon_FileSelected
728                     : TreeCtrlIcon_FolderSelected;
729     SetItemImage(item, image, wxTreeItemIcon_Selected);
730 }*/
731
732 void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event)
733 {
734     wxTreeItemId item = event.GetItem();
735     wxString text;
736     if ( item.IsOk() )
737         text << wxT('"') << GetItemText(item).c_str() << wxT('"');
738     else
739         text = wxT("invalid item");
740     wxLogMessage(wxT("%s(%s)"), name, text.c_str());
741 }
742
743 OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid, OPJChildFrame *subframe)
744 {
745     OPJParseThread *pthread = new OPJParseThread(this, parentid);
746
747     if (pthread->Create() != wxTHREAD_NO_ERROR)
748                 wxLogError(wxT("Can't create parse thread!"));
749
750     wxCriticalSectionLocker enter(wxGetApp().m_parse_critsect);
751     wxGetApp().m_parse_threads.Add(pthread);
752
753     return pthread;
754 }
755
756
757 /*// avoid repetition
758 #define TREE_EVENT_HANDLER(name)                                 \
759 void OPJMarkerTree::name(wxTreeEvent& event)                        \
760 {                                                                \
761     LogEvent(_T(#name), event);                                  \
762     SetLastItem(wxTreeItemId());                                 \
763     event.Skip();                                                \
764 }*/
765
766 /*TREE_EVENT_HANDLER(OnBeginRDrag)*/
767 /*TREE_EVENT_HANDLER(OnDeleteItem)*/
768 /*TREE_EVENT_HANDLER(OnGetInfo)
769 TREE_EVENT_HANDLER(OnSetInfo)*/
770 /*TREE_EVENT_HANDLER(OnItemExpanded)
771 TREE_EVENT_HANDLER(OnItemExpanding)*/
772 /*TREE_EVENT_HANDLER(OnItemCollapsed)*/
773 /*TREE_EVENT_HANDLER(OnSelChanged)
774 TREE_EVENT_HANDLER(OnSelChanging)*/
775
776 /*#undef TREE_EVENT_HANDLER*/
777
778 void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event)
779 {
780         wxTreeItemId item = event.GetItem();
781         OPJMarkerData* data = (OPJMarkerData *) GetItemData(item);
782         wxString text;
783
784         if (item.IsOk())
785                 text << wxT('"') << GetItemText(item).c_str() << wxT('"');
786         else
787                 text = wxT("invalid item");
788
789         if (wxStrcmp(data->GetDesc1(), wxT("INFO-CSTREAM")))
790                 return;
791
792         wxLogMessage(wxT("Expanding... (%s -> %s, %s, %d, %d)"),
793                 text.c_str(), data->GetDesc1(), data->GetDesc2(),
794                 data->m_start, data->m_length);
795
796         // the codestream box is being asked for expansion
797         wxTreeItemIdValue cookie;
798         if (!GetFirstChild(item, cookie).IsOk()) {
799                 OPJParseThread *pthread = CreateParseThread(item);
800                 if (pthread->Run() != wxTHREAD_NO_ERROR)
801                         wxLogMessage(wxT("Can't start parse thread!"));
802                 else
803                         wxLogMessage(wxT("New parse thread started."));
804         }
805 }
806
807 void OPJMarkerTree::OnSelChanged(wxTreeEvent& event)
808 {
809         int bunch_linesize = 16;
810         int bunch_numlines = 7;
811
812         wxTreeItemId item = event.GetItem();
813         OPJMarkerData* data = (OPJMarkerData *) GetItemData(item);
814         wxString text;
815         int l, c, pos = 0, pre_pos;
816
817         m_peektextCtrl->Clear();
818
819         /*text << wxString::Format(wxT("Selected... (%s -> %s, %s, %d, %d)"),
820                 text.c_str(), data->GetDesc1(), data->GetDesc2(),
821                 data->m_start, data->m_length) << wxT("\n");*/
822
823         // open the file and browse a little
824         wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read);
825
826         // go to position claimed
827         fp->Seek(data->m_start, wxFromStart);
828
829         // read a bunch
830         int max_read = wxMin(wxFileOffset(bunch_linesize * bunch_numlines), data->m_length - data->m_start + 1);
831         if (data->m_desc == wxT("MARK (65380)")) {
832                 /*wxLogMessage(data->m_desc);*/
833                 max_read = data->m_length - data->m_start + 1;
834                 bunch_numlines = (int) ceil((float) max_read / (float) bunch_linesize);
835         }
836         unsigned char *buffer = new unsigned char[bunch_linesize * bunch_numlines];
837         fp->Read(buffer, max_read);
838
839         // write the file data between start and stop
840         pos = 0;
841         for (l = 0; l < bunch_numlines; l++) {
842
843                 text << wxString::Format(wxT("%010d:"), data->m_start + pos);
844
845                 pre_pos = pos;
846
847                 // add hex browsing text
848                 for (c = 0; c < bunch_linesize; c++) {
849
850                         if (!(c % 8))
851                                 text << wxT(" ");
852
853                         if (pos < max_read) {
854                                 text << wxString::Format(wxT("%02X "), buffer[pos]);
855                         } else
856                                 text << wxT("   ");
857                         pos++;
858                 }
859
860                 text << wxT("    ");
861
862                 // add char browsing text
863                 for (c = 0; c < bunch_linesize; c++) {
864
865                         if (pre_pos < max_read) {
866                                 if ((buffer[pre_pos] == '\n') ||
867                                         (buffer[pre_pos] == '\t') ||
868                                         (buffer[pre_pos] == '\0') ||
869                                         (buffer[pre_pos] == 0x0D) ||
870                                         (buffer[pre_pos] == 0x0B))
871                                         buffer[pre_pos] = ' ';
872                                 text << wxString::FromAscii((char) buffer[pre_pos]) << wxT(".");
873                         } else
874                                 text << wxT("  ");
875                         pre_pos++;
876                 }
877
878                 text << wxT("\n");
879
880         }
881
882         // close the file
883         fp->Close();
884
885         m_peektextCtrl->WriteText(text);
886
887         delete buffer;
888 }
889
890 /*void LogKeyEvent(const wxChar *name, const wxKeyEvent& event)
891 {
892     wxString key;
893     long keycode = event.GetKeyCode();
894     {
895         switch ( keycode )
896         {
897             case WXK_BACK: key = wxT("BACK"); break;
898             case WXK_TAB: key = wxT("TAB"); break;
899             case WXK_RETURN: key = wxT("RETURN"); break;
900             case WXK_ESCAPE: key = wxT("ESCAPE"); break;
901             case WXK_SPACE: key = wxT("SPACE"); break;
902             case WXK_DELETE: key = wxT("DELETE"); break;
903             case WXK_START: key = wxT("START"); break;
904             case WXK_LBUTTON: key = wxT("LBUTTON"); break;
905             case WXK_RBUTTON: key = wxT("RBUTTON"); break;
906             case WXK_CANCEL: key = wxT("CANCEL"); break;
907             case WXK_MBUTTON: key = wxT("MBUTTON"); break;
908             case WXK_CLEAR: key = wxT("CLEAR"); break;
909             case WXK_SHIFT: key = wxT("SHIFT"); break;
910             case WXK_ALT: key = wxT("ALT"); break;
911             case WXK_CONTROL: key = wxT("CONTROL"); break;
912             case WXK_MENU: key = wxT("MENU"); break;
913             case WXK_PAUSE: key = wxT("PAUSE"); break;
914             case WXK_CAPITAL: key = wxT("CAPITAL"); break;
915             case WXK_END: key = wxT("END"); break;
916             case WXK_HOME: key = wxT("HOME"); break;
917             case WXK_LEFT: key = wxT("LEFT"); break;
918             case WXK_UP: key = wxT("UP"); break;
919             case WXK_RIGHT: key = wxT("RIGHT"); break;
920             case WXK_DOWN: key = wxT("DOWN"); break;
921             case WXK_SELECT: key = wxT("SELECT"); break;
922             case WXK_PRINT: key = wxT("PRINT"); break;
923             case WXK_EXECUTE: key = wxT("EXECUTE"); break;
924             case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break;
925             case WXK_INSERT: key = wxT("INSERT"); break;
926             case WXK_HELP: key = wxT("HELP"); break;
927             case WXK_NUMPAD0: key = wxT("NUMPAD0"); break;
928             case WXK_NUMPAD1: key = wxT("NUMPAD1"); break;
929             case WXK_NUMPAD2: key = wxT("NUMPAD2"); break;
930             case WXK_NUMPAD3: key = wxT("NUMPAD3"); break;
931             case WXK_NUMPAD4: key = wxT("NUMPAD4"); break;
932             case WXK_NUMPAD5: key = wxT("NUMPAD5"); break;
933             case WXK_NUMPAD6: key = wxT("NUMPAD6"); break;
934             case WXK_NUMPAD7: key = wxT("NUMPAD7"); break;
935             case WXK_NUMPAD8: key = wxT("NUMPAD8"); break;
936             case WXK_NUMPAD9: key = wxT("NUMPAD9"); break;
937             case WXK_MULTIPLY: key = wxT("MULTIPLY"); break;
938             case WXK_ADD: key = wxT("ADD"); break;
939             case WXK_SEPARATOR: key = wxT("SEPARATOR"); break;
940             case WXK_SUBTRACT: key = wxT("SUBTRACT"); break;
941             case WXK_DECIMAL: key = wxT("DECIMAL"); break;
942             case WXK_DIVIDE: key = wxT("DIVIDE"); break;
943             case WXK_F1: key = wxT("F1"); break;
944             case WXK_F2: key = wxT("F2"); break;
945             case WXK_F3: key = wxT("F3"); break;
946             case WXK_F4: key = wxT("F4"); break;
947             case WXK_F5: key = wxT("F5"); break;
948             case WXK_F6: key = wxT("F6"); break;
949             case WXK_F7: key = wxT("F7"); break;
950             case WXK_F8: key = wxT("F8"); break;
951             case WXK_F9: key = wxT("F9"); break;
952             case WXK_F10: key = wxT("F10"); break;
953             case WXK_F11: key = wxT("F11"); break;
954             case WXK_F12: key = wxT("F12"); break;
955             case WXK_F13: key = wxT("F13"); break;
956             case WXK_F14: key = wxT("F14"); break;
957             case WXK_F15: key = wxT("F15"); break;
958             case WXK_F16: key = wxT("F16"); break;
959             case WXK_F17: key = wxT("F17"); break;
960             case WXK_F18: key = wxT("F18"); break;
961             case WXK_F19: key = wxT("F19"); break;
962             case WXK_F20: key = wxT("F20"); break;
963             case WXK_F21: key = wxT("F21"); break;
964             case WXK_F22: key = wxT("F22"); break;
965             case WXK_F23: key = wxT("F23"); break;
966             case WXK_F24: key = wxT("F24"); break;
967             case WXK_NUMLOCK: key = wxT("NUMLOCK"); break;
968             case WXK_SCROLL: key = wxT("SCROLL"); break;
969             case WXK_PAGEUP: key = wxT("PAGEUP"); break;
970             case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break;
971             case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break;
972             case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break;
973             case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break;
974             case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break;
975             case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break;
976             case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break;
977             case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break;
978             case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break;
979             case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break;
980             case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break;
981             case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break;
982             case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break;
983             case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break;
984             case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break;
985             case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break;
986             case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break;
987             case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break;
988             case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break;
989             case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break;
990             case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break;
991             case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break;
992             case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break;
993             case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break;
994             case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break;
995
996             default:
997             {
998                if ( keycode < 128 && wxIsprint((int)keycode) )
999                    key.Printf(wxT("'%c'"), (char)keycode);
1000                else if ( keycode > 0 && keycode < 27 )
1001                    key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1);
1002                else
1003                    key.Printf(wxT("unknown (%ld)"), keycode);
1004             }
1005         }
1006     }
1007
1008     wxLogMessage(wxT("%s event: %s (flags = %c%c%c%c)"),
1009                   name,
1010                   key.c_str(),
1011                   event.ControlDown() ? wxT('C') : wxT('-'),
1012                   event.AltDown() ? wxT('A') : wxT('-'),
1013                   event.ShiftDown() ? wxT('S') : wxT('-'),
1014                   event.MetaDown() ? wxT('M') : wxT('-'));
1015 }
1016
1017 void OPJMarkerTree::OnTreeKeyDown(wxTreeEvent& event)
1018 {
1019     LogKeyEvent(wxT("Tree key down "), event.GetKeyEvent());
1020
1021     event.Skip();
1022 }*/
1023
1024 /*void OPJMarkerTree::OnBeginDrag(wxTreeEvent& event)
1025 {
1026     // need to explicitly allow drag
1027     if ( event.GetItem() != GetRootItem() )
1028     {
1029         m_draggedItem = event.GetItem();
1030
1031         wxLogMessage(wxT("OnBeginDrag: started dragging %s"),
1032                      GetItemText(m_draggedItem).c_str());
1033
1034         event.Allow();
1035     }
1036     else
1037     {
1038         wxLogMessage(wxT("OnBeginDrag: this item can't be dragged."));
1039     }
1040 }
1041
1042 void OPJMarkerTree::OnEndDrag(wxTreeEvent& event)
1043 {
1044     wxTreeItemId itemSrc = m_draggedItem,
1045                  itemDst = event.GetItem();
1046     m_draggedItem = (wxTreeItemId)0l;
1047
1048     // where to copy the item?
1049     if ( itemDst.IsOk() && !ItemHasChildren(itemDst) )
1050     {
1051         // copy to the parent then
1052         itemDst = GetItemParent(itemDst);
1053     }
1054
1055     if ( !itemDst.IsOk() )
1056     {
1057         wxLogMessage(wxT("OnEndDrag: can't drop here."));
1058
1059         return;
1060     }
1061
1062     wxString text = GetItemText(itemSrc);
1063     wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."),
1064                  text.c_str(), GetItemText(itemDst).c_str());
1065
1066     // just do append here - we could also insert it just before/after the item
1067     // on which it was dropped, but this requires slightly more work... we also
1068     // completely ignore the client data and icon of the old item but could
1069     // copy them as well.
1070     //
1071     // Finally, we only copy one item here but we might copy the entire tree if
1072     // we were dragging a folder.
1073     int image = wxGetApp().ShowImages() ? TreeCtrlIcon_File : -1;
1074     AppendItem(itemDst, text, image);
1075 }*/
1076
1077 /*void OPJMarkerTree::OnBeginLabelEdit(wxTreeEvent& event)
1078 {
1079     wxLogMessage(wxT("OnBeginLabelEdit"));
1080
1081     // for testing, prevent this item's label editing
1082     wxTreeItemId itemId = event.GetItem();
1083     if ( IsTestItem(itemId) )
1084     {
1085         wxMessageBox(wxT("You can't edit this item."));
1086
1087         event.Veto();
1088     }
1089     else if ( itemId == GetRootItem() )
1090     {
1091         // test that it is possible to change the text of the item being edited
1092         SetItemText(itemId, _T("Editing root item"));
1093     }
1094 }
1095
1096 void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event)
1097 {
1098     wxLogMessage(wxT("OnEndLabelEdit"));
1099
1100     // don't allow anything except letters in the labels
1101     if ( !event.GetLabel().IsWord() )
1102     {
1103         wxMessageBox(wxT("The new label should be a single word."));
1104
1105         event.Veto();
1106     }
1107 }*/
1108
1109 /*void OPJMarkerTree::OnItemCollapsing(wxTreeEvent& event)
1110 {
1111     wxLogMessage(wxT("OnItemCollapsing"));
1112
1113     // for testing, prevent the user from collapsing the first child folder
1114     wxTreeItemId itemId = event.GetItem();
1115     if ( IsTestItem(itemId) )
1116     {
1117         wxMessageBox(wxT("You can't collapse this item."));
1118
1119         event.Veto();
1120     }
1121 }*/
1122
1123 /*void OPJMarkerTree::OnItemActivated(wxTreeEvent& event)
1124 {
1125     // show some info about this item
1126     wxTreeItemId itemId = event.GetItem();
1127     OPJMarkerData *item = (OPJMarkerData *)GetItemData(itemId);
1128
1129     if ( item != NULL )
1130     {
1131         item->ShowInfo(this);
1132     }
1133
1134     wxLogMessage(wxT("OnItemActivated"));
1135 }*/
1136
1137 void OPJMarkerTree::OnItemMenu(wxTreeEvent& event)
1138 {
1139     /*wxTreeItemId itemId = event.GetItem();
1140     OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId)
1141                                          : NULL;
1142
1143     wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc()
1144                                                          : _T(""));*/
1145
1146         //wxLogMessage(wxT("EEEEEEEEEE"));
1147
1148     //event.Skip();
1149 }
1150
1151 /*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event)
1152 {
1153     wxPoint pt = event.GetPosition();
1154     wxTreeItemId item;
1155     wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y);
1156
1157     // check if event was generated by keyboard (MSW-specific?)
1158     if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it)
1159     {
1160         if ( !HasFlag(wxTR_MULTIPLE) )
1161             item = GetSelection();
1162
1163         // attempt to guess where to show the menu
1164         if ( item.IsOk() )
1165         {
1166             // if an item was clicked, show menu to the right of it
1167             wxRect rect;
1168             GetBoundingRect(item, rect, true );// only the label
1169             pt = wxPoint(rect.GetRight(), rect.GetTop());
1170         }
1171         else
1172         {
1173             pt = wxPoint(0, 0);
1174         }
1175     }
1176     else // event was generated by mouse, use supplied coords
1177     {
1178         pt = ScreenToClient(pt);
1179         item = HitTest(pt);
1180     }
1181
1182     ShowMenu(item, pt);
1183 }*/
1184
1185 /*void OPJMarkerTree::ShowMenu(wxTreeItemId id, const wxPoint& pt)
1186 {
1187     wxString title;
1188     if ( id.IsOk() )
1189     {
1190         title << wxT("Menu for ") << GetItemText(id);
1191     }
1192     else
1193     {
1194         title = wxT("Menu for no particular item");
1195     }
1196
1197 #if wxUSE_MENUS
1198     wxMenu menu(title);
1199     menu.Append(TreeTest_About, wxT("&About..."));
1200     menu.AppendSeparator();
1201     menu.Append(TreeTest_Highlight, wxT("&Highlight item"));
1202     menu.Append(TreeTest_Dump, wxT("&Dump"));
1203
1204     PopupMenu(&menu, pt);
1205 #endif // wxUSE_MENUS
1206 }*/
1207
1208 /*void OPJMarkerTree::OnItemRClick(wxTreeEvent& event)
1209 {
1210     wxTreeItemId itemId = event.GetItem();
1211     OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId)
1212                                          : NULL;
1213
1214     wxLogMessage(wxT("Item \"%s\" right clicked"), item ? item->GetDesc()
1215                                                         : _T(""));
1216
1217     event.Skip();
1218 }*/
1219
1220 /*
1221 void OPJMarkerTree::OnRMouseDown(wxMouseEvent& event)
1222 {
1223     wxLogMessage(wxT("Right mouse button down"));
1224
1225     event.Skip();
1226 }
1227
1228 void OPJMarkerTree::OnRMouseUp(wxMouseEvent& event)
1229 {
1230     wxLogMessage(wxT("Right mouse button up"));
1231
1232     event.Skip();
1233 }
1234
1235 void OPJMarkerTree::OnRMouseDClick(wxMouseEvent& event)
1236 {
1237     wxTreeItemId id = HitTest(event.GetPosition());
1238     if ( !id )
1239         wxLogMessage(wxT("No item under mouse"));
1240     else
1241     {
1242         OPJMarkerData *item = (OPJMarkerData *)GetItemData(id);
1243         if ( item )
1244             wxLogMessage(wxT("Item '%s' under mouse"), item->GetDesc());
1245     }
1246
1247     event.Skip();
1248 }
1249 */
1250
1251 static inline const wxChar *Bool2String(bool b)
1252 {
1253     return b ? wxT("") : wxT("not ");
1254 }
1255
1256 void OPJMarkerData::ShowInfo(wxTreeCtrl *tree)
1257 {
1258     wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n")
1259                  wxT("%u children (%u immediately under this item)."),
1260                  m_desc.c_str(),
1261                  Bool2String(tree->IsSelected(GetId())),
1262                  Bool2String(tree->IsExpanded(GetId())),
1263                  Bool2String(tree->IsBold(GetId())),
1264                  unsigned(tree->GetChildrenCount(GetId())),
1265                  unsigned(tree->GetChildrenCount(GetId(), false)));
1266 }
1267
1268