28 #include <QRegularExpression>
34 connect( mXMinLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
35 connect( mXMaxLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
36 connect( mYMinLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
37 connect( mYMaxLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromLineEdit );
39 mCondensedRe = QRegularExpression( QStringLiteral(
"\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*(?:\\[(.*?)\\])?" ) );
40 mCondensedLineEdit->setValidator(
new QRegularExpressionValidator( mCondensedRe,
this ) );
41 mCondensedLineEdit->setShowClearButton(
false );
43 connect( mCondensedLineEdit, &QLineEdit::textEdited,
this, &QgsExtentWidget::setOutputExtentFromCondensedLineEdit );
45 mLayerMenu =
new QMenu( tr(
"Calculate from Layer" ),
this );
46 mButtonCalcFromLayer->setMenu( mLayerMenu );
47 connect( mLayerMenu, &QMenu::aboutToShow,
this, &QgsExtentWidget::layerMenuAboutToShow );
50 mMenu =
new QMenu(
this );
51 mUseCanvasExtentAction =
new QAction( tr(
"Use Map Canvas Extent" ),
this );
54 mUseCurrentExtentAction =
new QAction( tr(
"Use Current Layer Extent" ),
this );
57 mDrawOnCanvasAction =
new QAction( tr(
"Draw on Canvas" ),
this );
60 mMenu->addMenu( mLayerMenu );
62 mCondensedToolButton->setMenu( mMenu );
63 mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
70 mOriginalExtentButton->setVisible(
false );
71 mButtonDrawOnCanvas->setVisible(
false );
72 mCurrentExtentButton->setVisible(
false );
81 mExpandedWidget->hide();
85 mCondensedFrame->hide();
89 setAcceptDrops(
true );
108 mOriginalExtentButton->setVisible(
true );
117 mCurrentExtentButton->setVisible(
true );
118 mMenu->addAction( mUseCurrentExtentAction );
123 mHasFixedOutputCrs =
true;
126 const bool prevExtentEnabled = mIsValid;
127 switch ( mExtentState )
166 if ( !prevExtentEnabled )
174 if ( !mHasFixedOutputCrs )
181 if ( mOutputCrs == srcCrs )
190 ct.setBallparkTransformsAreAppropriate(
true );
191 extent = ct.transformBoundingBox( r );
219 mXMinLineEdit->setText( QLocale().toString( extent.
xMinimum(),
'f', decimals ) );
220 mXMaxLineEdit->setText( QLocale().toString( extent.
xMaximum(),
'f', decimals ) );
221 mYMinLineEdit->setText( QLocale().toString( extent.
yMinimum(),
'f', decimals ) );
222 mYMaxLineEdit->setText( QLocale().toString( extent.
yMaximum(),
'f', decimals ) );
224 QString condensed = QStringLiteral(
"%1,%2,%3,%4" ).arg( QString::number( extent.
xMinimum(),
'f', decimals ),
225 QString::number( extent.
xMaximum(),
'f', decimals ),
226 QString::number( extent.
yMinimum(),
'f', decimals ),
227 QString::number( extent.
yMaximum(),
'f', decimals ) );
229 mCondensedLineEdit->setText( condensed );
231 mExtentState = state;
239 void QgsExtentWidget::setOutputExtentFromLineEdit()
245 void QgsExtentWidget::setOutputExtentFromCondensedLineEdit()
247 const QString text = mCondensedLineEdit->text();
248 if ( text.isEmpty() )
254 const QRegularExpressionMatch match = mCondensedRe.match( text );
255 if ( match.hasMatch() )
258 whileBlocking( mXMinLineEdit )->setText( QLocale().toString( match.captured( 1 ).toDouble() ) );
259 whileBlocking( mXMaxLineEdit )->setText( QLocale().toString( match.captured( 2 ).toDouble() ) );
260 whileBlocking( mYMinLineEdit )->setText( QLocale().toString( match.captured( 3 ).toDouble() ) );
261 whileBlocking( mYMaxLineEdit )->setText( QLocale().toString( match.captured( 4 ).toDouble() ) );
262 if ( !match.captured( 5 ).isEmpty() )
276 const bool prevWasNull = mIsValid;
291 return mExtentLayerName;
301 mCondensedLineEdit->setShowClearButton( allowed );
302 mCondensedLineEdit->setNullValue( notSetText );
305 void QgsExtentWidget::setValid(
bool valid )
307 if ( valid == mIsValid )
314 void QgsExtentWidget::layerMenuAboutToShow()
316 qDeleteAll( mLayerMenuActions );
317 mLayerMenuActions.clear();
319 for (
int i = 0; i < mMapLayerModel->
rowCount(); ++i )
321 const QModelIndex index = mMapLayerModel->
index( i, 0 );
322 const QIcon icon = qvariant_cast<QIcon>( mMapLayerModel->
data( index, Qt::DecorationRole ) );
323 const QString text = mMapLayerModel->
data( index, Qt::DisplayRole ).toString();
324 QAction *act =
new QAction( icon, text, mLayerMenu );
325 act->setToolTip( mMapLayerModel->
data( index, Qt::ToolTipRole ).toString() );
327 if ( mExtentState ==
ProjectLayerExtent && mExtentLayer && mExtentLayer->id() == layerId )
329 act->setCheckable(
true );
330 act->setChecked(
true );
332 connect( act, &QAction::triggered,
this, [
this, layerId]
334 setExtentToLayerExtent( layerId );
336 mLayerMenu->addAction( act );
337 mLayerMenuActions << act;
341 void QgsExtentWidget::setExtentToLayerExtent(
const QString &layerId )
350 QgsMapLayer *QgsExtentWidget::mapLayerFromMimeData(
const QMimeData *data )
const
375 setOutputExtent( mCurrentExtent, mCurrentCrs,
CurrentExtent );
395 mExtentLayer = layer;
396 mExtentLayerName = layer->
name();
405 mMapToolPrevious = mCanvas->
mapTool();
406 if ( !mMapToolExtent )
412 mMapToolExtent->setRatio( mRatio );
419 void QgsExtentWidget::extentDrawn(
const QgsRectangle &extent )
424 mMapToolPrevious =
nullptr;
427 void QgsExtentWidget::mapToolDeactivated()
430 mMapToolPrevious =
nullptr;
444 mButtonDrawOnCanvas->setVisible( drawOnCanvasOption );
445 mCurrentExtentButton->setVisible(
true );
447 mMenu->addAction( mUseCanvasExtentAction );
448 if ( drawOnCanvasOption )
449 mMenu->addAction( mDrawOnCanvasAction );
453 mButtonDrawOnCanvas->setVisible(
false );
454 mCurrentExtentButton->setVisible(
false );
455 mMenu->removeAction( mUseCanvasExtentAction );
456 mMenu->removeAction( mDrawOnCanvasAction );
462 if ( !( event->possibleActions() & Qt::CopyAction ) )
468 if ( mapLayerFromMimeData( event->mimeData() ) )
471 event->setDropAction( Qt::CopyAction );
473 mCondensedLineEdit->setHighlighted(
true );
484 if ( mCondensedLineEdit->isHighlighted() )
487 mCondensedLineEdit->setHighlighted(
false );
498 if ( !( event->possibleActions() & Qt::CopyAction ) )
504 if (
QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
507 setFocus( Qt::MouseFocusReason );
508 event->setDropAction( Qt::CopyAction );
517 mCondensedLineEdit->setHighlighted(
false );
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.
Q_GADGET QgsUnitTypes::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.
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.
The QgsMapLayerModel class is a model to display layers in widgets.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
@ LayerIdRole
Stores the map layer ID.
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)
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 yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
@ DistanceDegrees
Degrees, for planar geographic CRS distance measurements.
@ DistanceKilometers
Kilometers.
@ DistanceMiles
Terrestrial miles.
@ DistanceUnknownUnit
Unknown distance unit.
@ DistanceMillimeters
Millimeters.
@ DistanceYards
Imperial yards.
@ DistanceFeet
Imperial feet.
@ DistanceNauticalMiles
Nautical miles.
@ DistanceCentimeters
Centimeters.
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