35#include <QRegularExpression>
41 connect( mXMinLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
42 connect( mXMaxLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
43 connect( mYMinLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
44 connect( mYMaxLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
46 mCondensedRe = QRegularExpression( QStringLiteral(
"\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*(?:\\[(.*?)\\])?" ) );
47 mCondensedLineEdit->setValidator(
new QRegularExpressionValidator( mCondensedRe,
this ) );
48 mCondensedLineEdit->setShowClearButton(
false );
50 connect( mCondensedLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromCondensedLineEdit );
52 mLayerMenu =
new QMenu( tr(
"Calculate from Layer" ),
this );
53 mButtonCalcFromLayer->setMenu( mLayerMenu );
54 connect( mLayerMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::layerMenuAboutToShow );
58 mLayoutMenu =
new QMenu( tr(
"Calculate from Layout Map" ),
this );
59 mButtonCalcFromLayout->setMenu( mLayoutMenu );
60 connect( mLayoutMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::layoutMenuAboutToShow );
62 mBookmarkMenu =
new QMenu( tr(
"Calculate from Bookmark" ),
this );
63 mButtonCalcFromBookmark->setMenu( mBookmarkMenu );
64 connect( mBookmarkMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::bookmarkMenuAboutToShow );
66 mMenu =
new QMenu(
this );
67 mUseCanvasExtentAction =
new QAction( tr(
"Use Current Map Canvas Extent" ),
this );
69 mUseCanvasExtentAction->setVisible(
false );
72 mUseCurrentExtentAction =
new QAction( tr(
"Use Current Layer/Default Extent" ),
this );
73 mUseCurrentExtentAction->setVisible(
false );
76 mDrawOnCanvasAction =
new QAction( tr(
"Draw on Map Canvas" ),
this );
77 mDrawOnCanvasAction->setVisible(
false );
80 mMenu->addMenu( mLayerMenu );
81 mMenu->addMenu( mLayoutMenu );
82 mMenu->addMenu( mBookmarkMenu );
83 mMenu->addSeparator();
84 mMenu->addAction( mUseCanvasExtentAction );
85 mMenu->addAction( mDrawOnCanvasAction );
86 mMenu->addAction( mUseCurrentExtentAction );
88 mCondensedToolButton->setMenu( mMenu );
89 mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
96 mOriginalExtentButton->setVisible(
false );
97 mButtonDrawOnCanvas->setVisible(
false );
98 mCurrentExtentButton->setVisible(
false );
107 mExpandedWidget->hide();
111 mCondensedFrame->hide();
115 setAcceptDrops(
true );
120 if ( mMapToolExtent )
134 mOriginalExtentButton->setVisible(
true );
143 mCurrentExtentButton->setVisible(
true );
144 mUseCurrentExtentAction->setVisible(
true );
149 mHasFixedOutputCrs =
true;
152 const bool prevExtentEnabled = mIsValid;
153 switch ( mExtentState )
192 if ( !prevExtentEnabled )
200 if ( !mHasFixedOutputCrs )
207 if ( mOutputCrs == srcCrs )
216 ct.setBallparkTransformsAreAppropriate(
true );
217 extent = ct.transformBoundingBox( r );
246 mXMinLineEdit->setText( QLocale().toString( extent.
xMinimum(),
'f', decimals ) );
247 mXMaxLineEdit->setText( QLocale().toString( extent.
xMaximum(),
'f', decimals ) );
248 mYMinLineEdit->setText( QLocale().toString( extent.
yMinimum(),
'f', decimals ) );
249 mYMaxLineEdit->setText( QLocale().toString( extent.
yMaximum(),
'f', decimals ) );
251 QString condensed = QStringLiteral(
"%1,%2,%3,%4" ).arg( QString::number( extent.
xMinimum(),
'f', decimals ),
252 QString::number( extent.
xMaximum(),
'f', decimals ),
253 QString::number( extent.
yMinimum(),
'f', decimals ),
254 QString::number( extent.
yMaximum(),
'f', decimals ) );
256 mCondensedLineEdit->setText( condensed );
258 mExtentState = state;
266void QgsExtentWidget::setOutputExtentFromLineEdit()
272void QgsExtentWidget::setOutputExtentFromCondensedLineEdit()
274 const QString text = mCondensedLineEdit->text();
275 if ( text.isEmpty() )
281 const QRegularExpressionMatch match = mCondensedRe.match( text );
282 if ( match.hasMatch() )
285 whileBlocking( mXMinLineEdit )->setText( QLocale().toString( match.captured( 1 ).toDouble(),
'f', 10 ) );
286 whileBlocking( mXMaxLineEdit )->setText( QLocale().toString( match.captured( 2 ).toDouble(),
'f', 10 ) );
287 whileBlocking( mYMinLineEdit )->setText( QLocale().toString( match.captured( 3 ).toDouble(),
'f', 10 ) );
288 whileBlocking( mYMaxLineEdit )->setText( QLocale().toString( match.captured( 4 ).toDouble(),
'f', 10 ) );
289 if ( !match.captured( 5 ).isEmpty() )
303 const bool prevWasNull = mIsValid;
318 return mExtentLayerName;
328 mCondensedLineEdit->setShowClearButton( allowed );
329 mCondensedLineEdit->setNullValue( notSetText );
332void QgsExtentWidget::setValid(
bool valid )
334 if ( valid == mIsValid )
341void QgsExtentWidget::layerMenuAboutToShow()
343 qDeleteAll( mLayerMenuActions );
344 mLayerMenuActions.clear();
346 for (
int i = 0; i < mMapLayerModel->rowCount(); ++i )
348 const QModelIndex index = mMapLayerModel->index( i, 0 );
349 const QIcon icon = qvariant_cast<QIcon>( mMapLayerModel->data( index, Qt::DecorationRole ) );
350 const QString text = mMapLayerModel->data( index, Qt::DisplayRole ).toString();
351 QAction *act =
new QAction( icon, text, mLayerMenu );
352 act->setToolTip( mMapLayerModel->data( index, Qt::ToolTipRole ).toString() );
354 if ( mExtentState ==
ProjectLayerExtent && mExtentLayer && mExtentLayer->id() == layerId )
356 act->setCheckable(
true );
357 act->setChecked(
true );
359 connect( act, &QAction::triggered,
this, [
this, layerId]
361 setExtentToLayerExtent( layerId );
363 mLayerMenu->addAction( act );
364 mLayerMenuActions << act;
368void QgsExtentWidget::layoutMenuAboutToShow()
370 mLayoutMenu->clear();
374 const QList<QgsPrintLayout *> layouts = manager->printLayouts();
377 QList< QgsLayoutItemMap * > maps;
378 layout->layoutItems( maps );
382 QMenu *layoutMenu =
new QMenu( layout->name(), mMenu );
387 QAction *mapExtentAction =
new QAction( tr(
"%1" ).arg( map->displayName() ), mLayoutMenu );
389 layoutMenu->addAction( mapExtentAction );
391 mLayoutMenu->addMenu( layoutMenu );
396void QgsExtentWidget::bookmarkMenuAboutToShow()
398 mBookmarkMenu->clear();
400 if ( !mBookmarkModel )
403 QMap< QString, QMenu * > groupMenus;
404 for (
int i = 0; i < mBookmarkModel->rowCount(); ++i )
407 QMenu *destMenu = mBookmarkMenu;
408 if ( !group.isEmpty() )
410 destMenu = groupMenus.value( group );
413 destMenu =
new QMenu( group, mBookmarkMenu );
414 groupMenus[ group ] = destMenu;
420 destMenu->addAction( action );
423 QStringList groupKeys = groupMenus.keys();
424 groupKeys.sort( Qt::CaseInsensitive );
425 for (
int i = 0; i < groupKeys.count(); ++i )
427 if ( mBookmarkMenu->actions().value( i ) )
428 mBookmarkMenu->insertMenu( mBookmarkMenu->actions().at( i ), groupMenus.value( groupKeys.at( i ) ) );
430 mBookmarkMenu->addMenu( groupMenus.value( groupKeys.at( i ) ) );
434void QgsExtentWidget::setExtentToLayerExtent(
const QString &layerId )
443QgsMapLayer *QgsExtentWidget::mapLayerFromMimeData(
const QMimeData *data )
const
468 setOutputExtent( mCurrentExtent, mCurrentCrs,
CurrentExtent );
488 mExtentLayer = layer;
489 mExtentLayerName = layer->
name();
498 mMapToolPrevious = mCanvas->
mapTool();
499 if ( !mMapToolExtent )
505 mMapToolExtent->setRatio( mRatio );
512void QgsExtentWidget::extentDrawn(
const QgsRectangle &extent )
517 mMapToolPrevious =
nullptr;
520void QgsExtentWidget::mapToolDeactivated()
523 mMapToolPrevious =
nullptr;
546 mButtonDrawOnCanvas->setVisible( drawOnCanvasOption );
547 mCurrentExtentButton->setVisible(
true );
549 mUseCanvasExtentAction->setVisible(
true );
550 if ( drawOnCanvasOption )
551 mDrawOnCanvasAction->setVisible(
true );
553 mCondensedToolButton->setToolTip( tr(
"Set to current map canvas extent" ) );
556 mCondensedToolButton->setPopupMode( QToolButton::MenuButtonPopup );
560 mButtonDrawOnCanvas->setVisible(
false );
561 mCurrentExtentButton->setVisible(
false );
562 mUseCanvasExtentAction->setVisible(
false );
563 mUseCanvasExtentAction->setVisible(
false );
565 mCondensedToolButton->setToolTip( QString() );
566 mCondensedToolButton->setIcon( QIcon() );
568 mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
574 if ( !( event->possibleActions() & Qt::CopyAction ) )
580 if ( mapLayerFromMimeData( event->mimeData() ) )
583 event->setDropAction( Qt::CopyAction );
585 mCondensedLineEdit->setHighlighted(
true );
596 if ( mCondensedLineEdit->isHighlighted() )
599 mCondensedLineEdit->setHighlighted(
false );
610 if ( !( event->possibleActions() & Qt::CopyAction ) )
616 if (
QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
619 setFocus( Qt::MouseFocusReason );
620 event->setDropAction( Qt::CopyAction );
629 mCondensedLineEdit->setHighlighted(
false );
@ 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.
@ RoleExtent
Bookmark extent as a QgsReferencedRectangle.
@ RoleGroup
Bookmark group.
A QSortFilterProxyModel subclass for sorting the entries in a QgsBookmarkManagerModel.
This class represents a coordinate reference system (CRS).
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
QString userFriendlyIdentifier(IdentifierType type=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.
@ LayerIdRole
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