34#include <QRegularExpression>
40 connect( mXMinLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
41 connect( mXMaxLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
42 connect( mYMinLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
43 connect( mYMaxLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
45 mCondensedRe = QRegularExpression( QStringLiteral(
"\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*(?:\\[(.*?)\\])?" ) );
46 mCondensedLineEdit->setValidator(
new QRegularExpressionValidator( mCondensedRe,
this ) );
47 mCondensedLineEdit->setShowClearButton(
false );
49 connect( mCondensedLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromCondensedLineEdit );
51 mLayerMenu =
new QMenu( tr(
"Calculate from Layer" ),
this );
52 mButtonCalcFromLayer->setMenu( mLayerMenu );
53 connect( mLayerMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::layerMenuAboutToShow );
57 mLayoutMenu =
new QMenu( tr(
"Calculate from Layout Map" ),
this );
58 mButtonCalcFromLayout->setMenu( mLayoutMenu );
59 connect( mLayoutMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::layoutMenuAboutToShow );
61 mBookmarkMenu =
new QMenu( tr(
"Calculate from Bookmark" ),
this );
62 mButtonCalcFromBookmark->setMenu( mBookmarkMenu );
63 connect( mBookmarkMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::bookmarkMenuAboutToShow );
65 mMenu =
new QMenu(
this );
66 mUseCanvasExtentAction =
new QAction( tr(
"Use Current Map Canvas Extent" ),
this );
68 mUseCanvasExtentAction->setVisible(
false );
71 mUseCurrentExtentAction =
new QAction( tr(
"Use Current Layer/Default Extent" ),
this );
72 mUseCurrentExtentAction->setVisible(
false );
75 mDrawOnCanvasAction =
new QAction( tr(
"Draw on Map Canvas" ),
this );
76 mDrawOnCanvasAction->setVisible(
false );
79 mMenu->addMenu( mLayerMenu );
80 mMenu->addMenu( mLayoutMenu );
81 mMenu->addMenu( mBookmarkMenu );
82 mMenu->addSeparator();
83 mMenu->addAction( mUseCanvasExtentAction );
84 mMenu->addAction( mDrawOnCanvasAction );
85 mMenu->addAction( mUseCurrentExtentAction );
87 mCondensedToolButton->setMenu( mMenu );
88 mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
95 mOriginalExtentButton->setVisible(
false );
96 mButtonDrawOnCanvas->setVisible(
false );
97 mCurrentExtentButton->setVisible(
false );
106 mExpandedWidget->hide();
110 mCondensedFrame->hide();
114 setAcceptDrops(
true );
119 if ( mMapToolExtent )
133 mOriginalExtentButton->setVisible(
true );
142 mCurrentExtentButton->setVisible(
true );
143 mUseCurrentExtentAction->setVisible(
true );
148 mHasFixedOutputCrs =
true;
151 const bool prevExtentEnabled = mIsValid;
152 switch ( mExtentState )
191 if ( !prevExtentEnabled )
199 if ( !mHasFixedOutputCrs )
206 if ( mOutputCrs == srcCrs )
215 ct.setBallparkTransformsAreAppropriate(
true );
216 extent = ct.transformBoundingBox( r );
245 mXMinLineEdit->setText( QLocale().toString( extent.
xMinimum(),
'f', decimals ) );
246 mXMaxLineEdit->setText( QLocale().toString( extent.
xMaximum(),
'f', decimals ) );
247 mYMinLineEdit->setText( QLocale().toString( extent.
yMinimum(),
'f', decimals ) );
248 mYMaxLineEdit->setText( QLocale().toString( extent.
yMaximum(),
'f', decimals ) );
250 QString condensed = QStringLiteral(
"%1,%2,%3,%4" ).arg( QString::number( extent.
xMinimum(),
'f', decimals ),
251 QString::number( extent.
xMaximum(),
'f', decimals ),
252 QString::number( extent.
yMinimum(),
'f', decimals ),
253 QString::number( extent.
yMaximum(),
'f', decimals ) );
255 mCondensedLineEdit->setText( condensed );
257 mExtentState = state;
265void QgsExtentWidget::setOutputExtentFromLineEdit()
271void QgsExtentWidget::setOutputExtentFromCondensedLineEdit()
273 const QString text = mCondensedLineEdit->text();
274 if ( text.isEmpty() )
280 const QRegularExpressionMatch match = mCondensedRe.match( text );
281 if ( match.hasMatch() )
284 whileBlocking( mXMinLineEdit )->setText( QLocale().toString( match.captured( 1 ).toDouble(),
'f', 10 ) );
285 whileBlocking( mXMaxLineEdit )->setText( QLocale().toString( match.captured( 2 ).toDouble(),
'f', 10 ) );
286 whileBlocking( mYMinLineEdit )->setText( QLocale().toString( match.captured( 3 ).toDouble(),
'f', 10 ) );
287 whileBlocking( mYMaxLineEdit )->setText( QLocale().toString( match.captured( 4 ).toDouble(),
'f', 10 ) );
288 if ( !match.captured( 5 ).isEmpty() )
302 const bool prevWasNull = mIsValid;
317 return mExtentLayerName;
327 mCondensedLineEdit->setShowClearButton( allowed );
328 mCondensedLineEdit->setNullValue( notSetText );
331void QgsExtentWidget::setValid(
bool valid )
333 if ( valid == mIsValid )
340void QgsExtentWidget::layerMenuAboutToShow()
342 qDeleteAll( mLayerMenuActions );
343 mLayerMenuActions.clear();
345 for (
int i = 0; i < mMapLayerModel->rowCount(); ++i )
347 const QModelIndex index = mMapLayerModel->index( i, 0 );
348 const QIcon icon = qvariant_cast<QIcon>( mMapLayerModel->data( index, Qt::DecorationRole ) );
349 const QString text = mMapLayerModel->data( index, Qt::DisplayRole ).toString();
350 QAction *act =
new QAction( icon, text, mLayerMenu );
351 act->setToolTip( mMapLayerModel->data( index, Qt::ToolTipRole ).toString() );
353 if ( mExtentState ==
ProjectLayerExtent && mExtentLayer && mExtentLayer->id() == layerId )
355 act->setCheckable(
true );
356 act->setChecked(
true );
358 connect( act, &QAction::triggered,
this, [
this, layerId]
360 setExtentToLayerExtent( layerId );
362 mLayerMenu->addAction( act );
363 mLayerMenuActions << act;
367void QgsExtentWidget::layoutMenuAboutToShow()
369 mLayoutMenu->clear();
373 const QList<QgsPrintLayout *> layouts = manager->printLayouts();
376 QList< QgsLayoutItemMap * > maps;
377 layout->layoutItems( maps );
381 QMenu *layoutMenu =
new QMenu( layout->name(), mMenu );
386 QAction *mapExtentAction =
new QAction( tr(
"%1" ).arg( map->displayName() ), mLayoutMenu );
388 layoutMenu->addAction( mapExtentAction );
390 mLayoutMenu->addMenu( layoutMenu );
395void QgsExtentWidget::bookmarkMenuAboutToShow()
397 mBookmarkMenu->clear();
399 if ( !mBookmarkModel )
402 QMap< QString, QMenu * > groupMenus;
403 for (
int i = 0; i < mBookmarkModel->rowCount(); ++i )
406 QMenu *destMenu = mBookmarkMenu;
407 if ( !group.isEmpty() )
409 destMenu = groupMenus.value( group );
412 destMenu =
new QMenu( group, mBookmarkMenu );
413 groupMenus[ group ] = destMenu;
419 destMenu->addAction( action );
422 QStringList groupKeys = groupMenus.keys();
423 groupKeys.sort( Qt::CaseInsensitive );
424 for (
int i = 0; i < groupKeys.count(); ++i )
426 if ( mBookmarkMenu->actions().value( i ) )
427 mBookmarkMenu->insertMenu( mBookmarkMenu->actions().at( i ), groupMenus.value( groupKeys.at( i ) ) );
429 mBookmarkMenu->addMenu( groupMenus.value( groupKeys.at( i ) ) );
433void QgsExtentWidget::setExtentToLayerExtent(
const QString &layerId )
442QgsMapLayer *QgsExtentWidget::mapLayerFromMimeData(
const QMimeData *data )
const
467 setOutputExtent( mCurrentExtent, mCurrentCrs,
CurrentExtent );
487 mExtentLayer = layer;
488 mExtentLayerName = layer->
name();
497 mMapToolPrevious = mCanvas->
mapTool();
498 if ( !mMapToolExtent )
504 mMapToolExtent->setRatio( mRatio );
511void QgsExtentWidget::extentDrawn(
const QgsRectangle &extent )
516 mMapToolPrevious =
nullptr;
519void QgsExtentWidget::mapToolDeactivated()
522 mMapToolPrevious =
nullptr;
545 mButtonDrawOnCanvas->setVisible( drawOnCanvasOption );
546 mCurrentExtentButton->setVisible(
true );
548 mUseCanvasExtentAction->setVisible(
true );
549 if ( drawOnCanvasOption )
550 mDrawOnCanvasAction->setVisible(
true );
552 mCondensedToolButton->setToolTip( tr(
"Set to current map canvas extent" ) );
555 mCondensedToolButton->setPopupMode( QToolButton::MenuButtonPopup );
559 mButtonDrawOnCanvas->setVisible(
false );
560 mCurrentExtentButton->setVisible(
false );
561 mUseCanvasExtentAction->setVisible(
false );
562 mUseCanvasExtentAction->setVisible(
false );
564 mCondensedToolButton->setToolTip( QString() );
565 mCondensedToolButton->setIcon( QIcon() );
567 mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
573 if ( !( event->possibleActions() & Qt::CopyAction ) )
579 if ( mapLayerFromMimeData( event->mimeData() ) )
582 event->setDropAction( Qt::CopyAction );
584 mCondensedLineEdit->setHighlighted(
true );
595 if ( mCondensedLineEdit->isHighlighted() )
598 mCondensedLineEdit->setHighlighted(
false );
609 if ( !( event->possibleActions() & Qt::CopyAction ) )
615 if (
QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
618 setFocus( Qt::MouseFocusReason );
619 event->setDropAction( Qt::CopyAction );
628 mCondensedLineEdit->setHighlighted(
false );
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
@ Centimeters
Centimeters.
@ Millimeters
Millimeters.
@ Miles
Terrestrial miles.
@ Unknown
Unknown distance unit.
@ Degrees
Degrees, for planar geographic CRS distance measurements.
@ Inches
Inches (since QGIS 3.32)
@ NauticalMiles
Nautical miles.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsBookmarkManager * bookmarkManager()
Returns the application's bookmark manager, used for storing installation-wide bookmarks.
@ Extent
Bookmark extent as a QgsReferencedRectangle.
A QSortFilterProxyModel subclass for sorting the entries in a QgsBookmarkManagerModel.
This class represents a coordinate reference system (CRS).
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
Qgis::DistanceUnit mapUnits
Custom exception class for Coordinate Reference System related exceptions.
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
void cleared()
Emitted when the widget is cleared.
Layout graphical items for displaying a map.
Manages storage of a set of layouts.
Map canvas is a class for displaying all GIS data types on a canvas.
QgsMapTool * mapTool()
Returns the currently active tool.
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
@ LayerId
Stores the map layer ID.
The QgsMapLayerProxyModel class provides an easy to use model to display the list of layers in widget...
QgsMapLayerProxyModel * setFilters(Qgis::LayerFilters filters)
Sets filter flags which affect how layers are filtered within the model.
Base class for all map layer types.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
The QgsMapSettings class contains configuration for rendering of the map.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
QList< QgsMimeDataUtils::Uri > UriList
static UriList decodeUriList(const QMimeData *data)
Print layout, a QgsLayout subclass for static or atlas-based layouts.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsRectangle with associated coordinate reference system.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
const QgsCoordinateReferenceSystem & outputCrs
const QgsCoordinateReferenceSystem & crs