18 #include <QPushButton> 20 #include <QHBoxLayout> 40 switch ( p1.first.type() )
42 case QVariant::String:
43 return p1.first.toString() < p2.first.toString();
45 case QVariant::Double:
46 return p1.first.toDouble() < p2.first.toDouble();
49 return p1.first.toInt() < p2.first.toInt();
57 , mMessageBar( nullptr )
59 , mReferencedFieldIdx( -1 )
60 , mReferencingFieldIdx( -1 )
62 , mHighlight( nullptr )
64 , mMessageBarItem( nullptr )
66 , mReferencedAttributeForm( nullptr )
67 , mReferencedLayer( nullptr )
68 , mReferencingLayer( nullptr )
69 , mMasterModel( nullptr )
70 , mFilterModel( nullptr )
71 , mFeatureListModel( nullptr )
72 , mWindowWidget( nullptr )
76 , mReadOnlySelector( false )
77 , mAllowMapIdentification( false )
78 , mOrderByValue( false )
79 , mOpenFormButtonVisible( true )
80 , mChainFilters( false )
94 mChooserContainer =
new QWidget;
95 editLayout->
addWidget( mChooserContainer );
100 mFilterContainer =
new QWidget;
101 mFilterContainer->
setLayout( mFilterLayout );
102 mChooserContainer->
setLayout( chooserLayout );
103 chooserLayout->
addWidget( mFilterContainer );
117 mOpenFormButton->
setText(
tr(
"Open related feature form" ) );
118 editLayout->
addWidget( mOpenFormButton );
122 mHighlightFeatureButton->
setPopupMode( QToolButton::MenuButtonPopup );
126 mHighlightFeatureButton->
addAction( mHighlightFeatureAction );
127 mHighlightFeatureButton->
addAction( mScaleHighlightFeatureAction );
128 mHighlightFeatureButton->
addAction( mPanHighlightFeatureAction );
130 editLayout->
addWidget( mHighlightFeatureButton );
133 mMapIdentificationButton =
new QToolButton(
this );
135 mMapIdentificationButton->
setText(
tr(
"Select on map" ) );
137 editLayout->
addWidget( mMapIdentificationButton );
142 mRemoveFKButton->
setText(
tr(
"No selection" ) );
143 editLayout->
addWidget( mRemoveFKButton );
150 mAttributeEditorLayout =
new QVBoxLayout( mAttributeEditorFrame );
151 mAttributeEditorFrame->
setLayout( mAttributeEditorLayout );
152 mAttributeEditorFrame->
setSizePolicy( mAttributeEditorFrame->
sizePolicy().horizontalPolicy(), QSizePolicy::Expanding );
153 mTopLayout->
addWidget( mAttributeEditorFrame );
156 mInvalidLabel =
new QLabel(
tr(
"The relation is not valid. Please make sure your relation definitions are ok." ) );
161 mInvalidLabel->
setFont( font );
166 mMapIdentificationButton->
hide();
167 mHighlightFeatureButton->
hide();
168 mAttributeEditorFrame->
hide();
169 mInvalidLabel->
hide();
172 connect( mOpenFormButton, SIGNAL( clicked() ),
this, SLOT(
openForm() ) );
173 connect( mHighlightFeatureButton, SIGNAL( triggered(
QAction* ) ),
this, SLOT( highlightActionTriggered(
QAction* ) ) );
188 mAllowNull = allowNullValue;
189 mRemoveFKButton->
setVisible( allowNullValue && mReadOnlySelector );
193 mInvalidLabel->
hide();
195 mRelation = relation;
197 mRelationName = relation.
name();
206 mAttributeEditorFrame->
setTitle( mReferencedLayer->
name() );
209 mAttributeEditorLayout->
addWidget( mReferencedAttributeForm );
214 mInvalidLabel->
show();
230 mMapIdentificationButton->
setEnabled( editable );
232 mIsEditable = editable;
243 if ( !mReferencedLayer )
261 mForeignKey = mFeature.
attribute( mReferencedFieldIdx );
263 if ( mReadOnlySelector )
270 context.setFeature( mFeature );
271 QString title = expr.evaluate( &context ).toString();
272 if ( expr.hasEvalError() )
281 if ( i == -1 && mAllowNull )
292 highlightFeature( mFeature );
293 updateAttributeEditorFrame( mFeature );
300 if ( mReadOnlySelector )
305 nullText =
tr(
"%1 (no selection)" ).
arg( nullValue.
toString() );
307 mLineEdit->
setText( nullText );
330 if ( mReferencedLayer )
333 if ( mReadOnlySelector )
348 if ( mReadOnlySelector )
360 return mFeature.
attribute( mReferencedFieldIdx );
367 mEditorContext = context;
369 mMessageBar = messageBar;
374 mMapTool->
setButton( mMapIdentificationButton );
386 mEmbedForm = display;
391 mChooserContainer->
setHidden( readOnly );
393 mRemoveFKButton->
setVisible( mAllowNull && readOnly );
394 mReadOnlySelector = readOnly;
399 mHighlightFeatureButton->
setVisible( allowMapIdentification );
400 mMapIdentificationButton->
setVisible( allowMapIdentification );
411 mFilterFields = filterFields;
416 mOpenFormButton->
setVisible( openFormButtonVisible );
436 if ( !mReadOnlySelector && mComboBox->
count() == 0 && mReferencedLayer )
444 if ( !mFilterFields.
isEmpty() )
446 Q_FOREACH (
const QString& fieldName, mFilterFields )
448 QVariantList uniqueValues;
452 mFilterComboBoxes << cb;
458 Q_FOREACH (
const QVariant& v, uniqueValues )
463 connect( cb, SIGNAL( currentIndexChanged(
int ) ),
this, SLOT( filterChanged() ) );
466 requestedAttrs << fieldName;
479 for (
int i = 0; i < mFilterComboBoxes.
count() - 1; ++i )
485 mFilterCache[mFilterFields[i]][cf] << nf;
492 mFilterContainer->
hide();
497 requestedAttrs += exp.referencedColumns().toSet();
498 requestedAttrs << mRelation.
fieldPairs().at( 0 ).second;
501 Q_FOREACH (
const QString& attr, requestedAttrs )
517 if ( !referencedColumns.
isEmpty() )
520 mFilterModel->
sort( sortIdx );
524 mComboBox->
setModel( mFeatureListModel );
528 if ( mChainFilters && mFeature.
isValid() )
530 for (
int i = 0; i < mFilterFields.
size(); i++ )
534 mFilterComboBoxes.
at( i )->setCurrentIndex( mFilterComboBoxes.
at( i )->findText( f ) );
541 connect( mComboBox, SIGNAL( currentIndexChanged(
int ) ),
this, SLOT( comboReferenceChanged(
int ) ) );
546 void QgsRelationReferenceWidget::highlightActionTriggered(
QAction* action )
548 if ( action == mHighlightFeatureAction )
552 else if ( action == mScaleHighlightFeatureAction )
556 else if ( action == mPanHighlightFeatureAction )
571 attributeDialog.
exec();
594 if ( canvasExtent ==
Scale )
607 else if ( canvasExtent ==
Pan )
618 mHighlight =
new QgsHighlight( mCanvas, f, mReferencedLayer );
634 connect( timer, SIGNAL( timeout() ),
this, SLOT( deleteHighlight() ) );
635 timer->
start( 3000 );
638 void QgsRelationReferenceWidget::deleteHighlight()
645 mHighlight =
nullptr;
650 if ( !mAllowMapIdentification || !mReferencedLayer )
659 mMapTool->
setLayer( mReferencedLayer );
669 connect( mMapTool, SIGNAL( deactivated() ),
this, SLOT( mapToolDeactivated() ) );
674 QString msg =
tr(
"Identify a feature of %1 to be associated. Press <ESC> to cancel." ).
arg( mReferencedLayer->
name() );
676 mMessageBar->
pushItem( mMessageBarItem );
680 void QgsRelationReferenceWidget::comboReferenceChanged(
int index )
684 highlightFeature( mFeature );
685 updateAttributeEditorFrame( mFeature );
689 void QgsRelationReferenceWidget::updateAttributeEditorFrame(
const QgsFeature& feature )
692 if ( mAttributeEditorFrame )
694 if ( mReferencedAttributeForm )
696 mReferencedAttributeForm->
setFeature( feature );
701 void QgsRelationReferenceWidget::featureIdentified(
const QgsFeature& feature )
703 if ( mReadOnlySelector )
710 context.setFeature( feature );
711 QString title = expr.evaluate( &context ).toString();
712 if ( expr.hasEvalError() )
717 mForeignKey = feature.
attribute( mReferencedFieldIdx );
727 highlightFeature( feature );
728 updateAttributeEditorFrame( feature );
734 void QgsRelationReferenceWidget::unsetMapTool()
737 if ( mCanvas && mMapTool )
744 void QgsRelationReferenceWidget::mapToolDeactivated()
748 mWindowWidget->
raise();
752 if ( mMessageBar && mMessageBarItem )
754 mMessageBar->
popWidget( mMessageBarItem );
756 mMessageBarItem =
nullptr;
759 void QgsRelationReferenceWidget::filterChanged()
773 Q_FOREACH (
QComboBox* cb, mFilterComboBoxes )
809 Q_FOREACH (
QComboBox* cb, mFilterComboBoxes )
817 filters <<
QString(
"\"%1\" IS NULL" ).
arg( fieldName );
821 if ( mReferencedLayer->
fields().
field( fieldName ).
type() == QVariant::String )
834 QString filterExpression = filters.
join(
" AND " );
841 while ( it.nextFeature( f ) )
843 featureIds << f.id();
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
QgsFeatureId id() const
Get the feature ID for this feature.
When showing a single feature (e.g. district information when looking at the form of a house) ...
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").
Wrapper for iterator of features from vector data provider or vector layer.
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.
QgsPoint layerToMapCoordinates(QgsMapLayer *theLayer, QgsPoint point) const
transform point coordinates from layer's CRS to output CRS
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
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...
QString name() const
Get the display name of the layer.
bool isValid() const
Returns the validity of this feature.
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...
QgsFields fields() const
Returns the list of fields of this layer.
This class contains context information for attribute editor widgets.
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
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.
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
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.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
A bar for displaying non-blocking messages to the user.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
void refresh()
Repaints the canvas map.
A geometry is the spatial representation of a feature.
QString join(const QString &separator) const
QString name() const
Returns a human readable name for this relation.
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.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
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.
virtual void setFilteredFeatures(const QgsFeatureIds &ids)
Specify a list of features, which the filter will accept.
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...
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...
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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)
void restoreOverrideCursor()
int count() const
Return number of items.
QgsGeometry * centroid() const
Returns the center of mass of a geometry.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
QgsVectorLayerCache * layerCache() const
Returns the layer cache this model uses as backend.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
A class to represent a point.
QVariant itemData(int index, int role) const
bool blockSignals(bool block)
This class caches features of a given QgsVectorLayer.
void setItalic(bool enable)
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
void pushItem(QgsMessageBarItem *item)
Display a message item on the bar after hiding the currently visible one and putting it in a stack...
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
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)
const QgsVectorLayerTools * vectorLayerTools() const
void setCurrentIndex(int index)
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with 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...
void setText(const QString &text)
double toDouble(bool *ok) const
bool setProperty(const char *name, const QVariant &value)
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
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.
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
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)
void zoomByFactor(double scaleFactor, const QgsPoint *center=nullptr)
Zoom with the factor supplied.
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.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
void setSingleShot(bool singleShot)