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
qgsattributesformproperties.cpp
qgsidentifyresultsdialog.cpp
qgsinstallgridshiftdialog.cpp
qgsfeatureaction.cpp
qgslayercapabilitiesmodel.cpp
qgslayertreeviewindicatorprovider.cpp

View File

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

View File

@ -24,6 +24,7 @@
#include "qgsguiutils.h"
#include "qgsgui.h"
#include "qgshelp.h"
#include "qgsinstallgridshiftdialog.h"
#include <QDir>
#include <QPushButton>
@ -40,8 +41,10 @@ QgsCoordinateOperationWidget::QgsCoordinateOperationWidget( QWidget *parent )
mLabelSrcDescription->setTextInteractionFlags( Qt::TextBrowserInteraction );
mLabelSrcDescription->setOpenExternalLinks( true );
mInstallGridButton->hide();
#if PROJ_VERSION_MAJOR>=6
connect( mInstallGridButton, &QPushButton::clicked, this, &QgsCoordinateOperationWidget::installGrid );
mCoordinateOperationTableWidget->setColumnCount( 3 );
#else
mCoordinateOperationTableWidget->setColumnCount( 2 );
@ -201,10 +204,17 @@ void QgsCoordinateOperationWidget::loadAvailableOperations()
if ( !transform.isAvailable )
{
QStringList gridMessages;
QStringList missingGrids;
QStringList missingGridPackages;
QStringList missingGridUrls;
for ( const QgsDatumTransform::GridDetails &grid : transform.grids )
{
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 );
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 )
{
for ( int k = 0; k < gridMessages.count(); ++k )
@ -702,6 +716,7 @@ void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *,
mLabelDstDescription->clear();
#if PROJ_VERSION_MAJOR>=6
mAreaCanvas->hide();
mInstallGridButton->hide();
#endif
}
else
@ -721,6 +736,13 @@ void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *,
mAreaCanvas->setPreviewRect( rect );
#if PROJ_VERSION_MAJOR>=6
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
}
else
@ -728,6 +750,7 @@ void QgsCoordinateOperationWidget::tableCurrentItemChanged( QTableWidgetItem *,
mAreaCanvas->setPreviewRect( QgsRectangle() );
#if PROJ_VERSION_MAJOR>=6
mAreaCanvas->hide();
mInstallGridButton->hide();
#endif
}
QTableWidgetItem *destItem = mCoordinateOperationTableWidget->item( row, 1 );
@ -782,3 +805,42 @@ void QgsCoordinateOperationWidget::showSupersededToggled( bool )
#endif
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 installGrid();
private:
enum Roles
@ -166,7 +168,10 @@ class GUI_EXPORT QgsCoordinateOperationWidget : public QWidget, private Ui::QgsC
TransformIdRole = Qt::UserRole + 1,
ProjRole,
AvailableRole,
BoundsRole
BoundsRole,
MissingGridsRole,
MissingGridPackageNamesRole,
MissingGridUrlsRole
};
bool gridShiftTransformation( const QString &itemText ) const;

View File

@ -23,6 +23,8 @@
#include <QFileDialog>
#include <QMessageBox>
///@cond PRIVATE
QgsInstallGridShiftFileDialog::QgsInstallGridShiftFileDialog( const QString &gridName, QWidget *parent )
: QDialog( parent )
, 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 ) );
}
}
///@endcond

View File

@ -20,9 +20,12 @@
#include "ui_qgsinstallgridshiftdialog.h"
#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
public:
@ -39,5 +42,6 @@ class QgsInstallGridShiftFileDialog: public QDialog, private Ui::QgsInstallGridS
QString mGridName;
};
///@endcond
#endif // QGSINSTALLGRIDSHIFTDIALOG_H

View File

@ -29,23 +29,50 @@
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,0">
<item>
<widget class="QLabel" name="mLabelSrcDescription">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</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 row="1" column="0">
<widget class="QPushButton" name="mInstallGridButton">
<property name="text">
<string>Install Grid…</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<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>
<widget class="QLabel" name="mLabelDstDescription">