diff --git a/Plugins/org.mitk.gui.qt.python/files.cmake b/Plugins/org.mitk.gui.qt.python/files.cmake index eb74829c26..9e80499580 100644 --- a/Plugins/org.mitk.gui.qt.python/files.cmake +++ b/Plugins/org.mitk.gui.qt.python/files.cmake @@ -1,33 +1,35 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkPythonView.cpp QmitkCtkPythonShell.cpp + QmitkPythonVariableStackTableModel.cpp ) set(MOC_H_FILES src/internal/QmitkPythonView.h src/internal/QmitkCtkPythonShell.h src/internal/mitkPluginActivator.h + src/internal/QmitkPythonVariableStackTableModel.h ) set(CPP_FILES ) set(CACHED_RESOURCE_FILES plugin.xml resources/Python.png ) set(QRC_FILES resources/Python.qrc ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.cpp b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.cpp index 7d280792db..76b899e2f9 100644 --- a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.cpp +++ b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.cpp @@ -1,69 +1,71 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkCtkPythonShell.h" #include #include #include #include #include struct QmitkCtkPythonShellData { ctkAbstractPythonManager *m_PythonManager; }; QmitkCtkPythonShell::QmitkCtkPythonShell(QWidget* parent) : ctkPythonConsole(parent), d( new QmitkCtkPythonShellData ) { d->m_PythonManager = 0; } QmitkCtkPythonShell::~QmitkCtkPythonShell() { delete d; } void QmitkCtkPythonShell::SetPythonManager(ctkAbstractPythonManager *_PythonManager) { d->m_PythonManager = _PythonManager; this->initialize( _PythonManager ); } void QmitkCtkPythonShell::dragEnterEvent(QDragEnterEvent *event) { event->accept(); } void QmitkCtkPythonShell::dropEvent(QDropEvent *event) { QList urls = event->mimeData()->urls(); for(int i = 0; i < urls.size(); i++) { d->m_PythonManager->executeString(urls[i].toString()); } } bool QmitkCtkPythonShell::canInsertFromMimeData( const QMimeData *source ) const { return true; } void QmitkCtkPythonShell::executeCommand(const QString& command) { emit executeCommandSignal(command); ctkPythonConsole::executeCommand(command); + + emit newCommandExecuted(); } diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.h b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.h index 8333b5ea0f..9eed7b5f34 100644 --- a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.h +++ b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkCtkPythonShell.h @@ -1,62 +1,63 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkCtkPythonShell_h #define QmitkCtkPythonShell_h #include #include /// /// forward declarations /// struct QmitkCtkPythonShellData; class ctkAbstractPythonManager; class QDragEnterEvent; class QDropEvent; class QMimeData; /// /// Reimplements the ctkPythonConsole with drag and drop functionality for text /// class QmitkCtkPythonShell : public ctkPythonConsole { Q_OBJECT public: QmitkCtkPythonShell(QWidget* parent = 0); ~QmitkCtkPythonShell(); void SetPythonManager( ctkAbstractPythonManager* _PythonManager ); protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); bool canInsertFromMimeData( const QMimeData *source ) const; void executeCommand(const QString& command); signals: void executeCommandSignal(const QString&); + void newCommandExecuted(); private: QmitkCtkPythonShellData* d; }; #endif // QmitkCtkPythonShell_h diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonVariableStackTableModel.cpp b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonVariableStackTableModel.cpp new file mode 100755 index 0000000000..9b3845d5dc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonVariableStackTableModel.cpp @@ -0,0 +1,281 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkPythonVariableStackTableModel.h" + +QmitkPythonVariableStackTableModel::QmitkPythonVariableStackTableModel(QObject *parent) + :QAbstractTableModel(parent) +{ +} + +QmitkPythonVariableStackTableModel::~QmitkPythonVariableStackTableModel() +{ +} + +bool QmitkPythonVariableStackTableModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent ) +{ + /* + // Early exit, returning true, but not actually doing anything (ignoring data). + if (action == Qt::IgnoreAction) + return true; + + // Note, we are returning true if we handled it, and false otherwise + bool returnValue = false; + + if(data->hasFormat("application/x-mitk-datanodes")) + { + returnValue = true; + + QString arg = QString(data->data("application/x-mitk-datanodes").data()); + QStringList listOfDataNodeAddressPointers = arg.split(","); + + QStringList::iterator slIter; + for (slIter = listOfDataNodeAddressPointers.begin(); + slIter != listOfDataNodeAddressPointers.end(); + slIter++) + { + long val = (*slIter).toLong(); + mitk::DataNode* node = static_cast((void*)val); + + itk::SmartPointer * resultptr; + resultptr = new itk::SmartPointer((itk::SmartPointer &)node); + + if(resultptr) + { + int i = 0; + while(swig_types_initial[i] != 0) + { + if(swig_types_initial[i] == _swigt__p_itk__SmartPointerTmitk__DataNode_t) + SWIGTYPE_p_itk__SmartPointerTmitk__DataNode_t = SWIG_TypeRegister(swig_types_initial[i]); + i++; + } + + PyObject * resultObj = SWIG_NewPointerObj((void*)(resultptr), SWIGTYPE_p_itk__SmartPointerTmitk__DataNode_t, 1); + PyObject* dict = PyImport_GetModuleDict(); + PyObject* object = PyDict_GetItemString(dict, "__main__"); + + if(object){ + Py_INCREF(object); + PyModule_AddObject(object, node->GetName().c_str(), resultObj); + } + setVariableStack(this->getAttributeList()); + } + } + + } + return returnValue; + */ +} + +QVariant QmitkPythonVariableStackTableModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + QVariant headerData; + + // show only horizontal header + if ( role == Qt::DisplayRole ) + { + if( orientation == Qt::Horizontal ) + { + // first column: "Attribute" + if(section == 0) + headerData = "Attribute"; + else if(section == 1) + headerData = "Value"; + else if(section == 2) + headerData = "Type"; + } + } + + return headerData; +} + +Qt::ItemFlags QmitkPythonVariableStackTableModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if(index.isValid()) + return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | flags; + else + return Qt::ItemIsDropEnabled | flags; +} + +int QmitkPythonVariableStackTableModel::rowCount(const QModelIndex &) const +{ + return m_VariableStack.size(); +} + +int QmitkPythonVariableStackTableModel::columnCount(const QModelIndex &) const +{ + return 3; +} + +QVariant QmitkPythonVariableStackTableModel::data(const QModelIndex &index, int role) const +{ + if (index.isValid() && !m_VariableStack.empty()) + { + if(role == Qt::DisplayRole) + { + QStringList item = m_VariableStack.at(index.row()); + if(index.column() == 0) + return item[0]; + if(index.column() == 1) + return item[1]; + if(index.column() == 2) + return item[2]; + } + } + return QVariant(); +} + +void QmitkPythonVariableStackTableModel::clear() +{ + m_VariableStack.clear(); + QAbstractTableModel::reset(); +} + +void QmitkPythonVariableStackTableModel::setVariableStack(QList varStack) +{ + m_VariableStack = varStack; + QAbstractTableModel::reset(); +} + +QMimeData * QmitkPythonVariableStackTableModel::mimeData(const QModelIndexList & indexes) const +{ + return QAbstractTableModel::mimeData(indexes); + + /* + QMimeData * ret = new QMimeData; + + QString dataNodeAddresses(""); + + for (int indexesCounter = 0; indexesCounter < indexes.size(); indexesCounter++) + { + QString name = m_VariableStack[indexes.at(indexesCounter).row()][0]; + QString type = m_VariableStack[indexes.at(indexesCounter).row()][2]; + + if(type != "DataNode_PointerPtr") + return NULL; + + mitk::DataNode* node; + itk::SmartPointer *arg; + + PyObject * obj = this->getPyObjectString(&name); + int i = 0; + while(swig_types_initial[i] != 0) + { + if(swig_types_initial[i] == _swigt__p_itk__SmartPointerTmitk__DataNode_t) + SWIGTYPE_p_itk__SmartPointerTmitk__DataNode_t = SWIG_TypeRegister(swig_types_initial[i]); + i++; + } + if ((SWIG_ConvertPtr(obj,(void **)(&arg),SWIGTYPE_p_itk__SmartPointerTmitk__DataNode_t, + SWIG_POINTER_EXCEPTION | 0)) == -1) return NULL; + + if(arg == NULL){ + return NULL; + } + try { + node = (mitk::DataNode *)((itk::SmartPointer const *)arg)->GetPointer(); + } + catch(std::exception &_e) { + { + std::cout << "Not a DataNode" << std::endl; + } + } + + long a = reinterpret_cast(node); + + if (dataNodeAddresses.size() != 0) + { + QTextStream(&dataNodeAddresses) << ","; + } + QTextStream(&dataNodeAddresses) << a; + + ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toAscii())); + } + + return ret; + */ +} + +QStringList QmitkPythonVariableStackTableModel::mimeTypes() const +{ + return QAbstractTableModel::mimeTypes(); + /* + QStringList types; + types << "application/x-mitk-datanodes"; + types << "application/x-qabstractitemmodeldatalist"; + return types; + */ +} + +Qt::DropActions QmitkPythonVariableStackTableModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +Qt::DropActions QmitkPythonVariableStackTableModel::supportedDragActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +void QmitkPythonVariableStackTableModel::Update() +{ +// std::cout << "QmitkPythonVariableStackTableModel::update()" << std::endl; + this->setVariableStack(this->getAttributeList()); +} + +QList QmitkPythonVariableStackTableModel::getAttributeList() +{ + PyObject* dict = PyImport_GetModuleDict(); + PyObject* object = PyDict_GetItemString(dict, "__main__"); + PyObject* dirMain = PyObject_Dir(object); + PyObject* tempObject; + QList variableStack; + + if(dirMain) + { + QString attr, attrValue, attrType; + variableStack.clear(); + for(int i = 0; iob_type->tp_name; + if(PyUnicode_Check(tempObject) || PyString_Check(tempObject)) + attrValue = PyString_AsString(tempObject); + else + attrValue = ""; + variableStack.push_back(QStringList() << attr << attrValue << attrType); + } + } + return variableStack; +} + +PyObject * QmitkPythonVariableStackTableModel::getPyObject(PyObject * object) +{ + PyObject* dict = PyImport_GetModuleDict(); + PyObject* main = PyDict_GetItemString(dict, "__main__"); + return PyObject_GetAttr(main, object); +} + +PyObject * QmitkPythonVariableStackTableModel::getPyObjectString(const QString &objectName) +{ + PyObject* dict = PyImport_GetModuleDict(); + PyObject* main = PyDict_GetItemString(dict, "__main__"); + return PyObject_GetAttrString(main, objectName.toLocal8Bit().data()); +} diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonVariableStackTableModel.h b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonVariableStackTableModel.h new file mode 100755 index 0000000000..6a35ef358f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonVariableStackTableModel.h @@ -0,0 +1,66 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkPythonVariableStackTableModel_h +#define QmitkPythonVariableStackTableModel_h + +#include +#include +#include +#include +#include +#include + +/// +/// implements a table model to show the variables of the Python "__main__" dictionary +/// furthermore implements dragging and dropping of datanodes (conversion from and to python) +/// +class QmitkPythonVariableStackTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + QmitkPythonVariableStackTableModel(QObject *parent = 0); + virtual ~QmitkPythonVariableStackTableModel(); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags( const QModelIndex& index ) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, + int role) const; + QStringList mimeTypes() const; + + void clear(); + void setVariableStack(QList); + QList getVariableStack(); + + QMimeData * mimeData(const QModelIndexList &) const; + bool dropMimeData ( const QMimeData *, Qt::DropAction, int, int, const QModelIndex & ); + Qt::DropActions supportedDropActions() const; + Qt::DropActions supportedDragActions() const; + +public slots: + void Update(); +protected: + QList getAttributeList(); + PyObject* getPyObject(PyObject* object); + PyObject* getPyObjectString(const QString& objectName); +private: + QList m_VariableStack; +}; + +#endif // QmitkPythonVariableStackTableModel_h diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonView.cpp b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonView.cpp index c2df3a7d65..5263f0dd8e 100644 --- a/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonView.cpp +++ b/Plugins/org.mitk.gui.qt.python/src/internal/QmitkPythonView.cpp @@ -1,54 +1,68 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkPythonView.h" #include #include "QmitkCtkPythonShell.h" #include "mitkPluginActivator.h" +#include "QmitkPythonVariableStackTableModel.h" const std::string QmitkPythonView::VIEW_ID = "org.mitk.views.python"; struct QmitkPythonViewData { // widget + QmitkPythonVariableStackTableModel* m_VariableStackTableModel; QmitkCtkPythonShell* m_PythonShell; }; QmitkPythonView::QmitkPythonView() : d( new QmitkPythonViewData ) { d->m_PythonShell = 0; } QmitkPythonView::~QmitkPythonView() { delete d; } void QmitkPythonView::CreateQtPartControl(QWidget* parent) { + d->m_VariableStackTableModel = new QmitkPythonVariableStackTableModel(parent); + d->m_VariableStackTableModel->Update(); + + QSplitter* splitter = new QSplitter; + QTableView* variableStackView = new QTableView; + variableStackView->setModel( d->m_VariableStackTableModel ); + d->m_PythonShell = new QmitkCtkPythonShell; d->m_PythonShell->SetPythonManager( mitk::PluginActivator::GetPythonManager() ); + splitter->addWidget(variableStackView); + splitter->addWidget(d->m_PythonShell); + QGridLayout* layout = new QGridLayout; - layout->addWidget( d->m_PythonShell, 0, 0 ); + layout->addWidget( splitter, 0, 0 ); parent->setLayout(layout); + + connect( d->m_PythonShell, SIGNAL(newCommandExecuted()), d->m_VariableStackTableModel, SLOT(Update()) ); } void QmitkPythonView::SetFocus() { d->m_PythonShell->setFocus(); }