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 );
56 mMapLayerModel->
setFilters( QgsMapLayerProxyModel::Filter::SpatialLayer );
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 );
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;
265 void QgsExtentWidget::setOutputExtentFromLineEdit()
271 void 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 );
331 void QgsExtentWidget::setValid(
bool valid )
333 if ( valid == mIsValid )
340 void 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;
367 void 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 );
395 void 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 ) ) );
433 void QgsExtentWidget::setExtentToLayerExtent(
const QString &layerId )
442 QgsMapLayer *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 );
511 void QgsExtentWidget::extentDrawn(
const QgsRectangle &extent )
516 mMapToolPrevious =
nullptr;
519 void QgsExtentWidget::mapToolDeactivated()
522 mMapToolPrevious =
nullptr;
536 mButtonDrawOnCanvas->setVisible( drawOnCanvasOption );
537 mCurrentExtentButton->setVisible(
true );
539 mUseCanvasExtentAction->setVisible(
true );
540 if ( drawOnCanvasOption )
541 mDrawOnCanvasAction->setVisible(
true );
543 mCondensedToolButton->setToolTip( tr(
"Set to current map canvas extent" ) );
546 mCondensedToolButton->setPopupMode( QToolButton::MenuButtonPopup );
550 mButtonDrawOnCanvas->setVisible(
false );
551 mCurrentExtentButton->setVisible(
false );
552 mUseCanvasExtentAction->setVisible(
false );
553 mUseCanvasExtentAction->setVisible(
false );
555 mCondensedToolButton->setToolTip( QString() );
556 mCondensedToolButton->setIcon( QIcon() );
558 mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
564 if ( !( event->possibleActions() & Qt::CopyAction ) )
570 if ( mapLayerFromMimeData( event->mimeData() ) )
573 event->setDropAction( Qt::CopyAction );
575 mCondensedLineEdit->setHighlighted(
true );
586 if ( mCondensedLineEdit->isHighlighted() )
589 mCondensedLineEdit->setHighlighted(
false );
600 if ( !( event->possibleActions() & Qt::CopyAction ) )
606 if (
QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
609 setFocus( Qt::MouseFocusReason );
610 event->setDropAction( Qt::CopyAction );
619 mCondensedLineEdit->setHighlighted(
false );