Skip to content

Commit

Permalink
[FEATURE][composer] Add checkbox for showing unique records only in c…
Browse files Browse the repository at this point in the history
…omposer

attribute tables. (Sponsored by my OCD)
  • Loading branch information
nyalldawson committed Sep 23, 2014
1 parent d37f75f commit 34f00d1
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 24 deletions.
14 changes: 14 additions & 0 deletions python/core/composer/qgscomposerattributetablev2.sip
Expand Up @@ -146,7 +146,21 @@ class QgsComposerAttributeTableV2 : QgsComposerTableV2
* @see setMaximumNumberOfFeatures
*/
int maximumNumberOfFeatures() const;

/**Sets attribute table to only show unique rows.
* @param uniqueOnly set to true to show only unique rows. Duplicate rows
* will be stripped from the table.
* @see uniqueRowsOnly
*/
void setUniqueRowsOnly( const bool uniqueOnly );

/**Returns true if the table is set to show only unique rows.
* @returns true if table only shows unique rows and is stripping out
* duplicate rows.
* @see setUniqueRowsOnly
*/
bool uniqueRowsOnly() const;

/**Sets attribute table to only show features which are visible in a composer map item. Changing
* this setting forces the table to refetch features from its vector layer, and may result in
* the table changing size to accommodate the new displayed feature attributes.
Expand Down
7 changes: 7 additions & 0 deletions python/core/composer/qgscomposertablev2.sip
Expand Up @@ -358,4 +358,11 @@ class QgsComposerTableV2: QgsComposerMultiFrame
*/
void recalculateTableSize();

/**Checks whether a table contents contains a given row
* @param contents table contents to check
* @param row row to check for
* @returns true if contents contains rows
*/
bool contentsContainsRow( const QgsComposerTableContents &contents, const QgsComposerTableRow &row ) const;

};
58 changes: 43 additions & 15 deletions src/app/composer/qgsattributeselectiondialog.cpp
Expand Up @@ -383,15 +383,21 @@ void QgsAttributeSelectionDialog::on_mRemoveColumnPushButton_clicked()
{
//remove selected row from model
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModel->removeRow( selectedRow );
if ( viewSelection.length() > 0 )
{
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModel->removeRow( selectedRow );
}
}
if ( mComposerTableV1 )
{
//remove selected row from model
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModelV1->removeRow( selectedRow );
if ( viewSelection.length() > 0 )
{
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModelV1->removeRow( selectedRow );
}
}

}
Expand All @@ -416,15 +422,21 @@ void QgsAttributeSelectionDialog::on_mColumnUpPushButton_clicked()
{
//move selected row up
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModel->moveRow( selectedRow, QgsComposerAttributeTableColumnModelV2::ShiftUp );
if ( viewSelection.size() > 0 )
{
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModel->moveRow( selectedRow, QgsComposerAttributeTableColumnModelV2::ShiftUp );
}
}
else if ( mComposerTableV1 )
{
//move selected row up
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModelV1->moveRow( selectedRow, QgsComposerAttributeTableColumnModel::ShiftUp );
if ( viewSelection.size() > 0 )
{
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModelV1->moveRow( selectedRow, QgsComposerAttributeTableColumnModel::ShiftUp );
}
}
}

Expand All @@ -434,15 +446,21 @@ void QgsAttributeSelectionDialog::on_mColumnDownPushButton_clicked()
{
//move selected row down
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModel->moveRow( selectedRow, QgsComposerAttributeTableColumnModelV2::ShiftDown );
if ( viewSelection.size() > 0 )
{
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModel->moveRow( selectedRow, QgsComposerAttributeTableColumnModelV2::ShiftDown );
}
}
else if ( mComposerTableV1 )
{
//move selected row down
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModelV1->moveRow( selectedRow, QgsComposerAttributeTableColumnModel::ShiftDown );
if ( viewSelection.size() > 0 )
{
int selectedRow = viewSelection.indexes().at( 0 ).row();
mColumnModelV1->moveRow( selectedRow, QgsComposerAttributeTableColumnModel::ShiftDown );
}
}

}
Expand Down Expand Up @@ -498,8 +516,11 @@ void QgsAttributeSelectionDialog::on_mAddSortColumnPushButton_clicked()
void QgsAttributeSelectionDialog::on_mRemoveSortColumnPushButton_clicked()
{
//remove selected rows from sort order widget

QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
if ( sortSelection.length() < 1 )
{
return;
}
QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
int rowToRemove = selectedIndex.row();

Expand Down Expand Up @@ -536,6 +557,10 @@ void QgsAttributeSelectionDialog::on_mSortColumnUpPushButton_clicked()
{
//find selected row
QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
if ( sortSelection.length() < 1 )
{
return;
}
QModelIndex selectedIndex = sortSelection.indexes().at( 0 );

if ( mComposerTable )
Expand All @@ -562,10 +587,13 @@ void QgsAttributeSelectionDialog::on_mSortColumnUpPushButton_clicked()

void QgsAttributeSelectionDialog::on_mSortColumnDownPushButton_clicked()
{


//find selected row
QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
if ( sortSelection.length() < 1 )
{
return;
}

QModelIndex selectedIndex = sortSelection.indexes().at( 0 );

if ( mComposerTable )
Expand Down
22 changes: 22 additions & 0 deletions src/app/composer/qgscomposerattributetablewidget.cpp
Expand Up @@ -491,6 +491,7 @@ void QgsComposerAttributeTableWidget::updateGuiElements()
mComposerMapLabel->setEnabled( false );
}

mUniqueOnlyCheckBox->setChecked( mComposerTable->uniqueRowsOnly() );
mIntersectAtlasCheckBox->setChecked( mComposerTable->filterToAtlasFeature() );
mFeatureFilterEdit->setText( mComposerTable->featureFilter() );
mFeatureFilterCheckBox->setCheckState( mComposerTable->filterFeatures() ? Qt::Checked : Qt::Unchecked );
Expand Down Expand Up @@ -595,6 +596,7 @@ void QgsComposerAttributeTableWidget::blockAllSignals( bool b )
mGridStrokeWidthSpinBox->blockSignals( b );
mShowGridGroupCheckBox->blockSignals( b );
mShowOnlyVisibleFeaturesCheckBox->blockSignals( b );
mUniqueOnlyCheckBox->blockSignals( b );
mIntersectAtlasCheckBox->blockSignals( b );
mFeatureFilterEdit->blockSignals( b );
mFeatureFilterCheckBox->blockSignals( b );
Expand Down Expand Up @@ -640,6 +642,26 @@ void QgsComposerAttributeTableWidget::on_mShowOnlyVisibleFeaturesCheckBox_stateC
mComposerMapLabel->setEnabled( state == Qt::Checked );
}

void QgsComposerAttributeTableWidget::on_mUniqueOnlyCheckBox_stateChanged( int state )
{
if ( !mComposerTable )
{
return;
}

QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table remove duplicates changed" ) );
}
mComposerTable->setUniqueRowsOnly( state == Qt::Checked );
mComposerTable->update();
if ( composition )
{
composition->endMultiFrameCommand();
}
}

void QgsComposerAttributeTableWidget::on_mIntersectAtlasCheckBox_stateChanged( int state )
{
if ( !mComposerTable )
Expand Down
1 change: 1 addition & 0 deletions src/app/composer/qgscomposerattributetablewidget.h
Expand Up @@ -73,6 +73,7 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
void on_mEmptyModeComboBox_currentIndexChanged( int index );
void on_mEmptyMessageLineEdit_editingFinished();
void on_mIntersectAtlasCheckBox_stateChanged( int state );
void on_mUniqueOnlyCheckBox_stateChanged( int state );

/**Inserts a new maximum number of features into the spin box (without the spinbox emitting a signal)*/
void setMaximumNumberOfFeatures( int n );
Expand Down
23 changes: 21 additions & 2 deletions src/core/composer/qgscomposerattributetablev2.cpp
Expand Up @@ -104,6 +104,7 @@ QgsComposerAttributeTableV2::QgsComposerAttributeTableV2( QgsComposition* compos
, mCurrentAtlasLayer( 0 )
, mComposerMap( 0 )
, mMaximumNumberOfFeatures( 5 )
, mShowUniqueRowsOnly( false )
, mShowOnlyVisibleFeatures( false )
, mFilterToAtlasIntersection( false )
, mFilterFeatures( false )
Expand Down Expand Up @@ -293,6 +294,18 @@ void QgsComposerAttributeTableV2::setMaximumNumberOfFeatures( const int features
emit changed();
}

void QgsComposerAttributeTableV2::setUniqueRowsOnly( const bool uniqueOnly )
{
if ( uniqueOnly == mShowUniqueRowsOnly )
{
return;
}

mShowUniqueRowsOnly = uniqueOnly;
refreshAttributes();
emit changed();
}

void QgsComposerAttributeTableV2::setDisplayOnlyVisibleFeatures( const bool visibleOnly )
{
if ( visibleOnly == mShowOnlyVisibleFeatures )
Expand Down Expand Up @@ -555,8 +568,12 @@ bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &co
currentRow << value;
}
}
contents << currentRow;
++counter;

if ( !mShowUniqueRowsOnly || !contentsContainsRow( contents, currentRow ) )
{
contents << currentRow;
++counter;
}
}

//sort the list, starting with the last attribute
Expand Down Expand Up @@ -644,6 +661,7 @@ bool QgsComposerAttributeTableV2::writeXML( QDomElement& elem, QDomDocument & do
QDomElement composerTableElem = doc.createElement( "ComposerAttributeTableV2" );
composerTableElem.setAttribute( "source", QString::number(( int )mSource ) );
composerTableElem.setAttribute( "relationId", mRelationId );
composerTableElem.setAttribute( "showUniqueRowsOnly", mShowUniqueRowsOnly );
composerTableElem.setAttribute( "showOnlyVisibleFeatures", mShowOnlyVisibleFeatures );
composerTableElem.setAttribute( "filterToAtlasIntersection", mFilterToAtlasIntersection );
composerTableElem.setAttribute( "maxFeatures", mMaximumNumberOfFeatures );
Expand Down Expand Up @@ -698,6 +716,7 @@ bool QgsComposerAttributeTableV2::readXML( const QDomElement& itemElem, const QD
mCurrentAtlasLayer = mComposition->atlasComposition().coverageLayer();
}

mShowUniqueRowsOnly = itemElem.attribute( "showUniqueRowsOnly", "0" ).toInt();
mShowOnlyVisibleFeatures = itemElem.attribute( "showOnlyVisibleFeatures", "1" ).toInt();
mFilterToAtlasIntersection = itemElem.attribute( "filterToAtlasIntersection", "0" ).toInt();
mFilterFeatures = itemElem.attribute( "filterFeatures", "false" ) == "true" ? true : false;
Expand Down
17 changes: 17 additions & 0 deletions src/core/composer/qgscomposerattributetablev2.h
Expand Up @@ -170,6 +170,20 @@ class CORE_EXPORT QgsComposerAttributeTableV2: public QgsComposerTableV2
*/
int maximumNumberOfFeatures() const { return mMaximumNumberOfFeatures; }

/**Sets attribute table to only show unique rows.
* @param uniqueOnly set to true to show only unique rows. Duplicate rows
* will be stripped from the table.
* @see uniqueRowsOnly
*/
void setUniqueRowsOnly( const bool uniqueOnly );

/**Returns true if the table is set to show only unique rows.
* @returns true if table only shows unique rows and is stripping out
* duplicate rows.
* @see setUniqueRowsOnly
*/
bool uniqueRowsOnly() const { return mShowUniqueRowsOnly; }

/**Sets attribute table to only show features which are visible in a composer map item. Changing
* this setting forces the table to refetch features from its vector layer, and may result in
* the table changing size to accommodate the new displayed feature attributes.
Expand Down Expand Up @@ -278,6 +292,9 @@ class CORE_EXPORT QgsComposerAttributeTableV2: public QgsComposerTableV2
/**Maximum number of features that is displayed*/
int mMaximumNumberOfFeatures;

/**True if only unique rows should be shown*/
bool mShowUniqueRowsOnly;

/**Shows only the features that are visible in the associated composer map (true by default)*/
bool mShowOnlyVisibleFeatures;

Expand Down
12 changes: 12 additions & 0 deletions src/core/composer/qgscomposertablev2.cpp
Expand Up @@ -801,3 +801,15 @@ void QgsComposerTableV2::recalculateTableSize()
//fixed and minimum frame sizes
recalculateFrameRects();
}

bool QgsComposerTableV2::contentsContainsRow( const QgsComposerTableContents &contents, const QgsComposerTableRow &row ) const
{
if ( contents.indexOf( row ) >= 0 )
{
return true;
}
else
{
return false;
}
}
9 changes: 9 additions & 0 deletions src/core/composer/qgscomposertablev2.h
Expand Up @@ -428,6 +428,15 @@ class CORE_EXPORT QgsComposerTableV2: public QgsComposerMultiFrame
/**Recalculates and updates the size of the table and all table frames.
*/
void recalculateTableSize();

/**Checks whether a table contents contains a given row
* @param contents table contents to check
* @param row row to check for
* @returns true if contents contains rows
*/
bool contentsContainsRow( const QgsComposerTableContents &contents, const QgsComposerTableRow &row ) const;

friend class TestQgsComposerTableV2;
};

#endif // QGSCOMPOSERTABLEV2_H

0 comments on commit 34f00d1

Please sign in to comment.