diff options
| author | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
|---|---|---|
| committer | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
| commit | d518970039a19a2a9b6d2bdd592cc88a43897bbb (patch) | |
| tree | 57bac2cf7e63e9352228231062763baac627563c /src/bin/wx/OPJViewer/source/OPJThreads.cpp | |
| parent | 8363a6ab1e031bb4b2e40a92e56efd40fdab1aa1 (diff) | |
[trunk] Start FolderReorgProposal task
Update issue 177
Diffstat (limited to 'src/bin/wx/OPJViewer/source/OPJThreads.cpp')
| -rw-r--r-- | src/bin/wx/OPJViewer/source/OPJThreads.cpp | 1268 |
1 files changed, 1268 insertions, 0 deletions
diff --git a/src/bin/wx/OPJViewer/source/OPJThreads.cpp b/src/bin/wx/OPJViewer/source/OPJThreads.cpp new file mode 100644 index 00000000..14159ac9 --- /dev/null +++ b/src/bin/wx/OPJViewer/source/OPJThreads.cpp @@ -0,0 +1,1268 @@ +/* + * Copyright (c) 2007, Digital Signal Processing Laboratory, Universita' degli studi di Perugia (UPG), Italy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "OPJViewer.h" + + +///////////////////////////////////////////////////////////////////// +// Encoding thread class +///////////////////////////////////////////////////////////////////// + +OPJEncoThread::OPJEncoThread(OPJCanvas *canvas) + : wxThread() +{ + m_count = 0; + m_canvas = canvas; +} + +void OPJEncoThread::WriteText(const wxString& text) +{ + wxString msg; + + // before doing any GUI calls we must ensure that this thread is the only + // one doing it! + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif // __WXGTK__ + + msg << text; + m_canvas->WriteText(msg); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif // __WXGTK__ +} + +void OPJEncoThread::OnExit() +{ + wxCriticalSectionLocker locker(wxGetApp().m_enco_critsect); + + wxArrayThread& ethreads = wxGetApp().m_enco_threads; + ethreads.Remove(this); + + if (ethreads.IsEmpty() ) + { + // signal the main thread that there are no more threads left if it is + // waiting for us + if (wxGetApp().m_enco_waitingUntilAllDone) { + wxGetApp().m_enco_waitingUntilAllDone = false; + wxGetApp().m_enco_semAllDone.Post(); + } + } +} + +void *OPJEncoThread::Entry() +{ + wxString text; + + srand(GetId()); + //int m_countnum = rand() % 9; + //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), + // GetId(), GetPriority(), m_countnum); + text.Printf(wxT("Enco thread %d started"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + + // set handler properties + wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000); + jpeg2000handler->m_subsampling = wxGetApp().m_subsampling; + jpeg2000handler->m_origin = wxGetApp().m_origin; + jpeg2000handler->m_rates = wxGetApp().m_rates; + jpeg2000handler->m_quality = wxGetApp().m_quality; + jpeg2000handler->m_enablequality = wxGetApp().m_enablequality; + jpeg2000handler->m_multicomp = wxGetApp().m_multicomp; + jpeg2000handler->m_irreversible = wxGetApp().m_irreversible; + jpeg2000handler->m_resolutions = wxGetApp().m_resolutions; + jpeg2000handler->m_progression = wxGetApp().m_progression; + jpeg2000handler->m_cbsize = wxGetApp().m_cbsize; + jpeg2000handler->m_prsize = wxGetApp().m_prsize; + jpeg2000handler->m_tsize = wxGetApp().m_tsize; + jpeg2000handler->m_torigin = wxGetApp().m_torigin; + jpeg2000handler->m_enablesop = wxGetApp().m_enablesop; + jpeg2000handler->m_enableeph = wxGetApp().m_enableeph; + jpeg2000handler->m_enablebypass = wxGetApp().m_enablebypass; + jpeg2000handler->m_enablerestart = wxGetApp().m_enablerestart; + jpeg2000handler->m_enablereset = wxGetApp().m_enablereset; + jpeg2000handler->m_enablesegmark = wxGetApp().m_enablesegmark; + jpeg2000handler->m_enableerterm = wxGetApp().m_enableerterm; + jpeg2000handler->m_enablevsc = wxGetApp().m_enablevsc; + jpeg2000handler->m_enableidx = wxGetApp().m_enableidx; + jpeg2000handler->m_index = m_canvas->m_savename.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxGetApp().m_index; + jpeg2000handler->m_enablecomm = wxGetApp().m_enablecomm; + jpeg2000handler->m_comment = wxGetApp().m_comment; + jpeg2000handler->m_enablepoc = wxGetApp().m_enablepoc; + jpeg2000handler->m_poc = wxGetApp().m_poc; + + // save the file + if (!m_canvas->m_image100.SaveFile(m_canvas->m_savename.GetFullPath(), (wxBitmapType) wxBITMAP_TYPE_JPEG2000)) { + WriteText(wxT("Can't save image")); + return NULL; + } + + text.Printf(wxT("Enco thread %d finished"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + return NULL; +} + + +///////////////////////////////////////////////////////////////////// +// Decoding thread class +///////////////////////////////////////////////////////////////////// +OPJDecoThread::OPJDecoThread(OPJCanvas *canvas) + : wxThread() +{ + m_count = 0; + m_canvas = canvas; +} + +void OPJDecoThread::WriteText(const wxString& text) +{ + wxString msg; + + // we use a fake event and post it for inter-thread gui communication + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG); + event.SetInt(-1); + msg << text; + event.SetString(msg); + wxPostEvent(this->m_canvas->m_childframe->m_frame, event); + +/* + // before doing any GUI calls we must ensure that this thread is the only + // one doing it! + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif // __WXGTK__ + + msg << text; + m_canvas->WriteText(msg); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif // __WXGTK__ +*/ +} + +void OPJDecoThread::OnExit() +{ + wxCriticalSectionLocker locker(wxGetApp().m_deco_critsect); + + wxArrayThread& dthreads = wxGetApp().m_deco_threads; + dthreads.Remove(this); + + if (dthreads.IsEmpty() ) + { + // signal the main thread that there are no more threads left if it is + // waiting for us + if (wxGetApp().m_deco_waitingUntilAllDone) { + wxGetApp().m_deco_waitingUntilAllDone = false; + wxGetApp().m_deco_semAllDone.Post(); + } + } +} + +void *OPJDecoThread::Entry() +{ + + wxString text; + + //srand(GetId()); + //int m_countnum = rand() % 9; + //text.Printf(wxT("Deco thread 0x%lx started (priority = %u, time = %d)."), + // GetId(), GetPriority(), m_countnum); + + // we have started + text.Printf(wxT("Deco thread %d started"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + + // prepare dummy wximage + wxBitmap bitmap(100, 100); + wxImage image(100, 100, true); //= bitmap.ConvertToImage(); + image.Destroy(); + + // show image full name + WriteText(m_canvas->m_fname.GetFullPath()); + + // set handler properties + wxJPEG2000Handler *jpeg2000handler = (wxJPEG2000Handler *) wxImage::FindHandler(wxBITMAP_TYPE_JPEG2000); + jpeg2000handler->m_reducefactor = wxGetApp().m_reducefactor; + jpeg2000handler->m_qualitylayers = wxGetApp().m_qualitylayers; + jpeg2000handler->m_components = wxGetApp().m_components; + jpeg2000handler->m_framenum = wxGetApp().m_framenum; +#ifdef USE_JPWL + jpeg2000handler->m_enablejpwl = wxGetApp().m_enablejpwl; + jpeg2000handler->m_expcomps = wxGetApp().m_expcomps; + jpeg2000handler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL + +#ifdef USE_MXF + wxMXFHandler *mxfffhandler = (wxMXFHandler *) wxImage::FindHandler(wxBITMAP_TYPE_MXF); + mxfffhandler->m_reducefactor = wxGetApp().m_reducefactor; + mxfffhandler->m_qualitylayers = wxGetApp().m_qualitylayers; + mxfffhandler->m_components = wxGetApp().m_components; + mxfffhandler->m_framenum = wxGetApp().m_framenum; + mxfffhandler->m_filename = m_canvas->m_fname; +#ifdef USE_JPWL + mxfffhandler->m_enablejpwl = wxGetApp().m_enablejpwl; + mxfffhandler->m_expcomps = wxGetApp().m_expcomps; + mxfffhandler->m_maxtiles = wxGetApp().m_maxtiles; +#endif // USE_JPWL +#endif // USE_MXF + + // if decoding is enabled... + if (wxGetApp().m_enabledeco) { + + // load the file + if (!image.LoadFile(m_canvas->m_fname.GetFullPath(), wxBITMAP_TYPE_ANY, 0)) { + WriteText(wxT("Can't load image!")); + return NULL; + } + + } else { + + // display a warning + if (!image.Create(300, 5, false)) { + WriteText(wxT("Can't create image!")); + return NULL; + } + + } + + // assign 100% image + m_canvas->m_image100 = wxBitmap(image); + + // signal the frame to refresh the canvas + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_VIEWFIT); + event.SetString(wxT("Fit me")); + event.SetInt(m_canvas->m_childframe->m_winnumber); + wxPostEvent(m_canvas->m_childframe->m_frame, event); + + // find a fit-to-width zoom + /*int zooml, wzooml, hzooml; + wxSize clientsize = m_canvas->GetClientSize(); + wzooml = (int) floor(100.0 * (double) clientsize.GetWidth() / (double) (2 * OPJ_CANVAS_BORDER + image.GetWidth())); + hzooml = (int) floor(100.0 * (double) clientsize.GetHeight() / (double) (2 * OPJ_CANVAS_BORDER + image.GetHeight())); + zooml = wxMin(100, wxMin(wzooml, hzooml));*/ + + // fit to width +#ifndef __WXGTK__ + //m_canvas->m_childframe->m_frame->Rescale(zooml, m_canvas->m_childframe); +#endif // __WXGTK__ + + //m_canvas->m_image = m_canvas->m_image100; + //m_canvas->Refresh(); + //m_canvas->SetScrollbars(20, 20, (int)(0.5 + (double) image.GetWidth() / 20.0), (int)(0.5 + (double) image.GetHeight() / 20.0)); + + //text.Printf(wxT("Deco thread 0x%lx finished."), GetId()); + text.Printf(wxT("Deco thread %d finished"), m_canvas->m_childframe->m_winnumber); + WriteText(text); + return NULL; + +} + +///////////////////////////////////////////////////////////////////// +// Parsing thread class +///////////////////////////////////////////////////////////////////// + +OPJParseThread::OPJParseThread(OPJMarkerTree *tree, wxTreeItemId parentid) + : wxThread() +{ + m_count = 0; + m_tree = tree; + m_parentid = parentid; +} + +void OPJParseThread::WriteText(const wxString& text) +{ + wxString msg; + + // we use a fake event and post it for inter-thread gui communication + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, OPJFRAME_THREADLOGMSG); + event.SetInt(-1); + msg << text; + event.SetString(msg); + wxPostEvent(this->m_tree->m_childframe->m_frame, event); + +/* // before doing any GUI calls we must ensure that this thread is the only + // one doing it! + +#ifndef __WXGTK__ + wxMutexGuiEnter(); +#endif // __WXGTK + + msg << text; + m_tree->WriteText(msg); + +#ifndef __WXGTK__ + wxMutexGuiLeave(); +#endif // __WXGTK*/ +} + +void OPJParseThread::OnExit() +{ + wxCriticalSectionLocker locker(wxGetApp().m_parse_critsect); + + wxArrayThread& threads = wxGetApp().m_parse_threads; + threads.Remove(this); + + if (threads.IsEmpty()) { + // signal the main thread that there are no more threads left if it is + // waiting for us + if (wxGetApp().m_parse_waitingUntilAllDone) { + wxGetApp().m_parse_waitingUntilAllDone = false; + wxGetApp().m_parse_semAllDone.Post(); + } + } +} + +void *OPJParseThread::Entry() +{ + + printf("Entering\n\n"); + + wxString text; + + srand(GetId()); + int m_countnum = rand() % 9; + text.Printf(wxT("Parse thread 0x%lx started (priority = %u, time = %d)."), + GetId(), GetPriority(), m_countnum); + WriteText(text); + LoadFile(m_tree->m_fname); + text.Printf(wxT("Parse thread 0x%lx finished."), GetId()); + WriteText(text); + + + //wxLogMessage(wxT("Entering\n")); //test wxLog thread safeness + + //wxBusyCursor wait; + //wxBusyInfo wait(wxT("Decoding image ...")); + + + /*for ( m_count = 0; m_count < m_countnum; m_count++ ) + { + // check if we were asked to exit + if ( TestDestroy() ) + break; + + text.Printf(wxT("[%u] Parse thread 0x%lx here."), m_count, GetId()); + WriteText(text); + + // wxSleep() can't be called from non-GUI thread! + wxThread::Sleep(10); + }*/ + + // wxLogMessage(text); -- test wxLog thread safeness + + printf("Exiting\n\n"); + + return NULL; +} + + +/////////////////////////////////////////// +// Parsing hread and related +/////////////////////////////////////////// + +#if USE_GENERIC_TREECTRL +BEGIN_EVENT_TABLE(OPJMarkerTree, wxGenericTreeCtrl) +#else +BEGIN_EVENT_TABLE(OPJMarkerTree, wxTreeCtrl) +#endif + /*EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginDrag) + EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, OPJMarkerTree::OnBeginRDrag) + EVT_TREE_END_DRAG(TreeTest_Ctrl, OPJMarkerTree::OnEndDrag)*/ + /*EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnBeginLabelEdit) + EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, OPJMarkerTree::OnEndLabelEdit)*/ + /*EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, OPJMarkerTree::OnDeleteItem)*/ +#if 0 // there are so many of those that logging them causes flicker + /*EVT_TREE_GET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnGetInfo)*/ +#endif + /*EVT_TREE_SET_INFO(TreeTest_Ctrl, OPJMarkerTree::OnSetInfo) + EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanded)*/ + EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, OPJMarkerTree::OnItemExpanding) + /*EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsed) + EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, OPJMarkerTree::OnItemCollapsing)*/ + + EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, OPJMarkerTree::OnSelChanged) + /*EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, OPJMarkerTree::OnSelChanging)*/ + /*EVT_TREE_KEY_DOWN(TreeTest_Ctrl, OPJMarkerTree::OnTreeKeyDown)*/ + /*EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, OPJMarkerTree::OnItemActivated)*/ + + // so many differents ways to handle right mouse button clicks... + /*EVT_CONTEXT_MENU(OPJMarkerTree::OnContextMenu)*/ + // EVT_TREE_ITEM_MENU is the preferred event for creating context menus + // on a tree control, because it includes the point of the click or item, + // meaning that no additional placement calculations are required. + EVT_TREE_ITEM_MENU(TreeTest_Ctrl, OPJMarkerTree::OnItemMenu) + /*EVT_TREE_ITEM_RIGHT_CLICK(TreeTest_Ctrl, OPJMarkerTree::OnItemRClick)*/ + + /*EVT_RIGHT_DOWN(OPJMarkerTree::OnRMouseDown) + EVT_RIGHT_UP(OPJMarkerTree::OnRMouseUp) + EVT_RIGHT_DCLICK(OPJMarkerTree::OnRMouseDClick)*/ +END_EVENT_TABLE() + +// OPJMarkerTree implementation +#if USE_GENERIC_TREECTRL +IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxGenericTreeCtrl) +#else +IMPLEMENT_DYNAMIC_CLASS(OPJMarkerTree, wxTreeCtrl) +#endif + +OPJMarkerTree::OPJMarkerTree(wxWindow *parent, OPJChildFrame *subframe, wxFileName fname, wxString name, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style) + : wxTreeCtrl(parent, id, pos, size, style) +{ + m_reverseSort = false; + m_fname = fname; + + m_peektextCtrl = ((OPJFrame *) (parent->GetParent()->GetParent()))->m_textCtrlbrowse; + CreateImageList(); + + // Add some items to the tree + //AddTestItemsToTree(5, 5); + int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1; + wxTreeItemId rootId = AddRoot(name, + image, image, + new OPJMarkerData(name)); + + OPJParseThread *pthread = CreateParseThread(0x00, subframe); + if (pthread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start parse thread!")); + else + wxLogMessage(wxT("New parse thread started.")); + + m_childframe = subframe; +} + +void OPJMarkerTree::CreateImageList(int size) +{ + if (size == -1) { + SetImageList(NULL); + return; + } + if (size == 0) + size = m_imageSize; + else + m_imageSize = size; + + // Make an image list containing small icons + wxImageList *images = new wxImageList(size, size, true); + + // should correspond to TreeCtrlIcon_xxx enum + wxBusyCursor wait; + wxIcon icons[5]; + icons[0] = wxIcon(icon1_xpm); + icons[1] = wxIcon(icon2_xpm); + icons[2] = wxIcon(icon3_xpm); + icons[3] = wxIcon(icon4_xpm); + icons[4] = wxIcon(icon5_xpm); + + int sizeOrig = icons[0].GetWidth(); + for (size_t i = 0; i < WXSIZEOF(icons); i++) { + if (size == sizeOrig) { + images->Add(icons[i]); + } else { + images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); + } + } + + AssignImageList(images); +} + +#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) +void OPJMarkerTree::CreateButtonsImageList(int size) +{ + if ( size == -1 ) { + SetButtonsImageList(NULL); + return; + } + + // Make an image list containing small icons + wxImageList *images = new wxImageList(size, size, true); + + // should correspond to TreeCtrlIcon_xxx enum + wxBusyCursor wait; + wxIcon icons[4]; + icons[0] = wxIcon(icon3_xpm); // closed + icons[1] = wxIcon(icon3_xpm); // closed, selected + icons[2] = wxIcon(icon5_xpm); // open + icons[3] = wxIcon(icon5_xpm); // open, selected + + for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { + int sizeOrig = icons[i].GetWidth(); + if ( size == sizeOrig ) { + images->Add(icons[i]); + } else { + images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); + } + } + + AssignButtonsImageList(images); +#else +void OPJMarkerTree::CreateButtonsImageList(int WXUNUSED(size)) +{ +#endif +} + +void OPJParseThread::LoadFile(wxFileName fname) +{ + wxTreeItemId rootid; + + // this is the root node + int image = wxGetApp().ShowImages() ? m_tree->TreeCtrlIcon_Folder : -1; + + if (this->m_parentid) { + // leaf of a tree + rootid = m_parentid; + m_tree->SetItemText(rootid, wxT("Parsing...")); + + } else { + + // delete the existing tree hierarchy + m_tree->DeleteAllItems(); + + // new tree + rootid = m_tree->AddRoot(wxT("Parsing..."), + image, + image, + new OPJMarkerData(fname.GetFullPath()) + ); + //m_tree->SetItemFont(rootid, *wxITALIC_FONT); + m_tree->SetItemBold(rootid); + } + + // open the file + wxFile m_file(fname.GetFullPath().c_str(), wxFile::read); + + // parsing enabled? + if (wxGetApp().m_enableparse) { + + // what is the extension? + if ((fname.GetExt() == wxT("j2k")) || (fname.GetExt() == wxT("j2c"))) { + + // parse the file + ParseJ2KFile(&m_file, 0, m_file.Length(), rootid); + + } else if ((fname.GetExt() == wxT("jp2")) || (fname.GetExt() == wxT("mj2"))) { + + // parse the file + if (this->m_parentid) { + //WriteText(wxT("Only a subsection of jp2")); + OPJMarkerData *data = (OPJMarkerData *) m_tree->GetItemData(rootid); + ParseJ2KFile(&m_file, data->m_start, data->m_length, rootid); + m_tree->Expand(rootid); + + } else { + // as usual + ParseJP2File(&m_file, 0, m_file.Length(), rootid); + } + + } else { + + // unknown extension + WriteText(wxT("Unknown file format!")); + + } + + } + + // this is the root node + if (this->m_parentid) + m_tree->SetItemText(rootid, wxT("Codestream")); + else + //m_tree->SetItemText(rootid, wxString::Format(wxT("%s (%d B)"), fname.GetFullName(), m_file.Length())); + m_tree->SetItemText(rootid, fname.GetFullName()); + + // close the file + m_file.Close(); + + WriteText(wxT("Parsing finished!")); +} + +/*int OPJMarkerTree::OnCompareItems(const wxTreeItemId& item1, + const wxTreeItemId& item2) +{ + if ( m_reverseSort ) + { + // just exchange 1st and 2nd items + return wxTreeCtrl::OnCompareItems(item2, item1); + } + else + { + return wxTreeCtrl::OnCompareItems(item1, item2); + } +}*/ + +/*void OPJMarkerTree::AddItemsRecursively(const wxTreeItemId& idParent, + size_t numChildren, + size_t depth, + size_t folder) +{ + if ( depth > 0 ) + { + bool hasChildren = depth > 1; + + wxString str; + for ( size_t n = 0; n < numChildren; n++ ) + { + // at depth 1 elements won't have any more children + if ( hasChildren ) + str.Printf(wxT("%s child %u"), wxT("Folder"), unsigned(n + 1)); + else + str.Printf(wxT("%s child %u.%u"), wxT("File"), unsigned(folder), unsigned(n + 1)); + + // here we pass to AppendItem() normal and selected item images (we + // suppose that selected image follows the normal one in the enum) + int image, imageSel; + if ( wxGetApp().ShowImages() ) + { + image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder; + imageSel = image + 1; + } + else + { + image = imageSel = -1; + } + wxTreeItemId id = AppendItem(idParent, str, image, imageSel, + new OPJMarkerData(str)); + + // and now we also set the expanded one (only for the folders) + if ( hasChildren && wxGetApp().ShowImages() ) + { + SetItemImage(id, TreeCtrlIcon_FolderOpened, + wxTreeItemIcon_Expanded); + } + + // remember the last child for OnEnsureVisible() + if ( !hasChildren && n == numChildren - 1 ) + { + m_lastItem = id; + } + + AddItemsRecursively(id, numChildren, depth - 1, n + 1); + } + } + //else: done! +}*/ + +/*void OPJMarkerTree::AddTestItemsToTree(size_t numChildren, + size_t depth) +{ + int image = wxGetApp().ShowImages() ? OPJMarkerTree::TreeCtrlIcon_Folder : -1; + wxTreeItemId rootId = AddRoot(wxT("Root"), + image, image, + new OPJMarkerData(wxT("Root item"))); + if ( image != -1 ) + { + SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded); + } + + AddItemsRecursively(rootId, numChildren, depth, 0); + + // set some colours/fonts for testing + SetItemFont(rootId, *wxITALIC_FONT); + + wxTreeItemIdValue cookie; + wxTreeItemId id = GetFirstChild(rootId, cookie); + SetItemTextColour(id, *wxBLUE); + + id = GetNextChild(rootId, cookie); + id = GetNextChild(rootId, cookie); + SetItemTextColour(id, *wxRED); + SetItemBackgroundColour(id, *wxLIGHT_GREY); +}*/ + +/*void OPJMarkerTree::GetItemsRecursively(const wxTreeItemId& idParent, + wxTreeItemIdValue cookie) +{ + wxTreeItemId id; + + if ( !cookie ) + id = GetFirstChild(idParent, cookie); + else + id = GetNextChild(idParent, cookie); + + if ( !id.IsOk() ) + return; + + wxString text = GetItemText(id); + wxLogMessage(text); + + if (ItemHasChildren(id)) + GetItemsRecursively(id); + + GetItemsRecursively(idParent, cookie); +}*/ + +/*void OPJMarkerTree::DoToggleIcon(const wxTreeItemId& item) +{ + int image = (GetItemImage(item) == TreeCtrlIcon_Folder) + ? TreeCtrlIcon_File + : TreeCtrlIcon_Folder; + SetItemImage(item, image, wxTreeItemIcon_Normal); + + image = (GetItemImage(item) == TreeCtrlIcon_FolderSelected) + ? TreeCtrlIcon_FileSelected + : TreeCtrlIcon_FolderSelected; + SetItemImage(item, image, wxTreeItemIcon_Selected); +}*/ + +void OPJMarkerTree::LogEvent(const wxChar *name, const wxTreeEvent& event) +{ + wxTreeItemId item = event.GetItem(); + wxString text; + if ( item.IsOk() ) + text << wxT('"') << GetItemText(item).c_str() << wxT('"'); + else + text = wxT("invalid item"); + wxLogMessage(wxT("%s(%s)"), name, text.c_str()); +} + +OPJParseThread *OPJMarkerTree::CreateParseThread(wxTreeItemId parentid, OPJChildFrame *subframe) +{ + OPJParseThread *pthread = new OPJParseThread(this, parentid); + + if (pthread->Create() != wxTHREAD_NO_ERROR) + wxLogError(wxT("Can't create parse thread!")); + + wxCriticalSectionLocker enter(wxGetApp().m_parse_critsect); + wxGetApp().m_parse_threads.Add(pthread); + + return pthread; +} + + +/*// avoid repetition +#define TREE_EVENT_HANDLER(name) \ +void OPJMarkerTree::name(wxTreeEvent& event) \ +{ \ + LogEvent(_T(#name), event); \ + SetLastItem(wxTreeItemId()); \ + event.Skip(); \ +}*/ + +/*TREE_EVENT_HANDLER(OnBeginRDrag)*/ +/*TREE_EVENT_HANDLER(OnDeleteItem)*/ +/*TREE_EVENT_HANDLER(OnGetInfo) +TREE_EVENT_HANDLER(OnSetInfo)*/ +/*TREE_EVENT_HANDLER(OnItemExpanded) +TREE_EVENT_HANDLER(OnItemExpanding)*/ +/*TREE_EVENT_HANDLER(OnItemCollapsed)*/ +/*TREE_EVENT_HANDLER(OnSelChanged) +TREE_EVENT_HANDLER(OnSelChanging)*/ + +/*#undef TREE_EVENT_HANDLER*/ + +void OPJMarkerTree::OnItemExpanding(wxTreeEvent& event) +{ + wxTreeItemId item = event.GetItem(); + OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); + wxString text; + + if (item.IsOk()) + text << wxT('"') << GetItemText(item).c_str() << wxT('"'); + else + text = wxT("invalid item"); + + if (wxStrcmp(data->GetDesc1(), wxT("INFO-CSTREAM"))) + return; + + wxLogMessage(wxT("Expanding... (%s -> %s, %s, %d, %d)"), + text.c_str(), data->GetDesc1(), data->GetDesc2(), + data->m_start, data->m_length); + + // the codestream box is being asked for expansion + wxTreeItemIdValue cookie; + if (!GetFirstChild(item, cookie).IsOk()) { + OPJParseThread *pthread = CreateParseThread(item); + if (pthread->Run() != wxTHREAD_NO_ERROR) + wxLogMessage(wxT("Can't start parse thread!")); + else + wxLogMessage(wxT("New parse thread started.")); + } +} + +void OPJMarkerTree::OnSelChanged(wxTreeEvent& event) +{ + int bunch_linesize = 16; + int bunch_numlines = 7; + + wxTreeItemId item = event.GetItem(); + OPJMarkerData* data = (OPJMarkerData *) GetItemData(item); + wxString text; + int l, c, pos = 0, pre_pos; + + m_peektextCtrl->Clear(); + + /*text << wxString::Format(wxT("Selected... (%s -> %s, %s, %d, %d)"), + text.c_str(), data->GetDesc1(), data->GetDesc2(), + data->m_start, data->m_length) << wxT("\n");*/ + + // open the file and browse a little + wxFile *fp = new wxFile(m_fname.GetFullPath().c_str(), wxFile::read); + + // go to position claimed + fp->Seek(data->m_start, wxFromStart); + + // read a bunch + int max_read = wxMin(wxFileOffset(bunch_linesize * bunch_numlines), data->m_length - data->m_start + 1); + if (data->m_desc == wxT("MARK (65380)")) { + /*wxLogMessage(data->m_desc);*/ + max_read = data->m_length - data->m_start + 1; + bunch_numlines = (int) ceil((float) max_read / (float) bunch_linesize); + } + unsigned char *buffer = new unsigned char[bunch_linesize * bunch_numlines]; + fp->Read(buffer, max_read); + + // write the file data between start and stop + pos = 0; + for (l = 0; l < bunch_numlines; l++) { + + text << wxString::Format(wxT("%010d:"), data->m_start + pos); + + pre_pos = pos; + + // add hex browsing text + for (c = 0; c < bunch_linesize; c++) { + + if (!(c % 8)) + text << wxT(" "); + + if (pos < max_read) { + text << wxString::Format(wxT("%02X "), buffer[pos]); + } else + text << wxT(" "); + pos++; + } + + text << wxT(" "); + + // add char browsing text + for (c = 0; c < bunch_linesize; c++) { + + if (pre_pos < max_read) { + if ((buffer[pre_pos] == '\n') || + (buffer[pre_pos] == '\t') || + (buffer[pre_pos] == '\0') || + (buffer[pre_pos] == 0x0D) || + (buffer[pre_pos] == 0x0B)) + buffer[pre_pos] = ' '; + text << wxString::FromAscii((char) buffer[pre_pos]) << wxT("."); + } else + text << wxT(" "); + pre_pos++; + } + + text << wxT("\n"); + + } + + // close the file + fp->Close(); + + m_peektextCtrl->WriteText(text); + + delete buffer; +} + +/*void LogKeyEvent(const wxChar *name, const wxKeyEvent& event) +{ + wxString key; + long keycode = event.GetKeyCode(); + { + switch ( keycode ) + { + case WXK_BACK: key = wxT("BACK"); break; + case WXK_TAB: key = wxT("TAB"); break; + case WXK_RETURN: key = wxT("RETURN"); break; + case WXK_ESCAPE: key = wxT("ESCAPE"); break; + case WXK_SPACE: key = wxT("SPACE"); break; + case WXK_DELETE: key = wxT("DELETE"); break; + case WXK_START: key = wxT("START"); break; + case WXK_LBUTTON: key = wxT("LBUTTON"); break; + case WXK_RBUTTON: key = wxT("RBUTTON"); break; + case WXK_CANCEL: key = wxT("CANCEL"); break; + case WXK_MBUTTON: key = wxT("MBUTTON"); break; + case WXK_CLEAR: key = wxT("CLEAR"); break; + case WXK_SHIFT: key = wxT("SHIFT"); break; + case WXK_ALT: key = wxT("ALT"); break; + case WXK_CONTROL: key = wxT("CONTROL"); break; + case WXK_MENU: key = wxT("MENU"); break; + case WXK_PAUSE: key = wxT("PAUSE"); break; + case WXK_CAPITAL: key = wxT("CAPITAL"); break; + case WXK_END: key = wxT("END"); break; + case WXK_HOME: key = wxT("HOME"); break; + case WXK_LEFT: key = wxT("LEFT"); break; + case WXK_UP: key = wxT("UP"); break; + case WXK_RIGHT: key = wxT("RIGHT"); break; + case WXK_DOWN: key = wxT("DOWN"); break; + case WXK_SELECT: key = wxT("SELECT"); break; + case WXK_PRINT: key = wxT("PRINT"); break; + case WXK_EXECUTE: key = wxT("EXECUTE"); break; + case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break; + case WXK_INSERT: key = wxT("INSERT"); break; + case WXK_HELP: key = wxT("HELP"); break; + case WXK_NUMPAD0: key = wxT("NUMPAD0"); break; + case WXK_NUMPAD1: key = wxT("NUMPAD1"); break; + case WXK_NUMPAD2: key = wxT("NUMPAD2"); break; + case WXK_NUMPAD3: key = wxT("NUMPAD3"); break; + case WXK_NUMPAD4: key = wxT("NUMPAD4"); break; + case WXK_NUMPAD5: key = wxT("NUMPAD5"); break; + case WXK_NUMPAD6: key = wxT("NUMPAD6"); break; + case WXK_NUMPAD7: key = wxT("NUMPAD7"); break; + case WXK_NUMPAD8: key = wxT("NUMPAD8"); break; + case WXK_NUMPAD9: key = wxT("NUMPAD9"); break; + case WXK_MULTIPLY: key = wxT("MULTIPLY"); break; + case WXK_ADD: key = wxT("ADD"); break; + case WXK_SEPARATOR: key = wxT("SEPARATOR"); break; + case WXK_SUBTRACT: key = wxT("SUBTRACT"); break; + case WXK_DECIMAL: key = wxT("DECIMAL"); break; + case WXK_DIVIDE: key = wxT("DIVIDE"); break; + case WXK_F1: key = wxT("F1"); break; + case WXK_F2: key = wxT("F2"); break; + case WXK_F3: key = wxT("F3"); break; + case WXK_F4: key = wxT("F4"); break; + case WXK_F5: key = wxT("F5"); break; + case WXK_F6: key = wxT("F6"); break; + case WXK_F7: key = wxT("F7"); break; + case WXK_F8: key = wxT("F8"); break; + case WXK_F9: key = wxT("F9"); break; + case WXK_F10: key = wxT("F10"); break; + case WXK_F11: key = wxT("F11"); break; + case WXK_F12: key = wxT("F12"); break; + case WXK_F13: key = wxT("F13"); break; + case WXK_F14: key = wxT("F14"); break; + case WXK_F15: key = wxT("F15"); break; + case WXK_F16: key = wxT("F16"); break; + case WXK_F17: key = wxT("F17"); break; + case WXK_F18: key = wxT("F18"); break; + case WXK_F19: key = wxT("F19"); break; + case WXK_F20: key = wxT("F20"); break; + case WXK_F21: key = wxT("F21"); break; + case WXK_F22: key = wxT("F22"); break; + case WXK_F23: key = wxT("F23"); break; + case WXK_F24: key = wxT("F24"); break; + case WXK_NUMLOCK: key = wxT("NUMLOCK"); break; + case WXK_SCROLL: key = wxT("SCROLL"); break; + case WXK_PAGEUP: key = wxT("PAGEUP"); break; + case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break; + case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break; + case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break; + case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break; + case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break; + case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break; + case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break; + case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break; + case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break; + case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break; + case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break; + case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break; + case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break; + case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break; + case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break; + case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break; + case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break; + case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break; + case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break; + case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break; + case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break; + case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break; + case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break; + case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break; + case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break; + + default: + { + if ( keycode < 128 && wxIsprint((int)keycode) ) + key.Printf(wxT("'%c'"), (char)keycode); + else if ( keycode > 0 && keycode < 27 ) + key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1); + else + key.Printf(wxT("unknown (%ld)"), keycode); + } + } + } + + wxLogMessage(wxT("%s event: %s (flags = %c%c%c%c)"), + name, + key.c_str(), + event.ControlDown() ? wxT('C') : wxT('-'), + event.AltDown() ? wxT('A') : wxT('-'), + event.ShiftDown() ? wxT('S') : wxT('-'), + event.MetaDown() ? wxT('M') : wxT('-')); +} + +void OPJMarkerTree::OnTreeKeyDown(wxTreeEvent& event) +{ + LogKeyEvent(wxT("Tree key down "), event.GetKeyEvent()); + + event.Skip(); +}*/ + +/*void OPJMarkerTree::OnBeginDrag(wxTreeEvent& event) +{ + // need to explicitly allow drag + if ( event.GetItem() != GetRootItem() ) + { + m_draggedItem = event.GetItem(); + + wxLogMessage(wxT("OnBeginDrag: started dragging %s"), + GetItemText(m_draggedItem).c_str()); + + event.Allow(); + } + else + { + wxLogMessage(wxT("OnBeginDrag: this item can't be dragged.")); + } +} + +void OPJMarkerTree::OnEndDrag(wxTreeEvent& event) +{ + wxTreeItemId itemSrc = m_draggedItem, + itemDst = event.GetItem(); + m_draggedItem = (wxTreeItemId)0l; + + // where to copy the item? + if ( itemDst.IsOk() && !ItemHasChildren(itemDst) ) + { + // copy to the parent then + itemDst = GetItemParent(itemDst); + } + + if ( !itemDst.IsOk() ) + { + wxLogMessage(wxT("OnEndDrag: can't drop here.")); + + return; + } + + wxString text = GetItemText(itemSrc); + wxLogMessage(wxT("OnEndDrag: '%s' copied to '%s'."), + text.c_str(), GetItemText(itemDst).c_str()); + + // just do append here - we could also insert it just before/after the item + // on which it was dropped, but this requires slightly more work... we also + // completely ignore the client data and icon of the old item but could + // copy them as well. + // + // Finally, we only copy one item here but we might copy the entire tree if + // we were dragging a folder. + int image = wxGetApp().ShowImages() ? TreeCtrlIcon_File : -1; + AppendItem(itemDst, text, image); +}*/ + +/*void OPJMarkerTree::OnBeginLabelEdit(wxTreeEvent& event) +{ + wxLogMessage(wxT("OnBeginLabelEdit")); + + // for testing, prevent this item's label editing + wxTreeItemId itemId = event.GetItem(); + if ( IsTestItem(itemId) ) + { + wxMessageBox(wxT("You can't edit this item.")); + + event.Veto(); + } + else if ( itemId == GetRootItem() ) + { + // test that it is possible to change the text of the item being edited + SetItemText(itemId, _T("Editing root item")); + } +} + +void OPJMarkerTree::OnEndLabelEdit(wxTreeEvent& event) +{ + wxLogMessage(wxT("OnEndLabelEdit")); + + // don't allow anything except letters in the labels + if ( !event.GetLabel().IsWord() ) + { + wxMessageBox(wxT("The new label should be a single word.")); + + event.Veto(); + } +}*/ + +/*void OPJMarkerTree::OnItemCollapsing(wxTreeEvent& event) +{ + wxLogMessage(wxT("OnItemCollapsing")); + + // for testing, prevent the user from collapsing the first child folder + wxTreeItemId itemId = event.GetItem(); + if ( IsTestItem(itemId) ) + { + wxMessageBox(wxT("You can't collapse this item.")); + + event.Veto(); + } +}*/ + +/*void OPJMarkerTree::OnItemActivated(wxTreeEvent& event) +{ + // show some info about this item + wxTreeItemId itemId = event.GetItem(); + OPJMarkerData *item = (OPJMarkerData *)GetItemData(itemId); + + if ( item != NULL ) + { + item->ShowInfo(this); + } + + wxLogMessage(wxT("OnItemActivated")); +}*/ + +void OPJMarkerTree::OnItemMenu(wxTreeEvent& event) +{ + /*wxTreeItemId itemId = event.GetItem(); + OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) + : NULL; + + wxLogMessage(wxT("OnItemMenu for item \"%s\""), item ? item->GetDesc() + : _T(""));*/ + + //wxLogMessage(wxT("EEEEEEEEEE")); + + //event.Skip(); +} + +/*void OPJMarkerTree::OnContextMenu(wxContextMenuEvent& event) +{ + wxPoint pt = event.GetPosition(); + wxTreeItemId item; + wxLogMessage(wxT("OnContextMenu at screen coords (%i, %i)"), pt.x, pt.y); + + // check if event was generated by keyboard (MSW-specific?) + if ( pt.x == -1 && pt.y == -1 ) //(this is how MSW indicates it) + { + if ( !HasFlag(wxTR_MULTIPLE) ) + item = GetSelection(); + + // attempt to guess where to show the menu + if ( item.IsOk() ) + { + // if an item was clicked, show menu to the right of it + wxRect rect; + GetBoundingRect(item, rect, true );// only the label + pt = wxPoint(rect.GetRight(), rect.GetTop()); + } + else + { + pt = wxPoint(0, 0); + } + } + else // event was generated by mouse, use supplied coords + { + pt = ScreenToClient(pt); + item = HitTest(pt); + } + + ShowMenu(item, pt); +}*/ + +/*void OPJMarkerTree::ShowMenu(wxTreeItemId id, const wxPoint& pt) +{ + wxString title; + if ( id.IsOk() ) + { + title << wxT("Menu for ") << GetItemText(id); + } + else + { + title = wxT("Menu for no particular item"); + } + +#if wxUSE_MENUS + wxMenu menu(title); + menu.Append(TreeTest_About, wxT("&About...")); + menu.AppendSeparator(); + menu.Append(TreeTest_Highlight, wxT("&Highlight item")); + menu.Append(TreeTest_Dump, wxT("&Dump")); + + PopupMenu(&menu, pt); +#endif // wxUSE_MENUS +}*/ + +/*void OPJMarkerTree::OnItemRClick(wxTreeEvent& event) +{ + wxTreeItemId itemId = event.GetItem(); + OPJMarkerData *item = itemId.IsOk() ? (OPJMarkerData *)GetItemData(itemId) + : NULL; + + wxLogMessage(wxT("Item \"%s\" right clicked"), item ? item->GetDesc() + : _T("")); + + event.Skip(); +}*/ + +/* +void OPJMarkerTree::OnRMouseDown(wxMouseEvent& event) +{ + wxLogMessage(wxT("Right mouse button down")); + + event.Skip(); +} + +void OPJMarkerTree::OnRMouseUp(wxMouseEvent& event) +{ + wxLogMessage(wxT("Right mouse button up")); + + event.Skip(); +} + +void OPJMarkerTree::OnRMouseDClick(wxMouseEvent& event) +{ + wxTreeItemId id = HitTest(event.GetPosition()); + if ( !id ) + wxLogMessage(wxT("No item under mouse")); + else + { + OPJMarkerData *item = (OPJMarkerData *)GetItemData(id); + if ( item ) + wxLogMessage(wxT("Item '%s' under mouse"), item->GetDesc()); + } + + event.Skip(); +} +*/ + +static inline const wxChar *Bool2String(bool b) +{ + return b ? wxT("") : wxT("not "); +} + +void OPJMarkerData::ShowInfo(wxTreeCtrl *tree) +{ + wxLogMessage(wxT("Item '%s': %sselected, %sexpanded, %sbold,\n") + wxT("%u children (%u immediately under this item)."), + m_desc.c_str(), + Bool2String(tree->IsSelected(GetId())), + Bool2String(tree->IsExpanded(GetId())), + Bool2String(tree->IsBold(GetId())), + unsigned(tree->GetChildrenCount(GetId())), + unsigned(tree->GetChildrenCount(GetId(), false))); +} + + |
