33 #include <QMessageBox> 34 #include <QProgressDialog> 37 #include <QInputDialog> 42 , mMasterModel( nullptr )
43 , mFilterModel( nullptr )
44 , mFeatureListModel( nullptr )
45 , mAttributeForm( nullptr )
46 , mHorizontalHeaderMenu( nullptr )
47 , mLayerCache( nullptr )
48 , mProgressDlg( nullptr )
49 , mFeatureSelectionManager( nullptr )
50 , mAttributeEditorScrollArea( nullptr )
51 , mMapCanvas( nullptr )
55 mConditionalFormatWidget->hide();
59 mPreviewColumnsMenu =
new QMenu(
this );
60 mActionPreviewColumnsMenu->setMenu( mPreviewColumnsMenu );
66 connect( mActionExpressionPreview, SIGNAL( triggered() ), SLOT( previewExpressionBuilder() ) );
67 connect( mPreviewActionMapper, SIGNAL( mapped(
QObject* ) ), SLOT( previewColumnChanged(
QObject* ) ) );
73 mMapCanvas = mapCanvas;
80 mEditorContext = context;
83 mTableView->horizontalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
85 connect( mTableView, SIGNAL( columnResized(
int,
int ) ),
this, SLOT( tableColumnResized(
int,
int ) ) );
88 initModels( mapCanvas, request, loadFeatures );
90 mConditionalFormatWidget->setLayer( mLayer );
92 mTableView->setModel( mFilterModel );
93 mFeatureList->setModel( mFeatureListModel );
94 delete mAttributeForm;
100 mAttributeEditor->layout()->addWidget( mAttributeEditorScrollArea );
101 mAttributeEditorScrollArea->
setWidget( mAttributeForm );
105 mAttributeEditor->layout()->addWidget( mAttributeForm );
108 connect( mAttributeForm, SIGNAL( attributeChanged(
QString,
QVariant ) ),
this, SLOT( featureFormAttributeChanged() ) );
110 connect( mMasterModel, SIGNAL( modelChanged() ), mAttributeForm, SLOT( refreshFeature() ) );
112 connect( mFilterModel, SIGNAL( sortColumnChanged(
int, Qt::SortOrder ) ),
this, SLOT( onSortColumnChanged() ) );
113 if ( mFeatureListPreviewButton->defaultAction() )
114 mFeatureList->setDisplayExpression( mDisplayExpression );
135 if ( displayExpression.
isEmpty() )
140 displayExpression =
QString(
"COALESCE(\"%1\", '<NULL>')" ).
arg( defaultField );
145 if ( displayExpression.
isEmpty() )
151 if ( pkAttrs.
size() == 1 )
152 defaultField = pkAttrs.
at( 0 );
157 Q_FOREACH (
int attr, pkAttrs )
159 pkFields.
append(
"COALESCE(\"" + fields[attr].
name() +
"\", '<NULL>')" );
162 displayExpression = pkFields.
join(
"||', '||" );
166 if ( fields.
size() == 1 )
167 defaultField = fields.
at( 0 ).name();
171 Q_FOREACH (
const QgsField& field, fields )
173 fieldNames.
append(
"COALESCE(\"" + field.
name() +
"\", '<NULL>')" );
176 displayExpression = fieldNames.
join(
"||', '||" );
181 displayExpression =
"'[Please define preview text]'";
185 mFeatureListPreviewButton->addAction( mActionExpressionPreview );
186 mFeatureListPreviewButton->addAction( mActionPreviewColumnsMenu );
188 Q_FOREACH (
const QgsField& field, fields )
191 if ( fieldIndex == -1 )
200 QAction* previewAction =
new QAction( icon, text, mFeatureListPreviewButton );
201 mPreviewActionMapper->
setMapping( previewAction, previewAction );
202 connect( previewAction, SIGNAL( triggered() ), mPreviewActionMapper, SLOT( map() ) );
203 mPreviewColumnsMenu->
addAction( previewAction );
205 if ( text == defaultField )
207 mFeatureListPreviewButton->setDefaultAction( previewAction );
213 if ( !mFeatureListPreviewButton->defaultAction() )
215 mFeatureList->setDisplayExpression( displayExpression );
216 mFeatureListPreviewButton->setDefaultAction( mActionExpressionPreview );
217 mDisplayExpression = mFeatureList->displayExpression();
221 mFeatureListPreviewButton->defaultAction()->trigger();
225 connect( sortByPreviewExpression, SIGNAL( triggered(
bool ) ),
this, SLOT( sortByPreviewExpression() ) );
226 mFeatureListPreviewButton->addAction( sortByPreviewExpression );
245 disconnect( mMapCanvas, SIGNAL( extentsChanged() ),
this, SLOT( extentChanged() ) );
255 SLOT( updateSelectedFeatures() ) );
264 || ( mMasterModel->
rowCount() == 0 );
266 if ( !needsGeometry )
275 switch ( filterMode )
278 connect( mMapCanvas, SIGNAL( extentsChanged() ),
this, SLOT( extentChanged() ) );
292 connect(
masterModel()->layer(), SIGNAL( selectionChanged() ),
this, SLOT( updateSelectedFeatures() ) );
293 if (
masterModel()->layer()->selectedFeatureCount() > 0 )
298 if ( requiresTableReload )
301 whileBlocking( mLayerCache )->setCacheGeometry( needsGeometry );
315 void QgsDualView::initLayerCache(
bool cacheGeometry )
319 int cacheSize = settings.
value(
"/qgis/attributeTableRowCache",
"10000" ).
toInt();
324 connect( mLayerCache, SIGNAL( invalidated() ),
this, SLOT( rebuildFullLayerCache() ) );
325 rebuildFullLayerCache();
331 delete mFeatureListModel;
340 connect( mMasterModel, SIGNAL( progress(
int,
bool & ) ),
this, SLOT( progress(
int,
bool & ) ) );
341 connect( mMasterModel, SIGNAL( finished() ),
this, SLOT( finished() ) );
343 connect( mConditionalFormatWidget, SIGNAL( rulesUpdated(
QString ) ), mMasterModel, SLOT( fieldConditionalStyleChanged(
QString ) ) );
355 void QgsDualView::on_mFeatureList_aboutToChangeEditSelection(
bool& ok )
361 void QgsDualView::on_mFeatureList_currentEditSelectionChanged(
const QgsFeature &feat )
376 mFeatureList->setCurrentFeatureEdited(
false );
377 mFeatureList->setEditSelection( fids );
382 return mAttributeForm->
save();
387 mConditionalFormatWidget->setVisible( !mConditionalFormatWidget->isVisible() );
388 mConditionalFormatWidget->viewRules();
412 void QgsDualView::previewExpressionBuilder()
422 dlg.setExpressionText( mFeatureList->displayExpression() );
424 if ( dlg.exec() == QDialog::Accepted )
426 mFeatureList->setDisplayExpression( dlg.expressionText() );
427 mFeatureListPreviewButton->setDefaultAction( mActionExpressionPreview );
428 mFeatureListPreviewButton->setPopupMode( QToolButton::MenuButtonPopup );
431 mDisplayExpression = mFeatureList->displayExpression();
434 void QgsDualView::previewColumnChanged(
QObject* action )
440 if ( !mFeatureList->setDisplayExpression(
QString(
"COALESCE( \"%1\", '<NULL>' )" ).arg( previewAction->
text() ) ) )
443 tr(
"Could not set preview column" ),
444 tr(
"Could not set column '%1' as preview column.\nParser error:\n%2" )
445 .arg( previewAction->
text(), mFeatureList->parserErrorString() )
450 mFeatureListPreviewButton->setDefaultAction( previewAction );
451 mFeatureListPreviewButton->setPopupMode( QToolButton::InstantPopup );
455 mDisplayExpression = mFeatureList->displayExpression();
457 Q_ASSERT( previewAction );
482 void QgsDualView::viewWillShowContextMenu(
QMenu* menu,
const QModelIndex& atIndex )
492 QAction *copyContentAction =
new QAction(
tr(
"Copy cell content" ),
this );
493 copyContentAction->
setData( QVariant::fromValue<QModelIndex>( sourceIndex ) );
501 menu->
addAction(
tr(
"Zoom to feature" ),
this, SLOT( zoomToCurrentFeature() ) );
511 for (
int i = 0; i < mLayer->
actions()->
size(); i++ )
525 if ( !registeredActions.
isEmpty() )
531 for ( actionIt = registeredActions.
begin(); actionIt != registeredActions.
end(); ++actionIt )
534 menu->
addAction(( *actionIt )->text(), a, SLOT( execute() ) );
540 menu->
addAction(
tr(
"Open form" ), a, SLOT( featureForm() ) );
543 void QgsDualView::showViewHeaderMenu(
QPoint point )
545 int col = mTableView->columnAt( point.
x() );
547 delete mHorizontalHeaderMenu;
548 mHorizontalHeaderMenu =
new QMenu(
this );
551 connect( hide, SIGNAL( triggered(
bool ) ),
this, SLOT( hideColumn() ) );
553 mHorizontalHeaderMenu->
addAction( hide );
554 QAction* setWidth =
new QAction(
tr(
"&Set width..." ), mHorizontalHeaderMenu );
555 connect( setWidth, SIGNAL( triggered(
bool ) ),
this, SLOT( resizeColumn() ) );
557 mHorizontalHeaderMenu->
addAction( setWidth );
558 QAction* optimizeWidth =
new QAction(
tr(
"&Autosize" ), mHorizontalHeaderMenu );
559 connect( optimizeWidth, SIGNAL( triggered(
bool ) ),
this, SLOT( autosizeColumn() ) );
561 mHorizontalHeaderMenu->
addAction( optimizeWidth );
564 QAction* organize =
new QAction(
tr(
"&Organize columns..." ), mHorizontalHeaderMenu );
565 connect( organize, SIGNAL( triggered(
bool ) ),
this, SLOT( organizeColumns() ) );
566 mHorizontalHeaderMenu->
addAction( organize );
568 connect( sort, SIGNAL( triggered(
bool ) ),
this, SLOT( modifySort() ) );
569 mHorizontalHeaderMenu->
addAction( sort );
571 mHorizontalHeaderMenu->
popup( mTableView->horizontalHeader()->mapToGlobal( point ) );
574 void QgsDualView::organizeColumns()
582 if ( dialog.
exec() == QDialog::Accepted )
589 void QgsDualView::tableColumnResized(
int column,
int width )
593 if ( sourceCol >= 0 )
600 void QgsDualView::hideColumn()
606 if ( sourceCol >= 0 )
613 void QgsDualView::resizeColumn()
622 if ( sourceCol >= 0 )
626 mTableView->columnWidth( col ),
636 void QgsDualView::autosizeColumn()
640 mTableView->resizeColumnToContents( col );
643 void QgsDualView::modifySort()
654 connect( dialogButtonBox, SIGNAL( accepted() ), &orderByDlg, SLOT( accept() ) );
655 connect( dialogButtonBox, SIGNAL( rejected() ), &orderByDlg, SLOT( reject() ) );
659 sortingGroupBox->
setTitle(
tr(
"Defined sort order in attribute table" ) );
671 expressionBuilder->
setLayer( mLayer );
683 if ( orderByDlg.
exec() )
685 Qt::SortOrder sortOrder = cbxSortAscending->
isChecked() ? Qt::AscendingOrder : Qt::DescendingOrder;
702 void QgsDualView::zoomToCurrentFeature()
719 void QgsDualView::rebuildFullLayerCache()
721 connect( mLayerCache, SIGNAL( progress(
int,
bool& ) ),
this, SLOT( progress(
int,
bool& ) ), Qt::UniqueConnection );
722 connect( mLayerCache, SIGNAL( finished() ),
this, SLOT( finished() ), Qt::UniqueConnection );
727 void QgsDualView::previewExpressionChanged(
const QString& expression )
732 void QgsDualView::onSortColumnChanged()
740 void QgsDualView::sortByPreviewExpression()
742 Qt::SortOrder sortOrder = Qt::AscendingOrder;
745 sortOrder = mConfig.
sortOrder() == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder;
750 void QgsDualView::updateSelectedFeatures()
765 void QgsDualView::extentChanged()
778 void QgsDualView::featureFormAttributeChanged()
780 mFeatureList->setCurrentFeatureEdited(
true );
795 mTableView->setFeatureSelectionManager( featureSelectionManager );
796 mFeatureList->setFeatureSelectionManager( featureSelectionManager );
798 if ( mFeatureSelectionManager && mFeatureSelectionManager->
parent() == this )
799 delete mFeatureSelectionManager;
801 mFeatureSelectionManager = featureSelectionManager;
809 mTableView->setAttributeTableConfig( config );
814 if ( sortExpression.
isNull() )
815 mFilterModel->
sort( -1 );
817 mFilterModel->
sort( sortExpression, sortOrder );
829 void QgsDualView::progress(
int i,
bool& cancel )
833 mProgressDlg =
new QProgressDialog(
tr(
"Loading features..." ),
tr(
"Abort" ), 0, 0,
this );
836 mProgressDlg->
show();
839 mProgressDlg->
setLabelText(
tr(
"%1 features loaded." ).arg( i ) );
842 cancel = mProgressDlg && mProgressDlg->
wasCanceled();
845 void QgsDualView::finished()
848 mProgressDlg =
nullptr;
857 mDualView->masterModel()->executeAction( mAction, mFieldIdx );
863 editedIds << mDualView->masterModel()->rowToId( mFieldIdx.row() );
864 mDualView->setCurrentEditSelection( editedIds );
874 mDualView->masterModel()->executeMapLayerAction( mAction, mFieldIdx );
bool canConvert(Type t) const
void setRequest(const QgsFeatureRequest &request)
Set a request that will be used to fill this attribute table model.
QgsActionManager * actions()
Get all layer actions defined on this layer.
QgsFeatureId rowToId(const QModelIndex &row)
Returns the feature id for a given model index.
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
void setFilterMode(QgsAttributeTableFilterModel::FilterMode filterMode)
Set the filter mode.
A rectangle specified with double values.
void setSortExpression(const QString &sortExpression)
Set the sort expression used for sorting.
virtual void loadLayer()
Loads the layer into the model Preferably to be called, before using this model as source for any oth...
void setAttributeTableConfig(const QgsAttributeTableConfig &config)
Set the attribute table configuration to control which fields are shown, in which order they are show...
void init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext(), bool loadFeatures=true)
Has to be called to initialize the dual view.
QgsFeatureId idxToFid(const QModelIndex &index) const
QgsAttributeTableConfig config() const
Get the updated configuration.
const Flags & flags() const
void setSortOrder(const Qt::SortOrder &sortOrder)
Set the sort order.
void setSelectedOnTop(bool selectedOnTop)
Changes the sort order of the features.
QgsAttributeTableModel * masterModel() const
Returns the model which has the information about all features (not only filtered) ...
void filterExpressionSet(const QString &expression, QgsAttributeForm::FilterType type)
Is emitted when a filter expression is set using the view.
void setFilterMode(FilterMode filterMode)
Set the filter mode the filter will use.
void toggleSearchMode(bool enabled)
Toggles whether search mode should be enabled in the form.
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
Set the feature selection model.
void openConditionalStyles()
QIcon iconForField(int fieldIdx) const
Returns an icon corresponding to a field index, based on the field's type and source.
QSet< QgsFeatureId > QgsFeatureIds
QString sortExpression() const
Get the expression used for sorting the table and feature list.
This class contains context information for attribute editor widgets.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
void setLabelText(const QString &text)
ViewMode
The view modes, in which this widget can present information.
const T & at(int i) const
FilterType filterType() const
Return the filter type which is currently set on this request.
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
int filteredFeatureCount()
Returns the number of features which are currently visible, according to the filter restrictions...
void setDisplayExpression(const QString &displayExpression)
Set the preview expression, used to create a human readable preview string.
QString join(const QString &separator) const
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
A model backed by a QgsVectorLayerCache which is able to provide feature/attribute information to a Q...
Show only visible features (depends on the map canvas)
void setCurrentEditSelection(const QgsFeatureIds &fids)
Set the current edit selection in the AttributeEditor mode.
int mapVisibleColumnToIndex(int visibleColumn) const
Maps a visible column index to its original column index.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
const QgsRectangle & filterRect() const
Get the rectangle from which features will be taken.
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
const QgsAction & at(int idx) const
Get the action at the specified index.
virtual int rowCount(const QModelIndex &parent) const
void setView(ViewMode view)
Change the current view mode.
QgsEditFormConfig * editFormConfig() const
Get the configuration of the form used to represent this vector layer.
virtual void setFilteredFeatures(const QgsFeatureIds &ids)
Specify a list of features, which the filter will accept.
QgsFields fields() const
Returns the list of fields of this layer.
virtual QVariant data(const QModelIndex &index, int role) const override
Returns data on the given index.
void setAttributeTableConfig(const QgsAttributeTableConfig &config)
Set the attribute table config which should be used to control the appearance of the attribute table...
QgsDualView(QWidget *parent=nullptr)
Constructor.
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
const char * name() const
void setColumnWidth(int column, int width)
Sets the width of a column.
void copyCellContent() const
Copy the content of the selected cell in the clipboard.
void setMapping(QObject *sender, int id)
void setSortExpression(const QString &sortExpression, Qt::SortOrder sortOrder=Qt::AscendingOrder)
Set the expression used for sorting the table and feature list.
Show only selected features.
void processEvents(QFlags< QEventLoop::ProcessEventsFlag > flags)
void append(const T &value)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
FilterMode filterMode()
The current filterModel.
void setChecked(bool checked)
int toInt(bool *ok) const
void setExtraColumns(int extraColumns)
Empty extra columns to announce from this model.
FilterMode
The filter mode defines how the rows should be filtered.
Dialog for organising (hiding and reordering) columns in the attributes table.
void setEditorContext(const QgsAttributeEditorContext &context)
Sets the context in which this table is shown.
QgsFeatureRequest & disableFilter()
Disables filter conditions.
ViewMode view() const
Returns the current view mode.
Utility class that encapsulates an action based on vector attributes.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
bool runable() const
Checks if the action is runable on the current platform.
QgsFeatureIds filteredFeatures()
Get a list of currently visible feature ids.
void filterChanged()
Is emitted, whenever the filter changes.
QString name() const
The name of the action. This may be a longer description.
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
Show only features which have unsaved changes.
const QgsFeatureRequest & request() const
Get the the feature request.
Encapsulate a field in an attribute table or data source.
Fast access to features using their ID.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
QgsAttributeList pkAttributeList() const
Returns list of attributes making up the primary key.
QString displayField() const
Returns the primary display field name used in the identify results dialog.
void setData(const QVariant &userData)
QgsFeatureId id() const
Get the feature ID for this feature.
QString sortExpression() const
The expression which is used to sort the attribute table.
This class caches features of a given QgsVectorLayer.
const QgsAttributeEditorContext * parentContext() const
bool saveEditChanges()
saveEditChanges
Show only features whose ids are on the filter list. {.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
void setRequest(const QgsFeatureRequest &request)
Set the request.
QgsAttributeTableFilterModel::FilterMode filterMode()
Get the filter mode.
QgsAttributeTableConfig attributeTableConfig() const
Get the attribute table configuration object.
void setSelectedOnTop(bool selectedOnTop)
Toggle the selectedOnTop flag.
QVariant value(const QString &key, const QVariant &defaultValue) const
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
void zoomToFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids)
Set canvas extent to the bounding box of a set of features.
static QgsMapLayerActionRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Set feature IDs that should be fetched.
Qt::SortOrder sortOrder() const
QgsPoint mapToLayerCoordinates(QgsMapLayer *theLayer, QgsPoint point) const
transform point coordinates from output CRS to layer's CRS
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of rows.
void setCacheGeometry(bool cacheGeometry)
Enable or disable the caching of geometries.
void setFullCache(bool fullCache)
This enables or disables full caching.
virtual void sort(int column, Qt::SortOrder order=Qt::AscendingOrder) override
Sort by the given column using the given order.
void setTitle(const QString &title)
void setCheckable(bool checkable)
void setColumnHidden(int column, bool hidden)
Sets whether the specified column should be hidden.
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
bool isNull() const
test if the rectangle is null (all coordinates zero or after call to setMinimal()).
QgsMapCanvas * mapCanvas() const
Returns the map canvas.
void displayExpressionChanged(const QString &expression)
Is emitted, whenever the display expression is successfully changed.
QList< QgsMapLayerAction * > mapLayerActions(QgsMapLayer *layer, const QgsMapLayerAction::Targets &targets=QgsMapLayerAction::AllActions)
Returns the map layer actions which can run on the specified layer.
void formModeChanged(QgsAttributeForm::Mode mode)
Emitted when the form changes mode.
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
void setText(const QString &text, Mode mode)
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
QgsVectorDataProvider * dataProvider()
Returns the data provider.
void setFilteredFeatures(const QgsFeatureIds &filteredFeatures)
Set a list of currently visible features.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
This is a container for configuration of the attribute table.
Qt::SortOrder sortOrder() const
Get the sort order.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
void setMultiEditEnabled(bool enabled)
Sets whether multi edit mode is enabled.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Is an interface class to abstract feature selection handling.
QString displayExpression() const
Get the preview expression, used to create a human readable preview string.
Represents a vector layer which manages a vector based data sets.
int size() const
Get the number of actions managed by this.
int selectedFeatureCount()
The number of features that are selected in this layer.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void setAttributeTableConfig(const QgsAttributeTableConfig &attributeTableConfig)
Set the attribute table configuration object.
A generic dialog for building expression strings.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rect)
Set rectangle from which features will be taken.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
void columnBoxInit()
Initializes widgets which depend on the attributes of this layer.
int featureCount()
Returns the number of features on the layer.