diff --git a/GUI/Model/Data/IntensityDataItem.cpp b/GUI/Model/Data/IntensityDataItem.cpp index 45863620d8222a9b91c2b9edeaefba1fe0b61995..cb8b01926c6c8347ad750571bb73525cc5c9c5dd 100644 --- a/GUI/Model/Data/IntensityDataItem.cpp +++ b/GUI/Model/Data/IntensityDataItem.cpp @@ -30,6 +30,8 @@ const QString BaseData("BaseData"); const QString ZAxis("ZAxis"); const QString Interpolation("Interpolation"); const QString Gradient("Gradient"); +const QString MaskContainer("MaskContainer"); +const QString ProjectionContainer("ProjectionContainer"); } // namespace Tag @@ -335,6 +337,20 @@ void IntensityDataItem::writeTo(QXmlStreamWriter* w, const QString& projectDir) w->writeStartElement(Tag::ZAxis); m_zAxis->writeTo(w); w->writeEndElement(); + + // masks + if (m_maskContainerItem) { + w->writeStartElement(Tag::MaskContainer); + m_maskContainerItem->writeTo(w); + w->writeEndElement(); + } + + // projections + if (m_projectionContainerItem) { + w->writeStartElement(Tag::ProjectionContainer); + m_projectionContainerItem->writeTo(w); + w->writeEndElement(); + } } void IntensityDataItem::readFrom(QXmlStreamReader* r) @@ -365,6 +381,16 @@ void IntensityDataItem::readFrom(QXmlStreamReader* r) m_zAxis->readFrom(r); XML::gotoEndElementOfTag(r, tag); + // masks + } else if (tag == Tag::MaskContainer) { + getOrCreateMaskContainerItem()->readFrom(r); + XML::gotoEndElementOfTag(r, tag); + + // projections + } else if (tag == Tag::ProjectionContainer) { + getOrCreateProjectionContainerItem()->readFrom(r); + XML::gotoEndElementOfTag(r, tag); + } else r->skipCurrentElement(); } diff --git a/GUI/Model/Data/IntensityDataItem.h b/GUI/Model/Data/IntensityDataItem.h index 9e4e6c1763a326e2f63abc79bac17bbe608013b9..49c4a3e07dbf00b847003fa9e06c39c764f19b6b 100644 --- a/GUI/Model/Data/IntensityDataItem.h +++ b/GUI/Model/Data/IntensityDataItem.h @@ -19,6 +19,7 @@ class AmplitudeAxisItem; class MaskContainerItem; +class MaskItemObject; class ProjectionContainerItem; class QCPColorGradient; @@ -115,8 +116,8 @@ signals: void gradientChanged(); void interpolationChanged(bool isInterpol); void projectionCreated(); - void projectionPositionChanged(SessionItem* projection); - void projectionGone(SessionItem* projection); + void projectionPositionChanged(MaskItemObject* projection); + void projectionGone(MaskItemObject* projection); void alignRanges(); private: diff --git a/GUI/Model/Data/ProjectionItems.cpp b/GUI/Model/Data/ProjectionItems.cpp index c0200d34ff42bf448e4b46ba2a3ab72b61bdb2d3..05e5d325dd19d9b18260e6777ad8e3f68b561dc4 100644 --- a/GUI/Model/Data/ProjectionItems.cpp +++ b/GUI/Model/Data/ProjectionItems.cpp @@ -16,14 +16,10 @@ #include <stdexcept> ProjectionContainerItem::ProjectionContainerItem() - : MaskContainerItem(M_TYPE) + : MaskContainerItem() { - // const QString T_CHILDREN = "children tag"; - // registerTag(T_CHILDREN, 0, -1, {HorizontalLineItem::M_TYPE, VerticalLineItem::M_TYPE}); - // setDefaultTag(T_CHILDREN); } - void ProjectionContainerItem::insertMask(int row, MaskItem* maskItem) { verifyMask(maskItem); @@ -40,17 +36,17 @@ void ProjectionContainerItem::verifyMask(MaskItem* maskItem) const { ASSERT(maskItem); - ASSERT(maskItem->modelType() == HorizontalLineItem::M_TYPE - || maskItem->modelType() == VerticalLineItem::M_TYPE); + ASSERT(dynamic_cast<HorizontalLineItem*>(maskItem) + || dynamic_cast<VerticalLineItem*>(maskItem)); } -QVector<SessionItem*> ProjectionContainerItem::projectionsOfType(const QString& projectionType) +QVector<MaskItem*> ProjectionContainerItem::projectionsOfType(ProjectionType projectionType) { - QVector<SessionItem*> projections; - for (MaskItem* projection : m_maskItems) { - if (projection->modelType() == projectionType) - projections.push_back(projection); - } - - return projections; + if (projectionType == ProjectionType::Horizontal) + return projections<HorizontalLineItem>(); + else if (projectionType == ProjectionType::Vertical) + return projections<VerticalLineItem>(); + else + ASSERT(false); + return {}; } diff --git a/GUI/Model/Data/ProjectionItems.h b/GUI/Model/Data/ProjectionItems.h index 9ade761a8d23a4960e1202920fa108620a12e274..fc023750a49ba5e2c177c1230fe717efe7c8608d 100644 --- a/GUI/Model/Data/ProjectionItems.h +++ b/GUI/Model/Data/ProjectionItems.h @@ -16,20 +16,32 @@ #define BORNAGAIN_GUI_MODEL_DATA_PROJECTIONITEMS_H #include "GUI/Model/Device/MaskItems.h" +#include "GUI/Support/Data/ProjectionType.h" //! A container to hold ProjectionItems, intended to store projections of color map on X, Y axes. class ProjectionContainerItem : public MaskContainerItem { public: - static constexpr auto M_TYPE{"ProjectionContainer"}; - ProjectionContainerItem(); //! Verify the type of the given MaskItem (throws excepctions) void verifyMask(MaskItem* maskItem) const; void insertMask(int row, MaskItem* maskItem) override; void addMask(MaskItem* maskItem) override; - QVector<SessionItem*> projectionsOfType(const QString& projectionType); + + QVector<MaskItem*> projectionsOfType(ProjectionType projectionType); + +private: + template <typename LineType> + QVector<MaskItem*> projections() + { + QVector<MaskItem*> result; + for (const auto& proj : m_maskItems) + if (dynamic_cast<LineType*>(proj.currentItem())) + result.push_back(proj.currentItem()); + return result; + } }; + #endif // BORNAGAIN_GUI_MODEL_DATA_PROJECTIONITEMS_H diff --git a/GUI/Model/Device/MaskItems.cpp b/GUI/Model/Device/MaskItems.cpp index 6dc79bad250c115ea519e08eed7bcf1d642f53ee..423c4a41059e9ba278e3c4e9bd8e91d573611d6c 100644 --- a/GUI/Model/Device/MaskItems.cpp +++ b/GUI/Model/Device/MaskItems.cpp @@ -18,8 +18,8 @@ #include "Device/Mask/Line.h" #include "Device/Mask/Polygon.h" #include "Device/Mask/Rectangle.h" -#include "GUI/Model/Model/SessionModel.h" #include "GUI/Support/XML/UtilXML.h" +#include <QRegularExpression> namespace { namespace Tag { @@ -47,41 +47,25 @@ const QString Mask("Mask"); } // namespace MaskContainerItem::MaskContainerItem() - : MaskItemObject(M_TYPE) -{ -} - -MaskContainerItem::MaskContainerItem(const QString& modelType) - : MaskItemObject(modelType) + : MaskItemObject() { } QVector<MaskItem*> MaskContainerItem::maskItems() const { - return m_maskItems; -} - -std::vector<SelectionProperty<MaskItemCatalog>> MaskContainerItem::maskItemSelections() const -{ - std::vector<SelectionProperty<MaskItemCatalog>> maskSelections; - for (MaskItem* maskItem : m_maskItems) { - SelectionProperty<MaskItemCatalog> newMaskSelection; - newMaskSelection.setCurrentItem(maskItem); - maskSelections.push_back(std::move(newMaskSelection)); - } - return maskSelections; + return m_maskItems.toQVector(); } void MaskContainerItem::insertMask(int row, MaskItem* maskItem) { - maskItem->setParentAndModel(this, SessionItem::model()); - m_maskItems.insert(row, maskItem); + // takes owning of maskItem! + m_maskItems.insert_at(row, maskItem); } void MaskContainerItem::addMask(MaskItem* maskItem) { - maskItem->setParentAndModel(this, SessionItem::model()); - m_maskItems.push_back(maskItem); // TODO: check whether the order of masks matter + // takes owning of maskItem! + m_maskItems.push_back(maskItem); } void MaskContainerItem::moveMask(int from_row, int to_row) @@ -91,19 +75,19 @@ void MaskContainerItem::moveMask(int from_row, int to_row) void MaskContainerItem::removeMaskAt(int row) { - m_maskItems.removeAt(row); + m_maskItems.delete_at(row); } void MaskContainerItem::removeMask(MaskItem* maskItem) { - m_maskItems.removeOne(maskItem); + m_maskItems.delete_element(maskItem); } RegionOfInterestItem* MaskContainerItem::regionOfInterestItem() const { - for (MaskItem* maskItem : m_maskItems) - if (maskItem->modelType() == RegionOfInterestItem::M_TYPE) - return dynamic_cast<RegionOfInterestItem*>(maskItem); + for (const auto& maskSel : m_maskItems) + if (auto* roi = dynamic_cast<RegionOfInterestItem*>(maskSel.currentItem())) + return roi; return nullptr; } @@ -125,12 +109,12 @@ int MaskContainerItem::size() const MaskItem* MaskContainerItem::at(const int idx) { - return m_maskItems.at(idx); + return m_maskItems.at(idx).currentItem(); } int MaskContainerItem::indexOfItem(MaskItem* maskItem) const { - return m_maskItems.indexOf(maskItem); + return m_maskItems.index_of(maskItem); } void MaskContainerItem::copy(const MaskContainerItem* maskContainer) @@ -152,11 +136,33 @@ void MaskContainerItem::setModel(MaskContainerModel* model) model->maskContainer = this; } +void MaskContainerItem::updateMaskNames() +{ + const auto reg = QRegularExpression("[0-9]"); + + QMap<QString, int> numMasksByType; + for (size_t i = 0; i < m_maskItems.size(); i++) { + + QString name = m_maskItems[i].currentItem()->maskName(); + name.remove(reg); + + int numMasks = 1; + if (numMasksByType.contains(name)) { + numMasks = numMasksByType.value(name) + 1; + numMasksByType.remove(name); + } + numMasksByType.insert(name, numMasks); + name += QString::number(numMasks); + + m_maskItems[i].currentItem()->setMaskName(name); + } +} + void MaskContainerItem::writeTo(QXmlStreamWriter* w) const { XML::writeAttribute(w, XML::Attrib::version, uint(1)); - for (const SelectionProperty<MaskItemCatalog>& sel : maskItemSelections()) { + for (const auto& sel : m_maskItems) { w->writeStartElement(Tag::Mask); sel.writeTo(w); w->writeEndElement(); @@ -174,9 +180,8 @@ void MaskContainerItem::readFrom(QXmlStreamReader* r, MessageService*) QString tag = r->name().toString(); if (tag == Tag::Mask) { - SelectionProperty<MaskItemCatalog> sel; - sel.readFrom(r); - addMask(sel.currentItem()); + addMask(nullptr); + m_maskItems.back().readFrom(r); XML::gotoEndElementOfTag(r, tag); } else @@ -188,12 +193,12 @@ void MaskContainerItem::readFrom(QXmlStreamReader* r, MessageService*) QString MaskItem::maskName() const { - return itemName(); + return m_maskName; } void MaskItem::setMaskName(const QString& name) { - setItemName(name); + m_maskName = name; } /* ------------------------------------------------------------------------- */ @@ -226,17 +231,17 @@ void MaskItem::writeTo(QXmlStreamWriter* w) const // name w->writeStartElement(Tag::Name); - XML::writeAttribute(w, XML::Attrib::value, maskName()); + XML::writeAttribute(w, XML::Attrib::value, m_maskName); w->writeEndElement(); // mask value w->writeStartElement(Tag::MaskValue); - XML::writeAttribute(w, XML::Attrib::value, maskValue()); + XML::writeAttribute(w, XML::Attrib::value, m_maskValue); w->writeEndElement(); // is visible? w->writeStartElement(Tag::IsVisible); - XML::writeAttribute(w, XML::Attrib::value, isVisibleValue()); + XML::writeAttribute(w, XML::Attrib::value, m_isVisible); w->writeEndElement(); } @@ -250,23 +255,17 @@ void MaskItem::readFrom(QXmlStreamReader* r) // name if (tag == Tag::Name) { - QString name; - XML::readAttribute(r, XML::Attrib::value, &name); - setMaskName(name); + XML::readAttribute(r, XML::Attrib::value, &m_maskName); XML::gotoEndElementOfTag(r, tag); // mask value } else if (tag == Tag::MaskValue) { - bool maskValue = true; - XML::readAttribute(r, XML::Attrib::value, &maskValue); - setMaskValue(maskValue); + XML::readAttribute(r, XML::Attrib::value, &m_maskValue); XML::gotoEndElementOfTag(r, tag); // is visible? } else if (tag == Tag::IsVisible) { - bool isVisible = true; - XML::readAttribute(r, XML::Attrib::value, &isVisible); - setIsVisibleValue(isVisible); + XML::readAttribute(r, XML::Attrib::value, &m_isVisible); XML::gotoEndElementOfTag(r, tag); } else @@ -274,22 +273,17 @@ void MaskItem::readFrom(QXmlStreamReader* r) } } -MaskItem::MaskItem(const QString& name) - : MaskItemObject(name) +MaskItem::MaskItem() + : MaskItemObject() { } /* ------------------------------------------------------------------------- */ RectangleItem::RectangleItem() - : RectangleItem(M_TYPE) + : MaskItem() { -} - -RectangleItem::RectangleItem(const QString& modelType) - : MaskItem(modelType) -{ - setItemName(modelType); + setMaskName("RectangleMask"); } std::unique_ptr<IShape2D> RectangleItem::createShape(double scale) const @@ -424,8 +418,9 @@ void RectangleItem::readFrom(QXmlStreamReader* r) /* ------------------------------------------------------------------------- */ RegionOfInterestItem::RegionOfInterestItem() - : RectangleItem(M_TYPE) + : RectangleItem() { + setMaskName("RegionOfInterest"); setMaskValue(false); } @@ -439,9 +434,8 @@ std::unique_ptr<IShape2D> RegionOfInterestItem::createShape(double scale) const /* ------------------------------------------------------------------------- */ PolygonPointItem::PolygonPointItem() - : MaskItemObject(M_TYPE) + : MaskItemObject() { - setItemName(M_TYPE); } double PolygonPointItem::posX() const @@ -490,9 +484,9 @@ void PolygonPointItem::readFrom(QXmlStreamReader* r) /* ------------------------------------------------------------------------- */ PolygonItem::PolygonItem() - : MaskItem(M_TYPE) + : MaskItem() { - setItemName(M_TYPE); + setMaskName("PolygonMask"); } std::unique_ptr<IShape2D> PolygonItem::createShape(double scale) const @@ -525,9 +519,7 @@ void PolygonItem::addPoint(double x, double y) auto* pointItem = new PolygonPointItem; pointItem->setPosX(x); pointItem->setPosY(y); - pointItem->setParentAndModel(this, model()); m_points.push_back(pointItem); // TODO: check whether the order of points matter - // insertChild(-1, new PolygonPointItem); } void PolygonItem::writeTo(QXmlStreamWriter* w) const @@ -595,9 +587,9 @@ PolygonItem::~PolygonItem() /* ------------------------------------------------------------------------- */ VerticalLineItem::VerticalLineItem() - : MaskItem(M_TYPE) + : MaskItem() { - setItemName(M_TYPE); + setMaskName("VerticalLineMask"); } std::unique_ptr<IShape2D> VerticalLineItem::createShape(double scale) const @@ -659,9 +651,9 @@ void VerticalLineItem::readFrom(QXmlStreamReader* r) /* ------------------------------------------------------------------------- */ HorizontalLineItem::HorizontalLineItem() - : MaskItem(M_TYPE) + : MaskItem() { - setItemName(M_TYPE); + setMaskName("HorizontalLineMask"); } std::unique_ptr<IShape2D> HorizontalLineItem::createShape(double scale) const @@ -723,9 +715,9 @@ void HorizontalLineItem::readFrom(QXmlStreamReader* r) /* ------------------------------------------------------------------------- */ EllipseItem::EllipseItem() - : MaskItem(M_TYPE) + : MaskItem() { - setItemName(M_TYPE); + setMaskName("EllipseMask"); } std::unique_ptr<IShape2D> EllipseItem::createShape(double scale) const @@ -885,10 +877,9 @@ void EllipseItem::readFrom(QXmlStreamReader* r) /* ------------------------------------------------------------------------- */ MaskAllItem::MaskAllItem() - : MaskItem(M_TYPE) + : MaskItem() { - setItemName(M_TYPE); - // maskValueItem()->setEnabled(false); // TODO: Is this needed? + setMaskName("MaskAllMask"); } std::unique_ptr<IShape2D> MaskAllItem::createShape(double) const @@ -898,8 +889,8 @@ std::unique_ptr<IShape2D> MaskAllItem::createShape(double) const /* ------------------------------------------------------------------------- */ -MaskItemObject::MaskItemObject(const QString& modelType) - : SessionItem(modelType) +MaskItemObject::MaskItemObject() + : QObject() { } @@ -910,7 +901,6 @@ MaskItemObject::~MaskItemObject() /* ------------------------------------------------------------------------- */ // Implementation of MaskContainerModel is based on the Qt source code for QStringListModel -// NOTE: Dependence on SessionModel will be removed at the latest step of refactoring. MaskContainerModel::MaskContainerModel() {} @@ -950,7 +940,6 @@ void MaskContainerModel::insertMask(int row, MaskItem* maskItem) { QAbstractListModel::beginInsertRows(maskContainer->rootIndex, row, row); maskContainer->insertMask(row, maskItem); - // QModelIndex idx = index(row, 0, {}); QAbstractListModel::endInsertRows(); } @@ -958,7 +947,7 @@ void MaskContainerModel::addMask(MaskItem* maskItem) { qsizetype row = maskContainer->size() - 1; QAbstractListModel::beginInsertRows(maskContainer->rootIndex, row, row); - maskContainer->addMask(maskItem); // TODO: check whether the order of masks matter + maskContainer->addMask(maskItem); QAbstractListModel::endInsertRows(); } @@ -966,7 +955,6 @@ void MaskContainerModel::addMask(MaskItem* maskItem) //! Move mask to a given row void MaskContainerModel::moveMask(int from_row, int to_row) { - emit QAbstractListModel::beginMoveRows(maskContainer->rootIndex, from_row, from_row, maskContainer->rootIndex, to_row); maskContainer->moveMask(from_row, to_row); @@ -980,7 +968,6 @@ void MaskContainerModel::removeMaskAt(int row) QAbstractListModel::endRemoveRows(); } - void MaskContainerModel::removeMask(MaskItem* maskItem) { const int row = maskContainer->indexOfItem(maskItem); @@ -990,13 +977,13 @@ void MaskContainerModel::removeMask(MaskItem* maskItem) RegionOfInterestItem* MaskContainerModel::regionOfInterestItem() const { for (MaskItem* maskItem : maskContainer->maskItems()) - if (maskItem->modelType() == RegionOfInterestItem::M_TYPE) - return dynamic_cast<RegionOfInterestItem*>(maskItem); + if (auto* reg = dynamic_cast<RegionOfInterestItem*>(maskItem)) + return reg; return nullptr; } -QModelIndex MaskContainerModel::indexOfItem(SessionItem* item) const +QModelIndex MaskContainerModel::indexOfItem(MaskItemObject* item) const { const int row = maskContainer->indexOfItem(dynamic_cast<MaskItem*>(item)); return QAbstractListModel::index(row, 0, {}); diff --git a/GUI/Model/Device/MaskItems.h b/GUI/Model/Device/MaskItems.h index 5c6811ced876c1fbab42aa14a90683d9e85d08f4..993361a7ed21c48e939af6a25ea96bef23498a35 100644 --- a/GUI/Model/Device/MaskItems.h +++ b/GUI/Model/Device/MaskItems.h @@ -15,19 +15,21 @@ #ifndef BORNAGAIN_GUI_MODEL_DEVICE_MASKITEMS_H #define BORNAGAIN_GUI_MODEL_DEVICE_MASKITEMS_H -#include "GUI/Model/BaseItem/SessionItem.h" +#include "Base/Types/OwningVector.h" +#include "Base/Util/Assert.h" #include "GUI/Model/CatDevice/MaskItemCatalog.h" #include "GUI/Model/Descriptor/SelectionProperty.h" -#include "GUI/Model/Model/SessionModel.h" +#include <QAbstractListModel> class IShape2D; +class MessageService; -//! SessionItem with signals used in masks +//! QObject with signals used in masks -class MaskItemObject : public QObject, public SessionItem { +class MaskItemObject : public QObject { Q_OBJECT public: - explicit MaskItemObject(const QString& modelType); + explicit MaskItemObject(); ~MaskItemObject(); signals: @@ -55,16 +57,14 @@ public: virtual void readFrom(QXmlStreamReader* r); protected: - explicit MaskItem(const QString& name); + explicit MaskItem(); + QString m_maskName = "nameless by default"; bool m_maskValue = true; bool m_isVisible = true; }; class RectangleItem : public MaskItem { - public: - static constexpr auto M_TYPE{"RectangleMask"}; - explicit RectangleItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; @@ -92,15 +92,11 @@ private: class RegionOfInterestItem : public RectangleItem { public: - static constexpr auto M_TYPE{"RegionOfInterest"}; - RegionOfInterestItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; }; class PolygonPointItem : public MaskItemObject { - Q_OBJECT - public: static constexpr auto M_TYPE{"PolygonPoint"}; @@ -121,8 +117,6 @@ private: class PolygonItem : public MaskItem { public: - static constexpr auto M_TYPE{"PolygonMask"}; - PolygonItem(); ~PolygonItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; @@ -143,8 +137,6 @@ private: class VerticalLineItem : public MaskItem { public: - static constexpr auto M_TYPE{"VerticalLineMask"}; - VerticalLineItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; @@ -160,8 +152,6 @@ private: class HorizontalLineItem : public MaskItem { public: - static constexpr auto M_TYPE{"HorizontalLineMask"}; - HorizontalLineItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; @@ -177,8 +167,6 @@ private: class EllipseItem : public MaskItem { public: - static constexpr auto M_TYPE{"EllipseMask"}; - EllipseItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; @@ -210,8 +198,6 @@ private: class MaskAllItem : public MaskItem { public: - static constexpr auto M_TYPE{"MaskAllMask"}; - MaskAllItem(); std::unique_ptr<IShape2D> createShape(double scale) const override; }; @@ -222,15 +208,10 @@ class MaskContainerModel; //! Container holding various masks as children class MaskContainerItem : public MaskItemObject { - Q_OBJECT public: - static constexpr auto M_TYPE{"MaskContainer"}; - MaskContainerItem(); - MaskContainerItem(const QString& modelType); QVector<MaskItem*> maskItems() const; - std::vector<SelectionProperty<MaskItemCatalog>> maskItemSelections() const; //! Insert mask at given row. virtual void insertMask(int row, MaskItem* maskItem); @@ -254,13 +235,13 @@ public: //! Return true if the container has no MaskItems bool isEmpty() const; - //! Returns the number of MaskItems + //! Return the number of MaskItems int size() const; - //! Returns the MaskItem at a given index + //! Return the MaskItem at a given index int indexOfItem(MaskItem* maskItem) const; - //! Returns the index corresponding to a given MaskItem + //! Return the index corresponding to a given MaskItem MaskItem* at(const int idx); //! Copy masks from another MaskContainerItem @@ -270,17 +251,20 @@ public: void writeTo(QXmlStreamWriter* w) const; void readFrom(QXmlStreamReader* r, MessageService* messageService = nullptr); - //! Returns the corresponding MaskContainerModel + //! Return the corresponding MaskContainerModel MaskContainerModel* model(); - //! Sets the corresponding MaskContainerModel + //! Set the corresponding MaskContainerModel void setModel(MaskContainerModel* model); + //! Update numbers in mask names + void updateMaskNames(); + public: const QModelIndex rootIndex; protected: - QVector<MaskItem*> m_maskItems; + SelectionVector<MaskItemCatalog> m_maskItems; MaskContainerModel* m_model = nullptr; }; @@ -318,9 +302,9 @@ public: void moveMask(int from_row, int to_row); void removeMaskAt(int row); - QModelIndex indexOfItem(SessionItem* item) const; // TODO: change this to MaskItem* + QModelIndex indexOfItem(MaskItemObject* item) const; // TODO: change this to MaskItem* MaskItem* itemForIndex(const QModelIndex& index) const; - // QString modelType() const; + RegionOfInterestItem* regionOfInterestItem() const; void setParent(QObject* parent); diff --git a/GUI/Model/Device/MaskUnitsConverter.cpp b/GUI/Model/Device/MaskUnitsConverter.cpp index d5b2d6540190bff2c63ab0889c8322de612a3fbf..ce1b57363427c0be3e0e7055bb4a4b56cb84a2df 100644 --- a/GUI/Model/Device/MaskUnitsConverter.cpp +++ b/GUI/Model/Device/MaskUnitsConverter.cpp @@ -55,9 +55,8 @@ void MaskUnitsConverter::convertIntensityDataItem(IntensityDataItem* intensityDa convertMask(maskItem); if (intensityData->projectionContainerItem()) - for (SessionItem* item : intensityData->projectionContainerItem()->maskItems()) - if (auto* maskItem = dynamic_cast<MaskItem*>(item)) - convertMask(maskItem); + for (auto* maskItem : intensityData->projectionContainerItem()->maskItems()) + convertMask(maskItem); } //! Converts single mask from/to bin-fraction coordinates diff --git a/GUI/Model/Device/MaskUnitsConverter.h b/GUI/Model/Device/MaskUnitsConverter.h index 2879df43bb5f01e8c44fc855189fa18df3e90955..2f3a32406d7ab2e98e52043f4d4e49325bf0e4a5 100644 --- a/GUI/Model/Device/MaskUnitsConverter.h +++ b/GUI/Model/Device/MaskUnitsConverter.h @@ -16,10 +16,7 @@ #define BORNAGAIN_GUI_MODEL_DEVICE_MASKUNITSCONVERTER_H class IntensityDataItem; -class SessionItem; -class IAxis; class Datafield; -class QString; class MaskItem; //! The MaskUnitsConverter converts coordinates of all masks from one units to anoter. diff --git a/GUI/Model/MakeItem/ItemCatalog.cpp b/GUI/Model/MakeItem/ItemCatalog.cpp index 4cd328789c94804e11a4111fd96a978e3df19d76..f7d3fcc6581b997634a2a14a3a9091291e9f082d 100644 --- a/GUI/Model/MakeItem/ItemCatalog.cpp +++ b/GUI/Model/MakeItem/ItemCatalog.cpp @@ -37,20 +37,7 @@ ItemCatalog::ItemCatalog() addItem<IntensityDataItem>(); addItem<SpecularDataItem>(); - addItem<MaskContainerItem>(); - addItem<RectangleItem>(); - addItem<PolygonPointItem>(); - addItem<PolygonItem>(); - addItem<VerticalLineItem>(); - addItem<HorizontalLineItem>(); - addItem<EllipseItem>(); - addItem<MaskAllItem>(); - - addItem<RegionOfInterestItem>(); - addItem<RealItem>(); - - addItem<ProjectionContainerItem>(); } ItemCatalog& ItemCatalog::instance() diff --git a/GUI/Support/Data/ProjectionType.h b/GUI/Support/Data/ProjectionType.h new file mode 100644 index 0000000000000000000000000000000000000000..5bbb9e5284c424ec6e61bf24a758b543fc5961f0 --- /dev/null +++ b/GUI/Support/Data/ProjectionType.h @@ -0,0 +1,22 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Support/Data/ProjectionType.h +//! @brief Defines enum ProjectionType +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2022 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifndef BORNAGAIN_GUI_SUPPORT_DATA_PROJECTIONTYPES_H +#define BORNAGAIN_GUI_SUPPORT_DATA_PROJECTIONTYPES_H + +//! Lists the possible states of a projection type. + +enum ProjectionType { Horizontal, Vertical, Invalid }; + +#endif // BORNAGAIN_GUI_SUPPORT_DATA_PROJECTIONTYPES_H diff --git a/GUI/View/Import/RealDataMaskWidget.cpp b/GUI/View/Import/RealDataMaskWidget.cpp index 68e1385e96f442512efa974b6dd8881519c396bf..552ac10e28f114bd19a2028a8d7aad7a54c4a95b 100644 --- a/GUI/View/Import/RealDataMaskWidget.cpp +++ b/GUI/View/Import/RealDataMaskWidget.cpp @@ -91,7 +91,7 @@ void RealDataMaskWidget::setContext() m_editorPropertyPanel->setMaskContext(containerModel); - ASSERT(containerItem->modelType() == MaskContainerItem::M_TYPE); + ASSERT(dynamic_cast<MaskContainerItem*>(containerItem)); m_editorCanvas->setSelectionModel(m_editorPropertyPanel->selectionModel()); m_editorCanvas->setMaskContext(currentIntensityDataItem()); diff --git a/GUI/View/Mask/EllipseView.cpp b/GUI/View/Mask/EllipseView.cpp index 1111105ff21bcf6964f3b90075bfe0896979e83d..e45e4a83c8cd14d5d3a2e418cd9b4aa9f77663ed 100644 --- a/GUI/View/Mask/EllipseView.cpp +++ b/GUI/View/Mask/EllipseView.cpp @@ -95,7 +95,7 @@ QPainterPath EllipseView::shape() const return path; } -SessionItem* EllipseView::parameterizedItem() const +MaskItemObject* EllipseView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/EllipseView.h b/GUI/View/Mask/EllipseView.h index 0a746df9786c3792e040732b0b642d602be70d37..14046db34137b58b14b8f6526bcb4cd3dbc1f8c4 100644 --- a/GUI/View/Mask/EllipseView.h +++ b/GUI/View/Mask/EllipseView.h @@ -30,7 +30,7 @@ public: explicit EllipseView(EllipseItem* item); - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; protected slots: void onChangedX() override; diff --git a/GUI/View/Mask/IShape2DView.cpp b/GUI/View/Mask/IShape2DView.cpp index 956c43403e53d14eef5991ec86e3c8367ac94b92..bc459e472ee0f5dc1fec93c92ac9b388715aa241 100644 --- a/GUI/View/Mask/IShape2DView.cpp +++ b/GUI/View/Mask/IShape2DView.cpp @@ -22,7 +22,7 @@ namespace { -bool itemMaskValue(const SessionItem* item) +bool itemMaskValue(const MaskItemObject* item) { if (const auto* maskItem = dynamic_cast<const MaskItem*>(item)) return maskItem->maskValue(); diff --git a/GUI/View/Mask/IShape2DView.h b/GUI/View/Mask/IShape2DView.h index 33fbbaa930a524f1c67f5ddd4d91352bfb62a389..6d1c7a5498839f93d6e580c626d42eb1d2efd568 100644 --- a/GUI/View/Mask/IShape2DView.h +++ b/GUI/View/Mask/IShape2DView.h @@ -21,7 +21,6 @@ class MaskItemObject; class ISceneAdaptor; -class SessionItem; //! Main interface class for views representing MaskItems, Projections on graphics scene. @@ -33,7 +32,7 @@ public: QRectF boundingRect() const override; - virtual SessionItem* parameterizedItem() const = 0; + virtual MaskItemObject* parameterizedItem() const = 0; void setSceneAdaptor(const ISceneAdaptor* adaptor); diff --git a/GUI/View/Mask/LineViews.cpp b/GUI/View/Mask/LineViews.cpp index 1d070ab3799aec3085fec73f18930b9f85b80b5e..787012d245533a72a77a21e1567307596cc69343 100644 --- a/GUI/View/Mask/LineViews.cpp +++ b/GUI/View/Mask/LineViews.cpp @@ -43,7 +43,7 @@ QPainterPath VerticalLineView::shape() const return p; } -SessionItem* VerticalLineView::parameterizedItem() const +MaskItemObject* VerticalLineView::parameterizedItem() const { return m_item; } @@ -121,7 +121,7 @@ QPainterPath HorizontalLineView::shape() const return path; } -SessionItem* HorizontalLineView::parameterizedItem() const +MaskItemObject* HorizontalLineView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/LineViews.h b/GUI/View/Mask/LineViews.h index 3060f16f181c6c10fe23076b88f7582b98511fc2..93ecb378362962db16e8f3785e5d0301f4398af9 100644 --- a/GUI/View/Mask/LineViews.h +++ b/GUI/View/Mask/LineViews.h @@ -31,7 +31,7 @@ public: explicit VerticalLineView(VerticalLineItem* item); QPainterPath shape() const override; - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; protected slots: void update_view() override; @@ -58,7 +58,7 @@ public: explicit HorizontalLineView(HorizontalLineItem* item); QPainterPath shape() const override; - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; protected slots: void update_view() override; diff --git a/GUI/View/Mask/MaskAllView.cpp b/GUI/View/Mask/MaskAllView.cpp index 5b52c1a8e8af421f44ce58c4c55c7cacc5668b4b..dded5ae464f369ce5ebe5dbb8da50c6920337039 100644 --- a/GUI/View/Mask/MaskAllView.cpp +++ b/GUI/View/Mask/MaskAllView.cpp @@ -26,7 +26,7 @@ MaskAllView::MaskAllView(MaskAllItem* item) setFlag(QGraphicsItem::ItemIsSelectable); } -SessionItem* MaskAllView::parameterizedItem() const +MaskItemObject* MaskAllView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/MaskAllView.h b/GUI/View/Mask/MaskAllView.h index 601e248724eee0f052f9ca43a5a8b342e4d7f9c7..445e7f5754741196f9f356339b32fa2abcec32fe 100644 --- a/GUI/View/Mask/MaskAllView.h +++ b/GUI/View/Mask/MaskAllView.h @@ -29,7 +29,7 @@ public: explicit MaskAllView(MaskAllItem* item); - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; protected slots: void update_view() override; diff --git a/GUI/View/Mask/MaskContainerView.cpp b/GUI/View/Mask/MaskContainerView.cpp index 3a907b1c6d61bf585b182be96fdc56037ed5b55a..e6184c0b231d7db07c12c4e5be07fb231b8e6494 100644 --- a/GUI/View/Mask/MaskContainerView.cpp +++ b/GUI/View/Mask/MaskContainerView.cpp @@ -35,7 +35,7 @@ MaskContainerView::MaskContainerView(ProjectionContainerItem* item) setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); } -SessionItem* MaskContainerView::parameterizedItem() const +MaskItemObject* MaskContainerView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/MaskContainerView.h b/GUI/View/Mask/MaskContainerView.h index 8c56282f115d8888d461e4fa3f7c90763beb47a6..86ae900bce1081eeb25c27e9a8f0516756cb3347 100644 --- a/GUI/View/Mask/MaskContainerView.h +++ b/GUI/View/Mask/MaskContainerView.h @@ -38,7 +38,7 @@ public: explicit MaskContainerView(MaskContainerItem* item); explicit MaskContainerView(ProjectionContainerItem* item); - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; protected slots: void update_view() override; @@ -47,7 +47,7 @@ protected: void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) override; private: - SessionItem* m_item; + MaskContainerItem* m_item; }; #endif // BORNAGAIN_GUI_VIEW_MASK_MASKCONTAINERVIEW_H diff --git a/GUI/View/Mask/MaskDrawingContext.cpp b/GUI/View/Mask/MaskDrawingContext.cpp index 8c838d3337dc179afc5cbd59beb5334d7e7efd98..1f2b91b933004ecaf94a34a14d0cbb0316d357bc 100644 --- a/GUI/View/Mask/MaskDrawingContext.cpp +++ b/GUI/View/Mask/MaskDrawingContext.cpp @@ -118,19 +118,6 @@ bool MaskDrawingContext::isActivityRequiresDrawingCancel( && proposed_new_activity >= MaskEditorFlags::PAN_ZOOM_MODE; } -//! Returns model type corresponding to current activity. - -QString MaskDrawingContext::activityToModelType() const -{ - if (isRectangleMode()) - return RectangleItem::M_TYPE; - if (isEllipseMode()) - return EllipseItem::M_TYPE; - if (isROIMode()) - return RegionOfInterestItem::M_TYPE; - return ""; -} - //! Returns model row corresponding to given activity. All shapes, except ROI, will be added //! on top of each other. ROI shape will be added at the bottom. diff --git a/GUI/View/Mask/MaskDrawingContext.h b/GUI/View/Mask/MaskDrawingContext.h index 00f1c5200c2fafdd4e1390f88d6e2ba35de1c22d..2d0e40a4b910237fd6420853ea024dc968677178 100644 --- a/GUI/View/Mask/MaskDrawingContext.h +++ b/GUI/View/Mask/MaskDrawingContext.h @@ -46,7 +46,6 @@ public: bool isActivityRequiresDrawingCancel(MaskEditorFlags::Activity proposed_new_activity) const; - QString activityToModelType() const; int activityToRow() const; private: diff --git a/GUI/View/Mask/MaskGraphicsProxy.h b/GUI/View/Mask/MaskGraphicsProxy.h index 183987342240cd7353d40fdd55e87fa1d66b7f13..46de4d36c4bb25f1813974e8ff2ba49bb6105d6f 100644 --- a/GUI/View/Mask/MaskGraphicsProxy.h +++ b/GUI/View/Mask/MaskGraphicsProxy.h @@ -18,7 +18,6 @@ #include "GUI/View/Mask/MaskEditorHelper.h" #include <QGraphicsProxyWidget> -class SessionItem; class ISceneAdaptor; class ColorMapSceneAdaptor; class ColorMap; diff --git a/GUI/View/Mask/MaskGraphicsScene.cpp b/GUI/View/Mask/MaskGraphicsScene.cpp index 24ec49e0e201a3d51efa523f61553cc5b3097579..17c908c189d9fce7d5b24467db24c7f4138ef37c 100644 --- a/GUI/View/Mask/MaskGraphicsScene.cpp +++ b/GUI/View/Mask/MaskGraphicsScene.cpp @@ -18,18 +18,12 @@ #include "GUI/Model/Data/ProjectionItems.h" #include "GUI/Model/Device/MaskItems.h" #include "GUI/Model/MakeItem/ItemFactory.h" -#include "GUI/Model/Model/SessionModel.h" #include "GUI/Util/Error.h" #include "GUI/View/Mask/ColorMapSceneAdaptor.h" #include "GUI/View/Mask/MaskGraphicsProxy.h" #include "GUI/View/Mask/MaskViewFactory.h" #include "GUI/View/Mask/PolygonView.h" -#include <QGraphicsItem> -#include <QGraphicsSceneMoveEvent> -#include <QItemSelection> -#include <QLineF> -#include <QPainter> - +#include <QGraphicsSceneContextMenuEvent> #include <boost/polymorphic_cast.hpp> using boost::polymorphic_downcast; @@ -72,9 +66,8 @@ void MaskGraphicsScene::setMaskContext(IntensityDataItem* intensityItem) disconnectMaskContainer(m_maskContainerModel); // check container type - const QString containerType{maskContainerItem->modelType()}; - ASSERT(containerType == MaskContainerItem::M_TYPE - && containerType == ProjectionContainerItem::M_TYPE); + ASSERT(dynamic_cast<MaskContainerItem*>(maskContainerItem) + || dynamic_cast<ProjectionContainerItem*>(maskContainerItem)); m_maskContainerItem = maskContainerItem; m_maskContainerModel = maskContainerModel; @@ -391,21 +384,17 @@ void MaskGraphicsScene::updateViews() IShape2DView* maskView = addViewForItem(m_maskContainerItem); - for (SessionItem* maskItem : m_maskContainerItem->maskItems()) { + for (MaskItem* maskItem : m_maskContainerItem->maskItems()) { if (!maskItem) continue; - if (maskItem->hasModelType<PropertyItem>()) - continue; IShape2DView* itemView = addViewForItem(maskItem); if (itemView && maskView) { maskView->addView(itemView); - // Add views for the points of the PolygonItem without - // using the SessionItem mechanism - if (maskItem->hasModelType<PolygonItem>()) { - auto polygonItem = dynamic_cast<PolygonItem*>(maskItem); + // Add views for the points of the PolygonItem + if (auto polygonItem = dynamic_cast<PolygonItem*>(maskItem)) { IShape2DView* const polygonView = itemView; for (PolygonPointItem* pointItem : polygonItem->points()) { IShape2DView* pointView = addViewForItem(pointItem); @@ -418,7 +407,7 @@ void MaskGraphicsScene::updateViews() //! Creates a view for given item. -IShape2DView* MaskGraphicsScene::addViewForItem(SessionItem* item) +IShape2DView* MaskGraphicsScene::addViewForItem(MaskItemObject* item) { ASSERT(item); IShape2DView* view = m_ItemToView[item]; @@ -430,14 +419,14 @@ IShape2DView* MaskGraphicsScene::addViewForItem(SessionItem* item) return view; } } - subscribeMaskItemObject(dynamic_cast<MaskItemObject*>(item)); + subscribeMaskItemObject(item); return view; } //! Removes single view from scene. -void MaskGraphicsScene::removeItemViewFromScene(SessionItem* item) +void MaskGraphicsScene::removeItemViewFromScene(MaskItem* item) { for (auto it = m_ItemToView.begin(); it != m_ItemToView.end(); ++it) { if (it.key() == item) { @@ -477,8 +466,8 @@ bool MaskGraphicsScene::isValidForRectangleShapeDrawing(QGraphicsSceneMouseEvent return false; if (m_context.isROIMode()) { // only one ROI is allowed - for (SessionItem* item : m_ItemToView.keys()) - if (item->modelType() == RegionOfInterestItem::M_TYPE) + for (MaskItemObject* item : m_ItemToView.keys()) + if (dynamic_cast<RegionOfInterestItem*>(item)) return false; } return true; @@ -527,8 +516,9 @@ bool MaskGraphicsScene::isValidForMaskAllDrawing(QGraphicsSceneMouseEvent* event return false; if (!m_context.isMaskAllMode()) return false; - for (SessionItem* item : m_ItemToView.keys()) - if (item->modelType() == MaskAllItem::M_TYPE) + + for (MaskItemObject* item : m_ItemToView.keys()) + if (dynamic_cast<MaskAllItem*>(item)) return false; return true; } @@ -577,9 +567,9 @@ void MaskGraphicsScene::setInPanAndZoomMode(bool value) void MaskGraphicsScene::updateCursors() { for (auto it = m_ItemToView.begin(); it != m_ItemToView.end(); ++it) { - if (it.key()->modelType() == VerticalLineItem::M_TYPE) + if (dynamic_cast<VerticalLineItem*>(it.key())) it.value()->setCursor(m_context.isInZoomMode() ? Qt::ArrowCursor : Qt::SizeHorCursor); - else if (it.key()->modelType() == HorizontalLineItem::M_TYPE) + else if (dynamic_cast<HorizontalLineItem*>(it.key())) it.value()->setCursor(m_context.isInZoomMode() ? Qt::ArrowCursor : Qt::SizeVerCursor); } } @@ -606,8 +596,16 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent* if (!m_currentItem && line.length() > min_distance_to_create_rect) { - MaskItem* newMaskItem = dynamic_cast<MaskItem*>( - GUI::Model::ItemFactory::CreateItem(m_context.activityToModelType())); + MaskItem* newMaskItem; + if (m_context.isRectangleMode()) + newMaskItem = new RectangleItem; + else if (m_context.isEllipseMode()) + newMaskItem = new EllipseItem; + else if (m_context.isROIMode()) + newMaskItem = new RegionOfInterestItem; + else + ASSERT(false); + // TODO: What to do for the case when `m_context.isROIMode() = true`? m_maskContainerModel->addMask(newMaskItem); @@ -617,7 +615,8 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent* if (!m_context.isROIMode()) dynamic_cast<MaskItem*>(m_currentItem)->setMaskValue(m_context.getMaskValue()); - setItemName(m_currentItem); + + m_maskContainerItem->updateMaskNames(); } else if (!m_currentItem) return; @@ -626,15 +625,13 @@ void MaskGraphicsScene::processRectangleOrEllipseItem(QGraphicsSceneMouseEvent* qreal ymin = std::min(click_pos.y(), mouse_pos.y()); qreal ymax = std::max(click_pos.y(), mouse_pos.y()); - if (m_currentItem->modelType() == RectangleItem::M_TYPE - || m_currentItem->modelType() == RegionOfInterestItem::M_TYPE) { - auto* rectItem = polymorphic_downcast<RectangleItem*>(m_currentItem); + if (auto* rectItem = dynamic_cast<RectangleItem*>(m_currentItem)) { + // RectangleItem or RegionOfInterestItem rectItem->setXLow(m_adaptor->fromSceneX(xmin)); rectItem->setYLow(m_adaptor->fromSceneY(ymax)); rectItem->setXUp(m_adaptor->fromSceneX(xmax)); rectItem->setYUp(m_adaptor->fromSceneY(ymin)); - } else if (m_currentItem->modelType() == EllipseItem::M_TYPE) { - auto* ellItem = polymorphic_downcast<EllipseItem*>(m_currentItem); + } else if (auto* ellItem = dynamic_cast<EllipseItem*>(m_currentItem)) { ellItem->setXCenter(m_adaptor->fromSceneX(xmin + (xmax - xmin) / 2.)); ellItem->setYCenter(m_adaptor->fromSceneY(ymin + (ymax - ymin) / 2.)); ellItem->setXRadius((m_adaptor->fromSceneX(xmax) - m_adaptor->fromSceneX(xmin)) / 2.); @@ -658,9 +655,9 @@ void MaskGraphicsScene::processPolygonItem(QGraphicsSceneMouseEvent* event) m_selectionModel->clearSelection(); m_selectionModel->select(m_maskContainerModel->indexOfItem(m_currentItem), QItemSelectionModel::Select); - setItemName(m_currentItem); + m_maskContainerItem->updateMaskNames(); } - ASSERT(m_currentItem->modelType() == PolygonItem::M_TYPE); + ASSERT(dynamic_cast<PolygonItem*>(m_currentItem)); if (PolygonView* polygon = currentPolygon()) { if (polygon->closePolygonIfNecessary()) { @@ -690,7 +687,7 @@ void MaskGraphicsScene::processLineItem(QGraphicsSceneMouseEvent* event) m_selectionModel->clearSelection(); m_selectionModel->select(m_maskContainerModel->indexOfItem(m_currentItem), QItemSelectionModel::Select); - setItemName(m_currentItem); + m_maskContainerItem->updateMaskNames(); dynamic_cast<MaskItem*>(m_currentItem)->setMaskValue(m_context.getMaskValue()); subscribeMaskItemObject(m_currentItem); @@ -738,7 +735,7 @@ void MaskGraphicsScene::subscribeMaskItemObject(MaskItemObject* item) Qt::UniqueConnection); } -//! Update Z-values of all IMaskView to reflect stacking order in SessionModel. +//! Update Z-values of all IMaskView to reflect stacking order. void MaskGraphicsScene::setZValues() { @@ -764,27 +761,3 @@ PolygonView* MaskGraphicsScene::currentPolygon() const } return result; } - -//! Sets item name depending on alreay existent items. -//! If there is already "Rectangle1", the new name will be "Rectangle2" - -void MaskGraphicsScene::setItemName(SessionItem* itemToChange) -{ - if (itemToChange->modelType() == RegionOfInterestItem::M_TYPE) - return; - - const QString itemToChange_name = itemToChange->itemName(); - int i_row = 0, glob_index = i_row; - for (MaskItem* currentItem : m_maskContainerItem->maskItems()) { - if (currentItem->modelType() == itemToChange->modelType()) { - QString itemName = currentItem->itemName(); - if (itemName.startsWith(itemToChange_name)) { - int item_index = itemName.remove(0, itemToChange_name.size()).toInt(); - if (item_index > glob_index) - glob_index = item_index; - } - } - } - - itemToChange->setItemName(itemToChange_name + QString::number(glob_index + 1)); -} diff --git a/GUI/View/Mask/MaskGraphicsScene.h b/GUI/View/Mask/MaskGraphicsScene.h index a14b79ed51e2fcc68cc03fdacf3649149e05d32a..5ed6a703da83af94b62812013e20bb5c0a8446c6 100644 --- a/GUI/View/Mask/MaskGraphicsScene.h +++ b/GUI/View/Mask/MaskGraphicsScene.h @@ -18,25 +18,20 @@ #include "GUI/View/Mask/MaskDrawingContext.h" #include "GUI/View/Mask/MaskEditorHelper.h" #include <QGraphicsScene> -#include <QMap> -#include <QModelIndex> -#include <QSharedPointer> +#include <QItemSelection> +#include <QItemSelectionModel> -class SessionModel; -class SessionItem; -class IShape2DView; class ISceneAdaptor; -class MaskItemObject; +class IShape2DView; +class IntensityDataItem; class MaskContainerItem; class MaskContainerModel; +class MaskEditorAction; class MaskGraphicsProxy; -class QItemSelectionModel; -class QItemSelection; +class MaskItem; +class MaskItemObject; class PolygonView; -class MaskEditorAction; -class IntensityDataItem; -class QGraphicsSceneMouseEvent; -class QPainter; + class ColorMap; //! Graphics scene for MaskEditorCanvas to draw masks on top of intensity data widgets. @@ -85,8 +80,8 @@ protected: private: void updateProxyWidget(); void updateViews(); - IShape2DView* addViewForItem(SessionItem* sessionItem); - void removeItemViewFromScene(SessionItem* sessionItem); + IShape2DView* addViewForItem(MaskItemObject* item); + void removeItemViewFromScene(MaskItem* item); void connectMaskContainer(MaskContainerModel* maskContainerModel); void disconnectMaskContainer(MaskContainerModel* maskContainerModel); @@ -115,12 +110,11 @@ private: void setZValues(); PolygonView* currentPolygon() const; - void setItemName(SessionItem* itemToChange); MaskContainerModel* m_maskContainerModel = nullptr; MaskContainerItem* m_maskContainerItem = nullptr; QItemSelectionModel* m_selectionModel = nullptr; - QMap<SessionItem*, IShape2DView*> m_ItemToView; + QMap<MaskItemObject*, IShape2DView*> m_ItemToView; MaskGraphicsProxy* m_proxy = nullptr; QSharedPointer<ISceneAdaptor> m_adaptor; bool m_block_selection = false; diff --git a/GUI/View/Mask/MaskViewFactory.cpp b/GUI/View/Mask/MaskViewFactory.cpp index c120395489b9142550ef223f839c26b3b31f08a1..c04387a3564c652faa41f597a6494226bdf0fbec 100644 --- a/GUI/View/Mask/MaskViewFactory.cpp +++ b/GUI/View/Mask/MaskViewFactory.cpp @@ -13,7 +13,6 @@ // ************************************************************************************************ #include "GUI/View/Mask/MaskViewFactory.h" -#include "GUI/Model/BaseItem/SessionItem.h" #include "GUI/Model/Data/ProjectionItems.h" #include "GUI/Model/Device/MaskItems.h" #include "GUI/Util/Error.h" @@ -29,54 +28,42 @@ using boost::polymorphic_downcast; -IShape2DView* MaskViewFactory::createMaskView(SessionItem* item, ISceneAdaptor* adaptor) +IShape2DView* MaskViewFactory::createMaskView(MaskItemObject* item, ISceneAdaptor* adaptor) { IShape2DView* result(nullptr); - if (item->hasModelType<MaskContainerItem>()) - result = new MaskContainerView(polymorphic_downcast<MaskContainerItem*>(item)); + if (auto* mask = dynamic_cast<MaskContainerItem*>(item)) + result = new MaskContainerView(mask); - else if (item->hasModelType<ProjectionContainerItem>()) - result = new MaskContainerView(polymorphic_downcast<ProjectionContainerItem*>(item)); + else if (auto* mask = dynamic_cast<ProjectionContainerItem*>(item)) + result = new MaskContainerView(mask); + else if (auto* mask = dynamic_cast<RectangleItem*>(item)) + result = new RectangleView(mask); - else if (item->hasModelType<RectangleItem>()) - result = new RectangleView(polymorphic_downcast<RectangleItem*>(item)); + else if (auto* mask = dynamic_cast<PolygonItem*>(item)) + result = new PolygonView(mask); + else if (auto* mask = dynamic_cast<PolygonPointItem*>(item)) + result = new PolygonPointView(mask); - else if (item->hasModelType<PolygonItem>()) - result = new PolygonView(polymorphic_downcast<PolygonItem*>(item)); + else if (auto* mask = dynamic_cast<VerticalLineItem*>(item)) + result = new VerticalLineView(mask); + else if (auto* mask = dynamic_cast<HorizontalLineItem*>(item)) + result = new HorizontalLineView(mask); - else if (item->hasModelType<PolygonPointItem>()) - result = new PolygonPointView(polymorphic_downcast<PolygonPointItem*>(item)); + else if (auto* mask = dynamic_cast<EllipseItem*>(item)) + result = new EllipseView(mask); + else if (auto* mask = dynamic_cast<MaskAllItem*>(item)) + result = new MaskAllView(mask); - else if (item->hasModelType<VerticalLineItem>()) - result = new VerticalLineView(polymorphic_downcast<VerticalLineItem*>(item)); + else if (auto* mask = dynamic_cast<RegionOfInterestItem*>(item)) + result = new RegionOfInterestView(mask); - - else if (item->hasModelType<HorizontalLineItem>()) - result = new HorizontalLineView(polymorphic_downcast<HorizontalLineItem*>(item)); - - - else if (item->hasModelType<EllipseItem>()) - result = new EllipseView(polymorphic_downcast<EllipseItem*>(item)); - - - else if (item->hasModelType<MaskAllItem>()) - result = new MaskAllView(polymorphic_downcast<MaskAllItem*>(item)); - - - else if (item->hasModelType<RegionOfInterestItem>()) - result = new RegionOfInterestView(polymorphic_downcast<RegionOfInterestItem*>(item)); - - - else { - throw Error("MaskViewFactory::createSampleView() -> Error! " - "Cannot create a view for " - + item->modelType()); - } + else + ASSERT(false); result->setSceneAdaptor(adaptor); diff --git a/GUI/View/Mask/MaskViewFactory.h b/GUI/View/Mask/MaskViewFactory.h index 38852220e8cd806b5dbba5ffca7f0cbdade7a24e..e4c807dcba89b71178eb0f19ee655359f8045d94 100644 --- a/GUI/View/Mask/MaskViewFactory.h +++ b/GUI/View/Mask/MaskViewFactory.h @@ -18,14 +18,14 @@ #include <QString> class IShape2DView; -class SessionItem; +class MaskItemObject; class ISceneAdaptor; //! Factory to construct views out of MaskItems for MaskGraphicsScene class MaskViewFactory { public: - static IShape2DView* createMaskView(SessionItem* item, ISceneAdaptor* adaptor = nullptr); + static IShape2DView* createMaskView(MaskItemObject* item, ISceneAdaptor* adaptor = nullptr); }; #endif // BORNAGAIN_GUI_VIEW_MASK_MASKVIEWFACTORY_H diff --git a/GUI/View/Mask/PolygonPointView.cpp b/GUI/View/Mask/PolygonPointView.cpp index 14beb64b3acef1f2a6f325640017c2ff5b7f718b..349149654d9c3b40402688b0cfdf402b0eda5969 100644 --- a/GUI/View/Mask/PolygonPointView.cpp +++ b/GUI/View/Mask/PolygonPointView.cpp @@ -31,7 +31,7 @@ QRectF PolygonPointView::boundingRect() const return QRectF(-4, -4, 8, 8); } -SessionItem* PolygonPointView::parameterizedItem() const +MaskItemObject* PolygonPointView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/PolygonPointView.h b/GUI/View/Mask/PolygonPointView.h index c47e9c47de985d5474cfc08d8566f5f6f5123b01..9c9ff69ba2f54f395f0aa9534724ad3a1f0d7776 100644 --- a/GUI/View/Mask/PolygonPointView.h +++ b/GUI/View/Mask/PolygonPointView.h @@ -31,7 +31,7 @@ public: QRectF boundingRect() const override; - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; void updateParameterizedItem(const QPointF& pos); diff --git a/GUI/View/Mask/PolygonView.cpp b/GUI/View/Mask/PolygonView.cpp index 2642d00b4daebd9bf67688772f3e12d977a99f49..4204a45f33d657a54484d3ec6eae6d60560a29b8 100644 --- a/GUI/View/Mask/PolygonView.cpp +++ b/GUI/View/Mask/PolygonView.cpp @@ -34,7 +34,7 @@ PolygonView::PolygonView(PolygonItem* item) setFlag(QGraphicsItem::ItemSendsGeometryChanges); } -SessionItem* PolygonView::parameterizedItem() const +MaskItemObject* PolygonView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/PolygonView.h b/GUI/View/Mask/PolygonView.h index d86a25c50e1350fe8c76513ba2fcebc51ba069ae..2c891bd16ee88117195ebbea50223598fd4b3bd2 100644 --- a/GUI/View/Mask/PolygonView.h +++ b/GUI/View/Mask/PolygonView.h @@ -31,7 +31,7 @@ public: explicit PolygonView(PolygonItem* item); - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; void addView(IShape2DView* childView) override; bool isClosedPolygon(); diff --git a/GUI/View/Mask/RectangleView.cpp b/GUI/View/Mask/RectangleView.cpp index c350405e063d630740de33d56d1a9e87e0e3525f..e55fd790216fe995937d5bb7668b174e387cccdd 100644 --- a/GUI/View/Mask/RectangleView.cpp +++ b/GUI/View/Mask/RectangleView.cpp @@ -30,7 +30,7 @@ QPainterPath RectangleView::shape() const return path; } -SessionItem* RectangleView::parameterizedItem() const +MaskItemObject* RectangleView::parameterizedItem() const { return m_item; } diff --git a/GUI/View/Mask/RectangleView.h b/GUI/View/Mask/RectangleView.h index faa382c351fa106c0760f71c503dd8efe33ef400..07e193b7aec31dbb9e6d3f6b1ce300dc83c368cd 100644 --- a/GUI/View/Mask/RectangleView.h +++ b/GUI/View/Mask/RectangleView.h @@ -31,7 +31,7 @@ public: explicit RectangleView(RectangleItem* item); QPainterPath shape() const override; - SessionItem* parameterizedItem() const override; + MaskItemObject* parameterizedItem() const override; protected slots: void onChangedX() override; diff --git a/GUI/View/Projection/ProjectionsPlot.cpp b/GUI/View/Projection/ProjectionsPlot.cpp index 7cb5c33f6e374ce16090433f60c76e672a10c055..f70d1d2c4b047b71cef96da1f62c070726f24d09 100644 --- a/GUI/View/Projection/ProjectionsPlot.cpp +++ b/GUI/View/Projection/ProjectionsPlot.cpp @@ -27,9 +27,9 @@ using boost::polymorphic_downcast; -ProjectionsPlot::ProjectionsPlot(QString projectionType, QWidget* parent) +ProjectionsPlot::ProjectionsPlot(ProjectionType projectionType, QWidget* parent) : DataItemBundleWidget(parent) - , m_projectionType(std::move(projectionType)) + , m_projectionType(projectionType) , m_customPlot(new QCustomPlot) { auto* vlayout = new QVBoxLayout(this); @@ -140,17 +140,28 @@ ProjectionContainerItem* ProjectionsPlot::projectionContainerItem() return result; } -QVector<SessionItem*> ProjectionsPlot::projectionItems() +QVector<MaskItem*> ProjectionsPlot::projectionItems() { return projectionContainerItem()->projectionsOfType(m_projectionType); } -QCPGraph* ProjectionsPlot::graphForItem(SessionItem* item) +bool ProjectionsPlot::isCorrectProjectionType(MaskItemObject* item) +{ + if (m_projectionType == ProjectionType::Horizontal && dynamic_cast<HorizontalLineItem*>(item)) + return true; + + if (m_projectionType == ProjectionType::Vertical && dynamic_cast<VerticalLineItem*>(item)) + return true; + + return false; +} + +QCPGraph* ProjectionsPlot::graphForItem(MaskItemObject* item) { if (!intensityItem()) return nullptr; - if (item->modelType() != m_projectionType) + if (!isCorrectProjectionType(item)) return nullptr; QCPGraph* graph = m_item_to_graph[item]; @@ -189,7 +200,7 @@ void ProjectionsPlot::updateProjections() replot(); } -void ProjectionsPlot::onProjectionPropertyChanged(SessionItem* item) +void ProjectionsPlot::onProjectionPropertyChanged(MaskItemObject* item) { if (auto* graph = graphForItem(item)) setGraphFromItem(graph, item); @@ -224,7 +235,7 @@ void ProjectionsPlot::updateAxesTitle() //! Removes plot corresponding to given projection item. -void ProjectionsPlot::clearProjection(SessionItem* item) +void ProjectionsPlot::clearProjection(MaskItemObject* item) { if (auto* graph = graphForItem(item)) { m_customPlot->removePlottable(graph); @@ -243,7 +254,7 @@ void ProjectionsPlot::clearAll() //! Sets the data to graph from given projection iten. -void ProjectionsPlot::setGraphFromItem(QCPGraph* graph, SessionItem* item) +void ProjectionsPlot::setGraphFromItem(QCPGraph* graph, MaskItemObject* item) { if (!intensityItem() || !intensityItem()->datafield()) return; @@ -251,13 +262,13 @@ void ProjectionsPlot::setGraphFromItem(QCPGraph* graph, SessionItem* item) std::unique_ptr<Datafield> field; // TODO: merge with very similar code in SaveProjectionsAssistant::projectionsData - if (item->modelType() == HorizontalLineItem::M_TYPE) { - double value = polymorphic_downcast<HorizontalLineItem*>(item)->posY(); - field.reset(intensityItem()->datafield()->xProjection(value)); - } else { - double value = polymorphic_downcast<VerticalLineItem*>(item)->posX(); - field.reset(intensityItem()->datafield()->yProjection(value)); - } + if (const auto* horLine = dynamic_cast<HorizontalLineItem*>(item)) + field.reset(intensityItem()->datafield()->xProjection(horLine->posY())); + else if (const auto* verLine = dynamic_cast<VerticalLineItem*>(item)) + field.reset(intensityItem()->datafield()->yProjection(verLine->posX())); + else + ASSERT(false); + auto centers = field->axis(0).binCenters(); auto values = field->flatVector(); @@ -285,5 +296,5 @@ void ProjectionsPlot::replot() bool ProjectionsPlot::isHorizontalType() { - return m_projectionType == HorizontalLineItem::M_TYPE; + return m_projectionType == ProjectionType::Horizontal; } diff --git a/GUI/View/Projection/ProjectionsPlot.h b/GUI/View/Projection/ProjectionsPlot.h index 40a99c835fa5383500209619428b48c8f160979f..425857461f05a8a8ae7724803d1c3928fe61b68c 100644 --- a/GUI/View/Projection/ProjectionsPlot.h +++ b/GUI/View/Projection/ProjectionsPlot.h @@ -15,14 +15,15 @@ #ifndef BORNAGAIN_GUI_VIEW_PROJECTION_PROJECTIONSPLOT_H #define BORNAGAIN_GUI_VIEW_PROJECTION_PROJECTIONSPLOT_H +#include "GUI/Support/Data/ProjectionType.h" #include "GUI/View/Common/DataItemBundleWidget.h" #include <QMap> #include <memory> +class Datafield; class IntensityDataItem; +class MaskItem; class ProjectionContainerItem; -class Datafield; -class QCPGraph; //! A customplot based widget to display projections of IntensityDataItem on X,Y axes. @@ -30,7 +31,7 @@ class ProjectionsPlot : public DataItemBundleWidget { Q_OBJECT public: - ProjectionsPlot(QString projectionType, QWidget* parent = nullptr); + ProjectionsPlot(ProjectionType projectionType, QWidget* parent = nullptr); void setIntensityItem(IntensityDataItem* intensityDataItem) override; @@ -42,19 +43,20 @@ public slots: private: IntensityDataItem* intensityItem(); - QVector<SessionItem*> projectionItems(); + QVector<MaskItem*> projectionItems(); + bool isCorrectProjectionType(MaskItemObject* item); ProjectionContainerItem* projectionContainerItem(); - QCPGraph* graphForItem(SessionItem* item); + QCPGraph* graphForItem(MaskItemObject* item); void updateProjectionsData(); void updateProjections(); - void onProjectionPropertyChanged(SessionItem* item); + void onProjectionPropertyChanged(MaskItemObject* item); void updateAxesRange(); void updateAxesTitle(); - void clearProjection(SessionItem* item); + void clearProjection(MaskItemObject* item); void clearAll(); - void setGraphFromItem(QCPGraph* graph, SessionItem* item); + void setGraphFromItem(QCPGraph* graph, MaskItemObject* item); void setInterpolate(bool isInterpolated); void setLogz(bool isLogz); @@ -63,9 +65,9 @@ private: bool isHorizontalType(); - QString m_projectionType; + ProjectionType m_projectionType = ProjectionType::Invalid; QCustomPlot* m_customPlot; - QMap<SessionItem*, QCPGraph*> m_item_to_graph; + QMap<MaskItemObject*, QCPGraph*> m_item_to_graph; }; #endif // BORNAGAIN_GUI_VIEW_PROJECTION_PROJECTIONSPLOT_H diff --git a/GUI/View/Projection/ProjectionsWidget.cpp b/GUI/View/Projection/ProjectionsWidget.cpp index 0013ad622bbd6802ed06bcb2cb522761a6698aa0..f2abb5c956bd437751ac005d8b6415b1e0119e1f 100644 --- a/GUI/View/Projection/ProjectionsWidget.cpp +++ b/GUI/View/Projection/ProjectionsWidget.cpp @@ -28,8 +28,8 @@ const int vertical_projection_tab = 1; ProjectionsWidget::ProjectionsWidget(QWidget* parent) : QWidget(parent) - , m_xProjection(new ProjectionsPlot(HorizontalLineItem::M_TYPE)) - , m_yProjection(new ProjectionsPlot(VerticalLineItem::M_TYPE)) + , m_xProjection(new ProjectionsPlot(ProjectionType::Horizontal)) + , m_yProjection(new ProjectionsPlot(ProjectionType::Vertical)) , m_tabWidget(new QTabWidget) { auto* layout = new QVBoxLayout; @@ -37,8 +37,8 @@ ProjectionsWidget::ProjectionsWidget(QWidget* parent) layout->setSpacing(0); m_tabWidget->setTabPosition(QTabWidget::North); - m_tabWidget->insertTab(HORIZONTAL, m_xProjection, "Horizontal"); - m_tabWidget->insertTab(VERTICAL, m_yProjection, "Vertical"); + m_tabWidget->insertTab(ProjectionType::Horizontal, m_xProjection, "Horizontal"); + m_tabWidget->insertTab(ProjectionType::Vertical, m_yProjection, "Vertical"); layout->addWidget(m_tabWidget); setLayout(layout); diff --git a/GUI/View/Projection/ProjectionsWidget.h b/GUI/View/Projection/ProjectionsWidget.h index 4f683477abebcd5313ffc81fd44741aed3065c51..4b997f8aa9795cc56f279f9b9390200b0dd31f08 100644 --- a/GUI/View/Projection/ProjectionsWidget.h +++ b/GUI/View/Projection/ProjectionsWidget.h @@ -27,8 +27,6 @@ class ProjectionsWidget : public QWidget { Q_OBJECT public: - enum ETabId { HORIZONTAL, VERTICAL }; - ProjectionsWidget(QWidget* parent = nullptr); void setIntensityItem(IntensityDataItem* intensityDataItem); diff --git a/GUI/View/Projection/SaveProjectionsAssistant.cpp b/GUI/View/Projection/SaveProjectionsAssistant.cpp index 15b219a94610506f67cf6706de4767c1577147ed..74c404a24c9c109fcfa04f618bddbdb2e73b3816 100644 --- a/GUI/View/Projection/SaveProjectionsAssistant.cpp +++ b/GUI/View/Projection/SaveProjectionsAssistant.cpp @@ -17,7 +17,6 @@ #include "Device/Data/Datafield.h" #include "GUI/Application/ApplicationSettings.h" #include "GUI/Model/Data/IntensityDataItem.h" -#include "GUI/Model/Data/ProjectionItems.h" #include "GUI/Model/Device/MaskItems.h" #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Util/Error.h" @@ -45,13 +44,13 @@ QString to_double_str(double value) return QString("%1").arg(QString::fromStdString(str), -bin_centers_colwidth); } -bool vert_less_posx(SessionItem* item1, SessionItem* item2) +bool vert_less_posx(MaskItemObject* item1, MaskItemObject* item2) { return polymorphic_downcast<VerticalLineItem*>(item1)->posX() < polymorphic_downcast<VerticalLineItem*>(item2)->posX(); } -bool horiz_less_posy(SessionItem* item1, SessionItem* item2) +bool horiz_less_posy(MaskItemObject* item1, MaskItemObject* item2) { return polymorphic_downcast<HorizontalLineItem*>(item1)->posY() < polymorphic_downcast<HorizontalLineItem*>(item2)->posY(); @@ -88,11 +87,11 @@ void SaveProjectionsAssistant::saveProjections(QWidget* parent, IntensityDataIte QTextStream out(&file); out << "# Projections along x-axis (horizontal projections) \n"; - out << projectionsToString(HorizontalLineItem::M_TYPE, intensityItem); + out << projectionsToString(ProjectionType::Horizontal, intensityItem); out << "\n"; out << "# Projections along y-axis (vertical projections) \n"; - out << projectionsToString(VerticalLineItem::M_TYPE, intensityItem); + out << projectionsToString(ProjectionType::Vertical, intensityItem); out << "\n"; file.close(); @@ -100,7 +99,7 @@ void SaveProjectionsAssistant::saveProjections(QWidget* parent, IntensityDataIte //! Generates multi-line string with projections data of given type (horizontal, vertical). -QString SaveProjectionsAssistant::projectionsToString(const QString& projectionsType, +QString SaveProjectionsAssistant::projectionsToString(ProjectionType projectionsType, IntensityDataItem* intensityItem) { QString result; @@ -127,23 +126,24 @@ QString SaveProjectionsAssistant::projectionsToString(const QString& projections //! Returns projections data for all projections of given type (horizontal, vertical). SaveProjectionsAssistant::ProjectionsData -SaveProjectionsAssistant::projectionsData(const QString& projectionsType, +SaveProjectionsAssistant::projectionsData(ProjectionType projectionsType, IntensityDataItem* intensityItem) { ProjectionsData result; - result.is_horizontal = (projectionsType != VerticalLineItem::M_TYPE); + result.is_horizontal = (projectionsType == ProjectionType::Horizontal); for (auto* item : projectionItems(projectionsType, intensityItem)) { std::unique_ptr<Datafield> field; SaveProjectionsAssistant::Projection data; - if (item->modelType() == HorizontalLineItem::M_TYPE) { - data.axis_value = polymorphic_downcast<HorizontalLineItem*>(item)->posY(); + if (const auto* horLine = dynamic_cast<HorizontalLineItem*>(item)) { + data.axis_value = horLine->posY(); field.reset(m_field->xProjection(data.axis_value)); - } else { - data.axis_value = polymorphic_downcast<VerticalLineItem*>(item)->posX(); + } else if (const auto* verLine = dynamic_cast<VerticalLineItem*>(item)) { + data.axis_value = verLine->posX(); field.reset(m_field->yProjection(data.axis_value)); - } + } else + ASSERT(false); auto values = field->flatVector(); auto centers = field->axis(0).binCenters(); @@ -157,12 +157,12 @@ SaveProjectionsAssistant::projectionsData(const QString& projectionsType, //! Returns vector of ProjectionItems sorted according to axis value. -QVector<SessionItem*> SaveProjectionsAssistant::projectionItems(const QString& projectionsType, - IntensityDataItem* intensityItem) +QVector<MaskItem*> SaveProjectionsAssistant::projectionItems(ProjectionType projectionsType, + IntensityDataItem* intensityItem) { auto result = intensityItem->projectionContainerItem()->projectionsOfType(projectionsType); std::sort(result.begin(), result.end(), - projectionsType == HorizontalLineItem::M_TYPE ? horiz_less_posy : vert_less_posx); + projectionsType == ProjectionType::Horizontal ? horiz_less_posy : vert_less_posx); return result; } diff --git a/GUI/View/Projection/SaveProjectionsAssistant.h b/GUI/View/Projection/SaveProjectionsAssistant.h index 07b61e044a7f8871c8429ea84f0bd20aaf568798..78812aa8a0e5cfca221944691cc8a01074bbee0b 100644 --- a/GUI/View/Projection/SaveProjectionsAssistant.h +++ b/GUI/View/Projection/SaveProjectionsAssistant.h @@ -15,6 +15,7 @@ #ifndef BORNAGAIN_GUI_VIEW_PROJECTION_SAVEPROJECTIONSASSISTANT_H #define BORNAGAIN_GUI_VIEW_PROJECTION_SAVEPROJECTIONSASSISTANT_H +#include "GUI/Model/Data/ProjectionItems.h" #include <QString> #include <QVector> #include <QWidget> @@ -22,7 +23,6 @@ class IntensityDataItem; class Datafield; -class SessionItem; //! Assistant class which save all projections of IndensityDataItem into ASCII file. @@ -45,13 +45,13 @@ private: QVector<Projection> projections; }; - QString projectionsToString(const QString& projectionsType, IntensityDataItem* intensityItem); + QString projectionsToString(ProjectionType projectionsType, IntensityDataItem* intensityItem); const Datafield* m_field; - ProjectionsData projectionsData(const QString& projectionsType, + ProjectionsData projectionsData(ProjectionType projectionsType, IntensityDataItem* intensityItem); - QVector<SessionItem*> projectionItems(const QString& projectionsType, - IntensityDataItem* intensityItem); + QVector<MaskItem*> projectionItems(ProjectionType projectionsType, + IntensityDataItem* intensityItem); QString projectionFileHeader(ProjectionsData& projectionsData); }; diff --git a/Tests/Unit/GUI/TestMapperForItem.cpp b/Tests/Unit/GUI/TestMapperForItem.cpp index 044dab3a67d7a5f638a1d3e8ebb886f48ea9fefc..eaf360fc72ecd083e73e202ca4328d65324f7799 100644 --- a/Tests/Unit/GUI/TestMapperForItem.cpp +++ b/Tests/Unit/GUI/TestMapperForItem.cpp @@ -104,49 +104,3 @@ TEST_F(TestMapperForItem, initialCondition) EXPECT_TRUE(m_mapped_item == nullptr); EXPECT_TRUE(!m_mapper); } - - -// NOTE: TwoWidgetsSubscription works only with the SessionItem mechanism, -// but the SessionItem mechanism is removed from HorizontalLineItem. -// TODO: Remove/refactor this test after elimination of the -// SessionItem mechanism. -TEST_F(TestMapperForItem, DISABLED_TwoWidgetsSubscription) -{ - Widget w1, w2; - JobModel model; - auto* container = model.insertItem<ProjectionContainerItem>(); - auto* line = model.insertItem<HorizontalLineItem>(container); - - // Mapper is looking on child; set property of child - setItem(line); - w1.subscribe(m_mapper.get(), true); - w2.subscribe(m_mapper.get(), true); - EXPECT_EQ(w1.m_onPropertyChangeCount, 0); - EXPECT_EQ(w2.m_onPropertyChangeCount, 0); - - line->setPosY(1.0); - EXPECT_EQ(w1.m_onPropertyChangeCount, 1); - EXPECT_EQ(w2.m_onPropertyChangeCount, 1); - - w1.unsubscribe(m_mapper.get()); - line->setPosY(2.0); - EXPECT_EQ(w1.m_onPropertyChangeCount, 1); - EXPECT_EQ(w2.m_onPropertyChangeCount, 2); -} - -TEST_F(TestMapperForItem, DISABLED_AboutToRemoveChild) -{ - Widget w; - JobModel model; - auto* container = model.insertItem<ProjectionContainerItem>(); - auto* line = model.insertItem<HorizontalLineItem>(container); - - setItem(container, &w); - EXPECT_EQ(w.m_onAboutToRemoveChild, 0); - EXPECT_EQ(w.m_reported_items.size(), 0); - - delete line->itemParent()->takeRow(line->itemParent()->rowOfChild(line)); - EXPECT_EQ(w.m_onAboutToRemoveChild, 1); - EXPECT_EQ(w.m_reported_items.size(), 1); - EXPECT_EQ(w.m_reported_items.back(), line); -}