diff --git a/Modules/QtWidgets/include/QmitkNodeSelectionButton.h b/Modules/QtWidgets/include/QmitkNodeSelectionButton.h index 2b400c5900..111c63a34a 100644 --- a/Modules/QtWidgets/include/QmitkNodeSelectionButton.h +++ b/Modules/QtWidgets/include/QmitkNodeSelectionButton.h @@ -1,71 +1,71 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkNodeSelectionButton_h #define QmitkNodeSelectionButton_h #include #include #include #include /** * @class QmitkNodeSelectionButton * @brief Button class that can be used to display information about a given node. * If the given node is a nullptr the node info text will be shown. -* The node info can be formated text (e.g. HTML code; like the tooltip text). +* The node info can be formatted text (e.g. HTML code; like the tooltip text). */ class MITKQTWIDGETS_EXPORT QmitkNodeSelectionButton : public QPushButton { Q_OBJECT public: explicit QmitkNodeSelectionButton(QWidget *parent = nullptr); ~QmitkNodeSelectionButton() override; const mitk::DataNode* GetSelectedNode() const; bool GetSelectionIsOptional() const; public Q_SLOTS: virtual void SetSelectedNode(const mitk::DataNode* node); virtual void SetNodeInfo(QString info); /** Set the widget into an optional mode. Optional means that the selection of no valid node does not mean an invalid state. Thus no node is a valid "node" selection too. The state influences if the info text is handled as an information (optional) or a warning (optiona==false).*/ void SetSelectionIsOptional(bool isOptional); protected: void paintEvent(QPaintEvent *p) override; void changeEvent(QEvent *event) override; void AddNodeObserver(); void RemoveNodeObserver(); void OnNodeModified(const itk::Object * /*caller*/, const itk::EventObject &); mitk::DataNode::ConstPointer m_SelectedNode; QString m_Info; bool m_OutDatedThumbNail; QPixmap m_ThumbNail; itk::ModifiedTimeType m_DataMTime; itk::ModifiedTimeType m_SelectionPropMTime; bool m_IsOptional; unsigned long m_NodeModifiedObserverTag; bool m_NodeObserved; }; #endif diff --git a/Modules/QtWidgets/include/QmitkSingleNodeSelectionWidget.h b/Modules/QtWidgets/include/QmitkSingleNodeSelectionWidget.h index 2ce34485c9..44130cb7e6 100644 --- a/Modules/QtWidgets/include/QmitkSingleNodeSelectionWidget.h +++ b/Modules/QtWidgets/include/QmitkSingleNodeSelectionWidget.h @@ -1,97 +1,97 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkSingleNodeSelectionWidget_h #define QmitkSingleNodeSelectionWidget_h #include #include #include #include #include #include #include class QmitkAbstractDataStorageModel; /** * @class QmitkSingleNodeSelectionWidget * @brief Widget that represents a node selection of (max) one node. It acts like a button. Clicking on it * allows to change the selection. * * @remark This class provides a public function 'SetAutoSelectNewNodes' that can be used to enable * the auto selection mode (default is false). * The user of this class calling this function has to make sure that the base-class Q_SIGNAL * 'CurrentSelectionChanged', which will be emitted by this function, is already * connected to a receiving slot, if the initial valid auto selection should not get lost. */ class MITKQTWIDGETS_EXPORT QmitkSingleNodeSelectionWidget : public QmitkAbstractNodeSelectionWidget { Q_OBJECT public: explicit QmitkSingleNodeSelectionWidget(QWidget* parent = nullptr); mitk::DataNode::Pointer GetSelectedNode() const; bool GetAutoSelectNewNodes() const; using NodeList = QmitkAbstractNodeSelectionWidget::NodeList; public Q_SLOTS: void SetCurrentSelectedNode(mitk::DataNode* selectedNode); /** * Sets the auto selection mode (default is false). - * If auto select is true and the following conditions are fullfilled, the widget will + * If auto select is true and the following conditions are fulfilled, the widget will * select a node automatically from the data storage: * - a data storage is set * - data storage contains at least one node that matches the given predicate * - no selection is set * * @remark Enabling the auto selection mode by calling 'SetAutoSelectNewNodes(true)' * will directly emit a 'QmitkSingleNodeSelectionWidget::CurrentSelectionChanged' Q_SIGNAL * if a valid auto selection was made. * If this initial emission should not get lost, auto selection mode needs to be enabled after this * selection widget has been connected via the 'QmitkSingleNodeSelectionWidget::CurrentSelectionChanged' * Q_SIGNAL to a receiving function. */ void SetAutoSelectNewNodes(bool autoSelect); protected Q_SLOTS: virtual void OnClearSelection(); protected: void ReviseSelectionChanged(const NodeList& oldInternalSelection, NodeList& newInternalSelection) override; bool eventFilter(QObject *obj, QEvent *ev) override; void EditSelection(); void UpdateInfo() override; void OnDataStorageChanged() override; void OnNodeAddedToStorage(const mitk::DataNode* node) override; void AutoSelectNodes(); /** Helper function that gets a suitable auto selected node from the datastorage that fits to the predicate settings. - @param ignoreNodes You may pass a list of nodes that must not be choosen as auto selected node. */ + @param ignoreNodes You may pass a list of nodes that must not be chosen as auto selected node. */ mitk::DataNode::Pointer DetermineAutoSelectNode(const NodeList& ignoreNodes = {}); /** See documentation of SetAutoSelectNewNodes for details*/ bool m_AutoSelectNodes; Ui_QmitkSingleNodeSelectionWidget m_Controls; }; #endif diff --git a/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.cpp b/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.cpp index 883633b384..73d64e883f 100644 --- a/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.cpp +++ b/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.cpp @@ -1,259 +1,259 @@ /*============================================================================ 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 "QmitkContourModelToImageWidget.h" #include #include #include #include #include #include #include #include #include #include #include static const char* const HelpText = "Select a image and a contour(set)"; class QmitkContourModelToImageWidgetPrivate { public: QmitkContourModelToImageWidgetPrivate(); ~QmitkContourModelToImageWidgetPrivate(); /** @brief Check if selections is valid. */ void SelectionControl( unsigned int index, const mitk::DataNode* selection); - /** @brief Enable buttons if data selction is valid. */ + /** @brief Enable buttons if data selection is valid. */ void EnableButtons(bool enable = true); /** @brief Does the actual contour filling */ mitk::LabelSetImage::Pointer FillContourModelSetIntoImage(mitk::Image *image, mitk::ContourModelSet *contourSet, mitk::TimePointType timePoint); Ui::QmitkContourModelToImageWidgetControls m_Controls; QFutureWatcher m_Watcher; }; QmitkContourModelToImageWidgetPrivate::QmitkContourModelToImageWidgetPrivate() { } QmitkContourModelToImageWidgetPrivate::~QmitkContourModelToImageWidgetPrivate() { } void QmitkContourModelToImageWidgetPrivate::EnableButtons(bool enable) { m_Controls.btnProcess->setEnabled(enable); } void QmitkContourModelToImageWidgetPrivate::SelectionControl(unsigned int index, const mitk::DataNode* /*selection*/) { QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(index); dataSelectionWidget->SetHelpText(""); this->EnableButtons(); } mitk::LabelSetImage::Pointer QmitkContourModelToImageWidgetPrivate::FillContourModelSetIntoImage(mitk::Image* image, mitk::ContourModelSet* contourSet, mitk::TimePointType timePoint) { // Use mitk::ContourModelSetToImageFilter to fill the ContourModelSet into the image mitk::ContourModelSetToImageFilter::Pointer contourFiller = mitk::ContourModelSetToImageFilter::New(); auto timeStep = image->GetTimeGeometry()->TimePointToTimeStep(timePoint); contourFiller->SetTimeStep(timeStep); contourFiller->SetImage(image); contourFiller->SetInput(contourSet); contourFiller->MakeOutputBinaryOn(); try { contourFiller->Update(); } catch (const std::exception & e) { MITK_ERROR << "Error while converting contour model. "<< e.what(); } catch (...) { MITK_ERROR << "Unknown error while converting contour model."; } if (nullptr == contourFiller->GetOutput()) { MITK_ERROR<<"Could not write the selected contours into the image!"; } auto result = mitk::LabelSetImage::New(); result->InitializeByLabeledImage(contourFiller->GetOutput()); return result; } void QmitkContourModelToImageWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection) { Q_D(QmitkContourModelToImageWidget); QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node0 = dataSelectionWidget->GetSelection(0); mitk::DataNode::Pointer node1 = dataSelectionWidget->GetSelection(1); if (node0.IsNull() || node1.IsNull() ) { d->EnableButtons(false); dataSelectionWidget->SetHelpText(HelpText); } else { d->SelectionControl(index, selection); } } void QmitkContourModelToImageWidget::OnProcessingFinished() { // Called when processing finished // Adding the result to the data storage Q_D(QmitkContourModelToImageWidget); // Adding the result to the data storage auto result = d->m_Watcher.result(); if (result.IsNotNull()) { QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget; mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0); mitk::DataNode::Pointer contourNode = dataSelectionWidget->GetSelection(1); mitk::DataNode::Pointer filled = mitk::DataNode::New(); std::stringstream stream; stream << imageNode->GetName(); stream << "_"; stream << contourNode->GetName(); filled->SetName(stream.str()); filled->SetData(result); auto dataStorage = dataSelectionWidget->GetDataStorage(); if (dataStorage.IsNull()) { std::string exception = "Cannot add result to the data storage. Data storage invalid."; MITK_ERROR << "Error filling contours into an image: " << exception; QMessageBox::information(nullptr, "Error filling contours into an image", QString::fromStdString(exception)); } dataStorage->Add(filled, imageNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else { MITK_ERROR<<"Error filling contours into an image!"; } d->EnableButtons(); } void QmitkContourModelToImageWidget::OnProcessPressed() { Q_D(QmitkContourModelToImageWidget); QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget; mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0); mitk::DataNode::Pointer contourNode = dataSelectionWidget->GetSelection(1); // Check if data nodes are valid if(imageNode.IsNull() || contourNode.IsNull() ) { MITK_ERROR << "Selection does not contain valid data"; QMessageBox::information( this, "Contour To Image", "Selection does not contain valid data, please select a binary image and a contour(set)", QMessageBox::Ok ); d->m_Controls.btnProcess->setEnabled(false); return; } mitk::Image::Pointer image = static_cast(imageNode->GetData()); // Check if the image is valid if (image.IsNull()) { MITK_ERROR<<"Error writing contours into image! Invalid image data selected!"; return; } const auto timePoint = this->GetTimeNavigationController()->GetSelectedTimePoint(); if (!image->GetTimeGeometry()->IsValidTimePoint(timePoint)) { MITK_ERROR << "Error writing contours into image! Currently selected time point is not supported by selected image data."; return; } // Check if the selected contours are valid mitk::ContourModelSet::Pointer contourSet; mitk::ContourModel::Pointer contour = dynamic_cast(contourNode->GetData()); if (contour.IsNotNull()) { contourSet = mitk::ContourModelSet::New(); contourSet->AddContourModel(contour); } else { contourSet = static_cast(contourNode->GetData()); if (contourSet.IsNull()) { MITK_ERROR<<"Error writing contours into binary image! Invalid contour data selected!"; return; } } //Disable Buttons during calculation and initialize Progressbar d->EnableButtons(false); // Start the computation in a background thread QFuture< mitk::LabelSetImage::Pointer > future = QtConcurrent::run(d, &QmitkContourModelToImageWidgetPrivate::FillContourModelSetIntoImage, image, contourSet, timePoint); d->m_Watcher.setFuture(future); } QmitkContourModelToImageWidget::QmitkContourModelToImageWidget(mitk::DataStorage* dataStorage, mitk::SliceNavigationController* timeNavigationController, QWidget* parent) : QmitkSegmentationUtilityWidget(timeNavigationController, parent), d_ptr(new QmitkContourModelToImageWidgetPrivate()) { Q_D(QmitkContourModelToImageWidget); // Set up UI d->m_Controls.setupUi(this); d->m_Controls.dataSelectionWidget->SetDataStorage(dataStorage); d->m_Controls.dataSelectionWidget->AddDataSelection(QmitkDataSelectionWidget::ImageAndSegmentationPredicate); d->m_Controls.dataSelectionWidget->AddDataSelection(QmitkDataSelectionWidget::ContourModelPredicate); d->m_Controls.dataSelectionWidget->SetHelpText(HelpText); d->EnableButtons(false); // Create connections connect (d->m_Controls.btnProcess, SIGNAL(pressed()), this, SLOT(OnProcessPressed())); connect(d->m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)), this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*))); connect(&d->m_Watcher, SIGNAL(finished()), this, SLOT(OnProcessingFinished())); if( d->m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() && d->m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() ) { OnSelectionChanged(0, d->m_Controls.dataSelectionWidget->GetSelection(0)); } } QmitkContourModelToImageWidget::~QmitkContourModelToImageWidget() { } diff --git a/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.h b/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.h index 562d254434..7c56d7e265 100644 --- a/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.h +++ b/Modules/SegmentationUI/SegmentationUtilities/QmitkContourModelToImageWidget.h @@ -1,76 +1,76 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkContourModelToImageWidget_h #define QmitkContourModelToImageWidget_h #include #include #include class QmitkContourModelToImageWidgetPrivate; namespace mitk { class DataNode; class DataStorage; class Image; class ContourModelSet; class ContourModel; class Geometry3D; class PlaneGeometry; } /*! \brief QmitkContourModelToImageWidget Tool masks an image with a binary image or a surface. The Method requires an image and a binary image mask or a surface. The input image and the binary image mask must be of the same size. Masking with a surface creates first a binary image of the surface and then use this for the masking of the input image. */ class MITKSEGMENTATIONUI_EXPORT QmitkContourModelToImageWidget : public QmitkSegmentationUtilityWidget { Q_OBJECT public: /** @brief Default constructor, including creation of GUI elements and signals/slots connections. */ explicit QmitkContourModelToImageWidget(mitk::DataStorage* dataStorage, mitk::SliceNavigationController* timeNavigationController, QWidget* parent = nullptr); - /** @brief Defaul destructor. */ + /** @brief Default destructor. */ ~QmitkContourModelToImageWidget() override; private slots: /** @brief This slot is called if the selection in the workbench is changed. */ void OnSelectionChanged(unsigned int index, const mitk::DataNode* selection); /** @brief This slot is called if user activates the button to mask an image. */ void OnProcessPressed(); /** @brief This slot is called after processing is finished */ void OnProcessingFinished(); private: QScopedPointer d_ptr; Q_DECLARE_PRIVATE(QmitkContourModelToImageWidget) Q_DISABLE_COPY(QmitkContourModelToImageWidget) }; #endif diff --git a/Modules/SegmentationUI/SegmentationUtilities/QmitkImageMaskingWidget.h b/Modules/SegmentationUI/SegmentationUtilities/QmitkImageMaskingWidget.h index b8be1847bf..885ab6aa08 100644 --- a/Modules/SegmentationUI/SegmentationUtilities/QmitkImageMaskingWidget.h +++ b/Modules/SegmentationUI/SegmentationUtilities/QmitkImageMaskingWidget.h @@ -1,87 +1,87 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkImageMaskingWidget_h #define QmitkImageMaskingWidget_h #include #include #include #include namespace Ui { class QmitkImageMaskingWidgetControls; } namespace mitk { class DataStorage; class Image; } /*! \brief QmitkImageMaskingWidget Tool masks an image with a binary image or a surface. The Method requires an image and a binary image mask or a surface. The input image and the binary image mask must be of the same size. Masking with a surface creates first a binary image of the surface and then use this for the masking of the input image. */ class MITKSEGMENTATIONUI_EXPORT QmitkImageMaskingWidget : public QmitkSegmentationUtilityWidget { Q_OBJECT public: /** @brief Default constructor, including creation of GUI elements and signals/slots connections. */ explicit QmitkImageMaskingWidget(mitk::DataStorage* dataStorage, mitk::SliceNavigationController* timeNavigationController, QWidget* parent = nullptr); - /** @brief Defaul destructor. */ + /** @brief Default destructor. */ ~QmitkImageMaskingWidget() override; private slots: /** @brief This slot is called if the selection in the workbench is changed. */ void OnSelectionChanged(unsigned int index, const mitk::DataNode* selection); /** @brief This slot is called if user activates the button to mask an image. */ void OnMaskImagePressed(); /** @brief This slot is called if the user toggles the "Custom" radio button. */ void OnCustomValueButtonToggled(bool checked); private: /** @brief Check if selections is valid. */ void SelectionControl( unsigned int index, const mitk::DataNode* selection); - /** @brief Enable buttons if data selction is valid. */ + /** @brief Enable buttons if data selection is valid. */ void EnableButtons(bool enable = true); /** @brief Mask an image with a given binary mask. Note that the input image and the mask image must be of the same size. */ itk::SmartPointer MaskImage(itk::SmartPointer referenceImage, itk::SmartPointer maskImage ); /** @brief Convert a surface into an binary image. */ itk::SmartPointer ConvertSurfaceToImage( itk::SmartPointer image, mitk::Surface::Pointer surface ); /** @brief Adds a new data object to the DataStorage.*/ void AddToDataStorage(mitk::DataStorage::Pointer dataStorage, itk::SmartPointer segmentation, const std::string& name, mitk::DataNode::Pointer parent = nullptr); Ui::QmitkImageMaskingWidgetControls* m_Controls; }; #endif diff --git a/Modules/SegmentationUI/SegmentationUtilities/QmitkSurfaceToImageWidget.h b/Modules/SegmentationUI/SegmentationUtilities/QmitkSurfaceToImageWidget.h index 55e2178163..dcc182211c 100644 --- a/Modules/SegmentationUI/SegmentationUtilities/QmitkSurfaceToImageWidget.h +++ b/Modules/SegmentationUI/SegmentationUtilities/QmitkSurfaceToImageWidget.h @@ -1,77 +1,77 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkSurfaceToImageWidget_h #define QmitkSurfaceToImageWidget_h #include #include #include "itkSmartPointer.h" namespace Ui { class QmitkSurfaceToImageWidgetControls; } namespace mitk { class DataNode; class DataStorage; class Surface; class Image; class LabelSetImage; } /*! \brief QmitkSurfaceToImageWidget The Tool converts a surface to a binary image. The Method requires a surface and an image, which header information defines the output image. The resulting binary image has the same dimension, size, and Geometry3D as the input image. */ class MITKSEGMENTATIONUI_EXPORT QmitkSurfaceToImageWidget : public QmitkSegmentationUtilityWidget { Q_OBJECT public: /** @brief Default constructor, including creation of GUI elements and signals/slots connections. */ explicit QmitkSurfaceToImageWidget(mitk::DataStorage* dataStorage, mitk::SliceNavigationController* timeNavigationController, QWidget* parent = nullptr); - /** @brief Defaul destructor. */ + /** @brief Default destructor. */ ~QmitkSurfaceToImageWidget() override; private slots: /** @brief This slot is called if the selection in the workbench is changed. */ void OnSelectionChanged(unsigned int index, const mitk::DataNode* selection); /** @brief This slot is called if user activates the button to convert a surface into a binary image. */ void OnSurface2ImagePressed(); private: - /** @brief Enable buttons if data selction is valid. */ + /** @brief Enable buttons if data selection is valid. */ void EnableButtons(bool enable = true); /** @brief Convert a surface into an binary image. */ itk::SmartPointer ConvertSurfaceToImage( itk::SmartPointer image, itk::SmartPointer surface ); Ui::QmitkSurfaceToImageWidgetControls* m_Controls; }; #endif diff --git a/Plugins/org.blueberry.core.commands/src/berryCommandEvent.h b/Plugins/org.blueberry.core.commands/src/berryCommandEvent.h index 2fc3296faa..86348fa8ce 100755 --- a/Plugins/org.blueberry.core.commands/src/berryCommandEvent.h +++ b/Plugins/org.blueberry.core.commands/src/berryCommandEvent.h @@ -1,178 +1,178 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYCOMMANDEVENT_H_ #define BERRYCOMMANDEVENT_H_ #include "common/berryAbstractNamedHandleEvent.h" #include namespace berry { class Command; /** * An instance of this class describes changes to an instance of * Command. *

* This class is not intended to be extended by clients. *

* * @see ICommandListener#CommandChanged(CommandEvent::Pointer) */ class BERRY_COMMANDS CommandEvent : public AbstractNamedHandleEvent { public: berryObjectMacro(CommandEvent); /** * Creates a new instance of this class. * * @param command * the instance of the interface that changed. * @param categoryChanged * true, iff the category property changed. * @param definedChanged * true, iff the defined property changed. * @param descriptionChanged * true, iff the description property changed. * @param handledChanged * true, iff the handled property changed. * @param nameChanged * true, iff the name property changed. * @param parametersChanged * true if the parameters have changed; * false otherwise. * @param returnTypeChanged * true iff the return type property changed; * false otherwise. * @param helpContextIdChanged * true iff the help context identifier changed; * false otherwise. * @param enabledChanged - * true iff the comand enablement changed; + * true iff the command enablement changed; * false otherwise. * @since 3.3 */ CommandEvent(const SmartPointer command, bool categoryChanged, bool definedChanged, bool descriptionChanged, bool handledChanged, bool nameChanged, bool parametersChanged, bool returnTypeChanged = false, bool helpContextIdChanged = false, bool enabledChanged = false); /** * Returns the instance of the interface that changed. * * @return the instance of the interface that changed. Guaranteed not to be * null. */ SmartPointer GetCommand() const; /** * Returns whether or not the category property changed. * * @return true, iff the category property changed. */ bool IsCategoryChanged() const; /** * Returns whether or not the handled property changed. * * @return true, iff the handled property changed. */ bool IsHandledChanged() const; /** * Returns whether or not the help context identifier changed. * * @return true, iff the help context identifier changed. * @since 3.2 */ bool IsHelpContextIdChanged() const; /** * Returns whether or not the parameters have changed. * * @return true, iff the parameters property changed. */ bool IsParametersChanged() const; /** * Returns whether or not the return type property changed. * * @return true, iff the return type property changed. * @since 3.2 */ bool IsReturnTypeChanged() const; /** * Return whether the enable property changed. * - * @return true iff the comand enablement changed + * @return true iff the command enablement changed * @since 3.3 */ bool IsEnabledChanged() const; private: /** * The bit used to represent whether the command has changed its category. */ static int CHANGED_CATEGORY(); // = LAST_USED_BIT << 1; /** * The bit used to represent whether the command has changed its handler. */ static int CHANGED_HANDLED(); // = LAST_USED_BIT << 2; /** * The bit used to represent whether the command has changed its parameters. */ static int CHANGED_PARAMETERS(); // = LAST_USED_BIT << 3; /** * The bit used to represent whether the command has changed its return * type. * * @since 3.2 */ static int CHANGED_RETURN_TYPE(); // = LAST_USED_BIT << 4; /** * The bit used to represent whether the command has changed its help * context identifier. * * @since 3.2 */ static int CHANGED_HELP_CONTEXT_ID(); // = LAST_USED_BIT << 5; /** * The bit used to represent whether this commands active handler has * changed its enablement state. * * @since 3.3 */ static int CHANGED_ENABLED(); // = LAST_USED_BIT << 6; /** * The command that has changed; this value is never null. */ const SmartPointer command; }; } #endif /* BERRYCOMMANDEVENT_H_ */ diff --git a/Plugins/org.blueberry.core.commands/src/berryIParameterValueConverter.h b/Plugins/org.blueberry.core.commands/src/berryIParameterValueConverter.h index 487a0f66ee..f1139aeef0 100755 --- a/Plugins/org.blueberry.core.commands/src/berryIParameterValueConverter.h +++ b/Plugins/org.blueberry.core.commands/src/berryIParameterValueConverter.h @@ -1,89 +1,89 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYABSTRACTPARAMETERVALUECONVERTER_H_ #define BERRYABSTRACTPARAMETERVALUECONVERTER_H_ #include #include #include namespace berry { /** *

* Supports conversion between objects and strings for command parameter values. * Extenders must produce strings that identify objects (of a specific command * parameter type) as well as consume the strings to locate and return the * objects they identify. *

*

* This class offers multiple handlers of a command a consistent way of * converting string parameter values into the objects that the handlers would * prefer to deal with. This class also gives clients a way to serialize * object parameters as strings so that entire parameterized commands can be * serialized, stored and later deserialized and executed. *

*

* This class will typically be extended so the subclass can be referenced from * the converter attribute of the - * commandParameterType elemement of the + * commandParameterType element of the * org.blueberry.ui.commands extension-point. Objects implementing * this interface may also be passed directly to * {@link ParameterType#Define} by clients. *

* * @see ParameterType#Define(IParameterValueConverter::Pointer) * @see ParameterizedCommand#Serialize() */ struct BERRY_COMMANDS IParameterValueConverter { virtual ~IParameterValueConverter(); /** * Converts a string encoded command parameter value into the parameter * value object. * * @param parameterValue * a command parameter value string describing an object; may be * null * @return the object described by the command parameter value string; may * be null * @throws ParameterValueConversionException * if an object cannot be produced from the * parameterValue string */ virtual Object::Pointer ConvertToObject(const QString& parameterValue) = 0; /** * Converts a command parameter value object into a string that encodes a * reference to the object or serialization of the object. * * @param parameterValue * an object to convert into an identifying string; may be * null * @return a string describing the provided object; may be null * @throws ParameterValueConversionException * if a string reference or serialization cannot be provided for * the parameterValue */ virtual QString ConvertToString(const Object::Pointer& parameterValue) = 0; }; } Q_DECLARE_INTERFACE(berry::IParameterValueConverter, "org.blueberry.core.commands.IParameterValueConverter") #endif /* BERRYABSTRACTPARAMETERVALUECONVERTER_H_ */ diff --git a/Plugins/org.blueberry.core.commands/src/common/berryCommandExceptions.h b/Plugins/org.blueberry.core.commands/src/common/berryCommandExceptions.h index a0bbaf6124..e0523ac0b5 100644 --- a/Plugins/org.blueberry.core.commands/src/common/berryCommandExceptions.h +++ b/Plugins/org.blueberry.core.commands/src/common/berryCommandExceptions.h @@ -1,53 +1,53 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYCOMMANDEXCEPTIONS_H_ #define BERRYCOMMANDEXCEPTIONS_H_ #include #include namespace berry { CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, CommandException, ctkRuntimeException) CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, ExecutionException, CommandException) CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, NotHandledException, CommandException) CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, NotDefinedException, CommandException) CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, NotEnabledException, CommandException) CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, ParameterValueConversionException, CommandException) /** * Signals that a problem has occurred while trying to create an instance of * IParameterValues. In applications based on the registry * provided by core, this usually indicates a problem creating an * IExecutableExtension. For other applications, this exception * could be used to signify any general problem during initialization. * */ CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, ParameterValuesException, CommandException) /** - * Signals that an exception occured while serializing a + * Signals that an exception occurred while serializing a * {@link ParameterizedCommand} to a string or deserializing a string to a * {@link ParameterizedCommand}. * * This class is not intended to be extended by clients. * */ CTK_DECLARE_EXCEPTION(BERRY_COMMANDS, SerializationException, CommandException) } #endif /*BERRYCOMMANDEXCEPTIONS_H_*/ diff --git a/Plugins/org.blueberry.core.expressions/plugin.xml b/Plugins/org.blueberry.core.expressions/plugin.xml index 3509a3e70b..ed9cf70941 100644 --- a/Plugins/org.blueberry.core.expressions/plugin.xml +++ b/Plugins/org.blueberry.core.expressions/plugin.xml @@ -1,18 +1,18 @@ - + diff --git a/Plugins/org.blueberry.core.expressions/src/berryPropertyTester.h b/Plugins/org.blueberry.core.expressions/src/berryPropertyTester.h index ca5b531d59..aef7eeadf8 100644 --- a/Plugins/org.blueberry.core.expressions/src/berryPropertyTester.h +++ b/Plugins/org.blueberry.core.expressions/src/berryPropertyTester.h @@ -1,121 +1,121 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYPROPERTYTESTER_H_ #define BERRYPROPERTYTESTER_H_ #include #include "internal/berryPropertyTesterDescriptor.h" #include namespace berry { /** * Abstract superclass of all property testers. Implementation classes of - * the extension point org.blueberry.core.expresssions.propertyTesters + * the extension point org.blueberry.core.expressions.propertyTesters * must extend PropertyTester. *

* A property tester implements the property tests enumerated in the property * tester extension point. For the following property test extension * \code{.unparsed} * * * \endcode * the corresponding implementation class looks like: * \code * public class MyPackageFragmentTester { * public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { * IPackageFragment fragement= (IPackageFragment)receiver; * if ("isDefaultPackage".equals(property)) { * return expectedValue == null * ? fragement.isDefaultPackage() * : fragement.isDefaultPackage() == ((Boolean)expectedValue).booleanValue(); * } * Assert.isTrue(false); * return false; * } * } * \endcode * The property can then be used in a test expression as follows: *

  *   <instanceof value="org.blueberry.core.IPackageFragment"/>
  *   <test property="org.blueberry.jdt.core.isDefaultPackage"/>
  * 
*

*

* There is no guarantee that the same instance of a property tester is used * to handle <test property="..."/> requests. So property testers * should always be implemented in a stateless fashion. *

*/ class BERRY_EXPRESSIONS PropertyTester : public QObject, public IPropertyTester { Q_OBJECT Q_INTERFACES(berry::IPropertyTester) private: IConfigurationElement::Pointer fConfigElement; QString fNamespace; QString fProperties; public: /** * Initialize the property tester with the given name space and property. *

* Note: this method is for internal use only. Clients must not call * this method. *

* @param descriptor the descriptor object for this tester */ void InternalInitialize(PropertyTesterDescriptor::Pointer descriptor); /** * Note: this method is for internal use only. Clients must not call * this method. * * @return the property tester descriptor */ PropertyTesterDescriptor::Pointer InternalCreateDescriptor(); /** * {@inheritDoc} */ bool Handles(const QString& namespaze, const QString& property) override; /** * {@inheritDoc} */ bool IsInstantiated() override; /** * {@inheritDoc} */ bool IsDeclaringPluginActive() override; /** * {@inheritDoc} */ IPropertyTester* Instantiate() override; }; } // namespace berry #endif /*BERRYPROPERTYTESTER_H_*/ diff --git a/Plugins/org.blueberry.core.expressions/src/internal/berryTypeExtensionManager.h b/Plugins/org.blueberry.core.expressions/src/internal/berryTypeExtensionManager.h index aeace05b79..580fdc1752 100644 --- a/Plugins/org.blueberry.core.expressions/src/internal/berryTypeExtensionManager.h +++ b/Plugins/org.blueberry.core.expressions/src/internal/berryTypeExtensionManager.h @@ -1,123 +1,123 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYTYPEEXTENSIONMANAGER_H_ #define BERRYTYPEEXTENSIONMANAGER_H_ #include "berryIPropertyTester.h" #include "berryTypeExtension.h" #include "berryPropertyCache.h" #include "berryProperty.h" #include #include #include #include namespace berry { class TypeExtensionManager : private IRegistryEventListener { private: QString fExtensionPoint; static const QString TYPE; class nullptr_PROPERTY_TESTER_ : public IPropertyTester { public: bool Handles(const QString& /*namespaze*/, const QString& /*property*/) override { return false; } bool IsInstantiated() override { return true; } bool IsDeclaringPluginActive() override { return true; } IPropertyTester* Instantiate() override { return this; } bool Test(Object::ConstPointer, const QString& /*property*/, const QList& /*args*/, Object::Pointer /*expectedValue*/) override { return false; } }; static const nullptr_PROPERTY_TESTER_ nullptr_PROPERTY_TESTER; /* * Map containing all already created type extension object. */ QHash fTypeExtensionMap; /* * Table containing mapping of class name to configuration element */ QHash > fConfigurationElementMap; /* * A cache to give fast access to the last 1000 method invocations. */ PropertyCache* fPropertyCache; public: static bool DEBUG; TypeExtensionManager(const QString& extensionPoint); ~TypeExtensionManager() override; Property::Pointer GetProperty(Object::ConstPointer receiver, const QString& namespaze, const QString& method); /*synchronized*/Property::Pointer GetProperty(Object::ConstPointer receiver, const QString& namespaze, const QString& method, bool forcePluginActivation); protected: friend class TypeExtension; /* * This method doesn't need to be synchronized since it is called - * from withing the getProperty method which is synchronized + * from within the getProperty method which is synchronized */ TypeExtension::Pointer Get(const Reflection::TypeInfo& typeInfo); /* * This method doesn't need to be synchronized since it is called - * from withing the getProperty method which is synchronized + * from within the getProperty method which is synchronized */ QList LoadTesters(const QString& typeName); private: /*synchronized*/void InitializeCaches(); void Added(const QList >& extensions) override; void Removed(const QList >& extensions) override; void Added(const QList >& extensionPoints) override; void Removed(const QList >& extensionPoints) override; }; } #endif /*BERRYTYPEEXTENSIONMANAGER_H_*/ diff --git a/Plugins/org.blueberry.core.jobs/src/berryIJobChangeListener.h b/Plugins/org.blueberry.core.jobs/src/berryIJobChangeListener.h index 1d8e41422f..bd400e9ba1 100644 --- a/Plugins/org.blueberry.core.jobs/src/berryIJobChangeListener.h +++ b/Plugins/org.blueberry.core.jobs/src/berryIJobChangeListener.h @@ -1,140 +1,140 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIJOBCHANGELISTENER_H_ #define BERRYIJOBCHANGELISTENER_H_ #include "berryIJobChangeEvent.h" namespace berry { /** * Callback interface for clients interested in being notified when jobs change state. *

* A single job listener instance can be added either to the job manager, for notification * of all scheduled jobs, or to any set of individual jobs. A single listener instance should * not be added to both the job manager, and to individual jobs (such a listener may * receive duplicate notifications). *

* Clients should not rely on the result of the Job#GetState() * method on jobs for which notification is occurring. Listeners are notified of * all job state changes, but whether the state change occurs before, during, or * after listeners are notified is unspecified. *

* Clients may implement this interface. *

* @see IJobManager#AddJobChangeListener(IJobChangeListener::Pointer) * @see IJobManager#RemoveJobChangeListener(IJobChangeListener::Pointer) * @see Job#AddJobChangeListener(IJobChangeListener::Pointer) * @see Job#GetState() * @see Job#RemoveJobChangeListener(IJobChangeListener::Pointer) */ struct BERRY_JOBS IJobChangeListener { struct BERRY_JOBS Events { typedef Message1 JobChangeEventType; enum Type { NONE = 0x00000000, ABOUT_TO_RUN = 0x00000001, AWAKE = 0x00000002, DONE = 0x00000004, RUNNING = 0x00000008, SCHEDULED = 0x00000010, SLEEPING = 0x00000020, ALL = 0xffffffff }; Q_DECLARE_FLAGS(Types, Type) JobChangeEventType jobAboutToRun; JobChangeEventType jobAwake; JobChangeEventType jobDone; JobChangeEventType jobRunning; JobChangeEventType jobScheduled; JobChangeEventType jobSleeping; void AddListener(IJobChangeListener* listener); void RemoveListener(IJobChangeListener* listener); void SetExceptionHandler(const AbstractExceptionHandler& handler); typedef MessageDelegate1 Delegate; }; virtual Events::Types GetEventTypes() = 0; /** * Notification that a job is about to be run. Listeners are allowed to sleep, cancel, * or change the priority of the job before it is started (and as a result may prevent * the run from actually occurring). */ virtual void AboutToRun(const IJobChangeEvent::ConstPointer& /*event*/) { } /** * Notification that a job was previously sleeping and has now been rescheduled * to run. */ virtual void Awake(const IJobChangeEvent::ConstPointer& /*event*/) { } /** - * Notification that a job has completed execution, either due to cancelation, successful + * Notification that a job has completed execution, either due to cancellation, successful * completion, or failure. The event status object indicates how the job finished, * and the reason for failure, if applicable. */ virtual void Done(const IJobChangeEvent::ConstPointer& /*event*/) { } /** * Notification that a job has started running. */ virtual void Running(const IJobChangeEvent::ConstPointer& /*event*/) { } /** * Notification that a job is being added to the queue of scheduled jobs. * The event details includes the scheduling delay before the job should start * running. */ virtual void Scheduled(const IJobChangeEvent::ConstPointer& /*event*/) { } /** * Notification that a job was waiting to run and has now been put in the * sleeping state. */ virtual void Sleeping(const IJobChangeEvent::ConstPointer& /*event*/) { } }; } Q_DECLARE_OPERATORS_FOR_FLAGS(berry::IJobChangeListener::Events::Types) #endif /* BERRYIJOBCHANGELISTENER_H_ */ diff --git a/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.cpp b/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.cpp index 7bb26f7cfc..43fda5b558 100644 --- a/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.cpp +++ b/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.cpp @@ -1,1202 +1,1202 @@ /*============================================================================ 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. ============================================================================*/ #define NOMINMAX #include "berryJobManager.h" #include "berryIProgressMonitor.h" #include "berryNullProgressMonitor.h" #include "berryIStatus.h" #include "berryJobStatus.h" #include #include namespace berry { /** * test class implementing ISchedulingRule to validate client defined rules */ struct NullRule: public ISchedulingRule { bool Contains(ISchedulingRule::Pointer myRule) const override; bool IsConflicting(ISchedulingRule::Pointer myRule) const override; }; bool NullRule::IsConflicting(ISchedulingRule::Pointer dummyRule) const { return dummyRule == this; } bool NullRule::Contains(ISchedulingRule::Pointer dummyRule) const { return dummyRule == this; } JobManager::JobManager() : sptr_testRule(new NullRule()),m_active(true), m_Pool(new WorkerPool(this)), m_sptr_progressProvider(nullptr), m_JobQueueSleeping(true), m_JobQueueWaiting(false),m_suspended(false), m_waitQueueCounter(0) { m_JobListeners.global.SetExceptionHandler(MessageExceptionHandler< JobListeners> (&m_JobListeners, &JobListeners::HandleException)); } // DEBUG VARIABLES const QString& JobManager::PI_JOBS() { static const QString id("org.blueberry.core.jobs"); return id; } bool JobManager::DEBUG = false; bool JobManager::DEBUG_BEGIN_END = false; bool JobManager::DEBUG_DEADLOCK = false; bool JobManager::DEBUG_LOCKS = false; bool JobManager::DEBUG_TIMING = false; bool JobManager::DEBUG_SHUTDOWN = false; const int JobManager::PLUGIN_ERROR = 2; JobManager* JobManager::GetInstance() { // we don't need to lock the creation of "instance" because GetInstance() is // called when statically initializing InternalJob::ptr_manager (which happens // in single-threaded mode) static JobManager instance; return &instance; } std::string JobManager::PrintState(int state) { switch (state) { case Job::NONE: return "NONE"; case Job::WAITING: return "WAITING"; case Job::SLEEPING: return "SLEEPING"; case Job::RUNNING: return "RUNNING"; case InternalJob::BLOCKED: return "BLOCKED"; case InternalJob::ABOUT_TO_RUN: return "ABOUT_TO_RUN"; case InternalJob::ABOUT_TO_SCHEDULE: return "ABOUT_TO_SCHEDULE"; } return "UNKNOWN"; } void JobManager::Shutdown() { JobManager* ptr_instance(GetInstance()); if (ptr_instance != nullptr) { ptr_instance->DoShutdown(); // ptr_instance = 0; // need to call the destructor of the static object .. } } //void //JobManager //::Cancel(Object family) { // //don't synchronize because cancel calls listeners // for (Iterator it = select(family).iterator(); it.hasNext();) // cancel((Job) it.next()); // } IProgressMonitor::Pointer JobManager::CreateProgressGroup() { if (m_sptr_progressProvider != 0) return (m_sptr_progressProvider->CreateProgressGroup()); NullProgressMonitor::Pointer sptr_defaultProgressMonitor( new NullProgressMonitor); return sptr_defaultProgressMonitor; } Job* JobManager::CurrentJob() { //Poco::Thread* ptr_current = Poco::Thread::current(); //if (Worker* worker = dynamic_cast(ptr_current) ) // return ((Worker) ptr_current).currentJob(); // { // Poco::ScopedLock lockMe (m_mutex); // Poco::HashSet::Iterator it ; // for (it = m_running.begin(); it != m_running.end(); it ++) { // Job job* = dynamic_cast (it); // if (job->GetThread() == ptr_current) // return job; // } //} return nullptr; } //void //JobManager //::EndRule(ISchedulingRule rule) { //implicitJobs.end(rule, false); // } //Job[] //JobManager //::Find(Object family) { // List members = select(family); // return (Job[]) members.toArray(new Job[members.size()]); // } // // LockManager GetLockManager() { // return lockManager; // } // bool JobManager::IsIdle() { { Poco::ScopedLock m_managerLock(m_mutex); return m_running.empty() && m_JobQueueWaiting.IsEmpty(); } } bool JobManager::IsSuspended() { { Poco::ScopedLock m_managerLock(m_mutex); m_suspended = true; } return m_suspended; } // // /* // * @see IJobManager#join(String, IProgressMonitor) // */ //void //JobManager //::Join(final Object family, IProgressMonitor monitor) throws InterruptedException, OperationCanceledException { // monitor = monitorFor(monitor); // IJobChangeListener listener = null; // final Set jobs; // int jobCount; // Job blocking = null; // synchronized (lock) { // //don't join a waiting or sleeping job when suspended (deadlock risk) // int states = suspended ? Job.RUNNING : Job.RUNNING | Job.WAITING | Job.SLEEPING; // jobs = Collections.synchronizedSet(new HashSet(select(family, states))); // jobCount = jobs.size(); // if (jobCount > 0) { // //if there is only one blocking job, use it in the blockage callback below // if (jobCount == 1) // blocking = (Job) jobs.iterator().next(); // listener = new JobChangeAdapter() { // public void done(IJobChangeEvent event) { // //don't remove from list if job is being rescheduled // if (!((JobChangeEvent) event).reschedule) // jobs.remove(event.getJob()); // } // // //update the list of jobs if new ones are added during the join // public void scheduled(IJobChangeEvent event) { // //don't add to list if job is being rescheduled // if (((JobChangeEvent) event).reschedule) // return; // Job job = event.getJob(); // if (job.belongsTo(family)) // jobs.add(job); // } // }; // addJobChangeListener(listener); // } // } // if (jobCount == 0) { // //use up the monitor outside synchronized block because monitors call untrusted code // monitor.beginTask(JobMessages.jobs_blocked0, 1); // monitor.done(); // return; // } // //spin until all jobs are completed // try { // monitor.beginTask(JobMessages.jobs_blocked0, jobCount); // monitor.subTask(NLS.bind(JobMessages.jobs_waitFamSub, Integer.toString(jobCount))); // reportBlocked(monitor, blocking); // int jobsLeft; // int reportedWorkDone = 0; // while ((jobsLeft = jobs.size()) > 0) { // //don't let there be negative work done if new jobs have // //been added since the join began // int actualWorkDone = Math.max(0, jobCount - jobsLeft); // if (reportedWorkDone < actualWorkDone) { // monitor.worked(actualWorkDone - reportedWorkDone); // reportedWorkDone = actualWorkDone; // monitor.subTask(NLS.bind(JobMessages.jobs_waitFamSub, Integer.toString(jobsLeft))); // } // if (Thread.interrupted()) // throw new InterruptedException(); // if (monitor.isCanceled()) // throw new OperationCanceledException(); // //notify hook to service pending syncExecs before falling asleep // lockManager.aboutToWait(null); // Thread.sleep(100); // } // } finally { // lockManager.aboutToRelease(); // removeJobChangeListener(listener); // reportUnblocked(monitor); // monitor.done(); // } // } //JobManager //::NewLock() { // return lockManager.newLock(); // } void JobManager::RemoveJobChangeListener(IJobChangeListener* listener) { m_JobListeners.Remove(listener); } void JobManager::ReportBlocked(IProgressMonitor::Pointer sptr_monitor, InternalJob::Pointer sptr_blockingJob) const { if ( sptr_monitor.Cast() == 0 ) return ; if (sptr_blockingJob == 0 || sptr_blockingJob->IsSystem()) { Status::Pointer sptr_reason( new Status(IStatus::INFO_TYPE, JobManager::PI_JOBS(), 1, "the user operation is waiting for background work to complete", BERRY_STATUS_LOC)); } else { QString msg = "the user operation is waiting for : " + sptr_blockingJob->GetName() + " to complete. "; JobStatus::Pointer sptr_reason( new JobStatus(IStatus::INFO_TYPE, sptr_blockingJob.Cast(), msg, BERRY_STATUS_LOC)); } // ((IProgressmonitorWithBlocking) sptr_monitor)->SetBlocked(sptr_reason); } void JobManager::ReportUnblocked(IProgressMonitor::Pointer sptr_monitor) const { if ( IProgressMonitorWithBlocking::Pointer sptr_monitorWithBlocking = sptr_monitor.Cast() ) sptr_monitorWithBlocking->ClearBlocked(); } void JobManager::Resume() { { Poco::ScopedLock lockMe(m_mutex); m_suspended = false; //poke the job pool m_Pool->JobQueued(); } } //TODO implicit Jobs //void //JobManager //::Resume(ISchedulingRule rule)const { // implicitJobs.resume(rule); // } void JobManager::SetProgressProvider(ProgressProvider::Pointer provider) { m_sptr_progressProvider = provider; } void JobManager::SetRule(InternalJob::Pointer job, ISchedulingRule::Pointer sptr_rule) { Poco::ScopedLock m_managerLock(m_mutex); //cannot change the rule of a job that is already running ( GetRule is set to protected which should be // changed if this assert is needed // assert(job->GetState() == Job.NONE); ValidateRule(sptr_rule); job->InternalSetRule(sptr_rule); } //void //JobManager //::Sleep(Object family) { // //don't synchronize because sleep calls listeners // for (Iterator it = select(family).iterator(); it.hasNext();) { // sleep((InternalJob) it.next()); // } // } void JobManager::Suspend() { { Poco::ScopedLock lockMe(m_mutex); m_suspended = true; } } //void //JobManager //::Suspend(ISchedulingRule rule, IProgressMonitor monitor)const { // Assert.isNotNull(rule); // implicitJobs.suspend(rule, monitorFor(monitor)); // } //void //JobManager //::TransferRule(ISchedulingRule rule, Thread destinationThread) { // implicitJobs.transfer(rule, destinationThread); // } //void //JobManager //::SetLockListener(LockListener listener) { // lockManager.setLockListener(listener); // } //void //JobManager //::WakeUp(Object family) { // //don't synchronize because wakeUp calls listeners // for (Iterator it = select(family).iterator(); it.hasNext();) { // wakeUp((InternalJob) it.next(), 0L); // } // } void JobManager::AddJobChangeListener(IJobChangeListener* listener) { m_JobListeners.Add(listener); } //void //JobManager //::BeginRule(ISchedulingRule rule, IProgressMonitor monitor) { // validateRule(rule); // implicitJobs.begin(rule, monitorFor(monitor), false); // } // // /** // * For debugging purposes only // */ //std::String //JobManager //::PrintJobName(Job job) { // if (job instanceof ThreadJob) { // Job realJob = ((ThreadJob) job).realJob; // if (realJob != null) // return realJob.getClass().getName(); // return "ThreadJob on rule: " + job.getRule(); //$NON-NLS-1$ // } // return job.getClass().getName(); // } // // instance = this; // initDebugOptions(); // synchronized (lock) { // running = new HashSet(10); // } // pool.setDaemon(JobOSGiUtils.getDefault().useDaemonThreads()); //} void JobManager::ChangeState(InternalJob::Pointer sptr_job, int newState) { bool blockedJobs = false; { Poco::ScopedLock m_managerLock(m_mutex); int tmp_oldState = sptr_job->InternalGetState(); switch (tmp_oldState) { case Job::NONE: case InternalJob::ABOUT_TO_SCHEDULE: break; case InternalJob::BLOCKED: //remove this job from the linked list of blocked jobs sptr_job->Remove(); break; case Job::WAITING: m_JobQueueWaiting.Remove(sptr_job); // assert(false, "Tried to remove a job that wasn't in the queue"); break; case Job::SLEEPING: m_JobQueueSleeping.Remove(sptr_job); // assert(false, "Tried to remove a job that wasn't in the queue"); // this silences the warning but should be checked: // FALLTHRU case Job::RUNNING: case InternalJob::ABOUT_TO_RUN: m_running.remove(sptr_job); //add any blocked jobs back to the wait queue InternalJob::Pointer sptr_blocked(sptr_job->Previous()); sptr_job->Remove(); blockedJobs = sptr_blocked != 0; while (sptr_blocked != 0) { InternalJob::Pointer previous = sptr_blocked->Previous(); ChangeState(sptr_blocked, Job::WAITING); sptr_blocked = previous; } break; // default : // Assert.isLegal(false, "Invalid job state: " + job + ", state: " + oldState); } sptr_job->InternalSetState(newState); switch (newState) { case Job::NONE: sptr_job->SetStartTime(InternalJob::T_NONE); sptr_job->SetWaitQueueStamp(InternalJob::T_NONE); case InternalJob::BLOCKED: break; case Job::WAITING: m_JobQueueWaiting.Enqueue(sptr_job); break; case Job::SLEEPING: //try { m_JobQueueSleeping.Enqueue(sptr_job); //} catch (RuntimeException e) { // throw new RuntimeException("Error changing from state: " + oldState); //} break; case Job::RUNNING: case InternalJob::ABOUT_TO_RUN: sptr_job->SetStartTime(InternalJob::T_NONE); sptr_job->SetWaitQueueStamp(InternalJob::T_NONE); m_running.insert(sptr_job); break; case InternalJob::ABOUT_TO_SCHEDULE: break; // default : // Assert.isLegal(false, "Invalid job state: " + job + ", state: " + newState); } } //notify queue outside sync block if (blockedJobs) m_Pool->JobQueued(); } Poco::Timestamp::TimeDiff JobManager::DelayFor(int priority) { //these values may need to be tweaked based on machine speed switch (priority) { case Job::INTERACTIVE: return 0; case Job::SHORT: return 50; case Job::LONG: return 100; case Job::BUILD: return 500; case Job::DECORATE: return 1000; default: // Assert.isTrue(false, "Job has invalid priority: " + priority); //$NON-NLS-1$ return 0; } } void JobManager::DoSchedule(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay) { Poco::ScopedLock managerLock(m_mutex); //job may have been canceled already int state = job->InternalGetState(); if (state != InternalJob::ABOUT_TO_SCHEDULE && state != Job::SLEEPING) return; //if it's a decoration job with no rule, don't run it right now if the system is busy if (job->GetPriority() == Job::DECORATE && job->GetRule() == 0) { Poco::Timestamp::TimeDiff tmp_minDelay = m_running.size() * 100; delay = std::max(delay, tmp_minDelay); } if (delay > 0) { job->SetStartTime(Poco::Timestamp() + delay * 100); InternalJob::Pointer sptr_job(job); ChangeState(sptr_job, Job::SLEEPING); } else { job->SetStartTime(Poco::Timestamp() + DelayFor(job->GetPriority()) * 100); job->SetWaitQueueStamp(m_waitQueueCounter++); InternalJob::Pointer sptr_job(job); ChangeState(sptr_job, Job::WAITING); } } void JobManager::DoShutdown() { std::vector vec_ToCancel; { Poco::ScopedLock LockMe(m_mutex); if (m_active) { m_active = false; //cancel all running jobs vec_ToCancel.assign(m_running.begin(), m_running.end()); //clean up m_JobQueueSleeping.Clear(); m_JobQueueWaiting.Clear(); m_running.clear(); } } // Give running jobs a chance to finish. Wait 0.1 seconds for up to 3 times. if (!vec_ToCancel.empty()) { for (std::size_t i = 0; i < vec_ToCancel.size(); i++) { // cancel jobs outside sync block to avoid deadlock Cancel(vec_ToCancel[i]); } for (int waitAttempts = 0; waitAttempts < 3; waitAttempts++) { Poco::Thread::yield(); { Poco::ScopedLock LockMe(m_mutex); if (m_running.empty()) break; } if (DEBUG_SHUTDOWN) { // JobManager.debug("Shutdown - job wait cycle #" + (waitAttempts + 1)); std::vector vec_StillRunning; { Poco::ScopedLock LockMe(m_mutex); vec_StillRunning.assign(m_running.begin(), m_running.end()); // if (!vec_StillRunning.empty()) { //for (int j = 0; j < stillRunning.length; j++) { // JobManager.debug("\tJob: " + printJobName(stillRunning[j])); //$NON-NLS-1$ //} } } Poco::Thread::sleep(100); Poco::Thread::yield(); } // retrieve list of the jobs that are still running { Poco::ScopedLock LockMe(m_mutex); vec_ToCancel.assign(m_running.begin(), m_running.end()); } } if (!vec_ToCancel.empty()) { /*for (int i = 0; i < vec_ToCancel.size(); i++) {*/ // std::string tmp_jobName = PrintJobName(toCancel[i]); // //this doesn't need to be translated because it's just being logged // String msg = "Job found still running after platform shutdown. Jobs should be canceled by the plugin that // scheduled them during shutdown: " + jobName; // RuntimeLog.log(new Status(IStatus.WARNING, JobManager.PI_JOBS, JobManager.PLUGIN_ERROR, msg, null)); // // // TODO the RuntimeLog.log in its current implementation won't produce a log // // during this stage of shutdown. For now add a standard error output. // // One the logging story is improved, the System.err output below can be removed: // System.err.println(msg); // } } m_Pool->Shutdown(); } Job::Pointer JobManager::NextJob() { { Poco::ScopedLock managerLock(m_mutex); //do nothing if the job manager is suspended if (m_suspended) return Job::Pointer(nullptr); // tickle the sleep queue to see if anyone wakes up Poco::Timestamp now; InternalJob::Pointer ptr_job = m_JobQueueSleeping.Peek(); while (ptr_job != 0 && ptr_job->GetStartTime() < now) { // a job that slept to long is set a new start time and is put into the waiting queue ptr_job->SetStartTime(now + DelayFor(ptr_job->GetPriority())); ptr_job->SetWaitQueueStamp(m_waitQueueCounter++); InternalJob::Pointer sptr_job(ptr_job); ChangeState(sptr_job, Job::WAITING); ptr_job = m_JobQueueSleeping.Peek(); } //process the wait queue until we find a job whose rules are satisfied. while ((ptr_job = m_JobQueueWaiting.Peek()) != 0) { InternalJob::Pointer sptr_job(ptr_job); InternalJob::Pointer sptr_blocker = FindBlockingJob(sptr_job); if (sptr_blocker == 0) break; //queue this job after the job that's blocking it ChangeState(sptr_job, InternalJob::BLOCKED); //assert job does not already belong to some other data structure //Assert.isTrue(job.next() == null); //Assert.isTrue(job.previous() == null); sptr_blocker->AddLast(ptr_job); } // the job to run must be in the running list before we exit // the sync block, otherwise two jobs with conflicting rules could start at once if (ptr_job != 0) { InternalJob::Pointer sptr_job(ptr_job); ChangeState(sptr_job, InternalJob::ABOUT_TO_RUN); } return ptr_job.Cast (); } } //TODO Job families //void //JobManager //::Select(List members, Object family, InternalJob firstJob, int stateMask) { // if (firstJob == null) // return; // InternalJob job = firstJob; // do { // //note that job state cannot be NONE at this point // if ((family == null || job.belongsTo(family)) && ((job.getState() & stateMask) != 0)) // members.add(job); // job = job.previous(); // } while (job != null && job != firstJob); // } //List //JobManager //::Select(Object family) { // return select(family, Job.WAITING | Job.SLEEPING | Job.RUNNING); // } //List //JobManager //::Select(Object family, int stateMask) { // List members = new ArrayList(); // synchronized (lock) { // if ((stateMask & Job.RUNNING) != 0) { // for (Iterator it = running.iterator(); it.hasNext();) { // select(members, family, (InternalJob) it.next(), stateMask); // } // } // if ((stateMask & Job.WAITING) != 0) // select(members, family, waiting.peek(), stateMask); // if ((stateMask & Job.SLEEPING) != 0) // select(members, family, sleeping.peek(), stateMask); // } // return members; // } -// dummy validateRule implemenation +// dummy validateRule implementation void JobManager::ValidateRule(ISchedulingRule::Pointer sptr_rule) { //null rule always valid if (sptr_rule == 0) return; //contains method must be reflexive poco_assert(sptr_rule->Contains(sptr_rule)) ; //contains method must return false when given an unknown rule poco_assert(!sptr_rule->Contains(sptr_testRule)); //isConflicting method must be reflexive poco_assert(sptr_rule->IsConflicting(sptr_rule)); //isConflicting method must return false when given an unknown rule poco_assert(!sptr_rule->IsConflicting(sptr_testRule)); } bool JobManager::Cancel(InternalJob::Pointer sptr_job) { IProgressMonitor::Pointer sptr_progressMonitor(nullptr); bool runCanceling = false; { Poco::ScopedLock mangerMutex (m_mutex); switch (sptr_job->GetState()) { case Job::NONE : return true; case Job::RUNNING : //cannot cancel a job that has already started (as opposed to ABOUT_TO_RUN) if (sptr_job->InternalGetState() == Job::RUNNING) { sptr_progressMonitor = sptr_job->GetProgressMonitor(); runCanceling = sptr_job->IsRunCanceled(); if(runCanceling) sptr_job->SetRunCanceled(true); break ; } //signal that the job should be canceled before it gets a chance to run sptr_job->SetAboutToRunCanceled(true); return false; default : ChangeState(sptr_job, Job::NONE); } } //call monitor outside sync block if (sptr_progressMonitor != 0) { if(runCanceling) { if (!sptr_progressMonitor->IsCanceled()) sptr_progressMonitor->SetCanceled(true); sptr_job->Canceling(); } return false; } //only notify listeners if the job was waiting or sleeping m_JobListeners.Done(sptr_job.Cast(), Status::CANCEL_STATUS(BERRY_STATUS_LOC), false); return true; } IProgressMonitor::Pointer JobManager::CreateMonitor( Job::Pointer sptr_jobToMonitor) { IProgressMonitor::Pointer sptr_monitor(nullptr); if (m_sptr_progressProvider != 0) sptr_monitor = m_sptr_progressProvider->CreateMonitor(sptr_jobToMonitor); if (sptr_monitor == 0) { NullProgressMonitor::Pointer sptr_defaultMonitor(new NullProgressMonitor()); return sptr_defaultMonitor; } return sptr_monitor; } IProgressMonitor::Pointer JobManager::CreateMonitor(InternalJob::Pointer sptr_job, IProgressMonitor::Pointer group, int ticks) { { Poco::ScopedLock managerLock(m_mutex); //group must be set before the job is scheduled //this includes the ABOUT_TO_SCHEDULE state, during which it is still //valid to set the progress monitor if (sptr_job->GetState() != Job::NONE) { IProgressMonitor::Pointer dummy(nullptr); return dummy; } IProgressMonitor::Pointer sptr_monitor(nullptr); if (m_sptr_progressProvider != 0) sptr_monitor = m_sptr_progressProvider->CreateMonitor(sptr_job.Cast() , group, ticks); if (sptr_monitor == 0) { // return a default NullprogressMonitor NullProgressMonitor::Pointer sptr_defaultMonitor(new NullProgressMonitor() ); return sptr_defaultMonitor; } return sptr_monitor; } } void JobManager::EndJob(InternalJob::Pointer ptr_job, IStatus::Pointer result, bool notify) { Poco::Timestamp::TimeDiff rescheduleDelay(InternalJob::T_NONE); { Poco::ScopedLock lock ( m_mutex); // if the job is finishing asynchronously, there is nothing more to do for now if (result == Job::ASYNC_FINISH) return; //if job is not known then it cannot be done if (ptr_job->GetState() == Job::NONE) return; ptr_job->SetResult(result); ptr_job->SetProgressMonitor(IProgressMonitor::Pointer(nullptr)); ptr_job->SetThread(nullptr); rescheduleDelay = ptr_job->GetStartTime().epochMicroseconds(); InternalJob::Pointer sptr_job(ptr_job); ChangeState(sptr_job, Job::NONE); } //notify listeners outside sync block bool reschedule = m_active && rescheduleDelay > InternalJob::T_NONE && ptr_job->ShouldSchedule(); if (notify) m_JobListeners.Done(ptr_job.Cast(), result, reschedule); //reschedule the job if requested and we are still active if (reschedule) Schedule(ptr_job, rescheduleDelay, reschedule); } InternalJob::Pointer JobManager::FindBlockingJob(InternalJob::Pointer waitingJob) { if (waitingJob->GetRule() == 0) return InternalJob::Pointer(nullptr); { Poco::ScopedLock managerLock (m_mutex); if (m_running.empty() ) { InternalJob::Pointer dummy; return (dummy); } //check the running jobs bool hasBlockedJobs = false; QSet::Iterator it; for ( it = m_running.begin(); it != m_running.end(); it ++ ) { InternalJob::Pointer sptr_job = *it ++; if (waitingJob->IsConflicting(sptr_job)) return sptr_job; if (!hasBlockedJobs) hasBlockedJobs = sptr_job->Previous() != 0; } // there are no blocked jobs, so we are done if (!hasBlockedJobs) { InternalJob::Pointer dummy; return (dummy); } //check all jobs blocked by running jobs QSet::Iterator it_blocked; for( it_blocked = m_running.begin(); it_blocked != m_running.end(); it_blocked ++ ) { InternalJob::Pointer sptr_job = *it_blocked ++; while (true) { sptr_job = sptr_job->Previous(); if (sptr_job == 0) break; if (waitingJob->IsConflicting(sptr_job)) return sptr_job; } } } InternalJob::Pointer sptr_null; return (sptr_null); } bool JobManager::IsActive() { return m_active; } bool JobManager::IsBlocking(InternalJob::Pointer sptr_runningJob) { { Poco::ScopedLock lockMe (m_mutex); // if this job isn't running, it can't be blocking anyone if (sptr_runningJob->GetState() != Job::RUNNING) return false; // if any job is queued behind this one, it is blocked by it InternalJob::Pointer ptr_previous = sptr_runningJob->Previous(); while (ptr_previous != 0) { // ignore jobs of lower priority (higher priority value means lower priority) if (ptr_previous->GetPriority() < sptr_runningJob->GetPriority()) { if (!ptr_previous->IsSystem()) return true; // TODO Implicit Jobs // implicit jobs should interrupt unless they act on behalf of system jobs // if (previous instanceof ThreadJob && ((ThreadJob) previous).shouldInterrupt()) // return true; } ptr_previous = ptr_previous->previous; } // none found return false; } } //void //JobManager //::Join(InternalJob job) { // final IJobChangeListener listener; // final Semaphore barrier; // synchronized (lock) { // int state = job.getState(); // if (state == Job.NONE) // return; // //don't join a waiting or sleeping job when suspended (deadlock risk) // if (suspended && state != Job.RUNNING) // return; // //it's an error for a job to join itself // if (state == Job.RUNNING && job.getThread() == Thread.currentThread()) // throw new IllegalStateException("Job attempted to join itself"); //$NON-NLS-1$ // //the semaphore will be released when the job is done // barrier = new Semaphore(null); // listener = new JobChangeAdapter() { // public void done(IJobChangeEvent event) { // barrier.release(); // } // }; // job.addJobChangeListener(listener); // //compute set of all jobs that must run before this one // //add a listener that removes jobs from the blocking set when they finish // } // //wait until listener notifies this thread. // try { // while (true) { // //notify hook to service pending syncExecs before falling asleep // lockManager.aboutToWait(job.getThread()); // try { // if (barrier.acquire(Long.MAX_VALUE)) // break; // } catch (InterruptedException e) { // //loop and keep trying // } // } // } finally { // lockManager.aboutToRelease(); // job.removeJobChangeListener(listener); // } // } bool JobManager::RunNow(InternalJob::Pointer sptr_job) { { Poco::ScopedLock lockMe (m_mutex); //cannot start if there is a conflicting job if (FindBlockingJob(sptr_job) != 0) return false; ChangeState(sptr_job, Job::RUNNING); sptr_job->SetProgressMonitor(IProgressMonitor::Pointer(new NullProgressMonitor())); sptr_job->Run(IProgressMonitor::Pointer(nullptr)); } return true; } void JobManager::Schedule(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay, bool reschedule) { if (!m_active) throw Poco::IllegalStateException("Job manager has been shut down."); poco_assert(job); // "Job is null" poco_assert(delay >= 0); // "Scheduling delay is negative" { Poco::ScopedLock managerLock (m_mutex); //if the job is already running, set it to be rescheduled when done if (job->GetState() == Job::RUNNING) { job->SetStartTime(delay); return; } //can't schedule a job that is waiting or sleeping if (job->InternalGetState() != Job::NONE) return; //remember that we are about to schedule the job //to prevent multiple schedule attempts from succeeding (bug 68452) InternalJob::Pointer sptr_job(job); ChangeState(sptr_job, InternalJob::ABOUT_TO_SCHEDULE); } //notify listeners outside sync block m_JobListeners.Scheduled(job.Cast(), delay, reschedule); //schedule the job DoSchedule(job, delay); //call the pool outside sync block to avoid deadlock m_Pool->JobQueued(); } bool JobManager::Sleep(InternalJob::Pointer job) { { Poco::ScopedLock lockMe (m_mutex); InternalJob::Pointer sptr_job(job); switch (job->GetState()) { case Job::RUNNING : //cannot be paused if it is already running (as opposed to ABOUT_TO_RUN) if (job->InternalGetState() == Job::RUNNING) return false; //job hasn't started running yet (aboutToRun listener) break; case Job::SLEEPING : //update the job wake time job->SetStartTime(InternalJob::T_INFINITE); //change state again to re-shuffle the sleep queue ChangeState(sptr_job, Job::SLEEPING); return true; case Job::NONE : return true; case Job::WAITING : //put the job to sleep break; } job->SetStartTime(InternalJob::T_INFINITE); ChangeState(sptr_job, Job::SLEEPING); } m_JobListeners.Sleeping(job.Cast()); return true; } void JobManager::SetPriority(InternalJob::Pointer job, int newPriority) { { Poco::ScopedLock lockMe (m_mutex); InternalJob::Pointer sptr_job(job); int oldPriority = job->GetPriority(); if (oldPriority == newPriority) return; job->InternalSetPriority(newPriority); //if the job is waiting to run, re-shuffle the queue if (sptr_job->GetState() == Job::WAITING) { Poco::Timestamp oldStart = job->GetStartTime(); job->SetStartTime(oldStart += (DelayFor(newPriority) - DelayFor(oldPriority))); m_JobQueueWaiting.Resort(job); } } } Poco::Timespan::TimeDiff JobManager::SleepHint() { Poco::ScopedLock managerLock (m_mutex); // wait forever if job manager is suspended if (m_suspended) return InternalJob::T_INFINITE; if (!m_JobQueueWaiting.IsEmpty()) return 0; // return the anticipated time that the next sleeping job will wake InternalJob::Pointer ptr_next(nullptr); ptr_next = m_JobQueueSleeping.Peek(); if (ptr_next == 0) return InternalJob::T_INFINITE; Poco::Timestamp tmp_startTime = ptr_next->GetStartTime(); Poco::Timestamp tmp_currentTime; Poco::Timestamp::TimeDiff timeToStart = tmp_startTime - tmp_currentTime; return timeToStart; } Job::Pointer JobManager::StartJob() { Job::Pointer job(nullptr); while (true) { job = NextJob(); if (!job) return Job::Pointer(nullptr); //must perform this outside sync block because it is third party code bool shouldRun = job->ShouldRun(); //check for listener veto if (shouldRun) m_JobListeners.AboutToRun(job); //listeners may have canceled or put the job to sleep bool endJob = false; { Poco::ScopedLock lock(m_mutex); InternalJob::Pointer internal = job; if (internal->InternalGetState() == InternalJob::ABOUT_TO_RUN) { if (shouldRun && !internal->IsAboutToRunCanceled()) { internal->SetProgressMonitor(CreateMonitor(job)); //change from ABOUT_TO_RUN to RUNNING internal->InternalSetState(Job::RUNNING); break; } internal->SetAboutToRunCanceled(false); endJob = true; //fall through and end the job below } } if (endJob) { //job has been vetoed or canceled, so mark it as done EndJob(job,Status::CANCEL_STATUS(BERRY_STATUS_LOC), true); continue; } } m_JobListeners.Running(job); return job; } void JobManager::WakeUp(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay) { poco_assert(delay >= 0); // "Scheduling delay is negative" { Poco::ScopedLock m_managerLock (m_mutex); //cannot wake up if it is not sleeping if (job->GetState() != Job::SLEEPING) return; DoSchedule(job, delay); } //call the pool outside sync block to avoid deadlock m_Pool->JobQueued(); /// IListenerExtension only notify of wake up if immediate if (delay == 0) m_JobListeners.Awake(job.Cast()); } IProgressMonitor::Pointer JobManager::MonitorFor(IProgressMonitor::Pointer sptr_monitor) { if(sptr_monitor == 0 || sptr_monitor.Cast() ) { if(m_sptr_progressProvider != 0 ) sptr_monitor = m_sptr_progressProvider->GetDefaultMonitor(); } if(sptr_monitor == 0) { IProgressMonitor::Pointer sptr_nullProgressMonitor(new NullProgressMonitor()); return sptr_nullProgressMonitor; } return sptr_monitor; } } diff --git a/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.h b/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.h index dfc3597689..49f7e5d91b 100644 --- a/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.h +++ b/Plugins/org.blueberry.core.jobs/src/internal/berryJobManager.h @@ -1,431 +1,431 @@ /*============================================================================ 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. ============================================================================*/ // // #ifndef _BERRY_JOBMANAGER_H #define _BERRY_JOBMANAGER_H #include "berryInternalJob.h" #include "berryJobQueue.h" #include "berryWorkerPool.h" #include "berryJobListeners.h" #include "berryJob.h" #include "berryIProgressMonitorWithBlocking.h" #include "berryIJobManager.h" #include "berryISchedulingRule.h" #include #include #include #include #include #include #include #include #include namespace berry { /** * Implementation of API type IJobManager * * Implementation note: all the data structures of this class are protected * by a single lock object held as a private field in this class. The JobManager * instance itself is not used because this class is publicly reachable, and third * party clients may try to synchronize on it. * * The WorkerPool class uses its own monitor for synchronizing its data * structures. To avoid deadlock between the two classes, the JobManager * must NEVER call the worker pool while its own monitor is held. */ struct BERRY_JOBS JobManager: public IJobManager { public: friend class WorkerPool; friend struct InternalJob; friend struct NullRule; berryObjectMacro(JobManager); /** * The unique identifier constant of this plug-in. */ static const QString& PI_JOBS(); static bool DEBUG; static bool DEBUG_BEGIN_END; static bool DEBUG_DEADLOCK; static bool DEBUG_LOCKS; static bool DEBUG_TIMING; static bool DEBUG_SHUTDOWN; /** * Status code constant indicating an error occurred while running a plug-in. * For backward compatibility with Platform.PLUGIN_ERROR left at (value = 2). */ static const int PLUGIN_ERROR; /// const ImplicitJobs iImplicitJobs = new ImplicitJobs(this); /** * The singleton job manager instance. It must be a singleton because * all job instances maintain a reference (as an optimization) and have no way * of updating it. */ static JobManager* GetInstance(); /** * For debugging purposes only */ static std::string PrintState(int state); /** * Note that although this method is not API, clients have historically used * it to force jobs shutdown in cases where OSGi shutdown does not occur. * For this reason, this method should be considered near-API and should not * be changed if at all possible. */ static void Shutdown(); // void Cancel(Object family) ; IProgressMonitor::Pointer CreateProgressGroup() override; Job* CurrentJob(); // void EndRule(ISchedulingRule rule) ; // Job[] Find(Object family) ; // LockManager GetLockManager() { // return lockManager; // } bool IsIdle() override; bool IsSuspended() override; // void Join(final Object family, IProgressMonitor monitor) throws InterruptedException, OperationCanceledException ); // ILock NewLock() ; /** * @see IJobManager#RemoveChangeListener(IJobChangeListener*) */ void RemoveJobChangeListener(IJobChangeListener* listener) override; // /** //* report to the progress monitor that this thread is blocked, supplying //* an information message, and if possible the job that is causing the blockage. //* important: an invocation of this method must be followed eventually be //* an invocation of ReportUnblocked. //* @param monitor the monitor to report blocking to //* @param BlockingJob the job that is blocking this thread, or null //* @see #Reportunblocked //*/ void ReportBlocked( IProgressMonitor::Pointer monitor, InternalJob::Pointer blockingjob) const ; /** * Reports that this thread was blocked, but is no longer blocked and is able * to proceed. * @param monitor The monitor to report unblocking to. * @see #ReportBlocked */ void ReportUnblocked(IProgressMonitor::Pointer monitor) const ; /** * @have a look at IJobManager Resume */ void Resume(); // /** // * @have a look at IJobManager Resume // */ // void Resume(ISchedulingRule::Pointer rule)const ; /** * @have a look at IJobManager SetProgressProvider */ void SetProgressProvider(ProgressProvider::Pointer provider) override; void SetRule(InternalJob::Pointer job, ISchedulingRule::Pointer rule); // /* // * @see IJobManager#sleep(std::string) // */ // void Sleep(Object family) ; void Suspend(); /* * @see schedule(long) */ void Schedule(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay, bool reschedule); // void Suspend(ISchedulingRule::Pointer rule, IProgressMonitor::Pointer monitor)const ; // void TransferRule(ISchedulingRule rule, Thread destinationThread) ; // void SetLockListener(LockListener listener) ; // /** // * Puts a job to sleep. Returns true if the job was successfully put to sleep. // */ // void WakeUp(Object family) ; void AddJobChangeListener(IJobChangeListener* listener) override; // void beginRule(ISchedulingRule rule, IProgressMonitor monitor) ; protected: /** * Cancels a job */ bool Cancel(InternalJob::Pointer job); /** * Returns a new progress monitor for this job, belonging to the given * progress group. Returns null if it is not a valid time to set the job's group. */ IProgressMonitor::Pointer CreateMonitor(InternalJob::Pointer job, IProgressMonitor::Pointer group, int ticks); /** * Indicates that a job was running, and has now finished. Note that this method * can be called under OutOfMemoryError conditions and thus must be paranoid * about allocating objects. */ /// optional Extension IStatus for implementation help have a look at the Java JobAPI void EndJob(InternalJob::Pointer job,IStatus::Pointer result, bool notify); /** * Returns a running or blocked job whose scheduling rule conflicts with the * scheduling rule of the given waiting job. Returns null if there are no * conflicting jobs. A job can only run if there are no running jobs and no blocked * jobs whose scheduling rule conflicts with its rule. */ InternalJob::Pointer FindBlockingJob(InternalJob::Pointer waitingJob); /** * Returns whether the job manager is active (has not been shutdown). */ bool IsActive(); /** * Returns true if the given job is blocking the execution of a non-system * job. */ bool IsBlocking(InternalJob::Pointer runningJob); // void Join(InternalJob job) ; /** * Attempts to immediately start a given job. Returns true if the job was * successfully started, and false if it could not be started immediately * due to a currently running job with a conflicting rule. Listeners will never * be notified of jobs that are run in this way. */ bool RunNow(InternalJob::Pointer sptr_job); /** * Puts a job to sleep. Returns true if the job was successfully put to sleep. */ bool Sleep(InternalJob::Pointer job); /** * Changes a job priority. */ void SetPriority(InternalJob::Pointer job, int newPriority); /** * Returns the estimated time in milliseconds before the next job is scheduled * to wake up. The result may be negative. Returns InternalJob.T_INFINITE if * there are no sleeping or waiting jobs. */ Poco::Timespan::TimeDiff SleepHint(); /** * Returns the next job to be run, or null if no jobs are waiting to run. * The worker must call endJob when the job is finished running. */ Job::Pointer StartJob(); /* * @see Job#WakeUp(long) */ void WakeUp(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay); private: JobManager(); /* Poco Mutex for synchronizing purposes */ Poco::Mutex m_mutex; // Dummy Null rule to validate SchedulingRules implemented by clients SmartPointer sptr_testRule; // //ToDO static const ISchedulingRule nullRule = new ISchedulingRule() { // public bool Contains(ISchedulingRule rule) ; // public boolean IsConflicting(ISchedulingRule rule) ; /** * True if this manager is active, and false otherwise. A job manager * starts out active, and becomes inactive if it has been shutdown * and not restarted. */ volatile bool m_active; JobListeners m_JobListeners; // // /** // * The lock for synchronizing all activity in the job manager. To avoid deadlock, // * this lock must never be held for extended periods, and must never be // * held while third party code is being called. // */ // // private final Object lock = new Object(); // static const Object lock ; // // //private LockManager lockManager = new LockManager(); - // static const LockManger lockManager; + // static const LockManager lockManager; /** * The pool of worker threads. */ WorkerPool::Pointer m_Pool; ProgressProvider::Pointer m_sptr_progressProvider; /** * Jobs that are currently running. Should only be modified from changeState */ QSet m_running; /** * Jobs that are sleeping. Some sleeping jobs are scheduled to wake * up at a given start time, while others will sleep indefinitely until woken. * Should only be modified from changeState */ JobQueue m_JobQueueSleeping; /** * jobs that are waiting to be run. Should only be modified from changeState */ JobQueue m_JobQueueWaiting; /** * True if this manager has been suspended, and false otherwise. A job manager * starts out not suspended, and becomes suspended when suspend * is invoked. Once suspended, no jobs will start running until resume * is cancelled. */ bool m_suspended; /** * Counter to record wait queue insertion order. */ long long m_waitQueueCounter; // /** // * For debugging purposes only // */ // const std::string PrintJobName(Job job); /** * Atomically updates the state of a job, adding or removing from the * necessary queues or sets. */ void ChangeState(InternalJob::Pointer job, int newState); /** * Returns a new progress monitor for this job. Never returns null. */ IProgressMonitor::Pointer CreateMonitor(Job::Pointer sptr_jobToMonitor); /** * Returns the delay in milliseconds that a job with a given priority can * tolerate waiting. */ Poco::Timestamp::TimeDiff DelayFor(int priority); /** * Performs the scheduling of a job. Does not perform any notifications. */ void DoSchedule(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay); /** * Shuts down the job manager. Currently running jobs will be told * to stop, but worker threads may still continue processing. * (note: This implemented IJobManager.Shutdown which was removed * due to problems caused by premature shutdown) */ void DoShutdown(); // void InitDebugOptions() ; /** * Removes and returns the first waiting job in the queue. Returns null if there * are no items waiting in the queue. If an item is removed from the queue, * it is moved to the running jobs list. */ Job::Pointer NextJob(); /** * Returns a non-null progress monitor instance. If the monitor is null, * returns the default monitor supplied by the progress provider, or a * NullProgressMonitor if no default monitor is available. */ IProgressMonitor::Pointer MonitorFor(IProgressMonitor::Pointer monitor); // /** // * Adds all family members in the list of jobs to the collection // */ // void Select(List members, Object family, InternalJob firstJob, int stateMask) ; // // /** // * Returns a list of all jobs known to the job manager that belong to the given family. // */ // List Select(Object family) ; // // /** // * Returns a list of all jobs known to the job manager that belong to the given // * family and are in one of the provided states. // */ // List Select(Object family, int stateMask) ; /** * Validates that the given scheduling rule obeys the constraints of * scheduling rules as described in the ISchedulingRule */ void ValidateRule(ISchedulingRule::Pointer rule); }; } #endif /* _BERRY_TEMPLATE_H */ diff --git a/Plugins/org.blueberry.core.jobs/src/internal/berryJobQueue.cpp b/Plugins/org.blueberry.core.jobs/src/internal/berryJobQueue.cpp index 8818936f83..6d2dd57b5c 100644 --- a/Plugins/org.blueberry.core.jobs/src/internal/berryJobQueue.cpp +++ b/Plugins/org.blueberry.core.jobs/src/internal/berryJobQueue.cpp @@ -1,142 +1,142 @@ /*============================================================================ 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 "berryJobQueue.h" // changed Java JobQueue implementation .. // if only one element is in the queue than InternalJob->next and InternalJob->previous pointer are pointing to 0 and not to the Element itself // I think its better .. will see namespace berry { class DummyJob: public InternalJob { public: IStatus::Pointer Run(IProgressMonitor::Pointer) override { return Status::OK_STATUS(BERRY_STATUS_LOC); } DummyJob() : InternalJob("Queue-Head") { } }; JobQueue::JobQueue(bool allowConflictOvertaking) : dummy(new DummyJob()), m_allowConflictOvertaking(allowConflictOvertaking) { dummy->SetNext(dummy); dummy->SetPrevious(dummy); } -//TODO JobQueue Constructor IStatus Implementierung +//TODO JobQueue Constructor IStatus Implementation //TODO Constructor JobQueue IStatus .. implementation // public JobQueue(boolean allowConflictOvertaking) { // //compareTo on dummy is never called // dummy = new InternalJob("Queue-Head") {//$NON-NLS-1$ // public IStatus run(IProgressMonitor m) { // return Status.OK_STATUS; // } // }; // dummy.setNext(dummy); // dummy.setPrevious(dummy); // this.allowConflictOvertaking = allowConflictOvertaking; //} bool JobQueue::CanOvertake(InternalJob::Pointer newEntry, InternalJob::Pointer queueEntry) { //can never go past the end of the queue if (queueEntry == dummy.GetPointer()) return false; //if the new entry was already in the wait queue, ensure it is re-inserted in correct position (bug 211799) if (newEntry->GetWaitQueueStamp() > 0 && newEntry->GetWaitQueueStamp() < queueEntry->GetWaitQueueStamp()) return true; //if the new entry has lower priority, there is no need to overtake the existing entry if ((queueEntry == newEntry)) return false; // the new entry has higher priority, but only overtake the existing entry if the queue allows it InternalJob::Pointer sptr_queueEntry(queueEntry); return m_allowConflictOvertaking || !newEntry->IsConflicting(sptr_queueEntry); } void JobQueue::Clear() { dummy->SetNext(dummy); dummy->SetPrevious(dummy); } // notice: important that the first element in the queue is internally set as a dummy element InternalJob::Pointer JobQueue::Dequeue() { InternalJob::Pointer ptr_dummyPrevious = dummy->Previous(); // sets previous pointer to 0 if there is only 1 Element in the queue if (ptr_dummyPrevious == dummy) { dummy->previous = nullptr; return dummy; } return ptr_dummyPrevious->Remove(); } void JobQueue::Enqueue(InternalJob::Pointer newEntry) { InternalJob::Pointer tail = dummy->Next(); //overtake lower priority jobs. Only overtake conflicting jobs if allowed to while (CanOvertake(newEntry, tail)) tail = tail->Next(); InternalJob::Pointer tailPrevious = tail->Previous(); newEntry->SetNext(tail); newEntry->SetPrevious(tailPrevious); tailPrevious->SetNext(newEntry); tail->SetPrevious(newEntry); } void JobQueue::Remove(InternalJob::Pointer jobToRemove) { jobToRemove->Remove(); } void JobQueue::Resort(InternalJob::Pointer entry) { this->Remove(entry); this->Enqueue(entry); } bool JobQueue::IsEmpty() { return this->dummy->next == dummy; } InternalJob::Pointer JobQueue::Peek() { return dummy->Previous() == dummy ? InternalJob::Pointer(nullptr) : dummy->Previous(); } } diff --git a/Plugins/org.blueberry.core.jobs/src/internal/berryWorkerPool.cpp b/Plugins/org.blueberry.core.jobs/src/internal/berryWorkerPool.cpp index 9360e6ea59..41abb8fc98 100644 --- a/Plugins/org.blueberry.core.jobs/src/internal/berryWorkerPool.cpp +++ b/Plugins/org.blueberry.core.jobs/src/internal/berryWorkerPool.cpp @@ -1,215 +1,215 @@ /*============================================================================ 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. ============================================================================*/ #define NOMINMAX #include "berryWorkerPool.h" #include "berryJobManager.h" #include #include #include namespace berry { WorkerPool::WorkerPool(JobManager* myJobManager) : m_ptrManager(myJobManager), m_numThreads(0), m_sleepingThreads(0), m_threads( 10), m_busyThreads(0) // m_isDaemon(false), { } const long WorkerPool::BEST_BEFORE = 60000; const int WorkerPool::MIN_THREADS = 1; void WorkerPool::Shutdown() { Poco::ScopedLock LockMe(m_mutexOne); for(int i = 0; i<= m_numThreads; i++) { notify(); } } void WorkerPool::Add(Worker::Pointer worker) { Poco::Mutex::ScopedLock lock(m_mutexOne); m_threads.push_back(worker); } void WorkerPool::DecrementBusyThreads() { Poco::ScopedLock lockOne(m_mutexOne); //impossible to have less than zero busy threads if (--m_busyThreads < 0) { //TODO Decrementbusythreads if (jobmanager.debug) assert.istrue(false, integer.tostring(busythreads)); m_busyThreads = 0; } } void WorkerPool::IncrementBusyThreads() { Poco::ScopedLock lockOne(m_mutexOne); if (++m_busyThreads > m_numThreads) { m_busyThreads = m_numThreads; } } bool WorkerPool::Remove(Worker::Pointer worker) { Poco::ScopedLock lockOne(m_mutexOne); auto end = std::remove(m_threads.begin(), m_threads.end(), worker); bool removed = end != m_threads.end(); m_threads.erase(end); return removed; } void WorkerPool::EndWorker(Worker::Pointer sptr_worker) { Poco::ScopedLock lock(m_mutexOne); Remove(sptr_worker); } void WorkerPool::Sleep(long duration) { Poco::ScopedLock lock(m_mutexOne); m_sleepingThreads++; m_busyThreads--; try { wait(duration); throw FinallyThrowException(); } catch (FinallyThrowException&) { m_sleepingThreads--; m_busyThreads++; } catch (...) { m_sleepingThreads--; m_busyThreads++; } } InternalJob::Pointer WorkerPool::StartJob(Worker* worker) { // if we're above capacity, kill the thread { Poco::Mutex::ScopedLock lockOne(m_mutexOne); if (!m_ptrManager->IsActive()) { // must remove the worker immediately to prevent all threads from expiring Worker::Pointer sptr_worker(worker); EndWorker(sptr_worker); return InternalJob::Pointer(nullptr); } //set the thread to be busy now in case of reentrant scheduling IncrementBusyThreads(); } Job::Pointer ptr_job(nullptr); try { ptr_job = m_ptrManager->StartJob(); //spin until a job is found or until we have been idle for too long Poco::Timestamp idleStart; while (m_ptrManager->IsActive() && ptr_job == 0) { long tmpSleepTime = long(m_ptrManager->SleepHint()); if (tmpSleepTime > 0) Sleep(std::min(tmpSleepTime, BEST_BEFORE)); ptr_job = m_ptrManager->StartJob(); //if we were already idle, and there are still no new jobs, then the thread can expire { Poco::Mutex::ScopedLock lockOne(m_mutexOne); Poco::Timestamp tmpCurrentTime; long long tmpTime = tmpCurrentTime - idleStart; if (ptr_job == 0 && (tmpTime > BEST_BEFORE) && (m_numThreads - m_busyThreads) > MIN_THREADS) { //must remove the worker immediately to prevent all threads from expiring Worker::Pointer sptr_worker(worker); EndWorker(sptr_worker); return InternalJob::Pointer(nullptr); } } } if (ptr_job != 0) { //if this job has a rule, then we are essentially acquiring a lock //if ((job.getRule() != 0) && !(job instanceof ThreadJob)) { - // //don't need to re-aquire locks because it was not recorded in the graph + // //don't need to re-acquire locks because it was not recorded in the graph // //that this thread waited to get this rule // manager.getLockManager().addLockThread(Thread.currentThread(), job.getRule()); // } //see if we need to wake another worker if (m_ptrManager->SleepHint() <= 0) JobQueued(); } throw FinallyThrowException(); } catch (FinallyThrowException&) { //decrement busy thread count if we're not running a job if (ptr_job == 0) DecrementBusyThreads(); } catch (...) { DecrementBusyThreads(); } return ptr_job; } void WorkerPool::JobQueued() { Poco::ScopedLock lockOne(m_mutexOne); //if there is a sleeping thread, wake it up if (m_sleepingThreads > 0) { notify(); return; } //create a thread if all threads are busy if (m_busyThreads >= m_numThreads) { WorkerPool::WeakPtr wp_WorkerPool(WorkerPool::Pointer(this)); Worker::Pointer sptr_worker(new Worker(wp_WorkerPool)); Add(sptr_worker); sptr_worker->Start(); return; } } void WorkerPool::EndJob(InternalJob::Pointer job, IStatus::Pointer result) { DecrementBusyThreads(); //TODO LockManager // //need to end rule in graph before ending job so that 2 threads // //do not become the owners of the same rule in the graph // if ((job.getRule() != null) && !(job instanceof ThreadJob)) { // //remove any locks this thread may be owning on that rule // manager.getLockManager().removeLockCompletely(Thread.currentThread(), job.getRule()); // } m_ptrManager->EndJob(job, result, true); // //ensure this thread no longer owns any scheduling rules // manager.implicitJobs.endJob(job); } } diff --git a/Plugins/org.blueberry.core.runtime/src/berryIAdapterManager.h b/Plugins/org.blueberry.core.runtime/src/berryIAdapterManager.h index 96fa476b20..1c09fe9261 100644 --- a/Plugins/org.blueberry.core.runtime/src/berryIAdapterManager.h +++ b/Plugins/org.blueberry.core.runtime/src/berryIAdapterManager.h @@ -1,280 +1,280 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIADAPTERMANAGER_H_ #define BERRYIADAPTERMANAGER_H_ #include #include #include "berryPlatformObject.h" #include "berryIAdapterFactory.h" #include #include namespace berry { /** * An adapter manager maintains a registry of adapter factories. Clients * directly invoke methods on an adapter manager to register and unregister * adapters. All adaptable objects (that is, objects that implement the IAdaptable * interface) tunnel IAdaptable.getAdapter invocations to their - * adapter manager's IAdapterManger.getAdapter method. The + * adapter manager's IAdapterManager.getAdapter method. The * adapter manager then forwards this request unmodified to the IAdapterFactory.getAdapter * method on one of the registered adapter factories. *

* Adapter factories can be registered programmatically using the registerAdapters * method. Alternatively, they can be registered declaratively using the * org.blueberry.core.runtime.adapters extension point. Factories registered * with this extension point will not be able to provide adapters until their * corresponding plugin has been activated. *

* The following code snippet shows how one might register an adapter of type * com.example.acme.Sticky on resources in the workspace. *

* * \code * IAdapterFactory pr = new IAdapterFactory() { * public Class[] getAdapterList() { * return new Class[] { com.example.acme.Sticky.class }; * } * public Object getAdapter(Object adaptableObject, Class adapterType) { * IResource res = (IResource) adaptableObject; * QualifiedName key = new QualifiedName("com.example.acme", "sticky-note"); * try { * com.example.acme.Sticky v = (com.example.acme.Sticky) res.getSessionProperty(key); * if (v == null) { * v = new com.example.acme.Sticky(); * res.setSessionProperty(key, v); * } * } catch (CoreException e) { * // unable to access session property - ignore * } * return v; * } * } * Platform.getAdapterManager().registerAdapters(pr, IResource.class); * \endcode * *

* This interface can be used without OSGi running. *

* This interface is not intended to be implemented by clients. *

* @see IAdaptable * @see IAdapterFactory */ struct org_blueberry_core_runtime_EXPORT IAdapterManager: public Object { berryObjectMacro(berry::IAdapterManager); /** * This value can be returned to indicate that no applicable adapter factory * was found. * @since org.blueberry.equinox.common 3.3 */ static const int NONE; /** * This value can be returned to indicate that an adapter factory was found, * but has not been loaded. * @since org.blueberry.equinox.common 3.3 */ static const int NOT_LOADED; /** * This value can be returned to indicate that an adapter factory is loaded. * @since org.blueberry.equinox.common 3.3 */ static const int LOADED; /** * Returns a Poco::Any object which contains an instance of the given name associated * with the given adaptable. Returns an empty Poco::Any if no such object can * be found. *

* Note that this method will never cause plug-ins to be loaded. If the * only suitable factory is not yet loaded, this method will return an empty Poco::Any. * If activation of the plug-in providing the factory is required, use the * LoadAdapter method instead. * * @param adaptable the adaptable object being queried (usually an instance * of IAdaptable) * @return a Poco::Any castable to the given adapter type, or empty * if the given adaptable object does not have an available adapter of the * given type */ template A* GetAdapter(const Object* adaptable) { const char* typeName = qobject_interface_iid(); if (typeName == nullptr) { BERRY_WARN << "Error getting adapter for '" << Reflection::GetClassName(adaptable) << "': " << "Cannot get the interface id for type '" << Reflection::GetClassName() << "'. It is probably missing a Q_DECLARE_INTERFACE macro in its header."; return nullptr; } return dynamic_cast(this->GetAdapter(adaptable, typeName, false)); } /** * Returns an object which is an instance of the given class name associated * with the given object. Returns null if no such object can * be found. *

* Note that this method will never cause plug-ins to be loaded. If the * only suitable factory is not yet loaded, this method will return null. * If activation of the plug-in providing the factory is required, use the * loadAdapter method instead. * * @param adaptable the adaptable object being queried (usually an instance * of IAdaptable) * @param adapterTypeName the fully qualified name of the type of adapter to look up * @return an object castable to the given adapter type, or null * if the given adaptable object does not have an available adapter of the * given type */ virtual Object* GetAdapter(const Object* adaptable, const QString& adapterTypeName) = 0; /** * Returns whether there is an adapter factory registered that may be able * to convert adaptable to an object of type adapterTypeName. *

* Note that a return value of true does not guarantee that * a subsequent call to GetAdapter with the same arguments * will return a non-empty result. If the factory's plug-in has not yet been * loaded, or if the factory itself returns nothing, then * GetAdapter will still return an empty Poco::Any. * * @param adaptableType the adaptable object being queried (usually an instance * of IAdaptable) * @param adapterType the fully qualified class name of an adapter to * look up * @return true if there is an adapter factory that claims * it can convert adaptable to an object of type adapterType, * and false otherwise. */ virtual bool HasAdapter(const Object* adaptableType, const QString& adapterType) = 0; template int QueryAdapter(const Object* adaptable) { const char* typeName = qobject_interface_iid(); if (typeName == nullptr) { BERRY_WARN << "Error querying adapter manager for '" << Reflection::GetClassName(adaptable) << "': " << "Cannot get the interface id for type '" << Reflection::GetClassName() << "'. It is probably missing a Q_DECLARE_INTERFACE macro in its header."; return NONE; } return this->QueryAdapter(adaptable, typeName); } /** * Returns a status of an adapter factory registered that may be able * to convert adaptable to an object of type adapterTypeName. *

* One of the following values can be returned:

* @param adaptableType the adaptable object being queried (usually an instance * of IAdaptable) * @param adapterType the fully qualified class name of an adapter to * look up * @return a status of the adapter */ virtual int QueryAdapter(const Object* adaptableType, const QString& adapterType) = 0; /** * Returns an object that is an instance of the given class name associated * with the given object. Returns an empty Poco::Any if no such object can * be found. *

* Note that unlike the GetAdapter methods, this method * will cause the plug-in that contributes the adapter factory to be loaded * if necessary. As such, this method should be used judiciously, in order * to avoid unnecessary plug-in activations. Most clients should avoid * activation by using GetAdapter instead. * * @param adaptable the adaptable object being queried (usually an instance * of IAdaptable) * @return a Poco::Any castable to the given adapter type, or empty * if the given adaptable object does not have an available adapter of the * given type */ template A* LoadAdapter(const Object* adaptable) { const char* typeName = qobject_interface_iid(); if (typeName == nullptr) { BERRY_WARN << "Error getting adapter for '" << Reflection::GetClassName(adaptable) << "': " << "Cannot get the interface id for type '" << Reflection::GetClassName() << "'. It is probably missing a Q_DECLARE_INTERFACE macro in its header."; return nullptr; } return dynamic_cast(this->GetAdapter(adaptable, typeName, true)); } /** * Registers the given adapter factory as extending objects of the given * type. * * @param factory the adapter factory * @param adaptableTypeName the fully qualified typename being extended * @see #UnregisterAdapters */ virtual void RegisterAdapters(IAdapterFactory* factory, const QString& adaptableTypeName) = 0; /** * Removes the given adapter factory completely from the list of registered * factories. Equivalent to calling UnregisterAdapters(IAdapterFactory*, const std::string&) * on all classes against which it had been explicitly registered. Does * nothing if the given factory is not currently registered. * * @param factory the adapter factory to remove * @see #RegisterAdapters */ virtual void UnregisterAdapters(IAdapterFactory* factory) = 0; /** * Removes the given adapter factory from the list of factories registered * as extending the given class. Does nothing if the given factory and type * combination is not registered. * * @param factory the adapter factory to remove * @param adaptableTypeName one of the type names against which the given factory is * registered * @see #RegisterAdapters */ virtual void UnregisterAdapters(IAdapterFactory* factory, const QString& adaptableTypeName) = 0; private: virtual Object* GetAdapter(const Object* adaptable, const QString& adapterType, bool force) = 0; }; } // namespace berry Q_DECLARE_INTERFACE(berry::IAdapterManager, "org.blueberry.service.IAdapterManager") #endif /*BERRYIADAPTERMANAGER_H_*/ diff --git a/Plugins/org.blueberry.core.runtime/src/berryIStatus.h b/Plugins/org.blueberry.core.runtime/src/berryIStatus.h index cad224941c..c5fa114bf4 100644 --- a/Plugins/org.blueberry.core.runtime/src/berryIStatus.h +++ b/Plugins/org.blueberry.core.runtime/src/berryIStatus.h @@ -1,199 +1,199 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYISTATUS_H_ #define BERRYISTATUS_H_ #include #include #include namespace berry { /** * A status object represents the outcome of an operation. * All CoreExceptions carry a status object to indicate * what went wrong. Status objects are also returned by methods needing * to provide details of failures (e.g., validation methods). *

* A status carries the following information: *

* Some status objects, known as multi-statuses, have other status objects * as children. *

*

* The class Status is the standard public implementation * of status objects; the subclass MultiStatus is the * implements multi-status objects. *

* This interface can be used without OSGi running. *

* @see MultiStatus * @see Status */ struct org_blueberry_core_runtime_EXPORT IStatus: public Object { berryObjectMacro(berry::IStatus); enum Severity { /** Status severity constant (value 0) indicating this status represents the nominal case. * This constant is also used as the status code representing the nominal case. */ OK_TYPE = 0x00, /** Status type severity (bit mask, value 1) indicating this status is informational only. */ INFO_TYPE = 0x01, /** Status type severity (bit mask, value 2) indicating this status represents a warning. */ WARNING_TYPE = 0x02, /** Status type severity (bit mask, value 4) indicating this status represents an error. */ ERROR_TYPE = 0x04, - /** Status type severity (bit mask, value 8) indicating this status represents a cancelation. */ + /** Status type severity (bit mask, value 8) indicating this status represents a cancellation. */ CANCEL_TYPE = 0x08 }; Q_DECLARE_FLAGS(Severities, Severity) /** * Returns a list of status object immediately contained in this * multi-status, or an empty list if this is not a multi-status. * * @return an array of status objects * @see #IsMultiStatus() */ virtual QList GetChildren() const = 0; /** * Returns the plug-in-specific status code describing the outcome. * * @return plug-in-specific status code */ virtual int GetCode() const = 0; /** * Returns the relevant low-level exception, or null if none. * For example, when an operation fails because of a network communications * failure, this might return the java.io.IOException * describing the exact nature of that failure. * * @return the relevant low-level exception, or null if none */ virtual const ctkException* GetException() const = 0; /** * Returns the message describing the outcome. * The message is localized to the current locale. * * @return a localized message */ virtual QString GetMessage() const = 0; /** * Returns the unique identifier of the plug-in associated with this status * (this is the plug-in that defines the meaning of the status code). * * @return the unique identifier of the relevant plug-in */ virtual QString GetPlugin() const = 0; /** * Returns the severity. The severities are as follows (in * descending order): *
    - *
  • CANCEL_TYPE - cancelation occurred
  • + *
  • CANCEL_TYPE - cancellation occurred
  • *
  • ERROR_TYPE - a serious error (most severe)
  • *
  • WARNING_TYPE - a warning (less severe)
  • *
  • INFO_TYPE - an informational ("fyi") message (least severe)
  • *
  • OK_TYPE - everything is just fine
  • *
*

* The severity of a multi-status is defined to be the maximum * severity of any of its children, or OK if it has * no children. *

* * @return the severity: one of OK_TYPE, ERROR_TYPE, * INFO_TYPE, WARNING_TYPE, or CANCEL_TYPE */ virtual Severity GetSeverity() const = 0; /** * Returns whether this status is a multi-status. * A multi-status describes the outcome of an operation * involving multiple operands. *

* The severity of a multi-status is derived from the severities * of its children; a multi-status with no children is * OK_TYPE by definition. * A multi-status carries a plug-in identifier, a status code, * a message, and an optional exception. Clients may treat * multi-status objects in a multi-status unaware way. *

* * @return true for a multi-status, * false otherwise * @see #GetChildren() */ virtual bool IsMultiStatus() const = 0; /** * Returns whether this status indicates everything is okay * (neither info, warning, nor error). * * @return true if this status has severity * OK, and false otherwise */ virtual bool IsOK() const = 0; /** * Returns whether the severity of this status matches the given * severity mask. Note that a status with severity OK_TYPE * will never match; use isOK instead to detect * a status with a severity of OK. * * @param severityMask a mask formed by bitwise or'ing severity mask * constants (ERROR_TYPE, WARNING_TYPE, * INFO_TYPE, CANCEL_TYPE) * @return true if there is at least one match, * false if there are no matches * @see #GetSeverity() * @see #CANCEL_TYPE * @see #ERROR_TYPE * @see #WARNING_TYPE * @see #INFO_TYPE */ virtual bool Matches(const Severities& severityMask) const = 0; virtual QString GetFileName() const = 0; virtual QString GetMethodName() const = 0; virtual int GetLineNumber() const = 0; }; } Q_DECLARE_OPERATORS_FOR_FLAGS(berry::IStatus::Severities) #endif /* BERRYISTATUS_H_ */ diff --git a/Plugins/org.blueberry.core.runtime/src/berryObject.h b/Plugins/org.blueberry.core.runtime/src/berryObject.h index 325abc974d..513786dcd5 100644 --- a/Plugins/org.blueberry.core.runtime/src/berryObject.h +++ b/Plugins/org.blueberry.core.runtime/src/berryObject.h @@ -1,241 +1,241 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYOBJECT_H_ #define BERRYOBJECT_H_ #include #include "berryMacros.h" #include "berryMessage.h" #include #include #include #include #include #ifdef _MSC_VER // disable inheritance by dominance warnings #pragma warning( disable : 4250 4275 ) #endif class QDebug; class QTextStream; namespace berry { class org_blueberry_core_runtime_EXPORT Indent { public: /** Standard class typedefs. */ typedef Indent Self; /** Construct the object with an initial Indentation level. */ Indent(int ind = 0) { m_Indent=ind; } /** * Determine the next Indentation level. Keep Indenting by two until the * a maximum of forty spaces is reached. */ Indent GetNextIndent(); /** Print out the Indentation. Basically output a bunch of spaces. */ friend org_blueberry_core_runtime_EXPORT QDebug operator<<(QDebug os, const Indent& o); private: int m_Indent; }; /** \class Object * \brief Light weight base class for most BlueBerry classes. * * Object is copied from itk::LightObject and is the highest * level base class for most BlueBerry objects. It * implements reference counting and the API for object printing. * */ class org_blueberry_core_runtime_EXPORT Object { private: mutable Message<> m_DestroyMessage; public: typedef Object Self; typedef berry::SmartPointer Pointer; typedef berry::SmartPointer ConstPointer; typedef berry::WeakPointer WeakPtr; typedef berry::WeakPointer ConstWeakPtr; static const char* GetStaticClassName(); virtual QString GetClassName() const; static Reflection::TypeInfo GetStaticTypeInfo(); virtual Reflection::TypeInfo GetTypeInfo() const; static QList GetStaticSuperclasses(); virtual QList GetSuperclasses() const; /** Delete an BlueBerry object. This method should always be used to delete an * object when the new operator was used to create it. Using the C * delete method will not work with reference counting. */ virtual void Delete(); #ifdef _WIN32 /** Used to avoid dll boundary problems. */ void* operator new(size_t); void* operator new[](size_t); void operator delete(void*); void operator delete[](void*, size_t); #endif /** * Cause the object to print itself out. This is usually used to provide * detailed information about the object's state. It just calls the - * header/self/trailer virtual print methods, which can be overriden by + * header/self/trailer virtual print methods, which can be overridden by * subclasses. */ QDebug Print(QDebug os, Indent Indent=0) const; /** * Returns a string representation of this object. The default * implementation returns an empty string. */ virtual QString ToString() const; /** * Returns a hash code value for the object. */ virtual uint HashCode() const; /** * Override this method to implement a specific "less than" operator * for associative STL containers. */ virtual bool operator<(const Object*) const; /** Increase the reference count (mark as used by another object). */ void Register() const; /** Decrease the reference count (release by another object). * Set del to false if you do not want the object to be deleted if * the reference count is zero (use with care!) */ void UnRegister(bool del = true) const; /** Gets the reference count on this object. */ int GetReferenceCount() const { return m_ReferenceCount.load(); } /** Sets the reference count on this object. This is a dangerous * method, use it with care. */ void SetReferenceCount(int); inline void AddDestroyListener(const MessageAbstractDelegate<>& delegate) const { m_DestroyMessage += delegate; } inline void RemoveDestroyListener(const MessageAbstractDelegate<>& delegate) const { m_DestroyMessage -= delegate; } /** * A generic comparison method. Override this method in subclasses and * cast to your derived class to provide a more detailed comparison. */ virtual bool operator==(const Object*) const; #ifdef BLUEBERRY_DEBUG_SMARTPOINTER unsigned int GetTraceId() const; private: unsigned int m_TraceId; unsigned int& GetTraceIdCounter() const; public: #endif protected: friend struct QScopedPointerObjectDeleter; Object(); virtual ~Object(); /** * Methods invoked by Print() to print information about the object * including superclasses. Typically not called by the user (use Print() * instead) but used in the hierarchical print process to combine the * output of several classes. */ virtual QDebug PrintSelf(QDebug os, Indent indent) const; virtual QDebug PrintHeader(QDebug os, Indent indent) const; virtual QDebug PrintTrailer(QDebug os, Indent indent) const; /** Number of uses of this object by other objects. */ mutable QAtomicInt m_ReferenceCount; /** Mutex lock to protect modification to the reference count */ mutable QMutex m_ReferenceCountLock; private: Object(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; // A custom deleter for QScopedPointer // berry::Object instances in a QScopedPointer should have reference count one, // such that they are not accidentally deleted when a temporary smart pointer // pointing to it goes out of scope. This deleter fixes the reference count and // always deletes the instance. Use a berry::SmartPointer if the lifetime should // exceed the one of the pointer. struct QScopedPointerObjectDeleter { static inline void cleanup(Object* obj) { if (obj == nullptr) return; obj->UnRegister(false); delete obj; } }; org_blueberry_core_runtime_EXPORT QDebug operator<<(QDebug os, const berry::Indent& o); } /** * This operator allows all subclasses of Object to be printed via QDebug <<. * It in turn invokes the Print method, which in turn will invoke the * PrintSelf method that all objects should define, if they have anything * interesting to print out. */ org_blueberry_core_runtime_EXPORT QDebug operator<<(QDebug os, const berry::Object& o); org_blueberry_core_runtime_EXPORT QDebug operator<<(QDebug os, const berry::SmartPointer& o); org_blueberry_core_runtime_EXPORT QDebug operator<<(QDebug os, const berry::SmartPointer& o); org_blueberry_core_runtime_EXPORT QTextStream& operator<<(QTextStream& os, const berry::Object& o); org_blueberry_core_runtime_EXPORT QTextStream& operator<<(QTextStream& os, const berry::SmartPointer& o); //org_blueberry_core_runtime_EXPORT QTextStream& operator<<(QTextStream& os, const berry::SmartPointer& o); Q_DECLARE_METATYPE(berry::Object::Pointer) org_blueberry_core_runtime_EXPORT uint qHash(const berry::Object& o); #endif /*BERRYOBJECT_H_*/ diff --git a/Plugins/org.blueberry.core.runtime/src/berryPlatformObject.h b/Plugins/org.blueberry.core.runtime/src/berryPlatformObject.h index c36c7381eb..e89a1ace00 100755 --- a/Plugins/org.blueberry.core.runtime/src/berryPlatformObject.h +++ b/Plugins/org.blueberry.core.runtime/src/berryPlatformObject.h @@ -1,81 +1,81 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYPLATFORMOBJECT_H_ #define BERRYPLATFORMOBJECT_H_ #include #include #include "berryIAdaptable.h" namespace berry { /** * An abstract superclass implementing the IAdaptable * interface. getAdapter invocations are directed * to the platform's adapter manager. *

* Note: In situations where it would be awkward to subclass this * class, the same affect can be achieved simply by implementing * the IAdaptable interface and explicitly forwarding * the getAdapter request to the platform's - * adapater manager. The method would look like: + * adapter manager. The method would look like: *

  *     public Object getAdapter(Class adapter) {
  *         return Platform.getAdapterManager().getAdapter(this, adapter);
  *     }
  * 
*

*

* Clients may subclass. *

* * @see Platform#getAdapterManager */ class org_blueberry_core_runtime_EXPORT PlatformObject : public virtual Object, public virtual IAdaptable { public: berryObjectMacro(berry::PlatformObject); /** * Constructs a new platform object. */ PlatformObject(); /** * Returns an object which is an instance of the given class * associated with this object. Returns null if * no such object can be found. *

* This implementation of the method declared by IAdaptable * passes the request along to the platform's adapter manager; roughly * Platform.getAdapterManager().getAdapter(this, adapter). * Subclasses may override this method (however, if they do so, they * should invoke the method on their superclass to ensure that the * Platform's adapter manager is consulted). *

* * @see IAdaptable#getAdapter * @see Platform#getAdapterManager */ Object* GetAdapter(const QString& adapter) const override; }; } #endif /* BERRYPLATFORMOBJECT_H_ */ diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryApplicationContainer.h b/Plugins/org.blueberry.core.runtime/src/internal/berryApplicationContainer.h index 45c092537d..778bce9295 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryApplicationContainer.h +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryApplicationContainer.h @@ -1,180 +1,180 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYAPPLICATIONCONTAINER_H #define BERRYAPPLICATIONCONTAINER_H #include #include #include #include #include struct ctkApplicationLauncher; struct ctkApplicationRunnable; namespace berry { struct IBranding; struct IExtensionRegistry; class ApplicationDescriptor; class ApplicationHandle; class MainApplicationLauncher; /* * This container will discover installed BlueBerry applications and register the * appropriate ctkApplicationDescriptor service with the service registry. */ class ApplicationContainer : public QObject, public QMutex, private IRegistryEventListener, private ctkServiceTrackerCustomizer { Q_OBJECT private: static const QString PI_RUNTIME; // = "org.blueberry.core.runtime"; static const QString PT_APPLICATIONS; // = "applications"; static const QString PT_APP_VISIBLE; // = "visible"; static const QString PT_APP_THREAD; // = "thread"; static const QString PT_APP_THREAD_ANY; // = "any"; static const QString PT_APP_CARDINALITY; // = "cardinality"; static const QString PT_APP_CARDINALITY_SINGLETON_GLOBAL; // = "singleton-global"; static const QString PT_APP_CARDINALITY_SINGLETON_SCOPED; // = "singleton-scoped"; static const QString PT_APP_CARDINALITY_UNLIMITED; // = "*"; static const QString PT_APP_ICON; // = "icon"; static const QString PT_PRODUCTS; // = "products"; static const QString EXT_ERROR_APP; // = "org.blueberry.core.runtime.app.error"; static const QString PROP_PRODUCT; // = "blueberry.product"; static const QString PROP_BLUEBERRY_APPLICATION; // = "blueberry.application"; static const QString PROP_BLUEBERRY_APPLICATION_LAUNCH_DEFAULT; // = "blueberry.application.launchDefault"; static const int NOT_LOCKED; // = 0; static const int LOCKED_SINGLETON_GLOBAL_RUNNING; // = 1; static const int LOCKED_SINGLETON_GLOBAL_APPS_RUNNING; // = 2; static const int LOCKED_SINGLETON_SCOPED_RUNNING; // = 3; static const int LOCKED_SINGLETON_LIMITED_RUNNING; // = 4; static const int LOCKED_MAIN_THREAD_RUNNING; // = 5; ctkPluginContext* context; QMutex lock; // A map of ApplicationDescriptors keyed by application ID /* @GuardedBy(lock) */ QHash apps; IExtensionRegistry* extensionRegistry; QScopedPointer> launcherTracker; mutable QScopedPointer branding; mutable bool missingProductReported; /* @GuardedBy(lock) */ QList activeHandles; // the currently active application handles /* @GuardedBy(lock) */ ApplicationHandle* activeMain; // the handle currently running on the main thread /* @GuardedBy(lock) */ ApplicationHandle* activeGlobalSingleton; // the current global singleton handle /* @GuardedBy(lock) */ ApplicationHandle* activeScopedSingleton; // the current scoped singleton handle /* @GuardedBy(lock) */ QHash > activeLimited; // Map of handles that have cardinality limits mutable QString defaultAppId; //DefaultApplicationListener defaultAppListener; ctkApplicationRunnable* defaultMainThreadAppHandle; // holds the default app handle to be run on the main thread volatile bool missingApp; QScopedPointer missingAppLauncher; public: ApplicationContainer(ctkPluginContext* context, IExtensionRegistry* extensionRegistry); ~ApplicationContainer() override; void Start(); void Stop(); IBranding* GetBranding() const; ctkPluginContext* GetContext() const; void Launch(ApplicationHandle* appHandle); void Lock(ApplicationHandle* appHandle); void Unlock(ApplicationHandle* appHandle); int IsLocked(const ApplicationDescriptor* eclipseApp) const; void StartDefaultApp(bool delayError); private: Q_DISABLE_COPY(ApplicationContainer) friend class ApplicationHandle; /* * Only used to find the default application */ ApplicationDescriptor* GetAppDescriptor(const QString& applicationId); ApplicationDescriptor* CreateAppDescriptor(const SmartPointer& appExtension); ApplicationDescriptor* RemoveAppDescriptor(const QString& applicationId); /* * Registers an ApplicationDescriptor service for each eclipse application * available in the extension registry. */ void RegisterAppDescriptors(); void RegisterAppDescriptor(const QString& applicationId); /* * Returns a list of all the available application IDs which are available * in the extension registry. */ QList > GetAvailableAppExtensions() const; QString GetAvailableAppsMsg() const; /* - * Returns the application extension for the specified applicaiton ID. + * Returns the application extension for the specified application ID. * A RuntimeException is thrown if the extension does not exist for the * given application ID. */ SmartPointer GetAppExtension(const QString& applicationId) const; Q_SLOT void PluginChanged(const ctkPluginEvent& event); void StopAllApps(); QString GetDefaultAppId() const; ctkApplicationLauncher* addingService(const ctkServiceReference& reference) override; void modifiedService(const ctkServiceReference& reference, ctkApplicationLauncher* service) override; void removedService(const ctkServiceReference& reference, ctkApplicationLauncher* service) override; void Added(const QList >& extensions) override; void Added(const QList >& extensionPoints) override; void Removed(const QList >& extensions) override; void Removed(const QList >& extensionPoints) override; void RefreshAppDescriptors(); }; } #endif // BERRYAPPLICATIONCONTAINER_H diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryExtensionRegistry.cpp b/Plugins/org.blueberry.core.runtime/src/internal/berryExtensionRegistry.cpp index d83da9b8cc..bd600d2bcc 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryExtensionRegistry.cpp +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryExtensionRegistry.cpp @@ -1,1340 +1,1340 @@ /*============================================================================ 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 "berryExtensionRegistry.h" #include "berryCombinedEventDelta.h" #include "berryConfigurationElement.h" #include "berryConfigurationElementAttribute.h" #include "berryConfigurationElementDescription.h" #include "berryExtension.h" #include "berryExtensionHandle.h" #include "berryExtensionPoint.h" #include "berryExtensionPointHandle.h" #include "berryExtensionsParser.h" #include "berryIConfigurationElement.h" #include "berryIExtension.h" #include "berryIExtensionPoint.h" #include "berrySimpleExtensionPointFilter.h" #include "berryMultiStatus.h" #include "berryRegistryConstants.h" #include "berryRegistryContribution.h" #include "berryRegistryContributor.h" #include "berryRegistryMessages.h" #include "berryRegistryObjectFactory.h" #include "berryRegistryObjectManager.h" #include "berryRegistryProperties.h" #include "berryRegistryStrategy.h" #include "berryStatus.h" #include #include namespace berry { struct ExtensionRegistry::ListenerInfo { IExtensionPointFilter filter; IRegistryEventListener* listener; ListenerInfo(IRegistryEventListener* listener, const IExtensionPointFilter& filter) : filter(filter), listener(listener) { } /** * Used by ListenerList to ensure uniqueness. */ bool operator==(const ListenerInfo& another) const { return another.listener == this->listener; } }; void ExtensionRegistry::Add(const SmartPointer &element) { QWriteLocker l(&access); eventDelta = CombinedEventDelta::RecordAddition(); BasicAdd(element, true); FireRegistryChangeEvent(); eventDelta.Reset(); } QString ExtensionRegistry::AddExtension(int extension) { Extension::Pointer addedExtension = registryObjects->GetObject(extension, RegistryObjectManager::EXTENSION).Cast(); QString extensionPointToAddTo = addedExtension->GetExtensionPointIdentifier(); ExtensionPoint::Pointer extPoint = registryObjects->GetExtensionPointObject(extensionPointToAddTo); //orphan extension if (extPoint.IsNull()) { registryObjects->AddOrphan(extensionPointToAddTo, extension); return QString(); } // otherwise, link them QList newExtensions = extPoint->GetRawChildren(); newExtensions.push_back(extension); Link(extPoint, newExtensions); if (!eventDelta.IsNull()) eventDelta.RememberExtension(extPoint, extension); return extPoint->GetNamespace(); //return RecordChange(extPoint, extension, ExtensionDelta::ADDED); } QString ExtensionRegistry::AddExtensionPoint(int extPoint) { ExtensionPoint::Pointer extensionPoint = registryObjects->GetObject(extPoint, RegistryObjectManager::EXTENSION_POINT).Cast(); if (!eventDelta.IsNull()) eventDelta.RememberExtensionPoint(extensionPoint); QList orphans = registryObjects->RemoveOrphans(extensionPoint->GetUniqueIdentifier()); if (orphans.empty()) return QString(); Link(extensionPoint, orphans); if (!eventDelta.IsNull()) eventDelta.RememberExtensions(extensionPoint, orphans); return extensionPoint->GetNamespace(); //return RecordChange(extensionPoint, orphans, ExtensionDelta::ADDED); } QSet ExtensionRegistry::AddExtensionsAndExtensionPoints(const SmartPointer& element) { // now add and resolve extensions and extension points QSet affectedNamespaces; QList extPoints = element->GetExtensionPoints(); for (int i = 0; i < extPoints.size(); i++) { QString namespaze = this->AddExtensionPoint(extPoints[i]); if (!namespaze.isEmpty()) affectedNamespaces.insert(namespaze); } QList extensions = element->GetExtensions(); for (int i = 0; i < extensions.size(); i++) { QString namespaze = this->AddExtension(extensions[i]); if (!namespaze.isEmpty()) affectedNamespaces.insert(namespaze); } return affectedNamespaces; } void ExtensionRegistry::AddListenerInternal(IRegistryEventListener* listener, const IExtensionPointFilter& filter) { listeners.Add(ListenerInfo(listener, filter)); } void ExtensionRegistry::BasicAdd(const SmartPointer& element, bool link) { registryObjects->AddContribution(element); if (!link) return; AddExtensionsAndExtensionPoints(element); SetObjectManagers(registryObjects->CreateDelegatingObjectManager( registryObjects->GetAssociatedObjects(element->GetContributorId()))); } void ExtensionRegistry::SetObjectManagers(const SmartPointer& manager) { if (!eventDelta.IsNull()) eventDelta.SetObjectManager(manager); } void ExtensionRegistry::BasicRemove(const QString& contributorId) { // ignore anonymous namespaces RemoveExtensionsAndExtensionPoints(contributorId); QHash associatedObjects = registryObjects->GetAssociatedObjects(contributorId); registryObjects->RemoveObjects(associatedObjects); registryObjects->AddNavigableObjects(associatedObjects); // put the complete set of navigable objects SetObjectManagers(registryObjects->CreateDelegatingObjectManager(associatedObjects)); registryObjects->RemoveContribution(contributorId); registryObjects->RemoveContributor(contributorId); } void ExtensionRegistry::FireRegistryChangeEvent() { // if there is nothing to say, just bail out if (listeners.IsEmpty()) { return; } // for thread safety, create tmp collections QList tmpListeners = listeners.GetListeners(); // do the notification asynchronously //strategy->ScheduleChangeEvent(tmpListeners, tmpDeltas, this); this->ScheduleChangeEvent(tmpListeners, eventDelta); } //RegistryDelta ExtensionRegistry::GetDelta(const QString& namespaze) const //{ // // is there a delta for the plug-in? // RegistryDelta existingDelta = deltas.value(namespaze); // if (existingDelta != null) // return existingDelta; // //if not, create one // RegistryDelta delta = new RegistryDelta(); // deltas.put(namespace, delta); // return delta; //} void ExtensionRegistry::Link(const SmartPointer& extPoint, const QList& extensions) { extPoint->SetRawChildren(extensions); registryObjects->Add(extPoint, true); } //QString ExtensionRegistry::RecordChange(const SmartPointer& extPoint, int extension, int kind) //{ // // avoid computing deltas when there are no listeners // if (listeners.isEmpty()) // return QString(); // ExtensionDelta extensionDelta = new ExtensionDelta(); // extensionDelta.setExtension(extension); // extensionDelta.setExtensionPoint(extPoint.getObjectId()); // extensionDelta.setKind(kind); // getDelta(extPoint.getNamespace()).addExtensionDelta(extensionDelta); // return extPoint.getNamespace(); //} //QString ExtensionRegistry::RecordChange(const SmartPointer& extPoint, const QList& extensions, int kind) //{ // if (listeners.isEmpty()) // return null; // QString namespace = extPoint.getNamespace(); // if (extensions == null || extensions.length == 0) // return namespace; // RegistryDelta pluginDelta = getDelta(extPoint.getNamespace()); // for (int i = 0; i < extensions.length; i++) { // ExtensionDelta extensionDelta = new ExtensionDelta(); // extensionDelta.setExtension(extensions[i]); // extensionDelta.setExtensionPoint(extPoint.getObjectId()); // extensionDelta.setKind(kind); // pluginDelta.addExtensionDelta(extensionDelta); // } // return namespace; //} QString ExtensionRegistry::RemoveExtension(int extensionId) { Extension::Pointer extension = registryObjects->GetObject(extensionId, RegistryObjectManager::EXTENSION).Cast(); registryObjects->RemoveExtensionFromNamespaceIndex(extensionId, extension->GetNamespaceIdentifier()); QString xptName = extension->GetExtensionPointIdentifier(); ExtensionPoint::Pointer extPoint = registryObjects->GetExtensionPointObject(xptName); if (extPoint.IsNull()) { registryObjects->RemoveOrphan(xptName, extensionId); return QString(); } // otherwise, unlink the extension from the extension point QList existingExtensions = extPoint->GetRawChildren(); QList newExtensions; if (existingExtensions.size() > 1) { for (int i = 0; i < existingExtensions.size(); ++i) if (existingExtensions[i] != extension->GetObjectId()) newExtensions.push_back(existingExtensions[i]); } Link(extPoint, newExtensions); if (!eventDelta.IsNull()) eventDelta.RememberExtension(extPoint, extensionId); return extPoint->GetNamespace(); //return recordChange(extPoint, extension.getObjectId(), IExtensionDelta.REMOVED); } QString ExtensionRegistry::RemoveExtensionPoint(int extPoint) { ExtensionPoint::Pointer extensionPoint = registryObjects->GetObject( extPoint, RegistryObjectManager::EXTENSION_POINT).Cast(); registryObjects->RemoveExtensionPointFromNamespaceIndex(extPoint, extensionPoint->GetNamespace()); QList existingExtensions = extensionPoint->GetRawChildren(); if (!existingExtensions.empty()) { registryObjects->AddOrphans(extensionPoint->GetUniqueIdentifier(), existingExtensions); Link(extensionPoint, QList()); } if (!eventDelta.IsNull()) { eventDelta.RememberExtensionPoint(extensionPoint); eventDelta.RememberExtensions(extensionPoint, existingExtensions); } return extensionPoint->GetNamespace(); //return recordChange(extensionPoint, existingExtensions, IExtensionDelta.REMOVED); } QSet ExtensionRegistry::RemoveExtensionsAndExtensionPoints(const QString& contributorId) { QSet affectedNamespaces; QList extensions = registryObjects->GetExtensionsFrom(contributorId); for (int i = 0; i < extensions.size(); i++) { QString namespaze = this->RemoveExtension(extensions[i]); if (!namespaze.isEmpty()) affectedNamespaces.insert(namespaze); } // remove extension points QList extPoints = registryObjects->GetExtensionPointsFrom(contributorId); for (int i = 0; i < extPoints.size(); i++) { QString namespaze = this->RemoveExtensionPoint(extPoints[i]); if (!namespaze.isEmpty()) affectedNamespaces.insert(namespaze); } return affectedNamespaces; } struct ExtensionRegistry::QueueElement { QList listenerInfos; CombinedEventDelta scheduledDelta; QueueElement() { } QueueElement(const QList& infos, const CombinedEventDelta& delta) : listenerInfos(infos), scheduledDelta(delta) { } }; class ExtensionRegistry::RegistryEventThread : public QThread { private: QAtomicInt stop; ExtensionRegistry* registry; Queue& queue; public: RegistryEventThread(ExtensionRegistry* registry, Queue& queue) : stop(0), registry(registry), queue(queue) { this->setObjectName("Extension Registry Event Dispatcher"); } void interrupt() { stop.fetchAndStoreOrdered(1); } void run() override { while (!stop.fetchAndAddOrdered(0)) { QueueElement element; { Queue::Locker l(&queue); while (queue.empty()) queue.wait(); element = queue.takeFirst(); } registry->ProcessChangeEvent(element.listenerInfos, element.scheduledDelta); } } }; bool ExtensionRegistry::CheckReadWriteAccess(QObject* key, bool persist) const { if (masterToken == key) return true; if (userToken == key && !persist) return true; return false; } void ExtensionRegistry::LogError(const QString& owner, const QString& contributionName, const ctkException& e) { QString message = QString("Could not parse XML contribution for \"%1\". Any contributed extensions " "and extension points will be ignored.").arg(QString(owner) + "/" + contributionName); IStatus::Pointer status(new Status(IStatus::ERROR_TYPE, RegistryMessages::OWNER_NAME, 0, message, e, BERRY_STATUS_LOC)); Log(status); } void ExtensionRegistry::CreateExtensionData(const QString& contributorId, const ConfigurationElementDescription& description, const SmartPointer& parent, bool persist) { ConfigurationElement::Pointer currentConfigurationElement = GetElementFactory()->CreateConfigurationElement(persist); currentConfigurationElement->SetContributorId(contributorId); currentConfigurationElement->SetName(description.GetName()); QList descriptionProperties = description.GetAttributes(); QList properties; if (!descriptionProperties.empty()) { for (int i = 0; i < descriptionProperties.size(); i++) { properties.push_back(descriptionProperties[i].GetName()); properties.push_back(Translate(descriptionProperties[i].GetValue(), nullptr)); } } currentConfigurationElement->SetProperties(properties); QString value = description.GetValue(); if (!value.isEmpty()) currentConfigurationElement->SetValue(value); GetObjectManager()->Add(currentConfigurationElement, true); // process children QList children = description.GetChildren(); if (!children.empty()) { for (int i = 0; i < children.size(); i++) { CreateExtensionData(contributorId, children[i], currentConfigurationElement, persist); } } QList newValues = parent->GetRawChildren(); newValues.push_back(currentConfigurationElement->GetObjectId()); parent->SetRawChildren(newValues); currentConfigurationElement->SetParentId(parent->GetObjectId()); currentConfigurationElement->SetParentType(parent.Cast() ? RegistryObjectManager::CONFIGURATION_ELEMENT : RegistryObjectManager::EXTENSION); } bool ExtensionRegistry::RemoveObject(const SmartPointer& registryObject, bool isExtensionPoint, QObject* token) { if (!CheckReadWriteAccess(token, registryObject->ShouldPersist())) throw ctkInvalidArgumentException("Unauthorized access to the ExtensionRegistry.removeExtension() method. Check if proper access token is supplied."); int id = registryObject->GetObjectId(); QWriteLocker l(&access); eventDelta = CombinedEventDelta::RecordRemoval(); if (isExtensionPoint) { RemoveExtensionPoint(id); } else { RemoveExtension(id); } QHash removed; removed.insert(id, registryObject); // There is some asymmetry between extension and extension point removal. Removing extension point makes // extensions "orphans" but does not remove them. As a result, only extensions needs to be processed. if (!isExtensionPoint) { registryObjects->AddAssociatedObjects(removed, registryObject); } registryObjects->RemoveObjects(removed); registryObjects->AddNavigableObjects(removed); IObjectManager::Pointer manager = registryObjects->CreateDelegatingObjectManager(removed); //GetDelta(namespaze)->SetObjectManager(manager); //eventDelta->SetObjectManager(manager); registryObjects->UnlinkChildFromContributions(id); FireRegistryChangeEvent(); eventDelta.Reset(); return true; } void ExtensionRegistry::SetFileManager(const QString& /*cacheBase*/, bool /*isCacheReadOnly*/) { // if (cacheStorageManager != nullptr) // cacheStorageManager->Close(); // close existing file manager first // if (cacheBase != null) { // cacheStorageManager = new StorageManager(cacheBase, isCacheReadOnly ? "none" : null, isCacheReadOnly); //$NON-NLS-1$ // try { // cacheStorageManager.open(!isCacheReadOnly); // } catch (IOException e) { // // Ignore the exception. The registry will be rebuilt from source. // } // } } void ExtensionRegistry::EnterRead() { access.lockForRead(); } void ExtensionRegistry::ExitRead() { access.unlock(); } void ExtensionRegistry::SetElementFactory() { if (isMultiLanguage) { throw ctkRuntimeException("Multi-language registry not supported yet."); //theRegistryObjectFactory = new RegistryObjectFactoryMulti(this); } else { theRegistryObjectFactory.reset(new RegistryObjectFactory(this)); } } //TableReader ExtensionRegistry::getTableReader() const //{ // return theTableReader; //} bool ExtensionRegistry::CheckCache() { // for (int index = 0; index < strategy.getLocationsLength(); index++) { // File possibleCacheLocation = strategy.getStorage(index); // if (possibleCacheLocation == null) // break; // bail out on the first null // setFileManager(possibleCacheLocation, strategy.isCacheReadOnly(index)); // if (cacheStorageManager != null) { // // check this new location: // File cacheFile = null; // try { // cacheFile = cacheStorageManager.lookup(TableReader.getTestFileName(), false); // } catch (IOException e) { // //Ignore the exception. The registry will be rebuilt from the xml files. // } // if (cacheFile != null && cacheFile.isFile()) // return true; // found the appropriate location // } // } return false; } void ExtensionRegistry::StopChangeEventScheduler() { if (!eventThread.isNull()) { Queue::Locker l(&queue); eventThread->interrupt(); eventThread->wait(); eventThread.reset(); } } SmartPointer ExtensionRegistry::GetObjectManager() const { return registryObjects; } void ExtensionRegistry::AddListener(IRegistryEventListener* listener, const QString& extensionPointId) { AddListenerInternal(listener, extensionPointId.isEmpty() ? IExtensionPointFilter(nullptr) : IExtensionPointFilter(new SimpleExtensionPointFilter(extensionPointId))); } void ExtensionRegistry::AddListener(IRegistryEventListener* listener, const IExtensionPointFilter& filter) { this->AddListenerInternal(listener, filter); } QList > ExtensionRegistry::GetConfigurationElementsFor(const QString& extensionPointId) const { // this is just a convenience API - no need to do any sync'ing here int lastdot = extensionPointId.lastIndexOf('.'); if (lastdot == -1) { QList(); } return GetConfigurationElementsFor(extensionPointId.left(lastdot), extensionPointId.mid(lastdot + 1)); } QList > ExtensionRegistry::GetConfigurationElementsFor(const QString& pluginId, const QString& extensionPointSimpleId) const { // this is just a convenience API - no need to do any sync'ing here IExtensionPoint::Pointer extPoint = this->GetExtensionPoint(pluginId, extensionPointSimpleId); if (extPoint.IsNull()) return QList(); return extPoint->GetConfigurationElements(); } QList > ExtensionRegistry::GetConfigurationElementsFor(const QString& pluginId, const QString& extensionPointName, const QString& extensionId) const { // this is just a convenience API - no need to do any sync'ing here IExtension::Pointer extension = this->GetExtension(pluginId, extensionPointName, extensionId); if (extension.IsNull()) return QList(); return extension->GetConfigurationElements(); } SmartPointer ExtensionRegistry::GetExtension(const QString& extensionId) const { if (extensionId.isEmpty()) return IExtension::Pointer(); int lastdot = extensionId.lastIndexOf('.'); if (lastdot == -1) return IExtension::Pointer(); QString namespaze = extensionId.left(lastdot); QList extensions; { QReadLocker l(&access); extensions = registryObjects->GetExtensionsFromNamespace(namespaze); } for (int i = 0; i < extensions.size(); i++) { ExtensionHandle::Pointer suspect = extensions[i]; if (extensionId == suspect->GetUniqueIdentifier()) return suspect; } return IExtension::Pointer(); } SmartPointer ExtensionRegistry::GetExtension(const QString& extensionPointId, const QString& extensionId) const { // this is just a convenience API - no need to do any sync'ing here int lastdot = extensionPointId.lastIndexOf('.'); if (lastdot == -1) return IExtension::Pointer(); return GetExtension(extensionPointId.left(lastdot), extensionPointId.mid(lastdot + 1), extensionId); } SmartPointer ExtensionRegistry::GetExtension(const QString& pluginId, const QString& extensionPointName, const QString& extensionId) const { // this is just a convenience API - no need to do any sync'ing here IExtensionPoint::Pointer extPoint = GetExtensionPoint(pluginId, extensionPointName); if (extPoint.IsNotNull()) return extPoint->GetExtension(extensionId); return IExtension::Pointer(); } SmartPointer ExtensionRegistry::GetExtensionPoint(const QString& xptUniqueId) const { QReadLocker l(&access); return registryObjects->GetExtensionPointHandle(xptUniqueId); } SmartPointer ExtensionRegistry::GetExtensionPoint(const QString& elementName, const QString& xpt) const { QReadLocker l(&access); return registryObjects->GetExtensionPointHandle(elementName + '.' + xpt); } QList > ExtensionRegistry::GetExtensionPoints() const { QList handles; { QReadLocker l(&access); handles = registryObjects->GetExtensionPointsHandles(); } QList result; foreach(ExtensionPointHandle::Pointer handle, handles) { result.push_back(handle); } return result; } QList > ExtensionRegistry::GetExtensionPoints(const QString& namespaceName) const { QList handles; { QReadLocker l(&access); handles = registryObjects->GetExtensionPointsFromNamespace(namespaceName); } QList result; foreach(ExtensionPointHandle::Pointer handle, handles) { result.push_back(handle); } return result; } QList > ExtensionRegistry::GetExtensions(const QString& namespaceName) const { QList handles; { QReadLocker l(&access); handles = registryObjects->GetExtensionsFromNamespace(namespaceName); } QList result; foreach (ExtensionHandle::Pointer handle, handles) { result.push_back(handle); } return result; } QList > ExtensionRegistry::GetExtensions(const SmartPointer& contributor) const { RegistryContributor::Pointer regContributor = contributor.Cast(); if (regContributor.IsNull()) throw ctkInvalidArgumentException("Contributor must be a RegistryContributor."); // should never happen QString contributorId = regContributor->GetActualId(); QList handles; { QReadLocker l(&access); handles = registryObjects->GetExtensionsFromContributor(contributorId); } QList result; foreach (ExtensionHandle::Pointer handle, handles) { result.push_back(handle); } return result; } QList > ExtensionRegistry::GetExtensionPoints(const SmartPointer& contributor) const { RegistryContributor::Pointer regContributor = contributor.Cast(); if (regContributor.IsNull()) throw ctkInvalidArgumentException("Contributor must be a RegistryContributor."); // should never happen QString contributorId = regContributor->GetActualId(); QList handles; { QReadLocker l(&access); handles = registryObjects->GetExtensionPointsFromContributor(contributorId); } QList result; foreach (ExtensionPointHandle::Pointer handle, handles) { result.push_back(handle); } return result; } QList ExtensionRegistry::GetNamespaces() const { QReadLocker l(&access); QList namespaceElements = registryObjects->GetNamespacesIndex().Elements(); QList namespaceNames; for (int i = 0; i < namespaceElements.size(); i++) { namespaceNames.push_back(namespaceElements[i]->GetKey()); } return namespaceNames; } bool ExtensionRegistry::HasContributor(const SmartPointer& contributor) const { RegistryContributor::Pointer regContributor = contributor.Cast(); if (regContributor.IsNull()) throw ctkInvalidArgumentException("Contributor must be a RegistryContributor."); // should never happen QString contributorId = regContributor->GetActualId(); return HasContributor(contributorId); } bool ExtensionRegistry::HasContributor(const QString& contributorId) const { QReadLocker l(&access); return registryObjects->HasContribution(contributorId); } void ExtensionRegistry::Remove(const QString& removedContributorId, long timestamp) { Remove(removedContributorId); if (timestamp != 0) aggregatedTimestamp.Remove(timestamp); } void ExtensionRegistry::RemoveContributor(const SmartPointer& contributor, QObject* key) { RegistryContributor::Pointer regContributor = contributor.Cast(); if (regContributor.IsNull()) throw ctkInvalidArgumentException("Contributor must be a RegistryContributor."); // should never happen if (!CheckReadWriteAccess(key, true)) throw ctkInvalidArgumentException("Unauthorized access to the ExtensionRegistry.removeContributor() method. Check if proper access token is supplied."); QString contributorId = regContributor->GetActualId(); Remove(contributorId); } void ExtensionRegistry::Remove(const QString& removedContributorId) { QWriteLocker l(&access); eventDelta = CombinedEventDelta::RecordRemoval(); BasicRemove(removedContributorId); FireRegistryChangeEvent(); eventDelta.Reset(); } void ExtensionRegistry::RemoveListener(IRegistryEventListener* listener) { listeners.Remove(ListenerInfo(listener, IExtensionPointFilter(nullptr))); } ExtensionRegistry::ExtensionRegistry(RegistryStrategy* registryStrategy, QObject* masterToken, QObject* userToken) : registryObjects(nullptr), isMultiLanguage(false), mlErrorLogged(false), eventThread(nullptr) { isMultiLanguage = RegistryProperties::GetProperty(RegistryConstants::PROP_REGISTRY_MULTI_LANGUAGE) == "true"; if (registryStrategy != nullptr) strategy.reset(registryStrategy); else strategy.reset(new RegistryStrategy(QList(), QList(), nullptr)); this->masterToken = masterToken; this->userToken = userToken; registryObjects = new RegistryObjectManager(this); bool isRegistryFilledFromCache = false; // indicates if registry was able to use cache to populate it's content if (strategy->CacheUse()) { // Try to read the registry from the cache first. If that fails, create a new registry QTime timer; if (Debug()) timer.start(); //The cache is made of several files, find the real names of these other files. If all files are found, try to initialize the objectManager if (CheckCache()) { // TODO Registry Cache // try { // theTableReader.setTableFile(cacheStorageManager.lookup(TableReader.TABLE, false)); // theTableReader.setExtraDataFile(cacheStorageManager.lookup(TableReader.EXTRA, false)); // theTableReader.setMainDataFile(cacheStorageManager.lookup(TableReader.MAIN, false)); // theTableReader.setContributionsFile(cacheStorageManager.lookup(TableReader.CONTRIBUTIONS, false)); // theTableReader.setContributorsFile(cacheStorageManager.lookup(TableReader.CONTRIBUTORS, false)); // theTableReader.setNamespacesFile(cacheStorageManager.lookup(TableReader.NAMESPACES, false)); // theTableReader.setOrphansFile(cacheStorageManager.lookup(TableReader.ORPHANS, false)); // long timestamp = strategy.getContributionsTimestamp(); // isRegistryFilledFromCache = registryObjects.init(timestamp); // if (isRegistryFilledFromCache) // aggregatedTimestamp.set(timestamp); // } catch (IOException e) { // // The registry will be rebuilt from the xml files. Make sure to clear anything filled // // from cache so that we won't have partially filled items. // isRegistryFilledFromCache = false; // clearRegistryCache(); // log(new Status(IStatus.ERROR, RegistryMessages.OWNER_NAME, 0, RegistryMessages.registry_bad_cache, e)); // } } // if (!isRegistryFilledFromCache) // { // // set cache storage manager to a first writable location // for (int index = 0; index < strategy.getLocationsLength(); index++) { // if (!strategy.isCacheReadOnly(index)) { // setFileManager(strategy.getStorage(index), false); // break; // } // } // } if (Debug() && isRegistryFilledFromCache) BERRY_INFO << "Reading registry cache: " << timer.elapsed() << "ms"; if (Debug()) { if (!isRegistryFilledFromCache) BERRY_INFO << "Reloading registry from manifest files..."; else BERRY_INFO << "Using registry cache..."; } } if (DebugEvents()) { struct DebugRegistryListener : public IRegistryEventListener { void Added(const QList& extensions) override { BERRY_INFO << "Registry extensions ADDED:"; foreach(IExtension::Pointer extension, extensions) { BERRY_INFO << "\t" << extension->GetExtensionPointUniqueIdentifier() << " - " << extension->GetNamespaceIdentifier() << "." << extension->GetSimpleIdentifier(); } } void Removed(const QList& extensions) override { BERRY_INFO << "Registry extensions REMOVED:"; foreach(IExtension::Pointer extension, extensions) { BERRY_INFO << "\t" << extension->GetExtensionPointUniqueIdentifier() << " - " << extension->GetNamespaceIdentifier() << "." << extension->GetSimpleIdentifier(); } } void Added(const QList& extensionPoints) override { BERRY_INFO << "Registry extension-points ADDED:"; foreach(IExtensionPoint::Pointer extensionPoint, extensionPoints) { BERRY_INFO << "\t" << extensionPoint->GetUniqueIdentifier(); } } void Removed(const QList& extensionPoints) override { BERRY_INFO << "Registry extension-points REMOVED:"; foreach(IExtensionPoint::Pointer extensionPoint, extensionPoints) { BERRY_INFO << "\t" << extensionPoint->GetUniqueIdentifier(); } } }; debugRegistryListener.reset(new DebugRegistryListener()); AddListener(debugRegistryListener.data()); } // Do extra start processing if specified in the registry strategy strategy->OnStart(this, isRegistryFilledFromCache); } ExtensionRegistry::~ExtensionRegistry() { } void ExtensionRegistry::Stop(QObject* /*key*/) { // If the registry creator specified a key token, check that the key mathches it - // (it is assumed that registry owner keeps the key to prevent unautorized accesss). + // (it is assumed that registry owner keeps the key to prevent unautorized access). if (masterToken != nullptr && masterToken != nullptr) { throw ctkInvalidArgumentException("Unauthorized access to the ExtensionRegistry.stop() method. Check if proper access token is supplied."); //$NON-NLS-1$ } // Do extra stop processing if specified in the registry strategy strategy->OnStop(this); StopChangeEventScheduler(); // if (cacheStorageManager == nullptr) // return; // if (!registryObjects.isDirty() || cacheStorageManager.isReadOnly()) { // cacheStorageManager.close(); // theTableReader.close(); // return; // } // File tableFile = null; // File mainFile = null; // File extraFile = null; // File contributionsFile = null; // File contributorsFile = null; // File namespacesFile = null; // File orphansFile = null; // TableWriter theTableWriter = new TableWriter(this); // try { // cacheStorageManager.lookup(TableReader.TABLE, true); // cacheStorageManager.lookup(TableReader.MAIN, true); // cacheStorageManager.lookup(TableReader.EXTRA, true); // cacheStorageManager.lookup(TableReader.CONTRIBUTIONS, true); // cacheStorageManager.lookup(TableReader.CONTRIBUTORS, true); // cacheStorageManager.lookup(TableReader.NAMESPACES, true); // cacheStorageManager.lookup(TableReader.ORPHANS, true); // tableFile = File.createTempFile(TableReader.TABLE, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // mainFile = File.createTempFile(TableReader.MAIN, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // extraFile = File.createTempFile(TableReader.EXTRA, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // contributionsFile = File.createTempFile(TableReader.CONTRIBUTIONS, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // contributorsFile = File.createTempFile(TableReader.CONTRIBUTORS, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // namespacesFile = File.createTempFile(TableReader.NAMESPACES, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // orphansFile = File.createTempFile(TableReader.ORPHANS, ".new", cacheStorageManager.getBase()); //$NON-NLS-1$ // theTableWriter.setTableFile(tableFile); // theTableWriter.setExtraDataFile(extraFile); // theTableWriter.setMainDataFile(mainFile); // theTableWriter.setContributionsFile(contributionsFile); // theTableWriter.setContributorsFile(contributorsFile); // theTableWriter.setNamespacesFile(namespacesFile); // theTableWriter.setOrphansFile(orphansFile); // } catch (IOException e) { // cacheStorageManager.close(); // return; //Ignore the exception since we can recompute the cache // } // try { // long timestamp; // // A bit of backward compatibility: if registry was modified, but timestamp was not, // // it means that the new timestamp tracking mechanism was not used. In this case // // explicitly obtain timestamps for all contributions. Note that this logic // // maintains a problem described in the bug 104267 for contributions that // // don't use the timestamp tracking mechanism. // if (aggregatedTimestamp.isModifed()) // timestamp = aggregatedTimestamp.getContentsTimestamp(); // use timestamp tracking // else // timestamp = strategy.getContributionsTimestamp(); // use legacy approach // if (theTableWriter.saveCache(registryObjects, timestamp)) // cacheStorageManager.update(new QString[] {TableReader.TABLE, TableReader.MAIN, TableReader.EXTRA, TableReader.CONTRIBUTIONS, TableReader.CONTRIBUTORS, TableReader.NAMESPACES, TableReader.ORPHANS}, new QString[] {tableFile.getName(), mainFile.getName(), extraFile.getName(), contributionsFile.getName(), contributorsFile.getName(), namespacesFile.getName(), orphansFile.getName()}); // } catch (IOException e) { // //Ignore the exception since we can recompute the cache // } // theTableReader.close(); // cacheStorageManager.close(); } void ExtensionRegistry::ClearRegistryCache() { // QString[] keys = new QString[] {TableReader.TABLE, TableReader.MAIN, TableReader.EXTRA, TableReader.CONTRIBUTIONS, TableReader.ORPHANS}; // for (int i = 0; i < keys.length; i++) // try { // cacheStorageManager.remove(keys[i]); // } catch (IOException e) { // log(new Status(IStatus.ERROR, RegistryMessages.OWNER_NAME, IStatus.ERROR, RegistryMessages.meta_registryCacheReadProblems, e)); // } aggregatedTimestamp.Reset(); } RegistryObjectFactory* ExtensionRegistry::GetElementFactory() { if (theRegistryObjectFactory.isNull()) SetElementFactory(); return theRegistryObjectFactory.data(); } void ExtensionRegistry::Log(const SmartPointer& status) const { strategy->Log(status); } QString ExtensionRegistry::Translate(const QString& key, QTranslator* resources) const { if (isMultiLanguage) return key; return strategy->Translate(key, resources); } bool ExtensionRegistry::Debug() const { return strategy->Debug(); } bool ExtensionRegistry::DebugEvents() const { return strategy->DebugRegistryEvents(); } bool ExtensionRegistry::UseLazyCacheLoading() const { return strategy->CacheLazyLoading(); } long ExtensionRegistry::ComputeState() const { return strategy->GetContainerTimestamp(); } QObject* ExtensionRegistry::CreateExecutableExtension(const SmartPointer& defaultContributor, const QString& className, const QString& requestedContributorName) { return strategy->CreateExecutableExtension(defaultContributor, className, requestedContributorName); } void ExtensionRegistry::ProcessChangeEvent( const QList& listenerInfos, const CombinedEventDelta& scheduledDelta) { for (int i = 0; i < listenerInfos.size(); i++) { const ListenerInfo& listenerInfo = listenerInfos[i]; IRegistryEventListener* extensionListener = listenerInfo.listener; QList extensions = scheduledDelta.GetExtensions(listenerInfo.filter); QList extensionPoints = scheduledDelta.GetExtensionPoints(listenerInfo.filter); // notification order - on addition: extension points; then extensions if (scheduledDelta.IsAddition()) { if (!extensionPoints.empty()) extensionListener->Added(extensionPoints); if (!extensions.empty()) extensionListener->Added(extensions); } else { // on removal: extensions; then extension points if (!extensions.empty()) extensionListener->Removed(extensions); if (!extensionPoints.empty()) extensionListener->Removed(extensionPoints); } } IObjectManager::Pointer manager = scheduledDelta.GetObjectManager(); if (manager.IsNotNull()) manager->Close(); } void ExtensionRegistry::ScheduleChangeEvent(const QList& listenerInfos, const CombinedEventDelta& scheduledDelta) { QueueElement newElement(listenerInfos, scheduledDelta); if (eventThread.isNull()) { eventThread.reset(new RegistryEventThread(this, queue)); eventThread->start(); } { Queue::Locker l(&queue); queue.push_back(newElement); queue.notify(); } } bool ExtensionRegistry::AddContribution(QIODevice* is, const SmartPointer& contributor, bool persist, const QString& contributionName, QTranslator* translationBundle, QObject* key, long timestamp) { bool result = AddContribution(is, contributor, persist, contributionName, translationBundle, key); if (timestamp != 0) aggregatedTimestamp.Add(timestamp); return result; } bool ExtensionRegistry::AddContribution(QIODevice* is, const SmartPointer& contributor, bool persist, const QString& contributionName, QTranslator* translationBundle, QObject* key) { if (!CheckReadWriteAccess(key, persist)) throw ctkInvalidArgumentException("Unauthorized access to the ExtensionRegistry::AddContribution() method. Check if proper access token is supplied."); RegistryContributor::Pointer internalContributor = contributor.Cast(); registryObjects->AddContributor(internalContributor); // only adds a contributor if it is not already present QString ownerName = internalContributor->GetActualName(); QString message = QString("Problems parsing plug-in manifest for: \"%1\".").arg(ownerName); MultiStatus::Pointer problems(new MultiStatus(RegistryMessages::OWNER_NAME, ExtensionsParser::PARSE_PROBLEM, message, BERRY_STATUS_LOC)); ExtensionsParser parser(problems, this); RegistryContribution::Pointer contribution = GetElementFactory()->CreateContribution(internalContributor->GetActualId(), persist); try { QXmlInputSource xmlInput(is); bool success = parser.parseManifest(strategy->GetXMLParser(), &xmlInput, contributionName, GetObjectManager().GetPointer(), contribution, translationBundle); int status = problems->GetSeverity(); if (status != IStatus::OK_TYPE || !success) { Log(problems); if (status == IStatus::ERROR_TYPE || status == IStatus::CANCEL_TYPE || !success) return false; } } catch (const ctkException& e) { LogError(ownerName, contributionName, e); return false; } Add(contribution); // the add() method does synchronization return true; } bool ExtensionRegistry::AddExtensionPoint(const QString& identifier, const SmartPointer& contributor, bool persist, const QString& label, const QString& schemaReference, QObject* token) { if (!CheckReadWriteAccess(token, persist)) throw ctkInvalidArgumentException("Unauthorized access to the ExtensionRegistry::AddExtensionPoint() method. Check if proper access token is supplied."); RegistryContributor::Pointer internalContributor = contributor.Cast(); registryObjects->AddContributor(internalContributor); // only adds a contributor if it is not already present QString contributorId = internalContributor->GetActualId(); // Extension point Id might not be null if (identifier.isEmpty()) { QString message = QString("Missing ID for the extension point \"%1\". Element ignored.").arg(label); IStatus::Pointer status(new Status(IStatus::ERROR_TYPE, RegistryMessages::OWNER_NAME, 0, message, BERRY_STATUS_LOC)); Log(status); } // addition wraps in a contribution RegistryContribution::Pointer contribution = GetElementFactory()->CreateContribution(contributorId, persist); ExtensionPoint::Pointer currentExtPoint = GetElementFactory()->CreateExtensionPoint(persist); QString uniqueId; QString namespaceName; int simpleIdStart = identifier.lastIndexOf('.'); if (simpleIdStart == -1) { namespaceName = contribution->GetDefaultNamespace(); uniqueId = namespaceName + '.' + identifier; } else { namespaceName = identifier.left(simpleIdStart); uniqueId = identifier; } currentExtPoint->SetUniqueIdentifier(uniqueId); currentExtPoint->SetNamespace(namespaceName); QString labelNLS = Translate(label, nullptr); currentExtPoint->SetLabel(labelNLS); currentExtPoint->SetSchema(schemaReference); if (!GetObjectManager()->AddExtensionPoint(currentExtPoint, true)) { if (Debug()) { QString msg = QString("Ignored duplicate extension point \"%1\" supplied by \"%2\".").arg(uniqueId).arg(contribution->GetDefaultNamespace()); IStatus::Pointer status(new Status(IStatus::ERROR_TYPE, RegistryMessages::OWNER_NAME, 0, msg, BERRY_STATUS_LOC)); Log(status); } return false; } currentExtPoint->SetContributorId(contributorId); // array format: {Number of extension points, Number of extensions, Extension Id} QList contributionChildren; // Put the extension points into this namespace contributionChildren.push_back(1); contributionChildren.push_back(0); contributionChildren.push_back(currentExtPoint->GetObjectId()); contribution->SetRawChildren(contributionChildren); Add(contribution); return true; } bool ExtensionRegistry::AddExtension(const QString& identifier, const SmartPointer& contributor, bool persist, const QString& label, const QString& extensionPointId, const ConfigurationElementDescription& configurationElements, QObject* token) { if (!CheckReadWriteAccess(token, persist)) throw ctkInvalidArgumentException("Unauthorized access to the ExtensionRegistry::AddExtensionPoint() method. Check if proper access token is supplied."); // prepare namespace information RegistryContributor::Pointer internalContributor = contributor.Cast(); registryObjects->AddContributor(internalContributor); // only adds a contributor if it is not already present QString contributorId = internalContributor->GetActualId(); // addition wraps in a contribution RegistryContribution::Pointer contribution = GetElementFactory()->CreateContribution(contributorId, persist); Extension::Pointer currentExtension = GetElementFactory()->CreateExtension(persist); QString simpleId; QString namespaceName; int simpleIdStart = identifier.lastIndexOf('.'); if (simpleIdStart != -1) { simpleId = identifier.mid(simpleIdStart + 1); namespaceName = identifier.left(simpleIdStart); } else { simpleId = identifier; namespaceName = contribution->GetDefaultNamespace(); } currentExtension->SetSimpleIdentifier(simpleId); currentExtension->SetNamespaceIdentifier(namespaceName); QString extensionLabelNLS = Translate(label, nullptr); currentExtension->SetLabel(extensionLabelNLS); QString targetExtensionPointId; if (extensionPointId.indexOf('.') == -1) // No dots -> namespace name added at the start targetExtensionPointId = contribution->GetDefaultNamespace() + '.' + extensionPointId; else targetExtensionPointId = extensionPointId; currentExtension->SetExtensionPointIdentifier(targetExtensionPointId); // if we have an Id specified, check for duplicates. Only issue warning if duplicate found // as it might still work fine - depending on the access pattern. if (!simpleId.isNull() && Debug()) { QString uniqueId = namespaceName + '.' + simpleId; IExtension::Pointer existingExtension = GetExtension(uniqueId); if (existingExtension.IsNotNull()) { QString currentSupplier = contribution->GetDefaultNamespace(); QString existingSupplier = existingExtension->GetContributor()->GetName(); QString msg = QString("Extensions supplied by \"%1\" and \"%2\" have the same Id: \"%3\".") .arg(currentSupplier).arg(existingSupplier).arg(uniqueId); IStatus::Pointer status(new Status(IStatus::WARNING_TYPE, RegistryMessages::OWNER_NAME, 0, msg, BERRY_STATUS_LOC)); Log(status); return false; } } GetObjectManager()->Add(currentExtension, true); CreateExtensionData(contributorId, configurationElements, currentExtension, persist); currentExtension->SetContributorId(contributorId); QList contributionChildren; contributionChildren.push_back(0); contributionChildren.push_back(1); contributionChildren.push_back(currentExtension->GetObjectId()); contribution->SetRawChildren(contributionChildren); Add(contribution); return true; } bool ExtensionRegistry::RemoveExtension(const SmartPointer& extension, QObject* token) { ExtensionHandle::Pointer handle = extension.Cast(); if (handle.IsNull()) return false; return RemoveObject(handle->GetObject(), false, token); } bool ExtensionRegistry::RemoveExtensionPoint(const SmartPointer& extensionPoint, QObject* token) { ExtensionPointHandle::Pointer handle = extensionPoint.Cast(); if (handle.IsNull()) return false; return RemoveObject(handle->GetObject(), true, token); } QList > ExtensionRegistry::GetAllContributors() const { QList result; QReadLocker l(&access); foreach(RegistryContributor::Pointer contributor, registryObjects->GetContributors().values()) { result.push_back(contributor); } return result; } bool ExtensionRegistry::IsMultiLanguage() const { return isMultiLanguage; } QList ExtensionRegistry::Translate(const QList& nonTranslated, const SmartPointer& contributor, const QLocale& locale) const { return strategy->Translate(nonTranslated, contributor, locale); } QLocale ExtensionRegistry::GetLocale() const { return strategy->GetLocale(); } void ExtensionRegistry::LogMultiLangError() const { if (mlErrorLogged) // only log this error ones return; IStatus::Pointer status(new Status(IStatus::ERROR_TYPE, RegistryMessages::OWNER_NAME, 0, QString("The requested multi-language operation is not enabled. See runtime option \"") + RegistryConstants::PROP_REGISTRY_MULTI_LANGUAGE + "\".", ctkInvalidArgumentException(""), BERRY_STATUS_LOC)); Log(status); mlErrorLogged = true; } } diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryContributor.h b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryContributor.h index 2e27c93a20..2ffe88e19b 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryContributor.h +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryContributor.h @@ -1,139 +1,139 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYREGISTRYCONTRIBUTOR_H #define BERRYREGISTRYCONTRIBUTOR_H #include "berryIContributor.h" namespace berry { /** * This class describes a registry contributor which is an entity that supplies information * to the extension registry. Depending on the registry strategy, contributor might delegate * some of its functionality to a "host" contributor. For instance, OSGi registry strategy * uses "host" contributor to delegate some functionality from fragments to plug-ins. *

* This class can be instantiated by the registry Service Providers. *

* This class is not intended to be extended. *

* Note: This class/interface is part of an interim API that is still under * development and expected to change significantly before reaching stability. * It is being made available at this early stage to solicit feedback from pioneering * adopters on the understanding that any code that uses this API will almost certainly * be broken (repeatedly) as the API evolves. *

* @noextend This class is not intended to be subclassed by clients. */ class RegistryContributor : public IContributor { private: /** * Actual ID of the contributor (e.g., "12"). IDs are expected to be unique in the workspace. */ QString actualContributorId; /** * Actual name of the contributor (e.g., "org.eclipse.core.runtime.fragment"). */ QString actualContributorName; /** * ID associated with the entity "in charge" of the contributor (e.g., "1"). IDs are expected * to be unique in the workspace. If contributor does not rely on a host, this value should be * the same as the actual contributor ID. */ QString hostId; /** * Name of the entity "in charge" of the contributor (e.g. "org.eclipse.core.runtime"). * If contributor does not rely on a host, this value should be the same as the actual * contributor name. */ QString hostName; public: berryObjectMacro(berry::RegistryContributor); /** * Constructor for the registry contributor. *

* The actual ID is a string identifier for the contributor (e.g., "12") and is expected * to be unique within the workspace. The actual ID of the contributor must not * be null. *

* The actual name is the name associated with the contributor * (e.g., "org.eclipse.core.runtime.fragment"). The actual name of the contributor must * not be null. *

* The host ID is the identifier associated with the entity "in charge" of the contributor * (e.g., "1"). IDs are expected to be unique in the workspace. If contributor does not * rely on a host, then null should be used as the host ID. *

* The host name is the name of the entity "in charge" of the contributor * (e.g., "org.eclipse.core.runtime"). If contributor does not rely on a host, then * null should be used as the host name. *

- * There should be 1-to-1 mapping between the contributor and the contibutor ID. + * There should be 1-to-1 mapping between the contributor and the contributor ID. * The IDs (either actual or host) can not be re-used in the same registry. * For example, if ID of 12 was used to identify contributorA, the ID of 12 can not * be used to identify contributorB or a host for the contributorC. *

* @param actualId contributor identifier * @param actualName name of the contributor * @param hostId id associated with the host, or null * @param hostName name of the host, or null */ RegistryContributor(const QString& actualId, const QString& actualName, const QString& hostId, const QString& hostName); /** * Provides actual ID associated with the registry contributor (e.g., "12"). IDs are expected * to be unique in the workspace. * * @return actual ID of the registry contributor */ QString GetActualId() const; /** * Provides actual name of the registry contributor (e.g., "org.eclipe.core.runtime.fragment"). * * @return actual name of the registry contributor */ QString GetActualName() const; /** * Provides ID associated with the entity "in charge" of the contributor (e.g., "1"). IDs are expected * to be unique in the workspace. If contributor does not rely on a host, this value should be * the same as the actual contributor ID. * * @return id of the registry contributor */ QString GetId() const; /** * Provides name of the entity "in charge" of the contributor (e.g., "org.eclipse.core.runtime"). * If contributor does not rely on a host, this value should be the same as the actual contributor name. * * @return name of the registry contributor */ QString GetName() const override; }; } #endif // BERRYREGISTRYCONTRIBUTOR_H diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.cpp b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.cpp index 3a5f23ef26..402bf7a6ed 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.cpp +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.cpp @@ -1,119 +1,119 @@ /*============================================================================ 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 "berryRegistryObject.h" #include "berryExtensionRegistry.h" #include "berryRegistryObjectManager.h" namespace berry { // it is assumed that int has 32 bits (bits #0 to #31); // bits #0 - #29 are the offset (limited to about 1Gb) -// bit #30 - persistance flag +// bit #30 - persistence flag // bit #31 - registry object has no extra data offset // the bit#31 is a sign bit; bit#30 is the highest mantissa bit const int RegistryObject::EMPTY_MASK = 0x80000000; // only taking bit #31 const int RegistryObject::PERSIST_MASK = 0x40000000; // only taking bit #30 const int RegistryObject::OFFSET_MASK = 0x3FFFFFFF; // all bits but #30, #31 RegistryObject::RegistryObject() : registry(nullptr), objectId(RegistryObjectManager::UNKNOWN), extraDataOffset(EMPTY_MASK) { objectKey = QString::number(objectId); } QString RegistryObject::GetKey() const { return objectKey; } bool RegistryObject::IsEqual(const KeyedElement& other) const { return objectId == static_cast(other).objectId; } RegistryObject::RegistryObject(ExtensionRegistry* registry, bool persist) : registry(registry), objectId(RegistryObjectManager::UNKNOWN), extraDataOffset(EMPTY_MASK) { objectKey = QString::number(objectId); SetPersist(persist); } void RegistryObject::SetRawChildren(const QList& values) { children = values; } QList RegistryObject::GetRawChildren() const { return children; } void RegistryObject::SetObjectId(int value) { objectId = value; objectKey = QString::number(value); } int RegistryObject::GetObjectId() const { return objectId; } bool RegistryObject::ShouldPersist() const { return (extraDataOffset & PERSIST_MASK) == PERSIST_MASK; } bool RegistryObject::NoExtraData() const { return (extraDataOffset & EMPTY_MASK) == EMPTY_MASK; } int RegistryObject::GetExtraDataOffset() const { if (NoExtraData()) return -1; return extraDataOffset & OFFSET_MASK; } void RegistryObject::SetExtraDataOffset(int offset) { if (offset == -1) { extraDataOffset &= ~OFFSET_MASK; // clear all offset bits extraDataOffset |= EMPTY_MASK; return; } if ((offset & OFFSET_MASK) != offset) throw ctkInvalidArgumentException("Registry object: extra data offset is out of range"); extraDataOffset &= ~(OFFSET_MASK | EMPTY_MASK); // clear all offset bits; mark as non-empty extraDataOffset |= (offset & OFFSET_MASK); // set all offset bits } QLocale RegistryObject::GetLocale() const { return registry->GetLocale(); } void RegistryObject::SetPersist(bool persist) { if (persist) extraDataOffset |= PERSIST_MASK; else extraDataOffset &= ~PERSIST_MASK; } } diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.h b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.h index 2158df3d03..aecc42ad76 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.h +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObject.h @@ -1,98 +1,98 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYREGISTRYOBJECT_H #define BERRYREGISTRYOBJECT_H #include "berryKeyedElement.h" namespace berry { class ExtensionRegistry; /** * An object which has the general characteristics of all the nestable elements * in a plug-in manifest. */ class RegistryObject : public KeyedElement { public: berryObjectMacro(berry::RegistryObject); RegistryObject(); //Implementation of the KeyedElement interface QString GetKey() const override; int GetObjectId() const; //This can not return null. It returns the singleton empty array or an array QList GetRawChildren() const; bool NoExtraData() const; protected: friend class RegistryObjectManager; friend class ExtensionRegistry; friend class ExtensionsParser; QList children; // it is assumed that int has 32 bits (bits #0 to #31); // bits #0 - #29 are the offset (limited to about 1Gb) - // bit #30 - persistance flag + // bit #30 - persistence flag // bit #31 - registry object has no extra data offset // the bit#31 is a sign bit; bit#30 is the highest mantissa bit static const int EMPTY_MASK; // = 0x80000000; // only taking bit #31 static const int PERSIST_MASK; // = 0x40000000; // only taking bit #30 static const int OFFSET_MASK; // = 0x3FFFFFFF; // all bits but #30, #31 //The registry that owns this object ExtensionRegistry* registry; RegistryObject(ExtensionRegistry* registry, bool persist); void SetRawChildren(const QList& values); void SetObjectId(int value); bool ShouldPersist() const; // Convert no extra data to -1 on output int GetExtraDataOffset() const; // Accept -1 as "no extra data" on input void SetExtraDataOffset(int offset); QLocale GetLocale() const; private: //Object identifier uint objectId; // = RegistryObjectManager::UNKNOWN; // The key QString objectKey; // The field combines offset, persistence flag, and no offset flag int extraDataOffset; // = EMPTY_MASK; void SetPersist(bool persist); bool IsEqual(const KeyedElement& other) const override; }; } #endif // BERRYREGISTRYOBJECT_H diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectManager.h b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectManager.h index f962c2496f..566231a86a 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectManager.h +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectManager.h @@ -1,281 +1,281 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYREGISTRYOBJECTMANAGER_H #define BERRYREGISTRYOBJECTMANAGER_H #include "berryIObjectManager.h" #include "berryHashtableOfStringAndInt.h" #include "berryKeyedHashSet.h" #include namespace berry { class ExtensionHandle; class ExtensionPoint; class ExtensionPointHandle; class ExtensionRegistry; class RegistryContribution; class RegistryContributor; class RegistryIndexElement; class RegistryObject; class RegistryObjectReferenceMap; /** * This class manage all the object from the registry but does not deal with their dependencies. * It serves the objects which are either directly obtained from memory or read from a cache. * It also returns handles for objects. */ class RegistryObjectManager : public IObjectManager { public: berryObjectMacro(berry::RegistryObjectManager); //Constants used to get the objects and their handles enum Type { CONFIGURATION_ELEMENT = 1, EXTENSION, EXTENSION_POINT, THIRDLEVEL_CONFIGURATION_ELEMENT }; RegistryObjectManager(ExtensionRegistry* registry); ~RegistryObjectManager() override; void Add(const SmartPointer& registryObject, bool hold); SmartPointer GetObject(int id, short type) const override; - // The current impementation of this method assumes that we don't cache dynamic + // The current implementation of this method assumes that we don't cache dynamic // extension. In this case all extensions not yet loaded (i.e. not in the memory cache) // are "not dynamic" and we actually check memory objects to see if they are dynamic. // // If we decide to allow caching of dynamic objects, the implementation // of this method would have to retrieved the object from disk and check // its "dynamic" status. The problem is that id alone is not enough to get the object // from the disk; object type is needed as well. bool ShouldPersist(int id) const; QList > GetObjects(const QList& values, short type) const override; SmartPointer GetHandle(int id, short type) const override; QList > GetHandles(const QList& ids, short type) const override; bool IsDirty() const; void MarkDirty(); void Close() override; ExtensionRegistry* GetRegistry() const; QList > GetExtensionsFromContributor(const QString& contributorId) const; QList > GetExtensionPointsFromContributor(const QString& contributorId) const; QList > GetExtensionPointsFromNamespace(const QString& namespaceName) const; // This method filters out extensions with no extension point QList > GetExtensionsFromNamespace(const QString& namespaceName) const; SmartPointer GetContributor(const QString& id) const; protected: friend class Extension; friend class ExtensionPoint; friend class ExtensionRegistry; friend class ExtensionsParser; friend class RegistryContribution; friend class RegistryObject; mutable QMutex mutex; static const int CACHE_INITIAL_SIZE; // = 512; static int UNKNOWN; typedef QHash > OrphansMapType; typedef QHash > ContributorsMapType; /** * Initialize the object manager. Return true if the initialization succeeded, false otherwise */ bool Init(long timeStamp); void AddContribution(const SmartPointer& contribution); QList GetExtensionPointsFrom(const QString& id) const; QList GetExtensionPointsFrom_unlocked(const QString& id) const; bool HasContribution(const QString& id) const; void Remove(int id, bool release); void Remove_unlocked(int id, bool release); QList > GetObjects_unlocked(const QList& values, short type) const; SmartPointer GetExtensionPointObject(const QString& xptUniqueId) const; SmartPointer GetExtensionPointObject_unlocked(const QString& xptUniqueId) const; QList > GetExtensionPointsHandles() const; SmartPointer GetExtensionPointHandle(const QString& xptUniqueId); QList GetExtensionsFrom(const QString& contributorId) const; QList GetExtensionsFrom_unlocked(const QString& contributorId) const; bool AddExtensionPoint(const SmartPointer& currentExtPoint, bool hold); void RemoveExtensionPoint(const QString& extensionPointId); void RemoveContribution(const QString &contributorId); void AddOrphans(const QString& extensionPoint, const QList& extensions); void AddOrphan(const QString& extensionPoint, int extension); QList RemoveOrphans(const QString& extensionPoint); void RemoveOrphan(const QString& extensionPoint, int extension); //This method is only used by the writer to reach in QHash > GetOrphanExtensions() const; // This method is only used by the writer to reach in int GetNextId() const; // This method is only used by the writer to reach in HashtableOfStringAndInt GetExtensionPoints() const; // This method is only used by the writer to reach in QList GetContributions() const; // This method is used internally and by the writer to reach in. Notice that it doesn't // return contributors marked as removed. ContributorsMapType& GetContributors() const; // only adds a contributor if it is not already present in the table void AddContributor(const SmartPointer& newContributor); void RemoveContributor(const QString& id); KeyedHashSet& GetNamespacesIndex() const; /** * Collect all the objects that are removed by this operation and store * them in a IObjectManager so that they can be accessed from the appropriate * deltas but not from the registry. */ QHash > GetAssociatedObjects(const QString& contributionId) const; /** * Adds elements to be removed along with the registry object. */ void AddAssociatedObjects(QHash >& map, const SmartPointer& registryObject); /** * Add to the set of the objects all extensions and extension points that * could be navigated to from the objects in the set. */ void AddNavigableObjects(QHash >& associatedObjects); void RemoveObjects(const QHash >& associatedObjects); SmartPointer CreateDelegatingObjectManager(const QHash >& object); bool UnlinkChildFromContributions(int id); private: // key: extensionPointName, value: object id HashtableOfStringAndInt extensionPoints; //This is loaded on startup. Then entries can be added when loading a new plugin from the xml. // key: object id, value: an object RegistryObjectReferenceMap* cache; //Entries are added by getter. The structure is not thread safe. //key: int, value: int //OffsetTable fileOffsets = null; //This is read once on startup when loading from the cache. Entries are never added here. They are only removed to prevent "removed" objects to be reloaded. int nextId; //This is only used to get the next number available. mutable bool orphanExtensionsLoaded; //Those two data structures are only used when the addition or the removal of a plugin occurs. //They are used to keep track on a contributor basis of the extension being added or removed - KeyedHashSet newContributions; //represents the contributers added during this session. - mutable KeyedHashSet formerContributions; //represents the contributers encountered in previous sessions. This is loaded lazily. + KeyedHashSet newContributions; //represents the contributors added during this session. + mutable KeyedHashSet formerContributions; //represents the contributors encountered in previous sessions. This is loaded lazily. mutable bool formerContributionsLoaded; mutable QHash > contributors; // key: contributor ID; value: contributor name mutable bool contributorsLoaded; QHash > removedContributors; // key: contributor ID; value: contributor name mutable KeyedHashSet namespacesIndex; // registry elements (extension & extensionpoints) indexed by namespaces mutable bool namespacesIndexLoaded; // Map key: extensionPointFullyQualifiedName, value int[] of orphan extensions. // The orphan access does not need to be synchronized because the it is protected by the lock in extension registry. mutable QHash > orphanExtensions; KeyedHashSet heldObjects; //strong reference to the objects that must be hold on to //Indicate if objects have been removed or added from the table. This only needs to be set in a couple of places (addNamespace and removeNamespace) bool isDirty; bool fromCache; ExtensionRegistry* registry; // TODO make ExtensionPoint, Extension provide namespace in a same way (move it to the RegistryObject?) // See if all the registryObjects have the same namespace. If not, return null. // Also can return null if empty array is passed in or objects are of an unexpected type QString FindCommonNamespaceIdentifier(const QList >& registryObjects) const; void RemoveExtensionPointFromNamespaceIndex(int extensionPoint, const QString& namespaceName); void RemoveExtensionFromNamespaceIndex(int extensions, const QString& namespaceName); // Called from a synchronized method void UpdateNamespaceIndex(const SmartPointer& contribution, bool added); KeyedHashSet& GetFormerContributions() const; void Remove(const SmartPointer& registryObject, bool release); void Hold(const SmartPointer& toHold); void Release(const SmartPointer& toRelease); SmartPointer BasicGetObject(int id, short type) const; SmartPointer Load(int id, short type) const; OrphansMapType& GetOrphans() const; // Find or create required index element SmartPointer GetNamespaceIndex(const QString& namespaceName) const; void CollectChildren(const SmartPointer& ce, int level, QHash >& collector) const; // Called from a synchronized method only bool UnlinkChildFromContributions(const QList >& contributions, int id); }; } #endif // BERRYREGISTRYOBJECTMANAGER_H diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectReferenceMap.h b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectReferenceMap.h index 85e6f1ba51..398fe6d6b1 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectReferenceMap.h +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryObjectReferenceMap.h @@ -1,140 +1,140 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYREGISTRYOBJECTREFERENCEMAP_H #define BERRYREGISTRYOBJECTREFERENCEMAP_H #include #include namespace berry { class RegistryObject; class RegistryObjectReferenceMap { public: enum ReferenceType { /** * Constant indicating that hard references should be used. */ HARD = 0, /** - * Constant indiciating that soft references should be used. + * Constant indicating that soft references should be used. */ SOFT = 1 }; /** * Constructs a new ReferenceMap with the * specified reference type, load factor and initial * capacity. * * @param referenceType the type of reference to use for values; * must be {@link #HARD} or {@link #SOFT} * @param capacity the initial capacity for the map */ RegistryObjectReferenceMap(ReferenceType referenceType, int capacity); ~RegistryObjectReferenceMap(); /** * Returns the value associated with the given key, if any. * * @return the value associated with the given key, or null * if the key maps to no value */ SmartPointer Get(int key) const; /** * Associates the given key with the given value.

* The value may be null. * * @param key the key of the mapping * @param value the value of the mapping * @throws ctkInvalidArgumentException if either the key or value * is null */ void Put(int key, const SmartPointer& value); /** * Removes the key and its associated value from this map. * * @param key the key to remove * @return the value associated with that key, or null if * the key was not in the map */ SmartPointer Remove(int key); private: /** * The common interface for all elements in the map. Both * smart and weak pointer map values conform to this interface. */ struct IEntry; /** * IEntry implementation that acts as a hard reference. * The value of a hard reference entry is never garbage * collected until it is explicitly removed from the map. */ class SmartRef; /** * IEntry implementation that acts as a weak reference. */ class WeakRef; typedef QHash ReferenceMapType; mutable ReferenceMapType references; ReferenceType valueType; /** * Constructs a new table entry for the given data * * @param key The entry key * @param value The entry value * @param next The next value in the entry's collision chain * @return The new table entry */ IEntry* NewEntry(const SmartPointer& value) const; /** * Purges stale mappings from this map.

* * Ordinarily, stale mappings are only removed during * a write operation; typically a write operation will * occur often enough that you'll never need to manually * invoke this method.

* * Note that this method is not synchronized! Special * care must be taken if, for instance, you want stale * mappings to be removed on a periodic basis by some * background thread. */ void Purge() const; /** * @param key The key to remove * @param cleanup true if doing map maintenance; false if it is a real request to remove * @return The removed map value */ SmartPointer DoRemove(int key, bool cleanup); }; } #endif // BERRYREGISTRYOBJECTREFERENCEMAP_H diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryTimestamp.h b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryTimestamp.h index 91093af976..16be398138 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryTimestamp.h +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryRegistryTimestamp.h @@ -1,83 +1,83 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYREGISTRYTIMESTAMP_H #define BERRYREGISTRYTIMESTAMP_H namespace berry { /** * Aggregated registry timestamp. Corresponds to the current contents of the registry. *

* This class may be instantiated. *

- * This class is not indended to be subclassed. + * This class is not intended to be subclassed. */ class RegistryTimestamp { private: /** * Current aggregated timestamp */ long aggregateTimestamp; bool modified; public: /** * Public constructor. */ RegistryTimestamp(); /** * Returns value of the aggregated timestamp. * @return value of the aggregated timestamp */ long GetContentsTimestamp() const; /** * Set value of the aggregated timestamp. * @param timestamp the aggregated timestamp of the current registry contents */ void Set(long timestamp); /** * Sets aggregated timestamp to the value corresponding to an empty registry. */ void Reset(); /** * Determines if the aggregate timestamp was modified using add() or remove() * methods. * @return true: the timestamp was modified after the last set/reset */ bool IsModifed() const; /** * Add individual contribution timestamp to the aggregated timestamp. * @param timestamp the time stamp of the contribution being added to the registry */ void Add(long timestamp); /** * Remove individual contribution timestamp from the aggregated timestamp. * @param timestamp the time stamp of the contribution being removed from the registry */ void Remove(long timestamp); }; } #endif // BERRYREGISTRYTIMESTAMP_H diff --git a/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpIndexView.h b/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpIndexView.h index e2819f5db0..cb4c05330b 100644 --- a/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpIndexView.h +++ b/Plugins/org.blueberry.ui.qt.help/src/internal/berryHelpIndexView.h @@ -1,118 +1,118 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYHELPINDEXVIEW_H_ #define BERRYHELPINDEXVIEW_H_ #include #include #include class ctkSearchBox; class QHelpIndexWidget; namespace berry { class HelpIndexWidget : public QListView { Q_OBJECT Q_SIGNALS: /** * This signal is emitted when an item is activated and its * associated \a link should be shown. To know where the link - * belongs to, the \a keyword is given as a second paremeter. + * belongs to, the \a keyword is given as a second parameter. */ void linkActivated(const QUrl &link, const QString &keyword); /** * This signal is emitted when the item representing the \a keyword * is activated and the item has more than one link associated. * The \a links consist of the document title and their URL. */ void linksActivated(const QMap &links, const QString &keyword); public: HelpIndexWidget(); public Q_SLOTS: /** * Filters the indices according to \a filter or \a wildcard. * The item with the best match is set as current item. */ void filterIndices(const QString &filter, const QString &wildcard = QString()); /** * Activates the current item which will result eventually in * the emitting of a linkActivated() or linksActivated() * signal. */ void activateCurrentItem(); private Q_SLOTS: void showLink(const QModelIndex &index); }; class HelpIndexView : public QtViewPart { Q_OBJECT public: HelpIndexView(); ~HelpIndexView() override; void SetFocus() override; protected: void CreateQtPartControl(QWidget* parent) override; void setSearchLineEditText(const QString &text); QString searchLineEditText() const; protected Q_SLOTS: void linkActivated(const QUrl& link); void linksActivated(const QMap &links, const QString &keyword); private Q_SLOTS: void filterIndices(const QString &filter); void enableSearchLineEdit(); void disableSearchLineEdit(); void setIndexWidgetBusy(); void unsetIndexWidgetBusy(); private: bool eventFilter(QObject *obj, QEvent *e) override; void focusInEvent(QFocusEvent *e); void open(HelpIndexWidget *indexWidget, const QModelIndex &index); Q_DISABLE_COPY(HelpIndexView) ctkSearchBox* m_SearchLineEdit; HelpIndexWidget* m_IndexWidget; }; } // namespace berry #endif /*BERRYHELPINDEXVIEW_H_*/ diff --git a/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox b/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox index f4a0815bae..1dee9db8bc 100644 --- a/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox +++ b/Plugins/org.blueberry.ui.qt.log/documentation/UserManual/blueberrylogview.dox @@ -1,16 +1,16 @@ /** \page org_blueberry_views_logview The Logging Plugin \imageMacro{logview-dox.svg,"Icon of the Logging Plugin",2.00} This plug-in records all logging output of events and progress as specified in the source code with time of occurrence, level of importance (Info, Warning, Error, Fatal, Debug), the message given and the origin of the message (source code section). \imageMacro{LogView.png,"Screenshot of the Logging Plugin",16.00} There are different features available in the view. The 'Filter' text field provides the possibility to search for all log events containing a certain substring. The 'Copy to clipboard' button allows you to copy the current content of the logging view to your clipboard. This enables you to insert the logging information to any text processing application. In the simple logging view, you'll see logging messages and logging levels. A brief description of the logging levels can be found in the \ref LoggingPage "logging concept documentation". With two checkboxes more information on every logging message can be activated. The checkbox 'categories' adds a column for the category. The checkbox 'advanced fields' additionally displays the time from application start to the log message entry and the function, filename and line number of the logging message origin. -\imageMacro{LogViewExplain.png,"Details on the Vizualized Logging Information",16.00} +\imageMacro{LogViewExplain.png,"Details on the Visualized Logging Information",16.00} */ diff --git a/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp b/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp index 6dd5f99784..3e506e8aea 100644 --- a/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp +++ b/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp @@ -1,332 +1,332 @@ /*============================================================================ 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 "berryQtPlatformLogModel.h" #include "berryQtLogPlugin.h" #include #include #include #include #include #include #include #include #include namespace berry { const QString QtPlatformLogModel::Error = QString("Error"); const QString QtPlatformLogModel::Warn = QString("Warning"); const QString QtPlatformLogModel::Fatal = QString("Fatal"); const QString QtPlatformLogModel::Info = QString("Info"); const QString QtPlatformLogModel::Debug = QString("Debug"); void QtPlatformLogModel::slotFlushLogEntries() { m_Mutex.lock(); QList *tmp=m_Active; m_Active=m_Pending; m_Pending=tmp; m_Mutex.unlock(); int num = static_cast(m_Pending->size()); if (num > 0) { int row = static_cast(m_Entries.size()); this->beginInsertRows(QModelIndex(), row, row+num-1); do { m_Entries.push_back(m_Pending->front()); m_Pending->pop_front(); } while(--num); this->endInsertRows(); } } void QtPlatformLogModel::addLogEntry(const mitk::LogMessage &msg) { m_Mutex.lock(); //mitk::LogBackendCout::FormatSmart(msg); FormatSmart is not static any more. So commented out this statement. Todo: fix m_Active->push_back(ExtendedLogMessage(msg)); m_Mutex.unlock(); emit signalFlushLogEntries(); } void QtPlatformLogModel::SetShowAdvancedFiels( bool showAdvancedFiels ) { if( m_ShowAdvancedFiels != showAdvancedFiels ) { m_ShowAdvancedFiels = showAdvancedFiels; this->beginResetModel(); this->endResetModel(); } } void QtPlatformLogModel::SetShowCategory( bool showCategory ) { if( m_ShowCategory != showCategory ) { m_ShowCategory = showCategory; this->beginResetModel(); this->endResetModel(); } } void QtPlatformLogModel::addLogEntry(const ctkPluginFrameworkEvent& event) { auto level = mitk::LogLevel::Info; if (event.getType() == ctkPluginFrameworkEvent::PLUGIN_ERROR) { level = mitk::LogLevel::Error; } else if (event.getType() == ctkPluginFrameworkEvent::FRAMEWORK_WAIT_TIMEDOUT || event.getType() == ctkPluginFrameworkEvent::PLUGIN_WARNING) { level = mitk::LogLevel::Warn; } mitk::LogMessage msg(level,"n/a",-1,"n/a"); QString str; QDebug dbg(&str); dbg << event; msg.Message = str.toStdString(); //msg.moduleName = event.getPlugin()->getSymbolicName().toStdString(); addLogEntry(msg); } QtPlatformLogModel::QtPlatformLogModel(QObject* parent) : QAbstractTableModel(parent), m_ShowAdvancedFiels(false), m_ShowCategory(true) { m_Active=new QList; m_Pending=new QList; connect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ), Qt::QueuedConnection ); QtLogPlugin::GetInstance()->GetContext()->connectFrameworkListener(this, SLOT(addLogEntry(ctkPluginFrameworkEvent))); myBackend = new QtLogBackend(this); } QtPlatformLogModel::~QtPlatformLogModel() { disconnect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() )); QtLogPlugin::GetInstance()->GetContext()->disconnectFrameworkListener(this); - // dont delete and unregister backend, only deactivate it to avoid thread syncronization issues cause mitk::UnregisterBackend is not threadsafe + // dont delete and unregister backend, only deactivate it to avoid thread synchronization issues cause mitk::UnregisterBackend is not threadsafe // will be fixed. // delete myBackend; // delete m_Active; // delete m_Pending; m_Mutex.lock(); myBackend->Deactivate(); m_Mutex.unlock(); } // QT Binding int QtPlatformLogModel::rowCount(const QModelIndex&) const { return static_cast(m_Entries.size()); } int QtPlatformLogModel::columnCount(const QModelIndex&) const { int returnValue = 2; if( m_ShowAdvancedFiels ) returnValue += 7; if( m_ShowCategory ) returnValue += 1; return returnValue; } /* struct LogEntry { LogEntry(const std::string& msg, const std::string& src, std::time_t t) : message(msg.c_str()), moduleName(src.c_str()),time(std::clock()) { } QString message; clock_t time; QString level; QString filePath; QString lineNumber; QString moduleName; QString category; QString function; LogEntry(const mitk::LogMessage &msg) { message = msg.Message.c_str(); filePath = msg.filePath; std::stringstream out; out << msg.LineNumber; lineNumber = out.str().c_str(); moduleName = msg.ModuleName; category = msg.Category.c_str(); function = msg.FunctionName; time=std::clock(); } }; */ QVariant QtPlatformLogModel::data(const QModelIndex& index, int role) const { const ExtendedLogMessage *msg = &m_Entries[index.row()]; if (role == Qt::DisplayRole) { switch (index.column()) { case 0: if (m_ShowAdvancedFiels) return msg->getTime(); else return msg->getLevel(); case 1: if (m_ShowAdvancedFiels) return msg->getLevel(); else return msg->getMessage(); case 2: if (m_ShowAdvancedFiels) return msg->getMessage(); else return msg->getCategory(); case 3: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getCategory(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getModuleName(); else break; case 4: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getModuleName(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getFunctionName(); else break; case 5: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getFunctionName(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getPath(); else break; case 6: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getPath(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getLine(); else break; case 7: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getLine(); else break; } } else if( role == Qt::DecorationRole ) { if ( (m_ShowAdvancedFiels && index.column()==1) || (!m_ShowAdvancedFiels && index.column()==0) ) { QString file ( ":/org_blueberry_ui_qt_log/information.png" ); if( msg->message.Level == mitk::LogLevel::Error ) file = ":/org_blueberry_ui_qt_log/error.png"; else if( msg->message.Level == mitk::LogLevel::Warn ) file = ":/org_blueberry_ui_qt_log/warning.png"; else if( msg->message.Level == mitk::LogLevel::Debug ) file = ":/org_blueberry_ui_qt_log/debug.png"; else if( msg->message.Level == mitk::LogLevel::Fatal ) file = ":/org_blueberry_ui_qt_log/fatal.png"; QIcon icon(file); return QVariant(icon); } } return QVariant(); } QVariant QtPlatformLogModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if( m_ShowAdvancedFiels && m_ShowCategory ) { switch (section) { case 0: return QVariant(" Time "); case 1: return QVariant(" Level "); case 2: return QVariant(" Message "); case 3: return QVariant(" Category "); case 4: return QVariant(" Module "); case 5: return QVariant(" Function "); case 6: return QVariant(" File "); case 7: return QVariant(" Line "); } } else if (m_ShowAdvancedFiels && !m_ShowCategory) { switch (section) { case 0: return QVariant(" Time "); case 1: return QVariant(" Level "); case 2: return QVariant(" Message "); case 3: return QVariant(" Module "); case 4: return QVariant(" Function "); case 5: return QVariant(" File "); case 6: return QVariant(" Line "); } } - else //!m_ShowAdvancedFiels, m_ShowCategory is not handled seperately because it only activates case 2 + else //!m_ShowAdvancedFiels, m_ShowCategory is not handled separately because it only activates case 2 { switch (section) { case 0: return QVariant(" Level "); case 1: return QVariant(" Message "); case 2: return QVariant(" Category "); } } } return QVariant(); } QVariant QtPlatformLogModel::ExtendedLogMessage::getTime() const { std::stringstream ss; std::locale C("C"); ss.imbue(C); ss << std::setw(7) << std::setprecision(3) << std::fixed << ((double)this->time)/CLOCKS_PER_SEC; return QVariant(QString(ss.str().c_str())); } QString QtPlatformLogModel::GetDataAsString() { QString returnValue(""); for (int message=0; messagerowCount(QModelIndex()); message++) { for (int column=0; columncolumnCount(QModelIndex()); column++) { returnValue += " " + this->data(this->index(message,column),Qt::DisplayRole).toString(); } returnValue += "\n"; } return returnValue; } } diff --git a/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h b/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h index bd6b7f567e..561b148d9b 100644 --- a/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h +++ b/Plugins/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.h @@ -1,211 +1,211 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYQTPLATFORMLOGMODEL_H_ #define BERRYQTPLATFORMLOGMODEL_H_ #include "berryLog.h" #include "ctkPluginFrameworkEvent.h" #include #include #include #include #include "berryLog.h" #include namespace berry { /** Documentation * @brief An object of this class represents a table of logging data. * The table presentation can be modified by the methods * SetShowAdvancedFiels() and SetShowCategory(). */ class QtPlatformLogModel : public QAbstractTableModel { Q_OBJECT public: QtPlatformLogModel(QObject* parent = nullptr); ~QtPlatformLogModel() override; void SetShowAdvancedFiels( bool showAdvancedFiels ); void SetShowCategory( bool showCategory ); int rowCount(const QModelIndex&) const override; int columnCount(const QModelIndex&) const override; QVariant data(const QModelIndex& index, int) const override; /** Documentation - * @return Retruns the complete table data as string representation. + * @return Returns the complete table data as string representation. */ QString GetDataAsString(); QVariant headerData(int section, Qt::Orientation orientation, int) const override; void addLogEntry(const mitk::LogMessage &msg); Q_SLOT void addLogEntry(const ctkPluginFrameworkEvent& event); private: bool m_ShowAdvancedFiels; bool m_ShowCategory; /** Documentation * @brief An object of this struct internally represents a logging message. * It offers methods to convert the logging data into QVaraint objects * and also adds time and threadid as logging data. The struct is * internally used to store logging data in the table data model. */ struct ExtendedLogMessage { mitk::LogMessage message; clock_t time; int threadid; ExtendedLogMessage(const ExtendedLogMessage &src):message(src.message),time(src.time),threadid(src.threadid) { } ExtendedLogMessage(const mitk::LogMessage &msg):message(msg),time(std::clock()),threadid(0) { } ExtendedLogMessage operator = (const ExtendedLogMessage& src) { return ExtendedLogMessage(src); } QVariant getLevel() const { switch(this->message.Level) { default: case mitk::LogLevel::Info: return QVariant(Info); case mitk::LogLevel::Warn: return QVariant(Warn); case mitk::LogLevel::Error: return QVariant(Error); case mitk::LogLevel::Fatal: return QVariant(Fatal); case mitk::LogLevel::Debug: return QVariant(Debug); } } QVariant getMessage() const { return QVariant(QString::fromStdString(this->message.Message)); } QVariant getCategory() const { return QVariant(QString::fromStdString(this->message.Category)); } QVariant getModuleName() const { return QVariant(QString::fromStdString(this->message.ModuleName)); } QVariant getFunctionName() const { return QVariant(QString::fromStdString(this->message.FunctionName)); } QVariant getPath() const { return QVariant(QString::fromStdString(this->message.FilePath)); } QVariant getLine() const { return QVariant(QString::number(this->message.LineNumber)); } /** This method is implemented in the cpp file to save includes. */ QVariant getTime() const; }; class QtLogBackend : public mitk::LogBackendBase { public: QtLogBackend(QtPlatformLogModel *_myModel) { myModel=_myModel; deactivated = false; mitk::RegisterBackend(this); BERRY_INFO << "BlueBerry log backend registered"; } ~QtLogBackend() override { mitk::UnregisterBackend(this); } void ProcessMessage(const mitk::LogMessage &l ) override { if(!deactivated) myModel->addLogEntry(l); } mitk::LogBackendBase::OutputType GetOutputType() const override { return mitk::LogBackendBase::OutputType::Other; } void Deactivate() { deactivated=true; } private: QtPlatformLogModel *myModel; bool deactivated; } *myBackend; QList m_Entries; QList *m_Active,*m_Pending; static const QString Error; static const QString Warn; static const QString Fatal; static const QString Info; static const QString Debug; QMutex m_Mutex; signals: void signalFlushLogEntries(); protected slots: void slotFlushLogEntries(); }; } #endif /*BERRYQTPLATFORMLOGMODEL_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/actions/berryCommandContributionItemParameter.h b/Plugins/org.blueberry.ui.qt/src/actions/berryCommandContributionItemParameter.h index 52cb8ea7ff..b847146713 100644 --- a/Plugins/org.blueberry.ui.qt/src/actions/berryCommandContributionItemParameter.h +++ b/Plugins/org.blueberry.ui.qt/src/actions/berryCommandContributionItemParameter.h @@ -1,193 +1,193 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYCOMMANDCONTRIBUTIONITEMPARAMETER_H #define BERRYCOMMANDCONTRIBUTIONITEMPARAMETER_H #include #include #include #include "berryCommandContributionItem.h" namespace berry { struct IServiceLocator; /** * A help class for the various parameters that can be used with command * contributions. Mandatory parameters are in the constructor, and public fields * can be set to fill in other parameters. */ class BERRY_UI_QT CommandContributionItemParameter : public virtual Object { public: berryObjectMacro(CommandContributionItemParameter); /** * a service locator that is most appropriate for this contribution. * Typically the local {@link IWorkbenchWindow} or * {@link IWorkbenchPartSite} will be sufficient. Must not be * null. */ IServiceLocator* serviceLocator; /** * The id for this item. May be null. Items without an id * cannot be referenced later. */ QString id; /** * A command id for a defined command. Must not be null. */ QString commandId; /** * A map of strings to strings which represent parameter names to values. * The parameter names must match those in the command definition. May be * null */ QHash parameters; /** * An icon for this item. May be null. */ QIcon icon; /** * A label for this item. May be null. */ QString label; /** * A mnemonic for this item to be applied to the label. May be * null. */ QChar mnemonic; /** * A shortcut key sequence. This is a workaround and will be * removed when key binding support is fully implemented */ QKeySequence shortcut; /** * A tooltip for this item. May be null. Tooltips are * currently only valid for toolbar contributions. */ QString tooltip; /** * The style of this menu contribution. See the CommandContributionItem - * STYLE_* contants. + * STYLE_* constants. */ CommandContributionItem::Style style; /** * The help context id to be applied to this contribution. May be * null */ QString helpContextId; /** * The icon style to use. */ QString iconStyle; /** * The visibility tracking for a menu contribution. */ bool visibleEnabled; /** * Any number of mode bits, like * {@link CommandContributionItem#MODE_FORCE_TEXT}. */ CommandContributionItem::Modes mode; /** * Create the parameter object. Nullable attributes can be set directly. * * @param serviceLocator * a service locator that is most appropriate for this * contribution. Typically the local {@link IWorkbenchWindow} or * {@link IWorkbenchPartSite} will be sufficient. Must not be * null. * @param id * The id for this item. May be null. Items * without an id cannot be referenced later. * @param commandId * A command id for a defined command. Must not be * null. * @param style - * The style of this menu contribution. See the STYLE_* contants. + * The style of this menu contribution. See the STYLE_* constants. */ CommandContributionItemParameter(IServiceLocator* serviceLocator, const QString& id, const QString& commandId, CommandContributionItem::Style style); /** * Build the parameter object. *

* Note: This constructor should not be called outside the framework. *

* * @param serviceLocator * a service locator that is most appropriate for this * contribution. Typically the local {@link IWorkbenchWindow} or * {@link IWorkbenchPartSite} will be sufficient. Must not be * null. * @param id * The id for this item. May be null. Items * without an id cannot be referenced later. * @param commandId * A command id for a defined command. Must not be * null. * @param parameters * A map of strings to strings which represent parameter names to * values. The parameter names must match those in the command * definition. May be null * @param icon * An icon for this item. May be null. * @param label * A label for this item. May be null. * @param mnemonic * A mnemonic for this item to be applied to the label. May be * null. * @param tooltip * A tooltip for this item. May be null. Tooltips * are currently only valid for toolbar contributions. * @param style - * The style of this menu contribution. See the STYLE_* contants. + * The style of this menu contribution. See the STYLE_* constants. * @param helpContextId * the help context id to be applied to this contribution. May be * null * @param visibleEnabled * Visibility tracking for the menu contribution. * @note This constructor is not intended to be referenced by clients. */ CommandContributionItemParameter(IServiceLocator* serviceLocator, const QString& id, const QString& commandId, const QHash ¶meters, const QIcon& icon, const QString label, const QChar &mnemonic, const QString& tooltip, CommandContributionItem::Style style, const QString& helpContextId, bool visibleEnabled); }; } #endif // BERRYCOMMANDCONTRIBUTIONITEM_H diff --git a/Plugins/org.blueberry.ui.qt/src/actions/berryContributionItemFactory.h b/Plugins/org.blueberry.ui.qt/src/actions/berryContributionItemFactory.h index ade6420acf..2dda3b6f0c 100644 --- a/Plugins/org.blueberry.ui.qt/src/actions/berryContributionItemFactory.h +++ b/Plugins/org.blueberry.ui.qt/src/actions/berryContributionItemFactory.h @@ -1,132 +1,132 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYCONTRIBUTIONITEMFACTORY_H #define BERRYCONTRIBUTIONITEMFACTORY_H #include #include #include namespace berry { struct IContributionItem; struct IWorkbenchWindow; /** * Access to standard contribution items provided by the workbench. *

* Most of the functionality of this class is provided by * static methods and fields. * Example usage: *

  * MenuManager menu = ...;
  * IContributionItem::Pointer reEdit
  *     = ContributionItemFactory::REOPEN_EDITORS->Create(window);
  * menu->Add(reEdit);
  * 
*

*

* Clients may declare subclasses that provide additional application-specific * contribution item factories. *

*/ class BERRY_UI_QT ContributionItemFactory { private: /** * Id of contribution items created by this factory. */ const QString contributionItemId; protected: /** * Creates a new workbench contribution item factory with the given id. * * @param contributionItemId the id of contribution items created by this factory */ ContributionItemFactory(const QString& contributionItemId); public: /** * Creates a new standard contribution item for the given workbench window. *

* A typical contribution item automatically registers listeners against the * workbench window so that it can keep its enablement state up to date. * Ordinarily, the window's references to these listeners will be dropped * automatically when the window closes. However, if the client needs to get * rid of a contribution item while the window is still open, the client must * call IContributionItem#dispose to give the item an * opportunity to deregister its listeners and to perform any other cleanup. *

* * @param window the workbench window * @return the workbench contribution item */ virtual SmartPointer Create(IWorkbenchWindow* window) = 0; /** * Returns the id of this contribution item factory. * * @return the id of contribution items created by this factory */ QString GetId() const; /** * Workbench contribution item (id "openWindows"): A list of windows * currently open in the workbench. Selecting one of the items makes the * corresponding window the active window. * This action dynamically maintains the list of windows. */ static const QScopedPointer OPEN_WINDOWS; /** * Workbench contribution item (id "viewsShortlist"): A list of views * available to be opened in the window, arranged as a shortlist of * promising views and an "Other" subitem. Selecting * one of the items opens the corresponding view in the active window. * This action dynamically maintains the view shortlist. */ static const QScopedPointer VIEWS_SHORTLIST; /** * Workbench contribution item (id "reopenEditors"): A list of recent * editors (with inputs) available to be reopened in the window. Selecting * one of the items reopens the corresponding editor on its input in the * active window. This action dynamically maintains the list of editors. */ static const QScopedPointer REOPEN_EDITORS; /** * Workbench contribution item (id "perspectivesShortlist"): A list of * perspectives available to be opened, arranged as a shortlist of * promising perspectives and an "Other" subitem. Selecting * one of the items makes the corresponding perspective active. Should a * new perspective need to be opened, a workbench user preference controls - * whether the prespective is opened in the active window or a new window. + * whether the perspective is opened in the active window or a new window. * This action dynamically maintains the perspectives shortlist. */ static const QScopedPointer PERSPECTIVES_SHORTLIST; virtual ~ContributionItemFactory() = default; }; } #endif // BERRYCONTRIBUTIONITEMFACTORY_H diff --git a/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionItem.h b/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionItem.h index 7c2600b8bf..33b39e7e9e 100644 --- a/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionItem.h +++ b/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionItem.h @@ -1,194 +1,194 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYICONTRIBUTIONITEM_H #define BERRYICONTRIBUTIONITEM_H #include #include class QStatusBar; class QMenu; class QMenuBar; class QToolBar; class QAction; namespace berry { struct IContributionManager; /** * A contribution item represents a contribution to a shared UI resource such as a * menu or tool bar. More generally, contribution items are managed by a contribution * manager. * For instance, in a tool bar a contribution item is a tool bar button or a separator. * In a menu bar a contribution item is a menu, and in a menu a contribution item * is a menu item or separator. *

* A contribution item can realize itself in different Qt widgets, using the different * fill methods. The same type of contribution item can be used with a * MenuBarManager, ToolBarManager, * or a StatusLineManager. *

*

* This interface is internal to the framework; it should not be implemented outside * the framework. *

* * @see IContributionManager */ struct IContributionItem : public virtual Object { berryObjectMacro(berry::IContributionItem); /** * Fills the given status bar control with controls representing this * contribution item. Used by StatusLineManager. * * @param parent the parent control */ virtual void Fill(QStatusBar* parent) = 0; /** * Fills the given menu bar with controls representing this contribution item. * Used by MenuBarManager. * * @param parent the parent menu * @param before */ virtual void Fill(QMenuBar* parent, QAction* before) = 0; /** * Fills the given menu with controls representing this contribution item. * Used by MenuManager. * * @param parent the parent menu * @param before */ virtual void Fill(QMenu* parent, QAction* before) = 0; /** * Fills the given tool bar with controls representing this contribution item. * Used by ToolBarManager. * * @param parent the parent tool bar * @param before */ virtual void Fill(QToolBar* parent, QAction* before) = 0; /** * Returns the identifier of this contribution item. * The id is used for retrieving an item from its manager. * * @return the contribution item identifier, or null * if none */ virtual QString GetId() const = 0; /** * Returns whether this contribution item is enabled. * * @return true if this item is enabled */ virtual bool IsEnabled() const = 0; /** * Returns whether this contribution item is dirty. A dirty item will be * recreated when the action bar is updated. * * @return true if this item is dirty */ virtual bool IsDirty() const = 0; /** * Returns whether this contribution item is dynamic. A dynamic contribution * item contributes items conditionally, dependent on some internal state. * * @return true if this item is dynamic, and * false for normal items */ virtual bool IsDynamic() const = 0; /** * Returns whether this contribution item is a group marker. * This information is used when adding items to a group. * * @return true if this item is a group marker, and * false for normal items * * @see GroupMarker * @see IContributionManager#appendToGroup(String, IContributionItem) * @see IContributionManager#prependToGroup(String, IContributionItem) */ virtual bool IsGroupMarker() const = 0; /** * Returns whether this contribution item is a separator. * This information is used to enable hiding of unnecessary separators. * * @return true if this item is a separator, and * false for normal items * @see Separator */ virtual bool IsSeparator() const = 0; /** - * Returns whether this contribution item is visibile within its manager. + * Returns whether this contribution item is visible within its manager. * * @return true if this item is visible, and * false otherwise */ virtual bool IsVisible() const = 0; /** * Saves any state information of the control(s) owned by this contribution item. * The contribution manager calls this method before disposing of the controls. */ virtual void SaveWidgetState() = 0; /** * Sets the parent manager of this item * * @param parent the parent contribution manager */ virtual void SetParent(IContributionManager* parent) = 0; /** - * Sets whether this contribution item is visibile within its manager. + * Sets whether this contribution item is visible within its manager. * * @param visible true if this item should be visible, and * false otherwise */ virtual void SetVisible(bool visible) = 0; /** * Updates any controls cached by this contribution item with any * changes which have been made to this contribution item since the last update. * Called by contribution manager update methods. */ virtual void Update() = 0; /** * Updates any controls cached by this contribution item with changes * for the the given property. * * @param id the id of the changed property */ virtual void Update(const QString& id) = 0; }; } #endif // BERRYICONTRIBUTIONITEM_H diff --git a/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionManagerOverrides.h b/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionManagerOverrides.h index 8fdb67e9a7..e80564f5a8 100644 --- a/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionManagerOverrides.h +++ b/Plugins/org.blueberry.ui.qt/src/actions/berryIContributionManagerOverrides.h @@ -1,72 +1,72 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYICONTRIBUTIONMANAGEROVERRIDES_H #define BERRYICONTRIBUTIONMANAGEROVERRIDES_H #include #include #include namespace berry { struct IContributionItem; /** * This interface is used by instances of IContributionItem - * to determine if the values for certain properties have been overriden + * to determine if the values for certain properties have been overridden * by their manager. *

* This interface is internal to the framework; it should not be implemented outside * the framework. *

*/ struct BERRY_UI_QT IContributionManagerOverrides : virtual Object { berryObjectMacro(berry::IContributionManagerOverrides); /** * Id for the enabled property. Value is "enabled". */ static const QString P_ENABLED; /** * Find out the enablement of the item * @param item the contribution item for which the enable override value is * determined * @return
    *
  • 1 if the given contribution item should be enabled
  • *
  • 0 if the item should not be enabled
  • *
  • -1 if the item may determine its own enablement
  • *
*/ virtual int GetEnabled(const IContributionItem* item) const = 0; /** - * Visiblity override. + * Visibility override. * * @param item the contribution item in question * @return
    *
  • 1 if the given contribution item should be visible
  • *
  • 0 if the item should not be visible
  • *
  • -1 if the item may determine its own visibility
  • *
*/ virtual int GetVisible(const IContributionItem* item) const = 0; }; } #endif // BERRYICONTRIBUTIONMANAGEROVERRIDES_H diff --git a/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.cpp b/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.cpp index c3bc449562..1a3064882e 100644 --- a/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.cpp +++ b/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.cpp @@ -1,675 +1,675 @@ /*============================================================================ 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 "berryMenuManager.h" #include "berryIContributionManagerOverrides.h" #include "berryQActionProperties.h" #include "berrySubContributionItem.h" #include #include class QMenuProxy { public: QMenu* menu; QMenuBar* menuBar; enum Type { MenuBar, Menu }; QMenuProxy(Type type, QWidget* parent = nullptr) : menu(nullptr), menuBar(nullptr) { switch (type) { case MenuBar: menuBar = new QMenuBar(parent); break; case Menu: menu = new QMenu(parent); break; } } bool isMenuBar() const { return menuBar != nullptr; } void setTitle(const QString& title) { if (menu) menu->setTitle(title); } void setIcon(const QIcon& icon) { if (menu) menu->setIcon(icon); } QList actions() const { return menu ? menu->actions() : menuBar->actions(); } void removeAction(QAction* action) { menu ? menu->removeAction(action) : menuBar->removeAction(action); } bool isEnabled() const { return menu ? menu->isEnabled() : menuBar->isEnabled(); } void setEnabled(bool enabled) { menu ? menu->setEnabled(enabled) : menuBar->setEnabled(enabled); } QAction* getParentItem() const { return menu ? menu->menuAction() : nullptr; } }; namespace berry { struct NullOverrides: public IContributionManagerOverrides { public: int GetEnabled(const IContributionItem* /*item*/) const override { return -1; } int GetVisible(const IContributionItem* /*item*/) const override { return -1; } }; void MenuManager::HandleAboutToShow() { if (this->removeAllWhenShown) { this->RemoveAll(); } emit AboutToShow(this); this->Update(false, false); } void MenuManager::HandleAboutToHide() { emit AboutToHide(this); } MenuManager::MenuManager(const QString& text, const QString& id) : id(id), menu(nullptr), menuItem(nullptr) , menuText(text), parent(nullptr) , removeAllWhenShown(false), visible(true) { } MenuManager::MenuManager(const QString& text, const QIcon& image, const QString& id) : id(id), menu(nullptr), menuItem(nullptr) , menuText(text), image(image) , parent(nullptr), removeAllWhenShown(false), visible(true) { } bool MenuManager::IsDirty() const { return ContributionManager::IsDirty(); } MenuManager::~MenuManager() { delete menu; } QMenu* MenuManager::CreateContextMenu(QWidget* parent) { if (!menu) { menu = new QMenuProxy(QMenuProxy::Menu, parent); this->InitializeMenu(); } return menu->menu; } QMenuBar* MenuManager::CreateMenuBar(QWidget* parent) { if (!menu) { menu = new QMenuProxy(QMenuProxy::MenuBar, parent); this->Update(false); } return menu->menuBar; } void MenuManager::AddMenuListener(QObject* listener) { this->connect(this, SIGNAL(AboutToShow(IMenuManager*)), listener, SLOT(MenuAboutToShow(IMenuManager*))); this->connect(this, SIGNAL(AboutToHide(IMenuManager*)), listener, SLOT(MenuAboutToHide(IMenuManager*))); } void MenuManager::RemoveMenuListener(QObject* listener) { this->disconnect(listener); } void MenuManager::Fill(QStatusBar* /*parent*/) { } void MenuManager::Fill(QToolBar* /*parent*/, QAction* /*before*/) { } void MenuManager::Fill(QMenu* parent, QAction* before) { this->FillMenu(parent, before); } void MenuManager::Fill(QMenuBar* parent, QAction* before) { this->FillMenu(parent, before); } void MenuManager::FillMenu(QWidget* parent, QAction* before) { if (!menuItem) { menuItem = new QAction(parent); if (parent) { parent->insertAction(before, menuItem); } menuItem->setText(GetMenuText()); menuItem->setIcon(image); if(!menu) { menu = new QMenuProxy(QMenuProxy::Menu, parent); } if (!menu->isMenuBar()) menuItem->setMenu(menu->menu); this->InitializeMenu(); this->SetDirty(true); } } IMenuManager::Pointer MenuManager::FindMenuUsingPath(const QString& path) const { IContributionItem::Pointer item(this->FindUsingPath(path)); if (IMenuManager::Pointer manager = item.Cast()) { return manager; } return IMenuManager::Pointer(nullptr); } IContributionItem::Pointer MenuManager::FindUsingPath(const QString& path) const { QString id(path); QString rest; int separator = path.indexOf('/'); if (separator != -1) { id = path.left(separator); rest = path.mid(separator + 1); } else { return ContributionManager::Find(path); } IContributionItem::Pointer item(ContributionManager::Find(id)); if (IMenuManager::Pointer manager = item.Cast()) { return manager->FindUsingPath(rest); } return IContributionItem::Pointer(nullptr); } QString MenuManager::GetId() const { return id; } QMenu* MenuManager::GetMenu() const { return menu->menu; } QString MenuManager::GetMenuText() const { if (definitionId == "") { return menuText; } // ExternalActionManager::ICallback callback = ExternalActionManager // .getInstance().getCallback(); // if (callback != null) // { // String shortCut = callback.getAcceleratorText(definitionId); // if (shortCut == null) // { // return menuText; // } // return menuText + "\t" + shortCut; //$NON-NLS-1$ // } return menuText; } QIcon MenuManager::GetImage() const { return image; } SmartPointer MenuManager::GetOverrides() { if (!overrides) { if (!parent) { overrides = new NullOverrides(); } else { overrides = parent->GetOverrides(); } ContributionManager::SetOverrides(overrides); } return overrides; } IContributionManager* MenuManager::GetParent() const { return parent; } bool MenuManager::GetRemoveAllWhenShown() const { return removeAllWhenShown; } bool MenuManager::IsDynamic() const { return false; } bool MenuManager::IsEnabled() const { return true; } bool MenuManager::IsGroupMarker() const { return false; } bool MenuManager::IsSeparator() const { return false; } bool MenuManager::IsVisible() const { if (!visible) { return false; // short circuit calculations in this case } if (removeAllWhenShown) { // we have no way of knowing if the menu has children return true; } // menus aren't visible if all of its children are invisible (or only contains visible separators). bool visibleChildren = false; foreach(IContributionItem::Pointer item, this->GetItems()) { if (item->IsVisible() && !item->IsSeparator()) { visibleChildren = true; break; } } return visibleChildren; } void MenuManager::MarkDirty() { ContributionManager::MarkDirty(); // Can't optimize by short-circuiting when the first dirty manager is encountered, // since non-visible children are not even processed. // That is, it's possible to have a dirty sub-menu under a non-dirty parent menu // even after the parent menu has been updated. // If items are added/removed in the sub-menu, we still need to propagate the dirty flag up, // even if the sub-menu is already dirty, since the result of isVisible() may change // due to the added/removed items. IContributionManager* p = this->GetParent(); if (p) { p->MarkDirty(); } } void MenuManager::SaveWidgetState() { } void MenuManager::SetOverrides(SmartPointer newOverrides) { overrides = newOverrides; ContributionManager::SetOverrides(overrides); } void MenuManager::SetParent(IContributionManager* manager) { parent = manager; } void MenuManager::SetRemoveAllWhenShown(bool removeAll) { this->removeAllWhenShown = removeAll; } void MenuManager::SetVisible(bool visible) { this->visible = visible; } void MenuManager::SetCommandId(const QString& definitionId) { this->definitionId = definitionId; } void MenuManager::Update() { this->UpdateMenuItem(); } void MenuManager::Update(const QString& property) { QList items = GetItems(); for (int i = 0; i < items.size(); i++) { items[i]->Update(property); } if (menu != nullptr && menu->getParentItem() != nullptr) { if (QActionProperties::TEXT == property) { QString text = GetMenuText(); if (!text.isNull()) { menu->getParentItem()->setText(text); } } else if (QActionProperties::IMAGE == property && !image.isNull()) { menu->getParentItem()->setIcon(image); } } } void MenuManager::Update(bool force) { this->Update(force, false); } void MenuManager::UpdateAll(bool force) { this->Update(force, true); } void MenuManager::InitializeMenu() { menu->setTitle(GetMenuText()); menu->setIcon(GetImage()); if (!menu->isMenuBar()) { this->connect(menu->menu, SIGNAL(aboutToShow()), SLOT(HandleAboutToShow())); this->connect(menu->menu, SIGNAL(aboutToHide()), SLOT(HandleAboutToHide())); } // Don't do an update(true) here, in case menu is never opened. // Always do it lazily in handleAboutToShow(). } void MenuManager::UpdateMenuItem() { if (menuItem && menu) { bool enabled = removeAllWhenShown || menu->actions().size() > 0; if (menu->isEnabled() != enabled) { menuItem->setEnabled(enabled); } } } void MenuManager::DoItemFill(IContributionItem::Pointer ci, QAction* before) { if (menu->isMenuBar()) { ci->Fill(menu->menuBar, before); } else { ci->Fill(menu->menu, before); } } void MenuManager::Update(bool force, bool recursive) { if (ContributionManager::IsDirty() || force) { if (menu) { // clean contains all active items without double separators QList items = this->GetItems(); QList clean; IContributionItem::Pointer separator; foreach (IContributionItem::Pointer ci, items) { if (!ci->IsVisible()) { continue; } if (ci->IsSeparator()) { // delay creation until necessary // (handles both adjacent separators, and separator at end) separator = ci; } else { if (separator) { if (clean.size() > 0) { clean.push_back(separator); } separator = nullptr; } clean.push_back(ci); } } // remove obsolete (removed or non active) QList mi = menu->actions(); for (int i = 0; i < mi.size(); i++) { Object::Pointer data = mi[i]->data().value(); if (!data || !clean.contains(data.Cast())) { menu->removeAction(mi[i]); } else if (IContributionItem::Pointer ci = data.Cast()) { if(ci->IsDynamic() && ci->IsDirty()) { menu->removeAction(mi[i]); delete mi[i]; } } } // add new mi = menu->actions(); int srcIx = 0; int destIx = 0; for (QList::Iterator e = clean.begin(); e != clean.end(); ++e) { IContributionItem::Pointer src(*e); IContributionItem::Pointer dest; // get corresponding item in widget if (srcIx < mi.size()) { dest = mi[srcIx]->data().value().Cast(); } else { dest = nullptr; } if (dest && src == dest) { srcIx++; destIx++; } else if (dest && dest->IsSeparator() && src->IsSeparator()) { mi[srcIx]->setData(QVariant::fromValue(src)); srcIx++; destIx++; } else { int start = menu->actions().size(); //qDebug() << "***** Filling item destIx = " << destIx << " (size: " << start << ")"; this->DoItemFill(src, destIx >= start ? nullptr : menu->actions().at(destIx)); int newItems = menu->actions().size() - start; //qDebug() << "***** New items: " << newItems; for (int i = 0; i < newItems; ++i) { menu->actions().at(destIx++)->setData(QVariant::fromValue(src)); } } // May be we can optimize this call. If the menu has just // been created via the call src.fill(fMenuBar, destIx) then // the menu has already been updated with update(true) // (see MenuManager). So if force is true we do it again. But // we can't set force to false since then information for the // sub sub menus is lost. if (recursive) { IContributionItem::Pointer item(src); if (SubContributionItem::Pointer subItem = item.Cast()) { item = subItem->GetInnerItem(); } if (IMenuManager::Pointer mm = item.Cast()) { mm->UpdateAll(force); } } } // remove any old menu items not accounted for for (; srcIx < mi.size(); srcIx++) { menu->removeAction(mi[srcIx]); delete mi[srcIx]; } this->SetDirty(false); } } else { - // I am not dirty. Check if I must recursivly walk down the hierarchy. + // I am not dirty. Check if I must recursively walk down the hierarchy. if (recursive) { foreach (IContributionItem::Pointer ci, this->GetItems()) { if (IMenuManager::Pointer mm = ci.Cast()) { if (mm->IsVisible()) { mm->UpdateAll(force); } } } } } this->UpdateMenuItem(); } void MenuManager::DumpActionInfo(QMenuProxy* menu) { if (menu->isMenuBar()) { //qDebug() << "QMenuBar [" << menu->menuBar << "]"; DumpActionInfo(menu->menuBar, 1); } else { //qDebug() << "QMenu [" << menu->menu << "]" << menu->menu; DumpActionInfo(menu->menu, 1); } } void MenuManager::DumpActionInfo(QWidget* widget, int level) { QString indent = " |"; for (int i = 0; i < level; ++i) indent += "--"; foreach(QAction* action, widget->actions()) { qDebug() << qPrintable(indent) << action->text() << "[" << action << "]"; if (action->menu()) { DumpActionInfo(action->menu(), level+1); } } } } diff --git a/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.h b/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.h index 21b4b66e54..4e84952186 100644 --- a/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.h +++ b/Plugins/org.blueberry.ui.qt/src/actions/berryMenuManager.h @@ -1,403 +1,403 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYMENUMANAGER_H_ #define BERRYMENUMANAGER_H_ #include "berryIMenuManager.h" #include "berryContributionManager.h" #include #include class QMenu; class QMenuProxy; class QAction; namespace berry { /** * A menu manager is a contribution manager which realizes itself and its items * in a menu control; either as a menu bar, a sub-menu, or a context menu. *

* This class may be instantiated; it may also be subclassed. *

*/ class BERRY_UI_QT MenuManager: public QObject, public ContributionManager, public IMenuManager { Q_OBJECT public: berryObjectMacro(MenuManager); private: /** * The menu id. */ QString id; /** * The menu control; null before * creation and after disposal. */ QMenuProxy* menu; QAction* menuItem; /** * The menu item widget; null before * creation and after disposal. This field is used * when this menu manager is a sub-menu. */ //SmartPointer menuItem; /** * The text for a sub-menu. */ QString menuText; /** * The image for a sub-menu. */ QIcon image; /** * The overrides for items of this manager */ SmartPointer overrides; /** * The parent contribution manager. */ IContributionManager* parent; /** * Indicates whether removeAll should be * called just before the menu is displayed. */ bool removeAllWhenShown; /** * allows a submenu to display a shortcut key. This is often used with the * QuickMenu command or action which can pop up a menu using the shortcut. */ QString definitionId; private: Q_SLOT void HandleAboutToShow(); Q_SLOT void HandleAboutToHide(); protected: /** * Indicates this item is visible in its manager; true * by default. */ bool visible; public: Q_SIGNAL void AboutToShow(IMenuManager* mm); Q_SIGNAL void AboutToHide(IMenuManager* mm); /** * Creates a menu manager with the given text and id. * Typically no text is given when creating a context menu. * Supply a text and id for creating a sub-menu, where it needs to be referred to by the id. * * @param text the text for the menu, or "" if none * @param id the menu id, or "" if it is to have no id */ MenuManager(const QString& text = QString(), const QString& id = QString()); ~MenuManager() override; /** * Creates a menu manager with the given text, image, and id. * Typically used for creating a sub-menu, where it needs to be referred to by id. * * @param text the text for the menu, or "" if none * @param image the image for the menu, or ImageDescriptor::Pointer(0) if none * @param id the menu id, or "" if it is to have no id */ MenuManager(const QString& text, const QIcon& image, const QString& id); bool IsDirty() const override; /** * Creates and returns a Qt menu control for this menu, * and installs all registered contributions. * Does not create a new control if one already exists. *

* Note that the menu is not expected to be dynamic. *

* * @param parent the parent control * @return the menu control */ QMenu* CreateContextMenu(QWidget* parent); /** * Creates and returns a Qt menu bar control for this menu, * for use in the given QWidget, and installs all registered * contributions. Does not create a new control if one already exists. * * @param parent the parent decorations * @return the menu control * @since 2.1 */ QMenuBar* CreateMenuBar(QWidget* parent); void AddMenuListener(QObject* listener) override; void RemoveMenuListener(QObject *listener) override; /* * @see IContributionItem#Fill(QStatusBar*) */ void Fill(QStatusBar* parent) override; /* * @see IContributionItem#Fill(QToolBar*, int) */ void Fill(QToolBar* parent, QAction *index) override; /* * @see IContributionItem#Fill(QMenu*, int) */ void Fill(QMenu* parent, QAction *before) override; /* * @see IContributionItem#Fill(QMenuBar*, int) */ void Fill(QMenuBar* parent, QAction *before) override; /* * @see IMenuManager#FindMenuUsingPath(const QString&) */ IMenuManager::Pointer FindMenuUsingPath(const QString& path) const override; /* * @see IMenuManager#FindUsingPath(const QString&) */ IContributionItem::Pointer FindUsingPath(const QString& path) const override; /** * Returns the menu id. The menu id is used when creating a contribution * item for adding this menu as a sub menu of another. * * @return the menu id */ QString GetId() const override; /** * Returns the SWT menu control for this menu manager. * * @return the menu control */ QMenu* GetMenu() const; /** * Returns the text shown in the menu, potentially with a shortcut * appended. * * @return the menu text */ QString GetMenuText() const; /** * Returns the image for this menu as an image descriptor. * * @return the image, or null if this menu has no image */ QIcon GetImage() const; /* * @see IContributionManager#GetOverrides() */ SmartPointer GetOverrides() override; /** - * Returns the parent contribution manager of this manger. + * Returns the parent contribution manager of this manager. * * @return the parent contribution manager */ IContributionManager* GetParent() const; /* * @see IMenuManager#GetRemoveAllWhenShown() */ bool GetRemoveAllWhenShown() const override; /* * @see IContributionItem#IsDynamic() */ bool IsDynamic() const override; /** * Returns whether this menu should be enabled or not. * Used to enable the menu item containing this menu when it is realized as a sub-menu. *

* The default implementation of this framework method * returns true. Subclasses may reimplement. *

* * @return true if enabled, and * false if disabled */ bool IsEnabled() const override; /* * @see IContributionItem#IsGroupMarker() */ bool IsGroupMarker() const override; /* * @see IContributionItem#IsSeparator() */ bool IsSeparator() const override; /* * @see IContributionItem#IsVisible() */ bool IsVisible() const override; /** * The MenuManager implementation of this ContributionManager method * also propagates the dirty flag up the parent chain. */ void MarkDirty() override; /* * @see IMenuManager#removeMenuListener(IMenuListener) */ //void RemoveMenuListener(SmartPointer listener); /* * @IContributionItem#SaveWidgetState() */ void SaveWidgetState() override; /** * Sets the overrides for this contribution manager * * @param newOverrides the overrides for the items of this manager */ void SetOverrides(SmartPointer newOverrides); /* * @see IContributionItem#SetParent(IContributionManager) */ void SetParent(IContributionManager* manager) override; /* * @see IMenuManager#SetRemoveAllWhenShown(boolean) */ void SetRemoveAllWhenShown(bool removeAll) override; /* * @see IContributionItem#SetVisible(bool) */ void SetVisible(bool visible) override; /** * Sets the command id of this action. This simply allows the menu * item text to include a short cut if available. It can be used to * notify a user of a key combination that will open a quick menu. * * @param definitionId * the command definition id */ void SetCommandId(const QString& definitionId); /* * @see IContributionItem#Update() */ void Update() override; void Update(const QString& property) override; /** * The MenuManager implementation of this IContributionManager * updates this menu, but not any of its submenus. * * @see #UpdateAll */ void Update(bool force) override; /* * @see IMenuManager#UpdateAll(bool) */ void UpdateAll(bool force) override; private: /** * Initializes the menu control. */ void InitializeMenu(); /** * Dispose any images allocated for this menu */ // void DisposeOldImages(); /** * Updates the menu item for this sub menu. * The menu item is disabled if this sub menu is empty. * Does nothing if this menu is not a submenu. */ void UpdateMenuItem(); void FillMenu(QWidget* parent, QAction* before); void DumpActionInfo(QMenuProxy* menu); void DumpActionInfo(QWidget* widget, int level); protected: /** * Call an IContributionItem's fill method with the * implementation's widget. The default is to use the Menu * widget.
* fill(Menu menu, int index) * * @param ci * An IContributionItem whose fill() * method should be called. * @param before * The position the fill() method should start * inserting at. */ void DoItemFill(IContributionItem::Pointer ci, QAction *before); /** * Incrementally builds the menu from the contribution items. * This method leaves out double separators and separators in the first * or last position. * * @param force true means update even if not dirty, * and false for normal incremental updating * @param recursive true means recursively update * all submenus, and false means just this menu */ void Update(bool force, bool recursive); }; } #endif /* BERRYMENUMANAGER_H_ */ diff --git a/Plugins/org.blueberry.ui.qt/src/application/berryWorkbenchWindowAdvisor.h b/Plugins/org.blueberry.ui.qt/src/application/berryWorkbenchWindowAdvisor.h index 18f15f4ddb..7135b29cf2 100644 --- a/Plugins/org.blueberry.ui.qt/src/application/berryWorkbenchWindowAdvisor.h +++ b/Plugins/org.blueberry.ui.qt/src/application/berryWorkbenchWindowAdvisor.h @@ -1,262 +1,262 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYWORKBENCHWINDOWADVISOR_H_ #define BERRYWORKBENCHWINDOWADVISOR_H_ #include #include namespace berry { struct IActionBarConfigurer; struct IMemento; struct IWorkbenchWindowConfigurer; class ActionBarAdvisor; class Shell; /** * Public base class for configuring a workbench window. *

* The workbench window advisor object is created in response to a workbench * window being created (one per window), and is used to configure the window. *

*

* An application should declare a subclass of WorkbenchWindowAdvisor * and override methods to configure workbench windows to suit the needs of the * particular application. *

*

* The following advisor methods are called at strategic points in the * workbench window's lifecycle (as with the workbench advisor, all occur * within the dynamic scope of the call to * PlatformUI#CreateAndRunWorkbench()): *

    *
  • PreWindowOpen() - called as the window is being opened; * use to configure aspects of the window other than actions bars
  • *
  • PostWindowRestore() - called after the window has been * recreated from a previously saved state; use to adjust the restored * window
  • *
  • PostWindowCreate() - called after the window has been created, * either from an initial state or from a restored state; used to adjust the * window
  • *
  • OpenIntro() - called immediately before the window is opened in * order to create the introduction component, if any.
  • *
  • PostWindowOpen() - called after the window has been * opened; use to hook window listeners, etc.
  • *
  • PreWindowShellClose() - called when the window's shell * is closed by the user; use to pre-screen window closings
  • *
*

* */ class BERRY_UI_QT WorkbenchWindowAdvisor { private: SmartPointer windowConfigurer; protected: /** * Returns the workbench window configurer. * * @return the workbench window configurer */ SmartPointer GetWindowConfigurer(); public: /** * Creates a new workbench window advisor for configuring a workbench * window via the given workbench window configurer. * * @param configurer an object for configuring the workbench window */ WorkbenchWindowAdvisor(const SmartPointer& configurer); virtual ~WorkbenchWindowAdvisor(); /** * Performs arbitrary actions before the window is opened. *

* This method is called before the window's controls have been created. * Clients must not call this method directly (although super calls are okay). * The default implementation does nothing. Subclasses may override. * Typical clients will use the window configurer to tweak the * workbench window in an application-specific way; however, filling the * window's menu bar, tool bar, and status line must be done in * ActionBarAdvisor#FillActionBars(), which is called immediately * after this method is called. *

*/ virtual void PreWindowOpen(); /** * Creates a new action bar advisor to configure the action bars of the window * via the given action bar configurer. * The default implementation returns a new instance of ActionBarAdvisor. * * @param configurer the action bar configurer for the window * @return the action bar advisor for the window */ virtual SmartPointer CreateActionBarAdvisor( SmartPointer configurer); /** * Performs arbitrary actions after the window has been restored, * but before it is opened. *

* This method is called after a previously-saved window has been * recreated. This method is not called when a new window is created from * scratch. This method is never called when a workbench is started for the * very first time, or when workbench state is not saved or restored. * Clients must not call this method directly (although super calls are okay). * The default implementation does nothing. Subclasses may override. * It is okay to call IWorkbench#Close() from this method. *

* * @exception WorkbenchException thrown if there are any errors to report * from post-restoration of the window */ virtual void PostWindowRestore(); /** - * Opens the introduction componenet. + * Opens the introduction component. *

* Clients must not call this method directly (although super calls are okay). * The default implementation opens the intro in the first window provided * if the preference WorkbenchPreferenceConstants#SHOW_INTRO is true. If * an intro is shown then this preference will be set to false. * Subsequently, and intro will be shown only if * WorkbenchConfigurer#GetSaveAndRestore() returns * true and the introduction was visible on last shutdown. * Subclasses may override. *

*/ virtual void OpenIntro(); /** * Performs arbitrary actions after the window has been created (possibly * after being restored), but has not yet been opened. *

* This method is called after the window has been created from scratch, * or when it has been restored from a previously-saved window. In the latter case, * this method is called after PostWindowRestore(). * Clients must not call this method directly (although super calls are okay). * The default implementation does nothing. Subclasses may override. *

*/ virtual void PostWindowCreate(); /** * Performs arbitrary actions after the window has been opened (possibly * after being restored). *

* This method is called after the window has been opened. This method is * called after the window has been created from scratch, or when * it has been restored from a previously-saved window. * Clients must not call this method directly (although super calls are okay). * The default implementation does nothing. Subclasses may override. *

*/ virtual void PostWindowOpen(); /** * Performs arbitrary actions as the window's shell is being closed * directly, and possibly veto the close. *

* This method is called from a IShellListener associated with the window, * for example when the user clicks the window's close button. It is not * called when the window is being closed for other reasons, such as if the * user exits the workbench via the ActionFactory#QUIT action. * Clients must not call this method directly (although super calls are * okay). If this method returns false, then the user's * request to close the shell is ignored. This gives the workbench advisor * an opportunity to query the user and/or veto the closing of a window * under some circumstances. *

* * @return true to allow the window to close, and * false to prevent the window from closing * @see IWorkbenchWindow#Close() * @see WorkbenchAdvisor#PreShutdown() */ virtual bool PreWindowShellClose(); /** * Performs arbitrary actions after the window is closed. *

* This method is called after the window's controls have been disposed. * Clients must not call this method directly (although super calls are * okay). The default implementation does nothing. Subclasses may override. *

*/ virtual void PostWindowClose(); /** * Creates the contents of the window. *

* The default implementation adds a menu bar, a cool bar, a status line, * a perspective bar, and a fast view bar. The visibility of these controls * can be configured using the SetShow* methods on * IWorkbenchWindowConfigurer. *

*

* Subclasses may override to define custom window contents and layout, * but must call IWorkbenchWindowConfigurer#CreatePageComposite(). *

* * @param shell the window's shell * @see IWorkbenchWindowConfigurer#CreateMenuBar() * @see IWorkbenchWindowConfigurer#CreateCoolBarControl() * @see IWorkbenchWindowConfigurer#CreateStatusLineControl() * @see IWorkbenchWindowConfigurer#CreatePageComposite() */ virtual void CreateWindowContents(SmartPointer shell); /** * Creates and returns the control to be shown when the window has no open pages. * If null is returned, the default window background is shown. *

* The default implementation returns null. * Subclasses may override. *

* * @param parent the parent composite * @return the control or null */ virtual QWidget* CreateEmptyWindowContents(QWidget* parent); /** * Saves arbitrary application specific state information. * * @param memento the storage area for object's state * @return a status object indicating whether the save was successful */ virtual bool SaveState(SmartPointer memento); /** * Restores arbitrary application specific state information. * * @param memento the storage area for object's state * @return a status object indicating whether the restore was successful */ virtual bool RestoreState(SmartPointer memento); }; } #endif /*BERRYWORKBENCHWINDOWADVISOR_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIContributionRoot.h b/Plugins/org.blueberry.ui.qt/src/berryIContributionRoot.h index 5b3074227d..91a1a898d2 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIContributionRoot.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIContributionRoot.h @@ -1,67 +1,67 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYICONTRIBUTIONROOT_H #define BERRYICONTRIBUTIONROOT_H #include namespace berry { struct IContributionItem; class Expression; /** * Instances of this interface represent a position in the contribution * hierarchy into which {@link AbstractContributionFactory} instances may insert * elements. Instances of this interface are provided by the platform and this * interface should NOT be implemented by clients. */ struct IContributionRoot : public Object { berryObjectMacro(berry::IContributionRoot); /** * Adds a given contribution item with provided visibility expression and * kill-switch filtering as a direct child of this container. This should be * called for all top-level elements created in * berry::AbstractContributionFactory::CreateContributionItems(). * * @param item * the item to add * @param visibleWhen * the visibility expression. May be null. */ virtual void AddContributionItem(const SmartPointer& item, const SmartPointer& visibleWhen) = 0; /** - * Registers visibilty for arbitrary {@link IContributionItem} instances + * Registers visibility for arbitrary {@link IContributionItem} instances * that are NOT direct children of this container. Ie: children of a * {@link IContributionManager} that has been previously registered with a * call to AddContributionItem(). * * @param item * the item for which to register a visibility clause * @param visibleWhen * the visibility expression. May be null in which * case this method is a no-op. */ virtual void RegisterVisibilityForChild(const SmartPointer& item, const SmartPointer& visibleWhen) = 0; }; } #endif // BERRYICONTRIBUTIONROOT_H diff --git a/Plugins/org.blueberry.ui.qt/src/berryIEditorReference.h b/Plugins/org.blueberry.ui.qt/src/berryIEditorReference.h index aa6908b2c8..8dba8713c0 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIEditorReference.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIEditorReference.h @@ -1,79 +1,79 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIEDITORREFERENCE_H_ #define BERRYIEDITORREFERENCE_H_ #include "berryIWorkbenchPartReference.h" #include "berryIEditorPart.h" #include "berryIEditorInput.h" namespace berry { /** * \ingroup org_blueberry_ui_qt * * Implements a reference to a editor. - * The IEditorPart will not be instanciated until + * The IEditorPart will not be instantiated until * the editor becomes visible or the API getEditor * is sent with true; *

* This interface is not intended to be implemented by clients. *

*/ struct BERRY_UI_QT IEditorReference : public virtual IWorkbenchPartReference { berryObjectMacro(berry::IEditorReference); ~IEditorReference() override; /** * Returns the factory id of the factory used to * restore this editor. Returns null if the editor * is not persistable. */ virtual QString GetFactoryId() = 0; /** * Returns the editor input name. May return null is the * name is not available or if the editor failed to be * restored. */ virtual QString GetName() = 0; /** * Returns the editor referenced by this object. * Returns null if the editor was not instantiated or * it failed to be restored. Tries to restore the editor * if restore is true. */ virtual IEditorPart::Pointer GetEditor(bool restore) = 0; /** * Returns the editor input for the editor referenced by this object. *

* Unlike most of the other methods on this type, this method * can trigger plug-in activation. *

* * @return the editor input for the editor referenced by this object * @throws PartInitException if there was an error restoring the editor input * @since 3.1 */ virtual IEditorInput::Pointer GetEditorInput() = 0; }; } // namespace berry #endif /*BERRYIEDITORREFERENCE_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIEditorRegistry.h b/Plugins/org.blueberry.ui.qt/src/berryIEditorRegistry.h index ac26a03df3..c1e1006973 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIEditorRegistry.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIEditorRegistry.h @@ -1,275 +1,275 @@ /*============================================================================ 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. ============================================================================*/ #ifndef MITKIEDITORREGISTRY_H_ #define MITKIEDITORREGISTRY_H_ #include "berryIEditorDescriptor.h" #include "berryIFileEditorMapping.h" namespace berry { /** * \ingroup org_blueberry_ui_qt * * Registry of editors known to the workbench. *

* An editor can be created in one of two ways: *

    *
  • An editor can be defined by an extension to the workbench.
  • *
  • The user manually associates an editor with a given resource extension * type. This will override any default workbench or platform association. *
  • *
*

*

* The registry does not keep track of editors that are "implicitly" determined. * For example a bitmap (.bmp) file will typically not have a * registered editor. Instead, when no registered editor is found, the * underlying OS is consulted. *

*

* This interface is not intended to be implemented by clients. *

* * @see org.blueberry.ui.IWorkbench#getEditorRegistry() */ struct BERRY_UI_QT IEditorRegistry { /** * The property identifier for the contents of this registry. */ static const int PROP_CONTENTS; // = 0x01; /** * The identifier for the system external editor descriptor. This descriptor * is always present in the registry on all platforms. * Use {@link #FindEditor} to access the editor descriptor for this identifier. * * @since 3.0 */ static const QString SYSTEM_EXTERNAL_EDITOR_ID; // = "org.blueberry.ui.systemExternalEditor"; /** * The identifier for the system in-place editor descriptor. This descriptor * is only present in the registry on platforms that support in-place editing * (for example Win32). Use {@link #FindEditor} to access the editor * descriptor for this identifier. * * @since 3.0 */ static const QString SYSTEM_INPLACE_EDITOR_ID; // = "org.blueberry.ui.systemInPlaceEditor"; /* * Adds a listener for changes to properties of this registry. * Has no effect if an identical listener is already registered. *

* The properties ids are as follows: *

    *
  • PROP_CONTENTS: Triggered when the file editor mappings in * the editor registry change.
  • *
*

* * @param listener a property listener */ // virtual void AddPropertyListener(IPropertyListener listener) = 0; virtual ~IEditorRegistry(); /** * Finds and returns the descriptor of the editor with the given editor id. * * @param editorId the editor id * @return the editor descriptor with the given id, or null if not * found */ virtual IEditorDescriptor::Pointer FindEditor(const QString& editorId) = 0; /** * Returns the default editor. The default editor always exist. * * @return the descriptor of the default editor * @deprecated The system external editor is the default editor. * Use findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID) * instead. */ virtual IEditorDescriptor::Pointer GetDefaultEditor() = 0; /** * Returns the default editor for a given file name. This method assumes an * unknown content type for the given file. *

* The default editor is determined by taking the file extension for the * file and obtaining the default editor for that extension. *

* * @param fileName * the file name in the system * @return the descriptor of the default editor, or null if * not found */ virtual IEditorDescriptor::Pointer GetDefaultEditor(const QString& fileName) = 0; /* * Returns the default editor for a given file name and with the given content type. *

* The default editor is determined by taking the file extension for the * file and obtaining the default editor for that extension. *

* * @param fileName the file name in the system * @param contentType the content type or null for the unknown content type * @return the descriptor of the default editor, or null if not * found * @since 3.1 */ //virtual IEditorDescriptor::Pointer GetDefaultEditor(const QString& fileName, IContentType contentType) = 0; /** * Returns the list of file editors registered to work against the file with * the given file name. This method assumes an unknown content type for the * given file. *

* Note: Use getDefaultEditor(String) if you only the need * the default editor rather than all candidate editors. *

* * @param fileName * the file name in the system * @return a list of editor descriptors */ virtual QList GetEditors(const QString& fileName) = 0; /* * Returns the list of file editors registered to work against the file with * the given file name and with the given content type. *

* Note: Use getDefaultEditor(String) if you only the need * the default editor rather than all candidate editors. *

* * @param fileName * the file name in the system * @param contentType * the content type or null for the unknown * content type * @return a list of editor descriptors * @since 3.1 */ //virtual QList GetEditors(const QString& fileName, IContentType contentType) = 0; /** * Returns a list of mappings from file type to editor. The resulting list * is sorted in ascending order by file extension. *

* Each mapping defines an extension and the set of editors that are * available for that type. The set of editors includes those registered * via plug-ins and those explicitly associated with a type by the user * in the workbench preference pages. *

* * @return a list of mappings sorted alphabetically by extension */ virtual QList GetFileEditorMappings() = 0; /* * Returns the image descriptor associated with a given file. This image is * usually displayed next to the given file. This method assumes an unknown * content type for the given file. *

* The image is determined by taking the file extension of the file and * obtaining the image for the default editor associated with that * extension. A default image is returned if no default editor is available. *

* * @param filename * the file name in the system * @return the descriptor of the image to display next to the file */ // virtual ImageDescriptor* GetImageDescriptor(const QString& filename) = 0; /* * Returns the image descriptor associated with a given file. This image is * usually displayed next to the given file. *

* The image is determined by taking the file extension of the file and * obtaining the image for the default editor associated with that * extension. A default image is returned if no default editor is available. *

* * @param filename * the file name in the system * @param contentType * the content type of the file or null for the * unknown content type * @return the descriptor of the image to display next to the file * @since 3.1 */ - // virtual ImageDescriptor* GetImageDescriptor(const std::tring& filename, IContentType contentType) = 0; + // virtual ImageDescriptor* GetImageDescriptor(const std::string& filename, IContentType contentType) = 0; /* * Removes the given property listener from this registry. * Has no affect if an identical listener is not registered. * * @param listener a property listener */ // virtual void RemovePropertyListener(IPropertyListener listener) = 0; /** * Sets the default editor id for the files that match that * specified file name or extension. The specified editor must be * defined as an editor for that file name or extension. * * @param fileNameOrExtension the file name or extension pattern (e.g. "*.xml"); * @param editorId the editor id or null for no default */ virtual void SetDefaultEditor(const QString& fileNameOrExtension, const QString& editorId) = 0; /** * Returns whether there is an in-place editor that could handle a file * with the given name. * * @param filename the file name * @return true if an in-place editor is available, and * false otherwise * @since 3.0 */ virtual bool IsSystemInPlaceEditorAvailable(const QString& filename) = 0; /** * Returns whether the system has an editor that could handle a file * with the given name. * * @param filename the file name * @return true if an external editor available, and * false otherwise * @since 3.0 */ virtual bool IsSystemExternalEditorAvailable(const QString& filename) = 0; /* * Returns the image descriptor associated with the system editor that * would be used to edit this file externally. * * @param filename the file name * @return the descriptor of the external editor image, or null * if none * @since 3.0 */ // virtual ImageDescriptor GetSystemExternalEditorImageDescriptor(const QString& filename) = 0; }; } #endif /*MITKIEDITORREGISTRY_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIEditorSite.h b/Plugins/org.blueberry.ui.qt/src/berryIEditorSite.h index f04095c4df..5d9e33a7e4 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIEditorSite.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIEditorSite.h @@ -1,128 +1,128 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIEDITORSITE_H_ #define BERRYIEDITORSITE_H_ #include "berryIWorkbenchPartSite.h" namespace berry { /** * \ingroup org_blueberry_ui_qt * * The primary interface between an editor part and the workbench. *

- * The workbench exposes its implemention of editor part sites via this + * The workbench exposes its implementation of editor part sites via this * interface, which is not intended to be implemented or extended by clients. *

*/ struct BERRY_UI_QT IEditorSite : public virtual IWorkbenchPartSite { berryObjectMacro(berry::IEditorSite); ~IEditorSite() override; /** * Returns the action bar contributor for this editor. *

- * An action contributor is responsable for the creation of actions. + * An action contributor is responsible for the creation of actions. * By design, this contributor is used for one or more editors of the same type. * Thus, the contributor returned by this method is not owned completely * by the editor - it is shared. *

* * @return the editor action bar contributor, or null if none exists */ //virtual IEditorActionBarContributor getActionBarContributor(); /** * Returns the action bars for this part site. Editors of the same type (and * in the same window) share the same action bars. Contributions to the * action bars are done by the IEditorActionBarContributor. * * @return the action bars * @since 2.1 */ //virtual IActionBars getActionBars(); /** *

* Registers a pop-up menu with the default id for extension. The default id * is defined as the part id. *

*

* By default, context menus include object contributions based on the * editor input for the current editor. It is possible to override this * behaviour by calling this method with includeEditorInput * as false. This might be desirable for editors that * present a localized view of an editor input (e.g., a node in a model * editor). *

*

* For a detailed description of context menu registration see * {@link IWorkbenchPartSite#registerContextMenu(MenuManager, ISelectionProvider)} *

* * @param menuManager * the menu manager; must not be null. * @param selectionProvider * the selection provider; must not be null. * @param includeEditorInput * Whether the editor input should be included when adding object * contributions to this context menu. * @see IWorkbenchPartSite#registerContextMenu(MenuManager, * ISelectionProvider) * @since 3.1 */ // virtual void registerContextMenu(MenuManager menuManager, // ISelectionProvider selectionProvider, boolean includeEditorInput); /** *

* Registers a pop-up menu with a particular id for extension. This method * should only be called if the target part has more than one context menu * to register. *

*

* By default, context menus include object contributions based on the * editor input for the current editor. It is possible to override this * behaviour by calling this method with includeEditorInput * as false. This might be desirable for editors that * present a localized view of an editor input (e.g., a node in a model * editor). *

*

* For a detailed description of context menu registration see * {@link IWorkbenchPartSite#registerContextMenu(MenuManager, ISelectionProvider)} *

* * @param menuId * the menu id; must not be null. * @param menuManager * the menu manager; must not be null. * @param selectionProvider * the selection provider; must not be null. * @param includeEditorInput * Whether the editor input should be included when adding object * contributions to this context menu. * @see IWorkbenchPartSite#registerContextMenu(MenuManager, * ISelectionProvider) * @since 3.1 */ // virtual void registerContextMenu(String menuId, MenuManager menuManager, // ISelectionProvider selectionProvider, boolean includeEditorInput); }; } #endif /*BERRYIEDITORSITE_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIPersistableElement.h b/Plugins/org.blueberry.ui.qt/src/berryIPersistableElement.h index 35989b56ab..368394fb91 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIPersistableElement.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIPersistableElement.h @@ -1,63 +1,63 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIPERSISTABLEELEMENT_H #define BERRYIPERSISTABLEELEMENT_H #include namespace berry { /** * Interface for asking an object to store its state in a memento. *

* This interface is typically included in interfaces where - * persistance is required. + * persistence is required. *

* When the workbench is shutdown objects which implement this interface * will be persisted. At this time the GetFactoryId method * is invoked to discover the id of the element factory that will be used * to re-create the object from a memento. Then the SaveState * method is invoked to store the element data into a newly created memento. * The resulting mementos are collected up and written out to a single file. *

*

* During workbench startup these mementos are read from the file. The * factory Id for each is retrieved and mapped to an IElementFactory * which has been registered in the element factory extension point. If a * factory exists for the Id it will be engaged to re-create the original * object. *

* * @see IAdaptable * @see IMemento * @see IElementFactory */ struct IPersistableElement : public IPersistable { /** * Returns the id of the element factory which should be used to re-create this * object. *

* Factory ids are declared in extensions to the standard extension point * "org.eclipse.ui.elementFactories". *

* * @return the element factory id * @see IElementFactory */ virtual QString GetFactoryId() const = 0; }; } #endif // BERRYIPERSISTABLEELEMENT_H diff --git a/Plugins/org.blueberry.ui.qt/src/berryIStructuredSelection.h b/Plugins/org.blueberry.ui.qt/src/berryIStructuredSelection.h index 726dfa4325..4395446aab 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIStructuredSelection.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIStructuredSelection.h @@ -1,84 +1,84 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYISTRUCTUREDSELECTION_H_ #define BERRYISTRUCTUREDSELECTION_H_ #include "berryISelection.h" #include #include namespace berry { /** * A selection containing elements. */ struct BERRY_UI_QT IStructuredSelection : public ISelection { typedef ObjectList ContainerType; typedef ContainerType::const_iterator iterator; berryObjectMacro(berry::IStructuredSelection); /** * Returns the first element in this selection, or null * if the selection is empty. * * @return an element, or null if none */ virtual Object::Pointer GetFirstElement() const = 0; /** * Returns an iterator to the beginning of the elements of this selection. * * @return an iterator over the selected elements */ virtual iterator Begin() const = 0; /** * Returns an iterator to the end of the elements of this selection. * * @return an iterator over the selected elements */ virtual iterator End() const = 0; /** * Returns the number of elements selected in this selection. * * @return the number of elements selected */ virtual int Size() const = 0; /** * Returns the elements in this selection as a vector. * * @return the selected elements as a vector */ virtual ContainerType::Pointer ToVector() const = 0; /* * We need to define at least the destructor in this compilation unit * because of the export macro above. Otherwise Windows throws - * a linker error in dependent librraies. The export macro is needed + * a linker error in dependent libraries. The export macro is needed * for gcc < 4.5 to correctly mark the type_info object of this class * as visible (we have default visibility 'hidden') so that dynamic_cast calls work. */ ~IStructuredSelection() override; }; } #endif /* BERRYISTRUCTUREDSELECTION_H_ */ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIViewSite.h b/Plugins/org.blueberry.ui.qt/src/berryIViewSite.h index 70f052e120..ed4a144795 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIViewSite.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIViewSite.h @@ -1,57 +1,57 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIVIEWSITE_H_ #define BERRYIVIEWSITE_H_ #include "berryIWorkbenchPartSite.h" #include namespace berry { /** * \ingroup org_blueberry_ui_qt * * The primary interface between a view part and the workbench. *

- * The workbench exposes its implemention of view part sites via this interface, + * The workbench exposes its implementation of view part sites via this interface, * which is not intended to be implemented or extended by clients. *

*/ struct BERRY_UI_QT IViewSite : public virtual IWorkbenchPartSite { berryObjectMacro(berry::IViewSite); ~IViewSite() override; /** * Returns the action bars for this part site. * Views have exclusive use of their site's action bars. * * @return the action bars */ //IActionBars getActionBars(); /** * Returns the secondary id for this part site's part, * or null if it has none. * * @see IWorkbenchPage#showView(String, String, int) */ virtual QString GetSecondaryId() = 0; }; } #endif /*BERRYIVIEWSITE_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIWorkbench.h b/Plugins/org.blueberry.ui.qt/src/berryIWorkbench.h index 905f58a87f..8876d7e112 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIWorkbench.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIWorkbench.h @@ -1,421 +1,421 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIWORKBENCH_H_ #define BERRYIWORKBENCH_H_ #include #include "services/berryIServiceLocator.h" #include "berryIViewRegistry.h" #include "berryIEditorRegistry.h" #include "intro/berryIIntroManager.h" #include "berryIPerspectiveRegistry.h" #include "berryIWorkbenchWindow.h" #include "berryIWorkbenchListener.h" #include "berryIWindowListener.h" #include "berryDisplay.h" namespace berry { struct IElementFactory; struct IExtensionTracker; struct IWorkbenchPage; /** * \ingroup org_blueberry_ui_qt * * A workbench is the root object for the BlueBerry Platform user interface. *

* A workbench has one or more main windows which present to the end * user information based on some underlying model, typically on resources in an * underlying workspace. A workbench usually starts with a single open window, * and automatically closes when its last window closes. *

*

* Each workbench window has a collection of pages; the active * page is the one that is being presented to the end user; at most one page is * active in a window at a time. *

*

* Each workbench page has a collection of workbench parts, of which * there are two kinds: views and editors. A page's parts are arranged (tiled or * stacked) for presentation on the screen. The arrangement is not fixed; the * user can arrange the parts as they see fit. A perspective is a * template for a page, capturing a collection of parts and their arrangement. *

*

* The platform creates a workbench when the workbench plug-in is activated; * since this happens at most once during the life of the running platform, * there is only one workbench instance. Due to its singular nature, it is * commonly referred to as the workbench. *

*

* The workbench supports a few {@link IServiceLocator services} by default. If * these services are used to allocate resources, it is important to remember to * clean up those resources after you are done with them. Otherwise, the * resources will exist until the workbench shuts down. The supported services * are: *

*
    *
  • {@link ICommandService}
  • *
  • {@link IContextService}
  • *
  • {@link IHandlerService}
  • *
*

* This interface is not intended to be implemented by clients. *

* * @see PlatformUI#GetWorkbench */ struct BERRY_UI_QT IWorkbench : public IServiceLocator { berryObjectMacro(berry::IWorkbench); ~IWorkbench() override; /** * Returns the display for this workbench. *

* Code should always ask the workbench for the display rather than rely on * {@link Display#GetDefault Display.getDefault()}. *

* * @return the display to be used for all UI interactions with this * workbench */ virtual Display* GetDisplay() const = 0; /** * Adds a workbench listener. * * @param listener * the workbench listener to add * @since 3.2 */ virtual void AddWorkbenchListener(IWorkbenchListener* listener) = 0; /** * Removes a workbench listener. * * @param listener * the workbench listener to remove * @since 3.2 */ virtual void RemoveWorkbenchListener(IWorkbenchListener* listener) = 0; /** * Returns the workbench events object */ virtual IWorkbenchListener::Events& GetWorkbenchEvents() = 0; /** * Adds a window listener. * * @param listener * the window listener to add * @since 2.0 */ virtual void AddWindowListener(IWindowListener* listener) = 0; /** * Removes a window listener. * * @param listener * the window listener to remove * @since 2.0 */ virtual void RemoveWindowListener(IWindowListener* listener) = 0; /** * Returns the window events object * */ virtual IWindowListener::Events& GetWindowEvents() = 0; /** * Closes this workbench and all its open windows. *

* If the workbench has an open editor with unsaved content, the user will * be given the opportunity to save it. *

* * @return true if the workbench was successfully closed, and * false if it is still open */ virtual bool Close() = 0; /** * Returns the currently active window for this workbench (if any). Returns * null if there is no active workbench window. Returns * null if called from a non-UI thread. * * @return the active workbench window, or null if there is * no active workbench window or if called from a non-UI thread */ virtual IWorkbenchWindow::Pointer GetActiveWorkbenchWindow() const = 0; /** * Return the extension tracker for the workbench. This tracker may be used * by plug-ins to ensure responsiveness to changes to the plug-in registry. *

* The tracker at this level of the workbench is typically used to track * elements that persist for the life of the workbench. For example, * IEditorDescriptor objects fall into this category. *

* * @return the extension tracker * @see IWorkbenchWindow#GetExtensionTracker() * @see IWorkbenchPage#GetExtensionTracker() */ virtual IExtensionTracker* GetExtensionTracker() const = 0; /** * Returns the perspective registry for the workbench. * * @return the workbench perspective registry */ virtual IPerspectiveRegistry* GetPerspectiveRegistry() const = 0; /** * Returns the view registry for the workbench. * * @return the workbench view registry * @since 3.1 */ virtual IViewRegistry* GetViewRegistry() const = 0; /** * Returns the editor registry for the workbench. * * @return the workbench editor registry */ virtual IEditorRegistry* GetEditorRegistry() const = 0; /** * Returns the number of open main windows associated with this workbench. * Note that wizards and dialogs are not included in this list since they * are not considered main windows. * * @return the number of open windows * @since 3.0 */ virtual std::size_t GetWorkbenchWindowCount() const = 0; /** * Returns a list of the open main windows associated with this workbench. * Note that wizards and dialogs are not included in this list since they * are not considered main windows. * * @return a list of open windows */ virtual QList GetWorkbenchWindows() const = 0; /** * Creates and opens a new workbench window with one page. The perspective * of the new page is defined by the specified perspective ID. The new * window and new page become active. *

* Note: The caller is responsible to ensure the action using this * method will explicitly inform the user a new window will be opened. * Otherwise, callers are strongly recommended to use the * openPerspective APIs to programmatically show a * perspective to avoid confusing the user. *

*

* In most cases where this method is used the caller is tightly coupled to * a particular perspective. They define it in the registry and contribute * some user interface action to open or activate it. In situations like * this a static variable is often used to identify the perspective ID. *

* * @param perspectiveId * the perspective id for the window's initial page, or * null for no initial page * @param input * the page input, or null if there is no current * input. This is used to seed the input for the new page's * views. * @return the new workbench window * @exception WorkbenchException * if a new window and page could not be opened * * @see IWorkbench#showPerspective(String, IWorkbenchWindow, IAdaptable) */ virtual IWorkbenchWindow::Pointer OpenWorkbenchWindow(const QString& perspectiveId, IAdaptable* input) = 0; /** * Creates and opens a new workbench window with one page. The perspective * of the new page is defined by the default perspective ID. The new window * and new page become active. *

* Note: The caller is responsible to ensure the action using this * method will explicitly inform the user a new window will be opened. * Otherwise, callers are strongly recommended to use the * openPerspective APIs to programmatically show a * perspective to avoid confusing the user. *

* * @param input * the page input, or null if there is no current * input. This is used to seed the input for the new page's * views. * @return the new workbench window * @exception WorkbenchException * if a new window and page could not be opened * * @see IWorkbench#showPerspective(String, IWorkbenchWindow, IAdaptable) */ virtual IWorkbenchWindow::Pointer OpenWorkbenchWindow(IAdaptable* input) = 0; /** * Shows the specified perspective to the user. The caller should use this * method when the perspective to be shown is not dependent on the page's * input. That is, the perspective can open in any page depending on user * preferences. *

* The perspective may be shown in the specified window, in another existing * window, or in a new window depending on user preferences. The exact * policy is controlled by the workbench to ensure consistency to the user. * The policy is subject to change. The current policy is as follows: *

    *
  • If the specified window has the requested perspective open, then the * window is given focus and the perspective is shown. The page's input is * ignored.
  • *
  • If another window that has the workspace root as input and the * requested perspective open and active, then the window is given focus. *
  • *
  • Otherwise the requested perspective is opened and shown in the * specified window or in a new window depending on the current user * preference for opening perspectives, and that window is given focus. *
  • *
*

*

* The workbench also defines a number of menu items to activate or open * each registered perspective. A complete list of these perspectives is * available from the perspective registry found on IWorkbench. *

* * @param perspectiveId * the perspective ID to show * @param window * the workbench window of the action calling this method. * @return the workbench page that the perspective was shown * @exception WorkbenchException * if the perspective could not be shown * * @since 2.0 */ virtual SmartPointer ShowPerspective(const QString& perspectiveId, IWorkbenchWindow::Pointer window) = 0; /** * Shows the specified perspective to the user. The caller should use this * method when the perspective to be shown is dependent on the page's input. * That is, the perspective can only open in any page with the specified * input. *

* The perspective may be shown in the specified window, in another existing * window, or in a new window depending on user preferences. The exact * policy is controlled by the workbench to ensure consistency to the user. * The policy is subject to change. The current policy is as follows: *

    *
  • If the specified window has the requested perspective open and the * same requested input, then the window is given focus and the perspective * is shown.
  • *
  • If another window has the requested input and the requested * perspective open and active, then that window is given focus.
  • *
  • If the specified window has the same requested input but not the * requested perspective, then the window is given focus and the perspective * is opened and shown on condition that the user preference is not to open * perspectives in a new window.
  • *
  • Otherwise the requested perspective is opened and shown in a new * window, and the window is given focus.
  • *
*

*

* The workbench also defines a number of menu items to activate or open * each registered perspective. A complete list of these perspectives is * available from the perspective registry found on IWorkbench. *

* * @param perspectiveId * the perspective ID to show * @param window * the workbench window of the action calling this method. * @param input * the page input, or null if there is no current * input. This is used to seed the input for the page's views * @return the workbench page that the perspective was shown * @exception WorkbenchException * if the perspective could not be shown * * @since 2.0 */ virtual SmartPointer ShowPerspective(const QString& perspectiveId, IWorkbenchWindow::Pointer window, IAdaptable* input) = 0; /** * Save all dirty editors in the workbench. Opens a dialog to prompt the * user if confirm is true. Return true if successful. Return * false if the user has canceled the command. * * @param confirm true to ask the user before saving unsaved * changes (recommended), and false to save * unsaved changes without asking * @return true if the command succeeded, and * false if the operation was canceled by the user or * an error occurred while saving */ virtual bool SaveAllEditors(bool confirm) = 0; /** - * Returns the element factory with the given id. The calles takes + * Returns the element factory with the given id. The call takes * ownership of the returned pointer. * * @param factoryId * the id of the element factory * @return the element factory, or null if none * @see IElementFactory */ virtual IElementFactory* GetElementFactory(const QString& factoryId) const = 0; /** * Return the intro manager for this workbench. * * @return the intro manager for this workbench. Guaranteed not to be * null. */ virtual IIntroManager* GetIntroManager() const = 0; /** * Returns a boolean indicating whether the workbench is in the process of * closing. * * @return true if the workbench is in the process of * closing, false otherwise * @since 3.1 */ virtual bool IsClosing() const = 0; /** * Applies changes of the current theme to the user interface. */ virtual void UpdateTheme() = 0; }; } #endif /*BERRYIWORKBENCH_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryIWorkbenchPartReference.h b/Plugins/org.blueberry.ui.qt/src/berryIWorkbenchPartReference.h index cc5c390f3b..d205ac78c2 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryIWorkbenchPartReference.h +++ b/Plugins/org.blueberry.ui.qt/src/berryIWorkbenchPartReference.h @@ -1,138 +1,138 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYIWORKBENCHPARTREFERENCE_H_ #define BERRYIWORKBENCHPARTREFERENCE_H_ #include #include #include "berryIPropertyChangeListener.h" namespace berry { struct IWorkbenchPart; struct IWorkbenchPage; /** * \ingroup org_blueberry_ui_qt * * Implements a reference to a IWorkbenchPart. - * The IWorkbenchPart will not be instanciated until the part + * The IWorkbenchPart will not be instantiated until the part * becomes visible or the API getPart is sent with true; *

* This interface is not intended to be implemented by clients. *

*/ struct BERRY_UI_QT IWorkbenchPartReference : public Object { berryObjectMacro(berry::IWorkbenchPartReference); ~IWorkbenchPartReference() override; /** * Returns the IWorkbenchPart referenced by this object. * Returns null if the editors was not instantiated or * it failed to be restored. Tries to restore the editor * if restore is true. */ virtual SmartPointer GetPart(bool restore) = 0; /** * @see IWorkbenchPart#getTitleImage */ virtual QIcon GetTitleImage() const = 0; /** * @see IWorkbenchPart#getTitleToolTip */ virtual QString GetTitleToolTip() const = 0; /** * @see IWorkbenchPartSite#getId */ virtual QString GetId() const = 0; /** * @see IWorkbenchPart#addPropertyListener */ virtual void AddPropertyListener(IPropertyChangeListener* listener) = 0; /** * @see IWorkbenchPart#removePropertyListener */ virtual void RemovePropertyListener(IPropertyChangeListener* listener) = 0; /** * Returns the workbench page that contains this part */ virtual SmartPointer GetPage() const = 0; /** * Returns the name of the part, as it should be shown in tabs. * * @return the part name */ virtual QString GetPartName() const = 0; /** * Returns the content description for the part (or the empty string if none) * * @return the content description for the part */ virtual QString GetContentDescription() const = 0; /** * Returns true if the part is pinned otherwise returns false. */ virtual bool IsPinned() const = 0; /** * Returns whether the part is dirty (i.e. has unsaved changes). * * @return true if the part is dirty, false otherwise */ virtual bool IsDirty() const = 0; /** * Return an arbitrary property from the reference. If the part has been * instantiated, it just delegates to the part. If not, then it looks in its * own cache of properties. If the property is not available or the part has * never been instantiated, it can return null. * * @param key * The property to return. Must not be null. * @return The String property, or null. */ virtual QString GetPartProperty(const QString& key) const = 0; /** * Add a listener for changes in the arbitrary properties set. * * @param listener * Must not be null. */ //virtual void addPartPropertyListener(IPropertyChangeListener listener) = 0; /** * Remove a listener for changes in the arbitrary properties set. * * @param listener * Must not be null. */ //virtual void removePartPropertyListener(IPropertyChangeListener listener) = 0; }; } // namespace berry #endif /*BERRYIWORKBENCHPARTREFERENCE_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/berryMenuUtil.h b/Plugins/org.blueberry.ui.qt/src/berryMenuUtil.h index 12332c5974..ee61eb4867 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryMenuUtil.h +++ b/Plugins/org.blueberry.ui.qt/src/berryMenuUtil.h @@ -1,134 +1,134 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYMENUUTIL_H #define BERRYMENUUTIL_H #include namespace berry { /** * Provides utilities and constants for use with the new menus API. * * @note This class is not intended to be subclassed by clients. * @note This class is not intended to be instantiated by clients. */ class BERRY_UI_QT MenuUtil { public: /** * * Workbench Menu. On supported platforms, this menu is shown when no * workbench windows are active */ static QString WORKBENCH_MENU; // = "menu:org.blueberry.ui.workbench.menu"; /** Main Menu */ static QString MAIN_MENU; // = "menu:org.blueberry.ui.main.menu"; /** Main ToolBar */ static QString MAIN_TOOLBAR; // = "toolbar:org.blueberry.ui.main.toolbar"; /** -Any- Popup Menu */ static QString ANY_POPUP; // = "popup:org.blueberry.ui.popup.any"; /** * Valid query attribute. Usage menu:menu.id?before=contribution.id. */ static QString QUERY_BEFORE; // = "before"; /** * Valid query attribute. Usage menu:menu.id?after=contribution.id. */ static QString QUERY_AFTER; // = "after"; /** * Valid query attribute. Usage menu:menu.id?endof=contribution.id. *

* This menu contribution will be placed at the end of the group defined by * contribution.id (usually right in front of the next group marker * or separator). Further contribution processing can still place other * contributions after this one. *

*/ static QString QUERY_ENDOF; // = "endof"; /** * Contributions of targets to this location will be included with the show * in menu. */ static QString SHOW_IN_MENU_ID; // = "popup:org.blueberry.ui.menus.showInMenu"; /** * @param id * The menu's id * @return The locator URI for a menu with the given id */ static QString MenuUri(const QString& id); /** * @param id * The id of the menu * @param location * The relative location specifier * @param refId * The id of the menu element to be relative to * @return A location URI formatted with the given parameters */ static QString MenuAddition(const QString& id, const QString& location, const QString& refId); /** * Convenience method to create a standard menu addition The resulting * string has the format: "menu:[id]?after=additions" * * @param id * The id of the root element to contribute to * @return The formatted string */ static QString MenuAddition(const QString& id); /** * @param id * The toolbar's id - * @return The lcoation URI for a toolbar with the given id + * @return The location URI for a toolbar with the given id */ static QString ToolbarUri(const QString& id); /** * @param id * The id of the toolbar * @param location * The relative location specifier * @param refId * The id of the toolbar element to be relative to * @return A location URI formatted with the given parameters */ static QString ToolbarAddition(const QString& id, const QString& location, const QString& refId); /** * Convenience method to create a standard toolbar addition The resulting * string has the format: "toolbar:[id]?after=additions" * * @param id * The id of the root element to contribute to * @return The formatted string */ static QString ToolbarAddition(const QString& id); }; } #endif // BERRYMENUUTIL_H diff --git a/Plugins/org.blueberry.ui.qt/src/berryPropertyChangeEvent.h b/Plugins/org.blueberry.ui.qt/src/berryPropertyChangeEvent.h index 740bb995cc..e54c0d7a3b 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryPropertyChangeEvent.h +++ b/Plugins/org.blueberry.ui.qt/src/berryPropertyChangeEvent.h @@ -1,125 +1,125 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYPROPERTYCHANGEEVENT_H_ #define BERRYPROPERTYCHANGEEVENT_H_ #include #include #include namespace berry { /** * An event object describing a change to a named property. *

* This concrete class was designed to be instantiated, but may * also be subclassed if required. *

*

* The JFace frameworks contain classes that report property * change events for internal state changes that may be of interest * to external parties. A special listener interface * (IPropertyChangeListener) is defined for this purpose, * and a typical class allow listeners to be registered via * an addPropertyChangeListener method. *

* * @see IPropertyChangeListener */ class BERRY_UI_QT PropertyChangeEvent : public Object { public: berryObjectMacro(PropertyChangeEvent); private: /** * The name of the changed property. */ QString propertyName; /** * The old value of the changed property, or null if * not known or not relevant. */ Object::Pointer oldValue; /** * The new value of the changed property, or null if * not known or not relevant. */ Object::Pointer newValue; /** - * The object on which the property change occured + * The object on which the property change occurred */ Object::Pointer source; public: /** * Creates a new property change event. * * @param source the object whose property has changed * @param property the property that has changed (must not be null) * @param oldValue the old value of the property, or null if none * @param newValue the new value of the property, or null if none */ PropertyChangeEvent(Object::Pointer source, const QString& property, Object::Pointer oldValue, Object::Pointer newValue); /** * Returns the new value of the property. * * @return the new value, or null if not known * or not relevant (for instance if the property was removed). */ Object::Pointer GetNewValue(); /** * Returns the old value of the property. * * @return the old value, or null if not known * or not relevant (for instance if the property was just * added and there was no old value). */ Object::Pointer GetOldValue(); /** * Returns the name of the property that changed. *

* Warning: there is no guarantee that the property name returned * is a constant string. Callers must compare property names using * equals, not ==. *

* * @return the name of the property that changed */ QString GetProperty(); /** * Returns the object whose property has changed * * @return the object whose property has changed */ Object::Pointer GetSource(); }; } #endif /* BERRYPROPERTYCHANGEEVENT_H_ */ diff --git a/Plugins/org.blueberry.ui.qt/src/berrySameShellProvider.h b/Plugins/org.blueberry.ui.qt/src/berrySameShellProvider.h index e94e1595cd..c14ad3970b 100644 --- a/Plugins/org.blueberry.ui.qt/src/berrySameShellProvider.h +++ b/Plugins/org.blueberry.ui.qt/src/berrySameShellProvider.h @@ -1,70 +1,70 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYSAMESHELLPROVIDER_H_ #define BERRYSAMESHELLPROVIDER_H_ #include #include "berryShell.h" #include #include "berryIShellProvider.h" namespace berry { /** * Standard shell provider that always returns the shell containing the given * control. This will always return the correct shell for the control, even if * the control is reparented. * * @since 3.1 */ class BERRY_UI_QT SameShellProvider : public IShellProvider { private: QWidget* targetControl; Shell::Pointer shell; public: berryObjectMacro(SameShellProvider); /** * Returns a shell provider that always returns the current * shell for the given control. * * @param targetControl control whose shell will be tracked, or null if getShell() should always * return null */ SameShellProvider(QWidget* targetControl); /** * Returns a shell provider that always returns the given shell. * * @param shell the shell which should always be returned, - * or null if GetShell() should alway return null + * or null if GetShell() should always return null */ SameShellProvider(Shell::Pointer shell); /* (non-javadoc) * @see IShellProvider#getShell() */ Shell::Pointer GetShell() const override; }; } #endif /* BERRYSAMESHELLPROVIDER_H_ */ diff --git a/Plugins/org.blueberry.ui.qt/src/berryWindow.h b/Plugins/org.blueberry.ui.qt/src/berryWindow.h index beab88ed1a..56ea246b1c 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryWindow.h +++ b/Plugins/org.blueberry.ui.qt/src/berryWindow.h @@ -1,675 +1,675 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYWINDOW_H_ #define BERRYWINDOW_H_ #include #include "berryIShellProvider.h" #include "berryIShellListener.h" #include "internal/berryWindowManager.h" #include "tweaklets/berryGuiWidgetsTweaklet.h" #include #include namespace berry { //struct IToolBarManager; class MenuManager; //class StatusLineManager; /** * A JFace window is an object that has no visual representation (no widgets) * until it is told to open. *

* Creating a window involves the following steps: *

    *
  • creating an instance of a concrete subclass of Window *
  • *
  • creating the window's shell and widget tree by calling * create (optional)
  • *
  • assigning the window to a window manager using * WindowManager.add (optional)
  • *
  • opening the window by calling open
  • *
* Opening the window will create its shell and widget tree if they have not * already been created. When the window is closed, the shell and widget tree * are disposed of and are no longer referenced, and the window is automatically * removed from its window manager. A window may be reopened. *

*

* The JFace window framework (this package) consists of this class, * Window, the abstract base of all windows, and one concrete * window classes (ApplicationWindow) which may also be * subclassed. Clients may define additional window subclasses as required. *

*

* The Window class provides methods that subclasses may * override to configure the window, including: *

    *
  • close- extend to free other SWT resources
  • *
  • configureShell- extend or reimplement to set shell * properties before window opens
  • *
  • createContents- extend or reimplement to create controls * before window opens
  • *
  • getInitialSize- reimplement to give the initial size for * the shell
  • *
  • getInitialLocation- reimplement to give the initial * location for the shell
  • *
  • getShellListener- extend or reimplement to receive shell * events
  • *
  • handleFontChange- reimplement to respond to font changes *
  • *
  • handleShellCloseEvent- extend or reimplement to handle * shell closings
  • *
*

*/ class BERRY_UI_QT Window: public IShellProvider { public: berryObjectMacro(Window, IShellProvider); /** * Standard return code constant (value 0) indicating that the window was * opened. * * @see #Open */ static const int OK; // = 0; /** * Standard return code constant (value 1) indicating that the window was * canceled. * * @see #Open */ static const int CANCEL; // = 1; /** * An array of images to be used for the window. It is expected that the * array will contain the same icon rendered at different resolutions. */ static QList defaultImages; /** * This interface defines a Exception Handler which can be set as a global * handler and will be called if an exception happens in the event loop. */ struct IExceptionHandler: public Object { berryObjectMacro(IExceptionHandler); /** * Handle the exception. * * @param t - * The exception that occured. + * The exception that occurred. */ virtual void HandleException(const std::exception& t) = 0; }; private: struct WindowShellListener : public IShellListener { WindowShellListener(Window* wnd); void ShellClosed(const ShellEvent::Pointer& event) override; private: Window* window; }; QScopedPointer windowShellListener; /** * Defines a default exception handler. */ struct DefaultExceptionHandler: public IExceptionHandler { /* * (non-Javadoc) * * @see org.blueberry.jface.window.Window.IExceptionHandler#handleException(java.lang.Throwable) */ void HandleException(const std::exception& t) override; }; /** * Menu bar manager, or null if none (default). * * @see #AddMenuBar */ SmartPointer menuBarManager; /** * The exception handler for this application. */ static IExceptionHandler::Pointer exceptionHandler; /** * Object used to locate the default parent for modal shells */ struct DefaultModalParent: public IShellProvider { Shell::Pointer GetShell() const override; }; friend struct DefaultModalParent; static IShellProvider::Pointer defaultModalParent; /** * Object that returns the parent shell. */ IShellProvider::Pointer parentShell; /** * Shell style bits. * * @see #setShellStyle */ int shellStyle; // = Constants::SHELL_TRIM; /** * Window manager, or null if none. * * @see #setWindowManager */ WindowManager* windowManager; /** * Window shell, or null if none. */ Shell::Pointer shell; /** * Top level SWT control, or null if none */ QWidget* contents; /** * Window return code; initially OK. * * @see #setReturnCode */ int returnCode; // = OK; /** * true if the open method should not return * until the window closes, and false if the * open method should return immediately; initially * false (non-blocking). * * @see #setBlockOnOpen */ bool block; // = false; /** * Returns the most specific modal child from the given list of Shells. * * @param toSearch shells to search for modal children * @return the most specific modal child, or null if none * * @since 3.1 */ static Shell::Pointer GetModalChild( const QList& toSearch); protected: /** * Creates a window instance, whose shell will be created under the given * parent shell. Note that the window will have no visual representation * until it is told to open. By default, open does not block. * * @param parentShell * the parent shell, or null to create a top-level * shell. Try passing "(Shell)null" to this method instead of "null" * if your compiler complains about an ambiguity error. * @see #SetBlockOnOpen */ Window(Shell::Pointer parentShell); /** * Creates a new window which will create its shell as a child of whatever * the given shellProvider returns. * * @param shellProvider object that will return the current parent shell. Not null. * */ Window(IShellProvider::Pointer shellProvider); ~Window() override; /** * Given the desired position of the window, this method returns an adjusted * position such that the window is no larger than its monitor, and does not * extend beyond the edge of the monitor. This is used for computing the * initial window position, and subclasses can use this as a utility method * if they want to limit the region in which the window may be moved. * * @param preferredSize * the preferred position of the window * @return a rectangle as close as possible to preferredSize that does not * extend outside the monitor * */ QRect GetConstrainedShellBounds(const QRect& preferredSize); /** * Initializes this windows variables */ virtual void Init(); /** * Determines if the window should handle the close event or do nothing. *

* The default implementation of this framework method returns * true, which will allow the * handleShellCloseEvent method to be called. Subclasses may * extend or reimplement. *

* * @return whether the window should handle the close event. */ virtual bool CanHandleShellCloseEvent(); /** * Configures the given shell in preparation for opening this window in it. *

* The default implementation of this framework method sets the shell's * image and gives it a grid layout. Subclasses may extend or reimplement. *

* * @param newShell * the shell */ virtual void ConfigureShell(Shell::Pointer newShell); /** * Creates and returns this window's contents. Subclasses may attach any * number of children to the parent. As a convenience, the return value of * this method will be remembered and returned by subsequent calls to * getContents(). Subclasses may modify the parent's layout if they overload * getLayout() to return null. * *

- * It is common practise to create and return a single composite that + * It is common practice to create and return a single composite that * contains the entire window contents. *

* *

* The default implementation of this framework method creates an instance * of Composite. Subclasses may override. *

* * @param parent * the parent composite for the controls in this window. The type * of layout used is determined by getLayout() * * @return the control that will be returned by subsequent calls to * getContents() */ virtual QWidget* CreateContents(Shell::Pointer parent); /** * Creates and returns this window's shell. *

* The default implementation of this framework method creates a new shell * and configures it using configureShell. Rather than * override this method, subclasses should instead override * configureShell. *

* * @return the shell */ virtual Shell::Pointer CreateShell(); /** * Returns the top level control for this window. The parent of this control * is the shell. * * @return the top level control, or null if this window's * control has not been created yet */ virtual QWidget* GetContents(); /** * Returns the initial location to use for the shell. The default * implementation centers the shell horizontally (1/2 of the difference to * the left and 1/2 to the right) and vertically (1/3 above and 2/3 below) * relative to the parent shell, or display bounds if there is no parent * shell. * * @param initialSize * the initial size of the shell, as returned by * getInitialSize. * @return the initial location of the shell */ virtual QPoint GetInitialLocation(const QPoint& initialSize); /** * Returns the initial size to use for the shell. The default implementation * returns the preferred size of the shell, using * Shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true). * * @return the initial size of the shell */ virtual QPoint GetInitialSize(); /** * Returns parent shell, under which this window's shell is created. * * @return the parent shell, or null if there is no parent * shell */ Shell::Pointer GetParentShell(); /** * Returns a shell listener. This shell listener gets registered with this * window's shell. *

* The default implementation of this framework method returns a new * listener that makes this window the active window for its window manager * (if it has one) when the shell is activated, and calls the framework * method handleShellCloseEvent when the shell is closed. * Subclasses may extend or reimplement. *

* * @return a shell listener */ virtual IShellListener* GetShellListener(); /** * Returns the shell style bits. *

* The default value is SWT.CLOSE|SWT.MIN|SWT.MAX|SWT.RESIZE. * Subclassers should call setShellStyle to change this * value, rather than overriding this method. *

* * @return the shell style bits */ int GetShellStyle(); /** * Notifies that the window's close button was pressed, the close menu was * selected, or the ESCAPE key pressed. *

* The default implementation of this framework method sets the window's * return code to CANCEL and closes the window using * close. Subclasses may extend or reimplement. *

*/ virtual void HandleShellCloseEvent(); /** * Initializes the location and size of this window's SWT shell after it has * been created. *

* This framework method is called by the create framework * method. The default implementation calls getInitialSize * and getInitialLocation and passes the results to * Shell.setBounds. This is only done if the bounds of the * shell have not already been modified. Subclasses may extend or * reimplement. *

*/ virtual void InitializeBounds(); /** * Changes the parent shell. This is only safe to use when the shell is not * yet realized (i.e., created). Once the shell is created, it must be * disposed (i.e., closed) before this method can be called. * * @param newParentShell * The new parent shell; this value may be null if * there is to be no parent. * @since 3.1 */ void SetParentShell(Shell::Pointer newParentShell); /** * Sets this window's return code. The return code is automatically returned * by open if block on open is enabled. For non-blocking * opens, the return code needs to be retrieved manually using * getReturnCode. * * @param code * the return code */ void SetReturnCode(int code); /** * Sets the shell style bits. This method has no effect after the shell is * created. *

* The shell style bits are used by the framework method * createShell when creating this window's shell. *

* * @param newShellStyle * the new shell style bits */ void SetShellStyle(int newShellStyle); /** * Configures this window to have a menu bar. * Does nothing if it already has one. * This method must be called before this window's shell is created. */ void AddMenuBar(); /** * Returns a new menu manager for the window. *

* Subclasses may override this method to customize the menu manager. *

* @return a menu manager */ virtual SmartPointer CreateMenuManager(); /** * Creates the trim widgets around the content area. * * @param shell the shell */ virtual void CreateTrimWidgets(SmartPointer shell); public: /** * Closes this window, disposes its shell, and removes this window from its * window manager (if it has one). *

* This framework method may be extended (super.close must * be called). *

*

* Note that in order to prevent recursive calls to this method * it does not call Shell#close(). As a result ShellListeners * will not receive a shellClosed event. *

* * @return true if the window is (or was already) closed, and * false if it is still open */ virtual bool Close(); /** * Creates this window's widgetry in a new top-level shell. *

* The default implementation of this framework method creates this window's * shell (by calling createShell), and its controls (by * calling createContents), then initializes this window's * shell bounds (by calling initializeBounds). *

*/ virtual void Create(); /** * Returns the default image. This is the image that will be used for * windows that have no shell image at the time they are opened. There is no * default image unless one is installed via setDefaultImage. * * @return the default image, or null if none * @see #SetDefaultImage */ static QIcon GetDefaultImage(); /** * Returns the array of default images to use for newly opened windows. It * is expected that the array will contain the same icon rendered at * different resolutions. * * @see org.blueberry.swt.widgets.Decorations#setImages(org.blueberry.swt.graphics.Image[]) * * @return the array of images to be used when a new window is opened * @see #SetDefaultImages * @since 3.0 */ static QList GetDefaultImages(); /** * Returns this window's return code. A window's return codes are * window-specific, although two standard return codes are predefined: * OK and CANCEL. * * @return the return code */ int GetReturnCode(); /** * Returns this window's shell. * * @return this window's shell, or null if this window's * shell has not been created yet */ Shell::Pointer GetShell() const override; /** * Returns the window manager of this window. * * @return the WindowManager, or null if none */ WindowManager* GetWindowManager(); /** * Returns the menu bar manager for this window (if it has one). * * @return the menu bar manager, or null if * this window does not have a menu bar * @see #AddMenuBar() */ MenuManager* GetMenuBarManager() const; /** * Opens this window, creating it first if it has not yet been created. *

* If this window has been configured to block on open ( * setBlockOnOpen), this method waits until the window is * closed by the end user, and then it returns the window's return code; * otherwise, this method returns immediately. A window's return codes are * window-specific, although two standard return codes are predefined: * OK and CANCEL. *

* * @return the return code * * @see #Create() */ int Open(); /** * Sets whether the open method should block until the window * closes. * * @param shouldBlock * true if the open method should * not return until the window closes, and false * if the open method should return immediately */ void SetBlockOnOpen(bool shouldBlock); /** * Sets the default image. This is the image that will be used for windows * that have no shell image at the time they are opened. There is no default * image unless one is installed via this method. * * @param image * the default image, or null if none */ static void SetDefaultImage(const QIcon& image); /** * Sets the array of default images to use for newly opened windows. It is * expected that the array will contain the same icon rendered at different * resolutions. * * @see org.blueberry.swt.widgets.Decorations#setImages(org.blueberry.swt.graphics.Image[]) * * @param images * the array of images to be used when this window is opened * @since 3.0 */ static void SetDefaultImages(const QList& images); /** * Sets the window manager of this window. *

* Note that this method is used by WindowManager to maintain * a backpointer. Clients must not call the method directly. *

* * @param manager * the window manager, or null if none */ void SetWindowManager(WindowManager* manager); /** * Sets the exception handler for this application. *

* Note that the handler may only be set once. Subsequent calls to this method will be * ignored. *

* * @param handler * the exception handler for the application. */ static void SetExceptionHandler(IExceptionHandler::Pointer handler); /** * Sets the default parent for modal Windows. This will be used to locate * the parent for any modal Window constructed with a null parent. * * @param provider shell provider that will be used to locate the parent shell * whenever a Window is created with a null parent * @since 3.1 */ static void SetDefaultModalParent(IShellProvider::Pointer provider); }; } #endif /* BERRYWINDOW_H_ */ diff --git a/Plugins/org.blueberry.ui.qt/src/berryWorkbenchPart.h b/Plugins/org.blueberry.ui.qt/src/berryWorkbenchPart.h index 69cf519f19..2427402bc7 100644 --- a/Plugins/org.blueberry.ui.qt/src/berryWorkbenchPart.h +++ b/Plugins/org.blueberry.ui.qt/src/berryWorkbenchPart.h @@ -1,241 +1,241 @@ /*============================================================================ 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. ============================================================================*/ #ifndef __BERRY_WORKBENCH_PART_H__ #define __BERRY_WORKBENCH_PART_H__ #include "berryIWorkbenchPart.h" #include "berryIWorkbenchPartSite.h" #include #include #include namespace berry { /** * \ingroup org_blueberry_ui_qt * * Abstract base implementation of all workbench parts. *

* This class is not intended to be subclassed by clients outside this * package; clients should instead subclass ViewPart or * EditorPart. *

* * @see org.blueberry.ui.part.ViewPart * @see org.blueberry.ui.part.EditorPart */ class BERRY_UI_QT WorkbenchPart : public QObject, public virtual IWorkbenchPart, public IExecutableExtension { Q_OBJECT Q_INTERFACES(berry::IExecutableExtension); public: berryObjectMacro(WorkbenchPart, QObject, IWorkbenchPart, IExecutableExtension); ~WorkbenchPart() override; private: QString m_Title; QIcon m_TitleImage; QString m_ToolTip; IConfigurationElement::Pointer m_ConfigElement; IWorkbenchPartSite::Pointer m_PartSite; QString m_PartName; QString m_ContentDescription; QHash partProperties; IPropertyChangeListener::Events partChangeEvents; void InternalSetContentDescription(const QString& description); void InternalSetPartName(const QString& partName); protected: WorkbenchPart(); /** * Returns the configuration element for this part. The configuration element * comes from the plug-in registry entry for the extension defining this part. * * @return the configuration element for this part */ IConfigurationElement::Pointer GetConfigurationElement() const { return m_ConfigElement; } /** * Sets the part site. * * Subclasses must invoke this method from IEditorPart.init * and IViewPart.init. * * @param site the workbench part site */ void SetSite(IWorkbenchPartSite::Pointer site); /** * Checks that the given site is valid for this type of part. * The default implementation does nothing. * * @param site the site to check */ virtual void CheckSite(IWorkbenchPartSite::Pointer site); /** * Sets or clears the title image of this part. * * @param titleImage the title image, or null to clear */ virtual void SetTitleImage(const QIcon& titleImage); /** * Sets or clears the title tool tip text of this part. Clients should * call this method instead of overriding getTitleToolTip * * @param toolTip the new tool tip text, or null to clear */ virtual void SetTitleToolTip(const QString& toolTip); /** * Sets the name of this part. The name will be shown in the tab area for * the part. Clients should call this method instead of overriding getPartName. * Setting this to the empty string will cause a default part name to be used. * * @param partName the part name, as it should be displayed in tabs. */ virtual void SetPartName(const QString& partName); /** * Sets the content description for this part. The content description is typically * a short string describing the current contents of the part. Setting this to the * empty string will cause a default content description to be used. Clients should * call this method instead of overriding getContentDescription(). For views, the * content description is shown (by default) in a line near the top of the view. For * editors, the content description is shown beside the part name when showing a * list of editors. If the editor is open on a file, this typically contains the path * to the input file, without the filename or trailing slash. * * @param description the content description */ virtual void SetContentDescription(const QString& description); void FirePropertyChanged(const QString& key, const QString& oldValue, const QString& newValue); void FirePropertyChange(int propertyId); public: /* (non-Javadoc) * Method declared on IWorkbenchPart. */ void AddPropertyListener(IPropertyChangeListener* l) override; void RemovePropertyListener(IPropertyChangeListener* l) override; void SetPartProperty(const QString& key, const QString& value) override; /* (non-Javadoc) * @see org.blueberry.ui.IWorkbenchPart3#getPartProperty(java.lang.String) */ QString GetPartProperty(const QString& key) const override; /* (non-Javadoc) * @see org.blueberry.ui.IWorkbenchPart3#getPartProperties() */ const QHash& GetPartProperties() const override; /** * {@inheritDoc} * The WorkbenchPart implementation of this * IExecutableExtension records the configuration element in * and internal state variable (accessible via getConfigElement). * It also loads the title image, if one is specified in the configuration element. * Subclasses may extend. * * Should not be called by clients. It is called by the core plugin when creating * this executable extension. */ void SetInitializationData(const IConfigurationElement::Pointer& cfig, const QString& propertyName, const Object::Pointer& data) override; /* * Creates the controls for this workbench part. *

* Subclasses must implement this method. For a detailed description of the * requirements see IWorkbenchPart *

* * @param parent the parent control * @see IWorkbenchPart */ void CreatePartControl(QWidget* parent) override = 0; /* (non-Javadoc) * Asks this part to take focus within the workbench. *

* Subclasses must implement this method. For a detailed description of the * requirements see IWorkbenchPart *

* * @see IWorkbenchPart */ void SetFocus() override = 0; /* * Method declared on IWorkbenchPart. */ IWorkbenchPartSite::Pointer GetSite() const override; /** * {@inheritDoc} *

- * It is considered bad practise to overload or extend this method. + * It is considered bad practice to overload or extend this method. * Parts should call setPartName to change their part name. *

*/ QString GetPartName() const override; /** * {@inheritDoc} *

- * It is considered bad practise to overload or extend this method. + * It is considered bad practice to overload or extend this method. * Parts should call setContentDescription to change their content description. *

*/ QString GetContentDescription() const override; /* (non-Javadoc) * Method declared on IWorkbenchPart. */ QIcon GetTitleImage() const override; /* (non-Javadoc) * Gets the title tool tip text of this part. * * @return the tool tip text */ QString GetTitleToolTip() const override; }; } // namespace berry #endif // __BERRY_WORKBENCH_PART_H__ diff --git a/Plugins/org.blueberry.ui.qt/src/handlers/berryHandlerUtil.h b/Plugins/org.blueberry.ui.qt/src/handlers/berryHandlerUtil.h index d526f0ac1f..78e2e375d6 100644 --- a/Plugins/org.blueberry.ui.qt/src/handlers/berryHandlerUtil.h +++ b/Plugins/org.blueberry.ui.qt/src/handlers/berryHandlerUtil.h @@ -1,382 +1,382 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYHANDLERUTIL_H_ #define BERRYHANDLERUTIL_H_ #include #include #include #include #include "berryIWorkbenchPart.h" #include "berryIWorkbenchPartSite.h" #include "berryISelection.h" #include "berryIWorkbenchWindow.h" #include "berryISources.h" namespace berry { /** * \ingroup org_blueberry_ui_qt * * Some common utilities for working with handlers in Platform UI. *

* Note: this class should not be instantiated or extended by clients. *

* * @since 3.3 */ class BERRY_UI_QT HandlerUtil { private: static void NoVariableFound(const ExecutionEvent::ConstPointer& event, const QString& name); static void IncorrectTypeFound(const ExecutionEvent::ConstPointer& event, const QString& name, const QString& expectedType, const QString& wrongType); public: typedef ObjectList StringVectorType; /** * Extract the variable. * * @param event * The execution event that contains the application context * @param name * The variable name to extract. * @return The object from the application context, or null * if it could not be found. */ static Object::ConstPointer GetVariable(const ExecutionEvent::ConstPointer& event, const QString& name); /** * Extract the variable. * * @param event * The execution event that contains the application context * @param name * The variable name to extract. * @return The object from the application context. Will not return * null. * @throws ExecutionException * if the variable is not found. */ static Object::ConstPointer GetVariableChecked(const ExecutionEvent::ConstPointer& event, const QString& name); /** * Extract the variable. * * @param context * The IEvaluationContext or null * @param name * The variable name to extract. * @return The object from the application context, or null * if it could not be found. */ static Object::ConstPointer GetVariable(Object::Pointer context, const QString& name); /** * Return the active contexts. * * @param event * The execution event that contains the application context * @return a collection of String contextIds, or null. */ static StringVectorType::ConstPointer GetActiveContexts(const ExecutionEvent::ConstPointer& event); /** * Return the active contexts. * * @param event * The execution event that contains the application context * @return a collection of String contextIds. Will not return * null. * @throws ExecutionException * If the context variable is not found. */ static StringVectorType::ConstPointer GetActiveContextsChecked(const ExecutionEvent::ConstPointer& event); /** * Return the active workbench window. * * @param event * The execution event that contains the application context * @return the active workbench window, or null. */ static IWorkbenchWindow::Pointer GetActiveWorkbenchWindow(const ExecutionEvent::ConstPointer& event); /** * Return the active workbench window. * * @param event * The execution event that contains the application context * @return the active workbench window. Will not return null. * @throws ExecutionException * If the active workbench window variable is not found. */ static IWorkbenchWindow::Pointer GetActiveWorkbenchWindowChecked( const ExecutionEvent::ConstPointer& event); /** * Return the part id of the active editor. * * @param event * The execution event that contains the application context * @return the part id of the active editor, or null. */ static ObjectString::ConstPointer GetActiveEditorId(const ExecutionEvent::ConstPointer& event); /** * Return the part id of the active editor. * * @param event * The execution event that contains the application context * @return the part id of the active editor. Will not return * null. * @throws ExecutionException * If the active editor id variable is not found. */ static ObjectString::ConstPointer GetActiveEditorIdChecked(const ExecutionEvent::ConstPointer& event); /** * Return the active part. * * @param event * The execution event that contains the application context * @return the active part, or null. */ static IWorkbenchPart::Pointer GetActivePart(const ExecutionEvent::ConstPointer& event); /** * Return the active part. * * @param event * The execution event that contains the application context * @return the active part. Will not return null. * @throws ExecutionException * If the active part variable is not found. */ static IWorkbenchPart::Pointer GetActivePartChecked(const ExecutionEvent::ConstPointer& event); /** * Return the part id of the active part. * * @param event * The execution event that contains the application context * @return the part id of the active part, or null. */ static ObjectString::ConstPointer GetActivePartId(const ExecutionEvent::ConstPointer& event); /** * Return the part id of the active part. * * @param event * The execution event that contains the application context * @return the part id of the active part. Will not return null. * @throws ExecutionException * If the active part id variable is not found. */ static ObjectString::ConstPointer GetActivePartIdChecked(const ExecutionEvent::ConstPointer& event); /** * Return the active part site. * * @param event * The execution event that contains the application context * @return the active part site, or null. */ static IWorkbenchPartSite::Pointer GetActiveSite(const ExecutionEvent::ConstPointer& event); /** * Return the active part site. * * @param event * The execution event that contains the application context * @return the active part site. Will not return null. * @throws ExecutionException * If the active part site variable is not found. */ static IWorkbenchPartSite::Pointer GetActiveSiteChecked(const ExecutionEvent::ConstPointer& event); /** * Return the current selection. * * @param event * The execution event that contains the application context * @return the current selection, or null. */ static ISelection::ConstPointer GetCurrentSelection(const ExecutionEvent::ConstPointer& event); /** * Return the current selection. * * @param event * The execution event that contains the application context * @return the current selection. Will not return null. * @throws ExecutionException * If the current selection variable is not found. */ static ISelection::ConstPointer GetCurrentSelectionChecked(const ExecutionEvent::ConstPointer& event); /** * Return the menu IDs that were applied to the registered context menu. * * @param event * The execution event that contains the application context * @return the menu IDs, or null. */ static StringVectorType::ConstPointer GetActiveMenus(const ExecutionEvent::ConstPointer& event); /** * Return the menu IDs that were applied to the registered context menu. * * @param event * The execution event that contains the application context * @return the menu IDs. Will not return null. * @throws ExecutionException * If the active menus variable is not found. */ static StringVectorType::ConstPointer GetActiveMenusChecked(const ExecutionEvent::ConstPointer& event); /** * Return the active menu selection. The active menu is a registered context * menu. * * @param event * The execution event that contains the application context * @return the active menu selection, or null. */ static ISelection::ConstPointer GetActiveMenuSelection(const ExecutionEvent::ConstPointer& event); /** * Return the active menu selection. The active menu is a registered context * menu. * * @param event * The execution event that contains the application context * @return the active menu selection. Will not return null. * @throws ExecutionException * If the active menu selection variable is not found. */ static ISelection::ConstPointer GetActiveMenuSelectionChecked(const ExecutionEvent::ConstPointer& event); /** * Return the active menu editor input, if available. The active menu is a * registered context menu. * * @param event * The execution event that contains the application context * @return the active menu editor, or null. */ static ISelection::ConstPointer GetActiveMenuEditorInput(const ExecutionEvent::ConstPointer& event); /** * Return the active menu editor input. The active menu is a registered * context menu. Some context menus do not include the editor input which * will throw an exception. * * @param event * The execution event that contains the application context * @return the active menu editor input. Will not return null. * @throws ExecutionException * If the active menu editor input variable is not found. */ static ISelection::ConstPointer GetActiveMenuEditorInputChecked( const ExecutionEvent::ConstPointer& event); /** * Return the ShowInContext selection. * * @param event * The execution event that contains the application context * @return the show in selection, or null. */ static ISelection::ConstPointer GetShowInSelection(const ExecutionEvent::ConstPointer& event); /** * Return the ShowInContext selection. Will not return null. * * @param event * The execution event that contains the application context * @return the show in selection, or null. * @throws ExecutionException * If the show in selection variable is not found. */ static ISelection::ConstPointer GetShowInSelectionChecked(const ExecutionEvent::ConstPointer& event); /** * Return the ShowInContext input. * * @param event * The execution event that contains the application context * @return the show in input, or null. */ static Object::ConstPointer GetShowInInput(const ExecutionEvent::ConstPointer& event); /** * Return the ShowInContext input. Will not return null. * * @param event * The execution event that contains the application context * @return the show in input, or null. * @throws ExecutionException * If the show in input variable is not found. */ static Object::ConstPointer GetShowInInputChecked(const ExecutionEvent::ConstPointer& event); /** * Toggles the command's state. * * @param command The command whose state needs to be toggled * @return the original value before toggling * * @throws ExecutionException * When the command doesn't contain the toggle state or when the state doesn't contain a boolean value */ static bool ToggleCommandState(const SmartPointer& command); /** * Checks whether the radio state of the command is same as the radio state * parameter's value * * @param event * The execution event that contains the application context - * @return true whe the values are same, false + * @return true when the values are same, false * otherwise * * @throws ExecutionException * When the command doesn't have the radio state or the event * doesn't have the radio state parameter */ static bool MatchesRadioState(const SmartPointer& event); /** * Updates the radio state of the command to the given value * * @param command * the command whose state should be updated * @param newState * the new state * * @throws ExecutionException * When the command doesn't have a radio state */ static void UpdateRadioState(const SmartPointer& command, const QString& newState); }; } #endif /*BERRYHANDLERUTIL_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryCommandParameter.h b/Plugins/org.blueberry.ui.qt/src/internal/berryCommandParameter.h index 0ff245e569..84bae63608 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryCommandParameter.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryCommandParameter.h @@ -1,187 +1,187 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYCOMMANDPARAMETER_H #define BERRYCOMMANDPARAMETER_H #include "berryIParameter.h" #include "berryITypedParameter.h" namespace berry { struct IConfigurationElement; /** *

* A parameter for a command. A parameter identifies a type of information that * the command might accept. For example, a "Show View" command might accept the * id of a view for display. This parameter also identifies possible values, for * display in the user interface. *

*

* Parameters are mutable, and can change as the command changes. Notifications * will not be sent if the parameter itself changes. Listeners can be attached * to the command. *

*/ class CommandParameter : public IParameter, public ITypedParameter { public: berryObjectMacro(berry::CommandParameter); private: /** * The name of the configuration element attribute contain the values. This * is used to retrieve the executable extension * IParameterValues. */ static const QString ATTRIBUTE_VALUES; // = "values"; /** * The constant integer hash code value meaning the hash code has not yet * been computed. */ static const int HASH_CODE_NOT_COMPUTED; // = 0; /** * A factor for computing the hash code for all schemes. */ static const int HASH_FACTOR; // = 89; /** * The seed for the hash code for all schemes. */ static const int HASH_INITIAL; /** * The hash code for this object. This value is computed lazily, and marked * as invalid when one of the values on which it is based changes. */ mutable int hashCode; // = HASH_CODE_NOT_COMPUTED; /** * The non-externalized name of this parameter. The name is used as the in a * name-value parameter map. This value will never be null. */ const QString name; /** * Whether the parameter is optional (as opposed to required). */ const bool optional; /** * The type for this parameter. This value may be null if the * parameter is not typed. */ const SmartPointer parameterType; /** * The actual IParameterValues implementation. This is lazily * loaded from the valuesConfigurationElement, to avoid * unnecessary class-loading. */ mutable QScopedPointer values; /** * The configuration element providing the executable extension that will * implement IParameterValues. This value will not be * null. */ const SmartPointer valuesConfigurationElement; protected: /** * The identifier for this object. This identifier should be unique across * all objects of the same type and should never change. This value will * never be null. */ const QString id; /** * The string representation of this object. This string is for debugging * purposes only, and is not meant to be displayed to the user. This value * is computed lazily, and is cleared if one of its dependent values * changes. */ mutable QString str; public: /** * Constructs a new instance of Parameter with all of its * values pre-defined. * * @param id * The identifier for this parameter; must not be * null. * @param name * The name for this parameter; must not be null. * @param values * The values for this parameter; must not be null. * @param parameterType * the type for this parameter; may be null if the - * parmeter doesn't declare type. + * parameter doesn't declare type. * @param optional * Whether this parameter is optional (as opposed to required). * @param commandService * The command service from which parameter types can be * retrieved; must not be null. */ CommandParameter(const QString& id, const QString& name, const SmartPointer& values, const SmartPointer& parameterType, const bool optional); /** * Tests whether this object is equal to another object. A parameter is only * equal to another parameter with the same properties. * * @param object * The object with which to compare; may be null. * @return true if the objects are equal; false * otherwise. */ bool operator==(const Object* object) const override; QString GetId() const override; QString GetName() const override; SmartPointer GetParameterType() const override; IParameterValues* GetValues() const override; uint HashCode() const override { if (hashCode == HASH_CODE_NOT_COMPUTED) { hashCode = HASH_INITIAL * HASH_FACTOR + qHash(id); if (hashCode == HASH_CODE_NOT_COMPUTED) { hashCode++; } } return hashCode; } bool IsOptional() const override; QString ToString() const override; }; } #endif // BERRYCOMMANDPARAMETER_H diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryCommandService.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryCommandService.cpp index f37b522b35..889118ab0a 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryCommandService.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryCommandService.cpp @@ -1,313 +1,313 @@ /*============================================================================ 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 "berryCommandService.h" #include #include #include #include #include #include "berryPersistentState.h" #include "berryWorkbenchPlugin.h" #include "berryElementReference.h" #include #include #include #include #include #include #include namespace berry { const std::string CommandService::PREFERENCE_KEY_PREFIX = "org.blueberry.ui.commands/state"; std::string CommandService::CreatePreferenceKey(const SmartPointer& command, const QString& stateId) { return PREFERENCE_KEY_PREFIX + '/' + command->GetId().toStdString() + '/' + stateId.toStdString(); } CommandService::CommandService( CommandManager* commandManager) : commandManager(commandManager) , commandPersistence(this) { if (commandManager == nullptr) { throw std::invalid_argument("Cannot create a command service with a null manager"); } } CommandService::~CommandService() { this->Dispose(); } void CommandService::AddExecutionListener(IExecutionListener* listener) { commandManager->AddExecutionListener(listener); } void CommandService::DefineUncategorizedCategory(const QString& name, const QString& description) { commandManager->DefineUncategorizedCategory(name, description); } SmartPointer CommandService::Deserialize(const QString& serializedParameterizedCommand) const { return commandManager->Deserialize(serializedParameterizedCommand); } void CommandService::Dispose() { /* - * All state on all commands neeeds to be disposed. This is so that the + * All state on all commands needs to be disposed. This is so that the * state has a chance to persist any changes. */ const QList commands = commandManager->GetAllCommands(); foreach (const Command::Pointer& command, commands) { const QList stateIds = command->GetStateIds(); foreach(const QString& stateId, stateIds) { const State::Pointer state = command->GetState(stateId); if (PersistentState::Pointer persistentState = state.Cast()) { if (persistentState->ShouldPersist()) { persistentState->Save(WorkbenchPlugin::GetDefault()->GetPreferences(), CreatePreferenceKey(command, stateId)); } } } } commandCallbacks.clear(); } SmartPointer CommandService::GetCategory(const QString& categoryId) const { return commandManager->GetCategory(categoryId); } SmartPointer CommandService::GetCommand(const QString& commandId) const { return commandManager->GetCommand(commandId); } QList > CommandService::GetDefinedCategories() const { return commandManager->GetDefinedCategories(); } QStringList CommandService::GetDefinedCategoryIds() const { return commandManager->GetDefinedCategoryIds().toList(); } QStringList CommandService::GetDefinedCommandIds() const { return commandManager->GetDefinedCommandIds().toList(); } QList > CommandService::GetDefinedCommands() const { return commandManager->GetDefinedCommands(); } QStringList CommandService::GetDefinedParameterTypeIds() const { return commandManager->GetDefinedParameterTypeIds().toList(); } QList > CommandService::GetDefinedParameterTypes() const { return commandManager->GetDefinedParameterTypes(); } QString CommandService::GetHelpContextId(const SmartPointer& command) const { return commandManager->GetHelpContextId(command); } QString CommandService::GetHelpContextId(const QString& commandId) const { Command::Pointer command = GetCommand(commandId); return commandManager->GetHelpContextId(command); } SmartPointer CommandService::GetParameterType(const QString& parameterTypeId) const { return commandManager->GetParameterType(parameterTypeId); } void CommandService::ReadRegistry() { commandPersistence.Read(); } void CommandService::RemoveExecutionListener(IExecutionListener* listener) { commandManager->RemoveExecutionListener(listener); } void CommandService::SetHelpContextId(const SmartPointer& handler, const QString& helpContextId) { commandManager->SetHelpContextId(handler, helpContextId); } void CommandService::RefreshElements(const QString& commandId, const QHash& filter) { Command::Pointer cmd = GetCommand(commandId); if (!cmd->IsDefined() || !(cmd->GetHandler().Cast())) { return; } IElementUpdater::Pointer updater = cmd->GetHandler().Cast(); if (commandCallbacks.isEmpty()) { return; } if(!commandCallbacks.contains(commandId)) { return; } foreach (IElementReference::Pointer callbackRef, commandCallbacks[commandId]) { struct _SafeRunnable : public ISafeRunnable { IElementUpdater* updater; IElementReference* callbackRef; _SafeRunnable(IElementUpdater* updater, IElementReference* callbackRef) : updater(updater), callbackRef(callbackRef) {} void HandleException(const ctkException& exc) override { WorkbenchPlugin::Log(QString("Failed to update callback: ") + callbackRef->GetCommandId() + exc.what()); } void Run() override { updater->UpdateElement(callbackRef->GetElement().GetPointer(), callbackRef->GetParameters()); } }; QHash parms = callbackRef->GetParameters(); ISafeRunnable::Pointer run(new _SafeRunnable(updater.GetPointer(), callbackRef.GetPointer())); if (filter.isEmpty()) { SafeRunner::Run(run); } else { bool match = true; QHashIterator i(filter); while (i.hasNext()) { i.next(); Object::Pointer value = parms[i.key()]; if (i.value() != value) { match = false; break; } } if (match) { SafeRunner::Run(run); } } } } SmartPointer CommandService::RegisterElementForCommand( const SmartPointer& command, const SmartPointer& element) { if (!command->GetCommand()->IsDefined()) { throw NotDefinedException( "Cannot define a callback for undefined command " + command->GetCommand()->GetId()); } if (element.IsNull()) { throw NotDefinedException("No callback defined for command " + command->GetCommand()->GetId()); } QHash paramMap = command->GetParameterMap(); QHash parms; for (QHash::const_iterator i = paramMap.begin(); i != paramMap.end(); ++i) { Object::Pointer value(new ObjectString(i.value())); parms.insert(i.key(), value); } IElementReference::Pointer ref(new ElementReference(command->GetId(), element, parms)); RegisterElement(ref); return ref; } void CommandService::RegisterElement(const SmartPointer& elementReference) { QList& parameterizedCommands = commandCallbacks[elementReference->GetCommandId()]; parameterizedCommands.push_back(elementReference); // If the active handler wants to update the callback, it can do // so now Command::Pointer command = GetCommand(elementReference->GetCommandId()); if (command->IsDefined()) { if (IElementUpdater::Pointer updater = command->GetHandler().Cast()) { updater->UpdateElement(elementReference->GetElement().GetPointer(), elementReference->GetParameters()); } } } void CommandService::UnregisterElement(const SmartPointer& elementReference) { if (commandCallbacks.contains(elementReference->GetCommandId())) { QList& parameterizedCommands = commandCallbacks[elementReference->GetCommandId()]; parameterizedCommands.removeAll(elementReference); if (parameterizedCommands.isEmpty()) { commandCallbacks.remove(elementReference->GetCommandId()); } } } const CommandPersistence* CommandService::GetCommandPersistence() const { return &commandPersistence; } } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryDragUtil.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryDragUtil.cpp index 3cac5f379e..039cdb2950 100755 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryDragUtil.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryDragUtil.cpp @@ -1,289 +1,289 @@ /*============================================================================ 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 "berryDragUtil.h" #include "berryGeometry.h" #include "berryQtTracker.h" namespace berry { const QString DragUtil::DROP_TARGET_ID = "org.blueberry.ui.internal.dropTarget"; TestDropLocation::Pointer DragUtil::forcedDropTarget(nullptr); QList DragUtil::defaultTargets = QList(); DragUtil::TargetListType::Pointer DragUtil::GetTargetList(QWidget* control) { Object::Pointer data = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetData( control, DROP_TARGET_ID); TargetListType::Pointer list = data.Cast (); return list; } IDropTarget::Pointer DragUtil::GetDropTarget(const QList& toSearch, QWidget* mostSpecificControl, Object::Pointer draggedObject, const QPoint& position, const QRect& dragRectangle) { for (QList::const_iterator iter = toSearch.begin(); iter != toSearch.end(); ++iter) { IDragOverListener* next = *iter; IDropTarget::Pointer dropTarget = next->Drag(mostSpecificControl, draggedObject, position, dragRectangle); if (dropTarget != 0) { return dropTarget; } } return IDropTarget::Pointer(nullptr); } void DragUtil::AddDragTarget(QWidget* control, IDragOverListener* target) { if (control == nullptr) { defaultTargets.push_back(target); } else { TargetListType::Pointer targetList = GetTargetList(control); if (targetList == 0) { targetList = new TargetListType(); Tweaklets::Get(GuiWidgetsTweaklet::KEY)->SetData(control, DROP_TARGET_ID, targetList); } targetList->push_back(target); } } void DragUtil::RemoveDragTarget(QWidget* control, IDragOverListener* target) { if (control == nullptr) { defaultTargets.removeAll(target); } else { TargetListType::Pointer targetList = GetTargetList(control); if (targetList != 0) { targetList->removeAll(target); if (targetList->empty()) { Tweaklets::Get(GuiWidgetsTweaklet::KEY)->SetData(control, DROP_TARGET_ID, Object::Pointer(nullptr)); } } } } QRect DragUtil::GetDisplayBounds(QWidget* boundsControl) { QWidget* parent = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetParent( boundsControl); if (parent == nullptr) { return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetBounds(boundsControl); } QRect rect = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetBounds( boundsControl); return Geometry::ToDisplay(parent, rect); } bool DragUtil::PerformDrag(Object::Pointer draggedItem, const QRect& sourceBounds, const QPoint& initialLocation, bool allowSnapping) { IDropTarget::Pointer target = DragToTarget(draggedItem, sourceBounds, initialLocation, allowSnapping); if (target == 0) { return false; } target->Drop(); target->DragFinished(true); return true; } void DragUtil::ForceDropLocation(TestDropLocation::Pointer forcedLocation) { forcedDropTarget = forcedLocation; } IDropTarget::Pointer DragUtil::DragToTarget(Object::Pointer draggedItem, const QRect& sourceBounds, const QPoint& initialLocation, bool allowSnapping) { //final Display display = Display.getCurrent(); // Testing...immediately 'drop' onto the test target if (forcedDropTarget != 0) { QPoint location = forcedDropTarget->GetLocation(); QWidget* currentControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->FindControl( forcedDropTarget->GetShells(), location); return GetDropTarget(currentControl, draggedItem, location, sourceBounds); } // Create a tracker. This is just an XOR rect on the screen. // As it moves we notify the drag listeners. QtTracker tracker; //tracker.setStippled(true); QtTrackerMoveListener trackerListener(draggedItem, sourceBounds, initialLocation, allowSnapping); trackerListener.connect(&tracker, SIGNAL(Moved(QtTracker*,QPoint)), SLOT(Moved(QtTracker*,QPoint))); // Setup...when the drag starts we might already be over a valid target, check this... // If there is a 'global' target then skip the check IDropTarget::Pointer target; QWidget* startControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorControl(); if (startControl != nullptr && allowSnapping) { target = GetDropTarget(startControl, draggedItem, initialLocation, sourceBounds); } // Set up an initial tracker rectangle QRect startRect = sourceBounds; if (target != 0) { QRect rect = target->GetSnapRectangle(); if (rect.width() != 0 && rect.height() != 0) { startRect = rect; } tracker.SetCursor(target->GetCursor()); } if (startRect.width() != 0 && startRect.height() != 0) { tracker.SetRectangle(startRect); } - // Tracking Loop...tracking is preformed on the 'SWT.Move' listener registered + // Tracking Loop...tracking is performed on the 'SWT.Move' listener registered // against the tracker. // // HACK: // // Some control needs to capture the mouse during the drag or other // // controls will interfere with the cursor // Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); // if (shell != null) // { // shell.setCapture(true); // } // Run tracker until mouse up occurs or escape key pressed. bool trackingOk = tracker.Open(); // // HACK: // // Release the mouse now // if (shell != null) // { // shell.setCapture(false); // } // Done tracking... // Get the current drop target IDropTarget::Pointer dropTarget; QPoint finalLocation = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorLocation(); QWidget* targetControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorControl(); dropTarget = GetDropTarget(targetControl, draggedItem, finalLocation, tracker.GetRectangle()); // Cleanup... //delete tracker; // if we're going to perform a 'drop' then delay the issuing of the 'finished' // callback until after it's done... if (trackingOk) { return dropTarget; } else if (dropTarget != 0) { // If the target can handle a 'finished' notification then send one dropTarget->DragFinished(false); } return IDropTarget::Pointer(nullptr); } IDropTarget::Pointer DragUtil::GetDropTarget(QWidget* toSearch, Object::Pointer draggedObject, const QPoint& position, const QRect& dragRectangle) { // Search for a listener by walking the control's parent hierarchy for (QWidget* current = toSearch; current != nullptr; current = Tweaklets::Get( GuiWidgetsTweaklet::KEY)->GetParent(current)) { TargetListType::Pointer targetList = GetTargetList(current); QList targets; if (targetList != 0) targets = *targetList; IDropTarget::Pointer dropTarget = GetDropTarget(targets, toSearch, draggedObject, position, dragRectangle); if (dropTarget != 0) { return dropTarget; } // // Don't look to parent shells for drop targets // if (current instanceof Shell) { // break; // } } // No controls could handle this event -- check for default targets return GetDropTarget(defaultTargets, toSearch, draggedObject, position, dragRectangle); } //QPoint DragUtil::GetEventLoc(GuiTk::ControlEvent::Pointer event) //{ // Control ctrl = (Control) event.widget; // return ctrl.toDisplay(new QPoint(event.x, event.y)); //} } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorDescriptor.h b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorDescriptor.h index 53a6158445..f4649e1df2 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorDescriptor.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorDescriptor.h @@ -1,388 +1,388 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYEDITORDESCRIPTOR_H_ #define BERRYEDITORDESCRIPTOR_H_ #include "berryIEditorDescriptor.h" #include "berryIMemento.h" #include #include namespace berry { struct IEditorPart; /** * \ingroup org_blueberry_ui_internal * * @see IEditorDescriptor */ class BERRY_UI_QT EditorDescriptor : public IEditorDescriptor { //, Serializable, IPluginContribution { public: berryObjectMacro(EditorDescriptor); // @issue the following constants need not be public; see bug 47600 /** * Open internal constant. Value 0x01. */ static const int OPEN_INTERNAL; // = 0x01; /** * Open in place constant. Value 0x02. */ static const int OPEN_INPLACE; // = 0x02; /** * Open external constant. Value 0x04. */ static const int OPEN_EXTERNAL; // = 0x04; private: QString editorName; QString imageFilename; mutable QIcon imageDesc; mutable bool testImage; QString className; QString launcherName; QString fileName; QString id; bool matchingStrategyChecked; IEditorMatchingStrategy::Pointer matchingStrategy; //Program program; //The id of the plugin which contributed this editor, null for external editors QString pluginIdentifier; int openMode; IConfigurationElement::Pointer configurationElement; /** * Create a new instance of an editor descriptor. Limited * to internal framework calls. * @param element * @param id2 */ /* package */ public: EditorDescriptor(const QString& id2, IConfigurationElement::Pointer element); /** * Create a new instance of an editor descriptor. Limited * to internal framework calls. */ /* package */ public: EditorDescriptor(); /** * Creates a descriptor for an external program. * * @param filename the external editor full path and filename * @return the editor descriptor */ //public: static EditorDescriptor::Pointer CreateForProgram(const QString& filename) { // if (filename == null) { // throw new IllegalArgumentException(); // } // EditorDescriptor editor = new EditorDescriptor(); // // editor.setFileName(filename); // editor.setID(filename); // editor.setOpenMode(OPEN_EXTERNAL); // // //Isolate the program name (no directory or extension) // int start = filename.lastIndexOf(File.separator); // String name; // if (start != -1) { // name = filename.substring(start + 1); // } else { // name = filename; // } // int end = name.lastIndexOf('.'); // if (end != -1) { // name = name.substring(0, end); // } // editor.setName(name); // // // get the program icon without storing it in the registry // ImageDescriptor imageDescriptor = new ProgramImageDescriptor(filename, // 0); // editor.setImageDescriptor(imageDescriptor); // // return editor; // } /** * Return the program called programName. Return null if it is not found. * @return org.blueberry.swt.program.Program */ //private: static Program FindProgram(const QString& programName) { // // Program[] programs = Program.getPrograms(); // for (int i = 0; i < programs.length; i++) { // if (programs[i].getName().equals(programName)) { // return programs[i]; // } // } // // return null; // } /** * Create the editor action bar contributor for editors of this type. * * @return the action bar contributor, or null */ //public: IEditorActionBarContributor::Pointer CreateActionBarContributor(); /** * Return the editor class name. * * @return the class name */ public: QString GetEditorClassName() const; /** * Return the configuration element used to define this editor, or null. * * @return the element or null */ public: IConfigurationElement::Pointer GetConfigurationElement() const; /** * Create an editor part based on this descriptor. * * @return the editor part * @throws CoreException thrown if there is an issue creating the editor */ public: SmartPointer CreateEditor(); /** * Return the file name of the command to execute for this editor. * * @return the file name to execute */ public: QString GetFileName() const; /** * Return the id for this editor. * * @return the id */ public: QString GetId() const override; /** * Return the image descriptor describing this editor. * * @return the image descriptor */ public: QIcon GetImageDescriptor() const override; /** * Verifies that the image descriptor generates an image. If not, the * descriptor is replaced with the default image. * * @since 3.1 */ private: void VerifyImage() const; /** * The name of the image describing this editor. * * @return the image file name */ public: QString GetImageFilename() const; /** * Return the user printable label for this editor. * * @return the label */ public: QString GetLabel() const override; /** * Returns the class name of the launcher. * * @return the launcher class name */ public: QString GetLauncher() const; /** * Return the contributing plugin id. * * @return the contributing plugin id */ public: QString GetPluginID() const; /** * Get the program for the receiver if there is one. * @return Program */ //public: Program GetProgram() { // return this.program; // } /* (non-Javadoc) * @see org.blueberry.ui.IEditorDescriptor#isInternal */ public: bool IsInternal() const override; /* (non-Javadoc) * @see org.blueberry.ui.IEditorDescriptor#isOpenInPlace */ public: bool IsOpenInPlace() const override; /* (non-Javadoc) * @see org.blueberry.ui.IEditorDescriptor#isOpenExternal */ public: bool IsOpenExternal() const override; /** * Load the object properties from a memento. * * @return true if the values are valid, false otherwise */ protected: bool LoadValues(IMemento::Pointer memento); /** * Save the object values in a IMemento */ protected: void SaveValues(IMemento::Pointer memento); /** * Return the open mode of this editor. * * @return the open mode of this editor * @since 3.1 */ private: int GetOpenMode() const; /** * Set the class name of an internal editor. */ /* package */public: void SetClassName(const QString& newClassName); /** * Set the configuration element which contributed this editor. */ /* package */public: void SetConfigurationElement( IConfigurationElement::Pointer newConfigurationElement); /** * Set the filename of an external editor. */ /* package */public: void SetFileName(const QString& aFileName); /** * Set the id of the editor. * For internal editors this is the id as provided in the extension point * For external editors it is path and filename of the editor */ /* package */public: void SetID(const QString& anID); /** - * The Image to use to repesent this editor + * The Image to use to represent this editor */ /* package */ // public : void SetImageDescriptor(ImageDescriptor desc) { // imageDesc = desc; // testImage = true; // } /** * The name of the image to use for this editor. */ /* package */ // public: void SetImageFilename(const QString& aFileName) { // imageFilename = aFileName; // } /** * Sets the new launcher class name * * @param newLauncher the new launcher */ /* package */public: void SetLauncher(const QString& newLauncher); /** * The label to show for this editor. */ /* package */public: void SetName(const QString& newName); /** * Sets the open mode of this editor descriptor. * * @param mode the open mode * * @issue this method is public as a temporary fix for bug 47600 */ public: void SetOpenMode(int mode); /** * The id of the plugin which contributed this editor, null for external editors. */ /* package */public: void SetPluginIdentifier(const QString& anID); /** * Set the receivers program. * @param newProgram */ /* package */ // public: void SetProgram(Program newProgram) { // // this.program = newProgram; // if (editorName == null) { // setName(newProgram.getName()); // } // } /** * For debugging purposes only. */ public: QString ToString() const override; /* (non-Javadoc) * @see org.blueberry.ui.activities.support.IPluginContribution#getLocalId() */ public: QString GetLocalId() const; /* (non-Javadoc) * @see org.blueberry.ui.activities.support.IPluginContribution#getPluginId() */ public: QString GetPluginId() const; /* (non-Javadoc) * @see org.blueberry.ui.IEditorDescriptor#getEditorManagementPolicy() */ public: IEditorMatchingStrategy::Pointer GetEditorMatchingStrategy() override; }; } #endif /*BERRYEDITORDESCRIPTOR_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorReference.h b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorReference.h index 25cf8c269c..01052cfaf2 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorReference.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorReference.h @@ -1,232 +1,232 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYEDITORREFERENCE_H_ #define BERRYEDITORREFERENCE_H_ #include "berryWorkbenchPartReference.h" #include "berryIEditorReference.h" #include "berryIEditorInput.h" #include "berryIMemento.h" #include "berryIWorkbenchPart.h" #include "berryIEditorPart.h" namespace berry { class EditorManager; class EditorDescriptor; class PartPane; struct IWorkbenchPage; /** * \ingroup org_blueberry_ui_internal * */ class EditorReference : public WorkbenchPartReference, public IEditorReference { private: const EditorManager* manager; private: IMemento::Pointer editorMemento; private: IMemento::Pointer editorState; /** * Flag that lets us detect malfunctioning editors that don't fire PROP_INPUT events. * It is never needed for a correctly-functioning */ private: bool expectingInputChange; /** * Flag that determines whether we've already reported that this editor is malfunctioning. * This prevents us from spamming the event log if we repeatedly detect the same error in * a particular editor. If we ever detect an editor is violating its public contract in * a way we can recover from (such as a missing property change event), we report the error * once and then silently ignore errors from the same editor. */ private: bool reportedMalfunctioningEditor; /** * User-readable name of the editor's input */ QString name; QString factoryId; IEditorInput::Pointer restoredInput; /** * @param manager * The editor manager for this reference * @param input * our input * @param desc * the descriptor from the declaration * @param editorState - * propogate state from another editor. Can be null. + * propagate state from another editor. Can be null. */ public: berryObjectMacro(EditorReference); EditorReference(EditorManager* manager, IEditorInput::Pointer input, SmartPointer desc, IMemento::Pointer editorState = IMemento::Pointer(nullptr)); /** * Constructs a new editor reference for use by editors being restored from * a memento. */ EditorReference(EditorManager* manager, IMemento::Pointer memento); public: SmartPointer GetDescriptor(); /** * @param id the id * @return the editor descriptor */ private: SmartPointer GetDescriptor(const QString& id); /** * Initializes the necessary editor listeners and handlers */ private: void InitListenersAndHandlers(); protected: SmartPointer CreatePane() override; /** * This method is called when there should be a change in the editor pin * status (added or removed) so that it will ask its presentable part * to fire a PROP_TITLE event in order for the presentation to request * the new icon for this editor */ public: void PinStatusUpdated(); public: QString GetFactoryId() override; protected: QString ComputePartName() const override; public: QString GetName() override; public: IEditorPart::Pointer GetEditor(bool restore) override; public: void SetName(const QString& name); public: IMemento::Pointer GetMemento(); public: SmartPointer GetPage() const override; public: IEditorInput::Pointer GetEditorInput() override; private: IEditorInput::Pointer GetRestoredInput(); /* (non-Javadoc) * @see org.blueberry.ui.IWorkbenchPartReference#getTitleImage() * This method will append a pin to the icon of the editor * if the "automatically close editors" option in the * preferences is enabled and the editor has been pinned. */ //public: ImageDescriptor computeImageDescriptor() { // ImageDescriptor descriptor = super.computeImageDescriptor(); // if (!isPinned()) { // return descriptor; // } // // // Check if the pinned preference is set // IPreferenceStore prefStore = WorkbenchPlugin.getDefault() // .getPreferenceStore(); // boolean bUsePin = prefStore // .getBoolean(IPreferenceConstants.REUSE_EDITORS_BOOLEAN) // || ((TabBehaviour)Tweaklets.get(TabBehaviour.KEY)).alwaysShowPinAction(); // // if (!bUsePin) { // return descriptor; // } // // ImageDescriptor pinDesc = this.manager.getEditorPinImageDesc(); // if (pinDesc == null) { // return descriptor; // } // // return new OverlayIcon(descriptor, pinDesc, new Point(16, 16)); // } protected: /** * Wrapper for restoring the editor. First, this delegates to busyRestoreEditorHelper * to do the real work of restoring the view. If unable to restore the editor, this * method tries to substitute an error part and return success. * * @return the created part */ IWorkbenchPart::Pointer CreatePart() override; using WorkbenchPartReference::PropertyChanged; void PropertyChanged(Object::Pointer source, int propId); /** * Attempts to set the input of the editor to the given input. Note that the input * can't always be changed for an editor. Editors that don't implement IReusableEditor * can't have their input changed once they've been materialized. * * @param input new input * @return true iff the input was actually changed */ public: bool SetInput(IEditorInput::Pointer input); /** * Reports a recoverable malfunction in the system log. A recoverable malfunction would be * something like failure to fire an expected property change. Only the first malfunction is * * @param string */ private: void ReportMalfunction(const QString& string); private: IEditorPart::Pointer CreatePartHelper(); /** * Creates and returns an empty editor (ErrorEditorPart). * * @param descr the editor descriptor * @return the empty editor part or null in case of an exception */ public: IEditorPart::Pointer GetEmptyEditor(SmartPointer descr); }; } // namespace berry #endif /*BERRYEDITORREFERENCE_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.cpp index 0f994146b2..c4c35cbdda 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.cpp @@ -1,1295 +1,1295 @@ /*============================================================================ 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 "berryEditorRegistry.h" #include "berryWorkbenchPlugin.h" #include "berryEditorRegistryReader.h" #include "berryWorkbenchRegistryConstants.h" namespace berry { const QString EditorRegistry::EMPTY_EDITOR_ID = "org.blueberry.ui.internal.emptyEditorTab"; QHash EditorRegistry::EditorMap::defaultMap; QHash EditorRegistry::EditorMap::map; EditorRegistry::RelatedRegistry::RelatedRegistry(EditorRegistry* reg) : editorRegistry(reg) { } QList EditorRegistry::RelatedRegistry::GetRelatedObjects( const QString& fileName) { IFileEditorMapping::Pointer mapping = editorRegistry->GetMappingFor(fileName); if (mapping.IsNull()) { return QList(); } return mapping->GetEditors(); } EditorRegistry::EditorRegistry() : relatedRegistry(this) { this->InitialIdToEditorMap(mapIDtoEditor); this->InitializeFromStorage(); //IExtensionTracker tracker = PlatformUI.getWorkbench().getExtensionTracker(); //tracker.registerHandler(this, // ExtensionTracker.createExtensionPointFilter(getExtensionPointFilter())); } void EditorRegistry::AddEditorFromPlugin(EditorDescriptor::Pointer editor, const QList& extensions, const QList& filenames, const QList& /*contentTypeVector*/, bool bDefault) { //PlatformUI.getWorkbench().getExtensionTracker().registerObject(editor.getConfigurationElement().getDeclaringExtension(), editor, IExtensionTracker.REF_WEAK); // record it in our quick reference list sortedEditorsFromPlugins.push_back(editor); // add it to the table of mappings for (QList::const_iterator itr = extensions.begin(); itr != extensions.end(); ++itr) { QString fileExtension = *itr; if (!fileExtension.isEmpty()) { FileEditorMapping::Pointer mapping = this->GetMappingFor("*." + fileExtension); if (mapping.IsNull()) { // no mapping for that extension mapping = new FileEditorMapping(fileExtension); typeEditorMappings.PutDefault(this->MappingKeyFor(mapping), mapping); } mapping->AddEditor(editor); if (bDefault) { mapping->SetDefaultEditor(editor); } } } // add it to the table of mappings for (QList::const_iterator itr = filenames.begin(); itr != filenames.end(); ++itr) { QString filename = *itr; if (!filename.isEmpty()) { FileEditorMapping::Pointer mapping = this->GetMappingFor(filename); if (mapping.IsNull()) { // no mapping for that extension QString name; QString extension; int index = filename.indexOf('.'); if (index == -1) { name = filename; extension = ""; } else { name = filename.left(index); extension = filename.mid(index + 1); } mapping = new FileEditorMapping(name, extension); typeEditorMappings.PutDefault(this->MappingKeyFor(mapping), mapping); } mapping->AddEditor(editor); if (bDefault) { mapping->SetDefaultEditor(editor); } } } // for (QList::const_iterator itr = contentTypeVector.begin(); // itr != contentTypeVector.end(); ++itr) // { // QString contentTypeId = *itr; // if (!contentTypeId.empty()) // { // IContentType contentType = Platform.getContentTypeManager().getContentType(contentTypeId); // if (contentType != null) // { // IEditorDescriptor [] editorArray = (IEditorDescriptor[]) contentTypeToEditorMappings.get(contentType); // if (editorArray == null) // { // editorArray = new IEditorDescriptor[] // { editor}; // contentTypeToEditorMappings.put(contentType, editorArray); // } // else // { // IEditorDescriptor [] newArray = new IEditorDescriptor[editorArray.length + 1]; // if (bDefault) // { // default editors go to the front of the line // newArray[0] = editor; // System.arraycopy(editorArray, 0, newArray, 1, editorArray.length); // } // else // { // newArray[editorArray.length] = editor; // System.arraycopy(editorArray, 0, newArray, 0, editorArray.length); // } // contentTypeToEditorMappings.put(contentType, newArray); // } // } // } // } // Update editor map. mapIDtoEditor[editor->GetId()] = editor; } void EditorRegistry::AddExternalEditorsToEditorMap() { // Add registered editors (may include external editors). QList maps = typeEditorMappings.AllMappings(); for (int i = 0; i < maps.size(); ++i) { FileEditorMapping::Pointer map = maps[i]; QList descArray = map->GetEditors(); for (QList::iterator itr = descArray.begin(); itr != descArray.end(); ++itr) { mapIDtoEditor[(*itr)->GetId()] = itr->Cast (); } } } IEditorDescriptor::Pointer EditorRegistry::FindEditor(const QString& id) { return mapIDtoEditor[id]; } IEditorDescriptor::Pointer EditorRegistry::GetDefaultEditor() { // the default editor will always be the system external editor // this should never return null return this->FindEditor(IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID); } IEditorDescriptor::Pointer EditorRegistry::GetDefaultEditor( const QString& fileName) { //return this->GetDefaultEditor(filename, guessAtContentType(filename)); return this->GetEditorForContentType(fileName /*, contentType*/); } IEditorDescriptor::Pointer EditorRegistry::GetEditorForContentType( const QString& filename /*IContentType contentType*/) { IEditorDescriptor::Pointer desc; ; QList contentTypeResults = this->FindRelatedObjects(/*contentType,*/filename, relatedRegistry); if (contentTypeResults.size() > 0) { desc = contentTypeResults.front(); } return desc; } QList EditorRegistry::FindRelatedObjects( /*IContentType type,*/const QString& fileName, RelatedRegistry& /*registry*/) { QList allRelated; QList nonDefaultFileEditors; QList related; if (!fileName.isEmpty()) { FileEditorMapping::Pointer mapping = this->GetMappingFor(fileName); if (!mapping.IsNull()) { // backwards compatibility - add editors flagged as "default" related = mapping->GetDeclaredDefaultEditors(); for (QList::iterator itr = related.begin(); itr != related.end(); ++itr) { // we don't want to return duplicates if (std::find(allRelated.begin(), allRelated.end(), *itr) == allRelated.end()) { allRelated.push_back(*itr); } } // add all filename editors to the nonDefaultList // we'll later try to add them all after content types are resolved // duplicates (ie: default editors) will be ignored QList tmpList = mapping->GetEditors(); nonDefaultFileEditors.append(tmpList); } int index = fileName.indexOf('.'); if (index != -1) { QString extension = "*" + fileName.mid(index); mapping = this->GetMappingFor(extension); if (!mapping.IsNull()) { related = mapping->GetDeclaredDefaultEditors(); for (QList::iterator itr = related.begin(); itr != related.end(); ++itr) { // we don't want to return duplicates if (std::find(allRelated.begin(), allRelated.end(), *itr) == allRelated.end()) { allRelated.push_back(*itr); } } QList tmpList = mapping->GetEditors(); nonDefaultFileEditors.append(tmpList); } } } // if (type != null) { // // now add any objects directly related to the content type // related = registry.getRelatedObjects(type); // for (int i = 0; i < related.length; i++) { // // we don't want to return duplicates // if (!allRelated.contains(related[i])) { // // if it's not filtered, add it to the list // if (!WorkbenchActivityHelper.filterItem(related[i])) { // allRelated.add(related[i]); // } // } // } // // } // if (type != null) { // // now add any indirectly related objects, walking up the content type hierarchy // while ((type = type.getBaseType()) != null) { // related = registry.getRelatedObjects(type); // for (int i = 0; i < related.length; i++) { // // we don't want to return duplicates // if (!allRelated.contains(related[i])) { // // if it's not filtered, add it to the list // if (!WorkbenchActivityHelper.filterItem(related[i])) { // allRelated.add(related[i]); // } // } // } // } // } // add all non-default editors to the list for (QList::iterator i = nonDefaultFileEditors.begin(); i != nonDefaultFileEditors.end(); ++i) { IEditorDescriptor::Pointer editor = *i; if (std::find(allRelated.begin(), allRelated.end(), editor) == allRelated.end()) { allRelated.push_back(editor); } } return allRelated; } QList EditorRegistry::GetEditors( const QString& filename) { //return getEditors(filename, guessAtContentType(filename)); return this->FindRelatedObjects(/*contentType,*/filename, relatedRegistry); } QList EditorRegistry::GetFileEditorMappings() { QList array(typeEditorMappings.AllMappings()); std::sort(array.begin(), array.end(), CmpFileEditorMapping()); QList result; for (QList::iterator itr = array.begin(); itr != array.end(); ++itr) { result.push_back(itr->Cast ()); } return result; } FileEditorMapping::Pointer EditorRegistry::GetMappingFor(const QString& ext) { QString key = this->MappingKeyFor(ext); return typeEditorMappings.Get(key); } QList EditorRegistry::GetMappingForFilename( const QString& filename) { QList mapping; // Lookup on entire filename mapping[0] = this->GetMappingFor(filename); // Lookup on filename's extension int index = filename.indexOf('.'); if (index != -1) { QString extension = filename.mid(index); mapping[1] = this->GetMappingFor("*" + extension); } return mapping; } // QList EditorRegistry::GetSortedEditorsFromOS() // { // List externalEditors = new ArrayList(); // Program[] programs = Program.getPrograms(); // // for (int i = 0; i < programs.length; i++) // { // //1FPLRL2: ITPUI:WINNT - NOTEPAD editor cannot be launched // //Some entries start with %SystemRoot% // //For such cases just use the file name as they are generally // //in directories which are on the path // /* // * if (fileName.charAt(0) == '%') { fileName = name + ".exe"; } // */ // // EditorDescriptor editor = new EditorDescriptor(); // editor.setOpenMode(EditorDescriptor.OPEN_EXTERNAL); // editor.setProgram(programs[i]); // // // determine the program icon this editor would need (do not let it // // be cached in the workbench registry) // ImageDescriptor desc = new ExternalProgramImageDescriptor( // programs[i]); // editor.setImageDescriptor(desc); // externalEditors.add(editor); // } // // Object[] tempArray = sortEditors(externalEditors); // IEditorDescriptor[] array = new IEditorDescriptor[externalEditors // .size()]; // for (int i = 0; i < tempArray.length; i++) // { // array[i] = (IEditorDescriptor) tempArray[i]; // } // return array; // } QList EditorRegistry::GetSortedEditorsFromPlugins() { QList result; for (QList::iterator itr = sortedEditorsFromPlugins.begin(); itr != sortedEditorsFromPlugins.end(); ++itr) { result.push_back((*itr).Cast ()); } return result; } void EditorRegistry::InitialIdToEditorMap( QHash& map) { this->AddSystemEditors(map); } void EditorRegistry::AddSystemEditors( QHash& map) { // there will always be a system external editor descriptor EditorDescriptor::Pointer editor(new EditorDescriptor()); editor->SetID(IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID); editor->SetName("System Editor"); editor->SetOpenMode(EditorDescriptor::OPEN_EXTERNAL); // @issue we need a real icon for this editor? map[IEditorRegistry::SYSTEM_EXTERNAL_EDITOR_ID] = editor; // there may be a system in-place editor if supported by platform // if (ComponentSupport.inPlaceEditorSupported()) // { // editor = new EditorDescriptor(); // editor.setID(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID); // editor.setName(WorkbenchMessages.SystemInPlaceDescription_name); // editor.setOpenMode(EditorDescriptor.OPEN_INPLACE); // // @issue we need a real icon for this editor? // map.put(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID, editor); // } EditorDescriptor::Pointer emptyEditorDescriptor(new EditorDescriptor()); emptyEditorDescriptor->SetID(EMPTY_EDITOR_ID); emptyEditorDescriptor->SetName("(Empty)"); //$NON-NLS-1$ //emptyEditorDescriptor.setImageDescriptor(WorkbenchImages //.getImageDescriptor(IWorkbenchGraphicConstants.IMG_OBJ_ELEMENT)); map[EMPTY_EDITOR_ID] = emptyEditorDescriptor; } void EditorRegistry::InitializeFromStorage() { //Get editors from the registry EditorRegistryReader registryReader; registryReader.AddEditors(this); this->SortInternalEditors(); this->RebuildInternalEditorMap(); // IPreferenceStore store = PlatformUI.getPreferenceStore(); // String defaultEditors = store // .getString(IPreferenceConstants.DEFAULT_EDITORS); // String chachedDefaultEditors = store // .getString(IPreferenceConstants.DEFAULT_EDITORS_CACHE); //If defaults has changed load it afterwards so it overrides the users // associations. //if (defaultEditors == null // || defaultEditors.equals(chachedDefaultEditors)) //{ this->SetProductDefaults("");//defaultEditors); this->LoadAssociations(); //get saved earlier state // } // else // { // loadAssociations(); //get saved earlier state // setProductDefaults(defaultEditors); // store.putValue(IPreferenceConstants.DEFAULT_EDITORS_CACHE, // defaultEditors); // } this->AddExternalEditorsToEditorMap(); } void EditorRegistry::SetProductDefaults(const QString& defaultEditors) { if (defaultEditors.isEmpty()) { return; } // Poco::StringTokenizer extEditors(defaultEditors, // IPreferenceConstants::SEPARATOR, Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); // while (extEditors.hasMoreTokens()) // { // String extEditor = extEditors.nextToken().trim(); // int index = extEditor.indexOf(':'); // if (extEditor.length() < 3 || index <= 0 || index // >= (extEditor.length() - 1)) // { // //Extension and id must have at least one char. // WorkbenchPlugin // .log("Error setting default editor. Could not parse '" + extEditor // + "'. Default editors should be specified as '*.ext1:editorId1;*.ext2:editorId2'"); //$NON-NLS-1$ //$NON-NLS-2$ // return; // } // String ext = extEditor.substring(0, index).trim(); // String editorId = extEditor.substring(index + 1).trim(); // FileEditorMapping mapping = getMappingFor(ext); // if (mapping == null) // { // WorkbenchPlugin // .log("Error setting default editor. Could not find mapping for '" // + ext + "'."); //$NON-NLS-1$ //$NON-NLS-2$ // continue; // } // EditorDescriptor editor = (EditorDescriptor) findEditor(editorId); // if (editor == null) // { // WorkbenchPlugin // .log("Error setting default editor. Could not find editor: '" // + editorId + "'."); //$NON-NLS-1$ //$NON-NLS-2$ // continue; // } // mapping.setDefaultEditor(editor); // } } bool EditorRegistry::ReadEditors( QHash& /*editorTable*/) { //Get the workbench plugin's working directory QString workbenchStatePath = WorkbenchPlugin::GetDefault()->GetDataLocation(); if (workbenchStatePath.isNull()) { return false; } // IPreferenceStore store = WorkbenchPlugin.getDefault() // .getPreferenceStore(); // Reader reader = null; // try // { // // Get the editors defined in the preferences store // String xmlString = store.getString(IPreferenceConstants.EDITORS); // if (xmlString == null || xmlString.length() == 0) // { // FileInputStream stream = new FileInputStream(workbenchStatePath // .append(IWorkbenchConstants.EDITOR_FILE_NAME) // .toOSString()); // reader = new BufferedReader(new InputStreamReader(stream, // "utf-8")); //$NON-NLS-1$ // } // else // { // reader = new StringReader(xmlString); // } // XMLMemento memento = XMLMemento.createReadRoot(reader); // EditorDescriptor editor; // IMemento[] edMementos = memento // .getChildren(IWorkbenchConstants.TAG_DESCRIPTOR); // // Get the editors and validate each one // for (int i = 0; i < edMementos.length; i++) // { // editor = new EditorDescriptor(); // boolean valid = editor.loadValues(edMementos[i]); // if (!valid) // { // continue; // } // if (editor.getPluginID() != null) // { // //If the editor is from a plugin we use its ID to look it // // up in the mapping of editors we // //have obtained from plugins. This allows us to verify that // // the editor is still valid // //and allows us to get the editor description from the // // mapping table which has // //a valid config element field. // EditorDescriptor validEditorDescritor = (EditorDescriptor) mapIDtoEditor // .get(editor.getId()); // if (validEditorDescritor != null) // { // editorTable.put(validEditorDescritor.getId(), // validEditorDescritor); // } // } // else // { //This is either from a program or a user defined // // editor // ImageDescriptor descriptor; // if (editor.getProgram() == null) // { // descriptor = new ProgramImageDescriptor(editor // .getFileName(), 0); // } // else // { // descriptor = new ExternalProgramImageDescriptor(editor // .getProgram()); // } // editor.setImageDescriptor(descriptor); // editorTable.put(editor.getId(), editor); // } // } // } // catch (IOException e) // { // try // { // if (reader != null) // { // reader.close(); // } // } // catch (IOException ex) // { // e.printStackTrace(); // } // //Ignore this as the workbench may not yet have saved any state // return false; // } // catch (WorkbenchException e) // { // ErrorDialog.openError((Shell) null, WorkbenchMessages.EditorRegistry_errorTitle, // WorkbenchMessages.EditorRegistry_errorMessage, // e.getStatus()); // return false; // } return true; } void EditorRegistry::ReadResources( QHash& /*editorTable*/, std::ostream& /*reader*/) { // XMLMemento memento = XMLMemento.createReadRoot(reader); // String versionString = memento.getString(IWorkbenchConstants.TAG_VERSION); // boolean versionIs31 = "3.1".equals(versionString); //$NON-NLS-1$ // // IMemento[] extMementos = memento // .getChildren(IWorkbenchConstants.TAG_INFO); // for (int i = 0; i < extMementos.length; i++) // { // String name = extMementos[i] // .getString(IWorkbenchConstants.TAG_NAME); // if (name == null) // { // name = "*"; //$NON-NLS-1$ // } // String extension = extMementos[i] // .getString(IWorkbenchConstants.TAG_EXTENSION); // IMemento[] idMementos = extMementos[i] // .getChildren(IWorkbenchConstants.TAG_EDITOR); // String[] editorIDs = new String[idMementos.length]; // for (int j = 0; j < idMementos.length; j++) // { // editorIDs[j] = idMementos[j] // .getString(IWorkbenchConstants.TAG_ID); // } // idMementos = extMementos[i] // .getChildren(IWorkbenchConstants.TAG_DELETED_EDITOR); // String[] deletedEditorIDs = new String[idMementos.length]; // for (int j = 0; j < idMementos.length; j++) // { // deletedEditorIDs[j] = idMementos[j] // .getString(IWorkbenchConstants.TAG_ID); // } // FileEditorMapping mapping = getMappingFor(name + "." + extension); //$NON-NLS-1$ // if (mapping == null) // { // mapping = new FileEditorMapping(name, extension); // } // List editors = new ArrayList(); // for (int j = 0; j < editorIDs.length; j++) // { // if (editorIDs[j] != null) // { // EditorDescriptor editor = (EditorDescriptor) editorTable // .get(editorIDs[j]); // if (editor != null) // { // editors.add(editor); // } // } // } // List deletedEditors = new ArrayList(); // for (int j = 0; j < deletedEditorIDs.length; j++) // { // if (deletedEditorIDs[j] != null) // { // EditorDescriptor editor = (EditorDescriptor) editorTable // .get(deletedEditorIDs[j]); // if (editor != null) // { // deletedEditors.add(editor); // } // } // } // // List defaultEditors = new ArrayList(); // // if (versionIs31) // { // parse the new format // idMementos = extMementos[i] // .getChildren(IWorkbenchConstants.TAG_DEFAULT_EDITOR); // String[] defaultEditorIds = new String[idMementos.length]; // for (int j = 0; j < idMementos.length; j++) // { // defaultEditorIds[j] = idMementos[j] // .getString(IWorkbenchConstants.TAG_ID); // } // for (int j = 0; j < defaultEditorIds.length; j++) // { // if (defaultEditorIds[j] != null) // { // EditorDescriptor editor = (EditorDescriptor) editorTable // .get(defaultEditorIds[j]); // if (editor != null) // { // defaultEditors.add(editor); // } // } // } // } // else // { // guess at pre 3.1 format defaults // if (!editors.isEmpty()) // { // EditorDescriptor editor = (EditorDescriptor) editors.get(0); // if (editor != null) // { // defaultEditors.add(editor); // } // } // defaultEditors.addAll(Arrays.asList(mapping.getDeclaredDefaultEditors())); // } // // // Add any new editors that have already been read from the registry // // which were not deleted. // IEditorDescriptor[] editorsArray = mapping.getEditors(); // for (int j = 0; j < editorsArray.length; j++) // { // if (!contains(editors, editorsArray[j]) // && !deletedEditors.contains(editorsArray[j])) // { // editors.add(editorsArray[j]); // } // } // // Map the editor(s) to the file type // mapping.setEditorsList(editors); // mapping.setDeletedEditorsList(deletedEditors); // mapping.setDefaultEditors(defaultEditors); // typeEditorMappings.put(mappingKeyFor(mapping), mapping); // } } bool EditorRegistry::Contains( const QList& editorsArray, IEditorDescriptor::Pointer editorDescriptor) { IEditorDescriptor::Pointer currentEditorDescriptor; for (QList::const_iterator i = editorsArray.begin(); i != editorsArray.end(); ++i) { currentEditorDescriptor = *i; if (currentEditorDescriptor->GetId() == editorDescriptor->GetId()) { return true; } } return false; } bool EditorRegistry::ReadResources( QHash& /*editorTable*/) { //Get the workbench plugin's working directory QString workbenchStatePath = WorkbenchPlugin::GetDefault()->GetDataLocation(); // XXX: nobody cares about this return value if (workbenchStatePath.isNull()) { return false; } // IPreferenceStore store = WorkbenchPlugin.getDefault() // .getPreferenceStore(); // Reader reader = null; // try // { // // Get the resource types // String xmlString = store.getString(IPreferenceConstants.RESOURCES); // if (xmlString == null || xmlString.length() == 0) // { // FileInputStream stream = new FileInputStream(workbenchStatePath // .append(IWorkbenchConstants.RESOURCE_TYPE_FILE_NAME) // .toOSString()); // reader = new BufferedReader(new InputStreamReader(stream, // "utf-8")); //$NON-NLS-1$ // } // else // { // reader = new StringReader(xmlString); // } // // Read the defined resources into the table // readResources(editorTable, reader); // } // catch (IOException e) // { // try // { // if (reader != null) // { // reader.close(); // } // } // catch (IOException ex) // { // ex.printStackTrace(); // } // MessageDialog.openError((Shell) null, WorkbenchMessages.EditorRegistry_errorTitle, // WorkbenchMessages.EditorRegistry_errorMessage); // return false; // } // catch (WorkbenchException e) // { // ErrorDialog.openError((Shell) null, WorkbenchMessages.EditorRegistry_errorTitle, // WorkbenchMessages.EditorRegistry_errorMessage, // e.getStatus()); // return false; // } return true; } bool EditorRegistry::LoadAssociations() { QHash editorTable; if (!this->ReadEditors(editorTable)) { return false; } return this->ReadResources(editorTable); } QString EditorRegistry::MappingKeyFor(const QString& type) { - // keep everyting lower case for case-sensitive platforms + // keep everything lower case for case-sensitive platforms return type.toLower(); } QString EditorRegistry::MappingKeyFor(FileEditorMapping::Pointer mapping) { return this->MappingKeyFor(mapping->GetName() + (mapping->GetExtension().size() == 0 ? "" : "." + mapping->GetExtension())); //$NON-NLS-1$ //$NON-NLS-2$ } void EditorRegistry::RebuildEditorMap() { this->RebuildInternalEditorMap(); this->AddExternalEditorsToEditorMap(); } void EditorRegistry::RebuildInternalEditorMap() { EditorDescriptor::Pointer desc; // Allocate a new map. mapIDtoEditor.clear(); this->InitialIdToEditorMap(mapIDtoEditor); // Add plugin editors. for (QList::iterator itr = sortedEditorsFromPlugins.begin(); itr != sortedEditorsFromPlugins.end(); ++itr) { desc = *itr; mapIDtoEditor[desc->GetId()] = desc; } } void EditorRegistry::SaveAssociations() { //Save the resource type descriptions // List editors = new ArrayList(); // IPreferenceStore store = WorkbenchPlugin.getDefault() // .getPreferenceStore(); // // XMLMemento memento = XMLMemento // .createWriteRoot(IWorkbenchConstants.TAG_EDITORS); // memento.putString(IWorkbenchConstants.TAG_VERSION, "3.1"); //$NON-NLS-1$ // FileEditorMapping maps[] = typeEditorMappings.userMappings(); // for (int mapsIndex = 0; mapsIndex < maps.length; mapsIndex++) // { // FileEditorMapping type = maps[mapsIndex]; // IMemento editorMemento = memento // .createChild(IWorkbenchConstants.TAG_INFO); // editorMemento.putString(IWorkbenchConstants.TAG_NAME, type // .getName()); // editorMemento.putString(IWorkbenchConstants.TAG_EXTENSION, type // .getExtension()); // IEditorDescriptor[] editorArray = type.getEditors(); // for (int i = 0; i < editorArray.length; i++) // { // EditorDescriptor editor = (EditorDescriptor) editorArray[i]; // if (!editors.contains(editor)) // { // editors.add(editor); // } // IMemento idMemento = editorMemento // .createChild(IWorkbenchConstants.TAG_EDITOR); // idMemento.putString(IWorkbenchConstants.TAG_ID, editorArray[i] // .getId()); // } // editorArray = type.getDeletedEditors(); // for (int i = 0; i < editorArray.length; i++) // { // EditorDescriptor editor = (EditorDescriptor) editorArray[i]; // if (!editors.contains(editor)) // { // editors.add(editor); // } // IMemento idMemento = editorMemento // .createChild(IWorkbenchConstants.TAG_DELETED_EDITOR); // idMemento.putString(IWorkbenchConstants.TAG_ID, editorArray[i] // .getId()); // } // editorArray = type.getDeclaredDefaultEditors(); // for (int i = 0; i < editorArray.length; i++) // { // EditorDescriptor editor = (EditorDescriptor) editorArray[i]; // if (!editors.contains(editor)) // { // editors.add(editor); // } // IMemento idMemento = editorMemento // .createChild(IWorkbenchConstants.TAG_DEFAULT_EDITOR); // idMemento.putString(IWorkbenchConstants.TAG_ID, editorArray[i] // .getId()); // } // } // Writer writer = null; // try // { // writer = new StringWriter(); // memento.save(writer); // writer.close(); // store.setValue(IPreferenceConstants.RESOURCES, writer.toString()); // } // catch (IOException e) // { // try // { // if (writer != null) // { // writer.close(); // } // } // catch (IOException ex) // { // ex.printStackTrace(); // } // MessageDialog.openError((Shell) null, "Saving Problems", //$NON-NLS-1$ // "Unable to save resource associations."); //$NON-NLS-1$ // return; // } // // memento = XMLMemento.createWriteRoot(IWorkbenchConstants.TAG_EDITORS); // Iterator itr = editors.iterator(); // while (itr.hasNext()) // { // EditorDescriptor editor = (EditorDescriptor) itr.next(); // IMemento editorMemento = memento // .createChild(IWorkbenchConstants.TAG_DESCRIPTOR); // editor.saveValues(editorMemento); // } // writer = null; // try // { // writer = new StringWriter(); // memento.save(writer); // writer.close(); // store.setValue(IPreferenceConstants.EDITORS, writer.toString()); // } // catch (IOException e) // { // try // { // if (writer != null) // { // writer.close(); // } // } // catch (IOException ex) // { // ex.printStackTrace(); // } // MessageDialog.openError((Shell) null, // "Error", "Unable to save resource associations."); //$NON-NLS-1$ //$NON-NLS-2$ // return; // } } void EditorRegistry::SetFileEditorMappings( const QList& newResourceTypes) { typeEditorMappings.Clear(); for (int i = 0; i < newResourceTypes.size(); i++) { FileEditorMapping::Pointer mapping = newResourceTypes[i]; typeEditorMappings.Put(this->MappingKeyFor(mapping), mapping); } //extensionImages = new HashMap(); this->RebuildEditorMap(); //firePropertyChange(PROP_CONTENTS); } void EditorRegistry::SetDefaultEditor(const QString& fileName, const QString& editorId) { EditorDescriptor::Pointer desc = this->FindEditor(editorId).Cast< EditorDescriptor> (); QList mapping = this->GetMappingForFilename( fileName); if (!mapping[0].IsNull()) { mapping[0]->SetDefaultEditor(desc); } if (!mapping[1].IsNull()) { mapping[1]->SetDefaultEditor(desc); } } QList EditorRegistry::SortEditors( const QList& unsortedList) { QList result(unsortedList); std::sort(result.begin(), result.end(), CmpIEditorDescriptor()); return result; } void EditorRegistry::SortInternalEditors() { qSort(sortedEditorsFromPlugins.begin(), sortedEditorsFromPlugins.end(), CmpEditorDescriptor()); } void EditorRegistry::EditorMap::PutDefault(const QString& key, FileEditorMapping::Pointer value) { defaultMap[key] = value; } void EditorRegistry::EditorMap::Put(const QString& key, FileEditorMapping::Pointer value) { QHash::iterator result = defaultMap.find(key); if (result != defaultMap.end()) { map[key] = value; } } FileEditorMapping::Pointer EditorRegistry::EditorMap::Get( const QString& key) { QHash::const_iterator result = map.find(key); if (result == map.end()) { return defaultMap[key]; } return result.value(); } void EditorRegistry::EditorMap::Clear() { defaultMap.clear(); map.clear(); } QList EditorRegistry::EditorMap::AllMappings() { QSet resultSet; QHash::const_iterator iter; for (iter = defaultMap.begin(); iter != defaultMap.end(); ++iter) { resultSet.insert(iter.value()); } for (iter = map.begin(); iter != map.end(); ++iter) { resultSet.insert(iter.value()); } return resultSet.toList(); } QList EditorRegistry::EditorMap::UserMappings() { return map.values(); } bool EditorRegistry::IsSystemInPlaceEditorAvailable(const QString& /*filename*/) { //return ComponentSupport.inPlaceEditorAvailable(filename); return false; } bool EditorRegistry::IsSystemExternalEditorAvailable( const QString& /*filename*/) { // QString::size_type nDot = filename.find_last_of('.'); // if (nDot != QString::npos) // { // QString strName = filename.substr(nDot); // return Program.findProgram(strName) != null; // } return false; } void EditorRegistry::RemoveEditorFromMapping( QHash& map, IEditorDescriptor::Pointer desc) { FileEditorMapping::Pointer mapping; for (QHash::iterator iter = map.begin(); iter != map.end(); ++iter) { mapping = iter.value(); QList editors(mapping->GetEditors()); QList::iterator result = std::find( editors.begin(), editors.end(), desc); if (result != editors.end()) { mapping->RemoveEditor(result->Cast ()); editors.erase(result); } if (editors.empty()) { map.erase(iter); break; } } } IExtensionPoint::Pointer EditorRegistry::GetExtensionPointFilter() { return Platform::GetExtensionRegistry()->GetExtensionPoint( PlatformUI::PLUGIN_ID(), WorkbenchRegistryConstants::PL_EDITOR); } QList EditorRegistry::GetUnifiedMappings() { QList standardMappings( dynamic_cast (PlatformUI::GetWorkbench() ->GetEditorRegistry())->GetFileEditorMappings()); QList allMappings(standardMappings); // mock-up content type extensions into IFileEditorMappings // IContentType [] contentTypes = Platform.getContentTypeManager().getAllContentTypes(); // for (int i = 0; i < contentTypes.length; i++) // { // IContentType type = contentTypes[i]; // String [] extensions = type.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); // for (int j = 0; j < extensions.length; j++) // { // String extension = extensions[j]; // boolean found = false; // for (Iterator k = allMappings.iterator(); k.hasNext();) // { // IFileEditorMapping mapping = (IFileEditorMapping) k.next(); // if ("*".equals(mapping.getName()) // && extension.equals(mapping.getExtension())) // { //$NON-NLS-1$ // found = true; // break; // } // } // if (!found) // { // MockMapping mockMapping = new MockMapping(type, "*", extension); //$NON-NLS-1$ // allMappings.add(mockMapping); // } // } // // String [] filenames = type.getFileSpecs(IContentType.FILE_NAME_SPEC); // for (int j = 0; j < filenames.length; j++) // { // String wholename = filenames[j]; // int idx = wholename.indexOf('.'); // String name = idx == -1 ? wholename : wholename.substring(0, idx); // String extension = idx == -1 ? "" : wholename.substring(idx + 1); //$NON-NLS-1$ // // boolean found = false; // for (Iterator k = allMappings.iterator(); k.hasNext();) // { // IFileEditorMapping mapping = (IFileEditorMapping) k.next(); // if (name.equals(mapping.getName()) // && extension.equals(mapping.getExtension())) // { // found = true; // break; // } // } // if (!found) // { // MockMapping mockMapping = new MockMapping(type, name, extension); // allMappings.add(mockMapping); // } // } // } return allMappings; } MockMapping::MockMapping(/*IContentType type,*/const QString& name, const QString& ext) : extension(ext), filename(name) { //this.contentType = type; } IEditorDescriptor::Pointer MockMapping::GetDefaultEditor() { // QList candidates = PlatformUI::GetWorkbench()->GetEditorRegistry() // ->GetEditorsForContentType(contentType); // if (candidates.empty()) // { // return IEditorDescriptor::Pointer(); // } // return candidates[0]; return IEditorDescriptor::Pointer(); } QList MockMapping::GetEditors() const { // QList editorsForContentType = (dynamic_cast(PlatformUI // ::GetWorkbench()->GetEditorRegistry()) // ->GetEditorsForContentType(contentType); // return editorsForContentType; return QList(); } QList MockMapping::GetDeletedEditors() const { return QList(); } QString MockMapping::GetExtension() const { return extension; } QString MockMapping::GetLabel() const { return filename + '.' + extension; } QString MockMapping::GetName() const { return filename; } bool MockMapping::operator==(const Object* obj) const { if (const MockMapping* other = dynamic_cast(obj)) { if (this == other) { return true; } //MockMapping mapping = (MockMapping) obj; if (!(this->filename == other->filename)) { return false; } if (!(this->extension == other->extension)) { return false; } if (!(this->GetEditors() == other->GetEditors())) { return false; } return this->GetDeletedEditors() == other->GetDeletedEditors(); } return false; } } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.h b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.h index 3ac251dbc6..6716f0b9de 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorRegistry.h @@ -1,754 +1,754 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYEDITORREGISTRY_H_ #define BERRYEDITORREGISTRY_H_ #include #include "berryIEditorRegistry.h" #include "berryIFileEditorMapping.h" #include "berryEditorDescriptor.h" #include "berryFileEditorMapping.h" namespace berry { /** * \ingroup org_blueberry_ui_internal * * Provides access to the collection of defined editors for resource types. */ class EditorRegistry : public IEditorRegistry { class RelatedRegistry { public: RelatedRegistry(EditorRegistry* editorRegistry); /** * Return the objects related to the type. * * @param type * @return the objects related to the type */ // public: QList GetRelatedObjects(IContentType type) { // IEditorDescriptor[] relatedObjects = (IEditorDescriptor[]) contentTypeToEditorMappings.get(type); // if (relatedObjects == null) { // return EMPTY; // } // return (IEditorDescriptor[]) WorkbenchActivityHelper.restrictArray(relatedObjects); // } /** * Return the objects related to the filename * @param fileName * @return the objects related to the filename */ public: QList GetRelatedObjects( const QString& fileName); private: EditorRegistry* editorRegistry; }; friend class RelatedRegistry; /** * Map of FileEditorMapping (extension to FileEditorMapping) Uses two * java.util.HashMap: one keeps the default which are set by the plugins and * the other keeps the changes made by the user through the preference page. */ class EditorMap { static QHash defaultMap; static QHash map; public: void Clear(); /** * Put a default mapping into the editor map. * * @param key the key to set * @param value the value to associate */ public: static void PutDefault(const QString& key, FileEditorMapping::Pointer value); /** * Put a mapping into the user editor map. * * @param key the key to set * @param value the value to associate */ public: void Put(const QString& key, FileEditorMapping::Pointer value); /** * Return the mapping associated to the key. First searches user * map, and then falls back to the default map if there is no match. May * return null * * @param key * the key to search for * @return the mapping associated to the key or null */ public: FileEditorMapping::Pointer Get(const QString& key); /** * Return all mappings. This will return default mappings overlayed with * user mappings. * * @return the mappings */ public: QList AllMappings(); /** * Return all user mappings. * * @return the mappings */ public: QList UserMappings(); }; struct CmpFileEditorMapping { bool operator()(const FileEditorMapping::Pointer& x, const FileEditorMapping::Pointer& y) const { return x->GetLabel() < y->GetLabel(); } }; struct CmpIEditorDescriptor { bool operator()(const IEditorDescriptor::Pointer& x, const IEditorDescriptor::Pointer& y) const { return x->GetLabel() < y->GetLabel(); } }; struct CmpEditorDescriptor { bool operator()(const EditorDescriptor::Pointer& x, const EditorDescriptor::Pointer& y) const { return x->GetLabel() < y->GetLabel(); } }; //private: Map contentTypeToEditorMappings = new HashMap(); /* * Cached images - these include images from registered editors (via * plugins) and others hence this table is not one to one with the mappings * table. It is in fact a superset of the keys one would find in * typeEditorMappings */ //private: Map extensionImages = new HashMap(); /** * Vector of EditorDescriptor - all the editors loaded from plugin files. * The list is kept in order to be able to show in the editor selection * dialog of the resource associations page. This list is sorted based on the * human readable label of the editor descriptor. * * @see #comparer */ private: QList sortedEditorsFromPlugins; // Map of EditorDescriptor - map editor id to editor. private: QHash mapIDtoEditor; // Map of FileEditorMapping (extension to FileEditorMapping) private: EditorMap typeEditorMappings; /* * Compares the labels from two IEditorDescriptor objects */ //private: // static final Comparator comparer = new Comparator() // { // private Collator collator = Collator.getInstance(); // // public int compare(Object arg0, Object arg1) // { // String s1 = ((IEditorDescriptor) arg0).getLabel(); // String s2 = ((IEditorDescriptor) arg1).getLabel(); // return collator.compare(s1, s2); // } // }; private: RelatedRegistry relatedRegistry; public: static const QString EMPTY_EDITOR_ID; // = "org.blueberry.ui.internal.emptyEditorTab" /** * Return an instance of the receiver. Adds listeners into the extension * registry for dynamic UI purposes. */ public: EditorRegistry(); /** * Add an editor for the given extensions with the specified (possibly null) * extended type. The editor is being registered from a plugin * * @param editor * The description of the editor (as obtained from the plugin * file and built by the registry reader) * @param extensions * Collection of file extensions the editor applies to * @param filenames * Collection of filenames the editor applies to * @param contentTypeVector * @param bDefault * Indicates whether the editor should be made the default editor * and hence appear first inside a FileEditorMapping * * This method is not API and should not be called outside the workbench * code. */ public: void AddEditorFromPlugin(EditorDescriptor::Pointer editor, const QList& extensions, const QList& filenames, const QList& contentTypeVector, bool bDefault); /** * Add external editors to the editor mapping. */ private: void AddExternalEditorsToEditorMap(); /* * (non-Javadoc) Method declared on IEditorRegistry. */ //public: void AddPropertyListener(IPropertyListener l) { // addListenerObject(l); // } /* * (non-Javadoc) Method declared on IEditorRegistry. */ public: IEditorDescriptor::Pointer FindEditor(const QString& id) override; /** * Fires a property changed event to all registered listeners. * * @param type the type of event * @see IEditorRegistry#PROP_CONTENTS */ // private: void FirePropertyChange(final int type) { // Object[] array = getListeners(); // for (int nX = 0; nX < array.length; nX++) { // final IPropertyListener l = (IPropertyListener) array[nX]; // Platform.run(new SafeRunnable() { // public: void run() { // l.propertyChanged(EditorRegistry.this, type); // } // }); // } // } /* * (non-Javadoc) Method declared on IEditorRegistry. * * @deprecated */ public: IEditorDescriptor::Pointer GetDefaultEditor() override; /* * (non-Javadoc) Method declared on IEditorRegistry. */ public: IEditorDescriptor::Pointer GetDefaultEditor(const QString& filename) override; /** * Return the (approximated) content type for a file with the given name. * * @param filename the filename * @return the content type or null if it could not be determined * @since 3.1 */ // private: IContentType::Pointer GuessAtContentType(const QString& filename) { // return Platform.getContentTypeManager().findContentTypeFor(filename); // } /** * Returns the default file image descriptor. * * @return the image descriptor */ // private: ImageDescriptor GetDefaultImage() { // // @issue what should be the default image? // return WorkbenchImages.getImageDescriptor(ISharedImages.IMG_OBJ_FILE); // } /* * (non-Javadoc) Method declared on IEditorRegistry. */ public: QList GetEditors(const QString& filename) override; /* * (non-Javadoc) Method declared on IEditorRegistry. */ public: QList GetFileEditorMappings() override; /* * (non-Javadoc) Method declared on IEditorRegistry. */ // public: ImageDescriptor GetImageDescriptor(String filename) { // return getImageDescriptor(filename, guessAtContentType(filename)); // } /** * Find the file editor mapping for the file extension. Returns * null if not found. * * @param ext * the file extension * @return the mapping, or null */ private: FileEditorMapping::Pointer GetMappingFor(const QString& ext); /** * Find the file editor mappings for the given filename. *

* Return an array of two FileEditorMapping items, where the first mapping * is for the entire filename, and the second mapping is for the filename's * extension only. These items can be null if no mapping exist on the * filename and/or filename's extension.

* * @param filename the filename * @return the mappings */ private: QList GetMappingForFilename(const QString& filename); /** * Return the editor descriptors pulled from the OS. *

* WARNING! The image described by each editor descriptor is *not* known by * the workbench's graphic registry. Therefore clients must take care to * ensure that if they access any of the images held by these editors that * they also dispose them *

* @return the editor descriptors */ //public: QList GetSortedEditorsFromOS(); /** * Return the editors loaded from plugins. * * @return the sorted array of editors declared in plugins * @see #comparer */ public: QList GetSortedEditorsFromPlugins(); /** - * Answer an intial id to editor map. This will create a new map and + * Answer an initial id to editor map. This will create a new map and * populate it with the default system editors. * * @param initialSize * the initial size of the map * @return the new map */ private: void InitialIdToEditorMap(QHash& map); /** * Add the system editors to the provided map. This will always add an * editor with an id of {@link #SYSTEM_EXTERNAL_EDITOR_ID} and may also add * an editor with id of {@link #SYSTEM_INPLACE_EDITOR_ID} if the system * configuration supports it. * * @param map the map to augment */ private: void AddSystemEditors(QHash& map); /** * Initialize the registry state from plugin declarations and preference * overrides. */ private: void InitializeFromStorage(); /** * Set the default editors according to the preference store which can be * overwritten in the file properties.ini. In the form: *

* ext1:id1;ext2:id2;... *

* * @param defaultEditors the default editors to set */ private: void SetProductDefaults(const QString& defaultEditors); /** * Read the editors defined in the preferences store. * * @param editorTable * Editor table to store the editor definitions. - * @return true if the table is built succesfully. + * @return true if the table is built successfully. */ private: bool ReadEditors(QHash& editorTable); /** * Read the file types and associate them to their defined editor(s). * * @param editorTable * The editor table containing the defined editors. * @param reader * Reader containing the preferences content for the resources. * * @throws WorkbenchException */ public: void ReadResources(QHash& editorTable, std::ostream& reader); /** * Determine if the editors list contains the editor descriptor. * * @param editorsArray * The list of editors * @param editorDescriptor * The editor descriptor * @return true if the editors list contains the editor descriptor */ private: bool Contains(const QList& editorsArray, IEditorDescriptor::Pointer editorDescriptor); /** * Creates the reader for the resources preferences defined in the * preference store. * * @param editorTable * The editor table containing the defined editors. - * @return true if the resources are read succesfully. + * @return true if the resources are read successfully. */ private: bool ReadResources(QHash& editorTable); /** * Load the serialized resource associations Return true if the operation * was successful, false otherwise */ private: bool LoadAssociations(); /** * Return a friendly version of the given key suitable for use in the editor * map. */ private: QString MappingKeyFor(const QString& type); /** * Return a key that combines the file's name and extension of the given * mapping * * @param mapping the mapping to generate a key for */ private: QString MappingKeyFor(FileEditorMapping::Pointer mapping); /** * Rebuild the editor map */ private: void RebuildEditorMap(); /** * Rebuild the internal editor mapping. */ private: void RebuildInternalEditorMap(); /* * (non-Javadoc) Method declared on IEditorRegistry. */ // public: void RemovePropertyListener(IPropertyListener l) { // removeListenerObject(l); // } /** * Save the registry to the filesystem by serializing the current resource * associations. */ public: void SaveAssociations(); /** * Set the collection of FileEditorMappings. The given collection is * converted into the internal hash table for faster lookup Each mapping * goes from an extension to the collection of editors that work on it. This * operation will rebuild the internal editor mappings. * * @param newResourceTypes - * te new file editor mappings. + * the new file editor mappings. */ public: void SetFileEditorMappings(const QList& newResourceTypes); /* * (non-Javadoc) Method declared on IEditorRegistry. */ public: void SetDefaultEditor(const QString& fileName, const QString& editorId) override; /** * Alphabetically sort the internal editors. * * @see #comparer */ private: QList SortEditors(const QList& unsortedList); /** * Alphabetically sort the internal editors. * * @see #comparer */ private: void SortInternalEditors(); /* * (non-Javadoc) * * @see org.blueberry.ui.IEditorRegistry#isSystemInPlaceEditorAvailable(String) */ public: bool IsSystemInPlaceEditorAvailable(const QString& filename) override; /* * (non-Javadoc) * * @see org.blueberry.ui.IEditorRegistry#isSystemExternalEditorAvailable(String) */ public: bool IsSystemExternalEditorAvailable(const QString& filename) override; /* * (non-Javadoc) * * @see org.blueberry.ui.IEditorRegistry#getSystemExternalEditorImageDescriptor(java.lang.String) */ // public: ImageDescriptor GetSystemExternalEditorImageDescriptor( // const QString& filename) { // Program externalProgram = null; // int extensionIndex = filename.lastIndexOf('.'); // if (extensionIndex >= 0) { // externalProgram = Program.findProgram(filename // .substring(extensionIndex)); // } // if (externalProgram == null) { // return null; // } // // return new ExternalProgramImageDescriptor(externalProgram); // } /** * Removes the entry with the value of the editor descriptor from the given * map. If the descriptor is the last descriptor in a given * FileEditorMapping then the mapping is removed from the map. * * @param map * the map to search * @param desc * the descriptor value to remove */ private: void RemoveEditorFromMapping(QHash& map, IEditorDescriptor::Pointer desc); private: IExtensionPoint::Pointer GetExtensionPointFilter(); /* (non-Javadoc) * @see org.blueberry.ui.IEditorRegistry#getDefaultEditor(java.lang.String, org.blueberry.core.runtime.content.IContentType) */ // public: IEditorDescriptor::Pointer GetDefaultEditor(const QString& fileName, IContentType contentType) { // return getEditorForContentType(fileName, contentType); // } /** * Return the editor for a file with a given content type. * * @param filename the file name * @param contentType the content type * @return the editor for a file with a given content type * @since 3.1 */ private: IEditorDescriptor::Pointer GetEditorForContentType(const QString& filename /*IContentType contentType*/); /* (non-Javadoc) * @see org.blueberry.ui.IEditorRegistry#getEditors(java.lang.String, org.blueberry.core.runtime.content.IContentType) */ // public: QList GetEditors(const QString& fileName, IContentType contentType) { // return findRelatedObjects(contentType, fileName, relatedRegistry); // } /* (non-Javadoc) * @see org.blueberry.ui.IEditorRegistry#getImageDescriptor(java.lang.String, org.blueberry.core.runtime.content.IContentType) */ // public: ImageDescriptor GetImageDescriptor(const QString filename, IContentType contentType) { // if (filename == null) { // return getDefaultImage(); // } // // if (contentType != null) { // IEditorDescriptor desc = getEditorForContentType(filename, contentType); // if (desc != null) { // ImageDescriptor anImage = (ImageDescriptor) extensionImages.get(desc); // if (anImage != null) { // return anImage; // } // anImage = desc.getImageDescriptor(); // extensionImages.put(desc, anImage); // return anImage; // } // } // // Lookup in the cache first... // String key = mappingKeyFor(filename); // ImageDescriptor anImage = (ImageDescriptor) extensionImages.get(key); // if (anImage != null) { // return anImage; // } // // // See if we have a mapping for the filename or extension // FileEditorMapping[] mapping = getMappingForFilename(filename); // for (int i = 0; i < 2; i++) { // if (mapping[i] != null) { // // Lookup in the cache first... // String mappingKey = mappingKeyFor(mapping[i]); // ImageDescriptor mappingImage = (ImageDescriptor) extensionImages // .get(key); // if (mappingImage != null) { // return mappingImage; // } // // Create it and cache it // IEditorDescriptor editor = mapping[i].getDefaultEditor(); // if (editor != null) { // mappingImage = editor.getImageDescriptor(); // extensionImages.put(mappingKey, mappingImage); // return mappingImage; // } // } // } // // // Nothing - time to look externally for the icon // anImage = getSystemExternalEditorImageDescriptor(filename); // if (anImage == null) { // anImage = getDefaultImage(); // } // // for dynamic UI - comment out the next line // //extensionImages.put(key, anImage); // return anImage; // // } /** * Find objects related to the content type. * * This method is temporary and exists only to back us off of the * soon-to-be-removed IContentTypeManager.IRelatedRegistry API. * * @param type * @param fileName * @param registry * @return the related objects */ private: QList FindRelatedObjects(/*IContentType type,*/ const QString& fileName, RelatedRegistry& registry); /** * Return the editors bound to this content type, either directly or indirectly. * * @param type the content type to check * @return the editors * @since 3.1 * * TODO: this should be rolled in with the above findRelatedObjects code */ // public: QList GetEditorsForContentType(IContentType type) { // ArrayList allRelated = new ArrayList(); // if (type == null) { // return new IEditorDescriptor [0]; // } // // Object [] related = relatedRegistry.getRelatedObjects(type); // for (int i = 0; i < related.length; i++) { // // we don't want to return duplicates // if (!allRelated.contains(related[i])) { // // if it's not filtered, add it to the list // if (!WorkbenchActivityHelper.filterItem(related[i])) { // allRelated.add(related[i]); // } // // } // } // // // now add any indirectly related objects, walking up the content type hierarchy // while ((type = type.getBaseType()) != null) { // related = relatedRegistry.getRelatedObjects(type); // for (int i = 0; i < related.length; i++) { // // we don't want to return duplicates // if (!allRelated.contains(related[i])) { // // if it's not filtered, add it to the list // if (!WorkbenchActivityHelper.filterItem(related[i])) { // allRelated.add(related[i]); // } // } // } // } // // return (IEditorDescriptor[]) allRelated.toArray(new IEditorDescriptor[allRelated.size()]); // } /** * Get filemappings for all defined filetypes, including those defined by content type. * * @return the filetypes * @since 3.1 */ public: QList GetUnifiedMappings(); }; class MockMapping : public IFileEditorMapping { //private: IContentType contentType; private: QString extension; private: QString filename; MockMapping(/*IContentType type,*/const QString& name, const QString& ext); public: IEditorDescriptor::Pointer GetDefaultEditor() override; public: QList GetEditors() const override; public: QList GetDeletedEditors() const override; public: QString GetExtension() const override; // public: ImageDescriptor GetImageDescriptor() { // IEditorDescriptor editor = getDefaultEditor(); // if (editor == null) { // return WorkbenchImages // .getImageDescriptor(ISharedImages.IMG_OBJ_FILE); // } // // return editor.getImageDescriptor(); // } public: QString GetLabel() const override; public: QString GetName() const override; /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ public: bool operator==(const Object* obj) const override; }; } #endif /*BERRYEDITORREGISTRY_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSashContainer.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSashContainer.cpp index ea132a48e3..419749d786 100755 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSashContainer.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSashContainer.cpp @@ -1,605 +1,605 @@ /*============================================================================ 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 "berryEditorSashContainer.h" #include "berryPresentationSerializer.h" #include "berryWorkbenchConstants.h" #include "berryWorkbenchPlugin.h" #include "berryLayoutTree.h" #include "berryWorkbenchWindowConfigurer.h" #include "berryWorkbenchWindow.h" #include "berryQtDnDControlWidget.h" #include "tweaklets/berryGuiWidgetsTweaklet.h" #include #include namespace berry { const QString EditorSashContainer::DEFAULT_WORKBOOK_ID = "DefaultEditorWorkbook"; void EditorSashContainer::AddChild(const RelationshipInfo& info) { PartSashContainer::AddChild(info); this->UpdateStackButtons(); } void EditorSashContainer::ChildAdded(LayoutPart::Pointer child) { PartSashContainer::ChildAdded(child); if (child.Cast () != 0) { editorWorkbooks.push_back(child.Cast ()); } } void EditorSashContainer::ChildRemoved(LayoutPart::Pointer child) { PartSashContainer::ChildRemoved(child); if (child.Cast () != 0) { editorWorkbooks.removeAll(child.Cast()); if (activeEditorWorkbook == child) { this->SetActiveWorkbook(PartStack::Pointer(nullptr), false); } this->UpdateStackButtons(); } } PartStack::Pointer EditorSashContainer::CreateDefaultWorkbook() { PartStack::Pointer newWorkbook = this->NewEditorWorkbook(); newWorkbook->SetID(DEFAULT_WORKBOOK_ID); this->Add(newWorkbook); return newWorkbook; } void EditorSashContainer::AddDropSupport() { WorkbenchWindowConfigurer::Pointer winConfigurer = page->GetWorkbenchWindow().Cast()->GetWindowConfigurer(); QtDnDControlWidget* dropWidget = static_cast(GetParent()); dropWidget->SetTransferTypes(winConfigurer->GetTransfers()); dropWidget->AddDropListener(winConfigurer->GetDropTargetListener()); } PartStack::Pointer EditorSashContainer::NewEditorWorkbook() { PartStack::Pointer newWorkbook(new PartStack(page, true, PresentationFactoryUtil::ROLE_EDITOR)); QString str; QTextStream buf(&str); buf << newWorkbook->GetClassName() << newWorkbook.GetPointer(); newWorkbook->SetID(str); return newWorkbook; } QWidget* EditorSashContainer::CreateParent(QWidget* parentWidget) { //return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->CreateComposite(parentWidget); return new QtDnDControlWidget(static_cast(parentWidget)); } void EditorSashContainer::DisposeParent() { this->parent = nullptr; } bool EditorSashContainer::IsActiveWorkbook(PartStack::Pointer workbook) { return activeEditorWorkbook == workbook; } PartStack::Pointer EditorSashContainer::CreateStack() { return this->NewEditorWorkbook(); } void EditorSashContainer::SetVisiblePart( ILayoutContainer::Pointer container, PartPane::Pointer visiblePart) { PartStack::Pointer stack = container.Cast(); if (stack == 0) return; stack->GetContainer().Cast()->SetActiveWorkbook(stack, true); stack->SetSelection(visiblePart); } LayoutPart::Pointer EditorSashContainer::GetVisiblePart( ILayoutContainer::Pointer container) { PartStack::Pointer refPart = container.Cast(); return refPart->GetSelection(); } EditorSashContainer::EditorSashContainer(const QString& editorId, WorkbenchPage* page, QWidget* parent) : PartSashContainer(editorId, page, parent) { this->CreateDefaultWorkbook(); } bool EditorSashContainer::AllowsAdd(LayoutPart::Pointer layoutPart) { return LayoutPart::AllowsAdd(layoutPart); } void EditorSashContainer::AddEditor(PartPane::Pointer pane, PartStack::Pointer stack) { //EditorStack workbook = getActiveWorkbook(); stack->Add(pane); } void EditorSashContainer::UpdateStackButtons() { // // This is applicable only when the new // // min/max behaviour is being used // Perspective persp = getPage().getActivePerspective(); // if (!Perspective.useNewMinMax(persp)) // return; // // // Find the upper Right editor stack // LayoutPart[] stacks = getChildren(); // EditorStack winner = getUpperRightEditorStack(stacks); // // // Now hide the buttons for all but the upper right stack // for (int i = 0; i < stacks.length; i++) // { // if (!(stacks[i] instanceof EditorStack) // ) // continue; // ((EditorStack) stacks[i]).showMinMax(stacks[i] == winner); // } // // // Force the stack's presentation state to match its perspective // persp.refreshEditorAreaVisibility(); } PartStack::Pointer EditorSashContainer::GetUpperRightEditorStack() { return this->GetUpperRightEditorStack(this->GetChildren()); } PartStack::Pointer EditorSashContainer::GetUpperRightEditorStack( const ILayoutContainer::ChildrenType& stacks) { // Find the upper Right editor stack PartStack::Pointer winner; QRect winnerRect; for (ILayoutContainer::ChildrenType::const_iterator iter = stacks.begin(); iter != stacks.end(); ++iter) { LayoutPart::Pointer part = *iter; if (part.Cast() == 0) continue; PartStack::Pointer stack = part.Cast(); QRect bb = stack->GetBounds(); if (iter == stacks.begin() || bb.y() < winnerRect.y() || (bb.y() == winnerRect.y() && bb.x() > winnerRect.x())) { winner = stack; winnerRect = bb; } } return winner; } PartStack::Pointer EditorSashContainer::GetActiveWorkbook() { if (activeEditorWorkbook == 0) { if (editorWorkbooks.size() < 1) { this->SetActiveWorkbook(this->CreateDefaultWorkbook(), false); } else { this->SetActiveWorkbook(editorWorkbooks.front(), false); } } return activeEditorWorkbook; } QString EditorSashContainer::GetActiveWorkbookID() { return this->GetActiveWorkbook()->GetID(); } QList EditorSashContainer::GetEditorWorkbooks() { return editorWorkbooks; } std::size_t EditorSashContainer::GetEditorWorkbookCount() { return editorWorkbooks.size(); } void EditorSashContainer::FindSashes(LayoutPart::Pointer pane, PartPane::Sashes& sashes) { //Find the sashes around the current editor and //then the sashes around the editor area. PartSashContainer::FindSashes(pane, sashes); ILayoutContainer::Pointer container = this->GetContainer(); if (container != 0) { container->FindSashes(LayoutPart::Pointer(this), sashes); } } void EditorSashContainer::RemoveAllEditors() { PartStack::Pointer currentWorkbook = this->GetActiveWorkbook(); // Iterate over a copy so the original can be modified. QList workbooks(editorWorkbooks); for (QList::iterator iter = workbooks.begin(); iter != workbooks.end(); ++iter) { PartStack::Pointer workbook = *iter; QList children = workbook->GetChildren(); for (QList::iterator childIter = children.begin(); childIter != children.end(); ++childIter) { workbook->Remove(*childIter); } if (workbook != currentWorkbook) { this->Remove(workbook); workbook->Dispose(); } } } void EditorSashContainer::RemoveEditor(PartPane::Pointer pane) { PartStack::Pointer workbook = pane->GetContainer().Cast(); if (workbook == 0) { return; } workbook->Remove(pane); // remove the editor workbook if empty if (workbook->GetItemCount() < 1 /* && editorWorkbooks.size() > 1*/) { // // If the user closes the last editor and the editor area // // is maximized, restore it // Perspective persp = getPage().getActivePerspective(); // if (Perspective.useNewMinMax(persp)) // { // if (persp.getPresentation().getMaximizedStack() instanceof EditorStack) // persp.getPresentation().getMaximizedStack(). // setState(IStackPresentationSite.STATE_RESTORED); // } this->Remove(workbook); workbook->Dispose(); } } bool EditorSashContainer::RestoreState(IMemento::Pointer memento) { //TODO EditorSashContainer restore state // MultiStatus // result = // new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.RootLayoutContainer_problemsRestoringPerspective, 0); bool result = true; // Remove the default editor workbook that is - // initialy created with the editor area. + // initially created with the editor area. // StartupThreading.runWithoutExceptions(new StartupRunnable() // { // // public void runWithException() throws Throwable // { PartStack::Pointer defaultWorkbook; for (ILayoutContainer::ChildrenType::iterator i = children.begin(); i != children.end(); ++i) { LayoutPart::Pointer child = *i; if (child->GetID() == DEFAULT_WORKBOOK_ID) { defaultWorkbook = child.Cast(); if (defaultWorkbook->GetItemCount() > 0) { defaultWorkbook = nullptr; } } } if (defaultWorkbook) { Remove(defaultWorkbook); } // }} // ); // Restore the relationship/layout QList infos(memento->GetChildren(WorkbenchConstants::TAG_INFO)); QHash mapIDtoPart; for (int i = 0; i < infos.size(); i++) { // Get the info details. IMemento::Pointer childMem = infos[i]; QString partID; childMem->GetString(WorkbenchConstants::TAG_PART, partID); QString relativeID; childMem->GetString(WorkbenchConstants::TAG_RELATIVE, relativeID); int relationship = 0; int left = 0, right = 0; if (!relativeID.isEmpty()) { childMem->GetInteger(WorkbenchConstants::TAG_RELATIONSHIP, relationship); childMem->GetInteger(WorkbenchConstants::TAG_RATIO_LEFT, left); childMem->GetInteger(WorkbenchConstants::TAG_RATIO_RIGHT, right); } PartStack::Pointer workbook; // StartupThreading.runWithoutExceptions(new StartupRunnable() // { // // public void runWithException() throws Throwable // { // Create the part. workbook = NewEditorWorkbook(); workbook->SetID(partID); // 1FUN70C: ITPUI:WIN - Shouldn't set Container when not active workbook->SetContainer(ILayoutContainer::Pointer(this)); // }} // ); IMemento::Pointer workbookMemento = childMem->GetChild( WorkbenchConstants::TAG_FOLDER); if (workbookMemento) { //result.add(workbook[0].restoreState(workbookMemento)); result &= workbook->RestoreState(workbookMemento); } const int myLeft = left, myRight = right, myRelationship = relationship; // StartupThreading.runWithoutExceptions(new StartupRunnable() // { // // public void runWithException() throws Throwable // { // Add the part to the layout if (relativeID.isEmpty()) { Add(workbook); } else { LayoutPart::Pointer refPart = mapIDtoPart[relativeID]; if (refPart) { Add(workbook, myRelationship, myLeft, myRight, refPart); } else { WorkbenchPlugin::Log("Unable to find part for ID: " + relativeID); } } // }} // ); mapIDtoPart[partID] = workbook; } return result; } bool EditorSashContainer::SaveState(IMemento::Pointer memento) { QList relationships(ComputeRelation()); // MultiStatus // result = // new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.RootLayoutContainer_problemsSavingPerspective, 0); bool result = true; for (int i = 0; i < relationships.size(); i++) { // Save the relationship info .. // private LayoutPart part; // private int relationship; // private float ratio; // private LayoutPart relative; const RelationshipInfo& info = relationships[i]; IMemento::Pointer childMem = memento->CreateChild( WorkbenchConstants::TAG_INFO); childMem->PutString(WorkbenchConstants::TAG_PART, info.part->GetID()); PartStack::Pointer stack = info.part.Cast(); if (stack) { IMemento::Pointer folderMem = childMem->CreateChild( WorkbenchConstants::TAG_FOLDER); //result.add(stack.saveState(folderMem)); result &= stack->SaveState(folderMem); } if (info.relative != 0) { childMem->PutString(WorkbenchConstants::TAG_RELATIVE, info.relative->GetID()); childMem->PutInteger(WorkbenchConstants::TAG_RELATIONSHIP, info.relationship); childMem->PutInteger(WorkbenchConstants::TAG_RATIO_LEFT, info.left); childMem->PutInteger(WorkbenchConstants::TAG_RATIO_RIGHT, info.right); } } return result; } void EditorSashContainer::SetActiveWorkbook(PartStack::Pointer newWorkbook, bool hasFocus) { if (newWorkbook != 0) { if (std::find(editorWorkbooks.begin(), editorWorkbooks.end(), newWorkbook) == editorWorkbooks.end()) { return; } } PartStack::Pointer oldWorkbook = activeEditorWorkbook; activeEditorWorkbook = newWorkbook; if (oldWorkbook != 0 && oldWorkbook != newWorkbook) { oldWorkbook->SetActive(StackPresentation::AS_INACTIVE); } if (newWorkbook != 0) { if (hasFocus) { newWorkbook->SetActive(StackPresentation::AS_ACTIVE_FOCUS); } else { newWorkbook->SetActive(StackPresentation::AS_ACTIVE_NOFOCUS); } } this->UpdateTabList(); } void EditorSashContainer::SetActiveWorkbookFromID(const QString& id) { for (QList::iterator iter = editorWorkbooks.begin(); iter != editorWorkbooks.end(); ++iter) { PartStack::Pointer workbook = *iter; if (workbook->GetID() == id) { this->SetActiveWorkbook(workbook, false); } } } PartStack::Pointer EditorSashContainer::GetWorkbookFromID(const QString& id) { for (QList::iterator iter = editorWorkbooks.begin(); iter != editorWorkbooks.end(); ++iter) { PartStack::Pointer workbook = *iter; if (workbook->GetID() == id) { return workbook; } } return PartStack::Pointer(nullptr); } void EditorSashContainer::UpdateTabList() { QWidget* parent = this->GetParent(); if (parent != nullptr) { // parent may be 0 on startup PartStack::Pointer wb(this->GetActiveWorkbook()); //TODO EditorSashContainer update tab list // if (wb == 0) // { // parent.setTabList(new Control[0]); // } // else // { // parent.setTabList(wb.getTabList()); // } } } void EditorSashContainer::CreateControl(QWidget* parent) { PartSashContainer::CreateControl(parent); ///let the user drop files/editor input on the editor area this->AddDropSupport(); } bool EditorSashContainer::IsCompressible() { //Added for bug 19524 return true; } bool EditorSashContainer::IsStackType(ILayoutContainer::Pointer toTest) { if (toTest.Cast() == 0) return false; return (toTest.Cast ()->GetAppearance() == PresentationFactoryUtil::ROLE_EDITOR); } bool EditorSashContainer::IsPaneType(LayoutPart::Pointer toTest) { if (toTest.Cast() == 0) return false; return (toTest.Cast ()->GetPartReference().Cast () != 0); } bool EditorSashContainer::RestorePresentationState(IMemento::Pointer /*areaMem*/) { QList workbooks = this->GetEditorWorkbooks(); for (QList::iterator iter = workbooks.begin(); iter != workbooks.end(); ++iter) { PartStack::Pointer workbook = *iter; IMemento::Pointer memento = workbook->GetSavedPresentationState(); if (memento == 0) { continue; } QList parts = workbook->GetPresentableParts(); PresentationSerializer serializer(parts); //StartupThreading.runWithoutExceptions(new StartupRunnable() // { // public void runWithException() throws Throwable // { workbook->GetPresentation()->RestoreState(&serializer, memento); // }} // ); } //return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", 0); //$NON-NLS-1$ return true; } } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSite.h b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSite.h index 917032f56b..6b6f63aa2c 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSite.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryEditorSite.h @@ -1,150 +1,150 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYEDITORSITE_H_ #define BERRYEDITORSITE_H_ #include "berryPartSite.h" #include "berryEditorDescriptor.h" #include "berryIEditorPart.h" #include "berryWorkbenchPage.h" #include "berryIEditorSite.h" #include "berryIEditorReference.h" namespace berry { /** * \ingroup org_blueberry_ui_internal * * An editor container manages the services for an editor. */ class EditorSite : public PartSite, public IEditorSite { /* package */ //static final int PROP_REUSE_EDITOR = -0x101; private: EditorDescriptor::Pointer desc; //ListenerList propChangeListeners = new ListenerList(1); // SubActionBars ab = null; /** * Initialize the local services. */ // void InitializeDefaultServices() { // // Register an implementation of the service appropriate for the // // EditorSite. // final IDragAndDropService editorDTService = new EditorSiteDragAndDropServiceImpl(); // serviceLocator.registerService(IDragAndDropService.class, editorDTService); // } protected: QString GetInitialScopeId() override; public: berryObjectMacro(EditorSite); /** * Constructs an EditorSite for an editor. */ EditorSite(IEditorReference::Pointer ref, IEditorPart::Pointer editor, WorkbenchPage* page, EditorDescriptor::Pointer desc); // void SetActionBars(SubActionBars bars) { // super.setActionBars(bars); // // if (bars instanceof IActionBars2) { // ab = new SubActionBars2((IActionBars2)bars, this); // } else { // ab = new SubActionBars(bars, this); // } // } // void ActivateActionBars(bool forceVisibility) { // if (ab != null) { // ab.activate(forceVisibility); // } // super.activateActionBars(forceVisibility); // } // void DeactivateActionBars(bool forceHide) { // if (ab != null) { // ab.deactivate(forceHide); // } // super.deactivateActionBars(forceHide); // } /** * Returns the editor action bar contributor for this editor. *

- * An action contributor is responsable for the creation of actions. + * An action contributor is responsible for the creation of actions. * By design, this contributor is used for one or more editors of the same type. * Thus, the contributor returned by this method is not owned completely * by the editor. It is shared. *

* * @return the editor action bar contributor */ // IEditorActionBarContributor::Pointer GetActionBarContributor() { // EditorActionBars bars = (EditorActionBars) getActionBars(); // if (bars != null) { // return bars.getEditorContributor(); // } // // return null; // } /** * Returns the extension editor action bar contributor for this editor. */ // IEditorActionBarContributor::Pointer GetExtensionActionBarContributor() { // EditorActionBars bars = (EditorActionBars) getActionBars(); // if (bars != null) { // return bars.getExtensionContributor(); // } // // return null; // } /** * Returns the editor */ IEditorPart::Pointer GetEditorPart(); EditorDescriptor::Pointer GetEditorDescriptor(); // void registerContextMenu(final MenuManager menuManager, // final ISelectionProvider selectionProvider, // final boolean includeEditorInput) { // registerContextMenu(getId(), menuManager, selectionProvider, // includeEditorInput); // } // // void registerContextMenu(final String menuId, // final MenuManager menuManager, // final ISelectionProvider selectionProvider, // final boolean includeEditorInput) { // if (menuExtenders == null) { // menuExtenders = new ArrayList(1); // } // // PartSite.registerContextMenu(menuId, menuManager, selectionProvider, // includeEditorInput, getPart(), menuExtenders); // } }; } #endif /*BERRYEDITORSITE_H_*/ diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.cpp b/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.cpp index 7c23250034..92f2e9d911 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.cpp +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.cpp @@ -1,415 +1,415 @@ /*============================================================================ 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 "berryHandlerProxy.h" #include "berryIConfigurationElement.h" #include "berryIEvaluationContext.h" #include "berryIEvaluationService.h" #include "berryICommandService.h" #include "berryIContributor.h" #include "berryIEvaluationReference.h" #include "berryEvaluationResult.h" #include "berryExpression.h" #include "berryCoreException.h" #include "berryCommandExceptions.h" #include "berryUtil.h" #include "berryShell.h" #include "berryObjects.h" #include "berryObjectString.h" #include "berryUIElement.h" #include "berryRadioState.h" #include "berryRegistryToggleState.h" #include "berryHandlerEvent.h" #include "berryPlatformUI.h" #include "berryBundleUtility.h" #include "berryWorkbenchRegistryConstants.h" #include "berryStatus.h" #include "berryWorkbenchPlugin.h" #include namespace berry { QHash, HandlerProxy*> HandlerProxy::CEToProxyMap = QHash(); const QString HandlerProxy::PROP_ENABLED = "enabled"; HandlerProxy::HandlerProxy(const QString commandId, const SmartPointer& configurationElement, const QString handlerAttributeName, const SmartPointer enabledWhenExpression, IEvaluationService* evaluationService) : configurationElement(configurationElement) , enabledWhenExpression(enabledWhenExpression) , handlerAttributeName(handlerAttributeName) , evaluationService(evaluationService) , proxyEnabled(false) , commandId(commandId) , loadException(nullptr) { this->Register(); if (configurationElement.IsNull()) { throw ctkInvalidArgumentException( "The configuration element backing a handler proxy cannot be null"); } if (handlerAttributeName.isNull()) { throw ctkInvalidArgumentException( "The attribute containing the handler class must be known"); } if (enabledWhenExpression.IsNotNull() && evaluationService == nullptr) { throw ctkInvalidArgumentException( "We must have a handler service and evaluation service to support the enabledWhen expression"); } if (enabledWhenExpression.IsNotNull()) { SetProxyEnabled(false); RegisterEnablement(); } else { SetProxyEnabled(true); } CEToProxyMap.insert(configurationElement, this); this->UnRegister(false); } void HandlerProxy::UpdateStaleCEs(const QList >& replacements) { foreach (const IConfigurationElement::Pointer& ce, replacements) { QHash::const_iterator i = CEToProxyMap.find(ce); if (i != CEToProxyMap.end()) { (*i)->configurationElement = ce; } } } void HandlerProxy::SetEnabled(const Object::Pointer& evaluationContext) { IEvaluationContext* const context = dynamic_cast(evaluationContext.GetPointer()); if (context == nullptr) { return; } if (enabledWhenExpression.IsNotNull()) { try { SetProxyEnabled(enabledWhenExpression->Evaluate(context) == EvaluationResult::TRUE_EVAL); } catch (const CoreException& /*e*/) { // TODO should we log this exception, or just treat it as // a failure } } if (IsOkToLoad() && LoadHandler()) { handler->SetEnabled(evaluationContext); } } void HandlerProxy::Dispose() { if (handler.IsNotNull()) { handler->RemoveHandlerListener(GetHandlerListener()); handler->Dispose(); handler = nullptr; } if (evaluationService && enablementRef) { evaluationService->RemoveEvaluationListener(enablementRef); } enablementRef = nullptr; delete loadException; loadException = nullptr; } Object::Pointer HandlerProxy::Execute(const SmartPointer& event) { if (LoadHandler()) { if (!IsEnabled()) { Shell::Pointer shell = Util::GetShellToParentOn(); QWidget* parent = nullptr; if (shell.IsNotNull()) parent = shell->GetControl(); QMessageBox::information(parent, "Information", "The chosen operation is not enabled."); return Object::Pointer(nullptr); } return handler->Execute(event); } if(loadException != nullptr) - throw ExecutionException("Exception occured when loading the handler", *loadException); + throw ExecutionException("Exception occurred when loading the handler", *loadException); return Object::Pointer(nullptr); } bool HandlerProxy::IsEnabled() const { if (enabledWhenExpression.IsNotNull()) { // proxyEnabled reflects the enabledWhen clause if (!GetProxyEnabled()) { return false; } if (IsOkToLoad() && LoadHandler()) { return handler->IsEnabled(); } return true; } /* * There is no enabled when expression, so we just need to consult the * handler. */ if (IsOkToLoad() && LoadHandler()) { return handler->IsEnabled(); } return true; } bool HandlerProxy::IsHandled() const { if (configurationElement.IsNotNull() && handler.IsNull()) { return true; } if (IsOkToLoad() && LoadHandler()) { return handler->IsHandled(); } return false; } QString HandlerProxy::ToString() const { if (handler.IsNull()) { if (configurationElement.IsNotNull()) { const QString configurationElementAttribute = GetConfigurationElementAttribute(); if (!configurationElementAttribute.isEmpty()) { return configurationElementAttribute; } } return "HandlerProxy()"; } return handler->ToString(); } void HandlerProxy::UpdateElement(UIElement* element, const QHash& parameters) { if (checkedState.IsNotNull()) { ObjectBool::Pointer value = checkedState->GetValue().Cast(); element->SetChecked(value->GetValue()); } else if (radioState.IsNotNull()) { ObjectString::Pointer value = radioState->GetValue().Cast(); Object::Pointer parameter = parameters[RadioState::PARAMETER_ID]; element->SetChecked(value.IsNotNull() && parameter == value); } if (handler.IsNotNull()) { if (IElementUpdater::Pointer updater = handler.Cast()) { updater->UpdateElement(element, parameters); } } } void HandlerProxy::HandleStateChange(const SmartPointer& state, const Object::Pointer& oldValue) { if (state->GetId() == RegistryToggleState::STATE_ID) { checkedState = state; RefreshElements(); } else if (state->GetId() == RadioState::STATE_ID) { radioState = state; RefreshElements(); } if (IStateListener* stateListener = dynamic_cast(handler.GetPointer())) { stateListener->HandleStateChange(state, oldValue); } } SmartPointer HandlerProxy::GetConfigurationElement() const { return configurationElement; } QString HandlerProxy::GetAttributeName() const { return handlerAttributeName; } SmartPointer HandlerProxy::GetHandler() const { return handler; } void HandlerProxy::RegisterEnablement() { enablementRef = evaluationService->AddEvaluationListener( enabledWhenExpression, GetEnablementListener(), PROP_ENABLED); } void HandlerProxy::SetProxyEnabled(bool enabled) { proxyEnabled = enabled; } bool HandlerProxy::GetProxyEnabled() const { return proxyEnabled; } IPropertyChangeListener* HandlerProxy::GetEnablementListener() const { return const_cast(this); } void HandlerProxy::PropertyChange(const SmartPointer& event) { if (event->GetProperty() == PROP_ENABLED) { SetProxyEnabled(event->GetNewValue().IsNull() ? false : event->GetNewValue().Cast()->GetValue()); HandlerEvent::Pointer event(new HandlerEvent(IHandler::Pointer(this), true, false)); FireHandlerChanged(event); } } bool HandlerProxy::LoadHandler() const { if (handler.IsNull()) { HandlerProxy* self = const_cast(this); // Load the handler. try { if (configurationElement.IsNotNull()) { handler = configurationElement->CreateExecutableExtension(handlerAttributeName); if (handler.IsNotNull()) { handler->AddHandlerListener(GetHandlerListener()); self->SetEnabled(evaluationService == nullptr ? IEvaluationContext::Pointer(nullptr) : evaluationService->GetCurrentState()); self->RefreshElements(); return true; } else { const QString message = "The proxied handler was the wrong class"; IStatus::Pointer status( new Status(IStatus::ERROR_TYPE, PlatformUI::PLUGIN_ID(), 0, message, BERRY_STATUS_LOC)); WorkbenchPlugin::Log(message, status); configurationElement = nullptr; loadException = new ctkException("Class cast exception"); } } } catch (const CoreException& e) { const QString message = "The proxied handler for '" + configurationElement->GetAttribute(handlerAttributeName) + "' could not be loaded"; IStatus::Pointer status( new Status(IStatus::ERROR_TYPE, PlatformUI::PLUGIN_ID(), 0, message, e, BERRY_STATUS_LOC)); WorkbenchPlugin::Log(message, status); configurationElement = nullptr; loadException = e.clone(); } return false; } return true; } IHandlerListener* HandlerProxy::GetHandlerListener() const { return const_cast(this); } void HandlerProxy::HandlerChanged(const SmartPointer& handlerEvent) { HandlerEvent::Pointer event(new HandlerEvent(IHandler::Pointer(this), handlerEvent->IsEnabledChanged(), handlerEvent->IsHandledChanged())); FireHandlerChanged(event); } QString HandlerProxy::GetConfigurationElementAttribute() const { const QString attribute = configurationElement->GetAttribute(handlerAttributeName); if (attribute.isNull()) { QList children = configurationElement->GetChildren(handlerAttributeName); foreach (const IConfigurationElement::Pointer& child, children) { const QString childAttribute = child->GetAttribute(WorkbenchRegistryConstants::ATT_CLASS); if (!childAttribute.isNull()) { return childAttribute; } } } return attribute; } bool HandlerProxy::IsOkToLoad() const { if (configurationElement.IsNotNull() && handler.IsNull()) { const QString bundleId = configurationElement->GetContributor()->GetName(); return BundleUtility::IsActive(bundleId); } return true; } void HandlerProxy::RefreshElements() { if (commandId.isNull() || (!(handler.Cast()) && (checkedState.IsNull() && radioState.IsNull()))) { return; } ICommandService* cs = PlatformUI::GetWorkbench()->GetService(); cs->RefreshElements(commandId, QHash()); } } diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.h b/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.h index 82deb4cc46..dc4bdc1050 100644 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryHandlerProxy.h @@ -1,227 +1,227 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYHANDLERPROXY_H #define BERRYHANDLERPROXY_H #include "berryAbstractHandlerWithState.h" #include "berryIElementUpdater.h" #include "berryIHandlerListener.h" #include "berryIPropertyChangeListener.h" namespace berry { struct IConfigurationElement; struct IEvaluationReference; struct IEvaluationService; class Expression; /** *

* A proxy for a handler that has been defined in XML. This delays the class * loading until the handler is really asked for information (besides the * priority or the command identifier). Asking a proxy for anything but the * attributes defined publicly in this class will cause the proxy to instantiate * the proxied handler. *

*/ class HandlerProxy : public AbstractHandlerWithState, public IElementUpdater, private IHandlerListener, private IPropertyChangeListener { public: berryObjectMacro(berry::HandlerProxy); private: static QHash, HandlerProxy*> CEToProxyMap; /** * */ static const QString PROP_ENABLED; // = "enabled"; /** * The configuration element from which the handler can be created. This * value will exist until the element is converted into a real class -- at * which point this value will be set to null. */ mutable SmartPointer configurationElement; /** * The enabledWhen expression for the handler. Only if this * expression evaluates to true (or the value is * null) should we consult the handler. */ const SmartPointer enabledWhenExpression; /** * The real handler. This value is null until the proxy is * forced to load the real handler. At this point, the configuration element * is converted, nulled out, and this handler gains a reference. */ mutable SmartPointer handler; /** * The name of the configuration element attribute which contains the * information necessary to instantiate the real handler. */ const QString handlerAttributeName; /** * The evaluation service to use when evaluating * enabledWhenExpression. This value may be * null only if the enabledWhenExpression is * null. */ IEvaluationService* evaluationService; SmartPointer enablementRef; bool proxyEnabled; QString commandId; // // state to support checked or radio commands. SmartPointer checkedState; SmartPointer radioState; // Exception that occurs while loading the proxied handler class mutable ctkException* loadException; public: /** * Constructs a new instance of HandlerProxy with all the * information it needs to try to avoid loading until it is needed. * * @param commandId the id for this handler * @param configurationElement * The configuration element from which the real class can be * loaded at run-time; must not be null. * @param handlerAttributeName * The name of the attribute or element containing the handler * executable extension; must not be null. * @param enabledWhenExpression * The name of the element containing the enabledWhen expression. * This should be a child of the * configurationElement. If this value is * null, then there is no enablement expression * (i.e., enablement will be delegated to the handler when * possible). * @param evaluationService * The evaluation service to manage enabledWhen expressions * trying to evaluate the enabledWhenExpression. * This value may be null only if the * enabledWhenExpression is null. */ HandlerProxy(const QString commandId, const SmartPointer& configurationElement, const QString handlerAttributeName, const SmartPointer enabledWhenExpression = SmartPointer(), IEvaluationService* evaluationService = nullptr); static void UpdateStaleCEs(const QList >& replacements); void SetEnabled(const Object::Pointer& evaluationContext) override; /** - * Passes the dipose on to the proxied handler, if it has been loaded. + * Passes the dispose on to the proxied handler, if it has been loaded. */ void Dispose() override; Object::Pointer Execute(const SmartPointer& event) override; bool IsEnabled() const override; bool IsHandled() const override; QString ToString() const override; /* * (non-Javadoc) * * @see org.eclipse.ui.commands.IElementUpdater#updateElement(org.eclipse.ui.menus.UIElement, * java.util.Map) */ void UpdateElement(UIElement* element, const QHash& parameters) override; /* (non-Javadoc) * @see org.eclipse.core.commands.IStateListener#handleStateChange(org.eclipse.core.commands.State, java.lang.Object) */ void HandleStateChange(const SmartPointer& state, const Object::Pointer& oldValue) override; /** * @return the config element for use with the PDE framework. */ SmartPointer GetConfigurationElement() const; QString GetAttributeName() const; /** * @return Returns the handler. */ SmartPointer GetHandler() const; private: /** * */ void RegisterEnablement(); void SetProxyEnabled(bool enabled); bool GetProxyEnabled() const; /** * @return */ IPropertyChangeListener* GetEnablementListener() const; using IPropertyChangeListener::PropertyChange; void PropertyChange(const SmartPointer& event) override; /** * Loads the handler, if possible. If the handler is loaded, then the member * variables are updated accordingly. * * @return true if the handler is now non-null; * false otherwise. */ bool LoadHandler() const; IHandlerListener* GetHandlerListener() const; void HandlerChanged(const SmartPointer& handlerEvent) override; /** - * Retrives the ConfigurationElement attribute according to the + * Retrieves the ConfigurationElement attribute according to the * handlerAttributeName. * * @return the handlerAttributeName value, may be null. */ QString GetConfigurationElementAttribute() const; bool IsOkToLoad() const; void RefreshElements(); }; } #endif // BERRYHANDLERPROXY_H diff --git a/Plugins/org.blueberry.ui.qt/src/internal/berryLayoutHelper.h b/Plugins/org.blueberry.ui.qt/src/internal/berryLayoutHelper.h index b99eea53c7..21dbaa28f6 100755 --- a/Plugins/org.blueberry.ui.qt/src/internal/berryLayoutHelper.h +++ b/Plugins/org.blueberry.ui.qt/src/internal/berryLayoutHelper.h @@ -1,76 +1,76 @@ /*============================================================================ 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. ============================================================================*/ #ifndef BERRYLAYOUTHELPER_H_ #define BERRYLAYOUTHELPER_H_ #include "berryViewFactory.h" #include "berryPartPane.h" namespace berry { class PageLayout; /** * Helper methods that the internal layout classes (PageLayout and * FolderLayout) utilize for activities support and view creation. * * @since 3.0 */ class LayoutHelper { private: /** * Not intended to be instantiated. */ LayoutHelper(); public: /** * Creates a series of listeners that will activate the provided view on the * provided page layout when IIdentifier enablement changes. The * rules for this activation are as follows:

*