Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+343
@@ -0,0 +1,343 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class SymbolResult
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Own
|
||||
#include "advanced_symbology_export.h"
|
||||
#include "symbol_dictionary_types.h"
|
||||
#include <SymbologyImpl/advanced_symbology_logging.h>
|
||||
#include "result_watcher.h"
|
||||
|
||||
|
||||
// Qt
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <QLabel>
|
||||
#include <QFuture>
|
||||
#include <QSize>
|
||||
#include <QBuffer>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
|
||||
// forward
|
||||
class QUuid;
|
||||
class QComboBox;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
namespace AdvancedSymbology
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The SymbolResult class mainly contains a GeometryType and a SymbolImage.
|
||||
* It´s based on the future pattern. So the real result can only be retrieved if
|
||||
* the asynchron operation has finished (and the result is ready).
|
||||
* To standardize this you should use a propper watcher: SymbolResultWatcher.
|
||||
*
|
||||
* \sa \ref secResultWatcherExample
|
||||
*/
|
||||
class ADVANCED_SYMBOLOGY_EXPORT SymbolResult : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/*! \name Construction, Destruction */
|
||||
//@{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor / Destructor.
|
||||
*/
|
||||
explicit SymbolResult();
|
||||
virtual ~SymbolResult();
|
||||
//@}
|
||||
|
||||
|
||||
/*! \name Data regarding requested */
|
||||
//@{
|
||||
|
||||
/**
|
||||
* @brief symbolDataToRender What was requested?
|
||||
* @return Requested data
|
||||
*/
|
||||
const SymbolDataToRender &symbolDataToRender() const;
|
||||
//@}
|
||||
|
||||
/*! \name Data regarding processing*/
|
||||
//@{
|
||||
/**
|
||||
* @brief taskId internal taskId
|
||||
* @return internal taskId
|
||||
*/
|
||||
const QUuid &taskId() const;
|
||||
|
||||
/*! \name Data regarding result*/
|
||||
//@{
|
||||
/**
|
||||
* @brief Get geometryType of request
|
||||
* @return Geometry type
|
||||
*/
|
||||
GeometryType geometryType() const;
|
||||
|
||||
/**
|
||||
* @brief Get symbol image
|
||||
* @return symbol image
|
||||
*/
|
||||
SymbolImage symbolImage() const;
|
||||
//@}
|
||||
|
||||
|
||||
bool isResultReady() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/// This signal is for internal usage only. Use SymbolResultWatcher!
|
||||
void resultReadyInternal();
|
||||
|
||||
protected:
|
||||
friend class SymbolDictionaryImpl;
|
||||
friend class EsriDictionaryProcessor;
|
||||
friend class BaseSymbolModel;
|
||||
void fireResultReady();
|
||||
|
||||
friend class ResultWatcher<SymbolResult>;
|
||||
friend class SymbolResultWatcher;
|
||||
|
||||
void setSymbolDataToRender(const SymbolDataToRender &symDataToRender);
|
||||
void setTaskId(const QUuid &uuid);
|
||||
void setFuture(const QFuture<QImage> &future);
|
||||
void setGeometryType(GeometryType geometryType);
|
||||
void setSymbolImage(const SymbolImage &symbolImage);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onFinished();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
/**
|
||||
* The private d->pointer to not break BC when changing internals of this class
|
||||
*/
|
||||
Private *d = nullptr;
|
||||
|
||||
LOGGER_T m_logger; ///< Interface of the Logging-Facility
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief The SymbolResultWatcher class can watch one SymbolResult using setSymbolResult.
|
||||
* If the background operation has finished, the signal resultReady is emitted exactly one time.
|
||||
*
|
||||
* \sa \ref secResultWatcherExample
|
||||
*/
|
||||
class ADVANCED_SYMBOLOGY_EXPORT SymbolResultWatcher : public ResultWatcher<SymbolResult>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = ResultWatcher<SymbolResult>;
|
||||
|
||||
public:
|
||||
explicit SymbolResultWatcher(QObject *parent = nullptr);
|
||||
~SymbolResultWatcher() = default;
|
||||
|
||||
QSharedPointer<SymbolResult> symbolResult() const;
|
||||
void setSymbolResult(const QSharedPointer<SymbolResult> &symbolResult);
|
||||
|
||||
QElapsedTimer *m_et { nullptr };
|
||||
|
||||
protected:
|
||||
LOGGER_T m_logger; ///< Interface of the Logging-Facility
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// for convenience (ComboxBox)
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief The SymbolResultWatcherComboxBox class can be used to combine a comboBox
|
||||
* and an infinite number of item containing an icon.
|
||||
*
|
||||
* Here is an example:
|
||||
*
|
||||
* \code
|
||||
* AdvancedSymbology::SymbolResultWatcherComboxBox *srwCb;
|
||||
foreach(auto sidc, sidcs)
|
||||
{
|
||||
// SymbolResultWatcherComboxBox is stored as userData at every item.
|
||||
// The lifetime is limited to the lifetime of the comboBox since it`s the parent.
|
||||
|
||||
d->m_cbRubSidc->addItem(sidc, QVariant::fromValue(srwCb = new AdvancedSymbology::SymbolResultWatcherComboxBox(d->m_cbRubSidc)) );
|
||||
srwCb->setSymbolResult(dict.fetchSymbol(sidc));
|
||||
}
|
||||
* \endcode
|
||||
*/
|
||||
class ADVANCED_SYMBOLOGY_EXPORT SymbolResultWatcherComboxBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SymbolResultWatcherComboxBox(QComboBox *comboBox, int role = Qt::UserRole);
|
||||
|
||||
void setSymbolResult(const QSharedPointer<SymbolResult> &symbolResult);
|
||||
|
||||
/**
|
||||
* @brief enableToolTip of each entry
|
||||
* @param on
|
||||
*/
|
||||
void enableToolTip(bool on = true) { m_enableToolTip = on; }
|
||||
bool isToolTipEnabled() { return m_enableToolTip; }
|
||||
|
||||
|
||||
private slots:
|
||||
void onResultReady();
|
||||
|
||||
private:
|
||||
QComboBox *m_comboBox{nullptr};
|
||||
AdvancedSymbology::SymbolResultWatcher m_watcher;
|
||||
int m_role{Qt::UserRole};
|
||||
bool m_enableToolTip{true};
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// for convenience (QWidget)
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief The SymbolResultWatcherQWidgetBase class can be used with a QWidget,
|
||||
* most of the time a LtsWidgets::LtsDragIcon.
|
||||
* Required is a method 'setIcon(const QPixmap &pixmap)'
|
||||
*
|
||||
* Here is an example:
|
||||
*
|
||||
* \code
|
||||
LtsWidgets::LtsDragIcon *dummyIcon = new LtsWidgets::LtsDragIcon(this);
|
||||
|
||||
AdvancedSymbology::SymbolResultWatcherQWidgetBase *dummyIconSibling =
|
||||
new AdvancedSymbology::SymbolResultWatcherQWidget<LtsWidgets::LtsDragIcon>(dummyIcon);
|
||||
|
||||
AdvancedSymbology::SymbolDictionary &dict = d->m_mapImpl->symbolDictionary();
|
||||
dummyIconSibling->setSymbolResult(dict.fetchSymbol(SidcCodec::encodeComplete(SymbologyType::MIL2525D,"10042500001401040000")));
|
||||
* \endcode
|
||||
* This sibling define the lifetime.
|
||||
*/
|
||||
class ADVANCED_SYMBOLOGY_EXPORT SymbolResultWatcherQWidgetBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = QObject;
|
||||
|
||||
public:
|
||||
explicit SymbolResultWatcherQWidgetBase(QObject *widget);
|
||||
|
||||
void setSymbolResult(const QSharedPointer<SymbolResult> &symbolResult);
|
||||
QSharedPointer<AdvancedSymbology::SymbolResult> symbolResult() const;
|
||||
|
||||
private slots:
|
||||
void onResultReady();
|
||||
|
||||
signals:
|
||||
void resultReady();
|
||||
|
||||
protected:
|
||||
virtual void onResultReadyImpl() = 0;
|
||||
AdvancedSymbology::SymbolResultWatcher m_watcher;
|
||||
};
|
||||
|
||||
template <typename PARENT_TYPE>
|
||||
class SymbolResultWatcherQWidget : public SymbolResultWatcherQWidgetBase
|
||||
{
|
||||
using BaseClass = SymbolResultWatcherQWidgetBase;
|
||||
public:
|
||||
explicit SymbolResultWatcherQWidget(PARENT_TYPE *parentWidget, const QSize &size = QSize())
|
||||
: BaseClass(parentWidget)
|
||||
, m_size(size)
|
||||
, m_parentWidget(parentWidget)
|
||||
{}
|
||||
|
||||
private:
|
||||
void onResultReadyImpl() override
|
||||
{
|
||||
if (!m_parentWidget)
|
||||
return;
|
||||
|
||||
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = m_watcher.symbolResult();
|
||||
if (!symResult)
|
||||
return; // should NEVER happen! (Which object should have triggered the signal???)
|
||||
|
||||
const SymbolImage &symImage = symResult->symbolImage();
|
||||
const auto dpr = m_parentWidget->devicePixelRatioF();
|
||||
QImage imgCopy;
|
||||
if (m_size.isValid())
|
||||
imgCopy = symImage.image().scaled(m_size * dpr, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
else
|
||||
imgCopy = symImage.image();
|
||||
imgCopy.setDevicePixelRatio(dpr);
|
||||
|
||||
m_parentWidget->setIcon(QPixmap::fromImage(std::move(imgCopy)));
|
||||
|
||||
{
|
||||
QString tooltip;
|
||||
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
// XML-Symbol with scale = 4 will produce huge images. Limit the size:
|
||||
symImage.image().scaled(QSize(300, 300), Qt::KeepAspectRatio, Qt::SmoothTransformation).save(&buffer, "PNG", 100);
|
||||
|
||||
tooltip = QStringLiteral("<html>");
|
||||
|
||||
tooltip += QStringLiteral("<center>");
|
||||
tooltip += QStringLiteral("<img src='data:image/png;base64,%1'>").arg(QString::fromLatin1(data.toBase64()));
|
||||
tooltip += QStringLiteral("</center>");
|
||||
|
||||
tooltip += QStringLiteral("<center>");
|
||||
tooltip += symResult->symbolDataToRender().sidc;
|
||||
tooltip += QStringLiteral("</center>");
|
||||
|
||||
tooltip += QStringLiteral("<hr>");
|
||||
tooltip += QStringLiteral("</html>");
|
||||
m_parentWidget->setToolTip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
QSize m_size;
|
||||
PARENT_TYPE *m_parentWidget;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// for convenience (QLabel)
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief The SymbolResultWatcherLabel class can be used to combine a QLabel
|
||||
* Here is an example:
|
||||
*
|
||||
* \code
|
||||
* QLabel *label = new QLabel(this);
|
||||
* AdvancedSymbology::SymbolResultWatcherLabel *symbolLabelWatcher(label);
|
||||
*
|
||||
*
|
||||
*
|
||||
* \endcode
|
||||
*/
|
||||
class ADVANCED_SYMBOLOGY_EXPORT SymbolResultWatcherLabel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SymbolResultWatcherLabel(QLabel *label, const QSize &size = QSize(45, 45));
|
||||
|
||||
void setSymbolResult(const QSharedPointer<AdvancedSymbology::SymbolResult> &symbolResult);
|
||||
|
||||
private slots:
|
||||
void onResultReady();
|
||||
|
||||
private:
|
||||
QSize m_size;
|
||||
QLabel *m_label{nullptr};
|
||||
AdvancedSymbology::SymbolResultWatcher m_watcher;
|
||||
};
|
||||
|
||||
|
||||
} // namespace AdvancedSymbology
|
||||
|
||||
Q_DECLARE_METATYPE_TEMPLATE_1ARG(AdvancedSymbology::ResultWatcher)
|
||||
Reference in new issue
Block a user