Skip to content
Permalink
Browse files
[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
  • Loading branch information
dakcarto committed Feb 24, 2013
1 parent 3e6c803 commit 5ac7d03
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 17 deletions.
@@ -69,6 +69,7 @@
<file>themes/default/mActionDeleteVertex.png</file>
<file>themes/default/mActionDeselectAll.png</file>
<file>themes/default/mActionDraw.png</file>
<file>themes/default/mActionDuplicateComposer.png</file>
<file>themes/default/mActionEditCopy.png</file>
<file>themes/default/mActionEditCut.png</file>
<file>themes/default/mActionEditPaste.png</file>
@@ -316,6 +317,7 @@
<file>themes/gis/mActionDeleteVertex.png</file>
<file>themes/gis/mActionDeselectAll.png</file>
<file>themes/gis/mActionDraw.png</file>
<file>themes/gis/mActionDuplicateComposer.png</file>
<file>themes/gis/mActionEditCopy.png</file>
<file>themes/gis/mActionEditCut.png</file>
<file>themes/gis/mActionEditPaste.png</file>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -94,14 +94,6 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
int size = settings.value( "/IconSize", QGIS_ICON_SIZE ).toInt();
setIconSize( QSize( size, size ) );

// ability to save parent project from composer
mSaveProjectAction = mQgis->actionSaveProject();
QToolButton* saveProjectToolButton = new QToolButton( this );
saveProjectToolButton->addAction( mSaveProjectAction );
saveProjectToolButton->setDefaultAction( mSaveProjectAction );
mComposerToolbar->insertWidget( mActionLoadFromTemplate, saveProjectToolButton );
mComposerToolbar->insertSeparator( mActionLoadFromTemplate );

QToolButton* orderingToolButton = new QToolButton( this );
orderingToolButton->setPopupMode( QToolButton::InstantPopup );
orderingToolButton->setAutoRaise( true );
@@ -171,10 +163,11 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
#endif

QMenu *composerMenu = menuBar()->addMenu( tr( "Composer" ) );
composerMenu->addAction( mSaveProjectAction );
composerMenu->addAction( mActionSaveProject );
composerMenu->addSeparator();
composerMenu->addAction( mQgis->actionNewPrintComposer() );
composerMenu->addAction( mQgis->actionShowComposerManager() );
composerMenu->addAction( mActionNewComposer );
composerMenu->addAction( mActionDuplicateComposer );
composerMenu->addAction( mActionComposerManager );

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

void QgsComposer::on_mActionSaveProject_triggered()
{
mQgis->actionSaveProject()->trigger();
}

void QgsComposer::on_mActionNewComposer_triggered()
{
mQgis->actionNewPrintComposer()->trigger();
}

void QgsComposer::on_mActionDuplicateComposer_triggered()
{
mQgis->duplicateComposer( this, this );
}

void QgsComposer::on_mActionComposerManager_triggered()
{
mQgis->actionShowComposerManager()->trigger();
}

void QgsComposer::on_mActionSaveAsTemplate_triggered()
{
//show file dialog
@@ -1366,7 +1383,7 @@ void QgsComposer::on_mActionSaveAsTemplate_triggered()
}

QDomDocument saveDocument;
writeXML( saveDocument, saveDocument );
templateXML( saveDocument );

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

void QgsComposer::templateXML( QDomDocument& doc )
{
writeXML( doc, doc );
}

void QgsComposer::readXML( const QDomDocument& doc )
{
QDomNodeList composerNodeList = doc.elementsByTagName( "Composer" );
@@ -168,6 +168,22 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase

void on_mActionAddHtml_triggered();

//! Save parent project
//! @note added in 1.9
void on_mActionSaveProject_triggered();

//! Create new composer
//! @note added in 1.9
void on_mActionNewComposer_triggered();

//! Duplicate current composer
//! @note added in 1.9
void on_mActionDuplicateComposer_triggered();

//! Show composer manager
//! @note added in 1.9
void on_mActionComposerManager_triggered();

//! Save composer as template
void on_mActionSaveAsTemplate_triggered();

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

//! Stores only template as base Dom node
void templateXML( QDomDocument& doc );

//! Sets state from Dom document
void readXML( const QDomDocument& doc );
void readXML( const QDomElement& composerElem, const QDomDocument& doc, bool fromTemplate = false );
@@ -342,10 +361,6 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
QMenu* mPanelMenu;
QMenu* mToolbarMenu;

//! Save parent Project action
//! @note added in 1.9
QAction *mSaveProjectAction;

//! Print Composers menu as mirror of main app's
//! @note added in 1.9
QMenu* mPrintComposersMenu;
@@ -40,6 +40,10 @@ QgsComposerManager::QgsComposerManager( QWidget * parent, Qt::WindowFlags f ): Q
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
connect( pb, SIGNAL( clicked() ), this, SLOT( show_clicked() ) );

pb = new QPushButton( tr( "&Duplicate" ) );
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
connect( pb, SIGNAL( clicked() ), this, SLOT( duplicate_clicked() ) );

pb = new QPushButton( tr( "&Remove" ) );
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
connect( pb, SIGNAL( clicked() ), this, SLOT( remove_clicked() ) );
@@ -213,6 +217,34 @@ void QgsComposerManager::show_clicked()
close();
}

void QgsComposerManager::duplicate_clicked()
{
QListWidgetItem* item = mComposerListWidget->currentItem();
if ( !item )
{
return;
}

QgsComposer* currentComposer = 0;
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
{
currentComposer = it.value();
}
else
{
return;
}

QgsComposer* newComposer = QgisApp::instance()->duplicateComposer( currentComposer, this );

if ( newComposer )
{
// no need to add new composer to list widget, if just closing this->exec();
close();
}
}

void QgsComposerManager::rename_clicked()
{
QListWidgetItem* item = mComposerListWidget->currentItem();
@@ -47,6 +47,10 @@ class QgsComposerManager: public QDialog, private Ui::QgsComposerManagerBase
void on_mAddButton_clicked();
void remove_clicked();
void show_clicked();
/** Duplicate composer
* @note added in 1.9
*/
void duplicate_clicked();
void rename_clicked();
void on_mComposerListWidget_itemChanged( QListWidgetItem * item );
};
@@ -4632,6 +4632,90 @@ void QgisApp::deleteComposer( QgsComposer* c )
delete c;
}

QgsComposer* QgisApp::duplicateComposer( QgsComposer* currentComposer, QWidget* parent )
{
QgsComposer* newComposer = 0;
if ( !parent )
{
parent = this;
}

// test that current composer template write is valid
QDomDocument currentDoc;
currentComposer->templateXML( currentDoc );
QDomElement compositionElem = currentDoc.documentElement().firstChildElement( "Composition" );
if ( compositionElem.isNull() )
{
QMessageBox::warning( parent,
tr( "Write error" ),
tr( "Error, selected composer could not be stored as temporary template" ) );
return newComposer;
}

QList<QString> cNames;
foreach ( QgsComposer* c, printComposers() )
{
cNames << c->title();
}

bool ok = false;
bool titleValid = false;
QString newTitle = currentComposer->title() + tr( " copy" );
QString chooseMsg = tr( "Choose title" );
QString titleMsg = chooseMsg;
while ( !titleValid )
{
newTitle = QInputDialog::getText( parent,
tr( "New title" ),
titleMsg,
QLineEdit::Normal,
newTitle,
&ok );
if ( !ok )
{
return newComposer;
}

if ( cNames.contains( newTitle ) )
{
titleMsg = chooseMsg + tr( "\n (title already exists!)" );
}
else if ( newTitle.isEmpty() )
{
titleMsg = chooseMsg + tr( "\n (title can not be empty!)" );
}
else
{
titleValid = true;
}
}

newComposer = createNewComposer();
if ( !newComposer )
{
QMessageBox::warning( parent,
tr( "Composer error" ),
tr( "Error, could not create new composer" ) );
return newComposer;
}
newComposer->hide(); // until template is loaded (faster)

QApplication::setOverrideCursor( Qt::BusyCursor );
if ( !newComposer->composition()->loadFromTemplate( currentDoc, 0, false ) )
{
deleteComposer( newComposer );
QMessageBox::warning( parent,
tr( "Read error" ),
tr( "Error, composer could not be duplicated" ) );
return newComposer;
}
newComposer->setTitle( newTitle );
newComposer->activate();
QApplication::restoreOverrideCursor();

return newComposer;
}

bool QgisApp::loadComposersFromProject( const QDomDocument& doc )
{
if ( doc.isNull() )
@@ -218,6 +218,10 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QgsComposer* createNewComposer();
/**Deletes a composer and removes entry from Set*/
void deleteComposer( QgsComposer* c );
/** Duplicates a composer and adds it to Set
* @note added in 1.9
*/
QgsComposer* duplicateComposer( QgsComposer* currentComposer, QWidget* parent );

/** overloaded function used to sort menu entries alphabetically */
QMenu* createPopupMenu();
@@ -56,6 +56,11 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="mActionSaveProject"/>
<addaction name="separator"/>
<addaction name="mActionNewComposer"/>
<addaction name="mActionDuplicateComposer"/>
<addaction name="mActionComposerManager"/>
<addaction name="mActionLoadFromTemplate"/>
<addaction name="mActionSaveAsTemplate"/>
<addaction name="separator"/>
@@ -126,6 +131,9 @@
<property name="text">
<string>&amp;Print...</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
</action>
<action name="mActionZoomAll">
<property name="icon">
@@ -410,6 +418,9 @@
<property name="text">
<string>Page Setup</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+P</string>
</property>
</action>
<action name="mActionUndo">
<property name="icon">
@@ -480,12 +491,50 @@
<bool>true</bool>
</property>
<property name="text">
<string>Add html</string>
<string>Add HTML</string>
</property>
<property name="toolTip">
<string>Add html frame</string>
</property>
</action>
<action name="mActionComposerManager">
<property name="text">
<string>Composer Manager</string>
</property>
<property name="toolTip">
<string>Composer Manager</string>
</property>
</action>
<action name="mActionNewComposer">
<property name="text">
<string>&amp;New Composer</string>
</property>
<property name="toolTip">
<string>New Composer</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="mActionSaveProject">
<property name="text">
<string>&amp;Save Project</string>
</property>
<property name="toolTip">
<string>Save Project</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="mActionDuplicateComposer">
<property name="text">
<string>&amp;Duplicate Composer</string>
</property>
<property name="toolTip">
<string>Duplicate Composer</string>
</property>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>

0 comments on commit 5ac7d03

Please sign in to comment.