Skip to content

Commit b1f1cbd

Browse files
committed
Update Composer Manager's template functionality
- Add specific template path support - Add user templates directory support - Add buttons to open user or default template directory - Add selection of list item for newly added composers - Update GUI with collapsible group box - Use unique title dialog for composer rename function
1 parent 808547e commit b1f1cbd

File tree

4 files changed

+288
-42
lines changed

4 files changed

+288
-42
lines changed

src/app/composer/qgscomposer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ void QgsComposer::on_mActionSaveAsTemplate_triggered()
14191419
QString saveFileNameWithSuffix = saveFileName.append( ".qpt" );
14201420
saveFileInfo = QFileInfo( saveFileNameWithSuffix );
14211421
}
1422-
settings.setValue( "UI/LastComposerTemplateDir", saveFileInfo.absolutePath() );
1422+
settings.setValue( "UI/lastComposerTemplateDir", saveFileInfo.absolutePath() );
14231423

14241424
QFile templateFile( saveFileName );
14251425
if ( !templateFile.open( QIODevice::WriteOnly ) )

src/app/composer/qgscomposermanager.cpp

+135-18
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
#include "qgscomposer.h"
2121
#include "qgslogger.h"
2222

23+
#include <QDesktopServices>
2324
#include <QDialog>
2425
#include <QDir>
26+
#include <QFileDialog>
2527
#include <QInputDialog>
2628
#include <QListWidgetItem>
2729
#include <QMessageBox>
30+
#include <QUrl>
2831
#include <QSettings>
2932

3033
QgsComposerManager::QgsComposerManager( QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f )
@@ -65,6 +68,7 @@ QgsComposerManager::~QgsComposerManager()
6568

6669
void QgsComposerManager::initialize()
6770
{
71+
QSettings settings;
6872
QSet<QgsComposer*> composers = QgisApp::instance()->printComposers();
6973
QSet<QgsComposer*>::const_iterator it = composers.constBegin();
7074
for ( ; it != composers.constEnd(); ++it )
@@ -75,24 +79,42 @@ void QgsComposerManager::initialize()
7579
}
7680

7781
mTemplate->addItem( tr( "Empty composer" ) );
82+
mTemplate->addItem( tr( "Specific" ) );
83+
84+
mUserTemplatesDir = QgsApplication::qgisSettingsDirPath() + "/composer_templates";
85+
QMap<QString, QString> userTemplateMap = defaultTemplates( true );
86+
if ( userTemplateMap.size() > 0 )
87+
{
88+
mTemplate->insertSeparator( mTemplate->count() );
89+
QMap<QString, QString>::const_iterator templateIt = userTemplateMap.constBegin();
90+
for ( ; templateIt != userTemplateMap.constEnd(); ++templateIt )
91+
{
92+
mTemplate->addItem( templateIt.key(), templateIt.value() );
93+
}
94+
}
7895

79-
QMap<QString, QString> templateMap = defaultTemplates();
80-
if ( templateMap.size() > 0 )
96+
mDefaultTemplatesDir = QgsApplication::pkgDataPath() + "/composer_templates";
97+
QMap<QString, QString> defaultTemplateMap = defaultTemplates( false );
98+
if ( defaultTemplateMap.size() > 0 )
8199
{
82-
QMap<QString, QString>::const_iterator templateIt = templateMap.constBegin();
83-
for ( ; templateIt != templateMap.constEnd(); ++templateIt )
100+
mTemplate->insertSeparator( mTemplate->count() );
101+
QMap<QString, QString>::const_iterator templateIt = defaultTemplateMap.constBegin();
102+
for ( ; templateIt != defaultTemplateMap.constEnd(); ++templateIt )
84103
{
85104
mTemplate->addItem( templateIt.key(), templateIt.value() );
86105
}
87106
}
107+
108+
mTemplatePathLineEdit->setText( settings.value( "/UI/ComposerManager/templatePath", QString( "" ) ).toString() );
88109
}
89110

90-
QMap<QString, QString> QgsComposerManager::defaultTemplates() const
111+
QMap<QString, QString> QgsComposerManager::defaultTemplates( bool fromUser ) const
91112
{
92113
QMap<QString, QString> templateMap;
93114

94115
//search for default templates in $pkgDataPath/composer_templates
95-
QDir defaultTemplateDir( QgsApplication::pkgDataPath() + "/composer_templates" );
116+
// user templates in $qgisSettingsDirPath/composer_templates
117+
QDir defaultTemplateDir( fromUser ? mUserTemplatesDir : mDefaultTemplatesDir );
96118
if ( !defaultTemplateDir.exists() )
97119
{
98120
return templateMap;
@@ -109,7 +131,33 @@ QMap<QString, QString> QgsComposerManager::defaultTemplates() const
109131

110132
void QgsComposerManager::on_mAddButton_clicked()
111133
{
134+
QFile templateFile;
135+
bool loadingTemplate = ( mTemplate->currentIndex() > 0 );
136+
if ( loadingTemplate )
137+
{
138+
if ( mTemplate->currentIndex() == 1 )
139+
{
140+
templateFile.setFileName( mTemplatePathLineEdit->text() );
141+
}
142+
else
143+
{
144+
templateFile.setFileName( mTemplate->itemData( mTemplate->currentIndex() ).toString() );
145+
}
146+
147+
if ( !templateFile.exists() )
148+
{
149+
QMessageBox::warning( this, tr( "Template error" ), tr( "Error, template file not found" ) );
150+
return;
151+
}
152+
if ( !templateFile.open( QIODevice::ReadOnly ) )
153+
{
154+
QMessageBox::warning( this, tr( "Template error" ), tr( "Error, could not read file" ) );
155+
return;
156+
}
157+
}
158+
112159
QgsComposer* newComposer = 0;
160+
bool loadedOK = false;
113161

114162
QString title = QgisApp::instance()->uniqueComposerTitle( this, true );
115163
if ( title.isNull() )
@@ -120,25 +168,94 @@ void QgsComposerManager::on_mAddButton_clicked()
120168
newComposer = QgisApp::instance()->createNewComposer( title );
121169
if ( !newComposer )
122170
{
171+
QMessageBox::warning( this, tr( "Composer error" ), tr( "Error, could not create composer" ) );
123172
return;
124173
}
174+
else
175+
{
176+
loadedOK = true;
177+
}
125178

126-
if ( mTemplate->currentIndex() > 0 )
179+
if ( loadingTemplate )
127180
{
128181
QDomDocument templateDoc;
129-
QFile templateFile( mTemplate->itemData( mTemplate->currentIndex() ).toString() );
130-
if ( templateFile.open( QIODevice::ReadOnly ) )
182+
if ( templateDoc.setContent( &templateFile, false ) )
131183
{
132-
if ( templateDoc.setContent( &templateFile, false ) )
133-
{
134-
newComposer->readXML( templateDoc );
135-
}
184+
// provide feedback, since composer will be hidden when loading template (much faster)
185+
// (not needed for empty composer)
186+
QDialog* dlg = newComposer->busyIndicatorDialog( tr( "Loading template into composer..." ), this );
187+
dlg->show();
188+
newComposer->hide();
189+
loadedOK = newComposer->composition()->loadFromTemplate( templateDoc, 0, false );
190+
newComposer->activate();
191+
dlg->close();
136192
}
137193
}
138194

139-
QListWidgetItem* item = new QListWidgetItem( newComposer->title(), mComposerListWidget );
140-
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
141-
mItemComposerMap.insert( item, newComposer );
195+
if ( loadedOK )
196+
{
197+
// do not close on Add, since user may want to add multiple composers from templates
198+
QListWidgetItem* item = new QListWidgetItem( newComposer->title(), mComposerListWidget );
199+
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
200+
mItemComposerMap.insert( item, newComposer );
201+
mComposerListWidget->setCurrentItem( item );
202+
mComposerListWidget->setFocus();
203+
}
204+
else
205+
{
206+
if ( newComposer )
207+
{
208+
newComposer->close();
209+
QgisApp::instance()->deleteComposer( newComposer );
210+
newComposer = 0;
211+
}
212+
QMessageBox::warning( this, tr( "Template error" ), tr( "Error, could not load template file" ) );
213+
}
214+
}
215+
216+
void QgsComposerManager::on_mTemplate_currentIndexChanged( int indx )
217+
{
218+
bool specific = ( indx == 1 ); // comes just after empty template
219+
mTemplatePathLineEdit->setEnabled( specific );
220+
mTemplatePathBtn->setEnabled( specific );
221+
}
222+
223+
void QgsComposerManager::on_mTemplatePathBtn_pressed()
224+
{
225+
QSettings settings;
226+
QString lastTmplDir = settings.value( "/UI/lastComposerTemplateDir", "." ).toString();
227+
QString tmplPath = QFileDialog::getOpenFileName( this,
228+
tr( "Choose template" ),
229+
lastTmplDir,
230+
tr( "Composer templates" ) + " (*.qpt)" );
231+
if ( !tmplPath.isNull() )
232+
{
233+
mTemplatePathLineEdit->setText( tmplPath );
234+
settings.setValue( "UI/ComposerManager/templatePath", tmplPath );
235+
QFileInfo tmplFileInfo( tmplPath );
236+
settings.setValue( "UI/lastComposerTemplateDir", tmplFileInfo.absolutePath() );
237+
}
238+
}
239+
240+
void QgsComposerManager::on_mTemplatesDefaultDirBtn_pressed()
241+
{
242+
openLocalDirectory( mDefaultTemplatesDir );
243+
}
244+
245+
void QgsComposerManager::on_mTemplatesUserDirBtn_pressed()
246+
{
247+
openLocalDirectory( mUserTemplatesDir );
248+
}
249+
250+
void QgsComposerManager::openLocalDirectory( const QString& localDirPath )
251+
{
252+
QDir localDir;
253+
if ( !localDir.mkpath( localDirPath ) )
254+
{
255+
QMessageBox::warning( this, tr( "File system error" ), tr( "Error, could not open or create local directory" ) );
256+
return;
257+
}
258+
QDesktopServices::openUrl( QUrl::fromLocalFile( localDirPath ) );
142259
}
143260

144261
void QgsComposerManager::remove_clicked()
@@ -150,7 +267,7 @@ void QgsComposerManager::remove_clicked()
150267
}
151268

152269
//ask for confirmation
153-
if ( QMessageBox::warning( 0, tr( "Remove composer" ), tr( "Do you really want to remove the map composer '%1'?" ).arg( item->text() ), QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
270+
if ( QMessageBox::warning( this, tr( "Remove composer" ), tr( "Do you really want to remove the map composer '%1'?" ).arg( item->text() ), QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
154271
{
155272
return;
156273
}
@@ -291,7 +408,7 @@ void QgsComposerManager::rename_clicked()
291408
{
292409
return;
293410
}
294-
QString newTitle = QInputDialog::getText( 0, tr( "Change title" ), tr( "Title" ), QLineEdit::Normal, currentTitle );
411+
QString newTitle = QgisApp::instance()->uniqueComposerTitle( this, false, currentTitle );
295412
if ( newTitle.isNull() )
296413
{
297414
return;

src/app/composer/qgscomposermanager.h

+29-2
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,38 @@ class QgsComposerManager: public QDialog, private Ui::QgsComposerManagerBase
4040
/**Enters the composer instances and created the item-composer map*/
4141
void initialize();
4242

43-
/**Returns the default templates (key: template name, value: absolute path to template file)*/
44-
QMap<QString, QString> defaultTemplates() const;
43+
/** Returns the default templates (key: template name, value: absolute path to template file)
44+
* @param fromUser whether to return user templates from ~/.qgis/composer_templates (added in 1.9)
45+
*/
46+
QMap<QString, QString> defaultTemplates( bool fromUser = false ) const;
47+
48+
/** Open local directory with user's system, creating it if not present
49+
* @note added in QGIS 1.9
50+
*/
51+
void openLocalDirectory( const QString& localDirPath );
52+
53+
QString mDefaultTemplatesDir;
54+
QString mUserTemplatesDir;
4555

4656
private slots:
4757
void on_mAddButton_clicked();
58+
/** Slot to track combobox to use specific template path
59+
* @note added in 1.9
60+
*/
61+
void on_mTemplate_currentIndexChanged( int indx );
62+
/** Slot to choose path to template
63+
* @note added in QGIS 1.9
64+
*/
65+
void on_mTemplatePathBtn_pressed();
66+
/** Slot to open default templates dir with user's system
67+
* @note added in QGIS 1.9
68+
*/
69+
void on_mTemplatesDefaultDirBtn_pressed();
70+
/** Slot to open user templates dir with user's system
71+
* @note added in QGIS 1.9
72+
*/
73+
void on_mTemplatesUserDirBtn_pressed();
74+
4875
void remove_clicked();
4976
void show_clicked();
5077
/** Duplicate composer

0 commit comments

Comments
 (0)