From b0b21feb072e61416005fea464bd51f53ee7f1e6 Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Thu, 10 May 2018 11:16:08 +0200 Subject: [PATCH 01/11] Added ScaleBar and MessageLog to qgisquick + docs. Added to qgis_quick_app as well. --- doc/qgsquick.dox | 2 + src/quickgui/CMakeLists.txt | 4 + src/quickgui/plugin/CMakeLists.txt | 6 +- src/quickgui/plugin/qgsquickmessagelog.qml | 71 ++++++++++++ src/quickgui/plugin/qgsquickplugin.cpp | 9 +- src/quickgui/plugin/qgsquickplugin.h | 2 +- src/quickgui/plugin/qgsquickscalebar.qml | 102 +++++++++++++++++ src/quickgui/plugin/qmldir | 2 + src/quickgui/qgsquickmessagelogmodel.cpp | 67 +++++++++++ src/quickgui/qgsquickmessagelogmodel.h | 82 ++++++++++++++ src/quickgui/qgsquickscalebarkit.cpp | 114 +++++++++++++++++++ src/quickgui/qgsquickscalebarkit.h | 122 +++++++++++++++++++++ src/quickgui/qgsquickutils.cpp | 71 +++++++++--- src/quickgui/qgsquickutils.h | 41 ++++--- tests/src/quickgui/app/main.cpp | 5 +- tests/src/quickgui/app/main.qml | 61 ++++++++--- tests/src/quickgui/testqgsquickutils.cpp | 26 ++--- 17 files changed, 721 insertions(+), 66 deletions(-) create mode 100644 src/quickgui/plugin/qgsquickmessagelog.qml create mode 100644 src/quickgui/plugin/qgsquickscalebar.qml create mode 100644 src/quickgui/qgsquickmessagelogmodel.cpp create mode 100644 src/quickgui/qgsquickmessagelogmodel.h create mode 100644 src/quickgui/qgsquickscalebarkit.cpp create mode 100644 src/quickgui/qgsquickscalebarkit.h diff --git a/doc/qgsquick.dox b/doc/qgsquick.dox index 5276a7f45052..6178be0d8756 100644 --- a/doc/qgsquick.dox +++ b/doc/qgsquick.dox @@ -13,6 +13,8 @@ QGIS Quick consists of a Qt plugin that provides the QML components and of a sha \subsection qgsquick_overview_widgets QML Classes \subsubsection qgsquick_overview_widgets_mapcanvas MapCanvas +\subsubsection qgsquick_overview_widgets_scalebar ScaleBar +\subsubsection qgsquick_overview_widgets_messagelog MessageLog \section qgsquick_styling Styling diff --git a/src/quickgui/CMakeLists.txt b/src/quickgui/CMakeLists.txt index 041e8a7b25c1..e433c08f8713 100644 --- a/src/quickgui/CMakeLists.txt +++ b/src/quickgui/CMakeLists.txt @@ -3,6 +3,8 @@ SET(QGIS_QUICK_GUI_MOC_HDRS qgsquickmapcanvasmap.h qgsquickmapsettings.h + qgsquickmessagelogmodel.h + qgsquickscalebarkit.h qgsquickutils.h ) @@ -12,6 +14,8 @@ SET(QGIS_QUICK_GUI_HDRS SET(QGIS_QUICK_GUI_SRC qgsquickmapcanvasmap.cpp qgsquickmapsettings.cpp + qgsquickmessagelogmodel.cpp + qgsquickscalebarkit.cpp qgsquickutils.cpp ) diff --git a/src/quickgui/plugin/CMakeLists.txt b/src/quickgui/plugin/CMakeLists.txt index 691a2b84f724..6649248a4f6b 100644 --- a/src/quickgui/plugin/CMakeLists.txt +++ b/src/quickgui/plugin/CMakeLists.txt @@ -11,6 +11,8 @@ SET(QGIS_QUICK_PLUGIN_SRC SET(QGIS_QUICK_PLUGIN_RESOURCES qgsquickmapcanvas.qml + qgsquickmessagelog.qml + qgsquickscalebar.qml qmldir ) @@ -37,7 +39,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/core/metadata ${CMAKE_SOURCE_DIR}/src/core/expression ${CMAKE_SOURCE_DIR}/src/quickgui - + ${CMAKE_BINARY_DIR}/src/core ${CMAKE_BINARY_DIR}/src/quickgui ) @@ -104,7 +106,7 @@ IF(QMLPLUGINDUMP_FOUND) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${CMAKE_COMMAND} -E copy $ ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${QMLPLUGINDUMP_EXECUTABLE} - ARGS QgsQuick 0.1 . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO} + ARGS QgisQuick 0.1 . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" POST_BUILD ) diff --git a/src/quickgui/plugin/qgsquickmessagelog.qml b/src/quickgui/plugin/qgsquickmessagelog.qml new file mode 100644 index 000000000000..d666bf66901a --- /dev/null +++ b/src/quickgui/plugin/qgsquickmessagelog.qml @@ -0,0 +1,71 @@ +/*************************************************************************** + qgsquickmessagelog.qml + -------------------------------------- + Date : January 2018 + Copyright : (C) 2018 by Peter Petrik + Email : zilolv at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +import QtQuick.Controls 2.0 +import QtQuick 2.5 +import QgsQuick 0.1 as QgsQuick + +Item { + property alias model: table.model + property color bgColor: "white" + property color separatorColor: "gray" + property int separatorSize: 1 * QgsQuick.Utils.dp + property bool unreadMessages: false + + id: item + + Rectangle { + color: item.bgColor + anchors.fill: parent + } + + ListView { + id: table + anchors.fill: parent + + delegate: Column { + Text { + text: MessageTag + font.bold: true + } + + Text { + text: Message + width: table.width + wrapMode: Text.WordWrap + } + + Rectangle { + color: item.separatorColor + height: item.separatorSize + width: table.width + } + } + } + + Connections { + target: model + + onRowsInserted: { + if ( !visible ) + unreadMessages = true + } + } + + onVisibleChanged: { + if ( visible ) + unreadMessages = false + } +} diff --git a/src/quickgui/plugin/qgsquickplugin.cpp b/src/quickgui/plugin/qgsquickplugin.cpp index 22b1fe10c158..60116ea2d329 100644 --- a/src/quickgui/plugin/qgsquickplugin.cpp +++ b/src/quickgui/plugin/qgsquickplugin.cpp @@ -31,17 +31,19 @@ #include "qgsquickmapcanvasmap.h" #include "qgsquickmapsettings.h" +#include "qgsquickmessagelogmodel.h" #include "qgsquickplugin.h" +#include "qgsquickscalebarkit.h" #include "qgsquickutils.h" static QObject *_utilsProvider( QQmlEngine *engine, QJSEngine *scriptEngine ) { Q_UNUSED( engine ) Q_UNUSED( scriptEngine ) - return new QgsQuickUtils(); // the object will be owned by QML engine and destroyed by the engine on exit + return QgsQuickUtils::instance(); // the object will be owned by QML engine and destroyed by the engine on exit } -void QgsQuickPlugin::registerTypes( const char *uri ) +void QgisQuickPlugin::registerTypes( const char *uri ) { qRegisterMetaType< QList >( "QList" ); qRegisterMetaType< QgsAttributes > ( "QgsAttributes" ); @@ -52,9 +54,12 @@ void QgsQuickPlugin::registerTypes( const char *uri ) qRegisterMetaType< QgsPoint >( "QgsPoint" ); qRegisterMetaType< QgsPointXY >( "QgsPointXY" ); + qmlRegisterType< QgsProject >( uri, 0, 1, "Project" ); qmlRegisterType< QgsQuickMapCanvasMap >( uri, 0, 1, "MapCanvasMap" ); qmlRegisterType< QgsQuickMapSettings >( uri, 0, 1, "MapSettings" ); + qmlRegisterType< QgsQuickMessageLogModel >( uri, 0, 1, "MessageLogModel" ); + qmlRegisterType< QgsQuickScaleBarKit >( uri, 0, 1, "ScaleBarKit" ); qmlRegisterType< QgsVectorLayer >( uri, 0, 1, "VectorLayer" ); qmlRegisterSingletonType< QgsQuickUtils >( uri, 0, 1, "Utils", _utilsProvider ); diff --git a/src/quickgui/plugin/qgsquickplugin.h b/src/quickgui/plugin/qgsquickplugin.h index 1133dc42646c..e98ba920f57b 100644 --- a/src/quickgui/plugin/qgsquickplugin.h +++ b/src/quickgui/plugin/qgsquickplugin.h @@ -25,7 +25,7 @@ * * \since QGIS 3.2 */ -class QgsQuickPlugin : public QQmlExtensionPlugin +class QgisQuickPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA( IID "org.qt-project.Qt.QQmlExtensionInterface" ) diff --git a/src/quickgui/plugin/qgsquickscalebar.qml b/src/quickgui/plugin/qgsquickscalebar.qml new file mode 100644 index 000000000000..349eb9447fc3 --- /dev/null +++ b/src/quickgui/plugin/qgsquickscalebar.qml @@ -0,0 +1,102 @@ +/*************************************************************************** + qgsquickscalebar.qml + -------------------------------------- + Date : Nov 2017 + Copyright : (C) 2017 by Peter Petrik + Email : zilolv at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QgsQuick 0.1 as QgsQuick + +Item { + id: scaleBar + property alias mapSettings: scaleBarKit.mapSettings + property alias preferredWidth: scaleBarKit.preferredWidth + property QgsQuick.ScaleBarKit scaleBarKit: QgsQuick.ScaleBarKit {id: scaleBarKit} + + property int textWidth: fontMetrics.averageCharacterWidth * 8 + property color barColor: "white" + property color barBackgroundColor: "grey" + property double barOpacity: 0.8 + property string barText: scaleBarKit.distance + " " + scaleBarKit.units + property int barWidth: scaleBarKit.width + property int lineWidth: 5 * QgsQuick.Utils.dp + + width: textWidth + barWidth + + MouseArea { + anchors.fill: background + onClicked: { + animation.restart() + } + } + + NumberAnimation { + id: animation + target: scaleBar + property: "barWidth" + to: 200 + duration: 1000 + } + + Rectangle { + id: background + color: scaleBar.barBackgroundColor + opacity: scaleBar.barOpacity + width: parent.width + height: parent.height + } + + FontMetrics { + id: fontMetrics + font: text.font + } + + Row { + opacity: 1 + spacing: 0 + + Text { + id: text + width: textWidth + height: scaleBar.height + text: barText + color: barColor + font.pixelSize: scaleBar.height - 2 * scaleBar.lineWidth + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Rectangle { + id: leftBar + width: scaleBar.lineWidth + height: scaleBar.height - 20 * QgsQuick.Utils.dp + y: (scaleBar.height - leftBar.height) / 2 + color: barColor + opacity: 1 + } + + Rectangle { + width: scaleBar.width - text.width - 15 * QgsQuick.Utils.dp + height: scaleBar.lineWidth + y: (scaleBar.height - scaleBar.lineWidth) / 2 + color: barColor + } + + Rectangle { + id: rightBar + width: scaleBar.lineWidth + height: scaleBar.height - 20 * QgsQuick.Utils.dp + y: (scaleBar.height - leftBar.height) / 2 + color: barColor + } + } +} diff --git a/src/quickgui/plugin/qmldir b/src/quickgui/plugin/qmldir index ac0dc7a73637..567a64feb59e 100644 --- a/src/quickgui/plugin/qmldir +++ b/src/quickgui/plugin/qmldir @@ -14,5 +14,7 @@ module QgsQuick plugin qgis_quick_plugin MapCanvas 0.1 qgsquickmapcanvas.qml +ScaleBar 0.1 qgsquickscalebar.qml +MessageLog 0.1 qgsquickmessagelog.qml typeinfo qgsquick.qmltypes diff --git a/src/quickgui/qgsquickmessagelogmodel.cpp b/src/quickgui/qgsquickmessagelogmodel.cpp new file mode 100644 index 000000000000..0652f5693634 --- /dev/null +++ b/src/quickgui/qgsquickmessagelogmodel.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + qgsquickmessagelogmodel.cpp + -------------------------------------- + date : 13.7.2016 + copyright : (C) 2016 by Matthias Kuhn + email : matthias (at) opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgis.h" +#include "qgslogger.h" +#include "qgsmessagelog.h" +#include "qgsapplication.h" + +#include "qgsquickmessagelogmodel.h" + +QgsQuickMessageLogModel::QgsQuickMessageLogModel( QObject *parent ) + : QAbstractListModel( parent ) + , mMessageLog( QgsApplication::messageLog() ) +{ + connect( mMessageLog, static_cast( &QgsMessageLog::messageReceived ), this, &QgsQuickMessageLogModel::onMessageReceived ); +} + +QHash QgsQuickMessageLogModel::roleNames() const +{ + QHash roles = QAbstractListModel::roleNames(); + roles[MessageRole] = "Message"; + roles[MessageTagRole] = "MessageTag"; + roles[MessageLevelRole] = "MessageLevel"; + + return roles; +} + +int QgsQuickMessageLogModel::rowCount( const QModelIndex &parent ) const +{ + Q_UNUSED( parent ) + return mMessages.size(); +} + +QVariant QgsQuickMessageLogModel::data( const QModelIndex &index, int role ) const +{ + if ( index.row() >= mMessages.size() ) + return QVariant(); + + if ( role == MessageRole ) + return mMessages.at( index.row() ).message; + else if ( role == MessageTagRole ) + return mMessages.at( index.row() ).tag; + else if ( role == MessageLevelRole ) + return mMessages.at( index.row() ).level; + + return QVariant(); +} + +void QgsQuickMessageLogModel::onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ) +{ + beginInsertRows( QModelIndex(), 0, 0 ); + mMessages.prepend( LogMessage( tag, message, level ) ); + QgsDebugMsg( QStringLiteral( "Next message %1 : %2" ).arg( tag, message ) ); + endInsertRows(); +} diff --git a/src/quickgui/qgsquickmessagelogmodel.h b/src/quickgui/qgsquickmessagelogmodel.h new file mode 100644 index 000000000000..6d32d17c45bc --- /dev/null +++ b/src/quickgui/qgsquickmessagelogmodel.h @@ -0,0 +1,82 @@ +/*************************************************************************** + qgsquickmessagelogmodel.h + -------------------------------------- + date : 13.7.2016 + copyright : (C) 2016 by Matthias Kuhn + email : matthias (at) opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSQUICKMESSAGELOGMODEL_H +#define QGSQUICKMESSAGELOGMODEL_H + +#include + +#include "qgis.h" +#include "qgsmessagelog.h" + +#include "qgis_quick.h" + +/** + * \ingroup quick + * + * This model will connect to the QgsMessageLog and publish any + * messages received from there. Can be used as a model for QListView, + * for example QgsQuick MessageLog class. + * + * \note QML Type: MessageLogModel + * + * \since QGIS 3.2 + */ +class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel +{ + Q_OBJECT + + struct LogMessage + { + LogMessage() + {} + + LogMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ) + { + this->tag = tag; + this->message = message; + this->level = level; + } + + QString tag; + QString message; + Qgis::MessageLevel level; + }; + + enum Roles + { + MessageRole = Qt::UserRole, + MessageTagRole, + MessageLevelRole + }; + + public: + //! Create new message log model + QgsQuickMessageLogModel( QObject *parent = nullptr ); + + QHash roleNames() const override; + + int rowCount( const QModelIndex &parent ) const override; + QVariant data( const QModelIndex &index, int role ) const override; + + private slots: + void onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ); + + private: + QgsMessageLog *mMessageLog; + QVector mMessages; +}; + +#endif // QGSQUICKMESSAGELOGMODEL_H diff --git a/src/quickgui/qgsquickscalebarkit.cpp b/src/quickgui/qgsquickscalebarkit.cpp new file mode 100644 index 000000000000..e79ef7be14c9 --- /dev/null +++ b/src/quickgui/qgsquickscalebarkit.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + qgsquickscalebarkit.cpp + -------------------------------------- + Date : Nov 2017 + Copyright : (C) 2017 by Peter Petrik + Email : zilolv at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include + +#include "qgsdistancearea.h" +#include "qgspointxy.h" + +#include "qgsquickmapsettings.h" +#include "qgsquickscalebarkit.h" +#include "qgsquickutils.h" +#include "qgsunittypes.h" + +QgsQuickScaleBarKit::QgsQuickScaleBarKit( QObject *parent ) + : QObject( parent ) + , mPreferredWidth( 300 ) + , mWidth( mPreferredWidth ) + , mDistance( 0 ) + , mUnits( "" ) +{ + connect( this, &QgsQuickScaleBarKit::mapSettingsChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + connect( this, &QgsQuickScaleBarKit::preferredWidthChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); +} + +void QgsQuickScaleBarKit::setMapSettings( QgsQuickMapSettings *mapSettings ) +{ + if ( mMapSettings == mapSettings ) + return; + + // If we have already something connected, disconnect it! + if ( mMapSettings ) + { + disconnect( mMapSettings, nullptr, this, nullptr ); + } + + mMapSettings = mapSettings; + + // Connect all signals to change scale bar when needed! + if ( mMapSettings ) + { + connect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + connect( mMapSettings, &QgsQuickMapSettings::destinationCrsChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + connect( mMapSettings, &QgsQuickMapSettings::mapUnitsPerPixelChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + connect( mMapSettings, &QgsQuickMapSettings::visibleExtentChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + connect( mMapSettings, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + connect( mMapSettings, &QgsQuickMapSettings::outputDpiChanged, this, &QgsQuickScaleBarKit::updateScaleBar ); + } + + emit mapSettingsChanged(); +} + +int QgsQuickScaleBarKit::width() const +{ + return mWidth; +} + +QString QgsQuickScaleBarKit::units() const +{ + return mUnits; +} + +int QgsQuickScaleBarKit::distance() const +{ + return mDistance; +} + +void QgsQuickScaleBarKit::updateScaleBar() +{ + if ( !mMapSettings ) + return; + + double dist = QgsQuickUtils::instance()->screenUnitsToMeters( mMapSettings, mPreferredWidth ); // meters + if ( dist > 1000.0 ) + { + dist = dist / 1000.0; // meters to kilometers + mUnits = QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceKilometers ); + } + else + { + mUnits = QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceMeters ); + } + + // we want to show nice round distances e.g. 200 km instead of e.g. 273 km + // so we determine which "nice" number to use and also update the scale bar + // length accordingly. First digit will be 1, 2 or 5, the rest will be zeroes. + int digits = floor( log10( ( dist ) ) ); // number of digits after first one + double base = pow( 10, digits ); // e.g. for 1234 this will be 1000 + double first_digit = dist / base; // get the first digit + int round_digit; + if ( first_digit < 2 ) + round_digit = 1; + else if ( first_digit < 5 ) + round_digit = 2; + else + round_digit = 5; + + mDistance = round_digit * base; + mWidth = mPreferredWidth * mDistance / dist; + + emit scaleBarChanged(); +} diff --git a/src/quickgui/qgsquickscalebarkit.h b/src/quickgui/qgsquickscalebarkit.h new file mode 100644 index 000000000000..27332dcf0165 --- /dev/null +++ b/src/quickgui/qgsquickscalebarkit.h @@ -0,0 +1,122 @@ +/*************************************************************************** + qgsquickscalebarkit.h + -------------------------------------- + Date : Nov 2017 + Copyright : (C) 2017 by Peter Petrik + Email : zilolv at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSQUICKSCALEBARKIT_H +#define QGSQUICKSCALEBARKIT_H + +#include +#include + +#include "qgis_quick.h" + +class QgsQuickMapSettings; + +/** + * \ingroup quick + * + * The class QgsQuickScaleBarKit encapsulates the utilies to calculate + * scale bar properties + * + * It requires connection to mapSettings of the active canvas to automatically + * update text and width + * + * From preferred width in pixel, it calculates the width (pixel) of scalebar + * distance in meters or kilometers (int) rounded to "nice" number (e.g. 72.4 to 100) + * and units text (e.g. km) + * + * \note QML Type: ScaleBarKit + * + * \since QGIS 3.2 + */ +class QUICK_EXPORT QgsQuickScaleBarKit : public QObject +{ + Q_OBJECT + + /** + * Associated map settings + */ + Q_PROPERTY( QgsQuickMapSettings *mapSettings MEMBER mMapSettings WRITE setMapSettings NOTIFY mapSettingsChanged ) + + /** + * Preferred width of scalebar in pixels. Defaults to 300 + */ + Q_PROPERTY( int preferredWidth MEMBER mPreferredWidth NOTIFY preferredWidthChanged ) + + /** + * Units of distance (e.g. km or m) Read-only (result) + */ + Q_PROPERTY( QString units READ units NOTIFY scaleBarChanged ) + + /** + * Distance rounded to "nice" number (e.g. 100, 20). To be used with units property for labels. Read-only (result) + */ + Q_PROPERTY( int distance READ distance NOTIFY scaleBarChanged ) + + /** + * Calculated width of scalebar in pixels representing distance + units. Differs minimum possible from preferredWidth to + * get "nice" distance number. + */ + Q_PROPERTY( int width READ width NOTIFY scaleBarChanged ) + + public: + //! create new scale bar kit + explicit QgsQuickScaleBarKit( QObject *parent = nullptr ); + ~QgsQuickScaleBarKit() = default; + + //! Set map settings + void setMapSettings( QgsQuickMapSettings *mapSettings ); + + //! Returns calculated width in pixels + int width() const; + + /** + * Returns distance corensponding to width + * + * \see QgsQuickScaleBarKit::units() + */ + int distance() const; + + /** + * Returns units of distance (m, km) + * + * \see QgsQuickScaleBarKit::distance() + */ + QString units() const; + + signals: + //! width, distance and/or units changed + void scaleBarChanged(); + + //! map settings changed + void mapSettingsChanged(); + + //! preferred width changed + void preferredWidthChanged(); + + public slots: + //! recalculate width, distance and units + void updateScaleBar(); + + private: + QgsQuickMapSettings *mMapSettings = nullptr; + + int mPreferredWidth; // pixels + int mWidth; // pixels + int mDistance; // in meters or kilometers, rounded + QString mUnits; // km or m +}; + + +#endif // QGSQUICKSCALEBARKIT_H diff --git a/src/quickgui/qgsquickutils.cpp b/src/quickgui/qgsquickutils.cpp index bd559520fbd2..a646d448537f 100644 --- a/src/quickgui/qgsquickutils.cpp +++ b/src/quickgui/qgsquickutils.cpp @@ -27,10 +27,58 @@ #include "qgsunittypes.h" +QgsQuickUtils *QgsQuickUtils::sInstance = 0; + +QgsQuickUtils *QgsQuickUtils::instance() +{ + if ( !sInstance ) + { + QgsDebugMsg( QStringLiteral( "QgsQuickUtils created: %1" ).arg( long( QThread::currentThreadId() ) ) ); + sInstance = new QgsQuickUtils(); + } + return sInstance; +} + QgsQuickUtils::QgsQuickUtils( QObject *parent ) : QObject( parent ) - , mScreenDensity( calculateScreenDensity() ) { + + // calculate screen density for calculation of real pixel sizes from density-independent pixels + int dpiX = QApplication::desktop()->physicalDpiX(); + int dpiY = QApplication::desktop()->physicalDpiY(); + int dpi = dpiX < dpiY ? dpiX : dpiY; // In case of asymmetrical DPI. Improbable + mScreenDensity = dpi / 160.; // 160 DPI is baseline for density-independent pixels in Android +} + +QgsQuickUtils::~QgsQuickUtils() +{ +} + +QgsCoordinateReferenceSystem QgsQuickUtils::coordinateReferenceSystemFromEpsgId( long epsg ) const +{ + return QgsCoordinateReferenceSystem::fromEpsgId( epsg ); +} + +double QgsQuickUtils::screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const +{ + if ( mapSettings == 0 ) return 0; + + QgsDistanceArea mDistanceArea; + mDistanceArea.setEllipsoid( "WGS84" ); + mDistanceArea.setSourceCrs( mapSettings->destinationCrs(), mapSettings->transformContext() ); + + // calculate the geographic distance from the central point of extent + // to the specified number of points on the right side + QSize s = mapSettings->outputSize(); + QPoint pointCenter( s.width() / 2, s.height() / 2 ); + QgsPointXY p1 = mapSettings->screenToCoordinate( pointCenter ); + QgsPointXY p2 = mapSettings->screenToCoordinate( pointCenter + QPoint( baseLengthPixels, 0 ) ); + return mDistanceArea.measureLine( p1, p2 ); +} + +void QgsQuickUtils::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level ) +{ + QgsMessageLog::logMessage( message, tag, level ); } QString QgsQuickUtils::dumpScreenInfo() const @@ -40,14 +88,14 @@ QString QgsQuickUtils::dumpScreenInfo() const int dpiY = QApplication::desktop()->physicalDpiY(); int height = rec.height(); int width = rec.width(); - double sizeX = static_cast( width ) / dpiX * 25.4; - double sizeY = static_cast( height ) / dpiY * 25.4; + double sizeX = ( double ) width / dpiX * 25.4; + double sizeY = ( double ) height / dpiY * 25.4; QString msg; - msg += tr( "screen resolution: %1x%2 px\n" ).arg( width ).arg( height ); - msg += tr( "screen DPI: %1x%2\n" ).arg( dpiX ).arg( dpiY ); - msg += tr( "screen size: %1x%2 mm\n" ).arg( QString::number( sizeX, 'f', 0 ), QString::number( sizeY, 'f', 0 ) ); - msg += tr( "screen density: %1" ).arg( mScreenDensity ); + msg += "screen resolution: " + QString::number( width ) + "x" + QString::number( height ) + " px\n"; + msg += "screen DPI: " + QString::number( dpiX ) + "x" + QString::number( dpiY ) + "\n"; + msg += "screen size: " + QString::number( sizeX, 'f', 0 ) + "x" + QString::number( sizeY, 'f', 0 ) + " mm\n"; + msg += "screen density: " + QString::number( mScreenDensity ); return msg; } @@ -55,12 +103,3 @@ qreal QgsQuickUtils::screenDensity() const { return mScreenDensity; } - -qreal QgsQuickUtils::calculateScreenDensity() -{ - // calculate screen density for calculation of real pixel sizes from density-independent pixels - int dpiX = QApplication::desktop()->physicalDpiX(); - int dpiY = QApplication::desktop()->physicalDpiY(); - int dpi = dpiX < dpiY ? dpiX : dpiY; // In case of asymmetrical DPI. Improbable - return dpi / 160.; // 160 DPI is baseline for density-independent pixels in Android -} diff --git a/src/quickgui/qgsquickutils.h b/src/quickgui/qgsquickutils.h index 53499ab849fd..2764cba2cde4 100644 --- a/src/quickgui/qgsquickutils.h +++ b/src/quickgui/qgsquickutils.h @@ -21,14 +21,16 @@ #include #include "qgis.h" +#include "qgsmessagelog.h" +#include "qgsquickmapsettings.h" #include "qgis_quick.h" +class QgsCoordinateReferenceSystem; /** * \ingroup quick * - * Encapsulating the common utilies for QgsQuick library. + * Singleton encapsulating the common utilies for QgsQuick library. * - * \note QML Type: Utils (Singleton) * * \since QGIS 3.2 */ @@ -44,31 +46,42 @@ class QUICK_EXPORT QgsQuickUtils: public QObject * * 1dp is approximately 0.16mm. When screen has 160 DPI (baseline), the value of "dp" is 1. * On high DPI screen the value will be greater, e.g. 1.5. - * - * This is a readonly property. */ Q_PROPERTY( qreal dp READ screenDensity CONSTANT ) public: - //! Create new utilities - QgsQuickUtils( QObject *parent = nullptr ); - //! dtor - ~QgsQuickUtils() = default; + //! return instance of the QgsQuickUtils singleton + static QgsQuickUtils *instance(); - //! \copydoc QgsQuickUtils::dp + //! Calculated density of the screen - see "dp" property for more details qreal screenDensity() const; /** - * Returns a string with information about screen size and resolution - * - * Useful to log for debugging of graphical problems on various display sizes - */ + * Create crs from epsg code in QML + */ + Q_INVOKABLE QgsCoordinateReferenceSystem coordinateReferenceSystemFromEpsgId( long epsg ) const; + /** + * Calculate the distance in meter representing baseLengthPixels pixels on the screen based on the current map settings. + */ + Q_INVOKABLE double screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const; + +//! Log message in QgsMessageLog + Q_INVOKABLE void logMessage( const QString &message, + const QString &tag = QString( "QgsQuick" ), + Qgis::MessageLevel level = Qgis::Warning ); + +//! Returns a string with information about screen size and resolution - useful for debugging QString dumpScreenInfo() const; + private: - static qreal calculateScreenDensity(); + explicit QgsQuickUtils( QObject *parent = nullptr ); + ~QgsQuickUtils(); + + static QgsQuickUtils *sInstance; qreal mScreenDensity; + }; #endif // QGSQUICKUTILS_H diff --git a/tests/src/quickgui/app/main.cpp b/tests/src/quickgui/app/main.cpp index ceac47ad76d9..492749e4be55 100644 --- a/tests/src/quickgui/app/main.cpp +++ b/tests/src/quickgui/app/main.cpp @@ -84,8 +84,9 @@ int main( int argc, char *argv[] ) } // Add some data for debugging if needed - QgsApplication::messageLog()->logMessage( QgsQuickUtils().dumpScreenInfo() ); - QgsDebugMsg( QStringLiteral( "data directory: %1" ).arg( dataDir ) ); + QgsApplication::messageLog()->logMessage( QgsQuickUtils::instance()->dumpScreenInfo() ); + QgsApplication::messageLog()->logMessage( "data directory: " + dataDir ); + QgsApplication::messageLog()->logMessage( "All up and running" ); return app.exec(); } diff --git a/tests/src/quickgui/app/main.qml b/tests/src/quickgui/app/main.qml index 7e6cf8bd9121..851ab3ed863d 100644 --- a/tests/src/quickgui/app/main.qml +++ b/tests/src/quickgui/app/main.qml @@ -18,23 +18,56 @@ import QgsQuick 0.1 as QgsQuick import "." ApplicationWindow { - id: window - visible: true - visibility: "Maximized" - title: qsTr("QGIS Quick Test App") + id: window + visible: true + visibility: "Maximized" + title: qsTr("QGIS Quick Test App") - QgsQuick.MapCanvas { - id: mapCanvas + QgsQuick.MapCanvas { + id: mapCanvas - height: parent.height - width: parent.width + height: parent.height + width: parent.width - mapSettings.project: __project - mapSettings.layers: __layers + mapSettings.project: __project + mapSettings.layers: __layers - onClicked: { - var screenPoint = Qt.point(mouse.x, mouse.y) - console.log("clicked:" + screenPoint) + onClicked: { + var screenPoint = Qt.point(mouse.x, mouse.y) + console.log("clicked:" + screenPoint) + } + } + + Drawer { + id: logPanel + visible: false + modal: true + interactive: true + dragMargin: 0 // prevents opening the drawer by dragging. + height: window.height + width: QgsQuick.Utils.dp * 700 + edge: Qt.RightEdge + z: 2 // make sure items from here are on top of the Z-order + + background: Rectangle { + color: "white" + } + + QgsQuick.MessageLog { + id: messageLog + width: parent.width + height: parent.height + model: QgsQuick.MessageLogModel {} + visible: true + } + } + + QgsQuick.ScaleBar { + id: scaleBar + y: window.height - height + height: 50 + mapSettings: mapCanvas.mapSettings + preferredWidth: 115 * QgsQuick.Utils.dp + z: 1 } - } } diff --git a/tests/src/quickgui/testqgsquickutils.cpp b/tests/src/quickgui/testqgsquickutils.cpp index a83f7a9e5c58..32ce0ec2af5e 100644 --- a/tests/src/quickgui/testqgsquickutils.cpp +++ b/tests/src/quickgui/testqgsquickutils.cpp @@ -29,24 +29,20 @@ class TestQgsQuickUtils: public QObject void init() {} // will be called before each testfunction is executed. void cleanup() {} // will be called after every testfunction. - void screen_density(); - - void dump_screen_info(); - - private: - QgsQuickUtils utils; + void crs_and_geometry(); }; -void TestQgsQuickUtils::screen_density() -{ - qreal dp = utils.screenDensity(); - QVERIFY( ( dp > 0 ) && ( dp < 1000 ) ); -} - -void TestQgsQuickUtils::dump_screen_info() +void TestQgsQuickUtils::crs_and_geometry() { - qreal dp = utils.screenDensity(); - QVERIFY( utils.dumpScreenInfo().contains( QStringLiteral( "%1" ).arg( dp ) ) ); + QgsCoordinateReferenceSystem crsGPS = QgsQuickUtils::instance()->coordinateReferenceSystemFromEpsgId( 4326 ); + QVERIFY( crsGPS.authid() == "EPSG:4326" ); + + QgsQuickMapSettings ms; + ms.setDestinationCrs( crsGPS ); + ms.setExtent( QgsRectangle( 49, 16, 50, 17 ) ); + ms.setOutputSize( QSize( 1000, 500 ) ); + double sutm = QgsQuickUtils::instance()->screenUnitsToMeters( &ms, 1 ); + QVERIFY( fabs( sutm - 213 ) < 1.0 ); } QGSTEST_MAIN( TestQgsQuickUtils ) From e04e846994a2d36a5f6d8e4917c18f46a279fd0b Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Thu, 10 May 2018 14:41:36 +0200 Subject: [PATCH 02/11] Added scalebarkit test. --- src/quickgui/qgsquickutils.h | 2 + tests/src/quickgui/CMakeLists.txt | 1 + .../src/quickgui/testqgsquickscalebarkit.cpp | 60 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 tests/src/quickgui/testqgsquickscalebarkit.cpp diff --git a/src/quickgui/qgsquickutils.h b/src/quickgui/qgsquickutils.h index 2764cba2cde4..ec202189df95 100644 --- a/src/quickgui/qgsquickutils.h +++ b/src/quickgui/qgsquickutils.h @@ -26,6 +26,7 @@ #include "qgis_quick.h" class QgsCoordinateReferenceSystem; + /** * \ingroup quick * @@ -60,6 +61,7 @@ class QUICK_EXPORT QgsQuickUtils: public QObject * Create crs from epsg code in QML */ Q_INVOKABLE QgsCoordinateReferenceSystem coordinateReferenceSystemFromEpsgId( long epsg ) const; + /** * Calculate the distance in meter representing baseLengthPixels pixels on the screen based on the current map settings. */ diff --git a/tests/src/quickgui/CMakeLists.txt b/tests/src/quickgui/CMakeLists.txt index af99c766567b..4658b776f7a0 100644 --- a/tests/src/quickgui/CMakeLists.txt +++ b/tests/src/quickgui/CMakeLists.txt @@ -79,6 +79,7 @@ ENDMACRO (ADD_QGIS_TEST) # Tests: ADD_QGIS_TEST(qgsquickutils testqgsquickutils.cpp) +ADD_QGIS_TEST(qgsquickscalebarkit testqgsquickscalebarkit.cpp) ############################################################# diff --git a/tests/src/quickgui/testqgsquickscalebarkit.cpp b/tests/src/quickgui/testqgsquickscalebarkit.cpp new file mode 100644 index 000000000000..9ba6198027a0 --- /dev/null +++ b/tests/src/quickgui/testqgsquickscalebarkit.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + testqgsquickutils.cpp + -------------------------------------- + Date : Nov 2017 + Copyright : (C) 2017 by Peter Petrik + Email : zilolv at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include +#include +#include + +#include "qgsapplication.h" +#include "qgstest.h" +#include "qgis.h" + +#include "qgsquickutils.h" +#include "qgsquickmapcanvasmap.h" +#include "qgsquickscalebarkit.h" + +class TestQgsQuickScaleBarKit: public QObject +{ + Q_OBJECT + private slots: + void init() {} // will be called before each testfunction is executed. + void cleanup() {} // will be called after every testfunction. + + void updateScaleBar(); +}; + +void TestQgsQuickScaleBarKit::updateScaleBar() +{ + QgsCoordinateReferenceSystem crsGPS = QgsQuickUtils::instance()->coordinateReferenceSystemFromEpsgId( 4326 ); + QVERIFY( crsGPS.authid() == "EPSG:4326" ); + + QgsRectangle extent = QgsRectangle( 49, 16, 50, 17 ); + QgsQuickMapCanvasMap canvas; + + QgsQuickMapSettings *ms = canvas.mapSettings(); + ms->setDestinationCrs( crsGPS ); + ms->setExtent( extent ); + ms->setOutputSize( QSize( 1000, 500 ) ); + + QgsQuickScaleBarKit kit; + kit.setMapSettings( ms ); + QVERIFY( kit.units() == QString( "km" ) ); + + qreal scale = 0.000005; + canvas.zoom( extent.center().toQPointF(), scale ); + QVERIFY( kit.units() == QString( "m" ) ); +} + +QGSTEST_MAIN( TestQgsQuickScaleBarKit ) +#include "testqgsquickscalebarkit.moc" From 8de102fbe8501c12ce7bf952c103d1696165e06d Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Thu, 10 May 2018 14:55:02 +0200 Subject: [PATCH 03/11] distance test --- src/quickgui/plugin/qgsquickplugin.cpp | 1 - tests/src/quickgui/testqgsquickscalebarkit.cpp | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/quickgui/plugin/qgsquickplugin.cpp b/src/quickgui/plugin/qgsquickplugin.cpp index 60116ea2d329..fc653f5b9510 100644 --- a/src/quickgui/plugin/qgsquickplugin.cpp +++ b/src/quickgui/plugin/qgsquickplugin.cpp @@ -54,7 +54,6 @@ void QgisQuickPlugin::registerTypes( const char *uri ) qRegisterMetaType< QgsPoint >( "QgsPoint" ); qRegisterMetaType< QgsPointXY >( "QgsPointXY" ); - qmlRegisterType< QgsProject >( uri, 0, 1, "Project" ); qmlRegisterType< QgsQuickMapCanvasMap >( uri, 0, 1, "MapCanvasMap" ); qmlRegisterType< QgsQuickMapSettings >( uri, 0, 1, "MapSettings" ); diff --git a/tests/src/quickgui/testqgsquickscalebarkit.cpp b/tests/src/quickgui/testqgsquickscalebarkit.cpp index 9ba6198027a0..62589cbef63d 100644 --- a/tests/src/quickgui/testqgsquickscalebarkit.cpp +++ b/tests/src/quickgui/testqgsquickscalebarkit.cpp @@ -50,10 +50,12 @@ void TestQgsQuickScaleBarKit::updateScaleBar() QgsQuickScaleBarKit kit; kit.setMapSettings( ms ); QVERIFY( kit.units() == QString( "km" ) ); + QVERIFY( kit.distance() == 50 ); - qreal scale = 0.000005; + qreal scale = 0.005; canvas.zoom( extent.center().toQPointF(), scale ); QVERIFY( kit.units() == QString( "m" ) ); + QVERIFY( kit.distance() == 200 ); } QGSTEST_MAIN( TestQgsQuickScaleBarKit ) From e6724fd77ddfde8b1f7875b4c88d99272f494864 Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Fri, 11 May 2018 12:21:07 +0200 Subject: [PATCH 04/11] WIP - Some changes after review --- doc/qgsquick.dox | 4 + src/quickgui/plugin/CMakeLists.txt | 2 +- src/quickgui/plugin/qgsquickplugin.cpp | 4 +- src/quickgui/plugin/qgsquickplugin.h | 2 +- src/quickgui/plugin/qgsquickscalebar.qml | 33 ++++++ src/quickgui/qgsquickmessagelogmodel.cpp | 21 +++- src/quickgui/qgsquickmessagelogmodel.h | 17 ++- src/quickgui/qgsquickscalebarkit.cpp | 2 +- src/quickgui/qgsquickscalebarkit.h | 3 +- src/quickgui/qgsquickutils.cpp | 103 +++++++++++++----- src/quickgui/qgsquickutils.h | 61 +++++++++-- tests/src/quickgui/app/main.cpp | 5 +- tests/src/quickgui/app/main.qml | 84 +++++++------- .../src/quickgui/testqgsquickscalebarkit.cpp | 13 ++- tests/src/quickgui/testqgsquickutils.cpp | 74 ++++++++++++- 15 files changed, 317 insertions(+), 111 deletions(-) diff --git a/doc/qgsquick.dox b/doc/qgsquick.dox index 6178be0d8756..47d2d2437705 100644 --- a/doc/qgsquick.dox +++ b/doc/qgsquick.dox @@ -13,8 +13,12 @@ QGIS Quick consists of a Qt plugin that provides the QML components and of a sha \subsection qgsquick_overview_widgets QML Classes \subsubsection qgsquick_overview_widgets_mapcanvas MapCanvas +Similarly to QgsMapCanvas, this component can be used for displaying GIS data on a canvas. More info about the QgsQuickMapCanvas qgsquickmapcanvas.h qgsquickmapcanvas.cpp. \subsubsection qgsquick_overview_widgets_scalebar ScaleBar +A QML component that shows the scale ratio between its length and distance on the MapCanvas. There are predefined rounded values for several zooming levels with 'm' or 'km' postfixes. After any zoom in/out event on canvas recalculates its properties and updates text on the ScaleBar. + \subsubsection qgsquick_overview_widgets_messagelog MessageLog +A simple panel which can be used for publishing logs messages to a user such as basic information about the application or its status. \section qgsquick_styling Styling diff --git a/src/quickgui/plugin/CMakeLists.txt b/src/quickgui/plugin/CMakeLists.txt index 6649248a4f6b..5d4ba8e328f5 100644 --- a/src/quickgui/plugin/CMakeLists.txt +++ b/src/quickgui/plugin/CMakeLists.txt @@ -106,7 +106,7 @@ IF(QMLPLUGINDUMP_FOUND) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${CMAKE_COMMAND} -E copy $ ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${QMLPLUGINDUMP_EXECUTABLE} - ARGS QgisQuick 0.1 . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO} + ARGS QgsQuick 0.1 . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" POST_BUILD ) diff --git a/src/quickgui/plugin/qgsquickplugin.cpp b/src/quickgui/plugin/qgsquickplugin.cpp index fc653f5b9510..c4f01e8af926 100644 --- a/src/quickgui/plugin/qgsquickplugin.cpp +++ b/src/quickgui/plugin/qgsquickplugin.cpp @@ -40,10 +40,10 @@ static QObject *_utilsProvider( QQmlEngine *engine, QJSEngine *scriptEngine ) { Q_UNUSED( engine ) Q_UNUSED( scriptEngine ) - return QgsQuickUtils::instance(); // the object will be owned by QML engine and destroyed by the engine on exit + return new QgsQuickUtils(); // the object will be owned by QML engine and destroyed by the engine on exit } -void QgisQuickPlugin::registerTypes( const char *uri ) +void QgsQuickPlugin::registerTypes( const char *uri ) { qRegisterMetaType< QList >( "QList" ); qRegisterMetaType< QgsAttributes > ( "QgsAttributes" ); diff --git a/src/quickgui/plugin/qgsquickplugin.h b/src/quickgui/plugin/qgsquickplugin.h index e98ba920f57b..1133dc42646c 100644 --- a/src/quickgui/plugin/qgsquickplugin.h +++ b/src/quickgui/plugin/qgsquickplugin.h @@ -25,7 +25,7 @@ * * \since QGIS 3.2 */ -class QgisQuickPlugin : public QQmlExtensionPlugin +class QgsQuickPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA( IID "org.qt-project.Qt.QQmlExtensionInterface" ) diff --git a/src/quickgui/plugin/qgsquickscalebar.qml b/src/quickgui/plugin/qgsquickscalebar.qml index 349eb9447fc3..d408bc194b23 100644 --- a/src/quickgui/plugin/qgsquickscalebar.qml +++ b/src/quickgui/plugin/qgsquickscalebar.qml @@ -16,20 +16,53 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import QgsQuick 0.1 as QgsQuick +/*! + \qmltype ScaleBar + \brief A component that shows scale ratio between its length and distance on the MapCanvas +*/ Item { id: scaleBar property alias mapSettings: scaleBarKit.mapSettings + /*! + Preferred width of scalebar in pixels. Defaults set to 300. + */ property alias preferredWidth: scaleBarKit.preferredWidth + /*! + * Utility used for Scalebar properties. + */ property QgsQuick.ScaleBarKit scaleBarKit: QgsQuick.ScaleBarKit {id: scaleBarKit} + + /*! + Reserved text width. + */ property int textWidth: fontMetrics.averageCharacterWidth * 8 + /*! + Opacity of ScaleBar. + */ property color barColor: "white" + /*! + Background color of scaleBar. + */ property color barBackgroundColor: "grey" + /*! + Opacity of ScaleBar. + */ property double barOpacity: 0.8 + /*! + Defines text shown on ScaleBar. + */ property string barText: scaleBarKit.distance + " " + scaleBarKit.units + + /*! + Returns calculated width in pixels. + */ property int barWidth: scaleBarKit.width property int lineWidth: 5 * QgsQuick.Utils.dp + /*! + The real width of the component. + */ width: textWidth + barWidth MouseArea { diff --git a/src/quickgui/qgsquickmessagelogmodel.cpp b/src/quickgui/qgsquickmessagelogmodel.cpp index 0652f5693634..dc168ab1383f 100644 --- a/src/quickgui/qgsquickmessagelogmodel.cpp +++ b/src/quickgui/qgsquickmessagelogmodel.cpp @@ -22,17 +22,26 @@ QgsQuickMessageLogModel::QgsQuickMessageLogModel( QObject *parent ) : QAbstractListModel( parent ) - , mMessageLog( QgsApplication::messageLog() ) { - connect( mMessageLog, static_cast( &QgsMessageLog::messageReceived ), this, &QgsQuickMessageLogModel::onMessageReceived ); + connect( QgsApplication::messageLog(), static_cast( &QgsMessageLog::messageReceived ), this, &QgsQuickMessageLogModel::onMessageReceived ); +} + +QgsQuickMessageLogModel::LogMessage QgsQuickMessageLogModel::logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ) +{ + LogMessage msg; + msg.tag = tag; + msg.message = message; + msg.level = level; + + return msg; } QHash QgsQuickMessageLogModel::roleNames() const { QHash roles = QAbstractListModel::roleNames(); - roles[MessageRole] = "Message"; - roles[MessageTagRole] = "MessageTag"; - roles[MessageLevelRole] = "MessageLevel"; + roles[MessageRole] = QByteArrayLiteral( "Message" ); + roles[MessageTagRole] = QByteArrayLiteral( "MessageTag" ); + roles[MessageLevelRole] = QByteArrayLiteral( "MessageLevel" ); return roles; } @@ -61,7 +70,7 @@ QVariant QgsQuickMessageLogModel::data( const QModelIndex &index, int role ) con void QgsQuickMessageLogModel::onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ) { beginInsertRows( QModelIndex(), 0, 0 ); - mMessages.prepend( LogMessage( tag, message, level ) ); + mMessages.prepend( logMessage( tag, message, level ) ); QgsDebugMsg( QStringLiteral( "Next message %1 : %2" ).arg( tag, message ) ); endInsertRows(); } diff --git a/src/quickgui/qgsquickmessagelogmodel.h b/src/quickgui/qgsquickmessagelogmodel.h index 6d32d17c45bc..6a9160287f0c 100644 --- a/src/quickgui/qgsquickmessagelogmodel.h +++ b/src/quickgui/qgsquickmessagelogmodel.h @@ -17,6 +17,10 @@ #define QGSQUICKMESSAGELOGMODEL_H #include +#include +#include +#include +#include #include "qgis.h" #include "qgsmessagelog.h" @@ -40,15 +44,7 @@ class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel struct LogMessage { - LogMessage() - {} - - LogMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ) - { - this->tag = tag; - this->message = message; - this->level = level; - } + LogMessage() = default; QString tag; QString message; @@ -66,6 +62,8 @@ class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel //! Create new message log model QgsQuickMessageLogModel( QObject *parent = nullptr ); + LogMessage logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ); + QHash roleNames() const override; int rowCount( const QModelIndex &parent ) const override; @@ -75,7 +73,6 @@ class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel void onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ); private: - QgsMessageLog *mMessageLog; QVector mMessages; }; diff --git a/src/quickgui/qgsquickscalebarkit.cpp b/src/quickgui/qgsquickscalebarkit.cpp index e79ef7be14c9..ccd4b02c496a 100644 --- a/src/quickgui/qgsquickscalebarkit.cpp +++ b/src/quickgui/qgsquickscalebarkit.cpp @@ -82,7 +82,7 @@ void QgsQuickScaleBarKit::updateScaleBar() if ( !mMapSettings ) return; - double dist = QgsQuickUtils::instance()->screenUnitsToMeters( mMapSettings, mPreferredWidth ); // meters + double dist = QgsQuickUtils().screenUnitsToMeters( mMapSettings, mPreferredWidth ); // meters if ( dist > 1000.0 ) { dist = dist / 1000.0; // meters to kilometers diff --git a/src/quickgui/qgsquickscalebarkit.h b/src/quickgui/qgsquickscalebarkit.h index 27332dcf0165..4b18f5edef9d 100644 --- a/src/quickgui/qgsquickscalebarkit.h +++ b/src/quickgui/qgsquickscalebarkit.h @@ -20,6 +20,7 @@ #include #include "qgis_quick.h" +#include "qgsquickutils.h" class QgsQuickMapSettings; @@ -95,7 +96,7 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject */ QString units() const; - signals: +signals: //! width, distance and/or units changed void scaleBarChanged(); diff --git a/src/quickgui/qgsquickutils.cpp b/src/quickgui/qgsquickutils.cpp index a646d448537f..f4144257ecd6 100644 --- a/src/quickgui/qgsquickutils.cpp +++ b/src/quickgui/qgsquickutils.cpp @@ -27,44 +27,48 @@ #include "qgsunittypes.h" -QgsQuickUtils *QgsQuickUtils::sInstance = 0; +QgsQuickUtils::QgsQuickUtils( QObject *parent ) + : QObject( parent ) + , mScreenDensity( calculateScreenDensity() ) +{ +} -QgsQuickUtils *QgsQuickUtils::instance() +QgsCoordinateReferenceSystem QgsQuickUtils::coordinateReferenceSystemFromEpsgId( long epsg ) const { - if ( !sInstance ) - { - QgsDebugMsg( QStringLiteral( "QgsQuickUtils created: %1" ).arg( long( QThread::currentThreadId() ) ) ); - sInstance = new QgsQuickUtils(); - } - return sInstance; + return QgsCoordinateReferenceSystem::fromEpsgId( epsg ); } -QgsQuickUtils::QgsQuickUtils( QObject *parent ) - : QObject( parent ) +QgsPointXY QgsQuickUtils::pointXYFactory( double x, double y ) const { + return QgsPointXY( x, y ); +} - // calculate screen density for calculation of real pixel sizes from density-independent pixels - int dpiX = QApplication::desktop()->physicalDpiX(); - int dpiY = QApplication::desktop()->physicalDpiY(); - int dpi = dpiX < dpiY ? dpiX : dpiY; // In case of asymmetrical DPI. Improbable - mScreenDensity = dpi / 160.; // 160 DPI is baseline for density-independent pixels in Android +QgsPoint QgsQuickUtils::pointFactory( double x, double y ) const +{ + return QgsPoint( x, y ); } -QgsQuickUtils::~QgsQuickUtils() +QgsPoint QgsQuickUtils::coordinateToPoint( const QGeoCoordinate &coor ) const { + return QgsPoint( coor.longitude(), coor.latitude(), coor.altitude() ); } -QgsCoordinateReferenceSystem QgsQuickUtils::coordinateReferenceSystemFromEpsgId( long epsg ) const +QgsPointXY QgsQuickUtils::transformPoint( const QgsCoordinateReferenceSystem &srcCrs, + const QgsCoordinateReferenceSystem &destCrs, + const QgsCoordinateTransformContext &context, + const QgsPointXY &srcPoint ) const { - return QgsCoordinateReferenceSystem::fromEpsgId( epsg ); + QgsCoordinateTransform mTransform( srcCrs, destCrs, context ); + QgsPointXY pt = mTransform.transform( srcPoint ); + return pt; } double QgsQuickUtils::screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const { - if ( mapSettings == 0 ) return 0; + if ( mapSettings == nullptr ) return 0.0; QgsDistanceArea mDistanceArea; - mDistanceArea.setEllipsoid( "WGS84" ); + mDistanceArea.setEllipsoid( QStringLiteral( "WGS84" ) ); mDistanceArea.setSourceCrs( mapSettings->destinationCrs(), mapSettings->transformContext() ); // calculate the geographic distance from the central point of extent @@ -81,6 +85,44 @@ void QgsQuickUtils::logMessage( const QString &message, const QString &tag, Qgis QgsMessageLog::logMessage( message, tag, level ); } +QString QgsQuickUtils::qgsPointToString( const QgsPoint &point, int decimals ) +{ + QString label; + label += QString::number( point.x(), 'f', decimals ); + label += ", "; + label += QString::number( point.y(), 'f', decimals ); + return label; +} + +QString QgsQuickUtils::distanceToString( qreal dist, int decimals ) +{ + if ( dist < 0 ) + { + return "0 m"; + } + + QString label; + if ( dist > 1000 ) + { + label += QString::number( dist / 1000.0, 'f', decimals ); + label += QString( " km" ); + } + else + { + if ( dist > 1 ) + { + label += QString::number( dist, 'f', decimals ); + label += QString( " m" ); + } + else + { + label += QString::number( dist * 1000, 'f', decimals ); + label += QString( " mm" ); + } + } + return label; +} + QString QgsQuickUtils::dumpScreenInfo() const { QRect rec = QApplication::desktop()->screenGeometry(); @@ -88,14 +130,14 @@ QString QgsQuickUtils::dumpScreenInfo() const int dpiY = QApplication::desktop()->physicalDpiY(); int height = rec.height(); int width = rec.width(); - double sizeX = ( double ) width / dpiX * 25.4; - double sizeY = ( double ) height / dpiY * 25.4; + double sizeX = static_cast( width ) / dpiX * 25.4; + double sizeY = static_cast( height ) / dpiY * 25.4; QString msg; - msg += "screen resolution: " + QString::number( width ) + "x" + QString::number( height ) + " px\n"; - msg += "screen DPI: " + QString::number( dpiX ) + "x" + QString::number( dpiY ) + "\n"; - msg += "screen size: " + QString::number( sizeX, 'f', 0 ) + "x" + QString::number( sizeY, 'f', 0 ) + " mm\n"; - msg += "screen density: " + QString::number( mScreenDensity ); + msg += tr( "screen resolution: %1x%2 px\n" ).arg( width ).arg( height ); + msg += tr( "screen DPI: %1x%2\n" ).arg( dpiX ).arg( dpiY ); + msg += tr( "screen size: %1x%2 mm\n" ).arg( QString::number( sizeX, 'f', 0 ), QString::number( sizeY, 'f', 0 ) ); + msg += tr( "screen density: %1" ).arg( mScreenDensity ); return msg; } @@ -103,3 +145,12 @@ qreal QgsQuickUtils::screenDensity() const { return mScreenDensity; } + +qreal QgsQuickUtils::calculateScreenDensity() +{ + // calculate screen density for calculation of real pixel sizes from density-independent pixels + int dpiX = QApplication::desktop()->physicalDpiX(); + int dpiY = QApplication::desktop()->physicalDpiY(); + int dpi = dpiX < dpiY ? dpiX : dpiY; // In case of asymmetrical DPI. Improbable + return dpi / 160.; // 160 DPI is baseline for density-independent pixels in Android +} diff --git a/src/quickgui/qgsquickutils.h b/src/quickgui/qgsquickutils.h index ec202189df95..61331ad99d6b 100644 --- a/src/quickgui/qgsquickutils.h +++ b/src/quickgui/qgsquickutils.h @@ -19,9 +19,13 @@ #include #include +#include #include "qgis.h" #include "qgsmessagelog.h" +#include "qgspoint.h" +#include "qgspointxy.h" + #include "qgsquickmapsettings.h" #include "qgis_quick.h" @@ -30,8 +34,9 @@ class QgsCoordinateReferenceSystem; /** * \ingroup quick * - * Singleton encapsulating the common utilies for QgsQuick library. + * Encapsulating the common utilies for QgsQuick library. * + * \note QML Type: Utils (Singleton) * * \since QGIS 3.2 */ @@ -47,12 +52,16 @@ class QUICK_EXPORT QgsQuickUtils: public QObject * * 1dp is approximately 0.16mm. When screen has 160 DPI (baseline), the value of "dp" is 1. * On high DPI screen the value will be greater, e.g. 1.5. + * + * This is a readonly property. */ Q_PROPERTY( qreal dp READ screenDensity CONSTANT ) public: - //! return instance of the QgsQuickUtils singleton - static QgsQuickUtils *instance(); + //! Create new utilities + QgsQuickUtils( QObject *parent = nullptr ); + //! dtor + ~QgsQuickUtils() = default; //! Calculated density of the screen - see "dp" property for more details qreal screenDensity() const; @@ -62,6 +71,29 @@ class QUICK_EXPORT QgsQuickUtils: public QObject */ Q_INVOKABLE QgsCoordinateReferenceSystem coordinateReferenceSystemFromEpsgId( long epsg ) const; + /** + * Create QgsPointXY in QML + */ + Q_INVOKABLE QgsPointXY pointXYFactory( double x, double y ) const; + + /** + * Create QgsPoint in QML + */ + Q_INVOKABLE QgsPoint pointFactory( double x, double y ) const; + + /** + * Convert QGeoCoordinate to QgsPoint + */ + Q_INVOKABLE QgsPoint coordinateToPoint( const QGeoCoordinate &coor ) const; + + /** + * Transform point between different crs from QML + */ + Q_INVOKABLE QgsPointXY transformPoint( const QgsCoordinateReferenceSystem &srcCrs, + const QgsCoordinateReferenceSystem &destCrs, + const QgsCoordinateTransformContext &context, + const QgsPointXY &srcPoint ) const; + /** * Calculate the distance in meter representing baseLengthPixels pixels on the screen based on the current map settings. */ @@ -72,18 +104,27 @@ class QUICK_EXPORT QgsQuickUtils: public QObject const QString &tag = QString( "QgsQuick" ), Qgis::MessageLevel level = Qgis::Warning ); -//! Returns a string with information about screen size and resolution - useful for debugging - QString dumpScreenInfo() const; + /** + * point to string, e.g. -2.234521, 34.4444421 -> -2.234, 34.444 + */ + Q_INVOKABLE QString qgsPointToString( const QgsPoint &point, int decimals = 3 ); + + /** + * distance in meters to human readable length e.g. 1222.234 m -> 1.2 km + */ + Q_INVOKABLE QString distanceToString( qreal dist, int decimals = 1 ); + /** + * Returns a string with information about screen size and resolution + * + * Useful to log for debugging of graphical problems on various display sizes + */ + QString dumpScreenInfo() const; private: - explicit QgsQuickUtils( QObject *parent = nullptr ); - ~QgsQuickUtils(); - - static QgsQuickUtils *sInstance; + static qreal calculateScreenDensity(); qreal mScreenDensity; - }; #endif // QGSQUICKUTILS_H diff --git a/tests/src/quickgui/app/main.cpp b/tests/src/quickgui/app/main.cpp index 492749e4be55..ceac47ad76d9 100644 --- a/tests/src/quickgui/app/main.cpp +++ b/tests/src/quickgui/app/main.cpp @@ -84,9 +84,8 @@ int main( int argc, char *argv[] ) } // Add some data for debugging if needed - QgsApplication::messageLog()->logMessage( QgsQuickUtils::instance()->dumpScreenInfo() ); - QgsApplication::messageLog()->logMessage( "data directory: " + dataDir ); - QgsApplication::messageLog()->logMessage( "All up and running" ); + QgsApplication::messageLog()->logMessage( QgsQuickUtils().dumpScreenInfo() ); + QgsDebugMsg( QStringLiteral( "data directory: %1" ).arg( dataDir ) ); return app.exec(); } diff --git a/tests/src/quickgui/app/main.qml b/tests/src/quickgui/app/main.qml index 851ab3ed863d..bb89ea82e50d 100644 --- a/tests/src/quickgui/app/main.qml +++ b/tests/src/quickgui/app/main.qml @@ -18,56 +18,56 @@ import QgsQuick 0.1 as QgsQuick import "." ApplicationWindow { - id: window - visible: true - visibility: "Maximized" - title: qsTr("QGIS Quick Test App") + id: window + visible: true + visibility: "Maximized" + title: qsTr("QGIS Quick Test App") - QgsQuick.MapCanvas { - id: mapCanvas + QgsQuick.MapCanvas { + id: mapCanvas - height: parent.height - width: parent.width + height: parent.height + width: parent.width - mapSettings.project: __project - mapSettings.layers: __layers + mapSettings.project: __project + mapSettings.layers: __layers - onClicked: { - var screenPoint = Qt.point(mouse.x, mouse.y) - console.log("clicked:" + screenPoint) - } + onClicked: { + var screenPoint = Qt.point(mouse.x, mouse.y) + console.log("clicked:" + screenPoint) } + } - Drawer { - id: logPanel - visible: false - modal: true - interactive: true - dragMargin: 0 // prevents opening the drawer by dragging. - height: window.height - width: QgsQuick.Utils.dp * 700 - edge: Qt.RightEdge - z: 2 // make sure items from here are on top of the Z-order - - background: Rectangle { - color: "white" - } + Drawer { + id: logPanel + visible: true + modal: true + interactive: true + dragMargin: 0 // prevents opening the drawer by dragging. + height: window.height + width: QgsQuick.Utils.dp * 700 + edge: Qt.RightEdge + z: 2 // make sure items from here are on top of the Z-order - QgsQuick.MessageLog { - id: messageLog - width: parent.width - height: parent.height - model: QgsQuick.MessageLogModel {} - visible: true - } + background: Rectangle { + color: "white" } - QgsQuick.ScaleBar { - id: scaleBar - y: window.height - height - height: 50 - mapSettings: mapCanvas.mapSettings - preferredWidth: 115 * QgsQuick.Utils.dp - z: 1 + QgsQuick.MessageLog { + id: messageLog + width: parent.width + height: parent.height + model: QgsQuick.MessageLogModel {} + visible: true } + } + + QgsQuick.ScaleBar { + id: scaleBar + y: window.height - height + height: 50 + mapSettings: mapCanvas.mapSettings + preferredWidth: 115 * QgsQuick.Utils.dp + z: 1 + } } diff --git a/tests/src/quickgui/testqgsquickscalebarkit.cpp b/tests/src/quickgui/testqgsquickscalebarkit.cpp index 62589cbef63d..7ee0c4b2b579 100644 --- a/tests/src/quickgui/testqgsquickscalebarkit.cpp +++ b/tests/src/quickgui/testqgsquickscalebarkit.cpp @@ -1,9 +1,9 @@ /*************************************************************************** - testqgsquickutils.cpp + testqgsquickscalebarkit.cpp.cpp -------------------------------------- - Date : Nov 2017 - Copyright : (C) 2017 by Peter Petrik - Email : zilolv at gmail dot com + Date : May 2018 + Copyright : (C) 2018 by Viktor Sklencar + Email : vsklencar at gmail dot com *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * @@ -24,6 +24,7 @@ #include "qgsquickmapcanvasmap.h" #include "qgsquickscalebarkit.h" + class TestQgsQuickScaleBarKit: public QObject { Q_OBJECT @@ -31,12 +32,12 @@ class TestQgsQuickScaleBarKit: public QObject void init() {} // will be called before each testfunction is executed. void cleanup() {} // will be called after every testfunction. - void updateScaleBar(); + void updateScaleBar(); // test text of scalebar after update. }; void TestQgsQuickScaleBarKit::updateScaleBar() { - QgsCoordinateReferenceSystem crsGPS = QgsQuickUtils::instance()->coordinateReferenceSystemFromEpsgId( 4326 ); + QgsCoordinateReferenceSystem crsGPS = QgsQuickUtils().coordinateReferenceSystemFromEpsgId( 4326 ); QVERIFY( crsGPS.authid() == "EPSG:4326" ); QgsRectangle extent = QgsRectangle( 49, 16, 50, 17 ); diff --git a/tests/src/quickgui/testqgsquickutils.cpp b/tests/src/quickgui/testqgsquickutils.cpp index 32ce0ec2af5e..dc7cfc6103e6 100644 --- a/tests/src/quickgui/testqgsquickutils.cpp +++ b/tests/src/quickgui/testqgsquickutils.cpp @@ -29,21 +29,91 @@ class TestQgsQuickUtils: public QObject void init() {} // will be called before each testfunction is executed. void cleanup() {} // will be called after every testfunction. + void screen_density(); + + void dump_screen_info(); + void crs_and_geometry(); + + void formatting(); + + private: + QgsQuickUtils utils; }; +void TestQgsQuickUtils::screen_density() +{ + qreal dp = utils.screenDensity(); + QVERIFY( ( dp > 0 ) && ( dp < 1000 ) ); +} + +void TestQgsQuickUtils::dump_screen_info() +{ + qreal dp = utils.screenDensity(); + QVERIFY( utils.dumpScreenInfo().contains( QStringLiteral( "%1" ).arg( dp ) ) ); +} + void TestQgsQuickUtils::crs_and_geometry() { - QgsCoordinateReferenceSystem crsGPS = QgsQuickUtils::instance()->coordinateReferenceSystemFromEpsgId( 4326 ); + QgsCoordinateReferenceSystem crs3857 = utils.coordinateReferenceSystemFromEpsgId( 3857 ); + QVERIFY( crs3857.authid() == "EPSG:3857" ); + + QgsCoordinateReferenceSystem crsGPS = utils.coordinateReferenceSystemFromEpsgId( 4326 ); QVERIFY( crsGPS.authid() == "EPSG:4326" ); + QgsPointXY pointXY = utils.pointXYFactory( 49.9, 16.3 ); + QVERIFY( pointXY.x() == 49.9 ); + QVERIFY( pointXY.y() == 16.3 ); + + QgsPoint point = utils.pointFactory( 1.0, -1.0 ); + QVERIFY( point.x() == 1.0 ); + QVERIFY( point.y() == -1.0 ); + + QgsPointXY transformedPoint = utils.transformPoint( crsGPS, + crs3857, + QgsCoordinateTransformContext(), + pointXY ); + QVERIFY( fabs( transformedPoint.x() - 5554843 ) < 1.0 ); + QVERIFY( fabs( transformedPoint.y() - 1839491 ) < 1.0 ); + QgsQuickMapSettings ms; ms.setDestinationCrs( crsGPS ); ms.setExtent( QgsRectangle( 49, 16, 50, 17 ) ); ms.setOutputSize( QSize( 1000, 500 ) ); - double sutm = QgsQuickUtils::instance()->screenUnitsToMeters( &ms, 1 ); + double sutm = utils.screenUnitsToMeters( &ms, 1 ); QVERIFY( fabs( sutm - 213 ) < 1.0 ); } +void TestQgsQuickUtils::formatting() +{ + QgsPoint point( -2.234521, 34.4444421 ); + QString point2str = utils.qgsPointToString( point, 3 ); + QVERIFY( point2str == "-2.235, 34.444" ); + + point2str = utils.qgsPointToString( point, 2 ); + QVERIFY( point2str == "-2.23, 34.44" ); + + point2str = utils.qgsPointToString( point, 1 ); + QVERIFY( point2str == "-2.2, 34.4" ); + + point2str = utils.qgsPointToString( point, 0 ); + QVERIFY( point2str == "-2, 34" ); + + QString dist2str = utils.distanceToString( 1222.234, 2 ); + QVERIFY( dist2str == "1.22 km" ); + + dist2str = utils.distanceToString( 1222.234, 1 ); + QVERIFY( dist2str == "1.2 km" ); + + dist2str = utils.distanceToString( 1222.234, 0 ); + QVERIFY( dist2str == "1 km" ); + + dist2str = utils.distanceToString( 700.22, 1 ); + QVERIFY( dist2str == "700.2 m" ); + + dist2str = utils.distanceToString( 0.22, 0 ); + QVERIFY( dist2str == "220 mm" ); +} + QGSTEST_MAIN( TestQgsQuickUtils ) #include "testqgsquickutils.moc" From 49558a01cdae354edcb5ecc059856e508afb6b6c Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Fri, 11 May 2018 16:19:19 +0200 Subject: [PATCH 05/11] next part of review changes --- doc/qgsquick.dox | 7 ++-- src/quickgui/plugin/qgsquickmessagelog.qml | 33 ++++++++++++++++--- src/quickgui/qgsquickmessagelogmodel.h | 7 +++- src/quickgui/qgsquickscalebarkit.h | 27 ++++++++------- src/quickgui/qgsquickutils.cpp | 5 --- src/quickgui/qgsquickutils.h | 5 --- .../src/quickgui/testqgsquickscalebarkit.cpp | 2 +- tests/src/quickgui/testqgsquickutils.cpp | 4 +-- 8 files changed, 58 insertions(+), 32 deletions(-) diff --git a/doc/qgsquick.dox b/doc/qgsquick.dox index 47d2d2437705..6a5e7acbd3de 100644 --- a/doc/qgsquick.dox +++ b/doc/qgsquick.dox @@ -13,12 +13,15 @@ QGIS Quick consists of a Qt plugin that provides the QML components and of a sha \subsection qgsquick_overview_widgets QML Classes \subsubsection qgsquick_overview_widgets_mapcanvas MapCanvas -Similarly to QgsMapCanvas, this component can be used for displaying GIS data on a canvas. More info about the QgsQuickMapCanvas qgsquickmapcanvas.h qgsquickmapcanvas.cpp. +Similarly to QgsMapCanvas, this component can be used for displaying GIS data on a canvas. See also QgsQuickMapCanvasMap. \subsubsection qgsquick_overview_widgets_scalebar ScaleBar -A QML component that shows the scale ratio between its length and distance on the MapCanvas. There are predefined rounded values for several zooming levels with 'm' or 'km' postfixes. After any zoom in/out event on canvas recalculates its properties and updates text on the ScaleBar. +A QML component that shows the scale ratio between its length and distance on the MapCanvas. There are predefined rounded values +for several zooming levels with 'm' or 'km' postfixes. After any zoom in/out event on canvas recalculates its properties and updates +text. See also QgsQuickScaleBarKit. \subsubsection qgsquick_overview_widgets_messagelog MessageLog A simple panel which can be used for publishing logs messages to a user such as basic information about the application or its status. +See also QgsQuickMessageLogModel. \section qgsquick_styling Styling diff --git a/src/quickgui/plugin/qgsquickmessagelog.qml b/src/quickgui/plugin/qgsquickmessagelog.qml index d666bf66901a..b207348f1357 100644 --- a/src/quickgui/plugin/qgsquickmessagelog.qml +++ b/src/quickgui/plugin/qgsquickmessagelog.qml @@ -17,20 +17,37 @@ import QtQuick.Controls 2.0 import QtQuick 2.5 import QgsQuick 0.1 as QgsQuick +/*! + \brief A component shows all log messages. +*/ Item { + /*! + MessageLogModel + */ property alias model: table.model + /*! + Background color. + */ property color bgColor: "white" + /*! + Separator color + */ property color separatorColor: "gray" + + /*! + Separator width + */ property int separatorSize: 1 * QgsQuick.Utils.dp + /*! + True if a new message is added to the list. + */ property bool unreadMessages: false id: item - Rectangle { - color: item.bgColor - anchors.fill: parent - } - + /*! + List containing message logs. + */ ListView { id: table anchors.fill: parent @@ -47,6 +64,9 @@ Item { wrapMode: Text.WordWrap } + /*! + Message separator + */ Rectangle { color: item.separatorColor height: item.separatorSize @@ -55,6 +75,9 @@ Item { } } + /*! + Handles adding new messages to the list. + */ Connections { target: model diff --git a/src/quickgui/qgsquickmessagelogmodel.h b/src/quickgui/qgsquickmessagelogmodel.h index 6a9160287f0c..8cb72823b796 100644 --- a/src/quickgui/qgsquickmessagelogmodel.h +++ b/src/quickgui/qgsquickmessagelogmodel.h @@ -59,20 +59,25 @@ class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel }; public: - //! Create new message log model + //! Create new message log model. QgsQuickMessageLogModel( QObject *parent = nullptr ); + //! Returns new struct created according params. LogMessage logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ); QHash roleNames() const override; + //! number of messages stored in model. int rowCount( const QModelIndex &parent ) const override; + + //! Returns message data from model according index and role. QVariant data( const QModelIndex &index, int role ) const override; private slots: void onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ); private: + //! Stores all messages. QVector mMessages; }; diff --git a/src/quickgui/qgsquickscalebarkit.h b/src/quickgui/qgsquickscalebarkit.h index 4b18f5edef9d..3a4e3ef334f6 100644 --- a/src/quickgui/qgsquickscalebarkit.h +++ b/src/quickgui/qgsquickscalebarkit.h @@ -46,7 +46,7 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject Q_OBJECT /** - * Associated map settings + * Associated map settings. Should be initialized before the first use from mapcanvas map settings. */ Q_PROPERTY( QgsQuickMapSettings *mapSettings MEMBER mMapSettings WRITE setMapSettings NOTIFY mapSettingsChanged ) @@ -61,7 +61,7 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject Q_PROPERTY( QString units READ units NOTIFY scaleBarChanged ) /** - * Distance rounded to "nice" number (e.g. 100, 20). To be used with units property for labels. Read-only (result) + * Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result) */ Q_PROPERTY( int distance READ distance NOTIFY scaleBarChanged ) @@ -76,46 +76,51 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject explicit QgsQuickScaleBarKit( QObject *parent = nullptr ); ~QgsQuickScaleBarKit() = default; - //! Set map settings + //! \copydoc QgsQuickScaleBarKit::mapSettings void setMapSettings( QgsQuickMapSettings *mapSettings ); - //! Returns calculated width in pixels + //! \copydoc QgsQuickScaleBarKit::width int width() const; /** - * Returns distance corensponding to width - * + * \copydoc QgsQuickScaleBarKit::units * \see QgsQuickScaleBarKit::units() */ int distance() const; /** - * Returns units of distance (m, km) - * + * \copydoc QgsQuickScaleBarKit::units * \see QgsQuickScaleBarKit::distance() */ QString units() const; signals: //! width, distance and/or units changed + //! \copydoc QgsQuickScaleBarKit::width + //! \copydoc QgsQuickScaleBarKit::distance + //! \copydoc QgsQuickScaleBarKit::units void scaleBarChanged(); - //! map settings changed + //! \copydoc QgsQuickScaleBarKit::mapSettings void mapSettingsChanged(); - //! preferred width changed + //! \copydoc QgsQuickScaleBarKit::preferredWidth void preferredWidthChanged(); public slots: - //! recalculate width, distance and units + //! recalculate width, distance and units. void updateScaleBar(); private: QgsQuickMapSettings *mMapSettings = nullptr; + //! \copydoc QgsQuickScaleBarKit::preferredWidth int mPreferredWidth; // pixels + //! \copydoc QgsQuickScaleBarKit::width int mWidth; // pixels + //! \copydoc QgsQuickScaleBarKit::distance int mDistance; // in meters or kilometers, rounded + //! \copydoc QgsQuickScaleBarKit::units QString mUnits; // km or m }; diff --git a/src/quickgui/qgsquickutils.cpp b/src/quickgui/qgsquickutils.cpp index f4144257ecd6..76571089aa21 100644 --- a/src/quickgui/qgsquickutils.cpp +++ b/src/quickgui/qgsquickutils.cpp @@ -33,11 +33,6 @@ QgsQuickUtils::QgsQuickUtils( QObject *parent ) { } -QgsCoordinateReferenceSystem QgsQuickUtils::coordinateReferenceSystemFromEpsgId( long epsg ) const -{ - return QgsCoordinateReferenceSystem::fromEpsgId( epsg ); -} - QgsPointXY QgsQuickUtils::pointXYFactory( double x, double y ) const { return QgsPointXY( x, y ); diff --git a/src/quickgui/qgsquickutils.h b/src/quickgui/qgsquickutils.h index 61331ad99d6b..f30823f060a8 100644 --- a/src/quickgui/qgsquickutils.h +++ b/src/quickgui/qgsquickutils.h @@ -66,11 +66,6 @@ class QUICK_EXPORT QgsQuickUtils: public QObject //! Calculated density of the screen - see "dp" property for more details qreal screenDensity() const; - /** - * Create crs from epsg code in QML - */ - Q_INVOKABLE QgsCoordinateReferenceSystem coordinateReferenceSystemFromEpsgId( long epsg ) const; - /** * Create QgsPointXY in QML */ diff --git a/tests/src/quickgui/testqgsquickscalebarkit.cpp b/tests/src/quickgui/testqgsquickscalebarkit.cpp index 7ee0c4b2b579..5c7ac8cd5829 100644 --- a/tests/src/quickgui/testqgsquickscalebarkit.cpp +++ b/tests/src/quickgui/testqgsquickscalebarkit.cpp @@ -37,7 +37,7 @@ class TestQgsQuickScaleBarKit: public QObject void TestQgsQuickScaleBarKit::updateScaleBar() { - QgsCoordinateReferenceSystem crsGPS = QgsQuickUtils().coordinateReferenceSystemFromEpsgId( 4326 ); + QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 ); QVERIFY( crsGPS.authid() == "EPSG:4326" ); QgsRectangle extent = QgsRectangle( 49, 16, 50, 17 ); diff --git a/tests/src/quickgui/testqgsquickutils.cpp b/tests/src/quickgui/testqgsquickutils.cpp index dc7cfc6103e6..eb552ee82624 100644 --- a/tests/src/quickgui/testqgsquickutils.cpp +++ b/tests/src/quickgui/testqgsquickutils.cpp @@ -55,10 +55,10 @@ void TestQgsQuickUtils::dump_screen_info() void TestQgsQuickUtils::crs_and_geometry() { - QgsCoordinateReferenceSystem crs3857 = utils.coordinateReferenceSystemFromEpsgId( 3857 ); + QgsCoordinateReferenceSystem crs3857 = QgsCoordinateReferenceSystem::fromEpsgId( 3857 ); QVERIFY( crs3857.authid() == "EPSG:3857" ); - QgsCoordinateReferenceSystem crsGPS = utils.coordinateReferenceSystemFromEpsgId( 4326 ); + QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 ); QVERIFY( crsGPS.authid() == "EPSG:4326" ); QgsPointXY pointXY = utils.pointXYFactory( 49.9, 16.3 ); From 92e4a4662dc1760aed6537adc6fedd607cba2873 Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Fri, 11 May 2018 16:42:29 +0200 Subject: [PATCH 06/11] formatted. --- src/quickgui/qgsquickscalebarkit.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/quickgui/qgsquickscalebarkit.h b/src/quickgui/qgsquickscalebarkit.h index 3a4e3ef334f6..8bd579a2ed26 100644 --- a/src/quickgui/qgsquickscalebarkit.h +++ b/src/quickgui/qgsquickscalebarkit.h @@ -51,17 +51,17 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject Q_PROPERTY( QgsQuickMapSettings *mapSettings MEMBER mMapSettings WRITE setMapSettings NOTIFY mapSettingsChanged ) /** - * Preferred width of scalebar in pixels. Defaults to 300 + * Preferred width of scalebar in pixels. Default set to 300. */ Q_PROPERTY( int preferredWidth MEMBER mPreferredWidth NOTIFY preferredWidthChanged ) /** - * Units of distance (e.g. km or m) Read-only (result) + * Units of distance (e.g. km or m) Read-only (result). */ Q_PROPERTY( QString units READ units NOTIFY scaleBarChanged ) /** - * Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result) + * Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result). */ Q_PROPERTY( int distance READ distance NOTIFY scaleBarChanged ) @@ -94,11 +94,16 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject */ QString units() const; + QgsQuickUtils utils() const; + signals: - //! width, distance and/or units changed - //! \copydoc QgsQuickScaleBarKit::width - //! \copydoc QgsQuickScaleBarKit::distance - //! \copydoc QgsQuickScaleBarKit::units + + /** + * width, distance and/or units changed + * \copydoc QgsQuickScaleBarKit::width + * \copydoc QgsQuickScaleBarKit::distance + * \copydoc QgsQuickScaleBarKit::units + */ void scaleBarChanged(); //! \copydoc QgsQuickScaleBarKit::mapSettings @@ -122,6 +127,8 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject int mDistance; // in meters or kilometers, rounded //! \copydoc QgsQuickScaleBarKit::units QString mUnits; // km or m + + QgsQuickUtils mUtils; }; From e3ae4203ddc08c8142093f8630cbaf5f6de78976 Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Fri, 11 May 2018 16:42:45 +0200 Subject: [PATCH 07/11] formatted --- src/quickgui/qgsquickscalebarkit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quickgui/qgsquickscalebarkit.h b/src/quickgui/qgsquickscalebarkit.h index 8bd579a2ed26..d4205be9aa7a 100644 --- a/src/quickgui/qgsquickscalebarkit.h +++ b/src/quickgui/qgsquickscalebarkit.h @@ -96,7 +96,7 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject QgsQuickUtils utils() const; -signals: + signals: /** * width, distance and/or units changed From 7ab8214f32cc9156cc501389103e30255204d159 Mon Sep 17 00:00:00 2001 From: "viktor.sklencar@lutraconsulting.co.uk" Date: Fri, 11 May 2018 18:06:30 +0200 Subject: [PATCH 08/11] comment style changed to doxygen style --- src/quickgui/plugin/qgsquickmessagelog.qml | 54 +++++++++---------- src/quickgui/plugin/qgsquickscalebar.qml | 62 +++++++++++----------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/quickgui/plugin/qgsquickmessagelog.qml b/src/quickgui/plugin/qgsquickmessagelog.qml index b207348f1357..dc5e6fa5a574 100644 --- a/src/quickgui/plugin/qgsquickmessagelog.qml +++ b/src/quickgui/plugin/qgsquickmessagelog.qml @@ -17,37 +17,37 @@ import QtQuick.Controls 2.0 import QtQuick 2.5 import QgsQuick 0.1 as QgsQuick -/*! - \brief A component shows all log messages. -*/ +/** + * \brief A component shows all log messages. + */ Item { - /*! - MessageLogModel - */ + /** + * MessageLogModel. + */ property alias model: table.model - /*! - Background color. - */ + /** + *Background color. + */ property color bgColor: "white" - /*! - Separator color - */ + /** + * Separator color. + */ property color separatorColor: "gray" - /*! - Separator width - */ + /** + * Separator width. + */ property int separatorSize: 1 * QgsQuick.Utils.dp - /*! - True if a new message is added to the list. - */ + /** + * True if a new message is added to the list. + */ property bool unreadMessages: false id: item - /*! - List containing message logs. - */ + /** + * List containing message logs. + */ ListView { id: table anchors.fill: parent @@ -64,9 +64,9 @@ Item { wrapMode: Text.WordWrap } - /*! - Message separator - */ + /** + * Message separator. + */ Rectangle { color: item.separatorColor height: item.separatorSize @@ -75,9 +75,9 @@ Item { } } - /*! - Handles adding new messages to the list. - */ + /** + * Handles adding new messages to the list. + */ Connections { target: model diff --git a/src/quickgui/plugin/qgsquickscalebar.qml b/src/quickgui/plugin/qgsquickscalebar.qml index d408bc194b23..7261058dc1bd 100644 --- a/src/quickgui/plugin/qgsquickscalebar.qml +++ b/src/quickgui/plugin/qgsquickscalebar.qml @@ -16,53 +16,53 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import QgsQuick 0.1 as QgsQuick -/*! - \qmltype ScaleBar - \brief A component that shows scale ratio between its length and distance on the MapCanvas -*/ +/** + * \qmltype ScaleBar + * \brief A component that shows scale ratio between its length and distance on the MapCanvas + */ Item { id: scaleBar property alias mapSettings: scaleBarKit.mapSettings - /*! - Preferred width of scalebar in pixels. Defaults set to 300. - */ + /** + * Preferred width of scalebar in pixels. Defaults set to 300. + */ property alias preferredWidth: scaleBarKit.preferredWidth - /*! - * Utility used for Scalebar properties. - */ + /** + * Utility used for Scalebar properties. + */ property QgsQuick.ScaleBarKit scaleBarKit: QgsQuick.ScaleBarKit {id: scaleBarKit} - /*! - Reserved text width. - */ + /** + * Reserved text width. + */ property int textWidth: fontMetrics.averageCharacterWidth * 8 - /*! - Opacity of ScaleBar. - */ + /** + * Opacity of ScaleBar. + */ property color barColor: "white" - /*! - Background color of scaleBar. - */ + /** + * Background color of scaleBar. + */ property color barBackgroundColor: "grey" - /*! - Opacity of ScaleBar. - */ + /** + * Opacity of ScaleBar. + */ property double barOpacity: 0.8 - /*! - Defines text shown on ScaleBar. - */ + /** + * Defines text shown on ScaleBar. + */ property string barText: scaleBarKit.distance + " " + scaleBarKit.units - /*! - Returns calculated width in pixels. - */ + /** + * Returns calculated width in pixels. + */ property int barWidth: scaleBarKit.width property int lineWidth: 5 * QgsQuick.Utils.dp - /*! - The real width of the component. - */ + /** + * The real width of the component. + */ width: textWidth + barWidth MouseArea { From 9fd48a2763340215e1f5f868ae750e6f907364ea Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Mon, 14 May 2018 11:14:33 +0200 Subject: [PATCH 09/11] some final tweaks --- src/quickgui/plugin/CMakeLists.txt | 3 +- src/quickgui/plugin/qgsquickmessagelog.qml | 24 ++- src/quickgui/plugin/qgsquickplugin.cpp | 4 +- src/quickgui/plugin/qgsquickscalebar.qml | 208 +++++++++++---------- src/quickgui/qgsquickmessagelogmodel.h | 24 +-- src/quickgui/qgsquickscalebarkit.cpp | 6 +- src/quickgui/qgsquickscalebarkit.h | 36 ++-- tests/src/quickgui/app/main.qml | 3 +- 8 files changed, 151 insertions(+), 157 deletions(-) diff --git a/src/quickgui/plugin/CMakeLists.txt b/src/quickgui/plugin/CMakeLists.txt index 5d4ba8e328f5..4513599577a1 100644 --- a/src/quickgui/plugin/CMakeLists.txt +++ b/src/quickgui/plugin/CMakeLists.txt @@ -100,13 +100,14 @@ IF(QMLPLUGINDUMP_FOUND) # Extract QML Types Info from our QML plugin. This is useful for development with Qt Creator as it allows # Qt Creator understand also the C++ classes registered in the plugin and thus available in QML code SET(QGIS_QUICK_PLUGIN_TYPEINFO ${QGIS_QUICK_PLUGIN_RUNTIME_DIR}/qgsquick.qmltypes) + SET(QGIS_QUICK_VERSION 0.1) ADD_CUSTOM_COMMAND( TARGET qgis_quick_plugin COMMAND ${CMAKE_COMMAND} -E make_directory ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${CMAKE_COMMAND} -E copy $ ${QGIS_QUICK_TYPEINFO_GENERATE_DIR} COMMAND ${QMLPLUGINDUMP_EXECUTABLE} - ARGS QgsQuick 0.1 . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO} + ARGS QgsQuick ${QGIS_QUICK_VERSION} . -v --output ${QGIS_QUICK_PLUGIN_TYPEINFO} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" POST_BUILD ) diff --git a/src/quickgui/plugin/qgsquickmessagelog.qml b/src/quickgui/plugin/qgsquickmessagelog.qml index dc5e6fa5a574..536550897d24 100644 --- a/src/quickgui/plugin/qgsquickmessagelog.qml +++ b/src/quickgui/plugin/qgsquickmessagelog.qml @@ -12,41 +12,45 @@ * (at your option) any later version. * * * ***************************************************************************/ - import QtQuick.Controls 2.0 import QtQuick 2.5 import QgsQuick 0.1 as QgsQuick + /** - * \brief A component shows all log messages. + * \brief A component that shows all log messages. The component shows + * the items from QgsQuickMessageLogModel. */ Item { /** - * MessageLogModel. + * Input for messages. Must be connected before usage from QgsQuick.MessageLog. + * + * See also QgsQuickMessageLogModel */ property alias model: table.model /** - *Background color. + * Background color */ property color bgColor: "white" /** - * Separator color. + * Separator color */ property color separatorColor: "gray" /** - * Separator width. + * Separator width */ property int separatorSize: 1 * QgsQuick.Utils.dp /** - * True if a new message is added to the list. + * True if there are unread messages in the list. All messages + * are marked read when the widget receives visibility. */ property bool unreadMessages: false id: item /** - * List containing message logs. + * List containing message logs */ ListView { id: table @@ -82,13 +86,13 @@ Item { target: model onRowsInserted: { - if ( !visible ) + if (!visible) unreadMessages = true } } onVisibleChanged: { - if ( visible ) + if (visible) unreadMessages = false } } diff --git a/src/quickgui/plugin/qgsquickplugin.cpp b/src/quickgui/plugin/qgsquickplugin.cpp index c4f01e8af926..4e38ee1125e1 100644 --- a/src/quickgui/plugin/qgsquickplugin.cpp +++ b/src/quickgui/plugin/qgsquickplugin.cpp @@ -63,7 +63,7 @@ void QgsQuickPlugin::registerTypes( const char *uri ) qmlRegisterSingletonType< QgsQuickUtils >( uri, 0, 1, "Utils", _utilsProvider ); - qmlRegisterUncreatableType< QgsRelationManager >( uri, 0, 1, "RelationManager", "The relation manager is available from the Project. Try `qgisProject.relationManager`" ); - qmlRegisterUncreatableType< QgsMessageLog >( uri, 0, 1, "QgsMessageLog", "Expose MessageLevel" ); + //qmlRegisterUncreatableType< QgsRelationManager >( uri, 0, 1, "RelationManager", "The relation manager is available from the Project. Try `qgisProject.relationManager`" ); + //qmlRegisterUncreatableType< QgsMessageLog >( uri, 0, 1, "QgsMessageLog", "Expose MessageLevel" ); } diff --git a/src/quickgui/plugin/qgsquickscalebar.qml b/src/quickgui/plugin/qgsquickscalebar.qml index 7261058dc1bd..f5468e538d86 100644 --- a/src/quickgui/plugin/qgsquickscalebar.qml +++ b/src/quickgui/plugin/qgsquickscalebar.qml @@ -16,120 +16,126 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import QgsQuick 0.1 as QgsQuick -/** - * \qmltype ScaleBar - * \brief A component that shows scale ratio between its length and distance on the MapCanvas - */ Item { - id: scaleBar - property alias mapSettings: scaleBarKit.mapSettings - /** - * Preferred width of scalebar in pixels. Defaults set to 300. - */ - property alias preferredWidth: scaleBarKit.preferredWidth - /** - * Utility used for Scalebar properties. - */ - property QgsQuick.ScaleBarKit scaleBarKit: QgsQuick.ScaleBarKit {id: scaleBarKit} + id: scaleBar + /** + * The mapSettings property contains configuration for rendering of the map. + * + * Must be connected before usage from QgsQuick.MapCanvas::mapSettings + */ + property alias mapSettings: scaleBarKit.mapSettings + /** + * Preferred width of scalebar in pixels on the screen. Defaults set to 300. + * + * barWidth is calculated to be close to preferred width, but has "nice" textual + * representation + */ + property alias preferredWidth: scaleBarKit.preferredWidth + /** + * Kit for all calculation of width and text of the scalebar + * + * See also QgsQuickMapCanvasMap::mapSettings + */ + property QgsQuick.ScaleBarKit scaleBarKit: QgsQuick.ScaleBarKit { + id: scaleBarKit + } + /** + * Reserved text width. + */ + property int textWidth: fontMetrics.averageCharacterWidth * 8 + /** + * Text color + */ + property color barColor: "white" + /** + * Background color + */ + property color barBackgroundColor: "grey" + /** + * Opacity + */ + property double barOpacity: 0.8 + /** + * Textual representation of the bar length (e.g 800 m) + */ + property string barText: scaleBarKit.distance + " " + scaleBarKit.units + /** + * Calculated width of bar in pixels + */ + property int barWidth: scaleBarKit.width + /** + * Size of scalebar line (height of bar) + */ + property int lineWidth: 5 * QgsQuick.Utils.dp - /** - * Reserved text width. - */ - property int textWidth: fontMetrics.averageCharacterWidth * 8 - /** - * Opacity of ScaleBar. - */ - property color barColor: "white" - /** - * Background color of scaleBar. - */ - property color barBackgroundColor: "grey" - /** - * Opacity of ScaleBar. - */ - property double barOpacity: 0.8 - /** - * Defines text shown on ScaleBar. - */ - property string barText: scaleBarKit.distance + " " + scaleBarKit.units + width: textWidth + barWidth - /** - * Returns calculated width in pixels. - */ - property int barWidth: scaleBarKit.width - property int lineWidth: 5 * QgsQuick.Utils.dp + MouseArea { + anchors.fill: background + onClicked: { + animation.restart() + } + } - /** - * The real width of the component. - */ - width: textWidth + barWidth + NumberAnimation { + id: animation + target: scaleBar + property: "barWidth" + to: 200 + duration: 1000 + } - MouseArea { - anchors.fill: background - onClicked: { - animation.restart() - } - } + Rectangle { + id: background + color: scaleBar.barBackgroundColor + opacity: scaleBar.barOpacity + width: parent.width + height: parent.height + } + + FontMetrics { + id: fontMetrics + font: text.font + } - NumberAnimation { - id: animation - target: scaleBar - property: "barWidth" - to: 200 - duration: 1000 + Row { + opacity: 1 + spacing: 0 + + Text { + id: text + width: textWidth + height: scaleBar.height + text: barText + color: barColor + font.pixelSize: scaleBar.height - 2 * scaleBar.lineWidth + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter } Rectangle { - id: background - color: scaleBar.barBackgroundColor - opacity: scaleBar.barOpacity - width: parent.width - height: parent.height + id: leftBar + width: scaleBar.lineWidth + height: scaleBar.height - 20 * QgsQuick.Utils.dp + y: (scaleBar.height - leftBar.height) / 2 + color: barColor + opacity: 1 } - FontMetrics { - id: fontMetrics - font: text.font + Rectangle { + width: scaleBar.width - text.width - 15 * QgsQuick.Utils.dp + height: scaleBar.lineWidth + y: (scaleBar.height - scaleBar.lineWidth) / 2 + color: barColor } - Row { - opacity: 1 - spacing: 0 - - Text { - id: text - width: textWidth - height: scaleBar.height - text: barText - color: barColor - font.pixelSize: scaleBar.height - 2 * scaleBar.lineWidth - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - - Rectangle { - id: leftBar - width: scaleBar.lineWidth - height: scaleBar.height - 20 * QgsQuick.Utils.dp - y: (scaleBar.height - leftBar.height) / 2 - color: barColor - opacity: 1 - } - - Rectangle { - width: scaleBar.width - text.width - 15 * QgsQuick.Utils.dp - height: scaleBar.lineWidth - y: (scaleBar.height - scaleBar.lineWidth) / 2 - color: barColor - } - - Rectangle { - id: rightBar - width: scaleBar.lineWidth - height: scaleBar.height - 20 * QgsQuick.Utils.dp - y: (scaleBar.height - leftBar.height) / 2 - color: barColor - } + Rectangle { + id: rightBar + width: scaleBar.lineWidth + height: scaleBar.height - 20 * QgsQuick.Utils.dp + y: (scaleBar.height - leftBar.height) / 2 + color: barColor } + } } diff --git a/src/quickgui/qgsquickmessagelogmodel.h b/src/quickgui/qgsquickmessagelogmodel.h index 8cb72823b796..4b684568455f 100644 --- a/src/quickgui/qgsquickmessagelogmodel.h +++ b/src/quickgui/qgsquickmessagelogmodel.h @@ -17,9 +17,7 @@ #define QGSQUICKMESSAGELOGMODEL_H #include -#include #include -#include #include #include "qgis.h" @@ -30,12 +28,14 @@ /** * \ingroup quick * - * This model will connect to the QgsMessageLog and publish any - * messages received from there. Can be used as a model for QListView, - * for example QgsQuick MessageLog class. + * This model will connect to the QgsMessageLog singleton and store any + * messages received. Can be used as a model for QListView, + * for example QgsQuick.MessageLog (QML only) * * \note QML Type: MessageLogModel * + * \sa QgsMessageLog + * * \since QGIS 3.2 */ class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel @@ -59,25 +59,21 @@ class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel }; public: - //! Create new message log model. + //! Create new message log model QgsQuickMessageLogModel( QObject *parent = nullptr ); - //! Returns new struct created according params. - LogMessage logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ); - QHash roleNames() const override; - - //! number of messages stored in model. int rowCount( const QModelIndex &parent ) const override; - - //! Returns message data from model according index and role. QVariant data( const QModelIndex &index, int role ) const override; private slots: void onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ); private: - //! Stores all messages. + //! LogMessage factory + LogMessage logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level ); + + //! Storage of all messages. QVector mMessages; }; diff --git a/src/quickgui/qgsquickscalebarkit.cpp b/src/quickgui/qgsquickscalebarkit.cpp index ccd4b02c496a..4d646c94bbe2 100644 --- a/src/quickgui/qgsquickscalebarkit.cpp +++ b/src/quickgui/qgsquickscalebarkit.cpp @@ -96,7 +96,7 @@ void QgsQuickScaleBarKit::updateScaleBar() // we want to show nice round distances e.g. 200 km instead of e.g. 273 km // so we determine which "nice" number to use and also update the scale bar // length accordingly. First digit will be 1, 2 or 5, the rest will be zeroes. - int digits = floor( log10( ( dist ) ) ); // number of digits after first one + int digits = int( floor( log10( ( dist ) ) ) ); // number of digits after first one double base = pow( 10, digits ); // e.g. for 1234 this will be 1000 double first_digit = dist / base; // get the first digit int round_digit; @@ -107,8 +107,8 @@ void QgsQuickScaleBarKit::updateScaleBar() else round_digit = 5; - mDistance = round_digit * base; - mWidth = mPreferredWidth * mDistance / dist; + mDistance = int( round_digit * base ); + mWidth = int( mPreferredWidth * mDistance / dist ); emit scaleBarChanged(); } diff --git a/src/quickgui/qgsquickscalebarkit.h b/src/quickgui/qgsquickscalebarkit.h index d4205be9aa7a..6fd6751b62ac 100644 --- a/src/quickgui/qgsquickscalebarkit.h +++ b/src/quickgui/qgsquickscalebarkit.h @@ -46,29 +46,29 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject Q_OBJECT /** - * Associated map settings. Should be initialized before the first use from mapcanvas map settings. - */ + * Associated map settings. Should be initialized before the first use from mapcanvas map settings. + */ Q_PROPERTY( QgsQuickMapSettings *mapSettings MEMBER mMapSettings WRITE setMapSettings NOTIFY mapSettingsChanged ) /** - * Preferred width of scalebar in pixels. Default set to 300. - */ + * Preferred width of scalebar in pixels. Default set to 300. + */ Q_PROPERTY( int preferredWidth MEMBER mPreferredWidth NOTIFY preferredWidthChanged ) /** - * Units of distance (e.g. km or m) Read-only (result). - */ + * Units of distance (e.g. km or m) Read-only (result). + */ Q_PROPERTY( QString units READ units NOTIFY scaleBarChanged ) /** - * Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result). - */ + * Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result). + */ Q_PROPERTY( int distance READ distance NOTIFY scaleBarChanged ) /** - * Calculated width of scalebar in pixels representing distance + units. Differs minimum possible from preferredWidth to - * get "nice" distance number. - */ + * Calculated width of scalebar in pixels representing distance + units. Differs minimum possible from preferredWidth to + * get "nice" distance number. + */ Q_PROPERTY( int width READ width NOTIFY scaleBarChanged ) public: @@ -94,15 +94,10 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject */ QString units() const; - QgsQuickUtils utils() const; - signals: /** * width, distance and/or units changed - * \copydoc QgsQuickScaleBarKit::width - * \copydoc QgsQuickScaleBarKit::distance - * \copydoc QgsQuickScaleBarKit::units */ void scaleBarChanged(); @@ -117,18 +112,11 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject void updateScaleBar(); private: - QgsQuickMapSettings *mMapSettings = nullptr; - - //! \copydoc QgsQuickScaleBarKit::preferredWidth + QgsQuickMapSettings *mMapSettings = nullptr; // not owned int mPreferredWidth; // pixels - //! \copydoc QgsQuickScaleBarKit::width int mWidth; // pixels - //! \copydoc QgsQuickScaleBarKit::distance int mDistance; // in meters or kilometers, rounded - //! \copydoc QgsQuickScaleBarKit::units QString mUnits; // km or m - - QgsQuickUtils mUtils; }; diff --git a/tests/src/quickgui/app/main.qml b/tests/src/quickgui/app/main.qml index bb89ea82e50d..c29f5a320975 100644 --- a/tests/src/quickgui/app/main.qml +++ b/tests/src/quickgui/app/main.qml @@ -43,11 +43,10 @@ ApplicationWindow { visible: true modal: true interactive: true - dragMargin: 0 // prevents opening the drawer by dragging. height: window.height width: QgsQuick.Utils.dp * 700 edge: Qt.RightEdge - z: 2 // make sure items from here are on top of the Z-order + z: 2 // make sure items from here are on top of the Z-order background: Rectangle { color: "white" From 96812749c128d7b24b0ace520b178ec3207832e0 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Mon, 14 May 2018 11:30:55 +0200 Subject: [PATCH 10/11] remove unused functions --- src/quickgui/qgsquickutils.cpp | 66 ------------------------ src/quickgui/qgsquickutils.h | 40 +------------- tests/src/quickgui/testqgsquickutils.cpp | 57 +------------------- 3 files changed, 4 insertions(+), 159 deletions(-) diff --git a/src/quickgui/qgsquickutils.cpp b/src/quickgui/qgsquickutils.cpp index 76571089aa21..7ad60f6d4783 100644 --- a/src/quickgui/qgsquickutils.cpp +++ b/src/quickgui/qgsquickutils.cpp @@ -16,11 +16,8 @@ #include #include "qgis.h" -#include "qgscoordinatereferencesystem.h" -#include "qgscoordinatetransform.h" #include "qgsdistancearea.h" #include "qgslogger.h" -#include "qgsvectorlayer.h" #include "qgsquickmapsettings.h" #include "qgsquickutils.h" @@ -33,31 +30,6 @@ QgsQuickUtils::QgsQuickUtils( QObject *parent ) { } -QgsPointXY QgsQuickUtils::pointXYFactory( double x, double y ) const -{ - return QgsPointXY( x, y ); -} - -QgsPoint QgsQuickUtils::pointFactory( double x, double y ) const -{ - return QgsPoint( x, y ); -} - -QgsPoint QgsQuickUtils::coordinateToPoint( const QGeoCoordinate &coor ) const -{ - return QgsPoint( coor.longitude(), coor.latitude(), coor.altitude() ); -} - -QgsPointXY QgsQuickUtils::transformPoint( const QgsCoordinateReferenceSystem &srcCrs, - const QgsCoordinateReferenceSystem &destCrs, - const QgsCoordinateTransformContext &context, - const QgsPointXY &srcPoint ) const -{ - QgsCoordinateTransform mTransform( srcCrs, destCrs, context ); - QgsPointXY pt = mTransform.transform( srcPoint ); - return pt; -} - double QgsQuickUtils::screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const { if ( mapSettings == nullptr ) return 0.0; @@ -80,44 +52,6 @@ void QgsQuickUtils::logMessage( const QString &message, const QString &tag, Qgis QgsMessageLog::logMessage( message, tag, level ); } -QString QgsQuickUtils::qgsPointToString( const QgsPoint &point, int decimals ) -{ - QString label; - label += QString::number( point.x(), 'f', decimals ); - label += ", "; - label += QString::number( point.y(), 'f', decimals ); - return label; -} - -QString QgsQuickUtils::distanceToString( qreal dist, int decimals ) -{ - if ( dist < 0 ) - { - return "0 m"; - } - - QString label; - if ( dist > 1000 ) - { - label += QString::number( dist / 1000.0, 'f', decimals ); - label += QString( " km" ); - } - else - { - if ( dist > 1 ) - { - label += QString::number( dist, 'f', decimals ); - label += QString( " m" ); - } - else - { - label += QString::number( dist * 1000, 'f', decimals ); - label += QString( " mm" ); - } - } - return label; -} - QString QgsQuickUtils::dumpScreenInfo() const { QRect rec = QApplication::desktop()->screenGeometry(); diff --git a/src/quickgui/qgsquickutils.h b/src/quickgui/qgsquickutils.h index f30823f060a8..b17b162a2ef1 100644 --- a/src/quickgui/qgsquickutils.h +++ b/src/quickgui/qgsquickutils.h @@ -19,12 +19,9 @@ #include #include -#include #include "qgis.h" #include "qgsmessagelog.h" -#include "qgspoint.h" -#include "qgspointxy.h" #include "qgsquickmapsettings.h" #include "qgis_quick.h" @@ -63,52 +60,19 @@ class QUICK_EXPORT QgsQuickUtils: public QObject //! dtor ~QgsQuickUtils() = default; - //! Calculated density of the screen - see "dp" property for more details + //! \copydoc QgsQuickUtils::dp qreal screenDensity() const; - /** - * Create QgsPointXY in QML - */ - Q_INVOKABLE QgsPointXY pointXYFactory( double x, double y ) const; - - /** - * Create QgsPoint in QML - */ - Q_INVOKABLE QgsPoint pointFactory( double x, double y ) const; - - /** - * Convert QGeoCoordinate to QgsPoint - */ - Q_INVOKABLE QgsPoint coordinateToPoint( const QGeoCoordinate &coor ) const; - - /** - * Transform point between different crs from QML - */ - Q_INVOKABLE QgsPointXY transformPoint( const QgsCoordinateReferenceSystem &srcCrs, - const QgsCoordinateReferenceSystem &destCrs, - const QgsCoordinateTransformContext &context, - const QgsPointXY &srcPoint ) const; - /** * Calculate the distance in meter representing baseLengthPixels pixels on the screen based on the current map settings. */ Q_INVOKABLE double screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const; -//! Log message in QgsMessageLog + //! Log message in QgsMessageLog Q_INVOKABLE void logMessage( const QString &message, const QString &tag = QString( "QgsQuick" ), Qgis::MessageLevel level = Qgis::Warning ); - /** - * point to string, e.g. -2.234521, 34.4444421 -> -2.234, 34.444 - */ - Q_INVOKABLE QString qgsPointToString( const QgsPoint &point, int decimals = 3 ); - - /** - * distance in meters to human readable length e.g. 1222.234 m -> 1.2 km - */ - Q_INVOKABLE QString distanceToString( qreal dist, int decimals = 1 ); - /** * Returns a string with information about screen size and resolution * diff --git a/tests/src/quickgui/testqgsquickutils.cpp b/tests/src/quickgui/testqgsquickutils.cpp index eb552ee82624..845a8e11e5ed 100644 --- a/tests/src/quickgui/testqgsquickutils.cpp +++ b/tests/src/quickgui/testqgsquickutils.cpp @@ -30,12 +30,8 @@ class TestQgsQuickUtils: public QObject void cleanup() {} // will be called after every testfunction. void screen_density(); - void dump_screen_info(); - - void crs_and_geometry(); - - void formatting(); + void screenUnitsToMeters(); private: QgsQuickUtils utils; @@ -53,29 +49,11 @@ void TestQgsQuickUtils::dump_screen_info() QVERIFY( utils.dumpScreenInfo().contains( QStringLiteral( "%1" ).arg( dp ) ) ); } -void TestQgsQuickUtils::crs_and_geometry() +void TestQgsQuickUtils::screenUnitsToMeters() { - QgsCoordinateReferenceSystem crs3857 = QgsCoordinateReferenceSystem::fromEpsgId( 3857 ); - QVERIFY( crs3857.authid() == "EPSG:3857" ); - QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 ); QVERIFY( crsGPS.authid() == "EPSG:4326" ); - QgsPointXY pointXY = utils.pointXYFactory( 49.9, 16.3 ); - QVERIFY( pointXY.x() == 49.9 ); - QVERIFY( pointXY.y() == 16.3 ); - - QgsPoint point = utils.pointFactory( 1.0, -1.0 ); - QVERIFY( point.x() == 1.0 ); - QVERIFY( point.y() == -1.0 ); - - QgsPointXY transformedPoint = utils.transformPoint( crsGPS, - crs3857, - QgsCoordinateTransformContext(), - pointXY ); - QVERIFY( fabs( transformedPoint.x() - 5554843 ) < 1.0 ); - QVERIFY( fabs( transformedPoint.y() - 1839491 ) < 1.0 ); - QgsQuickMapSettings ms; ms.setDestinationCrs( crsGPS ); ms.setExtent( QgsRectangle( 49, 16, 50, 17 ) ); @@ -84,36 +62,5 @@ void TestQgsQuickUtils::crs_and_geometry() QVERIFY( fabs( sutm - 213 ) < 1.0 ); } -void TestQgsQuickUtils::formatting() -{ - QgsPoint point( -2.234521, 34.4444421 ); - QString point2str = utils.qgsPointToString( point, 3 ); - QVERIFY( point2str == "-2.235, 34.444" ); - - point2str = utils.qgsPointToString( point, 2 ); - QVERIFY( point2str == "-2.23, 34.44" ); - - point2str = utils.qgsPointToString( point, 1 ); - QVERIFY( point2str == "-2.2, 34.4" ); - - point2str = utils.qgsPointToString( point, 0 ); - QVERIFY( point2str == "-2, 34" ); - - QString dist2str = utils.distanceToString( 1222.234, 2 ); - QVERIFY( dist2str == "1.22 km" ); - - dist2str = utils.distanceToString( 1222.234, 1 ); - QVERIFY( dist2str == "1.2 km" ); - - dist2str = utils.distanceToString( 1222.234, 0 ); - QVERIFY( dist2str == "1 km" ); - - dist2str = utils.distanceToString( 700.22, 1 ); - QVERIFY( dist2str == "700.2 m" ); - - dist2str = utils.distanceToString( 0.22, 0 ); - QVERIFY( dist2str == "220 mm" ); -} - QGSTEST_MAIN( TestQgsQuickUtils ) #include "testqgsquickutils.moc" From fdbbc997bc9ab363c68f0c828e07a38aa698b2e3 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Mon, 14 May 2018 11:31:22 +0200 Subject: [PATCH 11/11] remove unused functions --- tests/src/quickgui/testqgsquickutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/quickgui/testqgsquickutils.cpp b/tests/src/quickgui/testqgsquickutils.cpp index 845a8e11e5ed..425545ea0dc0 100644 --- a/tests/src/quickgui/testqgsquickutils.cpp +++ b/tests/src/quickgui/testqgsquickutils.cpp @@ -33,7 +33,7 @@ class TestQgsQuickUtils: public QObject void dump_screen_info(); void screenUnitsToMeters(); - private: + private: QgsQuickUtils utils; };