Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  
  1269.