Skip to content

Commit d07dadf

Browse files
committed
[FEATURE][composer] Add page number combo box to atlas toolbar
(fix #13136)
1 parent b431187 commit d07dadf

File tree

5 files changed

+140
-59
lines changed

5 files changed

+140
-59
lines changed

python/core/composer/qgsatlascomposition.sip

+10-1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ public:
216216

217217
/** Returns the current atlas feature. Must be called after prepareForFeature( i ). */
218218
QgsFeature* currentFeature();
219+
220+
/** Returns the current feature number.
221+
* @note added in QGIS 2.12
222+
*/
223+
int currentFeatureNumber() const;
219224

220225
/** Recalculates the bounds of an atlas driven map */
221226
void prepareMap( QgsComposerMap* map );
@@ -253,5 +258,9 @@ public:
253258

254259
/**Is emitted when the current atlas feature changes*/
255260
void featureChanged( QgsFeature* feature );
256-
261+
262+
/** Is emitted when the number of features for the atlas changes.
263+
* @note added in QGIS 2.12
264+
*/
265+
void numberFeaturesChanged( int numFeatures );
257266
};

src/app/composer/qgscomposer.cpp

+50-2
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,17 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
407407
atlasExportToolButton->addAction( mActionExportAtlasAsPDF );
408408
atlasExportToolButton->setDefaultAction( mActionExportAtlasAsImage );
409409
mAtlasToolbar->insertWidget( mActionAtlasSettings, atlasExportToolButton );
410+
mAtlasPageComboBox = new QComboBox();
411+
mAtlasPageComboBox->setEditable( true );
412+
mAtlasPageComboBox->addItem( QString::number( 1 ) );
413+
mAtlasPageComboBox->setCurrentIndex( 0 );
414+
mAtlasPageComboBox->setMinimumHeight( mAtlasToolbar->height() );
415+
mAtlasPageComboBox->setMinimumContentsLength( 6 );
416+
mAtlasPageComboBox->setMaxVisibleItems( 20 );
417+
mAtlasPageComboBox->setInsertPolicy( QComboBox::NoInsert );
418+
connect( mAtlasPageComboBox->lineEdit(), SIGNAL( editingFinished() ), this, SLOT( atlasPageComboEditingFinished() ) );
419+
connect( mAtlasPageComboBox, SIGNAL( currentIndexChanged( QString ) ), this, SLOT( atlasPageComboEditingFinished() ) );
420+
mAtlasToolbar->insertWidget( mActionAtlasNext, mAtlasPageComboBox );
410421

411422
QMenu *settingsMenu = menuBar()->addMenu( tr( "&Settings" ) );
412423
settingsMenu->addAction( mActionOptions );
@@ -613,12 +624,14 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
613624
mActionAtlasNext->setEnabled( false );
614625
mActionAtlasPrev->setEnabled( false );
615626
mActionPrintAtlas->setEnabled( false );
627+
mAtlasPageComboBox->setEnabled( false );
616628
mActionExportAtlasAsImage->setEnabled( false );
617629
mActionExportAtlasAsSVG->setEnabled( false );
618630
mActionExportAtlasAsPDF->setEnabled( false );
619631
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
620632
connect( atlasMap, SIGNAL( toggled( bool ) ), this, SLOT( toggleAtlasControls( bool ) ) );
621633
connect( atlasMap, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( updateAtlasMapLayerAction( QgsVectorLayer * ) ) );
634+
connect( atlasMap, SIGNAL( numberFeaturesChanged( int ) ), this, SLOT( updateAtlasPageComboBox( int ) ) );
622635

623636
//default printer page setup
624637
setPrinterPageDefaults();
@@ -968,6 +981,7 @@ void QgsComposer::toggleAtlasControls( bool atlasEnabled )
968981
mActionAtlasLast->setEnabled( false );
969982
mActionAtlasNext->setEnabled( false );
970983
mActionAtlasPrev->setEnabled( false );
984+
mAtlasPageComboBox->setEnabled( false );
971985
mActionAtlasPreview->blockSignals( false );
972986
mActionAtlasPreview->setEnabled( atlasEnabled );
973987
mActionPrintAtlas->setEnabled( atlasEnabled );
@@ -978,6 +992,20 @@ void QgsComposer::toggleAtlasControls( bool atlasEnabled )
978992
updateAtlasMapLayerAction( atlasEnabled );
979993
}
980994

995+
void QgsComposer::updateAtlasPageComboBox( int pageCount )
996+
{
997+
if ( pageCount == mAtlasPageComboBox->count() )
998+
return;
999+
1000+
mAtlasPageComboBox->blockSignals( true );
1001+
mAtlasPageComboBox->clear();
1002+
for ( int i = 1; i <= pageCount && i < 500; ++i )
1003+
{
1004+
mAtlasPageComboBox->addItem( QString::number( i ), i );
1005+
}
1006+
mAtlasPageComboBox->blockSignals( false );
1007+
}
1008+
9811009
void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )
9821010
{
9831011
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@@ -1002,6 +1030,7 @@ void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )
10021030
mActionAtlasLast->setEnabled( checked );
10031031
mActionAtlasNext->setEnabled( checked );
10041032
mActionAtlasPrev->setEnabled( checked );
1033+
mAtlasPageComboBox->setEnabled( checked );
10051034

10061035
if ( checked )
10071036
{
@@ -1022,6 +1051,7 @@ void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )
10221051
mActionAtlasLast->setEnabled( false );
10231052
mActionAtlasNext->setEnabled( false );
10241053
mActionAtlasPrev->setEnabled( false );
1054+
mAtlasPageComboBox->setEnabled( false );
10251055
mActionAtlasPreview->blockSignals( false );
10261056
mStatusAtlasLabel->setText( QString() );
10271057
return;
@@ -1036,10 +1066,8 @@ void QgsComposer::on_mActionAtlasPreview_triggered( bool checked )
10361066
{
10371067
mStatusAtlasLabel->setText( QString() );
10381068
}
1039-
10401069
}
10411070

1042-
10431071
void QgsComposer::on_mActionAtlasNext_triggered()
10441072
{
10451073
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@@ -1100,6 +1128,23 @@ void QgsComposer::on_mActionAtlasLast_triggered()
11001128
emit atlasPreviewFeatureChanged();
11011129
}
11021130

1131+
void QgsComposer::atlasPageComboEditingFinished()
1132+
{
1133+
QString text = mAtlasPageComboBox->lineEdit()->text();
1134+
bool ok = false;
1135+
int page = text.toInt( &ok );
1136+
if ( !ok || page >= mComposition->atlasComposition().numFeatures() )
1137+
{
1138+
mAtlasPageComboBox->blockSignals( true );
1139+
mAtlasPageComboBox->setCurrentIndex( mComposition->atlasComposition().currentFeatureNumber() );
1140+
mAtlasPageComboBox->blockSignals( false );
1141+
}
1142+
else if ( page != mComposition->atlasComposition().currentFeatureNumber() + 1 )
1143+
{
1144+
mComposition->atlasComposition().prepareForFeature( page - 1 );
1145+
}
1146+
}
1147+
11031148
QgsMapCanvas *QgsComposer::mapCanvas( void )
11041149
{
11051150
return mQgis->mapCanvas();
@@ -1415,6 +1460,7 @@ void QgsComposer::setComposition( QgsComposition* composition )
14151460
toggleAtlasControls( atlasMap->enabled() );
14161461
connect( atlasMap, SIGNAL( toggled( bool ) ), this, SLOT( toggleAtlasControls( bool ) ) );
14171462
connect( atlasMap, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( updateAtlasMapLayerAction( QgsVectorLayer * ) ) );
1463+
connect( atlasMap, SIGNAL( numberFeaturesChanged( int ) ), this, SLOT( updateAtlasPageComboBox( int ) ) );
14181464

14191465
//default printer page setup
14201466
setPrinterPageDefaults();
@@ -3233,6 +3279,7 @@ void QgsComposer::readXML( const QDomElement& composerElem, const QDomDocument&
32333279
toggleAtlasControls( atlasMap->enabled() );
32343280
connect( atlasMap, SIGNAL( toggled( bool ) ), this, SLOT( toggleAtlasControls( bool ) ) );
32353281
connect( atlasMap, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( updateAtlasMapLayerAction( QgsVectorLayer * ) ) );
3282+
connect( atlasMap, SIGNAL( numberFeaturesChanged( int ) ), this, SLOT( updateAtlasPageComboBox( int ) ) );
32363283

32373284
//default printer page setup
32383285
setPrinterPageDefaults();
@@ -3716,6 +3763,7 @@ void QgsComposer::setAtlasFeature( QgsMapLayer* layer, const QgsFeature& feat )
37163763
mActionAtlasLast->setEnabled( true );
37173764
mActionAtlasNext->setEnabled( true );
37183765
mActionAtlasPrev->setEnabled( true );
3766+
mAtlasPageComboBox->setEnabled( true );
37193767
}
37203768

37213769
//bring composer window to foreground

src/app/composer/qgscomposer.h

+30-22
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
343343
//!Last atlas feature
344344
void on_mActionAtlasLast_triggered();
345345

346+
//!Jump to a specific atlas page
347+
void atlasPageComboEditingFinished();
348+
346349
//! Print the atlas
347350
void on_mActionPrintAtlas_triggered();
348351

@@ -367,40 +370,40 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
367370
//! Save window state
368371
void saveWindowState();
369372

370-
/**Add a composer arrow to the item/widget map and creates a configuration widget for it*/
373+
/** Add a composer arrow to the item/widget map and creates a configuration widget for it*/
371374
void addComposerArrow( QgsComposerArrow* arrow );
372375

373-
/**Add a composer map to the item/widget map and creates a configuration widget for it*/
376+
/** Add a composer map to the item/widget map and creates a configuration widget for it*/
374377
void addComposerMap( QgsComposerMap* map );
375378

376-
/**Adds a composer label to the item/widget map and creates a configuration widget for it*/
379+
/** Adds a composer label to the item/widget map and creates a configuration widget for it*/
377380
void addComposerLabel( QgsComposerLabel* label );
378381

379-
/**Adds a composer scale bar to the item/widget map and creates a configuration widget for it*/
382+
/** Adds a composer scale bar to the item/widget map and creates a configuration widget for it*/
380383
void addComposerScaleBar( QgsComposerScaleBar* scalebar );
381384

382-
/**Adds a composer legend to the item/widget map and creates a configuration widget for it*/
385+
/** Adds a composer legend to the item/widget map and creates a configuration widget for it*/
383386
void addComposerLegend( QgsComposerLegend* legend );
384387

385-
/**Adds a composer picture to the item/widget map and creates a configuration widget*/
388+
/** Adds a composer picture to the item/widget map and creates a configuration widget*/
386389
void addComposerPicture( QgsComposerPicture* picture );
387390

388-
/**Adds a composer shape to the item/widget map and creates a configuration widget*/
391+
/** Adds a composer shape to the item/widget map and creates a configuration widget*/
389392
void addComposerShape( QgsComposerShape* shape );
390393

391-
/**Adds a composer table to the item/widget map and creates a configuration widget*/
394+
/** Adds a composer table to the item/widget map and creates a configuration widget*/
392395
void addComposerTable( QgsComposerAttributeTable* table );
393396

394-
/**Adds a composer table v2 to the item/widget map and creates a configuration widget*/
397+
/** Adds a composer table v2 to the item/widget map and creates a configuration widget*/
395398
void addComposerTableV2( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
396399

397-
/**Adds composer html and creates a configuration widget*/
400+
/** Adds composer html and creates a configuration widget*/
398401
void addComposerHtmlFrame( QgsComposerHtml* html, QgsComposerFrame* frame );
399402

400-
/**Removes item from the item/widget map and deletes the configuration widget. Does not delete the item itself*/
403+
/** Removes item from the item/widget map and deletes the configuration widget. Does not delete the item itself*/
401404
void deleteItem( QgsComposerItem* item );
402405

403-
/**Shows the configuration widget for a composer item*/
406+
/** Shows the configuration widget for a composer item*/
404407
void showItemOptions( QgsComposerItem* i );
405408

406409
//XML, usually connected with QgsProject::readProject and QgsProject::writeProject
@@ -438,19 +441,19 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
438441

439442
private:
440443

441-
/**Establishes the signal slot connections from the QgsComposerView to the composer*/
444+
/** Establishes the signal slot connections from the QgsComposerView to the composer*/
442445
void connectViewSlots();
443446

444-
/**Establishes the signal slot connections from the QgsComposition to the composer*/
447+
/** Establishes the signal slot connections from the QgsComposition to the composer*/
445448
void connectCompositionSlots();
446449

447-
/**Establishes other signal slot connections for the composer*/
450+
/** Establishes other signal slot connections for the composer*/
448451
void connectOtherSlots();
449452

450-
/**Creates the composition widget*/
453+
/** Creates the composition widget*/
451454
void createCompositionWidget();
452455

453-
/**Sets up the compositions undo/redo connections*/
456+
/** Sets up the compositions undo/redo connections*/
454457
void setupUndoView();
455458

456459
//! True if a composer map contains a WMS layer
@@ -510,19 +513,19 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
510513

511514
QPrinter* printer();
512515

513-
/**Composer title*/
516+
/** Composer title*/
514517
QString mTitle;
515518

516-
/**Labels in status bar which shows current mouse position*/
519+
/** Labels in status bar which shows current mouse position*/
517520
QLabel* mStatusCursorXLabel;
518521
QLabel* mStatusCursorYLabel;
519522
QLabel* mStatusCursorPageLabel;
520-
/**Combobox in status bar which shows/adjusts current zoom level*/
523+
/** Combobox in status bar which shows/adjusts current zoom level*/
521524
QComboBox* mStatusZoomCombo;
522525
QList<double> mStatusZoomLevelsList;
523-
/**Label in status bar which shows messages from the composition*/
526+
/** Label in status bar which shows messages from the composition*/
524527
QLabel* mStatusCompositionLabel;
525-
/**Label in status bar which shows atlas details*/
528+
/** Label in status bar which shows atlas details*/
526529
QLabel* mStatusAtlasLabel;
527530

528531
//! Pointer to composer view
@@ -570,6 +573,8 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
570573
QAction *mActionPreviewProtanope;
571574
QAction *mActionPreviewDeuteranope;
572575

576+
QComboBox* mAtlasPageComboBox;
577+
573578
//! We load composer map content from project xml only on demand. Therefore we need to store the real preview mode type
574579
QMap< QgsComposerMap*, int > mMapsToRestore;
575580

@@ -649,6 +654,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
649654

650655
void dockVisibilityChanged( bool visible );
651656

657+
/** Repopulates the atlas page combo box with valid items.
658+
*/
659+
void updateAtlasPageComboBox( int pageCount );
652660
};
653661

654662
#endif

src/core/composer/qgsatlascomposition.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ int QgsAtlasComposition::updateFeatures()
263263
}
264264

265265
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );
266+
emit numberFeaturesChanged( mFeatureIds.size() );
266267

267268
//jump to first feature if currently using an atlas preview
268269
//need to do this in case filtering/layer change has altered matching features
@@ -396,6 +397,11 @@ bool QgsAtlasComposition::prepareForFeature( const int featureI, const bool upda
396397
return false;
397398
}
398399

400+
if ( featureI >= mFeatureIds.size() )
401+
{
402+
return false;
403+
}
404+
399405
mCurrentFeatureNo = featureI;
400406

401407
// retrieve the next feature, based on its id

0 commit comments

Comments
 (0)