/** * @RDE_HEADER@ * (Base) Symbol Model for Esri, XML, ETS Symbols * $Id$ * $HeadURL$ * $Author$ * Created by Norbert Thoden, NLE, 12.12.2019 */ #pragma once // Own #include #include #include #include #include #include // ESRI #include #include #include #include #include #include // XML: #include //Qt #include #include namespace AdvancedSymbology { class SymbolDictionaryImpl; class ResultWatcherData; //------------------------------------------------------------------------------ // BaseSymbolItem //------------------------------------------------------------------------------ class ADVANCED_SYMBOLOGY_EXPORT BaseSymbolItem : public QObject { Q_OBJECT public: // For Esri items explicit BaseSymbolItem(int id, Esri::ArcGISRuntime::Symbol *esriSymbol_Search); // For XML items explicit BaseSymbolItem(int id, const QString &baseSymbolCode, const QString &operatorName, qint64 lastModified, const SymbologyXML::Symbol &symbol); // For Ets items explicit BaseSymbolItem(int id, const QString &baseSymbolCode, const QImage &image); ~BaseSymbolItem(); BaseSymbolItem(const BaseSymbolItem &) = delete; // do not copy void emit_dataChanged() { emit dataChanged(m_id); } // Common int m_id = -1; QString m_operatorName; qint64 m_lastModified = 0; QString m_baseSymbolCode; QString baseSymbolCode(); QString sidc(); QString m_symbolSet; QString symbolSet(); int symbolSetAsInt(); QString getTooltip(const QImage &image); SymbolProperties m_symbolProperties; // ESRI related: SymbolDictionaryImpl *m_symbolDictionaryImpl = nullptr; Esri::ArcGISRuntime::DictionarySymbolStyle *m_esriDictionary = nullptr; void setSymbolDictionary(SymbolDictionary *symbolDictionary); void setEsriSearchSymbol(Esri::ArcGISRuntime::Symbol *esriSymbol_Search); // Xml related: private: void setXmlSymbol(const SymbologyXML::Symbol &symbol); public: // SEARCH void setEsriSymbol_Search(Esri::ArcGISRuntime::Symbol *esriSymbol_Search) { m_esriSearch.m_esriSymbol = esriSymbol_Search; } struct EsriSearch { mutable Esri::ArcGISRuntime::Symbol *m_esriSymbol = nullptr; mutable QUuid m_esriTaskUuid; mutable QImage m_esriSwatch; }; EsriSearch m_esriSearch; QImage getSearchSwatch(); // FETCH struct EsriFetch { mutable QString m_sidc; mutable QUuid m_esriFetchTaskIdUuid; Esri::ArcGISRuntime::Symbol *m_esriSymbol = nullptr; mutable QUuid m_esriSwatchTaskUuid; mutable QImage m_esriSwatch; mutable QImage m_esriToolTipSwatch; }; EsriFetch m_esriFetch; QImage getFetchSwatch() const; ResultWatcherData *m_findBaseSymbolRWD = nullptr; ResultWatcherData *m_findPreviewRWD = nullptr; ResultWatcherData *m_findImageRWD = nullptr; struct XmlSymbolStruct { SymbologyXML::Symbol m_symbol; }; XmlSymbolStruct *m_xmlSymbol = nullptr; Q_SIGNALS: void dataChanged(int id); public Q_SLOTS: // SEARCH_ICON: void onEsriSearchSymbolSwatchCompleted(const QUuid &taskId, const QImage &image); // FETCH_ICON: void onEsriFetchCompleted(const QUuid &taskId, Esri::ArcGISRuntime::Symbol *symbol); void onEsriFetchSymbolSwatchCompleted(const QUuid &taskId, const QImage &image); }; //------------------------------------------------------------------------------ // ResultWatcherData //------------------------------------------------------------------------------ class ResultWatcherData : public QObject { Q_OBJECT public: explicit ResultWatcherData(BaseSymbolItem *baseSymbolItem) : QObject(baseSymbolItem), m_baseSymbolItem(baseSymbolItem) {} AdvancedSymbology::SymbolResultWatcher *getResultWatcher() { if (!m_symbolResultWatcher) { m_symbolResultWatcher = new AdvancedSymbology::SymbolResultWatcher(this); connect(m_symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady, this, &ResultWatcherData::onResultReady); } return m_symbolResultWatcher; } QImage &image() { return m_scaledImage; } QImage &originalImage() { return m_orgImage; } public Q_SLOTS: void onResultReady(); Q_SIGNALS: void dataChanged(); private: AdvancedSymbology::SymbolResultWatcher *m_symbolResultWatcher = nullptr; QImage m_scaledImage; QImage m_orgImage; BaseSymbolItem *m_baseSymbolItem = nullptr; // 'parent' }; // class ResultWatcherData //------------------------------------------------------------------------------ // BaseSymbolModel //------------------------------------------------------------------------------ class ADVANCED_SYMBOLOGY_EXPORT BaseSymbolModel : public LtsWidgets::LtsAbstractTableModel> { Q_OBJECT using BaseClass = LtsWidgets::LtsAbstractTableModel>; public: using DATA_T = QSharedPointer; enum Columns { ID = 0, SEARCH_ICON, FETCH_ICON, FIND_BASE_SYMBOL, FIND_PREVIEW, FIND_IMAGE, ORIGINAL_KEY, KEY, BASE_SYMBOL_CODE, SIDC, SYMBOL_SET, NAME, OPERATOR_NAME, LAST_MODIFIED, XML_SYMBOL_SIZE, CATEGORY, SYMBOLCLASS, TAGS, GCTSTRING, GEOMETRYTYPE, }; explicit BaseSymbolModel(SymbolDictionary *symbolDictionary); ~BaseSymbolModel(); int getId(const DATA_T &data) const override { return data->m_id; } // Esri symbols void initModel(SymbolDictionary *symbolDictionary, const QList &searchResultList, const SidcCodec::SidcHashTable &baseSymbolCodeToSymbolPropertyTable); // Xml symbols: bool insertXmlSymbol(int fileId, const QString &operatorName, qint64 lastModified, const SymbologyXML::Symbol &symbol, const SymbolProperties &properties); bool removeXmlSymbol(int fileId); // Ets symbols: bool insertEtsSymbol(int fileId, const QString &sidc, const SymbolProperties &properties, const QImage &image); bool removeEtsSymbol(int fileId); void triggerFinishInitalization(); QVariant headerData(int section, Qt::Orientation orientation, int role) const override final; QVariant data(const QModelIndex &, int) const override final; Qt::ItemFlags flags(const QModelIndex &modelIndex) const override { return BaseClass::flags(modelIndex) | Qt::ItemIsDragEnabled; } int findRowForBaseSymbolCode(const QString &baseSymbolCode); SymbolProperties symbolProperties(const QString &baseSymbolCode); private Q_SLOTS: void onLoadStatusChanged(Esri::ArcGISRuntime::LoadStatus loadStatus); void onErrorDictionary(const Esri::ArcGISRuntime::Error &error); void onDataChanged(int id); void onFinishInitalization(); void onUpdateUsedItemsForComboBox(); private: LOGGER_T m_logger; struct Private; /** * The private d->pointer to not break BC when changing internals of this class */ Private *d = nullptr; friend class BaseSymbolProxyModel; }; //------------------------------------------------------------------------------ // BaseSymbolProxyModel //------------------------------------------------------------------------------ class ADVANCED_SYMBOLOGY_EXPORT BaseSymbolProxyModel : public LtsWidgets::LtsColumnFilterProxyModel { Q_OBJECT using BaseClass = LtsWidgets::LtsColumnFilterProxyModel; public: explicit BaseSymbolProxyModel(QObject *parent = nullptr); using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel; void setSourceModel(QAbstractItemModel *sourceModel) override; bool filterPoints() const; bool filterLines() const; bool filterAreas() const; QSet validBaseSymbolCodes() const; void setValidBaseSymbolCodes(const QSet &validBaseSymbolCodes); public Q_SLOTS: void onFilterPoints(bool on); void onFilterLines(bool on); void onFilterAreas(bool on); protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; protected: BaseSymbolModel *m_sourceModel = nullptr; QSet m_validBaseSymbolCodes; QSet m_geometrySet = {GeometryType::Undefined, GeometryType::Point, GeometryType::Polyline, GeometryType::Polygon}; }; } // namespace AdvancedSymbology