Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/SymbologyImpl/base_symbol_model.h
T
2026-08-13 18:33:10 +02:00

324 lines
9.2 KiB
C++
Executable File

/**
* @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 <Symbology/symbol_properties.h>
#include <Symbology/symbol_result.h>
#include <Symbology/sidc_codec.h>
#include <Common/situation_map_logging.h>
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
// ESRI
#include <arcgis/Symbol.h>
#include <arcgis/Loadable.h>
#include <arcgis/DictionarySymbolStyle.h>
#include <arcgis/SymbolStyleSearchParameters.h>
#include <arcgis/SymbolStyleSearchResultListModel.h>
#include <arcgis/SymbolStyleSearchResult.h>
// XML:
#include <SymbologyXML/symbol.h>
//Qt
#include <QObject>
#include <QPixmap>
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<QSharedPointer<BaseSymbolItem>>
{
Q_OBJECT
using BaseClass = LtsWidgets::LtsAbstractTableModel<QSharedPointer<BaseSymbolItem>>;
public:
using DATA_T = QSharedPointer<BaseSymbolItem>;
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<Esri::ArcGISRuntime::SymbolStyleSearchResult> &searchResultList,
const SidcCodec::SidcHashTable<SymbolProperties> &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<QString> validBaseSymbolCodes() const;
void setValidBaseSymbolCodes(const QSet<QString> &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<QString> m_validBaseSymbolCodes;
QSet<AdvancedSymbology::GeometryType> m_geometrySet = {GeometryType::Undefined, GeometryType::Point, GeometryType::Polyline, GeometryType::Polygon};
};
} // namespace AdvancedSymbology