Skip to content

Commit 4897cde

Browse files
author
mhugent
committedOct 29, 2009
[FEATURE]: Possibility to have several composers in one project
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@11865 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

10 files changed

+553
-317
lines changed

10 files changed

+553
-317
lines changed
 
1.19 KB
Loading

‎src/app/composer/qgscomposer.cpp

Lines changed: 175 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@
6565
#include <QSizeGrip>
6666
#include "qgslogger.h"
6767

68-
QgsComposer::QgsComposer( QgisApp *qgis ): QMainWindow(), mFirstPaint( true )
68+
QgsComposer::QgsComposer( QgisApp *qgis, const QString& id ): QMainWindow(), mId( id )
6969
{
7070
setupUi( this );
71+
setAttribute( Qt::WA_DeleteOnClose );
7172
setupTheme();
7273

7374
QToolButton* orderingToolButton = new QToolButton( this );
@@ -106,7 +107,7 @@ QgsComposer::QgsComposer( QgisApp *qgis ): QMainWindow(), mFirstPaint( true )
106107
toggleActionGroup->addAction( mActionSelectMoveItem );
107108
toggleActionGroup->setExclusive( true );
108109

109-
setWindowTitle( tr( "QGIS - print composer" ) );
110+
setWindowTitle( mId );
110111

111112
mActionAddNewMap->setCheckable( true );
112113
mActionAddNewLabel->setCheckable( true );
@@ -116,17 +117,21 @@ QgsComposer::QgsComposer( QgisApp *qgis ): QMainWindow(), mFirstPaint( true )
116117
mActionAddImage->setCheckable( true );
117118
mActionMoveItemContent->setCheckable( true );
118119

120+
#ifdef Q_WS_MAC
119121
QMenu *appMenu = menuBar()->addMenu( tr( "QGIS" ) );
120122
appMenu->addAction( QgisApp::instance()->actionAbout() );
121123
appMenu->addAction( QgisApp::instance()->actionOptions() );
124+
#endif
122125

123126
QMenu *fileMenu = menuBar()->addMenu( tr( "File" ) );
124-
fileMenu->addAction( tr( "Close" ), this, SLOT( close() ), tr( "Ctrl+W" ) );
125127
fileMenu->addAction( mActionExportAsImage );
126128
fileMenu->addAction( mActionExportAsPDF );
127129
fileMenu->addAction( mActionExportAsSVG );
128130
fileMenu->addSeparator();
129131
fileMenu->addAction( mActionPrint );
132+
fileMenu->addSeparator();
133+
fileMenu->addAction( mActionQuit );
134+
QObject::connect( mActionQuit, SIGNAL( triggered() ), this, SLOT( close() ) );
130135

131136
QMenu *viewMenu = menuBar()->addMenu( tr( "View" ) );
132137
viewMenu->addAction( mActionZoomIn );
@@ -159,14 +164,13 @@ QgsComposer::QgsComposer( QgisApp *qgis ): QMainWindow(), mFirstPaint( true )
159164
#endif
160165
#endif
161166

167+
mQgis = qgis;
168+
mFirstTime = true;
162169

163-
// Create action to select this window and add it to Window menu
170+
// Create action to select this window
164171
mWindowAction = new QAction( windowTitle(), this );
165172
connect( mWindowAction, SIGNAL( triggered() ), this, SLOT( activate() ) );
166173

167-
mQgis = qgis;
168-
mFirstTime = true;
169-
170174
QgsDebugMsg( "entered." );
171175

172176
setMouseTracking( true );
@@ -188,8 +192,6 @@ QgsComposer::QgsComposer( QgisApp *qgis ): QMainWindow(), mFirstPaint( true )
188192
mCompositionOptionsLayout->setMargin( 0 );
189193
mCompositionOptionsLayout->addWidget( compositionWidget );
190194

191-
mPrinter = 0;
192-
193195
QGridLayout *l = new QGridLayout( mViewFrame );
194196
l->setMargin( 0 );
195197
l->addWidget( mView, 0, 0 );
@@ -206,10 +208,9 @@ QgsComposer::QgsComposer( QgisApp *qgis ): QMainWindow(), mFirstPaint( true )
206208

207209
mView->setFocus();
208210

209-
//connect with signals from QgsProject to read/write project files
211+
//connect with signals from QgsProject to write project files
210212
if ( QgsProject::instance() )
211213
{
212-
connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument& ) ), this, SLOT( readXML( const QDomDocument& ) ) );
213214
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument& ) ), this, SLOT( writeXML( QDomDocument& ) ) );
214215
}
215216
}
@@ -229,6 +230,7 @@ void QgsComposer::setupTheme()
229230
{
230231
//now set all the icons - getThemeIcon will fall back to default theme if its
231232
//missing from active theme
233+
mActionQuit->setIcon( QgisApp::getThemeIcon( "/mActionFileExit.png" ) );
232234
mActionLoadFromTemplate->setIcon( QgisApp::getThemeIcon( "/mActionFileOpen.png" ) );
233235
mActionSaveAsTemplate->setIcon( QgisApp::getThemeIcon( "/mActionFileSaveAs.png" ) );
234236
mActionExportAsImage->setIcon( QgisApp::getThemeIcon( "/mActionSaveMapAsImage.png" ) );
@@ -290,36 +292,33 @@ void QgsComposer::open( void )
290292
}
291293
}
292294

293-
void QgsComposer::paintEvent( QPaintEvent* event )
294-
{
295-
QMainWindow::paintEvent( event );
296-
#if 0 //MH: disabled for now as there are segfaults on some systems
297-
//The cached content of the composer maps need to be recreated it is the first paint event of the composer after reading from XML file.
298-
//Otherwise the resolution of the composer map is not suitable for screen
299-
if ( mFirstPaint )
300-
{
301-
QMap<QgsComposerItem*, QWidget*>::iterator it = mItemWidgetMap.begin();
302-
for ( ; it != mItemWidgetMap.constEnd(); ++it )
303-
{
304-
QgsComposerMap* cm = qobject_cast<QgsComposerMap *>( it.key() );
305-
if ( cm )
306-
{
307-
mFirstPaint = false;
308-
cm->cache();
309-
cm->update();
310-
}
311-
}
312-
}
313-
#endif //0
314-
}
315-
316295
void QgsComposer::activate()
317296
{
318297
raise();
319298
setWindowState( windowState() & ~Qt::WindowMinimized );
320299
activateWindow();
321300
}
322301

302+
void QgsComposer::closeEvent( QCloseEvent *event )
303+
{
304+
if ( QMessageBox::warning( 0, tr( "Remove composer?" ), tr( "Do you really want to remove the composer instance '%1'?" ).arg( mId ), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Ok )
305+
{
306+
mQgis->checkOutComposer( this );
307+
event->accept();
308+
}
309+
else
310+
{
311+
event->ignore();
312+
}
313+
#if 0
314+
QMainWindow::closeEvent( event );
315+
if ( event->isAccepted() )
316+
{
317+
QgisApp::instance()->removeWindow( mWindowAction );
318+
}
319+
#endif //0
320+
}
321+
323322
#ifdef Q_WS_MAC
324323
void QgsComposer::changeEvent( QEvent* event )
325324
{
@@ -338,15 +337,6 @@ void QgsComposer::changeEvent( QEvent* event )
338337
}
339338
}
340339

341-
void QgsComposer::closeEvent( QCloseEvent *event )
342-
{
343-
QMainWindow::closeEvent( event );
344-
if ( event->isAccepted() )
345-
{
346-
QgisApp::instance()->removeWindow( mWindowAction );
347-
}
348-
}
349-
350340
void QgsComposer::showEvent( QShowEvent *event )
351341
{
352342
QMainWindow::showEvent( event );
@@ -1031,6 +1021,7 @@ void QgsComposer::writeXML( QDomDocument& doc )
10311021
void QgsComposer::writeXML( QDomNode& parentNode, QDomDocument& doc )
10321022
{
10331023
QDomElement composerElem = doc.createElement( "Composer" );
1024+
composerElem.setAttribute( "id", mId );
10341025
parentNode.appendChild( composerElem );
10351026

10361027
//store composer items:
@@ -1049,6 +1040,145 @@ void QgsComposer::writeXML( QDomNode& parentNode, QDomDocument& doc )
10491040
}
10501041
}
10511042

1043+
void QgsComposer::readXML( const QDomDocument& doc )
1044+
{
1045+
QDomNodeList composerNodeList = doc.elementsByTagName( "Composer" );
1046+
if ( composerNodeList.size() < 1 )
1047+
{
1048+
return;
1049+
}
1050+
readXML( composerNodeList.at( 0 ).toElement(), doc );
1051+
}
1052+
1053+
void QgsComposer::readXML( const QDomElement& composerElem, const QDomDocument& doc )
1054+
{
1055+
mId = composerElem.attribute( "id", "" );
1056+
setWindowTitle( mId );
1057+
1058+
// Create action to select this window
1059+
delete mWindowAction;
1060+
mWindowAction = new QAction( windowTitle(), this );
1061+
connect( mWindowAction, SIGNAL( triggered() ), this, SLOT( activate() ) );
1062+
1063+
//delete composer view and composition
1064+
delete mView;
1065+
mView = 0;
1066+
//delete every child of mViewFrame
1067+
QObjectList viewFrameChildren = mViewFrame->children();
1068+
QObjectList::iterator it = viewFrameChildren.begin();
1069+
for ( ; it != viewFrameChildren.end(); ++it )
1070+
{
1071+
delete( *it );
1072+
}
1073+
//delete composition widget
1074+
QgsCompositionWidget* oldCompositionWidget = qobject_cast<QgsCompositionWidget *>( mCompositionOptionsFrame->children().at( 0 ) );
1075+
delete oldCompositionWidget;
1076+
delete mCompositionOptionsLayout;
1077+
mCompositionOptionsLayout = 0;
1078+
1079+
mView = new QgsComposerView( mViewFrame );
1080+
connectSlots();
1081+
1082+
mComposition = new QgsComposition( mQgis->mapCanvas()->mapRenderer() );
1083+
mComposition->readXML( composerElem, doc );
1084+
1085+
QGridLayout *l = new QGridLayout( mViewFrame );
1086+
l->setMargin( 0 );
1087+
l->addWidget( mView, 0, 0 );
1088+
1089+
//create compositionwidget
1090+
QgsCompositionWidget* compositionWidget = new QgsCompositionWidget( mCompositionOptionsFrame, mComposition );
1091+
QObject::connect( mComposition, SIGNAL( paperSizeChanged() ), compositionWidget, SLOT( displayCompositionWidthHeight() ) );
1092+
compositionWidget->show();
1093+
1094+
mCompositionOptionsLayout = new QGridLayout( mCompositionOptionsFrame );
1095+
mCompositionOptionsLayout->setMargin( 0 );
1096+
mCompositionOptionsLayout->addWidget( compositionWidget );
1097+
1098+
//read and restore all the items
1099+
1100+
//composer labels
1101+
QDomNodeList composerLabelList = composerElem.elementsByTagName( "ComposerLabel" );
1102+
for ( int i = 0; i < composerLabelList.size(); ++i )
1103+
{
1104+
QDomElement currentComposerLabelElem = composerLabelList.at( i ).toElement();
1105+
QgsComposerLabel* newLabel = new QgsComposerLabel( mComposition );
1106+
newLabel->readXML( currentComposerLabelElem, doc );
1107+
addComposerLabel( newLabel );
1108+
mComposition->addItem( newLabel );
1109+
mComposition->update();
1110+
mComposition->clearSelection();
1111+
newLabel->setSelected( true );
1112+
showItemOptions( newLabel );
1113+
}
1114+
1115+
//composer maps
1116+
QDomNodeList composerMapList = composerElem.elementsByTagName( "ComposerMap" );
1117+
for ( int i = 0; i < composerMapList.size(); ++i )
1118+
{
1119+
QDomElement currentComposerMapElem = composerMapList.at( i ).toElement();
1120+
QgsComposerMap* newMap = new QgsComposerMap( mComposition );
1121+
newMap->readXML( currentComposerMapElem, doc );
1122+
addComposerMap( newMap );
1123+
mComposition->addItem( newMap );
1124+
mComposition->update();
1125+
mComposition->clearSelection();
1126+
newMap->setSelected( true );
1127+
showItemOptions( newMap );
1128+
}
1129+
1130+
//composer scalebars
1131+
QDomNodeList composerScaleBarList = composerElem.elementsByTagName( "ComposerScaleBar" );
1132+
for ( int i = 0; i < composerScaleBarList.size(); ++i )
1133+
{
1134+
QDomElement currentScaleBarElem = composerScaleBarList.at( i ).toElement();
1135+
QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( mComposition );
1136+
newScaleBar->readXML( currentScaleBarElem, doc );
1137+
addComposerScaleBar( newScaleBar );
1138+
mComposition->addItem( newScaleBar );
1139+
mComposition->update();
1140+
mComposition->clearSelection();
1141+
newScaleBar->setSelected( true );
1142+
showItemOptions( newScaleBar );
1143+
}
1144+
1145+
//composer legends
1146+
QDomNodeList composerLegendList = composerElem.elementsByTagName( "ComposerLegend" );
1147+
for ( int i = 0; i < composerLegendList.size(); ++i )
1148+
{
1149+
QDomElement currentLegendElem = composerLegendList.at( i ).toElement();
1150+
QgsComposerLegend* newLegend = new QgsComposerLegend( mComposition );
1151+
newLegend->readXML( currentLegendElem, doc );
1152+
addComposerLegend( newLegend );
1153+
mComposition->addItem( newLegend );
1154+
mComposition->update();
1155+
mComposition->clearSelection();
1156+
newLegend->setSelected( true );
1157+
showItemOptions( newLegend );
1158+
}
1159+
1160+
//composer pictures
1161+
QDomNodeList composerPictureList = composerElem.elementsByTagName( "ComposerPicture" );
1162+
for ( int i = 0; i < composerPictureList.size(); ++i )
1163+
{
1164+
QDomElement currentPictureElem = composerPictureList.at( i ).toElement();
1165+
QgsComposerPicture* newPicture = new QgsComposerPicture( mComposition );
1166+
newPicture->readXML( currentPictureElem, doc );
1167+
addComposerPicture( newPicture );
1168+
mComposition->addItem( newPicture );
1169+
mComposition->update();
1170+
mComposition->clearSelection();
1171+
newPicture->setSelected( true );
1172+
showItemOptions( newPicture );
1173+
}
1174+
1175+
mComposition->sortZList();
1176+
mView->setComposition( mComposition );
1177+
1178+
setSelectionTool();
1179+
}
1180+
1181+
#if 0
10521182
void QgsComposer::readXML( const QDomDocument& doc )
10531183
{
10541184
//look for Composer element
@@ -1058,6 +1188,7 @@ void QgsComposer::readXML( const QDomDocument& doc )
10581188
return; //nothing to do...
10591189
}
10601190
QDomElement composerElem = nl.at( 0 ).toElement();
1191+
mId = composerElem.attribute( "id", "" );
10611192

10621193
//look for Composition element
10631194
QDomNodeList cnl = composerElem.elementsByTagName( "Composition" );
@@ -1187,6 +1318,7 @@ void QgsComposer::readXML( const QDomDocument& doc )
11871318

11881319
setSelectionTool();
11891320
}
1321+
#endif //0
11901322

11911323
void QgsComposer::addComposerMap( QgsComposerMap* map )
11921324
{

‎src/app/composer/qgscomposer.h

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class QgsComposition;
3131
class QgsMapCanvas;
3232

3333
class QGridLayout;
34-
class QPrinter;
3534
class QDomNode;
3635
class QDomDocument;
3736
class QMoveEvent;
@@ -47,7 +46,7 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
4746
Q_OBJECT
4847

4948
public:
50-
QgsComposer( QgisApp *qgis );
49+
QgsComposer( QgisApp *qgis, const QString& id );
5150
~QgsComposer();
5251

5352
//! Set the pixmap / icons on the toolbar buttons
@@ -74,20 +73,24 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
7473
//! Restore the window and toolbar state
7574
void restoreWindowState();
7675

76+
QAction* windowAction() {return mWindowAction;}
77+
78+
QString id() const {return mId;}
79+
7780
protected:
7881
//! Move event
7982
virtual void moveEvent( QMoveEvent * );
8083

8184
//! Resize event
8285
virtual void resizeEvent( QResizeEvent * );
8386

87+
//! Close event (remove window from menu)
88+
virtual void closeEvent( QCloseEvent * );
89+
8490
#ifdef Q_WS_MAC
8591
//! Change event (update window menu on ActivationChange)
8692
virtual void changeEvent( QEvent * );
8793

88-
//! Close event (remove window from menu)
89-
virtual void closeEvent( QCloseEvent * );
90-
9194
//! Show event (add window to menu)
9295
virtual void showEvent( QShowEvent * );
9396
#endif
@@ -218,13 +221,10 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
218221

219222
//! Sets state from Dom document
220223
void readXML( const QDomDocument& doc );
224+
void readXML( const QDomElement& composerElem, const QDomDocument& doc );
221225

222226
void setSelectionTool();
223227

224-
protected:
225-
226-
void paintEvent( QPaintEvent* event );
227-
228228
private slots:
229229

230230
//! Raise, unminimize and activate this window
@@ -235,9 +235,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
235235
/**Establishes the signal slot connection for the class*/
236236
void connectSlots();
237237

238-
//! returns new world matrix for canvas view after zoom with factor scaleChange
239-
QMatrix updateMatrix( double scaleChange );
240-
241238
//! True if a composer map contains a WMS layer
242239
bool containsWMSLayer() const;
243240

@@ -252,15 +249,16 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
252249

253250
//! Writes state under DOM element
254251
void writeXML( QDomNode& parentNode, QDomDocument& doc );
252+
253+
/**Identification string*/
254+
QString mId;
255+
255256
//! Pointer to composer view
256257
QgsComposerView *mView;
257258

258259
//! Current composition
259260
QgsComposition *mComposition;
260261

261-
//! Printer
262-
QPrinter *mPrinter;
263-
264262
//! Pointer to QGIS application
265263
QgisApp *mQgis;
266264

@@ -282,9 +280,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
282280
//! Window menu action to select this window
283281
QAction *mWindowAction;
284282

285-
/**False if first paint already happened (used to create cache of composer maps for screen resolution after reading from project files)*/
286-
bool mFirstPaint;
287-
288283
//! Help context id
289284
static const int context_id = 985715179;
290285

‎src/app/composer/qgscomposermapwidget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,5 +702,6 @@ void QgsComposerMapWidget::on_mCoordinatePrecisionSpinBox_valueChanged( int valu
702702
return;
703703
}
704704
mComposerMap->setGridAnnotationPrecision( value );
705+
mComposerMap->updateBoundingRect();
705706
mComposerMap->update();
706707
}

‎src/app/qgisapp.cpp

Lines changed: 121 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ QgisApp *QgisApp::smInstance = 0;
327327
QgisApp::QgisApp( QSplashScreen *splash, QWidget * parent, Qt::WFlags fl )
328328
: QMainWindow( parent, fl ),
329329
mSplash( splash ),
330-
mComposer( 0 ),
331330
mPythonConsole( NULL ),
332331
mPythonUtils( NULL )
333332
{
@@ -372,7 +371,6 @@ QgisApp::QgisApp( QSplashScreen *splash, QWidget * parent, Qt::WFlags fl )
372371
readSettings();
373372
updateRecentProjectPaths();
374373

375-
mComposer = new QgsComposer( this ); // Map composer
376374
mInternalClipboard = new QgsClipboard; // create clipboard
377375
mQgisInterface = new QgisAppInterface( this ); // create the interfce
378376

@@ -464,9 +462,9 @@ QgisApp::QgisApp( QSplashScreen *splash, QWidget * parent, Qt::WFlags fl )
464462
qApp->processEvents();
465463
//finally show all the application settings as initialised above
466464

467-
QgsDebugMsg( "\n\n\nApplication Settings:\n--------------------------\n");
465+
QgsDebugMsg( "\n\n\nApplication Settings:\n--------------------------\n" );
468466
QgsDebugMsg( QgsApplication::showSettings() );
469-
QgsDebugMsg( "\n--------------------------\n\n\n");
467+
QgsDebugMsg( "\n--------------------------\n\n\n" );
470468
mMapCanvas->freeze( false );
471469
} // QgisApp ctor
472470

@@ -503,6 +501,8 @@ QgisApp::~QgisApp()
503501
delete mPythonConsole;
504502
delete mPythonUtils;
505503

504+
deletePrintComposers();
505+
506506
// delete map layer registry and provider registry
507507
QgsApplication::exitQgis();
508508
}
@@ -591,10 +591,10 @@ void QgisApp::createActions()
591591
mActionSaveMapAsImage->setStatusTip( tr( "Save map as image" ) );
592592
connect( mActionSaveMapAsImage, SIGNAL( triggered() ), this, SLOT( saveMapAsImage() ) );
593593

594-
mActionPrintComposer = new QAction( getThemeIcon( "mActionFilePrint.png" ), tr( "&Print Composer" ), this );
595-
shortcuts->registerAction( mActionPrintComposer, tr( "Ctrl+P", "Print Composer" ) );
596-
mActionPrintComposer->setStatusTip( tr( "Print Composer" ) );
597-
connect( mActionPrintComposer, SIGNAL( triggered() ), this, SLOT( filePrint() ) );
594+
mActionNewPrintComposer = new QAction( getThemeIcon( "mActionFilePrint.png" ), tr( "&New Print Composer" ), this );
595+
shortcuts->registerAction( mActionNewPrintComposer, tr( "Ctrl+P", "New Print Composer" ) );
596+
mActionNewPrintComposer->setStatusTip( tr( "New Print Composer" ) );
597+
connect( mActionNewPrintComposer, SIGNAL( triggered() ), this, SLOT( newPrintComposer() ) );
598598

599599
mActionExit = new QAction( getThemeIcon( "mActionFileExit.png" ), tr( "Exit" ), this );
600600
shortcuts->registerAction( mActionExit, tr( "Ctrl+Q", "Exit QGIS" ) );
@@ -1166,7 +1166,7 @@ void QgisApp::createMenus()
11661166
mActionFileSeparator3 = mFileMenu->addSeparator();
11671167
}
11681168

1169-
mFileMenu->addAction( mActionPrintComposer );
1169+
mFileMenu->addAction( mActionNewPrintComposer );
11701170
mActionFileSeparator4 = mFileMenu->addSeparator();
11711171

11721172
mFileMenu->addAction( mActionExit );
@@ -1332,6 +1332,10 @@ void QgisApp::createMenus()
13321332
mActionWindowSeparator2 = mWindowMenu->addSeparator();
13331333
#endif
13341334

1335+
//Print composers menu
1336+
1337+
mPrintComposersMenu = menuBar()->addMenu( tr( "Print Composers" ) );
1338+
13351339
// Help Menu
13361340

13371341
menuBar()->addSeparator();
@@ -1364,7 +1368,7 @@ void QgisApp::createToolBars()
13641368
mFileToolBar->addAction( mActionOpenProject );
13651369
mFileToolBar->addAction( mActionSaveProject );
13661370
mFileToolBar->addAction( mActionSaveProjectAs );
1367-
mFileToolBar->addAction( mActionPrintComposer );
1371+
mFileToolBar->addAction( mActionNewPrintComposer );
13681372
mFileToolBar->addAction( mActionAddOgrLayer );
13691373
mFileToolBar->addAction( mActionAddRasterLayer );
13701374
#ifdef HAVE_POSTGRESQL
@@ -1629,7 +1633,7 @@ void QgisApp::setTheme( QString theThemeName )
16291633
mActionOpenProject->setIcon( getThemeIcon( "/mActionFileOpen.png" ) );
16301634
mActionSaveProject->setIcon( getThemeIcon( "/mActionFileSave.png" ) );
16311635
mActionSaveProjectAs->setIcon( getThemeIcon( "/mActionFileSaveAs.png" ) );
1632-
mActionPrintComposer->setIcon( getThemeIcon( "/mActionFilePrint.png" ) );
1636+
mActionNewPrintComposer->setIcon( getThemeIcon( "/mActionNewComposer.png" ) );
16331637
mActionSaveMapAsImage->setIcon( getThemeIcon( "/mActionSaveMapAsImage.png" ) );
16341638
mActionExit->setIcon( getThemeIcon( "/mActionFileExit.png" ) );
16351639
mActionAddOgrLayer->setIcon( getThemeIcon( "/mActionAddOgrLayer.png" ) );
@@ -1695,10 +1699,13 @@ void QgisApp::setTheme( QString theThemeName )
16951699
mActionAddWmsLayer->setIcon( getThemeIcon( "/mActionAddWmsLayer.png" ) );
16961700
mActionAddToOverview->setIcon( getThemeIcon( "/mActionInOverview.png" ) );
16971701

1698-
if ( mComposer )
1702+
//change themes of all composers
1703+
QMap<QString, QgsComposer*>::iterator composerIt = mPrintComposers.begin();
1704+
for ( ; composerIt != mPrintComposers.end(); ++composerIt )
16991705
{
1700-
mComposer->setupTheme();
1706+
composerIt.value()->setupTheme();
17011707
}
1708+
17021709
emit currentThemeChanged( theThemeName );
17031710
}
17041711

@@ -3056,9 +3063,7 @@ void QgisApp::fileExit()
30563063

30573064
if ( saveDirty() )
30583065
{
3059-
delete mComposer;
3060-
mComposer = 0;
3061-
3066+
deletePrintComposers();
30623067
mMapCanvas->freeze( true );
30633068
removeAllLayers();
30643069
qApp->exit( 0 );
@@ -3081,8 +3086,7 @@ void QgisApp::fileNew( bool thePromptToSaveFlag )
30813086
return;
30823087
}
30833088

3084-
delete mComposer;
3085-
mComposer = new QgsComposer( this );
3089+
deletePrintComposers();
30863090

30873091
if ( thePromptToSaveFlag )
30883092
{
@@ -3299,9 +3303,7 @@ void QgisApp::fileOpen()
32993303
// Persist last used project dir
33003304
settings.setValue( "/UI/lastProjectDir", myPath );
33013305

3302-
delete mComposer;
3303-
mComposer = new QgsComposer( this );
3304-
3306+
deletePrintComposers();
33053307
// clear out any stuff from previous project
33063308
mMapCanvas->freeze( true );
33073309
removeAllLayers();
@@ -3347,6 +3349,9 @@ void QgisApp::fileOpen()
33473349
// project so that they can check any project
33483350
// specific plug-in state
33493351

3352+
//load the composers in the project
3353+
loadComposersFromProject( fullPath );
3354+
33503355
// add this to the list of recently used project files
33513356
saveRecentProjectPath( fullPath, settings );
33523357

@@ -3367,10 +3372,7 @@ bool QgisApp::addProject( QString projectFile )
33673372

33683373
QApplication::setOverrideCursor( Qt::WaitCursor );
33693374

3370-
//clear the composer
3371-
delete mComposer;
3372-
mComposer = new QgsComposer( this );
3373-
3375+
deletePrintComposers();
33743376
// clear the map canvas
33753377
removeAllLayers();
33763378

@@ -3442,6 +3444,8 @@ bool QgisApp::addProject( QString projectFile )
34423444
// project so that they can check any project
34433445
// specific plug-in state
34443446

3447+
loadComposersFromProject( projectFile );
3448+
34453449
// add this to the list of recently used project files
34463450
QSettings settings;
34473451
saveRecentProjectPath( projectFile, settings );
@@ -3680,13 +3684,41 @@ bool QgisApp::openLayer( const QString & fileName )
36803684
return ok;
36813685
}
36823686

3683-
void QgisApp::filePrint()
3687+
void QgisApp::newPrintComposer()
36843688
{
36853689
if ( mMapCanvas && mMapCanvas->isDrawing() )
36863690
{
36873691
return;
36883692
}
3689-
mComposer->open();
3693+
3694+
//ask user about name
3695+
bool composerExists = true;
3696+
QString composerId;
3697+
while ( composerExists )
3698+
{
3699+
composerId = QInputDialog::getText( 0, tr( "Enter id string for composer" ), tr( "id:" ) );
3700+
if ( composerId.isNull() )
3701+
{
3702+
return;
3703+
}
3704+
3705+
if ( mPrintComposers.contains( composerId ) )
3706+
{
3707+
QMessageBox::critical( 0, tr( "Composer id already exists" ), tr( "The entered composer id '%1' already exists. Please enter a different id" ).arg( composerId ) );
3708+
}
3709+
else
3710+
{
3711+
composerExists = false;
3712+
}
3713+
}
3714+
3715+
//create new composer object
3716+
QgsComposer* newComposerObject = new QgsComposer( this, composerId );
3717+
//add it to the map of existing print composers
3718+
mPrintComposers.insert( composerId, newComposerObject );
3719+
//and place action into print composers menu
3720+
mPrintComposersMenu->addAction( newComposerObject->windowAction() );
3721+
newComposerObject->open();
36903722
}
36913723

36923724
void QgisApp::saveMapAsImage()
@@ -4167,6 +4199,65 @@ QgsGeometry* QgisApp::unionGeometries( const QgsVectorLayer* vl, QgsFeatureList&
41674199
return unionGeom;
41684200
}
41694201

4202+
QList<QgsComposer*> QgisApp::printComposers()
4203+
{
4204+
QList<QgsComposer*> composerList;
4205+
QMap<QString, QgsComposer*>::iterator it = mPrintComposers.begin();
4206+
for ( ; it != mPrintComposers.end(); ++it )
4207+
{
4208+
composerList.push_back( it.value() );
4209+
}
4210+
return composerList;
4211+
}
4212+
4213+
void QgisApp::checkOutComposer( QgsComposer* c )
4214+
{
4215+
if ( !c )
4216+
{
4217+
return;
4218+
}
4219+
mPrintComposers.remove( c->id() );
4220+
mPrintComposersMenu->removeAction( c->windowAction() );
4221+
}
4222+
4223+
bool QgisApp::loadComposersFromProject( const QString& projectFilePath )
4224+
{
4225+
//create dom document from file
4226+
QDomDocument projectDom;
4227+
QFile projectFile( projectFilePath );
4228+
if ( !projectFile.open( QIODevice::ReadOnly ) )
4229+
{
4230+
return false;
4231+
}
4232+
4233+
if ( !projectDom.setContent( &projectFile, false ) )
4234+
{
4235+
return false;
4236+
}
4237+
4238+
//restore each composer
4239+
QDomNodeList composerNodes = projectDom.elementsByTagName( "Composer" );
4240+
for ( int i = 0; i < composerNodes.size(); ++i )
4241+
{
4242+
QgsComposer* composer = new QgsComposer( this, "" );
4243+
composer->readXML( composerNodes.at( i ).toElement(), projectDom );
4244+
mPrintComposers.insert( composer->id(), composer );
4245+
mPrintComposersMenu->addAction( composer->windowAction() );
4246+
composer->showMinimized();
4247+
composer->zoomFull();
4248+
}
4249+
}
4250+
4251+
void QgisApp::deletePrintComposers()
4252+
{
4253+
QMap<QString, QgsComposer*>::iterator it = mPrintComposers.begin();
4254+
for ( ; it != mPrintComposers.end(); ++it )
4255+
{
4256+
delete it.value();
4257+
}
4258+
mPrintComposers.clear();
4259+
}
4260+
41704261
void QgisApp::mergeSelectedFeatures()
41714262
{
41724263
//get active layer (hopefully vector)
@@ -5596,9 +5687,9 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
55965687

55975688
//merge tool needs editable layer and provider with the capability of adding and deleting features
55985689
if ( vlayer->isEditable() &&
5599-
(dprovider->capabilities() & QgsVectorDataProvider::DeleteFeatures) &&
5600-
(dprovider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues) &&
5601-
(dprovider->capabilities() & QgsVectorDataProvider::AddFeatures) )
5690+
( dprovider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) &&
5691+
( dprovider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) &&
5692+
( dprovider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
56025693
{
56035694
mActionMergeFeatures->setEnabled( layerHasSelection );
56045695
}

‎src/app/qgisapp.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ class QgisApp : public QMainWindow
143143
/** Get the mapcanvas object from the app */
144144
QgsMapCanvas * mapCanvas() { return mMapCanvas; };
145145

146-
QgsComposer* printComposer() {return mComposer;}
147-
148146
//! Set theme (icons)
149147
void setTheme( QString themeName = "default" );
150148
//! Setup the toolbar popup menus for a given theme
@@ -196,6 +194,12 @@ class QgisApp : public QMainWindow
196194
* windows which are hidden rather than deleted when closed. */
197195
void removeWindow( QAction *action );
198196

197+
/**Returns the print composers*/
198+
QList<QgsComposer*> printComposers();
199+
/**Unregisters a composer instance but does _not_ delete it. This method is usually called from within QgsComposer::closeEvent before
200+
the composer deletes itself using the Qt::WA_DeleteOnClose flag*/
201+
void checkOutComposer( QgsComposer* c );
202+
199203
//! Actions to be inserted in menus and toolbars
200204
QAction *actionNewProject() { return mActionNewProject; }
201205
QAction *actionOpenProject() { return mActionOpenProject; }
@@ -206,7 +210,7 @@ class QgisApp : public QMainWindow
206210
QAction *actionFileSeparator2() { return mActionFileSeparator2; }
207211
QAction *actionProjectProperties() { return mActionProjectProperties; }
208212
QAction *actionFileSeparator3() { return mActionFileSeparator3; }
209-
QAction *actionPrintComposer() { return mActionPrintComposer; }
213+
QAction *actionNewPrintComposer() { return mActionNewPrintComposer; }
210214
QAction *actionFileSeparator4() { return mActionFileSeparator4; }
211215
QAction *actionExit() { return mActionExit; }
212216

@@ -315,6 +319,7 @@ class QgisApp : public QMainWindow
315319
QMenu *firstRightStandardMenu() { return mHelpMenu; }
316320
QMenu *windowMenu() { return NULL; }
317321
#endif
322+
QMenu *printComposersMenu() {return mPrintComposersMenu;}
318323
QMenu *helpMenu() { return mHelpMenu; }
319324

320325
//! Toolbars
@@ -443,7 +448,7 @@ class QgisApp : public QMainWindow
443448
//! Create a new empty vector layer
444449
void newVectorLayer();
445450
//! Print the current map view frame
446-
void filePrint();
451+
void newPrintComposer();
447452
//! Add all loaded layers into the overview - overides qgisappbase method
448453
void addAllToOverview();
449454
//! Remove all loaded layers from the overview - overides qgisappbase method
@@ -675,6 +680,11 @@ class QgisApp : public QMainWindow
675680
@return 0 in case of error*/
676681
QgsGeometry* unionGeometries( const QgsVectorLayer* vl, QgsFeatureList& featureList );
677682

683+
/**Deletes all the composer objects and clears mPrintComposers*/
684+
void deletePrintComposers();
685+
/**Creates the composer instances in a project file and adds them to the menu*/
686+
bool loadComposersFromProject( const QString& projectFilePath );
687+
678688
/// QgisApp aren't copyable
679689
QgisApp( QgisApp const & );
680690
/// QgisApp aren't copyable
@@ -715,7 +725,7 @@ class QgisApp : public QMainWindow
715725
QAction *mActionFileSeparator2;
716726
QAction *mActionProjectProperties;
717727
QAction *mActionFileSeparator3;
718-
QAction *mActionPrintComposer;
728+
QAction *mActionNewPrintComposer;
719729
QAction *mActionFileSeparator4;
720730
QAction *mActionExit;
721731

@@ -831,6 +841,7 @@ class QgisApp : public QMainWindow
831841
#ifdef Q_WS_MAC
832842
QMenu *mWindowMenu;
833843
#endif
844+
QMenu *mPrintComposersMenu;
834845
QMenu *mHelpMenu;
835846

836847
// docks ------------------------------------------
@@ -932,8 +943,8 @@ class QgisApp : public QMainWindow
932943
QgsHelpViewer *mHelpViewer;
933944
//! list of recently opened/saved project files
934945
QStringList mRecentProjectPaths;
935-
//! Map composer
936-
QgsComposer *mComposer;
946+
//! Print composers of this project, accessible by id string
947+
QMap<QString, QgsComposer*> mPrintComposers;
937948
//! How to determine the number of decimal places used to
938949
//! display the mouse position
939950
bool mMousePrecisionAutomatic;

‎src/app/qgisappinterface.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,17 @@ QList<QgsComposerView*> QgisAppInterface::activeComposers()
152152
QList<QgsComposerView*> composerViewList;
153153
if ( qgis )
154154
{
155-
QgsComposer* c = qgis->printComposer();
156-
if ( c )
155+
QList<QgsComposer*> composerList = qgis->printComposers();
156+
QList<QgsComposer*>::iterator it = composerList.begin();
157+
for ( ; it != composerList.end(); ++it )
157158
{
158-
QgsComposerView* v = c->view();
159-
if ( v )
159+
if ( *it )
160160
{
161-
composerViewList.push_back( v );
161+
QgsComposerView* v = ( *it )->view();
162+
if ( v )
163+
{
164+
composerViewList.push_back( v );
165+
}
162166
}
163167
}
164168
}
@@ -228,7 +232,7 @@ QAction *QgisAppInterface::actionSaveMapAsImage() { return qgis->actionSaveMapAs
228232
QAction *QgisAppInterface::actionFileSeparator2() { return qgis->actionFileSeparator2(); }
229233
QAction *QgisAppInterface::actionProjectProperties() { return qgis->actionProjectProperties(); }
230234
QAction *QgisAppInterface::actionFileSeparator3() { return qgis->actionFileSeparator3(); }
231-
QAction *QgisAppInterface::actionPrintComposer() { return qgis->actionPrintComposer(); }
235+
QAction *QgisAppInterface::actionPrintComposer() { return qgis->actionNewPrintComposer(); }
232236
QAction *QgisAppInterface::actionFileSeparator4() { return qgis->actionFileSeparator4(); }
233237
QAction *QgisAppInterface::actionExit() { return qgis->actionExit(); }
234238

‎src/core/composer/qgscomposeritem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,11 @@ bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument&
204204
return false;
205205
}
206206

207+
mLastValidViewScaleFactor = itemElem.attribute( "lastValidViewScaleFactor", "-1" ).toDouble();
208+
207209
setSceneRect( QRectF( x, y, width, height ) );
208210
setZValue( itemElem.attribute( "zValue" ).toDouble() );
209211

210-
mLastValidViewScaleFactor = itemElem.attribute( "lastValidViewScaleFactor", "-1" ).toDouble();
211-
212212
//pen
213213
QDomNodeList frameColorList = itemElem.elementsByTagName( "FrameColor" );
214214
if ( frameColorList.size() > 0 )

‎src/core/composer/qgscomposition.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndef QGSCOMPOSITION_H
1717
#define QGSCOMPOSITION_H
1818

19+
#include <QDomDocument>
1920
#include <QGraphicsScene>
2021
#include <QLinkedList>
2122

@@ -25,7 +26,6 @@ class QgsPaperItem;
2526
class QGraphicsRectItem;
2627
class QgsMapRenderer;
2728

28-
class QDomDocument;
2929
class QDomElement;
3030

3131
/** \ingroup MapComposer

‎src/ui/qgscomposerbase.ui

Lines changed: 212 additions & 210 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.