X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FcreaImageIOWxGimmick.cpp;h=3ad5e81280ede7cdd930ffcaab3ae209e648a723;hb=26963d13f31f98807176a062b1d2c209df9c7869;hp=7bfed5b624ed7a85adf498ebb648410652db836e;hpb=684add23b4f64cb3c6e39e12a4af20d2c2500df6;p=creaImageIO.git diff --git a/src/creaImageIOWxGimmick.cpp b/src/creaImageIOWxGimmick.cpp index 7bfed5b..3ad5e81 100644 --- a/src/creaImageIOWxGimmick.cpp +++ b/src/creaImageIOWxGimmick.cpp @@ -19,7 +19,8 @@ #include #include -#include +#include +//#include using namespace crea; @@ -209,18 +210,6 @@ namespace creaImageIO - //================================================================ - class WxGimmickSettingsDialog : public wxDialog - { - public: - WxGimmickSettingsDialog(wxWindow *parent); - ~WxGimmickSettingsDialog(); - - - }; - //================================================================ - - @@ -255,14 +244,26 @@ namespace creaImageIO //================================================================ //================================================================ WxGimmick::WxGimmick(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - int threads) + 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(); @@ -333,9 +334,15 @@ namespace creaImageIO // 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(mSplitter2,-1, + mFieldsView = new WxGimmickFieldsView(mwxNotebook,-1, wxDefaultPosition, wxDefaultSize,0); @@ -350,16 +357,20 @@ namespace creaImageIO 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, mFieldsView, + mSplitter2->SplitHorizontally( mPanelImage, mwxNotebook, //mFieldsView, hsize - previewhsize); rsizer->Add( mSplitter2,1,wxGROW ,0); @@ -369,7 +380,7 @@ namespace creaImageIO rpanel->Layout(); // previewer - mInteractor = new wxVTKRenderWindowInteractor(mPanelImage,-1); + mInteractor = new crea::creawxVTKRenderWindowInteractor(mPanelImage,-1); mInteractor->UseCaptureMouseOn(); mViewer = vtkImageViewer2::New(); @@ -399,6 +410,16 @@ namespace creaImageIO ShowImage(mReader.GetImage("")); + // Show help if no collection + if (GetDicomDatabaseList().size()==0) + { + mwxNotebook->SetSelection(1); + } + else + { + mwxNotebook->SetSelection(0); + } + // mJustStarted = true; } //================================================================ @@ -847,6 +868,9 @@ namespace creaImageIO 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 ") @@ -854,8 +878,10 @@ namespace creaImageIO _T("Error"), wxOK,this); return; + } + */ } } @@ -891,9 +917,11 @@ namespace creaImageIO } } + if (GetDicomDatabaseList().size()==0) mFieldsView->UpdateFields(db); GetDicomDatabaseList().push_back(db); UpdateDicomDatabaseView(db); + } //================================================================ @@ -904,7 +932,8 @@ namespace creaImageIO wxBusyCursor busy; // std::cout << "WxGimmick : Reading config"< Loading collections from '"< Loading collections from '"< 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)."); } @@ -1023,6 +1052,54 @@ namespace creaImageIO } //================================================================ + //================================================================ + 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) { @@ -1033,7 +1110,10 @@ namespace creaImageIO wxBusyCursor busy; wxTreeItemId itemId = event.GetItem(); - + LoadChildren(itemId); + + return; + // expand if collapsed and collapse if expanded ... TreeItemData *item = (TreeItemData *)mTreeListCtrl->GetItemData(itemId); @@ -1230,8 +1310,9 @@ namespace creaImageIO } if (data->IsDicomNode()) { - /* + // LG : BUGGY + /* std::string str("&Remove "); str += data->GetDicomNode()->GetTypeName(); menu.Append(PopUp_Remove, std2wx(str)); @@ -1366,7 +1447,7 @@ namespace creaImageIO // Pop up menu callbacks void WxGimmick::OnPopUpAbout(wxCommandEvent& event) { - wxMessageBox( _T("Give me my medical images quick ! \n\n (c) CREATIS-LRMN 2008\n"), + wxMessageBox( _T("Give me my medical images quick ! \n\n (c) CREATIS-LRMN 2008\n laurent.guigues@creatis.insa-lyon.fr"), _T("Gimmick!"), wxOK | wxICON_INFORMATION, this); } @@ -1376,7 +1457,7 @@ namespace creaImageIO void WxGimmick::OnPopUpSettings(wxCommandEvent& event) { WxGimmickSettingsDialog* s = - new WxGimmickSettingsDialog(this); + new WxGimmickSettingsDialog(this,&mSettings); s->ShowModal(); delete s; } @@ -1725,25 +1806,111 @@ namespace creaImageIO } //================================================= + + + + + + + + //================================================================ + 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 << "ERROR : ID NOT OK"<GetItemData(id); - event.Veto(); + TreeItemData *data = (TreeItemData *)mTreeListCtrl->GetItemData(id); if (data->IsDicomNode()) { - if ((data->GetDicomNode()>0)&& - ( data->GetDicomNode()->GetType()==DicomNode::Image)) + if (data->GetDicomNode()>0) { - event.Allow(); + // 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(); + } } } } @@ -1817,9 +1984,9 @@ namespace creaImageIO // << nsib->GetFieldValue("FullFileName") // << "' prio="<GetFieldValue("FullFileName"), + nsib->ImageGetFullFileName(), prio); - mImageFileNameToNode[nsib->GetFieldValue("FullFileName")] = + mImageFileNameToNode[nsib->ImageGetFullFileName()] = nsib; prio--; } @@ -1836,9 +2003,9 @@ namespace creaImageIO // << nsib->GetFieldValue("FullFileName") // << "' prio="<GetFieldValue("FullFileName"), + nsib->ImageGetFullFileName(), prio); - mImageFileNameToNode[nsib->GetFieldValue("FullFileName")] = + mImageFileNameToNode[nsib->ImageGetFullFileName()] = nsib; prio--; } @@ -1995,13 +2162,29 @@ namespace creaImageIO 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::GetSelectedImages(std::vector& f) + void WxGimmick::GetSelectedFiles(std::vector& f) { wxArrayTreeItemIds id; // TO DO : TEST THAT STYLE IS MULTIPLE @@ -2015,7 +2198,7 @@ namespace creaImageIO { if (data->GetDicomNode()->GetType()==DicomNode::Image) { - f.push_back ( data->GetDicomNode()->GetFieldValue("FullFileName") ); + f.push_back ( data->GetDicomNode()->ImageGetFullFileName() ); } else if (data->GetDicomNode()->GetType()==DicomNode::Series) { @@ -2024,7 +2207,7 @@ namespace creaImageIO j!=data->GetDicomNode()->GetChildrenList().end(); j++) { - f.push_back((*j)->GetFieldValue("FullFileName")); + f.push_back((*j)->ImageGetFullFileName()); } } } @@ -2032,6 +2215,122 @@ namespace creaImageIO } //================================================================ + //================================================================ + 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 ? + + 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) @@ -2052,7 +2351,7 @@ namespace creaImageIO if (data->GetDicomNode()->GetType()==DicomNode::Image) { - f.push_back ( data->GetDicomNode() ); //->GetFieldValue("FullFileName") ); + f.push_back ( data->GetDicomNode() ); //->ImageGetFullFileName() ); } else if (data->GetDicomNode()->GetType()==DicomNode::Series) { @@ -2061,8 +2360,7 @@ namespace creaImageIO j!=data->GetDicomNode()->GetChildrenList().end(); j++) { - f.push_back((*j)); //->GetFieldValue("FullFileName")); - } + f.push_back((*j)); //->ImageGetFullFileName() ); } } } */ @@ -2477,10 +2775,19 @@ namespace creaImageIO } - - - - + //==================================================================== + void WxGimmick::ShowHelp() + { + /* + if (mHelpWindow==0) + { + mHelpWindow = new WxGimmickHelpWindow(this); + } + mHelpWindow->CenterOnParent(); + mHelpWindow->ShowModal(); + */ + } + //==================================================================== @@ -2596,17 +2903,14 @@ namespace creaImageIO //================================================================ //================================================================ WxGimmickFrame::WxGimmickFrame( wxWindow *parent, - wxString title, - wxSize size) + wxString title, + wxSize size) : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size) { wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); - long style = wxTR_DEFAULT_STYLE | -#ifndef NO_VARIABLE_HEIGHT - wxTR_HAS_VARIABLE_ROW_HEIGHT | -#endif - wxTR_EDIT_LABELS | wxSUNKEN_BORDER; - mWxGimmick = new WxGimmick(this,-1,wxDefaultPosition,wxDefaultSize,style); + mWxGimmick = new WxGimmick(this,-1, + wxDefaultPosition, + wxDefaultSize); sizer->Add(mWxGimmick,1,wxGROW); SetSizer(sizer); SetAutoLayout(true); @@ -2665,38 +2969,7 @@ namespace creaImageIO - //================================================================ - //================================================================ - //================================================================ - //================================================================ - - //================================================================ - WxGimmickSettingsDialog::WxGimmickSettingsDialog(wxWindow *parent) - : - wxDialog( parent, - -1, - _T("Settings"), - wxDefaultPosition, - wxSize(400,400), - wxRESIZE_BORDER | - wxSYSTEM_MENU | - wxCLOSE_BOX | - wxMAXIMIZE_BOX | - wxMINIMIZE_BOX | - wxCAPTION - ) - { - } - //================================================================ - - //================================================================ - WxGimmickSettingsDialog::~WxGimmickSettingsDialog() - { - } - //================================================================ - - - +