Skip to content

Commit 5ac7d03

Browse files
committed
[FEATURE] Add duplicate function to composer manager and composer ui
- Addresses feature request #7203 - Add actions to composer that trigger main app's, instead of referencing - Allows Ctrl(Cmd)-P to initiate printing (instead of a new composer) - Allows Ctrl(Cmd)-N to create new composer - Use new templateXML function when saving composer template
1 parent 3e6c803 commit 5ac7d03

10 files changed

+229
-17
lines changed

images/images.qrc

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
<file>themes/default/mActionDeleteVertex.png</file>
7070
<file>themes/default/mActionDeselectAll.png</file>
7171
<file>themes/default/mActionDraw.png</file>
72+
<file>themes/default/mActionDuplicateComposer.png</file>
7273
<file>themes/default/mActionEditCopy.png</file>
7374
<file>themes/default/mActionEditCut.png</file>
7475
<file>themes/default/mActionEditPaste.png</file>
@@ -316,6 +317,7 @@
316317
<file>themes/gis/mActionDeleteVertex.png</file>
317318
<file>themes/gis/mActionDeselectAll.png</file>
318319
<file>themes/gis/mActionDraw.png</file>
320+
<file>themes/gis/mActionDuplicateComposer.png</file>
319321
<file>themes/gis/mActionEditCopy.png</file>
320322
<file>themes/gis/mActionEditCut.png</file>
321323
<file>themes/gis/mActionEditPaste.png</file>
441 Bytes
Loading
441 Bytes
Loading

src/app/composer/qgscomposer.cpp

+34-12
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,6 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
9494
int size = settings.value( "/IconSize", QGIS_ICON_SIZE ).toInt();
9595
setIconSize( QSize( size, size ) );
9696

97-
// ability to save parent project from composer
98-
mSaveProjectAction = mQgis->actionSaveProject();
99-
QToolButton* saveProjectToolButton = new QToolButton( this );
100-
saveProjectToolButton->addAction( mSaveProjectAction );
101-
saveProjectToolButton->setDefaultAction( mSaveProjectAction );
102-
mComposerToolbar->insertWidget( mActionLoadFromTemplate, saveProjectToolButton );
103-
mComposerToolbar->insertSeparator( mActionLoadFromTemplate );
104-
10597
QToolButton* orderingToolButton = new QToolButton( this );
10698
orderingToolButton->setPopupMode( QToolButton::InstantPopup );
10799
orderingToolButton->setAutoRaise( true );
@@ -171,10 +163,11 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
171163
#endif
172164

173165
QMenu *composerMenu = menuBar()->addMenu( tr( "Composer" ) );
174-
composerMenu->addAction( mSaveProjectAction );
166+
composerMenu->addAction( mActionSaveProject );
175167
composerMenu->addSeparator();
176-
composerMenu->addAction( mQgis->actionNewPrintComposer() );
177-
composerMenu->addAction( mQgis->actionShowComposerManager() );
168+
composerMenu->addAction( mActionNewComposer );
169+
composerMenu->addAction( mActionDuplicateComposer );
170+
composerMenu->addAction( mActionComposerManager );
178171

179172
mPrintComposersMenu = new QMenu( tr( "Print Composers" ), this );
180173
mPrintComposersMenu->setObjectName( "mPrintComposersMenu" );
@@ -360,6 +353,10 @@ void QgsComposer::setupTheme()
360353
//now set all the icons - getThemeIcon will fall back to default theme if its
361354
//missing from active theme
362355
mActionQuit->setIcon( QgsApplication::getThemeIcon( "/mActionFileExit.png" ) );
356+
mActionSaveProject->setIcon( QgsApplication::getThemeIcon( "/mActionFileSave.png" ) );
357+
mActionNewComposer->setIcon( QgsApplication::getThemeIcon( "/mActionNewComposer.png" ) );
358+
mActionDuplicateComposer->setIcon( QgsApplication::getThemeIcon( "/mActionDuplicateComposer.png" ) );
359+
mActionComposerManager->setIcon( QgsApplication::getThemeIcon( "/mActionComposerManager.png" ) );
363360
mActionLoadFromTemplate->setIcon( QgsApplication::getThemeIcon( "/mActionFileOpen.png" ) );
364361
mActionSaveAsTemplate->setIcon( QgsApplication::getThemeIcon( "/mActionFileSaveAs.png" ) );
365362
mActionExportAsImage->setIcon( QgsApplication::getThemeIcon( "/mActionSaveMapAsImage.png" ) );
@@ -1337,6 +1334,26 @@ void QgsComposer::on_mActionAddArrow_triggered()
13371334
}
13381335
}
13391336

1337+
void QgsComposer::on_mActionSaveProject_triggered()
1338+
{
1339+
mQgis->actionSaveProject()->trigger();
1340+
}
1341+
1342+
void QgsComposer::on_mActionNewComposer_triggered()
1343+
{
1344+
mQgis->actionNewPrintComposer()->trigger();
1345+
}
1346+
1347+
void QgsComposer::on_mActionDuplicateComposer_triggered()
1348+
{
1349+
mQgis->duplicateComposer( this, this );
1350+
}
1351+
1352+
void QgsComposer::on_mActionComposerManager_triggered()
1353+
{
1354+
mQgis->actionShowComposerManager()->trigger();
1355+
}
1356+
13401357
void QgsComposer::on_mActionSaveAsTemplate_triggered()
13411358
{
13421359
//show file dialog
@@ -1366,7 +1383,7 @@ void QgsComposer::on_mActionSaveAsTemplate_triggered()
13661383
}
13671384

13681385
QDomDocument saveDocument;
1369-
writeXML( saveDocument, saveDocument );
1386+
templateXML( saveDocument );
13701387

13711388
if ( templateFile.write( saveDocument.toByteArray() ) == -1 )
13721389
{
@@ -1633,6 +1650,11 @@ void QgsComposer::writeXML( QDomNode& parentNode, QDomDocument& doc )
16331650
mComposition->atlasComposition().writeXML( composerElem, doc );
16341651
}
16351652

1653+
void QgsComposer::templateXML( QDomDocument& doc )
1654+
{
1655+
writeXML( doc, doc );
1656+
}
1657+
16361658
void QgsComposer::readXML( const QDomDocument& doc )
16371659
{
16381660
QDomNodeList composerNodeList = doc.elementsByTagName( "Composer" );

src/app/composer/qgscomposer.h

+19-4
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,22 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
168168

169169
void on_mActionAddHtml_triggered();
170170

171+
//! Save parent project
172+
//! @note added in 1.9
173+
void on_mActionSaveProject_triggered();
174+
175+
//! Create new composer
176+
//! @note added in 1.9
177+
void on_mActionNewComposer_triggered();
178+
179+
//! Duplicate current composer
180+
//! @note added in 1.9
181+
void on_mActionDuplicateComposer_triggered();
182+
183+
//! Show composer manager
184+
//! @note added in 1.9
185+
void on_mActionComposerManager_triggered();
186+
171187
//! Save composer as template
172188
void on_mActionSaveAsTemplate_triggered();
173189

@@ -259,6 +275,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
259275
//! Stores state in Dom node
260276
void writeXML( QDomDocument& doc );
261277

278+
//! Stores only template as base Dom node
279+
void templateXML( QDomDocument& doc );
280+
262281
//! Sets state from Dom document
263282
void readXML( const QDomDocument& doc );
264283
void readXML( const QDomElement& composerElem, const QDomDocument& doc, bool fromTemplate = false );
@@ -342,10 +361,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
342361
QMenu* mPanelMenu;
343362
QMenu* mToolbarMenu;
344363

345-
//! Save parent Project action
346-
//! @note added in 1.9
347-
QAction *mSaveProjectAction;
348-
349364
//! Print Composers menu as mirror of main app's
350365
//! @note added in 1.9
351366
QMenu* mPrintComposersMenu;

src/app/composer/qgscomposermanager.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ QgsComposerManager::QgsComposerManager( QWidget * parent, Qt::WindowFlags f ): Q
4040
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
4141
connect( pb, SIGNAL( clicked() ), this, SLOT( show_clicked() ) );
4242

43+
pb = new QPushButton( tr( "&Duplicate" ) );
44+
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
45+
connect( pb, SIGNAL( clicked() ), this, SLOT( duplicate_clicked() ) );
46+
4347
pb = new QPushButton( tr( "&Remove" ) );
4448
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
4549
connect( pb, SIGNAL( clicked() ), this, SLOT( remove_clicked() ) );
@@ -213,6 +217,34 @@ void QgsComposerManager::show_clicked()
213217
close();
214218
}
215219

220+
void QgsComposerManager::duplicate_clicked()
221+
{
222+
QListWidgetItem* item = mComposerListWidget->currentItem();
223+
if ( !item )
224+
{
225+
return;
226+
}
227+
228+
QgsComposer* currentComposer = 0;
229+
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
230+
if ( it != mItemComposerMap.end() )
231+
{
232+
currentComposer = it.value();
233+
}
234+
else
235+
{
236+
return;
237+
}
238+
239+
QgsComposer* newComposer = QgisApp::instance()->duplicateComposer( currentComposer, this );
240+
241+
if ( newComposer )
242+
{
243+
// no need to add new composer to list widget, if just closing this->exec();
244+
close();
245+
}
246+
}
247+
216248
void QgsComposerManager::rename_clicked()
217249
{
218250
QListWidgetItem* item = mComposerListWidget->currentItem();

src/app/composer/qgscomposermanager.h

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class QgsComposerManager: public QDialog, private Ui::QgsComposerManagerBase
4747
void on_mAddButton_clicked();
4848
void remove_clicked();
4949
void show_clicked();
50+
/** Duplicate composer
51+
* @note added in 1.9
52+
*/
53+
void duplicate_clicked();
5054
void rename_clicked();
5155
void on_mComposerListWidget_itemChanged( QListWidgetItem * item );
5256
};

src/app/qgisapp.cpp

+84
Original file line numberDiff line numberDiff line change
@@ -4632,6 +4632,90 @@ void QgisApp::deleteComposer( QgsComposer* c )
46324632
delete c;
46334633
}
46344634

4635+
QgsComposer* QgisApp::duplicateComposer( QgsComposer* currentComposer, QWidget* parent )
4636+
{
4637+
QgsComposer* newComposer = 0;
4638+
if ( !parent )
4639+
{
4640+
parent = this;
4641+
}
4642+
4643+
// test that current composer template write is valid
4644+
QDomDocument currentDoc;
4645+
currentComposer->templateXML( currentDoc );
4646+
QDomElement compositionElem = currentDoc.documentElement().firstChildElement( "Composition" );
4647+
if ( compositionElem.isNull() )
4648+
{
4649+
QMessageBox::warning( parent,
4650+
tr( "Write error" ),
4651+
tr( "Error, selected composer could not be stored as temporary template" ) );
4652+
return newComposer;
4653+
}
4654+
4655+
QList<QString> cNames;
4656+
foreach ( QgsComposer* c, printComposers() )
4657+
{
4658+
cNames << c->title();
4659+
}
4660+
4661+
bool ok = false;
4662+
bool titleValid = false;
4663+
QString newTitle = currentComposer->title() + tr( " copy" );
4664+
QString chooseMsg = tr( "Choose title" );
4665+
QString titleMsg = chooseMsg;
4666+
while ( !titleValid )
4667+
{
4668+
newTitle = QInputDialog::getText( parent,
4669+
tr( "New title" ),
4670+
titleMsg,
4671+
QLineEdit::Normal,
4672+
newTitle,
4673+
&ok );
4674+
if ( !ok )
4675+
{
4676+
return newComposer;
4677+
}
4678+
4679+
if ( cNames.contains( newTitle ) )
4680+
{
4681+
titleMsg = chooseMsg + tr( "\n (title already exists!)" );
4682+
}
4683+
else if ( newTitle.isEmpty() )
4684+
{
4685+
titleMsg = chooseMsg + tr( "\n (title can not be empty!)" );
4686+
}
4687+
else
4688+
{
4689+
titleValid = true;
4690+
}
4691+
}
4692+
4693+
newComposer = createNewComposer();
4694+
if ( !newComposer )
4695+
{
4696+
QMessageBox::warning( parent,
4697+
tr( "Composer error" ),
4698+
tr( "Error, could not create new composer" ) );
4699+
return newComposer;
4700+
}
4701+
newComposer->hide(); // until template is loaded (faster)
4702+
4703+
QApplication::setOverrideCursor( Qt::BusyCursor );
4704+
if ( !newComposer->composition()->loadFromTemplate( currentDoc, 0, false ) )
4705+
{
4706+
deleteComposer( newComposer );
4707+
QMessageBox::warning( parent,
4708+
tr( "Read error" ),
4709+
tr( "Error, composer could not be duplicated" ) );
4710+
return newComposer;
4711+
}
4712+
newComposer->setTitle( newTitle );
4713+
newComposer->activate();
4714+
QApplication::restoreOverrideCursor();
4715+
4716+
return newComposer;
4717+
}
4718+
46354719
bool QgisApp::loadComposersFromProject( const QDomDocument& doc )
46364720
{
46374721
if ( doc.isNull() )

src/app/qgisapp.h

+4
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
218218
QgsComposer* createNewComposer();
219219
/**Deletes a composer and removes entry from Set*/
220220
void deleteComposer( QgsComposer* c );
221+
/** Duplicates a composer and adds it to Set
222+
* @note added in 1.9
223+
*/
224+
QgsComposer* duplicateComposer( QgsComposer* currentComposer, QWidget* parent );
221225

222226
/** overloaded function used to sort menu entries alphabetically */
223227
QMenu* createPopupMenu();

src/ui/qgscomposerbase.ui

+50-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
<attribute name="toolBarBreak">
5757
<bool>false</bool>
5858
</attribute>
59+
<addaction name="mActionSaveProject"/>
60+
<addaction name="separator"/>
61+
<addaction name="mActionNewComposer"/>
62+
<addaction name="mActionDuplicateComposer"/>
63+
<addaction name="mActionComposerManager"/>
5964
<addaction name="mActionLoadFromTemplate"/>
6065
<addaction name="mActionSaveAsTemplate"/>
6166
<addaction name="separator"/>
@@ -126,6 +131,9 @@
126131
<property name="text">
127132
<string>&amp;Print...</string>
128133
</property>
134+
<property name="shortcut">
135+
<string>Ctrl+P</string>
136+
</property>
129137
</action>
130138
<action name="mActionZoomAll">
131139
<property name="icon">
@@ -410,6 +418,9 @@
410418
<property name="text">
411419
<string>Page Setup</string>
412420
</property>
421+
<property name="shortcut">
422+
<string>Ctrl+Shift+P</string>
423+
</property>
413424
</action>
414425
<action name="mActionUndo">
415426
<property name="icon">
@@ -480,12 +491,50 @@
480491
<bool>true</bool>
481492
</property>
482493
<property name="text">
483-
<string>Add html</string>
494+
<string>Add HTML</string>
484495
</property>
485496
<property name="toolTip">
486497
<string>Add html frame</string>
487498
</property>
488499
</action>
500+
<action name="mActionComposerManager">
501+
<property name="text">
502+
<string>Composer Manager</string>
503+
</property>
504+
<property name="toolTip">
505+
<string>Composer Manager</string>
506+
</property>
507+
</action>
508+
<action name="mActionNewComposer">
509+
<property name="text">
510+
<string>&amp;New Composer</string>
511+
</property>
512+
<property name="toolTip">
513+
<string>New Composer</string>
514+
</property>
515+
<property name="shortcut">
516+
<string>Ctrl+N</string>
517+
</property>
518+
</action>
519+
<action name="mActionSaveProject">
520+
<property name="text">
521+
<string>&amp;Save Project</string>
522+
</property>
523+
<property name="toolTip">
524+
<string>Save Project</string>
525+
</property>
526+
<property name="shortcut">
527+
<string>Ctrl+S</string>
528+
</property>
529+
</action>
530+
<action name="mActionDuplicateComposer">
531+
<property name="text">
532+
<string>&amp;Duplicate Composer</string>
533+
</property>
534+
<property name="toolTip">
535+
<string>Duplicate Composer</string>
536+
</property>
537+
</action>
489538
</widget>
490539
<resources>
491540
<include location="../../images/images.qrc"/>

0 commit comments

Comments
 (0)