Skip to content

Commit

Permalink
[feature][composer] Allow multiple selection of compositions in manager
Browse files Browse the repository at this point in the history
Allows multiple compositions to be opened and deleted. Fix #2917.
  • Loading branch information
Médéric RIBREUX authored and nyalldawson committed Nov 29, 2015
1 parent 052fd79 commit 3c33177
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 85 deletions.
205 changes: 121 additions & 84 deletions src/app/composer/qgscomposermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@

QgsComposerManager::QgsComposerManager( QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f )
{
QPushButton *pb;

setupUi( this );

QSettings settings;
Expand All @@ -47,21 +45,19 @@ QgsComposerManager::QgsComposerManager( QWidget * parent, Qt::WindowFlags f ): Q
connect( QgisApp::instance(), SIGNAL( composerAdded( QgsComposerView* ) ), this, SLOT( refreshComposers() ) );
connect( QgisApp::instance(), SIGNAL( composerRemoved( QgsComposerView* ) ), this, SLOT( refreshComposers() ) );

pb = new QPushButton( tr( "&Show" ) );
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
connect( pb, SIGNAL( clicked() ), this, SLOT( show_clicked() ) );
connect( mComposerListWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( toggleButtons() ) );

mShowButton = mButtonBox->addButton( tr( "&Show" ), QDialogButtonBox::ActionRole );
connect( mShowButton, SIGNAL( clicked() ), this, SLOT( show_clicked() ) );

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

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

pb = new QPushButton( tr( "Re&name" ) );
mButtonBox->addButton( pb, QDialogButtonBox::ActionRole );
connect( pb, SIGNAL( clicked() ), this, SLOT( rename_clicked() ) );
mRenameButton = mButtonBox->addButton( tr( "Re&name" ), QDialogButtonBox::ActionRole );
connect( mRenameButton, SIGNAL( clicked() ), this, SLOT( rename_clicked() ) );

#ifdef Q_OS_MAC
// Create action to select this window
Expand Down Expand Up @@ -94,7 +90,16 @@ QgsComposerManager::~QgsComposerManager()

void QgsComposerManager::refreshComposers()
{
QString selName = mComposerListWidget->currentItem() ? mComposerListWidget->currentItem()->text() : "";
// Backup selection
QSet<QgsComposer *> selectedComposers;
Q_FOREACH ( QListWidgetItem* item, mComposerListWidget->selectedItems() )
{
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
{
selectedComposers << it.value();
}
}

mItemComposerMap.clear();
mComposerListWidget->clear();
Expand All @@ -110,14 +115,60 @@ void QgsComposerManager::refreshComposers()
mComposerListWidget->sortItems();

// Restore selection
if ( !selName.isEmpty() )
bool selectionRestored = false;
if ( !selectedComposers.isEmpty() )
{
QList<QListWidgetItem*> items = mComposerListWidget->findItems( selName, Qt::MatchExactly );
if ( !items.isEmpty() )
QMap<QListWidgetItem*, QgsComposer*>::const_iterator i = mItemComposerMap.constBegin();
while ( i != mItemComposerMap.constEnd() )
{
mComposerListWidget->setCurrentItem( items.first() );
// This composer was selected: reselect it !
if ( selectedComposers.contains( i.value() ) )
{
selectionRestored = true;
int inDex = mComposerListWidget->row( i.key() );
QModelIndex selectLine = mComposerListWidget->model()->index( inDex, 0, QModelIndex() );
mComposerListWidget->selectionModel()->select( selectLine, QItemSelectionModel::Select );
}
++i;
}
}
// Select the first item by default
if ( !selectionRestored && mComposerListWidget->count() > 0 )
{
QModelIndex firstLine = mComposerListWidget->model()->index( 0, 0, QModelIndex() );
mComposerListWidget->selectionModel()->select( firstLine, QItemSelectionModel::Select );
}

// Update buttons
toggleButtons();
}

void QgsComposerManager::toggleButtons()
{
// Nothing selected: no button.
if ( mComposerListWidget->selectedItems().isEmpty() )
{
mShowButton->setEnabled( false );
mRemoveButton->setEnabled( false );
mRenameButton->setEnabled( false );
mDuplicateButton->setEnabled( false );
}
// toggle everything if one composer is selected
else if ( mComposerListWidget->selectedItems().count() == 1 )
{
mShowButton->setEnabled( true );
mRemoveButton->setEnabled( true );
mRenameButton->setEnabled( true );
mDuplicateButton->setEnabled( true );
}
// toggle only show and remove buttons in other cases
else
{
mShowButton->setEnabled( true );
mRemoveButton->setEnabled( true );
mRenameButton->setEnabled( false );
mDuplicateButton->setEnabled( false );
}
}

void QgsComposerManager::addTemplates( const QMap<QString, QString>& templates )
Expand Down Expand Up @@ -164,7 +215,6 @@ QMap<QString, QString> QgsComposerManager::otherTemplates() const
return templateMap;
}


QMap<QString, QString> QgsComposerManager::templatesFromPath( const QString& path ) const
{
QMap<QString, QString> templateMap;
Expand Down Expand Up @@ -338,101 +388,86 @@ void QgsComposerManager::changeEvent( QEvent* event )

void QgsComposerManager::remove_clicked()
{
QListWidgetItem* item = mComposerListWidget->currentItem();
if ( !item )
QList<QgsComposer *> composerList;
QList<QListWidgetItem *> composerItems = mComposerListWidget->selectedItems();
QString title = tr( "Remove composers" );
QString message = tr( "Do you really want to remove all selected map composers ?" );

if ( composerItems.isEmpty() )
{
return;
}

//ask for confirmation
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 )
// Ask for confirmation
if ( composerItems.count() == 1 )
{
title = tr( "Remove composer" );
QListWidgetItem* uniqItem = composerItems.at( 0 );
message = tr( "Do you really want to remove the map composer '%1'?" ).arg( uniqItem->text() );
}

if ( QMessageBox::warning( this, title, message, QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
{
return;
}

//delete composer
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
// Find the QgsComposers that need to be deleted
Q_FOREACH ( QListWidgetItem* item, composerItems )
{
QgisApp::instance()->deleteComposer( it.value() );
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
{
composerList << it.value();
}
}
}

void QgsComposerManager::show_clicked()
{
QListWidgetItem* item = mComposerListWidget->currentItem();
if ( !item )
// Once we have the composer list, we can delete all of them !
Q_FOREACH ( QgsComposer* c, composerList )
{
return;
QgisApp::instance()->deleteComposer( c );
}
}

QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
void QgsComposerManager::show_clicked()
{
Q_FOREACH ( QListWidgetItem* item, mComposerListWidget->selectedItems() )
{
QgsComposer* c = 0;
if ( it.value() ) //a normal composer
QMap<QListWidgetItem*, QgsComposer*>::const_iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.constEnd() )
{
c = it.value();
if ( c )
QgsComposer* c = 0;
if ( it.value() ) //a normal composer
{
// extra activation steps for Windows
bool shown = c->isVisible();
c = it.value();
if ( c )
{
// extra activation steps for Windows
bool shown = c->isVisible();

c->activate();
c->activate();

// extra activation steps for Windows
if ( !shown )
{
c->on_mActionZoomAll_triggered();
// extra activation steps for Windows
if ( !shown )
{
c->on_mActionZoomAll_triggered();
}
}
}
}
}
#if 0
else //create composer from default template
{
QMap<QString, QString>::const_iterator templateIt = mDefaultTemplateMap.find( it.key()->text() );
if ( templateIt == mDefaultTemplateMap.constEnd() )
{
return;
}

QDomDocument templateDoc;
QFile templateFile( templateIt.value() );
if ( !templateFile.open( QIODevice::ReadOnly ) )
{
return;
}

if ( !templateDoc.setContent( &templateFile, false ) )
{
return;
}
c = QgisApp::instance()->createNewComposer();
c->setTitle( it.key()->text() );
if ( c )
{
c->readXML( templateDoc );
}
}

if ( c )
{
c->activate();
}
#endif //0
}

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

QgsComposer* currentComposer = 0;
QString currentTitle;

QListWidgetItem* item = mComposerListWidget->selectedItems().at( 0 );
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
{
Expand Down Expand Up @@ -475,14 +510,15 @@ void QgsComposerManager::duplicate_clicked()

void QgsComposerManager::rename_clicked()
{
QListWidgetItem* item = mComposerListWidget->currentItem();
if ( !item )
if ( mComposerListWidget->selectedItems().isEmpty() )
{
return;
}

QString currentTitle;
QgsComposer* currentComposer = 0;

QListWidgetItem* item = mComposerListWidget->selectedItems().at( 0 );
QMap<QListWidgetItem*, QgsComposer*>::iterator it = mItemComposerMap.find( item );
if ( it != mItemComposerMap.end() )
{
Expand All @@ -493,6 +529,7 @@ void QgsComposerManager::rename_clicked()
{
return;
}

QString newTitle;
if ( !QgisApp::instance()->uniqueComposerTitle( this, newTitle, false, currentTitle ) )
{
Expand Down
6 changes: 6 additions & 0 deletions src/app/composer/qgscomposermanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class QgsComposerManager: public QDialog, private Ui::QgsComposerManagerBase

QString mDefaultTemplatesDir;
QString mUserTemplatesDir;
QPushButton* mShowButton;
QPushButton* mRemoveButton;
QPushButton* mRenameButton;
QPushButton* mDuplicateButton;

#ifdef Q_OS_MAC
void showEvent( QShowEvent *event );
Expand All @@ -86,6 +90,8 @@ class QgsComposerManager: public QDialog, private Ui::QgsComposerManagerBase
#endif

private slots:
/** Slot to update buttons state when selecting compositions */
void toggleButtons();
void on_mAddButton_clicked();
/** Slot to track combobox to use specific template path */
void on_mTemplate_currentIndexChanged( int indx );
Expand Down
9 changes: 8 additions & 1 deletion src/ui/composer/qgscomposermanagerbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="mComposerListWidget"/>
<widget class="QListWidget" name="mComposerListWidget">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item>
<widget class="QgsCollapsibleGroupBox" name="mTemplateGrpBox">
Expand Down

0 comments on commit 3c33177

Please sign in to comment.