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