diff --git a/Modules/AppUtil/src/mitkProvisioningInfo.cpp b/Modules/AppUtil/src/mitkProvisioningInfo.cpp index 7ccdb6c8ca..7b5990b3e7 100644 --- a/Modules/AppUtil/src/mitkProvisioningInfo.cpp +++ b/Modules/AppUtil/src/mitkProvisioningInfo.cpp @@ -1,206 +1,207 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkProvisioningInfo.h" #include #include #include #include +#include #include namespace mitk { #ifdef CMAKE_INTDIR const QString ProvisioningInfo::intermediateOutDir = QString(CMAKE_INTDIR); #else const QString ProvisioningInfo::intermediateOutDir = QString(); #endif ProvisioningInfo::ProvisioningInfo(const QString &file) { this->readProvisioningFile(file); } QStringList ProvisioningInfo::getPluginDirs() const { return pluginDirs.toList(); } QList ProvisioningInfo::getPluginsToInstall() const { return pluginsToInstall; } QList ProvisioningInfo::getPluginsToStart() const { return pluginsToStart; } void ProvisioningInfo::readProvisioningFile(const QString &filePath) { QFile file(filePath); file.open(QFile::ReadOnly); QTextStream fileStream(&file); - QRegExp sep("\\s+"); + QRegularExpression sep("\\s+"); QString line; int count = 1; do { line = fileStream.readLine().trimmed(); if (!line.isEmpty() && !line.startsWith('#')) { QString keyword = line.section(sep, 0, 0); QString value = line.mid(keyword.size()).trimmed(); value = substituteKeywords(value); if (keyword.isEmpty()) { MITK_WARN << "Keyword missing in line " << count << " of provisioning file " << filePath.toStdString(); continue; } Keyword key = UNKNOWN; if (keyword.compare("READ", Qt::CaseInsensitive) == 0) { key = READ; } else if (keyword.compare("INSTALL", Qt::CaseInsensitive) == 0) { key = INSTALL; } else if (keyword.compare("START", Qt::CaseInsensitive) == 0) { key = START; } else if (keyword.compare("STOP", Qt::CaseInsensitive) == 0) { key = STOP; } if (key == UNKNOWN) { MITK_WARN << "Keyword " << keyword.toStdString() << " in line " << count << " of provisioning file " << filePath.toStdString() << " unknown"; continue; } if (value.isEmpty()) { MITK_WARN << "Value after keyword " << keyword.toStdString() << " missing in line " << count << " of provisioning file " << filePath.toStdString(); continue; } switch (key) { case READ: { QUrl readFileUrl(value); if (!readFileUrl.isValid()) { MITK_WARN << "The READ URL " << value.toStdString() << "is invalid: " << readFileUrl.errorString().toStdString(); break; } this->readProvisioningFile(readFileUrl.toLocalFile()); break; } case INSTALL: { this->addPluginToInstall(value); break; } case START: { this->addPluginToStart(value); break; } case STOP: { break; } case UNKNOWN: { break; // error handled above } } } ++count; } while (!line.isNull()); } QUrl ProvisioningInfo::addPluginToInstall(const QString &file) { QUrl pluginUrl(file); if (!pluginUrl.isValid()) { MITK_WARN << "The plugin URL " << file.toStdString() << " is invalid:" << pluginUrl.errorString().toStdString(); return QUrl(); } QFileInfo fileInfo(pluginUrl.toLocalFile()); if (!fileInfo.exists()) { QString fileName = fileInfo.fileName(); QString filePath = fileInfo.absolutePath(); if (!intermediateOutDir.isEmpty()) { // search in the intermediate output dir QString filePath2 = filePath + "/" + intermediateOutDir; fileInfo = QFileInfo(filePath2 + "/" + fileName); if (!fileInfo.exists()) { MITK_WARN << "The plugin " << fileName.toStdString() << " was not found in " << filePath.toStdString() << " or " << filePath2.toStdString(); return QUrl(); } pluginUrl = QUrl::fromLocalFile(fileInfo.canonicalFilePath()); pluginDirs.insert(fileInfo.canonicalPath()); } else { MITK_WARN << "The plugin " << fileName.toStdString() << " was not found in " << filePath.toStdString(); return QUrl(); } } else { pluginDirs.insert(fileInfo.canonicalPath()); } pluginsToInstall.append(pluginUrl); return pluginUrl; } void ProvisioningInfo::addPluginToStart(const QString &file) { QUrl pluginUrl = this->addPluginToInstall(file); if (!pluginUrl.isEmpty()) { pluginsToStart.append(pluginUrl); } } QString ProvisioningInfo::substituteKeywords(const QString &value) const { QString appPath = QCoreApplication::applicationDirPath(); if (appPath.endsWith('/')) { appPath.chop(1); } #ifdef CMAKE_INTDIR // Strip the intermediate dir from the application path QString intDir(CMAKE_INTDIR); if (appPath.endsWith(intDir)) { appPath.chop(intDir.size() + 1); } #endif #ifdef _WIN32 if (value.contains("@EXECUTABLE_DIR") && value.contains("blueberry_osgi")) { // special case for org_blueberry_osgi in install trees for Windows return QString(value).replace("@EXECUTABLE_DIR", appPath, Qt::CaseInsensitive).replace("plugins/", ""); } #endif return QString(value).replace("@EXECUTABLE_DIR", appPath, Qt::CaseInsensitive); } } diff --git a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSetupConnectionWidget.cpp b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSetupConnectionWidget.cpp index 11cdc1a0c0..96431b93c8 100644 --- a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSetupConnectionWidget.cpp +++ b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSetupConnectionWidget.cpp @@ -1,436 +1,436 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkIGTLDeviceSetupConnectionWidget.h" //mitk headers #include #include #include #include //qt headers #include #include #include #include //igtl #include #include #include #include //poco headers #include -#include +#include const std::string QmitkIGTLDeviceSetupConnectionWidget::VIEW_ID = "org.mitk.views.igtldevicesetupconnectionwidget"; QmitkIGTLDeviceSetupConnectionWidget::QmitkIGTLDeviceSetupConnectionWidget( QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f), m_IsClient(false) { m_Controls = nullptr; this->m_IGTLDevice = nullptr; CreateQtPartControl(this); m_NumSentFramesSinceLastUpdate = 0; m_NumReceivedFramesSinceLastUpdate = 0; } QmitkIGTLDeviceSetupConnectionWidget::~QmitkIGTLDeviceSetupConnectionWidget() { this->RemoveObserver(); } void QmitkIGTLDeviceSetupConnectionWidget::RemoveObserver() { if (this->m_IGTLDevice.IsNotNull()) { this->m_IGTLDevice->RemoveObserver(m_MessageReceivedObserverTag); this->m_IGTLDevice->RemoveObserver(m_MessageSentObserverTag); this->m_IGTLDevice->RemoveObserver(m_CommandReceivedObserverTag); this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag); this->m_IGTLDevice->RemoveObserver(m_NewConnectionObserverTag); this->m_IGTLDevice->RemoveObserver(m_StateModifiedObserverTag); } } void QmitkIGTLDeviceSetupConnectionWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkIGTLDeviceSetupConnectionWidgetControls; // setup GUI widgets m_Controls->setupUi(parent); } // set the validator for the ip edit box (values must be between 0 and 255 and // there are four of them, seperated with a point - QRegExpValidator *v = new QRegExpValidator(this); - QRegExp rx("((1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})\\.){3,3}(1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})"); - v->setRegExp(rx); + auto v = new QRegularExpressionValidator(this); + QRegularExpression rx("((1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})\\.){3,3}(1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})"); + v->setRegularExpression(rx); m_Controls->editIP->setValidator(v); // set the validator for the port edit box (values must be between 1 and 65535) m_Controls->editPort->setValidator(new QIntValidator(1, 65535, this)); m_FPSCalculationTimer.start(1000); //connect slots with signals CreateConnections(); } void QmitkIGTLDeviceSetupConnectionWidget::CreateConnections() { if (m_Controls) { // connect the widget items with the methods connect(m_Controls->butConnect, SIGNAL(clicked()), this, SLOT(OnConnect())); connect(m_Controls->editPort, SIGNAL(editingFinished()), this, SLOT(OnPortChanged())); connect(m_Controls->editIP, SIGNAL(editingFinished()), this, SLOT(OnHostnameChanged())); connect(m_Controls->bufferInMsgCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnBufferIncomingMessages(int))); connect(m_Controls->bufferOutMsgCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnBufferOutgoingMessages(int))); connect(&m_FPSCalculationTimer, SIGNAL(timeout()), this, SLOT(OnUpdateFPSLabel())); connect(m_Controls->logMessageDetailsCheckBox, SIGNAL(clicked()), this, SLOT(OnLogMessageDetailsCheckBoxClicked())); } //this is used for thread seperation, otherwise the worker thread would change the ui elements //which would cause an exception connect(this, SIGNAL(AdaptGUIToStateSignal()), this, SLOT(AdaptGUIToState())); } void QmitkIGTLDeviceSetupConnectionWidget::OnDeviceStateChanged() { emit AdaptGUIToStateSignal(); } void QmitkIGTLDeviceSetupConnectionWidget::AdaptGUIToState() { //check the validity of the device if (this->m_IGTLDevice.IsNull()) { return; } //check the state of the device mitk::IGTLDevice::IGTLDeviceState state = this->m_IGTLDevice->GetState(); switch (state) { case mitk::IGTLDevice::Setup: if (!m_IsClient) { m_Controls->butConnect->setText("Go Online"); this->m_Controls->editIP->setEnabled(false); } else { m_Controls->butConnect->setText("Connect"); this->m_Controls->editIP->setEnabled(true); } this->m_Controls->editPort->setEnabled(true); this->m_Controls->logMessageStatusCheckBox->setChecked(false); this->m_Controls->logMessageDetailsCheckBox->setChecked(false); this->m_Controls->logMessageStatusCheckBox->setEnabled(false); this->m_Controls->logMessageDetailsCheckBox->setEnabled(false); this->m_Controls->bufferInMsgCheckBox->setEnabled(false); this->m_Controls->bufferOutMsgCheckBox->setEnabled(false); this->m_Controls->butConnect->setEnabled(true); this->m_Controls->fpsInLabel->setEnabled(false); this->m_Controls->fpsOutLabel->setEnabled(false); this->m_Controls->fpsInDescrLabel->setEnabled(false); this->m_Controls->fpsOutDescrLabel->setEnabled(false); if( this->m_IGTLDevice.IsNotNull() ) { this->m_IGTLDevice->SetLogMessages(false); } break; case mitk::IGTLDevice::Ready: if (m_IsClient) { this->m_Controls->butConnect->setText("Disconnect"); } else { this->m_Controls->butConnect->setText("Go Offline"); } this->m_Controls->editIP->setEnabled(false); this->m_Controls->editPort->setEnabled(false); this->m_Controls->logMessageStatusCheckBox->setEnabled(true); this->m_Controls->logMessageDetailsCheckBox->setEnabled(true); this->m_Controls->bufferInMsgCheckBox->setEnabled(true); this->m_Controls->bufferOutMsgCheckBox->setEnabled(true); this->m_Controls->butConnect->setEnabled(true); this->m_Controls->fpsInLabel->setEnabled(true); this->m_Controls->fpsOutLabel->setEnabled(true); this->m_Controls->fpsInDescrLabel->setEnabled(true); this->m_Controls->fpsOutDescrLabel->setEnabled(true); break; case mitk::IGTLDevice::Running: if (m_IsClient) { this->m_Controls->butConnect->setText("Disconnect"); } else { this->m_Controls->butConnect->setText("Go Offline"); } this->m_Controls->editIP->setEnabled(false); this->m_Controls->editPort->setEnabled(false); this->m_Controls->logMessageStatusCheckBox->setEnabled(true); this->m_Controls->logMessageDetailsCheckBox->setEnabled(true); this->m_Controls->bufferInMsgCheckBox->setEnabled(true); this->m_Controls->bufferOutMsgCheckBox->setEnabled(true); this->m_Controls->butConnect->setEnabled(true); this->m_Controls->fpsInLabel->setEnabled(true); this->m_Controls->fpsOutLabel->setEnabled(true); this->m_Controls->fpsInDescrLabel->setEnabled(true); this->m_Controls->fpsOutDescrLabel->setEnabled(true); break; default: mitkThrow() << "Invalid Device State"; break; } } void QmitkIGTLDeviceSetupConnectionWidget::Initialize( mitk::IGTLDevice::Pointer device) { //reset the GUI DisableSourceControls(); //reset the observers this->RemoveObserver(); if (device.IsNotNull()) { this->m_IGTLDevice = device; //check if the device is a server or a client if (dynamic_cast( this->m_IGTLDevice.GetPointer()) == nullptr) { m_IsClient = false; } else { m_IsClient = true; } this->AdaptGUIToState(); typedef itk::SimpleMemberCommand< QmitkIGTLDeviceSetupConnectionWidget > CurCommandType; CurCommandType::Pointer messageSentCommand = CurCommandType::New(); messageSentCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSetupConnectionWidget::OnMessageSent); this->m_MessageSentObserverTag = this->m_IGTLDevice->AddObserver( mitk::MessageSentEvent(), messageSentCommand); CurCommandType::Pointer messageReceivedCommand = CurCommandType::New(); messageReceivedCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSetupConnectionWidget::OnMessageReceived); this->m_MessageReceivedObserverTag = this->m_IGTLDevice->AddObserver( mitk::MessageReceivedEvent(), messageReceivedCommand); CurCommandType::Pointer commandReceivedCommand = CurCommandType::New(); commandReceivedCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSetupConnectionWidget::OnCommandReceived); this->m_CommandReceivedObserverTag = this->m_IGTLDevice->AddObserver( mitk::CommandReceivedEvent(), commandReceivedCommand); CurCommandType::Pointer connectionLostCommand = CurCommandType::New(); connectionLostCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSetupConnectionWidget::OnLostConnection); this->m_LostConnectionObserverTag = this->m_IGTLDevice->AddObserver( mitk::LostConnectionEvent(), connectionLostCommand); CurCommandType::Pointer newConnectionCommand = CurCommandType::New(); newConnectionCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSetupConnectionWidget::OnNewConnection); this->m_NewConnectionObserverTag = this->m_IGTLDevice->AddObserver( mitk::NewClientConnectionEvent(), newConnectionCommand); CurCommandType::Pointer stateModifiedCommand = CurCommandType::New(); stateModifiedCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSetupConnectionWidget::OnDeviceStateChanged); this->m_StateModifiedObserverTag = this->m_IGTLDevice->AddObserver( itk::ModifiedEvent(), stateModifiedCommand); OnBufferIncomingMessages(m_Controls->bufferInMsgCheckBox->isChecked()); OnBufferOutgoingMessages(m_Controls->bufferOutMsgCheckBox->isChecked()); } else { m_IGTLDevice = nullptr; } } void QmitkIGTLDeviceSetupConnectionWidget::DisableSourceControls() { m_Controls->editIP->setEnabled(false); m_Controls->editPort->setEnabled(false); m_Controls->butConnect->setEnabled(false); m_Controls->bufferInMsgCheckBox->setEnabled(false); m_Controls->bufferOutMsgCheckBox->setEnabled(false); this->m_Controls->logMessageStatusCheckBox->setChecked(false); this->m_Controls->logMessageDetailsCheckBox->setChecked(false); this->m_Controls->logMessageStatusCheckBox->setEnabled(false); this->m_Controls->logMessageDetailsCheckBox->setEnabled(false); if( this->m_IGTLDevice.IsNotNull() ) { this->m_IGTLDevice->SetLogMessages(false); } } void QmitkIGTLDeviceSetupConnectionWidget::OnConnect() { if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Setup) { QString port = m_Controls->editPort->text(); m_IGTLDevice->SetPortNumber(port.toInt()); std::string hostname = m_Controls->editIP->text().toStdString(); m_IGTLDevice->SetHostname(hostname); //connect with the other OpenIGTLink device => changes the state from Setup //to Ready if (m_IGTLDevice->OpenConnection()) { //starts the communication thread => changes the state from Ready to //Running if (m_IGTLDevice->StartCommunication()) { if (this->m_IsClient) { MITK_INFO("IGTLDeviceSourceManagementWidget") << "Successfully connected to " << hostname << " on port " << port.toStdString(); } } else { MITK_ERROR("QmitkIGTLDeviceSetupConnectionWidget") << "Could not start a communication with the" "server because the client is in the wrong state"; } } else { MITK_ERROR("QmitkIGTLDeviceSetupConnectionWidget") << "Could not connect to the server. " "Please check the hostname and port."; } } else if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready || m_IGTLDevice->GetState() == mitk::IGTLDevice::Running) { m_IGTLDevice->CloseConnection(); MITK_INFO("QmitkIGTLDeviceSetupConnectionWidget") << "Closed connection"; } else { mitkThrow() << "Invalid state of IGTLDevice"; } this->AdaptGUIToState(); } void QmitkIGTLDeviceSetupConnectionWidget::OnPortChanged() { } void QmitkIGTLDeviceSetupConnectionWidget::OnHostnameChanged() { } void QmitkIGTLDeviceSetupConnectionWidget::OnLostConnection() { emit AdaptGUIToStateSignal(); } void QmitkIGTLDeviceSetupConnectionWidget::OnNewConnection() { emit AdaptGUIToStateSignal(); } void QmitkIGTLDeviceSetupConnectionWidget::OnMessageReceived() { if( this->m_Controls->logMessageStatusCheckBox->isChecked() ) { MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Received a message."; } m_NumReceivedFramesSinceLastUpdate++; } void QmitkIGTLDeviceSetupConnectionWidget::OnMessageSent() { if( this->m_Controls->logMessageStatusCheckBox->isChecked() ) { MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Sent a message."; } m_NumSentFramesSinceLastUpdate++; } void QmitkIGTLDeviceSetupConnectionWidget::OnCommandReceived() { if( this->m_Controls->logMessageStatusCheckBox->isChecked() ) { MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Received a command."; } } void QmitkIGTLDeviceSetupConnectionWidget::OnBufferIncomingMessages(int state) { if (this->m_IGTLDevice.IsNotNull()) { this->m_IGTLDevice->EnableNoBufferingMode( this->m_IGTLDevice->GetMessageQueue(), (bool)state); } } void QmitkIGTLDeviceSetupConnectionWidget::OnBufferOutgoingMessages(int state) { if (this->m_IGTLDevice.IsNotNull()) { this->m_IGTLDevice->EnableNoBufferingMode( this->m_IGTLDevice->GetMessageQueue(), (bool)state); } } void QmitkIGTLDeviceSetupConnectionWidget::OnUpdateFPSLabel() { double fpsIn = m_NumReceivedFramesSinceLastUpdate / 1.0; double fpsOut = m_NumSentFramesSinceLastUpdate / 1.0; this->m_Controls->fpsInLabel->setText(QString::number(fpsIn)); this->m_Controls->fpsOutLabel->setText(QString::number(fpsOut)); m_NumReceivedFramesSinceLastUpdate = 0; m_NumSentFramesSinceLastUpdate = 0; } void QmitkIGTLDeviceSetupConnectionWidget::OnLogMessageDetailsCheckBoxClicked() { if( this->m_IGTLDevice.IsNull() ) { MITK_WARN << "Logging information not passed down to Message Provider."; return; } else { this->m_IGTLDevice->SetLogMessages( this->m_Controls->logMessageDetailsCheckBox->isChecked() ); } } diff --git a/Modules/XNAT/src/QmitkXnatTreeModel.cpp b/Modules/XNAT/src/QmitkXnatTreeModel.cpp index deb1309bc4..65fe4a215d 100644 --- a/Modules/XNAT/src/QmitkXnatTreeModel.cpp +++ b/Modules/XNAT/src/QmitkXnatTreeModel.cpp @@ -1,310 +1,321 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkXnatTreeModel.h" #include #include #include +#include #include #include #include #include #include #include #include #include #include #include #include QmitkXnatTreeModel::QmitkXnatTreeModel() : ctkXnatTreeModel() { } QModelIndexList QmitkXnatTreeModel::match( const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const { QModelIndexList result; - uint matchType = flags & 0x0F; - Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; + uint matchType = flags & Qt::MatchTypeMask; + Qt::CaseSensitivity cs = flags.testFlag(Qt::MatchCaseSensitive) + ? Qt::CaseSensitive + : Qt::CaseInsensitive; bool recurse = flags & Qt::MatchRecursive; bool wrap = flags & Qt::MatchWrap; bool allHits = (hits == -1); QString text; // only convert to a string if it is needed QModelIndex p = parent(start); int from = start.row(); int to = rowCount(p); // iterates twice if wrapping for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) { for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) { QModelIndex idx = index(r, start.column(), p); if (!idx.isValid()) continue; QVariant v = data(idx, role); // QVariant based matching if (matchType == Qt::MatchExactly) { if (value != v) result.append(idx); } else { // QString based matching if (text.isEmpty()) // lazy conversion text = value.toString(); QString t = v.toString(); switch (matchType) { - case Qt::MatchRegExp: - if (!QRegExp(text, cs).exactMatch(t)) + case Qt::MatchRegularExpression: + { + QRegularExpression::PatternOptions options; + options.setFlag(QRegularExpression::CaseInsensitiveOption, !flags.testFlag(Qt::MatchCaseSensitive)); + QRegularExpression regExp(QString("^%1$").arg(text), options); + if (!regExp.match(t).hasMatch()) result.append(idx); break; + } case Qt::MatchWildcard: - if (!QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t)) + { + auto regExp = QRegularExpression::fromWildcard(text, cs); + if (!regExp.match(t).hasMatch()) result.append(idx); break; + } case Qt::MatchStartsWith: if (!t.startsWith(text, cs)) result.append(idx); break; case Qt::MatchEndsWith: if (!t.endsWith(text, cs)) result.append(idx); break; case Qt::MatchFixedString: if (t.compare(text, cs) != 0) result.append(idx); break; case Qt::MatchContains: default: if (!t.contains(text, cs)) result.append(idx); } } if (recurse && hasChildren(idx)) { // search the hierarchy result += match(index(0, idx.column(), idx), role, (text.isEmpty() ? value : text), (allHits ? -1 : hits - result.count()), flags); } } // prepare for the next iteration from = 0; to = start.row(); } return result; } void QmitkXnatTreeModel::fetchMore(const QModelIndex &index) { try { ctkXnatTreeModel::fetchMore(index); } catch (const ctkRuntimeException& e) { QmitkHttpStatusCodeHandler::HandleErrorMessage(e.what()); emit Error(index); } } QVariant QmitkXnatTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } if (role == Qt::DecorationRole) { ctkXnatObject *xnatObject = this->xnatObject(index); QString path; if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-server.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-project.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-subject.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-experiment.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-folder.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-resource.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-folder.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-scan.png"; } else if (dynamic_cast(xnatObject)) { path = ":/xnat-module/xnat-file.png"; } return QIcon(path); } return ctkXnatTreeModel::data(index, role); } bool QmitkXnatTreeModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; // Return true if data can be handled bool returnVal(false); if (data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { returnVal = true; QList droppedNodes = QmitkMimeTypes::ToDataNodePtrList(data); ctkXnatObject *parentXnatObj = this->xnatObject(parent); emit ResourceDropped(droppedNodes, parentXnatObj, parent); } return returnVal; } Qt::DropActions QmitkXnatTreeModel::supportedDropActions() { return Qt::CopyAction; } Qt::ItemFlags QmitkXnatTreeModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = ctkXnatTreeModel::flags(index); if (index.isValid()) { bool droppingAllowed = dynamic_cast(this->xnatObject(index)) != nullptr; droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; // No dropping at project, session or data model level allowed if (droppingAllowed) { return Qt::ItemIsDropEnabled | defaultFlags; } else { return defaultFlags; } } else return defaultFlags; } ctkXnatObject *QmitkXnatTreeModel::InternalGetXnatObjectFromUrl(const QString &xnatObjectType, const QString &url, ctkXnatObject *parent) { // 1. Find project int start = url.lastIndexOf(xnatObjectType); if (start == -1) return nullptr; start += xnatObjectType.length(); parent->fetch(); QList children = parent->children(); foreach (ctkXnatObject *child, children) { if (url.indexOf(child->resourceUri()) != -1) { return child; } } return nullptr; } ctkXnatObject *QmitkXnatTreeModel::GetXnatObjectFromUrl(const QString &url) { QModelIndex index = this->index(0, 0, QModelIndex()); ctkXnatObject *currentXnatObject = nullptr; currentXnatObject = this->xnatObject(index); if (currentXnatObject != nullptr) { // 1. Find project ctkXnatObject *project = nullptr; project = this->InternalGetXnatObjectFromUrl("projects/", url, currentXnatObject); // 2. Find subject ctkXnatObject *subject = nullptr; if (project != nullptr) { currentXnatObject = project; subject = this->InternalGetXnatObjectFromUrl("subjects/", url, project); } // 3. Find experiment ctkXnatObject *experiment = nullptr; if (subject != nullptr) { currentXnatObject = subject; experiment = this->InternalGetXnatObjectFromUrl("experiments/", url, subject); } // 4. Find scan ctkXnatObject *scan = nullptr; if (experiment != nullptr) { currentXnatObject = experiment; scan = this->InternalGetXnatObjectFromUrl("scans/", url, experiment); } if (scan != nullptr) { scan->fetch(); QList scans = scan->children(); foreach (ctkXnatObject *child, scans) { if (url.indexOf(child->resourceUri()) != -1) { return child; } } } currentXnatObject->fetch(); QList bla = currentXnatObject->children(); foreach (ctkXnatObject *child, bla) { if (child->name() == "Resources") return child; } } return nullptr; } diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryConfigurationElement.cpp b/Plugins/org.blueberry.core.runtime/src/internal/berryConfigurationElement.cpp index 5b98a2a021..ce073e600e 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryConfigurationElement.cpp +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryConfigurationElement.cpp @@ -1,311 +1,311 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "berryConfigurationElement.h" #include "berryIExecutableExtension.h" #include "berryIExecutableExtensionFactory.h" #include "berryConfigurationElementHandle.h" #include "berryStatus.h" #include "berryRegistryMessages.h" #include "berryRegistryConstants.h" #include "berryCoreException.h" #include "berryExtensionRegistry.h" #include "berryRegistryObjectManager.h" #include "berryRegistryContributor.h" #include "berryObjectString.h" #include "berryObjectStringMap.h" -#include +#include namespace berry { ConfigurationElement::ConfigurationElement(ExtensionRegistry* registry, bool persist) : RegistryObject(registry, persist) { } ConfigurationElement::ConfigurationElement(int self, const QString& contributorId, const QString& name, const QList& propertiesAndValue, const QList& children, int extraDataOffset, int parent, short parentType, ExtensionRegistry* registry, bool persist) : RegistryObject(registry, persist), parentId(parent), parentType(parentType), propertiesAndValue(propertiesAndValue), name(name), contributorId(contributorId) { SetObjectId(self); SetRawChildren(children); SetExtraDataOffset(extraDataOffset); } void ConfigurationElement::ThrowException(const QString& message, const ctkException& exc) { IStatus::Pointer status(new Status(IStatus::ERROR_TYPE, RegistryMessages::OWNER_NAME, RegistryConstants::PLUGIN_ERROR, message, exc, BERRY_STATUS_LOC)); throw CoreException(status); } void ConfigurationElement::ThrowException(const QString &message) { IStatus::Pointer status(new Status(IStatus::ERROR_TYPE, RegistryMessages::OWNER_NAME, RegistryConstants::PLUGIN_ERROR, message, BERRY_STATUS_LOC)); throw CoreException(status); } QString ConfigurationElement::GetValue() const { return GetValueAsIs(); } QString ConfigurationElement::GetValueAsIs() const { if (!propertiesAndValue.empty() && propertiesAndValue.size() % 2 == 1) return propertiesAndValue.back(); return QString(); } QString ConfigurationElement::GetAttributeAsIs(const QString& attrName) const { if (propertiesAndValue.size() <= 1) return QString(); int size = propertiesAndValue.size() - (propertiesAndValue.size() % 2); for (int i = 0; i < size; i += 2) { if (propertiesAndValue[i] == attrName) return propertiesAndValue[i + 1]; } return QString(); } QList ConfigurationElement::GetAttributeNames() const { if (propertiesAndValue.size() <= 1) return QList(); QList result; int size = propertiesAndValue.size() / 2; for (int i = 0; i < size; i++) { result.push_back(propertiesAndValue[i * 2]); } return result; } void ConfigurationElement::SetProperties(const QList& value) { propertiesAndValue = value; } QList ConfigurationElement::GetPropertiesAndValue() const { return propertiesAndValue; } void ConfigurationElement::SetValue(const QString& value) { if (propertiesAndValue.empty()) { propertiesAndValue.push_back(value); return; } if (propertiesAndValue.size() % 2 == 1) { propertiesAndValue[propertiesAndValue.size() - 1] = value; return; } propertiesAndValue.push_back(value); } void ConfigurationElement::SetContributorId(const QString& id) { contributorId = id; } QString ConfigurationElement::GetContributorId() const { return contributorId; } void ConfigurationElement::SetParentId(int objectId) { parentId = objectId; } QString ConfigurationElement::GetName() const { return name; } void ConfigurationElement::SetName(const QString& name) { this->name = name; } void ConfigurationElement::SetParentType(short type) { parentType = type; } QObject* ConfigurationElement::CreateExecutableExtension(const QString& attributeName) { QString prop; QString executable; QString contributorName; QString className; Object::Pointer initData; int i = 0; if (!attributeName.isEmpty()) { prop = GetAttribute(attributeName); } else { // property not specified, try as element value prop = GetValue().trimmed(); } if (prop.isEmpty()) { // property not defined, try as a child element QList exec = GetChildren(attributeName); if (!exec.empty()) { ConfigurationElement::Pointer element = exec[0]; // assumes single definition contributorName = element->GetAttribute("plugin"); className = element->GetAttribute("class"); QList parms = element->GetChildren("parameter"); if (!parms.empty()) { QHash initParms; for (i = 0; i < parms.size(); i++) { QString pname = parms[i]->GetAttribute("name"); if (!pname.isEmpty()) initParms.insert(pname, parms[i]->GetAttribute("value")); } if (!initParms.isEmpty()) initData = new ObjectStringMap(initParms); } } else { // specified name is not a simple attribute nor child element ThrowException(QString("Executable extension definition for \"%1\" not found.").arg(attributeName)); } } else { // simple property or element value, parse it into its components - i = prop.indexOf(QRegExp("[^:]:[^:]")); + i = prop.indexOf(QRegularExpression("[^:]:[^:]")); if (i != -1) { executable = prop.left(i+1).trimmed(); initData = new ObjectString(prop.mid(i + 2).trimmed()); } else { executable = prop; } i = executable.indexOf('/'); if (i != -1) { contributorName = executable.left(i).trimmed(); className = executable.mid(i + 1).trimmed(); } else { className = executable; } } // create a new instance RegistryContributor::Pointer defaultContributor = registry->GetObjectManager()->GetContributor(contributorId); QObject* result = registry->CreateExecutableExtension(defaultContributor, className, contributorName); // Check if we have extension adapter and initialize; // Make the call even if the initialization string is null try { // We need to take into account both "old" and "new" style executable extensions if (IExecutableExtension* execExt = qobject_cast(result)) { ConfigurationElementHandle::Pointer confElementHandle(new ConfigurationElementHandle( registry->GetObjectManager(), GetObjectId())); execExt->SetInitializationData(confElementHandle, attributeName, initData); } } catch (const CoreException& ce) { // user code threw exception throw ce; } catch (const ctkException& te) { // user code caused exception ThrowException(QString("Plug-in \"%1\" was unable to execute setInitializationData on an instance of \"%2\".") .arg(GetContributor()->GetName()).arg(className), te); } // Deal with executable extension factories. if (IExecutableExtensionFactory* execExtFactory = qobject_cast(result)) { result = execExtFactory->Create(); } return result; } QString ConfigurationElement::GetAttribute(const QString& attrName, const QLocale& /*locale*/) const { registry->LogMultiLangError(); return GetAttribute(attrName); } QString ConfigurationElement::GetValue(const QLocale& /*locale*/) const { registry->LogMultiLangError(); return GetValue(); } QString ConfigurationElement::GetAttribute(const QString& attrName) const { return GetAttributeAsIs(attrName); } QList ConfigurationElement::GetChildren(const QString& childrenName) const { QList result; if (GetRawChildren().empty()) return result; RegistryObjectManager::Pointer objectManager = registry->GetObjectManager(); for (int i = 0; i < children.size(); i++) { ConfigurationElement::Pointer toTest = objectManager->GetObject( children[i], NoExtraData() ? RegistryObjectManager::CONFIGURATION_ELEMENT : RegistryObjectManager::THIRDLEVEL_CONFIGURATION_ELEMENT).Cast(); if (toTest->name == childrenName) { result.push_back(toTest); } } return result; } SmartPointer ConfigurationElement::GetContributor() const { return registry->GetObjectManager()->GetContributor(contributorId); } } diff --git a/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtLogView.cpp b/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtLogView.cpp index d1960b8dd7..c3052f2719 100644 --- a/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtLogView.cpp +++ b/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtLogView.cpp @@ -1,152 +1,153 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "berryQtLogView.h" #include "berryQtLogPlugin.h" #include #include #include #include #include #include #include namespace berry { QtLogView::QtLogView(QWidget *parent) : QWidget(parent) { auto* prefService = berry::Platform::GetPreferencesService(); auto* prefs = prefService->GetSystemPreferences()->Node("org_blueberry_ui_qt_log"); prefs->PutBool("ShowAdvancedFields", false); prefs->PutBool("ShowCategory", true); bool showAdvancedFields = false; ui.setupUi(this); model = QtLogPlugin::GetInstance()->GetLogModel(); model->SetShowAdvancedFiels( showAdvancedFields ); filterModel = new QSortFilterProxyModel(this); filterModel->setSourceModel(model); filterModel->setFilterKeyColumn(-1); #ifdef __APPLE__ QFont fnt = ui.tableView->font(); fnt.setPointSize(11); ui.tableView->setFont(fnt); #endif ui.tableView->setModel(filterModel); ui.tableView->verticalHeader()->setVisible(false); ui.tableView->horizontalHeader()->setStretchLastSection(true); connect( ui.filterContent, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotFilterChange( const QString& ) ) ); connect( filterModel, SIGNAL( rowsInserted ( const QModelIndex &, int, int ) ), this, SLOT( slotRowAdded( const QModelIndex &, int , int ) ) ); connect( ui.SaveToClipboard, SIGNAL( clicked()),this, SLOT(on_SaveToClipboard_clicked())); ui.ShowAdvancedFields->setChecked( showAdvancedFields ); ui.filterContent->setClearButtonEnabled(true); } QtLogView::~QtLogView() { } void QtLogView::slotScrollDown( ) { ui.tableView->scrollToBottom(); } void QtLogView::slotFilterChange( const QString& q ) { - filterModel->setFilterRegExp(QRegExp(q, Qt::CaseInsensitive, QRegExp::FixedString)); + QRegularExpression regExp(QRegularExpression::escape(q), QRegularExpression::CaseInsensitiveOption); + filterModel->setFilterRegularExpression(regExp); } void QtLogView::slotRowAdded ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { ui.tableView->setVisible(false); ui.tableView->resizeRowsToContents(); //only resize columns when first entry is added static bool first = true; if(first) { ui.tableView->resizeColumnsToContents(); first = false; } ui.tableView->setVisible(true); QTimer::singleShot(0,this,SLOT( slotScrollDown() ) ); } void QtLogView::showEvent( QShowEvent * /*event*/ ) { ui.tableView->setVisible(false); ui.tableView->resizeColumnsToContents(); ui.tableView->resizeRowsToContents(); ui.tableView->setVisible(true); } void QtLogView::on_ShowAdvancedFields_clicked( bool checked ) { ui.tableView->setVisible(false); QtLogPlugin::GetInstance()->GetLogModel()->SetShowAdvancedFiels( checked ); ui.tableView->resizeColumnsToContents(); ui.tableView->setVisible(true); auto* prefService = berry::Platform::GetPreferencesService(); auto* prefs = prefService->GetSystemPreferences()->Node("org_blueberry_ui_qt_log"); prefs->PutBool("ShowAdvancedFields", checked); prefs->Flush(); } void QtLogView::on_ShowCategory_clicked( bool checked ) { ui.tableView->setVisible(false); QtLogPlugin::GetInstance()->GetLogModel()->SetShowCategory( checked ); ui.tableView->resizeColumnsToContents(); ui.tableView->setVisible(true); auto* prefService = berry::Platform::GetPreferencesService(); auto* prefs = prefService->GetSystemPreferences()->Node("org_blueberry_ui_qt_log"); prefs->PutBool("ShowCategory", checked); prefs->Flush(); } void QtLogView::on_SaveToClipboard_clicked() { QClipboard *clipboard = QApplication::clipboard(); QString loggingMessagesAsText = QString(""); for (int i=0; imodel()->rowCount(); i++) { for (int j=0; jmodel()->columnCount(); j++) { QModelIndex index = ui.tableView->model()->index(i, j); loggingMessagesAsText += ui.tableView->model()->data(index, Qt::DisplayRole).toString() + " "; } loggingMessagesAsText += "\n"; } clipboard->setText(loggingMessagesAsText); } } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryPerspectiveHelper.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryPerspectiveHelper.cpp index e35824ad1c..6ce8a99aab 100755 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryPerspectiveHelper.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryPerspectiveHelper.cpp @@ -1,1515 +1,1515 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "tweaklets/berryGuiWidgetsTweaklet.h" #include "berryPerspectiveHelper.h" #include "berryLayoutTree.h" #include "berryEditorSashContainer.h" #include "berryDragUtil.h" #include "berryPresentationFactoryUtil.h" #include "berryWorkbenchConstants.h" #include "berryWorkbenchPlugin.h" #include "berryPolicy.h" #include namespace berry { const int PerspectiveHelper::MIN_DETACH_WIDTH = 150; const int PerspectiveHelper::MIN_DETACH_HEIGHT = 250; PerspectiveHelper::DragOverListener::DragOverListener(PerspectiveHelper* perspHelper) : perspHelper(perspHelper) { } IDropTarget::Pointer PerspectiveHelper::DragOverListener::Drag( QWidget* /*currentControl*/, const Object::Pointer& draggedObject, const QPoint& /*position*/, const QRect& dragRectangle) { if (draggedObject.Cast() != 0) { PartPane::Pointer part = draggedObject.Cast(); if (part->GetContainer().Cast()->GetAppearance() == PresentationFactoryUtil::ROLE_EDITOR) return IDropTarget::Pointer(nullptr); // Views that haven't been shown yet have no 'control' which causes // 'GetWorkbenchWindow' to return 'null' so check explicitly if (part->GetPage() != perspHelper->page) return IDropTarget::Pointer(nullptr); else if (part->GetWorkbenchWindow() != perspHelper->page->GetWorkbenchWindow()) return IDropTarget::Pointer(nullptr); if (perspHelper->dropTarget == 0) perspHelper->dropTarget = new ActualDropTarget(perspHelper, part, dragRectangle); else perspHelper->dropTarget->SetTarget(part, dragRectangle); } else if (draggedObject.Cast() != 0) { PartStack::Pointer stack = draggedObject.Cast(); if (stack->GetAppearance() == PresentationFactoryUtil::ROLE_EDITOR) return IDropTarget::Pointer(nullptr); if (stack->GetWorkbenchWindow() != perspHelper->page->GetWorkbenchWindow()) return IDropTarget::Pointer(nullptr); if (perspHelper->dropTarget == 0) perspHelper->dropTarget = new ActualDropTarget(perspHelper, stack, dragRectangle); else perspHelper->dropTarget->SetTarget(stack, dragRectangle); } return perspHelper->dropTarget; } void PerspectiveHelper::ActualDropTarget::SetTarget(PartPane::Pointer part, const QRect& dragRectangle) { this->stack = nullptr; this->part = part; this->dragRectangle = dragRectangle; } void PerspectiveHelper::ActualDropTarget::SetTarget(PartStack::Pointer stack, const QRect& dragRectangle) { this->stack = stack; this->part = nullptr; this->dragRectangle = dragRectangle; } PerspectiveHelper::ActualDropTarget::ActualDropTarget(PerspectiveHelper* perspHelper, PartPane::Pointer part, const QRect& dragRectangle) : AbstractDropTarget(), perspHelper(perspHelper) { this->SetTarget(part, dragRectangle); } PerspectiveHelper::ActualDropTarget::ActualDropTarget(PerspectiveHelper* perspHelper, PartStack::Pointer stack, const QRect& dragRectangle) : AbstractDropTarget(), perspHelper(perspHelper) { this->SetTarget(stack, dragRectangle); } void PerspectiveHelper::ActualDropTarget::Drop() { if (part != 0) { Shell::Pointer shell = part->GetShell(); if (shell->GetData().Cast () != 0) { // if only one view in tab folder then do a window move ILayoutContainer::Pointer container = part->GetContainer(); if (container.Cast () != 0) { if (container.Cast()->GetItemCount() == 1) { shell->SetLocation(dragRectangle.x(), dragRectangle.y()); return; } } } // // If layout is modified always zoom out. // if (isZoomed()) // { // zoomOut(); // } // do a normal part detach perspHelper->DetachPart(part, dragRectangle.x(), dragRectangle.y()); } else if (stack != 0) { Shell::Pointer shell = stack->GetShell(); if (shell->GetData().Cast () != 0) { // only one tab folder in a detach window, so do window // move shell->SetLocation(dragRectangle.x(), dragRectangle.y()); return; } // // If layout is modified always zoom out. // if (isZoomed()) // { // zoomOut(); // } // do a normal part detach perspHelper->Detach(stack, dragRectangle.x(), dragRectangle.y()); } } CursorType PerspectiveHelper::ActualDropTarget::GetCursor() { return CURSOR_OFFSCREEN; } PerspectiveHelper::MatchingPart::MatchingPart(const QString& pid, const QString& sid, LayoutPart::Pointer part) { this->pid = pid; this->sid = sid; this->part = part; this->len = pid.size() + sid.size(); this->hasWildcard = (pid.indexOf(PartPlaceholder::WILD_CARD) != -1) || (sid.indexOf(PartPlaceholder::WILD_CARD) != -1); } bool PerspectiveHelper::CompareMatchingParts::operator()(const MatchingPart& m1, const MatchingPart& m2) const { // specific ids always outweigh ids with wildcards if (m1.hasWildcard && !m2.hasWildcard) { return true; } if (!m1.hasWildcard && m2.hasWildcard) { return false; } // if both are specific or both have wildcards, simply compare based on length return m1.len > m2.len; } PerspectiveHelper::PerspectiveHelper(WorkbenchPage* workbenchPage, ViewSashContainer::Pointer mainLayout, Perspective* persp) : page(workbenchPage), perspective(persp), mainLayout(mainLayout), detachable(false), active(false) { // Views can be detached if the feature is enabled (true by default, // use the plug-in customization file to disable), and if the platform // supports detaching. this->dragTarget.reset(new DragOverListener(this)); //TODO preference store // IPreferenceStore store = PlatformUI.getPreferenceStore(); // this.detachable = store.getBoolean( // IWorkbenchPreferenceConstants.ENABLE_DETACHED_VIEWS); this->detachable = true; if (this->detachable) { // Check if some arbitrary Composite supports reparenting. If it // doesn't, views cannot be detached. QWidget* client = workbenchPage->GetClientComposite(); if (client == nullptr) { // The workbench page is not initialized. I don't think this can happen, // but if it does, silently set detachable to false. this->detachable = false; } else { this->detachable = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->IsReparentable(client); } } } void PerspectiveHelper::Activate(QWidget* parent) { if (active) { return; } parentWidget = parent; // Activate main layout // make sure all the views have been properly parented QList children; this->CollectViewPanes(children, mainLayout->GetChildren()); for (QList::iterator iter = children.begin(); iter != children.end(); ++iter) { PartPane::Pointer part = *iter; part->Reparent(parent); } mainLayout->CreateControl(parent); mainLayout->SetActive(true); // Open the detached windows. for (DetachedWindowsType::iterator iter = detachedWindowList.begin(); iter != detachedWindowList.end(); ++iter) { (*iter)->Open(); } this->EnableAllDrag(); // // Ensure that the maximized stack's presentation state is correct // if (maximizedStackId != 0) // { // LayoutPart part = this->FindPart(maximizedStackId); // if (part.Cast() != 0) // { // maximizedStack = (PartStack) part; // maximizedStackId = 0; // } // } // // // NOTE: we only handle ViewStacks here; Editor Stacks are handled by the // // perspective // if (maximizedStack instanceof ViewStack) // { // maximizedStack.setPresentationState(IStackPresentationSite.STATE_MAXIMIZED); // } active = true; } void PerspectiveHelper::AddPart(LayoutPart::Pointer part) { // Look for a placeholder. PartPlaceholder::Pointer placeholder; LayoutPart::Pointer testPart; QString primaryId = part->GetID(); QString secondaryId; IViewReference::Pointer ref; if (part.Cast () != 0) { PartPane::Pointer pane = part.Cast (); ref = pane->GetPartReference().Cast (); if (ref != 0) secondaryId = ref->GetSecondaryId(); } if (secondaryId != "") { testPart = this->FindPart(primaryId, secondaryId); } else { testPart = this->FindPart(primaryId); } // validate the testPart if (testPart != 0 && testPart.Cast() != 0) { placeholder = testPart.Cast (); } // If there is no placeholder do a simple add. Otherwise, replace the // placeholder if its not a pattern matching placeholder if (placeholder == 0) { part->Reparent(mainLayout->GetParent()); LayoutPart::Pointer relative = mainLayout->FindBottomRight(); if (relative != 0 && relative.Cast() != 0) { ILayoutContainer::Pointer stack = relative.Cast (); if (stack->AllowsAdd(part)) { mainLayout->Stack(part, stack); } else { mainLayout->AddPart(part); } } else { mainLayout->AddPart(part); } } else { ILayoutContainer::Pointer container = placeholder->GetContainer(); if (container != 0) { if (container.Cast () != 0) { //Create a detached window add the part on it. DetachedPlaceHolder::Pointer holder = container.Cast(); detachedPlaceHolderList.removeAll(holder); container->Remove(testPart); DetachedWindow::Pointer window(new DetachedWindow(page)); detachedWindowList.push_back(window); window->Create(); part->CreateControl(window->GetShell()->GetControl()); // Open window. window->GetShell()->SetBounds(holder->GetBounds()); window->Open(); // add part to detached window. PartPane::Pointer pane = part.Cast(); window->Add(pane); QList otherChildren = holder->GetChildren(); for (QList::iterator iter = otherChildren.begin(); iter != otherChildren.end(); ++iter) { part->GetContainer()->Add(*iter); } } else { // show parent if necessary if (container.Cast () != 0) { ContainerPlaceholder::Pointer containerPlaceholder = container.Cast(); ILayoutContainer::Pointer parentContainer = containerPlaceholder->GetContainer(); if (parentContainer == 0) { if (Policy::DEBUG_PERSPECTIVES()) { QString msg = "Previous ContainerPlaceholder for " + tmpViewId; if (tmpStackTrace.isNull()) { WorkbenchPlugin::Log(msg); } else { WorkbenchPlugin::Log(msg, *tmpStackTrace.data()); } tmpViewId.clear(); tmpStackTrace.reset(new ctkException("")); WorkbenchPlugin::Log("Current ContainerPlaceholder with null parent for " + primaryId + ":" + secondaryId, *tmpStackTrace.data()); tmpStackTrace.reset(); } return; } if (Policy::DEBUG_PERSPECTIVES()) { tmpViewId = primaryId + ":" + secondaryId; tmpStackTrace.reset(new ctkException("")); } container = containerPlaceholder->GetRealContainer().Cast(); if (container.Cast () != 0) { parentContainer->Replace(containerPlaceholder, container.Cast()); } containerPlaceholder->SetRealContainer(ILayoutContainer::Pointer(nullptr)); } // // reparent part. // if (container.Cast() == 0) // { // // We don't need to reparent children of PartTabFolders since they will automatically // // reparent their children when they become visible. This if statement used to be // // part of an else branch. Investigate if it is still necessary. // part->Reparent(mainLayout->GetParent()); // } // see if we should replace the placeholder if (placeholder->HasWildCard()) { if (PartSashContainer::Pointer sashContainer = container.Cast()) { sashContainer->AddChildForPlaceholder(part, placeholder); } else { container->Add(part); } } else { container->Replace(placeholder, part); } } } } } void PerspectiveHelper::AttachPart(IViewReference::Pointer ref) { PartPane::Pointer pane = ref.Cast()->GetPane(); // Restore any maximized part before re-attaching. // Note that 'getMaximizedStack != 0' implies 'useNewMinMax' // if (getMaximizedStack() != 0) // { // getMaximizedStack().setState(IStackPresentationSite.STATE_RESTORED); // } this->DerefPart(pane); this->AddPart(pane); this->BringPartToTop(pane); pane->SetFocus(); } bool PerspectiveHelper::CanDetach() { return detachable; } bool PerspectiveHelper::BringPartToTop(LayoutPart::Pointer part) { ILayoutContainer::Pointer container = part->GetContainer(); if (container != 0 && container.Cast () != 0) { PartStack::Pointer folder = container.Cast (); if (folder->GetSelection() != part) { folder->SetSelection(part); return true; } } return false; } bool PerspectiveHelper::IsPartVisible(IWorkbenchPartReference::Pointer partRef) { LayoutPart::Pointer foundPart; if (partRef.Cast () != 0) { foundPart = this->FindPart(partRef->GetId(), partRef.Cast()->GetSecondaryId()); } else { foundPart = this->FindPart(partRef->GetId()); } if (foundPart == 0) { return false; } if (foundPart.Cast () != 0) { return false; } ILayoutContainer::Pointer container = foundPart->GetContainer(); if (container.Cast () != 0) { return false; } if (container.Cast () != 0) { PartStack::Pointer folder = container.Cast(); LayoutPart::Pointer visiblePart = folder->GetSelection(); if (visiblePart == 0) { return false; } return partRef == visiblePart.Cast()->GetPartReference(); } return true; } bool PerspectiveHelper::WillPartBeVisible(const QString& partId) { return this->WillPartBeVisible(partId, nullptr); } bool PerspectiveHelper::WillPartBeVisible(const QString& partId, const QString& secondaryId) { LayoutPart::Pointer part = this->FindPart(partId, secondaryId); if (part == 0) { return false; } ILayoutContainer::Pointer container = part->GetContainer(); if (container != 0 && container.Cast () != 0) { container = container.Cast()->GetRealContainer().Cast(); } if (container != 0 && container.Cast () != 0) { PartStack::Pointer folder = container.Cast(); if (folder->GetSelection() == 0) { return false; } return part->GetID() == folder->GetSelection()->GetID(); } return true; } QList PerspectiveHelper::CollectPlaceholders() { // Scan the main window. QList results = this->CollectPlaceholders( mainLayout->GetChildren()); // Scan each detached window. if (detachable) { for (DetachedWindowsType::iterator winIter = detachedWindowList.begin(); winIter != detachedWindowList.end(); ++winIter) { DetachedWindow::Pointer win = *winIter; QList moreResults = win->GetChildren(); if (moreResults.size()> 0) { for (QList::iterator iter = moreResults.begin(); iter != moreResults.end(); ++iter) { if (iter->Cast() != 0) results.push_back(iter->Cast()); } } } } return results; } QList PerspectiveHelper::CollectPlaceholders( const QList& parts) { QList result; for (QList::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { LayoutPart::Pointer part = *iter; if (ILayoutContainer::Pointer container = part.Cast()) { // iterate through sub containers to find sub-parts QList newParts = this->CollectPlaceholders( container->GetChildren()); result.append(newParts); } else if (PartPlaceholder::Pointer placeholder = part.Cast()) { result.push_back(placeholder); } } return result; } void PerspectiveHelper::CollectViewPanes(QList& result) { // Scan the main window. this->CollectViewPanes(result, mainLayout->GetChildren()); // Scan each detached window. if (detachable) { for (DetachedWindowsType::iterator winIter = detachedWindowList.begin(); winIter != detachedWindowList.end(); ++winIter) { DetachedWindow::Pointer win = *winIter; CollectViewPanes(result, win->GetChildren()); } } } void PerspectiveHelper::CollectViewPanes(QList& result, const QList& parts) { for (QList::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { LayoutPart::Pointer part = *iter; if (PartPane::Pointer partPane = part.Cast()) { if(partPane->GetPartReference().Cast()) { result.push_back(partPane); } } else if (ILayoutContainer::Pointer container = part.Cast ()) { this->CollectViewPanes(result, container->GetChildren()); } } } void PerspectiveHelper::Deactivate() { if (!active) { return; } this->DisableAllDrag(); // Reparent all views to the main window QWidget* parent = mainLayout->GetParent(); QList children; this->CollectViewPanes(children, mainLayout->GetChildren()); for (DetachedWindowsType::iterator winIter = detachedWindowList.begin(); winIter != detachedWindowList.end(); ++winIter) { DetachedWindow::Pointer window = *winIter; CollectViewPanes(children, window->GetChildren()); } // *** Do we even need to do this if detached windows not supported? for (QList::iterator itr = children.begin(); itr != children.end(); ++itr) { PartPane::Pointer part = *itr; part->Reparent(parent); } // Dispose main layout. mainLayout->SetActive(false); // Dispose the detached windows for (DetachedWindowsType::iterator iter = detachedWindowList.begin(); iter != detachedWindowList.end(); ++iter) { (*iter)->Close(); } active = false; } PerspectiveHelper::~PerspectiveHelper() { mainLayout->Dispose(); mainLayout->DisposeSashes(); } void PerspectiveHelper::DescribeLayout(QString& buf) const { if (detachable) { if (detachedWindowList.size() != 0) { buf.append("detachedWindows ("); //$NON-NLS-1$ for (DetachedWindowsType::const_iterator winIter = detachedWindowList.begin(); winIter != detachedWindowList.end(); ++winIter) { DetachedWindow::ConstPointer window = *winIter; QList children = window->GetChildren(); int j = 0; if (children.size() != 0) { buf.append("dWindow ("); //$NON-NLS-1$ for (QList::iterator partIter = children.begin(); partIter != children.end(); ++partIter, ++j) { if (partIter->Cast() != 0) buf.append(partIter->Cast()->GetPlaceHolderId()); else if (partIter->Cast() != 0) buf.append( partIter->Cast()->GetPartReference()->GetPartName()); if (j < (children.size() - 1)) { buf.append(", "); //$NON-NLS-1$ } } buf.append(")"); //$NON-NLS-1$ } } buf.append("), "); //$NON-NLS-1$ } } this->GetLayout()->DescribeLayout(buf); } void PerspectiveHelper::DerefPart(LayoutPart::Pointer part) { // if (part.Cast () != 0) // { // IViewReference::Pointer ref = ((ViewPane) part).getViewReference(); // if (perspective.isFastView(ref)) // { // // Special check: if it's a fast view then it's actual ViewStack // // may only contain placeholders and the stack is represented in // // the presentation by a container placeholder...make sure the // // PartPlaceHolder for 'ref' is removed from the ViewStack // String id = perspective.getFastViewManager().getIdForRef(ref); // LayoutPart parentPart = findPart(id, 0); // if (parentPart.Cast () != 0) // { // ViewStack vs = // (ViewStack) ((ContainerPlaceholder) parentPart).getRealContainer(); // QList kids = vs.getChildren(); // for (int i = 0; i < kids.length; i++) // { // if (kids[i].Cast () != 0) // { // if (ref.getId().equals(kids[i].id)) // vs.remove(kids[i]); // } // } // } // perspective.getFastViewManager().removeViewReference(ref, true, true); // } // } // Get vital part stats before reparenting. ILayoutContainer::Pointer oldContainer = part->GetContainer(); bool wasDocked = part->IsDocked(); Shell::Pointer oldShell = part->GetShell(); // Reparent the part back to the main window part->Reparent(mainLayout->GetParent()); // Update container. if (oldContainer == 0) { return; } oldContainer->Remove(part); ILayoutContainer::ChildrenType children = oldContainer->GetChildren(); if (wasDocked) { bool hasChildren = (children.size()> 0); if (hasChildren) { // make sure one is at least visible int childVisible = 0; for (ILayoutContainer::ChildrenType::iterator iter = children.begin(); iter != children.end(); ++iter) { if ((*iter)->GetControl() != nullptr) { childVisible++; } } // none visible, then reprarent and remove container if (oldContainer.Cast () != 0) { PartStack::Pointer folder = oldContainer.Cast(); // Is the part in the trim? bool inTrim = false; // // Safety check...there may be no FastViewManager // if (perspective.getFastViewManager() != 0) // inTrim // = perspective.getFastViewManager().getFastViews(folder.getID()).size() // > 0; if (childVisible == 0 && !inTrim) { ILayoutContainer::Pointer parentContainer = folder->GetContainer(); hasChildren = folder->GetChildren().size()> 0; // We maintain the stack as a place-holder if it has children // (which at this point would represent view place-holders) if (hasChildren) { folder->Dispose(); // replace the real container with a ContainerPlaceholder ContainerPlaceholder::Pointer placeholder( new ContainerPlaceholder(folder->GetID())); placeholder->SetRealContainer(folder); parentContainer->Replace(folder, placeholder); } } else if (childVisible == 1) { LayoutTree::Pointer layout = mainLayout->GetLayoutTree(); layout = layout->Find(folder); layout->SetBounds(layout->GetBounds()); } } } if (!hasChildren) { // There are no more children in this container, so get rid of // it if (oldContainer.Cast () != 0) { //BERRY_INFO << "No children left, removing container\n"; LayoutPart::Pointer parent = oldContainer.Cast(); ILayoutContainer::Pointer parentContainer = parent->GetContainer(); if (parentContainer != 0) { parentContainer->Remove(parent); parent->Print(qDebug()); parent->Dispose(); } } } } else if (!wasDocked) { if (children.empty()) { // There are no more children in this container, so get rid of // it // Turn on redraw again just in case it was off. //oldShell.setRedraw(true); DetachedWindow::Pointer w = oldShell->GetData().Cast(); oldShell->Close(); detachedWindowList.removeAll(w); } else { // There are children. If none are visible hide detached // window. bool allInvisible = true; for (ILayoutContainer::ChildrenType::iterator iter = children.begin(); iter != children.end(); ++iter) { if (iter->Cast () == 0) { allInvisible = false; break; } } if (allInvisible) { DetachedPlaceHolder::Pointer placeholder(new DetachedPlaceHolder("", oldShell->GetBounds())); for (ILayoutContainer::ChildrenType::iterator iter = children.begin(); iter != children.end(); ++iter) { oldContainer->Remove(*iter); (*iter)->SetContainer(placeholder); placeholder->Add(*iter); } detachedPlaceHolderList.push_back(placeholder); DetachedWindow::Pointer w = oldShell->GetData().Cast(); oldShell->Close(); detachedWindowList.removeAll(w); } } } } void PerspectiveHelper::Detach(LayoutPart::Pointer part, int x, int y) { // Detaching is disabled on some platforms .. if (!detachable) { return; } // Calculate detached window size. QSize size = part->GetSize(); if (size.width() == 0 || size.height() == 0) { ILayoutContainer::Pointer container = part->GetContainer(); if (container.Cast () != 0) { size = container.Cast()->GetSize(); } } int width = std::max(size.width(), MIN_DETACH_WIDTH); int height = std::max(size.height(), MIN_DETACH_HEIGHT); // Create detached window. DetachedWindow::Pointer window(new DetachedWindow(page)); detachedWindowList.push_back(window); // Open window. window->Create(); window->GetShell()->SetBounds(x, y, width, height); window->Open(); if (part.Cast () != 0) { //window.getShell().setRedraw(false); //parentWidget.setRedraw(false); PartStack::Pointer stack = part.Cast(); LayoutPart::Pointer visiblePart = stack->GetSelection(); ILayoutContainer::ChildrenType children = stack->GetChildren(); for (ILayoutContainer::ChildrenType::iterator iter = children.begin(); iter != children.end(); ++iter) { if (PartPane::Pointer partPane = iter->Cast() // && check it is a view? ) { // remove the part from its current container this->DerefPart(*iter); // add part to detached window. window->Add(*iter); } } if (visiblePart != 0) { this->BringPartToTop(visiblePart); visiblePart->SetFocus(); } //window.getShell().setRedraw(true); //parentWidget.setRedraw(true); } } void PerspectiveHelper::DetachPart(LayoutPart::Pointer part, int x, int y) { // Detaching is disabled on some platforms .. if (!detachable) { return; } // Calculate detached window size. QSize size = part->GetSize(); if (size.width() == 0 || size.height() == 0) { ILayoutContainer::Pointer container = part->GetContainer(); if (container.Cast () != 0) { size = container.Cast()->GetSize(); } } int width = std::max(size.width(), MIN_DETACH_WIDTH); int height = std::max(size.height(), MIN_DETACH_HEIGHT); // Create detached window. DetachedWindow::Pointer window(new DetachedWindow(page)); detachedWindowList.push_back(window); // Open window. window->Create(); window->GetShell()->SetBounds(x, y, width, height); window->Open(); // remove the part from its current container this->DerefPart(part); // add part to detached window. window->Add(part); part->SetFocus(); } void PerspectiveHelper::DetachPart(IViewReference::Pointer ref) { PartPane::Pointer pane = ref.Cast()->GetPane(); if (this->CanDetach() && pane != 0) { // if (getMaximizedStack() != 0) // getMaximizedStack().setState(IStackPresentationSite.STATE_RESTORED); QRect bounds = pane->GetParentBounds(); this->DetachPart(pane, bounds.x(), bounds.y()); } } void PerspectiveHelper::AddDetachedPart(LayoutPart::Pointer part) { // Calculate detached window size. QRect bounds = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetShell(parentWidget)->GetBounds(); bounds.setX(bounds.x() + (bounds.width() - 300) / 2); bounds.setY(bounds.y() + (bounds.height() - 300) / 2); this->AddDetachedPart(part, bounds); } void PerspectiveHelper::AddDetachedPart(LayoutPart::Pointer part, const QRect& bounds) { // Detaching is disabled on some platforms .. if (!detachable) { this->AddPart(part); return; } // Create detached window. DetachedWindow::Pointer window(new DetachedWindow(page)); detachedWindowList.push_back(window); window->Create(); // add part to detached window. part->CreateControl(window->GetShell()->GetControl()); window->Add(part); // Open window. window->GetShell()->SetBounds(bounds.x(), bounds.y(), bounds.width(), bounds.height()); window->Open(); part->SetFocus(); } void PerspectiveHelper::DisableAllDrag() { DragUtil::RemoveDragTarget(nullptr, dragTarget.data()); } void PerspectiveHelper::EnableAllDrag() { DragUtil::AddDragTarget(nullptr, dragTarget.data()); } LayoutPart::Pointer PerspectiveHelper::FindPart(const QString& id) { return this->FindPart(id, ""); } LayoutPart::Pointer PerspectiveHelper::FindPart(const QString& primaryId, const QString& secondaryId) { //BERRY_INFO << "Looking for part: " << primaryId << ":" << secondaryId << std::endl; // check main window. QList matchingParts; LayoutPart::Pointer part = (secondaryId != "") ? this->FindPart(primaryId, secondaryId, mainLayout->GetChildren(), matchingParts) : this->FindPart(primaryId, mainLayout->GetChildren(), matchingParts); if (part != 0) { return part; } // check each detached windows. for (DetachedWindowsType::iterator iter = detachedWindowList.begin(); iter != detachedWindowList.end(); ++iter) { DetachedWindow::Pointer window = *iter; part = (secondaryId != "") ? this->FindPart(primaryId, secondaryId, window->GetChildren(), matchingParts) : this->FindPart(primaryId, window->GetChildren(), matchingParts); if (part != 0) { return part; } } for (DetachedPlaceHoldersType::iterator iter = detachedPlaceHolderList.begin(); iter != detachedPlaceHolderList.end(); ++iter) { DetachedPlaceHolder::Pointer holder = *iter; part = (secondaryId != "") ? this->FindPart(primaryId, secondaryId, holder->GetChildren(), matchingParts) : this->FindPart(primaryId, holder->GetChildren(), matchingParts); if (part != 0) { return part; } } //BERRY_INFO << "Looking through the matched parts (count: " << matchingParts.size() << ")\n"; // sort the matching parts if (matchingParts.size()> 0) { std::partial_sort(matchingParts.begin(), (matchingParts.begin()), matchingParts.end(), CompareMatchingParts()); const MatchingPart& mostSignificantPart = matchingParts.front(); return mostSignificantPart.part; } // Not found. return LayoutPart::Pointer(nullptr); } LayoutPart::Pointer PerspectiveHelper::FindPart(const QString& id, const QList& parts, QList& matchingParts) { for (QList::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { LayoutPart::Pointer part = *iter; // check for part equality, parts with secondary ids fail if (part->GetID() == id) { if (part.Cast () != 0) { PartPane::Pointer pane = part.Cast(); IViewReference::Pointer ref = pane->GetPartReference().Cast(); if (ref->GetSecondaryId() != "") { continue; } } return part; } // check pattern matching placeholders else if (part->IsPlaceHolder() && part.Cast()->HasWildCard()) { - QRegExp re(id, Qt::CaseInsensitive); - if (re.exactMatch(part->GetID())) + QRegularExpression re(QString("^%1$").arg(id), QRegularExpression::CaseInsensitiveOption); + if (re.match(part->GetID()).hasMatch()) { matchingParts.push_back(MatchingPart(part->GetID(), "", part)); } // StringMatcher sm = new StringMatcher(part.getID(), true, false); // if (sm.match(id)) // { // matchingParts .add(new MatchingPart(part.getID(), 0, part)); // } } else if (ILayoutContainer::Pointer layoutContainer = part.Cast()) { part = FindPart(id, layoutContainer->GetChildren(), matchingParts); if (part) { return part; } } } //BERRY_INFO << "Returning 0\n"; return LayoutPart::Pointer(nullptr); } LayoutPart::Pointer PerspectiveHelper::FindPart(const QString& primaryId, const QString& secondaryId, const QList& parts, QList& matchingParts) { for (QList::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { LayoutPart::Pointer part = *iter; // check containers first if (ILayoutContainer::Pointer layoutContainer = part.Cast()) { LayoutPart::Pointer testPart = FindPart(primaryId, secondaryId, layoutContainer->GetChildren(), matchingParts); if (testPart) { return testPart; } } // check for view part equality if (part.Cast () != 0) { PartPane::Pointer pane = part.Cast(); IViewReference::Pointer ref = pane->GetPartReference().Cast(); if (ref->GetId() == primaryId && ref->GetSecondaryId() == secondaryId) { return part; } } // check placeholders else if (part.Cast () != 0) { QString id = part->GetID(); // optimization: don't bother parsing id if it has no separator -- it can't match QString phSecondaryId = ViewFactory::ExtractSecondaryId(id); if (phSecondaryId == "") { // but still need to check for wildcard case if (id == PartPlaceholder::WILD_CARD) { matchingParts.push_back(MatchingPart(id, "", part)); } continue; } QString phPrimaryId = ViewFactory::ExtractPrimaryId(id); // perfect matching pair if (phPrimaryId == primaryId && phSecondaryId == secondaryId) { return part; } // check for partial matching pair - QRegExp pre(phPrimaryId, Qt::CaseInsensitive); - if (pre.exactMatch(primaryId)) + QRegularExpression pre(QString("^%1$").arg(phPrimaryId), QRegularExpression::CaseInsensitiveOption); + if (pre.match(primaryId).hasMatch()) { - QRegExp sre(phSecondaryId, Qt::CaseInsensitive); - if (sre.exactMatch(secondaryId)) + QRegularExpression sre(QString("^%1$").arg(phSecondaryId), QRegularExpression::CaseInsensitiveOption); + if (sre.match(secondaryId).hasMatch()) { matchingParts.push_back(MatchingPart(phPrimaryId, phSecondaryId, part)); } } } } return LayoutPart::Pointer(nullptr); } bool PerspectiveHelper::HasPlaceholder(const QString& id) { return this->HasPlaceholder(id, nullptr); } bool PerspectiveHelper::HasPlaceholder(const QString& primaryId, const QString& secondaryId) { LayoutPart::Pointer testPart; if (secondaryId == "") { testPart = this->FindPart(primaryId); } else { testPart = this->FindPart(primaryId, secondaryId); } return (testPart != 0 && testPart.Cast () != 0); } PartSashContainer::Pointer PerspectiveHelper::GetLayout() const { return mainLayout; } bool PerspectiveHelper::IsActive() { return active; } float PerspectiveHelper::GetDockingRatio(LayoutPart::Pointer source, LayoutPart::Pointer target) { if ((source.Cast () != 0 || source.Cast () != 0) && target.Cast () != 0) { return 0.25f; } return 0.5f; } void PerspectiveHelper::RemovePart(LayoutPart::Pointer part) { // Reparent the part back to the main window QWidget* parent = mainLayout->GetParent(); part->Reparent(parent); // Replace part with a placeholder ILayoutContainer::Pointer container = part->GetContainer(); if (container != 0) { QString placeHolderId = part->GetPlaceHolderId(); container->Replace(part, LayoutPart::Pointer(new PartPlaceholder(placeHolderId))); // // If the parent is root we're done. Do not try to replace // // it with placeholder. // if (container == mainLayout) // { // return; // } // If the parent is empty replace it with a placeholder. QList children = container->GetChildren(); bool allInvisible = true; for (QList::iterator childIter = children.begin(); childIter != children.end(); ++childIter) { if (childIter->Cast () == 0) { allInvisible = false; break; } } if (allInvisible && (container.Cast () != 0)) { // what type of window are we in? LayoutPart::Pointer cPart = container.Cast(); //Window oldWindow = cPart.getWindow(); bool wasDocked = cPart->IsDocked(); Shell::Pointer oldShell = cPart->GetShell(); if (wasDocked) { // PR 1GDFVBY: ViewStack not disposed when page // closed. if (container.Cast () != 0) { container.Cast()->Dispose(); } // replace the real container with a // ContainerPlaceholder ILayoutContainer::Pointer parentContainer = cPart->GetContainer(); ContainerPlaceholder::Pointer placeholder( new ContainerPlaceholder(cPart->GetID())); placeholder->SetRealContainer(container); parentContainer->Replace(cPart, placeholder); } else { DetachedPlaceHolder::Pointer placeholder( new DetachedPlaceHolder("", oldShell->GetBounds())); //$NON-NLS-1$ for (QList::iterator childIter2 = children.begin(); childIter2 != children.end(); ++childIter2) { (*childIter2)->GetContainer()->Remove(*childIter2); (*childIter2)->SetContainer(placeholder); placeholder->Add(*childIter2); } detachedPlaceHolderList.push_back(placeholder); DetachedWindow::Pointer w = oldShell->GetData().Cast(); oldShell->Close(); detachedWindowList.removeAll(w); } } } } void PerspectiveHelper::ReplacePlaceholderWithPart(LayoutPart::Pointer part) { // Look for a PartPlaceholder that will tell us how to position this // object QList placeholders = this->CollectPlaceholders(); for (int i = 0; i < placeholders.size(); i++) { if (placeholders[i]->GetID() == part->GetID()) { // found a matching placeholder which we can replace with the // new View ILayoutContainer::Pointer container = placeholders[i]->GetContainer(); if (container != 0) { if (ContainerPlaceholder::Pointer containerPlaceholder = container.Cast ()) { // One of the children is now visible so replace the // ContainerPlaceholder with the real container ILayoutContainer::Pointer parentContainer = containerPlaceholder->GetContainer(); container = containerPlaceholder->GetRealContainer().Cast(); if (LayoutPart::Pointer layoutPart = container.Cast ()) { parentContainer->Replace(containerPlaceholder, layoutPart); } containerPlaceholder->SetRealContainer(ILayoutContainer::Pointer(nullptr)); } container->Replace(placeholders[i], part); return; } } } } bool PerspectiveHelper::RestoreState(IMemento::Pointer memento) { // Restore main window. IMemento::Pointer childMem = memento->GetChild(WorkbenchConstants::TAG_MAIN_WINDOW); //IStatus r = mainLayout->RestoreState(childMem); bool r = mainLayout->RestoreState(childMem); // Restore each floating window. if (detachable) { QList detachedWindows(memento->GetChildren( WorkbenchConstants::TAG_DETACHED_WINDOW)); for (QList::iterator iter = detachedWindows.begin(); iter != detachedWindows.end(); ++iter) { DetachedWindow::Pointer win(new DetachedWindow(page)); detachedWindowList.push_back(win); win->RestoreState(*iter); } QList childrenMem(memento->GetChildren( WorkbenchConstants::TAG_HIDDEN_WINDOW)); for (QList::iterator iter = childrenMem.begin(); iter != childrenMem.end(); ++iter) { DetachedPlaceHolder::Pointer holder( new DetachedPlaceHolder("", QRect(0, 0, 0, 0))); holder->RestoreState(*iter); detachedPlaceHolderList.push_back(holder); } } // Get the cached id of the currently maximized stack //maximizedStackId = childMem.getString(IWorkbenchConstants.TAG_MAXIMIZED); return r; } bool PerspectiveHelper::SaveState(IMemento::Pointer memento) { // Persist main window. IMemento::Pointer childMem = memento->CreateChild(WorkbenchConstants::TAG_MAIN_WINDOW); //IStatus r = mainLayout->SaveState(childMem); bool r = mainLayout->SaveState(childMem); if (detachable) { // Persist each detached window. for (DetachedWindowsType::iterator iter = detachedWindowList.begin(); iter != detachedWindowList.end(); ++iter) { childMem = memento->CreateChild(WorkbenchConstants::TAG_DETACHED_WINDOW); (*iter)->SaveState(childMem); } for (DetachedPlaceHoldersType::iterator iter = detachedPlaceHolderList.begin(); iter != detachedPlaceHolderList.end(); ++iter) { childMem = memento->CreateChild(WorkbenchConstants::TAG_HIDDEN_WINDOW); (*iter)->SaveState(childMem); } } // Write out the id of the maximized (View) stack (if any) // NOTE: we only write this out if it's a ViewStack since the // Editor Area is handled by the perspective // if (maximizedStack.Cast () != 0) // { // childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED, // maximizedStack.getID()); // } // else if (maximizedStackId != 0) // { // // Maintain the cache if the perspective has never been activated // childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED, maximizedStackId); // } return r; } void PerspectiveHelper::UpdateBoundsMap() { boundsMap.clear(); // Walk the layout gathering the current bounds of each stack // and the editor area QList kids = mainLayout->GetChildren(); for (QList::iterator iter = kids.begin(); iter != kids.end(); ++iter) { if (iter->Cast () != 0) { PartStack::Pointer vs = iter->Cast(); boundsMap.insert(vs->GetID(), vs->GetBounds()); } else if (iter->Cast () != 0) { EditorSashContainer::Pointer esc = iter->Cast(); boundsMap.insert(esc->GetID(), esc->GetBounds()); } } } void PerspectiveHelper::ResetBoundsMap() { boundsMap.clear(); } QRect PerspectiveHelper::GetCachedBoundsFor(const QString& id) { return boundsMap[id]; } } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp index bf38e33d11..04a00c6a33 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryQtShowViewDialog.cpp @@ -1,328 +1,328 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "berryQtShowViewDialog.h" #include #include #include "berryWorkbenchPlugin.h" #include "berryXMLMemento.h" #include #include #include namespace berry { static const QString TAG_SHOWVIEWDIALOG = "ShowViewDialog"; static const QString TAG_CATEGORY = "category"; static const QString TAG_SELECTION = "selection"; static const QString TAG_GEOMETRY = "geometry"; class ViewFilterProxyModel : public QSortFilterProxyModel { public: ViewFilterProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent) , m_FilterOnKeywords(true) { this->setFilterCaseSensitivity(Qt::CaseInsensitive); } bool filterOnKeywords() const { return m_FilterOnKeywords; } void setFilterOnKeywords(bool filterOnKeywords) { if (m_FilterOnKeywords != filterOnKeywords) { m_FilterOnKeywords = filterOnKeywords; this->filterChanged(); } } protected: bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override { - QRegExp regExp = filterRegExp(); - if (!regExp.isValid() || regExp.isEmpty()) return true; + QRegularExpression regExp = filterRegularExpression(); + if (!regExp.isValid() || regExp.pattern().isEmpty()) return true; QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); QStringList keywords; if (m_FilterOnKeywords) { keywords = sourceModel()->data(sourceIndex, ViewTreeModel::Keywords).toStringList(); } else { if (sourceModel()->hasChildren(sourceIndex)) { // this is a category item int numChildren = sourceModel()->rowCount(sourceIndex); for (int i = 0; i < numChildren; ++i) { keywords.push_back(sourceModel()->data(sourceIndex.child(i, 0)).toString()); } } else { // this is a view item keywords.push_back(sourceModel()->data(sourceIndex).toString()); } } for(auto& keyword : keywords) { if (keyword.contains(regExp)) return true; } return false; } private: bool m_FilterOnKeywords; }; QtShowViewDialog::QtShowViewDialog(const IWorkbenchWindow* window, IViewRegistry* registry, QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) , m_Window(window) , m_ViewReg(registry) , m_FilterModel(nullptr) { m_UserInterface.setupUi(this); m_UserInterface.m_TreeView->header()->setVisible(false); m_UserInterface.m_TreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_FilterModel = new ViewFilterProxyModel(this); auto sourceModel = new ViewTreeModel(window, m_FilterModel); m_FilterModel->setSourceModel(sourceModel); m_UserInterface.m_TreeView->setModel(m_FilterModel); connect(m_UserInterface.m_Filter, SIGNAL(textChanged(QString)), this, SLOT(setFilter(QString))); connect(m_UserInterface.m_TreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(setDescription(QModelIndex))); connect(m_UserInterface.m_TreeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(categoryCollapsed(QModelIndex))); connect(m_UserInterface.m_TreeView, SIGNAL(expanded(QModelIndex)), this, SLOT(categoryExpanded(QModelIndex))); connect(m_UserInterface.m_TreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); connect(m_UserInterface.m_TreeView, SIGNAL(activated(QModelIndex)), this, SLOT(accept())); connect(m_UserInterface.m_TreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection))); connect(m_UserInterface.m_KeywordFilter, SIGNAL(clicked(bool)), this, SLOT(enableKeywordFilter(bool))); this->RestoreState(); m_UserInterface.m_Filter->selectAll(); this->UpdateButtons(); } void QtShowViewDialog::setDescription(const QModelIndex& index) { QString description = m_UserInterface.m_TreeView->model()->data(index, Qt::WhatsThisRole).toString(); m_UserInterface.m_Description->setText(description); } void QtShowViewDialog::enableKeywordFilter(bool enable) { m_FilterModel->setFilterOnKeywords(enable); this->RestoreExpandedState(); } void QtShowViewDialog::setFilter(const QString& filter) { m_FilterModel->setFilterWildcard(filter); this->RestoreExpandedState(); } void QtShowViewDialog::categoryCollapsed(const QModelIndex& index) { m_ExpandedCategories.removeAll(m_FilterModel->mapToSource(index)); } void QtShowViewDialog::categoryExpanded(const QModelIndex& index) { m_ExpandedCategories.push_back(m_FilterModel->mapToSource(index)); } void QtShowViewDialog::selectionChanged(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) { UpdateButtons(); } void QtShowViewDialog::RestoreExpandedState() { int rowCount = m_FilterModel->rowCount(); for (int i = 0; i < rowCount; ++i) { QModelIndex index = m_FilterModel->index(i, 0); if (m_ExpandedCategories.contains(m_FilterModel->mapToSource(index))) { m_UserInterface.m_TreeView->expand(index); } } } void QtShowViewDialog::UpdateButtons() { QPushButton* okBtn = m_UserInterface.m_ButtonBox->button(QDialogButtonBox::Ok); if (okBtn) { okBtn->setEnabled(!m_UserInterface.m_TreeView->selectionModel()->selection().isEmpty()); } } void QtShowViewDialog::RestoreState() { auto* prefs = WorkbenchPlugin::GetDefault()->GetPreferences(); auto str = QString::fromStdString(prefs->Get(TAG_SHOWVIEWDIALOG.toStdString(), "")); if (str.isEmpty()) return; std::stringstream ss(str.toStdString()); XMLMemento::Pointer memento = XMLMemento::CreateReadRoot(ss); bool keywordFilter = false; if (memento->GetBoolean("keywordFilter", keywordFilter)) { m_UserInterface.m_KeywordFilter->setChecked(keywordFilter); m_FilterModel->setFilterOnKeywords(keywordFilter); } QString filter; if (memento->GetString("filter", filter)) { m_UserInterface.m_Filter->setText(filter); } IMemento::Pointer geomChild = memento->GetChild(TAG_GEOMETRY); if (geomChild.IsNotNull()) { QString geom = geomChild->GetTextData(); if (!geom.isEmpty()) { QByteArray ba = QByteArray::fromBase64(geom.toLatin1()); this->restoreGeometry(ba); } } QHash rootIndices; int rowCount = m_FilterModel->sourceModel()->rowCount(); for (int i = 0; i < rowCount; ++i) { QModelIndex sourceIndex = m_FilterModel->sourceModel()->index(i, 0); QString id = sourceIndex.data(ViewTreeModel::Id).toString(); if (!id.isEmpty()) { rootIndices[id] = sourceIndex; } } for (const IMemento::Pointer &categoryChild : memento->GetChildren(TAG_CATEGORY)) { QString id = categoryChild->GetID(); if (!id.isEmpty()) { if (rootIndices.contains(id)) { m_ExpandedCategories.push_back(rootIndices[id]); } } } this->RestoreExpandedState(); QItemSelection itemSelection; for (const IMemento::Pointer &selectionChild : memento->GetChildren(TAG_SELECTION)) { QString id = selectionChild->GetID(); if (!id.isEmpty()) { QModelIndexList indexList = m_FilterModel->match(m_FilterModel->index(0, 0), ViewTreeModel::Id, QVariant::fromValue(id), 1, Qt::MatchExactly | Qt::MatchRecursive); if (!indexList.isEmpty()) { QItemSelection subSelection(indexList.front(), indexList.front()); itemSelection.merge(subSelection, QItemSelectionModel::SelectCurrent); } } } m_UserInterface.m_TreeView->selectionModel()->select(itemSelection, QItemSelectionModel::ClearAndSelect); } void QtShowViewDialog::SaveState() { XMLMemento::Pointer memento = XMLMemento::CreateWriteRoot(TAG_SHOWVIEWDIALOG); memento->PutString("filter", m_UserInterface.m_Filter->text()); memento->PutBoolean("keywordFilter", m_UserInterface.m_KeywordFilter->isChecked()); // dialog geometry QByteArray geom = this->saveGeometry(); IMemento::Pointer geomChild = memento->CreateChild(TAG_GEOMETRY); geomChild->PutTextData(geom.toBase64().constData()); // expanded categories for (const QPersistentModelIndex &index : qAsConst(m_ExpandedCategories)) { if (index.isValid()) { QString id = index.data(ViewTreeModel::Id).toString(); if (!id.isEmpty()) { memento->CreateChild(TAG_CATEGORY, id); } } } // we only record a single selected item. restoring a multi-selection might be // confusing for the user QModelIndexList selectedIndices = m_UserInterface.m_TreeView->selectionModel()->selectedIndexes(); if (!selectedIndices.isEmpty()) { QString id = selectedIndices.back().data(ViewTreeModel::Id).toString(); if (!id.isEmpty()) { memento->CreateChild(TAG_SELECTION, id); } } std::stringstream ss; memento->Save(ss); auto* prefs = WorkbenchPlugin::GetDefault()->GetPreferences(); prefs->Put(TAG_SHOWVIEWDIALOG.toStdString(), ss.str()); prefs->Flush(); } void QtShowViewDialog::done(int r) { this->SaveState(); QDialog::done(r); } QList QtShowViewDialog::GetSelection() const { QList selected; QModelIndexList indices = m_UserInterface.m_TreeView->selectionModel()->selectedIndexes(); for(QModelIndex index : qAsConst(indices)) { QString id = m_FilterModel->data(index, ViewTreeModel::Id).toString(); selected.push_back(id); } return selected; } } diff --git a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp index b6f5c20ae0..d9020f909b 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtWorkbenchWindowAdvisor.cpp @@ -1,1444 +1,1444 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkExtWorkbenchWindowAdvisor.h" #include "QmitkExtActionBarAdvisor.h" #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // UGLYYY #include "internal/QmitkExtWorkbenchWindowAdvisorHack.h" #include "internal/QmitkCommonExtPlugin.h" #include "mitkUndoController.h" #include "mitkVerboseLimitedLinearUndo.h" #include #include #include #include #include #include QmitkExtWorkbenchWindowAdvisorHack* QmitkExtWorkbenchWindowAdvisorHack::undohack = new QmitkExtWorkbenchWindowAdvisorHack(); QString QmitkExtWorkbenchWindowAdvisor::QT_SETTINGS_FILENAME = "QtSettings.ini"; static bool USE_EXPERIMENTAL_COMMAND_CONTRIBUTIONS = false; class PartListenerForTitle: public berry::IPartListener { public: PartListenerForTitle(QmitkExtWorkbenchWindowAdvisor* wa) : windowAdvisor(wa) { } Events::Types GetPartEventTypes() const override { return Events::ACTIVATED | Events::BROUGHT_TO_TOP | Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartActivated(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref.Cast ()) { windowAdvisor->UpdateTitle(false); } } void PartBroughtToTop(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref.Cast ()) { windowAdvisor->UpdateTitle(false); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& /*ref*/) override { windowAdvisor->UpdateTitle(false); } void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override { auto lockedLastActiveEditor = windowAdvisor->lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull() && ref->GetPart(false) == lockedLastActiveEditor) { windowAdvisor->UpdateTitle(true); } } void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override { auto lockedLastActiveEditor = windowAdvisor->lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull() && ref->GetPart(false) == lockedLastActiveEditor) { windowAdvisor->UpdateTitle(false); } } private: QmitkExtWorkbenchWindowAdvisor* windowAdvisor; }; class PartListenerForViewNavigator: public berry::IPartListener { public: PartListenerForViewNavigator(QAction* act) : viewNavigatorAction(act) { } Events::Types GetPartEventTypes() const override { return Events::OPENED | Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartOpened(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.viewnavigator") { viewNavigatorAction->setChecked(true); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.viewnavigator") { viewNavigatorAction->setChecked(false); } } void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.viewnavigator") { viewNavigatorAction->setChecked(true); } } void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.viewnavigator") { viewNavigatorAction->setChecked(false); } } private: QAction* viewNavigatorAction; }; class PartListenerForImageNavigator: public berry::IPartListener { public: PartListenerForImageNavigator(QAction* act) : imageNavigatorAction(act) { } Events::Types GetPartEventTypes() const override { return Events::OPENED | Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartOpened(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(true); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(false); } } void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(true); } } void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(false); } } private: QAction* imageNavigatorAction; }; class PerspectiveListenerForTitle: public berry::IPerspectiveListener { public: PerspectiveListenerForTitle(QmitkExtWorkbenchWindowAdvisor* wa) : windowAdvisor(wa) , perspectivesClosed(false) { } Events::Types GetPerspectiveEventTypes() const override { if (USE_EXPERIMENTAL_COMMAND_CONTRIBUTIONS) { return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED; } else { return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED | Events::CLOSED | Events::OPENED; } } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { windowAdvisor->UpdateTitle(false); } void PerspectiveSavedAs(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*oldPerspective*/, const berry::IPerspectiveDescriptor::Pointer& /*newPerspective*/) override { windowAdvisor->UpdateTitle(false); } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { windowAdvisor->UpdateTitle(false); } void PerspectiveOpened(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { if (perspectivesClosed) { QListIterator i(windowAdvisor->viewActions); while (i.hasNext()) { i.next()->setEnabled(true); } //GetViewRegistry()->Find("org.mitk.views.imagenavigator"); if(windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicombrowser")) { windowAdvisor->openDicomEditorAction->setEnabled(true); } if (windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.stdmultiwidget")) { windowAdvisor->openStdMultiWidgetEditorAction->setEnabled(true); } if (windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.mxnmultiwidget")) { windowAdvisor->openMxNMultiWidgetEditorAction->setEnabled(true); } windowAdvisor->fileSaveProjectAction->setEnabled(true); windowAdvisor->closeProjectAction->setEnabled(true); windowAdvisor->undoAction->setEnabled(true); windowAdvisor->redoAction->setEnabled(true); windowAdvisor->imageNavigatorAction->setEnabled(true); windowAdvisor->viewNavigatorAction->setEnabled(true); windowAdvisor->resetPerspAction->setEnabled(true); if( windowAdvisor->GetShowClosePerspectiveMenuItem() ) { windowAdvisor->closePerspAction->setEnabled(true); } } perspectivesClosed = false; } void PerspectiveClosed(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { berry::IWorkbenchWindow::Pointer wnd = windowAdvisor->GetWindowConfigurer()->GetWindow(); bool allClosed = true; if (wnd->GetActivePage()) { QList perspectives(wnd->GetActivePage()->GetOpenPerspectives()); allClosed = perspectives.empty(); } if (allClosed) { perspectivesClosed = true; QListIterator i(windowAdvisor->viewActions); while (i.hasNext()) { i.next()->setEnabled(false); } if(windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicombrowser")) { windowAdvisor->openDicomEditorAction->setEnabled(false); } if (windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.stdmultiwidget")) { windowAdvisor->openStdMultiWidgetEditorAction->setEnabled(false); } if (windowAdvisor->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.mxnmultiwidget")) { windowAdvisor->openMxNMultiWidgetEditorAction->setEnabled(false); } windowAdvisor->fileSaveProjectAction->setEnabled(false); windowAdvisor->closeProjectAction->setEnabled(false); windowAdvisor->undoAction->setEnabled(false); windowAdvisor->redoAction->setEnabled(false); windowAdvisor->imageNavigatorAction->setEnabled(false); windowAdvisor->viewNavigatorAction->setEnabled(false); windowAdvisor->resetPerspAction->setEnabled(false); if( windowAdvisor->GetShowClosePerspectiveMenuItem() ) { windowAdvisor->closePerspAction->setEnabled(false); } } } private: QmitkExtWorkbenchWindowAdvisor* windowAdvisor; bool perspectivesClosed; }; class PerspectiveListenerForMenu: public berry::IPerspectiveListener { public: PerspectiveListenerForMenu(QmitkExtWorkbenchWindowAdvisor* wa) : windowAdvisor(wa) { } Events::Types GetPerspectiveEventTypes() const override { return Events::ACTIVATED | Events::DEACTIVATED; } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& perspective) override { QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()]; if (action) { action->setChecked(true); } } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& perspective) override { QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()]; if (action) { action->setChecked(false); } } private: QmitkExtWorkbenchWindowAdvisor* windowAdvisor; }; QmitkExtWorkbenchWindowAdvisor::QmitkExtWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor, berry::IWorkbenchWindowConfigurer::Pointer configurer) : berry::WorkbenchWindowAdvisor(configurer) , lastInput(nullptr) , wbAdvisor(wbAdvisor) , showViewToolbar(true) , showPerspectiveToolbar(false) , showVersionInfo(true) , showMitkVersionInfo(true) , showViewMenuItem(true) , showNewWindowMenuItem(false) , showClosePerspectiveMenuItem(true) , viewNavigatorFound(false) , showMemoryIndicator(true) , dropTargetListener(new QmitkDefaultDropTargetListener) { productName = QCoreApplication::applicationName(); viewExcludeList.push_back("org.mitk.views.viewnavigator"); } QmitkExtWorkbenchWindowAdvisor::~QmitkExtWorkbenchWindowAdvisor() { } berry::ActionBarAdvisor::Pointer QmitkExtWorkbenchWindowAdvisor::CreateActionBarAdvisor(berry::IActionBarConfigurer::Pointer configurer) { if (USE_EXPERIMENTAL_COMMAND_CONTRIBUTIONS) { berry::ActionBarAdvisor::Pointer actionBarAdvisor(new QmitkExtActionBarAdvisor(configurer)); return actionBarAdvisor; } else { return berry::WorkbenchWindowAdvisor::CreateActionBarAdvisor(configurer); } } QWidget* QmitkExtWorkbenchWindowAdvisor::CreateEmptyWindowContents(QWidget* parent) { QWidget* parentWidget = static_cast(parent); auto label = new QLabel(parentWidget); label->setText("No perspectives are open. Open a perspective in the Window->Open Perspective menu."); label->setContentsMargins(10,10,10,10); label->setAlignment(Qt::AlignTop); label->setEnabled(false); parentWidget->layout()->addWidget(label); return label; } void QmitkExtWorkbenchWindowAdvisor::ShowClosePerspectiveMenuItem(bool show) { showClosePerspectiveMenuItem = show; } bool QmitkExtWorkbenchWindowAdvisor::GetShowClosePerspectiveMenuItem() { return showClosePerspectiveMenuItem; } void QmitkExtWorkbenchWindowAdvisor::ShowMemoryIndicator(bool show) { showMemoryIndicator = show; } bool QmitkExtWorkbenchWindowAdvisor::GetShowMemoryIndicator() { return showMemoryIndicator; } void QmitkExtWorkbenchWindowAdvisor::ShowNewWindowMenuItem(bool show) { showNewWindowMenuItem = show; } void QmitkExtWorkbenchWindowAdvisor::ShowViewToolbar(bool show) { showViewToolbar = show; } void QmitkExtWorkbenchWindowAdvisor::ShowViewMenuItem(bool show) { showViewMenuItem = show; } void QmitkExtWorkbenchWindowAdvisor::ShowPerspectiveToolbar(bool show) { showPerspectiveToolbar = show; } void QmitkExtWorkbenchWindowAdvisor::ShowVersionInfo(bool show) { showVersionInfo = show; } void QmitkExtWorkbenchWindowAdvisor::ShowMitkVersionInfo(bool show) { showMitkVersionInfo = show; } void QmitkExtWorkbenchWindowAdvisor::SetProductName(const QString& product) { productName = product; } void QmitkExtWorkbenchWindowAdvisor::SetWindowIcon(const QString& wndIcon) { windowIcon = wndIcon; } void QmitkExtWorkbenchWindowAdvisor::PostWindowCreate() { // very bad hack... berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow(); QMainWindow* mainWindow = qobject_cast (window->GetShell()->GetControl()); if (!windowIcon.isEmpty()) { mainWindow->setWindowIcon(QIcon(windowIcon)); } mainWindow->setContextMenuPolicy(Qt::PreventContextMenu); // Load icon theme QIcon::setThemeSearchPaths(QStringList() << QStringLiteral(":/org_mitk_icons/icons/")); QIcon::setThemeName(QStringLiteral("awesome")); // ==== Application menu ============================ QMenuBar* menuBar = mainWindow->menuBar(); menuBar->setContextMenuPolicy(Qt::PreventContextMenu); #ifdef __APPLE__ menuBar->setNativeMenuBar(true); #else menuBar->setNativeMenuBar(false); #endif auto basePath = QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/"); auto fileOpenAction = new QmitkFileOpenAction(berry::QtStyleManager::ThemeIcon(basePath + "document-open.svg"), window); fileOpenAction->setShortcut(QKeySequence::Open); auto fileSaveAction = new QmitkFileSaveAction(berry::QtStyleManager::ThemeIcon(basePath + "document-save.svg"), window); fileSaveAction->setShortcut(QKeySequence::Save); fileSaveProjectAction = new QmitkExtFileSaveProjectAction(window); fileSaveProjectAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "document-save.svg")); closeProjectAction = new QmitkCloseProjectAction(window); closeProjectAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "edit-delete.svg")); auto perspGroup = new QActionGroup(menuBar); std::map VDMap; // sort elements (converting vector to map...) QList::const_iterator iter; berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry(); const QList viewDescriptors = viewRegistry->GetViews(); bool skip = false; for (iter = viewDescriptors.begin(); iter != viewDescriptors.end(); ++iter) { // if viewExcludeList is set, it contains the id-strings of view, which // should not appear as an menu-entry in the menu if (viewExcludeList.size() > 0) { for (int i=0; iGetId()) { skip = true; break; } } if (skip) { skip = false; continue; } } if ((*iter)->GetId() == "org.blueberry.ui.internal.introview") continue; if ((*iter)->GetId() == "org.mitk.views.imagenavigator") continue; if ((*iter)->GetId() == "org.mitk.views.viewnavigator") continue; std::pair p((*iter)->GetLabel(), (*iter)); VDMap.insert(p); } std::map::const_iterator MapIter; for (MapIter = VDMap.begin(); MapIter != VDMap.end(); ++MapIter) { berry::QtShowViewAction* viewAction = new berry::QtShowViewAction(window, (*MapIter).second); viewActions.push_back(viewAction); } if (!USE_EXPERIMENTAL_COMMAND_CONTRIBUTIONS) { QMenu* fileMenu = menuBar->addMenu("&File"); fileMenu->setObjectName("FileMenu"); fileMenu->addAction(fileOpenAction); fileMenu->addAction(fileSaveAction); fileMenu->addAction(fileSaveProjectAction); fileMenu->addAction(closeProjectAction); fileMenu->addSeparator(); QAction* fileExitAction = new QmitkFileExitAction(window); fileExitAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "system-log-out.svg")); fileExitAction->setShortcut(QKeySequence::Quit); fileExitAction->setObjectName("QmitkFileExitAction"); fileMenu->addAction(fileExitAction); // another bad hack to get an edit/undo menu... QMenu* editMenu = menuBar->addMenu("&Edit"); undoAction = editMenu->addAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-undo.svg"), "&Undo", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onUndo()), QKeySequence("CTRL+Z")); undoAction->setToolTip("Undo the last action (not supported by all modules)"); redoAction = editMenu->addAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-redo.svg"), "&Redo", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onRedo()), QKeySequence("CTRL+Y")); redoAction->setToolTip("execute the last action that was undone again (not supported by all modules)"); // ==== Window Menu ========================== QMenu* windowMenu = menuBar->addMenu("Window"); if (showNewWindowMenuItem) { windowMenu->addAction("&New Window", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onNewWindow())); windowMenu->addSeparator(); } QMenu* perspMenu = windowMenu->addMenu("&Open Perspective"); QMenu* viewMenu = nullptr; if (showViewMenuItem) { viewMenu = windowMenu->addMenu("Show &View"); viewMenu->setObjectName("Show View"); } windowMenu->addSeparator(); resetPerspAction = windowMenu->addAction("&Reset Perspective", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onResetPerspective())); if(showClosePerspectiveMenuItem) closePerspAction = windowMenu->addAction("&Close Perspective", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onClosePerspective())); windowMenu->addSeparator(); windowMenu->addAction("&Preferences...", QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onEditPreferences()), QKeySequence("CTRL+P")); // fill perspective menu berry::IPerspectiveRegistry* perspRegistry = window->GetWorkbench()->GetPerspectiveRegistry(); QList perspectives( perspRegistry->GetPerspectives()); skip = false; for (QList::iterator perspIt = perspectives.begin(); perspIt != perspectives.end(); ++perspIt) { // if perspectiveExcludeList is set, it contains the id-strings of perspectives, which // should not appear as an menu-entry in the perspective menu if (perspectiveExcludeList.size() > 0) { for (int i=0; iGetId()) { skip = true; break; } } if (skip) { skip = false; continue; } } QAction* perspAction = new berry::QtOpenPerspectiveAction(window, *perspIt, perspGroup); mapPerspIdToAction.insert((*perspIt)->GetId(), perspAction); } perspMenu->addActions(perspGroup->actions()); if (showViewMenuItem) { for (auto viewAction : qAsConst(viewActions)) { viewMenu->addAction(viewAction); } } // ===== Help menu ==================================== QMenu* helpMenu = menuBar->addMenu("&Help"); helpMenu->addAction("&Welcome",this, SLOT(onIntro())); helpMenu->addAction("&Open Help Perspective", this, SLOT(onHelpOpenHelpPerspective())); helpMenu->addAction("&Context Help",this, SLOT(onHelp()), QKeySequence("F1")); helpMenu->addAction("&About",this, SLOT(onAbout())); // ===================================================== } else { undoAction = new QmitkUndoAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-undo.svg"), nullptr); undoAction->setShortcut(QKeySequence::Undo); redoAction = new QmitkRedoAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-redo.svg"), nullptr); redoAction->setShortcut(QKeySequence::Redo); } // toolbar for showing file open, undo, redo and other main actions auto mainActionsToolBar = new QToolBar; mainActionsToolBar->setObjectName("mainActionsToolBar"); mainActionsToolBar->setContextMenuPolicy(Qt::PreventContextMenu); #ifdef __APPLE__ mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon ); #else mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon ); #endif basePath = QStringLiteral(":/org.mitk.gui.qt.ext/"); imageNavigatorAction = new QAction(berry::QtStyleManager::ThemeIcon(basePath + "image_navigator.svg"), "&Image Navigator", nullptr); bool imageNavigatorViewFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.imagenavigator"); if (this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicombrowser")) { openDicomEditorAction = new QmitkOpenDicomEditorAction(berry::QtStyleManager::ThemeIcon(basePath + "dicom.svg"), window); } if (this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.stdmultiwidget")) { openStdMultiWidgetEditorAction = new QmitkOpenStdMultiWidgetEditorAction(berry::QtStyleManager::ThemeIcon(basePath + "Editor.svg"), window); } if (this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.mxnmultiwidget")) { openMxNMultiWidgetEditorAction = new QmitkOpenMxNMultiWidgetEditorAction(berry::QtStyleManager::ThemeIcon(basePath + "Editor.svg"), window); } if (imageNavigatorViewFound) { QObject::connect(imageNavigatorAction, SIGNAL(triggered(bool)), QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onImageNavigator())); imageNavigatorAction->setCheckable(true); // add part listener for image navigator imageNavigatorPartListener.reset(new PartListenerForImageNavigator(imageNavigatorAction)); window->GetPartService()->AddPartListener(imageNavigatorPartListener.data()); berry::IViewPart::Pointer imageNavigatorView = window->GetActivePage()->FindView("org.mitk.views.imagenavigator"); imageNavigatorAction->setChecked(false); if (imageNavigatorView) { bool isImageNavigatorVisible = window->GetActivePage()->IsPartVisible(imageNavigatorView); if (isImageNavigatorVisible) imageNavigatorAction->setChecked(true); } imageNavigatorAction->setToolTip("Toggle image navigator for navigating through image"); } viewNavigatorAction = new QAction(berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org.mitk.gui.qt.ext/view-manager.svg")),"&View Navigator", nullptr); viewNavigatorFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.viewnavigator"); if (viewNavigatorFound) { QObject::connect(viewNavigatorAction, SIGNAL(triggered(bool)), QmitkExtWorkbenchWindowAdvisorHack::undohack, SLOT(onViewNavigator())); viewNavigatorAction->setCheckable(true); // add part listener for view navigator viewNavigatorPartListener.reset(new PartListenerForViewNavigator(viewNavigatorAction)); window->GetPartService()->AddPartListener(viewNavigatorPartListener.data()); berry::IViewPart::Pointer viewnavigatorview = window->GetActivePage()->FindView("org.mitk.views.viewnavigator"); viewNavigatorAction->setChecked(false); if (viewnavigatorview) { bool isViewNavigatorVisible = window->GetActivePage()->IsPartVisible(viewnavigatorview); if (isViewNavigatorVisible) viewNavigatorAction->setChecked(true); } viewNavigatorAction->setToolTip("Toggle View Navigator"); } mainActionsToolBar->addAction(fileOpenAction); mainActionsToolBar->addAction(fileSaveProjectAction); mainActionsToolBar->addAction(closeProjectAction); mainActionsToolBar->addAction(undoAction); mainActionsToolBar->addAction(redoAction); if(this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.dicombrowser")) { mainActionsToolBar->addAction(openDicomEditorAction); } if (this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.stdmultiwidget")) { mainActionsToolBar->addAction(openStdMultiWidgetEditorAction); } if (this->GetWindowConfigurer()->GetWindow()->GetWorkbench()->GetEditorRegistry()->FindEditor("org.mitk.editors.mxnmultiwidget")) { mainActionsToolBar->addAction(openMxNMultiWidgetEditorAction); } if (imageNavigatorViewFound) { mainActionsToolBar->addAction(imageNavigatorAction); } if (viewNavigatorFound) { mainActionsToolBar->addAction(viewNavigatorAction); } mainWindow->addToolBar(mainActionsToolBar); // ==== Perspective Toolbar ================================== auto qPerspectiveToolbar = new QToolBar; qPerspectiveToolbar->setObjectName("perspectiveToolBar"); if (showPerspectiveToolbar) { qPerspectiveToolbar->addActions(perspGroup->actions()); mainWindow->addToolBar(qPerspectiveToolbar); } else delete qPerspectiveToolbar; if (showViewToolbar) { auto* prefService = mitk::CoreServices::GetPreferencesService(); auto* stylePrefs = prefService->GetSystemPreferences()->Node(berry::QtPreferences::QT_STYLES_NODE); bool showCategoryNames = stylePrefs->GetBool(berry::QtPreferences::QT_SHOW_TOOLBAR_CATEGORY_NAMES, true); // Order view descriptors by category QMultiMap categoryViewDescriptorMap; for (const auto &labelViewDescriptorPair : VDMap) { auto viewDescriptor = labelViewDescriptorPair.second; auto category = !viewDescriptor->GetCategoryPath().isEmpty() ? viewDescriptor->GetCategoryPath().back() : QString(); categoryViewDescriptorMap.insert(category, viewDescriptor); } // Create a separate toolbar for each category for (const auto &category : categoryViewDescriptorMap.uniqueKeys()) { auto viewDescriptorsInCurrentCategory = categoryViewDescriptorMap.values(category); if (!viewDescriptorsInCurrentCategory.isEmpty()) { auto toolbar = new QToolBar; toolbar->setObjectName(category + " View Toolbar"); mainWindow->addToolBar(toolbar); if (showCategoryNames && !category.isEmpty()) { auto categoryButton = new QToolButton; categoryButton->setToolButtonStyle(Qt::ToolButtonTextOnly); categoryButton->setText(category); categoryButton->setStyleSheet("background: transparent; margin: 0; padding: 0;"); toolbar->addWidget(categoryButton); connect(categoryButton, &QToolButton::clicked, [toolbar]() { for (QWidget* widget : toolbar->findChildren()) { if (QStringLiteral("qt_toolbar_ext_button") == widget->objectName() && widget->isVisible()) { QMouseEvent pressEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QApplication::sendEvent(widget, &pressEvent); QApplication::sendEvent(widget, &releaseEvent); } } }); } for (const auto &viewDescriptor : qAsConst(viewDescriptorsInCurrentCategory)) { auto viewAction = new berry::QtShowViewAction(window, viewDescriptor); toolbar->addAction(viewAction); } } } } QSettings settings(GetQSettingsFile(), QSettings::IniFormat); mainWindow->restoreState(settings.value("ToolbarPosition").toByteArray()); auto qStatusBar = new QStatusBar(); //creating a QmitkStatusBar for Output on the QStatusBar and connecting it with the MainStatusBar auto statusBar = new QmitkStatusBar(qStatusBar); //disabling the SizeGrip in the lower right corner statusBar->SetSizeGripEnabled(false); auto progBar = new QmitkProgressBar(); qStatusBar->addPermanentWidget(progBar, 0); progBar->hide(); // progBar->AddStepsToDo(2); // progBar->Progress(1); mainWindow->setStatusBar(qStatusBar); if (showMemoryIndicator) { auto memoryIndicator = new QmitkMemoryUsageIndicatorView(); qStatusBar->addPermanentWidget(memoryIndicator, 0); } } void QmitkExtWorkbenchWindowAdvisor::PreWindowOpen() { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); // show the shortcut bar and progress indicator, which are hidden by // default //configurer->SetShowPerspectiveBar(true); //configurer->SetShowFastViewBars(true); //configurer->SetShowProgressIndicator(true); // // add the drag and drop support for the editor area // configurer.addEditorAreaTransfer(EditorInputTransfer.getInstance()); // configurer.addEditorAreaTransfer(ResourceTransfer.getInstance()); // configurer.addEditorAreaTransfer(FileTransfer.getInstance()); // configurer.addEditorAreaTransfer(MarkerTransfer.getInstance()); // configurer.configureEditorAreaDropListener(new EditorAreaDropAdapter( // configurer.getWindow())); this->HookTitleUpdateListeners(configurer); menuPerspectiveListener.reset(new PerspectiveListenerForMenu(this)); configurer->GetWindow()->AddPerspectiveListener(menuPerspectiveListener.data()); configurer->AddEditorAreaTransfer(QStringList("text/uri-list")); configurer->ConfigureEditorAreaDropListener(dropTargetListener.data()); } void QmitkExtWorkbenchWindowAdvisor::PostWindowOpen() { berry::WorkbenchWindowAdvisor::PostWindowOpen(); // Force Rendering Window Creation on startup. berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); ctkPluginContext* context = QmitkCommonExtPlugin::getContext(); ctkServiceReference serviceRef = context->getServiceReference(); if (serviceRef) { mitk::IDataStorageService *dsService = context->getService(serviceRef); if (dsService) { mitk::IDataStorageReference::Pointer dsRef = dsService->GetDataStorage(); mitk::DataStorageEditorInput::Pointer dsInput(new mitk::DataStorageEditorInput(dsRef)); mitk::WorkbenchUtil::OpenEditor(configurer->GetWindow()->GetActivePage(),dsInput); } } auto introPart = configurer->GetWindow()->GetWorkbench()->GetIntroManager()->GetIntro(); if (introPart.IsNotNull()) { configurer->GetWindow()->GetWorkbench()->GetIntroManager()->ShowIntro(GetWindowConfigurer()->GetWindow(), false); } } void QmitkExtWorkbenchWindowAdvisor::onIntro() { QmitkExtWorkbenchWindowAdvisorHack::undohack->onIntro(); } void QmitkExtWorkbenchWindowAdvisor::onHelp() { QmitkExtWorkbenchWindowAdvisorHack::undohack->onHelp(); } void QmitkExtWorkbenchWindowAdvisor::onHelpOpenHelpPerspective() { QmitkExtWorkbenchWindowAdvisorHack::undohack->onHelpOpenHelpPerspective(); } void QmitkExtWorkbenchWindowAdvisor::onAbout() { QmitkExtWorkbenchWindowAdvisorHack::undohack->onAbout(); } //-------------------------------------------------------------------------------- // Ugly hack from here on. Feel free to delete when command framework // and undo buttons are done. //-------------------------------------------------------------------------------- QmitkExtWorkbenchWindowAdvisorHack::QmitkExtWorkbenchWindowAdvisorHack() : QObject() { } QmitkExtWorkbenchWindowAdvisorHack::~QmitkExtWorkbenchWindowAdvisorHack() { } void QmitkExtWorkbenchWindowAdvisorHack::onUndo() { mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel(); if (model) { if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast( model )) { mitk::VerboseLimitedLinearUndo::StackDescription descriptions = verboseundo->GetUndoDescriptions(); if (descriptions.size() >= 1) { MITK_INFO << "Undo " << descriptions.front().second; } } model->Undo(); } else { MITK_ERROR << "No undo model instantiated"; } } void QmitkExtWorkbenchWindowAdvisorHack::onRedo() { mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel(); if (model) { if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast( model )) { mitk::VerboseLimitedLinearUndo::StackDescription descriptions = verboseundo->GetRedoDescriptions(); if (descriptions.size() >= 1) { MITK_INFO << "Redo " << descriptions.front().second; } } model->Redo(); } else { MITK_ERROR << "No undo model instantiated"; } } // safe calls to the complete chain // berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.imagenavigator"); // to cover for all possible cases of closed pages etc. static void SafeHandleNavigatorView(QString view_query_name) { berry::IWorkbench* wbench = berry::PlatformUI::GetWorkbench(); if( wbench == nullptr ) return; berry::IWorkbenchWindow::Pointer wbench_window = wbench->GetActiveWorkbenchWindow(); if( wbench_window.IsNull() ) return; berry::IWorkbenchPage::Pointer wbench_page = wbench_window->GetActivePage(); if( wbench_page.IsNull() ) return; auto wbench_view = wbench_page->FindView( view_query_name ); if( wbench_view.IsNotNull() ) { bool isViewVisible = wbench_page->IsPartVisible( wbench_view ); if( isViewVisible ) { wbench_page->HideView( wbench_view ); return; } } wbench_page->ShowView( view_query_name ); } void QmitkExtWorkbenchWindowAdvisorHack::onImageNavigator() { // show/hide ImageNavigatorView SafeHandleNavigatorView("org.mitk.views.imagenavigator"); } void QmitkExtWorkbenchWindowAdvisorHack::onViewNavigator() { // show/hide viewnavigatorView SafeHandleNavigatorView("org.mitk.views.viewnavigator"); } void QmitkExtWorkbenchWindowAdvisorHack::onEditPreferences() { QmitkPreferencesDialog _PreferencesDialog(QApplication::activeWindow()); _PreferencesDialog.exec(); } void QmitkExtWorkbenchWindowAdvisorHack::onQuit() { berry::PlatformUI::GetWorkbench()->Close(); } void QmitkExtWorkbenchWindowAdvisorHack::onResetPerspective() { berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective(); } void QmitkExtWorkbenchWindowAdvisorHack::onClosePerspective() { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); page->ClosePerspective(page->GetPerspective(), true, true); } void QmitkExtWorkbenchWindowAdvisorHack::onNewWindow() { berry::PlatformUI::GetWorkbench()->OpenWorkbenchWindow(nullptr); } void QmitkExtWorkbenchWindowAdvisorHack::onIntro() { bool hasIntro = berry::PlatformUI::GetWorkbench()->GetIntroManager()->HasIntro(); if (!hasIntro) { - QRegExp reg("(.*)(\\n)*"); - QRegExp reg2("(\\n)*(.*)"); + QRegularExpression reg("(.*)(\\n)*"); + QRegularExpression reg2("(\\n)*(.*)"); QFile file(":/org.mitk.gui.qt.ext/index.html"); file.open(QIODevice::ReadOnly | QIODevice::Text); //text file only for reading QString text = QString(file.readAll()); file.close(); QString title = text; title.replace(reg, ""); title.replace(reg2, ""); std::cout << title.toStdString() << std::endl; QMessageBox::information(nullptr, title, text, "Close"); } else { berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro( berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(), false); } } void QmitkExtWorkbenchWindowAdvisorHack::onHelp() { ctkPluginContext* context = QmitkCommonExtPlugin::getContext(); if (context == nullptr) { MITK_WARN << "Plugin context not set, unable to open context help"; return; } // Check if the org.blueberry.ui.qt.help plug-in is installed and started QList > plugins = context->getPlugins(); foreach(QSharedPointer p, plugins) { if (p->getSymbolicName() == "org.blueberry.ui.qt.help") { if (p->getState() != ctkPlugin::ACTIVE) { // try to activate the plug-in explicitly try { p->start(ctkPlugin::START_TRANSIENT); } catch (const ctkPluginException& pe) { MITK_ERROR << "Activating org.blueberry.ui.qt.help failed: " << pe.what(); return; } } } } ctkServiceReference eventAdminRef = context->getServiceReference(); ctkEventAdmin* eventAdmin = nullptr; if (eventAdminRef) { eventAdmin = context->getService(eventAdminRef); } if (eventAdmin == nullptr) { MITK_WARN << "ctkEventAdmin service not found. Unable to open context help"; } else { ctkEvent ev("org/blueberry/ui/help/CONTEXTHELP_REQUESTED"); eventAdmin->postEvent(ev); } } void QmitkExtWorkbenchWindowAdvisorHack::onHelpOpenHelpPerspective() { berry::PlatformUI::GetWorkbench()->ShowPerspective("org.blueberry.perspectives.help", berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()); } void QmitkExtWorkbenchWindowAdvisorHack::onAbout() { auto aboutDialog = new QmitkAboutDialog(QApplication::activeWindow(),nullptr); aboutDialog->open(); } void QmitkExtWorkbenchWindowAdvisor::HookTitleUpdateListeners(berry::IWorkbenchWindowConfigurer::Pointer configurer) { // hook up the listeners to update the window title titlePartListener.reset(new PartListenerForTitle(this)); titlePerspectiveListener.reset(new PerspectiveListenerForTitle(this)); editorPropertyListener.reset(new berry::PropertyChangeIntAdapter< QmitkExtWorkbenchWindowAdvisor>(this, &QmitkExtWorkbenchWindowAdvisor::PropertyChange)); // configurer.getWindow().addPageListener(new IPageListener() { // public void pageActivated(IWorkbenchPage page) { // updateTitle(false); // } // // public void pageClosed(IWorkbenchPage page) { // updateTitle(false); // } // // public void pageOpened(IWorkbenchPage page) { // // do nothing // } // }); configurer->GetWindow()->AddPerspectiveListener(titlePerspectiveListener.data()); configurer->GetWindow()->GetPartService()->AddPartListener(titlePartListener.data()); } QString QmitkExtWorkbenchWindowAdvisor::ComputeTitle() { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); berry::IWorkbenchPage::Pointer currentPage = configurer->GetWindow()->GetActivePage(); berry::IEditorPart::Pointer activeEditor; if (currentPage) { activeEditor = lastActiveEditor.Lock(); } QString title; berry::IProduct::Pointer product = berry::Platform::GetProduct(); if (product.IsNotNull()) { title = product->GetName(); } if (title.isEmpty()) { // instead of the product name, we use a custom variable for now title = productName; } if(showMitkVersionInfo) { QString mitkVersionInfo = MITK_REVISION_DESC; if(mitkVersionInfo.isEmpty()) mitkVersionInfo = MITK_VERSION_STRING; title += " " + mitkVersionInfo; } if (showVersionInfo) { // add version informatioin QString versions = QString(" (ITK %1.%2.%3 | VTK %4.%5.%6 | Qt %7)") .arg(ITK_VERSION_MAJOR).arg(ITK_VERSION_MINOR).arg(ITK_VERSION_PATCH) .arg(VTK_MAJOR_VERSION).arg(VTK_MINOR_VERSION).arg(VTK_BUILD_VERSION) .arg(QT_VERSION_STR); title += versions; } if (currentPage) { if (activeEditor) { lastEditorTitle = activeEditor->GetTitleToolTip(); if (!lastEditorTitle.isEmpty()) title = lastEditorTitle + " - " + title; } berry::IPerspectiveDescriptor::Pointer persp = currentPage->GetPerspective(); QString label = ""; if (persp) { label = persp->GetLabel(); } berry::IAdaptable* input = currentPage->GetInput(); if (input && input != wbAdvisor->GetDefaultPageInput()) { label = currentPage->GetLabel(); } if (!label.isEmpty()) { title = label + " - " + title; } } title += " (Not for use in diagnosis or treatment of patients)"; return title; } void QmitkExtWorkbenchWindowAdvisor::RecomputeTitle() { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); QString oldTitle = configurer->GetTitle(); QString newTitle = ComputeTitle(); if (newTitle != oldTitle) { configurer->SetTitle(newTitle); } } void QmitkExtWorkbenchWindowAdvisor::UpdateTitle(bool editorHidden) { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); berry::IWorkbenchWindow::Pointer window = configurer->GetWindow(); berry::IEditorPart::Pointer activeEditor; berry::IWorkbenchPage::Pointer currentPage = window->GetActivePage(); berry::IPerspectiveDescriptor::Pointer persp; berry::IAdaptable* input = nullptr; if (currentPage) { activeEditor = currentPage->GetActiveEditor(); persp = currentPage->GetPerspective(); input = currentPage->GetInput(); } if (editorHidden) { activeEditor = nullptr; } // Nothing to do if the editor hasn't changed if (activeEditor == lastActiveEditor.Lock() && currentPage == lastActivePage.Lock() && persp == lastPerspective.Lock() && input == lastInput) { return; } auto lockedLastActiveEditor = lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull()) { lockedLastActiveEditor->RemovePropertyListener(editorPropertyListener.data()); } lastActiveEditor = activeEditor; lastActivePage = currentPage; lastPerspective = persp; lastInput = input; if (activeEditor) { activeEditor->AddPropertyListener(editorPropertyListener.data()); } RecomputeTitle(); } void QmitkExtWorkbenchWindowAdvisor::PropertyChange(const berry::Object::Pointer& /*source*/, int propId) { if (propId == berry::IWorkbenchPartConstants::PROP_TITLE) { auto lockedLastActiveEditor = lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull()) { QString newTitle = lockedLastActiveEditor->GetPartName(); if (lastEditorTitle != newTitle) { RecomputeTitle(); } } } } void QmitkExtWorkbenchWindowAdvisor::SetPerspectiveExcludeList(const QList& v) { this->perspectiveExcludeList = v; } QList QmitkExtWorkbenchWindowAdvisor::GetPerspectiveExcludeList() { return this->perspectiveExcludeList; } void QmitkExtWorkbenchWindowAdvisor::SetViewExcludeList(const QList& v) { this->viewExcludeList = v; } QList QmitkExtWorkbenchWindowAdvisor::GetViewExcludeList() { return this->viewExcludeList; } void QmitkExtWorkbenchWindowAdvisor::PostWindowClose() { berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow(); QMainWindow* mainWindow = static_cast (window->GetShell()->GetControl()); auto fileName = this->GetQSettingsFile(); if (!fileName.isEmpty()) { QSettings settings(fileName, QSettings::IniFormat); settings.setValue("ToolbarPosition", mainWindow->saveState()); } } QString QmitkExtWorkbenchWindowAdvisor::GetQSettingsFile() const { QFileInfo settingsInfo = QmitkCommonExtPlugin::getContext()->getDataFile(QT_SETTINGS_FILENAME); return settingsInfo.canonicalFilePath(); } diff --git a/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp b/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp index 35379f49fa..3cbb9d8ac1 100644 --- a/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp +++ b/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp @@ -1,1158 +1,1158 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkFlowApplicationWorkbenchWindowAdvisor.h" #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "QmitkExtFileSaveProjectAction.h" #include #include #include #include #include #include #include #include #include #include // UGLYYY #include "QmitkFlowApplicationWorkbenchWindowAdvisorHack.h" #include "QmitkFlowApplicationPlugin.h" #include "mitkUndoController.h" #include "mitkVerboseLimitedLinearUndo.h" #include #include #include #include #include #include QmitkFlowApplicationWorkbenchWindowAdvisorHack* QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack = new QmitkFlowApplicationWorkbenchWindowAdvisorHack(); QString QmitkFlowApplicationWorkbenchWindowAdvisor::QT_SETTINGS_FILENAME = "QtSettings.ini"; class PartListenerForTitle: public berry::IPartListener { public: PartListenerForTitle(QmitkFlowApplicationWorkbenchWindowAdvisor* wa) : windowAdvisor(wa) { } Events::Types GetPartEventTypes() const override { return Events::ACTIVATED | Events::BROUGHT_TO_TOP | Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartActivated(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref.Cast ()) { windowAdvisor->UpdateTitle(false); } } void PartBroughtToTop(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref.Cast ()) { windowAdvisor->UpdateTitle(false); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& /*ref*/) override { windowAdvisor->UpdateTitle(false); } void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override { auto lockedLastActiveEditor = windowAdvisor->lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull() && ref->GetPart(false) == lockedLastActiveEditor) { windowAdvisor->UpdateTitle(true); } } void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override { auto lockedLastActiveEditor = windowAdvisor->lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull() && ref->GetPart(false) == lockedLastActiveEditor) { windowAdvisor->UpdateTitle(false); } } private: QmitkFlowApplicationWorkbenchWindowAdvisor* windowAdvisor; }; class PartListenerForImageNavigator: public berry::IPartListener { public: PartListenerForImageNavigator(QAction* act) : imageNavigatorAction(act) { } Events::Types GetPartEventTypes() const override { return Events::OPENED | Events::CLOSED | Events::HIDDEN | Events::VISIBLE; } void PartOpened(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(true); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(false); } } void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(true); } } void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override { if (ref->GetId()=="org.mitk.views.imagenavigator") { imageNavigatorAction->setChecked(false); } } private: QAction* imageNavigatorAction; }; class PerspectiveListenerForTitle: public berry::IPerspectiveListener { public: PerspectiveListenerForTitle(QmitkFlowApplicationWorkbenchWindowAdvisor* wa) : windowAdvisor(wa) , perspectivesClosed(false) { } Events::Types GetPerspectiveEventTypes() const override { return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED | Events::CLOSED | Events::OPENED; } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { windowAdvisor->UpdateTitle(false); } void PerspectiveSavedAs(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*oldPerspective*/, const berry::IPerspectiveDescriptor::Pointer& /*newPerspective*/) override { windowAdvisor->UpdateTitle(false); } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { windowAdvisor->UpdateTitle(false); } void PerspectiveOpened(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { if (perspectivesClosed) { QListIterator i(windowAdvisor->viewActions); while (i.hasNext()) { i.next()->setEnabled(true); } windowAdvisor->fileSaveProjectAction->setEnabled(true); windowAdvisor->undoAction->setEnabled(true); windowAdvisor->redoAction->setEnabled(true); windowAdvisor->imageNavigatorAction->setEnabled(true); windowAdvisor->resetPerspAction->setEnabled(true); } perspectivesClosed = false; } void PerspectiveClosed(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { berry::IWorkbenchWindow::Pointer wnd = windowAdvisor->GetWindowConfigurer()->GetWindow(); bool allClosed = true; if (wnd->GetActivePage()) { QList perspectives(wnd->GetActivePage()->GetOpenPerspectives()); allClosed = perspectives.empty(); } if (allClosed) { perspectivesClosed = true; QListIterator i(windowAdvisor->viewActions); while (i.hasNext()) { i.next()->setEnabled(false); } windowAdvisor->fileSaveProjectAction->setEnabled(false); windowAdvisor->undoAction->setEnabled(false); windowAdvisor->redoAction->setEnabled(false); windowAdvisor->imageNavigatorAction->setEnabled(false); windowAdvisor->resetPerspAction->setEnabled(false); } } private: QmitkFlowApplicationWorkbenchWindowAdvisor* windowAdvisor; bool perspectivesClosed; }; class PerspectiveListenerForMenu: public berry::IPerspectiveListener { public: PerspectiveListenerForMenu(QmitkFlowApplicationWorkbenchWindowAdvisor* wa) : windowAdvisor(wa) { } Events::Types GetPerspectiveEventTypes() const override { return Events::ACTIVATED | Events::DEACTIVATED; } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& perspective) override { QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()]; if (action) { action->setChecked(true); } } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& perspective) override { QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()]; if (action) { action->setChecked(false); } } private: QmitkFlowApplicationWorkbenchWindowAdvisor* windowAdvisor; }; QmitkFlowApplicationWorkbenchWindowAdvisor::QmitkFlowApplicationWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor, berry::IWorkbenchWindowConfigurer::Pointer configurer) : berry::WorkbenchWindowAdvisor(configurer) , lastInput(nullptr) , wbAdvisor(wbAdvisor) , showViewToolbar(true) , showVersionInfo(true) , showMitkVersionInfo(true) , showMemoryIndicator(true) , dropTargetListener(new QmitkDefaultDropTargetListener) { productName = QCoreApplication::applicationName(); viewExcludeList.push_back("org.mitk.views.viewnavigator"); } QmitkFlowApplicationWorkbenchWindowAdvisor::~QmitkFlowApplicationWorkbenchWindowAdvisor() { } QWidget* QmitkFlowApplicationWorkbenchWindowAdvisor::CreateEmptyWindowContents(QWidget* parent) { QWidget* parentWidget = static_cast(parent); auto label = new QLabel(parentWidget); label->setText("No perspectives are open. Open a perspective in the Window->Open Perspective menu."); label->setContentsMargins(10,10,10,10); label->setAlignment(Qt::AlignTop); label->setEnabled(false); parentWidget->layout()->addWidget(label); return label; } void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowMemoryIndicator(bool show) { showMemoryIndicator = show; } bool QmitkFlowApplicationWorkbenchWindowAdvisor::GetShowMemoryIndicator() { return showMemoryIndicator; } void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowViewToolbar(bool show) { showViewToolbar = show; } void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowVersionInfo(bool show) { showVersionInfo = show; } void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowMitkVersionInfo(bool show) { showMitkVersionInfo = show; } void QmitkFlowApplicationWorkbenchWindowAdvisor::SetProductName(const QString& product) { productName = product; } void QmitkFlowApplicationWorkbenchWindowAdvisor::SetWindowIcon(const QString& wndIcon) { windowIcon = wndIcon; } void QmitkFlowApplicationWorkbenchWindowAdvisor::PostWindowCreate() { // very bad hack... berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow(); QMainWindow* mainWindow = qobject_cast (window->GetShell()->GetControl()); if (!windowIcon.isEmpty()) { mainWindow->setWindowIcon(QIcon(windowIcon)); } mainWindow->setContextMenuPolicy(Qt::PreventContextMenu); // Load icon theme QIcon::setThemeSearchPaths(QStringList() << QStringLiteral(":/org_mitk_icons/icons/")); QIcon::setThemeName(QStringLiteral("awesome")); // ==== Application menu ============================ QMenuBar* menuBar = mainWindow->menuBar(); menuBar->setContextMenuPolicy(Qt::PreventContextMenu); #ifdef __APPLE__ menuBar->setNativeMenuBar(true); #else menuBar->setNativeMenuBar(false); #endif auto basePath = QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/"); fileSaveProjectAction = new QmitkExtFileSaveProjectAction(window); fileSaveProjectAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "document-save.svg")); auto perspGroup = new QActionGroup(menuBar); std::map VDMap; // sort elements (converting vector to map...) QList::const_iterator iter; berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry(); const QList viewDescriptors = viewRegistry->GetViews(); bool skip = false; for (iter = viewDescriptors.begin(); iter != viewDescriptors.end(); ++iter) { // if viewExcludeList is set, it contains the id-strings of view, which // should not appear as an menu-entry in the menu if (viewExcludeList.size() > 0) { for (int i=0; iGetId()) { skip = true; break; } } if (skip) { skip = false; continue; } } if ((*iter)->GetId() == "org.blueberry.ui.internal.introview") continue; if ((*iter)->GetId() == "org.mitk.views.imagenavigator") continue; if ((*iter)->GetId() == "org.mitk.views.viewnavigator") continue; std::pair p((*iter)->GetLabel(), (*iter)); VDMap.insert(p); } std::map::const_iterator MapIter; for (MapIter = VDMap.begin(); MapIter != VDMap.end(); ++MapIter) { berry::QtShowViewAction* viewAction = new berry::QtShowViewAction(window, (*MapIter).second); viewActions.push_back(viewAction); } QMenu* fileMenu = menuBar->addMenu("&File"); fileMenu->setObjectName("FileMenu"); fileMenu->addAction(fileSaveProjectAction); fileMenu->addSeparator(); QAction* fileExitAction = new QmitkFileExitAction(window); fileExitAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "system-log-out.svg")); fileExitAction->setShortcut(QKeySequence::Quit); fileExitAction->setObjectName("QmitkFileExitAction"); fileMenu->addAction(fileExitAction); // another bad hack to get an edit/undo menu... QMenu* editMenu = menuBar->addMenu("&Edit"); undoAction = editMenu->addAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-undo.svg"), "&Undo", QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onUndo()), QKeySequence("CTRL+Z")); undoAction->setToolTip("Undo the last action (not supported by all modules)"); redoAction = editMenu->addAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-redo.svg"), "&Redo", QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onRedo()), QKeySequence("CTRL+Y")); redoAction->setToolTip("execute the last action that was undone again (not supported by all modules)"); // ==== Window Menu ========================== QMenu* windowMenu = menuBar->addMenu("Window"); QMenu* perspMenu = windowMenu->addMenu("&Open Perspective"); windowMenu->addSeparator(); resetPerspAction = windowMenu->addAction("&Reset Perspective", QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onResetPerspective())); windowMenu->addSeparator(); windowMenu->addAction("&Preferences...", QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onEditPreferences()), QKeySequence("CTRL+P")); // fill perspective menu berry::IPerspectiveRegistry* perspRegistry = window->GetWorkbench()->GetPerspectiveRegistry(); QList perspectives( perspRegistry->GetPerspectives()); skip = false; for (QList::iterator perspIt = perspectives.begin(); perspIt != perspectives.end(); ++perspIt) { // if perspectiveExcludeList is set, it contains the id-strings of perspectives, which // should not appear as an menu-entry in the perspective menu if (perspectiveExcludeList.size() > 0) { for (int i=0; iGetId()) { skip = true; break; } } if (skip) { skip = false; continue; } } QAction* perspAction = new berry::QtOpenPerspectiveAction(window, *perspIt, perspGroup); mapPerspIdToAction.insert((*perspIt)->GetId(), perspAction); } perspMenu->addActions(perspGroup->actions()); // ===== Help menu ==================================== QMenu* helpMenu = menuBar->addMenu("&Help"); helpMenu->addAction("&Welcome",this, SLOT(onIntro())); helpMenu->addAction("&Open Help Perspective", this, SLOT(onHelpOpenHelpPerspective())); helpMenu->addAction("&Context Help",this, SLOT(onHelp()), QKeySequence("F1")); helpMenu->addAction("&About",this, SLOT(onAbout())); // ===================================================== // toolbar for showing file open, undo, redo and other main actions auto mainActionsToolBar = new QToolBar; mainActionsToolBar->setObjectName("mainActionsToolBar"); mainActionsToolBar->setContextMenuPolicy(Qt::PreventContextMenu); #ifdef __APPLE__ mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon ); #else mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon ); #endif basePath = QStringLiteral(":/org.mitk.gui.qt.ext/"); imageNavigatorAction = new QAction(berry::QtStyleManager::ThemeIcon(basePath + "image_navigator.svg"), "&Image Navigator", nullptr); bool imageNavigatorViewFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.imagenavigator"); if (imageNavigatorViewFound) { QObject::connect(imageNavigatorAction, SIGNAL(triggered(bool)), QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onImageNavigator())); imageNavigatorAction->setCheckable(true); // add part listener for image navigator imageNavigatorPartListener.reset(new PartListenerForImageNavigator(imageNavigatorAction)); window->GetPartService()->AddPartListener(imageNavigatorPartListener.data()); berry::IViewPart::Pointer imageNavigatorView = window->GetActivePage()->FindView("org.mitk.views.imagenavigator"); imageNavigatorAction->setChecked(false); if (imageNavigatorView) { bool isImageNavigatorVisible = window->GetActivePage()->IsPartVisible(imageNavigatorView); if (isImageNavigatorVisible) imageNavigatorAction->setChecked(true); } imageNavigatorAction->setToolTip("Toggle image navigator for navigating through image"); } mainActionsToolBar->addAction(undoAction); mainActionsToolBar->addAction(redoAction); if (imageNavigatorViewFound) { mainActionsToolBar->addAction(imageNavigatorAction); } mainWindow->addToolBar(mainActionsToolBar); // ==== View Toolbar ================================== if (showViewToolbar) { auto* prefService = mitk::CoreServices::GetPreferencesService(); auto* stylePrefs = prefService->GetSystemPreferences()->Node(berry::QtPreferences::QT_STYLES_NODE); bool showCategoryNames = stylePrefs->GetBool(berry::QtPreferences::QT_SHOW_TOOLBAR_CATEGORY_NAMES, true); // Order view descriptors by category QMultiMap categoryViewDescriptorMap; for (auto labelViewDescriptorPair : VDMap) { auto viewDescriptor = labelViewDescriptorPair.second; auto category = !viewDescriptor->GetCategoryPath().isEmpty() ? viewDescriptor->GetCategoryPath().back() : QString(); categoryViewDescriptorMap.insert(category, viewDescriptor); } // Create a separate toolbar for each category for (auto category : categoryViewDescriptorMap.uniqueKeys()) { auto viewDescriptorsInCurrentCategory = categoryViewDescriptorMap.values(category); QList > relevantViewDescriptors; for (auto viewDescriptor : viewDescriptorsInCurrentCategory) { if (viewDescriptor->GetId() != "org.mitk.views.flow.control" && viewDescriptor->GetId() != "org.mitk.views.segmentationtasklist") { relevantViewDescriptors.push_back(viewDescriptor); } } if (!relevantViewDescriptors.isEmpty()) { auto toolbar = new QToolBar; toolbar->setObjectName(category + " View Toolbar"); mainWindow->addToolBar(toolbar); if (showCategoryNames && !category.isEmpty()) { auto categoryButton = new QToolButton; categoryButton->setToolButtonStyle(Qt::ToolButtonTextOnly); categoryButton->setText(category); categoryButton->setStyleSheet("background: transparent; margin: 0; padding: 0;"); toolbar->addWidget(categoryButton); connect(categoryButton, &QToolButton::clicked, [toolbar]() { for (QWidget* widget : toolbar->findChildren()) { if (QStringLiteral("qt_toolbar_ext_button") == widget->objectName() && widget->isVisible()) { QMouseEvent pressEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QApplication::sendEvent(widget, &pressEvent); QApplication::sendEvent(widget, &releaseEvent); } } }); } for (auto viewDescriptor : relevantViewDescriptors) { auto viewAction = new berry::QtShowViewAction(window, viewDescriptor); toolbar->addAction(viewAction); } } } } QSettings settings(GetQSettingsFile(), QSettings::IniFormat); mainWindow->restoreState(settings.value("ToolbarPosition").toByteArray()); auto qStatusBar = new QStatusBar(); //creating a QmitkStatusBar for Output on the QStatusBar and connecting it with the MainStatusBar auto statusBar = new QmitkStatusBar(qStatusBar); //disabling the SizeGrip in the lower right corner statusBar->SetSizeGripEnabled(false); auto progBar = new QmitkProgressBar(); qStatusBar->addPermanentWidget(progBar, 0); progBar->hide(); mainWindow->setStatusBar(qStatusBar); if (showMemoryIndicator) { auto memoryIndicator = new QmitkMemoryUsageIndicatorView(); qStatusBar->addPermanentWidget(memoryIndicator, 0); } } void QmitkFlowApplicationWorkbenchWindowAdvisor::PreWindowOpen() { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); this->HookTitleUpdateListeners(configurer); menuPerspectiveListener.reset(new PerspectiveListenerForMenu(this)); configurer->GetWindow()->AddPerspectiveListener(menuPerspectiveListener.data()); configurer->AddEditorAreaTransfer(QStringList("text/uri-list")); configurer->ConfigureEditorAreaDropListener(dropTargetListener.data()); } void QmitkFlowApplicationWorkbenchWindowAdvisor::PostWindowOpen() { berry::WorkbenchWindowAdvisor::PostWindowOpen(); // Force Rendering Window Creation on startup. berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); ctkPluginContext* context = QmitkFlowApplicationPlugin::GetDefault()->GetPluginContext(); ctkServiceReference serviceRef = context->getServiceReference(); if (serviceRef) { mitk::IDataStorageService *dsService = context->getService(serviceRef); if (dsService) { mitk::IDataStorageReference::Pointer dsRef = dsService->GetDataStorage(); mitk::DataStorageEditorInput::Pointer dsInput(new mitk::DataStorageEditorInput(dsRef)); mitk::WorkbenchUtil::OpenEditor(configurer->GetWindow()->GetActivePage(),dsInput); } } } void QmitkFlowApplicationWorkbenchWindowAdvisor::onIntro() { QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onIntro(); } void QmitkFlowApplicationWorkbenchWindowAdvisor::onHelp() { QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onHelp(); } void QmitkFlowApplicationWorkbenchWindowAdvisor::onHelpOpenHelpPerspective() { QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onHelpOpenHelpPerspective(); } void QmitkFlowApplicationWorkbenchWindowAdvisor::onAbout() { QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onAbout(); } void QmitkFlowApplicationWorkbenchWindowAdvisor::HookTitleUpdateListeners(berry::IWorkbenchWindowConfigurer::Pointer configurer) { // hook up the listeners to update the window title titlePartListener.reset(new PartListenerForTitle(this)); titlePerspectiveListener.reset(new PerspectiveListenerForTitle(this)); editorPropertyListener.reset(new berry::PropertyChangeIntAdapter< QmitkFlowApplicationWorkbenchWindowAdvisor>(this, &QmitkFlowApplicationWorkbenchWindowAdvisor::PropertyChange)); configurer->GetWindow()->AddPerspectiveListener(titlePerspectiveListener.data()); configurer->GetWindow()->GetPartService()->AddPartListener(titlePartListener.data()); } QString QmitkFlowApplicationWorkbenchWindowAdvisor::ComputeTitle() { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); berry::IWorkbenchPage::Pointer currentPage = configurer->GetWindow()->GetActivePage(); berry::IEditorPart::Pointer activeEditor; if (currentPage) { activeEditor = lastActiveEditor.Lock(); } QString title; berry::IProduct::Pointer product = berry::Platform::GetProduct(); if (product.IsNotNull()) { title = product->GetName(); } if (title.isEmpty()) { // instead of the product name, we use a custom variable for now title = productName; } if(showMitkVersionInfo) { QString mitkVersionInfo = MITK_REVISION_DESC; if(mitkVersionInfo.isEmpty()) mitkVersionInfo = MITK_VERSION_STRING; title += " " + mitkVersionInfo; } if (showVersionInfo) { // add version informatioin QString versions = QString(" (ITK %1.%2.%3 | VTK %4.%5.%6 | Qt %7)") .arg(ITK_VERSION_MAJOR).arg(ITK_VERSION_MINOR).arg(ITK_VERSION_PATCH) .arg(VTK_MAJOR_VERSION).arg(VTK_MINOR_VERSION).arg(VTK_BUILD_VERSION) .arg(QT_VERSION_STR); title += versions; } if (currentPage) { if (activeEditor) { lastEditorTitle = activeEditor->GetTitleToolTip(); if (!lastEditorTitle.isEmpty()) title = lastEditorTitle + " - " + title; } berry::IPerspectiveDescriptor::Pointer persp = currentPage->GetPerspective(); QString label = ""; if (persp) { label = persp->GetLabel(); } berry::IAdaptable* input = currentPage->GetInput(); if (input && input != wbAdvisor->GetDefaultPageInput()) { label = currentPage->GetLabel(); } if (!label.isEmpty()) { title = label + " - " + title; } } title += " (Not for use in diagnosis or treatment of patients)"; return title; } void QmitkFlowApplicationWorkbenchWindowAdvisor::RecomputeTitle() { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); QString oldTitle = configurer->GetTitle(); QString newTitle = ComputeTitle(); if (newTitle != oldTitle) { configurer->SetTitle(newTitle); } } void QmitkFlowApplicationWorkbenchWindowAdvisor::UpdateTitle(bool editorHidden) { berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); berry::IWorkbenchWindow::Pointer window = configurer->GetWindow(); berry::IEditorPart::Pointer activeEditor; berry::IWorkbenchPage::Pointer currentPage = window->GetActivePage(); berry::IPerspectiveDescriptor::Pointer persp; berry::IAdaptable* input = nullptr; if (currentPage) { activeEditor = currentPage->GetActiveEditor(); persp = currentPage->GetPerspective(); input = currentPage->GetInput(); } if (editorHidden) { activeEditor = nullptr; } // Nothing to do if the editor hasn't changed if (activeEditor == lastActiveEditor.Lock() && currentPage == lastActivePage.Lock() && persp == lastPerspective.Lock() && input == lastInput) { return; } auto lockedLastActiveEditor = lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull()) { lockedLastActiveEditor->RemovePropertyListener(editorPropertyListener.data()); } lastActiveEditor = activeEditor; lastActivePage = currentPage; lastPerspective = persp; lastInput = input; if (activeEditor) { activeEditor->AddPropertyListener(editorPropertyListener.data()); } RecomputeTitle(); } void QmitkFlowApplicationWorkbenchWindowAdvisor::PropertyChange(const berry::Object::Pointer& /*source*/, int propId) { if (propId == berry::IWorkbenchPartConstants::PROP_TITLE) { auto lockedLastActiveEditor = lastActiveEditor.Lock(); if (lockedLastActiveEditor.IsNotNull()) { QString newTitle = lockedLastActiveEditor->GetPartName(); if (lastEditorTitle != newTitle) { RecomputeTitle(); } } } } void QmitkFlowApplicationWorkbenchWindowAdvisor::SetPerspectiveExcludeList(const QList& v) { this->perspectiveExcludeList = v; } QList QmitkFlowApplicationWorkbenchWindowAdvisor::GetPerspectiveExcludeList() { return this->perspectiveExcludeList; } void QmitkFlowApplicationWorkbenchWindowAdvisor::SetViewExcludeList(const QList& v) { this->viewExcludeList = v; } QList QmitkFlowApplicationWorkbenchWindowAdvisor::GetViewExcludeList() { return this->viewExcludeList; } void QmitkFlowApplicationWorkbenchWindowAdvisor::PostWindowClose() { berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow(); QMainWindow* mainWindow = static_cast (window->GetShell()->GetControl()); auto fileName = this->GetQSettingsFile(); if (!fileName.isEmpty()) { QSettings settings(fileName, QSettings::IniFormat); settings.setValue("ToolbarPosition", mainWindow->saveState()); } } QString QmitkFlowApplicationWorkbenchWindowAdvisor::GetQSettingsFile() const { QFileInfo settingsInfo = QmitkFlowApplicationPlugin::GetDefault()->GetPluginContext()->getDataFile(QT_SETTINGS_FILENAME); return settingsInfo.canonicalFilePath(); } //-------------------------------------------------------------------------------- // Ugly hack from here on. Feel free to delete when command framework // and undo buttons are done. //-------------------------------------------------------------------------------- QmitkFlowApplicationWorkbenchWindowAdvisorHack::QmitkFlowApplicationWorkbenchWindowAdvisorHack() : QObject() { } QmitkFlowApplicationWorkbenchWindowAdvisorHack::~QmitkFlowApplicationWorkbenchWindowAdvisorHack() { } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onUndo() { mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel(); if (model) { if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast(model)) { mitk::VerboseLimitedLinearUndo::StackDescription descriptions = verboseundo->GetUndoDescriptions(); if (descriptions.size() >= 1) { MITK_INFO << "Undo " << descriptions.front().second; } } model->Undo(); } else { MITK_ERROR << "No undo model instantiated"; } } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onRedo() { mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel(); if (model) { if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast(model)) { mitk::VerboseLimitedLinearUndo::StackDescription descriptions = verboseundo->GetRedoDescriptions(); if (descriptions.size() >= 1) { MITK_INFO << "Redo " << descriptions.front().second; } } model->Redo(); } else { MITK_ERROR << "No undo model instantiated"; } } // safe calls to the complete chain // berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.imagenavigator"); // to cover for all possible cases of closed pages etc. static void SafeHandleNavigatorView(QString view_query_name) { berry::IWorkbench* wbench = berry::PlatformUI::GetWorkbench(); if (wbench == nullptr) return; berry::IWorkbenchWindow::Pointer wbench_window = wbench->GetActiveWorkbenchWindow(); if (wbench_window.IsNull()) return; berry::IWorkbenchPage::Pointer wbench_page = wbench_window->GetActivePage(); if (wbench_page.IsNull()) return; auto wbench_view = wbench_page->FindView(view_query_name); if (wbench_view.IsNotNull()) { bool isViewVisible = wbench_page->IsPartVisible(wbench_view); if (isViewVisible) { wbench_page->HideView(wbench_view); return; } } wbench_page->ShowView(view_query_name); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onImageNavigator() { // show/hide ImageNavigatorView SafeHandleNavigatorView("org.mitk.views.imagenavigator"); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onEditPreferences() { QmitkPreferencesDialog _PreferencesDialog(QApplication::activeWindow()); _PreferencesDialog.exec(); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onQuit() { berry::PlatformUI::GetWorkbench()->Close(); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onResetPerspective() { berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective(); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onClosePerspective() { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); page->ClosePerspective(page->GetPerspective(), true, true); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onIntro() { bool hasIntro = berry::PlatformUI::GetWorkbench()->GetIntroManager()->HasIntro(); if (!hasIntro) { - QRegExp reg("(.*)(\\n)*"); - QRegExp reg2("(\\n)*(.*)"); + QRegularExpression reg("(.*)(\\n)*"); + QRegularExpression reg2("(\\n)*(.*)"); QFile file(":/org.mitk.gui.qt.ext/index.html"); file.open(QIODevice::ReadOnly | QIODevice::Text); //text file only for reading QString text = QString(file.readAll()); file.close(); QString title = text; title.replace(reg, ""); title.replace(reg2, ""); std::cout << title.toStdString() << std::endl; QMessageBox::information(nullptr, title, text, "Close"); } else { berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro( berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(), false); } } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onHelp() { ctkPluginContext* context = QmitkFlowApplicationPlugin::GetDefault()->GetPluginContext(); if (context == nullptr) { MITK_WARN << "Plugin context not set, unable to open context help"; return; } // Check if the org.blueberry.ui.qt.help plug-in is installed and started QList > plugins = context->getPlugins(); foreach(QSharedPointer p, plugins) { if (p->getSymbolicName() == "org.blueberry.ui.qt.help") { if (p->getState() != ctkPlugin::ACTIVE) { // try to activate the plug-in explicitly try { p->start(ctkPlugin::START_TRANSIENT); } catch (const ctkPluginException& pe) { MITK_ERROR << "Activating org.blueberry.ui.qt.help failed: " << pe.what(); return; } } } } ctkServiceReference eventAdminRef = context->getServiceReference(); ctkEventAdmin* eventAdmin = nullptr; if (eventAdminRef) { eventAdmin = context->getService(eventAdminRef); } if (eventAdmin == nullptr) { MITK_WARN << "ctkEventAdmin service not found. Unable to open context help"; } else { ctkEvent ev("org/blueberry/ui/help/CONTEXTHELP_REQUESTED"); eventAdmin->postEvent(ev); } } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onHelpOpenHelpPerspective() { berry::PlatformUI::GetWorkbench()->ShowPerspective("org.blueberry.perspectives.help", berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()); } void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onAbout() { auto aboutDialog = new QmitkAboutDialog(QApplication::activeWindow(), nullptr); aboutDialog->open(); } diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp index f54284c507..a34c9c62f6 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp @@ -1,269 +1,269 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h" // Blueberry #include #include // Qmitk #include "QmitkMatchPointBrowser.h" // Qt #include #include #include #include //MITK #include #include "MatchPointBrowserConstants.h" #include "mitkAlgorithmInfoSelectionProvider.h" #include #include #include // MatchPoint #include "mapRegistrationAlgorithmInterface.h" #include "mapAlgorithmEvents.h" #include "mapAlgorithmWrapperEvent.h" #include "mapExceptionObjectMacros.h" #include "mapDeploymentDLLDirectoryBrowser.h" #include "mapDeploymentEvents.h" const std::string QmitkMatchPointBrowser::VIEW_ID = "org.mitk.views.matchpoint.algorithm.browser"; QmitkMatchPointBrowser::QmitkMatchPointBrowser() : m_Parent(nullptr), m_LoadedDLLHandle(nullptr), m_LoadedAlgorithm(nullptr) { } QmitkMatchPointBrowser::~QmitkMatchPointBrowser() { } void QmitkMatchPointBrowser::OnPreferencesChanged(const mitk::IPreferences* /*prefs*/) { this->OnSearchFolderButtonPushed(); } void QmitkMatchPointBrowser::CreateConnections() { connect(m_Controls.m_pbSearchFolder, SIGNAL(clicked()), this, SLOT(OnSearchFolderButtonPushed())); connect(m_Controls.m_algoTreeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(OnAlgoListSelectionChanged(const QModelIndex&))); connect(m_Controls.pbClearSearch, SIGNAL(clicked()), m_Controls.lineSearch, SLOT(clear())); connect(m_Controls.lineSearch, SIGNAL(textChanged(const QString&)), this, SLOT(OnSearchChanged(const QString&))); } void QmitkMatchPointBrowser::OnSearchFolderButtonPushed() { RetrieveAndStorePreferenceValues(); // test if some folder list non-empty int folderCount = m_currentSearchPaths.count(); if (!folderCount) { Error(QString("No search folder selected for MatchPoint algorithm browser! Please set search paths in the MatchPoint preference page.")); m_DLLInfoList.clear(); } else { map::deployment::DLLDirectoryBrowser::Pointer browser = map::deployment::DLLDirectoryBrowser::New(); auto validCommand = ::itk::MemberCommand::New(); validCommand->SetCallbackFunction(this, &QmitkMatchPointBrowser::OnValidDeploymentEvent); browser->AddObserver(::map::events::ValidDLLEvent(), validCommand); auto invalidCommand = ::itk::MemberCommand::New(); invalidCommand->SetCallbackFunction(this, &QmitkMatchPointBrowser::OnInvalidDeploymentEvent); browser->AddObserver(::map::events::InvalidDLLEvent(), invalidCommand); foreach(QString path, m_currentSearchPaths) { browser->addDLLSearchLocation(path.toStdString()); } browser->update(); m_DLLInfoList = browser->getLibraryInfos(); } m_Controls.groupWarning->setVisible(m_DLLInfoList.empty()); m_Controls.groupList->setVisible(!m_DLLInfoList.empty()); m_algModel->SetAlgorithms(m_DLLInfoList); m_Controls.lineSearch->clear(); } void QmitkMatchPointBrowser::OnAlgoListSelectionChanged(const QModelIndex& index) { QVariant vIndex = index.data(Qt::UserRole).toInt(); map::deployment::DLLInfo::ConstPointer currentItemInfo = nullptr; if (vIndex.isValid()) { std::size_t algListIndex = vIndex.toInt(); if (algListIndex < m_DLLInfoList.size()) { currentItemInfo = m_DLLInfoList[algListIndex]; } } m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); if (currentItemInfo) { //update selection provider mitk::MAPAlgorithmInfoSelection::Pointer infoSelection = mitk::MAPAlgorithmInfoSelection::Pointer( new mitk::MAPAlgorithmInfoSelection(currentItemInfo)); this->m_SelectionProvider->SetInfoSelection(infoSelection); } } void QmitkMatchPointBrowser::OnSearchChanged(const QString& text) { - m_filterProxy->setFilterRegExp(text); + m_filterProxy->setFilterRegularExpression(text); m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); }; void QmitkMatchPointBrowser::OnInvalidDeploymentEvent(const ::itk::Object *, const itk::EventObject &event) { auto deployEvent = dynamic_cast(&event); this->Error(QString("Error when try to inspect deployed registration algorithm. Details: ")+QString::fromStdString(deployEvent->getComment())); } void QmitkMatchPointBrowser::OnValidDeploymentEvent(const ::itk::Object *, const itk::EventObject &event) { auto deployEvent = dynamic_cast(&event); auto info = static_cast(deployEvent->getData()); MITK_INFO << "Successfully inspected deployed registration algorithm. UID: " << info->getAlgorithmUID().toStr() << ". Path: " << info->getLibraryFilePath(); } void QmitkMatchPointBrowser::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; m_algModel = new QmitkAlgorithmListModel(parent); m_filterProxy = new QSortFilterProxyModel(parent); //! [Qt Selection Provider registration] // create new qt selection provider m_SelectionProvider = new mitk::AlgorithmInfoSelectionProvider(); m_filterProxy->setSourceModel(m_algModel); m_filterProxy->setDynamicSortFilter(true); m_filterProxy->setFilterKeyColumn(-1); m_Controls.m_algoTreeView->setModel(m_filterProxy); m_Controls.m_algoTreeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_algoTreeView->header()->setStretchLastSection(false); m_Controls.m_algoTreeView->header()->setSectionResizeMode(0, QHeaderView::Stretch); m_Controls.m_algoTreeView->setColumnHidden(3, true); this->CreateConnections(); } void QmitkMatchPointBrowser::SetSelectionProvider() { this->GetSite()->SetSelectionProvider(m_SelectionProvider); } void QmitkMatchPointBrowser::SetFocus() { } void QmitkMatchPointBrowser::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); } void QmitkMatchPointBrowser::RetrieveAndStorePreferenceValues() { auto* prefs = this->RetrievePreferences(); bool loadApplicationDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR, true); bool loadHomeDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR, false); bool loadCurrentDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR, false); bool loadAutoLoadDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR, false); // Get some default application paths. QStringList newPaths; // Here we can use the preferences to set up the builder, if (loadApplicationDir) { newPaths << QCoreApplication::applicationDirPath(); } if (loadHomeDir) { newPaths << QDir::homePath(); } if (loadCurrentDir) { newPaths << QDir::currentPath(); } if (loadAutoLoadDir) { char* deployedAlgorithmLoadPath = getenv("MAP_MDRA_LOAD_PATH"); if (deployedAlgorithmLoadPath != nullptr) { // The load path may in fact be a semi-colon or colon separated list of directories, not just one. QString paths(deployedAlgorithmLoadPath); #ifdef Q_OS_WIN32 QString pathSeparator(";"); #else QString pathSeparator(":"); #endif QStringList splitPath = paths.split(pathSeparator, Qt::SkipEmptyParts); foreach(QString path, splitPath) { QDir dir = QDir(path); newPaths << dir.absolutePath(); } } } // We get additional directory paths from preferences. const auto pathString = QString::fromStdString(prefs->Get(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME, "")); QStringList additionalPaths = pathString.split(";", Qt::SkipEmptyParts); newPaths << additionalPaths; const auto additionalAlgorirthmsString = QString::fromStdString(prefs->Get(MatchPointBrowserConstants::MDAR_FILES_NODE_NAME, "")); additionalPaths = additionalAlgorirthmsString.split(";", Qt::SkipEmptyParts); newPaths << additionalPaths; m_currentSearchPaths = newPaths; } mitk::IPreferences* QmitkMatchPointBrowser::RetrievePreferences() { const auto id = "/" + MatchPointBrowserConstants::VIEW_ID; return mitk::CoreServices::GetPreferencesService()->GetSystemPreferences()->Node(id); } diff --git a/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp b/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp index 5a2270499a..061fecfaa5 100644 --- a/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp @@ -1,531 +1,531 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include // Blueberry #include #include // Qmitk #include "QmitkAddNewPropertyDialog.h" #include "QmitkOverlayManagerView.h" #include "QmitkPropertyItemDelegate.h" #include "QmitkPropertyItemModel.h" #include // Qt #include #include #include #include "internal/org_mitk_gui_qt_overlaymanager_Activator.h" #include "mitkAnnotationUtils.h" #include "mitkGetPropertyService.h" #include "mitkLayoutAnnotationRenderer.h" #include "mitkManualPlacementAnnotationRenderer.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include #include #include const std::string QmitkOverlayManagerView::VIEW_ID = "org.mitk.views.overlaymanager"; QmitkOverlayManagerView::QmitkOverlayManagerView() : m_Parent(nullptr), m_PropertyNameChangedTag(0), m_OverlayManagerObserverTag(0), m_PropertyAliases(nullptr), m_PropertyDescriptions(nullptr), m_PropertyPersistence(nullptr), m_ProxyModel(nullptr), m_Model(nullptr), m_Delegate(nullptr), m_Renderer(nullptr), m_AddOverlayMenu(nullptr) { } QmitkOverlayManagerView::~QmitkOverlayManagerView() { } void QmitkOverlayManagerView::SetFocus() { } void QmitkOverlayManagerView::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.m_OverlayList->clear(); auto* renderWindowPart = this->GetRenderWindowPart(); if (renderWindowPart != nullptr) { QHash renderWindows = renderWindowPart->GetQmitkRenderWindows(); Q_FOREACH (QString renderWindow, renderWindows.keys()) { if (!m_Renderer) m_Renderer = renderWindows[renderWindow]->GetRenderer(); m_Controls.m_RendererCB->addItem(renderWindow); } } InitializeAddOverlayMenu(); m_ProxyModel = new QSortFilterProxyModel(m_Controls.m_PropertyTree); m_Model = new QmitkPropertyItemModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_Model); m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setDynamicSortFilter(true); m_Delegate = new QmitkPropertyItemDelegate(m_Controls.m_PropertyTree); m_Controls.m_PropertyTree->setItemDelegateForColumn(1, m_Delegate); m_Controls.m_PropertyTree->setModel(m_ProxyModel); m_Controls.m_PropertyTree->setColumnWidth(0, 160); m_Controls.m_PropertyTree->sortByColumn(0, Qt::AscendingOrder); m_Controls.m_PropertyTree->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.m_PropertyTree->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_PropertyTree->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked); connect(m_Controls.m_RendererCB, SIGNAL(currentIndexChanged(int)), this, SLOT(OnPropertyListChanged(int))); connect(m_Controls.newButton, SIGNAL(clicked()), this, SLOT(OnAddNewProperty())); connect(m_Controls.m_PropertyTree->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(OnCurrentRowChanged(const QModelIndex &, const QModelIndex &))); connect(m_Controls.m_OverlayList, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(OnOverlaySelectionChanged(QListWidgetItem *, QListWidgetItem *))); connect(m_Controls.m_DeleteOverlay, SIGNAL(clicked()), this, SLOT(OnDelete())); connect(m_Controls.m_AddOverlay, SIGNAL(clicked()), this, SLOT(OnAddOverlay())); itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction(this, &QmitkOverlayManagerView::OnFocusChanged); m_RenderWindowFocusObserverTag = mitk::RenderingManager::GetInstance()->AddObserver(mitk::FocusChangedEvent(), command); } void QmitkOverlayManagerView::OnFocusChanged(itk::Object * /*caller*/, const itk::EventObject &event) { const mitk::FocusChangedEvent *focusEvent = dynamic_cast(&event); if (focusEvent) { QHash renderWindows = this->GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindows(); m_Controls.m_RendererCB->clear(); Q_FOREACH (QString renderWindow, renderWindows.keys()) { m_Controls.m_RendererCB->addItem(renderWindow); if (renderWindows[renderWindow]->GetVtkRenderWindow() == mitk::RenderingManager::GetInstance()->GetFocusedRenderWindow()) { m_Controls.m_RendererCB->setCurrentText(renderWindow); } } this->OnActivateOverlayList(); } } QString QmitkOverlayManagerView::GetPropertyNameOrAlias(const QModelIndex &index) { QString propertyName; if (index.isValid()) { QModelIndex current = index; while (current.isValid()) { QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString(); propertyName.prepend(propertyName.isEmpty() ? name : name.append('.')); current = current.parent(); } } return propertyName; } void QmitkOverlayManagerView::OnCurrentRowChanged(const QModelIndex ¤t, const QModelIndex &) { if (m_PropertyDescriptions != nullptr && current.isValid()) { QString name = this->GetPropertyNameOrAlias(current); if (!name.isEmpty()) { QString alias; bool isTrueName = true; if (m_PropertyAliases != nullptr) { std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString()); if (trueName.empty() && !m_SelectionClassName.empty()) trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName); if (!trueName.empty()) { alias = name; name = QString::fromStdString(trueName); isTrueName = false; } } QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString())); std::vector aliases; if (!isTrueName && m_PropertyAliases != nullptr) { aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName); if (aliases.empty() && !m_SelectionClassName.empty()) aliases = m_PropertyAliases->GetAliases(name.toStdString()); } bool isPersistent = false; // QString persistenceKey; if (m_PropertyPersistence != nullptr) { isPersistent = m_PropertyPersistence->HasInfo(name.toStdString()); /*if (isPersistent) { persistenceKey = QString::fromStdString(m_PropertyPersistence->GetInfo(name.toStdString())->GetKey()); if (persistenceKey.isEmpty()) persistenceKey = name; }*/ } if (!description.isEmpty() || !aliases.empty() || isPersistent) { QString customizedDescription; if (!description.isEmpty()) customizedDescription += "

" + description + "

"; if (!aliases.empty() || isPersistent) { customizedDescription += "
"; if (!aliases.empty()) { customizedDescription += aliases.size() > 1 ? "" : ""; } if (isPersistent) customizedDescription += ""; customizedDescription += "
"; } return; } } } } void QmitkOverlayManagerView::OnPropertyNameChanged(const itk::EventObject &) { mitk::PropertyList *propertyList = m_Model->GetPropertyList(); if (propertyList != nullptr) { mitk::BaseProperty *nameProperty = propertyList->GetProperty("name"); if (nameProperty != nullptr) { QString partName = "Properties ("; partName.append(QString::fromStdString(nameProperty->GetValueAsString())).append(')'); this->SetPartName(partName); } } } void QmitkOverlayManagerView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList &) { } void QmitkOverlayManagerView::InitializeAddOverlayMenu() { m_AddOverlayMenu = new QMenu(m_Controls.m_AddOverlay); m_AddOverlayMenu->addAction("TextAnnotation2D"); m_AddOverlayMenu->addAction("TextAnnotation3D"); m_AddOverlayMenu->addAction("LabelAnnotation"); m_AddOverlayMenu->addAction("ColorBarAnnotation"); m_AddOverlayMenu->addAction("ScaleLegendAnnotation"); m_AddOverlayMenu->addAction("LogoAnnotation"); } void QmitkOverlayManagerView::Activated() { // this->OnActivateOverlayList(); } void QmitkOverlayManagerView::Deactivated() { } void QmitkOverlayManagerView::Visible() { this->OnActivateOverlayList(); } void QmitkOverlayManagerView::Hidden() { } void QmitkOverlayManagerView::OnPropertyListChanged(int index) { if (index == -1) return; QString renderer = m_Controls.m_RendererCB->itemText(index); auto *renwin = this->GetRenderWindowPart()->GetQmitkRenderWindow(renderer); m_Renderer = renwin ? renwin->GetRenderer() : nullptr; this->OnOverlaySelectionChanged(m_Controls.m_OverlayList->currentItem(), nullptr); this->OnActivateOverlayList(); } void QmitkOverlayManagerView::OnAddNewProperty() { std::unique_ptr dialog( new QmitkAddNewPropertyDialog(m_SelectedOverlay, m_Renderer, m_Parent)); if (dialog->exec() == QDialog::Accepted) this->m_Model->Update(); } void QmitkOverlayManagerView::OnActivateOverlayList() { if (!m_Renderer) return; std::vector arList = mitk::AnnotationUtils::GetAnnotationRenderer(m_Renderer->GetName()); m_Controls.m_OverlayList->clear(); for (auto ar : arList) { for (auto overlay : ar->GetServices()) { QListWidgetItem *item = new QListWidgetItem(); item->setData(Qt::UserRole, QVariant(overlay->GetMicroserviceID().c_str())); QString text(overlay->GetName().c_str()); if (text.length() > 0) { text.append(" : "); } text.append(overlay->GetNameOfClass()); item->setText(text); m_Controls.m_OverlayList->addItem(item); } } } void QmitkOverlayManagerView::OnOverlaySelectionChanged(QListWidgetItem *current, QListWidgetItem *) { mitk::PropertyList *propertyList = m_Model->GetPropertyList(); if (propertyList != nullptr) { mitk::BaseProperty *nameProperty = propertyList->GetProperty("name"); if (nameProperty != nullptr) nameProperty->RemoveObserver(m_PropertyNameChangedTag); m_PropertyNameChangedTag = 0; } mitk::Annotation *overlay = nullptr; QString oID; if (current) { oID = current->data(Qt::UserRole).toString(); OverlayMapType::iterator it = m_OverlayMap.find(oID.toStdString()); if (it != m_OverlayMap.end()) overlay = it->second; else { overlay = mitk::AnnotationUtils::GetAnnotation(oID.toStdString()); } } if (!overlay) { m_SelectedOverlay = nullptr; this->SetPartName("Overlay Properties"); m_Model->SetPropertyList(nullptr); m_Delegate->SetPropertyList(nullptr); m_Controls.newButton->setEnabled(false); } else { m_SelectedOverlay = overlay; QString selectionClassName = m_SelectedOverlay->GetNameOfClass(); m_SelectionClassName = selectionClassName.toStdString(); mitk::PropertyList::Pointer propertyList = overlay->GetPropertyList(); m_Model->SetPropertyList(propertyList, selectionClassName); m_Delegate->SetPropertyList(propertyList); OnPropertyNameChanged(itk::ModifiedEvent()); mitk::BaseProperty *nameProperty = m_SelectedOverlay->GetProperty("name"); if (nameProperty != nullptr) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkOverlayManagerView::OnPropertyNameChanged); m_PropertyNameChangedTag = nameProperty->AddObserver(itk::ModifiedEvent(), command); } m_Controls.newButton->setEnabled(true); } - if (!m_ProxyModel->filterRegExp().isEmpty()) + if (!m_ProxyModel->filterRegularExpression().pattern().isEmpty()) m_Controls.m_PropertyTree->expandAll(); } void QmitkOverlayManagerView::OnDelete() { if (m_SelectedOverlay.IsNotNull()) { m_OverlayMap.erase(m_SelectedOverlay->GetMicroserviceID()); m_SelectedOverlay = nullptr; OnActivateOverlayList(); } } void QmitkOverlayManagerView::OnAddOverlay() { QAction *action = m_AddOverlayMenu->exec(QCursor::pos()); mitk::Annotation::Pointer overlay; if (action != nullptr) { const QString widgetKey = action->text(); if (widgetKey == "TextAnnotation2D") overlay = CreateTextOverlay2D(); else if (widgetKey == "TextAnnotation3D") overlay = CreateTextOverlay3D(); else if (widgetKey == "LabelAnnotation") overlay = CreateLabelOverlay(); else if (widgetKey == "ColorBarAnnotation") overlay = CreateColorBarOverlay(); else if (widgetKey == "ScaleLegendAnnotation") overlay = CreateScaleLegendOverlay(); else if (widgetKey == "LogoAnnotation") overlay = CreateLogoOverlay(); mitk::BaseRenderer *renderer = this->GetRenderWindowPart(mitk::WorkbenchUtil::OPEN)->GetQmitkRenderWindow(m_Controls.m_RendererCB->currentText())->GetRenderer(); mitk::LayoutAnnotationRenderer::AddAnnotation(overlay, renderer); m_OverlayMap[overlay->GetMicroserviceID()] = overlay; } OnActivateOverlayList(); } mitk::Annotation::Pointer QmitkOverlayManagerView::CreateTextOverlay2D() { mitk::TextAnnotation2D::Pointer to = mitk::TextAnnotation2D::New(); to->SetText("Test"); return to.GetPointer(); } mitk::Annotation::Pointer QmitkOverlayManagerView::CreateTextOverlay3D() { mitk::TextAnnotation3D::Pointer to = mitk::TextAnnotation3D::New(); return to.GetPointer(); } mitk::Annotation::Pointer QmitkOverlayManagerView::CreateLabelOverlay() { mitk::LabelAnnotation3D::Pointer to = mitk::LabelAnnotation3D::New(); return to.GetPointer(); } mitk::Annotation::Pointer QmitkOverlayManagerView::CreateColorBarOverlay() { mitk::ColorBarAnnotation::Pointer to = mitk::ColorBarAnnotation::New(); return to.GetPointer(); } mitk::Annotation::Pointer QmitkOverlayManagerView::CreateScaleLegendOverlay() { mitk::ScaleLegendAnnotation::Pointer to = mitk::ScaleLegendAnnotation::New(); return to.GetPointer(); } mitk::Annotation::Pointer QmitkOverlayManagerView::CreateLogoOverlay() { mitk::LogoAnnotation::Pointer to = mitk::LogoAnnotation::New(); return to.GetPointer(); } void QmitkOverlayManagerView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if (m_Controls.m_RendererCB->count() == 0) { QHash renderWindows = renderWindowPart->GetQmitkRenderWindows(); Q_FOREACH (QString renderWindow, renderWindows.keys()) { m_Controls.m_RendererCB->addItem(renderWindow); } } OnActivateOverlayList(); } void QmitkOverlayManagerView::RenderWindowPartDeactivated(mitk::IRenderWindowPart *) { if (m_Controls.m_RendererCB->count() > 0) { m_Controls.m_RendererCB->clear(); } m_Controls.m_OverlayList->clear(); } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemSortFilterProxyModel.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemSortFilterProxyModel.cpp index c0cceb0cdb..ae94c7b090 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemSortFilterProxyModel.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemSortFilterProxyModel.cpp @@ -1,54 +1,54 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkPropertyItemSortFilterProxyModel.h" QmitkPropertyItemSortFilterProxyModel::QmitkPropertyItemSortFilterProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { } QmitkPropertyItemSortFilterProxyModel::~QmitkPropertyItemSortFilterProxyModel() { } bool QmitkPropertyItemSortFilterProxyModel::FilterAcceptsAnyChildRow(const QModelIndex& sourceParent) const { QString propertyName = this->sourceModel()->data(sourceParent).toString(); - if (propertyName.contains(this->filterRegExp())) + if (propertyName.contains(this->filterRegularExpression())) return true; if (this->sourceModel()->hasChildren(sourceParent)) { for (int row = 0; row < this->sourceModel()->rowCount(sourceParent); ++row) { if(this->FilterAcceptsAnyChildRow(this->sourceModel()->index(row, 0, sourceParent))) return true; } } return false; } bool QmitkPropertyItemSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { return this->FilterAcceptsAnyChildRow(this->sourceModel()->index(sourceRow, 0, sourceParent)); } bool QmitkPropertyItemSortFilterProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { QString leftString = this->sourceModel()->data(left).toString(); QString rightString = this->sourceModel()->data(right).toString(); return leftString.compare(rightString, this->sortCaseSensitivity()) < 0; } diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp index d431fa5643..44be82cacb 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp @@ -1,730 +1,729 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // View navigator plugin #include #include #include // Blueberry #include #include #include #include #include #include #include #include // MITK #include // Qt #include #include #include #include #include namespace { QFont getLargeFont() { QFont font = qApp->font(); font.setPointSizeF(font.pointSizeF() * 1.25f); return font; } } class KeywordRegistry { public: KeywordRegistry() { berry::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); auto keywordExts = extensionPointService->GetConfigurationElementsFor("org.blueberry.ui.keywords"); for (auto keywordExtsIt = keywordExts.begin(); keywordExtsIt != keywordExts.end(); ++keywordExtsIt) { QString keywordId = (*keywordExtsIt)->GetAttribute("id"); QString keywordLabels = (*keywordExtsIt)->GetAttribute("label"); m_Keywords[keywordId].push_back(keywordLabels); } } QStringList GetKeywords(const QString& id) { return m_Keywords[id]; } QStringList GetKeywords(const QStringList& ids) { QStringList result; for (const auto& id : ids) { result.append(this->GetKeywords(id)); } return result; } private: QHash m_Keywords; }; class ClassFilterProxyModel : public QSortFilterProxyModel { public: ClassFilterProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent) { } bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); return hasToBeDisplayed(index); } private: bool displayElement(const QModelIndex index) const { QString type = sourceModel()->data(index, Qt::DisplayRole).toString(); QStandardItem* item = dynamic_cast(sourceModel())->itemFromIndex(index); - if (type.contains(filterRegExp())) + if (type.contains(filterRegularExpression())) { return true; } QmitkViewItem* viewItem = dynamic_cast(item); if (nullptr != viewItem) { for (const auto& tag : viewItem->m_Tags) { - if (tag.contains(filterRegExp())) + if (tag.contains(filterRegularExpression())) { return true; } } - if (viewItem->m_Description.contains(filterRegExp())) + if (viewItem->m_Description.contains(filterRegularExpression())) { return true; } } QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { for (const auto& tag : perspectiveItem->m_Tags) { - if (tag.contains(filterRegExp())) + if (tag.contains(filterRegularExpression())) { return true; } } - if (perspectiveItem->m_Description.contains(filterRegExp())) + if (perspectiveItem->m_Description.contains(filterRegularExpression())) { return true; } } return false; } bool hasToBeDisplayed(const QModelIndex index) const { bool result = false; if (sourceModel()->rowCount(index) > 0) { for (int i = 0; i < sourceModel()->rowCount(index); i++) { QModelIndex childIndex = sourceModel()->index(i, 0, index); if (!childIndex.isValid()) { break; } result = hasToBeDisplayed(childIndex); result |= displayElement(index); if (result) { break; } } } else { result = displayElement(index); } return result; } }; class ViewNavigatorPerspectiveListener: public berry::IPerspectiveListener { public: ViewNavigatorPerspectiveListener(QmitkViewNavigatorWidget* parent) : m_ParentWidget(parent) { } Events::Types GetPerspectiveEventTypes() const override { return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED // remove the following line when command framework is finished | Events::CLOSED | Events::OPENED | Events::PART_CHANGED; } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->UpdateTreeList(); } void PerspectiveSavedAs(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*oldPerspective*/, const berry::IPerspectiveDescriptor::Pointer& /*newPerspective*/) override { m_ParentWidget->UpdateTreeList(); } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->m_ActivePerspective = nullptr; } void PerspectiveOpened(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->UpdateTreeList(); } void PerspectiveClosed(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { m_ParentWidget->m_ActivePerspective = nullptr; } using IPerspectiveListener::PerspectiveChanged; void PerspectiveChanged(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/, const berry::IWorkbenchPartReference::Pointer& partRef, const std::string& changeId) { if (changeId == "viewHide" && partRef->GetId() == "org.mitk.views.viewnavigator") berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->RemovePerspectiveListener(m_ParentWidget->m_PerspectiveListener.data()); else m_ParentWidget->UpdateTreeList(); } private: QmitkViewNavigatorWidget* m_ParentWidget; }; class ViewNavigatorViewListener: public berry::IPartListener { public: ViewNavigatorViewListener(QmitkViewNavigatorWidget* parent) : m_ParentWidget(parent) { } Events::Types GetPartEventTypes() const override { return Events::OPENED | Events::CLOSED; } void PartOpened(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() != "org.mitk.views.viewnavigator") { m_ParentWidget->UpdateTreeList((partRef->GetPart(false)).GetPointer()); } else { m_ParentWidget->FillTreeList(); m_ParentWidget->UpdateTreeList(); } } void PartClosed(const berry::IWorkbenchPartReference::Pointer& partRef) override { if (partRef->GetId() != "org.mitk.views.viewnavigator") { m_ParentWidget->UpdateTreeList(); } } private: QmitkViewNavigatorWidget* m_ParentWidget; }; bool compareViews(const berry::IViewDescriptor::Pointer& a, const berry::IViewDescriptor::Pointer& b) { if (a.IsNull() || b.IsNull()) { return false; } return a->GetLabel().compare(b->GetLabel()) < 0; } bool comparePerspectives(const berry::IPerspectiveDescriptor::Pointer& a, const berry::IPerspectiveDescriptor::Pointer& b) { if (a.IsNull() || b.IsNull()) { return false; } return a->GetLabel().compare(b->GetLabel()) < 0; } bool compareQStandardItems(const QStandardItem* a, const QStandardItem* b) { if (nullptr == a || nullptr== b) { return false; } return a->text().compare(b->text()) < 0; } QmitkViewNavigatorWidget::QmitkViewNavigatorWidget(berry::IWorkbenchWindow::Pointer window, QWidget* parent, Qt::WindowFlags) : QWidget(parent) , m_Window(window) { this->CreateQtPartControl(this); } QmitkViewNavigatorWidget::~QmitkViewNavigatorWidget() { m_Window->RemovePerspectiveListener(m_PerspectiveListener.data()); m_Window->GetPartService()->RemovePartListener(m_ViewPartListener.data()); } void QmitkViewNavigatorWidget::SetFocus() { m_Controls.lineEdit->setFocus(); } void QmitkViewNavigatorWidget::UpdateTreeList(berry::IWorkbenchPart* workbenchPart) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); if (page.IsNull()) { return; } m_ActivePerspective = page->GetPerspective(); QList viewParts = page->GetViews(); // iterate over all tree items for (const auto& item : m_TreeModel->findItems("*", Qt::MatchWildcard | Qt::MatchRecursive)) { QFont font = qApp->font(); // check if the item is a view item and if it is equal to any opened view QmitkViewItem* viewItem = dynamic_cast(item); if (nullptr != viewItem) { if (nullptr != workbenchPart && workbenchPart->GetPartName() == viewItem->m_ItemDescriptor->GetLabel()) { font.setBold(true); } else { for (const auto& viewPart : viewParts) { if (viewPart->GetPartName() == viewItem->m_ItemDescriptor->GetLabel()) { font.setBold(true); break; } } } viewItem->setFont(font); } else { // check if the item is a perspective item and if it is equal to the current perspective QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { if (m_ActivePerspective.IsNotNull() && m_ActivePerspective->GetId() == perspectiveItem->m_ItemDescriptor->GetId()) { font.setBold(true); } perspectiveItem->setFont(font); } } } } bool QmitkViewNavigatorWidget::FillTreeList() { // initialize tree model m_TreeModel->clear(); // add all available views this->AddViewsToTree(); // add all available perspectives this->AddPerspectivesToTree(); m_Controls.m_PluginTreeView->expandAll(); return true; } void QmitkViewNavigatorWidget::FilterChanged() { QString filterString = m_Controls.lineEdit->text(); m_Controls.m_PluginTreeView->expandAll(); - Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; QString strPattern = "^*" + filterString; - QRegExp regExp(strPattern, caseSensitivity); + QRegularExpression regExp(strPattern, QRegularExpression::CaseInsensitiveOption); - m_FilterProxyModel->setFilterRegExp(regExp); + m_FilterProxyModel->setFilterRegularExpression(regExp); } void QmitkViewNavigatorWidget::ItemClicked(const QModelIndex &index) { QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index)); QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { try { berry::PlatformUI::GetWorkbench()->ShowPerspective( perspectiveItem->m_ItemDescriptor->GetId(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()); } catch (...) { QMessageBox::critical(nullptr, "Opening Perspective Failed", QString("The requested perspective could not be opened.\nSee the log for details.")); } return; } QmitkViewItem* viewItem = dynamic_cast(item); if (nullptr != viewItem) { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); if (page.IsNotNull()) { try { page->ShowView(viewItem->m_ItemDescriptor->GetId()); } catch (const berry::PartInitException& e) { BERRY_ERROR << "Error: " << e.what() << std::endl; } } } } void QmitkViewNavigatorWidget::SaveCurrentPerspectiveAs() { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); berry::IPerspectiveDescriptor::Pointer currentPerspective = page->GetPerspective(); bool ok = false; QString perspectiveLabel = QInputDialog::getText(this, "Save perspective as ...", "New perspective name:", QLineEdit::Normal, "", &ok); if (!ok) { return; } if (perspectiveLabel.isEmpty()) { QMessageBox::information(this, "Save perspective as ...", "Please select a valid perspective name."); return; } berry::IPerspectiveRegistry* perspectiveRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); berry::IPerspectiveDescriptor::Pointer newPerspective = perspectiveRegistry->CreatePerspective(perspectiveLabel, currentPerspective); if (nullptr == newPerspective) { QMessageBox::information(this, "Save perspective as ...", "The selected perspective name is already in use."); return; } page->SavePerspectiveAs(newPerspective); this->FillTreeList(); this->UpdateTreeList(); } void QmitkViewNavigatorWidget::ResetCurrentPerspective() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to reset the current perspective?", QMessageBox::Yes | QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); page->ResetPerspective(); } } void QmitkViewNavigatorWidget::ClosePerspective() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close the current perspective?", QMessageBox::Yes | QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); page->ClosePerspective(page->GetPerspective(), true, true); } } void QmitkViewNavigatorWidget::CloseAllPerspectives() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close all perspectives?", QMessageBox::Yes | QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); page->CloseAllPerspectives(true, true); } } void QmitkViewNavigatorWidget::ExpandAll() { m_Controls.m_PluginTreeView->expandAll(); } void QmitkViewNavigatorWidget::CollapseAll() { m_Controls.m_PluginTreeView->collapseAll(); } void QmitkViewNavigatorWidget::CustomMenuRequested(QPoint pos) { QModelIndex index = m_Controls.m_PluginTreeView->indexAt(pos); QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index)); if (nullptr == m_ContextMenu) return; m_ContextMenu->clear(); QmitkPerspectiveItem* perspectiveItem = dynamic_cast(item); if (nullptr != perspectiveItem) { berry::IPerspectiveDescriptor::Pointer perspectiveDescriptor = perspectiveItem->m_ItemDescriptor; if (this->m_ActivePerspective.IsNotNull() && this->m_ActivePerspective == perspectiveDescriptor) { QAction* saveAsAction = new QAction("Save perspective as ...", this); m_ContextMenu->addAction(saveAsAction); connect(saveAsAction, SIGNAL(triggered()), SLOT(SaveCurrentPerspectiveAs())); m_ContextMenu->addSeparator(); } } QAction* resetAction = new QAction("Reset current perspective", this); m_ContextMenu->addAction(resetAction); connect(resetAction, SIGNAL(triggered()), SLOT(ResetCurrentPerspective())); QAction* closeAction = new QAction("Close perspective", this); m_ContextMenu->addAction(closeAction); connect(closeAction, SIGNAL(triggered()), SLOT(ClosePerspective())); QAction* closeAllAction = new QAction("Close all perspectives", this); m_ContextMenu->addAction(closeAllAction); connect(closeAllAction, SIGNAL(triggered()), SLOT(CloseAllPerspectives())); m_ContextMenu->addSeparator(); QAction* expandAction = new QAction("Expand tree", this); m_ContextMenu->addAction(expandAction); connect(expandAction, SIGNAL(triggered()), SLOT(ExpandAll())); QAction* collapseAction = new QAction("Collapse tree", this); m_ContextMenu->addAction(collapseAction); connect(collapseAction, SIGNAL(triggered()), SLOT(CollapseAll())); m_ContextMenu->popup(m_Controls.m_PluginTreeView->viewport()->mapToGlobal(pos)); } void QmitkViewNavigatorWidget::CreateQtPartControl(QWidget* parent) { // active workbench window available? if (m_Window.IsNull()) { return; } m_Controls.setupUi(parent); connect(m_Controls.m_PluginTreeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint))); connect(m_Controls.m_PluginTreeView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(ItemClicked(const QModelIndex&))); connect(m_Controls.lineEdit, SIGNAL(textChanged(QString)), SLOT(FilterChanged())); m_ContextMenu = new QMenu(m_Controls.m_PluginTreeView); m_Controls.m_PluginTreeView->setContextMenuPolicy(Qt::CustomContextMenu); // Create a new TreeModel for the data m_TreeModel = new QStandardItemModel(); m_FilterProxyModel = new ClassFilterProxyModel(this); m_FilterProxyModel->setSourceModel(m_TreeModel); m_Controls.m_PluginTreeView->setModel(m_FilterProxyModel); m_PerspectiveListener.reset(new ViewNavigatorPerspectiveListener(this)); m_Window->AddPerspectiveListener(m_PerspectiveListener.data()); m_ViewPartListener.reset(new ViewNavigatorViewListener(this)); m_Window->GetPartService()->AddPartListener(m_ViewPartListener.data()); } void QmitkViewNavigatorWidget::AddPerspectivesToTree() { berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); QList perspectiveDescriptors(perspRegistry->GetPerspectives()); qSort(perspectiveDescriptors.begin(), perspectiveDescriptors.end(), comparePerspectives); QStandardItem* perspectiveRootItem = new QStandardItem("Perspectives"); perspectiveRootItem->setFont(getLargeFont()); perspectiveRootItem->setEditable(false); QStandardItem* treeRootItem = m_TreeModel->invisibleRootItem(); treeRootItem->appendRow(perspectiveRootItem); this->AddItemsToTree, QmitkPerspectiveItem>( perspectiveDescriptors, perspectiveRootItem); } void QmitkViewNavigatorWidget::AddViewsToTree() { berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry(); QList viewDescriptors(viewRegistry->GetViews()); qSort(viewDescriptors.begin(), viewDescriptors.end(), compareViews); auto largeFont = getLargeFont(); QStandardItem* viewRootItem = new QStandardItem("Views"); viewRootItem->setFont(largeFont); viewRootItem->setEditable(false); QStandardItem* treeRootItem = m_TreeModel->invisibleRootItem(); treeRootItem->appendRow(viewRootItem); QStandardItem* miscellaneousCategoryItem = new QStandardItem("Miscellaneous"); miscellaneousCategoryItem->setFont(largeFont); miscellaneousCategoryItem->setEditable(false); QStringList viewExcludeList; // internal view used for the intro screen, will crash when opened directly, see T22352 viewExcludeList.append(QString("org.blueberry.ui.internal.introview")); viewExcludeList.append(QString("org.mitk.views.controlvisualizationpropertiesview")); viewExcludeList.append(QString("org.mitk.views.modules")); viewExcludeList.append(QString("org.mitk.views.viewnavigator")); this->AddItemsToTree, QmitkViewItem>( viewDescriptors, viewRootItem, miscellaneousCategoryItem, viewExcludeList); } template void QmitkViewNavigatorWidget::AddItemsToTree(D itemDescriptors, QStandardItem* rootItem, QStandardItem* miscellaneousItem, const QStringList& itemExcludeList) { KeywordRegistry keywordRegistry; std::vector categoryItems; for (const auto& itemDescriptor : itemDescriptors) { bool excludeView = itemExcludeList.contains(itemDescriptor->GetId()); if (excludeView) { continue; } QIcon icon = itemDescriptor->GetImageDescriptor(); I* item = new I(icon, itemDescriptor->GetLabel()); item->m_ItemDescriptor = itemDescriptor; item->m_Description = itemDescriptor->GetDescription(); item->setToolTip(itemDescriptor->GetDescription()); QStringList keylist = itemDescriptor->GetKeywordReferences(); item->m_Tags = keywordRegistry.GetKeywords(keylist); item->setEditable(false); QStringList categoryPath = itemDescriptor->GetCategoryPath(); if (categoryPath.empty()) { // If a root item for general / non-categorized item views is given, use it. // Otherwise put the non-categorized item views into the top root item. if (nullptr != miscellaneousItem) { miscellaneousItem->appendRow(item); } else { rootItem->appendRow(item); } } else { QStandardItem* categoryItem = nullptr; for (const auto& currentCategoryItem : categoryItems) { if (currentCategoryItem->text() == categoryPath.front()) { categoryItem = currentCategoryItem; break; } } if (nullptr == categoryItem) { categoryItem = new QStandardItem(QIcon(), categoryPath.front()); categoryItems.push_back(categoryItem); } auto font = getLargeFont(); categoryItem->setFont(font); categoryItem->setEditable(false); categoryItem->appendRow(item); } } std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems); for (const auto& categoryItem : categoryItems) { rootItem->appendRow(categoryItem); } if (nullptr != miscellaneousItem && miscellaneousItem->hasChildren()) { rootItem->appendRow(miscellaneousItem); } } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp index 5eaf8a507d..7c69d7a407 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatConnectionPreferencePage.cpp @@ -1,296 +1,296 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkXnatConnectionPreferencePage.h" #include "QmitkXnatTreeBrowserView.h" #include "org_mitk_gui_qt_xnatinterface_Activator.h" #include #include #include #include #include #include #include #include #include "ctkXnatSession.h" #include "ctkXnatLoginProfile.h" #include "ctkXnatException.h" #include #include #include #include using namespace berry; namespace { mitk::IPreferences* GetPreferences() { auto* preferencesService = mitk::CoreServices::GetPreferencesService(); return preferencesService->GetSystemPreferences()->Node(QmitkXnatTreeBrowserView::VIEW_ID.toStdString()); } } QmitkXnatConnectionPreferencePage::QmitkXnatConnectionPreferencePage() : m_Control(nullptr) { } void QmitkXnatConnectionPreferencePage::Init(berry::IWorkbench::Pointer) { } void QmitkXnatConnectionPreferencePage::CreateQtControl(QWidget* parent) { m_Controls.setupUi(parent); m_Control = new QWidget(parent); m_Control->setLayout(m_Controls.gridLayout); ctkXnatSession* session; try { session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (std::invalid_argument&) { session = nullptr; } if (session != nullptr && session->isOpen()) { m_Controls.xnatTestConnectionLabel->setStyleSheet("color: green"); m_Controls.xnatTestConnectionLabel->setText("Already connected."); m_Controls.xnatTestConnectionButton->setEnabled(false); } const QIntValidator *portV = new QIntValidator(0, 65535, parent); m_Controls.inXnatPort->setValidator(portV); - const QRegExp hostRx("^(https?)://[^ /](\\S)+$"); - const QRegExpValidator *hostV = new QRegExpValidator(hostRx, parent); + const QRegularExpression hostRx("^(https?)://[^ /](\\S)+$"); + const QRegularExpressionValidator *hostV = new QRegularExpressionValidator(hostRx, parent); m_Controls.inXnatHostAddress->setValidator(hostV); connect(m_Controls.xnatTestConnectionButton, SIGNAL(clicked()), this, SLOT(TestConnection())); connect(m_Controls.inXnatHostAddress, SIGNAL(editingFinished()), this, SLOT(UrlChanged())); connect(m_Controls.inXnatDownloadPath, SIGNAL(editingFinished()), this, SLOT(DownloadPathChanged())); connect(m_Controls.cbUseNetworkProxy, SIGNAL(toggled(bool)), this, SLOT(onUseNetworkProxy(bool))); connect(m_Controls.btnDownloadPath, SIGNAL(clicked()), this, SLOT(OnDownloadPathButtonClicked())); m_Controls.groupBoxProxySettings->setVisible(m_Controls.cbUseNetworkProxy->isChecked()); this->Update(); } QWidget* QmitkXnatConnectionPreferencePage::GetQtControl() const { return m_Control; } bool QmitkXnatConnectionPreferencePage::PerformOk() { auto* prefs = GetPreferences(); if (prefs != nullptr) { prefs->Put(m_Controls.xnatHostAddressLabel->text().toStdString(), m_Controls.inXnatHostAddress->text().toStdString()); prefs->Put(m_Controls.xnatPortLabel->text().toStdString(), m_Controls.inXnatPort->text().toStdString()); prefs->Put(m_Controls.xnatUsernameLabel->text().toStdString(), m_Controls.inXnatUsername->text().toStdString()); prefs->Put(m_Controls.xnatPasswortLabel->text().toStdString(), m_Controls.inXnatPassword->text().toStdString()); prefs->Put(m_Controls.xnatDownloadPathLabel->text().toStdString(), m_Controls.inXnatDownloadPath->text().toStdString()); // Network proxy settings prefs->PutBool(m_Controls.cbUseNetworkProxy->text().toStdString(), m_Controls.cbUseNetworkProxy->isChecked()); prefs->Put(m_Controls.proxyAddressLabel->text().toStdString(), m_Controls.inProxyAddress->text().toStdString()); prefs->Put(m_Controls.proxyPortLabel->text().toStdString(), m_Controls.inProxyPort->text().toStdString()); prefs->Put(m_Controls.proxyUsernameLabel->text().toStdString(), m_Controls.inProxyUsername->text().toStdString()); prefs->Put(m_Controls.proxyPasswordLabel->text().toStdString(), m_Controls.inProxyPassword->text().toStdString()); // Silent Mode prefs->PutBool(m_Controls.cbUseSilentMode->text().toStdString(), m_Controls.cbUseSilentMode->isChecked()); //Write prefs->Flush(); return true; } return false; } void QmitkXnatConnectionPreferencePage::PerformCancel() { } bool QmitkXnatConnectionPreferencePage::UserInformationEmpty() { // To check empty QLineEdits in the following QString errString; if (m_Controls.inXnatHostAddress->text().isEmpty()) { errString += "Server Address is empty.\n"; } if (m_Controls.inXnatUsername->text().isEmpty()) { errString += "Username is empty.\n"; } if (m_Controls.inXnatPassword->text().isEmpty()) { errString += "Password is empty.\n"; } // if something is empty if (!errString.isEmpty()) { m_Controls.xnatTestConnectionLabel->setStyleSheet("color: red"); m_Controls.xnatTestConnectionLabel->setText("Connecting failed.\n" + errString); return true; } else { return false; } } void QmitkXnatConnectionPreferencePage::Update() { auto* prefs = GetPreferences(); if (prefs != nullptr) { m_Controls.inXnatHostAddress->setText(QString::fromStdString(prefs->Get(m_Controls.xnatHostAddressLabel->text().toStdString(), m_Controls.inXnatHostAddress->text().toStdString()))); m_Controls.inXnatPort->setText(QString::fromStdString(prefs->Get(m_Controls.xnatPortLabel->text().toStdString(), m_Controls.inXnatPort->text().toStdString()))); m_Controls.inXnatUsername->setText(QString::fromStdString(prefs->Get(m_Controls.xnatUsernameLabel->text().toStdString(), m_Controls.inXnatUsername->text().toStdString()))); m_Controls.inXnatPassword->setText(QString::fromStdString(prefs->Get(m_Controls.xnatPasswortLabel->text().toStdString(), m_Controls.inXnatPassword->text().toStdString()))); m_Controls.inXnatDownloadPath->setText(QString::fromStdString(prefs->Get(m_Controls.xnatDownloadPathLabel->text().toStdString(), m_Controls.inXnatDownloadPath->text().toStdString()))); // Network proxy settings m_Controls.cbUseNetworkProxy->setChecked(prefs->GetBool(m_Controls.cbUseNetworkProxy->text().toStdString(), false)); m_Controls.inProxyAddress->setText(QString::fromStdString(prefs->Get(m_Controls.proxyAddressLabel->text().toStdString(), m_Controls.inProxyAddress->text().toStdString()))); m_Controls.inProxyPort->setText(QString::fromStdString(prefs->Get(m_Controls.proxyPortLabel->text().toStdString(), m_Controls.inProxyPort->text().toStdString()))); m_Controls.inProxyUsername->setText(QString::fromStdString(prefs->Get(m_Controls.proxyUsernameLabel->text().toStdString(), m_Controls.inProxyUsername->text().toStdString()))); m_Controls.inProxyPassword->setText(QString::fromStdString(prefs->Get(m_Controls.proxyPasswordLabel->text().toStdString(), m_Controls.inProxyPassword->text().toStdString()))); // Silent Mode m_Controls.cbUseSilentMode->setChecked(prefs->GetBool(m_Controls.cbUseSilentMode->text().toStdString(), false)); } } void QmitkXnatConnectionPreferencePage::UrlChanged() { m_Controls.inXnatHostAddress->setStyleSheet(""); QString str = m_Controls.inXnatHostAddress->text(); while (str.endsWith("/")) { str = str.left(str.length() - 1); } m_Controls.inXnatHostAddress->setText(str); QUrl url(m_Controls.inXnatHostAddress->text()); if (!url.isValid()) { m_Controls.inXnatHostAddress->setStyleSheet("background-color: red"); } } void QmitkXnatConnectionPreferencePage::DownloadPathChanged() { m_Controls.inXnatDownloadPath->setStyleSheet(""); QString downloadPath = m_Controls.inXnatDownloadPath->text(); if (!downloadPath.isEmpty()) { if (downloadPath.lastIndexOf("/") != downloadPath.size() - 1) { downloadPath.append("/"); m_Controls.inXnatDownloadPath->setText(downloadPath); } QFileInfo path(m_Controls.inXnatDownloadPath->text()); if (!path.isDir()) { m_Controls.inXnatDownloadPath->setStyleSheet("background-color: red"); } } } void QmitkXnatConnectionPreferencePage::onUseNetworkProxy(bool status) { m_Controls.groupBoxProxySettings->setVisible(status); } void QmitkXnatConnectionPreferencePage::OnDownloadPathButtonClicked() { QString dir = QFileDialog::getExistingDirectory(); if (!dir.endsWith("/") || !dir.endsWith("\\")) dir.append("/"); m_Controls.inXnatDownloadPath->setText(dir); } void QmitkXnatConnectionPreferencePage::TestConnection() { if(UserInformationEmpty()) { return; } try { mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (const std::invalid_argument &) { if (!UserInformationEmpty()) { PerformOk(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CreateXnatSession(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } } try { mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->OpenXnatSession(); m_Controls.xnatTestConnectionLabel->setStyleSheet("color: green"); m_Controls.xnatTestConnectionLabel->setText("Connecting successful."); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); } catch (const ctkXnatAuthenticationException& auth) { m_Controls.xnatTestConnectionLabel->setStyleSheet("color: red"); m_Controls.xnatTestConnectionLabel->setText("Connecting failed:\nAuthentication error."); MITK_INFO << auth.message().toStdString(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); } catch (const ctkException& e) { m_Controls.xnatTestConnectionLabel->setStyleSheet("color: red"); m_Controls.xnatTestConnectionLabel->setText("Connecting failed:\nInvalid Server Address\nPossibly due to missing OpenSSL for HTTPS connections"); MITK_INFO << e.message().toStdString(); mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()->CloseXnatSession(); } } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp index 20d52799b8..7d393bfb13 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatEditor.cpp @@ -1,571 +1,570 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkXnatEditor.h" // Qmitk #include "QmitkXnatObjectEditorInput.h" #include "org_mitk_gui_qt_xnatinterface_Activator.h" // CTK XNAT Core #include "ctkXnatObject.h" #include "ctkXnatDataModel.h" #include "ctkXnatFile.h" #include "ctkXnatResource.h" #include "ctkXnatScan.h" #include "ctkXnatScanFolder.h" #include "ctkXnatAssessor.h" #include "ctkXnatAssessorFolder.h" #include "ctkXnatReconstruction.h" #include "ctkXnatReconstructionFolder.h" // CTK XNAT Widgets #include "ctkXnatListModel.h" // Blueberry #include #include // Qt #include -#include #include #include #include #include // MITK #include #include #include #include #include // Poco #include const QString QmitkXnatEditor::EDITOR_ID = "org.mitk.editors.xnat.browser"; QmitkXnatEditor::QmitkXnatEditor() : m_DownloadPath(QString::fromStdString(mitk::CoreServices::GetPreferencesService()-> GetSystemPreferences()->Node("/XnatConnection")->Get("Download Path", ""))), m_ListModel(new ctkXnatListModel()), m_Session(0), m_DataStorageServiceTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()), m_SelectionListener(new berry::SelectionChangedAdapter(this, &QmitkXnatEditor::SelectionChanged)) { m_DataStorageServiceTracker.open(); if (m_DownloadPath.isEmpty()) { QString xnatFolder = "XNAT_DOWNLOADS"; QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath()); dir.mkdir(xnatFolder); dir.setPath(dir.path() + "/" + xnatFolder); m_DownloadPath = dir.path() + "/"; } } QmitkXnatEditor::~QmitkXnatEditor() { delete m_ListModel; berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); s->RemoveSelectionListener(m_SelectionListener.data()); m_DataStorageServiceTracker.close(); } bool QmitkXnatEditor::IsDirty() const { return false; } bool QmitkXnatEditor::IsSaveAsAllowed() const { return false; } void QmitkXnatEditor::Init(berry::IEditorSite::Pointer site, berry::IEditorInput::Pointer input) { this->SetSite(site); berry::QtEditorPart::SetInput(input); this->SetInput(input); } void QmitkXnatEditor::DoSave() { } void QmitkXnatEditor::DoSaveAs() { } void QmitkXnatEditor::SetInput(berry::IEditorInput::Pointer input) { QmitkXnatObjectEditorInput::Pointer oPtr = input.Cast(); if (oPtr.IsNotNull()) { berry::QtEditorPart::SetInput(oPtr); this->GetEditorInput().Cast()->GetXnatObject()->fetch(); } } void QmitkXnatEditor::SetFocus() { } void QmitkXnatEditor::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.buttonDownload->setEnabled(false); m_Controls.labelDownload->setText("Select a xnat file, resource, scan, or scan folder to download..."); GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener(m_SelectionListener.data()); connect(m_Controls.treeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(OnObjectActivated(const QModelIndex&))); connect(m_Controls.buttonDownload, SIGNAL(clicked()), this, SLOT(DownloadResource())); connect(m_Controls.buttonDataModel, SIGNAL(clicked()), this, SLOT(OnDataModelButtonClicked())); connect(m_Controls.buttonProject, SIGNAL(clicked()), this, SLOT(OnProjectButtonClicked())); connect(m_Controls.buttonSubject, SIGNAL(clicked()), this, SLOT(OnSubjectButtonClicked())); connect(m_Controls.buttonExperiment, SIGNAL(clicked()), this, SLOT(OnExperimentButtonClicked())); connect(m_Controls.buttonKindOfData, SIGNAL(clicked()), this, SLOT(OnKindOfDataButtonClicked())); connect(m_Controls.buttonSession, SIGNAL(clicked()), this, SLOT(OnSessionButtonClicked())); connect(m_Controls.buttonResource, SIGNAL(clicked()), this, SLOT(OnResourceButtonClicked())); connect(m_Controls.treeView, SIGNAL(clicked(const QModelIndex&)), SLOT(itemSelected(const QModelIndex&))); m_Tracker = new mitk::XnatSessionTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()); connect(m_Tracker, SIGNAL(AboutToBeClosed(ctkXnatSession*)), this, SLOT(CleanListModel(ctkXnatSession*))); connect(m_Tracker, SIGNAL(Opened(ctkXnatSession*)), this, SLOT(UpdateSession(ctkXnatSession*))); m_Tracker->Open(); // Makes the breadcrumb feature invisible for (int i = 0; i < m_Controls.breadcrumbHorizontalLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i); child->widget()->setVisible(false); } for (int i = 0; i < m_Controls.breadcrumbDescriptionLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbDescriptionLayout->itemAt(i); child->widget()->setVisible(false); } QmitkXnatObjectEditorInput::Pointer oPtr = GetEditorInput().Cast(); if (oPtr.IsNotNull()) { UpdateList(); } else { ctkXnatSession* session; try { session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (std::invalid_argument) { session = 0; } UpdateSession(session); } } void QmitkXnatEditor::UpdateList() { QmitkXnatObjectEditorInput::Pointer xoPtr(GetEditorInput().Cast()); if (xoPtr.IsNull()) return; ctkXnatObject* inputObject = xoPtr->GetXnatObject(); if (inputObject == nullptr) return; m_Controls.treeView->setModel(m_ListModel); m_ListModel->setRootObject(inputObject); m_Controls.treeView->reset(); // recursive method to check parents of the inputObject m_ParentCount = ParentChecker(inputObject); // breadcrumb labels for (int i = 0; i < m_Controls.breadcrumbHorizontalLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i); child->widget()->setVisible(false); } for (int i = 0; i < m_Controls.breadcrumbDescriptionLayout->count() - 1; i++) { QLayoutItem* child = m_Controls.breadcrumbDescriptionLayout->itemAt(i); child->widget()->setVisible(false); } ctkXnatObject* parent = nullptr; for (int i = m_ParentCount * 2; i >= 0; i--) { if (i > 12) break; m_Controls.breadcrumbDescriptionLayout->itemAt(i)->widget()->setVisible(true); QLayoutItem* child = m_Controls.breadcrumbHorizontalLayout->itemAt(i); child->widget()->setVisible(true); if (i > 0) { m_Controls.breadcrumbHorizontalLayout->itemAt(i - 1)->widget()->setVisible(true); m_Controls.breadcrumbDescriptionLayout->itemAt(i - 1)->widget()->setVisible(true); } if (parent == nullptr) { parent = inputObject; } // create breadcrumb button QPushButton* breadcrumbButton = dynamic_cast(child->widget()); breadcrumbButton->setText(parent->id()); parent = parent->parent(); i--; } m_Controls.buttonDataModel->setText("root"); m_Controls.buttonDownload->setEnabled(false); m_Controls.labelDownload->setVisible(true); } void QmitkXnatEditor::SelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, const berry::ISelection::ConstPointer& selection) { // check for null selection if (selection.IsNull()) { return; } // exclude own selection events and check whether this kind of selection can be handled if (sourcepart != this && selection.Cast()) { berry::IStructuredSelection::ConstPointer currentSelection = selection.Cast(); // iterates over the selection for (berry::IStructuredSelection::iterator itr = currentSelection->Begin(); itr != currentSelection->End(); ++itr) { if (berry::SmartPointer objectPointer = itr->Cast()) { // get object of selected ListWidgetElement ctkXnatObject* object = objectPointer->GetQModelIndex().data(Qt::UserRole).value(); // if a file is selected, don't change the input and list view if (dynamic_cast(object) == nullptr) { QmitkXnatObjectEditorInput::Pointer oPtr(new QmitkXnatObjectEditorInput(object)); berry::IEditorInput::Pointer editorInput(oPtr); if (!(editorInput == this->GetEditorInput())) this->SetInput(editorInput); UpdateList(); } } } } } void QmitkXnatEditor::DownloadResource() { if (!m_Controls.listView->selectionModel()->hasSelection()) return; const QModelIndex index = m_Controls.listView->selectionModel()->currentIndex(); QVariant variant = m_ListModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatObject* resource = variant.value(); if (dynamic_cast(resource) == nullptr) { MITK_INFO << "Download started ..."; MITK_INFO << "..."; QString resourceName = m_ListModel->data(index, Qt::DisplayRole).toString(); QString resourcePath = m_DownloadPath + resourceName + ".zip"; resource->download(resourcePath); // Testing if the path exists QDir downDir(m_DownloadPath); if (downDir.exists(resourceName + ".zip")) { MITK_INFO << "Download of " << resourceName.toStdString() << ".zip was completed!"; } else { MITK_INFO << "Download of " << resourceName.toStdString() << ".zip failed!"; } } else { InternalFileDownload(index); } } } void QmitkXnatEditor::DownloadFile() { if (!m_Controls.listView->selectionModel()->hasSelection()) return; const QModelIndex index = m_Controls.listView->selectionModel()->currentIndex(); InternalFileDownload(index); } void QmitkXnatEditor::ToHigherLevel() { ctkXnatObject* parent = GetEditorInput().Cast()->GetXnatObject()->parent(); if (parent == nullptr) { return; } QmitkXnatObjectEditorInput::Pointer oPtr(new QmitkXnatObjectEditorInput(parent)); berry::IEditorInput::Pointer editorInput(oPtr); this->SetInput(editorInput); UpdateList(); } void QmitkXnatEditor::OnObjectActivated(const QModelIndex &index) { if (!index.isValid()) return; ctkXnatObject* child = GetEditorInput().Cast()->GetXnatObject()->children().at(index.row()); if (child != nullptr) { ctkXnatFile* file = dynamic_cast(child); if (file != nullptr) { // Download file and put into datamanager InternalFileDownload(index); mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService(); if (dsService != nullptr) { QString name = file->property("Name"); QString filePath = m_DownloadPath + name; if (file->property("collection") == "DICOM") { QDirIterator it(m_DownloadPath, QStringList() << name, QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { it.next(); filePath = it.filePath(); } } mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService(); mitk::DataStorage::Pointer dataStorage = dsService->GetDataStorage()->GetDataStorage(); QStringList list; list << filePath; try { QmitkIOUtil::Load(list, *dataStorage); } catch (const mitk::Exception& e) { MITK_INFO << e; return; } mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects( dsService->GetDataStorage()->GetDataStorage()); } } else { // Updates the root item QmitkXnatObjectEditorInput::Pointer oPtr(new QmitkXnatObjectEditorInput(child)); berry::IEditorInput::Pointer editorInput(oPtr); this->SetInput(editorInput); this->GetEditorInput().Cast()->GetXnatObject()->fetch(); UpdateList(); } } } void QmitkXnatEditor::InternalFileDownload(const QModelIndex& index) { QVariant variant = m_ListModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatFile* file = dynamic_cast(variant.value()); if (file != nullptr) { // Testing if the file exists QDir downDir(m_DownloadPath); if (downDir.exists(file->property("Name"))) { MITK_INFO << "File exists already!"; return; } if (file->property("collection") == QString("DICOM")) { ctkXnatObject* parent = file->parent(); QString filePath = m_DownloadPath + parent->property("label") + ".zip"; parent->download(filePath); std::ifstream in(filePath.toStdString().c_str(), std::ios::binary); poco_assert(in); // decompress to XNAT_DOWNLOAD dir Poco::Zip::Decompress dec(in, Poco::Path(m_DownloadPath.toStdString())); dec.decompressAllFiles(); in.close(); QFile::remove(filePath); } else { MITK_INFO << "Download started ..."; MITK_INFO << "..."; QString name = file->property("Name"); QString filePath = m_DownloadPath + name; file->download(filePath); // Testing if the file exists QDir downDir(m_DownloadPath); if (downDir.exists(name)) { MITK_INFO << "Download of " << file->name().toStdString() << " was completed!"; } else { MITK_INFO << "Download of " << file->name().toStdString() << " failed!"; } } } else { MITK_INFO << "Selection was not a file!"; } } } int QmitkXnatEditor::ParentChecker(ctkXnatObject* child) { int sum; if (child->parent() == nullptr) { return 0; } else { sum = 1 + ParentChecker(child->parent()); } return sum; } void QmitkXnatEditor::OnDataModelButtonClicked() { for (int i = m_ParentCount; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnProjectButtonClicked() { for (int i = m_ParentCount - 1; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnSubjectButtonClicked() { for (int i = m_ParentCount - 2; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnExperimentButtonClicked() { for (int i = m_ParentCount - 3; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnKindOfDataButtonClicked() { for (int i = m_ParentCount - 4; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnSessionButtonClicked() { for (int i = m_ParentCount - 5; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::OnResourceButtonClicked() { for (int i = m_ParentCount - 6; i > 0; i--) { ToHigherLevel(); } } void QmitkXnatEditor::UpdateSession(ctkXnatSession* session) { GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemoveSelectionListener(m_SelectionListener.data()); if (session != 0 && session->isOpen()) { m_Controls.labelInfo->setText("Current Position:"); m_Controls.labelInfo->setStyleSheet("QLabel { color: black; }"); // Fill model and show in the GUI QmitkXnatObjectEditorInput::Pointer xoPtr(new QmitkXnatObjectEditorInput(session->dataModel())); berry::IEditorInput::Pointer editorInput(xoPtr); this->SetInput(editorInput); this->GetEditorInput().Cast()->GetXnatObject()->fetch(); UpdateList(); } else { m_Controls.labelInfo->setText("Please check the Preferences of the XNAT Connection.\nMaybe they are not ok."); m_Controls.labelInfo->setStyleSheet("QLabel { color: red; }"); } GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener(m_SelectionListener.data()); } void QmitkXnatEditor::CleanListModel(ctkXnatSession* session) { if (session != 0) { m_Controls.listView->setModel(0); m_ListModel->setRootObject(0); m_Controls.treeView->reset(); } } void QmitkXnatEditor::itemSelected(const QModelIndex &index) { ctkXnatObject* xnatObject = m_ListModel->data(index, Qt::UserRole).value(); bool downloadable = false; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; downloadable |= dynamic_cast(xnatObject) != nullptr; m_Controls.buttonDownload->setEnabled(downloadable); m_Controls.labelDownload->setVisible(!downloadable); } diff --git a/Utilities/qtsingleapplication/qtlocalpeer.cpp b/Utilities/qtsingleapplication/qtlocalpeer.cpp index 1f1c7f2b2b..d52366e56d 100644 --- a/Utilities/qtsingleapplication/qtlocalpeer.cpp +++ b/Utilities/qtsingleapplication/qtlocalpeer.cpp @@ -1,202 +1,203 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlocalpeer.h" #include #include +#include #include #if defined(Q_OS_WIN) #include #include typedef BOOL(WINAPI *PProcessIdToSessionId)(DWORD, DWORD *); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include #include #include #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } const char *QtLocalPeer::ack = "ack"; QtLocalPeer::QtLocalPeer(QObject *parent, const QString &appId) : QObject(parent), id(appId) { QString prefix = id; if (id.isEmpty()) { id = QCoreApplication::applicationFilePath(); #if defined(Q_OS_WIN) id = id.toLower(); #endif prefix = id.section(QLatin1Char('/'), -1); } - prefix.remove(QRegExp("[^a-zA-Z]")); + prefix.remove(QRegularExpression("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); quint16 idNum = qChecksum(idc.constData(), idc.size()); socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); } #else socketName += QLatin1Char('-') + QString::number(::getuid(), 16); #endif server = new QLocalServer(this); QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile"); lockFile.setFileName(lockName); lockFile.open(QIODevice::ReadWrite); } bool QtLocalPeer::isClient() { if (lockFile.isLocked()) return false; if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) return true; bool res = server->listen(socketName); #if defined(Q_OS_UNIX) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName); res = server->listen(socketName); } #endif if (!res) qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); return false; } bool QtLocalPeer::sendMessage(const QByteArray &message, int timeout) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for (int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout / 2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = {ms / 1000, (ms % 1000) * 1000 * 1000}; nanosleep(&ts, nullptr); #endif } if (!connOk) return false; QDataStream ds(&socket); ds.writeBytes(message.constData(), message.size()); bool res = socket.waitForBytesWritten(timeout); if (res) { res &= socket.waitForReadyRead(timeout); // wait for ack if (res) res &= (socket.read(qstrlen(ack)) == ack); } return res; } void QtLocalPeer::receiveConnection() { QLocalSocket *socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char *uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); // make sure client reads ack delete socket; emit messageReceived(uMsg); //### (might take a long time to return) }