mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
Modularize editor widgets
This commit is contained in:
parent
7628c8f34f
commit
770e52b0e5
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,5 +52,6 @@ i18n/*.qm
|
||||
scripts/qgisstyle
|
||||
.kdev4/
|
||||
qgis.kdev4
|
||||
qgis.supp
|
||||
src/core/qgscontexthelp_texts.cpp
|
||||
src/core/qgsexpression_texts.cpp
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
@ -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
|
||||
|
||||
14
python/core/qgseditorwidgetconfig.sip
Normal file
14
python/core/qgseditorwidgetconfig.sip
Normal file
@ -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
python/gui/editorwidgets/qgseditorconfigwidget.sip
Normal file
31
python/gui/editorwidgets/qgseditorconfigwidget.sip
Normal file
@ -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
python/gui/editorwidgets/qgseditorwidgetfactory.sip
Normal file
34
python/gui/editorwidgets/qgseditorwidgetfactory.sip
Normal file
@ -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
python/gui/editorwidgets/qgseditorwidgetregistry.sip
Normal file
32
python/gui/editorwidgets/qgseditorwidgetregistry.sip
Normal file
@ -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
python/gui/editorwidgets/qgseditorwidgetwrapper.sip
Normal file
42
python/gui/editorwidgets/qgseditorwidgetwrapper.sip
Normal file
@ -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 );
|
||||
|
||||
};
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -57,6 +57,7 @@ class QgsPoint;
|
||||
class QgsProviderRegistry;
|
||||
class QgsPythonUtils;
|
||||
class QgsRectangle;
|
||||
|
||||
class QgsUndoWidget;
|
||||
class QgsVectorLayer;
|
||||
|
||||
@ -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 */
|
||||
@ -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; }
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "qgisapp.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
#include "qgseditorwidgetregistry.h"
|
||||
|
||||
#include <QTableWidgetItem>
|
||||
#include <QFile>
|
||||
@ -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() )
|
||||
{
|
||||
@ -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;
|
||||
@ -357,6 +416,10 @@ void QgsAttributeTypeDialog::setPageForEditType( QgsVectorLayer::EditType editTy
|
||||
case QgsVectorLayer::Color:
|
||||
setPage( 16 );
|
||||
break;
|
||||
|
||||
case QgsVectorLayer::EditorWidgetV2:
|
||||
setPage( 17 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -740,6 +837,9 @@ void QgsAttributeTypeDialog::accept()
|
||||
case 16:
|
||||
mEditType = QgsVectorLayer::Color;
|
||||
break;
|
||||
case 17:
|
||||
mEditType = QgsVectorLayer::EditorWidgetV2;
|
||||
break;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "ui_qgsattributetypeedit.h"
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgseditorconfigwidget.h"
|
||||
|
||||
class QDialog;
|
||||
class QLayout;
|
||||
@ -58,6 +59,14 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
|
||||
*/
|
||||
QgsVectorLayer::EditType editType();
|
||||
|
||||
const QString editorWidgetV2Type();
|
||||
|
||||
const QString editorWidgetV2Text();
|
||||
|
||||
const QMap<QString, QVariant> editorWidgetV2Config();
|
||||
|
||||
void setWidgetV2Config( const QMap<QString, QVariant>& config );
|
||||
|
||||
/**
|
||||
* Setter to value map variable to display actual value
|
||||
* @param valueMap map which is to be dispayed in this dialog
|
||||
@ -224,6 +233,10 @@ class APP_EXPORT QgsAttributeTypeDialog: public QDialog, private Ui::QgsAttribut
|
||||
QgsVectorLayer::EditType mEditType;
|
||||
QString mDateFormat;
|
||||
QSize mWidgetSize;
|
||||
|
||||
QMap<QString, QVariant> mWidgetV2Config;
|
||||
|
||||
QMap< QString, QgsEditorConfigWidget* > mEditorConfigWidgets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -13,16 +13,19 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsfieldsproperties.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
#include "qgseditorwidgetregistry.h"
|
||||
#include "qgsaddattrdialog.h"
|
||||
#include "qgsaddtaborgroup.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsattributetypedialog.h"
|
||||
#include "qgsfieldcalculator.h"
|
||||
#include "qgsfieldsproperties.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsattributetypedialog.h"
|
||||
#include "qgsaddattrdialog.h"
|
||||
#include "qgsfieldcalculator.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsaddtaborgroup.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QWidget>
|
||||
@ -34,129 +37,6 @@
|
||||
#include <QSettings>
|
||||
#include <QFileDialog>
|
||||
|
||||
QTreeWidgetItem* QgsAttributesTree::addContainer( QTreeWidgetItem* parent, QString title )
|
||||
{
|
||||
QTreeWidgetItem *newItem = new QTreeWidgetItem( QList<QString>() << title );
|
||||
newItem->setBackground( 0 , QBrush( Qt::lightGray ) );
|
||||
newItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
|
||||
newItem->setData( 0 , Qt::UserRole , "container" );
|
||||
parent->addChild( newItem );
|
||||
newItem->setExpanded( true );
|
||||
return newItem;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* QgsAttributesTree::addItem( QTreeWidgetItem* parent , QString fieldName )
|
||||
{
|
||||
QTreeWidgetItem* attributeItem = new QTreeWidgetItem( QList<QString>() << fieldName );
|
||||
attributeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
|
||||
attributeItem->setData( 0 , Qt::UserRole , "field" );
|
||||
parent->addChild( attributeItem );
|
||||
|
||||
return attributeItem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is called when mouse is moved over attributes tree before a
|
||||
* drop event. Used to inhibit dropping fields onto the root item.
|
||||
*/
|
||||
|
||||
void QgsAttributesTree::dragMoveEvent( QDragMoveEvent *event )
|
||||
{
|
||||
QTreeWidgetItem* targetItem = itemAt( event->pos() );
|
||||
const QMimeData* data = event->mimeData();
|
||||
|
||||
if ( data->hasFormat( "application/x-qabstractitemmodeldatalist" ) )
|
||||
{
|
||||
QString itemType;
|
||||
if ( event->source() == this )
|
||||
{
|
||||
QByteArray itemData = data->data( "application/x-qabstractitemmodeldatalist" );
|
||||
QDataStream stream( &itemData, QIODevice::ReadOnly );
|
||||
int r, c;
|
||||
QMap<int, QVariant> roleDataMap;
|
||||
stream >> r >> c >> roleDataMap;
|
||||
|
||||
itemType = roleDataMap.value( Qt::UserRole ).toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
itemType = "field";
|
||||
}
|
||||
|
||||
// Forbid dropping fields on root item
|
||||
if ( itemType == "field" && !targetItem )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
// Inner drag and drop actions are always MoveAction
|
||||
if ( event->source() == this )
|
||||
{
|
||||
event->setDropAction( Qt::MoveAction );
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidget::dragMoveEvent( event );
|
||||
}
|
||||
|
||||
|
||||
bool QgsAttributesTree::dropMimeData( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action )
|
||||
{
|
||||
Q_UNUSED( index )
|
||||
bool bDropSuccessful = false;
|
||||
|
||||
if ( action == Qt::IgnoreAction )
|
||||
{
|
||||
bDropSuccessful = true;
|
||||
}
|
||||
else if ( data->hasFormat( "application/x-qabstractitemmodeldatalist" ) )
|
||||
{
|
||||
QByteArray itemData = data->data( "application/x-qabstractitemmodeldatalist" );
|
||||
QDataStream stream( &itemData, QIODevice::ReadOnly );
|
||||
int row, col;
|
||||
|
||||
while ( !stream.atEnd() )
|
||||
{
|
||||
QMap<int, QVariant> roleDataMap;
|
||||
stream >> row >> col >> roleDataMap;
|
||||
|
||||
if ( col == 1 )
|
||||
{
|
||||
/* do something with the data */
|
||||
|
||||
QString itemName = roleDataMap.value( Qt::DisplayRole ).toString();
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
addItem( parent, itemName );
|
||||
bDropSuccessful = true;
|
||||
}
|
||||
else // Should never happen as we ignore drops of fields onto the root element in dragMoveEvent, but actually does happen. Qt?
|
||||
{
|
||||
// addItem( invisibleRootItem(), itemName );
|
||||
// bDropSuccessful = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bDropSuccessful;
|
||||
}
|
||||
|
||||
void QgsAttributesTree::dropEvent( QDropEvent *event )
|
||||
{
|
||||
if ( !event->mimeData()->hasFormat( "application/x-qabstractitemmodeldatalist" ) )
|
||||
return;
|
||||
|
||||
if ( event->source() == this )
|
||||
{
|
||||
event->setDropAction( Qt::MoveAction );
|
||||
}
|
||||
|
||||
QTreeWidget::dropEvent( event );
|
||||
}
|
||||
|
||||
QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent )
|
||||
: QWidget( parent ), mLayer( layer )
|
||||
{
|
||||
@ -185,23 +65,36 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
|
||||
// tab and group display
|
||||
mAddItemButton->setEnabled( false );
|
||||
|
||||
QVBoxLayout *attrTreeLayout = new QVBoxLayout( mAttributesTreeFrame );
|
||||
QVBoxLayout *attrListLayout = new QVBoxLayout( mAttributesListFrame );
|
||||
mDesignerTree = new DesignerTree( mAttributesTreeFrame );
|
||||
mDesignerListLayout->addWidget( mDesignerTree );
|
||||
mDesignerTree->setHeaderLabels( QStringList() << tr( "Label" ) );
|
||||
|
||||
attrTreeLayout->setMargin( 0 );
|
||||
attrListLayout->setMargin( 0 );
|
||||
mAttributesTree = new QgsAttributesTree( mAttributesTreeFrame );
|
||||
mAttributesList = new QTableWidget( mAttributesListFrame );
|
||||
attrTreeLayout->addWidget( mAttributesTree );
|
||||
attrListLayout->addWidget( mAttributesList );
|
||||
mAttributesTreeFrame->setLayout( attrTreeLayout );
|
||||
mAttributesListFrame->setLayout( attrListLayout );
|
||||
mFieldsList = new DragList( mAttributesListFrame );
|
||||
mAttributesListLayout->addWidget( mFieldsList );
|
||||
|
||||
connect( mAttributesTree, SIGNAL( itemSelectionChanged() ), this, SLOT( onAttributeSelectionChanged() ) );
|
||||
connect( mAttributesList, SIGNAL( itemSelectionChanged() ), this, SLOT( onAttributeSelectionChanged() ) );
|
||||
mFieldsList->setColumnCount( attrColCount );
|
||||
mFieldsList->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mFieldsList->setDragDropMode( QAbstractItemView::DragOnly );
|
||||
mFieldsList->setHorizontalHeaderItem( attrIdCol, new QTableWidgetItem( tr( "Id" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrNameCol, new QTableWidgetItem( tr( "Name" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrTypeCol, new QTableWidgetItem( tr( "Type" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrTypeNameCol, new QTableWidgetItem( tr( "Type name" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrLengthCol, new QTableWidgetItem( tr( "Length" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrEditTypeCol, new QTableWidgetItem( tr( "Edit widget" ) ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrWMSCol, new QTableWidgetItem( "WMS" ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrWFSCol, new QTableWidgetItem( "WFS" ) );
|
||||
mFieldsList->setHorizontalHeaderItem( attrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) );
|
||||
|
||||
mAttributesList->sortByColumn( 0, Qt::AscendingOrder );
|
||||
mAttributesTree->setHeaderLabels( QStringList() << tr( "Label" ) );
|
||||
mFieldsList->setSortingEnabled( true );
|
||||
mFieldsList->sortByColumn( 0, Qt::AscendingOrder );
|
||||
mFieldsList->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mFieldsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
mFieldsList->verticalHeader()->hide();
|
||||
|
||||
connect( mDesignerTree, SIGNAL( itemSelectionChanged() ), this, SLOT( onAttributeSelectionChanged() ) );
|
||||
connect( mFieldsList, SIGNAL( itemSelectionChanged() ), this, SLOT( onAttributeSelectionChanged() ) );
|
||||
|
||||
leEditForm->setText( layer->editForm() );
|
||||
leEditFormInit->setText( layer->editFormInit() );
|
||||
@ -227,8 +120,8 @@ void QgsFieldsProperties::init()
|
||||
void QgsFieldsProperties::onAttributeSelectionChanged()
|
||||
{
|
||||
bool isAddPossible = false;
|
||||
if ( mAttributesTree->selectedItems().count() == 1 && mAttributesList->selectedItems().count() > 0 )
|
||||
if ( mAttributesTree->selectedItems()[0]->data( 0, Qt::UserRole ) != "field" )
|
||||
if ( mDesignerTree->selectedItems().count() == 1 && mFieldsList->selectedItems().count() > 0 )
|
||||
if ( mDesignerTree->selectedItems()[0]->data( 0, DesignerTreeRole ).value<DesignerTreeItemData>().type() == DesignerTreeItemData::Container )
|
||||
isAddPossible = true;
|
||||
mAddItemButton->setEnabled( isAddPossible );
|
||||
}
|
||||
@ -239,18 +132,18 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
|
||||
switch ( widgetDef->type() )
|
||||
{
|
||||
case QgsAttributeEditorElement::AeTypeField:
|
||||
newWidget = mAttributesTree->addItem( parent, widgetDef->name() );
|
||||
newWidget = mDesignerTree->addItem( parent, DesignerTreeItemData( DesignerTreeItemData::Field, widgetDef->name() ) );
|
||||
break;
|
||||
|
||||
case QgsAttributeEditorElement::AeTypeContainer:
|
||||
{
|
||||
newWidget = mAttributesTree->addContainer( parent, widgetDef->name() );
|
||||
newWidget = mDesignerTree->addItem( parent, DesignerTreeItemData( DesignerTreeItemData::Container, widgetDef->name() ) );
|
||||
|
||||
const QgsAttributeEditorContainer* container = dynamic_cast<const QgsAttributeEditorContainer*>( widgetDef );
|
||||
QList<QgsAttributeEditorElement*> children = container->children();
|
||||
for ( QList<QgsAttributeEditorElement*>::const_iterator it = children.begin(); it != children.end(); ++it )
|
||||
|
||||
Q_FOREACH( QgsAttributeEditorElement* wdg, container->children() )
|
||||
{
|
||||
loadAttributeEditorTreeItem( *it, newWidget );
|
||||
loadAttributeEditorTreeItem( wdg, newWidget );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -265,110 +158,99 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
|
||||
void QgsFieldsProperties::loadAttributeEditorTree()
|
||||
{
|
||||
// tabs and groups info
|
||||
mAttributesTree->clear();
|
||||
mAttributesTree->setSortingEnabled( false );
|
||||
mAttributesTree->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mAttributesTree->setDragDropMode( QAbstractItemView::InternalMove );
|
||||
mAttributesTree->setAcceptDrops( true );
|
||||
mAttributesTree->setDragDropMode( QAbstractItemView::DragDrop );
|
||||
mDesignerTree->clear();
|
||||
mDesignerTree->setSortingEnabled( false );
|
||||
mDesignerTree->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mDesignerTree->setDragDropMode( QAbstractItemView::InternalMove );
|
||||
mDesignerTree->setAcceptDrops( true );
|
||||
mDesignerTree->setDragDropMode( QAbstractItemView::DragDrop );
|
||||
|
||||
QList<QgsAttributeEditorElement*> widgets = mLayer->attributeEditorElements();
|
||||
|
||||
for ( QList<QgsAttributeEditorElement*>::const_iterator it = widgets.begin(); it != widgets.end(); ++it )
|
||||
Q_FOREACH( QgsAttributeEditorElement* wdg, mLayer->attributeEditorElements() )
|
||||
{
|
||||
loadAttributeEditorTreeItem( *it, mAttributesTree->invisibleRootItem() );
|
||||
loadAttributeEditorTreeItem( wdg, mDesignerTree->invisibleRootItem() );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::loadRows()
|
||||
{
|
||||
disconnect( mAttributesList, SIGNAL( cellChanged( int, int ) ), this, SLOT( attributesListCellChanged( int, int ) ) );
|
||||
disconnect( mFieldsList, SIGNAL( cellChanged( int, int ) ), this, SLOT( attributesListCellChanged( int, int ) ) );
|
||||
const QgsFields &fields = mLayer->pendingFields();
|
||||
|
||||
mIndexedWidgets.clear();
|
||||
mAttributesList->clear();
|
||||
mAttributesList->setRowCount( 0 );
|
||||
|
||||
mAttributesList->setColumnCount( attrColCount );
|
||||
mAttributesList->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mAttributesList->setDragDropMode( QAbstractItemView::DragOnly );
|
||||
mAttributesList->setHorizontalHeaderItem( attrIdCol, new QTableWidgetItem( tr( "Id" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrNameCol, new QTableWidgetItem( tr( "Name" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrTypeCol, new QTableWidgetItem( tr( "Type" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrTypeNameCol, new QTableWidgetItem( tr( "Type name" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrLengthCol, new QTableWidgetItem( tr( "Length" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrEditTypeCol, new QTableWidgetItem( tr( "Edit widget" ) ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrWMSCol, new QTableWidgetItem( "WMS" ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrWFSCol, new QTableWidgetItem( "WFS" ) );
|
||||
mAttributesList->setHorizontalHeaderItem( attrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) );
|
||||
|
||||
mAttributesList->setSortingEnabled( true );
|
||||
mAttributesList->setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
mAttributesList->setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
mAttributesList->verticalHeader()->hide();
|
||||
mFieldsList->setRowCount( 0 );
|
||||
|
||||
for ( int i = 0; i < fields.count(); ++i )
|
||||
attributeAdded( i );
|
||||
|
||||
mAttributesList->resizeColumnsToContents();
|
||||
connect( mAttributesList, SIGNAL( cellChanged( int, int ) ), this, SLOT( attributesListCellChanged( int, int ) ) );
|
||||
mFieldsList->resizeColumnsToContents();
|
||||
connect( mFieldsList, SIGNAL( cellChanged( int, int ) ), this, SLOT( attributesListCellChanged( int, int ) ) );
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::setRow( int row, int idx, const QgsField &field )
|
||||
{
|
||||
mAttributesList->setItem( row, attrIdCol, new QTableWidgetItem( idx ) );
|
||||
mIndexedWidgets.insert( idx, mAttributesList->item( row, 0 ) );
|
||||
mAttributesList->setItem( row, attrNameCol, new QTableWidgetItem( field.name() ) );
|
||||
mAttributesList->setItem( row, attrTypeCol, new QTableWidgetItem( QVariant::typeToName( field.type() ) ) );
|
||||
mAttributesList->setItem( row, attrTypeNameCol, new QTableWidgetItem( field.typeName() ) );
|
||||
mAttributesList->setItem( row, attrLengthCol, new QTableWidgetItem( QString::number( field.length() ) ) );
|
||||
mAttributesList->setItem( row, attrPrecCol, new QTableWidgetItem( QString::number( field.precision() ) ) );
|
||||
mAttributesList->setItem( row, attrCommentCol, new QTableWidgetItem( field.comment() ) );
|
||||
QTableWidgetItem* dataItem = new QTableWidgetItem( idx );
|
||||
DesignerTreeItemData itemData( DesignerTreeItemData::Field, field.name() );
|
||||
dataItem->setData( DesignerTreeRole, itemData.asQVariant() );
|
||||
mFieldsList->setItem( row, attrIdCol, dataItem );
|
||||
mIndexedWidgets.insert( idx, mFieldsList->item( row, 0 ) );
|
||||
mFieldsList->setItem( row, attrNameCol, new QTableWidgetItem( field.name() ) );
|
||||
mFieldsList->setItem( row, attrTypeCol, new QTableWidgetItem( QVariant::typeToName( field.type() ) ) );
|
||||
mFieldsList->setItem( row, attrTypeNameCol, new QTableWidgetItem( field.typeName() ) );
|
||||
mFieldsList->setItem( row, attrLengthCol, new QTableWidgetItem( QString::number( field.length() ) ) );
|
||||
mFieldsList->setItem( row, attrPrecCol, new QTableWidgetItem( QString::number( field.precision() ) ) );
|
||||
mFieldsList->setItem( row, attrCommentCol, new QTableWidgetItem( field.comment() ) );
|
||||
|
||||
for ( int i = 0; i < attrEditTypeCol; i++ )
|
||||
mAttributesList->item( row, i )->setFlags( mAttributesList->item( row, i )->flags() & ~Qt::ItemIsEditable );
|
||||
mFieldsList->item( row, i )->setFlags( mFieldsList->item( row, i )->flags() & ~Qt::ItemIsEditable );
|
||||
|
||||
FieldConfig cfg( mLayer, idx );
|
||||
cfg.mEditType = mLayer->editType( idx );
|
||||
QPushButton *pb = new QPushButton( editTypeButtonText( cfg.mEditType ) );
|
||||
mAttributesList->setCellWidget( row, attrEditTypeCol, pb );
|
||||
QPushButton *pb;
|
||||
if ( cfg.mEditType == QgsVectorLayer::EditorWidgetV2 )
|
||||
{
|
||||
pb = new QPushButton( QgsEditorWidgetRegistry::instance()->name( cfg.mEditorWidgetV2Type ) );
|
||||
pb->setProperty( "EditWidgetV2", cfg.mEditType );
|
||||
}
|
||||
else
|
||||
{
|
||||
pb = new QPushButton( editTypeButtonText( cfg.mEditType ) );
|
||||
}
|
||||
|
||||
mFieldsList->setCellWidget( row, attrEditTypeCol, pb );
|
||||
connect( pb, SIGNAL( pressed() ), this, SLOT( attributeTypeDialog( ) ) );
|
||||
|
||||
cfg.mButton = pb;
|
||||
setConfigForRow( row, cfg );
|
||||
|
||||
//set the alias for the attribute
|
||||
mAttributesList->setItem( row, attrAliasCol, new QTableWidgetItem( mLayer->attributeAlias( idx ) ) );
|
||||
mFieldsList->setItem( row, attrAliasCol, new QTableWidgetItem( mLayer->attributeAlias( idx ) ) );
|
||||
|
||||
//published WMS/WFS attributes
|
||||
QTableWidgetItem* wmsAttrItem = new QTableWidgetItem();
|
||||
wmsAttrItem->setCheckState( mLayer->excludeAttributesWMS().contains( field.name() ) ? Qt::Unchecked : Qt::Checked );
|
||||
wmsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
|
||||
mAttributesList->setItem( row, attrWMSCol, wmsAttrItem );
|
||||
mFieldsList->setItem( row, attrWMSCol, wmsAttrItem );
|
||||
QTableWidgetItem* wfsAttrItem = new QTableWidgetItem();
|
||||
wfsAttrItem->setCheckState( mLayer->excludeAttributesWFS().contains( field.name() ) ? Qt::Unchecked : Qt::Checked );
|
||||
wfsAttrItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
|
||||
mAttributesList->setItem( row, attrWFSCol, wfsAttrItem );
|
||||
mFieldsList->setItem( row, attrWFSCol, wfsAttrItem );
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::on_mAddItemButton_clicked()
|
||||
{
|
||||
QList<QTableWidgetItem*> listItems = mAttributesList->selectedItems();
|
||||
QList<QTreeWidgetItem*> treeItems = mAttributesTree->selectedItems();
|
||||
QList<QTableWidgetItem*> listItems = mFieldsList->selectedItems();
|
||||
QList<QTreeWidgetItem*> treeItems = mDesignerTree->selectedItems();
|
||||
|
||||
if ( treeItems.count() != 1 && listItems.count() == 0 )
|
||||
return;
|
||||
|
||||
QTreeWidgetItem *parent = treeItems[0];
|
||||
if ( parent->data( 0, Qt::UserRole ) == "field" )
|
||||
if ( parent->data( 0, DesignerTreeRole ).value<DesignerTreeItemData>().type() != DesignerTreeItemData::Container )
|
||||
return;
|
||||
|
||||
for ( QList<QTableWidgetItem*>::const_iterator it = listItems.begin(); it != listItems.end(); it++ )
|
||||
Q_FOREACH( QTableWidgetItem* item, listItems )
|
||||
{
|
||||
if (( *it )->column() == attrNameCol )
|
||||
mAttributesTree->addItem( parent , ( *it )->text() );
|
||||
if ( item->column() == 0 ) // Information is in the first column
|
||||
mDesignerTree->addItem( parent , item->data( DesignerTreeRole ).value<DesignerTreeItemData>() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,12 +258,12 @@ void QgsFieldsProperties::on_mAddTabOrGroupButton_clicked()
|
||||
{
|
||||
QList<QgsAddTabOrGroup::TabPair> tabList;
|
||||
|
||||
|
||||
for ( QTreeWidgetItemIterator it( mAttributesTree ); *it; ++it )
|
||||
for ( QTreeWidgetItemIterator it( mDesignerTree ); *it; ++it )
|
||||
{
|
||||
if (( *it )->data( 0 , Qt::UserRole ) == "container" )
|
||||
DesignerTreeItemData itemData = ( *it )->data( 0, DesignerTreeRole ).value<DesignerTreeItemData>();
|
||||
if ( itemData.type() == DesignerTreeItemData::Container )
|
||||
{
|
||||
tabList.append( QgsAddTabOrGroup::TabPair(( *it )->text( 0 ), *it ) );
|
||||
tabList.append( QgsAddTabOrGroup::TabPair( itemData.name(), *it ) );
|
||||
}
|
||||
}
|
||||
QgsAddTabOrGroup addTabOrGroup( mLayer, tabList, this );
|
||||
@ -392,27 +274,23 @@ void QgsFieldsProperties::on_mAddTabOrGroupButton_clicked()
|
||||
QString name = addTabOrGroup.name();
|
||||
if ( addTabOrGroup.tabButtonIsChecked() )
|
||||
{
|
||||
mAttributesTree->addContainer( mAttributesTree->invisibleRootItem(), name );
|
||||
mDesignerTree->addContainer( mDesignerTree->invisibleRootItem(), name );
|
||||
}
|
||||
else
|
||||
{
|
||||
QTreeWidgetItem* tabItem = addTabOrGroup.tab();
|
||||
mAttributesTree->addContainer( tabItem , name );
|
||||
mDesignerTree->addContainer( tabItem , name );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::on_mRemoveTabGroupItemButton_clicked()
|
||||
{
|
||||
QList<QTreeWidgetItem*> items = mAttributesTree->selectedItems();
|
||||
for ( QList<QTreeWidgetItem*>::const_iterator it = items.begin(); it != items.end(); it++ )
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
qDeleteAll( mDesignerTree->selectedItems() );
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::on_mMoveDownItem_clicked()
|
||||
{
|
||||
QList<QTreeWidgetItem*> itemList = mAttributesTree->selectedItems();
|
||||
QList<QTreeWidgetItem*> itemList = mDesignerTree->selectedItems();
|
||||
if ( itemList.count() != 1 )
|
||||
return;
|
||||
|
||||
@ -420,7 +298,7 @@ void QgsFieldsProperties::on_mMoveDownItem_clicked()
|
||||
QTreeWidgetItem* parent = itemToMoveDown->parent();
|
||||
if ( !parent )
|
||||
{
|
||||
parent = mAttributesTree->invisibleRootItem();
|
||||
parent = mDesignerTree->invisibleRootItem();
|
||||
}
|
||||
int itemIndex = parent->indexOfChild( itemToMoveDown );
|
||||
|
||||
@ -436,7 +314,7 @@ void QgsFieldsProperties::on_mMoveDownItem_clicked()
|
||||
|
||||
void QgsFieldsProperties::on_mMoveUpItem_clicked()
|
||||
{
|
||||
QList<QTreeWidgetItem*> itemList = mAttributesTree->selectedItems();
|
||||
QList<QTreeWidgetItem*> itemList = mDesignerTree->selectedItems();
|
||||
if ( itemList.count() != 1 )
|
||||
return;
|
||||
|
||||
@ -444,7 +322,7 @@ void QgsFieldsProperties::on_mMoveUpItem_clicked()
|
||||
QTreeWidgetItem* parent = itemToMoveUp->parent();
|
||||
if ( !parent )
|
||||
{
|
||||
parent = mAttributesTree->invisibleRootItem();
|
||||
parent = mDesignerTree->invisibleRootItem();
|
||||
}
|
||||
int itemIndex = parent->indexOfChild( itemToMoveUp );
|
||||
|
||||
@ -468,9 +346,9 @@ void QgsFieldsProperties::attributeTypeDialog()
|
||||
int index = -1;
|
||||
int row = -1;
|
||||
|
||||
foreach ( QTableWidgetItem* wdg, mIndexedWidgets )
|
||||
Q_FOREACH( QTableWidgetItem* wdg, mIndexedWidgets )
|
||||
{
|
||||
cfg = wdg->data( Qt::UserRole ).value<FieldConfig>();
|
||||
cfg = wdg->data( FieldConfigRole ).value<FieldConfig>();
|
||||
if ( cfg.mButton == pb )
|
||||
{
|
||||
index = mIndexedWidgets.indexOf( wdg );
|
||||
@ -495,6 +373,7 @@ void QgsFieldsProperties::attributeTypeDialog()
|
||||
attributeTypeDialog.setWidgetSize( cfg.mWidgetSize );
|
||||
attributeTypeDialog.setFieldEditable( cfg.mEditable );
|
||||
attributeTypeDialog.setLabelOnTop( cfg.mLabelOnTop );
|
||||
attributeTypeDialog.setWidgetV2Config( cfg.mEditorWidgetV2Config );
|
||||
|
||||
attributeTypeDialog.setIndex( index, cfg.mEditType );
|
||||
attributeTypeDialog.setFieldEditableEnabled( cfg.mEditableEnabled );
|
||||
@ -541,21 +420,35 @@ void QgsFieldsProperties::attributeTypeDialog()
|
||||
case QgsVectorLayer::UuidGenerator:
|
||||
case QgsVectorLayer::Color:
|
||||
break;
|
||||
|
||||
case QgsVectorLayer::EditorWidgetV2:
|
||||
cfg.mEditorWidgetV2Type = attributeTypeDialog.editorWidgetV2Type();
|
||||
cfg.mEditorWidgetV2Config = attributeTypeDialog.editorWidgetV2Config();
|
||||
break;
|
||||
}
|
||||
|
||||
if ( cfg.mEditType == QgsVectorLayer::EditorWidgetV2 )
|
||||
{
|
||||
pb->setText( attributeTypeDialog.editorWidgetV2Text() );
|
||||
pb->setProperty( "EditWidgetV2", cfg.mEditType );
|
||||
}
|
||||
else
|
||||
{
|
||||
pb->setText( editTypeButtonText( cfg.mEditType ) );
|
||||
pb->setProperty( "EditWidgetV2", QVariant() );
|
||||
}
|
||||
|
||||
setConfigForRow( row, cfg );
|
||||
|
||||
pb->setText( editTypeButtonText( cfg.mEditType ) );
|
||||
}
|
||||
|
||||
|
||||
void QgsFieldsProperties::attributeAdded( int idx )
|
||||
{
|
||||
bool sorted = mAttributesList->isSortingEnabled();
|
||||
mAttributesList->setSortingEnabled( false );
|
||||
bool sorted = mFieldsList->isSortingEnabled();
|
||||
mFieldsList->setSortingEnabled( false );
|
||||
const QgsFields &fields = mLayer->pendingFields();
|
||||
int row = mAttributesList->rowCount();
|
||||
mAttributesList->insertRow( row );
|
||||
int row = mFieldsList->rowCount();
|
||||
mFieldsList->insertRow( row );
|
||||
setRow( row, idx, fields[idx] );
|
||||
|
||||
for ( int i = idx; i < mIndexedWidgets.count(); i++ )
|
||||
@ -563,14 +456,14 @@ void QgsFieldsProperties::attributeAdded( int idx )
|
||||
mIndexedWidgets[i]->setData( Qt::DisplayRole, i );
|
||||
}
|
||||
|
||||
mAttributesList->setCurrentCell( row, idx );
|
||||
mAttributesList->setSortingEnabled( sorted );
|
||||
mFieldsList->setCurrentCell( row, idx );
|
||||
mFieldsList->setSortingEnabled( sorted );
|
||||
}
|
||||
|
||||
|
||||
void QgsFieldsProperties::attributeDeleted( int idx )
|
||||
{
|
||||
mAttributesList->removeRow( mIndexedWidgets.at( idx )->row() );
|
||||
mFieldsList->removeRow( mIndexedWidgets.at( idx )->row() );
|
||||
mIndexedWidgets.removeAt( idx );
|
||||
for ( int i = idx; i < mIndexedWidgets.count(); i++ )
|
||||
{
|
||||
@ -623,7 +516,7 @@ QgsFieldsProperties::FieldConfig QgsFieldsProperties::configForRow( int row )
|
||||
{
|
||||
if ( wdg->row() == row )
|
||||
{
|
||||
return wdg->data( Qt::UserRole ).value<FieldConfig>();
|
||||
return wdg->data( FieldConfigRole ).value<FieldConfig>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,7 +531,7 @@ void QgsFieldsProperties::setConfigForRow( int row, QgsFieldsProperties::FieldCo
|
||||
{
|
||||
if ( wdg->row() == row )
|
||||
{
|
||||
wdg->setData( Qt::UserRole, QVariant::fromValue<FieldConfig>( cfg ) );
|
||||
wdg->setData( FieldConfigRole, QVariant::fromValue<FieldConfig>( cfg ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -668,7 +561,7 @@ void QgsFieldsProperties::on_mAddAttributeButton_clicked()
|
||||
void QgsFieldsProperties::on_mDeleteAttributeButton_clicked()
|
||||
{
|
||||
QSet<int> attrs;
|
||||
foreach ( QTableWidgetItem* item, mAttributesList->selectedItems() )
|
||||
foreach ( QTableWidgetItem* item, mFieldsList->selectedItems() )
|
||||
{
|
||||
if ( item->column() == 0 )
|
||||
{
|
||||
@ -708,7 +601,7 @@ void QgsFieldsProperties::attributesListCellChanged( int row, int column )
|
||||
{
|
||||
if ( column == attrAliasCol && mLayer ) //only consider attribute aliases in this function
|
||||
{
|
||||
int idx = mAttributesList->item( row, attrIdCol )->text().toInt();
|
||||
int idx = mFieldsList->item( row, attrIdCol )->text().toInt();
|
||||
|
||||
const QgsFields &fields = mLayer->pendingFields();
|
||||
|
||||
@ -717,7 +610,7 @@ void QgsFieldsProperties::attributesListCellChanged( int row, int column )
|
||||
return; // index must be wrong
|
||||
}
|
||||
|
||||
QTableWidgetItem *aliasItem = mAttributesList->item( row, column );
|
||||
QTableWidgetItem *aliasItem = mFieldsList->item( row, column );
|
||||
if ( aliasItem )
|
||||
{
|
||||
mLayer->addAttributeAlias( idx, aliasItem->text() );
|
||||
@ -768,6 +661,7 @@ void QgsFieldsProperties::setupEditTypes()
|
||||
editTypeMap.insert( QgsVectorLayer::Photo, tr( "Photo" ) );
|
||||
editTypeMap.insert( QgsVectorLayer::WebView, tr( "Web view" ) );
|
||||
editTypeMap.insert( QgsVectorLayer::Color, tr( "Color" ) );
|
||||
editTypeMap.insert( QgsVectorLayer::EditorWidgetV2, tr( "Editor Widget" ) );
|
||||
}
|
||||
|
||||
QString QgsFieldsProperties::editTypeButtonText( QgsVectorLayer::EditType type )
|
||||
@ -775,30 +669,42 @@ QString QgsFieldsProperties::editTypeButtonText( QgsVectorLayer::EditType type )
|
||||
return editTypeMap[ type ];
|
||||
}
|
||||
|
||||
QgsVectorLayer::EditType QgsFieldsProperties::editTypeFromButtonText( QString text )
|
||||
QgsVectorLayer::EditType QgsFieldsProperties::editTypeFromButton( QPushButton* btn )
|
||||
{
|
||||
return editTypeMap.key( text );
|
||||
QVariant editWidgetId = btn->property( "EditWidgetV2" );
|
||||
|
||||
if ( editWidgetId.isNull() )
|
||||
return editTypeMap.key( btn->text() );
|
||||
else
|
||||
return QgsVectorLayer::EditorWidgetV2;
|
||||
}
|
||||
|
||||
QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTreeWidgetItem* item, QObject *parent )
|
||||
{
|
||||
QgsAttributeEditorElement* widgetDef;
|
||||
|
||||
if ( item->data( 0, Qt::UserRole ) == "field" )
|
||||
DesignerTreeItemData itemData = item->data( 0, DesignerTreeRole ).value<DesignerTreeItemData>();
|
||||
switch ( itemData.type() )
|
||||
{
|
||||
int idx = *( mLayer->dataProvider()->fieldNameMap() ).find( item->text( 0 ) );
|
||||
widgetDef = new QgsAttributeEditorField( item->text( 0 ), idx, parent );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( item->text( 0 ), parent );
|
||||
|
||||
for ( int t = 0; t < item->childCount(); t++ )
|
||||
case DesignerTreeItemData::Field:
|
||||
{
|
||||
container->addChildElement( createAttributeEditorWidget( item->child( t ), container ) );
|
||||
int idx = mLayer->fieldNameIndex( itemData.name() );
|
||||
widgetDef = new QgsAttributeEditorField( itemData.name(), idx, parent );
|
||||
break;
|
||||
}
|
||||
|
||||
widgetDef = container;
|
||||
case DesignerTreeItemData::Container:
|
||||
{
|
||||
QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( itemData.name(), parent );
|
||||
|
||||
for ( int t = 0; t < item->childCount(); t++ )
|
||||
{
|
||||
container->addChildElement( createAttributeEditorWidget( item->child( t ), container ) );
|
||||
}
|
||||
|
||||
widgetDef = container;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return widgetDef;
|
||||
@ -840,12 +746,12 @@ void QgsFieldsProperties::apply()
|
||||
{
|
||||
QSet<QString> excludeAttributesWMS, excludeAttributesWFS;
|
||||
|
||||
for ( int i = 0; i < mAttributesList->rowCount(); i++ )
|
||||
for ( int i = 0; i < mFieldsList->rowCount(); i++ )
|
||||
{
|
||||
int idx = mAttributesList->item( i, attrIdCol )->text().toInt();
|
||||
int idx = mFieldsList->item( i, attrIdCol )->text().toInt();
|
||||
FieldConfig cfg = configForRow( i );
|
||||
|
||||
QPushButton *pb = qobject_cast<QPushButton *>( mAttributesList->cellWidget( i, attrEditTypeCol ) );
|
||||
QPushButton *pb = qobject_cast<QPushButton *>( mFieldsList->cellWidget( i, attrEditTypeCol ) );
|
||||
if ( !pb )
|
||||
continue;
|
||||
|
||||
@ -895,28 +801,33 @@ void QgsFieldsProperties::apply()
|
||||
case QgsVectorLayer::UuidGenerator:
|
||||
case QgsVectorLayer::Color:
|
||||
break;
|
||||
|
||||
case QgsVectorLayer::EditorWidgetV2:
|
||||
mLayer->setEditorWidgetV2( idx, cfg.mEditorWidgetV2Type );
|
||||
mLayer->setEditorWidgetV2Config( idx, cfg.mEditorWidgetV2Config );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( mAttributesList->item( i, attrWMSCol )->checkState() == Qt::Unchecked )
|
||||
if ( mFieldsList->item( i, attrWMSCol )->checkState() == Qt::Unchecked )
|
||||
{
|
||||
excludeAttributesWMS.insert( mAttributesList->item( i, attrNameCol )->text() );
|
||||
excludeAttributesWMS.insert( mFieldsList->item( i, attrNameCol )->text() );
|
||||
}
|
||||
if ( mAttributesList->item( i, attrWFSCol )->checkState() == Qt::Unchecked )
|
||||
if ( mFieldsList->item( i, attrWFSCol )->checkState() == Qt::Unchecked )
|
||||
{
|
||||
excludeAttributesWFS.insert( mAttributesList->item( i, attrNameCol )->text() );
|
||||
excludeAttributesWFS.insert( mFieldsList->item( i, attrNameCol )->text() );
|
||||
}
|
||||
}
|
||||
|
||||
//tabs and groups
|
||||
mLayer->clearAttributeEditorWidgets();
|
||||
for ( int t = 0; t < mAttributesTree->invisibleRootItem()->childCount(); t++ )
|
||||
for ( int t = 0; t < mDesignerTree->invisibleRootItem()->childCount(); t++ )
|
||||
{
|
||||
QTreeWidgetItem* tabItem = mAttributesTree->invisibleRootItem()->child( t );
|
||||
QTreeWidgetItem* tabItem = mDesignerTree->invisibleRootItem()->child( t );
|
||||
|
||||
mLayer->addAttributeEditorWidget( createAttributeEditorWidget( tabItem, mLayer ) );
|
||||
}
|
||||
|
||||
mLayer->setEditorLayout(( QgsVectorLayer::EditorLayout )mEditorLayoutComboBox->currentIndex() );
|
||||
mLayer->setEditorLayout(( QgsVectorLayer::EditorLayout ) mEditorLayoutComboBox->currentIndex() );
|
||||
mLayer->setEditForm( leEditForm->text() );
|
||||
mLayer->setEditFormInit( leEditFormInit->text() );
|
||||
mLayer->setFeatureFormSuppress(( QgsVectorLayer::FeatureFormSuppress )mFormSuppressCmbBx->currentIndex() );
|
||||
@ -925,6 +836,9 @@ void QgsFieldsProperties::apply()
|
||||
mLayer->setExcludeAttributesWFS( excludeAttributesWFS );
|
||||
}
|
||||
|
||||
/*
|
||||
* FieldConfig implementation
|
||||
*/
|
||||
|
||||
QgsFieldsProperties::FieldConfig::FieldConfig()
|
||||
: mButton( NULL )
|
||||
@ -944,4 +858,238 @@ QgsFieldsProperties::FieldConfig::FieldConfig( QgsVectorLayer* layer, int idx )
|
||||
mEditType = layer->editType( idx );
|
||||
mDateFormat = layer->dateFormat( idx );
|
||||
mWidgetSize = layer->widgetSize( idx );
|
||||
mEditorWidgetV2Type = layer->editorWidgetV2( idx );
|
||||
mEditorWidgetV2Config = layer->editorWidgetV2Config( idx );
|
||||
}
|
||||
|
||||
/*
|
||||
* DragList implementation
|
||||
*/
|
||||
|
||||
QStringList QgsFieldsProperties::DragList::mimeTypes() const
|
||||
{
|
||||
return QStringList() << QLatin1String( "application/x-qgsattributetabledesignerelement" );
|
||||
}
|
||||
|
||||
QMimeData* QgsFieldsProperties::DragList::mimeData( const QList<QTableWidgetItem*> items ) const
|
||||
{
|
||||
if ( items.count() <= 0 )
|
||||
return NULL;
|
||||
|
||||
QStringList types = mimeTypes();
|
||||
|
||||
if ( types.isEmpty() )
|
||||
return NULL;
|
||||
|
||||
QMimeData* data = new QMimeData();
|
||||
QString format = types.at( 0 );
|
||||
QByteArray encoded;
|
||||
QDataStream stream( &encoded, QIODevice::WriteOnly );
|
||||
|
||||
Q_FOREACH( const QTableWidgetItem* item, items )
|
||||
{
|
||||
// Relevant information is always in the UserRole of the first column
|
||||
if ( item && item->column() == 0 )
|
||||
{
|
||||
DesignerTreeItemData itemData = item->data( DesignerTreeRole ).value<DesignerTreeItemData>();
|
||||
stream << itemData;
|
||||
}
|
||||
}
|
||||
|
||||
data->setData( format, encoded );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* DesignerTree implementation
|
||||
*/
|
||||
|
||||
QTreeWidgetItem* QgsFieldsProperties::DesignerTree::addContainer( QTreeWidgetItem* parent, QString title )
|
||||
{
|
||||
QTreeWidgetItem *newItem = new QTreeWidgetItem( QStringList() << title );
|
||||
newItem->setBackground( 0 , QBrush( Qt::lightGray ) );
|
||||
newItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
|
||||
newItem->setData( 0, DesignerTreeRole, DesignerTreeItemData( DesignerTreeItemData::Container, title ).asQVariant() );
|
||||
parent->addChild( newItem );
|
||||
newItem->setExpanded( true );
|
||||
return newItem;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* QgsFieldsProperties::DesignerTree::addItem( QTreeWidgetItem* parent, DesignerTreeItemData data )
|
||||
{
|
||||
QTreeWidgetItem* newItem = new QTreeWidgetItem( QStringList() << data.name() );
|
||||
newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled );
|
||||
if ( data.type() == DesignerTreeItemData::Container )
|
||||
{
|
||||
newItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled );
|
||||
newItem->setBackground( 0 , QBrush( Qt::lightGray ) );
|
||||
|
||||
#if 0
|
||||
switch ( data.type() )
|
||||
{
|
||||
case DesignerTreeItemData::Field:
|
||||
newItem->setIcon( 0, QgsApplication::getThemeIcon( "/mFieldIcon.svg" ) );
|
||||
break;
|
||||
|
||||
case DesignerTreeItemData::Relation:
|
||||
newItem->setIcon( 0, QgsApplication::getThemeIcon( "/mRelationIcon.svg" ) );
|
||||
break;
|
||||
|
||||
case DesignerTreeItemData::Container:
|
||||
newItem->setIcon( 0, QgsApplication::getThemeIcon( "/mContainerIcon.svg" ) );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
newItem->setData( 0 , DesignerTreeRole, data.asQVariant() );
|
||||
parent->addChild( newItem );
|
||||
|
||||
return newItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called when mouse is moved over attributes tree before a
|
||||
* drop event. Used to inhibit dropping fields onto the root item.
|
||||
*/
|
||||
|
||||
void QgsFieldsProperties::DesignerTree::dragMoveEvent( QDragMoveEvent *event )
|
||||
{
|
||||
QTreeWidgetItem* targetItem = itemAt( event->pos() );
|
||||
const QMimeData* data = event->mimeData();
|
||||
|
||||
if ( data->hasFormat( "application/x-qgsattributetabledesignerelement" ) )
|
||||
{
|
||||
DesignerTreeItemData itemElement;
|
||||
|
||||
QByteArray itemData = data->data( "application/x-qgsattributetabledesignerelement" );
|
||||
QDataStream stream( &itemData, QIODevice::ReadOnly );
|
||||
stream >> itemElement;
|
||||
|
||||
// Forbid dropping fields on root item
|
||||
if ( itemElement.type() == DesignerTreeItemData::Field && !targetItem )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
// Inner drag and drop actions are always MoveAction
|
||||
if ( event->source() == this )
|
||||
{
|
||||
event->setDropAction( Qt::MoveAction );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
QTreeWidget::dragMoveEvent( event );
|
||||
}
|
||||
|
||||
|
||||
bool QgsFieldsProperties::DesignerTree::dropMimeData( QTreeWidgetItem* parent, int index, const QMimeData * data, Qt::DropAction action )
|
||||
{
|
||||
Q_UNUSED( index )
|
||||
bool bDropSuccessful = false;
|
||||
|
||||
if ( action == Qt::IgnoreAction )
|
||||
{
|
||||
bDropSuccessful = true;
|
||||
}
|
||||
else if ( data->hasFormat( "application/x-qgsattributetabledesignerelement" ) )
|
||||
{
|
||||
QByteArray itemData = data->data( "application/x-qgsattributetabledesignerelement" );
|
||||
QDataStream stream( &itemData, QIODevice::ReadOnly );
|
||||
DesignerTreeItemData itemElement;
|
||||
|
||||
while ( !stream.atEnd() )
|
||||
{
|
||||
stream >> itemElement;
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
addItem( parent, itemElement );
|
||||
bDropSuccessful = true;
|
||||
}
|
||||
else // Should never happen as we ignore drops of fields onto the root element in dragMoveEvent, but actually does happen. Qt?
|
||||
{
|
||||
// addItem( invisibleRootItem(), itemName );
|
||||
// bDropSuccessful = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bDropSuccessful;
|
||||
}
|
||||
|
||||
void QgsFieldsProperties::DesignerTree::dropEvent( QDropEvent* event )
|
||||
{
|
||||
if ( !event->mimeData()->hasFormat( "application/x-qgsattributetabledesignerelement" ) )
|
||||
return;
|
||||
|
||||
if ( event->source() == this )
|
||||
{
|
||||
event->setDropAction( Qt::MoveAction );
|
||||
}
|
||||
|
||||
QTreeWidget::dropEvent( event );
|
||||
}
|
||||
|
||||
QStringList QgsFieldsProperties::DesignerTree::mimeTypes() const
|
||||
{
|
||||
return QStringList() << QLatin1String( "application/x-qgsattributetabledesignerelement" );
|
||||
}
|
||||
|
||||
QMimeData* QgsFieldsProperties::DesignerTree::mimeData( const QList<QTreeWidgetItem*> items ) const
|
||||
{
|
||||
if ( items.count() <= 0 )
|
||||
return NULL;
|
||||
|
||||
QStringList types = mimeTypes();
|
||||
|
||||
if ( types.isEmpty() )
|
||||
return NULL;
|
||||
|
||||
QMimeData* data = new QMimeData();
|
||||
QString format = types.at( 0 );
|
||||
QByteArray encoded;
|
||||
QDataStream stream( &encoded, QIODevice::WriteOnly );
|
||||
|
||||
Q_FOREACH( const QTreeWidgetItem* item, items )
|
||||
{
|
||||
if ( item )
|
||||
{
|
||||
// Relevant information is always in the DesignerTreeRole of the first column
|
||||
DesignerTreeItemData itemData = item->data( 0, DesignerTreeRole ).value<DesignerTreeItemData>();
|
||||
stream << itemData;
|
||||
}
|
||||
}
|
||||
|
||||
data->setData( format, encoded );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialization helpers for DesigerTreeItemData so we can stuff this easily into QMimeData
|
||||
*/
|
||||
|
||||
QDataStream& operator<<( QDataStream& stream, const QgsFieldsProperties::DesignerTreeItemData& data )
|
||||
{
|
||||
stream << ( quint32 )data.type() << data.name();
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream& operator>>( QDataStream& stream, QgsFieldsProperties::DesignerTreeItemData& data )
|
||||
{
|
||||
QString name;
|
||||
quint32 type;
|
||||
|
||||
stream >> type >> name;
|
||||
|
||||
data.setType(( QgsFieldsProperties::DesignerTreeItemData::Type )type );
|
||||
data.setName( name );
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
@ -20,33 +20,101 @@
|
||||
#include <QPushButton>
|
||||
#include <QTreeWidget>
|
||||
#include <QTableWidget>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "ui_qgsfieldspropertiesbase.h"
|
||||
|
||||
class APP_EXPORT QgsAttributesTree : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QgsAttributesTree( QWidget* parent = 0 )
|
||||
: QTreeWidget( parent )
|
||||
{}
|
||||
QTreeWidgetItem* addContainer( QTreeWidgetItem* parent , QString title );
|
||||
QTreeWidgetItem* addItem( QTreeWidgetItem* parent , QString fieldName );
|
||||
|
||||
protected:
|
||||
virtual void dragMoveEvent( QDragMoveEvent *event );
|
||||
virtual void dropEvent( QDropEvent *event );
|
||||
virtual bool dropMimeData( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action );
|
||||
/* Qt::DropActions supportedDropActions() const;*/
|
||||
};
|
||||
|
||||
|
||||
class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPropertiesBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum FieldPropertiesRoles
|
||||
{
|
||||
DesignerTreeRole = Qt::UserRole,
|
||||
FieldConfigRole
|
||||
};
|
||||
|
||||
class DesignerTreeItemData
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
Field,
|
||||
Container
|
||||
};
|
||||
|
||||
DesignerTreeItemData()
|
||||
{}
|
||||
|
||||
DesignerTreeItemData( Type type, const QString& name )
|
||||
: mType( type )
|
||||
, mName( name ) {}
|
||||
|
||||
QString name() const { return mName; }
|
||||
void setName( const QString& name ) { mName = name; }
|
||||
|
||||
Type type() const { return mType; }
|
||||
void setType( const Type& type ) { mType = type; }
|
||||
|
||||
QVariant asQVariant() { return QVariant::fromValue<DesignerTreeItemData>( *this ); }
|
||||
|
||||
protected:
|
||||
Type mType;
|
||||
QString mName;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class overrides mime type handling to be able to work with
|
||||
* the drag and drop attribute editor.
|
||||
*
|
||||
* The mime type is application/x-qgsattributetablefield
|
||||
*/
|
||||
|
||||
class DragList : public QTableWidget
|
||||
{
|
||||
public:
|
||||
DragList( QWidget* parent = 0 )
|
||||
: QTableWidget( parent )
|
||||
{}
|
||||
|
||||
// QTreeWidget interface
|
||||
protected:
|
||||
virtual QStringList mimeTypes() const;
|
||||
|
||||
virtual QMimeData* mimeData( const QList<QTableWidgetItem*> items ) const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Graphical representation for the attribute editor drag and drop editor
|
||||
*/
|
||||
class DesignerTree : public QTreeWidget
|
||||
{
|
||||
public:
|
||||
DesignerTree( QWidget* parent = 0 )
|
||||
: QTreeWidget( parent )
|
||||
{}
|
||||
QTreeWidgetItem* addItem( QTreeWidgetItem* parent, DesignerTreeItemData data );
|
||||
QTreeWidgetItem* addContainer( QTreeWidgetItem* parent, QString title );
|
||||
|
||||
protected:
|
||||
virtual void dragMoveEvent( QDragMoveEvent *event );
|
||||
virtual void dropEvent( QDropEvent *event );
|
||||
virtual bool dropMimeData( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action );
|
||||
/* Qt::DropActions supportedDropActions() const;*/
|
||||
|
||||
// QTreeWidget interface
|
||||
protected:
|
||||
virtual QStringList mimeTypes() const;
|
||||
virtual QMimeData* mimeData( const QList<QTreeWidgetItem*> items ) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds the configuration for a field
|
||||
*/
|
||||
class FieldConfig
|
||||
{
|
||||
public:
|
||||
@ -64,6 +132,8 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
QPushButton* mButton;
|
||||
QString mDateFormat;
|
||||
QSize mWidgetSize;
|
||||
QString mEditorWidgetV2Type;
|
||||
QMap<QString, QVariant> mEditorWidgetV2Config;
|
||||
};
|
||||
|
||||
public:
|
||||
@ -125,8 +195,8 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
void setConfigForRow( int row, FieldConfig cfg );
|
||||
|
||||
QgsVectorLayer* mLayer;
|
||||
QgsAttributesTree* mAttributesTree;
|
||||
QTableWidget* mAttributesList;
|
||||
DesignerTree* mDesignerTree;
|
||||
DragList* mFieldsList;
|
||||
|
||||
// Holds all the first column items (header: id) of the table.
|
||||
// The index in the list is the fieldIdx, and therefore acts as a mapping
|
||||
@ -152,10 +222,14 @@ class APP_EXPORT QgsFieldsProperties : public QWidget, private Ui_QgsFieldsPrope
|
||||
static QMap< QgsVectorLayer::EditType, QString > editTypeMap;
|
||||
static void setupEditTypes();
|
||||
static QString editTypeButtonText( QgsVectorLayer::EditType type );
|
||||
static QgsVectorLayer::EditType editTypeFromButtonText( QString text );
|
||||
static QgsVectorLayer::EditType editTypeFromButton( QPushButton* btn );
|
||||
|
||||
};
|
||||
|
||||
QDataStream& operator<< ( QDataStream& stream, const QgsFieldsProperties::DesignerTreeItemData& data );
|
||||
QDataStream& operator>> ( QDataStream& stream, QgsFieldsProperties::DesignerTreeItemData& data );
|
||||
|
||||
Q_DECLARE_METATYPE( QgsFieldsProperties::FieldConfig )
|
||||
Q_DECLARE_METATYPE( QgsFieldsProperties::DesignerTreeItemData )
|
||||
|
||||
#endif // QGSFIELDSPROPERTIES_H
|
||||
|
||||
@ -382,6 +382,7 @@ SET(QGIS_CORE_HDRS
|
||||
qgsdataitem.h
|
||||
qgsdistancearea.h
|
||||
qgscsexception.h
|
||||
qgseditorwidgetconfig.h
|
||||
qgserror.h
|
||||
qgsexception.h
|
||||
qgsexpression.h
|
||||
|
||||
@ -62,7 +62,7 @@ class CORE_EXPORT QgsDistanceArea
|
||||
void setSourceAuthId( QString authid );
|
||||
|
||||
//! returns source spatial reference system
|
||||
long sourceCrs() { return mSourceRefSys; }
|
||||
long sourceCrs() const { return mSourceRefSys; }
|
||||
//! What sort of coordinate system is being used?
|
||||
bool geographic() { return mCoordTransform->sourceCrs().geographicFlag(); }
|
||||
|
||||
|
||||
19
src/core/qgseditorwidgetconfig.h
Normal file
19
src/core/qgseditorwidgetconfig.h
Normal file
@ -0,0 +1,19 @@
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@ -1666,15 +1666,10 @@ void QgsExpression::initGeomCalculator()
|
||||
mCalc->setEllipsoidalMode( false );
|
||||
}
|
||||
|
||||
void QgsExpression::setGeomCalculator( QgsDistanceArea &calc )
|
||||
void QgsExpression::setGeomCalculator( const QgsDistanceArea &calc )
|
||||
{
|
||||
if ( !mCalc )
|
||||
mCalc = new QgsDistanceArea();
|
||||
|
||||
// Copy from supplied calculator
|
||||
mCalc->setEllipsoid( calc.ellipsoid() );
|
||||
mCalc->setEllipsoidalMode( calc.ellipsoidalEnabled() );
|
||||
mCalc->setSourceCrs( calc.sourceCrs() );
|
||||
delete mCalc;
|
||||
mCalc = new QgsDistanceArea( calc );
|
||||
}
|
||||
|
||||
bool QgsExpression::prepare( const QgsFields& fields )
|
||||
|
||||
@ -162,7 +162,7 @@ class CORE_EXPORT QgsExpression
|
||||
|
||||
//! Sets the geometry calculator used in evaluation of expressions,
|
||||
// instead of the default.
|
||||
void setGeomCalculator( QgsDistanceArea &calc );
|
||||
void setGeomCalculator( const QgsDistanceArea &calc );
|
||||
|
||||
/** This function currently replaces each expression between [% and %]
|
||||
in the string with the result of its evaluation on the feature
|
||||
|
||||
@ -1964,6 +1964,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
|
||||
case UniqueValuesEditable:
|
||||
case UuidGenerator:
|
||||
case Color:
|
||||
case EditorWidgetV2: // Will get a signal and read there
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2086,6 +2087,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
|
||||
QgsAttributeEditorElement *attributeEditorWidget = attributeEditorElementFromDomElement( elem, this );
|
||||
mAttributeEditorElements.append( attributeEditorWidget );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2103,7 +2105,8 @@ QgsAttributeEditorElement* QgsVectorLayer::attributeEditorElementFromDomElement(
|
||||
{
|
||||
QDomElement childElem = childNodeList.at( i ).toElement();
|
||||
QgsAttributeEditorElement* myElem = attributeEditorElementFromDomElement( childElem, container );
|
||||
container->addChildElement( myElem );
|
||||
if ( myElem )
|
||||
container->addChildElement( myElem );
|
||||
}
|
||||
|
||||
newElement = container;
|
||||
@ -2114,7 +2117,6 @@ QgsAttributeEditorElement* QgsVectorLayer::attributeEditorElementFromDomElement(
|
||||
int idx = *( dataProvider()->fieldNameMap() ).find( name );
|
||||
newElement = new QgsAttributeEditorField( name, idx, parent );
|
||||
}
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
@ -2282,6 +2284,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
|
||||
case Immutable:
|
||||
case UuidGenerator:
|
||||
case Color:
|
||||
case EditorWidgetV2: // Will get a signal and save there
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2479,6 +2482,16 @@ void QgsVectorLayer::addAttributeEditorWidget( QgsAttributeEditorElement* data )
|
||||
mAttributeEditorElements.append( data );
|
||||
}
|
||||
|
||||
const QString QgsVectorLayer::editorWidgetV2( int fieldIdx )
|
||||
{
|
||||
return mEditorWidgetV2Types.value( fieldIdx );
|
||||
}
|
||||
|
||||
const QgsEditorWidgetConfig QgsVectorLayer::editorWidgetV2Config( int fieldIdx )
|
||||
{
|
||||
return mEditorWidgetV2Configs.value( fieldIdx );
|
||||
}
|
||||
|
||||
QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
|
||||
{
|
||||
if ( attributeIndex < 0 || attributeIndex >= pendingFields().count() )
|
||||
@ -3006,6 +3019,16 @@ void QgsVectorLayer::setEditorLayout( EditorLayout editorLayout )
|
||||
mEditorLayout = editorLayout;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setEditorWidgetV2( int attrIdx, const QString& widgetType )
|
||||
{
|
||||
mEditorWidgetV2Types[ attrIdx ] = widgetType;
|
||||
}
|
||||
|
||||
void QgsVectorLayer::setEditorWidgetV2Config( int attrIdx, const QMap<QString, QVariant>& config )
|
||||
{
|
||||
mEditorWidgetV2Configs[ attrIdx ] = config;
|
||||
}
|
||||
|
||||
QString QgsVectorLayer::editForm()
|
||||
{
|
||||
return mEditForm;
|
||||
@ -3842,19 +3865,40 @@ QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
|
||||
{
|
||||
QDomElement elem = doc.createElement( "attributeEditorContainer" );
|
||||
elem.setAttribute( "name", mName );
|
||||
for ( QList< QgsAttributeEditorElement* >::const_iterator it = mChildren.begin(); it != mChildren.end(); ++it )
|
||||
|
||||
Q_FOREACH( QgsAttributeEditorElement* child, mChildren )
|
||||
{
|
||||
elem.appendChild(( *it )->toDomElement( doc ) );
|
||||
elem.appendChild( child->toDomElement( doc ) );
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
|
||||
void QgsAttributeEditorContainer::addChildElement( QgsAttributeEditorElement *widget )
|
||||
{
|
||||
mChildren.append( widget );
|
||||
}
|
||||
|
||||
QList<QgsAttributeEditorElement*> QgsAttributeEditorContainer::findElements( QgsAttributeEditorElement::AttributeEditorType type ) const
|
||||
{
|
||||
QList<QgsAttributeEditorElement*> results;
|
||||
|
||||
Q_FOREACH( QgsAttributeEditorElement* elem, mChildren )
|
||||
{
|
||||
if ( elem->type() == type )
|
||||
{
|
||||
results.append( elem );
|
||||
}
|
||||
|
||||
if ( elem->type() == AeTypeContainer )
|
||||
{
|
||||
QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
|
||||
results += cont->findElements( type );
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
|
||||
{
|
||||
QDomElement elem = doc.createElement( "attributeEditorField" );
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include "qgseditorwidgetconfig.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgssnapper.h"
|
||||
#include "qgsfield.h"
|
||||
@ -36,11 +37,12 @@ class QImage;
|
||||
|
||||
class QgsAttributeAction;
|
||||
class QgsCoordinateTransform;
|
||||
class QgsEditorWidgetWrapper;
|
||||
class QgsFeatureRequest;
|
||||
class QgsGeometry;
|
||||
class QgsGeometryVertexIndex;
|
||||
class QgsMapToPixel;
|
||||
class QgsLabel;
|
||||
class QgsMapToPixel;
|
||||
class QgsRectangle;
|
||||
class QgsVectorDataProvider;
|
||||
class QgsSingleSymbolRendererV2;
|
||||
@ -69,7 +71,6 @@ class CORE_EXPORT QgsAttributeEditorElement : public QObject
|
||||
AeTypeInvalid
|
||||
};
|
||||
|
||||
|
||||
QgsAttributeEditorElement( AttributeEditorType type, QString name, QObject *parent = NULL )
|
||||
: QObject( parent ), mType( type ), mName( name ) {}
|
||||
|
||||
@ -96,7 +97,9 @@ class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement
|
||||
|
||||
virtual QDomElement toDomElement( QDomDocument& doc ) const;
|
||||
virtual void addChildElement( QgsAttributeEditorElement *widget );
|
||||
virtual bool isGroupBox() const { return true; }
|
||||
QList<QgsAttributeEditorElement*> children() const { return mChildren; }
|
||||
virtual QList<QgsAttributeEditorElement*> findElements( AttributeEditorType type ) const;
|
||||
|
||||
private:
|
||||
QList<QgsAttributeEditorElement*> mChildren;
|
||||
@ -431,19 +434,20 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
Classification,
|
||||
EditRange,
|
||||
SliderRange,
|
||||
CheckBox, /**< @note added in 1.4 */
|
||||
CheckBox, /**< @note added in 1.4 */
|
||||
FileName,
|
||||
Enumeration,
|
||||
Immutable, /**< The attribute value should not be changed in the attribute form */
|
||||
Hidden, /**< The attribute value should not be shown in the attribute form @note added in 1.4 */
|
||||
TextEdit, /**< multiline edit @note added in 1.4*/
|
||||
Calendar, /**< calendar widget @note added in 1.5 */
|
||||
DialRange, /**< dial range @note added in 1.5 */
|
||||
ValueRelation, /**< value map from an table @note added in 1.8 */
|
||||
UuidGenerator, /**< uuid generator - readonly and automatically intialized @note added in 1.9 */
|
||||
Photo, /**< phote widget @note added in 1.9 */
|
||||
WebView, /**< webview widget @note added in 1.9 */
|
||||
Color, /**< color @note added in 1.9 */
|
||||
Immutable, /**< The attribute value should not be changed in the attribute form */
|
||||
Hidden, /**< The attribute value should not be shown in the attribute form @note added in 1.4 */
|
||||
TextEdit, /**< multiline edit @note added in 1.4*/
|
||||
Calendar, /**< calendar widget @note added in 1.5 */
|
||||
DialRange, /**< dial range @note added in 1.5 */
|
||||
ValueRelation, /**< value map from an table @note added in 1.8 */
|
||||
UuidGenerator, /**< uuid generator - readonly and automatically intialized @note added in 1.9 */
|
||||
Photo, /**< phote widget @note added in 1.9 */
|
||||
WebView, /**< webview widget @note added in 1.9 */
|
||||
Color, /**< color @note added in 1.9 */
|
||||
EditorWidgetV2, /**< modularized edit widgets @note added in 2.1 */
|
||||
};
|
||||
|
||||
/** Types of feature form suppression after feature creation
|
||||
@ -1034,27 +1038,57 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
@note added in version 1.2 */
|
||||
bool addAttribute( const QgsField &field );
|
||||
|
||||
/**Sets an alias (a display name) for attributes to display in dialogs
|
||||
@note added in version 1.2*/
|
||||
/**
|
||||
* Sets an alias (a display name) for attributes to display in dialogs
|
||||
* @note added in version 1.2
|
||||
*/
|
||||
void addAttributeAlias( int attIndex, QString aliasString );
|
||||
|
||||
/**Adds a tab (for the attribute editor form) holding groups and fields
|
||||
@note added in version 1.9*/
|
||||
/**
|
||||
* Adds a tab (for the attribute editor form) holding groups and fields
|
||||
* @note added in version 2.0
|
||||
*/
|
||||
void addAttributeEditorWidget( QgsAttributeEditorElement* data );
|
||||
|
||||
/**Returns a list of tabs holding groups and fields
|
||||
@note added in version 1.9*/
|
||||
/**
|
||||
* Get the id for the editor widget used to represent the field at the given index
|
||||
*
|
||||
* @param fieldIdx The index of the field
|
||||
*
|
||||
* @return The id for the editor widget or a NULL string if not applicable
|
||||
*/
|
||||
const QString editorWidgetV2( int fieldIdx );
|
||||
|
||||
/**
|
||||
* Get the configuration for the editor widget used to represent the field at the given index
|
||||
*
|
||||
* @param fieldIdx The index of the field
|
||||
*
|
||||
* @return The id for the editor widget or a NULL string if not configured
|
||||
*/
|
||||
const QgsEditorWidgetConfig editorWidgetV2Config( int fieldIdx );
|
||||
|
||||
/**
|
||||
* Returns a list of tabs holding groups and fields
|
||||
* @note added in version 2.0
|
||||
*/
|
||||
QList< QgsAttributeEditorElement* > &attributeEditorElements();
|
||||
/**Clears all the tabs for the attribute editor form
|
||||
@note added in version 1.9*/
|
||||
/**
|
||||
* Clears all the tabs for the attribute editor form
|
||||
* @note added in version 2.0
|
||||
*/
|
||||
void clearAttributeEditorWidgets();
|
||||
|
||||
/**Returns the alias of an attribute name or an empty string if there is no alias
|
||||
@note added in version 1.2*/
|
||||
/**
|
||||
* Returns the alias of an attribute name or an empty string if there is no alias
|
||||
* @note added in version 1.2
|
||||
*/
|
||||
QString attributeAlias( int attributeIndex ) const;
|
||||
|
||||
/**Convenience function that returns the attribute alias if defined or the field name else
|
||||
@note added in version 1.2*/
|
||||
/**
|
||||
* Convenience function that returns the attribute alias if defined or the field name else
|
||||
* @note added in version 1.2
|
||||
*/
|
||||
QString attributeDisplayName( int attributeIndex ) const;
|
||||
|
||||
const QMap< QString, QString >& attributeAliases() const { return mAttributeAliasMap; }
|
||||
@ -1118,6 +1152,10 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
/** set the active layout for the attribute editor for this layer (added in 1.9) */
|
||||
void setEditorLayout( EditorLayout editorLayout );
|
||||
|
||||
void setEditorWidgetV2( int attrIdx, const QString& widgetType );
|
||||
|
||||
void setEditorWidgetV2Config( int attrIdx, const QMap<QString, QVariant>& config );
|
||||
|
||||
/** set string representing 'true' for a checkbox (added in 1.4) */
|
||||
void setCheckedState( int idx, QString checked, QString notChecked );
|
||||
|
||||
@ -1268,6 +1306,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
*/
|
||||
int layerTransparency() const;
|
||||
|
||||
QString metadata();
|
||||
|
||||
/** @note not available in python bindings */
|
||||
inline QgsGeometryCache* cache() { return mCache; }
|
||||
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Select feature by its ID
|
||||
@ -1323,11 +1367,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
@note added in 1.7 */
|
||||
void checkJoinLayerRemove( QString theLayerId );
|
||||
|
||||
QString metadata();
|
||||
|
||||
/** @note not available in python bindings */
|
||||
inline QgsGeometryCache* cache() { return mCache; }
|
||||
|
||||
/**
|
||||
* @brief Is called when the cache image is being deleted. Overwrite and use to clean up.
|
||||
* @note added in 2.0
|
||||
@ -1564,6 +1603,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
QMap< QString, QString> mDateFormats;
|
||||
QMap< QString, QSize> mWidgetSize;
|
||||
|
||||
QMap<int, QString> mEditorWidgetV2Types;
|
||||
QMap<int, QMap<QString, QVariant> > mEditorWidgetV2Configs;
|
||||
|
||||
/** Defines the default layout to use for the attribute editor (Drag and drop, UI File, Generated) */
|
||||
EditorLayout mEditorLayout;
|
||||
|
||||
|
||||
@ -48,6 +48,11 @@ attributetable/qgsfeaturelistviewdelegate.cpp
|
||||
attributetable/qgsfeatureselectionmodel.cpp
|
||||
attributetable/qgsdualview.cpp
|
||||
|
||||
editorwidgets/core/qgseditorconfigwidget.cpp
|
||||
editorwidgets/core/qgseditorwidgetfactory.cpp
|
||||
editorwidgets/core/qgseditorwidgetregistry.cpp
|
||||
editorwidgets/core/qgseditorwidgetwrapper.cpp
|
||||
|
||||
qgisgui.cpp
|
||||
qgisinterface.cpp
|
||||
qgsannotationitem.cpp
|
||||
@ -97,6 +102,7 @@ qgsnewvectorlayerdialog.cpp
|
||||
qgsnumericsortlistviewitem.cpp
|
||||
qgsoptionsdialogbase.cpp
|
||||
qgscredentialdialog.cpp
|
||||
qgsattributeeditorcontext.cpp
|
||||
qgsowssourceselect.cpp
|
||||
qgsprojectbadlayerguihandler.cpp
|
||||
qgsprojectionselector.cpp
|
||||
@ -177,6 +183,10 @@ attributetable/qgsfeatureselectionmodel.h
|
||||
attributetable/qgsfeaturelistviewdelegate.h
|
||||
attributetable/qgsdualview.h
|
||||
|
||||
editorwidgets/core/qgseditorconfigwidget.h
|
||||
editorwidgets/core/qgseditorwidgetregistry.h
|
||||
editorwidgets/core/qgseditorwidgetwrapper.h
|
||||
|
||||
qgsattributedialog.h
|
||||
qgsattributeeditor.h
|
||||
qgsblendmodecombobox.h
|
||||
@ -236,6 +246,7 @@ QT4_WRAP_CPP(QGIS_GUI_MOC_SRCS ${QGIS_GUI_MOC_HDRS})
|
||||
SET(QGIS_GUI_HDRS
|
||||
qgisgui.h
|
||||
qgisinterface.h
|
||||
qgsattributeeditorcontext.h
|
||||
qgsbusyindicatordialog.h
|
||||
qgscharacterselectdialog.h
|
||||
qgscolordialog.h
|
||||
@ -296,6 +307,11 @@ attributetable/qgsfeaturelistviewdelegate.h
|
||||
attributetable/qgsfeatureselectionmodel.h
|
||||
attributetable/qgsdualview.h
|
||||
|
||||
editorwidgets/core/qgseditorconfigwidget.h
|
||||
editorwidgets/core/qgseditorwidgetfactory.h
|
||||
editorwidgets/core/qgseditorwidgetregistry.h
|
||||
editorwidgets/core/qgseditorwidgetwrapper.h
|
||||
|
||||
raster/qgsrasterrendererwidget.h
|
||||
)
|
||||
|
||||
@ -339,6 +355,8 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/symbology-ng
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/attributetable
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/editorwidgets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/editorwidgets/core
|
||||
../core
|
||||
../core/composer
|
||||
../core/raster
|
||||
|
||||
36
src/gui/editorwidgets/core/qgseditorconfigwidget.cpp
Normal file
36
src/gui/editorwidgets/core/qgseditorconfigwidget.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/***************************************************************************
|
||||
qgseditorconfigwidget.cpp
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgseditorconfigwidget.h"
|
||||
|
||||
|
||||
QgsEditorConfigWidget::QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, mLayer( vl )
|
||||
, mField( fieldIdx )
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
int QgsEditorConfigWidget::field()
|
||||
{
|
||||
return mField;
|
||||
}
|
||||
|
||||
QgsVectorLayer*QgsEditorConfigWidget::layer()
|
||||
{
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
84
src/gui/editorwidgets/core/qgseditorconfigwidget.h
Normal file
84
src/gui/editorwidgets/core/qgseditorconfigwidget.h
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
qgseditorconfigwidget.h
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSEDITORCONFIGWIDGET_H
|
||||
#define QGSEDITORCONFIGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**
|
||||
* This class should be subclassed for every configurable editor widget type.
|
||||
*
|
||||
* It implements the GUI configuration widget and transforms this to/from a configuration.
|
||||
*
|
||||
* It will only be instantiated by {@see QgsEditorWidgetFactory}
|
||||
*/
|
||||
|
||||
class GUI_EXPORT QgsEditorConfigWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Create a new configuration widget
|
||||
*
|
||||
* @param vl The layer for which the configuration dialog will be created
|
||||
* @param fieldIdx The index of the field on the layer for which this dialog will be created
|
||||
* @param parent A parent widget
|
||||
*/
|
||||
explicit QgsEditorConfigWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent );
|
||||
|
||||
/**
|
||||
* @brief Create a configuration from the current GUI state
|
||||
*
|
||||
* @return A widget configuration
|
||||
*/
|
||||
virtual QgsEditorWidgetConfig config() = 0;
|
||||
|
||||
/**
|
||||
* @brief Update the configuration widget to represent the given configuration.
|
||||
*
|
||||
* @param config The configuration which should be represented by this widget
|
||||
*/
|
||||
virtual void setConfig( const QgsEditorWidgetConfig& config ) = 0;
|
||||
|
||||
/**
|
||||
* Returns the field for which this configuration widget applies
|
||||
*
|
||||
* @return The field index
|
||||
*/
|
||||
int field();
|
||||
|
||||
/**
|
||||
* Returns the layer for which this configuration widget applies
|
||||
*
|
||||
* @return The layer
|
||||
*/
|
||||
QgsVectorLayer* layer();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~QgsEditorConfigWidget() {}
|
||||
|
||||
private:
|
||||
QgsVectorLayer* mLayer;
|
||||
int mField;
|
||||
};
|
||||
|
||||
#endif // QGSEDITORCONFIGWIDGET_H
|
||||
49
src/gui/editorwidgets/core/qgseditorwidgetfactory.cpp
Normal file
49
src/gui/editorwidgets/core/qgseditorwidgetfactory.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/***************************************************************************
|
||||
qgseditorwidgetfactory.cpp
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
|
||||
QgsEditorWidgetFactory::QgsEditorWidgetFactory( const QString& name )
|
||||
: mName( name )
|
||||
{
|
||||
}
|
||||
|
||||
QgsEditorWidgetFactory::~QgsEditorWidgetFactory()
|
||||
{
|
||||
}
|
||||
|
||||
QString QgsEditorWidgetFactory::name()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
QgsEditorWidgetConfig QgsEditorWidgetFactory::readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx )
|
||||
{
|
||||
Q_UNUSED( configElement );
|
||||
Q_UNUSED( layer );
|
||||
Q_UNUSED( fieldIdx );
|
||||
|
||||
return QgsEditorWidgetConfig();
|
||||
}
|
||||
|
||||
void QgsEditorWidgetFactory::writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx )
|
||||
{
|
||||
Q_UNUSED( config );
|
||||
Q_UNUSED( configElement );
|
||||
Q_UNUSED( doc );
|
||||
Q_UNUSED( layer );
|
||||
Q_UNUSED( fieldIdx );
|
||||
}
|
||||
|
||||
163
src/gui/editorwidgets/core/qgseditorwidgetfactory.h
Normal file
163
src/gui/editorwidgets/core/qgseditorwidgetfactory.h
Normal file
@ -0,0 +1,163 @@
|
||||
/***************************************************************************
|
||||
qgseditorwidgetfactory.h
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSEDITORWIDGETFACTORY_H
|
||||
#define QGSEDITORWIDGETFACTORY_H
|
||||
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
#include "qgsapplication.h"
|
||||
|
||||
#include <QDomNode>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
class QgsEditorConfigWidget;
|
||||
|
||||
/**
|
||||
* Every attribute editor widget needs a factory, which inherits this class
|
||||
*
|
||||
* It provides metadata for the widgets such as the name (human readable), it serializes
|
||||
* the configuration to an xml structure and loads the configuration from there.
|
||||
*
|
||||
* It also has factory methods to create a widget wrapper for the attribute editor itself
|
||||
* and another factory method to create a configuration dialog.
|
||||
*/
|
||||
class GUI_EXPORT QgsEditorWidgetFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param name A human readable name for this widget type
|
||||
*/
|
||||
QgsEditorWidgetFactory( const QString& name );
|
||||
|
||||
virtual ~QgsEditorWidgetFactory();
|
||||
|
||||
/**
|
||||
* Override this in your implementation.
|
||||
* Create a new editor widget wrapper. Call {@link QgsEditorWidgetRegistry::create()}
|
||||
* instead of calling this method directly.
|
||||
*
|
||||
* @param vl The vector layer on which this widget will act
|
||||
* @param fieldIdx The field index on which this widget will act
|
||||
* @param editor An editor widget if already existent. If NULL is provided, a new widget will be created.
|
||||
* @param parent The parent for the wrapper class and any created widget.
|
||||
*
|
||||
* @return A new widget wrapper
|
||||
*/
|
||||
virtual QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const = 0;
|
||||
|
||||
/**
|
||||
* Return The human readable name of this widget type
|
||||
*
|
||||
* By default returns the name specified when constructing and does not need to be overwritten
|
||||
*
|
||||
* @return a name
|
||||
*/
|
||||
virtual QString name();
|
||||
|
||||
/**
|
||||
* Override this in your implementation.
|
||||
* Create a new configuration widget for this widget type.
|
||||
*
|
||||
* @param vl The layer for which the widget will be created
|
||||
* @param fieldIdx The field index for which the widget will be created
|
||||
* @param parent The parent widget of the created config widget
|
||||
*
|
||||
* @return A configuration widget
|
||||
*/
|
||||
virtual QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent ) const = 0;
|
||||
|
||||
/**
|
||||
* Read the config from an XML file and map it to a proper {@link QgsEditorWidgetConfig}.
|
||||
*
|
||||
* @param configElement The configuration element from the project file
|
||||
* @param layer The layer for which this configuration applies
|
||||
* @param fieldIdx The field on the layer for which this configuration applies
|
||||
*
|
||||
* @return A configuration object. This will be passed to your widget wrapper later on
|
||||
*/
|
||||
virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx );
|
||||
|
||||
/**
|
||||
* Serialize your configuration and save it in a xml doc.
|
||||
*
|
||||
* @param config The configuration to serialize
|
||||
* @param configElement The element, where you can write your configuration into
|
||||
* @param doc The document. You can use this to create new nodes
|
||||
* @param layer The layer for which this configuration applies
|
||||
* @param fieldIdx The field on the layer for which this configuration applies
|
||||
*/
|
||||
virtual void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx );
|
||||
|
||||
private:
|
||||
QString mName;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a templated wrapper class, which inherits QgsEditWidgetFactory and does the boring work for you.
|
||||
* C++ only
|
||||
*/
|
||||
template<typename F, typename G>
|
||||
class GUI_EXPORT QgsEditWidgetFactoryHelper : public QgsEditorWidgetFactory
|
||||
{
|
||||
public:
|
||||
QgsEditWidgetFactoryHelper( QString name )
|
||||
: QgsEditorWidgetFactory( name ) {}
|
||||
|
||||
QgsEditorWidgetWrapper* create( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent ) const
|
||||
{
|
||||
return new F( vl, fieldIdx, editor, parent );
|
||||
}
|
||||
|
||||
QgsEditorConfigWidget* configWidget( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
|
||||
{
|
||||
return new G( vl, fieldIdx, parent );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the config from an XML file and map it to a proper {@link QgsEditorWidgetConfig}.
|
||||
*
|
||||
* Implement this method yourself somewhere with the class template parameters
|
||||
* specified. To keep things clean, every implementation of this class should be placed
|
||||
* next to the associated widget factory implementation.
|
||||
*
|
||||
* @param configElement The configuration element from the project file
|
||||
* @param layer The layer for which this configuration applies
|
||||
* @param fieldIdx The field on the layer for which this configuration applies
|
||||
*
|
||||
* @return A configuration object. This will be passed to your widget wrapper later on
|
||||
*/
|
||||
|
||||
virtual QgsEditorWidgetConfig readConfig( const QDomElement& configElement, QgsVectorLayer* layer, int fieldIdx );
|
||||
|
||||
/**
|
||||
* Serialize your configuration and save it in a xml doc.
|
||||
*
|
||||
* Implement this method yourself somewhere with the class template parameters
|
||||
* specified. To keep things clean, every implementation of this class should be placed
|
||||
* next to the associated widget factory implementation.
|
||||
*
|
||||
* @param config The configuration to serialize
|
||||
* @param configElement The element, where you can write your configuration into
|
||||
* @param doc The document. You can use this to create new nodes
|
||||
* @param layer The layer for which this configuration applies
|
||||
* @param fieldIdx The field on the layer for which this configuration applies
|
||||
*/
|
||||
virtual void writeConfig( const QgsEditorWidgetConfig& config, QDomElement& configElement, const QDomDocument& doc, const QgsVectorLayer* layer, int fieldIdx );
|
||||
};
|
||||
|
||||
#endif // QGSEDITORWIDGETFACTORY_H
|
||||
218
src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp
Normal file
218
src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
/***************************************************************************
|
||||
qgseditorwidgetregistry.cpp
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgseditorwidgetregistry.h"
|
||||
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsmessagelog.h"
|
||||
|
||||
|
||||
QgsEditorWidgetRegistry QgsEditorWidgetRegistry::sInstance;
|
||||
|
||||
QgsEditorWidgetRegistry* QgsEditorWidgetRegistry::instance()
|
||||
{
|
||||
return &sInstance;
|
||||
}
|
||||
|
||||
QgsEditorWidgetRegistry::QgsEditorWidgetRegistry()
|
||||
{
|
||||
connect( QgsProject::instance(), SIGNAL( readMapLayer( QgsMapLayer*, const QDomElement& ) ), this, SLOT( readMapLayer( QgsMapLayer*, const QDomElement& ) ) );
|
||||
connect( QgsProject::instance(), SIGNAL( writeMapLayer( QgsMapLayer*, QDomElement&, QDomDocument& ) ), this, SLOT( writeMapLayer( QgsMapLayer*, QDomElement&, QDomDocument& ) ) );
|
||||
}
|
||||
|
||||
QgsEditorWidgetRegistry::~QgsEditorWidgetRegistry()
|
||||
{
|
||||
qDeleteAll( mWidgetFactories.values() );
|
||||
}
|
||||
|
||||
QgsEditorWidgetWrapper* QgsEditorWidgetRegistry::create( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* editor, QWidget* parent )
|
||||
{
|
||||
if ( mWidgetFactories.contains( widgetId ) )
|
||||
{
|
||||
QgsEditorWidgetWrapper* ww = mWidgetFactories[widgetId]->create( vl, fieldIdx, editor, parent );
|
||||
if ( ww )
|
||||
{
|
||||
ww->setConfig( config );
|
||||
return ww;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QgsEditorConfigWidget* QgsEditorWidgetRegistry::createConfigWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
|
||||
{
|
||||
if ( mWidgetFactories.contains( widgetId ) )
|
||||
{
|
||||
return mWidgetFactories[widgetId]->configWidget( vl, fieldIdx, parent );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString QgsEditorWidgetRegistry::name( const QString& widgetId )
|
||||
{
|
||||
if ( mWidgetFactories.contains( widgetId ) )
|
||||
{
|
||||
return mWidgetFactories[widgetId]->name();
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QMap<QString, QgsEditorWidgetFactory*> QgsEditorWidgetRegistry::factories()
|
||||
{
|
||||
return mWidgetFactories;
|
||||
}
|
||||
|
||||
bool QgsEditorWidgetRegistry::registerWidget( const QString& widgetId, QgsEditorWidgetFactory* widgetFactory )
|
||||
{
|
||||
if ( !widgetFactory )
|
||||
{
|
||||
QgsMessageLog::instance()->logMessage( "QgsEditorWidgetRegistry: Factory not valid." );
|
||||
return false;
|
||||
}
|
||||
else if ( mWidgetFactories.contains( widgetId ) )
|
||||
{
|
||||
QgsMessageLog::instance()->logMessage( QString( "QgsEditorWidgetRegistry: Factory with id %1 already registered." ).arg( widgetId ) );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mWidgetFactories.insert( widgetId, widgetFactory );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomElement& layerElem )
|
||||
{
|
||||
if ( mapLayer->type() != QgsMapLayer::VectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
|
||||
if ( !vectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int idx = 0; idx < vectorLayer->pendingFields().count(); ++idx )
|
||||
{
|
||||
if ( vectorLayer->editType( idx ) != QgsVectorLayer::EditorWidgetV2 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QDomNodeList editTypeNodes = layerElem.namedItem( "edittypes" ).childNodes();
|
||||
|
||||
for ( int i = 0; i < editTypeNodes.size(); i++ )
|
||||
{
|
||||
QDomNode editTypeNode = editTypeNodes.at( i );
|
||||
QDomElement editTypeElement = editTypeNode.toElement();
|
||||
|
||||
QString name = editTypeElement.attribute( "name" );
|
||||
|
||||
if ( vectorLayer->fieldNameIndex( name ) != idx )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer::EditType editType =
|
||||
( QgsVectorLayer::EditType ) editTypeElement.attribute( "type" ).toInt();
|
||||
|
||||
if ( editType != QgsVectorLayer::EditorWidgetV2 )
|
||||
continue;
|
||||
|
||||
QString ewv2Type = editTypeElement.attribute( "widgetv2type" );
|
||||
|
||||
if ( mWidgetFactories.contains( ewv2Type ) )
|
||||
{
|
||||
vectorLayer->setEditorWidgetV2( idx, ewv2Type );
|
||||
QDomElement ewv2CfgElem = editTypeElement.namedItem( "widgetv2config" ).toElement();
|
||||
|
||||
if ( !ewv2CfgElem.isNull() )
|
||||
{
|
||||
QMap<QString, QVariant> cfg = mWidgetFactories[ewv2Type]->readConfig( ewv2CfgElem, vectorLayer, idx );
|
||||
vectorLayer->setEditorWidgetV2Config( idx, cfg );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsMessageLog::logMessage( tr( "Unknown attribute editor widget '%1'" ).arg( ewv2Type ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc )
|
||||
{
|
||||
if ( mapLayer->type() != QgsMapLayer::VectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
|
||||
if ( !vectorLayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int idx = 0; idx < vectorLayer->pendingFields().count(); ++idx )
|
||||
{
|
||||
if ( vectorLayer->editType( idx ) != QgsVectorLayer::EditorWidgetV2 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString& widgetType = vectorLayer->editorWidgetV2( idx );
|
||||
if ( !mWidgetFactories.contains( widgetType ) )
|
||||
{
|
||||
QgsMessageLog::logMessage( tr( "Could not save unknown editor widget type '%1'." ).arg( widgetType ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
QDomNodeList editTypeNodes = layerElem.namedItem( "edittypes" ).childNodes();
|
||||
|
||||
for ( int i = 0; i < editTypeNodes.size(); i++ )
|
||||
{
|
||||
QDomElement editTypeElement = editTypeNodes.at( i ).toElement();
|
||||
|
||||
QString name = editTypeElement.attribute( "name" );
|
||||
|
||||
if ( vectorLayer->fieldNameIndex( name ) != idx )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer::EditType editType =
|
||||
( QgsVectorLayer::EditType ) editTypeElement.attribute( "type" ).toInt();
|
||||
|
||||
if ( editType != QgsVectorLayer::EditorWidgetV2 )
|
||||
continue;
|
||||
|
||||
editTypeElement.setAttribute( "widgetv2type", widgetType );
|
||||
|
||||
if ( mWidgetFactories.contains( widgetType ) )
|
||||
{
|
||||
QDomElement ewv2CfgElem = doc.createElement( "widgetv2config" );
|
||||
|
||||
mWidgetFactories[widgetType]->writeConfig( vectorLayer->editorWidgetV2Config( idx ), ewv2CfgElem, doc, vectorLayer, idx );
|
||||
|
||||
editTypeElement.appendChild( ewv2CfgElem );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsMessageLog::logMessage( tr( "Unknown attribute editor widget '%1'" ).arg( widgetType ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
119
src/gui/editorwidgets/core/qgseditorwidgetregistry.h
Normal file
119
src/gui/editorwidgets/core/qgseditorwidgetregistry.h
Normal file
@ -0,0 +1,119 @@
|
||||
/***************************************************************************
|
||||
qgseditorwidgetregistry.h
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSEDITORWIDGETREGISTRY_H
|
||||
#define QGSEDITORWIDGETREGISTRY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
|
||||
class QgsMapLayer;
|
||||
class QDomNode;
|
||||
|
||||
/**
|
||||
* This class manages all known edit widget factories
|
||||
*/
|
||||
class GUI_EXPORT QgsEditorWidgetRegistry : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* This class is a singleton and has therefore to be accessed with this method instead
|
||||
* of a constructor.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static QgsEditorWidgetRegistry* instance();
|
||||
~QgsEditorWidgetRegistry();
|
||||
|
||||
/**
|
||||
* Create an attribute editor widget wrapper of a given type for a given field.
|
||||
* The editor may be NULL if you want the widget wrapper to create a default widget.
|
||||
*
|
||||
* @param widgetId The id of the widget type to create an attribute editor for
|
||||
* @param vl The vector layer for which this widget will be created
|
||||
* @param fieldIdx The field index on the specified layer for which this widget will be created
|
||||
* @param config A configuration which should be used for the widget creation
|
||||
* @param editor An editor widget which will be used instead of an autocreated widget
|
||||
* @param parent The parent which will be used for the created wrapper and the created widget
|
||||
*
|
||||
* @return A new widget wrapper
|
||||
*/
|
||||
QgsEditorWidgetWrapper* create( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, const QgsEditorWidgetConfig& config, QWidget* editor, QWidget* parent );
|
||||
|
||||
/**
|
||||
* Creates a configuration widget
|
||||
*
|
||||
* @param widgetId The id of the widget type to create a configuration widget for
|
||||
* @param vl The vector layer for which this widget will be created
|
||||
* @param fieldIdx The field index on the specified layer for which this widget will be created
|
||||
* @param parent The parent widget for the created widget
|
||||
*
|
||||
* @return A new configuration widget
|
||||
*/
|
||||
QgsEditorConfigWidget* createConfigWidget( const QString& widgetId, QgsVectorLayer* vl, int fieldIdx, QWidget* parent );
|
||||
|
||||
/**
|
||||
* Get the human readable name for a widget type
|
||||
*
|
||||
* @param widgetId The widget type to get the name for
|
||||
*
|
||||
* @return A human readable name
|
||||
*/
|
||||
QString name( const QString& widgetId );
|
||||
|
||||
/**
|
||||
* Get access to all registered factories
|
||||
*
|
||||
* @return All ids and factories
|
||||
*/
|
||||
const QMap<QString, QgsEditorWidgetFactory*> factories();
|
||||
|
||||
/**
|
||||
* The other part which does the boring work for you
|
||||
*/
|
||||
template <class W, class C>
|
||||
void registerWidget( const QString& widgetType, const QString& name )
|
||||
{
|
||||
mWidgetFactories.insert( widgetType, new QgsEditWidgetFactoryHelper<W, C>( name ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new widget factory with the given id
|
||||
*
|
||||
* @param widgetId The id which will be used later to refer to this widget type
|
||||
* @param widgetFactory The factory which will create this widget type
|
||||
*
|
||||
* @return true, if successful, false, if the widgetId is already in use or widgetFactory is NULL
|
||||
*/
|
||||
bool registerWidget( const QString& widgetId, QgsEditorWidgetFactory* widgetFactory );
|
||||
|
||||
protected:
|
||||
QgsEditorWidgetRegistry();
|
||||
|
||||
private slots:
|
||||
void readMapLayer( QgsMapLayer* mapLayer , const QDomElement& layerElem );
|
||||
void writeMapLayer( QgsMapLayer* mapLayer , QDomElement& layerElem, QDomDocument& doc );
|
||||
|
||||
private:
|
||||
QMap<QString, QgsEditorWidgetFactory*> mWidgetFactories;
|
||||
static QgsEditorWidgetRegistry sInstance;
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSEDITORWIDGETREGISTRY_H
|
||||
94
src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
Normal file
94
src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/***************************************************************************
|
||||
qgseditorwidgetwrapper.cpp
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QgsEditorWidgetWrapper::QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent )
|
||||
: QObject( parent )
|
||||
, mWidget( editor )
|
||||
, mParent( parent )
|
||||
, mLayer( vl )
|
||||
{
|
||||
mField = fieldIdx;
|
||||
}
|
||||
|
||||
QWidget* QgsEditorWidgetWrapper::widget()
|
||||
{
|
||||
if ( !mWidget )
|
||||
{
|
||||
mWidget = createWidget( mParent );
|
||||
mWidget->setProperty( "EWV2Wrapper", QVariant::fromValue( this ) );
|
||||
initWidget( mWidget );
|
||||
}
|
||||
|
||||
return mWidget;
|
||||
}
|
||||
|
||||
void QgsEditorWidgetWrapper::setConfig( const QgsEditorWidgetConfig& config )
|
||||
{
|
||||
mConfig = config;
|
||||
// If an editor widget was supplied, we can initialize this now
|
||||
if ( mWidget )
|
||||
{
|
||||
mWidget->setProperty( "EWV2Wrapper", QVariant::fromValue( this ) );
|
||||
initWidget( mWidget );
|
||||
}
|
||||
}
|
||||
|
||||
QVariant QgsEditorWidgetWrapper::config( QString key, QVariant defaultVal )
|
||||
{
|
||||
if ( mConfig.contains( key ) )
|
||||
{
|
||||
return mConfig[key];
|
||||
}
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
QgsVectorLayer* QgsEditorWidgetWrapper::layer()
|
||||
{
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
int QgsEditorWidgetWrapper::field()
|
||||
{
|
||||
return mField;
|
||||
}
|
||||
|
||||
QgsEditorWidgetWrapper* QgsEditorWidgetWrapper::fromWidget( QWidget* widget )
|
||||
{
|
||||
QVariant w = widget->property( "EWV2Wrapper" );
|
||||
|
||||
if ( w.isNull() )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return w.value<QgsEditorWidgetWrapper*>();
|
||||
}
|
||||
|
||||
void QgsEditorWidgetWrapper::initWidget( QWidget* editor )
|
||||
{
|
||||
Q_UNUSED( editor )
|
||||
}
|
||||
|
||||
void QgsEditorWidgetWrapper::setEnabled( bool enabled )
|
||||
{
|
||||
if ( mWidget )
|
||||
{
|
||||
mWidget->setEnabled( enabled );
|
||||
}
|
||||
}
|
||||
181
src/gui/editorwidgets/core/qgseditorwidgetwrapper.h
Normal file
181
src/gui/editorwidgets/core/qgseditorwidgetwrapper.h
Normal file
@ -0,0 +1,181 @@
|
||||
/***************************************************************************
|
||||
qgseditorwidgetwrapper.h
|
||||
--------------------------------------
|
||||
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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSEDITORWIDGETWRAPPER_H
|
||||
#define QGSEDITORWIDGETWRAPPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
#include "qgseditorwidgetconfig.h"
|
||||
|
||||
/**
|
||||
* Manages an editor widget
|
||||
* Widget and wrapper share the same parent
|
||||
*
|
||||
* A wrapper controls one attribute editor widget and is able to create a default
|
||||
* widget or use a pre-existent widget. It is able to set the widget to the value implied
|
||||
* by a field of a vector layer, or return the value it currently holds. Every time it is changed
|
||||
* it has to emit a valueChanged signal (this does not yet mean, that the value is accepted).
|
||||
*
|
||||
*/
|
||||
class GUI_EXPORT QgsEditorWidgetWrapper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Create a new widget wrapper
|
||||
*
|
||||
* @param vl The layer on which the field is
|
||||
* @param fieldIdx The field which will be controlled
|
||||
* @param editor An editor widget. Can be NULL if one should be autogenerated.
|
||||
* @param parent A parent widget for this widget wrapper and the created widget.
|
||||
*/
|
||||
explicit QgsEditorWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor = 0, QWidget* parent = 0 );
|
||||
|
||||
/**
|
||||
* Will be used to access the widget's value. Read the value from the widget and
|
||||
* return it properly formatted to be saved in the attribute.
|
||||
*
|
||||
* @return The current value the widget represents
|
||||
*/
|
||||
virtual QVariant value() = 0;
|
||||
|
||||
/**
|
||||
* @brief Access the widget managed by this wrapper
|
||||
*
|
||||
* @return The widget
|
||||
*/
|
||||
QWidget* widget();
|
||||
|
||||
/**
|
||||
* @brief Access the widget managed by this wrapper and cast it to a given type
|
||||
* Example: QPushButton* pb = wrapper->widget<QPushButton*>();
|
||||
*
|
||||
* @return The widget as template type or NULL, if it cannot be cast to this type.
|
||||
*/
|
||||
template <class T>
|
||||
T* widget() { return dynamic_cast<T>( mWidget ); }
|
||||
|
||||
/**
|
||||
* Will set the config of this wrapper to the specified config.
|
||||
*
|
||||
* @param config The config for this wrapper
|
||||
*/
|
||||
void setConfig( const QgsEditorWidgetConfig& config );
|
||||
|
||||
/**
|
||||
* Use this inside your overriden classes to access the configuration.
|
||||
*
|
||||
* @param key The configuration option you want to load
|
||||
* @param defaultVal Default value
|
||||
*
|
||||
* @return the value assigned to this configuration option
|
||||
*/
|
||||
QVariant config( QString key, QVariant defaultVal = QVariant() );
|
||||
|
||||
/**
|
||||
* Returns the whole config
|
||||
*
|
||||
* @return The configuration
|
||||
*/
|
||||
const QgsEditorWidgetConfig config();
|
||||
|
||||
/**
|
||||
* Access the QgsVectorLayer, you are working on
|
||||
*
|
||||
* @return The layer
|
||||
*
|
||||
* @see field()
|
||||
*/
|
||||
QgsVectorLayer* layer();
|
||||
|
||||
/**
|
||||
* Access the field index.
|
||||
*
|
||||
* @return The index of the field you are working on
|
||||
*
|
||||
* @see layer()
|
||||
*/
|
||||
int field();
|
||||
|
||||
/**
|
||||
* Will return a wrapper for a given widget
|
||||
* @param widget The widget which was created by a wrapper
|
||||
* @return The wrapper for the widget or NULL
|
||||
*/
|
||||
static QgsEditorWidgetWrapper* fromWidget( QWidget* widget );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This method should create a new widget with the provided parent. This will only be called
|
||||
* if the form did not already provide a widget, so it is not guaranteed to be called!
|
||||
* You should not do initialisation stuff, which also has to be done for custom editor
|
||||
* widgets inside this method. Things like filling comboboxes and assigning other data which
|
||||
* will also be used to make widgets on forms created in the QtDesigner usable should be assigned
|
||||
* in {@link initWidget(QWidget*)}.
|
||||
*
|
||||
* @param parent You should set this parent on the created widget.
|
||||
* @return A new widget
|
||||
*/
|
||||
virtual QWidget* createWidget( QWidget* parent ) = 0;
|
||||
|
||||
/**
|
||||
* This method should initialize the editor widget with runtime data. Fill your comboboxes here.
|
||||
*
|
||||
* @param editor The widget which will represent this attribute editor in a form.
|
||||
*/
|
||||
virtual void initWidget( QWidget* editor );
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Emit this signal, whenever the value changed.
|
||||
*
|
||||
* @param value The new value
|
||||
*/
|
||||
void valueChanged( const QVariant& value );
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Is called, when the value of the widget needs to be changed. Update the widget representation
|
||||
* to reflect the new value.
|
||||
*
|
||||
* @param value The new value of the attribute
|
||||
*/
|
||||
virtual void setValue( const QVariant& value ) = 0;
|
||||
|
||||
/**
|
||||
* Is used to enable or disable the edit functionality of the managed widget.
|
||||
* By default this will enable or disable the whole widget
|
||||
*
|
||||
* @param enabled Enable or Disable?
|
||||
*/
|
||||
virtual void setEnabled( bool enabled );
|
||||
|
||||
private:
|
||||
QgsEditorWidgetConfig mConfig;
|
||||
QWidget* mWidget;
|
||||
QWidget* mParent;
|
||||
QgsVectorLayer* mLayer;
|
||||
int mField;
|
||||
};
|
||||
|
||||
// We'll use this class inside a QVariant in the widgets properties
|
||||
Q_DECLARE_METATYPE( QgsEditorWidgetWrapper* )
|
||||
|
||||
#endif // QGSEDITORWIDGETWRAPPER_H
|
||||
@ -15,6 +15,7 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgsattributedialog.h"
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
@ -42,52 +43,73 @@
|
||||
#include <QWebView>
|
||||
#include <QPushButton>
|
||||
|
||||
int QgsAttributeDialog::smFormCounter = 0;
|
||||
int QgsAttributeDialog::sFormCounter = 0;
|
||||
QString QgsAttributeDialog::sSettingsPath = "/Windows/AttributeDialog/";
|
||||
|
||||
QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent, bool showDialogButtons )
|
||||
QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer* vl, QgsFeature* thepFeature, bool featureOwner, QWidget* parent, bool showDialogButtons, QgsAttributeEditorContext context )
|
||||
: QObject( parent )
|
||||
, mDialog( 0 )
|
||||
, mSettingsPath( "/Windows/AttributeDialog/" )
|
||||
, mContext( context )
|
||||
, mLayer( vl )
|
||||
, mFeature( thepFeature )
|
||||
, mFeatureOwner( featureOwner )
|
||||
, mHighlight( 0 )
|
||||
, mFormNr( -1 )
|
||||
, mFormNr( sFormCounter++ )
|
||||
, mShowDialogButtons( showDialogButtons )
|
||||
{
|
||||
if ( !mFeature || !vl->dataProvider() )
|
||||
mContext.adjustForLayer( mLayer );
|
||||
init();
|
||||
}
|
||||
|
||||
QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer* vl, QgsFeature* thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent, bool showDialogButtons )
|
||||
: QObject( parent )
|
||||
, mDialog( 0 )
|
||||
, mContext( )
|
||||
, mLayer( vl )
|
||||
, mFeature( thepFeature )
|
||||
, mFeatureOwner( featureOwner )
|
||||
, mHighlight( 0 )
|
||||
, mFormNr( sFormCounter++ )
|
||||
, mShowDialogButtons( showDialogButtons )
|
||||
{
|
||||
mContext.setDistanceArea( myDa );
|
||||
mContext.adjustForLayer( mLayer );
|
||||
init();
|
||||
}
|
||||
|
||||
void QgsAttributeDialog::init()
|
||||
{
|
||||
if ( !mFeature || !mLayer->dataProvider() )
|
||||
return;
|
||||
|
||||
const QgsFields &theFields = vl->pendingFields();
|
||||
const QgsFields &theFields = mLayer->pendingFields();
|
||||
if ( theFields.isEmpty() )
|
||||
return;
|
||||
|
||||
QgsAttributes myAttributes = mFeature->attributes();
|
||||
|
||||
QDialogButtonBox *buttonBox = NULL;
|
||||
|
||||
if ( vl->editorLayout() == QgsVectorLayer::UiFileLayout && !vl->editForm().isEmpty() )
|
||||
if ( mLayer->editorLayout() == QgsVectorLayer::UiFileLayout && !mLayer->editForm().isEmpty() )
|
||||
{
|
||||
// UI-File defined layout
|
||||
QFile file( vl->editForm() );
|
||||
QFile file( mLayer->editForm() );
|
||||
|
||||
if ( file.open( QFile::ReadOnly ) )
|
||||
{
|
||||
QUiLoader loader;
|
||||
|
||||
QFileInfo fi( vl->editForm() );
|
||||
QFileInfo fi( mLayer->editForm() );
|
||||
loader.setWorkingDirectory( fi.dir() );
|
||||
QWidget *myWidget = loader.load( &file, parent );
|
||||
QWidget *myWidget = loader.load( &file, qobject_cast<QWidget*>( parent() ) );
|
||||
file.close();
|
||||
|
||||
mDialog = qobject_cast<QDialog*>( myWidget );
|
||||
buttonBox = myWidget->findChild<QDialogButtonBox*>();
|
||||
}
|
||||
}
|
||||
else if ( vl->editorLayout() == QgsVectorLayer::TabLayout )
|
||||
else if ( mLayer->editorLayout() == QgsVectorLayer::TabLayout )
|
||||
{
|
||||
// Tab display
|
||||
mDialog = new QDialog( parent );
|
||||
mDialog = new QDialog( qobject_cast<QWidget*>( parent() ) );
|
||||
|
||||
QGridLayout *gridLayout;
|
||||
QTabWidget *tabWidget;
|
||||
@ -99,7 +121,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
tabWidget = new QTabWidget( mDialog );
|
||||
gridLayout->addWidget( tabWidget );
|
||||
|
||||
foreach ( const QgsAttributeEditorElement *widgDef, vl->attributeEditorElements() )
|
||||
foreach ( const QgsAttributeEditorElement *widgDef, mLayer->attributeEditorElements() )
|
||||
{
|
||||
QWidget* tabPage = new QWidget( tabWidget );
|
||||
|
||||
@ -108,7 +130,9 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
|
||||
if ( widgDef->type() == QgsAttributeEditorElement::AeTypeContainer )
|
||||
{
|
||||
tabPageLayout->addWidget( QgsAttributeEditor::createWidgetFromDef( widgDef, tabPage, vl, myAttributes, mProxyWidgets, false ) );
|
||||
QString dummy1;
|
||||
bool dummy2;
|
||||
tabPageLayout->addWidget( QgsAttributeEditor::createWidgetFromDef( widgDef, tabPage, mLayer, *mFeature, mContext, dummy1, dummy2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -121,9 +145,10 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
gridLayout->addWidget( buttonBox );
|
||||
}
|
||||
|
||||
// Still no dialog: create the default generated dialog
|
||||
if ( !mDialog )
|
||||
{
|
||||
mDialog = new QDialog( parent );
|
||||
mDialog = new QDialog( qobject_cast<QWidget*>( parent() ) );
|
||||
|
||||
QGridLayout *gridLayout;
|
||||
QFrame *mFrame;
|
||||
@ -174,35 +199,35 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
for ( int fldIdx = 0; fldIdx < theFields.count(); ++fldIdx )
|
||||
{
|
||||
//show attribute alias if available
|
||||
QString myFieldName = vl->attributeDisplayName( fldIdx );
|
||||
QString myFieldName = mLayer->attributeDisplayName( fldIdx );
|
||||
// by default (until user defined alias) append date format
|
||||
// (validator does not allow to enter a value in wrong format)
|
||||
const QgsField &myField = theFields[fldIdx];
|
||||
if ( myField.type() == QVariant::Date && vl->attributeAlias( fldIdx ).isEmpty() )
|
||||
if ( myField.type() == QVariant::Date && mLayer->attributeAlias( fldIdx ).isEmpty() )
|
||||
{
|
||||
myFieldName += " (" + vl->dateFormat( fldIdx ) + ")";
|
||||
myFieldName += " (" + mLayer->dateFormat( fldIdx ) + ")";
|
||||
}
|
||||
|
||||
QWidget *myWidget = QgsAttributeEditor::createAttributeEditor( 0, 0, vl, fldIdx, myAttributes[fldIdx], mProxyWidgets );
|
||||
QWidget *myWidget = QgsAttributeEditor::createAttributeEditor( mDialog, 0, mLayer, fldIdx, mFeature->attribute( fldIdx ), mContext );
|
||||
if ( !myWidget )
|
||||
continue;
|
||||
|
||||
QLabel *mypLabel = new QLabel( myFieldName, mypInnerFrame );
|
||||
|
||||
if ( vl->editType( fldIdx ) != QgsVectorLayer::Immutable )
|
||||
if ( mLayer->editType( fldIdx ) != QgsVectorLayer::Immutable )
|
||||
{
|
||||
if ( vl->isEditable() && vl->fieldEditable( fldIdx ) )
|
||||
if ( mLayer->isEditable() && mLayer->fieldEditable( fldIdx ) )
|
||||
{
|
||||
myWidget->setEnabled( true );
|
||||
}
|
||||
else if ( vl->editType( fldIdx ) == QgsVectorLayer::Photo )
|
||||
else if ( mLayer->editType( fldIdx ) == QgsVectorLayer::Photo )
|
||||
{
|
||||
foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
w->setEnabled( qobject_cast<QLabel *>( w ) ? true : false );
|
||||
}
|
||||
}
|
||||
else if ( vl->editType( fldIdx ) == QgsVectorLayer::WebView )
|
||||
else if ( mLayer->editType( fldIdx ) == QgsVectorLayer::WebView )
|
||||
{
|
||||
foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
@ -214,13 +239,21 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
w->setEnabled( false );
|
||||
}
|
||||
}
|
||||
else if ( mLayer->editType( fldIdx ) == QgsVectorLayer::EditorWidgetV2 )
|
||||
{
|
||||
QgsEditorWidgetWrapper* ww = QgsEditorWidgetWrapper::fromWidget( myWidget );
|
||||
if ( ww )
|
||||
{
|
||||
ww->setEnabled( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myWidget->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
if ( vl->labelOnTop( fldIdx ) )
|
||||
if ( mLayer->labelOnTop( fldIdx ) )
|
||||
{
|
||||
mypInnerLayout->addWidget( mypLabel, index++, 0, 1, 2 );
|
||||
mypInnerLayout->addWidget( myWidget, index++, 0, 1, 2 );
|
||||
@ -261,28 +294,36 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
|
||||
foreach ( QWidget *myWidget, myWidgets )
|
||||
{
|
||||
QgsAttributeEditor::createAttributeEditor( mDialog, myWidget, vl, fldIdx, myAttributes[fldIdx], mProxyWidgets );
|
||||
QgsAttributeEditor::createAttributeEditor( mDialog, myWidget, mLayer, fldIdx, mFeature->attribute( fldIdx ), mContext );
|
||||
|
||||
if ( vl->editType( fldIdx ) != QgsVectorLayer::Immutable )
|
||||
if ( mLayer->editType( fldIdx ) != QgsVectorLayer::Immutable )
|
||||
{
|
||||
if ( vl->isEditable() && vl->fieldEditable( fldIdx ) )
|
||||
if ( mLayer->isEditable() && mLayer->fieldEditable( fldIdx ) )
|
||||
{
|
||||
myWidget->setEnabled( true );
|
||||
}
|
||||
else if ( vl->editType( fldIdx ) == QgsVectorLayer::Photo )
|
||||
else if ( mLayer->editType( fldIdx ) == QgsVectorLayer::Photo )
|
||||
{
|
||||
foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
w->setEnabled( qobject_cast<QLabel *>( w ) ? true : false );
|
||||
}
|
||||
}
|
||||
else if ( vl->editType( fldIdx ) == QgsVectorLayer::WebView )
|
||||
else if ( mLayer->editType( fldIdx ) == QgsVectorLayer::WebView )
|
||||
{
|
||||
foreach ( QWidget *w, myWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
w->setEnabled( qobject_cast<QWebView *>( w ) ? true : false );
|
||||
}
|
||||
}
|
||||
else if ( mLayer->editType( fldIdx ) == QgsVectorLayer::EditorWidgetV2 )
|
||||
{
|
||||
QgsEditorWidgetWrapper* ww = QgsEditorWidgetWrapper::fromWidget( myWidget );
|
||||
if ( ww )
|
||||
{
|
||||
ww->setEnabled( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myWidget->setEnabled( false );
|
||||
@ -308,15 +349,15 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
if ( !mFeature->geometry() && exp.needsGeometry() )
|
||||
{
|
||||
QgsFeature f;
|
||||
if ( vl->getFeatures( QgsFeatureRequest().setFilterFid( mFeature->id() ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) && f.geometry() )
|
||||
if ( mLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeature->id() ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) && f.geometry() )
|
||||
{
|
||||
mFeature->setGeometry( *f.geometry() );
|
||||
}
|
||||
}
|
||||
|
||||
exp.setGeomCalculator( myDa );
|
||||
exp.setGeomCalculator( mContext.distanceArea() );
|
||||
|
||||
QVariant value = exp.evaluate( mFeature, vl->pendingFields() );
|
||||
QVariant value = exp.evaluate( mFeature, mLayer->pendingFields() );
|
||||
|
||||
if ( !exp.hasEvalError() )
|
||||
{
|
||||
@ -344,7 +385,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
mDialog->setObjectName( "QgsAttributeDialogBase" );
|
||||
|
||||
if ( mDialog->windowTitle().isEmpty() )
|
||||
mDialog->setWindowTitle( tr( "Attributes - %1" ).arg( vl->name() ) );
|
||||
mDialog->setWindowTitle( tr( "Attributes - %1" ).arg( mLayer->name() ) );
|
||||
}
|
||||
|
||||
if ( mShowDialogButtons )
|
||||
@ -353,7 +394,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
{
|
||||
buttonBox->clear();
|
||||
|
||||
if ( vl->isEditable() )
|
||||
if ( mLayer->isEditable() )
|
||||
{
|
||||
buttonBox->setStandardButtons( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
|
||||
connect( buttonBox, SIGNAL( accepted() ), mDialog, SLOT( accept() ) );
|
||||
@ -379,7 +420,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
|
||||
connect( mDialog, SIGNAL( destroyed() ), this, SLOT( dialogDestroyed() ) );
|
||||
|
||||
if ( !vl->editFormInit().isEmpty() )
|
||||
if ( !mLayer->editFormInit().isEmpty() )
|
||||
{
|
||||
#if 0
|
||||
// would be nice if only PyQt's QVariant.toPyObject() wouldn't take ownership
|
||||
@ -387,7 +428,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
vl->setProperty( "featureForm.id", QVariant( mpFeature->id() ) );
|
||||
#endif
|
||||
|
||||
QString module = vl->editFormInit();
|
||||
QString module = mLayer->editFormInit();
|
||||
int pos = module.lastIndexOf( "." );
|
||||
if ( pos >= 0 )
|
||||
{
|
||||
@ -402,15 +443,13 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
|
||||
QgsPythonRunner::run( reload );
|
||||
|
||||
mFormNr = smFormCounter++;
|
||||
|
||||
QString form = QString( "_qgis_featureform_%1 = sip.wrapinstance( %2, QtGui.QDialog )" )
|
||||
.arg( mFormNr )
|
||||
.arg(( unsigned long ) mDialog );
|
||||
|
||||
QString layer = QString( "_qgis_layer_%1 = sip.wrapinstance( %2, qgis.core.QgsVectorLayer )" )
|
||||
.arg( vl->id() )
|
||||
.arg(( unsigned long ) vl );
|
||||
.arg( mLayer->id() )
|
||||
.arg(( unsigned long ) mLayer );
|
||||
|
||||
// Generate the unique ID of this feature. We used to use feature ID but some providers
|
||||
// return a ID that is an invalid python variable when we have new unsaved features.
|
||||
@ -426,9 +465,9 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
|
||||
mReturnvarname = QString( "_qgis_feature_form_%1" ).arg( dt.toString( "yyyyMMddhhmmsszzz" ) );
|
||||
QString expr = QString( "%5 = %1(_qgis_featureform_%2, _qgis_layer_%3, %4)" )
|
||||
.arg( vl->editFormInit() )
|
||||
.arg( mLayer->editFormInit() )
|
||||
.arg( mFormNr )
|
||||
.arg( vl->id() )
|
||||
.arg( mLayer->id() )
|
||||
.arg( featurevarname )
|
||||
.arg( mReturnvarname );
|
||||
|
||||
@ -437,7 +476,7 @@ QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeat
|
||||
}
|
||||
|
||||
// Only restore the geometry of the dialog if it's not a custom one.
|
||||
if ( vl->editorLayout() != QgsVectorLayer::UiFileLayout )
|
||||
if ( mLayer->editorLayout() != QgsVectorLayer::UiFileLayout )
|
||||
{
|
||||
restoreGeometry();
|
||||
}
|
||||
@ -480,7 +519,7 @@ void QgsAttributeDialog::accept()
|
||||
{
|
||||
QVariant value;
|
||||
|
||||
if ( QgsAttributeEditor::retrieveValue( mProxyWidgets.value( idx ), mLayer, idx, value ) )
|
||||
if ( QgsAttributeEditor::retrieveValue( mContext.proxyWidget( mLayer, idx ), mLayer, idx, value ) )
|
||||
mFeature->setAttribute( idx, value );
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,21 +18,37 @@
|
||||
#define QGSATTRIBUTEDIALOG_H
|
||||
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
|
||||
class QDialog;
|
||||
class QgsFeature;
|
||||
class QLayout;
|
||||
class QgsField;
|
||||
class QgsVectorLayer;
|
||||
class QgsHighlight;
|
||||
|
||||
class QgsDistanceArea;
|
||||
class QgsFeature;
|
||||
class QgsField;
|
||||
class QgsHighlight;
|
||||
class QgsVectorLayer;
|
||||
|
||||
class GUI_EXPORT QgsAttributeDialog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief QgsAttributeDialog
|
||||
* @param vl
|
||||
* @param thepFeature
|
||||
* @param featureOwner
|
||||
* @param myDa
|
||||
* @param parent
|
||||
* @param showDialogButtons
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QgsDistanceArea myDa, QWidget* parent = 0, bool showDialogButtons = true );
|
||||
|
||||
QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QWidget* parent = 0, bool showDialogButtons = true, QgsAttributeEditorContext context = QgsAttributeEditorContext() );
|
||||
|
||||
~QgsAttributeDialog();
|
||||
|
||||
/** Saves the size and position for the next time
|
||||
@ -63,18 +79,22 @@ class GUI_EXPORT QgsAttributeDialog : public QObject
|
||||
bool eventFilter( QObject *obj, QEvent *event );
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
QDialog *mDialog;
|
||||
QString mSettingsPath;
|
||||
// Used to sync multiple widgets for the same field
|
||||
QMap<int, QWidget*> mProxyWidgets;
|
||||
QgsAttributeEditorContext mContext;
|
||||
QgsVectorLayer *mLayer;
|
||||
QgsFeature *mFeature;
|
||||
QgsFeature* mFeature;
|
||||
bool mFeatureOwner;
|
||||
QgsHighlight *mHighlight;
|
||||
int mFormNr;
|
||||
static int smFormCounter;
|
||||
bool mShowDialogButtons;
|
||||
QString mReturnvarname;
|
||||
|
||||
static int sFormCounter;
|
||||
static QString sSettingsPath;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -15,18 +15,25 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgseditorwidgetfactory.h"
|
||||
#include "qgseditorwidgetregistry.h"
|
||||
#include "qgseditorwidgetwrapper.h"
|
||||
|
||||
#include "qgsattributedialog.h"
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
#include "qgsattributeeditor.h"
|
||||
#include <qgsvectorlayer.h>
|
||||
#include <qgsvectordataprovider.h>
|
||||
#include <qgscategorizedsymbolrendererv2.h>
|
||||
#include <qgslonglongvalidator.h>
|
||||
#include <qgsfieldvalidator.h>
|
||||
#include <qgsmaplayerregistry.h>
|
||||
#include <qgslogger.h>
|
||||
#include <qgsexpression.h>
|
||||
#include <qgsfilterlineedit.h>
|
||||
#include <qgscolorbutton.h>
|
||||
#include <qgsnetworkaccessmanager.h>
|
||||
#include "qgscategorizedsymbolrendererv2.h"
|
||||
#include "qgscolorbutton.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsfieldvalidator.h"
|
||||
#include "qgsfilterlineedit.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgslonglongvalidator.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QPushButton>
|
||||
@ -265,11 +272,21 @@ QListWidget *QgsAttributeEditor::listWidget( QWidget *editor, QWidget *parent )
|
||||
|
||||
QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value )
|
||||
{
|
||||
QMap<int, QWidget*> dummyProxyWidgets;
|
||||
return createAttributeEditor( parent, editor, vl, idx, value, dummyProxyWidgets );
|
||||
QgsAttributeEditorContext context;
|
||||
context.addProxyWidgets( vl, QMap<int, QWidget*>() );
|
||||
|
||||
return createAttributeEditor( parent, editor, vl, idx, value, context );
|
||||
}
|
||||
|
||||
QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap<int, QWidget*> &proxyWidgets )
|
||||
{
|
||||
QgsAttributeEditorContext context;
|
||||
context.addProxyWidgets( vl, proxyWidgets );
|
||||
|
||||
return createAttributeEditor( parent, editor, vl, idx, value, context );
|
||||
}
|
||||
|
||||
QWidget* QgsAttributeEditor::createAttributeEditor( QWidget* parent, QWidget* editor, QgsVectorLayer* vl, int idx, const QVariant& value, QgsAttributeEditorContext& context )
|
||||
{
|
||||
if ( !vl )
|
||||
return 0;
|
||||
@ -444,6 +461,18 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
|
||||
}
|
||||
break;
|
||||
|
||||
case QgsVectorLayer::EditorWidgetV2:
|
||||
{
|
||||
const QString& widgetType = vl->editorWidgetV2( idx );
|
||||
const QgsEditorWidgetConfig widgetConfig = vl->editorWidgetV2Config( idx );
|
||||
|
||||
QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, vl, idx, widgetConfig, editor, parent );
|
||||
|
||||
if ( eww )
|
||||
myWidget = eww->widget();
|
||||
}
|
||||
break;
|
||||
|
||||
case QgsVectorLayer::Classification:
|
||||
{
|
||||
QMap<QString, QString> classes;
|
||||
@ -658,11 +687,10 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
|
||||
|
||||
QgsStringRelay* relay = NULL;
|
||||
|
||||
QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
|
||||
if ( it != proxyWidgets.end() )
|
||||
QWidget* pwdg = context.proxyWidget( vl, idx );
|
||||
if ( pwdg )
|
||||
{
|
||||
QObject* obj = qvariant_cast<QObject*>(( *it )->property( "QgisAttrEditProxy" ) );
|
||||
relay = qobject_cast<QgsStringRelay*>( obj );
|
||||
relay = pwdg->property( "QgisAttrEditProxy" ).value<QgsStringRelay*>();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -697,7 +725,7 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
|
||||
if ( !cb || cb->isEditable() )
|
||||
{
|
||||
myWidget->setProperty( "QgisAttrEditSlot", QVariant( QByteArray( wSlot ) ) );
|
||||
myWidget->setProperty( "QgisAttrEditProxy", QVariant( QMetaType::QObjectStar, &relay ) );
|
||||
myWidget->setProperty( "QgisAttrEditProxy", QVariant::fromValue<QgsStringRelay*>( relay ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -893,8 +921,7 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
|
||||
break;
|
||||
}
|
||||
|
||||
QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
|
||||
if ( it != proxyWidgets.end() )
|
||||
if ( context.proxyWidget( vl, idx ) )
|
||||
{
|
||||
if ( !synchronized )
|
||||
{
|
||||
@ -903,7 +930,7 @@ QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *ed
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyWidgets.insert( idx, myWidget );
|
||||
context.addProxyWidget( vl, idx, myWidget );
|
||||
}
|
||||
|
||||
setValue( myWidget, vl, idx, value );
|
||||
@ -916,6 +943,14 @@ bool QgsAttributeEditor::retrieveValue( QWidget *widget, QgsVectorLayer *vl, int
|
||||
if ( !widget )
|
||||
return false;
|
||||
|
||||
QgsEditorWidgetWrapper* wrapper = QgsEditorWidgetWrapper::fromWidget( widget );
|
||||
|
||||
if ( wrapper )
|
||||
{
|
||||
value = wrapper->value();
|
||||
return true;
|
||||
}
|
||||
|
||||
const QgsField &theField = vl->pendingFields()[idx];
|
||||
QgsVectorLayer::EditType editType = vl->editType( idx );
|
||||
bool modified = false;
|
||||
@ -1332,12 +1367,20 @@ bool QgsAttributeEditor::setValue( QWidget *editor, QgsVectorLayer *vl, int idx,
|
||||
|
||||
case QgsVectorLayer::Hidden:
|
||||
break;
|
||||
|
||||
case QgsVectorLayer::EditorWidgetV2:
|
||||
QgsEditorWidgetWrapper* wrapper = QgsEditorWidgetWrapper::fromWidget( editor );
|
||||
if ( wrapper )
|
||||
{
|
||||
wrapper->setValue( value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, QgsAttributes &attrs, QMap<int, QWidget*> &proxyWidgets, bool createGroupBox )
|
||||
QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, const QgsFeature& feat, QgsAttributeEditorContext& context, QString& labelText, bool& labelOnTop )
|
||||
{
|
||||
QWidget *newWidget = 0;
|
||||
|
||||
@ -1347,7 +1390,7 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
|
||||
{
|
||||
const QgsAttributeEditorField* fieldDef = dynamic_cast<const QgsAttributeEditorField*>( widgetDef );
|
||||
int fldIdx = fieldDef->idx();
|
||||
newWidget = createAttributeEditor( parent, 0, vl, fldIdx, attrs.value( fldIdx, QVariant() ), proxyWidgets );
|
||||
newWidget = createAttributeEditor( parent, 0, vl, fldIdx, feat.attributes().value( fldIdx, QVariant() ), context );
|
||||
|
||||
if ( newWidget )
|
||||
{
|
||||
@ -1382,7 +1425,8 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
labelOnTop = vl->labelOnTop( fieldDef->idx() );
|
||||
labelText = vl->attributeDisplayName( fieldDef->idx() );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1391,7 +1435,7 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
|
||||
const QgsAttributeEditorContainer* container = dynamic_cast<const QgsAttributeEditorContainer*>( widgetDef );
|
||||
QWidget* myContainer;
|
||||
|
||||
if ( createGroupBox )
|
||||
if ( container->isGroupBox() )
|
||||
{
|
||||
QGroupBox* groupBox = new QGroupBox( parent );
|
||||
groupBox->setTitle( container->name() );
|
||||
@ -1418,26 +1462,23 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
|
||||
|
||||
QList<QgsAttributeEditorElement*> children = container->children();
|
||||
|
||||
for ( QList<QgsAttributeEditorElement*>::const_iterator it = children.begin(); it != children.end(); ++it )
|
||||
Q_FOREACH( QgsAttributeEditorElement* childDef, children )
|
||||
{
|
||||
QgsAttributeEditorElement* childDef = *it;
|
||||
QWidget* editor = createWidgetFromDef( childDef, myContainer, vl, attrs, proxyWidgets, true );
|
||||
QString labelText;
|
||||
bool labelOnTop;
|
||||
QWidget* editor = createWidgetFromDef( childDef, myContainer, vl, feat, context, labelText, labelOnTop );
|
||||
|
||||
if ( childDef->type() == QgsAttributeEditorElement::AeTypeContainer )
|
||||
if ( labelText == QString::null )
|
||||
{
|
||||
gbLayout->addWidget( editor, index, 0, 1, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
const QgsAttributeEditorField* fieldDef = dynamic_cast<const QgsAttributeEditorField*>( childDef );
|
||||
|
||||
//show attribute alias if available
|
||||
QString myFieldName = vl->attributeDisplayName( fieldDef->idx() );
|
||||
QLabel *mypLabel = new QLabel( myFieldName, myContainer );
|
||||
|
||||
if ( vl->labelOnTop( fieldDef->idx() ) )
|
||||
QLabel* mypLabel = new QLabel( labelText );
|
||||
if ( labelOnTop )
|
||||
{
|
||||
gbLayout->addWidget( mypLabel, index++, 0, 1, 2 );
|
||||
gbLayout->addWidget( mypLabel, index, 0, 1, 2 );
|
||||
++index;
|
||||
gbLayout->addWidget( editor, index, 0, 1 , 2 );
|
||||
}
|
||||
else
|
||||
@ -1451,6 +1492,8 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
|
||||
}
|
||||
gbLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index , 0 );
|
||||
|
||||
labelText = QString::null;
|
||||
labelOnTop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -19,15 +19,19 @@
|
||||
|
||||
#include <QVariant>
|
||||
#include <QMetaType>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "qgsfeature.h"
|
||||
|
||||
class QObject;
|
||||
class QWidget;
|
||||
class QgsVectorLayer;
|
||||
class QComboBox;
|
||||
class QListWidget;
|
||||
|
||||
class QgsAttributeEditorContext;
|
||||
class QgsAttributeEditorElement;
|
||||
class QgsDualView;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/* \brief create attribute widget for editing */
|
||||
class GUI_EXPORT QgsAttributeEditor : public QObject
|
||||
@ -35,11 +39,11 @@ class GUI_EXPORT QgsAttributeEditor : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsAttributeEditor( QObject *parent, QgsVectorLayer *vl = 0, int idx = -1 )
|
||||
QgsAttributeEditor( QObject* parent, QgsVectorLayer* vl = 0, int idx = -1 )
|
||||
: QObject( parent )
|
||||
, mLayer( vl )
|
||||
, mIdx( idx )
|
||||
{};
|
||||
{}
|
||||
/**
|
||||
* Creates or prepares a attributre editor widget
|
||||
* @param parent The parent object
|
||||
@ -49,8 +53,10 @@ class GUI_EXPORT QgsAttributeEditor : public QObject
|
||||
* @param value the value to initiate this widget with
|
||||
* @param proxyWidgets an array of widgets, which will act as a value proxy if the same field is inserted multiple times
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
static QWidget *createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap<int, QWidget*> &proxyWidgets );
|
||||
static QWidget* createAttributeEditor( QWidget* parent, QWidget* editor, QgsVectorLayer* vl, int idx, const QVariant &value, QMap<int, QWidget*>& proxyWidgets );
|
||||
|
||||
/**
|
||||
* Creates or prepares a attributre editor widget
|
||||
* @param parent The parent object
|
||||
@ -60,24 +66,42 @@ class GUI_EXPORT QgsAttributeEditor : public QObject
|
||||
* @param value the value to initiate this widget with
|
||||
*
|
||||
*/
|
||||
static QWidget *createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value );
|
||||
static QWidget* createAttributeEditor( QWidget* parent, QWidget* editor, QgsVectorLayer* vl, int idx, const QVariant& value );
|
||||
|
||||
/**
|
||||
* Creates or prepares a attributre editor widget
|
||||
* @param parent The parent object
|
||||
* @param editor The widget to prepare. Set to null if it should be generated
|
||||
* @param vl The vector layer to use as data source
|
||||
* @param idx The field index this widget refers to
|
||||
* @param value the value to initiate this widget with
|
||||
* @param context the context used for the created attribute editor
|
||||
*
|
||||
*/
|
||||
static QWidget* createAttributeEditor( QWidget* parent, QWidget* editor, QgsVectorLayer* vl, int idx, const QVariant& value, QgsAttributeEditorContext& context );
|
||||
|
||||
/**
|
||||
* Creates a widget form a QgsAttributeEditorElement definition. Will recursively generate containers and widgets.
|
||||
* @param widgetDef The definition for the widget
|
||||
* @param parent The parent object
|
||||
* @param vl The vector layer to use as data source
|
||||
* @param attrs Attributes for the current feature.
|
||||
* @param proxyWidgets An array of widgets, which will act as a value proxy if the same field is inserted multiple times
|
||||
* @param createGroupBox If the element is a container, should a GroupBox be created to hold the children?
|
||||
* @param feat The feature to create the widget for
|
||||
* @param context the context used for the created attribute editor
|
||||
* @param [out] labelText An optional label text will be written into the referenced QString. It will be set to
|
||||
* a QString::null value if no label should be shown
|
||||
* @param [out] labelOnTop Will be set to true if the label should be placed on top of the field.
|
||||
* If set to false, the label should be shown left or right of the field
|
||||
*
|
||||
*/
|
||||
static QWidget *createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, QgsAttributes &attrs, QMap<int, QWidget*> &proxyWidgets, bool createGroupBox );
|
||||
static QWidget *createWidgetFromDef( const QgsAttributeEditorElement* widgetDef, QWidget* parent, QgsVectorLayer* vl, const QgsFeature &feat, QgsAttributeEditorContext& context, QString& labelText, bool& labelOnTop );
|
||||
|
||||
static bool retrieveValue( QWidget *widget, QgsVectorLayer *vl, int idx, QVariant &value );
|
||||
static bool setValue( QWidget *widget, QgsVectorLayer *vl, int idx, const QVariant &value );
|
||||
|
||||
private:
|
||||
static QComboBox *comboBox( QWidget *editor, QWidget *parent );
|
||||
static QListWidget *listWidget( QWidget *editor, QWidget *parent );
|
||||
static QgsDualView* dualView( QWidget* editor, QWidget* parent );
|
||||
|
||||
public slots:
|
||||
void selectFileName();
|
||||
@ -115,4 +139,6 @@ class GUI_EXPORT QgsStringRelay : public QObject
|
||||
QList<QWidget*> mProxyList;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QgsStringRelay* )
|
||||
|
||||
#endif
|
||||
|
||||
42
src/gui/qgsattributeeditorcontext.cpp
Normal file
42
src/gui/qgsattributeeditorcontext.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
qgsattributeeditorcontext.cpp
|
||||
--------------------------------------
|
||||
Date : 30.7.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsattributeeditorcontext.h"
|
||||
|
||||
QgsAttributeEditorContext::QgsAttributeEditorContext()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QWidget*QgsAttributeEditorContext::proxyWidget( QgsVectorLayer* vl, int fieldIdx )
|
||||
{
|
||||
return mProxyWidgets.value( vl ).value( fieldIdx );
|
||||
}
|
||||
|
||||
void QgsAttributeEditorContext::addProxyWidgets( QgsVectorLayer* vl, QMap<int, QWidget*> proxyWidgets )
|
||||
{
|
||||
mProxyWidgets[ vl ].unite( proxyWidgets );
|
||||
}
|
||||
|
||||
void QgsAttributeEditorContext::addProxyWidget( QgsVectorLayer* vl, int idx, QWidget* widget )
|
||||
{
|
||||
mProxyWidgets[ vl ].insert( idx, widget );
|
||||
}
|
||||
|
||||
|
||||
void QgsAttributeEditorContext::adjustForLayer( QgsVectorLayer* layer )
|
||||
{
|
||||
mDistanceArea.setSourceCrs( layer->crs() );
|
||||
}
|
||||
59
src/gui/qgsattributeeditorcontext.h
Normal file
59
src/gui/qgsattributeeditorcontext.h
Normal file
@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
qgsattributeeditorcontext.h
|
||||
--------------------------------------
|
||||
Date : 30.7.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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSATTRIBUTEEDITORCONTEXT_H
|
||||
#define QGSATTRIBUTEEDITORCONTEXT_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QWidget>
|
||||
|
||||
#include <qgsdistancearea.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
|
||||
|
||||
/**
|
||||
* This class contains context information for attribute editor widgets.
|
||||
* It will be passed to embedded widgets whenever this occurs (e.g. when
|
||||
* showing an embedded form due to relations)
|
||||
*/
|
||||
|
||||
class GUI_EXPORT QgsAttributeEditorContext
|
||||
{
|
||||
public:
|
||||
QgsAttributeEditorContext();
|
||||
|
||||
QWidget* proxyWidget( QgsVectorLayer* vl, int fieldIdx );
|
||||
void addProxyWidgets( QgsVectorLayer* vl, QMap<int, QWidget*> proxyWidgets );
|
||||
void addProxyWidget( QgsVectorLayer* vl, int idx, QWidget* widget );
|
||||
|
||||
void setDistanceArea( const QgsDistanceArea& distanceArea ) { mDistanceArea = distanceArea; }
|
||||
inline const QgsDistanceArea& distanceArea() { return mDistanceArea; }
|
||||
|
||||
/**
|
||||
* When copying the context for another layer, call this.
|
||||
* Will adjast the distance area for this layer
|
||||
*
|
||||
* @param layer The layer to adjust for.
|
||||
*/
|
||||
void adjustForLayer( QgsVectorLayer* layer );
|
||||
|
||||
private:
|
||||
//! vectorlayer => ( fieldIdx, proxyWidget )
|
||||
QMap<QgsVectorLayer*, QMap<int, QWidget*> > mProxyWidgets;
|
||||
|
||||
QgsDistanceArea mDistanceArea;
|
||||
};
|
||||
|
||||
#endif // QGSATTRIBUTEEDITORCONTEXT_H
|
||||
@ -7,23 +7,13 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>751</width>
|
||||
<height>487</height>
|
||||
<height>451</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Attribute Edit Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="4" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="5">
|
||||
<widget class="QListWidget" name="selectionListWidget">
|
||||
<item>
|
||||
@ -123,6 +113,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="sizePolicy">
|
||||
@ -878,6 +878,9 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageEditorWidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
|
||||
@ -6,32 +6,11 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>871</width>
|
||||
<height>712</height>
|
||||
<width>613</width>
|
||||
<height>634</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="toolTip">
|
||||
<string>QGIS forms can have a Python function that is called when the form is opened.
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
An example is (in module MyForms.py):
|
||||
|
||||
def open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget,"MyLineEdit")
|
||||
|
||||
Reference in Python Init Function like so: MyForms.open
|
||||
|
||||
MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Python Init function</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
@ -45,6 +24,13 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Attribute editor layout:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QToolButton" name="mAddAttributeButton">
|
||||
<property name="sizePolicy">
|
||||
@ -68,13 +54,19 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLineEdit" name="leEditFormInit"/>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="mCalculateFieldButton">
|
||||
<property name="toolTip">
|
||||
<string>Field calculator</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Click to toggle table editing</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Attribute editor layout:</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -94,43 +86,37 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QComboBox" name="mEditorLayoutComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Autogenerate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Drag and drop designer</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Provide ui-file</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="7">
|
||||
<widget class="QSplitter" name="mSplitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="mAttributesListFrame" native="true">
|
||||
<widget class="QWidget" name="mRelationsAndFieldsFrame" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="mAttributesListFrame" native="true">
|
||||
<layout class="QGridLayout" name="mAttributesListLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStackedWidget" name="mAttributeEditorOptionsWidget">
|
||||
<property name="currentIndex">
|
||||
@ -138,6 +124,9 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@ -175,150 +164,178 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<widget class="QWidget" name="mAttributesTreeButtonFrame" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>9</x>
|
||||
<y>9</y>
|
||||
<width>30</width>
|
||||
<height>548</height>
|
||||
</rect>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<property name="horizontalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="mAttributesTreeButtonFrame" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>186</height>
|
||||
</size>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddTabOrGroupButton">
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>186</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddTabOrGroupButton">
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionSignPlus.png</normaloff>:/images/themes/default/mActionSignPlus.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mRemoveTabGroupItemButton">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionSignMinus.png</normaloff>:/images/themes/default/mActionSignMinus.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddItemButton">
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionArrowRight.png</normaloff>:/images/themes/default/mActionArrowRight.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mMoveUpItem">
|
||||
<property name="text">
|
||||
<string>^</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionArrowUp.png</normaloff>:/images/themes/default/mActionArrowUp.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mMoveDownItem">
|
||||
<property name="text">
|
||||
<string>v</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionArrowDown.png</normaloff>:/images/themes/default/mActionArrowDown.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>176</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QWidget" name="mAttributesTreeFrame" native="true">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="mDesignerListLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionSignPlus.png</normaloff>:/images/themes/default/mActionSignPlus.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mRemoveTabGroupItemButton">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionSignMinus.png</normaloff>:/images/themes/default/mActionSignMinus.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mAddItemButton">
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionArrowRight.png</normaloff>:/images/themes/default/mActionArrowRight.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mMoveUpItem">
|
||||
<property name="text">
|
||||
<string>^</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionArrowUp.png</normaloff>:/images/themes/default/mActionArrowUp.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="mMoveDownItem">
|
||||
<property name="text">
|
||||
<string>v</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionArrowDown.png</normaloff>:/images/themes/default/mActionArrowDown.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>176</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="mAttributesTreeFrame" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>45</x>
|
||||
<y>9</y>
|
||||
<width>702</width>
|
||||
<height>548</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="mCalculateFieldButton">
|
||||
<property name="toolTip">
|
||||
<string>Field calculator</string>
|
||||
<item row="0" column="6">
|
||||
<widget class="QComboBox" name="mEditorLayoutComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>Click to toggle table editing</string>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Autogenerate</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Drag and drop designer</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Provide ui-file</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="toolTip">
|
||||
<string>QGIS forms can have a Python function that is called when the form is opened.
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
An example is (in module MyForms.py):
|
||||
|
||||
def open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget,"MyLineEdit")
|
||||
|
||||
Reference in Python Init Function like so: MyForms.open
|
||||
|
||||
MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
<string>Python Init function</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -393,6 +410,24 @@ MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.<
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLineEdit" name="leEditFormInit">
|
||||
<property name="toolTip">
|
||||
<string>QGIS forms can have a Python function that is called when the form is opened.
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
An example is (in module MyForms.py):
|
||||
|
||||
def open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget,"MyLineEdit")
|
||||
|
||||
Reference in Python Init Function like so: MyForms.open
|
||||
|
||||
MyForms.py must live on PYTHONPATH, .qgis/python, or inside the project folder.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user