Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- allow setting of field width and precision when adding attributes
- update vector data providers accordingly
- postgres provider:
  - add support for more native types and setting of column comments
  - catch errors on retrieval of defaults values (fixes #1713)



git-svn-id: http://svn.osgeo.org/qgis/trunk@10863 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed May 30, 2009
1 parent d8b9321 commit 3e01e6d
Show file tree
Hide file tree
Showing 19 changed files with 342 additions and 167 deletions.
11 changes: 7 additions & 4 deletions python/core/qgsvectordataprovider.sip
Expand Up @@ -164,7 +164,7 @@ class QgsVectorDataProvider : QgsDataProvider
* @param attributes map with attribute name as key and type as value
* @return true in case of success and false in case of failure
*/
virtual bool addAttributes(const QMap<QString, QString> & attributes);
virtual bool addAttributes(const QList<QgsField> & attributes);

/**
* Deletes existing attributes
Expand Down Expand Up @@ -231,9 +231,12 @@ class QgsVectorDataProvider : QgsDataProvider
*/
QList<int> attributeIndexes();

/**Returns the names of the numerical types*/
const QMap<QString,QVariant::Type> &supportedNativeTypes() const;

/**
* check if provider supports type of field
* @note added in 1.2
*/
bool supportedType( const QgsField &field ) const;

/**
* Set whether provider should return also features that don't have
* associated geometry. FALSE by default
Expand Down
2 changes: 1 addition & 1 deletion python/core/qgsvectorlayer.sip
Expand Up @@ -325,7 +325,7 @@ public:

/** add an attribute field (but does not commit it)
returns the field index or -1 in case of failure */
bool addAttribute(QString name, QString type);
bool addAttribute( const QgsField &field );

/** delete an attribute field (but does not commit it) */
bool deleteAttribute(int attr);
Expand Down
68 changes: 52 additions & 16 deletions src/app/qgsaddattrdialog.cpp
Expand Up @@ -17,38 +17,74 @@

#include "qgsaddattrdialog.h"
#include "qgsvectordataprovider.h"
#include "qgslogger.h"

QgsAddAttrDialog::QgsAddAttrDialog( QgsVectorDataProvider* provider, QWidget *parent, Qt::WFlags fl )
: QDialog( parent, fl ), mDataProvider( provider )
{
setupUi( this );

//fill data types into the combo box
const QgsNativeTypeMap &typelist = mDataProvider->supportedNativeTypes();
const QList< QgsVectorDataProvider::NativeType > &typelist = mDataProvider->nativeTypes();

for ( QgsNativeTypeMap::const_iterator it = typelist.constBegin(); it != typelist.constEnd(); ++it )
for ( int i = 0; i < typelist.size(); i++ )
{
mTypeBox->addItem( it.key() );
QgsDebugMsg( QString( "name:%1 type:%2 typeName:%3 length:%4-%5 prec:%6-%7" )
.arg( typelist[i].mTypeDesc )
.arg( typelist[i].mType )
.arg( typelist[i].mTypeName )
.arg( typelist[i].mMinLen ).arg( typelist[i].mMaxLen )
.arg( typelist[i].mMinPrec ).arg( typelist[i].mMaxPrec ) );

mTypeBox->addItem( typelist[i].mTypeDesc );
mTypeBox->setItemData( i, static_cast<int>( typelist[i].mType ), Qt::UserRole );
mTypeBox->setItemData( i, typelist[i].mTypeName, Qt::UserRole + 1 );
mTypeBox->setItemData( i, typelist[i].mMinLen, Qt::UserRole + 2 );
mTypeBox->setItemData( i, typelist[i].mMaxLen, Qt::UserRole + 3 );
mTypeBox->setItemData( i, typelist[i].mMinPrec, Qt::UserRole + 4 );
mTypeBox->setItemData( i, typelist[i].mMaxPrec, Qt::UserRole + 5 );
}

on_mTypeBox_currentIndexChanged( 0 );
}

QgsAddAttrDialog::QgsAddAttrDialog( const std::list<QString>& typelist, QWidget *parent, Qt::WFlags fl )
: QDialog( parent, fl ), mDataProvider( 0 )
void QgsAddAttrDialog::on_mTypeBox_currentIndexChanged( int idx )
{
setupUi( this );
mTypeName->setText( mTypeBox->itemData( idx, Qt::UserRole + 1 ).toString() );

for ( std::list<QString>::const_iterator iter = typelist.begin();iter != typelist.end();++iter )
{
mTypeBox->addItem( *iter );
}
}
mLength->setMinimum( mTypeBox->itemData( idx, Qt::UserRole + 2 ).toInt() );
mLength->setMaximum( mTypeBox->itemData( idx, Qt::UserRole + 3 ).toInt() );
mLength->setVisible( mLength->minimum() < mLength->maximum() );
if ( mLength->value() < mLength->minimum() )
mLength->setValue( mLength->minimum() );
if ( mLength->value() > mLength->maximum() )
mLength->setValue( mLength->maximum() );

QString QgsAddAttrDialog::name() const
{
return mNameEdit->text();
mPrec->setMinimum( mTypeBox->itemData( idx, Qt::UserRole + 4 ).toInt() );
mPrec->setMaximum( mTypeBox->itemData( idx, Qt::UserRole + 5 ).toInt() );
mPrec->setVisible( mPrec->minimum() < mPrec->maximum() );
if ( mPrec->value() < mPrec->minimum() )
mPrec->setValue( mPrec->minimum() );
if ( mPrec->value() > mPrec->maximum() )
mPrec->setValue( mPrec->maximum() );
}

QString QgsAddAttrDialog::type() const
QgsField QgsAddAttrDialog::field() const
{
return mTypeBox->currentText();
QgsDebugMsg( QString( "idx:%1 name:%2 type:%3 typeName:%4 length:%5 prec:%6 comment:%7" )
.arg( mTypeBox->currentIndex() )
.arg( mNameEdit->text() )
.arg( mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole ).toInt() )
.arg( mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole + 1 ).toString() )
.arg( mLength->value() )
.arg( mPrec->value() )
.arg( mCommentEdit->text() ) );

return QgsField(
mNameEdit->text(),
( QVariant::Type ) mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole ).toInt(),
mTypeBox->itemData( mTypeBox->currentIndex(), Qt::UserRole + 1 ).toString(),
mLength->value(),
mPrec->value(),
mCommentEdit->text() );
}
9 changes: 7 additions & 2 deletions src/app/qgsaddattrdialog.h
Expand Up @@ -20,6 +20,7 @@

#include "ui_qgsaddattrdialogbase.h"
#include "qgisgui.h"
#include "qgsfield.h"

class QgsVectorDataProvider;

Expand All @@ -31,8 +32,12 @@ class QgsAddAttrDialog: public QDialog, private Ui::QgsAddAttrDialogBase
QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
QgsAddAttrDialog( const std::list<QString>& typelist,
QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
QString name() const;
QString type() const;

QgsField field() const;

public slots:
void on_mTypeBox_currentIndexChanged( int idx );

protected:
QgsVectorDataProvider* mDataProvider;
};
Expand Down
8 changes: 4 additions & 4 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -261,17 +261,17 @@ void QgsVectorLayerProperties::addAttribute()
QgsAddAttrDialog dialog( layer->dataProvider(), this );
if ( dialog.exec() == QDialog::Accepted )
{
if ( !addAttribute( dialog.name(), dialog.type() ) )
if ( !addAttribute( dialog.field() ) )
{
QMessageBox::information( this, tr( "Name conflict" ), tr( "The attribute could not be inserted. The name already exists in the table." ) );
}
}
}

bool QgsVectorLayerProperties::addAttribute( QString name, QString type )
bool QgsVectorLayerProperties::addAttribute( const QgsField &field )
{
QgsDebugMsg( "inserting attribute " + name + " of type " + type );
return layer->addAttribute( name, type );
QgsDebugMsg( "inserting attribute " + field.name() + " of type " + field.typeName() );
return layer->addAttribute( field );
}

void QgsVectorLayerProperties::deleteAttribute()
Expand Down
7 changes: 3 additions & 4 deletions src/app/qgsvectorlayerproperties.h
Expand Up @@ -50,10 +50,9 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
void setDisplayField( QString name );

/**Adds an attribute to the table (but does not commit it yet)
@param name attribute name
@param type attribute type
@return false in case of a name conflict, true in case of success*/
bool addAttribute( QString name, QString type );
@param field the field to add
@return false in case of a name conflict, true in case of success */
bool addAttribute( const QgsField &field );

/**Deletes an attribute (but does not commit it)
@param name attribute name
Expand Down
22 changes: 19 additions & 3 deletions src/core/qgsvectordataprovider.cpp
Expand Up @@ -78,7 +78,7 @@ bool QgsVectorDataProvider::deleteFeatures( const QgsFeatureIds & id )
return false;
}

bool QgsVectorDataProvider::addAttributes( const QgsNewAttributesMap & attributes )
bool QgsVectorDataProvider::addAttributes( const QList<QgsField> & attributes )
{
return false;
}
Expand Down Expand Up @@ -262,12 +262,28 @@ void QgsVectorDataProvider::enableGeometrylessFeatures( bool fetch )
mFetchFeaturesWithoutGeom = fetch;
}

const QgsNativeTypeMap &QgsVectorDataProvider::supportedNativeTypes() const
const QList< QgsVectorDataProvider::NativeType > &QgsVectorDataProvider::nativeTypes() const
{
return mSupportedNativeTypes;
return mNativeTypes;
}


bool QgsVectorDataProvider::supportedType( const QgsField &field ) const
{
int i;
for ( i = 0; i < mNativeTypes.size(); i++ )
{
if ( field.type() == mNativeTypes[i].mType &&
field.length() >= mNativeTypes[i].mMinLen && field.length() <= mNativeTypes[i].mMaxLen &&
field.precision() >= mNativeTypes[i].mMinPrec && field.precision() <= mNativeTypes[i].mMaxPrec )
{
break;
}
}

return i < mNativeTypes.size();
}

QVariant QgsVectorDataProvider::minimumValue( int index )
{
if ( !fields().contains( index ) )
Expand Down
39 changes: 29 additions & 10 deletions src/core/qgsvectordataprovider.h
Expand Up @@ -29,9 +29,6 @@ class QTextCodec;
#include "qgsvectorlayer.h"
#include "qgsfield.h"

typedef QMap<QString, QString> QgsNewAttributesMap;
typedef QMap<QString, QVariant::Type> QgsNativeTypeMap;

/** \ingroup core
* This is the base class for vector data providers.
*
Expand Down Expand Up @@ -208,21 +205,21 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
* @param attributes map with attribute name as key and type as value
* @return true in case of success and false in case of failure
*/
virtual bool addAttributes( const QgsNewAttributesMap & attributes );
virtual bool addAttributes( const QList<QgsField> &attributes );

/**
* Deletes existing attributes
* @param attributes a set containing names of attributes
* @return true in case of success and false in case of failure
*/
virtual bool deleteAttributes( const QgsAttributeIds& attributes );
virtual bool deleteAttributes( const QgsAttributeIds &attributes );

/**
* Changes attribute values of existing features.
* @param attr_map a map containing changed attributes
* @return true in case of success and false in case of failure
*/
virtual bool changeAttributeValues( const QgsChangedAttributesMap & attr_map );
virtual bool changeAttributeValues( const QgsChangedAttributesMap &attr_map );

/**
* Returns the default value for field specified by @c fieldId
Expand Down Expand Up @@ -279,15 +276,37 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
*/
virtual QgsAttributeList attributeIndexes();

/**Returns the names of the numerical types*/
const QgsNativeTypeMap &supportedNativeTypes() const;

/**
* Set whether provider should also return features that don't have
* associated geometry. FALSE by default
*/
void enableGeometrylessFeatures( bool fetch );

/**
* check if provider supports type of field
* @note added in 1.2
*/
bool supportedType( const QgsField &field ) const;

struct NativeType
{
NativeType( QString typeDesc, QString typeName, QVariant::Type type, int minLen = 0, int maxLen = 0, int minPrec = 0, int maxPrec = 0 ) :
mTypeDesc( typeDesc ), mTypeName( typeName ), mType( type ), mMinLen( minLen ), mMaxLen( maxLen ), mMinPrec( minPrec ), mMaxPrec( maxPrec ) {};

QString mTypeDesc;
QString mTypeName;
QVariant::Type mType;
int mMinLen, mMaxLen;
int mMinPrec, mMaxPrec;
};


/**
* Returns the names of the numerical types
* @note added in 1.2
*/
const QList< NativeType > &nativeTypes() const;

protected:
QVariant convertValue( QVariant::Type type, QString value );

Expand All @@ -309,7 +328,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
QgsAttributeList mAttributesToFetch;

/**The names of the providers native types*/
QgsNativeTypeMap mSupportedNativeTypes;
QList< NativeType > mNativeTypes;
};

#endif

0 comments on commit 3e01e6d

Please sign in to comment.