2017-08-21 08:40:24 +02:00
# include "qgssourcefieldsproperties.h"
QgsSourceFieldsProperties : : QgsSourceFieldsProperties ( QgsVectorLayer * layer , QWidget * parent )
: QWidget ( parent )
, mLayer ( layer )
{
if ( ! layer )
return ;
2017-10-28 11:00:17 +02:00
setupUi ( this ) ;
2017-08-21 08:40:24 +02:00
//button appearance
mAddAttributeButton - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /mActionNewAttribute.svg " ) ) ) ;
mDeleteAttributeButton - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /mActionDeleteAttribute.svg " ) ) ) ;
mToggleEditingButton - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /mActionToggleEditing.svg " ) ) ) ;
mCalculateFieldButton - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /mActionCalculateField.svg " ) ) ) ;
//button signals
connect ( mToggleEditingButton , & QAbstractButton : : clicked , this , & QgsSourceFieldsProperties : : toggleEditing ) ;
connect ( mAddAttributeButton , & QAbstractButton : : clicked , this , & QgsSourceFieldsProperties : : addAttributeClicked ) ;
connect ( mDeleteAttributeButton , & QAbstractButton : : clicked , this , & QgsSourceFieldsProperties : : deleteAttributeClicked ) ;
connect ( mCalculateFieldButton , & QAbstractButton : : clicked , this , & QgsSourceFieldsProperties : : calculateFieldClicked ) ;
//slots
connect ( mLayer , & QgsVectorLayer : : editingStarted , this , & QgsSourceFieldsProperties : : editingToggled ) ;
connect ( mLayer , & QgsVectorLayer : : editingStopped , this , & QgsSourceFieldsProperties : : editingToggled ) ;
connect ( mLayer , & QgsVectorLayer : : attributeAdded , this , & QgsSourceFieldsProperties : : attributeAdded ) ;
connect ( mLayer , & QgsVectorLayer : : attributeDeleted , this , & QgsSourceFieldsProperties : : attributeDeleted ) ;
//field list appearance
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 ( AttrWMSCol , new QTableWidgetItem ( QStringLiteral ( " WMS " ) ) ) ;
mFieldsList - > setHorizontalHeaderItem ( AttrWFSCol , new QTableWidgetItem ( QStringLiteral ( " WFS " ) ) ) ;
mFieldsList - > setHorizontalHeaderItem ( AttrAliasCol , new QTableWidgetItem ( tr ( " Alias " ) ) ) ;
mFieldsList - > setSortingEnabled ( true ) ;
mFieldsList - > sortByColumn ( 0 , Qt : : AscendingOrder ) ;
mFieldsList - > setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
mFieldsList - > setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
mFieldsList - > verticalHeader ( ) - > hide ( ) ;
//load buttons and field list
updateButtons ( ) ;
}
QgsSourceFieldsProperties : : ~ QgsSourceFieldsProperties ( )
{
}
void QgsSourceFieldsProperties : : init ( )
{
loadRows ( ) ;
//not used here: mEditorLayoutComboBox->setCurrentIndex( mLayer->editFormConfig().layout() );
//used here????? mFormSuppressCmbBx->setCurrentIndex( mLayer->editFormConfig().suppress() );
//not used here: loadAttributeEditorTree();
}
void QgsSourceFieldsProperties : : loadRows ( )
{
disconnect ( mFieldsList , & QTableWidget : : cellChanged , this , & QgsSourceFieldsProperties : : attributesListCellChanged ) ;
const QgsFields & fields = mLayer - > fields ( ) ;
mIndexedWidgets . clear ( ) ;
mFieldsList - > setRowCount ( 0 ) ;
for ( int i = 0 ; i < fields . count ( ) ; + + i )
attributeAdded ( i ) ;
mFieldsList - > resizeColumnsToContents ( ) ;
connect ( mFieldsList , & QTableWidget : : cellChanged , this , & QgsSourceFieldsProperties : : attributesListCellChanged ) ;
updateFieldRenamingStatus ( ) ;
}
void QgsSourceFieldsProperties : : updateFieldRenamingStatus ( )
{
bool canRenameFields = mLayer - > isEditable ( ) & & ( mLayer - > dataProvider ( ) - > capabilities ( ) & QgsVectorDataProvider : : RenameAttributes ) & & ! mLayer - > readOnly ( ) ;
for ( int row = 0 ; row < mFieldsList - > rowCount ( ) ; + + row )
{
if ( canRenameFields )
mFieldsList - > item ( row , AttrNameCol ) - > setFlags ( mFieldsList - > item ( row , AttrNameCol ) - > flags ( ) | Qt : : ItemIsEditable ) ;
else
mFieldsList - > item ( row , AttrNameCol ) - > setFlags ( mFieldsList - > item ( row , AttrNameCol ) - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
}
}
void QgsSourceFieldsProperties : : updateExpression ( )
{
QToolButton * btn = qobject_cast < QToolButton * > ( sender ( ) ) ;
Q_ASSERT ( btn ) ;
int index = btn - > property ( " Index " ) . toInt ( ) ;
const QString exp = mLayer - > expressionField ( index ) ;
QgsExpressionContext context ;
context < < QgsExpressionContextUtils : : globalScope ( )
< < QgsExpressionContextUtils : : projectScope ( QgsProject : : instance ( ) ) ;
QgsExpressionBuilderDialog dlg ( mLayer , exp , nullptr , QStringLiteral ( " generic " ) , context ) ;
if ( dlg . exec ( ) )
{
mLayer - > updateExpressionField ( index , dlg . expressionText ( ) ) ;
loadRows ( ) ;
}
}
void QgsSourceFieldsProperties : : attributeAdded ( int idx )
{
bool sorted = mFieldsList - > isSortingEnabled ( ) ;
if ( sorted )
mFieldsList - > setSortingEnabled ( false ) ;
const QgsFields & fields = mLayer - > fields ( ) ;
int row = mFieldsList - > rowCount ( ) ;
mFieldsList - > insertRow ( row ) ;
setRow ( row , idx , fields . at ( idx ) ) ;
mFieldsList - > setCurrentCell ( row , idx ) ;
for ( int i = idx + 1 ; i < mIndexedWidgets . count ( ) ; i + + )
mIndexedWidgets . at ( i ) - > setData ( Qt : : DisplayRole , i ) ;
if ( sorted )
mFieldsList - > setSortingEnabled ( true ) ;
2017-10-28 11:00:17 +02:00
for ( int i = 0 ; i < 7 ; i + + ) { // mFieldsList->columnCount()
2017-08-21 08:40:24 +02:00
switch ( mLayer - > fields ( ) . fieldOrigin ( idx ) )
{
case QgsFields : : OriginExpression :
2017-10-28 11:00:17 +02:00
mFieldsList - > item ( idx , i ) - > setBackgroundColor ( QColor ( 200 , 200 , 255 ) ) ;
2017-08-21 08:40:24 +02:00
break ;
case QgsFields : : OriginJoin :
2017-10-28 11:00:17 +02:00
mFieldsList - > item ( idx , i ) - > setBackgroundColor ( QColor ( 200 , 255 , 200 ) ) ;
2017-08-21 08:40:24 +02:00
break ;
default :
2017-10-28 11:00:17 +02:00
mFieldsList - > item ( idx , i ) - > setBackgroundColor ( QColor ( 255 , 255 , 200 ) ) ;
2017-08-21 08:40:24 +02:00
break ;
}
}
}
void QgsSourceFieldsProperties : : attributeDeleted ( int idx )
{
mFieldsList - > removeRow ( mIndexedWidgets . at ( idx ) - > row ( ) ) ;
mIndexedWidgets . removeAt ( idx ) ;
for ( int i = idx ; i < mIndexedWidgets . count ( ) ; i + + )
{
mIndexedWidgets . at ( i ) - > setData ( Qt : : DisplayRole , i ) ;
}
}
void QgsSourceFieldsProperties : : setRow ( int row , int idx , const QgsField & field )
{
QTableWidgetItem * dataItem = new QTableWidgetItem ( ) ;
dataItem - > setData ( Qt : : DisplayRole , idx ) ;
switch ( mLayer - > fields ( ) . fieldOrigin ( idx ) )
{
case QgsFields : : OriginExpression :
dataItem - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /mIconExpression.svg " ) ) ) ;
break ;
case QgsFields : : OriginJoin :
dataItem - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /propertyicons/join.png " ) ) ) ;
break ;
default :
dataItem - > setIcon ( mLayer - > fields ( ) . iconForField ( idx ) ) ;
break ;
}
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 ( ) ) ) ) ;
if ( mLayer - > fields ( ) . fieldOrigin ( idx ) = = QgsFields : : OriginExpression )
{
QWidget * expressionWidget = new QWidget ;
expressionWidget - > setLayout ( new QHBoxLayout ) ;
QToolButton * editExpressionButton = new QToolButton ;
editExpressionButton - > setProperty ( " Index " , idx ) ;
editExpressionButton - > setIcon ( QgsApplication : : getThemeIcon ( QStringLiteral ( " /mIconExpression.svg " ) ) ) ;
connect ( editExpressionButton , & QAbstractButton : : clicked , this , & QgsSourceFieldsProperties : : updateExpression ) ;
expressionWidget - > layout ( ) - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
expressionWidget - > layout ( ) - > addWidget ( editExpressionButton ) ;
expressionWidget - > layout ( ) - > addWidget ( new QLabel ( mLayer - > expressionField ( idx ) ) ) ;
mFieldsList - > setCellWidget ( row , AttrCommentCol , expressionWidget ) ;
}
else
{
mFieldsList - > setItem ( row , AttrCommentCol , new QTableWidgetItem ( field . comment ( ) ) ) ;
}
QList < int > notEditableCols = QList < int > ( )
< < AttrIdCol
< < AttrNameCol
< < AttrTypeCol
< < AttrTypeNameCol
< < AttrLengthCol
< < AttrPrecCol ;
Q_FOREACH ( int i , notEditableCols )
mFieldsList - > item ( row , i ) - > setFlags ( mFieldsList - > item ( row , i ) - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
bool canRenameFields = mLayer - > isEditable ( ) & & ( mLayer - > dataProvider ( ) - > capabilities ( ) & QgsVectorDataProvider : : RenameAttributes ) & & ! mLayer - > readOnly ( ) ;
if ( canRenameFields )
mFieldsList - > item ( row , AttrNameCol ) - > setFlags ( mFieldsList - > item ( row , AttrNameCol ) - > flags ( ) | Qt : : ItemIsEditable ) ;
else
mFieldsList - > item ( row , AttrNameCol ) - > setFlags ( mFieldsList - > item ( row , AttrNameCol ) - > flags ( ) & ~ Qt : : ItemIsEditable ) ;
//set the alias for the attribute
mFieldsList - > setItem ( row , AttrAliasCol , new QTableWidgetItem ( field . alias ( ) ) ) ;
//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 ) ;
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 ) ;
mFieldsList - > setItem ( row , AttrWFSCol , wfsAttrItem ) ;
}
bool QgsSourceFieldsProperties : : addAttribute ( const QgsField & field )
{
QgsDebugMsg ( " inserting attribute " + field . name ( ) + " of type " + field . typeName ( ) ) ;
mLayer - > beginEditCommand ( tr ( " Added attribute " ) ) ;
if ( mLayer - > addAttribute ( field ) )
{
mLayer - > endEditCommand ( ) ;
return true ;
}
else
{
mLayer - > destroyEditCommand ( ) ;
QMessageBox : : critical ( this , tr ( " Failed to add field " ) , tr ( " Failed to add field '%1' of type '%2'. Is the field name unique? " ) . arg ( field . name ( ) , field . typeName ( ) ) ) ;
return false ;
}
}
//SLOTS
void QgsSourceFieldsProperties : : editingToggled ( )
{
updateButtons ( ) ;
updateFieldRenamingStatus ( ) ;
}
2017-10-28 11:00:17 +02:00
void QgsSourceFieldsProperties : : addAttributeClicked ( )
{
2017-08-21 08:40:24 +02:00
QgsAddAttrDialog dialog ( mLayer , this ) ;
if ( dialog . exec ( ) = = QDialog : : Accepted )
{
addAttribute ( dialog . field ( ) ) ;
}
}
2017-10-28 11:00:17 +02:00
void QgsSourceFieldsProperties : : deleteAttributeClicked ( )
{
2017-08-21 08:40:24 +02:00
QSet < int > providerFields ;
QSet < int > expressionFields ;
Q_FOREACH ( QTableWidgetItem * item , mFieldsList - > selectedItems ( ) )
{
if ( item - > column ( ) = = 0 )
{
int idx = mIndexedWidgets . indexOf ( item ) ;
if ( idx < 0 )
continue ;
if ( mLayer - > fields ( ) . fieldOrigin ( idx ) = = QgsFields : : OriginExpression )
expressionFields < < idx ;
else
providerFields < < idx ;
}
}
if ( ! expressionFields . isEmpty ( ) )
mLayer - > deleteAttributes ( expressionFields . toList ( ) ) ;
if ( ! providerFields . isEmpty ( ) )
{
mLayer - > beginEditCommand ( tr ( " Deleted attributes " ) ) ;
if ( mLayer - > deleteAttributes ( providerFields . toList ( ) ) )
mLayer - > endEditCommand ( ) ;
else
mLayer - > destroyEditCommand ( ) ;
}
}
2017-10-28 11:00:17 +02:00
void QgsSourceFieldsProperties : : calculateFieldClicked ( )
{
2017-08-21 08:40:24 +02:00
if ( ! mLayer )
{
return ;
}
QgsFieldCalculator calc ( mLayer , this ) ;
calc . exec ( ) ;
}
void QgsSourceFieldsProperties : : attributesListCellChanged ( int row , int column )
{
if ( column = = AttrAliasCol & & mLayer )
{
int idx = mFieldsList - > item ( row , AttrIdCol ) - > text ( ) . toInt ( ) ;
const QgsFields & fields = mLayer - > fields ( ) ;
if ( idx > = fields . count ( ) )
{
return ; // index must be wrong
}
QTableWidgetItem * aliasItem = mFieldsList - > item ( row , column ) ;
if ( aliasItem )
{
if ( ! aliasItem - > text ( ) . trimmed ( ) . isEmpty ( ) )
{
mLayer - > setFieldAlias ( idx , aliasItem - > text ( ) ) ;
}
else
{
mLayer - > removeFieldAlias ( idx ) ;
}
}
}
else if ( column = = AttrNameCol & & mLayer & & mLayer - > isEditable ( ) )
{
QTableWidgetItem * nameItem = mFieldsList - > item ( row , column ) ;
if ( ! nameItem | |
nameItem - > text ( ) . isEmpty ( ) | |
! mLayer - > fields ( ) . exists ( row ) | |
mLayer - > fields ( ) . at ( row ) . name ( ) = = nameItem - > text ( ) )
return ;
mLayer - > beginEditCommand ( tr ( " Rename attribute " ) ) ;
if ( mLayer - > renameAttribute ( row , nameItem - > text ( ) ) )
{
mLayer - > endEditCommand ( ) ;
}
else
{
mLayer - > destroyEditCommand ( ) ;
QMessageBox : : critical ( this , tr ( " Failed to rename field " ) , tr ( " Failed to rename field to '%1'. Is the field name unique? " ) . arg ( nameItem - > text ( ) ) ) ;
}
}
}
//NICE FUNCTIONS
void QgsSourceFieldsProperties : : updateButtons ( )
{
int cap = mLayer - > dataProvider ( ) - > capabilities ( ) ;
mToggleEditingButton - > setEnabled ( ( cap & QgsVectorDataProvider : : ChangeAttributeValues ) & & ! mLayer - > readOnly ( ) ) ;
if ( mLayer - > isEditable ( ) )
{
mDeleteAttributeButton - > setEnabled ( cap & QgsVectorDataProvider : : DeleteAttributes ) ;
mAddAttributeButton - > setEnabled ( cap & QgsVectorDataProvider : : AddAttributes ) ;
mToggleEditingButton - > setChecked ( true ) ;
}
else
{
mToggleEditingButton - > setChecked ( false ) ;
mAddAttributeButton - > setEnabled ( false ) ;
// Enable delete button if items are selected
mDeleteAttributeButton - > setEnabled ( ! mFieldsList - > selectedItems ( ) . isEmpty ( ) ) ;
// and only if all selected items have their origin in an expression
Q_FOREACH ( QTableWidgetItem * item , mFieldsList - > selectedItems ( ) )
{
if ( item - > column ( ) = = 0 )
{
int idx = mIndexedWidgets . indexOf ( item ) ;
if ( mLayer - > fields ( ) . fieldOrigin ( idx ) ! = QgsFields : : OriginExpression )
{
mDeleteAttributeButton - > setEnabled ( false ) ;
break ;
}
}
}
}
}