18 #include <QPushButton> 20 #include <QHBoxLayout> 41 , mMessageBar( nullptr )
43 , mReferencedFieldIdx( -1 )
44 , mReferencingFieldIdx( -1 )
46 , mHighlight( nullptr )
48 , mMessageBarItem( nullptr )
50 , mReferencedAttributeForm( nullptr )
51 , mReferencedLayer( nullptr )
52 , mReferencingLayer( nullptr )
53 , mMasterModel( nullptr )
54 , mFilterModel( nullptr )
55 , mFeatureListModel( nullptr )
56 , mWindowWidget( nullptr )
60 , mReadOnlySelector( false )
61 , mAllowMapIdentification( false )
62 , mOrderByValue( false )
63 , mOpenFormButtonVisible( true )
64 , mChainFilters( false )
78 mChooserContainer =
new QWidget;
79 editLayout->
addWidget( mChooserContainer );
85 mFilterContainer->
setLayout( mFilterLayout );
86 mChooserContainer->
setLayout( chooserLayout );
87 chooserLayout->
addWidget( mFilterContainer );
101 mOpenFormButton->
setText(
tr(
"Open related feature form" ) );
102 editLayout->
addWidget( mOpenFormButton );
106 mHighlightFeatureButton->
setPopupMode( QToolButton::MenuButtonPopup );
110 mHighlightFeatureButton->
addAction( mHighlightFeatureAction );
111 mHighlightFeatureButton->
addAction( mScaleHighlightFeatureAction );
112 mHighlightFeatureButton->
addAction( mPanHighlightFeatureAction );
114 editLayout->
addWidget( mHighlightFeatureButton );
117 mMapIdentificationButton =
new QToolButton(
this );
119 mMapIdentificationButton->
setText(
tr(
"Select on map" ) );
121 editLayout->
addWidget( mMapIdentificationButton );
126 mRemoveFKButton->
setText(
tr(
"No selection" ) );
127 editLayout->
addWidget( mRemoveFKButton );
134 mAttributeEditorLayout =
new QVBoxLayout( mAttributeEditorFrame );
135 mAttributeEditorFrame->
setLayout( mAttributeEditorLayout );
136 mAttributeEditorFrame->
setSizePolicy( mAttributeEditorFrame->
sizePolicy().horizontalPolicy(), QSizePolicy::Expanding );
137 mTopLayout->
addWidget( mAttributeEditorFrame );
140 mInvalidLabel =
new QLabel(
tr(
"The relation is not valid. Please make sure your relation definitions are ok." ) );
145 mInvalidLabel->
setFont( font );
150 mMapIdentificationButton->
hide();
151 mHighlightFeatureButton->
hide();
152 mAttributeEditorFrame->
hide();
153 mInvalidLabel->
hide();
156 connect( mOpenFormButton, SIGNAL( clicked() ),
this, SLOT(
openForm() ) );
157 connect( mHighlightFeatureButton, SIGNAL( triggered(
QAction* ) ),
this, SLOT( highlightActionTriggered(
QAction* ) ) );
172 mAllowNull = allowNullValue;
173 mRemoveFKButton->
setVisible( allowNullValue && mReadOnlySelector );
177 mInvalidLabel->
hide();
179 mRelation = relation;
181 mRelationName = relation.
name();
190 mAttributeEditorFrame->
setTitle( mReferencedLayer->
name() );
193 mAttributeEditorLayout->
addWidget( mReferencedAttributeForm );
198 mInvalidLabel->
show();
214 mMapIdentificationButton->
setEnabled( editable );
216 mIsEditable = editable;
227 if ( !mReferencedLayer )
245 mForeignKey = mFeature.
attribute( mReferencedFieldIdx );
247 if ( mReadOnlySelector )
254 context.setFeature( mFeature );
255 QString title = expr.evaluate( &context ).toString();
256 if ( expr.hasEvalError() )
265 if ( i == -1 && mAllowNull )
276 highlightFeature( mFeature );
277 updateAttributeEditorFrame( mFeature );
284 if ( mReadOnlySelector )
289 nullText =
tr(
"%1 (no selection)" ).
arg( nullValue.
toString() );
291 mLineEdit->
setText( nullText );
314 if ( mReferencedLayer )
317 if ( mReadOnlySelector )
332 if ( mReadOnlySelector )
338 if ( mReferencingFieldIdx < 0 || mReferencingFieldIdx >= mReferencingLayer->
fields().
count() )
342 else if ( !mFeature.
isValid() )
348 return mFeature.
attribute( mReferencedFieldIdx );
355 mEditorContext = context;
357 mMessageBar = messageBar;
362 mMapTool->
setButton( mMapIdentificationButton );
374 mEmbedForm = display;
379 mChooserContainer->
setHidden( readOnly );
381 mRemoveFKButton->
setVisible( mAllowNull && readOnly );
382 mReadOnlySelector = readOnly;
387 mHighlightFeatureButton->
setVisible( allowMapIdentification );
388 mMapIdentificationButton->
setVisible( allowMapIdentification );
399 mFilterFields = filterFields;
404 mOpenFormButton->
setVisible( openFormButtonVisible );
424 if ( !mReadOnlySelector && mComboBox->
count() == 0 && mReferencedLayer )
432 if ( !mFilterFields.
isEmpty() )
434 Q_FOREACH (
const QString& fieldName, mFilterFields )
436 QVariantList uniqueValues;
440 mFilterComboBoxes << cb;
446 Q_FOREACH (
const QVariant& v, uniqueValues )
451 connect( cb, SIGNAL( currentIndexChanged(
int ) ),
this, SLOT( filterChanged() ) );
454 requestedAttrs << fieldName;
467 for (
int i = 0; i < mFilterComboBoxes.
count() - 1; ++i )
473 mFilterCache[mFilterFields[i]][cf] << nf;
480 mFilterContainer->
hide();
485 requestedAttrs += exp.referencedColumns().toSet();
486 requestedAttrs << mRelation.
fieldPairs().at( 0 ).second;
489 Q_FOREACH (
const QString& attr, requestedAttrs )
505 if ( !referencedColumns.
isEmpty() )
508 mFilterModel->
sort( sortIdx );
512 mComboBox->
setModel( mFeatureListModel );
516 if ( mChainFilters && mFeature.
isValid() )
518 for (
int i = 0; i < mFilterFields.
size(); i++ )
522 mFilterComboBoxes.
at( i )->setCurrentIndex( mFilterComboBoxes.
at( i )->findText( f ) );
529 connect( mComboBox, SIGNAL( currentIndexChanged(
int ) ),
this, SLOT( comboReferenceChanged(
int ) ) );
534 void QgsRelationReferenceWidget::highlightActionTriggered(
QAction* action )
536 if ( action == mHighlightFeatureAction )
540 else if ( action == mScaleHighlightFeatureAction )
544 else if ( action == mPanHighlightFeatureAction )
559 attributeDialog.
exec();
582 if ( canvasExtent ==
Scale )
595 else if ( canvasExtent ==
Pan )
606 mHighlight =
new QgsHighlight( mCanvas, f, mReferencedLayer );
622 connect( timer, SIGNAL( timeout() ),
this, SLOT( deleteHighlight() ) );
623 timer->
start( 3000 );
626 void QgsRelationReferenceWidget::deleteHighlight()
633 mHighlight =
nullptr;
638 if ( !mAllowMapIdentification || !mReferencedLayer )
647 mMapTool->
setLayer( mReferencedLayer );
657 connect( mMapTool, SIGNAL( deactivated() ),
this, SLOT( mapToolDeactivated() ) );
662 QString msg =
tr(
"Identify a feature of %1 to be associated. Press <ESC> to cancel." ).
arg( mReferencedLayer->
name() );
664 mMessageBar->
pushItem( mMessageBarItem );
668 void QgsRelationReferenceWidget::comboReferenceChanged(
int index )
672 highlightFeature( mFeature );
673 updateAttributeEditorFrame( mFeature );
677 void QgsRelationReferenceWidget::updateAttributeEditorFrame(
const QgsFeature& feature )
680 if ( mAttributeEditorFrame )
682 if ( mReferencedAttributeForm )
684 mReferencedAttributeForm->
setFeature( feature );
689 void QgsRelationReferenceWidget::featureIdentified(
const QgsFeature& feature )
691 if ( mReadOnlySelector )
698 context.setFeature( feature );
699 QString title = expr.evaluate( &context ).toString();
700 if ( expr.hasEvalError() )
705 mForeignKey = feature.
attribute( mReferencedFieldIdx );
715 highlightFeature( feature );
716 updateAttributeEditorFrame( feature );
722 void QgsRelationReferenceWidget::unsetMapTool()
725 if ( mCanvas && mMapTool )
732 void QgsRelationReferenceWidget::mapToolDeactivated()
736 mWindowWidget->
raise();
740 if ( mMessageBar && mMessageBarItem )
742 mMessageBar->
popWidget( mMessageBarItem );
744 mMessageBarItem =
nullptr;
747 void QgsRelationReferenceWidget::filterChanged()
761 Q_FOREACH (
QComboBox* cb, mFilterComboBoxes )
797 Q_FOREACH (
QComboBox* cb, mFilterComboBoxes )
805 filters <<
QString(
"\"%1\" IS NULL" ).
arg( fieldName );
809 if ( mReferencedLayer->
fields().
field( fieldName ).
type() == QVariant::String )
822 QString filterExpression = filters.
join(
" AND " );
829 while ( it.nextFeature( f ) )
831 featureIds << f.id();
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
When showing a single feature (e.g. district information when looking at the form of a house) ...
bool isValid() const
Returns the validity of this feature.
void setRequest(const QgsFeatureRequest &request)
Set a request that will be used to fill this attribute table model.
Class for parsing and evaluation of expressions (formerly called "search strings").
const QgsVectorLayerTools * vectorLayerTools() const
Wrapper for iterator of features from vector data provider or vector layer.
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
bool isValid() const
Returns the validity of this relation.
static double DEFAULT_HIGHLIGHT_BUFFER_MM
Default highlight buffer in mm.
A rectangle specified with double values.
static const QColor DEFAULT_HIGHLIGHT_COLOR
Default highlight color.
void setContentsMargins(int left, int top, int right, int bottom)
virtual void loadLayer()
Loads the layer into the model Preferably to be called, before using this model as source for any oth...
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
bool setDisplayExpression(const QString &expression)
A form was opened as a new dialog.
void setText(const QString &)
A groupbox that collapses/expands when toggled and can save its collapsed and checked states...
This class contains context information for attribute editor widgets.
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Calculates a list of unique values contained within an attribute in the layer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
void setExtent(const QgsRectangle &r)
Set the extent of the map canvas.
const T & at(int i) const
void scale(double scaleFactor, const QgsPoint *c=nullptr)
Scale the rectangle around its center point.
void setFillColor(const QColor &fillColor)
Set polygons fill color.
A bar for displaying non-blocking messages to the user.
void refresh()
Repaints the canvas map.
A geometry is the spatial representation of a feature.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
QString join(const QString &separator) const
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...
const QString displayExpression()
Get the preview expression, used to create a human readable preview string.
int count() const
Return number of items.
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
void setCacheSubsetOfAttributes(const QgsAttributeList &attributes)
Set the subset of attributes to be cached.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
QgsGeometry * centroid() const
Returns the center of mass of a geometry.
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.
void addItem(const QString &text, const QVariant &userData)
void setMapTool(QgsMapTool *mapTool)
Sets the map tool currently being used on the canvas.
void setBuffer(double buffer)
Set line / outline buffer in millimeters.
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
make out a widget containing a message to be displayed on the bar
int count(const T &value) const
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
QVariant property(const char *name) const
int toInt(bool *ok) const
bool popWidget(QgsMessageBarItem *item)
Remove the passed widget from the bar (if previously added), then display the next one in the stack i...
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.
A class for highlight features on the map.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void setOverrideCursor(const QCursor &cursor)
QgsVectorLayerCache * layerCache() const
Returns the layer cache this model uses as backend.
void restoreOverrideCursor()
A class to represent a point.
QVariant itemData(int index, int role) const
QgsFeatureId id() const
Get the feature ID for this feature.
QList< FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names f...
bool blockSignals(bool block)
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
This class caches features of a given QgsVectorLayer.
void setItalic(bool enable)
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
void setValid(bool validity)
Sets the validity of the feature.
bool setAlignment(QWidget *w, QFlags< Qt::AlignmentFlag > alignment)
QVariant value(const QString &key, const QVariant &defaultValue) const
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
QString name() const
Get the display name of the layer.
void pushItem(QgsMessageBarItem *item)
Display a message item on the bar after hiding the currently visible one and putting it in a stack...
QgsPoint layerToMapCoordinates(QgsMapLayer *theLayer, QgsPoint point) const
transform point coordinates from layer's CRS to output CRS
int findData(const QVariant &data, int role, QFlags< Qt::MatchFlag > flags) const
void setColor(const QColor &color)
Set line/outline to color, polygon fill to color with alpha = 63.
void setModel(QAbstractItemModel *model)
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)
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
void setCurrentIndex(int index)
void setText(const QString &text)
double toDouble(bool *ok) const
bool setProperty(const char *name, const QVariant &value)
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
void setInjectNull(bool injectNull)
If true is specified, a NULL value will be injected.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
bool nextFeature(QgsFeature &f)
Geometry is not required. It may still be returned if e.g. required for a filter condition.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static double DEFAULT_HIGHLIGHT_MIN_WIDTH_MM
Default highlight line/outline minimum width in mm.
void setWordWrap(bool on)
void setSpacing(int spacing)
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
QString name() const
Returns a human readable name for this relation.
void zoomByFactor(double scaleFactor, const QgsPoint *center=nullptr)
Zoom with the factor supplied.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
A form was embedded as a widget on another form.
void addLayout(QLayout *layout, int stretch)
void setMinWidth(double width)
Set minimum line / outline width in millimeters.
void setSingleShot(bool singleShot)