Skip to content

Commit c1ede00

Browse files
committedMar 6, 2017
[Feature] Path prefix for attachment widget can be defined by expression
1 parent ac53a3d commit c1ede00

File tree

6 files changed

+189
-72
lines changed

6 files changed

+189
-72
lines changed
 

‎src/gui/editorwidgets/core/qgseditorwidgetwrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class GUI_EXPORT QgsEditorWidgetWrapper : public QgsWidgetWrapper
191191
*
192192
* @param feature The new feature
193193
*/
194-
void setFeature( const QgsFeature &feature ) override;
194+
virtual void setFeature( const QgsFeature &feature ) override;
195195

196196
/**
197197
* Is called, when the value of the widget needs to be changed. Update the widget representation

‎src/gui/editorwidgets/qgsexternalresourceconfigdlg.cpp

Lines changed: 97 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,30 @@
1717
#include "qgsexternalresourcewidget.h"
1818
#include "qgsproject.h"
1919
#include "qgssettings.h"
20+
#include "qgsexpressionbuilderdialog.h"
21+
#include "qgsapplication.h"
22+
#include "qgsvectorlayer.h"
23+
#include "qgspropertyoverridebutton.h"
2024

2125
#include <QFileDialog>
2226

2327
class QgsExternalResourceWidgetWrapper;
2428

29+
const QgsPropertiesDefinition &QgsExternalResourceConfigDlg::propertyDefinitions()
30+
{
31+
static QgsPropertiesDefinition propertyDefinitions;
32+
33+
if ( propertyDefinitions.isEmpty() )
34+
{
35+
propertyDefinitions = QgsPropertiesDefinition
36+
{
37+
{ RootPath, QgsPropertyDefinition( "propertyRootPath", QgsPropertyDefinition::DataTypeString, QObject::tr( "Root path" ), QString() ) }
38+
};
39+
}
40+
41+
return propertyDefinitions;
42+
}
43+
2544
QgsExternalResourceConfigDlg::QgsExternalResourceConfigDlg( QgsVectorLayer *vl, int fieldIdx, QWidget *parent )
2645
: QgsEditorConfigWidget( vl, fieldIdx, parent )
2746
{
@@ -36,14 +55,17 @@ QgsExternalResourceConfigDlg::QgsExternalResourceConfigDlg( QgsVectorLayer *vl,
3655

3756
mRootPath->setPlaceholderText( QgsSettings().value( QStringLiteral( "/UI/lastExternalResourceWidgetDefaultPath" ), QDir::toNativeSeparators( QDir::cleanPath( defpath ) ) ).toString() );
3857

39-
// Add connection to button for choosing default path
40-
connect( mRootPathButton, SIGNAL( clicked() ), this, SLOT( chooseDefaultPath() ) );
58+
connect( mRootPathButton, &QToolButton::clicked, this, &QgsExternalResourceConfigDlg::chooseDefaultPath );
4159

42-
// Activate Relative Default Path option only if Default Path is set
43-
connect( mRootPath, SIGNAL( textChanged( const QString & ) ), this, SLOT( enableRelativeDefault() ) );
60+
mRootPathPropertyOverrideButton->init( RootPath, mPropertyCollection, propertyDefinitions(), vl );
4461

45-
// Dynamic GroupBox for relative paths option
46-
connect( mRelativeGroupBox, SIGNAL( toggled( bool ) ), this, SLOT( enableRelative( bool ) ) );
62+
mRootPathPropertyOverrideButton->setVectorLayer( vl );
63+
connect( mRootPathPropertyOverrideButton, &QgsPropertyOverrideButton::changed, this, &QgsExternalResourceConfigDlg::rootPathPropertyChanged );
64+
65+
// Activate Relative Default Path option only if Default Path is set
66+
connect( mRootPath, &QLineEdit::textChanged, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
67+
connect( mRootPathExpression, &QLineEdit::textChanged, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
68+
connect( mRelativeGroupBox, &QGroupBox::toggled, this, &QgsExternalResourceConfigDlg::enableRelativeDefault );
4769

4870
// set ids for StorageTypeButtons
4971
mStorageButtonGroup->setId( mStoreFilesButton, QgsFileWidget::GetFile );
@@ -59,15 +81,15 @@ QgsExternalResourceConfigDlg::QgsExternalResourceConfigDlg( QgsVectorLayer *vl,
5981
mDocumentViewerContentComboBox->addItem( tr( "Web view" ), QgsExternalResourceWidget::Web );
6082

6183

62-
connect( mFileWidgetGroupBox, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
63-
connect( mFileWidgetButtonGroupBox, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
84+
connect( mFileWidgetGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
85+
connect( mFileWidgetButtonGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
6486
connect( mFileWidgetFilterLineEdit, SIGNAL( textChanged( QString ) ), this, SIGNAL( changed() ) );
65-
connect( mUseLink, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
66-
connect( mFullUrl, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
67-
connect( mRootPath, SIGNAL( textChanged( QString ) ), this, SIGNAL( changed() ) );
87+
connect( mUseLink, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
88+
connect( mFullUrl, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
89+
connect( mRootPath, &QLineEdit::textChanged, this, &QgsEditorConfigWidget::changed );
6890
connect( mStorageButtonGroup, SIGNAL( buttonClicked( int ) ), this, SIGNAL( changed() ) );
69-
connect( mRelativeGroupBox, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
70-
connect( mDocumentViewerGroupBox, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
91+
connect( mRelativeGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
92+
connect( mDocumentViewerGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
7193
connect( mDocumentViewerContentComboBox, SIGNAL( currentIndexChanged( int ) ), this, SIGNAL( changed() ) );
7294
connect( mDocumentViewerHeight, SIGNAL( valueChanged( int ) ), this, SIGNAL( changed() ) );
7395
connect( mDocumentViewerWidth, SIGNAL( valueChanged( int ) ), this, SIGNAL( changed() ) );
@@ -87,40 +109,44 @@ void QgsExternalResourceConfigDlg::chooseDefaultPath()
87109

88110
QString rootName = QFileDialog::getExistingDirectory( this, tr( "Select a directory" ), dir, QFileDialog::ShowDirsOnly );
89111

90-
if ( rootName.isNull() )
91-
return;
92-
93-
mRootPath->setText( rootName );
112+
if ( !rootName.isNull() )
113+
mRootPath->setText( rootName );
94114
}
95115

96-
void QgsExternalResourceConfigDlg::enableRelativeDefault()
116+
void QgsExternalResourceConfigDlg::rootPathPropertyChanged()
97117
{
98-
// Activate (or not) the RelativeDefault button if default path
99-
if ( mRelativeGroupBox->isChecked() )
100-
mRelativeDefault->setEnabled( !mRootPath->text().isEmpty() );
118+
QgsProperty prop = mRootPathPropertyOverrideButton->toProperty();
101119

102-
// If no default path, RelativeProj button enabled by default
103-
if ( mRootPath->text().isEmpty() )
104-
mRelativeProject->toggle();
120+
setRootPathExpression( prop.expressionString() );
121+
122+
mRootPathExpression->setVisible( prop.isActive() );
123+
mRootPath->setVisible( !prop.isActive() );
124+
mRootPathButton->setEnabled( !prop.isActive() );
105125
}
106126

107-
void QgsExternalResourceConfigDlg::enableRelative( bool state )
127+
void QgsExternalResourceConfigDlg::enableRelativeDefault()
108128
{
109-
if ( state )
129+
bool relativePathActive = false;
130+
131+
if ( mRootPathPropertyOverrideButton->isActive() )
110132
{
111-
mRelativeProject->setEnabled( true );
112-
if ( mRootPath->text().isEmpty() )
113-
mRelativeDefault->setEnabled( false );
114-
else
115-
mRelativeDefault->setEnabled( true );
133+
if ( !mRootPathExpression->text().isEmpty() )
134+
relativePathActive = true;
116135
}
117136
else
118137
{
119-
mRelativeProject->setEnabled( false );
120-
mRelativeDefault->setEnabled( false );
138+
if ( !mRootPath->text().isEmpty() )
139+
relativePathActive = true;
121140
}
122-
}
123141

142+
// Activate (or not) the RelativeDefault button if default path
143+
if ( mRelativeGroupBox->isChecked() )
144+
mRelativeDefault->setEnabled( relativePathActive );
145+
146+
// If no default path, RelativeProj button enabled by default
147+
if ( !relativePathActive )
148+
mRelativeProject->toggle();
149+
}
124150

125151
QVariantMap QgsExternalResourceConfigDlg::config()
126152
{
@@ -137,10 +163,17 @@ QVariantMap QgsExternalResourceConfigDlg::config()
137163
cfg.insert( QStringLiteral( "FullUrl" ), mFullUrl->isChecked() );
138164
}
139165

166+
if ( mRootPathPropertyOverrideButton->isActive() )
167+
cfg.insert( QStringLiteral( "DefaultRootStyle" ), QStringLiteral( "expression" ) );
168+
else
169+
cfg.insert( QStringLiteral( "DefaultRootStyle" ), QStringLiteral( "path" ) );
170+
171+
140172
if ( !mRootPath->text().isEmpty() )
141-
{
142173
cfg.insert( QStringLiteral( "DefaultRoot" ), mRootPath->text() );
143-
}
174+
175+
if ( !mRootPathExpression->text().isEmpty() )
176+
cfg.insert( QStringLiteral( "DefaultRootExpression" ), mRootPathExpression->toolTip() );
144177

145178
// Save Storage Mode
146179
cfg.insert( QStringLiteral( "StorageMode" ), mStorageButtonGroup->checkedId() );
@@ -192,10 +225,18 @@ void QgsExternalResourceConfigDlg::setConfig( const QVariantMap &config )
192225
mFullUrl->setChecked( true );
193226
}
194227

195-
if ( config.contains( QStringLiteral( "DefaultRoot" ) ) )
196-
{
197-
mRootPath->setText( config.value( QStringLiteral( "DefaultRoot" ) ).toString() );
198-
}
228+
mRootPath->setText( config.value( QStringLiteral( "DefaultRoot" ) ).toString() );
229+
setRootPathExpression( config.value( QStringLiteral( "DefaultRootExpression" ) ).toString() );
230+
231+
bool rootPathIsExpression = config.value( QStringLiteral( "DefaultRootStyle" ) ) == QStringLiteral( "expression" );
232+
233+
QgsProperty prop = mRootPathPropertyOverrideButton->toProperty();
234+
prop.setActive( rootPathIsExpression );
235+
mRootPathPropertyOverrideButton->setToProperty( prop );
236+
rootPathPropertyChanged();
237+
238+
mRootPathExpression->setVisible( rootPathIsExpression );
239+
mRootPath->setVisible( !rootPathIsExpression );
199240

200241
// relative storage
201242
if ( config.contains( QStringLiteral( "RelativeStorage" ) ) )
@@ -239,3 +280,19 @@ void QgsExternalResourceConfigDlg::setConfig( const QVariantMap &config )
239280
}
240281
}
241282
}
283+
284+
void QgsExternalResourceConfigDlg::setRootPathExpression( const QString &expression )
285+
{
286+
mRootPathExpression->setToolTip( expression );
287+
mRootPathPropertyOverrideButton->setText( expression );
288+
289+
QgsProperty prop = mRootPathPropertyOverrideButton->toProperty();
290+
prop.setExpressionString( expression );
291+
mRootPathPropertyOverrideButton->setToProperty( prop );
292+
293+
QgsExpression exp( expression );
294+
QgsExpressionContext ctx = layer()->createExpressionContext();
295+
296+
mRootPathExpression->setText( exp.evaluate( &ctx ).toString() );
297+
enableRelativeDefault();
298+
}

‎src/gui/editorwidgets/qgsexternalresourceconfigdlg.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,22 @@ class GUI_EXPORT QgsExternalResourceConfigDlg : public QgsEditorConfigWidget, pr
4242
//! Choose a base directory for rootPath
4343
void chooseDefaultPath();
4444

45+
void rootPathPropertyChanged();
46+
4547
//! Modify RelativeDefault according to mRootPath content
4648
void enableRelativeDefault();
4749

48-
//! Dynamic activation of RelativeGroupBox
49-
void enableRelative( bool state );
50+
private:
51+
enum Properties
52+
{
53+
RootPath
54+
};
55+
56+
void setRootPathExpression( const QString &expression );
57+
58+
const QgsPropertiesDefinition &propertyDefinitions();
59+
60+
QgsPropertyCollection mPropertyCollection;
5061
};
5162

5263
#endif // QGSEXTERNALRESOURCECONFIGDLG_H

‎src/gui/editorwidgets/qgsexternalresourcewidgetwrapper.cpp

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <QSettings>
2020
#include <QLabel>
2121

22-
22+
#include "qgsproject.h"
2323
#include "qgsexternalresourcewidget.h"
2424
#include "qgsfilterlineedit.h"
2525

@@ -77,6 +77,21 @@ bool QgsExternalResourceWidgetWrapper::valid() const
7777
return mLineEdit || mLabel || mQgsWidget;
7878
}
7979

80+
void QgsExternalResourceWidgetWrapper::setFeature( const QgsFeature &feature )
81+
{
82+
if ( mQgsWidget && mDefaultRootExpression.isValid() )
83+
{
84+
QgsExpressionContext expressionContext = QgsExpressionContextUtils::createFeatureBasedContext( feature, layer()->fields() );
85+
86+
QVariant value = mDefaultRootExpression.evaluate( &expressionContext );
87+
qWarning() << "Default root << " << value.toString();
88+
89+
mQgsWidget->setDefaultRoot( value.toString() );
90+
}
91+
92+
QgsEditorWidgetWrapper::setFeature( feature );
93+
}
94+
8095
QWidget *QgsExternalResourceWidgetWrapper::createWidget( QWidget *parent )
8196
{
8297
return new QgsExternalResourceWidget( parent );
@@ -102,41 +117,50 @@ void QgsExternalResourceWidgetWrapper::initWidget( QWidget *editor )
102117
if ( mQgsWidget )
103118
{
104119
mQgsWidget->fileWidget()->setStorageMode( QgsFileWidget::GetFile );
105-
if ( config().contains( QStringLiteral( "UseLink" ) ) )
120+
121+
QVariantMap cfg = config();
122+
123+
if ( cfg.contains( QStringLiteral( "UseLink" ) ) )
106124
{
107-
mQgsWidget->fileWidget()->setUseLink( config( QStringLiteral( "UseLink" ) ).toBool() );
125+
mQgsWidget->fileWidget()->setUseLink( cfg.value( QStringLiteral( "UseLink" ) ).toBool() );
108126
}
109-
if ( config().contains( QStringLiteral( "FullUrl" ) ) )
127+
if ( cfg.contains( QStringLiteral( "FullUrl" ) ) )
110128
{
111-
mQgsWidget->fileWidget()->setFullUrl( config( QStringLiteral( "FullUrl" ) ).toBool() );
129+
mQgsWidget->fileWidget()->setFullUrl( cfg.value( QStringLiteral( "FullUrl" ) ).toBool() );
112130
}
113-
if ( config().contains( QStringLiteral( "DefaultRoot" ) ) )
131+
132+
qWarning() << "Default root style " << cfg.value( QStringLiteral( "DefaultRootStyle" ) );
133+
if ( cfg.value( QStringLiteral( "DefaultRootStyle" ) ).toString() == QStringLiteral( "expression" ) )
134+
{
135+
mDefaultRootExpression = QgsExpression( cfg.value( QStringLiteral( "DefaultRootExpression" ) ).toString() );
136+
}
137+
else
114138
{
115-
mQgsWidget->setDefaultRoot( config( QStringLiteral( "DefaultRoot" ) ).toString() );
139+
mQgsWidget->setDefaultRoot( cfg.value( QStringLiteral( "DefaultRoot" ) ).toString() );
116140
}
117-
if ( config().contains( QStringLiteral( "StorageMode" ) ) )
141+
if ( cfg.contains( QStringLiteral( "StorageMode" ) ) )
118142
{
119-
mQgsWidget->fileWidget()->setStorageMode( ( QgsFileWidget::StorageMode )config( QStringLiteral( "StorageMode" ) ).toInt() );
143+
mQgsWidget->fileWidget()->setStorageMode( ( QgsFileWidget::StorageMode )cfg.value( QStringLiteral( "StorageMode" ) ).toInt() );
120144
}
121-
if ( config().contains( QStringLiteral( "RelativeStorage" ) ) )
145+
if ( cfg.contains( QStringLiteral( "RelativeStorage" ) ) )
122146
{
123-
mQgsWidget->setRelativeStorage( ( QgsFileWidget::RelativeStorage )config( QStringLiteral( "RelativeStorage" ) ).toInt() );
147+
mQgsWidget->setRelativeStorage( ( QgsFileWidget::RelativeStorage )cfg.value( QStringLiteral( "RelativeStorage" ) ).toInt() );
124148
}
125-
if ( config().contains( QStringLiteral( "FileWidget" ) ) )
149+
if ( cfg.contains( QStringLiteral( "FileWidget" ) ) )
126150
{
127-
mQgsWidget->setFileWidgetVisible( config( QStringLiteral( "FileWidget" ) ).toBool() );
151+
mQgsWidget->setFileWidgetVisible( cfg.value( QStringLiteral( "FileWidget" ) ).toBool() );
128152
}
129-
if ( config().contains( QStringLiteral( "FileWidgetButton" ) ) )
153+
if ( cfg.contains( QStringLiteral( "FileWidgetButton" ) ) )
130154
{
131-
mQgsWidget->fileWidget()->setFileWidgetButtonVisible( config( QStringLiteral( "FileWidgetButton" ) ).toBool() );
155+
mQgsWidget->fileWidget()->setFileWidgetButtonVisible( cfg.value( QStringLiteral( "FileWidgetButton" ) ).toBool() );
132156
}
133-
if ( config().contains( QStringLiteral( "DocumentViewer" ) ) )
157+
if ( cfg.contains( QStringLiteral( "DocumentViewer" ) ) )
134158
{
135-
mQgsWidget->setDocumentViewerContent( ( QgsExternalResourceWidget::DocumentViewerContent )config( QStringLiteral( "DocumentViewer" ) ).toInt() );
159+
mQgsWidget->setDocumentViewerContent( ( QgsExternalResourceWidget::DocumentViewerContent )cfg.value( QStringLiteral( "DocumentViewer" ) ).toInt() );
136160
}
137-
if ( config().contains( QStringLiteral( "FileWidgetFilter" ) ) )
161+
if ( cfg.contains( QStringLiteral( "FileWidgetFilter" ) ) )
138162
{
139-
mQgsWidget->fileWidget()->setFilter( config( QStringLiteral( "FileWidgetFilter" ) ).toString() );
163+
mQgsWidget->fileWidget()->setFilter( cfg.value( QStringLiteral( "FileWidgetFilter" ) ).toString() );
140164
}
141165
}
142166

‎src/gui/editorwidgets/qgsexternalresourcewidgetwrapper.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class GUI_EXPORT QgsExternalResourceWidgetWrapper : public QgsEditorWidgetWrappe
5151
bool valid() const override;
5252

5353
public slots:
54+
void setFeature( const QgsFeature &feature ) override;
5455
void setValue( const QVariant &value ) override;
5556
void setEnabled( bool enabled ) override;
5657

@@ -61,7 +62,7 @@ class GUI_EXPORT QgsExternalResourceWidgetWrapper : public QgsEditorWidgetWrappe
6162
QLabel *mLabel = nullptr;
6263
QgsExternalResourceWidget *mQgsWidget = nullptr;
6364

64-
65+
QgsExpression mDefaultRootExpression;
6566
};
6667

6768
#endif // QGSEXTERNALRESOURCEWIDGETWRAPPER_H

‎src/ui/editorwidgets/qgsexternalresourceconfigdlg.ui

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<x>0</x>
99
<y>0</y>
1010
<width>481</width>
11-
<height>371</height>
11+
<height>690</height>
1212
</rect>
1313
</property>
1414
<property name="windowTitle">
@@ -46,8 +46,8 @@
4646
<rect>
4747
<x>0</x>
4848
<y>0</y>
49-
<width>465</width>
50-
<height>621</height>
49+
<width>467</width>
50+
<height>715</height>
5151
</rect>
5252
</property>
5353
<layout class="QVBoxLayout" name="verticalLayout_4">
@@ -66,16 +66,16 @@
6666
<enum>QLayout::SetMinimumSize</enum>
6767
</property>
6868
<property name="leftMargin">
69-
<number>9</number>
69+
<number>0</number>
7070
</property>
7171
<property name="topMargin">
72-
<number>6</number>
72+
<number>0</number>
7373
</property>
7474
<property name="rightMargin">
75-
<number>9</number>
75+
<number>0</number>
7676
</property>
7777
<property name="bottomMargin">
78-
<number>6</number>
78+
<number>0</number>
7979
</property>
8080
<item>
8181
<widget class="QLabel" name="label">
@@ -101,7 +101,27 @@
101101
</widget>
102102
</item>
103103
<item>
104-
<widget class="QPushButton" name="mRootPathButton">
104+
<widget class="QLineEdit" name="mRootPathExpression">
105+
<property name="enabled">
106+
<bool>false</bool>
107+
</property>
108+
</widget>
109+
</item>
110+
<item>
111+
<widget class="QToolButton" name="mRootPathButton">
112+
<property name="sizePolicy">
113+
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
114+
<horstretch>0</horstretch>
115+
<verstretch>0</verstretch>
116+
</sizepolicy>
117+
</property>
118+
<property name="text">
119+
<string>...</string>
120+
</property>
121+
</widget>
122+
</item>
123+
<item>
124+
<widget class="QgsPropertyOverrideButton" name="mRootPathPropertyOverrideButton">
105125
<property name="text">
106126
<string>...</string>
107127
</property>
@@ -394,6 +414,11 @@
394414
</layout>
395415
</widget>
396416
<customwidgets>
417+
<customwidget>
418+
<class>QgsPropertyOverrideButton</class>
419+
<extends>QToolButton</extends>
420+
<header>qgspropertyoverridebutton.h</header>
421+
</customwidget>
397422
<customwidget>
398423
<class>QgsSpinBox</class>
399424
<extends>QSpinBox</extends>
@@ -403,7 +428,6 @@
403428
<tabstops>
404429
<tabstop>scrollArea</tabstop>
405430
<tabstop>mRootPath</tabstop>
406-
<tabstop>mRootPathButton</tabstop>
407431
<tabstop>mRelativeGroupBox</tabstop>
408432
<tabstop>mRelativeProject</tabstop>
409433
<tabstop>mRelativeDefault</tabstop>

0 commit comments

Comments
 (0)
Please sign in to comment.