Medical Imaging Interaction Toolkit  2018.4.99-c7ee88da
Medical Imaging Interaction Toolkit
QmitkPythonVariableStackTableModel.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include <QMimeData>
15 #include <usModuleContext.h>
16 #include <mitkDataNode.h>
17 #include <usGetModuleContext.h>
18 #include <QStringList>
19 #include <QMessageBox>
20 #include "QmitkMimeTypes.h"
21 
24 
26  :QAbstractTableModel(parent)
27 {
28  us::ModuleContext* context = us::GetModuleContext();
29  m_PythonServiceRef = context->GetServiceReference<mitk::IPythonService>();
30  m_PythonService = context->GetService<mitk::IPythonService>(m_PythonServiceRef);
31  m_PythonService->AddPythonCommandObserver( this );
32 }
33 
35 {
36  us::ModuleContext* context = us::GetModuleContext();
37  context->UngetService( m_PythonServiceRef );
38  m_PythonService->RemovePythonCommandObserver( this );
39 }
40 
41 bool QmitkPythonVariableStackTableModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int, int, const QModelIndex &)
42 {
43  // Early exit, returning true, but not actually doing anything (ignoring data).
44  if (action == Qt::IgnoreAction)
45  return true;
46 
47  // Note, we are returning true if we handled it, and false otherwise
48  bool returnValue = false;
49 
50  if(data->hasFormat(QmitkMimeTypes::DataNodePtrs))
51  {
52  MITK_DEBUG("QmitkPythonVariableStackTableModel") << "dropped MITK DataNode";
53  returnValue = true;
54 
55  int i = 0;
56  QList<mitk::DataNode*> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
57  mitk::DataNode* node = nullptr;
58  foreach(node, dataNodeList)
59  {
60  mitk::Image* mitkImage = dynamic_cast<mitk::Image*>(node->GetData());
61  MITK_DEBUG("QmitkPythonVariableStackTableModel") << "mitkImage is not null " << (mitkImage != nullptr? "true": "false");
62 
63  QRegExp rx("^\\d");
64  QString varName(node->GetName().c_str());
65  // regex replace every character that is not allowed in a python variable
66  varName = varName.replace(QRegExp("[.\\+\\-*\\s\\/\\n\\t\\r]"),QString("_"));
67 
68  if( mitkImage )
69  {
70  if ( varName.isEmpty() )
71  varName = MITK_IMAGE_VAR_NAME;
72  if ( rx.indexIn(varName) == 0)
73  varName.prepend("_").prepend(MITK_IMAGE_VAR_NAME);
74 
75  if( i > 0 )
76  varName = QString("%1%2").arg(varName).arg(i);
77  MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString();
78 
79  bool exportAsCvImage = mitkImage->GetDimension() == 2 && m_PythonService->IsOpenCvPythonWrappingAvailable();
80 
81  if( exportAsCvImage )
82  {
83  int ret = QMessageBox::question(nullptr, "Export option",
84  "2D image detected. Export as OpenCV image to Python instead of an SimpleITK image?",
85  QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
86  exportAsCvImage = ret == QMessageBox::Yes;
87  if(exportAsCvImage)
88  {
89  m_PythonService->CopyToPythonAsCvImage( mitkImage, varName.toStdString() );
90  ++i;
91  }
92  }
93  if( !exportAsCvImage )
94  {
95  if( m_PythonService->IsSimpleItkPythonWrappingAvailable() )
96  {
97  m_PythonService->CopyToPythonAsSimpleItkImage( mitkImage, varName.toStdString() );
98  ++i;
99  }
100  else
101  {
102  MITK_ERROR << "SimpleITK Python wrapping not available. Skipping export for image " << node->GetName();
103  }
104  }
105  }
106  else
107  {
108  mitk::Surface* surface = dynamic_cast<mitk::Surface*>(node->GetData());
109  MITK_DEBUG("QmitkPythonVariableStackTableModel") << "found surface";
110 
111  if( surface )
112  {
113  if (varName.isEmpty() )
114  varName = MITK_SURFACE_VAR_NAME;
115  if ( rx.indexIn(varName) == 0)
116  varName.prepend("_").prepend(MITK_SURFACE_VAR_NAME);
117 
118  MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName;
119 
120  if( m_PythonService->IsVtkPythonWrappingAvailable() )
121  {
122  m_PythonService->CopyToPythonAsVtkPolyData( surface, varName.toStdString() );
123  }
124  else
125  {
126  MITK_ERROR << "VTK Python wrapping not available. Skipping export for surface " << node->GetName();
127  }
128  }
129  }
130  }
131  }
132  return returnValue;
133 }
134 
135 QVariant QmitkPythonVariableStackTableModel::headerData(int section, Qt::Orientation orientation,
136  int role) const
137 {
138  QVariant headerData;
139 
140  // show only horizontal header
141  if ( role == Qt::DisplayRole )
142  {
143  if( orientation == Qt::Horizontal )
144  {
145  // first column: "Attribute"
146  if(section == 0)
147  headerData = "Attribute";
148  else if(section == 1)
149  headerData = "Type";
150  else if(section == 2)
151  headerData = "Value";
152  }
153  }
154 
155  return headerData;
156 }
157 
158 Qt::ItemFlags QmitkPythonVariableStackTableModel::flags(const QModelIndex &index) const
159 {
160  Qt::ItemFlags flags = QAbstractItemModel::flags(index);
161 
162  if(index.isValid())
163  return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | flags;
164  else
165  return Qt::ItemIsDropEnabled | flags;
166 }
167 
168 int QmitkPythonVariableStackTableModel::rowCount(const QModelIndex &) const
169 {
170  return m_VariableStack.size();
171 }
172 
174 {
175  return 3;
176 }
177 
178 QVariant QmitkPythonVariableStackTableModel::data(const QModelIndex &index, int role) const
179 {
180  if (index.isValid() && !m_VariableStack.empty())
181  {
182  if(role == Qt::DisplayRole)
183  {
184  mitk::PythonVariable item = m_VariableStack.at(index.row());
185  if(index.column() == 0)
186  return QString::fromStdString(item.m_Name);
187  if(index.column() == 1)
188  return QString::fromStdString(item.m_Type);
189  if(index.column() == 2)
190  return QString::fromStdString(item.m_Value);
191  }
192  }
193  return QVariant();
194 }
195 
197 {
198  return QAbstractTableModel::mimeTypes();
199  QStringList types;
200  types << "application/x-mitk-datanodes";
201  types << "application/x-qabstractitemmodeldatalist";
202  return types;
203 }
204 
206 {
207  return Qt::CopyAction | Qt::MoveAction;
208 }
209 
210 void QmitkPythonVariableStackTableModel::CommandExecuted(const std::string& pythonCommand)
211 {
212  MITK_DEBUG("QmitkPythonVariableStackTableModel") << "command was executed " << pythonCommand;
213  m_VariableStack = m_PythonService->GetVariableStack();
214  QAbstractTableModel::beginResetModel();
215  QAbstractTableModel::endResetModel();
216 }
217 
218 std::vector<mitk::PythonVariable> QmitkPythonVariableStackTableModel::GetVariableStack() const
219 {
220  return m_VariableStack;
221 }
void CommandExecuted(const std::string &pythonCommand) override
virtual bool CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &varName)=0
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:28
virtual void AddPythonCommandObserver(PythonCommandObserver *observer)=0
adds a command observer which is informed after a command was issued with "Execute" ...
Qt::ItemFlags flags(const QModelIndex &index) const override
#define MITK_ERROR
Definition: mitkLogMacros.h:20
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
static QList< mitk::DataNode * > ToDataNodePtrList(const QByteArray &ba)
virtual bool IsVtkPythonWrappingAvailable()=0
static const QString DataNodePtrs
bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &) override
virtual bool IsOpenCvPythonWrappingAvailable()=0
virtual void RemovePythonCommandObserver(PythonCommandObserver *observer)=0
removes a specific command observer
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:106
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Image class for storing images.
Definition: mitkImage.h:72
virtual std::vector< PythonVariable > GetVariableStack() const =0
virtual bool IsSimpleItkPythonWrappingAvailable()=0
int columnCount(const QModelIndex &parent=QModelIndex()) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
std::vector< mitk::PythonVariable > GetVariableStack() const
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
virtual bool CopyToPythonAsCvImage(mitk::Image *image, const std::string &varName)=0
bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="name") const
Convenience access method for accessing the name of an object (instance of StringProperty with proper...
Definition: mitkDataNode.h:368
virtual bool CopyToPythonAsVtkPolyData(mitk::Surface *surface, const std::string &varName)=0
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override