mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-16 00:05:45 -04:00
- 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
This commit is contained in:
parent
d8b93214e8
commit
3e01e6d3d5
@ -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
|
||||
@ -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
|
||||
|
@ -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);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "qgsaddattrdialog.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgslogger.h"
|
||||
|
||||
QgsAddAttrDialog::QgsAddAttrDialog( QgsVectorDataProvider* provider, QWidget *parent, Qt::WFlags fl )
|
||||
: QDialog( parent, fl ), mDataProvider( provider )
|
||||
@ -24,31 +25,66 @@ QgsAddAttrDialog::QgsAddAttrDialog( QgsVectorDataProvider* provider, QWidget *pa
|
||||
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() );
|
||||
|
||||
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::name() const
|
||||
QgsField QgsAddAttrDialog::field() const
|
||||
{
|
||||
return mNameEdit->text();
|
||||
}
|
||||
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() ) );
|
||||
|
||||
QString QgsAddAttrDialog::type() const
|
||||
{
|
||||
return mTypeBox->currentText();
|
||||
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() );
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "ui_qgsaddattrdialogbase.h"
|
||||
#include "qgisgui.h"
|
||||
#include "qgsfield.h"
|
||||
|
||||
class QgsVectorDataProvider;
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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 ) )
|
||||
|
@ -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.
|
||||
*
|
||||
@ -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
|
||||
@ -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 );
|
||||
|
||||
@ -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
|
||||
|
@ -172,9 +172,9 @@ QgsVectorLayer::~QgsVectorLayer()
|
||||
//delete remaining overlays
|
||||
|
||||
QList<QgsVectorOverlay*>::iterator overlayIt = mOverlays.begin();
|
||||
for(; overlayIt != mOverlays.end(); ++overlayIt)
|
||||
for ( ; overlayIt != mOverlays.end(); ++overlayIt )
|
||||
{
|
||||
delete (*overlayIt);
|
||||
delete *overlayIt;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1469,7 +1469,7 @@ bool QgsVectorLayer::addFeature( QgsFeature& f, bool alsoUpdateExtent )
|
||||
// and add to the known added features.
|
||||
f.setFeatureId( addedIdLowWaterMark );
|
||||
mAddedFeatures.append( f );
|
||||
mCachedGeometries[f.id()] = *(f.geometry());
|
||||
mCachedGeometries[f.id()] = *f.geometry();
|
||||
|
||||
setModified( true );
|
||||
|
||||
@ -1666,7 +1666,7 @@ int QgsVectorLayer::addIsland( const QList<QgsPoint>& ring )
|
||||
if ( addedIt->id() == selectedFeatureId )
|
||||
{
|
||||
return addedIt->geometry()->addIsland( ring );
|
||||
mCachedGeometries[selectedFeatureId] = *(addedIt->geometry());
|
||||
mCachedGeometries[selectedFeatureId] = *addedIt->geometry();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1737,19 +1737,19 @@ int QgsVectorLayer::translateFeature( int featureId, double dx, double dy )
|
||||
|
||||
//else get the geometry from provider (may be slow)
|
||||
QgsFeature f;
|
||||
if(mDataProvider && mDataProvider->featureAtId(featureId, f, true))
|
||||
if ( mDataProvider && mDataProvider->featureAtId( featureId, f, true ) )
|
||||
{
|
||||
if(f.geometry())
|
||||
if ( f.geometry() )
|
||||
{
|
||||
QgsGeometry translateGeom( *( f.geometry() ) );
|
||||
int errorCode = translateGeom.translate( dx, dy );
|
||||
if ( errorCode == 0 )
|
||||
{
|
||||
QgsGeometry translateGeom(*(f.geometry()));
|
||||
int errorCode = translateGeom.translate(dx, dy);
|
||||
if(errorCode == 0)
|
||||
{
|
||||
mChangedGeometries.insert(featureId, translateGeom);
|
||||
setModified(true, true);
|
||||
}
|
||||
return errorCode;
|
||||
mChangedGeometries.insert( featureId, translateGeom );
|
||||
setModified( true, true );
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
return 1; //geometry not found
|
||||
}
|
||||
@ -2571,7 +2571,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
|
||||
}
|
||||
|
||||
|
||||
bool QgsVectorLayer::changeGeometry(int fid, QgsGeometry* geom)
|
||||
bool QgsVectorLayer::changeGeometry( int fid, QgsGeometry* geom )
|
||||
{
|
||||
if ( !mEditable || !mDataProvider )
|
||||
{
|
||||
@ -2621,24 +2621,22 @@ bool QgsVectorLayer::changeAttributeValue( int fid, int field, QVariant value, b
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsVectorLayer::addAttribute( QString name, QString type )
|
||||
bool QgsVectorLayer::addAttribute( const QgsField &field )
|
||||
{
|
||||
if ( !isEditable() )
|
||||
return false;
|
||||
|
||||
for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
|
||||
{
|
||||
if ( it.value().name() == name )
|
||||
if ( it.value().name() == field.name() )
|
||||
return false;
|
||||
}
|
||||
|
||||
const QgsNativeTypeMap &types = mDataProvider->supportedNativeTypes();
|
||||
QVariant::Type typeType = QVariant::String;
|
||||
if ( types.contains( type ) )
|
||||
typeType = ( QVariant::Type ) types[type];
|
||||
if ( !mDataProvider->supportedType( field ) )
|
||||
return false;
|
||||
|
||||
mMaxUpdatedIndex++;
|
||||
mUpdatedFields.insert( mMaxUpdatedIndex, QgsField( name, typeType, type ) );
|
||||
mUpdatedFields.insert( mMaxUpdatedIndex, field );
|
||||
mAddedAttributeIds.insert( mMaxUpdatedIndex );
|
||||
|
||||
setModified( true, false );
|
||||
@ -2656,10 +2654,12 @@ bool QgsVectorLayer::deleteAttribute( int index )
|
||||
if ( mDeletedAttributeIds.contains( index ) )
|
||||
return false;
|
||||
|
||||
if ( !mDataProvider->fields().contains( index ) )
|
||||
if ( !mAddedAttributeIds.contains( index ) &&
|
||||
!mDataProvider->fields().contains( index ) )
|
||||
return false;
|
||||
|
||||
mDeletedAttributeIds.insert( index );
|
||||
mAddedAttributeIds.remove( index );
|
||||
mUpdatedFields.remove( index );
|
||||
|
||||
setModified( true, false );
|
||||
@ -2748,9 +2748,9 @@ bool QgsVectorLayer::commitChanges()
|
||||
//
|
||||
if ( mAddedAttributeIds.size() > 0 )
|
||||
{
|
||||
QgsNewAttributesMap addedAttributes;
|
||||
QList<QgsField> addedAttributes;
|
||||
for ( QgsAttributeIds::const_iterator it = mAddedAttributeIds.begin(); it != mAddedAttributeIds.end(); it++ )
|
||||
addedAttributes[ mUpdatedFields[ *it ].name()] = mUpdatedFields[ *it ].typeName();
|
||||
addedAttributes << mUpdatedFields[ *it ];
|
||||
|
||||
if (( cap & QgsVectorDataProvider::AddAttributes ) && mDataProvider->addAttributes( addedAttributes ) )
|
||||
{
|
||||
@ -3244,7 +3244,7 @@ int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snapping
|
||||
int n = 0;
|
||||
QgsFeature f;
|
||||
|
||||
if (mCachedGeometriesRect.contains( searchRect ) )
|
||||
if ( mCachedGeometriesRect.contains( searchRect ) )
|
||||
{
|
||||
QgsDebugMsg( "Using cached geometries for snapping." );
|
||||
|
||||
|
@ -380,14 +380,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
|
||||
/** change feature's geometry
|
||||
@note added in version 1.2 */
|
||||
bool changeGeometry(int fid, QgsGeometry* geom);
|
||||
bool changeGeometry( int fid, QgsGeometry* geom );
|
||||
|
||||
/** changed an attribute value (but does not commit it) */
|
||||
bool changeAttributeValue( int fid, int field, QVariant value, bool emitSignal = true );
|
||||
|
||||
/** 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 );
|
||||
returns true if the field was added
|
||||
@note added in version 1.2 */
|
||||
bool addAttribute( const QgsField &field );
|
||||
|
||||
/** delete an attribute field (but does not commit it) */
|
||||
bool deleteAttribute( int attr );
|
||||
|
@ -271,30 +271,26 @@ bool QgsMemoryProvider::deleteFeatures( const QgsFeatureIds & id )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool QgsMemoryProvider::addAttributes( const QgsNewAttributesMap & attributes )
|
||||
bool QgsMemoryProvider::addAttributes( const QList<QgsField> &attributes )
|
||||
{
|
||||
for ( QgsNewAttributesMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
|
||||
for ( QList<QgsField>::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
|
||||
{
|
||||
QString name = it.key();
|
||||
QString typeName = it.value();
|
||||
QVariant::Type type;
|
||||
if ( typeName == "int" )
|
||||
type = QVariant::Int;
|
||||
else if ( typeName == "double" )
|
||||
type = QVariant::Double;
|
||||
else if ( typeName == "string" )
|
||||
type = QVariant::String;
|
||||
else
|
||||
switch ( it->type() )
|
||||
{
|
||||
QgsDebugMsg( "Field type not supported: " + typeName );
|
||||
continue;
|
||||
case QVariant::Int:
|
||||
case QVariant::Double:
|
||||
case QVariant::String:
|
||||
break;
|
||||
default:
|
||||
QgsDebugMsg( "Field type not supported: " + it->typeName() );
|
||||
continue;
|
||||
}
|
||||
|
||||
// add new field as a last one
|
||||
int nextId = -1;
|
||||
for ( QgsFieldMap::iterator it2 = mFields.begin(); it2 != mFields.end(); ++it2 )
|
||||
if ( it2.key() > nextId ) nextId = it2.key();
|
||||
mFields[nextId+1] = QgsField( name, type, typeName );
|
||||
mFields[nextId+1] = *it;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class QgsMemoryProvider : public QgsVectorDataProvider
|
||||
* @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
|
||||
|
@ -184,9 +184,11 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
|
||||
valid = false;
|
||||
}
|
||||
|
||||
mSupportedNativeTypes.insert( "Integer", QVariant::Int );
|
||||
mSupportedNativeTypes.insert( "Real", QVariant::Double );
|
||||
mSupportedNativeTypes.insert( "String", QVariant::String );
|
||||
mNativeTypes
|
||||
<< QgsVectorDataProvider::NativeType( tr( "Integer" ), "integer", QVariant::Int, 1, 10 )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "Real" ), "double", QVariant::Double, 1, 20, 0, 5 )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "String" ), "string", QVariant::String, 1, 20, 0, 5 )
|
||||
;
|
||||
}
|
||||
|
||||
QgsOgrProvider::~QgsOgrProvider()
|
||||
@ -672,34 +674,35 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList & flist )
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
bool QgsOgrProvider::addAttributes( const QgsNewAttributesMap & attributes )
|
||||
bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
|
||||
{
|
||||
bool returnvalue = true;
|
||||
|
||||
for ( QgsNewAttributesMap::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter )
|
||||
for ( QList<QgsField>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter )
|
||||
{
|
||||
OGRFieldDefnH fielddefn = OGR_Fld_Create( mEncoding->fromUnicode( iter.key() ).data(), OFTInteger );
|
||||
OGRFieldType type;
|
||||
|
||||
if ( *iter == "Integer" )
|
||||
switch ( iter->type() )
|
||||
{
|
||||
OGR_Fld_SetType( fielddefn, OFTInteger );
|
||||
OGR_Fld_SetWidth( fielddefn, 10 );
|
||||
}
|
||||
else if ( *iter == "Real" )
|
||||
{
|
||||
OGR_Fld_SetType( fielddefn, OFTReal );
|
||||
}
|
||||
else if ( *iter == "String" )
|
||||
{
|
||||
OGR_Fld_SetType( fielddefn, OFTString );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsLogger::warning( QString( "QgsOgrProvider::addAttributes, type %1 not found" ).arg( *iter ) );
|
||||
returnvalue = false;
|
||||
continue;
|
||||
case QVariant::Int:
|
||||
type = OFTInteger;
|
||||
break;
|
||||
case QVariant::Double:
|
||||
type = OFTReal;
|
||||
break;
|
||||
case QVariant::String:
|
||||
type = OFTString;
|
||||
break;
|
||||
default:
|
||||
QgsLogger::warning( QString( "QgsOgrProvider::addAttributes, type %1 not found" ).arg( iter->typeName() ) );
|
||||
returnvalue = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
OGRFieldDefnH fielddefn = OGR_Fld_Create( mEncoding->fromUnicode( iter->name() ).data(), type );
|
||||
OGR_Fld_SetWidth( fielddefn, iter->length() );
|
||||
OGR_Fld_SetPrecision( fielddefn, iter->precision() );
|
||||
|
||||
if ( OGR_L_CreateField( ogrLayer, fielddefn, TRUE ) != OGRERR_NONE )
|
||||
{
|
||||
QgsLogger::warning( "QgsOgrProvider.cpp: writing of field failed" );
|
||||
|
@ -133,7 +133,7 @@ class QgsOgrProvider : public QgsVectorDataProvider
|
||||
virtual bool deleteFeatures( const QgsFeatureIds & id );
|
||||
|
||||
/**Adds new attributess. Unfortunately not supported for layers with features in it*/
|
||||
virtual bool addAttributes( const QgsNewAttributesMap & attributes );
|
||||
virtual bool addAttributes( const QList<QgsField> &attributes );
|
||||
|
||||
/**Changes attribute values of existing features */
|
||||
virtual bool changeAttributeValues( const QgsChangedAttributesMap & attr_map );
|
||||
|
@ -224,11 +224,23 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
|
||||
#endif
|
||||
|
||||
//fill type names into sets
|
||||
mSupportedNativeTypes.insert( "double precision", QVariant::Double );
|
||||
mSupportedNativeTypes.insert( "int4", QVariant::Int );
|
||||
mSupportedNativeTypes.insert( "int8", QVariant::LongLong );
|
||||
mSupportedNativeTypes.insert( "text", QVariant::String );
|
||||
mSupportedNativeTypes.insert( "varchar(30)", QVariant::String );
|
||||
mNativeTypes
|
||||
// integer types
|
||||
<< QgsVectorDataProvider::NativeType( tr( "smallint (16bit)" ), "int2", QVariant::Int )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "integer (32bit)" ), "int4", QVariant::Int )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "integer (64bit)" ), "int8", QVariant::LongLong )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "numeric" ), "numeric", QVariant::LongLong, 1, 20, 0, 20 )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "decimal" ), "decimal", QVariant::LongLong, 1, 20, 0, 20 )
|
||||
|
||||
// floating point
|
||||
<< QgsVectorDataProvider::NativeType( tr( "real" ), "real", QVariant::Double )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "double" ), "double precision", QVariant::Double )
|
||||
|
||||
// string types
|
||||
<< QgsVectorDataProvider::NativeType( tr( "char" ), "char", QVariant::String, 1, 255 )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "varchar" ), "varchar", QVariant::String, 1, 255 )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "text" ), "text", QVariant::String )
|
||||
;
|
||||
|
||||
if ( primaryKey.isEmpty() )
|
||||
{
|
||||
@ -875,9 +887,13 @@ void QgsPostgresProvider::loadFields()
|
||||
|
||||
if ( fieldTypeName == "int8" )
|
||||
fieldType = QVariant::LongLong;
|
||||
else if ( fieldTypeName.startsWith( "int" ) || fieldTypeName == "serial" )
|
||||
else if ( fieldTypeName.startsWith( "int" ) ||
|
||||
fieldTypeName == "serial" )
|
||||
fieldType = QVariant::Int;
|
||||
else if ( fieldTypeName == "real" || fieldTypeName == "double precision" || fieldTypeName.startsWith( "float" ) || fieldTypeName == "numeric" )
|
||||
else if ( fieldTypeName == "real" ||
|
||||
fieldTypeName == "double precision" ||
|
||||
fieldTypeName.startsWith( "float" ) ||
|
||||
fieldTypeName == "numeric" )
|
||||
fieldType = QVariant::Double;
|
||||
else if ( fieldTypeName == "text" ||
|
||||
fieldTypeName == "char" ||
|
||||
@ -1828,15 +1844,19 @@ QByteArray QgsPostgresProvider::paramValue( QString fieldValue, const QString &d
|
||||
|
||||
if ( fieldValue == defaultValue && !defaultValue.isNull() )
|
||||
{
|
||||
Result result = connectionRO->PQexec( QString( "select %1" ).arg( defaultValue ) );
|
||||
PGresult *result = connectionRW->PQexec( QString( "select %1" ).arg( defaultValue ) );
|
||||
if ( PQresultStatus( result ) == PGRES_FATAL_ERROR )
|
||||
throw PGException( result );
|
||||
|
||||
if ( PQgetisnull( result, 0, 0 ) )
|
||||
{
|
||||
PQclear( result );
|
||||
return QByteArray( 0 ); // QByteArray(0).isNull() is true
|
||||
}
|
||||
else
|
||||
{
|
||||
QString val = QString::fromUtf8( PQgetvalue( result, 0, 0 ) );
|
||||
return val.toUtf8();
|
||||
PQclear( result );
|
||||
return QString::fromUtf8( PQgetvalue( result, 0, 0 ) ).toUtf8();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2060,7 +2080,7 @@ bool QgsPostgresProvider::deleteFeatures( const QgsFeatureIds & id )
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
bool QgsPostgresProvider::addAttributes( const QgsNewAttributesMap & name )
|
||||
bool QgsPostgresProvider::addAttributes( const QList<QgsField> &attributes )
|
||||
{
|
||||
bool returnvalue = true;
|
||||
|
||||
@ -2071,12 +2091,22 @@ bool QgsPostgresProvider::addAttributes( const QgsNewAttributesMap & name )
|
||||
{
|
||||
connectionRW->PQexecNR( "BEGIN" );
|
||||
|
||||
for ( QgsNewAttributesMap::const_iterator iter = name.begin();iter != name.end();++iter )
|
||||
for ( QList<QgsField>::const_iterator iter = attributes.begin();iter != attributes.end();++iter )
|
||||
{
|
||||
QString type = iter->typeName();
|
||||
if ( type == "char" || type == "varchar" )
|
||||
{
|
||||
type = QString( "%1(%2)" ).arg( type ).arg( iter->length() );
|
||||
}
|
||||
else if ( type == "numeric" || type == "decimal" )
|
||||
{
|
||||
type = QString( "%1(%2,%3)" ).arg( type ).arg( iter->length() ).arg( iter->precision() );
|
||||
}
|
||||
|
||||
QString sql = QString( "ALTER TABLE %1 ADD COLUMN %2 %3" )
|
||||
.arg( mSchemaTableName )
|
||||
.arg( quotedIdentifier( iter.key() ) )
|
||||
.arg( iter.value() );
|
||||
.arg( quotedIdentifier( iter->name() ) )
|
||||
.arg( type );
|
||||
QgsDebugMsg( sql );
|
||||
|
||||
//send sql statement and do error handling
|
||||
@ -2084,6 +2114,18 @@ bool QgsPostgresProvider::addAttributes( const QgsNewAttributesMap & name )
|
||||
if ( result == 0 || PQresultStatus( result ) == PGRES_FATAL_ERROR )
|
||||
throw PGException( result );
|
||||
PQclear( result );
|
||||
|
||||
if ( !iter->comment().isEmpty() )
|
||||
{
|
||||
sql = QString( "COMMENT ON COLUMN %1.%2 IS %3" )
|
||||
.arg( mSchemaTableName )
|
||||
.arg( quotedIdentifier( iter->name() ) )
|
||||
.arg( quotedValue( iter->comment() ) );
|
||||
result = connectionRW->PQexec( sql );
|
||||
if ( result == 0 || PQresultStatus( result ) == PGRES_FATAL_ERROR )
|
||||
throw PGException( result );
|
||||
PQclear( result );
|
||||
}
|
||||
}
|
||||
|
||||
connectionRW->PQexecNR( "COMMIT" );
|
||||
|
@ -215,7 +215,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
|
||||
/**Adds new attributes
|
||||
@param name map with attribute name as key and type as value
|
||||
@return true in case of success and false in case of failure*/
|
||||
bool addAttributes( const QgsNewAttributesMap & name );
|
||||
bool addAttributes( const QList<QgsField> &attributes );
|
||||
|
||||
/**Deletes existing attributes
|
||||
@param names of the attributes to delete
|
||||
|
@ -42,7 +42,7 @@ const QString SPATIALITE_DESCRIPTION = "SpatiaLite data provider";
|
||||
QMap < QString, QgsSpatiaLiteProvider::SqliteHandles * >QgsSpatiaLiteProvider::SqliteHandles::handles;
|
||||
|
||||
QgsSpatiaLiteProvider::QgsSpatiaLiteProvider( QString const &uri ): QgsVectorDataProvider( uri ),
|
||||
geomType( QGis::WKBUnknown ), mSrid( -1 ), spatialIndexRTree( false ), sqliteHandle( NULL ), spatialIndexMbrCache( false ), sqliteStatement( NULL )
|
||||
geomType( QGis::WKBUnknown ), sqliteHandle( NULL ), sqliteStatement( NULL ), mSrid( -1 ), spatialIndexRTree( false ), spatialIndexMbrCache( false )
|
||||
{
|
||||
QgsDataSourceURI mUri = QgsDataSourceURI( uri );
|
||||
|
||||
@ -107,10 +107,12 @@ QgsSpatiaLiteProvider::QgsSpatiaLiteProvider( QString const &uri ): QgsVectorDat
|
||||
return;
|
||||
}
|
||||
//fill type names into sets
|
||||
mSupportedNativeTypes.insert( "SQLITE_BLOB", QVariant::ByteArray );
|
||||
mSupportedNativeTypes.insert( "SQLITE_TEXT", QVariant::String );
|
||||
mSupportedNativeTypes.insert( "SQLITE_FLOAT", QVariant::Double );
|
||||
mSupportedNativeTypes.insert( "SQLITE_INTEGER", QVariant::LongLong );
|
||||
mNativeTypes
|
||||
<< QgsVectorDataProvider::NativeType( tr( "BLOB" ), "SQLITE_BLOB", QVariant::ByteArray )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "Text" ), "SQLITE_TEXT", QVariant::String )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "Double" ), "SQLITE_FLOAT", QVariant::Double, 0, 20, 0, 20 )
|
||||
<< QgsVectorDataProvider::NativeType( tr( "Integer" ), "SQLITE_INTEGER", QVariant::LongLong, 0, 20 )
|
||||
;
|
||||
}
|
||||
|
||||
QgsSpatiaLiteProvider::~QgsSpatiaLiteProvider()
|
||||
@ -175,7 +177,7 @@ void QgsSpatiaLiteProvider::loadFields()
|
||||
fieldType = QVariant::Double;
|
||||
}
|
||||
|
||||
attributeFields.insert( i - 1, QgsField( name, fieldType, type, 0, 0, tr( "" ) ) );
|
||||
attributeFields.insert( i - 1, QgsField( name, fieldType, type, 0, 0, "" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1096,7 +1098,7 @@ abort:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsSpatiaLiteProvider::addAttributes( const QgsNewAttributesMap & name )
|
||||
bool QgsSpatiaLiteProvider::addAttributes( const QList<QgsField> &attributes )
|
||||
{
|
||||
char *errMsg = NULL;
|
||||
bool toCommit = false;
|
||||
@ -1112,9 +1114,12 @@ bool QgsSpatiaLiteProvider::addAttributes( const QgsNewAttributesMap & name )
|
||||
}
|
||||
toCommit = true;
|
||||
|
||||
for ( QgsNewAttributesMap::const_iterator iter = name.begin(); iter != name.end(); ++iter )
|
||||
for ( QList<QgsField>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter )
|
||||
{
|
||||
sql = QString( "ALTER TABLE %1 ADD COLUMN %2 %3" ).arg( quotedValue( mTableName ) ).arg( quotedValue( iter.key() ) ).arg( iter.value() );
|
||||
sql = QString( "ALTER TABLE %1 ADD COLUMN %2 %3" )
|
||||
.arg( quotedValue( mTableName ) )
|
||||
.arg( quotedValue( iter->name() ) )
|
||||
.arg( iter->typeName() );
|
||||
strcpy( xSql, sql.toUtf8().constData() );
|
||||
ret = sqlite3_exec( sqliteHandle, xSql, NULL, NULL, &errMsg );
|
||||
if ( ret != SQLITE_OK )
|
||||
|
@ -168,7 +168,7 @@ class QgsSpatiaLiteProvider: public QgsVectorDataProvider
|
||||
/**Adds new attributes
|
||||
@param name map with attribute name as key and type as value
|
||||
@return true in case of success and false in case of failure*/
|
||||
bool addAttributes( const QgsNewAttributesMap & name );
|
||||
bool addAttributes( const QList<QgsField> &attributes );
|
||||
|
||||
/**Changes attribute values of existing features
|
||||
@param attr_map a map containing the new attributes. The integer is the feature id,
|
||||
|
@ -1,57 +1,107 @@
|
||||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsAddAttrDialogBase</class>
|
||||
<widget class="QDialog" name="QgsAddAttrDialogBase" >
|
||||
<property name="geometry" >
|
||||
<widget class="QDialog" name="QgsAddAttrDialogBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>312</width>
|
||||
<height>132</height>
|
||||
<width>356</width>
|
||||
<height>207</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>Add Attribute</string>
|
||||
</property>
|
||||
<property name="modal" >
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="textLabel1" >
|
||||
<property name="text" >
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="textLabel1">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>mNameEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLineEdit" name="mNameEdit" />
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="mNameEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="textLabel2" >
|
||||
<property name="text" >
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="textLabel1_2">
|
||||
<property name="text">
|
||||
<string>Comment:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mCommentEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="mCommentEdit"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="textLabel2">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>mTypeBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QComboBox" name="mTypeBox" />
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="mTypeBox"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2" >
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="mTypeName">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mTypeBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="textLabel2_2">
|
||||
<property name="text">
|
||||
<string>Width</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mLength</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="mLength"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="textLabel2_3">
|
||||
<property name="text">
|
||||
<string>Precision</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mPrec</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="mPrec"/>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11" />
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>mNameEdit</tabstop>
|
||||
<tabstop>mTypeBox</tabstop>
|
||||
@ -64,11 +114,11 @@
|
||||
<receiver>QgsAddAttrDialogBase</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>260</x>
|
||||
<y>109</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>307</x>
|
||||
<y>68</y>
|
||||
</hint>
|
||||
@ -80,11 +130,11 @@
|
||||
<receiver>QgsAddAttrDialogBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>196</x>
|
||||
<y>106</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>6</x>
|
||||
<y>77</y>
|
||||
</hint>
|
||||
|
Loading…
x
Reference in New Issue
Block a user