Add "install grid" button to coordinate operation widget when a grid is missing

This syncs the coordinate operation widget UX with other grid-related handling
widgets, where a user-friendly option to install a grid file is presented
This commit is contained in:
Nyall Dawson 2020-02-04 12:50:40 +10:00
parent fac99702b4
commit 941f59f045
7 changed files with 123 additions and 20 deletions

View File

@ -53,7 +53,6 @@ SET(QGIS_APP_SRCS
qgssourcefieldsproperties.cpp qgssourcefieldsproperties.cpp
qgsattributesformproperties.cpp qgsattributesformproperties.cpp
qgsidentifyresultsdialog.cpp qgsidentifyresultsdialog.cpp
qgsinstallgridshiftdialog.cpp
qgsfeatureaction.cpp qgsfeatureaction.cpp
qgslayercapabilitiesmodel.cpp qgslayercapabilitiesmodel.cpp
qgslayertreeviewindicatorprovider.cpp qgslayertreeviewindicatorprovider.cpp

View File

@ -357,6 +357,7 @@ SET(QGIS_GUI_SRCS
qgshistogramwidget.cpp qgshistogramwidget.cpp
qgshelp.cpp qgshelp.cpp
qgsidentifymenu.cpp qgsidentifymenu.cpp
qgsinstallgridshiftdialog.cpp
qgskeyvaluewidget.cpp qgskeyvaluewidget.cpp
qgslistwidget.cpp qgslistwidget.cpp
qgslegendfilterbutton.cpp qgslegendfilterbutton.cpp
@ -561,6 +562,7 @@ SET(QGIS_GUI_HDRS
qgshighlightablecombobox.h qgshighlightablecombobox.h
qgshistogramwidget.h qgshistogramwidget.h
qgsidentifymenu.h qgsidentifymenu.h
qgsinstallgridshiftdialog.h
qgskeyvaluewidget.h qgskeyvaluewidget.h
qgslegendfilterbutton.h qgslegendfilterbutton.h
qgslimitedrandomcolorrampdialog.h qgslimitedrandomcolorrampdialog.h

View File

@ -24,6 +24,7 @@
#include "qgsguiutils.h" #include "qgsguiutils.h"
#include "qgsgui.h" #include "qgsgui.h"
#include "qgshelp.h" #include "qgshelp.h"
#include "qgsinstallgridshiftdialog.h"
#include <QDir> #include <QDir>
#include <QPushButton> #include <QPushButton>
@ -40,8 +41,10 @@ QgsCoordinateOperationWidget::QgsCoordinateOperationWidget( QWidget *parent )
mLabelSrcDescription->setTextInteractionFlags( Qt::TextBrowserInteraction ); mLabelSrcDescription->setTextInteractionFlags( Qt::TextBrowserInteraction );
mLabelSrcDescription->setOpenExternalLinks( true ); mLabelSrcDescription->setOpenExternalLinks( true );
mInstallGridButton->hide();
#if PROJ_VERSION_MAJOR>=6 #if PROJ_VERSION_MAJOR>=6
connect( mInstallGridButton, &QPushButton::clicked, this, &QgsCoordinateOperationWidget::installGrid );
mCoordinateOperationTableWidget->setColumnCount( 3 ); mCoordinateOperationTableWidget->setColumnCount( 3 );
#else #else
mCoordinateOperationTableWidget->setColumnCount( 2 ); mCoordinateOperationTableWidget->setColumnCount( 2 );
@ -201,10 +204,17 @@ void QgsCoordinateOperationWidget::loadAvailableOperations()
if ( !transform.isAvailable ) if ( !transform.isAvailable )
{ {
QStringList gridMessages; QStringList gridMessages;
QStringList missingGrids;
QStringList missingGridPackages;
QStringList missingGridUrls;
for ( const QgsDatumTransform::GridDetails &grid : transform.grids ) for ( const QgsDatumTransform::GridDetails &grid : transform.grids )
{ {
if ( !grid.isAvailable ) if ( !grid.isAvailable )
{ {
missingGrids << grid.shortName;
missingGridPackages << grid.packageName;
missingGridUrls << grid.url;
QString m = tr( "This transformation requires the grid file “%1”, which is not available for use on the system." ).arg( grid.shortName ); QString m = tr( "This transformation requires the grid file “%1”, which is not available for use on the system." ).arg( grid.shortName );
if ( !grid.url.isEmpty() ) if ( !grid.url.isEmpty() )
{ {
@ -221,6 +231,10 @@ void QgsCoordinateOperationWidget::loadAvailableOperations()
} }
} }
item->setData( MissingGridsRole, missingGrids );
item->setData( MissingGridPackageNamesRole, missingGridPackages );
item->setData( MissingGridUrlsRole, missingGridUrls );
if ( gridMessages.count() > 1 ) if ( gridMessages.count() > 1 )
{ {
for ( int k = 0; k < gridMessages.count(); ++k ) for ( int k = 0; k < gridMessages.count(); ++k )
@ -702,6 +716,7 @@ void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *,
mLabelDstDescription->clear(); mLabelDstDescription->clear();
#if PROJ_VERSION_MAJOR>=6 #if PROJ_VERSION_MAJOR>=6
mAreaCanvas->hide(); mAreaCanvas->hide();
mInstallGridButton->hide();
#endif #endif
} }
else else
@ -721,6 +736,13 @@ void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *,
mAreaCanvas->setPreviewRect( rect ); mAreaCanvas->setPreviewRect( rect );
#if PROJ_VERSION_MAJOR>=6 #if PROJ_VERSION_MAJOR>=6
mAreaCanvas->show(); mAreaCanvas->show();
const QStringList missingGrids = srcItem->data( MissingGridsRole ).toStringList();
mInstallGridButton->setVisible( !missingGrids.empty() );
if ( !missingGrids.empty() )
{
mInstallGridButton->setText( tr( "Install “%1” Grid…" ).arg( missingGrids.at( 0 ) ) );
}
#endif #endif
} }
else else
@ -728,6 +750,7 @@ void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *,
mAreaCanvas->setPreviewRect( QgsRectangle() ); mAreaCanvas->setPreviewRect( QgsRectangle() );
#if PROJ_VERSION_MAJOR>=6 #if PROJ_VERSION_MAJOR>=6
mAreaCanvas->hide(); mAreaCanvas->hide();
mInstallGridButton->hide();
#endif #endif
} }
QTableWidgetItem *destItem = mCoordinateOperationTableWidget->item( row, 1 ); QTableWidgetItem *destItem = mCoordinateOperationTableWidget->item( row, 1 );
@ -782,3 +805,42 @@ void QgsCoordinateOperationWidget::showSupersededToggled( bool )
#endif #endif
loadAvailableOperations(); loadAvailableOperations();
} }
void QgsCoordinateOperationWidget::installGrid()
{
#if PROJ_VERSION_MAJOR>=6
int row = mCoordinateOperationTableWidget->currentRow();
QTableWidgetItem *srcItem = mCoordinateOperationTableWidget->item( row, 0 );
if ( !srcItem )
return;
const QStringList missingGrids = srcItem->data( MissingGridsRole ).toStringList();
if ( missingGrids.empty() )
return;
const QStringList missingGridPackagesNames = srcItem->data( MissingGridPackageNamesRole ).toStringList();
const QString packageName = missingGridPackagesNames.value( 0 );
const QStringList missingGridUrls = srcItem->data( MissingGridUrlsRole ).toStringList();
const QString gridUrl = missingGridUrls.value( 0 );
QString downloadMessage;
if ( !packageName.isEmpty() )
{
downloadMessage = tr( "This grid is part of the “<i>%1</i>” package, available for download from <a href=\"%2\">%2</a>." ).arg( packageName, gridUrl );
}
else if ( !gridUrl.isEmpty() )
{
downloadMessage = tr( "This grid is available for download from <a href=\"%1\">%1</a>." ).arg( gridUrl );
}
const QString longMessage = tr( "<p>This transformation requires the grid file “%1”, which is not available for use on the system.</p>" ).arg( missingGrids.at( 0 ) );
QgsInstallGridShiftFileDialog *dlg = new QgsInstallGridShiftFileDialog( missingGrids.at( 0 ), this );
dlg->setAttribute( Qt::WA_DeleteOnClose );
dlg->setWindowTitle( tr( "Install Grid File" ) );
dlg->setDescription( longMessage );
dlg->setDownloadMessage( downloadMessage );
dlg->exec();
#endif
}

View File

@ -159,6 +159,8 @@ class GUI_EXPORT QgsCoordinateOperationWidget : public QWidget, private Ui::QgsC
void showSupersededToggled( bool toggled ); void showSupersededToggled( bool toggled );
void installGrid();
private: private:
enum Roles enum Roles
@ -166,7 +168,10 @@ class GUI_EXPORT QgsCoordinateOperationWidget : public QWidget, private Ui::QgsC
TransformIdRole = Qt::UserRole + 1, TransformIdRole = Qt::UserRole + 1,
ProjRole, ProjRole,
AvailableRole, AvailableRole,
BoundsRole BoundsRole,
MissingGridsRole,
MissingGridPackageNamesRole,
MissingGridUrlsRole
}; };
bool gridShiftTransformation( const QString &itemText ) const; bool gridShiftTransformation( const QString &itemText ) const;

View File

@ -23,6 +23,8 @@
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
///@cond PRIVATE
QgsInstallGridShiftFileDialog::QgsInstallGridShiftFileDialog( const QString &gridName, QWidget *parent ) QgsInstallGridShiftFileDialog::QgsInstallGridShiftFileDialog( const QString &gridName, QWidget *parent )
: QDialog( parent ) : QDialog( parent )
, mGridName( gridName ) , mGridName( gridName )
@ -75,3 +77,5 @@ void QgsInstallGridShiftFileDialog::installFromFile()
QMessageBox::critical( this, tr( "Install Grid File" ), tr( "Could not copy %1 to %2. Please check folder permissions and retry." ).arg( mGridName, destPath ) ); QMessageBox::critical( this, tr( "Install Grid File" ), tr( "Could not copy %1 to %2. Please check folder permissions and retry." ).arg( mGridName, destPath ) );
} }
} }
///@endcond

View File

@ -20,9 +20,12 @@
#include "ui_qgsinstallgridshiftdialog.h" #include "ui_qgsinstallgridshiftdialog.h"
#include <QDialog> #include <QDialog>
#include "qgis_app.h" #include "qgis_gui.h"
class QgsInstallGridShiftFileDialog: public QDialog, private Ui::QgsInstallGridShiftFileDialogBase #define SIP_NO_FILE
///@cond PRIVATE
class GUI_EXPORT QgsInstallGridShiftFileDialog: public QDialog, private Ui::QgsInstallGridShiftFileDialogBase
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -39,5 +42,6 @@ class QgsInstallGridShiftFileDialog: public QDialog, private Ui::QgsInstallGridS
QString mGridName; QString mGridName;
}; };
///@endcond
#endif // QGSINSTALLGRIDSHIFTDIALOG_H #endif // QGSINSTALLGRIDSHIFTDIALOG_H

View File

@ -29,23 +29,50 @@
<item row="1" column="0" colspan="2"> <item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,0"> <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,0">
<item> <item>
<widget class="QLabel" name="mLabelSrcDescription"> <layout class="QGridLayout" name="gridLayout_2">
<property name="cursor"> <property name="leftMargin">
<cursorShape>IBeamCursor</cursorShape> <number>0</number>
</property> </property>
<property name="text"> <item row="1" column="0">
<string notr="true">Description</string> <widget class="QPushButton" name="mInstallGridButton">
</property> <property name="text">
<property name="alignment"> <string>Install Grid…</string>
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property>
</property> </widget>
<property name="wordWrap"> </item>
<bool>true</bool> <item row="1" column="1">
</property> <spacer name="horizontalSpacer_2">
<property name="textInteractionFlags"> <property name="orientation">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="mLabelSrcDescription">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string notr="true">Description</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QLabel" name="mLabelDstDescription"> <widget class="QLabel" name="mLabelDstDescription">