Skip to content

Commit 250fcbc

Browse files
committedFeb 3, 2016
[GRASS] multiple vector field option, fixes #3539
1 parent 0af7006 commit 250fcbc

File tree

2 files changed

+206
-108
lines changed

2 files changed

+206
-108
lines changed
 

‎src/plugins/grass/qgsgrassmoduleparam.cpp

Lines changed: 158 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,82 @@ QList<QDomNode> QgsGrassModuleParam::nodesByType( QDomElement descDomElement, ST
207207
return nodes;
208208
}
209209

210+
/***************** QgsGrassModuleGroupBoxItem *********************/
211+
212+
QgsGrassModuleGroupBoxItem::QgsGrassModuleGroupBoxItem( QgsGrassModule *module, QString key,
213+
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
214+
bool direct, QWidget * parent )
215+
: QGroupBox( parent )
216+
, QgsGrassModuleParam( module, key, qdesc, gdesc, gnode, direct )
217+
{
218+
adjustTitle();
219+
setToolTip( mToolTip );
220+
}
221+
222+
QgsGrassModuleGroupBoxItem::~QgsGrassModuleGroupBoxItem() {}
223+
224+
void QgsGrassModuleGroupBoxItem::resizeEvent( QResizeEvent * event )
225+
{
226+
Q_UNUSED( event );
227+
adjustTitle();
228+
setToolTip( mToolTip );
229+
}
230+
231+
void QgsGrassModuleGroupBoxItem::adjustTitle()
232+
{
233+
QString tit = fontMetrics().elidedText( mTitle, Qt::ElideRight, width() - 20 );
234+
235+
setTitle( tit );
236+
}
237+
238+
/***************** QgsGrassModuleMultiParam *********************/
239+
240+
QgsGrassModuleMultiParam::QgsGrassModuleMultiParam( QgsGrassModule *module, QString key,
241+
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
242+
bool direct, QWidget * parent )
243+
: QgsGrassModuleGroupBoxItem( module, key, qdesc, gdesc, gnode, direct, parent )
244+
, mLayout(0)
245+
, mParamsLayout(0)
246+
, mButtonsLayout(0)
247+
{
248+
adjustTitle();
249+
setToolTip( mToolTip );
250+
251+
// variable number of line edits
252+
// add/delete buttons for multiple options
253+
mLayout = new QHBoxLayout( this );
254+
mParamsLayout = new QVBoxLayout();
255+
256+
mLayout->insertLayout( -1, mParamsLayout );
257+
258+
}
259+
260+
QgsGrassModuleMultiParam::~QgsGrassModuleMultiParam() {}
261+
262+
void QgsGrassModuleMultiParam::showAddRemoveButtons()
263+
{
264+
mButtonsLayout = new QVBoxLayout();
265+
mLayout->insertLayout( -1, mButtonsLayout );
266+
267+
// TODO: how to keep both buttons on the top?
268+
QPushButton *addButton = new QPushButton( "+", this );
269+
connect( addButton, SIGNAL( clicked() ), this, SLOT( addRow() ) );
270+
mButtonsLayout->addWidget( addButton, 0, Qt::AlignTop );
271+
272+
QPushButton *removeButton = new QPushButton( "-", this );
273+
connect( removeButton, SIGNAL( clicked() ), this, SLOT( removeRow() ) );
274+
mButtonsLayout->addWidget( removeButton, 0, Qt::AlignTop );
275+
276+
// Don't enable this, it makes the group box expanding
277+
// mButtonsLayout->addStretch();
278+
}
279+
210280
/********************** QgsGrassModuleOption *************************/
211281

212282
QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
213283
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
214284
bool direct, QWidget * parent )
215-
: QgsGrassModuleGroupBoxItem( module, key, qdesc, gdesc, gnode, direct, parent )
285+
: QgsGrassModuleMultiParam( module, key, qdesc, gdesc, gnode, direct, parent )
216286
, mControlType( NoControl )
217287
, mValueType( String )
218288
, mOutputType( None )
@@ -222,16 +292,15 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
222292
, mComboBox( 0 )
223293
, mIsOutput( false )
224294
, mValidator( 0 )
225-
, mLayout( 0 )
226295
, mUsesRegion( false )
227296
{
228297
QgsDebugMsg( "entered" );
229298
setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
230299

231300
if ( mHidden )
301+
{
232302
hide();
233-
234-
mLayout = new QVBoxLayout();
303+
}
235304

236305
// Is it output?
237306
QDomNode promptNode = gnode.namedItem( "gisprompt" );
@@ -271,9 +340,10 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
271340

272341
if ( !valuesNode.isNull() && valuesNode.childNodes().count() > 1 )
273342
{
274-
setLayout( mLayout );
275343
// predefined values -> ComboBox or CheckBox
276344

345+
// TODO: add add/removeRow support for ComboBox?
346+
277347
// one or many?
278348
if ( gelem.attribute( "multiple" ) == "yes" )
279349
{
@@ -283,7 +353,7 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
283353
{
284354
mControlType = ComboBox;
285355
mComboBox = new QComboBox( this );
286-
mLayout->addWidget( mComboBox );
356+
paramsLayout()->addWidget( mComboBox );
287357
}
288358

289359
// List of values to be excluded
@@ -331,7 +401,7 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
331401
{
332402
QgsGrassModuleCheckBox *cb = new QgsGrassModuleCheckBox( desc, this );
333403
mCheckBoxes.push_back( cb );
334-
mLayout->addWidget( cb );
404+
paramsLayout()->addWidget( cb );
335405
}
336406

337407
mValues.push_back( val );
@@ -417,37 +487,16 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
417487
//QString itemDesc = nodeItem.firstChild().toText().data();
418488
QgsDebugMsg( "keydesc item = " + itemDesc );
419489

420-
addLineEdit();
490+
addRow();
421491
}
422-
423-
setLayout( mLayout );
424-
}
425-
else if ( gelem.attribute( "multiple" ) == "yes" )
426-
{
427-
// variable number of line edits
428-
// add/delete buttons for multiple options
429-
QHBoxLayout *l = new QHBoxLayout( this );
430-
QVBoxLayout *vl = new QVBoxLayout();
431-
l->insertLayout( -1, mLayout );
432-
l->insertLayout( -1, vl );
433-
434-
// TODO: how to keep both buttons on the top?
435-
QPushButton *b = new QPushButton( "+", this );
436-
connect( b, SIGNAL( clicked() ), this, SLOT( addLineEdit() ) );
437-
vl->addWidget( b, 0, Qt::AlignTop );
438-
439-
b = new QPushButton( "-", this );
440-
connect( b, SIGNAL( clicked() ), this, SLOT( removeLineEdit() ) );
441-
vl->addWidget( b, 0, Qt::AlignTop );
442-
443-
// Don't enable this, it makes the group box expanding
444-
// vl->addStretch();
445492
}
446493
else
447494
{
448-
// only one line edit
449-
addLineEdit();
450-
setLayout( mLayout );
495+
addRow();
496+
if ( gelem.attribute( "multiple" ) == "yes" )
497+
{
498+
showAddRemoveButtons();
499+
}
451500
}
452501
}
453502
}
@@ -470,13 +519,13 @@ QgsGrassModuleOption::QgsGrassModuleOption( QgsGrassModule *module, QString key,
470519
QgsDebugMsg( QString( "mUsesRegion = %1" ).arg( mUsesRegion ) );
471520
}
472521

473-
void QgsGrassModuleOption::addLineEdit()
522+
void QgsGrassModuleOption::addRow()
474523
{
475524
QgsDebugMsg( "entered" );
476525

477526
// TODO make the widget growing with new lines. HOW???!!!
478527
QLineEdit *lineEdit = new QLineEdit( this );
479-
mLineEdits.push_back( lineEdit );
528+
mLineEdits << lineEdit;
480529
lineEdit->setText( mAnswer );
481530

482531
if ( mValueType == Integer )
@@ -523,18 +572,30 @@ void QgsGrassModuleOption::addLineEdit()
523572
{
524573
QHBoxLayout *l = new QHBoxLayout();
525574
l->addWidget( lineEdit );
526-
lineEdit->setSizePolicy( QSizePolicy::Expanding, QSizePolicy:: Preferred );
575+
lineEdit->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
527576
QPushButton *button = new QPushButton( tr( "Browse" ) );
528577
l->addWidget( button );
529-
mLayout->addItem( l );
578+
paramsLayout()->addItem( l );
530579
connect( button, SIGNAL( clicked( bool ) ), this, SLOT( browse( bool ) ) );
531580
}
532581
else
533582
{
534-
mLayout->addWidget( lineEdit );
583+
paramsLayout()->addWidget( lineEdit );
535584
}
536585
}
537586

587+
void QgsGrassModuleOption::removeRow()
588+
{
589+
QgsDebugMsg( "entered" );
590+
591+
if ( mLineEdits.size() < 2 )
592+
{
593+
return;
594+
}
595+
delete mLineEdits.at( mLineEdits.size() - 1 );
596+
mLineEdits.removeLast();
597+
}
598+
538599
void QgsGrassModuleOption::browse( bool checked )
539600
{
540601
Q_UNUSED( checked );
@@ -554,16 +615,6 @@ void QgsGrassModuleOption::browse( bool checked )
554615
}
555616
}
556617

557-
void QgsGrassModuleOption::removeLineEdit()
558-
{
559-
QgsDebugMsg( "entered" );
560-
561-
if ( mLineEdits.size() < 2 )
562-
return;
563-
delete mLineEdits.at( mLineEdits.size() - 1 );
564-
mLineEdits.pop_back();
565-
}
566-
567618
QString QgsGrassModuleOption::outputExists()
568619
{
569620
QgsDebugMsg( "entered" );
@@ -761,35 +812,6 @@ QgsGrassModuleFlag::~QgsGrassModuleFlag()
761812
{
762813
}
763814

764-
/***************** QgsGrassModuleGroupBoxItem *********************/
765-
766-
QgsGrassModuleGroupBoxItem::QgsGrassModuleGroupBoxItem( QgsGrassModule *module, QString key,
767-
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
768-
bool direct, QWidget * parent )
769-
: QGroupBox( parent )
770-
, QgsGrassModuleParam( module, key, qdesc, gdesc, gnode, direct )
771-
{
772-
adjustTitle();
773-
774-
setToolTip( mToolTip );
775-
}
776-
777-
QgsGrassModuleGroupBoxItem::~QgsGrassModuleGroupBoxItem() {}
778-
779-
void QgsGrassModuleGroupBoxItem::resizeEvent( QResizeEvent * event )
780-
{
781-
Q_UNUSED( event );
782-
adjustTitle();
783-
setToolTip( mToolTip );
784-
}
785-
786-
void QgsGrassModuleGroupBoxItem::adjustTitle()
787-
{
788-
QString tit = fontMetrics().elidedText( mTitle, Qt::ElideRight, width() - 20 );
789-
790-
setTitle( tit );
791-
}
792-
793815
/***************** QgsGrassModuleGdalInput *********************/
794816

795817
QgsGrassModuleGdalInput::QgsGrassModuleGdalInput(
@@ -1095,7 +1117,7 @@ QgsGrassModuleVectorField::QgsGrassModuleVectorField(
10951117
QgsGrassModule *module, QgsGrassModuleStandardOptions *options,
10961118
QString key, QDomElement &qdesc,
10971119
QDomElement &gdesc, QDomNode &gnode, bool direct, QWidget * parent )
1098-
: QgsGrassModuleGroupBoxItem( module, key, qdesc, gdesc, gnode, direct, parent )
1120+
: QgsGrassModuleMultiParam( module, key, qdesc, gdesc, gnode, direct, parent )
10991121
, mModuleStandardOptions( options ), mLayerInput( 0 )
11001122
{
11011123
if ( mTitle.isEmpty() )
@@ -1105,8 +1127,7 @@ QgsGrassModuleVectorField::QgsGrassModuleVectorField(
11051127
adjustTitle();
11061128

11071129
QDomNode promptNode = gnode.namedItem( "gisprompt" );
1108-
QDomElement promptElem = promptNode.toElement();
1109-
QString element = promptElem.attribute( "element" );
1130+
QDomElement gelem = gnode.toElement();
11101131

11111132
mType = qdesc.attribute( "type" );
11121133

@@ -1126,36 +1147,65 @@ QgsGrassModuleVectorField::QgsGrassModuleVectorField(
11261147
}
11271148
}
11281149

1129-
QHBoxLayout *l = new QHBoxLayout( this );
1130-
mFieldComboBox = new QComboBox();
1131-
l->addWidget( mFieldComboBox );
1150+
addRow();
1151+
if ( gelem.attribute( "multiple" ) == "yes" )
1152+
{
1153+
showAddRemoveButtons();
1154+
}
11321155

11331156
// Fill in layer current fields
11341157
updateFields();
11351158
}
11361159

1137-
void QgsGrassModuleVectorField::updateFields()
1160+
void QgsGrassModuleVectorField::addRow()
11381161
{
11391162
QgsDebugMsg( "entered" );
1163+
QComboBox *comboBox = new QComboBox();
1164+
comboBox->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
1165+
paramsLayout()->addWidget( comboBox );
1166+
mComboBoxList << comboBox;
1167+
updateFields();
1168+
}
11401169

1141-
QString current = mFieldComboBox->currentText();
1142-
mFieldComboBox->clear();
1143-
1144-
//QgsMapCanvas *canvas = mModule->qgisIface()->mapCanvas();
1170+
void QgsGrassModuleVectorField::removeRow()
1171+
{
1172+
QgsDebugMsg( "entered" );
11451173

1146-
if ( mLayerInput == 0 )
1174+
if ( mComboBoxList.size() < 2 )
1175+
{
11471176
return;
1177+
}
1178+
delete mComboBoxList.at( mComboBoxList.size() - 1 );
1179+
mComboBoxList.removeLast();
1180+
}
11481181

1149-
QgsFields fields = mLayerInput->currentFields();
1182+
void QgsGrassModuleVectorField::updateFields()
1183+
{
1184+
QgsDebugMsg( "entered" );
11501185

1151-
for ( int i = 0; i < fields.size(); i++ )
1186+
Q_FOREACH( QComboBox *comboBox, mComboBoxList )
11521187
{
1153-
if ( mType.contains( fields.at( i ).typeName() ) )
1188+
QString current = comboBox->currentText();
1189+
comboBox->clear();
1190+
1191+
if ( mLayerInput == 0 )
1192+
{
1193+
continue;
1194+
}
1195+
QgsFields fields = mLayerInput->currentFields();
1196+
1197+
int index = 0;
1198+
for ( int i = 0; i < fields.size(); i++ )
11541199
{
1155-
mFieldComboBox->addItem( fields.at( i ).name() );
1156-
if ( fields.at( i ).name() == current )
1200+
if ( mType.contains( fields.at( i ).typeName() ) )
11571201
{
1158-
mFieldComboBox->setItemText( mFieldComboBox->currentIndex(), current );
1202+
comboBox->addItem( fields.at( i ).name() );
1203+
QgsDebugMsg( "current = " + current + " field = " + fields.at( i ).name() );
1204+
if ( fields.at( i ).name() == current )
1205+
{
1206+
comboBox->setCurrentIndex( index );
1207+
}
1208+
index++;
11591209
}
11601210
}
11611211
}
@@ -1165,10 +1215,19 @@ QStringList QgsGrassModuleVectorField::options()
11651215
{
11661216
QStringList list;
11671217

1168-
if ( !mFieldComboBox->currentText().isEmpty() )
1218+
QStringList valueList;
1219+
Q_FOREACH( QComboBox *comboBox, mComboBoxList )
11691220
{
1170-
QString opt( mKey + "=" + mFieldComboBox->currentText() );
1171-
list.push_back( opt );
1221+
if ( !comboBox->currentText().isEmpty() )
1222+
{
1223+
valueList << comboBox->currentText();
1224+
}
1225+
}
1226+
1227+
if ( !valueList.isEmpty() )
1228+
{
1229+
QString opt = mKey + "=" + valueList.join(",");
1230+
list << opt;
11721231
}
11731232

11741233
return list;

‎src/plugins/grass/qgsgrassmoduleparam.h

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,51 @@ class QgsGrassModuleGroupBoxItem : public QGroupBox, public QgsGrassModuleParam
189189
public slots:
190190
//! Adjust title size, called on resize
191191
void adjustTitle();
192+
};
193+
194+
/****************** QgsGrassModuleMultiParam ************************/
195+
196+
/** \class QgsGrassModuleMultiParam
197+
* \brief GRASS module multiple params box
198+
*/
199+
class QgsGrassModuleMultiParam : public QgsGrassModuleGroupBoxItem
200+
{
201+
Q_OBJECT
202+
203+
public:
204+
QgsGrassModuleMultiParam( QgsGrassModule *module, QString key,
205+
QDomElement &qdesc, QDomElement &gdesc, QDomNode &gnode,
206+
bool direct, QWidget * parent = 0 );
207+
208+
virtual ~QgsGrassModuleMultiParam();
209+
210+
public slots:
211+
virtual void addRow() {}
192212

213+
virtual void removeRow() {}
214+
215+
protected:
216+
QVBoxLayout *paramsLayout() { return mParamsLayout; }
217+
218+
void showAddRemoveButtons();
219+
220+
private:
221+
// Parameters layout
222+
QHBoxLayout *mLayout;
223+
224+
// Parameters layout
225+
QVBoxLayout *mParamsLayout;
226+
227+
// Parameters layout
228+
QVBoxLayout *mButtonsLayout;
193229
};
194230

195231
/****************** QgsGrassModuleOption ************************/
196232

197233
/** \class QgsGrassModuleOption
198234
* \brief GRASS option
199235
*/
200-
class QgsGrassModuleOption : public QgsGrassModuleGroupBoxItem
236+
class QgsGrassModuleOption : public QgsGrassModuleMultiParam
201237
{
202238
Q_OBJECT
203239

@@ -250,10 +286,10 @@ class QgsGrassModuleOption : public QgsGrassModuleGroupBoxItem
250286

251287
public slots:
252288
// Add new line edit for multiple options
253-
void addLineEdit();
289+
virtual void addRow() override;
254290

255291
// Remove one line edit for multiple options
256-
void removeLineEdit();
292+
virtual void removeRow() override;
257293

258294
// Browse output
259295
void browse( bool checked );
@@ -294,9 +330,6 @@ class QgsGrassModuleOption : public QgsGrassModuleGroupBoxItem
294330
//! Line input validator
295331
QValidator *mValidator;
296332

297-
// Layout inside box
298-
QVBoxLayout *mLayout;
299-
300333
//! Uses region
301334
bool mUsesRegion;
302335
};
@@ -415,7 +448,7 @@ class QgsGrassModuleField : public QgsGrassModuleOption
415448
/** \class QgsGrassModuleVectorField
416449
* \brief GRASS vector attribute column.
417450
*/
418-
class QgsGrassModuleVectorField : public QgsGrassModuleGroupBoxItem
451+
class QgsGrassModuleVectorField : public QgsGrassModuleMultiParam
419452
{
420453
Q_OBJECT
421454

@@ -443,6 +476,12 @@ class QgsGrassModuleVectorField : public QgsGrassModuleGroupBoxItem
443476
//! Fill combobox with currently available maps in QGIS canvas
444477
void updateFields();
445478

479+
// Add new combo for multiple options
480+
virtual void addRow() override;
481+
482+
// Remove one combo for multiple options
483+
virtual void removeRow() override;
484+
446485
private:
447486
// Module options
448487
QgsGrassModuleStandardOptions *mModuleStandardOptions;
@@ -456,8 +495,8 @@ class QgsGrassModuleVectorField : public QgsGrassModuleGroupBoxItem
456495
// ! Field type (integer,double,string,datetime)
457496
QString mType;
458497

459-
//! Combobox for QGIS layer fieldsnviz
460-
QComboBox *mFieldComboBox;
498+
//! List of ComboBoxes for QGIS layer fields
499+
QList<QComboBox*> mComboBoxList;
461500
};
462501

463502
/*********************** QgsGrassModuleSelection **********************/

0 commit comments

Comments
 (0)
Please sign in to comment.