Skip to content

Commit 0c777dd

Browse files
committed
Add unique title input dialog for new and duplicate composers
- Allows user to title composer before creation (optionally based on existing composer titles) - Helps limit duplicate titles - Non-GUI generation of new and duplicate composers not restricted (unchanged) - Duplicate composer slot now free of GUI interruptions - Change from hiding of duplicate composer (during template loading) to pausing updates to give user feedback
1 parent 208c920 commit 0c777dd

File tree

4 files changed

+119
-60
lines changed

4 files changed

+119
-60
lines changed

src/app/composer/qgscomposer.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,12 @@ void QgsComposer::on_mActionNewComposer_triggered()
13461346

13471347
void QgsComposer::on_mActionDuplicateComposer_triggered()
13481348
{
1349-
mQgis->duplicateComposer( this, this );
1349+
QString newTitle = mQgis->uniqueComposerTitle( this, false, title() + tr( " copy" ) );
1350+
if ( newTitle.isNull() )
1351+
{
1352+
return;
1353+
}
1354+
mQgis->duplicateComposer( this, newTitle );
13501355
}
13511356

13521357
void QgsComposer::on_mActionComposerManager_triggered()

src/app/composer/qgscomposermanager.cpp

+16-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ void QgsComposerManager::on_mAddButton_clicked()
109109
{
110110
QgsComposer* newComposer = 0;
111111

112-
newComposer = QgisApp::instance()->createNewComposer();
112+
QString title = QgisApp::instance()->uniqueComposerTitle( this, true );
113+
if ( title.isNull() )
114+
{
115+
return;
116+
}
117+
118+
newComposer = QgisApp::instance()->createNewComposer( title );
113119
if ( !newComposer )
114120
{
115121
return;
@@ -226,17 +232,25 @@ void QgsComposerManager::duplicate_clicked()
226232
}
227233

228234
QgsComposer* currentComposer = 0;
235+
QString currentTitle;
229236
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
230237
if ( it != mItemComposerMap.end() )
231238
{
232239
currentComposer = it.value();
240+
currentTitle = it.value()->title();
233241
}
234242
else
235243
{
236244
return;
237245
}
238246

239-
QgsComposer* newComposer = QgisApp::instance()->duplicateComposer( currentComposer, this );
247+
QString newTitle = QgisApp::instance()->uniqueComposerTitle( this, false, currentTitle + tr( " copy" ) );
248+
if ( newTitle.isNull() )
249+
{
250+
return;
251+
}
252+
253+
QgsComposer* newComposer = QgisApp::instance()->duplicateComposer( currentComposer, newTitle );
240254

241255
if ( newComposer )
242256
{

src/app/qgisapp.cpp

+88-55
Original file line numberDiff line numberDiff line change
@@ -3842,7 +3842,12 @@ void QgisApp::newPrintComposer()
38423842
return;
38433843
}
38443844

3845-
createNewComposer();
3845+
QString title = uniqueComposerTitle( this, true );
3846+
if ( title.isNull() )
3847+
{
3848+
return;
3849+
}
3850+
createNewComposer( title );
38463851
}
38473852

38483853
void QgisApp::showComposerManager()
@@ -4604,12 +4609,79 @@ QgsGeometry* QgisApp::unionGeometries( const QgsVectorLayer* vl, QgsFeatureList&
46044609
return unionGeom;
46054610
}
46064611

4607-
QgsComposer* QgisApp::createNewComposer()
4612+
QString QgisApp::uniqueComposerTitle( QWidget* parent, bool acceptEmpty, const QString& currentName )
4613+
{
4614+
if ( !parent )
4615+
{
4616+
parent = this;
4617+
}
4618+
bool ok = false;
4619+
bool titleValid = false;
4620+
QString newTitle = QString( currentName );
4621+
QString chooseMsg = tr( "Create unique print composer title" );
4622+
if ( acceptEmpty )
4623+
{
4624+
chooseMsg += "\n" + tr( "(title generated if left empty)" );
4625+
}
4626+
QString titleMsg = chooseMsg;
4627+
4628+
QStringList cNames;
4629+
cNames << newTitle;
4630+
foreach ( QgsComposer* c, printComposers() )
4631+
{
4632+
cNames << c->title();
4633+
}
4634+
4635+
while ( !titleValid )
4636+
{
4637+
newTitle = QInputDialog::getItem( parent,
4638+
tr( "Composer title" ),
4639+
titleMsg,
4640+
cNames,
4641+
cNames.indexOf( newTitle ),
4642+
true,
4643+
&ok );
4644+
if ( !ok )
4645+
{
4646+
return QString::null;
4647+
}
4648+
4649+
if ( newTitle.isEmpty() )
4650+
{
4651+
if ( !acceptEmpty )
4652+
{
4653+
titleMsg = chooseMsg + "\n\n" + tr( "Title can not be empty!" );
4654+
}
4655+
else
4656+
{
4657+
newTitle = QString( "" );
4658+
titleValid = true;
4659+
}
4660+
}
4661+
else if ( cNames.indexOf( newTitle, 1 ) >= 0 )
4662+
{
4663+
cNames[0] = QString( "" ); // clear non-unique name
4664+
titleMsg = chooseMsg + "\n\n" + tr( "Title already exists!" );
4665+
}
4666+
else
4667+
{
4668+
titleValid = true;
4669+
}
4670+
}
4671+
4672+
return newTitle;
4673+
}
4674+
4675+
QgsComposer* QgisApp::createNewComposer( QString title )
46084676
{
46094677
//ask user about name
46104678
mLastComposerId++;
4679+
if ( title.isEmpty() )
4680+
{
4681+
title = tr( "Composer %1" ).arg( mLastComposerId );
4682+
}
46114683
//create new composer object
4612-
QgsComposer* newComposerObject = new QgsComposer( this, tr( "Composer %1" ).arg( mLastComposerId ) );
4684+
QgsComposer* newComposerObject = new QgsComposer( this, title );
46134685

46144686
//add it to the map of existing print composers
46154687
mPrintComposers.insert( newComposerObject );
@@ -4632,84 +4704,45 @@ void QgisApp::deleteComposer( QgsComposer* c )
46324704
delete c;
46334705
}
46344706

4635-
QgsComposer* QgisApp::duplicateComposer( QgsComposer* currentComposer, QWidget* parent )
4707+
QgsComposer* QgisApp::duplicateComposer( QgsComposer* currentComposer, QString title )
46364708
{
46374709
QgsComposer* newComposer = 0;
4638-
if ( !parent )
4639-
{
4640-
parent = this;
4641-
}
46424710

46434711
// test that current composer template write is valid
46444712
QDomDocument currentDoc;
46454713
currentComposer->templateXML( currentDoc );
46464714
QDomElement compositionElem = currentDoc.documentElement().firstChildElement( "Composition" );
46474715
if ( compositionElem.isNull() )
46484716
{
4649-
QMessageBox::warning( parent,
4650-
tr( "Write error" ),
4651-
tr( "Error, selected composer could not be stored as temporary template" ) );
4717+
QgsDebugMsg( "selected composer could not be stored as temporary template" );
46524718
return newComposer;
46534719
}
46544720

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 )
4721+
if ( title.isEmpty() )
46674722
{
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-
}
4723+
// TODO: inject a bit of randomness in auto-titles?
4724+
title = currentComposer->title() + tr( " copy" );
46914725
}
46924726

4693-
newComposer = createNewComposer();
4727+
newComposer = createNewComposer( title );
46944728
if ( !newComposer )
46954729
{
4696-
QMessageBox::warning( parent,
4697-
tr( "Composer error" ),
4698-
tr( "Error, could not create new composer" ) );
4730+
QgsDebugMsg( "could not create new composer" );
46994731
return newComposer;
47004732
}
4701-
newComposer->hide(); // until template is loaded (faster)
47024733

4734+
// disable updates until template is loaded (may be faster, but still gives user feedback),
4735+
// but is not as fast as hiding composer until template is loaded
4736+
newComposer->setUpdatesEnabled( false );
47034737
QApplication::setOverrideCursor( Qt::BusyCursor );
47044738
if ( !newComposer->composition()->loadFromTemplate( currentDoc, 0, false ) )
47054739
{
47064740
deleteComposer( newComposer );
4707-
QMessageBox::warning( parent,
4708-
tr( "Read error" ),
4709-
tr( "Error, composer could not be duplicated" ) );
4741+
newComposer = 0;
4742+
QgsDebugMsg( "Error, composer could not be duplicated" );
47104743
return newComposer;
47114744
}
4712-
newComposer->setTitle( newTitle );
4745+
newComposer->setUpdatesEnabled( true );
47134746
newComposer->activate();
47144747
QApplication::restoreOverrideCursor();
47154748

src/app/qgisapp.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,21 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
214214

215215
/**Returns the print composers*/
216216
QSet<QgsComposer*> printComposers() const {return mPrintComposers;}
217+
/** Get a unique title from user for new and duplicate composers
218+
* @param acceptEmpty whether to accept empty titles (one will be generated)
219+
* @param currentTitle base name for initial title choice
220+
* @return QString::null if user cancels input dialog
221+
* @note added in 1.9
222+
*/
223+
QString uniqueComposerTitle( QWidget* parent, bool acceptEmpty, const QString& currentTitle = QString( "" ) );
217224
/**Creates a new composer and returns a pointer to it*/
218-
QgsComposer* createNewComposer();
225+
QgsComposer* createNewComposer( QString title = QString( "" ) );
219226
/**Deletes a composer and removes entry from Set*/
220227
void deleteComposer( QgsComposer* c );
221228
/** Duplicates a composer and adds it to Set
222229
* @note added in 1.9
223230
*/
224-
QgsComposer* duplicateComposer( QgsComposer* currentComposer, QWidget* parent );
231+
QgsComposer* duplicateComposer( QgsComposer* currentComposer, QString title = QString( "" ) );
225232

226233
/** overloaded function used to sort menu entries alphabetically */
227234
QMenu* createPopupMenu();

0 commit comments

Comments
 (0)