mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
[composer] Initial groundwork for multiframe table item (Sponsored
by City of Uster, Switzerland)
This commit is contained in:
parent
39700e7d97
commit
fefc243b71
@ -114,6 +114,7 @@ SET(QGIS_APP_SRCS
|
||||
composer/qgsattributeselectiondialog.cpp
|
||||
composer/qgscomposer.cpp
|
||||
composer/qgscomposerarrowwidget.cpp
|
||||
composer/qgscomposerattributetablewidget.cpp
|
||||
composer/qgscomposerhtmlwidget.cpp
|
||||
composer/qgscomposeritemwidget.cpp
|
||||
composer/qgscomposerlabelwidget.cpp
|
||||
@ -253,6 +254,7 @@ SET (QGIS_APP_MOC_HDRS
|
||||
composer/qgsattributeselectiondialog.h
|
||||
composer/qgscomposer.h
|
||||
composer/qgscomposerarrowwidget.h
|
||||
composer/qgscomposerattributetablewidget.h
|
||||
composer/qgscomposerhtmlwidget.h
|
||||
composer/qgscomposeritemwidget.h
|
||||
composer/qgscomposerlabelwidget.h
|
||||
|
@ -16,8 +16,9 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsattributeselectiondialog.h"
|
||||
#include "qgscomposerattributetable.h"
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgscomposerattributetablemodel.h"
|
||||
#include "qgscomposerattributetablemodelv2.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsfieldexpressionwidget.h"
|
||||
#include <QCheckBox>
|
||||
@ -219,13 +220,17 @@ void QgsComposerColumnSortOrderDelegate::updateEditorGeometry( QWidget* editor,
|
||||
|
||||
// QgsAttributeSelectionDialog
|
||||
|
||||
QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTable* table, QgsVectorLayer* vLayer,
|
||||
QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTableV2* table, QgsVectorLayer* vLayer,
|
||||
QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f ),
|
||||
mComposerTable( table ),
|
||||
mComposerTableV1( 0 ),
|
||||
mVectorLayer( vLayer ),
|
||||
mColumnModel( 0 ),
|
||||
mColumnModelV1( 0 ),
|
||||
mSortedProxyModel( 0 ),
|
||||
mSortedProxyModelV1( 0 ),
|
||||
mAvailableSortProxyModel( 0 ),
|
||||
mAvailableSortProxyModelV1( 0 ),
|
||||
mColumnAlignmentDelegate( 0 ),
|
||||
mColumnSortOrderDelegate( 0 )
|
||||
{
|
||||
@ -237,7 +242,7 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
|
||||
if ( mComposerTable )
|
||||
{
|
||||
//set up models, views and delegates
|
||||
mColumnModel = new QgsComposerAttributeTableColumnModel( mComposerTable , mColumnsTableView );
|
||||
mColumnModel = new QgsComposerAttributeTableColumnModelV2( mComposerTable , mColumnsTableView );
|
||||
mColumnsTableView->setModel( mColumnModel );
|
||||
mColumnsTableView->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
|
||||
|
||||
@ -246,7 +251,7 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
|
||||
mColumnAlignmentDelegate = new QgsComposerColumnAlignmentDelegate( mColumnsTableView );
|
||||
mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
|
||||
|
||||
mAvailableSortProxyModel = new QgsComposerTableSortColumnsProxyModel( mComposerTable, QgsComposerTableSortColumnsProxyModel::ShowUnsortedColumns, mSortColumnComboBox );
|
||||
mAvailableSortProxyModel = new QgsComposerTableSortColumnsProxyModelV2( mComposerTable, QgsComposerTableSortColumnsProxyModelV2::ShowUnsortedColumns, mSortColumnComboBox );
|
||||
mAvailableSortProxyModel->setSourceModel( mColumnModel );
|
||||
mSortColumnComboBox->setModel( mAvailableSortProxyModel );
|
||||
mSortColumnComboBox->setModelColumn( 0 );
|
||||
@ -254,7 +259,7 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
|
||||
mColumnSortOrderDelegate = new QgsComposerColumnSortOrderDelegate( mSortColumnTableView );
|
||||
mSortColumnTableView->setItemDelegateForColumn( 1, mColumnSortOrderDelegate );
|
||||
|
||||
mSortedProxyModel = new QgsComposerTableSortColumnsProxyModel( mComposerTable, QgsComposerTableSortColumnsProxyModel::ShowSortedColumns, mSortColumnTableView );
|
||||
mSortedProxyModel = new QgsComposerTableSortColumnsProxyModelV2( mComposerTable, QgsComposerTableSortColumnsProxyModelV2::ShowSortedColumns, mSortColumnTableView );
|
||||
mSortedProxyModel->setSourceModel( mColumnModel );
|
||||
mSortedProxyModel->sort( 0, Qt::AscendingOrder );
|
||||
mSortColumnTableView->setSortingEnabled( false );
|
||||
@ -266,6 +271,57 @@ QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTa
|
||||
mOrderComboBox->insertItem( 1, tr( "Descending" ) );
|
||||
}
|
||||
|
||||
QgsAttributeSelectionDialog::QgsAttributeSelectionDialog( QgsComposerAttributeTable *table, QgsVectorLayer *vLayer, QWidget *parent, Qt::WindowFlags f )
|
||||
: QDialog( parent, f ),
|
||||
mComposerTable( 0 ),
|
||||
mComposerTableV1( table ),
|
||||
mVectorLayer( vLayer ),
|
||||
mColumnModel( 0 ),
|
||||
mColumnModelV1( 0 ),
|
||||
mSortedProxyModel( 0 ),
|
||||
mSortedProxyModelV1( 0 ),
|
||||
mAvailableSortProxyModel( 0 ),
|
||||
mAvailableSortProxyModelV1( 0 ),
|
||||
mColumnAlignmentDelegate( 0 ),
|
||||
mColumnSortOrderDelegate( 0 )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
QSettings settings;
|
||||
restoreGeometry( settings.value( "/Windows/AttributeSelectionDialog/geometry" ).toByteArray() );
|
||||
|
||||
if ( mComposerTableV1 )
|
||||
{
|
||||
//set up models, views and delegates
|
||||
mColumnModelV1 = new QgsComposerAttributeTableColumnModel( mComposerTableV1 , mColumnsTableView );
|
||||
mColumnsTableView->setModel( mColumnModelV1 );
|
||||
mColumnsTableView->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
|
||||
|
||||
mColumnSourceDelegate = new QgsComposerColumnSourceDelegate( vLayer, mColumnsTableView );
|
||||
mColumnsTableView->setItemDelegateForColumn( 0, mColumnSourceDelegate );
|
||||
mColumnAlignmentDelegate = new QgsComposerColumnAlignmentDelegate( mColumnsTableView );
|
||||
mColumnsTableView->setItemDelegateForColumn( 2, mColumnAlignmentDelegate );
|
||||
|
||||
mAvailableSortProxyModelV1 = new QgsComposerTableSortColumnsProxyModel( mComposerTableV1, QgsComposerTableSortColumnsProxyModel::ShowUnsortedColumns, mSortColumnComboBox );
|
||||
mAvailableSortProxyModelV1->setSourceModel( mColumnModelV1 );
|
||||
mSortColumnComboBox->setModel( mAvailableSortProxyModelV1 );
|
||||
mSortColumnComboBox->setModelColumn( 0 );
|
||||
|
||||
mColumnSortOrderDelegate = new QgsComposerColumnSortOrderDelegate( mSortColumnTableView );
|
||||
mSortColumnTableView->setItemDelegateForColumn( 1, mColumnSortOrderDelegate );
|
||||
|
||||
mSortedProxyModelV1 = new QgsComposerTableSortColumnsProxyModel( mComposerTableV1, QgsComposerTableSortColumnsProxyModel::ShowSortedColumns, mSortColumnTableView );
|
||||
mSortedProxyModelV1->setSourceModel( mColumnModelV1 );
|
||||
mSortedProxyModelV1->sort( 0, Qt::AscendingOrder );
|
||||
mSortColumnTableView->setSortingEnabled( false );
|
||||
mSortColumnTableView->setModel( mSortedProxyModelV1 );
|
||||
mSortColumnTableView->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
|
||||
}
|
||||
|
||||
mOrderComboBox->insertItem( 0, tr( "Ascending" ) );
|
||||
mOrderComboBox->insertItem( 1, tr( "Descending" ) );
|
||||
}
|
||||
|
||||
QgsAttributeSelectionDialog::~QgsAttributeSelectionDialog()
|
||||
{
|
||||
QSettings settings;
|
||||
@ -274,63 +330,86 @@ QgsAttributeSelectionDialog::~QgsAttributeSelectionDialog()
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mRemoveColumnPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
//remove selected row from model
|
||||
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
|
||||
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 );
|
||||
}
|
||||
|
||||
//remove selected row from model
|
||||
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
|
||||
int selectedRow = viewSelection.indexes().at( 0 ).row();
|
||||
mColumnModel->removeRow( selectedRow );
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mAddColumnPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
//add a new row to the model
|
||||
mColumnModel->insertRow( mColumnModel->rowCount() );
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
//add a new row to the model
|
||||
mColumnModelV1->insertRow( mColumnModelV1->rowCount() );
|
||||
}
|
||||
|
||||
//add a new row to the model
|
||||
mColumnModel->insertRow( mColumnModel->rowCount() );
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mColumnUpPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
//move selected row up
|
||||
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
|
||||
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 );
|
||||
}
|
||||
|
||||
//move selected row up
|
||||
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
|
||||
int selectedRow = viewSelection.indexes().at( 0 ).row();
|
||||
mColumnModel->moveRow( selectedRow, QgsComposerAttributeTableColumnModel::ShiftUp );
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mColumnDownPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
//move selected row down
|
||||
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
|
||||
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 );
|
||||
}
|
||||
|
||||
//move selected row down
|
||||
QItemSelection viewSelection( mColumnsTableView->selectionModel()->selection() );
|
||||
int selectedRow = viewSelection.indexes().at( 0 ).row();
|
||||
mColumnModel->moveRow( selectedRow, QgsComposerAttributeTableColumnModel::ShiftDown );
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mResetColumnsPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
//reset columns to match vector layer's fields
|
||||
mColumnModel->resetToLayer();
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
//reset columns to match vector layer's fields
|
||||
mColumnModelV1->resetToLayer();
|
||||
}
|
||||
|
||||
//reset columns to match vector layer's fields
|
||||
mColumnModel->resetToLayer();
|
||||
|
||||
mSortColumnComboBox->setCurrentIndex( 0 );
|
||||
}
|
||||
@ -338,83 +417,126 @@ void QgsAttributeSelectionDialog::on_mResetColumnsPushButton_clicked()
|
||||
void QgsAttributeSelectionDialog::on_mAddSortColumnPushButton_clicked()
|
||||
{
|
||||
//add column to sort order widget
|
||||
if ( !mComposerTable )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
QgsComposerTableColumn* column = mAvailableSortProxyModel->columnFromRow( mSortColumnComboBox->currentIndex() );
|
||||
if ( ! column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mColumnModel->setColumnAsSorted( column, mOrderComboBox->currentIndex() == 0 ? Qt::AscendingOrder : Qt::DescendingOrder );
|
||||
|
||||
//required so that rows can be reordered if initially no rows were shown in the table view
|
||||
mSortedProxyModel->resetFilter();
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
QgsComposerTableColumn* column = mAvailableSortProxyModelV1->columnFromRow( mSortColumnComboBox->currentIndex() );
|
||||
if ( ! column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mColumnModelV1->setColumnAsSorted( column, mOrderComboBox->currentIndex() == 0 ? Qt::AscendingOrder : Qt::DescendingOrder );
|
||||
|
||||
//required so that rows can be reordered if initially no rows were shown in the table view
|
||||
mSortedProxyModelV1->resetFilter();
|
||||
}
|
||||
|
||||
QgsComposerTableColumn* column = mAvailableSortProxyModel->columnFromRow( mSortColumnComboBox->currentIndex() );
|
||||
if ( ! column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mColumnModel->setColumnAsSorted( column, mOrderComboBox->currentIndex() == 0 ? Qt::AscendingOrder : Qt::DescendingOrder );
|
||||
|
||||
//required so that rows can be reordered if initially no rows were shown in the table view
|
||||
mSortedProxyModel->resetFilter();
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mRemoveSortColumnPushButton_clicked()
|
||||
{
|
||||
//remove selected rows from sort order widget
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
|
||||
QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
|
||||
int rowToRemove = selectedIndex.row();
|
||||
|
||||
//find corresponding column
|
||||
QgsComposerTableColumn * column = mSortedProxyModel->columnFromIndex( selectedIndex );
|
||||
QgsComposerTableColumn * column = 0;
|
||||
if ( mComposerTable )
|
||||
{
|
||||
column = mSortedProxyModel->columnFromIndex( selectedIndex );
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
column = mSortedProxyModelV1->columnFromIndex( selectedIndex );
|
||||
}
|
||||
|
||||
if ( !column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//set column as unsorted
|
||||
mColumnModel->setColumnAsUnsorted( column );
|
||||
|
||||
if ( mComposerTable )
|
||||
{
|
||||
mColumnModel->setColumnAsUnsorted( column );
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
mColumnModelV1->setColumnAsUnsorted( column );
|
||||
}
|
||||
//set next row as selected
|
||||
mSortColumnTableView->selectRow( rowToRemove );
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mSortColumnUpPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//find selected row
|
||||
QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
|
||||
QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
|
||||
QgsComposerTableColumn * column = mSortedProxyModel->columnFromIndex( selectedIndex );
|
||||
|
||||
if ( !column )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
QgsComposerTableColumn * column = mSortedProxyModel->columnFromIndex( selectedIndex );
|
||||
|
||||
if ( !column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
mColumnModel->moveColumnInSortRank( column, QgsComposerAttributeTableColumnModelV2::ShiftUp );
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
QgsComposerTableColumn * column = mSortedProxyModelV1->columnFromIndex( selectedIndex );
|
||||
|
||||
if ( !column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
mColumnModelV1->moveColumnInSortRank( column, QgsComposerAttributeTableColumnModel::ShiftUp );
|
||||
}
|
||||
mColumnModel->moveColumnInSortRank( column, QgsComposerAttributeTableColumnModel::ShiftUp );
|
||||
}
|
||||
|
||||
void QgsAttributeSelectionDialog::on_mSortColumnDownPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//find selected row
|
||||
QItemSelection sortSelection( mSortColumnTableView->selectionModel()->selection() );
|
||||
QModelIndex selectedIndex = sortSelection.indexes().at( 0 );
|
||||
QgsComposerTableColumn * column = mSortedProxyModel->columnFromIndex( selectedIndex );
|
||||
|
||||
if ( !column )
|
||||
if ( mComposerTable )
|
||||
{
|
||||
return;
|
||||
QgsComposerTableColumn * column = mSortedProxyModel->columnFromIndex( selectedIndex );
|
||||
|
||||
if ( !column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
mColumnModel->moveColumnInSortRank( column, QgsComposerAttributeTableColumnModelV2::ShiftDown );
|
||||
}
|
||||
else if ( mComposerTableV1 )
|
||||
{
|
||||
QgsComposerTableColumn * column = mSortedProxyModelV1->columnFromIndex( selectedIndex );
|
||||
|
||||
if ( !column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
mColumnModelV1->moveColumnInSortRank( column, QgsComposerAttributeTableColumnModel::ShiftDown );
|
||||
}
|
||||
mColumnModel->moveColumnInSortRank( column, QgsComposerAttributeTableColumnModel::ShiftDown );
|
||||
}
|
||||
|
@ -28,9 +28,12 @@ class QGridLayout;
|
||||
class QgsVectorLayer;
|
||||
class QPushButton;
|
||||
class QgsComposerAttributeTable;
|
||||
class QgsComposerAttributeTableV2;
|
||||
class QgsComposerAttributeTableColumnModel;
|
||||
class QgsComposerAttributeTableColumnModelV2;
|
||||
class QgsComposerTableSortColumnsProxyModel;
|
||||
class QgsComposerTableAvailableSortProxyModel;
|
||||
class QgsComposerTableSortColumnsProxyModelV2;
|
||||
class QgsComposerTableAvailableSortProxyModelV2;
|
||||
|
||||
// QgsComposerColumnAlignmentDelegate
|
||||
|
||||
@ -93,7 +96,12 @@ class QgsAttributeSelectionDialog: public QDialog, private Ui::QgsAttributeSelec
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsAttributeSelectionDialog( QgsComposerAttributeTableV2* table, QgsVectorLayer* vLayer, QWidget * parent = 0, Qt::WindowFlags f = 0 );
|
||||
|
||||
//todo - remove for QGIS 3.0
|
||||
QgsAttributeSelectionDialog( QgsComposerAttributeTable* table, QgsVectorLayer* vLayer, QWidget * parent = 0, Qt::WindowFlags f = 0 );
|
||||
|
||||
|
||||
~QgsAttributeSelectionDialog();
|
||||
|
||||
private slots:
|
||||
@ -108,12 +116,20 @@ class QgsAttributeSelectionDialog: public QDialog, private Ui::QgsAttributeSelec
|
||||
void on_mSortColumnDownPushButton_clicked();
|
||||
|
||||
private:
|
||||
QgsComposerAttributeTable* mComposerTable;
|
||||
QgsComposerAttributeTableV2* mComposerTable;
|
||||
QgsComposerAttributeTable* mComposerTableV1;
|
||||
|
||||
const QgsVectorLayer* mVectorLayer;
|
||||
|
||||
QgsComposerAttributeTableColumnModel* mColumnModel;
|
||||
QgsComposerTableSortColumnsProxyModel* mSortedProxyModel;
|
||||
QgsComposerTableSortColumnsProxyModel* mAvailableSortProxyModel;
|
||||
QgsComposerAttributeTableColumnModelV2* mColumnModel;
|
||||
QgsComposerAttributeTableColumnModel* mColumnModelV1;
|
||||
|
||||
QgsComposerTableSortColumnsProxyModelV2* mSortedProxyModel;
|
||||
QgsComposerTableSortColumnsProxyModel* mSortedProxyModelV1;
|
||||
|
||||
QgsComposerTableSortColumnsProxyModelV2* mAvailableSortProxyModel;
|
||||
QgsComposerTableSortColumnsProxyModel* mAvailableSortProxyModelV1;
|
||||
|
||||
QgsComposerColumnAlignmentDelegate *mColumnAlignmentDelegate;
|
||||
QgsComposerColumnSourceDelegate *mColumnSourceDelegate;
|
||||
QgsComposerColumnSortOrderDelegate *mColumnSortOrderDelegate;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "qgsatlascompositionwidget.h"
|
||||
#include "qgscomposerarrow.h"
|
||||
#include "qgscomposerarrowwidget.h"
|
||||
#include "qgscomposerattributetablewidget.h"
|
||||
#include "qgscomposerframe.h"
|
||||
#include "qgscomposerhtml.h"
|
||||
#include "qgscomposerhtmlwidget.h"
|
||||
@ -46,6 +47,7 @@
|
||||
#include "qgscomposershape.h"
|
||||
#include "qgscomposershapewidget.h"
|
||||
#include "qgscomposerattributetable.h"
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgscomposertablewidget.h"
|
||||
#include "qgsexception.h"
|
||||
#include "qgslogger.h"
|
||||
@ -166,6 +168,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
|
||||
toggleActionGroup->addAction( mActionAddEllipse );
|
||||
toggleActionGroup->addAction( mActionAddArrow );
|
||||
toggleActionGroup->addAction( mActionAddTable );
|
||||
toggleActionGroup->addAction( mActionAddAttributeTable );
|
||||
toggleActionGroup->addAction( mActionAddHtml );
|
||||
toggleActionGroup->setExclusive( true );
|
||||
|
||||
@ -353,6 +356,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
|
||||
layoutMenu->addAction( mActionAddImage );
|
||||
layoutMenu->addAction( mActionAddArrow );
|
||||
layoutMenu->addAction( mActionAddTable );
|
||||
layoutMenu->addAction( mActionAddAttributeTable );
|
||||
layoutMenu->addSeparator();
|
||||
layoutMenu->addAction( mActionSelectMoveItem );
|
||||
layoutMenu->addAction( mActionMoveItemContent );
|
||||
@ -667,6 +671,7 @@ void QgsComposer::setupTheme()
|
||||
mActionAddEllipse->setIcon( QgsApplication::getThemeIcon( "/mActionAddBasicShape.png" ) );
|
||||
mActionAddArrow->setIcon( QgsApplication::getThemeIcon( "/mActionAddArrow.png" ) );
|
||||
mActionAddTable->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ) );
|
||||
mActionAddAttributeTable->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ) );
|
||||
mActionAddHtml->setIcon( QgsApplication::getThemeIcon( "/mActionAddHtml.png" ) );
|
||||
mActionSelectMoveItem->setIcon( QgsApplication::getThemeIcon( "/mActionSelect.svg" ) );
|
||||
mActionMoveItemContent->setIcon( QgsApplication::getThemeIcon( "/mActionMoveItemContent.png" ) );
|
||||
@ -730,6 +735,7 @@ void QgsComposer::connectCompositionSlots()
|
||||
connect( mComposition, SIGNAL( composerPictureAdded( QgsComposerPicture* ) ), this, SLOT( addComposerPicture( QgsComposerPicture* ) ) );
|
||||
connect( mComposition, SIGNAL( composerShapeAdded( QgsComposerShape* ) ), this, SLOT( addComposerShape( QgsComposerShape* ) ) );
|
||||
connect( mComposition, SIGNAL( composerTableAdded( QgsComposerAttributeTable* ) ), this, SLOT( addComposerTable( QgsComposerAttributeTable* ) ) );
|
||||
connect( mComposition, SIGNAL( composerTableFrameAdded( QgsComposerAttributeTableV2*, QgsComposerFrame* ) ), this, SLOT( addComposerTableV2( QgsComposerAttributeTableV2*, QgsComposerFrame* ) ) );
|
||||
connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( deleteItem( QgsComposerItem* ) ) );
|
||||
connect( mComposition, SIGNAL( paperSizeChanged() ), mHorizontalRuler, SLOT( update() ) );
|
||||
connect( mComposition, SIGNAL( paperSizeChanged() ), mVerticalRuler, SLOT( update() ) );
|
||||
@ -2427,6 +2433,14 @@ void QgsComposer::on_mActionAddTable_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposer::on_mActionAddAttributeTable_triggered()
|
||||
{
|
||||
if ( mView )
|
||||
{
|
||||
mView->setCurrentTool( QgsComposerView::AddAttributeTable );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposer::on_mActionAddHtml_triggered()
|
||||
{
|
||||
if ( mView )
|
||||
@ -3211,10 +3225,21 @@ void QgsComposer::addComposerTable( QgsComposerAttributeTable* table )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposerTableWidget* tWidget = new QgsComposerTableWidget( table );
|
||||
mItemWidgetMap.insert( table, tWidget );
|
||||
}
|
||||
|
||||
void QgsComposer::addComposerTableV2( QgsComposerAttributeTableV2 *table, QgsComposerFrame* frame )
|
||||
{
|
||||
if ( !table )
|
||||
{
|
||||
return;
|
||||
}
|
||||
QgsComposerAttributeTableWidget* tWidget = new QgsComposerAttributeTableWidget( table, frame );
|
||||
mItemWidgetMap.insert( frame, tWidget );
|
||||
}
|
||||
|
||||
void QgsComposer::addComposerHtmlFrame( QgsComposerHtml* html, QgsComposerFrame* frame )
|
||||
{
|
||||
if ( !html )
|
||||
|
@ -34,6 +34,7 @@ class QgsComposerRuler;
|
||||
class QgsComposerScaleBar;
|
||||
class QgsComposerShape;
|
||||
class QgsComposerAttributeTable;
|
||||
class QgsComposerAttributeTableV2;
|
||||
class QgsComposerView;
|
||||
class QgsComposition;
|
||||
class QgsMapCanvas;
|
||||
@ -192,6 +193,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
|
||||
//! Add attribute table
|
||||
void on_mActionAddTable_triggered();
|
||||
|
||||
//! Add attribute table
|
||||
void on_mActionAddAttributeTable_triggered();
|
||||
|
||||
void on_mActionAddHtml_triggered();
|
||||
|
||||
//! Save parent project
|
||||
@ -387,6 +391,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
|
||||
/**Adds a composer table to the item/widget map and creates a configuration widget*/
|
||||
void addComposerTable( QgsComposerAttributeTable* table );
|
||||
|
||||
/**Adds a composer table v2 to the item/widget map and creates a configuration widget*/
|
||||
void addComposerTableV2( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
|
||||
|
||||
/**Adds composer html and creates a configuration widget*/
|
||||
void addComposerHtmlFrame( QgsComposerHtml* html, QgsComposerFrame* frame );
|
||||
|
||||
|
681
src/app/composer/qgscomposerattributetablewidget.cpp
Normal file
681
src/app/composer/qgscomposerattributetablewidget.cpp
Normal file
@ -0,0 +1,681 @@
|
||||
/***************************************************************************
|
||||
qgscomposerattributetablewidget.cpp
|
||||
-----------------------------------
|
||||
begin : September 2014
|
||||
copyright : (C) 2014 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscomposerattributetablewidget.h"
|
||||
#include "qgscomposerframe.h"
|
||||
#include "qgsattributeselectiondialog.h"
|
||||
#include "qgscomposeritemwidget.h"
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgscomposermultiframecommand.h"
|
||||
#include "qgscomposertablecolumn.h"
|
||||
#include "qgscomposermap.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsexpressionbuilderdialog.h"
|
||||
#include <QColorDialog>
|
||||
#include <QFontDialog>
|
||||
|
||||
QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame )
|
||||
: QgsComposerItemBaseWidget( 0, table )
|
||||
, mComposerTable( table )
|
||||
, mFrame( frame )
|
||||
{
|
||||
setupUi( this );
|
||||
//add widget for general composer item properties
|
||||
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, mFrame );
|
||||
mainLayout->addWidget( itemPropertiesWidget );
|
||||
|
||||
blockAllSignals( true );
|
||||
mLayerComboBox->setFilters( QgsMapLayerProxyModel::VectorLayer );
|
||||
connect( mLayerComboBox, SIGNAL( layerChanged( QgsMapLayer* ) ), this, SLOT( changeLayer( QgsMapLayer* ) ) );
|
||||
|
||||
refreshMapComboBox();
|
||||
|
||||
mHeaderFontColorButton->setColorDialogTitle( tr( "Select header font color" ) );
|
||||
mHeaderFontColorButton->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
|
||||
mHeaderFontColorButton->setContext( "composer" );
|
||||
mContentFontColorButton->setColorDialogTitle( tr( "Select content font color" ) );
|
||||
mContentFontColorButton->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
|
||||
mContentFontColorButton->setContext( "composer" );
|
||||
mGridColorButton->setColorDialogTitle( tr( "Select grid color" ) );
|
||||
mGridColorButton->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
|
||||
mGridColorButton->setContext( "composer" );
|
||||
|
||||
updateGuiElements();
|
||||
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );
|
||||
|
||||
if ( mComposerTable )
|
||||
{
|
||||
QObject::connect( mComposerTable, SIGNAL( maximumNumberOfFeaturesChanged( int ) ), this, SLOT( setMaximumNumberOfFeatures( int ) ) );
|
||||
QObject::connect( mComposerTable, SIGNAL( itemChanged() ), this, SLOT( updateGuiElements() ) );
|
||||
}
|
||||
}
|
||||
|
||||
QgsComposerAttributeTableWidget::~QgsComposerAttributeTableWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::showEvent( QShowEvent* /* event */ )
|
||||
{
|
||||
refreshMapComboBox();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::refreshMapComboBox()
|
||||
{
|
||||
//save the current entry in case it is still present after refresh
|
||||
QString saveCurrentComboText = mComposerMapComboBox->currentText();
|
||||
|
||||
mComposerMapComboBox->blockSignals( true );
|
||||
mComposerMapComboBox->clear();
|
||||
if ( mComposerTable )
|
||||
{
|
||||
const QgsComposition* tableComposition = mComposerTable->composition();
|
||||
if ( tableComposition )
|
||||
{
|
||||
QList<const QgsComposerMap*> mapList = tableComposition->composerMapItems();
|
||||
QList<const QgsComposerMap*>::const_iterator mapIt = mapList.constBegin();
|
||||
for ( ; mapIt != mapList.constEnd(); ++mapIt )
|
||||
{
|
||||
int mapId = ( *mapIt )->id();
|
||||
mComposerMapComboBox->addItem( tr( "Map %1" ).arg( mapId ), mapId );
|
||||
}
|
||||
}
|
||||
}
|
||||
mComposerMapComboBox->blockSignals( false );
|
||||
|
||||
if ( mComposerMapComboBox->findText( saveCurrentComboText ) == -1 )
|
||||
{
|
||||
//the former entry is no longer present. Inform the scalebar about the changed composer map
|
||||
on_mComposerMapComboBox_activated( mComposerMapComboBox->currentIndex() );
|
||||
}
|
||||
else
|
||||
{
|
||||
//the former entry is still present. Make it the current entry again
|
||||
mComposerMapComboBox->setCurrentIndex( mComposerMapComboBox->findText( saveCurrentComboText ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mRefreshPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mComposerTable->refreshAttributes();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mAttributesPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//make deep copy of current columns, so we can restore them in case of cancellation
|
||||
QList<QgsComposerTableColumn*> currentColumns;
|
||||
QList<QgsComposerTableColumn*>::const_iterator it = mComposerTable->columns()->constBegin();
|
||||
for ( ; it != mComposerTable->columns()->constEnd() ; ++it )
|
||||
{
|
||||
QgsComposerTableColumn* copy = ( *it )->clone();
|
||||
currentColumns.append( copy );
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table attribute settings" ) );
|
||||
}
|
||||
|
||||
QgsAttributeSelectionDialog d( mComposerTable, mComposerTable->vectorLayer(), 0 );
|
||||
if ( d.exec() == QDialog::Accepted )
|
||||
{
|
||||
mComposerTable->refreshAttributes();
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
|
||||
//clear currentColumns to free memory
|
||||
qDeleteAll( currentColumns );
|
||||
currentColumns.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
//undo changes
|
||||
mComposerTable->setColumns( currentColumns );
|
||||
if ( composition )
|
||||
{
|
||||
composition->cancelMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mComposerMapComboBox_activated( int index )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant itemData = mComposerMapComboBox->itemData( index );
|
||||
if ( itemData.type() == QVariant::Invalid )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int mapId = itemData.toInt();
|
||||
const QgsComposition* tableComposition = mComposerTable->composition();
|
||||
if ( tableComposition )
|
||||
{
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( sender() && composition ) //only create command if called from GUI
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table map changed" ) );
|
||||
}
|
||||
mComposerTable->setComposerMap( tableComposition->getComposerMapById( mapId ) );
|
||||
mComposerTable->update();
|
||||
if ( sender() && composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mMaximumColumnsSpinBox_valueChanged( int i )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table maximum columns" ), QgsComposerMultiFrameMergeCommand::TableMaximumFeatures );
|
||||
}
|
||||
mComposerTable->setMaximumNumberOfFeatures( i );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mMarginSpinBox_valueChanged( double d )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table margin changed" ), QgsComposerMultiFrameMergeCommand::TableMargin );
|
||||
}
|
||||
mComposerTable->setCellMargin( d );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mHeaderFontPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
|
||||
// Native Mac dialog works only for Qt Carbon
|
||||
QFont newFont = QFontDialog::getFont( &ok, mComposerTable->headerFont(), 0, tr( "Select Font" ), QFontDialog::DontUseNativeDialog );
|
||||
#else
|
||||
QFont newFont = QFontDialog::getFont( &ok, mComposerTable->headerFont(), 0, tr( "Select Font" ) );
|
||||
#endif
|
||||
if ( ok )
|
||||
{
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table header font" ) );
|
||||
}
|
||||
mComposerTable->setHeaderFont( newFont );
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mHeaderFontColorButton_colorChanged( const QColor &newColor )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table header font color" ) );
|
||||
}
|
||||
mComposerTable->setHeaderFontColor( newColor );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mContentFontPushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
|
||||
// Native Mac dialog works only for Qt Carbon
|
||||
QFont newFont = QFontDialog::getFont( &ok, mComposerTable->contentFont(), 0, tr( "Select Font" ), QFontDialog::DontUseNativeDialog );
|
||||
#else
|
||||
QFont newFont = QFontDialog::getFont( &ok, mComposerTable->contentFont(), 0, tr( "Select Font" ) );
|
||||
#endif
|
||||
if ( ok )
|
||||
{
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table content font" ) );
|
||||
}
|
||||
mComposerTable->setContentFont( newFont );
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mContentFontColorButton_colorChanged( const QColor &newColor )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table content font color" ) );
|
||||
}
|
||||
mComposerTable->setContentFontColor( newColor );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mGridStrokeWidthSpinBox_valueChanged( double d )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table grid stroke" ), QgsComposerMultiFrameMergeCommand::TableGridStrokeWidth );
|
||||
}
|
||||
mComposerTable->setGridStrokeWidth( d );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mGridColorButton_colorChanged( const QColor& newColor )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table grid color" ) );
|
||||
}
|
||||
mComposerTable->setGridColor( newColor );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mShowGridGroupCheckBox_toggled( bool state )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table grid toggled" ) );
|
||||
}
|
||||
mComposerTable->setShowGrid( state );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QgsComposerAttributeTableWidget::updateGuiElements()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
blockAllSignals( true );
|
||||
|
||||
//layer combo box
|
||||
if ( mComposerTable->vectorLayer() )
|
||||
{
|
||||
mLayerComboBox->setLayer( mComposerTable->vectorLayer() );
|
||||
if ( mComposerTable->vectorLayer()->geometryType() == QGis::NoGeometry )
|
||||
{
|
||||
//layer has no geometry, so uncheck & disable controls which require geometry
|
||||
mShowOnlyVisibleFeaturesCheckBox->setChecked( false );
|
||||
mShowOnlyVisibleFeaturesCheckBox->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mShowOnlyVisibleFeaturesCheckBox->setEnabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
//map combo box
|
||||
const QgsComposerMap* cm = mComposerTable->composerMap();
|
||||
if ( cm )
|
||||
{
|
||||
int mapIndex = mComposerMapComboBox->findText( tr( "Map %1" ).arg( cm->id() ) );
|
||||
if ( mapIndex != -1 )
|
||||
{
|
||||
mComposerMapComboBox->setCurrentIndex( mapIndex );
|
||||
}
|
||||
}
|
||||
mMaximumColumnsSpinBox->setValue( mComposerTable->maximumNumberOfFeatures() );
|
||||
mMarginSpinBox->setValue( mComposerTable->cellMargin() );
|
||||
mGridStrokeWidthSpinBox->setValue( mComposerTable->gridStrokeWidth() );
|
||||
mGridColorButton->setColor( mComposerTable->gridColor() );
|
||||
if ( mComposerTable->showGrid() )
|
||||
{
|
||||
mShowGridGroupCheckBox->setChecked( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mShowGridGroupCheckBox->setChecked( false );
|
||||
}
|
||||
|
||||
mHeaderFontColorButton->setColor( mComposerTable->headerFontColor() );
|
||||
mContentFontColorButton->setColor( mComposerTable->contentFontColor() );
|
||||
|
||||
if ( mComposerTable->displayOnlyVisibleFeatures() && mShowOnlyVisibleFeaturesCheckBox->isEnabled() )
|
||||
{
|
||||
mShowOnlyVisibleFeaturesCheckBox->setCheckState( Qt::Checked );
|
||||
mComposerMapComboBox->setEnabled( true );
|
||||
mComposerMapLabel->setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mShowOnlyVisibleFeaturesCheckBox->setCheckState( Qt::Unchecked );
|
||||
mComposerMapComboBox->setEnabled( false );
|
||||
mComposerMapLabel->setEnabled( false );
|
||||
}
|
||||
|
||||
mFeatureFilterEdit->setText( mComposerTable->featureFilter() );
|
||||
mFeatureFilterCheckBox->setCheckState( mComposerTable->filterFeatures() ? Qt::Checked : Qt::Unchecked );
|
||||
mFeatureFilterEdit->setEnabled( mComposerTable->filterFeatures() );
|
||||
mFeatureFilterButton->setEnabled( mComposerTable->filterFeatures() );
|
||||
|
||||
mHeaderHAlignmentComboBox->setCurrentIndex(( int )mComposerTable->headerHAlignment() );
|
||||
|
||||
blockAllSignals( false );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::blockAllSignals( bool b )
|
||||
{
|
||||
mLayerComboBox->blockSignals( b );
|
||||
mComposerMapComboBox->blockSignals( b );
|
||||
mMaximumColumnsSpinBox->blockSignals( b );
|
||||
mMarginSpinBox->blockSignals( b );
|
||||
mGridColorButton->blockSignals( b );
|
||||
mGridStrokeWidthSpinBox->blockSignals( b );
|
||||
mShowGridGroupCheckBox->blockSignals( b );
|
||||
mShowOnlyVisibleFeaturesCheckBox->blockSignals( b );
|
||||
mFeatureFilterEdit->blockSignals( b );
|
||||
mFeatureFilterCheckBox->blockSignals( b );
|
||||
mHeaderHAlignmentComboBox->blockSignals( b );
|
||||
mHeaderFontColorButton->blockSignals( b );
|
||||
mContentFontColorButton->blockSignals( b );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::setMaximumNumberOfFeatures( int n )
|
||||
{
|
||||
mMaximumColumnsSpinBox->blockSignals( true );
|
||||
mMaximumColumnsSpinBox->setValue( n );
|
||||
mMaximumColumnsSpinBox->blockSignals( false );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mShowOnlyVisibleFeaturesCheckBox_stateChanged( int state )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table visible only toggled" ) );
|
||||
}
|
||||
bool showOnlyVisibleFeatures = ( state == Qt::Checked );
|
||||
mComposerTable->setDisplayOnlyVisibleFeatures( showOnlyVisibleFeatures );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
|
||||
//enable/disable map combobox based on state of checkbox
|
||||
mComposerMapComboBox->setEnabled( state == Qt::Checked );
|
||||
mComposerMapLabel->setEnabled( state == Qt::Checked );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mFeatureFilterCheckBox_stateChanged( int state )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( state == Qt::Checked )
|
||||
{
|
||||
mFeatureFilterEdit->setEnabled( true );
|
||||
mFeatureFilterButton->setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mFeatureFilterEdit->setEnabled( false );
|
||||
mFeatureFilterButton->setEnabled( false );
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table feature filter toggled" ) );
|
||||
}
|
||||
mComposerTable->setFilterFeatures( state == Qt::Checked );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mFeatureFilterEdit_editingFinished()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table feature filter modified" ) );
|
||||
}
|
||||
mComposerTable->setFeatureFilter( mFeatureFilterEdit->text() );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mFeatureFilterButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsExpressionBuilderDialog exprDlg( mComposerTable->vectorLayer(), mFeatureFilterEdit->text(), this );
|
||||
exprDlg.setWindowTitle( tr( "Expression based filter" ) );
|
||||
if ( exprDlg.exec() == QDialog::Accepted )
|
||||
{
|
||||
QString expression = exprDlg.expressionText();
|
||||
if ( !expression.isEmpty() )
|
||||
{
|
||||
mFeatureFilterEdit->setText( expression );
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table feature filter modified" ) );
|
||||
}
|
||||
mComposerTable->setFeatureFilter( mFeatureFilterEdit->text() );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mHeaderHAlignmentComboBox_currentIndexChanged( int index )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table header alignment changed" ) );
|
||||
}
|
||||
mComposerTable->setHeaderHAlignment(( QgsComposerTableV2::HeaderHAlignment )index );
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::changeLayer( QgsMapLayer *layer )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
|
||||
if ( !vl )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Table layer changed" ) );
|
||||
}
|
||||
mComposerTable->setVectorLayer( vl );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
|
||||
if ( vl->geometryType() == QGis::NoGeometry )
|
||||
{
|
||||
//layer has no geometry, so uncheck & disable controls which require geometry
|
||||
mShowOnlyVisibleFeaturesCheckBox->setChecked( false );
|
||||
mShowOnlyVisibleFeaturesCheckBox->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mShowOnlyVisibleFeaturesCheckBox->setEnabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mAddFramePushButton_clicked()
|
||||
{
|
||||
if ( !mComposerTable || !mFrame )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//create a new frame based on the current frame
|
||||
QPointF pos = mFrame->pos();
|
||||
//shift new frame so that it sits 10 units below current frame
|
||||
pos.ry() += mFrame->rect().height() + 10;
|
||||
|
||||
QgsComposerFrame * newFrame = mComposerTable->createNewFrame( mFrame, pos, mFrame->rect().size() );
|
||||
mComposerTable->recalculateFrameSizes();
|
||||
|
||||
//set new frame as selection
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->setSelectedItem( newFrame );
|
||||
}
|
||||
}
|
74
src/app/composer/qgscomposerattributetablewidget.h
Executable file
74
src/app/composer/qgscomposerattributetablewidget.h
Executable file
@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
qgscomposerattributetablewidget.h
|
||||
---------------------------------
|
||||
begin : September 2014
|
||||
copyright : (C) 2014 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERATTRIBUTETABLEWIDGET_H
|
||||
#define QGSCOMPOSERATTRIBUTETABLEWIDGET_H
|
||||
|
||||
#include "ui_qgscomposerattributetablewidgetbase.h"
|
||||
#include "qgscomposeritemwidget.h"
|
||||
|
||||
class QgsComposerAttributeTableV2;
|
||||
class QgsComposerFrame;
|
||||
|
||||
class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private Ui::QgsComposerAttributeTableWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsComposerAttributeTableWidget( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
|
||||
~QgsComposerAttributeTableWidget();
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent * event );
|
||||
|
||||
private:
|
||||
QgsComposerAttributeTableV2* mComposerTable;
|
||||
QgsComposerFrame* mFrame;
|
||||
|
||||
/**Blocks / unblocks the signals of all GUI elements*/
|
||||
void blockAllSignals( bool b );
|
||||
void refreshMapComboBox();
|
||||
|
||||
private slots:
|
||||
void on_mRefreshPushButton_clicked();
|
||||
void on_mAttributesPushButton_clicked();
|
||||
void on_mComposerMapComboBox_activated( int index );
|
||||
void on_mMaximumColumnsSpinBox_valueChanged( int i );
|
||||
void on_mMarginSpinBox_valueChanged( double d );
|
||||
void on_mGridStrokeWidthSpinBox_valueChanged( double d );
|
||||
void on_mGridColorButton_colorChanged( const QColor& newColor );
|
||||
void on_mHeaderFontPushButton_clicked();
|
||||
void on_mHeaderFontColorButton_colorChanged( const QColor& newColor );
|
||||
void on_mContentFontPushButton_clicked();
|
||||
void on_mContentFontColorButton_colorChanged( const QColor& newColor );
|
||||
void on_mShowGridGroupCheckBox_toggled( bool state );
|
||||
void on_mShowOnlyVisibleFeaturesCheckBox_stateChanged( int state );
|
||||
void on_mFeatureFilterCheckBox_stateChanged( int state );
|
||||
void on_mFeatureFilterEdit_editingFinished();
|
||||
void on_mFeatureFilterButton_clicked();
|
||||
void on_mHeaderHAlignmentComboBox_currentIndexChanged( int index );
|
||||
void changeLayer( QgsMapLayer* layer );
|
||||
void on_mAddFramePushButton_clicked();
|
||||
|
||||
/**Inserts a new maximum number of features into the spin box (without the spinbox emitting a signal)*/
|
||||
void setMaximumNumberOfFeatures( int n );
|
||||
|
||||
/**Sets the GUI elements to the values of mComposerTable*/
|
||||
void updateGuiElements();
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERATTRIBUTETABLEWIDGET_H
|
@ -25,7 +25,10 @@
|
||||
#include <QSettings>
|
||||
|
||||
|
||||
QgsComposerHtmlWidget::QgsComposerHtmlWidget( QgsComposerHtml* html, QgsComposerFrame* frame ): QgsComposerItemBaseWidget( 0, html ), mHtml( html ), mFrame( frame )
|
||||
QgsComposerHtmlWidget::QgsComposerHtmlWidget( QgsComposerHtml* html, QgsComposerFrame* frame )
|
||||
: QgsComposerItemBaseWidget( 0, html )
|
||||
, mHtml( html )
|
||||
, mFrame( frame )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
|
@ -181,9 +181,12 @@ SET(QGIS_CORE_SRCS
|
||||
composer/qgscomposermapgrid.cpp
|
||||
composer/qgscomposermapoverview.cpp
|
||||
composer/qgscomposertable.cpp
|
||||
composer/qgscomposertablev2.cpp
|
||||
composer/qgscomposertablecolumn.cpp
|
||||
composer/qgscomposerattributetable.cpp
|
||||
composer/qgscomposerattributetablev2.cpp
|
||||
composer/qgscomposerattributetablemodel.cpp
|
||||
composer/qgscomposerattributetablemodelv2.cpp
|
||||
composer/qgscomposertexttable.cpp
|
||||
composer/qgscomposerscalebar.cpp
|
||||
composer/qgscomposershape.cpp
|
||||
@ -385,8 +388,11 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
composer/qgscomposerlabel.h
|
||||
composer/qgscomposershape.h
|
||||
composer/qgscomposerattributetable.h
|
||||
composer/qgscomposerattributetablemodel.h
|
||||
composer/qgscomposerattributetablev2.h
|
||||
composer/qgscomposerattributetablemodel.h
|
||||
composer/qgscomposerattributetablemodelv2.h
|
||||
composer/qgscomposertable.h
|
||||
composer/qgscomposertablev2.h
|
||||
composer/qgscomposertablecolumn.h
|
||||
composer/qgscomposerhtml.h
|
||||
composer/qgscomposermultiframe.h
|
||||
@ -561,6 +567,7 @@ SET(QGIS_CORE_HDRS
|
||||
composer/qgsaddremovemultiframecommand.h
|
||||
composer/qgsdoubleboxscalebarstyle.h
|
||||
composer/qgscomposertable.h
|
||||
composer/qgscomposertablev2.h
|
||||
composer/qgscomposertablecolumn.h
|
||||
composer/qgspaperitem.h
|
||||
composer/qgsticksscalebarstyle.h
|
||||
|
598
src/core/composer/qgscomposerattributetablemodelv2.cpp
Normal file
598
src/core/composer/qgscomposerattributetablemodelv2.cpp
Normal file
@ -0,0 +1,598 @@
|
||||
/***************************************************************************
|
||||
qgscomposerattributetablemodelv2.cpp
|
||||
--------------------
|
||||
begin : September 2014
|
||||
copyright : (C) 2014 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgscomposerattributetablemodelv2.h"
|
||||
#include "qgscomposertablev2.h"
|
||||
#include "qgscomposertablecolumn.h"
|
||||
|
||||
|
||||
//QgsComposerAttributeTableColumnModelV2V2
|
||||
|
||||
QgsComposerAttributeTableColumnModelV2::QgsComposerAttributeTableColumnModelV2( QgsComposerAttributeTableV2 *composerTable, QObject *parent ) : QAbstractTableModel( parent )
|
||||
, mComposerTable( composerTable )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsComposerAttributeTableColumnModelV2::~QgsComposerAttributeTableColumnModelV2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QModelIndex QgsComposerAttributeTableColumnModelV2::index( int row, int column, const QModelIndex &parent ) const
|
||||
{
|
||||
if ( hasIndex( row, column, parent ) )
|
||||
{
|
||||
if (( *mComposerTable->columns() )[row] )
|
||||
{
|
||||
return createIndex( row, column, ( *mComposerTable->columns() )[row] );
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex QgsComposerAttributeTableColumnModelV2::parent( const QModelIndex &child ) const
|
||||
{
|
||||
Q_UNUSED( child );
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int QgsComposerAttributeTableColumnModelV2::rowCount( const QModelIndex &parent ) const
|
||||
{
|
||||
if ( parent.isValid() )
|
||||
return 0;
|
||||
|
||||
return mComposerTable->columns()->length();
|
||||
}
|
||||
|
||||
int QgsComposerAttributeTableColumnModelV2::columnCount( const QModelIndex &parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
return 3;
|
||||
}
|
||||
|
||||
QVariant QgsComposerAttributeTableColumnModelV2::data( const QModelIndex &index, int role ) const
|
||||
{
|
||||
if ( !index.isValid() ||
|
||||
( role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::UserRole ) )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( index.row() >= mComposerTable->columns()->length() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
//get column for index
|
||||
QgsComposerTableColumn* column = columnFromIndex( index );
|
||||
if ( !column )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( role == Qt::UserRole )
|
||||
{
|
||||
//user role stores reference in column object
|
||||
return qVariantFromValue( qobject_cast<QObject *>( column ) );
|
||||
}
|
||||
|
||||
switch ( index.column() )
|
||||
{
|
||||
case 0:
|
||||
return column->attribute();
|
||||
case 1:
|
||||
return column->heading();
|
||||
case 2:
|
||||
{
|
||||
if ( role == Qt::DisplayRole )
|
||||
{
|
||||
switch ( column->hAlignment() )
|
||||
{
|
||||
case Qt::AlignHCenter:
|
||||
return tr( "Center" );
|
||||
case Qt::AlignRight:
|
||||
return tr( "Right" );
|
||||
case Qt::AlignLeft:
|
||||
default:
|
||||
return tr( "Left" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//edit role
|
||||
return column->hAlignment();
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QVariant QgsComposerAttributeTableColumnModelV2::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( role == Qt::DisplayRole )
|
||||
{
|
||||
if ( orientation == Qt::Vertical ) //row
|
||||
{
|
||||
return QVariant( section );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( section )
|
||||
{
|
||||
case 0:
|
||||
return QVariant( tr( "Attribute" ) );
|
||||
|
||||
case 1:
|
||||
return QVariant( tr( "Heading" ) );
|
||||
|
||||
case 2:
|
||||
return QVariant( tr( "Alignment" ) );
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableColumnModelV2::setData( const QModelIndex& index, const QVariant& value, int role )
|
||||
{
|
||||
if ( !index.isValid() || role != Qt::EditRole || !mComposerTable )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( index.row() >= mComposerTable->columns()->length() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//get column for index
|
||||
QgsComposerTableColumn* column = columnFromIndex( index );
|
||||
if ( !column )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( index.column() )
|
||||
{
|
||||
case 0:
|
||||
// also update column's heading, if it hasn't been customised
|
||||
if ( column->heading().isEmpty() || ( column->heading() == column->attribute() ) )
|
||||
{
|
||||
column->setHeading( value.toString() );
|
||||
emit dataChanged( createIndex( index.row(), 1, 0 ), createIndex( index.row(), 1, 0 ) );
|
||||
}
|
||||
column->setAttribute( value.toString() );
|
||||
emit dataChanged( index, index );
|
||||
return true;
|
||||
case 1:
|
||||
column->setHeading( value.toString() );
|
||||
emit dataChanged( index, index );
|
||||
return true;
|
||||
case 2:
|
||||
column->setHAlignment(( Qt::AlignmentFlag )value.toInt() );
|
||||
emit dataChanged( index, index );
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags QgsComposerAttributeTableColumnModelV2::flags( const QModelIndex& index ) const
|
||||
{
|
||||
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
|
||||
|
||||
if ( index.isValid() )
|
||||
{
|
||||
return flags | Qt::ItemIsEditable;
|
||||
}
|
||||
else
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableColumnModelV2::removeRows( int row, int count, const QModelIndex& parent )
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
|
||||
int maxRow = qMin( row + count - 1, mComposerTable->columns()->length() - 1 );
|
||||
beginRemoveRows( QModelIndex(), row, maxRow );
|
||||
//move backwards through rows, removing each corresponding QgsComposerTableColumn
|
||||
for ( int i = maxRow; i >= row; --i )
|
||||
{
|
||||
delete( *mComposerTable->columns() )[i];
|
||||
mComposerTable->columns()->removeAt( i );
|
||||
}
|
||||
endRemoveRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableColumnModelV2::insertRows( int row, int count, const QModelIndex& parent )
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
beginInsertRows( QModelIndex(), row, row + count - 1 );
|
||||
//create new QgsComposerTableColumns for each inserted row
|
||||
for ( int i = row; i < row + count; ++i )
|
||||
{
|
||||
QgsComposerTableColumn* col = new QgsComposerTableColumn;
|
||||
mComposerTable->columns()->insert( i, col );
|
||||
}
|
||||
endInsertRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableColumnModelV2::moveRow( int row, ShiftDirection direction )
|
||||
{
|
||||
if (( direction == ShiftUp && row <= 0 ) ||
|
||||
( direction == ShiftDown && row >= rowCount() - 1 ) )
|
||||
{
|
||||
//row is already at top/bottom
|
||||
return false;
|
||||
}
|
||||
|
||||
//we shift a row by removing the next row up/down, then reinserting it before/after the target row
|
||||
int swapWithRow = direction == ShiftUp ? row - 1 : row + 1;
|
||||
|
||||
//remove row
|
||||
beginRemoveRows( QModelIndex(), swapWithRow, swapWithRow );
|
||||
QgsComposerTableColumn* temp = mComposerTable->columns()->takeAt( swapWithRow );
|
||||
endRemoveRows();
|
||||
|
||||
//insert row
|
||||
beginInsertRows( QModelIndex(), row, row );
|
||||
mComposerTable->columns()->insert( row, temp );
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableColumnModelV2::resetToLayer()
|
||||
{
|
||||
beginResetModel();
|
||||
mComposerTable->resetColumns();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QgsComposerTableColumn* QgsComposerAttributeTableColumnModelV2::columnFromIndex( const QModelIndex &index ) const
|
||||
{
|
||||
QgsComposerTableColumn* column = static_cast<QgsComposerTableColumn*>( index.internalPointer() );
|
||||
return column;
|
||||
}
|
||||
|
||||
QModelIndex QgsComposerAttributeTableColumnModelV2::indexFromColumn( QgsComposerTableColumn* column )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int r = mComposerTable->columns()->indexOf( column );
|
||||
|
||||
QModelIndex idx = index( r, 0, QModelIndex() );
|
||||
if ( idx.isValid() )
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableColumnModelV2::setColumnAsSorted( QgsComposerTableColumn* column, Qt::SortOrder order )
|
||||
{
|
||||
if ( !column || !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//find current highest sort by rank
|
||||
int highestRank = 0;
|
||||
QList<QgsComposerTableColumn*>::const_iterator columnIt = mComposerTable->columns()->constBegin();
|
||||
for ( ; columnIt != mComposerTable->columns()->constEnd(); ++columnIt )
|
||||
{
|
||||
highestRank = qMax( highestRank, ( *columnIt )->sortByRank() );
|
||||
}
|
||||
|
||||
column->setSortByRank( highestRank + 1 );
|
||||
column->setSortOrder( order );
|
||||
|
||||
QModelIndex idx = indexFromColumn( column );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableColumnModelV2::setColumnAsUnsorted( QgsComposerTableColumn * column )
|
||||
{
|
||||
if ( !mComposerTable || !column )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
column->setSortByRank( 0 );
|
||||
QModelIndex idx = indexFromColumn( column );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
|
||||
static bool columnsBySortRank( QgsComposerTableColumn * a, QgsComposerTableColumn * b )
|
||||
{
|
||||
return a->sortByRank() < b->sortByRank();
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableColumnModelV2::moveColumnInSortRank( QgsComposerTableColumn * column, ShiftDirection direction )
|
||||
{
|
||||
if ( !mComposerTable || !column )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (( direction == ShiftUp && column->sortByRank() <= 1 )
|
||||
|| ( direction == ShiftDown && column->sortByRank() <= 0 ) )
|
||||
{
|
||||
//already at start/end of list or not being used for sort
|
||||
return false;
|
||||
}
|
||||
|
||||
//find column before this one in sort order
|
||||
QList<QgsComposerTableColumn*> sortedColumns;
|
||||
QList<QgsComposerTableColumn*>::iterator columnIt = mComposerTable->columns()->begin();
|
||||
for ( ; columnIt != mComposerTable->columns()->end(); ++columnIt )
|
||||
{
|
||||
if (( *columnIt )->sortByRank() > 0 )
|
||||
{
|
||||
sortedColumns.append( *columnIt );
|
||||
}
|
||||
}
|
||||
qStableSort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
|
||||
int columnPos = sortedColumns.indexOf( column );
|
||||
|
||||
if (( columnPos == 0 && direction == ShiftUp )
|
||||
|| (( columnPos == sortedColumns.length() - 1 ) && direction == ShiftDown ) )
|
||||
{
|
||||
//column already at start/end
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsComposerTableColumn* swapColumn = direction == ShiftUp ?
|
||||
sortedColumns[ columnPos - 1]
|
||||
: sortedColumns[ columnPos + 1];
|
||||
QModelIndex idx = indexFromColumn( column );
|
||||
QModelIndex idxSwap = indexFromColumn( swapColumn );
|
||||
|
||||
//now swap sort ranks
|
||||
int oldSortRank = column->sortByRank();
|
||||
column->setSortByRank( swapColumn->sortByRank() );
|
||||
emit dataChanged( idx, idx );
|
||||
|
||||
swapColumn->setSortByRank( oldSortRank );
|
||||
emit dataChanged( idxSwap, idxSwap );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//QgsComposerTableSortColumnsProxyModelV2V2
|
||||
|
||||
QgsComposerTableSortColumnsProxyModelV2::QgsComposerTableSortColumnsProxyModelV2( QgsComposerAttributeTableV2 *composerTable, ColumnFilterType filterType, QObject *parent )
|
||||
: QSortFilterProxyModel( parent )
|
||||
, mComposerTable( composerTable )
|
||||
, mFilterType( filterType )
|
||||
{
|
||||
setDynamicSortFilter( true );
|
||||
}
|
||||
|
||||
QgsComposerTableSortColumnsProxyModelV2::~QgsComposerTableSortColumnsProxyModelV2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QgsComposerTableSortColumnsProxyModelV2::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
|
||||
{
|
||||
//get QgsComposerTableColumn corresponding to row
|
||||
QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
|
||||
QgsComposerTableColumn* column = columnFromSourceIndex( index );
|
||||
|
||||
if ( !column )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (( column->sortByRank() > 0 && mFilterType == ShowSortedColumns )
|
||||
|| ( column->sortByRank() <= 0 && mFilterType == ShowUnsortedColumns ) )
|
||||
{
|
||||
//column matches filter type
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QgsComposerTableColumn *QgsComposerTableSortColumnsProxyModelV2::columnFromIndex( const QModelIndex &index ) const
|
||||
{
|
||||
//get column corresponding to an index from the proxy
|
||||
QModelIndex sourceIndex = mapToSource( index );
|
||||
return columnFromSourceIndex( sourceIndex );
|
||||
}
|
||||
|
||||
QgsComposerTableColumn* QgsComposerTableSortColumnsProxyModelV2::columnFromSourceIndex( const QModelIndex &sourceIndex ) const
|
||||
{
|
||||
//get column corresponding to an index from the source model
|
||||
QVariant columnAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole );
|
||||
QgsComposerTableColumn* column = qobject_cast<QgsComposerTableColumn *>( columnAsVariant.value<QObject *>() );
|
||||
return column;
|
||||
}
|
||||
|
||||
bool QgsComposerTableSortColumnsProxyModelV2::lessThan( const QModelIndex &left, const QModelIndex &right ) const
|
||||
{
|
||||
QgsComposerTableColumn* column1 = columnFromSourceIndex( left );
|
||||
QgsComposerTableColumn* column2 = columnFromSourceIndex( right );
|
||||
if ( !column1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( !column2 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return column1->sortByRank() < column2->sortByRank();
|
||||
}
|
||||
|
||||
int QgsComposerTableSortColumnsProxyModelV2::columnCount( const QModelIndex &parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant QgsComposerTableSortColumnsProxyModelV2::data( const QModelIndex &index, int role ) const
|
||||
{
|
||||
if (( role != Qt::DisplayRole && role != Qt::EditRole ) || !index.isValid() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QgsComposerTableColumn* column = columnFromIndex( index );
|
||||
if ( !column )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch ( index.column() )
|
||||
{
|
||||
case 0:
|
||||
return column->attribute();
|
||||
case 1:
|
||||
if ( role == Qt::DisplayRole )
|
||||
{
|
||||
switch ( column->sortOrder() )
|
||||
{
|
||||
case Qt::DescendingOrder:
|
||||
return tr( "Descending" );
|
||||
case Qt::AscendingOrder:
|
||||
default:
|
||||
return tr( "Ascending" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//edit role
|
||||
return column->sortOrder();
|
||||
}
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant QgsComposerTableSortColumnsProxyModelV2::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( role == Qt::DisplayRole )
|
||||
{
|
||||
if ( orientation == Qt::Vertical ) //row
|
||||
{
|
||||
return QVariant( section );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( section )
|
||||
{
|
||||
case 0:
|
||||
return QVariant( tr( "Attribute" ) );
|
||||
|
||||
case 1:
|
||||
return QVariant( tr( "Sort Order" ) );
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags QgsComposerTableSortColumnsProxyModelV2::flags( const QModelIndex& index ) const
|
||||
{
|
||||
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
|
||||
|
||||
if ( index.column() == 1 )
|
||||
{
|
||||
//only sort order is editable
|
||||
flags |= Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool QgsComposerTableSortColumnsProxyModelV2::setData( const QModelIndex& index, const QVariant& value, int role )
|
||||
{
|
||||
if ( !index.isValid() || role != Qt::EditRole )
|
||||
return false;
|
||||
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsComposerTableColumn* column = columnFromIndex( index );
|
||||
if ( !column )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( index.column() == 1 )
|
||||
{
|
||||
column->setSortOrder(( Qt::SortOrder )value.toInt() );
|
||||
emit dataChanged( index, index );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsComposerTableColumn *QgsComposerTableSortColumnsProxyModelV2::columnFromRow( int row )
|
||||
{
|
||||
QModelIndex proxyIndex = index( row, 0 );
|
||||
return columnFromIndex( proxyIndex );
|
||||
}
|
||||
|
||||
void QgsComposerTableSortColumnsProxyModelV2::resetFilter()
|
||||
{
|
||||
invalidate();
|
||||
}
|
205
src/core/composer/qgscomposerattributetablemodelv2.h
Normal file
205
src/core/composer/qgscomposerattributetablemodelv2.h
Normal file
@ -0,0 +1,205 @@
|
||||
/***************************************************************************
|
||||
qgscomposerattributetablemodelv2.h
|
||||
--------------------
|
||||
begin : September 2014
|
||||
copyright : (C) 2014 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERATTRIBUTETABLEMODELV2_H
|
||||
#define QGSCOMPOSERATTRIBUTETABLEMODELV2_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class QgsComposerAttributeTableV2;
|
||||
class QgsComposerTableColumn;
|
||||
|
||||
//QgsComposerAttributeTableColumnModelV2
|
||||
|
||||
/**A model for displaying columns shown in a QgsComposerAttributeTableV2*/
|
||||
class CORE_EXPORT QgsComposerAttributeTableColumnModelV2: public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/*! Controls whether a row/column is shifted up or down
|
||||
*/
|
||||
enum ShiftDirection
|
||||
{
|
||||
ShiftUp, /*!< shift the row/column up */
|
||||
ShiftDown /*!< shift the row/column down */
|
||||
};
|
||||
|
||||
/**Constructor for QgsComposerAttributeTableColumnModel.
|
||||
* @param composerTable QgsComposerAttributeTable the model is attached to
|
||||
* @param parent optional parent
|
||||
*/
|
||||
QgsComposerAttributeTableColumnModelV2( QgsComposerAttributeTableV2 *composerTable, QObject *parent = 0 );
|
||||
virtual ~QgsComposerAttributeTableColumnModelV2();
|
||||
|
||||
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
|
||||
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
|
||||
virtual QVariant data( const QModelIndex &index, int role ) const;
|
||||
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
|
||||
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
|
||||
Qt::ItemFlags flags( const QModelIndex &index ) const;
|
||||
bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() );
|
||||
bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() );
|
||||
QModelIndex index( int row, int column, const QModelIndex &parent ) const;
|
||||
QModelIndex parent( const QModelIndex &child ) const;
|
||||
|
||||
/**Moves the specified row up or down in the model. Used for rearranging the attribute tables
|
||||
* columns.
|
||||
* @returns true if the move is allowed
|
||||
* @param row row in model representing attribute table column to move
|
||||
* @param direction direction to move the attribute table column
|
||||
* @note added in 2.3
|
||||
*/
|
||||
bool moveRow( int row , ShiftDirection direction );
|
||||
|
||||
/**Resets the attribute table's columns to match the source layer's fields. Remove all existing
|
||||
* attribute table columns and column customisations.
|
||||
* @note added in 2.3
|
||||
*/
|
||||
void resetToLayer();
|
||||
|
||||
/**Returns the QgsComposerTableColumn corresponding to an index in the model.
|
||||
* @returns QgsComposerTableColumn for specified index
|
||||
* @param index a QModelIndex
|
||||
* @note added in 2.3
|
||||
* @see indexFromColumn
|
||||
*/
|
||||
QgsComposerTableColumn* columnFromIndex( const QModelIndex & index ) const;
|
||||
|
||||
/**Returns a QModelIndex corresponding to a QgsComposerTableColumn in the model.
|
||||
* @returns QModelIndex for specified QgsComposerTableColumn
|
||||
* @param column a QgsComposerTableColumn
|
||||
* @note added in 2.3
|
||||
* @see columnFromIndex
|
||||
*/
|
||||
QModelIndex indexFromColumn( QgsComposerTableColumn *column );
|
||||
|
||||
/**Sets a specified column as a sorted column in the QgsComposerAttributeTable. The column will be
|
||||
* added to the end of the sort rank list, ie it will take the next largest available sort rank.
|
||||
* @param column a QgsComposerTableColumn
|
||||
* @param order sort order for column
|
||||
* @note added in 2.3
|
||||
* @see removeColumnFromSort
|
||||
* @see moveColumnInSortRank
|
||||
*/
|
||||
void setColumnAsSorted( QgsComposerTableColumn *column, Qt::SortOrder order );
|
||||
|
||||
/**Sets a specified column as an unsorted column in the QgsComposerAttributeTable. The column will be
|
||||
* removed from the sort rank list.
|
||||
* @param column a QgsComposerTableColumn
|
||||
* @note added in 2.3
|
||||
* @see setColumnAsSorted
|
||||
*/
|
||||
void setColumnAsUnsorted( QgsComposerTableColumn * column );
|
||||
|
||||
/**Moves a column up or down in the sort rank for the QgsComposerAttributeTable.
|
||||
* @param column a QgsComposerTableColumn
|
||||
* @param direction direction to move the column in the sort rank list
|
||||
* @note added in 2.3
|
||||
* @see setColumnAsSorted
|
||||
*/
|
||||
bool moveColumnInSortRank( QgsComposerTableColumn * column, ShiftDirection direction );
|
||||
|
||||
private:
|
||||
QgsComposerAttributeTableV2 * mComposerTable;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//QgsComposerTableSortColumnsProxyModelV2
|
||||
|
||||
/**Allows for filtering QgsComposerAttributeTable columns by columns which are sorted or unsorted*/
|
||||
class CORE_EXPORT QgsComposerTableSortColumnsProxyModelV2: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/*! Controls whether the proxy model shows sorted or unsorted columns
|
||||
*/
|
||||
enum ColumnFilterType
|
||||
{
|
||||
ShowSortedColumns, /*!< show only sorted columns */
|
||||
ShowUnsortedColumns/*!< show only unsorted columns */
|
||||
};
|
||||
|
||||
/**Constructor for QgsComposerTableSortColumnsProxyModel.
|
||||
* @param composerTable QgsComposerAttributeTable the model is attached to
|
||||
* @param filterType filter for columns, controls whether sorted or unsorted columns are shown
|
||||
* @param parent optional parent
|
||||
*/
|
||||
QgsComposerTableSortColumnsProxyModelV2( QgsComposerAttributeTableV2 *composerTable, ColumnFilterType filterType, QObject *parent = 0 );
|
||||
|
||||
virtual ~QgsComposerTableSortColumnsProxyModelV2();
|
||||
|
||||
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;
|
||||
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
|
||||
virtual QVariant data( const QModelIndex &index, int role ) const;
|
||||
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
|
||||
Qt::ItemFlags flags( const QModelIndex &index ) const;
|
||||
virtual bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
|
||||
|
||||
/**Returns the QgsComposerTableColumn corresponding to a row in the proxy model.
|
||||
* @returns QgsComposerTableColumn for specified row
|
||||
* @param row a row number
|
||||
* @note added in 2.3
|
||||
* @see columnFromIndex
|
||||
*/
|
||||
QgsComposerTableColumn* columnFromRow( int row );
|
||||
|
||||
/**Returns the QgsComposerTableColumn corresponding to an index in the proxy model.
|
||||
* @returns QgsComposerTableColumn for specified index
|
||||
* @param index a QModelIndex
|
||||
* @note added in 2.3
|
||||
* @see columnFromRow
|
||||
* @see columnFromSourceIndex
|
||||
*/
|
||||
QgsComposerTableColumn* columnFromIndex( const QModelIndex & index ) const;
|
||||
|
||||
|
||||
/**Returns the QgsComposerTableColumn corresponding to an index from the source
|
||||
* QgsComposerAttributeTableColumnModel model.
|
||||
* @returns QgsComposerTableColumn for specified index from QgsComposerAttributeTableColumnModel
|
||||
* @param sourceIndex a QModelIndex
|
||||
* @note added in 2.3
|
||||
* @see columnFromRow
|
||||
* @see columnFromIndex
|
||||
*/
|
||||
QgsComposerTableColumn* columnFromSourceIndex( const QModelIndex& sourceIndex ) const;
|
||||
|
||||
/**Invalidates the current filter used by the proxy model
|
||||
* @note added in 2.3
|
||||
*/
|
||||
void resetFilter();
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow( int source_row, const QModelIndex & source_parent ) const;
|
||||
|
||||
private:
|
||||
QgsComposerAttributeTableV2 * mComposerTable;
|
||||
ColumnFilterType mFilterType;
|
||||
|
||||
/**Returns a list of QgsComposerTableColumns without a set sort rank
|
||||
* @returns QgsComposerTableColumns in attribute table without a sort rank
|
||||
* @note added in 2.3
|
||||
*/
|
||||
QList<QgsComposerTableColumn*> columnsWithoutSortRank() const;
|
||||
|
||||
};
|
||||
#endif // QGSCOMPOSERATTRIBUTETABLEMODELV2_H
|
644
src/core/composer/qgscomposerattributetablev2.cpp
Normal file
644
src/core/composer/qgscomposerattributetablev2.cpp
Normal file
@ -0,0 +1,644 @@
|
||||
/***************************************************************************
|
||||
QgsComposerAttributeTableV2.cpp
|
||||
-----------------------------
|
||||
begin : September 2014
|
||||
copyright : (C) 2014 by Marco Hugentobler
|
||||
email : marco at hugis dot net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgscomposertablecolumn.h"
|
||||
#include "qgscomposermap.h"
|
||||
#include "qgscomposerutils.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgscomposerframe.h"
|
||||
|
||||
//QgsComposerAttributeTableCompareV2
|
||||
|
||||
QgsComposerAttributeTableCompareV2::QgsComposerAttributeTableCompareV2()
|
||||
: mCurrentSortColumn( 0 ), mAscending( true )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool QgsComposerAttributeTableCompareV2::operator()( const QgsComposerTableRow& m1, const QgsComposerTableRow& m2 )
|
||||
{
|
||||
QVariant v1 = m1[mCurrentSortColumn];
|
||||
QVariant v2 = m2[mCurrentSortColumn];
|
||||
|
||||
bool less = false;
|
||||
|
||||
//sort null values first
|
||||
if ( v1.isNull() && v2.isNull() )
|
||||
{
|
||||
less = false;
|
||||
}
|
||||
else if ( v1.isNull() )
|
||||
{
|
||||
less = true;
|
||||
}
|
||||
else if ( v2.isNull() )
|
||||
{
|
||||
less = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise sort by converting to corresponding type and comparing
|
||||
switch ( v1.type() )
|
||||
{
|
||||
case QVariant::Int:
|
||||
case QVariant::UInt:
|
||||
case QVariant::LongLong:
|
||||
case QVariant::ULongLong:
|
||||
less = v1.toLongLong() < v2.toLongLong();
|
||||
break;
|
||||
|
||||
case QVariant::Double:
|
||||
less = v1.toDouble() < v2.toDouble();
|
||||
break;
|
||||
|
||||
case QVariant::Date:
|
||||
less = v1.toDate() < v2.toDate();
|
||||
break;
|
||||
|
||||
case QVariant::DateTime:
|
||||
less = v1.toDateTime() < v2.toDateTime();
|
||||
break;
|
||||
|
||||
case QVariant::Time:
|
||||
less = v1.toTime() < v2.toTime();
|
||||
break;
|
||||
|
||||
default:
|
||||
//use locale aware compare for strings
|
||||
less = v1.toString().localeAwareCompare( v2.toString() ) < 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ( mAscending ? less : !less );
|
||||
}
|
||||
|
||||
//
|
||||
// QgsComposerAttributeTableV2
|
||||
//
|
||||
|
||||
QgsComposerAttributeTableV2::QgsComposerAttributeTableV2( QgsComposition* composition, bool createUndoCommands )
|
||||
: QgsComposerTableV2( composition, createUndoCommands )
|
||||
, mVectorLayer( 0 )
|
||||
, mComposerMap( 0 )
|
||||
, mMaximumNumberOfFeatures( 5 )
|
||||
, mShowOnlyVisibleFeatures( false )
|
||||
, mFilterFeatures( false )
|
||||
, mFeatureFilter( "" )
|
||||
{
|
||||
//set first vector layer from layer registry as default one
|
||||
QMap<QString, QgsMapLayer*> layerMap = QgsMapLayerRegistry::instance()->mapLayers();
|
||||
QMap<QString, QgsMapLayer*>::const_iterator mapIt = layerMap.constBegin();
|
||||
for ( ; mapIt != layerMap.constEnd(); ++mapIt )
|
||||
{
|
||||
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( mapIt.value() );
|
||||
if ( vl )
|
||||
{
|
||||
mVectorLayer = vl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( mVectorLayer )
|
||||
{
|
||||
resetColumns();
|
||||
}
|
||||
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( removeLayer( const QString& ) ) );
|
||||
|
||||
if ( mComposition )
|
||||
{
|
||||
//refresh table attributes when composition is refreshed
|
||||
connect( mComposition, SIGNAL( refreshItemsTriggered() ), this, SLOT( refreshAttributes() ) );
|
||||
|
||||
//connect to atlas feature changes to update table rows
|
||||
connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
}
|
||||
|
||||
QgsComposerAttributeTableV2::~QgsComposerAttributeTableV2()
|
||||
{
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setVectorLayer( QgsVectorLayer* layer )
|
||||
{
|
||||
if ( layer == mVectorLayer )
|
||||
{
|
||||
//no change
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mVectorLayer )
|
||||
{
|
||||
//disconnect from previous layer
|
||||
QObject::disconnect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
|
||||
mVectorLayer = layer;
|
||||
|
||||
//rebuild column list to match all columns from layer
|
||||
resetColumns();
|
||||
refreshAttributes();
|
||||
|
||||
//listen for modifications to layer and refresh table when they occur
|
||||
QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::resetColumns()
|
||||
{
|
||||
if ( !mVectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//remove existing columns
|
||||
qDeleteAll( mColumns );
|
||||
mColumns.clear();
|
||||
|
||||
//rebuild columns list from vector layer fields
|
||||
const QgsFields& fields = mVectorLayer->pendingFields();
|
||||
for ( int idx = 0; idx < fields.count(); ++idx )
|
||||
{
|
||||
QString currentAlias = mVectorLayer->attributeDisplayName( idx );
|
||||
QgsComposerTableColumn* col = new QgsComposerTableColumn;
|
||||
col->setAttribute( fields[idx].name() );
|
||||
col->setHeading( currentAlias );
|
||||
mColumns.append( col );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setComposerMap( const QgsComposerMap* map )
|
||||
{
|
||||
if ( map == mComposerMap )
|
||||
{
|
||||
//no change
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mComposerMap )
|
||||
{
|
||||
//disconnect from previous map
|
||||
QObject::disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
mComposerMap = map;
|
||||
if ( mComposerMap )
|
||||
{
|
||||
//listen out for extent changes in linked map
|
||||
QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
refreshAttributes();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setMaximumNumberOfFeatures( int features )
|
||||
{
|
||||
if ( features == mMaximumNumberOfFeatures )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mMaximumNumberOfFeatures = features;
|
||||
refreshAttributes();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setDisplayOnlyVisibleFeatures( bool visibleOnly )
|
||||
{
|
||||
if ( visibleOnly == mShowOnlyVisibleFeatures )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mShowOnlyVisibleFeatures = visibleOnly;
|
||||
refreshAttributes();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setFilterFeatures( bool filter )
|
||||
{
|
||||
if ( filter == mFilterFeatures )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mFilterFeatures = filter;
|
||||
refreshAttributes();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setFeatureFilter( const QString& expression )
|
||||
{
|
||||
if ( expression == mFeatureFilter )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mFeatureFilter = expression;
|
||||
refreshAttributes();
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::setDisplayAttributes( const QSet<int>& attr, bool refresh )
|
||||
{
|
||||
if ( !mVectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//rebuild columns list, taking only attributes with index in supplied QSet
|
||||
qDeleteAll( mColumns );
|
||||
mColumns.clear();
|
||||
|
||||
const QgsFields& fields = mVectorLayer->pendingFields();
|
||||
|
||||
if ( !attr.empty() )
|
||||
{
|
||||
QSet<int>::const_iterator attIt = attr.constBegin();
|
||||
for ( ; attIt != attr.constEnd(); ++attIt )
|
||||
{
|
||||
int attrIdx = ( *attIt );
|
||||
if ( !fields.exists( attrIdx ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString currentAlias = mVectorLayer->attributeDisplayName( attrIdx );
|
||||
QgsComposerTableColumn* col = new QgsComposerTableColumn;
|
||||
col->setAttribute( fields[attrIdx].name() );
|
||||
col->setHeading( currentAlias );
|
||||
mColumns.append( col );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//resetting, so add all attributes to columns
|
||||
for ( int idx = 0; idx < fields.count(); ++idx )
|
||||
{
|
||||
QString currentAlias = mVectorLayer->attributeDisplayName( idx );
|
||||
QgsComposerTableColumn* col = new QgsComposerTableColumn;
|
||||
col->setAttribute( fields[idx].name() );
|
||||
col->setHeading( currentAlias );
|
||||
mColumns.append( col );
|
||||
}
|
||||
}
|
||||
|
||||
if ( refresh )
|
||||
{
|
||||
refreshAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::restoreFieldAliasMap( const QMap<int, QString>& map )
|
||||
{
|
||||
if ( !mVectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
int attrIdx = mVectorLayer->fieldNameIndex(( *columnIt )->attribute() );
|
||||
if ( map.contains( attrIdx ) )
|
||||
{
|
||||
( *columnIt )->setHeading( map.value( attrIdx ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
( *columnIt )->setHeading( mVectorLayer->attributeDisplayName( attrIdx ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &contents )
|
||||
{
|
||||
if ( !mVectorLayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
contents.clear();
|
||||
|
||||
//prepare filter expression
|
||||
std::auto_ptr<QgsExpression> filterExpression;
|
||||
bool activeFilter = false;
|
||||
if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
|
||||
{
|
||||
filterExpression = std::auto_ptr<QgsExpression>( new QgsExpression( mFeatureFilter ) );
|
||||
if ( !filterExpression->hasParserError() )
|
||||
{
|
||||
activeFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
QgsRectangle selectionRect;
|
||||
if ( mComposerMap && mShowOnlyVisibleFeatures )
|
||||
{
|
||||
selectionRect = *mComposerMap->currentMapExtent();
|
||||
if ( mVectorLayer && mComposition->mapSettings().hasCrsTransformEnabled() )
|
||||
{
|
||||
//transform back to layer CRS
|
||||
QgsCoordinateTransform coordTransform( mVectorLayer->crs(), mComposition->mapSettings().destinationCrs() );
|
||||
try
|
||||
{
|
||||
selectionRect = coordTransform.transformBoundingBox( selectionRect, QgsCoordinateTransform::ReverseTransform );
|
||||
}
|
||||
catch ( QgsCsException &cse )
|
||||
{
|
||||
Q_UNUSED( cse );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureRequest req;
|
||||
if ( !selectionRect.isEmpty() )
|
||||
req.setFilterRect( selectionRect );
|
||||
|
||||
req.setFlags( mShowOnlyVisibleFeatures ? QgsFeatureRequest::ExactIntersect : QgsFeatureRequest::NoFlags );
|
||||
|
||||
QgsFeature f;
|
||||
int counter = 0;
|
||||
QgsFeatureIterator fit = mVectorLayer->getFeatures( req );
|
||||
|
||||
while ( fit.nextFeature( f ) && counter < mMaximumNumberOfFeatures )
|
||||
{
|
||||
//check feature against filter
|
||||
if ( activeFilter )
|
||||
{
|
||||
QVariant result = filterExpression->evaluate( &f, mVectorLayer->pendingFields() );
|
||||
// skip this feature if the filter evaluation is false
|
||||
if ( !result.toBool() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
QgsComposerTableRow currentRow;
|
||||
|
||||
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
int idx = mVectorLayer->fieldNameIndex(( *columnIt )->attribute() );
|
||||
if ( idx != -1 )
|
||||
{
|
||||
currentRow << f.attributes()[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lets assume it's an expression
|
||||
QgsExpression* expression = new QgsExpression(( *columnIt )->attribute() );
|
||||
expression->setCurrentRowNumber( counter + 1 );
|
||||
expression->prepare( mVectorLayer->pendingFields() );
|
||||
QVariant value = expression->evaluate( f ) ;
|
||||
currentRow << value;
|
||||
}
|
||||
}
|
||||
contents << currentRow;
|
||||
++counter;
|
||||
}
|
||||
|
||||
//sort the list, starting with the last attribute
|
||||
QgsComposerAttributeTableCompareV2 c;
|
||||
QList< QPair<int, bool> > sortColumns = sortAttributes();
|
||||
for ( int i = sortColumns.size() - 1; i >= 0; --i )
|
||||
{
|
||||
c.setSortColumn( sortColumns.at( i ).first );
|
||||
c.setAscending( sortColumns.at( i ).second );
|
||||
qStableSort( contents.begin(), contents.end(), c );
|
||||
}
|
||||
|
||||
adjustFrameToSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::removeLayer( QString layerId )
|
||||
{
|
||||
if ( mVectorLayer )
|
||||
{
|
||||
if ( layerId == mVectorLayer->id() )
|
||||
{
|
||||
mVectorLayer = 0;
|
||||
//remove existing columns
|
||||
qDeleteAll( mColumns );
|
||||
mColumns.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool columnsBySortRank( QPair<int, QgsComposerTableColumn* > a, QPair<int, QgsComposerTableColumn* > b )
|
||||
{
|
||||
return a.second->sortByRank() < b.second->sortByRank();
|
||||
}
|
||||
|
||||
QList<QPair<int, bool> > QgsComposerAttributeTableV2::sortAttributes() const
|
||||
{
|
||||
//generate list of all sorted columns
|
||||
QList< QPair<int, QgsComposerTableColumn* > > sortedColumns;
|
||||
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
|
||||
int idx = 0;
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
if (( *columnIt )->sortByRank() > 0 )
|
||||
{
|
||||
sortedColumns.append( qMakePair( idx, *columnIt ) );
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
//sort columns by rank
|
||||
qSort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
|
||||
|
||||
//generate list of column index, bool for sort direction (to match 2.0 api)
|
||||
QList<QPair<int, bool> > attributesBySortRank;
|
||||
QList< QPair<int, QgsComposerTableColumn* > >::const_iterator sortedColumnIt = sortedColumns.constBegin();
|
||||
for ( ; sortedColumnIt != sortedColumns.constEnd(); ++sortedColumnIt )
|
||||
{
|
||||
|
||||
attributesBySortRank.append( qMakePair(( *sortedColumnIt ).first,
|
||||
( *sortedColumnIt ).second->sortOrder() == Qt::AscendingOrder ) );
|
||||
}
|
||||
return attributesBySortRank;
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableV2::writeXML( QDomElement& elem, QDomDocument & doc ) const
|
||||
{
|
||||
QDomElement composerTableElem = doc.createElement( "ComposerAttributeTable" );
|
||||
composerTableElem.setAttribute( "showOnlyVisibleFeatures", mShowOnlyVisibleFeatures );
|
||||
composerTableElem.setAttribute( "maxFeatures", mMaximumNumberOfFeatures );
|
||||
composerTableElem.setAttribute( "filterFeatures", mFilterFeatures ? "true" : "false" );
|
||||
composerTableElem.setAttribute( "featureFilter", mFeatureFilter );
|
||||
|
||||
if ( mComposerMap )
|
||||
{
|
||||
composerTableElem.setAttribute( "composerMap", mComposerMap->id() );
|
||||
}
|
||||
else
|
||||
{
|
||||
composerTableElem.setAttribute( "composerMap", -1 );
|
||||
}
|
||||
if ( mVectorLayer )
|
||||
{
|
||||
composerTableElem.setAttribute( "vectorLayer", mVectorLayer->id() );
|
||||
}
|
||||
|
||||
elem.appendChild( composerTableElem );
|
||||
//todo
|
||||
//bool ok = tableWriteXML( composerTableElem, doc );
|
||||
bool ok = true;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool QgsComposerAttributeTableV2::readXML( const QDomElement& itemElem, const QDomDocument& doc )
|
||||
{
|
||||
if ( itemElem.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO
|
||||
//read general table properties
|
||||
//if ( !tableReadXML( itemElem, doc ) )
|
||||
//{
|
||||
// return false;
|
||||
// }
|
||||
|
||||
mShowOnlyVisibleFeatures = itemElem.attribute( "showOnlyVisibleFeatures", "1" ).toInt();
|
||||
mFilterFeatures = itemElem.attribute( "filterFeatures", "false" ) == "true" ? true : false;
|
||||
mFeatureFilter = itemElem.attribute( "featureFilter", "" );
|
||||
|
||||
//composer map
|
||||
int composerMapId = itemElem.attribute( "composerMap", "-1" ).toInt();
|
||||
if ( composerMapId == -1 )
|
||||
{
|
||||
mComposerMap = 0;
|
||||
}
|
||||
|
||||
if ( composition() )
|
||||
{
|
||||
mComposerMap = composition()->getComposerMapById( composerMapId );
|
||||
}
|
||||
else
|
||||
{
|
||||
mComposerMap = 0;
|
||||
}
|
||||
|
||||
if ( mComposerMap )
|
||||
{
|
||||
//if we have found a valid map item, listen out to extent changes on it and refresh the table
|
||||
QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
|
||||
//vector layer
|
||||
QString layerId = itemElem.attribute( "vectorLayer", "not_existing" );
|
||||
if ( layerId == "not_existing" )
|
||||
{
|
||||
mVectorLayer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );
|
||||
if ( ml )
|
||||
{
|
||||
mVectorLayer = dynamic_cast<QgsVectorLayer*>( ml );
|
||||
if ( mVectorLayer )
|
||||
{
|
||||
//if we have found a valid vector layer, listen for modifications on it and refresh the table
|
||||
QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//restore display attribute map. This is required to upgrade pre 2.4 projects.
|
||||
QSet<int> displayAttributes;
|
||||
QDomNodeList displayAttributeList = itemElem.elementsByTagName( "displayAttributes" );
|
||||
if ( displayAttributeList.size() > 0 )
|
||||
{
|
||||
QDomElement displayAttributesElem = displayAttributeList.at( 0 ).toElement();
|
||||
QDomNodeList attributeEntryList = displayAttributesElem.elementsByTagName( "attributeEntry" );
|
||||
for ( int i = 0; i < attributeEntryList.size(); ++i )
|
||||
{
|
||||
QDomElement attributeEntryElem = attributeEntryList.at( i ).toElement();
|
||||
int index = attributeEntryElem.attribute( "index", "-1" ).toInt();
|
||||
if ( index != -1 )
|
||||
{
|
||||
displayAttributes.insert( index );
|
||||
}
|
||||
}
|
||||
setDisplayAttributes( displayAttributes, false );
|
||||
}
|
||||
|
||||
//restore alias map. This is required to upgrade pre 2.4 projects.
|
||||
QMap<int, QString> fieldAliasMap;
|
||||
QDomNodeList aliasMapNodeList = itemElem.elementsByTagName( "attributeAliasMap" );
|
||||
if ( aliasMapNodeList.size() > 0 )
|
||||
{
|
||||
QDomElement attributeAliasMapElem = aliasMapNodeList.at( 0 ).toElement();
|
||||
QDomNodeList aliasMepEntryList = attributeAliasMapElem.elementsByTagName( "aliasEntry" );
|
||||
for ( int i = 0; i < aliasMepEntryList.size(); ++i )
|
||||
{
|
||||
QDomElement aliasEntryElem = aliasMepEntryList.at( i ).toElement();
|
||||
int key = aliasEntryElem.attribute( "key", "-1" ).toInt();
|
||||
QString value = aliasEntryElem.attribute( "value", "" );
|
||||
fieldAliasMap.insert( key, value );
|
||||
}
|
||||
restoreFieldAliasMap( fieldAliasMap );
|
||||
}
|
||||
|
||||
//restore sort columns. This is required to upgrade pre 2.4 projects.
|
||||
QDomElement sortColumnsElem = itemElem.firstChildElement( "sortColumns" );
|
||||
if ( !sortColumnsElem.isNull() && mVectorLayer )
|
||||
{
|
||||
QDomNodeList columns = sortColumnsElem.elementsByTagName( "column" );
|
||||
const QgsFields& fields = mVectorLayer->pendingFields();
|
||||
|
||||
for ( int i = 0; i < columns.size(); ++i )
|
||||
{
|
||||
QDomElement columnElem = columns.at( i ).toElement();
|
||||
int attribute = columnElem.attribute( "index" ).toInt();
|
||||
Qt::SortOrder order = columnElem.attribute( "ascending" ) == "true" ? Qt::AscendingOrder : Qt::DescendingOrder;
|
||||
//find corresponding column
|
||||
QList<QgsComposerTableColumn*>::iterator columnIt = mColumns.begin();
|
||||
for ( ; columnIt != mColumns.end(); ++columnIt )
|
||||
{
|
||||
if (( *columnIt )->attribute() == fields[attribute].name() )
|
||||
{
|
||||
( *columnIt )->setSortByRank( i + 1 );
|
||||
( *columnIt )->setSortOrder( order );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//must be done here because tableReadXML->setSceneRect changes mMaximumNumberOfFeatures
|
||||
mMaximumNumberOfFeatures = itemElem.attribute( "maxFeatures", "5" ).toInt();
|
||||
|
||||
refreshAttributes();
|
||||
|
||||
emit itemChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableV2::addFrame( QgsComposerFrame *frame, bool recalcFrameSizes )
|
||||
{
|
||||
mFrameItems.push_back( frame );
|
||||
connect( frame, SIGNAL( sizeChanged() ), this, SLOT( recalculateFrameSizes() ) );
|
||||
if ( mComposition )
|
||||
{
|
||||
mComposition->addComposerTableFrame( this, frame );
|
||||
}
|
||||
|
||||
if ( recalcFrameSizes )
|
||||
{
|
||||
recalculateFrameSizes();
|
||||
}
|
||||
}
|
236
src/core/composer/qgscomposerattributetablev2.h
Normal file
236
src/core/composer/qgscomposerattributetablev2.h
Normal file
@ -0,0 +1,236 @@
|
||||
/***************************************************************************
|
||||
qgscomposerattributetablev2.h
|
||||
---------------------------
|
||||
begin : September 2014
|
||||
copyright : (C) 2014 by Marco Hugentobler
|
||||
email : marco at hugis dot net
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERATTRIBUTETABLEV2_H
|
||||
#define QGSCOMPOSERATTRIBUTETABLEV2_H
|
||||
|
||||
#include "qgscomposertablev2.h"
|
||||
#include "qgscomposerattributetable.h"
|
||||
|
||||
class QgsComposerMap;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**Helper class for sorting tables, takes into account sorting column and ascending / descending*/
|
||||
class CORE_EXPORT QgsComposerAttributeTableCompareV2
|
||||
{
|
||||
public:
|
||||
QgsComposerAttributeTableCompareV2();
|
||||
bool operator()( const QgsComposerTableRow& m1, const QgsComposerTableRow& m2 );
|
||||
|
||||
/**Sets column number to sort by
|
||||
* @param col column number for sorting
|
||||
*/
|
||||
void setSortColumn( int col ) { mCurrentSortColumn = col; }
|
||||
|
||||
/**Sets sort order for column sorting
|
||||
* @param asc set to true to sort in ascending order, false to sort in descending order
|
||||
*/
|
||||
void setAscending( bool asc ) { mAscending = asc; }
|
||||
|
||||
private:
|
||||
int mCurrentSortColumn;
|
||||
bool mAscending;
|
||||
};
|
||||
|
||||
|
||||
/**A table class that displays a vector attribute table*/
|
||||
class CORE_EXPORT QgsComposerAttributeTableV2: public QgsComposerTableV2
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsComposerAttributeTableV2( QgsComposition* composition, bool createUndoCommands );
|
||||
~QgsComposerAttributeTableV2();
|
||||
|
||||
/**Writes properties specific to attribute tables
|
||||
* @param elem an existing QDomElement in which to store the attribute table's properties.
|
||||
* @param doc QDomDocument for the destination xml.
|
||||
* @see readXML
|
||||
*/
|
||||
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
|
||||
|
||||
/**Reads the properties specific to an attribute table from xml.
|
||||
* @param itemElem a QDomElement holding the attribute table's desired properties.
|
||||
* @param doc QDomDocument for the source xml.
|
||||
* @see writeXML
|
||||
*/
|
||||
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
|
||||
|
||||
virtual void addFrame( QgsComposerFrame* frame, bool recalcFrameSizes = true );
|
||||
|
||||
/**Sets the vector layer from which to display feature attributes
|
||||
* @param layer Vector layer for attribute table
|
||||
* @see vectorLayer
|
||||
*/
|
||||
void setVectorLayer( QgsVectorLayer* layer );
|
||||
|
||||
/**Returns the vector layer the attribute table is currently using
|
||||
* @returns attribute table's current vector layer
|
||||
* @see setVectorLayer
|
||||
*/
|
||||
QgsVectorLayer* vectorLayer() const { return mVectorLayer; }
|
||||
|
||||
/**Resets the attribute table's columns to match the vector layer's fields
|
||||
* @see setVectorLayer
|
||||
*/
|
||||
void resetColumns();
|
||||
|
||||
/**Sets the composer map to use to limit the extent of features shown in the
|
||||
* attribute table. This setting only has an effect if setDisplayOnlyVisibleFeatures is
|
||||
* set to true. Changing the composer map 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.
|
||||
* @param map QgsComposerMap which drives the extents of the table's features
|
||||
* @see composerMap
|
||||
* @see setDisplayOnlyVisibleFeatures
|
||||
*/
|
||||
void setComposerMap( const QgsComposerMap* map );
|
||||
|
||||
/**Returns the composer map whose extents are controlling the features shown in the
|
||||
* table. The extents of the map are only used if displayOnlyVisibleFeatures() is true.
|
||||
* @returns composer map controlling the attribute table
|
||||
* @see setComposerMap
|
||||
* @see displayOnlyVisibleFeatures
|
||||
*/
|
||||
const QgsComposerMap* composerMap() const { return mComposerMap; }
|
||||
|
||||
/**Sets the maximum number of features shown by the table. Changing this setting may result
|
||||
* in the attribute table changing its size to accommodate the new number of rows, and requires
|
||||
* the table to refetch features from its vector layer.
|
||||
* @param features maximum number of features to show in the table
|
||||
* @see maximumNumberOfFeatures
|
||||
*/
|
||||
void setMaximumNumberOfFeatures( int features );
|
||||
|
||||
/**Returns the maximum number of features to be shown by the table.
|
||||
* @returns maximum number of features
|
||||
* @see setMaximumNumberOfFeatures
|
||||
*/
|
||||
int maximumNumberOfFeatures() const { return mMaximumNumberOfFeatures; }
|
||||
|
||||
/**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.
|
||||
* @param visibleOnly set to true to show only visible features
|
||||
* @see displayOnlyVisibleFeatures
|
||||
* @see setComposerMap
|
||||
*/
|
||||
void setDisplayOnlyVisibleFeatures( bool visibleOnly );
|
||||
|
||||
/**Returns true if the table is set to show only features visible on a corresponding
|
||||
* composer map item.
|
||||
* @returns true if table only shows visible features
|
||||
* @see composerMap
|
||||
* @see setDisplayOnlyVisibleFeatures
|
||||
*/
|
||||
bool displayOnlyVisibleFeatures() const { return mShowOnlyVisibleFeatures; }
|
||||
|
||||
/**Returns true if a feature filter is active on the attribute table
|
||||
* @returns bool state of the feature filter
|
||||
* @see setFilterFeatures
|
||||
* @see featureFilter
|
||||
*/
|
||||
bool filterFeatures() const { return mFilterFeatures; }
|
||||
|
||||
/**Sets whether the feature filter is active for the attribute table. 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.
|
||||
* @param filter Set to true to enable the feature filter
|
||||
* @see filterFeatures
|
||||
* @see setFeatureFilter
|
||||
*/
|
||||
void setFilterFeatures( bool filter );
|
||||
|
||||
/**Returns the current expression used to filter features for the table. The filter is only
|
||||
* active if filterFeatures() is true.
|
||||
* @returns feature filter expression
|
||||
* @see setFeatureFilter
|
||||
* @see filterFeatures
|
||||
*/
|
||||
QString featureFilter() const { return mFeatureFilter; }
|
||||
|
||||
/**Sets the expression used for filtering features in the table. The filter is only
|
||||
* active if filterFeatures() is set to true. 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.
|
||||
* @param expression filter to use for selecting which features to display in the table
|
||||
* @see featureFilter
|
||||
* @see setFilterFeatures
|
||||
*/
|
||||
void setFeatureFilter( const QString& expression );
|
||||
|
||||
/**Sets the attributes to display in the table.
|
||||
* @param attr QSet of integer values refering to the attributes from the vector layer to show.
|
||||
* Set to an empty QSet to show all feature attributes.
|
||||
* @param refresh set to true to force the table to refetch features from its vector layer
|
||||
* and immediately update the display of the table. This may result in the table changing size
|
||||
* to accommodate the new displayed feature attributes.
|
||||
* @see displayAttributes
|
||||
*/
|
||||
void setDisplayAttributes( const QSet<int>& attr, bool refresh = true );
|
||||
|
||||
/**Returns the attributes used to sort the table's features.
|
||||
* @returns a QList of integer/bool pairs, where the integer refers to the attribute index and
|
||||
* the bool to the sort order for the attribute. If true the attribute is sorted ascending,
|
||||
* if false, the attribute is sorted in descending order.
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
QList<QPair<int, bool> > sortAttributes() const;
|
||||
|
||||
/**Queries the attribute table's vector layer for attributes to show in the table.
|
||||
* @param attributeMaps list of QgsAttributeMaps where the fetched feature attributes will be stored
|
||||
* @returns true if attributes were successfully fetched
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
bool getTableContents( QgsComposerTableContents &contents );
|
||||
|
||||
private:
|
||||
/**Associated vector layer*/
|
||||
QgsVectorLayer* mVectorLayer;
|
||||
/**Associated composer map (used to display the visible features)*/
|
||||
const QgsComposerMap* mComposerMap;
|
||||
/**Maximum number of features that is displayed*/
|
||||
int mMaximumNumberOfFeatures;
|
||||
|
||||
/**Shows only the features that are visible in the associated composer map (true by default)*/
|
||||
bool mShowOnlyVisibleFeatures;
|
||||
|
||||
/**True if feature filtering enabled*/
|
||||
bool mFilterFeatures;
|
||||
/**Feature filter expression*/
|
||||
QString mFeatureFilter;
|
||||
|
||||
/**Returns a list of attribute indices corresponding to displayed fields in the table.
|
||||
* @note kept for compatibility with 2.0 api only
|
||||
*/
|
||||
QList<int> fieldsToDisplay() const;
|
||||
|
||||
/**Restores a field alias map from a pre 2.4 format project file format
|
||||
* @param map QMap of integers to strings, where the string is the alias to use for the
|
||||
* corresponding field, and the integer is the field index from the vector layer
|
||||
*/
|
||||
void restoreFieldAliasMap( const QMap<int, QString>& map );
|
||||
|
||||
private slots:
|
||||
/**Checks if this vector layer will be removed (and sets mVectorLayer to 0 if yes) */
|
||||
void removeLayer( QString layerId );
|
||||
|
||||
signals:
|
||||
/**This signal is emitted if the maximum number of feature changes (interactively)*/
|
||||
void maximumNumberOfFeaturesChanged( int n );
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERATTRIBUTETABLEV2_H
|
@ -69,7 +69,11 @@ class CORE_EXPORT QgsComposerMultiFrameMergeCommand: public QgsComposerMultiFram
|
||||
//composer html
|
||||
HtmlSource,
|
||||
HtmlStylesheet,
|
||||
HtmlBreakDistance
|
||||
HtmlBreakDistance,
|
||||
//attribute table
|
||||
TableMaximumFeatures,
|
||||
TableMargin,
|
||||
TableGridStrokeWidth
|
||||
};
|
||||
|
||||
QgsComposerMultiFrameMergeCommand( Context c, QgsComposerMultiFrame* multiFrame, const QString& text );
|
||||
|
472
src/core/composer/qgscomposertablev2.cpp
Normal file
472
src/core/composer/qgscomposertablev2.cpp
Normal file
@ -0,0 +1,472 @@
|
||||
/***************************************************************************
|
||||
qgscomposertablev2.cpp
|
||||
------------------
|
||||
begin : July 2014
|
||||
copyright : (C) 2014 by Nyall Dawson, Marco Hugentobler
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscomposertablev2.h"
|
||||
#include "qgscomposerutils.h"
|
||||
#include "qgscomposertablecolumn.h"
|
||||
#include "qgssymbollayerv2utils.h"
|
||||
#include "qgscomposerframe.h"
|
||||
|
||||
QgsComposerTableV2::QgsComposerTableV2( QgsComposition *composition, bool createUndoCommands )
|
||||
: QgsComposerMultiFrame( composition, createUndoCommands )
|
||||
, mCellMargin( 1.0 )
|
||||
, mHeaderFontColor( Qt::black )
|
||||
, mHeaderHAlignment( FollowColumn )
|
||||
, mContentFontColor( Qt::black )
|
||||
, mShowGrid( true )
|
||||
, mGridStrokeWidth( 0.5 )
|
||||
, mGridColor( Qt::black )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsComposerTableV2::QgsComposerTableV2()
|
||||
: QgsComposerMultiFrame( 0, false )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsComposerTableV2::~QgsComposerTableV2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QgsComposerTableV2::writeXML( QDomElement& elem, QDomDocument & doc, bool ignoreFrames ) const
|
||||
{
|
||||
QDomElement tableElem = doc.createElement( "ComposerTableV2" );
|
||||
elem.setAttribute( "cellMargin", QString::number( mCellMargin ) );
|
||||
elem.setAttribute( "headerFont", mHeaderFont.toString() );
|
||||
elem.setAttribute( "headerFontColor", QgsSymbolLayerV2Utils::encodeColor( mHeaderFontColor ) );
|
||||
elem.setAttribute( "headerHAlignment", QString::number(( int )mHeaderHAlignment ) );
|
||||
elem.setAttribute( "contentFont", mContentFont.toString() );
|
||||
elem.setAttribute( "contentFontColor", QgsSymbolLayerV2Utils::encodeColor( mContentFontColor ) );
|
||||
elem.setAttribute( "gridStrokeWidth", QString::number( mGridStrokeWidth ) );
|
||||
elem.setAttribute( "gridColor", QgsSymbolLayerV2Utils::encodeColor( mGridColor ) );
|
||||
elem.setAttribute( "showGrid", mShowGrid );
|
||||
|
||||
//columns
|
||||
QDomElement displayColumnsElem = doc.createElement( "displayColumns" );
|
||||
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
QDomElement columnElem = doc.createElement( "column" );
|
||||
( *columnIt )->writeXML( columnElem, doc );
|
||||
displayColumnsElem.appendChild( columnElem );
|
||||
}
|
||||
tableElem.appendChild( displayColumnsElem );
|
||||
|
||||
bool state = _writeXML( tableElem, doc, ignoreFrames );
|
||||
elem.appendChild( tableElem );
|
||||
return state;
|
||||
}
|
||||
|
||||
bool QgsComposerTableV2::readXML( const QDomElement &itemElem, const QDomDocument &doc, bool ignoreFrames )
|
||||
{
|
||||
deleteFrames();
|
||||
|
||||
//first create the frames
|
||||
if ( !_readXML( itemElem, doc, ignoreFrames ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( itemElem.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mHeaderFont.fromString( itemElem.attribute( "headerFont", "" ) );
|
||||
mHeaderFontColor = QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "headerFontColor", "0,0,0,255" ) );
|
||||
mHeaderHAlignment = QgsComposerTableV2::HeaderHAlignment( itemElem.attribute( "headerHAlignment", "0" ).toInt() );
|
||||
mContentFont.fromString( itemElem.attribute( "contentFont", "" ) );
|
||||
mContentFontColor = QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "contentFontColor", "0,0,0,255" ) );
|
||||
mCellMargin = itemElem.attribute( "cellMargin", "1.0" ).toDouble();
|
||||
mGridStrokeWidth = itemElem.attribute( "gridStrokeWidth", "0.5" ).toDouble();
|
||||
mShowGrid = itemElem.attribute( "showGrid", "1" ).toInt();
|
||||
mGridColor = QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "gridColor", "0,0,0,255" ) );
|
||||
|
||||
//restore column specifications
|
||||
qDeleteAll( mColumns );
|
||||
mColumns.clear();
|
||||
QDomNodeList columnsList = itemElem.elementsByTagName( "displayColumns" );
|
||||
if ( columnsList.size() > 0 )
|
||||
{
|
||||
QDomElement columnsElem = columnsList.at( 0 ).toElement();
|
||||
QDomNodeList columnEntryList = columnsElem.elementsByTagName( "column" );
|
||||
for ( int i = 0; i < columnEntryList.size(); ++i )
|
||||
{
|
||||
QDomElement columnElem = columnEntryList.at( i ).toElement();
|
||||
QgsComposerTableColumn* column = new QgsComposerTableColumn;
|
||||
column->readXML( columnElem );
|
||||
mColumns.append( column );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QSizeF QgsComposerTableV2::totalSize() const
|
||||
{
|
||||
//TODO - handle multiple cell headers
|
||||
return mTableSize;
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::render( QPainter *p, const QRectF &renderExtent )
|
||||
{
|
||||
//do this via rows
|
||||
//eg, calculate how rows to->from
|
||||
//and render them
|
||||
|
||||
if ( !p )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mComposition->plotStyle() == QgsComposition::Print ||
|
||||
mComposition->plotStyle() == QgsComposition::Postscript )
|
||||
{
|
||||
//exporting composition, so force an attribute refresh
|
||||
//we do this in case vector layer has changed via an external source (eg, another database user)
|
||||
refreshAttributes();
|
||||
}
|
||||
|
||||
p->save();
|
||||
//antialiasing on
|
||||
p->setRenderHint( QPainter::Antialiasing, true );
|
||||
|
||||
p->setPen( Qt::SolidLine );
|
||||
|
||||
//now draw the text
|
||||
double currentX = mGridStrokeWidth;
|
||||
double currentY;
|
||||
|
||||
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
|
||||
|
||||
int col = 0;
|
||||
double cellHeaderHeight = QgsComposerUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin;
|
||||
double cellBodyHeight = QgsComposerUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin;
|
||||
QRectF cell;
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
currentY = mGridStrokeWidth;
|
||||
currentX += mCellMargin;
|
||||
|
||||
cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellHeaderHeight );
|
||||
|
||||
//calculate alignment of header
|
||||
Qt::AlignmentFlag headerAlign = Qt::AlignLeft;
|
||||
switch ( mHeaderHAlignment )
|
||||
{
|
||||
case FollowColumn:
|
||||
headerAlign = ( *columnIt )->hAlignment();
|
||||
break;
|
||||
case HeaderLeft:
|
||||
headerAlign = Qt::AlignLeft;
|
||||
break;
|
||||
case HeaderCenter:
|
||||
headerAlign = Qt::AlignHCenter;
|
||||
break;
|
||||
case HeaderRight:
|
||||
headerAlign = Qt::AlignRight;
|
||||
break;
|
||||
}
|
||||
|
||||
QgsComposerUtils::drawText( p, cell, ( *columnIt )->heading(), mHeaderFont, mHeaderFontColor, headerAlign, Qt::AlignVCenter, Qt::TextDontClip );
|
||||
|
||||
currentY += cellHeaderHeight;
|
||||
currentY += mGridStrokeWidth;
|
||||
|
||||
//draw the attribute values
|
||||
QgsComposerTableContents::const_iterator attIt = mTableContents.begin();
|
||||
for ( ; attIt != mTableContents.end(); ++attIt )
|
||||
{
|
||||
cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellBodyHeight );
|
||||
|
||||
QVariant cellContents = ( *attIt ).at( col );
|
||||
QString str = cellContents.toString();
|
||||
QgsComposerUtils::drawText( p, cell, str, mContentFont, mContentFontColor, ( *columnIt )->hAlignment(), Qt::AlignVCenter, Qt::TextDontClip );
|
||||
|
||||
currentY += cellBodyHeight;
|
||||
currentY += mGridStrokeWidth;
|
||||
}
|
||||
|
||||
currentX += mMaxColumnWidthMap[ col ];
|
||||
currentX += mCellMargin;
|
||||
currentX += mGridStrokeWidth;
|
||||
col++;
|
||||
}
|
||||
|
||||
//and the borders
|
||||
if ( mShowGrid )
|
||||
{
|
||||
QPen gridPen;
|
||||
gridPen.setWidthF( mGridStrokeWidth );
|
||||
gridPen.setColor( mGridColor );
|
||||
gridPen.setJoinStyle( Qt::MiterJoin );
|
||||
p->setPen( gridPen );
|
||||
drawHorizontalGridLines( p, mTableContents.size() );
|
||||
drawVerticalGridLines( p, mMaxColumnWidthMap );
|
||||
}
|
||||
|
||||
p->restore();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setCellMargin( const double margin )
|
||||
{
|
||||
if ( margin == mCellMargin )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mCellMargin = margin;
|
||||
//since spacing has changed, we need to recalculate the table size
|
||||
adjustFrameToSize();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setHeaderFont( const QFont &font )
|
||||
{
|
||||
if ( font == mHeaderFont )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mHeaderFont = font;
|
||||
//since font attributes have changed, we need to recalculate the table size
|
||||
adjustFrameToSize();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setHeaderFontColor( const QColor &color )
|
||||
{
|
||||
if ( color == mHeaderFontColor )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mHeaderFontColor = color;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setHeaderHAlignment( const QgsComposerTableV2::HeaderHAlignment alignment )
|
||||
{
|
||||
if ( alignment == mHeaderHAlignment )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mHeaderHAlignment = alignment;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setContentFont( const QFont &font )
|
||||
{
|
||||
if ( font == mContentFont )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mContentFont = font;
|
||||
//since font attributes have changed, we need to recalculate the table size
|
||||
adjustFrameToSize();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setContentFontColor( const QColor &color )
|
||||
{
|
||||
if ( color == mContentFontColor )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mContentFontColor = color;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setShowGrid( const bool showGrid )
|
||||
{
|
||||
if ( showGrid == mShowGrid )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mShowGrid = showGrid;
|
||||
//since grid spacing has changed, we need to recalculate the table size
|
||||
adjustFrameToSize();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setGridStrokeWidth( const double width )
|
||||
{
|
||||
if ( width == mGridStrokeWidth )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mGridStrokeWidth = width;
|
||||
//since grid spacing has changed, we need to recalculate the table size
|
||||
adjustFrameToSize();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setGridColor( const QColor &color )
|
||||
{
|
||||
if ( color == mGridColor )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mGridColor = color;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setColumns( QgsComposerTableColumns columns )
|
||||
{
|
||||
//remove existing columns
|
||||
qDeleteAll( mColumns );
|
||||
mColumns.clear();
|
||||
|
||||
mColumns.append( columns );
|
||||
}
|
||||
|
||||
QMap<int, QString> QgsComposerTableV2::headerLabels() const
|
||||
{
|
||||
QMap<int, QString> headers;
|
||||
|
||||
QgsComposerTableColumns::const_iterator columnIt = mColumns.constBegin();
|
||||
int col = 0;
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
headers.insert( col, ( *columnIt )->heading() );
|
||||
col++;
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::refreshAttributes()
|
||||
{
|
||||
mMaxColumnWidthMap.clear();
|
||||
mTableContents.clear();
|
||||
|
||||
//get new contents
|
||||
if ( !getTableContents( mTableContents ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//since contents have changed, we also need to recalculate the column widths
|
||||
//and size of table
|
||||
adjustFrameToSize();
|
||||
}
|
||||
|
||||
bool QgsComposerTableV2::calculateMaxColumnWidths()
|
||||
{
|
||||
mMaxColumnWidthMap.clear();
|
||||
|
||||
//first, go through all the column headers and calculate the max width values
|
||||
QgsComposerTableColumns::const_iterator columnIt = mColumns.constBegin();
|
||||
int col = 0;
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
mMaxColumnWidthMap.insert( col, QgsComposerUtils::textWidthMM( mHeaderFont, ( *columnIt )->heading() ) );
|
||||
col++;
|
||||
}
|
||||
|
||||
//next, go through all the table contents and calculate the max width values
|
||||
QgsComposerTableContents::const_iterator rowIt = mTableContents.constBegin();
|
||||
double currentCellTextWidth;
|
||||
for ( ; rowIt != mTableContents.constEnd(); ++rowIt )
|
||||
{
|
||||
QgsComposerTableRow::const_iterator colIt = rowIt->constBegin();
|
||||
int columnNumber = 0;
|
||||
for ( ; colIt != rowIt->constEnd(); ++colIt )
|
||||
{
|
||||
currentCellTextWidth = QgsComposerUtils::textWidthMM( mContentFont, ( *colIt ).toString() );
|
||||
mMaxColumnWidthMap[ columnNumber ] = qMax( currentCellTextWidth, mMaxColumnWidthMap[ columnNumber ] );
|
||||
columnNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double QgsComposerTableV2::totalWidth()
|
||||
{
|
||||
//check how much space each column needs
|
||||
if ( !calculateMaxColumnWidths() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//adapt frame to total width
|
||||
double totalWidth = 0;
|
||||
QMap<int, double>::const_iterator maxColWidthIt = mMaxColumnWidthMap.constBegin();
|
||||
for ( ; maxColWidthIt != mMaxColumnWidthMap.constEnd(); ++maxColWidthIt )
|
||||
{
|
||||
totalWidth += maxColWidthIt.value();
|
||||
}
|
||||
totalWidth += ( 2 * mMaxColumnWidthMap.size() * mCellMargin );
|
||||
totalWidth += ( mMaxColumnWidthMap.size() + 1 ) * mGridStrokeWidth;
|
||||
|
||||
return totalWidth;
|
||||
}
|
||||
|
||||
double QgsComposerTableV2::totalHeight() const
|
||||
{
|
||||
//calculate height
|
||||
int n = mTableContents.size();
|
||||
double totalHeight = QgsComposerUtils::fontAscentMM( mHeaderFont )
|
||||
+ n * QgsComposerUtils::fontAscentMM( mContentFont )
|
||||
+ ( n + 1 ) * mCellMargin * 2
|
||||
+ ( n + 2 ) * mGridStrokeWidth;
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::drawHorizontalGridLines( QPainter *painter, const int rows ) const
|
||||
{
|
||||
//horizontal lines
|
||||
double halfGridStrokeWidth = mGridStrokeWidth / 2.0;
|
||||
double currentY = halfGridStrokeWidth;
|
||||
painter->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( mTableSize.width() - halfGridStrokeWidth, currentY ) );
|
||||
currentY += mGridStrokeWidth;
|
||||
currentY += ( QgsComposerUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin );
|
||||
for ( int row = 0; row < rows; ++row )
|
||||
{
|
||||
painter->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( mTableSize.width() - halfGridStrokeWidth, currentY ) );
|
||||
currentY += mGridStrokeWidth;
|
||||
currentY += ( QgsComposerUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin );
|
||||
}
|
||||
painter->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( mTableSize.width() - halfGridStrokeWidth, currentY ) );
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<int, double> &maxWidthMap ) const
|
||||
{
|
||||
//vertical lines
|
||||
double halfGridStrokeWidth = mGridStrokeWidth / 2.0;
|
||||
double currentX = halfGridStrokeWidth;
|
||||
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, mTableSize.height() - halfGridStrokeWidth ) );
|
||||
currentX += mGridStrokeWidth;
|
||||
QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
|
||||
for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
|
||||
{
|
||||
currentX += ( maxColWidthIt.value() + 2 * mCellMargin );
|
||||
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, mTableSize.height() - halfGridStrokeWidth ) );
|
||||
currentX += mGridStrokeWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::adjustFrameToSize()
|
||||
{
|
||||
mTableSize = QSizeF( totalWidth(), totalHeight() );
|
||||
}
|
311
src/core/composer/qgscomposertablev2.h
Normal file
311
src/core/composer/qgscomposertablev2.h
Normal file
@ -0,0 +1,311 @@
|
||||
/***************************************************************************
|
||||
qgscomposertablev2.h
|
||||
------------------
|
||||
begin : July 2014
|
||||
copyright : (C) 2014 by Nyall Dawson, Marco Hugentobler
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERTABLEV2_H
|
||||
#define QGSCOMPOSERTABLEV2_H
|
||||
|
||||
#include "qgscomposermultiframe.h"
|
||||
#include <QFont>
|
||||
#include <QColor>
|
||||
|
||||
class QgsComposerTableColumn;
|
||||
|
||||
/**List of QVariants, representing a the contents of a single row in
|
||||
* a QgsComposerTable
|
||||
* \note Added in version 2.5
|
||||
*/
|
||||
typedef QList< QVariant > QgsComposerTableRow;
|
||||
|
||||
/**List of QgsComposerTableRows, representing rows and column cell contents
|
||||
* for a QgsComposerTable
|
||||
* \note Added in version 2.5
|
||||
*/
|
||||
typedef QList< QgsComposerTableRow > QgsComposerTableContents;
|
||||
|
||||
/**List of column definitions for a QgsComposerTable
|
||||
* \note Added in version 2.5
|
||||
*/
|
||||
typedef QList<QgsComposerTableColumn*> QgsComposerTableColumns;
|
||||
|
||||
/**A class to display feature attributes in the print composer, and allow
|
||||
* the table to span over multiple frames
|
||||
* @note added in QGIS 2.5
|
||||
*/
|
||||
class CORE_EXPORT QgsComposerTableV2: public QgsComposerMultiFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/*! Controls how headers are horizontally aligned in a table
|
||||
*/
|
||||
enum HeaderHAlignment
|
||||
{
|
||||
FollowColumn, /*!< header uses the same alignment as the column */
|
||||
HeaderLeft, /*!< align headers left */
|
||||
HeaderCenter, /*!< align headers to center */
|
||||
HeaderRight /*!< align headers right */
|
||||
};
|
||||
|
||||
QgsComposerTableV2( QgsComposition* composition, bool createUndoCommands );
|
||||
QgsComposerTableV2();
|
||||
|
||||
virtual ~QgsComposerTableV2();
|
||||
|
||||
virtual bool writeXML( QDomElement& elem, QDomDocument & doc, bool ignoreFrames = false ) const;
|
||||
|
||||
virtual bool readXML( const QDomElement& itemElem, const QDomDocument& doc, bool ignoreFrames = false );
|
||||
|
||||
virtual QSizeF totalSize() const;
|
||||
virtual void render( QPainter* p, const QRectF& renderExtent );
|
||||
|
||||
/**Sets the margin distance between cell borders and their contents.
|
||||
* @param margin margin for cell contents
|
||||
* @see cellMargin
|
||||
*/
|
||||
void setCellMargin( const double margin );
|
||||
|
||||
/**Returns the margin distance between cell borders and their contents.
|
||||
* @returns margin for cell contents
|
||||
* @see setCellMargin
|
||||
*/
|
||||
double cellMargin() const { return mCellMargin; }
|
||||
|
||||
/**Sets the font used to draw header text in the table.
|
||||
* @param font font for header cells
|
||||
* @see headerFont
|
||||
* @see setContentFont
|
||||
*/
|
||||
void setHeaderFont( const QFont& font );
|
||||
|
||||
/**Returns the font used to draw header text in the table.
|
||||
* @returns font for header cells
|
||||
* @see setHeaderFont
|
||||
* @see contentFont
|
||||
*/
|
||||
QFont headerFont() const { return mHeaderFont; }
|
||||
|
||||
/**Sets the color used to draw header text in the table.
|
||||
* @param color header text color
|
||||
* @see headerFontColor
|
||||
* @see setHeaderFont
|
||||
* @see setContentFontColor
|
||||
*/
|
||||
void setHeaderFontColor( const QColor& color );
|
||||
|
||||
/**Returns the color used to draw header text in the table.
|
||||
* @returns color for header text
|
||||
* @see setHeaderFontColor
|
||||
* @see headerFont
|
||||
* @see contentFontColor
|
||||
*/
|
||||
QColor headerFontColor() const { return mHeaderFontColor; }
|
||||
|
||||
/**Sets the horizontal alignment for table headers
|
||||
* @param alignment Horizontal alignment for table header cells
|
||||
* @see headerHAlignment
|
||||
*/
|
||||
void setHeaderHAlignment( const HeaderHAlignment alignment );
|
||||
|
||||
/**Returns the horizontal alignment for table headers
|
||||
* @returns Horizontal alignment for table header cells
|
||||
* @see setHeaderHAlignment
|
||||
*/
|
||||
HeaderHAlignment headerHAlignment() const { return mHeaderHAlignment; }
|
||||
|
||||
/**Sets the font used to draw text in table body cells.
|
||||
* @param font font for table cells
|
||||
* @see contentFont
|
||||
* @see setHeaderFont
|
||||
*/
|
||||
void setContentFont( const QFont& font );
|
||||
|
||||
/**Returns the font used to draw text in table body cells.
|
||||
* @returns font for table cells
|
||||
* @see setContentFont
|
||||
* @see headerFont
|
||||
*/
|
||||
QFont contentFont() const { return mContentFont; }
|
||||
|
||||
/**Sets the color used to draw text in table body cells.
|
||||
* @param color table cell text color
|
||||
* @see contentFontColor
|
||||
* @see setContentFont
|
||||
* @see setHeaderFontColor
|
||||
*/
|
||||
void setContentFontColor( const QColor& color );
|
||||
|
||||
/**Returns the color used to draw text in table body cells.
|
||||
* @returns text color for table cells
|
||||
* @see setContentFontColor
|
||||
* @see contentFont
|
||||
* @see headerFontColor
|
||||
*/
|
||||
QColor contentFontColor() const { return mContentFontColor; }
|
||||
|
||||
/**Sets whether grid lines should be drawn in the table
|
||||
* @param showGrid set to true to show grid lines
|
||||
* @see showGrid
|
||||
* @see setGridStrokeWidth
|
||||
* @see setGridColor
|
||||
*/
|
||||
void setShowGrid( const bool showGrid );
|
||||
|
||||
/**Returns whether grid lines are drawn in the table
|
||||
* @returns true if grid lines are shown
|
||||
* @see setShowGrid
|
||||
* @see gridStrokeWidth
|
||||
* @see gridColor
|
||||
*/
|
||||
bool showGrid() const { return mShowGrid; }
|
||||
|
||||
/**Sets the width for grid lines in the table.
|
||||
* @param width grid line width
|
||||
* @see gridStrokeWidth
|
||||
* @see setShowGrid
|
||||
* @see setGridColor
|
||||
*/
|
||||
void setGridStrokeWidth( const double width );
|
||||
|
||||
/**Returns the width of grid lines in the table.
|
||||
* @returns grid line width
|
||||
* @see setGridStrokeWidth
|
||||
* @see showGrid
|
||||
* @see gridColor
|
||||
*/
|
||||
double gridStrokeWidth() const { return mGridStrokeWidth; }
|
||||
|
||||
/**Sets color used for grid lines in the table.
|
||||
* @param color grid line color
|
||||
* @see gridColor
|
||||
* @see setShowGrid
|
||||
* @see setGridStrokeWidth
|
||||
*/
|
||||
void setGridColor( const QColor& color );
|
||||
|
||||
/**Returns the color used for grid lines in the table.
|
||||
* @returns grid line color
|
||||
* @see setGridColor
|
||||
* @see showGrid
|
||||
* @see gridStrokeWidth
|
||||
*/
|
||||
QColor gridColor() const { return mGridColor; }
|
||||
|
||||
/**Returns a pointer to the list of QgsComposerTableColumns shown in the table
|
||||
* @returns pointer to list of columns in table
|
||||
* @see setColumns
|
||||
*/
|
||||
QgsComposerTableColumns* columns() { return &mColumns; }
|
||||
|
||||
/**Replaces the columns in the table with a specified list of QgsComposerTableColumns.
|
||||
* @param columns list of QgsComposerTableColumns to show in table
|
||||
* @see columns
|
||||
*/
|
||||
void setColumns( QgsComposerTableColumns columns );
|
||||
|
||||
/**Returns the text used in the column headers for the table.
|
||||
* @returns QMap of int to QString, where the int is the column index (starting at 0),
|
||||
* and the string is the text to use for the column's header
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
virtual QMap<int, QString> headerLabels() const;
|
||||
|
||||
/**Fetches the contents used for the cells in the table.
|
||||
* @returns true if table contents were successfully retrieved.
|
||||
* @param contents QgsComposerTableContents to store retrieved row data in
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
virtual bool getTableContents( QgsComposerTableContents &contents ) = 0;
|
||||
|
||||
public slots:
|
||||
|
||||
/**Refreshes the contents shown in the table by querying for new data.
|
||||
* This also causes the column widths and size of the table to change to accommodate the
|
||||
* new data.
|
||||
* @see adjustFrameToSize
|
||||
*/
|
||||
virtual void refreshAttributes();
|
||||
|
||||
protected:
|
||||
/**Margin between cell borders and cell text*/
|
||||
double mCellMargin;
|
||||
|
||||
/**Header font*/
|
||||
QFont mHeaderFont;
|
||||
|
||||
/**Header font color*/
|
||||
QColor mHeaderFontColor;
|
||||
|
||||
/**Alignment for table headers*/
|
||||
HeaderHAlignment mHeaderHAlignment;
|
||||
|
||||
/**Table contents font*/
|
||||
QFont mContentFont;
|
||||
|
||||
/**Table contents font color*/
|
||||
QColor mContentFontColor;
|
||||
|
||||
/**True if grid should be shown*/
|
||||
bool mShowGrid;
|
||||
|
||||
/**Width of grid lines*/
|
||||
double mGridStrokeWidth;
|
||||
|
||||
/**Color for grid lines*/
|
||||
QColor mGridColor;
|
||||
|
||||
/**Columns to show in table*/
|
||||
QgsComposerTableColumns mColumns;
|
||||
|
||||
/**Contents to show in table*/
|
||||
QgsComposerTableContents mTableContents;
|
||||
|
||||
/**Map of maximum width for each column*/
|
||||
QMap<int, double> mMaxColumnWidthMap;
|
||||
|
||||
QSizeF mTableSize;
|
||||
|
||||
/**Calculates the maximum width of text shown in columns.
|
||||
*/
|
||||
virtual bool calculateMaxColumnWidths();
|
||||
|
||||
//not const
|
||||
double totalWidth();
|
||||
|
||||
double totalHeight() const;
|
||||
|
||||
/**Draws the horizontal grid lines for the table.
|
||||
* @param painter destination painter for grid lines
|
||||
* @param rows number of rows shown in table
|
||||
* @see drawVerticalGridLines
|
||||
*/
|
||||
void drawHorizontalGridLines( QPainter* painter, const int rows ) const;
|
||||
|
||||
/**Draws the vertical grid lines for the table.
|
||||
* @param painter destination painter for grid lines
|
||||
* @param maxWidthMap QMap of int to double, where the int contains the column number and the double is the
|
||||
* maximum width of text present in the column.
|
||||
* @note not available in python bindings
|
||||
* @see drawVerticalGridLines
|
||||
* @see calculateMaxColumnWidths
|
||||
*/
|
||||
void drawVerticalGridLines( QPainter* painter, const QMap<int, double>& maxWidthMap ) const;
|
||||
|
||||
void adjustFrameToSize();
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERTABLEV2_H
|
@ -31,6 +31,7 @@
|
||||
#include "qgscomposerlabel.h"
|
||||
#include "qgscomposermodel.h"
|
||||
#include "qgscomposerattributetable.h"
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgsaddremovemultiframecommand.h"
|
||||
#include "qgscomposermultiframecommand.h"
|
||||
#include "qgspaintenginehack.h"
|
||||
@ -2141,6 +2142,12 @@ void QgsComposition::endMultiFrameCommand()
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposition::cancelMultiFrameCommand()
|
||||
{
|
||||
delete mActiveMultiFrameCommand;
|
||||
mActiveMultiFrameCommand = 0;
|
||||
}
|
||||
|
||||
void QgsComposition::addMultiFrame( QgsComposerMultiFrame* multiFrame )
|
||||
{
|
||||
mMultiFrames.insert( multiFrame );
|
||||
@ -2255,6 +2262,16 @@ void QgsComposition::addComposerHtmlFrame( QgsComposerHtml* html, QgsComposerFra
|
||||
emit composerHtmlFrameAdded( html, frame );
|
||||
}
|
||||
|
||||
void QgsComposition::addComposerTableFrame( QgsComposerAttributeTableV2 *table, QgsComposerFrame *frame )
|
||||
{
|
||||
addItem( frame );
|
||||
|
||||
updateBounds();
|
||||
connect( frame, SIGNAL( sizeChanged() ), this, SLOT( updateBounds() ) );
|
||||
|
||||
emit composerTableFrameAdded( table, frame );
|
||||
}
|
||||
|
||||
void QgsComposition::removeComposerItem( QgsComposerItem* item, const bool createCommand, const bool removeGroupItems )
|
||||
{
|
||||
QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( item );
|
||||
@ -2420,6 +2437,11 @@ void QgsComposition::sendItemAddedSignal( QgsComposerItem* item )
|
||||
{
|
||||
emit composerHtmlFrameAdded( html, frame );
|
||||
}
|
||||
QgsComposerAttributeTableV2* table = dynamic_cast<QgsComposerAttributeTableV2*>( mf );
|
||||
if ( table )
|
||||
{
|
||||
emit composerTableFrameAdded( table, frame );
|
||||
}
|
||||
emit selectedItemChanged( frame );
|
||||
return;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ class QDomElement;
|
||||
class QgsComposerArrow;
|
||||
class QgsComposerMouseHandles;
|
||||
class QgsComposerHtml;
|
||||
class QgsComposerTableV2;
|
||||
class QgsComposerItem;
|
||||
class QgsComposerLabel;
|
||||
class QgsComposerLegend;
|
||||
@ -53,6 +54,7 @@ class QgsComposerPicture;
|
||||
class QgsComposerScaleBar;
|
||||
class QgsComposerShape;
|
||||
class QgsComposerAttributeTable;
|
||||
class QgsComposerAttributeTableV2;
|
||||
class QgsComposerMultiFrame;
|
||||
class QgsComposerMultiFrameCommand;
|
||||
class QgsVectorLayer;
|
||||
@ -459,6 +461,8 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
|
||||
|
||||
void beginMultiFrameCommand( QgsComposerMultiFrame* multiFrame, const QString& text, const QgsComposerMultiFrameMergeCommand::Context c = QgsComposerMultiFrameMergeCommand::Unknown );
|
||||
void endMultiFrameCommand();
|
||||
/**Deletes current multi frame command*/
|
||||
void cancelMultiFrameCommand();
|
||||
|
||||
/**Adds multiframe. The object is owned by QgsComposition until removeMultiFrame is called*/
|
||||
void addMultiFrame( QgsComposerMultiFrame* multiFrame );
|
||||
@ -481,8 +485,10 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
|
||||
void addComposerShape( QgsComposerShape* shape );
|
||||
/**Adds a composer table to the graphics scene and advices composer to create a widget for it (through signal)*/
|
||||
void addComposerTable( QgsComposerAttributeTable* table );
|
||||
/**Adds composer html frame and advices composer to create a widget for it (through signal)*/
|
||||
/**Adds composer html frame and advises composer to create a widget for it (through signal)*/
|
||||
void addComposerHtmlFrame( QgsComposerHtml* html, QgsComposerFrame* frame );
|
||||
/**Adds composer tablev2 frame and advises composer to create a widget for it (through signal)*/
|
||||
void addComposerTableFrame( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
|
||||
|
||||
/**Remove item from the graphics scene. Additionally to QGraphicsScene::removeItem, this function considers undo/redo command*/
|
||||
void removeComposerItem( QgsComposerItem* item, const bool createCommand = true, const bool removeGroupItems = true );
|
||||
@ -787,6 +793,8 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
|
||||
void composerShapeAdded( QgsComposerShape* shape );
|
||||
/**Is emitted when a new composer table has been added*/
|
||||
void composerTableAdded( QgsComposerAttributeTable* table );
|
||||
/**Is emitted when a new composer table frame has been added to the view*/
|
||||
void composerTableFrameAdded( QgsComposerAttributeTableV2* table, QgsComposerFrame* frame );
|
||||
/**Is emitted when a composer item has been removed from the scene*/
|
||||
void itemRemoved( QgsComposerItem* );
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "qgscomposerruler.h"
|
||||
#include "qgscomposerscalebar.h"
|
||||
#include "qgscomposershape.h"
|
||||
#include "qgscomposerattributetable.h"
|
||||
#include "qgscomposerattributetablev2.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsaddremovemultiframecommand.h"
|
||||
#include "qgspaperitem.h"
|
||||
@ -113,6 +113,7 @@ void QgsComposerView::setCurrentTool( QgsComposerView::Tool t )
|
||||
case QgsComposerView::AddEllipse:
|
||||
case QgsComposerView::AddTriangle:
|
||||
case QgsComposerView::AddTable:
|
||||
case QgsComposerView::AddAttributeTable:
|
||||
{
|
||||
//using a drawing tool
|
||||
//lock cursor to prevent composer items changing it
|
||||
@ -345,6 +346,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
|
||||
case AddLabel:
|
||||
case AddLegend:
|
||||
case AddTable:
|
||||
case AddAttributeTable:
|
||||
{
|
||||
QTransform t;
|
||||
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
|
||||
@ -416,6 +418,7 @@ QCursor QgsComposerView::defaultCursorForTool( Tool currentTool )
|
||||
case AddLegend:
|
||||
case AddPicture:
|
||||
case AddTable:
|
||||
case AddAttributeTable:
|
||||
{
|
||||
QPixmap myCrosshairQPixmap = QPixmap(( const char ** )( cross_hair_cursor ) );
|
||||
return QCursor( myCrosshairQPixmap, 8, 8 );
|
||||
@ -865,12 +868,13 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
|
||||
else
|
||||
{
|
||||
QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() );
|
||||
newTable->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), qMax( mRubberBandItem->rect().height(), (qreal)15.0 ) ) );
|
||||
QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems();
|
||||
if ( mapItemList.size() > 0 )
|
||||
{
|
||||
newTable->setComposerMap( mapItemList.at( 0 ) );
|
||||
}
|
||||
newTable->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ) );
|
||||
|
||||
composition()->addComposerTable( newTable );
|
||||
|
||||
composition()->setAllUnselected();
|
||||
@ -883,6 +887,39 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
|
||||
}
|
||||
break;
|
||||
|
||||
case AddAttributeTable:
|
||||
if ( !composition() || !mRubberBandItem )
|
||||
{
|
||||
removeRubberBand();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsComposerAttributeTableV2* newTable = new QgsComposerAttributeTableV2( composition(), true );
|
||||
QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems();
|
||||
if ( mapItemList.size() > 0 )
|
||||
{
|
||||
newTable->setComposerMap( mapItemList.at( 0 ) );
|
||||
}
|
||||
QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added,
|
||||
newTable, composition(), tr( "Attribute table added" ) );
|
||||
composition()->undoStack()->push( command );
|
||||
QgsComposerFrame* frame = new QgsComposerFrame( composition(), newTable, mRubberBandItem->transform().dx(),
|
||||
mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(),
|
||||
mRubberBandItem->rect().height() );
|
||||
composition()->beginMultiFrameCommand( newTable, tr( "Attribute table frame added" ) );
|
||||
newTable->addFrame( frame );
|
||||
composition()->endMultiFrameCommand();
|
||||
|
||||
composition()->setAllUnselected();
|
||||
frame->setSelected( true );
|
||||
emit selectedItemChanged( frame );
|
||||
|
||||
removeRubberBand();
|
||||
emit actionFinished();
|
||||
}
|
||||
break;
|
||||
|
||||
case AddHtml:
|
||||
if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
|
||||
{
|
||||
@ -994,6 +1031,7 @@ void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
|
||||
case AddLabel:
|
||||
case AddLegend:
|
||||
case AddTable:
|
||||
case AddAttributeTable:
|
||||
//adjust rubber band item
|
||||
{
|
||||
updateRubberBandRect( scenePoint, shiftModifier, altModifier );
|
||||
|
@ -36,7 +36,7 @@ class QgsComposerPicture;
|
||||
class QgsComposerRuler;
|
||||
class QgsComposerScaleBar;
|
||||
class QgsComposerShape;
|
||||
class QgsComposerAttributeTable;
|
||||
class QgsComposerAttributeTableV2;
|
||||
|
||||
/** \ingroup MapComposer
|
||||
* Widget to display the composer items. Manages the composer tools and the
|
||||
@ -64,7 +64,8 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
|
||||
AddRectangle,
|
||||
AddEllipse,
|
||||
AddTriangle,
|
||||
AddTable, //add attribute table
|
||||
AddTable, //add table
|
||||
AddAttributeTable,
|
||||
MoveItemContent, //move content of item (e.g. content of map)
|
||||
Pan,
|
||||
Zoom
|
||||
|
505
src/ui/qgscomposerattributetablewidgetbase.ui
Executable file
505
src/ui/qgscomposerattributetablewidgetbase.ui
Executable file
@ -0,0 +1,505 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsComposerAttributeTableWidgetBase</class>
|
||||
<widget class="QWidget" name="QgsComposerAttributeTableWidgetBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>410</width>
|
||||
<height>815</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Attribute Table</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">padding: 2px; font-weight: bold; background-color: rgb(200, 200, 200);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Attribute table</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>392</width>
|
||||
<height>813</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="mainLayout">
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Main properties</string>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">composeritem</string>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mLayerLabel">
|
||||
<property name="text">
|
||||
<string>Layer</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsMapLayerComboBox" name="mLayerComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="mRefreshPushButton">
|
||||
<property name="text">
|
||||
<string>Refresh table data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="mAttributesPushButton">
|
||||
<property name="text">
|
||||
<string>Attributes...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="mMarginLabel">
|
||||
<property name="text">
|
||||
<string>Margin</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mMarginSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Feature filtering</string>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">composeritem</string>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mMaxNumFeaturesLabel">
|
||||
<property name="text">
|
||||
<string>Maximum rows</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mMaximumColumnsSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="mMaximumColumnsSpinBox">
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mShowOnlyVisibleFeaturesCheckBox">
|
||||
<property name="text">
|
||||
<string>Show only visible features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mComposerMapLabel">
|
||||
<property name="text">
|
||||
<string>Composer map</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mComposerMapComboBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="mComposerMapComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="mFeatureFilterCheckBox">
|
||||
<property name="text">
|
||||
<string>Filter with</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="mFeatureFilterEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mFeatureFilterButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mIconExpression.svg</normaloff>:/images/themes/default/mIconExpression.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>mShowOnlyVisibleFeaturesCheckBox</zorder>
|
||||
<zorder>mComposerMapLabel</zorder>
|
||||
<zorder>mComposerMapComboBox</zorder>
|
||||
<zorder>mFeatureFilterCheckBox</zorder>
|
||||
<zorder>mMaximumColumnsSpinBox</zorder>
|
||||
<zorder>mMaxNumFeaturesLabel</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mShowGridGroupCheckBox">
|
||||
<property name="title">
|
||||
<string>Show grid</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">composeritem</string>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mGridStrokeWidthLabel">
|
||||
<property name="text">
|
||||
<string>Stroke width</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mGridStrokeWidthSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mGridStrokeWidthSpinBox">
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsColorButtonV2" name="mGridColorButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Fonts and text styling</string>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">composeritem</string>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Table heading</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mHeaderHAlignmentComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Follow column alignment</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Alignment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Font</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QPushButton" name="mHeaderFontPushButton">
|
||||
<property name="text">
|
||||
<string>Choose font...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QgsColorButtonV2" name="mHeaderFontColorButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Table contents</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QgsColorButtonV2" name="mContentFontColorButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QPushButton" name="mContentFontPushButton">
|
||||
<property name="text">
|
||||
<string>Choose font...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblContentsFont">
|
||||
<property name="text">
|
||||
<string>Font</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="frameGroupBox">
|
||||
<property name="title">
|
||||
<string>Frames</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mResizeModeLabel">
|
||||
<property name="text">
|
||||
<string>Resize mode</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="mResizeModeComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="mAddFramePushButton">
|
||||
<property name="text">
|
||||
<string>Add Frame</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBoxBasic</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header location="global">qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsColorButtonV2</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>qgscolorbuttonv2.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsMapLayerComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header location="global">qgsmaplayercombobox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../images/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
@ -118,6 +118,7 @@
|
||||
<addaction name="mActionAddNewScalebar"/>
|
||||
<addaction name="mActionAddArrow"/>
|
||||
<addaction name="mActionAddTable"/>
|
||||
<addaction name="mActionAddAttributeTable"/>
|
||||
<addaction name="mActionAddHtml"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mAtlasToolbar">
|
||||
@ -573,6 +574,17 @@
|
||||
<property name="text">
|
||||
<string>Add Table</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Add table</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionAddAttributeTable">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Attribute Table</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Add attribute table</string>
|
||||
</property>
|
||||
|
Loading…
x
Reference in New Issue
Block a user