X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FcreaImageIOWxGimmick.cpp;fp=src%2FcreaImageIOWxGimmick.cpp;h=0000000000000000000000000000000000000000;hb=916a5e3008de7387aaf45e9d4e4ebbe6503205c3;hp=63470ba141b56f8d126d92715499c4a1fc90b79d;hpb=fc9f416364ea520257fac4163be2de826491fe60;p=creaImageIO.git diff --git a/src/creaImageIOWxGimmick.cpp b/src/creaImageIOWxGimmick.cpp deleted file mode 100644 index 63470ba..0000000 --- a/src/creaImageIOWxGimmick.cpp +++ /dev/null @@ -1,3003 +0,0 @@ - -#include -#include - -#include - -#include "icons/database.xpm" -#include "icons/folder.xpm" -#include "icons/dicomdir.xpm" -#include "icons/patient.xpm" -#include "icons/study.xpm" -#include "icons/series.xpm" -#include "icons/image.xpm" -#include "icons/root.xpm" -#include -#include - -#include -#include -#include - -#include -//#include - -using namespace crea; - -#include -#include - -namespace creaImageIO -{ - //================================================================ - const int WxGimmick::UserMenuFirstId = 1000; - //================================================================ - - //================================================================ - typedef enum - { - Icon_Root, - Icon_Database, - Icon_Folder, - Icon_DicomDir, - Icon_Patient, - Icon_Study, - Icon_Series, - Icon_Image - } - icon_id; - //================================================================ - - //================================================================ - enum - { - PopUp_NewCollection = 100, - PopUp_OpenCollection = 101, - PopUp_CloseCollection = 102, - PopUp_DeleteCollection = 103, - PopUp_AddDirectory = 110, - PopUp_AddFile = 111, - PopUp_AddRawFile = 112, - PopUp_Remove = 120, - PopUp_Sort = 200, - PopUp_Settings = 501, - PopUp_About = 502, - PopUp_User = WxGimmick::UserMenuFirstId, - PopUp_SaveAs = 701, - PopUp_AddToFavorites = 702 - }; - //================================================================ - - //================================================================ -#define TreeListCtrlId 10000 - //================================================================ - - //================================================================ - const icon_id Icon[5] = { Icon_Database, - Icon_Patient, - Icon_Study, - Icon_Series, - Icon_Image }; - //================================================================ - - - //================================================================ - class WxGimmickDicomNodeData : public DicomNodeData - { - public: - WxGimmickDicomNodeData - (WxGimmickTreeItemData* d = 0) : - mTreeItemData(d), - mLoaded(false) - {} - ~WxGimmickDicomNodeData(); - - WxGimmickTreeItemData* GetTreeItemData() - { return mTreeItemData; } - void SetTreeItemData( WxGimmickTreeItemData* d) - { mTreeItemData = d; } - inline bool IsLoaded() { return mLoaded; } - inline void SetLoaded(bool v) { mLoaded = v; } - - private: - WxGimmickTreeItemData* mTreeItemData; - bool mLoaded; - }; - //================================================================ - - - //================================================================ - class WxGimmickTreeItemData : public wxTreeItemData - { - public: - WxGimmickTreeItemData(DicomNode* node) - : - mType(0), - mDicomNode(node), - // mLoaded(false), - mUpdateTime(0), - mUserFlags(0) - { - if (node) - { - WxGimmickDicomNodeData* data = - node->GetData(); - if (data!=0) - { - if (data->GetTreeItemData()!=0) - { - std::cout << "WxGimmickTreeItemData ERROR ****" - << std::endl; - return; - } - data->SetTreeItemData(this); - return; - } - node->SetData( new WxGimmickDicomNodeData(this) ); - if (node->GetType()==DicomNode::Database) - { - mType = 2; - } - else - { - mType = 1; - } - } - } - ~WxGimmickTreeItemData() - { - if (mDicomNode) - { - WxGimmickDicomNodeData* data = - mDicomNode->GetData(); - if (data) data->SetTreeItemData(0); - - } - } - inline void ResetDicomNode() - { - mDicomNode = 0; - } - - inline void SetItemId ( const wxTreeItemId& item ) { mItemId = item; } - inline const wxTreeItemId& GetItemId() const { return mItemId; } - - inline bool IsDefault() const { return (mType == 0); } - inline bool IsDatabase() const { return (mType == 2); } - inline bool IsDicomNode() const { return (mType == 1); } - - inline DicomNode* GetDicomNode() { return mDicomNode; } - inline long& UpdateTime() { return mUpdateTime; } - inline bool IsLoaded() - { - mDicomNode->GetData()->IsLoaded(); - } - inline void SetLoaded(bool v) - { - mDicomNode->GetData()->SetLoaded(v); - } - - inline int GetUserFlags() const { return mUserFlags; } - inline void SetUserFlags(int f) { mUserFlags = f; } - - private: - // The type of item : - // 0 = Default - // 1 = DicomNode - // 2 = DicomNode of type Database - int mType; - wxTreeItemId mItemId; - DicomNode* mDicomNode; - // bool mLoaded; - long mUpdateTime; - int mUserFlags; - }; - //================================================================ - - - //================================================================ - WxGimmickDicomNodeData::~WxGimmickDicomNodeData() - { - if (mTreeItemData) - { - mTreeItemData->ResetDicomNode(); - } - } - //================================================================ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //================================================================ - //================================================================ - //================================================================ - //================================================================ - //================================================================ - //================================================================ - //================================================================ - WxGimmick::WxGimmick(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - int image_type, - int threads) - : wxPanel(parent,id,pos,size), - mSelectionType(image_type), - mSaveConfigurationOnClose(true), - mReader(threads) - { - // Initialize image size corresponding to current selection - switch (mSelectionType) - { - case GIMMICK_2D_IMAGE_SELECTION : mSelectionMaxImageDimension = 2; break; - case GIMMICK_3D_IMAGE_SELECTION : mSelectionMaxImageDimension = 3; break; - case GIMMICK_4D_IMAGE_SELECTION : mSelectionMaxImageDimension = 4; break; - default : mSelectionMaxImageDimension = 0; - } - - - // Start the threads ... - mReader.Start(); - - // - SetDatabaseExtension("sqlite3"); - // Create the UserSettings dir if does not exist - CreateUserSettingsDirectory(); - // Sets the current directory to the Setting dir - mCurrentDirectory = std2wx(GetUserSettingsDirectory()); - - // Window layout creation - wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); - - // Left/Right split - mSplitter1 = new wxSplitterWindow( this, -1); - - // TreeCtrl on the left - long style = - wxTR_HIDE_ROOT - | wxTR_HAS_BUTTONS - | wxTR_NO_LINES - //| wxTR_LINES_AT_ROOT - | wxTR_FULL_ROW_HIGHLIGHT - // | wxTR_SINGLE - | wxTR_MULTIPLE - | wxTR_EDIT_LABELS ; - - /* - style = style - | wxTR_EDIT_LABELS //Use this style if you wish the user to be able to edit labels in the tree list control. - //wxTR_NO_BUTTONS For convenience to document that no buttons are to be drawn. - | wxTR_HAS_BUTTONS //Use this style to show + and - buttons to the left of parent items. - | wxTR_TWIST_BUTTONS //Use this style to show Mac-style twister buttons to the left of parent items. If both wxTR_HAS_BUTTONS and wxTR_TWIST_BUTTONS are given, twister buttons are generated. - //wxTR_NO_LINES Use this style to hide vertical level connectors. - | wxTR_FULL_ROW_HIGHLIGHT //Use this style to have the background colour and the selection highlight extend over the entire horizontal row of the tree list control window. (This flag is ignored under Windows unless you specify wxTR_NO_LINES as well.) - | wxTR_LINES_AT_ROOT //Use this style to show lines between root nodes. Only applicable if wxTR_HIDE_ROOT is set and wxTR_NO_LINES is not set. - | wxTR_HIDE_ROOT //Use this style to suppress the display of the root node, effectively causing the first-level nodes to appear as a series of root nodes. - // wxTR_ROW_LINES // Use this style to draw a contrasting border between displayed rows. - // wxTR_HAS_VARIABLE_ROW_HEIGHT// Use this style to cause row heights to be just big enough to fit the content. If not set, all rows use the largest row height. The default is that this flag is unset. - // wxTR_SINGLE For convenience to document that only one item may be selected at a time. Selecting another item causes the current selection, if any, to be deselected. This is the default. - | wxTR_MULTIPLE // Use this style to allow a range of items to be selected. If a second range is selected, the current range, if any, is deselected. - | wxTR_EXTENDED // Use this style to allow disjoint items to be selected. (Only partially implemented; may not work in all cases.) - //wxTR_DEFAULT_STYLE The set of flags that are closest to the defaults for the native control for a particular toolkit. - //| wxTR_VIRTUAL //The application provides items text on demand. - */ - - mTreeListCtrl = new wxTreeListCtrl(mSplitter1, - TreeListCtrlId, - wxDefaultPosition, - wxDefaultSize, - style); - - mTreeListCtrl->SetIndent(0); - mTreeListCtrl->SetLineSpacing(5); - - CreateImageList(); - - // Right panel - wxPanel *rpanel = new wxPanel( mSplitter1, -1 ); - // Right sizer - wxBoxSizer *rsizer = new wxBoxSizer(wxHORIZONTAL); - // Right panel top/bottom split - mSplitter2 = new wxSplitterWindow( rpanel , -1); - - // Image panel (top) - mPanelImage = new wxPanel(mSplitter2,-1); - mPanelImage->SetBackgroundColour( wxColour(0,0,0) ); - // Image sizer - wxBoxSizer *isizer = new wxBoxSizer(wxHORIZONTAL ); - mPanelImage->SetSizer( isizer ); - - // Notebook - mwxNotebook = new wxNotebook(mSplitter2, - -1,wxDefaultPosition, wxDefaultSize, 0); - - - - // Fields view (bottom) - mFieldsView = new WxGimmickFieldsView(mwxNotebook,-1, - wxDefaultPosition, - wxDefaultSize,0); - - mFieldsView->SetColors - ( GetSettings().Colour(DicomNode::Database), - GetSettings().BgColour(DicomNode::Database), - GetSettings().Colour(DicomNode::Patient), - GetSettings().BgColour(DicomNode::Patient), - GetSettings().Colour(DicomNode::Study), - GetSettings().BgColour(DicomNode::Study), - GetSettings().Colour(DicomNode::Series), - GetSettings().BgColour(DicomNode::Series), - GetSettings().Colour(DicomNode::Image), - GetSettings().BgColour(DicomNode::Image)); - mwxNotebook->AddPage( mFieldsView, _T("Dicom fields")); - - // Help - mHelp = new WxGimmickHelp(mwxNotebook); - mwxNotebook->AddPage( mHelp, _T("Help")); - - // Splitting - int wsize = size.GetWidth(); - int hsize = size.GetHeight(); - int previewhsize = 150; - int previewwsize = 400; - - mSplitter2->SetMinimumPaneSize( previewhsize ); - mSplitter2->SplitHorizontally( mPanelImage, mwxNotebook, //mFieldsView, - hsize - previewhsize); - - rsizer->Add( mSplitter2,1,wxGROW ,0); - - rpanel->SetAutoLayout(true); - rpanel->SetSizer( rsizer ); - rpanel->Layout(); - - // previewer - mInteractor = new crea::creawxVTKRenderWindowInteractor(mPanelImage,-1); - mInteractor->UseCaptureMouseOn(); - - mViewer = vtkImageViewer2::New(); - mViewer->SetupInteractor ( mInteractor ); - mViewer->SetInput(mReader.GetImage("")); - - isizer-> Add( mInteractor ,1,wxGROW ,0); - - topsizer->Add( mSplitter1,1,wxGROW ,0); - - // Left/right split - mSplitter1->SetMinimumPaneSize( 200 ); - mSplitter1->SplitVertically(mTreeListCtrl, - rpanel, - wsize - previewwsize ); - - - // ProcessImageEvents(); - SetSizer( topsizer ); - SetAutoLayout(true); - - mDatabaseListFile = GetUserSettingsDirectory(); - mDatabaseListFile += "collections.txt"; - - LoadConfiguration(); - Layout(); - - ShowImage(mReader.GetImage("")); - - // Show help if no collection - if (GetDicomDatabaseList().size()==0) - { - mwxNotebook->SetSelection(1); - } - else - { - mwxNotebook->SetSelection(0); - } - // mJustStarted = true; - } - //================================================================ - -// file separator -#if defined(_WIN32) -#define VALID_FILE_SEPARATOR "\\" -#define INVALID_FILE_SEPARATOR "/" -#else -#define INVALID_FILE_SEPARATOR "\\" -#define VALID_FILE_SEPARATOR "/" -#endif - - //================================================================ - const std::string& WxGimmick::GetUserSettingsDirectory() - { - if (mUserSettingsDirectory.size()==0) - { -#if defined(__GNUC__) - mUserSettingsDirectory = getenv("HOME"); -#elif defined(_WIN32) - mUserSettingsDirectory = getenv("USERPROFILE"); -#endif - mUserSettingsDirectory += "/.gimmick/"; - boost::algorithm::replace_all( mUserSettingsDirectory, - INVALID_FILE_SEPARATOR , - VALID_FILE_SEPARATOR); - } - return mUserSettingsDirectory; - } - //================================================================ - - //======================================================================== - void WxGimmick::CreateUserSettingsDirectory() - { - if (! boost::filesystem::is_directory( GetUserSettingsDirectory() ) ) - { - creaMessage("Gimmick!",1,"==> Directory '"<Delete(); - delete mInteractor; - } - //================================================================ - - - //================================================================ - void WxGimmick::RebuildView() - { - wxBusyCursor busy; - - mTreeListCtrl->DeleteRoot(); //DeleteAllItems(); - // mTreeDefaultItemId = wxTreeItemId(); - - - int nbattr = mSettings.GetMaxNumberOfColumns(); - - for (int j=0;jAddColumn (_T(""), - 200, //DEFAULT_COL_WIDTH, - wxALIGN_LEFT, - -1, - true, - false); - } - mTreeListCtrl->SetMainColumn (0); - mTreeListCtrl->SetColumnEditable (0, true); - - mTreeRootId = mTreeListCtrl->AddRoot( _T(""),Icon_Root,Icon_Root); - - // The collections columns legends - mCollectionsTitlesItemId = - CreateChildrenColumnsTitles(mTreeRootId,DicomNode::Database); - - DicomDatabaseListType::iterator i; - for (i =GetDicomDatabaseList().begin(); - i!=GetDicomDatabaseList().end(); - ++i) - { - UpdateDicomDatabaseView(*i); - } - - mTreeListCtrl->Expand(mTreeRootId); - // LG : test - // mTreeListCtrl->ExpandAll(mTreeRootId); - // std::cout << "EO RebuildAll"<GetFirstChild(mTreeRootId,cookie); - dbid.IsOk(); - dbid = mTreeListCtrl->GetNextChild(mTreeRootId,cookie)) - { - data = (TreeItemData *)mTreeListCtrl->GetItemData(dbid); - if ((data->IsDatabase())&&(data->GetDicomNode()==db)) break; - } - - // Not found : create - if (!dbid.IsOk()) - { - // Icon - int iconid = Icon[DicomNode::Database]; - - // Creation - // std::cout << " -> Creating item for '"<GetLabel()<<"'"<AppendItem( mTreeRootId, - std2wx(db->GetLabel()), - iconid, - iconid, - data ); - data->SetItemId(dbid); - mTreeListCtrl->SetItemTextColour - (dbid,mSettings.Colour(DicomNode::Database)); - mTreeListCtrl->SetItemBackgroundColour - (dbid,mSettings.BgColour(DicomNode::Database)); - UpdateColumns(dbid); - // The patients columns legends - CreateChildrenColumnsTitles(dbid,DicomNode::Patient); - - } - // Increase UpdateTime to detect obsolete items after - // tree traversal - data->UpdateTime()++; - // Recurse - DicomNode::ChildrenListType::iterator j; - for (j= db->GetChildrenList().begin(); - j!=db->GetChildrenList().end(); - j++) - { - UpdateDicomNodeView(*j,dbid); - } - - DeleteObsoleteChildren(dbid); - - mTreeListCtrl->EnsureVisible(dbid); - - } - //================================================================ - - //================================================================ - void WxGimmick::UpdateDicomNodeView(DicomNode* n, - const wxTreeItemId& parent) - { - - wxBusyCursor busy; - // std::cout << "* UpdateDicomNodeView("<GetLabel()<<")"<GetType() != DicomNode::Study)) - { - // Does the item exist ? - wxTreeItemIdValue cookie; - for (newparent = mTreeListCtrl->GetFirstChild(parent,cookie); - newparent.IsOk(); - newparent = mTreeListCtrl->GetNextChild(parent,cookie)) - { - data = (TreeItemData *)mTreeListCtrl->GetItemData(newparent); - if (data->GetDicomNode() == n) break; - } - // Not found : create - if (!newparent.IsOk()) - { - int image(Icon[n->GetType()]); - wxColour *colour(&mSettings.Colour(n->GetType())); - wxColour *bgcolour(&mSettings.BgColour(n->GetType())); - - if (n->GetType()==DicomNode::Image) - { - // std::cout << "!!!Image"<GetData()!=0) - { - // std::cout << ">> n->GetData()!=0" << std::endl; - if (n->GetData()->IsLoaded()) - { - colour = &mSettings.LoadedImageColour(); - } - // std::cout << "<< n->GetData()!=0" << std::endl; - } - } - - data = new TreeItemData(n); - newparent = mTreeListCtrl->AppendItem(parent, - _T(""), - image, image, - data); - data->SetItemId(newparent); - mTreeListCtrl->SetItemTextColour(newparent,*colour); - mTreeListCtrl->SetItemBackgroundColour(newparent,*bgcolour); - - UpdateColumns(newparent); - - - if (n->GetType()!=DicomNode::Image) - { - CreateChildrenColumnsTitles(newparent,n->GetType()+1); - } - - } - else - { - UpdateColumns(newparent,true); - - } - // synchonise update time with parent - TreeItemData * parent_data = - (TreeItemData *)mTreeListCtrl->GetItemData(parent); - data->UpdateTime() = parent_data->UpdateTime(); - } - - DicomNode::ChildrenListType::iterator i; - for (i=n->GetChildrenList().begin(); - i!=n->GetChildrenList().end(); - i++) - { - UpdateDicomNodeView(*i,newparent); - } - - if (n->GetType() != DicomNode::Image) - DeleteObsoleteChildren(newparent); - - } - //================================================================ - - //================================================================ - void WxGimmick::UpdateColumns(wxTreeItemId& item, - bool only_first) - { - TreeItemData *data = - (TreeItemData *)mTreeListCtrl->GetItemData(item); - DicomNode* node = data->GetDicomNode(); - - if (only_first) - { - // Update only the first field (for #children update) - DicomNode* node2 = node; - // If Study and Series level are merged and node type is Series - // then have to get back to the Study level - if ((mSettings.MergeStudySeries())&& - (node->GetType() == DicomNode::Series)) - node2 = node->GetParent(); - - std::string lab; - lab += node2->GetFieldValueMap() - [ mSettings.GetColumnList(node2->GetType())[0].Key ]; - - if (node->GetType() != DicomNode::Image) - { - if (node->GetChildrenList().size()>0) - { - char sz[100]; - sprintf(sz," [%d]",node->GetNumberOfChildren()); - lab += sz; - } - } - mTreeListCtrl->SetItemText(item,std2wx(lab)); - } - else - { - int c = 0; - Settings::ColumnListType::iterator col; - // If Study and Series level are merged and node type is Series - // then have to fill the Study level cols first - if ((mSettings.MergeStudySeries())&& - (node->GetType() == DicomNode::Series)) - { - DicomNode* node2 = node->GetParent(); - for (col = mSettings.GetColumnList(node2->GetType()).begin(); - col != mSettings.GetColumnList(node2->GetType()).end(); - ++col) - { - std::string s = node2->GetFieldValueMap()[col->Key]; - - if (c==0) - { - char sz[100]; - sprintf(sz," [%d]",node->GetNumberOfChildren()); - s += sz; - } - mTreeListCtrl->SetItemText (item, c, std2wx(s)); - c++; - } - } - - for (col = mSettings.GetColumnList(node->GetType()).begin(); - col != mSettings.GetColumnList(node->GetType()).end(); - ++col) - { - std::string s = node->GetFieldValueMap()[col->Key]; - if ((c==0)&&(node->GetType() != DicomNode::Image)) - { - char sz[100]; - sprintf(sz," [%d]",node->GetNumberOfChildren()); - s += sz; - } - mTreeListCtrl->SetItemText (item, c, std2wx(s)); - c++; - } - } - - } - //================================================================ - - //================================================================ - wxTreeItemId WxGimmick::CreateChildrenColumnsTitles - (wxTreeItemId& item, - DicomNode::Type t) - { - // Creates the sub-level columns titles - TreeItemData* data - = new TreeItemData(0); - wxTreeItemId id = mTreeListCtrl->AppendItem( item, - _T(""), - -1, - -1, - data ); - data->SetItemId(id); - mTreeListCtrl->SetItemFont(id, *wxITALIC_FONT); - mTreeListCtrl->SetItemTextColour(id, mSettings.Colour(t)); - mTreeListCtrl->SetItemBackgroundColour(id, mSettings.BgColour(t)); - UpdateColumnsTitles(id,t); - return id; - } - //================================================================ - - //================================================================ - void WxGimmick::UpdateColumnsTitles(wxTreeItemId& item, - DicomNode::Type t) - { - // std::cout << "Update columns titles "<Name << std::endl; - mTreeListCtrl->SetItemText (item, c, std2wx(col->Name)); - c++; - } - } - //================================================================ - - - //================================================================ - void WxGimmick::DeleteObsoleteChildren(wxTreeItemId& id) - - { - TreeItemData * parent_data = - (TreeItemData *)mTreeListCtrl->GetItemData(id); - - wxTreeItemId child; - wxTreeItemIdValue cookie; - std::vector children; - for (child = mTreeListCtrl->GetFirstChild(id,cookie); - child.IsOk(); - child = mTreeListCtrl->GetNextChild(id,cookie)) - { - children.push_back(child); - } - std::vector::iterator i; - for (i=children.begin();i!=children.end();++i) - { - TreeItemData *data = - (TreeItemData *)mTreeListCtrl->GetItemData(*i); - if ( - ((data->GetDicomNode()>0) && - ((data->UpdateTime() != parent_data->UpdateTime()))) || - ((data->IsDicomNode()) && - (data->GetDicomNode()==0)) - ) - { - // std::cout << "DOBSC="<GetItemText(*i)<Delete(*i); - } - } - } - //================================================================ - - //================================================================ - void WxGimmick::OpenOrNewDatabase(bool open) - { - wxBusyCursor busy; - - long style = wxFD_SAVE | wxFD_OVERWRITE_PROMPT; - if (open) style = wxOPEN | wxFILE_MUST_EXIST; - std::string wc("*."); - wc += GetDatabaseExtension(); - - // TO DO : Handler give their wildcards - wxFileDialog* FD = new wxFileDialog( 0, - _T("Select file"), - mCurrentDirectory, - _T(""), - std2wx(wc), - style, - wxDefaultPosition); - - if (FD->ShowModal()!=wxID_OK) return; - - std::string filename = wx2std (FD->GetPath()); - mCurrentDirectory = FD->GetDirectory(); - - if (!open) - { - boost::filesystem::path filepath(filename); - boost::filesystem::change_extension(filepath,GetDatabaseExtension()); - if ( boost::filesystem::exists(filepath) ) - { - boost::filesystem::remove(filepath); - /* - LG : works on Linux but not Windows : - if ( ! boost::filesystem::remove(filepath) ) - { - wxMessageBox(_T("Could not overwrite ") - +std2wx(filepath.string()), - _T("Error"), - wxOK,this); - return; - - - } - */ - } - } - - DicomDatabase* db = new DicomDatabase(filename); - bool r; - if (open) - { - r = db->Open(); - if (!r) - { - wxMessageBox(_T("An error occured while opening ") - +std2wx(filename), - _T("Error"), - wxOK,this); - return; - } - } - else - { - wxString collname = - wxGetTextFromUser(_T("Enter collection name"),_T("New collection"), - _T(""),this); - db->SetName(wx2std(collname)); - - r = db->New(); - if (!r) - { - wxMessageBox(_T("An error occured while creating ") - +std2wx(filename), - _T("Error"), - wxOK,this); - return; - } - } - - if (GetDicomDatabaseList().size()==0) mFieldsView->UpdateFields(db); - GetDicomDatabaseList().push_back(db); - UpdateDicomDatabaseView(db); - - - } - //================================================================ - - - //================================================================ - void WxGimmick::LoadConfiguration() - { - wxBusyCursor busy; - // std::cout << "WxGimmick : Reading config"< Loading collections from '"< tokens; - boost::split( tokens, str, boost::is_any_of("\t") ); - - DicomDatabase* db = new DicomDatabase(tokens[0]); - - // std::cout << " -> Loading collection '"<SetName(tokens[1]); - } - - if (db->Open()) - { - GetDicomDatabaseList().push_back(db); - db->DBLoadChildren(db,DicomNode::Patient); - if (mSettings.HasActiveComparator(DicomNode::Patient)) - { - db->SortChildren - ( mSettings.GetActiveComparator(DicomNode::Patient) ); - } - } - else - { - creaMessage("Gimmick!",1," ==> ERROR opening collection '"< File does not exist. It will be created on exit (if you already ran Gimmick! and exited normally, this is not normal. Send a bug report)."); - } - - - mTreeListCtrl->SetBackgroundColour(mSettings.BgColour(DicomNode::Database)); - if (GetDicomDatabaseList().begin() != - GetDicomDatabaseList().end() ) - { - mFieldsView->UpdateFields(*GetDicomDatabaseList().begin()); - } - - RebuildView(); - - } - //================================================================ - - //================================================================ - void WxGimmick::SaveConfiguration() - { - wxBusyCursor busy; - creaMessage("Gimmick!",1,"Gimmick! : Saving configuration..."< Saving collections in '" - <GetFileName() << "\t"; - s << (*i)->GetName() << std::endl; - } - - s.close(); - - } - //================================================================ - - //================================================================ - void WxGimmick::LoadOrCreateFavoritesDatabase() - { - // TODO - } - //================================================================ - - /* - //================================================================ - void WxGimmick::OnClose(wxCloseEvent& event) - { - if (mSaveConfigurationOnClose) SaveConfiguration(); - } - //================================================================ - */ - //================================================================ - void WxGimmick::OnItemActivated(wxTreeEvent& event) - { - event.Skip(); - return; - - wxBusyCursor busy; - // std::cout << "OnItemActivated" <IsExpanded(itemId)) - { - mTreeListCtrl->Collapse(itemId); - } - else - { - mTreeListCtrl->Expand(itemId); - } - } - //================================================================ - - //================================================================ - void WxGimmick::LoadChildren(wxTreeItemId& id) - { - TreeItemData *item = (TreeItemData *)mTreeListCtrl->GetItemData(id); - if (item) - { - if ( ( item->IsDicomNode() || item->IsDatabase() ) && - ( ! item->GetDicomNode()->ChildrenLoaded() ) ) - { - - // If children not already loaded : do it - if ( - item->GetDicomNode()->GetDicomDatabase()->DBLoadChildren - (item->GetDicomNode(),item->GetDicomNode()->GetType()+1) - > 0 ) - { - // Some new children loaded - // Sort them - if (mSettings.HasActiveComparator - (item->GetDicomNode()->GetType()+1)) - { - /* std::cout << "Sorting using '" - << mSettings.GetActiveComparator - (item->GetDicomNode()->GetType()+1).GetName() - << "' ... "; - */ - item->GetDicomNode()->SortChildren - ( mSettings.GetActiveComparator - (item->GetDicomNode()->GetType()+1) - ); - // std::cout << "ok"<GetDicomNode()->GetChildrenList().begin(); - i!=item->GetDicomNode()->GetChildrenList().end(); - i++) - { - UpdateDicomNodeView(*i,id); - } - } - // EO If children not already loaded - } - } - } - //================================================================ - - - //================================================================ - void WxGimmick::OnItemExpanded(wxTreeEvent& event) - { - // std::cout << "* Expanded *"<GetItemData(itemId); - if (item) - { - if ( ( item->IsDicomNode() || item->IsDatabase() ) && - ( ! item->GetDicomNode()->ChildrenLoaded() ) ) - { - - // If children not already loaded : do it - if ( - item->GetDicomNode()->GetDicomDatabase()->DBLoadChildren - (item->GetDicomNode(),item->GetDicomNode()->GetType()+1) - > 0 ) - { - - // Some new children loaded - // Sort them - if (mSettings.HasActiveComparator - (item->GetDicomNode()->GetType()+1)) - { - /* std::cout << "Sorting using '" - << mSettings.GetActiveComparator - (item->GetDicomNode()->GetType()+1).GetName() - << "' ... "; - */ - item->GetDicomNode()->SortChildren - ( mSettings.GetActiveComparator - (item->GetDicomNode()->GetType()+1) - ); - // std::cout << "ok"<IsDicomNode()) - { - if (item->GetDicomNode()->GetType()==DicomNode::Series) - { - // SORT - - LexicographicalDicomNodeComparator compare; - // DicomNodeImageImageNumberComparator c1; - - DicomNodeImageSliceLocationComparator c1; - DicomNodeImageImageNumberComparator c2; - DicomNodeImageFileNameComparator cn; - compare.Add(c1); - compare.Add(c2); - compare.Add(cn); - // std::cout << "SORT"<GetDicomNode()->SortChildren(compare); - // std::cout << "EO SORT"<GetDicomNode()->GetChildrenList().begin(); - i!=item->GetDicomNode()->GetChildrenList().end(); - i++) - { - UpdateDicomNodeView(*i,itemId); - } - } - // EO If children not already loaded - } - } - // mTreeListCtrl->Expand(itemId); - - } - //================================================================ - - - /* - //===================================================================== - void WxGimmick::InsertRoot(wxTreeItemId& id, Root* r) - { - wxBusyCursor busy; - TreeItemData *data = (TreeItemData *)mTreeListCtrl->GetItemData(id); - if (data) - { - - wxStopWatch sw; - data->GetDicomNode()->GetDicomDatabase()->LoadAll(); - printf(">>>>>> Time to load all = %ldms \n",sw.Time()); - - UpdateRootView(data->GetDicomNode()->GetDicomDatabase()); - - - if (data->IsDicomNode()) - { - wxStopWatch sw1; - r->Insert(data->GetDicomNode()); - printf(">>>>>> Time to insert = %ldms \n",sw1.Time()); - UpdateRootView(r); - } - else if (data->IsDatabase()) - { - wxStopWatch sw1; - DicomNode::ChildrenListType::iterator j; - for (j= data->GetDicomNode()->GetChildrenList().begin(); - j!=data->GetDicomNode()->GetChildrenList().end(); - j++) - { - r->Insert(*j); - } - printf(">>>>>> Time to insert = %ldms \n",sw1.Time()); - UpdateRootView(r); - } - - } - } - //===================================================================== - */ - - - //================================================= - void WxGimmick::DeleteDicomDatabase(wxTreeItemId& id, - DicomDatabase* db) - { - wxBusyCursor busy; - DicomDatabaseListType::iterator i = find(GetDicomDatabaseList().begin(), - GetDicomDatabaseList().end(), - db); - delete (*i); - GetDicomDatabaseList().erase(i); - mTreeListCtrl->Delete(id); - } - //================================================= - - - - //===================================================================== - - void WxGimmick::OnItemRightClick(wxTreeEvent& event) - { - wxTreeItemId itemId = event.GetItem(); - if (itemId.IsOk()) - { - wxPoint clientpt = event.GetPoint(); - wxPoint screenpt = ClientToScreen(clientpt); - ShowMenu(itemId, clientpt); - } - event.Skip(); - } - //===================================================================== - - //===================================================================== - void WxGimmick::ShowMenu(wxTreeItemId id, const wxPoint& pt) - { - - // std::cout << "ShowMenu" <GetItemData(id); - - /* - wxString title; - if ( id.IsOk() ) - { - title << wxT("Menu for ") << mTreeListCtrl->GetItemText(id); - } - else - { - title = wxT("Menu for no particular item"); - } - */ - -#if wxUSE_MENUS - wxMenu menu; - - if (id==mCollectionsTitlesItemId) - { - menu.Append(PopUp_NewCollection, _T("&New collection")); - menu.Append(PopUp_OpenCollection, _T("&Open collection")); - } - if (data) - { - if (data->IsDatabase()) - { - wxMenu* addmenu = new wxMenu; - addmenu->Append(PopUp_AddDirectory, _T("Scan &Directory")); - addmenu->Append(PopUp_AddFile, _T("Select &File(s)")); - // addmenu->Append(PopUp_AddRawFile, _T("Add &Raw image")); - menu.AppendSubMenu(addmenu, _T("&Add image(s) to collection...")); - menu.Append(PopUp_CloseCollection, _T("&Close collection")); - menu.Append(PopUp_DeleteCollection, _T("&Delete collection")); - } - if (data->IsDicomNode()) - { - - // LG : BUGGY - /* - std::string str("&Remove "); - str += data->GetDicomNode()->GetTypeName(); - menu.Append(PopUp_Remove, std2wx(str)); - */ - } - - if ((data->GetDicomNode()>0)&& - ( data->GetDicomNode()->GetType()GetDicomNode()->GetType()+1; - if (mSettings.HasActiveComparator(ctype)) - { - wxMenu* sortmenu = new wxMenu; - int n = 0; - Settings::ComparatorsList::iterator i; - for (i =mSettings.GetComparatorsList(ctype).begin(); - i !=mSettings.GetComparatorsList(ctype).end(); - ++i) - { - sortmenu->AppendRadioItem(PopUp_Sort+n, std2wx(i->GetName())); - n++; - } - - sortmenu->Check(PopUp_Sort+ - mSettings.GetActiveComparatorIndex(ctype) - ,true); - - std::string sortmenustr("&Sort "); - sortmenustr += DicomNode::GetPluralTypeName(ctype); - sortmenustr += " by..."; - if (menu.GetMenuItemCount()>0) menu.AppendSeparator(); - menu.AppendSubMenu(sortmenu,std2wx(sortmenustr)); - - /* - item->GetDicomNode()->SortChildren - ( mSettings.GetActiveComparator - (item->GetDicomNode()->GetType()+1) - ); - std::cout << "ok"<GetDicomNode()); - } - GetEventHandler()->ProcessEvent(ev); - // - - if (menu.GetMenuItemCount()>0) menu.AppendSeparator(); - menu.Append(PopUp_Settings, wxT("&Settings...")); - menu.Append(PopUp_About, wxT("&About...")); - - /* - wxMenu* newmenu = new wxMenu; - wxMenu* openmenu = new wxMenu; - Tree::RootHandlerListType::iterator h; - int i=0; - for (h= Tree::GetRootHandlerList().begin(); - h!=Tree::GetRootHandlerList().end(); - h++) - { - if ((*h)->SupportsNew()) - { - newmenu->Append(PopUp_New+i, std2wx((*h)->GetName())); - } - if ((*h)->SupportsOpen()) - openmenu->Append(PopUp_Open+i, std2wx((*h)->GetName())); - i++; - } - - menu.AppendSubMenu(openmenu, _T("&Open")); - menu.AppendSubMenu(newmenu, _T("&New")); - - if (data) - { - if ((data->IsDatabase())||(data->IsDicomNode())) - { - Root* itroot = data->GetDicomNode()->GetDicomDatabase(); - // if (!itroot) itroot = data->GetDicomNode()->GetRoot(); - wxMenu* insertmenu = new wxMenu; - bool hasone = false; - i = 0; - Tree::RootListType::iterator j; - for (j = mTree->GetDatabaseList().begin(); - j != mTree->GetDatabaseList().end(); - j++) - { - // std::cout << (*j)->GetName() << " " - // << (*j)->GetTypeName() - // << " i="<<(*j)->SupportsInsert()<SupportsInsert()) ) - { - insertmenu->Append(PopUp_Insert+i, - std2wx((*j)->GetName())); - hasone = true; - } - i++; - } - - if (hasone) menu.AppendSubMenu(insertmenu, _T("&Insert into")); - } - if (data->IsDatabase()) - { - menu.Append(PopUp_Close, wxT("&Close")); - } - if (data->IsDicomNode() && data->GetDicomNode()->GetDicomDatabase()->SupportsRemove()) - { - menu.Append(PopUp_Remove, wxT("&Remove")); - } - } - */ - - PopupMenu(&menu, pt); -#endif // wxUSE_MENUS - - // std::cout << "EO ShowMenu" <ShowModal(); - delete s; - } - //===================================================================== - - //===================================================================== - void WxGimmick::OnPopUpNewCollection(wxCommandEvent& event) - { - wxBusyCursor busy; - OpenOrNewDatabase(false); - } - //===================================================================== - - - //===================================================================== - void WxGimmick::OnPopUpOpenCollection(wxCommandEvent& event) - { - wxBusyCursor busy; - OpenOrNewDatabase(true); - } - //===================================================================== - - - //===================================================================== - void WxGimmick::OnPopUpCloseCollection(wxCommandEvent& event) - { - if (wxMessageBox(_T("This will remove this collection from your list of collections but will not delete the collection's file on disk. Proceed ?"),_T("Confirm"),wxYES_NO,this)==wxNO) return; - - wxBusyCursor busy; - // std::cout << "OnPopUpClose"<GetItemData(mItemOfMenu); - DicomDatabase* r = data->GetDicomNode()->GetDicomDatabase(); - // std::cout << "OnPopUpClose '"<GetName()<<"'"<GetItemData(mItemOfMenu); - DicomDatabase* r = data->GetDicomNode()->GetDicomDatabase(); - - wxRemoveFile(std2wx(r->GetFileName())); - // std::cout << "OnPopUpClose '"<GetName()<<"'"<ShowModal()==wxID_OK) - { - wxBusyCursor busy; - - mCurrentDirectory = FD->GetDirectory(); - wxArrayString files; - FD->GetPaths(files); - unsigned int i; - std::vector filenames; - for (i=0;iGetItemData(mItemOfMenu); - DicomDatabase* db = data->GetDicomNode()->GetDicomDatabase(); - DicomDatabase::UpdateSummary summary; - wxProgressDialog* progress = - new wxProgressDialog(_T("Adding file(s)"), - _T(""), - 1000, - this, - wxPD_ELAPSED_TIME | - wxPD_ESTIMATED_TIME | - wxPD_REMAINING_TIME | - wxPD_CAN_ABORT ); - - db->AddFiles(filenames,progress,summary); - - progress->Pulse(_T("Updating view...")); - UpdateDicomDatabaseView(db); - delete progress; - DisplayUpdateSummary(summary,this); - } - - } - //===================================================================== - - //===================================================================== - void WxGimmick::OnPopUpAddRawFile(wxCommandEvent& event) - { - wxMessageBox(_T("Not yet implemented !"),_T("Sorry"),wxOK,this); - } - //===================================================================== - - //===================================================================== - void WxGimmick::OnPopUpAddDirectory(wxCommandEvent& event) - { - long style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST; - wxDirDialog* FD = - new wxDirDialog( 0, - _T("Select directory"), - mCurrentDirectory, - style); - - if (FD->ShowModal()==wxID_OK) - { - - bool recurse = false; - if (wxMessageBox(_T("Recurse into sub-directories ?"), - _T("Scan directory"), - wxYES_NO,this ) == wxYES) - { - recurse = true; - } - - wxBusyCursor busy; - wxProgressDialog* progress = - new wxProgressDialog(_T("Scanning directory"), - _T("Parsing directory"), - 1000, - this, - wxPD_ELAPSED_TIME | - wxPD_ESTIMATED_TIME | - wxPD_REMAINING_TIME | - wxPD_CAN_ABORT ); - DicomDatabase::UpdateSummary summary; - - std::string dirname = wx2std (FD->GetPath()) ; - mCurrentDirectory = FD->GetPath(); - TreeItemData *data = - (TreeItemData *) - mTreeListCtrl->GetItemData(mItemOfMenu); - DicomDatabase* db = data->GetDicomNode()->GetDicomDatabase(); - db->AddDirectory(dirname,recurse,progress,summary); - - progress->Pulse(_T("Updating view...")); - UpdateDicomDatabaseView(db); - - delete progress; - DisplayUpdateSummary(summary,this); - /* - if (summary.cancelled_by_user) - { - std::cout << "!! Cancelled by user !!"<GetItemData(mItemOfMenu); - - std::string mess("Remove "); - mess += data->GetDicomNode()->GetTypeName(); - mess += " from collection ?"; - int answer = wxMessageBox(std2wx(mess), _T("Confirm"), wxYES_NO); - if (answer == wxNO) return; - - if ( mTreeListCtrl->IsSelected(mItemOfMenu) ) - { - wxTreeItemId next = mTreeListCtrl->GetNextSibling(mItemOfMenu); - if (next.IsOk()) - { - mTreeListCtrl->SelectItem(next); - } - else - { - return; - } - } - - DicomDatabase* db = data->GetDicomNode()->GetDicomDatabase(); - db->Remove(data->GetDicomNode()); - // std::cout << "OnPopUpClose '"<GetName()<<"'"<GetItemData(mItemOfMenu); - int index = event.GetId() - PopUp_Sort; - DicomNode* node = data->GetDicomNode(); - DicomNode::Type ctype = node->GetType()+1; - mSettings.SetActiveComparatorIndex(ctype,index); - - if (node->ChildrenLoaded()) - { - // Remove children - mTreeListCtrl->DeleteChildren(mItemOfMenu); - - /* std::cout << "Sorting using '" - << mSettings.GetActiveComparator(ctype).GetName() - << "' ... "; - */ - node->SortChildren ( mSettings.GetActiveComparator(ctype) ); - // std::cout << "ok"<GetChildrenList().begin(); - i!=node->GetChildrenList().end(); - i++) - { - UpdateDicomNodeView(*i,mItemOfMenu); - } - } - } - //===================================================================== - - - //===================================================================== - void WxGimmick::OnPopUpUser(wxCommandEvent& event) - { - // std::cout << "OnPopUpUser"<SetImageList(NULL); - return; - } - if ( size == 0 ) - size = m_imageSize; - else - m_imageSize = size; - - wxIcon icons[20]; - // should correspond to Icon_xxx enum - icons[Icon_Patient] = wxIcon(patient_xpm); - icons[Icon_Study] = wxIcon(study_xpm); - icons[Icon_Series] = wxIcon(series_xpm); - icons[Icon_Image] = wxIcon(image_xpm); - icons[Icon_Database] = wxIcon(database_xpm); - icons[Icon_Folder] = wxIcon(folder_xpm); - icons[Icon_DicomDir] = wxIcon(dicomdir_xpm); - icons[Icon_Root] = wxIcon(root_xpm); - - - // mFirstRootIconIndex = 8; - // int i=0; - /* - Tree::RootHandlerListType::iterator h; - - for (h= Tree::GetDatabaseHandlerList().begin(); - h!=Tree::GetDatabaseHandlerList().end(); - h++) - { - icons[mFirstRootIconIndex+i] = (*h)->GetIcon(); - i++; - } - */ - unsigned int NbIcons = 8;//mFirstRootIconIndex + i; - // Make an image list containing small icons - wxImageList *images = new wxImageList(size, size, true); - - int sizeOrig = icons[0].GetWidth(); - for ( size_t i = 0; i < NbIcons; i++ ) - { - if ( size == sizeOrig ) - { - images->Add(icons[i]); - } - else - { - images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); - } - } - mTreeListCtrl->AssignImageList(images); - } - //================================================= - - - - - - - - - //================================================================ - bool WxGimmick::IsImageSelectable(DicomNode* node) - { - int rows = node->ImageGetRows(); - int cols = node->ImageGetColumns(); - int frms = node->ImageGetFrames(); - - // std::cout << "R/C/F = " << rows << "/"<< cols <<"/"<0) dim=3; - else if (cols>0) dim=2; - else if (rows>0) dim=1; - - if (dim == 0) - { - std::cout << "Unknown image dimension : cannot select !" - << std::endl; - return false; - } - else if (dim>mSelectionMaxImageDimension) - { - std::cout << "Selecting "<GetSelectionSize() == 0 ) - { - mCurrentSelectionImageSize[0] = cols; - mCurrentSelectionImageSize[1] = rows; - mCurrentSelectionImageSize[2] = frms; - return true; - } - else - { - if ( dim == mSelectionMaxImageDimension ) - { - std::cout << "Cannot add this image to selection : would result in a "<ImageGetFullFileName() << std::endl; - return true; - } - //================================================================ - - //================================================================ - void WxGimmick::OnSelChanging(wxTreeEvent& event) - { - event.Veto(); - wxTreeItemId id = event.GetItem(); - if (!id.IsOk()) - { - std::cout << "INTERNAL ERROR : ID NOT OK"<GetItemData(id); - if (data->IsDicomNode()) - { - if (data->GetDicomNode()>0) - { - // An image was selected - if (data->GetDicomNode()->GetType()==DicomNode::Image) - { - if (IsImageSelectable(data->GetDicomNode())) event.Allow(); - } - // A series was selected - else if (data->GetDicomNode()->GetType()==DicomNode::Series) - { - // If images not loaded do it - LoadChildren(id); - // can be selected if all its images can - wxTreeItemId child; - wxTreeItemIdValue cookie; - for (child = mTreeListCtrl->GetFirstChild(id,cookie); - child.IsOk(); - child = mTreeListCtrl->GetNextChild(id,cookie)) - { - TreeItemData *cdata = - (TreeItemData *)mTreeListCtrl->GetItemData(child); - if ((cdata->IsDicomNode())&& - (cdata->GetDicomNode()>0)&& - (cdata->GetDicomNode()->GetType()==DicomNode::Image)&& - (!IsImageSelectable(cdata->GetDicomNode()))) - return; - } - event.Allow(); - } - } - } - } - //================================================================ - - //================================================================ - void WxGimmick::OnSelChanged(wxTreeEvent& event) - { - // wxBusyCursor busy; - // std::vector items; - // GetSelectedItems(items); - /* - std::vector::iterator i; - for (i=nodes.begin();i!=nodes.end();++i) - { - std::cout << "'" << (*i)->GetFieldValue("FullFileName") - << "'" << std::endl; - } - std::cout << "++++++++++++++++++++" << std::endl; - */ - // ShowImage(mReader.GetImage("")); - - bool no_image = true; - - static int max = 1000; - - - // if (items.size()>0) - // { - - // Update image preview : send requests to the MTImageReader - // bool first = true; - // std::vector::iterator i; - // for (i=items.begin();i!=items.end();++i) - // { - - /* - if (first) - { - DicomNode* node = GetDicomNodeOfItem(items[0]); - if (!node) return; - // Update dicom fields panel - mFieldsView->UpdateValues(node); - } - */ - - wxTreeItemId item = mTreeListCtrl->GetCurrent(); - - DicomNode* n = GetDicomNodeOfItem(item); - - if (n) mFieldsView->UpdateValues(n); - - if ( (n!=0) && - (n->GetType()==DicomNode::Image) ) - { - - // - no_image = false; - //if (i==items.begin()) - mCurImageItemToShow = item; - - int maxprio = mReader.GetMaximalPriority(); - int prio = maxprio + 1000; - wxTreeItemId sib = item; //GetTreeListCtrl()->GetNextSibling(*i); - while (sib.IsOk()) - { - DicomNode* nsib = GetDicomNodeOfItem(sib); - if (nsib>0) - { - // std::cout << "-- Request '" - // << nsib->GetFieldValue("FullFileName") - // << "' prio="<ImageGetFullFileName(), - prio); - mImageFileNameToNode[nsib->ImageGetFullFileName()] = - nsib; - prio--; - } - sib = GetTreeListCtrl()->GetNextSibling(sib); - } - prio = maxprio + 999; - sib = GetTreeListCtrl()->GetPrevSibling(item); - while (sib.IsOk()) - { - DicomNode* nsib = GetDicomNodeOfItem(sib); - if (nsib>0) - { - // std::cout << "-- Request '" - // << nsib->GetFieldValue("FullFileName") - // << "' prio="<ImageGetFullFileName(), - prio); - mImageFileNameToNode[nsib->ImageGetFullFileName()] = - nsib; - prio--; - } - sib = GetTreeListCtrl()->GetPrevSibling(sib); - } - // mImageFileNameToNode[n->GetFieldValue("FullFileName")] = n; - max += 1000; - - ProcessImageEvents(); - } - // std::cout << "* Selection changed * (im)"<ProcessEvent(ev); - - if (no_image) ShowImage(mReader.GetImage("")); - - } - //================================================================ - - //================================================================ - void WxGimmick::ShowImage(vtkImageData* im) - { - // wxBusyCursor busy; - mViewer->SetInput( im ); - mViewer->SetSlice( 0 ); - - - int x1,x2,y1,y2,z1,z2; - double spx,spy,spz; - im->Update(); - im->GetSpacing(spx,spy,spz); - im->GetExtent (x1,x2,y1,y2,z1,z2); - /* - std::cout << "-----------------------------"<GetScalarRange(); - mViewer->SetColorWindow(range[1] - range[0]); - mViewer->SetColorLevel(0.5 * (range[1] + range[0])); - - mViewer->GetRenderer()->ResetCamera(); - double bounds[6]; - - - mViewer->GetRenderer()->ComputeVisiblePropBounds(bounds); - - /* - std::cout <<"bounds : "<GetRenderer()->ResetCameraClippingRange(bounds); - /* - vtkCamera *camera = mViewer->GetRenderer()->GetActiveCamera(); - - camera->SetViewUp ( spx*0, -spy*1, spz*0); - camera->SetPosition( spx*(x1+x2)/2, spy*(y1+y2)/2, spz*10000000); - camera->SetFocalPoint ( spx*(x1+x2)/2 , spy*(y1+y2)/2 , spz*0); - - camera->ComputeViewPlaneNormal(); - camera->SetParallelScale( spx*(x2-x1)/2.0 ); - - camera->Roll ( 180 ); - */ - } - - mInteractor->Render(); - } - //================================================================ - - - - - - - //================================================================ - void WxGimmick:: - OnMultiThreadImageReaderEvent(const std::string& filename, - MultiThreadImageReaderUser::EventType e, - vtkImageData* image) - { - if (filename.size()==0) - { - mImageEventQueue.push_back(ImageEventType(image)); - return; - } - std::map::iterator i; - i = mImageFileNameToNode.find(filename); - if (i!=mImageFileNameToNode.end()) - { - wxTreeItemId id = i->second->GetData()->GetTreeItemData()->GetItemId(); - mImageEventQueue.push_back(ImageEventType(id,image)); - } - } - //================================================================ - - //================================================================ - // Processes the queue of image events - void WxGimmick::ProcessImageEvents() - { - // std::cout << "++++++++++ ProcessImageEvents " << std::endl; - MultiThreadImageReaderEventLock(); - - - while (!mImageEventQueue.empty()) - { - ImageEventType e = mImageEventQueue.front(); - mImageEventQueue.pop_front(); - if( e.image!=0 ) - { - if (e.item.IsOk()) - { - mTreeListCtrl->SetItemTextColour(e.item, - mSettings.LoadedImageColour());//wxImageLoadedColour); - TreeItemData *data = - (TreeItemData *)mTreeListCtrl->GetItemData(e.item); - data->SetLoaded(true); - - if (mCurImageItemToShow == e.item) - { - ShowImage(e.image); - } - } - else if (!mCurImageItemToShow.IsOk()) - { - ShowImage(e.image); - } - } - else if (e.item.IsOk()) - { - mTreeListCtrl->SetItemTextColour(e.item,mSettings.Colour(DicomNode::Image)); //.wxImageUnloadedColour); - TreeItemData *data = - (TreeItemData *)mTreeListCtrl->GetItemData(e.item); - data->SetLoaded(false); - } - } - mImageEventQueue.clear(); - MultiThreadImageReaderEventUnlock(); - // std::cout << "++++++++++ END ProcessImageEvents " << std::endl; - } - //================================================================ - - //================================================================ - void WxGimmick::OnInternalIdle() - { - ProcessImageEvents(); - /* - if (mJustStarted) - { - - mJustStarted = false; - } - */ - // - } - //================================================================ - - - //================================================================ - // LG : For the moment any selection is valid but in the future - // incomplete selections can be invalid... - bool WxGimmick::IsSelectionValid() - { - return (mTreeListCtrl->GetSelectionSize()>0); - } - //================================================================ - - //================================================================ - void WxGimmick::GetSelectedFiles(std::vector& f) - { - wxArrayTreeItemIds id; - // TO DO : TEST THAT STYLE IS MULTIPLE - unsigned int nb = mTreeListCtrl->GetSelections(id); - f.clear(); - for (unsigned int i=0; iGetItemData(id[i]); - if ((data) && (data->IsDicomNode())) - { - if (data->GetDicomNode()->GetType()==DicomNode::Image) - { - f.push_back ( data->GetDicomNode()->ImageGetFullFileName() ); - } - else if (data->GetDicomNode()->GetType()==DicomNode::Series) - { - DicomNode::ChildrenListType::iterator j; - for (j =data->GetDicomNode()->GetChildrenList().begin(); - j!=data->GetDicomNode()->GetChildrenList().end(); - j++) - { - f.push_back((*j)->ImageGetFullFileName()); - } - } - } - } - } - //================================================================ - - //================================================================ - void WxGimmick::GetSelectedImages(std::vector& f) - { - wxArrayTreeItemIds id; - // TO DO : TEST THAT STYLE IS MULTIPLE - unsigned int nb = mTreeListCtrl->GetSelections(id); - f.clear(); - - // Collect the brute vector of Image nodes - std::vector im; - for (unsigned int i=0; iGetItemData(id[i]); - if ((data) && (data->IsDicomNode())) - { - if (data->GetDicomNode()->GetType()==DicomNode::Image) - { - im.push_back ( data->GetDicomNode() ); - - } - else if (data->GetDicomNode()->GetType()==DicomNode::Series) - { - DicomNode::ChildrenListType::iterator j; - for (j =data->GetDicomNode()->GetChildrenList().begin(); - j!=data->GetDicomNode()->GetChildrenList().end(); - j++) - { - im.push_back ( *j ); - } - } - } - } - // Create the output data - if (im.size()==1) - { - // Only one image : give it - vtkImageData* out = vtkImageData::New(); - out->ShallowCopy(mReader.GetImage(im.front()->ImageGetFullFileName())); - f.push_back( out ); - } - else if (im.size()>1) - { - vtkImageData* first = mReader.GetImage( im.front()->ImageGetFullFileName() ); - if (first->GetDataDimension()==2) - { - // n2D to 3D - vtkImageData* out = vtkImageData::New(); - out->CopyStructure(first); - out->SetScalarType(first->GetScalarType()); - int ext[6]; - first->GetExtent(ext); - ext[5] = im.size(); - out->SetExtent(ext); - // LG : TODO : Z Spacing ? - // - // ==> to get an accurate ZSpacing from a Dicom set of files - // ==> you need a gdcm::SerieHelper - // JPR - - out->AllocateScalars(); - - //first->Print(std::cout); - // out->Print(std::cout); - - int dim[3]; - first->GetDimensions(dim); - unsigned long imsize = - ( (unsigned long)first->GetScalarPointer(0,1,0) - - (unsigned long)first->GetScalarPointer(0,0,0)) - *dim[1]; - - int slice = 0; - std::vector::iterator it; - for (it=im.begin(); it!=im.end(); ++it) - { - //std::cout << "copying slice "<ImageGetFullFileName() ); - - void* src = cur->GetScalarPointer(0,0,0); - void* dst = out->GetScalarPointer(0,0,slice); - // std::cout << "src="<GetScalarComponentAsFloat(x,y,slice,0) - << std::endl; - } - } - */ - - slice++; - } - f.push_back(out); - } - else - { - // n3D - std::vector::iterator it; - for (it=im.begin(); it!=im.end(); ++it) - { - vtkImageData* out = vtkImageData::New(); - out->ShallowCopy(mReader.GetImage((*it)->ImageGetFullFileName())); - f.push_back(out); - } - } - } - } - //================================================================ - - - //================================================================ - void WxGimmick::GetSelectedDicomNodes(std::vector& f) - { - wxArrayTreeItemIds id; - // TO DO : TEST THAT STYLE IS MULTIPLE - unsigned int nb = mTreeListCtrl->GetSelections(id); - f.clear(); - for (unsigned int i=0; iGetItemData(id[i]); - if ((data) && (data->IsDicomNode())) - { - f.push_back ( data->GetDicomNode() ); - } - /* - - if (data->GetDicomNode()->GetType()==DicomNode::Image) - { - f.push_back ( data->GetDicomNode() ); //->ImageGetFullFileName() ); - } - else if (data->GetDicomNode()->GetType()==DicomNode::Series) - { - DicomNode::ChildrenListType::iterator j; - for (j =data->GetDicomNode()->GetChildrenList().begin(); - j!=data->GetDicomNode()->GetChildrenList().end(); - j++) - { - f.push_back((*j)); //->ImageGetFullFileName() ); } - } - } - */ - } - } - //================================================================ - - //================================================================ - void WxGimmick::GetSelectedItems(std::vector& f) - { - wxArrayTreeItemIds id; - // TO DO : TEST THAT STYLE IS MULTIPLE - unsigned int nb = mTreeListCtrl->GetSelections(id); - f.clear(); - for (unsigned int i=0; iGetItemData(i); - if (data) return ( data->GetDicomNode() ); - return 0; - } - //================================================================ - - //================================================================ - //================================================================ - //================================================================ - //================================================================ - - - - - - - - - - - - - - - - //================================================================ - //================================================================ - //================================================================ - //================================================================ - - BEGIN_EVENT_TABLE(WxGimmick, wxPanel) - // POP UP MENU - EVT_MENU(PopUp_NewCollection,WxGimmick::OnPopUpNewCollection) - EVT_MENU(PopUp_OpenCollection,WxGimmick::OnPopUpOpenCollection) - EVT_MENU(PopUp_CloseCollection,WxGimmick::OnPopUpCloseCollection) - EVT_MENU(PopUp_DeleteCollection,WxGimmick::OnPopUpDeleteCollection) - EVT_MENU(PopUp_AddFile, WxGimmick::OnPopUpAddFile) - EVT_MENU(PopUp_AddRawFile, WxGimmick::OnPopUpAddRawFile) - EVT_MENU(PopUp_AddDirectory, WxGimmick::OnPopUpAddDirectory) - EVT_MENU(PopUp_Remove, WxGimmick::OnPopUpRemove) - EVT_MENU(PopUp_About, WxGimmick::OnPopUpAbout) - EVT_MENU(PopUp_Settings, WxGimmick::OnPopUpSettings) - - EVT_MENU_RANGE(PopUp_Sort, PopUp_Sort+99, WxGimmick::OnPopUpSort) - EVT_MENU_RANGE(PopUp_User, PopUp_User+99, WxGimmick::OnPopUpUser) - - - - // DRAG - EVT_TREE_BEGIN_DRAG(TreeListCtrlId, WxGimmick::OnBeginDrag) - EVT_TREE_BEGIN_RDRAG(TreeListCtrlId, WxGimmick::OnBeginRDrag) - EVT_TREE_END_DRAG(TreeListCtrlId, WxGimmick::OnEndDrag) - - // LABEL - EVT_TREE_BEGIN_LABEL_EDIT(TreeListCtrlId, WxGimmick::OnBeginLabelEdit) - EVT_TREE_END_LABEL_EDIT(TreeListCtrlId, WxGimmick::OnEndLabelEdit) - - //DELETE : UNUSED - EVT_TREE_DELETE_ITEM(TreeListCtrlId, WxGimmick::OnDeleteItem) -#if 0 // there are so many of those that logging them causes flicker - EVT_TREE_GET_INFO(TreeListCtrlId, WxGimmick::OnGetInfo) -#endif - // UNUSED - EVT_TREE_SET_INFO(TreeListCtrlId, WxGimmick::OnSetInfo) - - // EXPAND/COLLAPSE - EVT_TREE_ITEM_EXPANDED(TreeListCtrlId, WxGimmick::OnItemExpanded) - EVT_TREE_ITEM_EXPANDING(TreeListCtrlId, WxGimmick::OnItemExpanding) - EVT_TREE_ITEM_COLLAPSED(TreeListCtrlId, WxGimmick::OnItemCollapsed) - EVT_TREE_ITEM_COLLAPSING(TreeListCtrlId, WxGimmick::OnItemCollapsing) - - // SELECTION - EVT_TREE_SEL_CHANGED(TreeListCtrlId, WxGimmick::OnSelChanged) - EVT_TREE_SEL_CHANGING(TreeListCtrlId, WxGimmick::OnSelChanging) - // KEY - EVT_TREE_KEY_DOWN(TreeListCtrlId, WxGimmick::OnTreeKeyDown) - // ACTIVATION = DOUBLE CLICK OR ENTER ON SELECTED - EVT_TREE_ITEM_ACTIVATED(TreeListCtrlId, WxGimmick::OnItemActivated) - - // so many differents ways to handle right mouse button clicks... - // EVT_CONTEXT_MENU(WxGimmick::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(TreeListCtrlId, WxGimmick::OnItemMenu) - - EVT_TREE_ITEM_RIGHT_CLICK(TreeListCtrlId, WxGimmick::OnItemRightClick) - - // UNUSED - // EVT_RIGHT_DOWN(WxGimmick::OnRMouseDown) - // EVT_RIGHT_UP(WxGimmick::OnRMouseUp) - // EVT_RIGHT_DCLICK(WxGimmick::OnRMouseDClick) - END_EVENT_TABLE() - - //IMPLEMENT_DYNAMIC_CLASS(WxGimmick, wxTreeListCtrl) - - /* - wxTree::wxTree(wxWindow *parent, const wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style) - : wxTreeListCtrl(parent, id, pos, size, style) - { - m_reverseSort = false; - - CreateImageList(); - - // Add some items to the tree - AddTestItemsToTree(5, 2); - } - */ - - - -#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) - void WxGimmick::CreateButtonsImageList(int size) - { - /* - if ( size == -1 ) - { - mTreeListCtrl->SetButtonsImageList(NULL); - return; - } - - // Make an image list containing small icons - wxImageList *images = new wxImageList(size, size, true); - - // should correspond to TreeListCtrlIcon_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))); - } - } - - mTreeListCtrl->AssignButtonsImageList(images); - */ -#else - void WxGimmick::CreateButtonsImageList(int WXUNUSED(size)) - { -#endif - } - - /* - int WxGimmick::OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2) - { - if ( m_reverseSort ) - { - // just exchange 1st and 2nd items - return mTreeListCtrl->OnCompareItems(item2, item1); - } - else - { - return mTreeListCtrl->OnCompareItems(item1, item2); - } - } - - - void WxGimmick::DoToggleIcon(const wxTreeItemId& item) - { - - int image = (mTreeListCtrl->GetItemImage(item) == TreeIcon_Folder) - ? TreeIcon_File - : TreeIcon_Folder; - mTreeListCtrl->SetItemImage(item, image, wxTreeItemIcon_Normal); - - image = (mTreeListCtrl->GetItemImage(item) == TreeIcon_FolderSelected) - ? TreeIcon_FileSelected - : TreeIcon_FolderSelected; - mTreeListCtrl->SetItemImage(item, image, wxTreeItemIcon_Selected); - } - - void WxGimmick::LogEvent(const wxChar *name, const wxTreeEvent& event) - { - wxTreeItemId item = event.GetItem(); - wxString text; - if ( item.IsOk() ) - text << _T('"') << mTreeListCtrl->GetItemText(item).c_str() << _T('"'); - else - text = _T("invalid item"); - // wxLogMessage(wxT("%s(%s)"), name, text.c_str()); - } - - */ - // avoid repetition -#define TREE_EVENT_HANDLER(name) \ - void WxGimmick::name(wxTreeEvent& event) \ - { \ - /* LogEvent(_T(#name), event); */ \ - /* SetLastItem(mTreeListCtrl->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) - - - void WxGimmick::OnItemCollapsed(wxTreeEvent& event) - { - // std::cout << "* Collapsed *"<GetSelection(); - if (itemId.IsOk()) - { - std::cout << "item is ok"<GetItemData(id); - // std::cout << "OnBeginDrag("<IsDatabase()) - { - // std::cout << "-- IS ROOT"<IsDicomNode()) - { - // std::cout << "-- IS NODE"<GetItemData(id); - if (data->IsDatabase()) - { - // std::cout << "-- IS ROOT"<IsDicomNode()) - { - // std::cout << "-- IS NODE"<GetItemData(id); - // If not a root : veto - if (data->IsDatabase()) - { - event.Allow(); - return; - } - event.Veto(); - } - //==================================================================== - - //==================================================================== - void WxGimmick::OnEndLabelEdit(wxTreeEvent& event) - { - // std::cout << "OnEndLabelEdit"<IsDatabase()) - { - data->GetDicomNode()->GetDicomDatabase()->SetName(wx2std(event.GetLabel())); - mFieldsView->UpdateValues(data->GetDicomNode()); - } - else - { - std::cerr<< "!!!! Internal error : send bug report !!!!"<CenterOnParent(); - mHelpWindow->ShowModal(); - */ - } - //==================================================================== - - - - - - //================================================================ - //================================================================ - //================================================================ - //================================================================ - //================================================================ - // WxGimmickEvent - //================================================================ - //================================================================ - //================================================================ - //================================================================ - //================================================================ - - - - - - // ---------------------------------------------------------------------------- - // events - // ---------------------------------------------------------------------------- - /* - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_BEGIN_DRAG) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_BEGIN_RDRAG) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_DELETE_ITEM) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_GET_INFO) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_SET_INFO) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_EXPANDED) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_EXPANDING) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_COLLAPSED) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_COLLAPSING) - */ - - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_END_LABEL_EDIT) - - - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGED) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_SEL_CHANGING) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_KEY_DOWN) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_CONTEXTUAL_MENU) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREEVIEWLIST_ITEM_STYLE_CHANGED) - /* - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_ACTIVATED) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_END_DRAG) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_MENU) - */ - // ---------------------------------------------------------------------------- - // Tree event - // ---------------------------------------------------------------------------- - - IMPLEMENT_ABSTRACT_CLASS(WxGimmickEvent, wxNotifyEvent) - - - WxGimmickEvent::WxGimmickEvent(wxEventType commandType, - WxGimmick *tree, - const wxTreeItemId& item) - : - wxNotifyEvent(commandType, tree->GetId()), - m_item(item), - mDicomNode(0) - { - // m_editCancelled = false; - - SetEventObject(tree); - - if ( item.IsOk() ) - SetClientObject(tree->mTreeListCtrl->GetItemData(item)); - } - - WxGimmickEvent::WxGimmickEvent(wxEventType commandType, int id) - : - wxNotifyEvent(commandType, id), - mDicomNode(0) - { - m_itemOld = 0l; - // m_editCancelled = false; - } - - WxGimmickEvent::WxGimmickEvent(const WxGimmickEvent & event) - : - wxNotifyEvent(event), - mDicomNode(0) - - { - m_evtKey = event.m_evtKey; - m_item = event.m_item; - m_itemOld = event.m_itemOld; - mColor = event.mColor; - mUserData = event.mUserData; - // m_pointDrag = event.m_pointDrag; - // m_label = event.m_label; - // m_editCancelled = event.m_editCancelled; - } - - - - - - - - - //================================================================ - //================================================================ - //================================================================ - //================================================================ - //================================================================ - WxGimmickFrame::WxGimmickFrame( wxWindow *parent, - wxString title, - wxSize size) - : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size) - { - wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); - mWxGimmick = new WxGimmick(this,-1, - wxDefaultPosition, - wxDefaultSize); - sizer->Add(mWxGimmick,1,wxGROW); - SetSizer(sizer); - SetAutoLayout(true); - Layout(); - } - //================================================================ - - //================================================================ - WxGimmickFrame::~WxGimmickFrame() - { - } - //================================================================ - - //================================================================ - void WxGimmickFrame::OnSelChanged(WxGimmickEvent& event) - { - // std::cout << "+++++ WxGimmickFrame::OnSelChanged ++++++++++" - // < file; - // mWxGimmick->GetSelectedImages(file); - /* - std::vector::iterator i; - for (i=file.begin();i!=file.end();++i) - { - std::cout << "'" << *i << "'" << std::endl; - } - std::cout << "++++++++++++++++++++" << std::endl; - */ - } - //================================================================ - - //================================================================ - BEGIN_EVENT_TABLE(WxGimmickFrame, wxFrame) - EVT_TREEVIEWLIST_SEL_CHANGED(-1,WxGimmickFrame::OnSelChanged) - END_EVENT_TABLE() - //================================================================ - - - - - - - - - - - - - - - - - - - - - - - - - - - }