Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[processing] port enum parameter definition widget to C++
  • Loading branch information
alexbruy authored and nyalldawson committed Mar 26, 2020
1 parent 8f58372 commit 48af1c0
Show file tree
Hide file tree
Showing 4 changed files with 399 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -266,6 +266,7 @@ SET(QGIS_GUI_SRCS
processing/qgsprocessingalgorithmconfigurationwidget.cpp
processing/qgsprocessingalgorithmdialogbase.cpp
processing/qgsprocessingconfigurationwidgets.cpp
processing/qgsprocessingenummodelerwidget.cpp
processing/qgsprocessingfeaturesourceoptionswidget.cpp
processing/qgsprocessingguiregistry.cpp
processing/qgsprocessingmaplayercombobox.cpp
Expand Down Expand Up @@ -954,6 +955,7 @@ SET(QGIS_GUI_HDRS
processing/qgsprocessingalgorithmconfigurationwidget.h
processing/qgsprocessingalgorithmdialogbase.h
processing/qgsprocessingconfigurationwidgets.h
processing/qgsprocessingenummodelerwidget.h
processing/qgsprocessingfeaturesourceoptionswidget.h
processing/qgsprocessinggui.h
processing/qgsprocessingguiregistry.h
Expand Down
187 changes: 187 additions & 0 deletions src/gui/processing/qgsprocessingenummodelerwidget.cpp
@@ -0,0 +1,187 @@
/***************************************************************************
qgsprocessingenummodelerwidget.cpp
------------------------------------
Date : March 2020
Copyright : (C) 2020 Alexander Bruy
Email : alexander dot bruy at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsprocessingenummodelerwidget.h"
#include "qgsgui.h"
#include <QMessageBox>
#include <QToolButton>

///@cond NOT_STABLE

QgsProcessingEnumModelerWidget::QgsProcessingEnumModelerWidget( QWidget *parent )
: QWidget( parent )
{
setupUi( this );

mModel = new QStandardItemModel( this );
mItemList->setModel( mModel );
connect( mModel, &QStandardItemModel::itemChanged, this, &QgsProcessingEnumModelerWidget::onItemChanged );

connect( mButtonAdd, &QToolButton::clicked, this, &QgsProcessingEnumModelerWidget::addItem );
connect( mButtonRemove, &QToolButton::clicked, this, [ = ] { removeItems( false ); } );
connect( mButtonClear, &QToolButton::clicked, this, [ = ] { removeItems( true ); } );
}

void QgsProcessingEnumModelerWidget::addItem()
{
QStandardItem *item = new QStandardItem( tr( "new item" ) );
item->setCheckable( true );
item->setDropEnabled( false );
item->setData( Qt::Unchecked );
mModel->appendRow( item );
}

void QgsProcessingEnumModelerWidget::removeItems( const bool removeAll )
{
if ( removeAll )
{
if ( QMessageBox::question( nullptr, tr( "Delete items" ),
tr( "Are you sure you want to delete all items" ),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes )
mModel->clear();
}
else
{
QModelIndexList selected = mItemList->selectionModel()->selectedIndexes();
QSet< int > rows;
rows.reserve( selected.count() );
for ( const QModelIndex &i : selected )
rows << i.row();

QList< int > rowsToDelete = rows.toList();
std::sort( rowsToDelete.begin(), rowsToDelete.end(), std::greater<int>() );

mItemList->setUpdatesEnabled( false );
for ( int i : qgis::as_const( rowsToDelete ) )
mModel->removeRows( i, 1 );
mItemList->setUpdatesEnabled( true );
}
}

void QgsProcessingEnumModelerWidget::onItemChanged( QStandardItem *item )
{
int checkedItemIndex = -1;
for ( int i = 0; i < mModel->rowCount(); i++ )
{
QStandardItem *itm = mModel->item( i );
if ( itm->checkState() == Qt::Checked && itm->data() == Qt::Checked )
{
checkedItemIndex = i;
break;
}
}

mModel->blockSignals( true );
if ( checkedItemIndex < 0 )
{
item->setData( item->checkState() );
}
else
{
if ( mAllowMultiple->isChecked() )
{
item->setData( item->checkState() );
}
else
{
mModel->item( checkedItemIndex )->setCheckState( Qt::Unchecked );
mModel->item( checkedItemIndex )->setData( Qt::Unchecked );
item->setData( item->checkState() );
}
}
mModel->blockSignals( false );
}

QStringList QgsProcessingEnumModelerWidget::options() const
{
QStringList options;
options.reserve( mModel->rowCount() );
for ( int i = 0; i < mModel->rowCount(); ++i )
{
options << mModel->item( i )->text();
}
return options;
}

void QgsProcessingEnumModelerWidget::setOptions( const QStringList &options )
{
for ( const QString &option : options )
{
QStandardItem *item = new QStandardItem( option );
item->setCheckable( true );
item->setDropEnabled( false );
item->setData( Qt::Unchecked );
mModel->appendRow( item );
}
}

QVariant QgsProcessingEnumModelerWidget::defaultOptions() const
{
QVariantList defaults;
for ( int i = 0; i < mModel->rowCount(); ++i )
{
if ( mModel->item( i )->checkState() == Qt::Checked )
defaults << i;
}
QVariant val( defaults );
return val;
}

void QgsProcessingEnumModelerWidget::setDefaultOptions( const QVariant &defaultValue )
{
if ( !defaultValue.isValid() )
return;

QVariant val = defaultValue;
QList< int > values;
if ( val.type() == QVariant::List || val.type() == QVariant::StringList )
{
for ( const QVariant &var : val.toList() )
values << var.toInt();
}
else if ( val.type() == QVariant::String )
{
QStringList split = val.toString().split( ',' );
for ( const QString &var : split )
values << var.toInt();
}
else if ( val.type() == QVariant::Int )
{
values << val.toInt();
}

QStandardItem *item;
for ( const int &i : values )
{
item = mModel->item( i );
if ( item )
{
item->setCheckState( Qt::Checked );
item->setData( Qt::Checked );
}
}
}

bool QgsProcessingEnumModelerWidget::allowMultiple() const
{
return mAllowMultiple->isChecked();
}

void QgsProcessingEnumModelerWidget::setAllowMultiple( bool allowMultiple )
{
mAllowMultiple->setChecked( allowMultiple );
}

///@endcond
100 changes: 100 additions & 0 deletions src/gui/processing/qgsprocessingenummodelerwidget.h
@@ -0,0 +1,100 @@
/***************************************************************************
qgsprocessingenummodelerwidget.h
----------------------------------
Date : March 2020
Copyright : (C) 2020 Alexander Bruy
Email : alexander dot bruy at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSPROCESSINGENUMMODELERWIDGET_H
#define QGSPROCESSINGENUMMODELERWIDGET_H

#define SIP_NO_FILE

#include "qgis.h"
#include "qgis_gui.h"
#include "ui_qgsprocessingenummodelerwidgetbase.h"
#include <QStandardItem>
#include <QStandardItemModel>

///@cond PRIVATE

/**
* Processing enum widget for configuring enum parameter in modeler.
* \ingroup gui
* \note Not stable API
* \since QGIS 3.14
*/
class GUI_EXPORT QgsProcessingEnumModelerWidget : public QWidget, private Ui::QgsProcessingEnumModelerWidgetBase
{
Q_OBJECT

public:

/**
* Constructor for QgsProcessingEnumModelerWidget.
*/
QgsProcessingEnumModelerWidget( QWidget *parent = nullptr );

/**
* Returns list of all available options.
*
* \see setOptions()
*/
QStringList options() const;

/**
* Populate widget with available options.
*
* \see options()
*/
void setOptions( const QStringList &options );

/**
* Returns indices of options used by default.
*
* \see setDefaultOptions()
*/
QVariant defaultOptions() const;

/**
* Mark default options as checked.
*
* \see defaultOptions()
*/
void setDefaultOptions( const QVariant &defaultValue );

/**
* Returns TRUE if the parameter allows multiple selected values.
* \see setAllowMultiple()
*/
bool allowMultiple() const;

/**
* Sets whether the parameter allows multiple selected values.
* \see allowMultiple()
*/
void setAllowMultiple( bool allowMultiple );

private slots:

void addItem();
void removeItems( const bool removeAll );
void onItemChanged( QStandardItem *item );

private:
QStandardItemModel *mModel = nullptr;

friend class TestProcessingGui;
};

///@endcond

#endif // QGSPROCESSINGENUMMODELERWIDGET_H

0 comments on commit 48af1c0

Please sign in to comment.