Skip to content

Commit b44d991

Browse files
committedApr 24, 2023
Add buttons in the QgsProjectionTree to clear recent CRS
1 parent 08bf81d commit b44d991

File tree

4 files changed

+145
-54
lines changed

4 files changed

+145
-54
lines changed
 

‎python/gui/auto_generated/qgsprojectionselectiontreewidget.sip.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ Marks the current selected projection for push to front of recent projections li
155155
Has no effect since QGIS 3.20
156156
%End
157157

158+
159+
void clearRecentCrs();
160+
%Docstring
161+
Clear the list of recent projections.
162+
163+
.. versionadded:: 3.32
164+
%End
165+
158166
signals:
159167

160168
void crsSelected();

‎src/gui/qgsprojectionselectiontreewidget.cpp

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ QgsProjectionSelectionTreeWidget::QgsProjectionSelectionTreeWidget( QWidget *par
5151
connect( lstRecent, &QTreeWidget::currentItemChanged, this, &QgsProjectionSelectionTreeWidget::lstRecent_currentItemChanged );
5252
connect( cbxHideDeprecated, &QCheckBox::stateChanged, this, &QgsProjectionSelectionTreeWidget::updateFilter );
5353
connect( leSearch, &QgsFilterLineEdit::textChanged, this, &QgsProjectionSelectionTreeWidget::updateFilter );
54+
connect( mClearRecentCrs, &QToolButton::clicked, this, &QgsProjectionSelectionTreeWidget::clearRecentCrs );
5455

5556
mAreaCanvas->setVisible( mShowMap );
5657

@@ -63,14 +64,16 @@ QgsProjectionSelectionTreeWidget::QgsProjectionSelectionTreeWidget( QWidget *par
6364

6465
// Hide (internal) ID column
6566
lstCoordinateSystems->setColumnHidden( QgisCrsIdColumn, true );
66-
6767
lstRecent->header()->setSectionResizeMode( AuthidColumn, QHeaderView::Stretch );
6868
lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
6969
lstRecent->header()->setSectionResizeMode( QgisCrsIdColumn, QHeaderView::Fixed );
70-
71-
// Hide (internal) ID column
7270
lstRecent->setColumnHidden( QgisCrsIdColumn, true );
7371

72+
// Clear Crs Column
73+
lstRecent->header()->setMinimumSectionSize( 10 );
74+
lstRecent->header()->setStretchLastSection( false );
75+
lstRecent->header()->resizeSection( ClearColumn, 20 );
76+
7477
mRecentProjections = QgsCoordinateReferenceSystem::recentCoordinateReferenceSystems();
7578

7679
mCheckBoxNoProjection->setHidden( true );
@@ -112,9 +115,10 @@ void QgsProjectionSelectionTreeWidget::resizeEvent( QResizeEvent *event )
112115
lstCoordinateSystems->header()->resizeSection( AuthidColumn, 240 );
113116
lstCoordinateSystems->header()->resizeSection( QgisCrsIdColumn, 0 );
114117

115-
lstRecent->header()->resizeSection( NameColumn, event->size().width() - 240 );
118+
lstRecent->header()->resizeSection( NameColumn, event->size().width() - 260 );
116119
lstRecent->header()->resizeSection( AuthidColumn, 240 );
117120
lstRecent->header()->resizeSection( QgisCrsIdColumn, 0 );
121+
lstRecent->header()->resizeSection( ClearColumn, 20 );
118122
}
119123

120124
void QgsProjectionSelectionTreeWidget::showEvent( QShowEvent *event )
@@ -253,13 +257,25 @@ void QgsProjectionSelectionTreeWidget::insertRecent( const QgsCoordinateReferenc
253257
if ( nodes.isEmpty() )
254258
return;
255259

256-
lstRecent->insertTopLevelItem( 0, new QTreeWidgetItem( lstRecent, QStringList()
257-
<< nodes.first()->text( NameColumn )
258-
<< nodes.first()->text( AuthidColumn )
259-
<< nodes.first()->text( QgisCrsIdColumn ) ) );
260+
QTreeWidgetItem *item = new QTreeWidgetItem( lstRecent, QStringList()
261+
<< nodes.first()->text( NameColumn )
262+
<< nodes.first()->text( AuthidColumn )
263+
<< nodes.first()->text( QgisCrsIdColumn ) );
264+
265+
// Insert clear button in the last column
266+
QToolButton *clearButton = new QToolButton();
267+
clearButton->setIcon( QgsApplication::getThemeIcon( "/mIconClearItem.svg" ) );
268+
clearButton->setAutoRaise( true );
269+
clearButton->setToolTip( tr( "Clear from recently used coordinate reference systems" ) );
270+
connect( clearButton, &QToolButton::clicked, this, [this, item] { removeRecentCrsItem( item ); } );
271+
lstRecent->setItemWidget( item, ClearColumn, clearButton );
272+
273+
274+
lstRecent->insertTopLevelItem( 0, item );
275+
260276
}
261277

262-
//note this line just returns the projection name!
278+
// note this line just returns the projection name!
263279
QString QgsProjectionSelectionTreeWidget::selectedName()
264280
{
265281
// return the selected wkt name from the list view
@@ -307,25 +323,19 @@ QgsRectangle QgsProjectionSelectionTreeWidget::previewRect() const
307323
return mAreaCanvas->canvasRect();
308324
}
309325

310-
QString QgsProjectionSelectionTreeWidget::getSelectedExpression( const QString &expression ) const
326+
QString QgsProjectionSelectionTreeWidget::expressionForItem( QTreeWidgetItem *item, const QString &expression ) const
311327
{
312-
// Only return the attribute if there is a node in the tree
313-
// selected that has an srs_id. This prevents error if the user
314-
// selects a top-level node rather than an actual coordinate
315-
// system
316-
//
317-
// Get the selected node and make sure it is a srs andx
318-
// not a top-level projection node
319-
QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
320-
if ( !lvi || lvi->text( QgisCrsIdColumn ).isEmpty() )
328+
// Only return the attribute if the selected item that has an srs_id.
329+
// This prevents error if the user selects a top-level node rather
330+
// than an actual coordinate system
331+
if ( !item || item->text( QgisCrsIdColumn ).isEmpty() )
321332
return QString();
322333

323-
//
334+
324335
// Determine if this is a user projection or a system on
325336
// user projection defs all have srs_id >= 100000
326-
//
327337
QString databaseFileName;
328-
if ( lvi->text( QgisCrsIdColumn ).toLong() >= USER_CRS_START_ID )
338+
if ( item->text( QgisCrsIdColumn ).toLong() >= USER_CRS_START_ID )
329339
{
330340
databaseFileName = QgsApplication::qgisUserDatabaseFilePath();
331341
if ( !QFileInfo::exists( databaseFileName ) )
@@ -338,7 +348,6 @@ QString QgsProjectionSelectionTreeWidget::getSelectedExpression( const QString &
338348
databaseFileName = mSrsDatabaseFileName;
339349
}
340350

341-
//
342351
// set up the database
343352
// XXX We could probably hold the database open for the life of this object,
344353
// assuming that it will never be used anywhere else. Given the low overhead,
@@ -358,7 +367,7 @@ QString QgsProjectionSelectionTreeWidget::getSelectedExpression( const QString &
358367
sqlite3_stmt *stmt = nullptr;
359368
QString sql = QStringLiteral( "select %1 from tbl_srs where srs_id=%2" )
360369
.arg( expression,
361-
lvi->text( QgisCrsIdColumn ) );
370+
item->text( QgisCrsIdColumn ) );
362371

363372
QgsDebugMsgLevel( QStringLiteral( "Finding selected attribute using : %1" ).arg( sql ), 4 );
364373
rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );
@@ -379,36 +388,42 @@ QString QgsProjectionSelectionTreeWidget::getSelectedExpression( const QString &
379388
return attributeValue;
380389
}
381390

382-
QgsCoordinateReferenceSystem QgsProjectionSelectionTreeWidget::crs() const
391+
392+
393+
QgsCoordinateReferenceSystem QgsProjectionSelectionTreeWidget::crsForItem( QTreeWidgetItem *item ) const
383394
{
384395
if ( mCheckBoxNoProjection->isEnabled() && mCheckBoxNoProjection->isChecked() )
385396
return QgsCoordinateReferenceSystem();
386397

387398
if ( !mInitialized && mDeferredLoadCrs.isValid() )
388399
return mDeferredLoadCrs;
389400

390-
const QString srsIdString = getSelectedExpression( QStringLiteral( "srs_id" ) );
401+
const QString srsIdString = expressionForItem( item, QStringLiteral( "srs_id" ) );
391402
if ( !srsIdString.isEmpty() )
392403
{
393404
int srid = srsIdString.toLong();
394405
if ( srid >= USER_CRS_START_ID )
395406
return QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "USER:%1" ).arg( srid ) );
396407
else
397-
return QgsCoordinateReferenceSystem::fromOgcWmsCrs( getSelectedExpression( QStringLiteral( "upper(auth_name||':'||auth_id)" ) ) );
408+
return QgsCoordinateReferenceSystem::fromOgcWmsCrs( expressionForItem( item, QStringLiteral( "upper(auth_name||':'||auth_id)" ) ) );
398409
}
399410
else
400411
{
401412
// custom CRS
402-
QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
403-
if ( lvi && lvi->data( 0, RoleWkt ).isValid() )
404-
return QgsCoordinateReferenceSystem::fromWkt( lvi->data( 0, RoleWkt ).toString() );
405-
else if ( lvi && lvi->data( 0, RoleProj ).isValid() )
406-
return QgsCoordinateReferenceSystem::fromProj( lvi->data( 0, RoleProj ).toString() );
413+
if ( item && item->data( 0, RoleWkt ).isValid() )
414+
return QgsCoordinateReferenceSystem::fromWkt( item->data( 0, RoleWkt ).toString() );
415+
else if ( item && item->data( 0, RoleProj ).isValid() )
416+
return QgsCoordinateReferenceSystem::fromProj( item->data( 0, RoleProj ).toString() );
407417
else
408418
return QgsCoordinateReferenceSystem();
409419
}
410420
}
411421

422+
QgsCoordinateReferenceSystem QgsProjectionSelectionTreeWidget::crs() const
423+
{
424+
return crsForItem( lstCoordinateSystems->currentItem() );
425+
}
426+
412427
void QgsProjectionSelectionTreeWidget::setShowNoProjection( bool show )
413428
{
414429
mCheckBoxNoProjection->setVisible( show );
@@ -1053,3 +1068,21 @@ void QgsProjectionSelectionTreeWidget::showDBMissingWarning( const QString &file
10531068
"Because of this the projection selector will not work…" )
10541069
.arg( fileName ) );
10551070
}
1071+
1072+
void QgsProjectionSelectionTreeWidget::clearRecentCrs()
1073+
{
1074+
QgsCoordinateReferenceSystem::clearRecentCoordinateReferenceSystems();
1075+
lstRecent->clear();
1076+
}
1077+
1078+
1079+
void QgsProjectionSelectionTreeWidget::removeRecentCrsItem( QTreeWidgetItem *item )
1080+
{
1081+
int index = lstRecent->indexOfTopLevelItem( item );
1082+
if ( index == -1 )
1083+
return;
1084+
QgsCoordinateReferenceSystem crs = crsForItem( item );
1085+
QgsCoordinateReferenceSystem::removeRecentCoordinateReferenceSystem( crs );
1086+
lstRecent->takeTopLevelItem( index );
1087+
delete item;
1088+
}

‎src/gui/qgsprojectionselectiontreewidget.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
145145
*/
146146
Q_DECL_DEPRECATED void pushProjectionToFront() SIP_DEPRECATED;
147147

148+
149+
/**
150+
* Clear the list of recent projections.
151+
*
152+
* \since QGIS 3.32
153+
*/
154+
void clearRecentCrs();
155+
148156
signals:
149157

150158
/**
@@ -236,12 +244,11 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
236244
*/
237245
void applySelection( int column = QgsProjectionSelectionTreeWidget::None, QString value = QString() );
238246

239-
/**
240-
* \brief gets an arbitrary sqlite3 expression from the selection
241-
*
242-
* \param e The sqlite3 expression (typically "srid" or "sridid")
243-
*/
244-
QString getSelectedExpression( const QString &e ) const;
247+
//! gets an arbitrary sqlite3 expression from the given item
248+
QString expressionForItem( QTreeWidgetItem *item, const QString &expression ) const;
249+
250+
//! Returns the CRS of the given item
251+
QgsCoordinateReferenceSystem crsForItem( QTreeWidgetItem *item ) const;
245252

246253
QString selectedName();
247254

@@ -290,7 +297,7 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
290297
//! Has the Recent Projection List been populated?
291298
bool mRecentProjListDone = false;
292299

293-
enum Columns { NameColumn, AuthidColumn, QgisCrsIdColumn, None };
300+
enum Columns { NameColumn, AuthidColumn, QgisCrsIdColumn, ClearColumn, None };
294301
int mSearchColumn = QgsProjectionSelectionTreeWidget::None;
295302
QString mSearchValue;
296303

@@ -320,6 +327,8 @@ class GUI_EXPORT QgsProjectionSelectionTreeWidget : public QWidget, private Ui::
320327
void lstCoordinateSystems_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem *prev );
321328
void lstRecent_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem *prev );
322329
void updateFilter();
330+
331+
void removeRecentCrsItem( QTreeWidgetItem *item );
323332
};
324333

325334
#endif

‎src/ui/qgsprojectionselectorbase.ui

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,51 @@
8282
</layout>
8383
</item>
8484
<item>
85-
<widget class="QLabel" name="label_3">
86-
<property name="font">
87-
<font>
88-
<weight>75</weight>
89-
<bold>true</bold>
90-
</font>
91-
</property>
92-
<property name="text">
93-
<string>Recently Used Coordinate Reference Systems</string>
94-
</property>
95-
</widget>
85+
<layout class="QHBoxLayout" name="horizontalLayout_2">
86+
<item>
87+
<widget class="QLabel" name="label_3">
88+
<property name="font">
89+
<font>
90+
<weight>75</weight>
91+
<bold>true</bold>
92+
</font>
93+
</property>
94+
<property name="text">
95+
<string>Recently Used Coordinate Reference Systems</string>
96+
</property>
97+
</widget>
98+
</item>
99+
<item>
100+
<widget class="QToolButton" name="mClearRecentCrs">
101+
<property name="toolTip">
102+
<string>Clear all recently used coordinate reference systems</string>
103+
</property>
104+
<property name="text">
105+
<string>Clear</string>
106+
</property>
107+
<property name="icon">
108+
<iconset resource="../../images/images.qrc">
109+
<normaloff>:/images/themes/default/console/iconClearConsole.svg</normaloff>:/images/themes/default/console/iconClearConsole.svg</iconset>
110+
</property>
111+
<property name="autoRaise">
112+
<bool>true</bool>
113+
</property>
114+
</widget>
115+
</item>
116+
<item>
117+
<spacer name="horizontalSpacer">
118+
<property name="orientation">
119+
<enum>Qt::Horizontal</enum>
120+
</property>
121+
<property name="sizeHint" stdset="0">
122+
<size>
123+
<width>40</width>
124+
<height>20</height>
125+
</size>
126+
</property>
127+
</spacer>
128+
</item>
129+
</layout>
96130
</item>
97131
<item>
98132
<widget class="QSplitter" name="mSplitter">
@@ -125,7 +159,7 @@
125159
<bool>true</bool>
126160
</property>
127161
<property name="columnCount">
128-
<number>3</number>
162+
<number>4</number>
129163
</property>
130164
<column>
131165
<property name="text">
@@ -142,8 +176,13 @@
142176
<string>ID</string>
143177
</property>
144178
</column>
179+
<column>
180+
<property name="text">
181+
<string/>
182+
</property>
183+
</column>
145184
</widget>
146-
<widget class="QWidget" name="">
185+
<widget class="QWidget" name="layoutWidget">
147186
<layout class="QGridLayout" name="gridLayout">
148187
<property name="horizontalSpacing">
149188
<number>0</number>
@@ -223,7 +262,7 @@
223262
</item>
224263
</layout>
225264
</widget>
226-
<widget class="QWidget" name="">
265+
<widget class="QWidget" name="layoutWidget">
227266
<layout class="QHBoxLayout" name="horizontalLayout_4">
228267
<property name="topMargin">
229268
<number>0</number>
@@ -314,6 +353,8 @@
314353
<tabstop>cbxHideDeprecated</tabstop>
315354
<tabstop>lstCoordinateSystems</tabstop>
316355
</tabstops>
317-
<resources/>
356+
<resources>
357+
<include location="../../images/images.qrc"/>
358+
</resources>
318359
<connections/>
319360
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.