mirror of
https://github.com/qgis/QGIS.git
synced 2025-07-04 00:02:42 -04:00
Compare commits
17 Commits
31787bb2e7
...
958b4c36e3
Author | SHA1 | Date | |
---|---|---|---|
|
958b4c36e3 | ||
|
e5e3b9a44a | ||
|
88dd13a0ca | ||
|
e67201a2aa | ||
|
f2c61f819f | ||
|
55f2cbe674 | ||
|
9853fa2da1 | ||
|
d678daf1d5 | ||
|
13f020ef86 | ||
|
32b0327dbf | ||
|
7ccd8f0435 | ||
|
021467a178 | ||
|
88f59e4c37 | ||
|
a06f6ee8b1 | ||
|
ee23cf7c44 | ||
|
86f372948e | ||
|
ccdb476318 |
@ -173,6 +173,16 @@ full details (``longMessage``).
|
||||
%Docstring
|
||||
Requests a complete rebuild of a model by emitting the according signal
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
void updateBounds();
|
||||
%Docstring
|
||||
Updates the scene rect based on the bounds of the model.
|
||||
|
||||
The bounding rectangle of the model is calculated off all components of
|
||||
the model, with an additional margin arounds items.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
|
@ -57,6 +57,15 @@ widget.
|
||||
void setModelScene( QgsModelGraphicsScene *scene );
|
||||
%Docstring
|
||||
Sets the related ``scene``.
|
||||
%End
|
||||
|
||||
void friendlySetSceneRect();
|
||||
%Docstring
|
||||
Sets the scene rect used for scrollbar without disturbing the user i.e:
|
||||
- We growth the scene rect as the model growth - We shrink only if the
|
||||
model scene rect is outside the current viewed viewport
|
||||
|
||||
Called each time the view viewport moved or the model scene changed
|
||||
%End
|
||||
|
||||
QgsModelGraphicsScene *modelScene() const;
|
||||
@ -134,12 +143,10 @@ Pastes items from clipboard, using the specified ``mode``.
|
||||
%End
|
||||
|
||||
public slots:
|
||||
|
||||
void snapSelected();
|
||||
%Docstring
|
||||
Snaps the selected items to the grid.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void algorithmDropped( const QString &algorithmId, const QPointF &pos );
|
||||
|
@ -173,6 +173,16 @@ full details (``longMessage``).
|
||||
%Docstring
|
||||
Requests a complete rebuild of a model by emitting the according signal
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
void updateBounds();
|
||||
%Docstring
|
||||
Updates the scene rect based on the bounds of the model.
|
||||
|
||||
The bounding rectangle of the model is calculated off all components of
|
||||
the model, with an additional margin arounds items.
|
||||
|
||||
.. versionadded:: 3.44
|
||||
%End
|
||||
|
||||
|
@ -57,6 +57,15 @@ widget.
|
||||
void setModelScene( QgsModelGraphicsScene *scene );
|
||||
%Docstring
|
||||
Sets the related ``scene``.
|
||||
%End
|
||||
|
||||
void friendlySetSceneRect();
|
||||
%Docstring
|
||||
Sets the scene rect used for scrollbar without disturbing the user i.e:
|
||||
- We growth the scene rect as the model growth - We shrink only if the
|
||||
model scene rect is outside the current viewed viewport
|
||||
|
||||
Called each time the view viewport moved or the model scene changed
|
||||
%End
|
||||
|
||||
QgsModelGraphicsScene *modelScene() const;
|
||||
@ -134,12 +143,10 @@ Pastes items from clipboard, using the specified ``mode``.
|
||||
%End
|
||||
|
||||
public slots:
|
||||
|
||||
void snapSelected();
|
||||
%Docstring
|
||||
Snaps the selected items to the grid.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void algorithmDropped( const QString &algorithmId, const QPointF &pos );
|
||||
|
@ -71,7 +71,6 @@ pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||
|
||||
|
||||
class ModelerDialog(QgsModelDesignerDialog):
|
||||
CANVAS_SIZE = 4000
|
||||
|
||||
update_model = pyqtSignal()
|
||||
|
||||
@ -97,7 +96,6 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
self.setStyleSheet(iface.mainWindow().styleSheet())
|
||||
|
||||
scene = ModelerScene(self)
|
||||
scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
|
||||
self.setModelScene(scene)
|
||||
|
||||
self.view().ensureVisible(0, 0, 10, 10)
|
||||
@ -244,8 +242,6 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
|
||||
def repaintModel(self, showControls=True):
|
||||
scene = ModelerScene(self)
|
||||
scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
|
||||
|
||||
if not showControls:
|
||||
scene.setFlag(QgsModelGraphicsScene.Flag.FlagHideControls)
|
||||
|
||||
@ -259,6 +255,7 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
self.setModelScene(scene)
|
||||
# create items later that setModelScene to setup link to messageBar to the scene
|
||||
scene.createItems(self.model(), context)
|
||||
scene.updateBounds()
|
||||
|
||||
def create_widget_context(self):
|
||||
"""
|
||||
@ -347,7 +344,7 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
for i in list(self.model().parameterComponents().values())
|
||||
]
|
||||
)
|
||||
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
||||
newX = MARGIN + BOX_WIDTH + maxX
|
||||
else:
|
||||
newX = MARGIN + BOX_WIDTH / 2
|
||||
return QPointF(newX, MARGIN + BOX_HEIGHT / 2)
|
||||
@ -415,8 +412,8 @@ class ModelerDialog(QgsModelDesignerDialog):
|
||||
for alg in list(self.model().childAlgorithms().values())
|
||||
]
|
||||
)
|
||||
newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
|
||||
newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE - BOX_HEIGHT)
|
||||
newX = MARGIN + BOX_WIDTH + maxX
|
||||
newY = MARGIN + BOX_HEIGHT + maxY
|
||||
else:
|
||||
newX = MARGIN + BOX_WIDTH / 2
|
||||
newY = MARGIN * 2 + BOX_HEIGHT + BOX_HEIGHT / 2
|
||||
|
@ -440,7 +440,7 @@ void QgsModelDesignerDialog::setModel( QgsProcessingModelAlgorithm *model )
|
||||
|
||||
mGroupEdit->setText( mModel->group() );
|
||||
mNameEdit->setText( mModel->displayName() );
|
||||
repaintModel();
|
||||
repaintModel( true );
|
||||
updateVariablesGui();
|
||||
|
||||
mView->centerOn( 0, 0 );
|
||||
@ -480,7 +480,6 @@ void QgsModelDesignerDialog::setModelScene( QgsModelGraphicsScene *scene )
|
||||
mScene->setModel( mModel.get() );
|
||||
mScene->setMessageBar( mMessageBar );
|
||||
|
||||
const QPointF center = mView->mapToScene( mView->viewport()->rect().center() );
|
||||
mView->setModelScene( mScene );
|
||||
|
||||
mSelectTool->resetCache();
|
||||
@ -499,8 +498,6 @@ void QgsModelDesignerDialog::setModelScene( QgsModelGraphicsScene *scene )
|
||||
connect( mScene, &QgsModelGraphicsScene::showChildAlgorithmOutputs, this, &QgsModelDesignerDialog::showChildAlgorithmOutputs );
|
||||
connect( mScene, &QgsModelGraphicsScene::showChildAlgorithmLog, this, &QgsModelDesignerDialog::showChildAlgorithmLog );
|
||||
|
||||
mView->centerOn( center );
|
||||
|
||||
if ( oldScene )
|
||||
oldScene->deleteLater();
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ QgsModelGraphicsScene::QgsModelGraphicsScene( QObject *parent )
|
||||
: QGraphicsScene( parent )
|
||||
{
|
||||
setItemIndexMethod( QGraphicsScene::NoIndex );
|
||||
|
||||
connect( this, &QgsModelGraphicsScene::componentChanged, this, &QgsModelGraphicsScene::updateBounds );
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm *QgsModelGraphicsScene::model()
|
||||
@ -60,6 +62,28 @@ void QgsModelGraphicsScene::mousePressEvent( QGraphicsSceneMouseEvent *event )
|
||||
QGraphicsScene::mousePressEvent( event );
|
||||
}
|
||||
|
||||
void QgsModelGraphicsScene::updateBounds()
|
||||
{
|
||||
//start with an empty rectangle
|
||||
QRectF bounds;
|
||||
|
||||
//add all items
|
||||
const QList<QGraphicsItem *> constItems = items();
|
||||
for ( QGraphicsItem *item : constItems )
|
||||
{
|
||||
QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item );
|
||||
if ( componentItem )
|
||||
bounds = bounds.united( componentItem->sceneBoundingRect() );
|
||||
}
|
||||
|
||||
if ( bounds.isValid() )
|
||||
{
|
||||
bounds.adjust( -SCENE_COMPONENT_MARGIN, -SCENE_COMPONENT_MARGIN, SCENE_COMPONENT_MARGIN, SCENE_COMPONENT_MARGIN );
|
||||
}
|
||||
|
||||
setSceneRect( bounds );
|
||||
}
|
||||
|
||||
QgsModelComponentGraphicItem *QgsModelGraphicsScene::createParameterGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelParameter *param ) const
|
||||
{
|
||||
return new QgsModelParameterGraphicItem( param, model, nullptr );
|
||||
|
@ -181,6 +181,15 @@ class GUI_EXPORT QgsModelGraphicsScene : public QGraphicsScene
|
||||
*/
|
||||
void requestRebuildRequired();
|
||||
|
||||
/**
|
||||
* Updates the scene rect based on the bounds of the model.
|
||||
|
||||
* The bounding rectangle of the model is calculated off all components of the model, with an additional margin arounds items.
|
||||
*
|
||||
* \since QGIS 3.44
|
||||
*/
|
||||
void updateBounds();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
@ -282,6 +291,8 @@ class GUI_EXPORT QgsModelGraphicsScene : public QGraphicsScene
|
||||
QMap<QString, QgsModelComponentGraphicItem *> mGroupBoxItems;
|
||||
QgsProcessingModelResult mLastResult;
|
||||
|
||||
static constexpr int SCENE_COMPONENT_MARGIN = 50;
|
||||
|
||||
QgsMessageBar *mMessageBar = nullptr;
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,9 @@ QgsModelGraphicsView::QgsModelGraphicsView( QWidget *parent )
|
||||
mMidMouseButtonPanTool = new QgsModelViewToolTemporaryMousePan( this );
|
||||
mSpaceZoomTool = new QgsModelViewToolTemporaryKeyZoom( this );
|
||||
|
||||
connect( horizontalScrollBar(), &QScrollBar::sliderReleased, this, [=] { friendlySetSceneRect(); } );
|
||||
connect( verticalScrollBar(), &QScrollBar::sliderReleased, this, [=] { friendlySetSceneRect(); } );
|
||||
|
||||
mSnapper.setSnapToGrid( true );
|
||||
}
|
||||
|
||||
@ -397,6 +400,8 @@ void QgsModelGraphicsView::setModelScene( QgsModelGraphicsScene *scene )
|
||||
{
|
||||
setScene( scene );
|
||||
|
||||
connect( scene, &QgsModelGraphicsScene::sceneRectChanged, this, [=] { friendlySetSceneRect(); } );
|
||||
|
||||
// IMPORTANT!
|
||||
// previous snap markers, snap lines are owned by previous layout - so don't delete them here!
|
||||
mSnapMarker = new QgsModelViewSnapMarker();
|
||||
@ -468,7 +473,6 @@ void QgsModelGraphicsView::endCommand()
|
||||
emit commandEnded();
|
||||
}
|
||||
|
||||
|
||||
void QgsModelGraphicsView::snapSelected()
|
||||
{
|
||||
QgsModelGraphicsScene *s = modelScene();
|
||||
@ -492,6 +496,21 @@ void QgsModelGraphicsView::snapSelected()
|
||||
endMacroCommand();
|
||||
}
|
||||
|
||||
void QgsModelGraphicsView::friendlySetSceneRect()
|
||||
{
|
||||
QRectF modelSceneRect = modelScene()->sceneRect();
|
||||
QRectF viewSceneRect = sceneRect();
|
||||
|
||||
QRectF visibleRect = mapToScene( viewport()->rect() ).boundingRect();
|
||||
|
||||
viewSceneRect.setLeft( std::min( modelSceneRect.left(), visibleRect.left() ) );
|
||||
viewSceneRect.setRight( std::max( modelSceneRect.right(), visibleRect.right() ) );
|
||||
viewSceneRect.setTop( std::min( modelSceneRect.top(), visibleRect.top() ) );
|
||||
viewSceneRect.setBottom( std::max( modelSceneRect.bottom(), visibleRect.bottom() ) );
|
||||
|
||||
setSceneRect( viewSceneRect );
|
||||
}
|
||||
|
||||
void QgsModelGraphicsView::copySelectedItems( QgsModelGraphicsView::ClipboardOperation operation )
|
||||
{
|
||||
copyItems( modelScene()->selectedComponentItems(), operation );
|
||||
|
@ -66,6 +66,16 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
|
||||
*/
|
||||
void setModelScene( QgsModelGraphicsScene *scene );
|
||||
|
||||
/**
|
||||
* Sets the scene rect used for scrollbar without disturbing the user
|
||||
* i.e:
|
||||
* - We growth the scene rect as the model growth
|
||||
* - We shrink only if the model scene rect is outside the current viewed viewport
|
||||
*
|
||||
* Called each time the view viewport moved or the model scene changed
|
||||
*/
|
||||
void friendlySetSceneRect();
|
||||
|
||||
/**
|
||||
* Returns the scene associated with the tool.
|
||||
* \see view()
|
||||
@ -158,12 +168,10 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
|
||||
void pasteItems( PasteMode mode );
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
* Snaps the selected items to the grid.
|
||||
*/
|
||||
void snapSelected();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
|
@ -81,6 +81,7 @@ void QgsModelViewToolPan::modelReleaseEvent( QgsModelViewMouseEvent *event )
|
||||
|
||||
mIsPanning = false;
|
||||
view()->viewport()->setCursor( Qt::OpenHandCursor );
|
||||
view()->friendlySetSceneRect();
|
||||
}
|
||||
|
||||
void QgsModelViewToolPan::deactivate()
|
||||
|
@ -37,6 +37,7 @@ void QgsModelViewToolTemporaryKeyPan::keyReleaseEvent( QKeyEvent *event )
|
||||
if ( event->key() == Qt::Key_Space && !event->isAutoRepeat() )
|
||||
{
|
||||
view()->setTool( mPreviousViewTool );
|
||||
view()->friendlySetSceneRect();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ void QgsModelViewToolTemporaryMousePan::modelReleaseEvent( QgsModelViewMouseEven
|
||||
if ( event->button() == Qt::MiddleButton )
|
||||
{
|
||||
view()->setTool( mPreviousViewTool );
|
||||
view()->friendlySetSceneRect();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11455,6 +11455,42 @@ void TestProcessingGui::testModelGraphicsView()
|
||||
// should not exist
|
||||
QVERIFY( !layerCommentItem );
|
||||
|
||||
//check model bounds
|
||||
scene2.updateBounds();
|
||||
QRectF modelRect = scene2.sceneRect();
|
||||
QGSCOMPARENEAR( modelRect.height(), 624.4, 3 ); // Sligtly higher threeshold because of various font size can marginally change the bounding rect
|
||||
QGSCOMPARENEAR( modelRect.width(), 655.00, 0.01 );
|
||||
QGSCOMPARENEAR( modelRect.left(), -252.0, 0.01 );
|
||||
QGSCOMPARENEAR( modelRect.top(), -232.0, 0.01 );
|
||||
|
||||
|
||||
// test model large modelRect
|
||||
QgsProcessingModelAlgorithm model2;
|
||||
|
||||
QgsProcessingModelChildAlgorithm algc2;
|
||||
algc2.setChildId( "buffer" );
|
||||
algc2.setAlgorithmId( "native:buffer" );
|
||||
algc2.setPosition( QPointF( 4250, 4250 ) );
|
||||
QgsProcessingModelParameter param1;
|
||||
param1.setParameterName( QStringLiteral( "LAYER" ) );
|
||||
param1.setSize( QSizeF( 500, 400 ) );
|
||||
param1.setPosition( QPointF( -250, -250 ) );
|
||||
model2.addModelParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "LAYER" ) ), param );
|
||||
algc2.addParameterSources( QStringLiteral( "INPUT" ), QList<QgsProcessingModelChildParameterSource>() << QgsProcessingModelChildParameterSource::fromModelParameter( QStringLiteral( "LAYER" ) ) );
|
||||
|
||||
model2.addChildAlgorithm( algc2 );
|
||||
|
||||
QgsModelGraphicsScene scene3;
|
||||
scene3.setModel( &model2 );
|
||||
scene3.createItems( &model2, context );
|
||||
|
||||
scene3.updateBounds();
|
||||
QRectF modelRect2 = scene3.sceneRect();
|
||||
QGSCOMPARENEAR( modelRect2.height(), 4505.4, 3 ); // Sligtly higher threeshold because of various font size can marginally change the bounding rect
|
||||
QGSCOMPARENEAR( modelRect2.width(), 4603.0, 0.01 );
|
||||
QGSCOMPARENEAR( modelRect2.left(), -201.0, 0.01 );
|
||||
QGSCOMPARENEAR( modelRect2.top(), -150.0, 0.01 );
|
||||
|
||||
|
||||
QgsModelGraphicsScene scene;
|
||||
QVERIFY( !scene.model() );
|
||||
|
Loading…
x
Reference in New Issue
Block a user