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