Skip to content

Commit c60a73c

Browse files
committedMar 21, 2017
[composer] Composer windows are created on demand and destroyed on close
Avoids having to create a window and all widgets for every composition when loading a project. Speeds up loading projects. Fix #15193
1 parent bfb15da commit c60a73c

File tree

4 files changed

+118
-447
lines changed

4 files changed

+118
-447
lines changed
 

‎src/app/composer/qgscomposer.cpp

Lines changed: 71 additions & 336 deletions
Large diffs are not rendered by default.

‎src/app/composer/qgscomposer.h

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "ui_qgscomposerbase.h"
2020

2121
#include "qgspanelwidget.h"
22+
#include "qgsvectorlayer.h"
23+
2224
class QgisApp;
2325
class QgsComposerArrow;
2426
class QgsComposerPolygon;
@@ -44,7 +46,6 @@ class QgsComposerItem;
4446
class QgsDockWidget;
4547
class QgsMapLayer;
4648
class QgsFeature;
47-
class QgsVectorLayer;
4849
class QgsPanelWidgetStack;
4950

5051
class QGridLayout;
@@ -76,7 +77,7 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
7677
Atlas
7778
};
7879

79-
QgsComposer( QgisApp *qgis, const QString &title );
80+
QgsComposer( QgsComposition *composition );
8081
~QgsComposer();
8182

8283
//! Set the pixmap / icons on the toolbar buttons
@@ -102,8 +103,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
102103
//! Restore the window and toolbar state
103104
void restoreWindowState();
104105

105-
QAction *windowAction() {return mWindowAction;}
106-
107106
QString title() const {return mTitle;}
108107
void setTitle( const QString &title );
109108

@@ -137,15 +136,15 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
137136
virtual void showEvent( QShowEvent *event ) override;
138137
#endif
139138

140-
virtual void changeEvent( QEvent *ev ) override;
141-
142139
signals:
143140
//! Is emitted every time the view zoom has changed
144141
void zoomLevelChanged();
145142

146143
//! Is emitted when the atlas preview feature changes
147144
void atlasPreviewFeatureChanged();
148145

146+
void aboutToClose();
147+
149148
public slots:
150149

151150
//! Zoom to full extent of the paper
@@ -434,18 +433,10 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
434433
//! Shows the configuration widget for a composer item
435434
void showItemOptions( QgsComposerItem *i );
436435

437-
//XML, usually connected with QgsProject::readProject and QgsProject::writeProject
438-
439-
//! Stores state in Dom node
440-
void writeXml( QDomDocument &doc );
441436

442437
//! Stores only template as base Dom node
443438
void templateXml( QDomDocument &doc );
444439

445-
//! Sets state from Dom document
446-
void readXml( const QDomDocument &doc );
447-
void readXml( const QDomElement &composerElem, const QDomDocument &doc, bool fromTemplate = false );
448-
449440
void setSelectionTool();
450441

451442
//! Raise, unminimize and activate this window
@@ -481,9 +472,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
481472
//! Creates the composition widget
482473
void createCompositionWidget();
483474

484-
//! Sets up the compositions undo/redo connections
485-
void setupUndoView();
486-
487475
//! True if a composer map contains a WMS layer
488476
bool containsWmsLayer() const;
489477

@@ -505,10 +493,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
505493
//! Removes all the item from the graphics scene and deletes them
506494
void deleteItemWidgets();
507495

508-
//! Restores composer map preview states.
509-
//! Initially after reading from xml, states are set to rectangle to achieve faster project loading.
510-
void restoreComposerMapStates();
511-
512496
//! Create composer view and rulers
513497
void createComposerView();
514498

@@ -578,17 +562,14 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
578562
//! To know which item to show if selection changes
579563
QMap<QgsComposerItem *, QgsPanelWidget *> mItemWidgetMap;
580564

581-
//! Window menu action to select this window
582-
QAction *mWindowAction = nullptr;
583-
584565
//! Copy/cut/paste actions
585566
QAction *mActionCut = nullptr;
586567
QAction *mActionCopy = nullptr;
587568
QAction *mActionPaste = nullptr;
588569

589570
//! Page & Printer Setup
590571
QPrinter *mPrinter = nullptr;
591-
bool mSetPageOrientation;
572+
bool mSetPageOrientation = false;
592573

593574
QUndoView *mUndoView = nullptr;
594575

@@ -601,9 +582,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
601582

602583
QComboBox *mAtlasPageComboBox = nullptr;
603584

604-
//! We load composer map content from project xml only on demand. Therefore we need to store the real preview mode type
605-
QMap< QgsComposerMap *, int > mMapsToRestore;
606-
607585
QgsDockWidget *mItemDock = nullptr;
608586
QgsPanelWidgetStack *mItemPropertiesStack = nullptr;
609587
QgsDockWidget *mUndoDock = nullptr;
@@ -682,9 +660,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
682660
void activateProtanopePreview();
683661
void activateDeuteranopePreview();
684662

685-
//! Sets the composition for the composer window
686-
void setComposition( QgsComposition *composition );
687-
688663
void dockVisibilityChanged( bool visible );
689664

690665
/** Repopulates the atlas page combo box with valid items.

‎src/app/qgisapp.cpp

Lines changed: 39 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2938,6 +2938,9 @@ void QgisApp::setupConnections()
29382938

29392939
// setup undo/redo actions
29402940
connect( mUndoWidget, SIGNAL( undoStackChanged() ), this, SLOT( updateUndoActions() ) );
2941+
2942+
connect( mPrintComposersMenu, &QMenu::aboutToShow, this, &QgisApp::composerMenuAboutToShow );
2943+
connect( QgsProject::instance()->layoutManager(), &QgsLayoutManager::compositionAboutToBeRemoved, this, &QgisApp::compositionAboutToBeRemoved );
29412944
}
29422945

29432946
void QgisApp::createCanvasTools()
@@ -6980,40 +6983,35 @@ QgsComposer *QgisApp::createNewComposer( QString title )
69806983
{
69816984
title = tr( "Composer %1" ).arg( mLastComposerId );
69826985
}
6983-
//create new composer object
6984-
QgsComposer *newComposerObject = new QgsComposer( this, title );
6986+
//create new composition object
6987+
QgsComposition *composition = new QgsComposition( QgsProject::instance() );
6988+
composition->setName( title );
6989+
QgsProject::instance()->layoutManager()->addComposition( composition );
6990+
6991+
QgsComposer *newComposerObject = new QgsComposer( composition );
6992+
connect( newComposerObject, &QgsComposer::aboutToClose, this, [this, newComposerObject]
6993+
{
6994+
emit composerWillBeRemoved( newComposerObject->view() );
6995+
mPrintComposers.remove( newComposerObject );
6996+
emit composerRemoved( newComposerObject->view() );
6997+
} );
69856998

69866999
//add it to the map of existing print composers
69877000
mPrintComposers.insert( newComposerObject );
6988-
//and place action into print composers menu
6989-
mPrintComposersMenu->addAction( newComposerObject->windowAction() );
7001+
69907002
newComposerObject->open();
69917003
emit composerAdded( newComposerObject->view() );
69927004
connect( newComposerObject, &QgsComposer::atlasPreviewFeatureChanged, this, &QgisApp::refreshMapCanvas );
6993-
markDirty();
7005+
69947006
return newComposerObject;
69957007
}
69967008

69977009
void QgisApp::deleteComposer( QgsComposer *c )
69987010
{
69997011
emit composerWillBeRemoved( c->view() );
70007012
mPrintComposers.remove( c );
7001-
mPrintComposersMenu->removeAction( c->windowAction() );
7002-
markDirty();
70037013
emit composerRemoved( c->view() );
7004-
7005-
//save a reference to the composition
7006-
QgsComposition *composition = c->composition();
7007-
7008-
//first, delete the composer. This must occur before deleting the composition as some of the cleanup code in
7009-
//composer or in composer item widgets may require the composition to still be around
70107014
delete c;
7011-
7012-
//next, delete the composition
7013-
if ( composition )
7014-
{
7015-
delete composition;
7016-
}
70177015
}
70187016

70197017
QgsComposer *QgisApp::duplicateComposer( QgsComposer *currentComposer, QString title )
@@ -7057,48 +7055,6 @@ QgsComposer *QgisApp::duplicateComposer( QgsComposer *currentComposer, QString t
70577055
return newComposer;
70587056
}
70597057

7060-
bool QgisApp::loadComposersFromProject( const QDomDocument &doc )
7061-
{
7062-
if ( doc.isNull() )
7063-
{
7064-
return false;
7065-
}
7066-
7067-
//restore each composer
7068-
QDomNodeList composerNodes = doc.elementsByTagName( QStringLiteral( "Composer" ) );
7069-
for ( int i = 0; i < composerNodes.size(); ++i )
7070-
{
7071-
QString title( composerNodes.at( i ).toElement().attribute( QStringLiteral( "title" ) ) );
7072-
showStatusMessage( tr( "Loading composer %1" ).arg( title ) );
7073-
showProgress( i, composerNodes.size() );
7074-
++mLastComposerId;
7075-
7076-
QTime t;
7077-
t.start();
7078-
QgsComposer *composer = new QgsComposer( this, tr( "Composer %1" ).arg( mLastComposerId ) );
7079-
composer->readXml( composerNodes.at( i ).toElement(), doc );
7080-
mPrintComposers.insert( composer );
7081-
mPrintComposersMenu->addAction( composer->windowAction() );
7082-
#ifndef Q_OS_MACX
7083-
composer->setWindowState( Qt::WindowMinimized );
7084-
#endif
7085-
composer->zoomFull();
7086-
QgsComposerView *composerView = composer->view();
7087-
if ( composerView )
7088-
{
7089-
composerView->updateRulers();
7090-
}
7091-
emit composerAdded( composer->view() );
7092-
connect( composer, &QgsComposer::atlasPreviewFeatureChanged, this, &QgisApp::refreshMapCanvas );
7093-
7094-
QgsDebugMsg( QString( "Loaded composer %1: %2ms" ).arg( title ).arg( t.elapsed() ) );
7095-
}
7096-
7097-
showProgress( 0, 0 );
7098-
7099-
return true;
7100-
}
7101-
71027058
void QgisApp::deletePrintComposers()
71037059
{
71047060
QSet<QgsComposer *>::iterator it = mPrintComposers.begin();
@@ -7108,28 +7064,20 @@ void QgisApp::deletePrintComposers()
71087064
emit composerWillBeRemoved( c->view() );
71097065
it = mPrintComposers.erase( it );
71107066
emit composerRemoved( c->view() );
7111-
7112-
//save a reference to the composition
7113-
QgsComposition *composition = c->composition();
7114-
7115-
//first, delete the composer. This must occur before deleting the composition as some of the cleanup code in
7116-
//composer or in composer item widgets may require the composition to still be around
71177067
delete ( c );
7118-
7119-
//next, delete the composition
7120-
if ( composition )
7121-
{
7122-
delete composition;
7123-
}
71247068
}
71257069
mLastComposerId = 0;
7126-
markDirty();
71277070
}
71287071

7129-
void QgisApp::on_mPrintComposersMenu_aboutToShow()
7072+
void QgisApp::composerMenuAboutToShow()
71307073
{
7131-
QList<QAction *> acts = mPrintComposersMenu->actions();
71327074
mPrintComposersMenu->clear();
7075+
QList<QAction *> acts;
7076+
Q_FOREACH ( QgsComposition *c, QgsProject::instance()->layoutManager()->compositions() )
7077+
{
7078+
7079+
7080+
}
71337081
if ( acts.size() > 1 )
71347082
{
71357083
// sort actions by text
@@ -7138,6 +7086,21 @@ void QgisApp::on_mPrintComposersMenu_aboutToShow()
71387086
mPrintComposersMenu->addActions( acts );
71397087
}
71407088

7089+
void QgisApp::compositionAboutToBeRemoved( const QString &name )
7090+
{
7091+
Q_FOREACH ( QgsComposer *composer, mPrintComposers )
7092+
{
7093+
if ( composer->composition()->name() == name )
7094+
{
7095+
emit composerWillBeRemoved( composer->view() );
7096+
mPrintComposers.remove( composer );
7097+
emit composerRemoved( composer->view() );
7098+
delete composer;
7099+
return;
7100+
}
7101+
}
7102+
}
7103+
71417104
void QgisApp::showPinnedLabels( bool show )
71427105
{
71437106
qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels )->showPinnedLabels( show );

‎src/app/qgisapp.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,11 +1362,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
13621362

13631363
void showStyleManager();
13641364

1365-
//! Creates the composer instances in a project file and adds them to the menu
1366-
bool loadComposersFromProject( const QDomDocument &doc );
1367-
13681365
//! Slot to handle display of composers menu, e.g. sorting
1369-
void on_mPrintComposersMenu_aboutToShow();
1366+
void composerMenuAboutToShow();
1367+
void compositionAboutToBeRemoved( const QString &name );
13701368

13711369
//! Toggles whether to show pinned labels
13721370
void showPinnedLabels( bool show );

0 commit comments

Comments
 (0)
Please sign in to comment.