Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Modularize editor widgets
  • Loading branch information
m-kuhn committed Sep 26, 2013
1 parent 7628c8f commit 770e52b
Show file tree
Hide file tree
Showing 39 changed files with 2,455 additions and 627 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -52,5 +52,6 @@ i18n/*.qm
scripts/qgisstyle
.kdev4/
qgis.kdev4
qgis.supp
src/core/qgscontexthelp_texts.cpp
src/core/qgsexpression_texts.cpp
2 changes: 2 additions & 0 deletions python/CMakeLists.txt
Expand Up @@ -44,6 +44,8 @@ INCLUDE_DIRECTORIES(

../src/gui/raster
../src/gui/attributetable
../src/gui/editorwidgets
../src/gui/editorwidgets/core

${CMAKE_BINARY_DIR} # qgsconfig.h, qgsversion.h
)
Expand Down
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -29,6 +29,7 @@
%Include qgsdistancearea.sip
%Include qgserror.sip
%Include qgsexpression.sip
%Include qgseditorwidgetconfig.sip
%Include qgsfeature.sip
%Include qgsfeatureiterator.sip
%Include qgsfeaturerequest.sip
Expand Down
14 changes: 14 additions & 0 deletions python/core/qgseditorwidgetconfig.sip
@@ -0,0 +1,14 @@
/**
* Holds a set of configuration parameters for a editor widget wrapper.
* It's basically a set of key => value pairs.
*
* If you need more advanced structures than a simple key => value pair,
* you can use a value to hold any structure a QVariant can handle (and that's
* about anything you get through your compiler)
*
* These are the user configurable options in the field properties tab of the
* vector layer properties. They are saved in the project file per layer and field.
* You get these passed, for every new widget wrapper.
*/

typedef QMap<QString, QVariant> QgsEditorWidgetConfig;
31 changes: 31 additions & 0 deletions python/gui/editorwidgets/qgseditorconfigwidget.sip
@@ -0,0 +1,31 @@
/***************************************************************************
qgseditorconfigwidget.sip
--------------------------------------
Date : 24.4.2013
Copyright : (C) 2013 Matthias Kuhn
Email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/

class QgsEditorConfigWidget : QWidget
{
%TypeHeaderCode
#include <qgseditorconfigwidget.h>
%End

public:
explicit QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent /TransferThis/ );
int field();

QgsVectorLayer* layer();

virtual QgsEditorWidgetConfig config() = 0;
virtual void setConfig( const QgsEditorWidgetConfig& config ) = 0;
};

34 changes: 34 additions & 0 deletions python/gui/editorwidgets/qgseditorwidgetfactory.sip
@@ -0,0 +1,34 @@
/***************************************************************************
qgseditorwidgetfactory.sip
--------------------------------------
Date : 21.4.2013
Copyright : (C) 2013 Matthias Kuhn
Email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/

/**
* Every attribute editor widget needs a factory, which inherits this class
*/
class QgsEditorWidgetFactory
{
%TypeHeaderCode
#include <qgseditorwidgetfactory.h>
%End

public:
QgsEditorWidgetFactory( const QString& name );
virtual ~QgsEditorWidgetFactory();
virtual QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const = 0 /Factory/;
virtual QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const = 0 /Factory/;
virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx );
virtual void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx );

virtual QString name();
};
32 changes: 32 additions & 0 deletions python/gui/editorwidgets/qgseditorwidgetregistry.sip
@@ -0,0 +1,32 @@
/***************************************************************************
qgseditorwidgetregistry.sip
--------------------------------------
Date : 21.4.2013
Copyright : (C) 2013 Matthias Kuhn
Email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/

/**
* This class manages all known edit widget factories
*/
class QgsEditorWidgetRegistry : QObject
{
%TypeHeaderCode
#include <qgseditorwidgetregistry.h>
%End

public:
static QgsEditorWidgetRegistry* instance();
void registerWidget( const QString& widgetType, QgsEditorWidgetFactory* widgetFactory /Transfer/ );
QgsEditorWidgetWrapper* create( const QString& widgetType, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* editor = NULL, QWidget* parent = NULL ) /Factory/;
QgsEditorConfigWidget* createConfigWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) /Factory/;

const QMap<QString, QgsEditorWidgetFactory*> factories();
};
42 changes: 42 additions & 0 deletions python/gui/editorwidgets/qgseditorwidgetwrapper.sip
@@ -0,0 +1,42 @@
/***************************************************************************
qgseditorwidgetwrapper.sip
--------------------------------------
Date : 20.4.2013
Copyright : (C) 2013 Matthias Kuhn
Email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/

class QgsEditorWidgetWrapper : QObject
{
%TypeHeaderCode
#include <qgseditorwidgetwrapper.h>
%End

public:
explicit QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor = 0, QWidget* parent /TransferThis/ = 0 );
QWidget* widget();
virtual void setConfig( QMap<QString, QVariant> config );
virtual QVariant value() = 0;
QVariant config( QString key );

QgsVectorLayer* layer();
int field();

protected:
virtual QWidget* createWidget( QWidget* parent ) = 0 /Factory/;

signals:
void valueChanged( const QVariant& value );

public slots:
virtual void setValue( const QVariant& value ) = 0;
virtual void setEnabled( bool enabled );

};
5 changes: 5 additions & 0 deletions python/gui/gui.sip
Expand Up @@ -127,3 +127,8 @@
%Include symbology-ng/qgsdatadefinedsymboldialog.sip
%Include symbology-ng/qgsstylev2exportimportdialog.sip
%Include symbology-ng/qgssvgselectorwidget.sip

%Include editorwidgets/qgseditorconfigwidget.sip
%Include editorwidgets/qgseditorwidgetfactory.sip
%Include editorwidgets/qgseditorwidgetregistry.sip
%Include editorwidgets/qgseditorwidgetwrapper.sip
2 changes: 1 addition & 1 deletion src/app/CMakeLists.txt
Expand Up @@ -422,7 +422,7 @@ INCLUDE_DIRECTORIES(
../core
../core/gps
../core/composer ../core/raster ../core/symbology-ng
../gui ../gui/symbology-ng ../gui/attributetable ../gui/raster
../gui ../gui/symbology-ng ../gui/attributetable ../gui/raster ../gui/editorwidgets ../gui/editorwidgets/core
../plugins
../python
gps
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgisapp.h
Expand Up @@ -57,6 +57,7 @@ class QgsPoint;
class QgsProviderRegistry;
class QgsPythonUtils;
class QgsRectangle;

class QgsUndoWidget;
class QgsVectorLayer;

Expand Down Expand Up @@ -175,6 +176,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
/** Get the mapcanvas object from the app */
QgsMapCanvas *mapCanvas();

/** Return the messageBar object which allows to display unobtrusive messages to the user.*/
QgsMessageBar* messageBar();

/** Get the mapcanvas object from the app */
Expand Down Expand Up @@ -240,7 +242,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
/** overloaded function used to sort menu entries alphabetically */
QMenu* createPopupMenu();


//! Actions to be inserted in menus and toolbars
QAction *actionNewProject() { return mActionNewProject; }
QAction *actionOpenProject() { return mActionOpenProject; }
Expand Down
102 changes: 101 additions & 1 deletion src/app/qgsattributetypedialog.cpp
Expand Up @@ -24,6 +24,8 @@
#include "qgisapp.h"
#include "qgsproject.h"
#include "qgslogger.h"
#include "qgseditorwidgetfactory.h"
#include "qgseditorwidgetregistry.h"

#include <QTableWidgetItem>
#include <QFile>
Expand All @@ -47,6 +49,16 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl )
connect( tableWidget, SIGNAL( cellChanged( int, int ) ), this, SLOT( vCellChanged( int, int ) ) );
connect( valueRelationEditExpression, SIGNAL( clicked() ), this, SLOT( editValueRelationExpression() ) );

QMapIterator<QString, QgsEditorWidgetFactory*> i( QgsEditorWidgetRegistry::instance()->factories() );
while ( i.hasNext() )
{
i.next();
QListWidgetItem* item = new QListWidgetItem( selectionListWidget );
item->setText( i.value()->name() );
item->setData( Qt::UserRole, i.key() );
selectionListWidget->addItem( item );
}

valueRelationLayer->clear();
foreach ( QgsMapLayer *l, QgsMapLayerRegistry::instance()->mapLayers() )
{
Expand All @@ -69,6 +81,53 @@ QgsVectorLayer::EditType QgsAttributeTypeDialog::editType()
return mEditType;
}

const QString QgsAttributeTypeDialog::editorWidgetV2Type()
{
QListWidgetItem* item = selectionListWidget->currentItem();
if ( item )
{
return item->data( Qt::UserRole ).toString();
}
else
{
return QString();
}
}

const QString QgsAttributeTypeDialog::editorWidgetV2Text()
{
QListWidgetItem* item = selectionListWidget->currentItem();
if ( item )
{
return item->text();
}
else
{
return QString();
}
}

const QMap<QString, QVariant> QgsAttributeTypeDialog::editorWidgetV2Config()
{
QListWidgetItem* item = selectionListWidget->currentItem();
if ( item )
{
QString widgetType = item->data( Qt::UserRole ).toString();
QgsEditorConfigWidget* cfgWdg = mEditorConfigWidgets[ widgetType ];
if ( cfgWdg )
{
return cfgWdg->config();
}
}

return QMap<QString, QVariant>();
}

void QgsAttributeTypeDialog::setWidgetV2Config( const QMap<QString, QVariant>& config )
{
mWidgetV2Config = config;
}

QgsVectorLayer::RangeData QgsAttributeTypeDialog::rangeData()
{
return mRangeData;
Expand Down Expand Up @@ -357,6 +416,10 @@ void QgsAttributeTypeDialog::setPageForEditType( QgsVectorLayer::EditType editTy
case QgsVectorLayer::Color:
setPage( 16 );
break;

case QgsVectorLayer::EditorWidgetV2:
setPage( 17 );
break;
}
}

Expand Down Expand Up @@ -544,6 +607,7 @@ void QgsAttributeTypeDialog::setIndex( int index, QgsVectorLayer::EditType editT
case QgsVectorLayer::TextEdit:
case QgsVectorLayer::UuidGenerator:
case QgsVectorLayer::Color:
case QgsVectorLayer::EditorWidgetV2:
break;
}
}
Expand Down Expand Up @@ -612,7 +676,40 @@ void QgsAttributeTypeDialog::setStackPage( int index )
stackedWidget->setCurrentIndex( 15 );
break;
default:
stackedWidget->setCurrentIndex( index );
if ( selectionListWidget->item( index )->data( Qt::UserRole ).isNull() )
{
stackedWidget->setCurrentIndex( index );
}
else
{
QString factoryId = selectionListWidget->item( index )->data( Qt::UserRole ).toString();

// Set to (empty) editor widget page
stackedWidget->setCurrentIndex( 16 );

if ( mEditorConfigWidgets.contains( factoryId ) )
{
mEditorConfigWidgets[factoryId]->show();
}
else
{
QgsEditorConfigWidget* cfgWdg = QgsEditorWidgetRegistry::instance()->createConfigWidget( factoryId, mLayer, mIndex, this );
QgsEditorConfigWidget* oldWdg = pageEditorWidget->findChild<QgsEditorConfigWidget*>();

if ( oldWdg )
{
oldWdg->hide();
}

if ( cfgWdg )
{
cfgWdg->setConfig( mWidgetV2Config );
pageEditorWidget->layout()->addWidget( cfgWdg );

mEditorConfigWidgets.insert( factoryId, cfgWdg );
}
}
}
break;
}

Expand Down Expand Up @@ -740,6 +837,9 @@ void QgsAttributeTypeDialog::accept()
case 16:
mEditType = QgsVectorLayer::Color;
break;
case 17:
mEditType = QgsVectorLayer::EditorWidgetV2;
break;
}

QDialog::accept();
Expand Down

0 comments on commit 770e52b

Please sign in to comment.