324 lines
9.2 KiB
C++
Executable File
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
|