2015-01-22 14:52:52 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
"""
|
|
|
|
***************************************************************************
|
|
|
|
FieldsMappingWidget.py
|
|
|
|
---------------------
|
|
|
|
Date : October 2014
|
|
|
|
Copyright : (C) 2014 by Arnaud Morvan
|
|
|
|
Email : arnaud dot morvan at camptocamp dot com
|
|
|
|
***************************************************************************
|
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
* *
|
|
|
|
***************************************************************************
|
|
|
|
"""
|
|
|
|
|
|
|
|
__author__ = 'Arnaud Morvan'
|
|
|
|
__date__ = 'October 2014'
|
|
|
|
__copyright__ = '(C) 2014, Arnaud Morvan'
|
|
|
|
|
|
|
|
# This will get replaced with a git SHA1 when you do a git archive
|
|
|
|
|
|
|
|
__revision__ = '$Format:%H$'
|
|
|
|
|
2015-05-18 21:04:20 +03:00
|
|
|
import os
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
from collections import OrderedDict
|
|
|
|
|
2016-04-29 11:39:26 +02:00
|
|
|
from qgis.PyQt import uic
|
2016-04-22 10:38:48 +02:00
|
|
|
from qgis.PyQt.QtGui import QBrush, QIcon
|
|
|
|
from qgis.PyQt.QtWidgets import QComboBox, QHeaderView, QLineEdit, QMessageBox, QSpinBox, QStyledItemDelegate
|
2016-09-11 20:41:21 +02:00
|
|
|
from qgis.PyQt.QtCore import QItemSelectionModel, QAbstractTableModel, QModelIndex, QVariant, Qt, pyqtSlot
|
2015-01-22 14:52:52 +01:00
|
|
|
|
2016-09-11 20:41:21 +02:00
|
|
|
from qgis.core import QgsExpression, QgsExpressionContextUtils, QgsApplication
|
2015-01-22 14:52:52 +01:00
|
|
|
from qgis.gui import QgsFieldExpressionWidget
|
|
|
|
|
|
|
|
from processing.tools import dataobjects
|
|
|
|
|
2015-05-18 21:04:20 +03:00
|
|
|
pluginPath = os.path.dirname(__file__)
|
|
|
|
WIDGET, BASE = uic.loadUiType(
|
|
|
|
os.path.join(pluginPath, 'widgetFieldsMapping.ui'))
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
class FieldsMappingModel(QAbstractTableModel):
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
fieldTypes = OrderedDict([
|
2016-03-14 20:26:58 +01:00
|
|
|
(QVariant.Int, "Integer"),
|
|
|
|
(QVariant.Double, "Double"),
|
|
|
|
(QVariant.String, "String"),
|
|
|
|
(QVariant.DateTime, "Date"),
|
|
|
|
(QVariant.LongLong, "Double"),
|
|
|
|
(QVariant.Date, "Date")])
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
columns = [
|
2016-03-14 20:26:58 +01:00
|
|
|
{'name': 'name', 'type': QVariant.String},
|
|
|
|
{'name': 'type', 'type': QVariant.Type},
|
|
|
|
{'name': 'length', 'type': QVariant.Int},
|
|
|
|
{'name': 'precision', 'type': QVariant.Int},
|
|
|
|
# {'name': 'comment', 'type': QVariant.String},
|
2015-01-22 14:52:52 +01:00
|
|
|
{'name': 'expression', 'type': QgsExpression}]
|
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(FieldsMappingModel, self).__init__(parent)
|
|
|
|
self._mapping = []
|
|
|
|
self._errors = []
|
|
|
|
self._layer = None
|
|
|
|
|
|
|
|
def mapping(self):
|
|
|
|
return self._mapping
|
|
|
|
|
|
|
|
def setMapping(self, value):
|
|
|
|
self.beginResetModel()
|
|
|
|
self._mapping = value
|
|
|
|
self.testAllExpressions()
|
|
|
|
self.endResetModel()
|
|
|
|
|
|
|
|
def testAllExpressions(self):
|
2016-03-21 04:58:12 +01:00
|
|
|
self._errors = [None for i in xrange(len(self._mapping))]
|
|
|
|
for row in xrange(len(self._mapping)):
|
2015-01-22 14:52:52 +01:00
|
|
|
self.testExpression(row)
|
|
|
|
|
|
|
|
def testExpression(self, row):
|
|
|
|
self._errors[row] = None
|
|
|
|
field = self._mapping[row]
|
|
|
|
expression = QgsExpression(field['expression'])
|
|
|
|
if expression.hasParserError():
|
|
|
|
self._errors[row] = expression.parserErrorString()
|
|
|
|
return
|
|
|
|
if self._layer is None:
|
|
|
|
return
|
2016-08-06 20:47:55 +10:00
|
|
|
context = QgsExpressionContextUtils.createFeatureBasedContext(QgsFeature(), self._layer.fields())
|
2015-01-22 14:52:52 +01:00
|
|
|
for feature in dp.getFeatures():
|
2016-08-06 20:47:55 +10:00
|
|
|
context.setFeature(feature)
|
|
|
|
expression.evaluate(context)
|
2015-01-22 14:52:52 +01:00
|
|
|
if expression.hasEvalError():
|
|
|
|
self._errors[row] = expression.evalErrorString()
|
|
|
|
return
|
|
|
|
break
|
|
|
|
|
|
|
|
def layer(self):
|
|
|
|
return self._layer
|
|
|
|
|
|
|
|
def setLayer(self, layer):
|
|
|
|
self._layer = layer
|
|
|
|
self.testAllExpressions()
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def columnCount(self, parent=QModelIndex()):
|
2015-01-22 14:52:52 +01:00
|
|
|
if parent.isValid():
|
|
|
|
return 0
|
|
|
|
return len(self.columns)
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def rowCount(self, parent=QModelIndex()):
|
2015-01-22 14:52:52 +01:00
|
|
|
if parent.isValid():
|
|
|
|
return 0
|
|
|
|
return self._mapping.__len__()
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
|
|
if role == Qt.DisplayRole:
|
|
|
|
if orientation == Qt.Horizontal:
|
2015-01-22 14:52:52 +01:00
|
|
|
return self.columns[section]['name'].title()
|
2016-03-14 20:26:58 +01:00
|
|
|
if orientation == Qt.Vertical:
|
2015-01-22 14:52:52 +01:00
|
|
|
return section
|
|
|
|
|
|
|
|
def flags(self, index):
|
2016-03-14 20:26:58 +01:00
|
|
|
flags = (Qt.ItemIsSelectable
|
|
|
|
+ Qt.ItemIsEditable
|
|
|
|
+ Qt.ItemIsEnabled)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
return Qt.ItemFlags(flags)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def data(self, index, role=Qt.DisplayRole):
|
2015-01-22 14:52:52 +01:00
|
|
|
column = index.column()
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
if role == Qt.DisplayRole:
|
2015-01-22 14:52:52 +01:00
|
|
|
field = self._mapping[index.row()]
|
|
|
|
column_def = self.columns[column]
|
|
|
|
value = field[column_def['name']]
|
|
|
|
|
|
|
|
fieldType = column_def['type']
|
2016-03-14 20:26:58 +01:00
|
|
|
if fieldType == QVariant.Type:
|
|
|
|
if value == QVariant.Invalid:
|
2015-01-22 14:52:52 +01:00
|
|
|
return ''
|
|
|
|
return self.fieldTypes[value]
|
|
|
|
return value
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
if role == Qt.EditRole:
|
2015-01-22 14:52:52 +01:00
|
|
|
field = self._mapping[index.row()]
|
|
|
|
column_def = self.columns[column]
|
|
|
|
value = field[column_def['name']]
|
|
|
|
return value
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
if role == Qt.TextAlignmentRole:
|
2015-01-22 14:52:52 +01:00
|
|
|
fieldType = self.columns[column]['type']
|
2016-03-14 20:26:58 +01:00
|
|
|
if fieldType in [QVariant.Int]:
|
|
|
|
hAlign = Qt.AlignRight
|
2015-01-22 14:52:52 +01:00
|
|
|
else:
|
2016-03-14 20:26:58 +01:00
|
|
|
hAlign = Qt.AlignLeft
|
|
|
|
return hAlign + Qt.AlignVCenter
|
2015-01-22 14:52:52 +01:00
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
if role == Qt.ForegroundRole:
|
2015-01-22 14:52:52 +01:00
|
|
|
column_def = self.columns[column]
|
|
|
|
if column_def['name'] == 'expression':
|
2016-03-14 20:26:58 +01:00
|
|
|
brush = QBrush()
|
2015-01-22 14:52:52 +01:00
|
|
|
if self._errors[index.row()]:
|
2016-03-14 20:26:58 +01:00
|
|
|
brush.setColor(Qt.red)
|
2015-01-22 14:52:52 +01:00
|
|
|
else:
|
2016-03-14 20:26:58 +01:00
|
|
|
brush.setColor(Qt.black)
|
2015-01-22 14:52:52 +01:00
|
|
|
return brush
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
if role == Qt.ToolTipRole:
|
2015-01-22 14:52:52 +01:00
|
|
|
column_def = self.columns[column]
|
|
|
|
if column_def['name'] == 'expression':
|
|
|
|
return self._errors[index.row()]
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def setData(self, index, value, role=Qt.EditRole):
|
|
|
|
if role == Qt.EditRole:
|
2015-01-22 14:52:52 +01:00
|
|
|
field = self._mapping[index.row()]
|
|
|
|
column = index.column()
|
|
|
|
column_def = self.columns[column]
|
|
|
|
field[column_def['name']] = value
|
|
|
|
if column_def['name'] == 'expression':
|
|
|
|
self.testExpression(index.row())
|
|
|
|
self.dataChanged.emit(index, index)
|
|
|
|
return True
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def insertRows(self, row, count, index=QModelIndex()):
|
2015-01-22 14:52:52 +01:00
|
|
|
self.beginInsertRows(index, row, row + count - 1)
|
|
|
|
|
2016-03-21 04:58:12 +01:00
|
|
|
for i in xrange(count):
|
2015-01-22 14:52:52 +01:00
|
|
|
field = self.newField()
|
|
|
|
self._mapping.insert(row + i, field)
|
|
|
|
self._errors.insert(row + i, None)
|
|
|
|
self.testExpression(row)
|
|
|
|
|
|
|
|
self.endInsertRows()
|
|
|
|
return True
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
def removeRows(self, row, count, index=QModelIndex()):
|
2015-01-22 14:52:52 +01:00
|
|
|
self.beginRemoveRows(index, row, row + count - 1)
|
|
|
|
|
|
|
|
for i in xrange(row + count - 1, row + 1):
|
|
|
|
self._mapping.pop(i)
|
|
|
|
self._errors.pop(i)
|
|
|
|
|
|
|
|
self.endRemoveRows()
|
|
|
|
return True
|
|
|
|
|
|
|
|
def newField(self, field=None):
|
|
|
|
if field is None:
|
|
|
|
return {'name': '',
|
2016-03-14 20:26:58 +01:00
|
|
|
'type': QVariant.Invalid,
|
2015-01-22 14:52:52 +01:00
|
|
|
'length': 0,
|
|
|
|
'precision': 0,
|
|
|
|
'expression': ''}
|
|
|
|
|
|
|
|
return {'name': field.name(),
|
|
|
|
'type': field.type(),
|
|
|
|
'length': field.length(),
|
|
|
|
'precision': field.precision(),
|
2016-06-02 16:22:09 +07:00
|
|
|
'expression': QgsExpression.quotedColumnRef(field.name())}
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
def loadLayerFields(self, layer):
|
|
|
|
self.beginResetModel()
|
|
|
|
|
|
|
|
self._mapping = []
|
|
|
|
if layer is not None:
|
|
|
|
dp = layer.dataProvider()
|
|
|
|
for field in dp.fields():
|
|
|
|
self._mapping.append(self.newField(field))
|
|
|
|
self.testAllExpressions()
|
|
|
|
|
|
|
|
self.endResetModel()
|
|
|
|
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
class FieldDelegate(QStyledItemDelegate):
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(FieldDelegate, self).__init__(parent)
|
|
|
|
|
|
|
|
def createEditor(self, parent, option, index):
|
|
|
|
column = index.column()
|
|
|
|
|
|
|
|
fieldType = FieldsMappingModel.columns[column]['type']
|
2016-03-14 20:26:58 +01:00
|
|
|
if fieldType == QVariant.Type:
|
|
|
|
editor = QComboBox(parent)
|
2015-01-22 14:52:52 +01:00
|
|
|
for key, text in FieldsMappingModel.fieldTypes.iteritems():
|
|
|
|
editor.addItem(text, key)
|
|
|
|
|
|
|
|
elif fieldType == QgsExpression:
|
|
|
|
editor = QgsFieldExpressionWidget(parent)
|
|
|
|
editor.setLayer(index.model().layer())
|
2015-02-11 15:46:51 +01:00
|
|
|
editor.fieldChanged.connect(self.on_expression_fieldChange)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
else:
|
2016-03-14 20:26:58 +01:00
|
|
|
editor = QStyledItemDelegate.createEditor(self, parent, option, index)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
editor.setAutoFillBackground(True)
|
|
|
|
return editor
|
|
|
|
|
|
|
|
def setEditorData(self, editor, index):
|
|
|
|
if not editor:
|
|
|
|
return
|
|
|
|
|
|
|
|
column = index.column()
|
2016-03-14 20:26:58 +01:00
|
|
|
value = index.model().data(index, Qt.EditRole)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
fieldType = FieldsMappingModel.columns[column]['type']
|
2016-03-14 20:26:58 +01:00
|
|
|
if fieldType == QVariant.Type:
|
2015-01-22 14:52:52 +01:00
|
|
|
editor.setCurrentIndex(editor.findData(value))
|
|
|
|
|
|
|
|
elif fieldType == QgsExpression:
|
|
|
|
editor.setField(value)
|
|
|
|
|
|
|
|
else:
|
2016-03-14 20:26:58 +01:00
|
|
|
QStyledItemDelegate.setEditorData(self, editor, index)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
def setModelData(self, editor, model, index):
|
|
|
|
if not editor:
|
|
|
|
return
|
|
|
|
|
|
|
|
column = index.column()
|
|
|
|
|
|
|
|
fieldType = FieldsMappingModel.columns[column]['type']
|
2016-03-14 20:26:58 +01:00
|
|
|
if fieldType == QVariant.Type:
|
2015-01-22 14:52:52 +01:00
|
|
|
value = editor.itemData(editor.currentIndex())
|
2015-02-11 14:34:12 +01:00
|
|
|
if value is None:
|
2016-03-14 20:26:58 +01:00
|
|
|
value = QVariant.Invalid
|
2015-01-22 14:52:52 +01:00
|
|
|
model.setData(index, value)
|
|
|
|
|
|
|
|
elif fieldType == QgsExpression:
|
|
|
|
(value, isExpression, isValid) = editor.currentField()
|
2016-06-02 16:22:09 +07:00
|
|
|
if isExpression is True:
|
|
|
|
model.setData(index, value)
|
|
|
|
else:
|
|
|
|
model.setData(index, QgsExpression.quotedColumnRef(value))
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
else:
|
2016-03-14 20:26:58 +01:00
|
|
|
QStyledItemDelegate.setModelData(self, editor, model, index)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
def updateEditorGeometry(self, editor, option, index):
|
|
|
|
editor.setGeometry(option.rect)
|
|
|
|
|
2015-02-11 15:46:51 +01:00
|
|
|
def on_expression_fieldChange(self, fieldName):
|
|
|
|
self.commitData.emit(self.sender())
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
|
2015-05-18 21:04:20 +03:00
|
|
|
class FieldsMappingPanel(BASE, WIDGET):
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
2015-05-18 21:04:20 +03:00
|
|
|
super(FieldsMappingPanel, self).__init__(parent)
|
2015-01-22 14:52:52 +01:00
|
|
|
self.setupUi(self)
|
|
|
|
|
2016-09-11 20:41:21 +02:00
|
|
|
self.addButton.setIcon(QgsApplication.getThemeIcon("/mActionNewAttribute.svg"))
|
|
|
|
self.deleteButton.setIcon(QgsApplication.getThemeIcon('/mActionDeleteAttribute.svg'))
|
|
|
|
self.upButton.setIcon(QgsApplication.getThemeIcon('/mActionArrowUp.png'))
|
|
|
|
self.downButton.setIcon(QgsApplication.getThemeIcon('/mActionArrowDown.png'))
|
|
|
|
self.resetButton.setIcon(QgsApplication.getThemeIcon('/mIconClear.svg'))
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
self.model = FieldsMappingModel()
|
|
|
|
self.fieldsView.setModel(self.model)
|
|
|
|
|
|
|
|
self.model.rowsInserted.connect(self.on_model_rowsInserted)
|
|
|
|
self.fieldsView.setItemDelegate(FieldDelegate())
|
|
|
|
|
|
|
|
self.updateLayerCombo()
|
|
|
|
|
|
|
|
def setLayer(self, layer):
|
|
|
|
self.model.setLayer(layer)
|
|
|
|
if self.model.rowCount() == 0:
|
|
|
|
self.on_resetButton_clicked()
|
|
|
|
else:
|
2016-03-14 20:26:58 +01:00
|
|
|
dlg = QMessageBox(self)
|
2015-01-22 14:52:52 +01:00
|
|
|
dlg.setText("Do you want to reset the field mapping?")
|
|
|
|
dlg.setStandardButtons(
|
2016-09-11 20:41:21 +02:00
|
|
|
QMessageBox.StandardButtons(QMessageBox.Yes |
|
|
|
|
QMessageBox.No))
|
2016-03-14 20:26:58 +01:00
|
|
|
dlg.setDefaultButton(QMessageBox.No)
|
|
|
|
if dlg.exec_() == QMessageBox.Yes:
|
2015-01-22 14:52:52 +01:00
|
|
|
self.on_resetButton_clicked()
|
|
|
|
|
|
|
|
def value(self):
|
|
|
|
return self.model.mapping()
|
|
|
|
|
|
|
|
def setValue(self, value):
|
|
|
|
self.model.setMapping(value)
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
@pyqtSlot(bool, name='on_addButton_clicked')
|
2015-01-22 14:52:52 +01:00
|
|
|
def on_addButton_clicked(self, checked=False):
|
|
|
|
rowCount = self.model.rowCount()
|
|
|
|
self.model.insertRows(rowCount, 1)
|
|
|
|
index = self.model.index(rowCount, 0)
|
|
|
|
self.fieldsView.selectionModel().select(index,
|
2016-09-11 20:41:21 +02:00
|
|
|
QItemSelectionModel.SelectionFlags(QItemSelectionModel.Clear |
|
|
|
|
QItemSelectionModel.Select |
|
|
|
|
QItemSelectionModel.Current |
|
|
|
|
QItemSelectionModel.Rows))
|
2015-01-22 14:52:52 +01:00
|
|
|
self.fieldsView.scrollTo(index)
|
|
|
|
self.fieldsView.scrollTo(index)
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
@pyqtSlot(bool, name='on_deleteButton_clicked')
|
2015-01-22 14:52:52 +01:00
|
|
|
def on_deleteButton_clicked(self, checked=False):
|
|
|
|
sel = self.fieldsView.selectionModel()
|
|
|
|
if not sel.hasSelection():
|
|
|
|
return
|
|
|
|
|
|
|
|
indexes = sel.selectedRows()
|
|
|
|
for index in indexes:
|
|
|
|
self.model.removeRows(index.row(), 1)
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
@pyqtSlot(bool, name='on_upButton_clicked')
|
2015-01-22 14:52:52 +01:00
|
|
|
def on_upButton_clicked(self, checked=False):
|
|
|
|
sel = self.fieldsView.selectionModel()
|
|
|
|
if not sel.hasSelection():
|
|
|
|
return
|
|
|
|
|
|
|
|
row = sel.selectedRows()[0].row()
|
|
|
|
if row == 0:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.model.insertRows(row - 1, 1)
|
|
|
|
|
2016-03-21 04:58:12 +01:00
|
|
|
for column in xrange(self.model.columnCount()):
|
2015-01-22 14:52:52 +01:00
|
|
|
srcIndex = self.model.index(row + 1, column)
|
|
|
|
dstIndex = self.model.index(row - 1, column)
|
2016-03-14 20:26:58 +01:00
|
|
|
value = self.model.data(srcIndex, Qt.EditRole)
|
|
|
|
self.model.setData(dstIndex, value, Qt.EditRole)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
self.model.removeRows(row + 1, 1)
|
|
|
|
|
|
|
|
sel.select(self.model.index(row - 1, 0),
|
2016-09-11 20:41:21 +02:00
|
|
|
QItemSelectionModel.SelectionFlags(QItemSelectionModel.Clear |
|
|
|
|
QItemSelectionModel.Select |
|
|
|
|
QItemSelectionModel.Current |
|
|
|
|
QItemSelectionModel.Rows))
|
2015-01-22 14:52:52 +01:00
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
@pyqtSlot(bool, name='on_downButton_clicked')
|
2015-01-22 14:52:52 +01:00
|
|
|
def on_downButton_clicked(self, checked=False):
|
|
|
|
sel = self.fieldsView.selectionModel()
|
|
|
|
if not sel.hasSelection():
|
|
|
|
return
|
|
|
|
|
|
|
|
row = sel.selectedRows()[0].row()
|
|
|
|
if row == self.model.rowCount() - 1:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.model.insertRows(row + 2, 1)
|
|
|
|
|
2016-03-21 04:58:12 +01:00
|
|
|
for column in xrange(self.model.columnCount()):
|
2015-01-22 14:52:52 +01:00
|
|
|
srcIndex = self.model.index(row, column)
|
|
|
|
dstIndex = self.model.index(row + 2, column)
|
2016-03-14 20:26:58 +01:00
|
|
|
value = self.model.data(srcIndex, Qt.EditRole)
|
|
|
|
self.model.setData(dstIndex, value, Qt.EditRole)
|
2015-01-22 14:52:52 +01:00
|
|
|
|
|
|
|
self.model.removeRows(row, 1)
|
|
|
|
|
|
|
|
sel.select(self.model.index(row + 1, 0),
|
2016-09-11 20:41:21 +02:00
|
|
|
QItemSelectionModel.SelectionFlags(QItemSelectionModel.Clear |
|
|
|
|
QItemSelectionModel.Select |
|
|
|
|
QItemSelectionModel.Current |
|
|
|
|
QItemSelectionModel.Rows))
|
2015-01-22 14:52:52 +01:00
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
@pyqtSlot(bool, name='on_resetButton_clicked')
|
2015-01-22 14:52:52 +01:00
|
|
|
def on_resetButton_clicked(self, checked=False):
|
|
|
|
self.model.loadLayerFields(self.model.layer())
|
|
|
|
self.openPersistentEditor(
|
|
|
|
self.model.index(0, 0),
|
|
|
|
self.model.index(self.model.rowCount() - 1,
|
|
|
|
self.model.columnCount() - 1))
|
|
|
|
self.resizeColumns()
|
|
|
|
|
|
|
|
def resizeColumns(self):
|
|
|
|
header = self.fieldsView.horizontalHeader()
|
2016-03-14 20:26:58 +01:00
|
|
|
header.resizeSections(QHeaderView.ResizeToContents)
|
2016-03-21 04:58:12 +01:00
|
|
|
for section in xrange(header.count()):
|
2015-01-22 14:52:52 +01:00
|
|
|
size = header.sectionSize(section)
|
|
|
|
fieldType = FieldsMappingModel.columns[section]['type']
|
|
|
|
if fieldType == QgsExpression:
|
|
|
|
header.resizeSection(section, size + 100)
|
|
|
|
else:
|
|
|
|
header.resizeSection(section, size + 20)
|
|
|
|
|
|
|
|
def openPersistentEditor(self, topLeft, bottomRight):
|
|
|
|
return
|
|
|
|
for row in xrange(topLeft.row(), bottomRight.row() + 1):
|
|
|
|
for column in xrange(topLeft.column(), bottomRight.column() + 1):
|
|
|
|
self.fieldsView.openPersistentEditor(self.model.index(row, column))
|
|
|
|
editor = self.fieldsView.indexWidget(self.model.index(row, column))
|
2016-03-14 20:26:58 +01:00
|
|
|
if isinstance(editor, QLineEdit):
|
2015-01-22 14:52:52 +01:00
|
|
|
editor.deselect()
|
2016-03-14 20:26:58 +01:00
|
|
|
if isinstance(editor, QSpinBox):
|
|
|
|
lineEdit = editor.findChild(QLineEdit)
|
|
|
|
lineEdit.setAlignment(Qt.AlignRight or Qt.AlignVCenter)
|
2015-01-22 14:52:52 +01:00
|
|
|
lineEdit.deselect()
|
|
|
|
|
|
|
|
def on_model_rowsInserted(self, parent, start, end):
|
|
|
|
self.openPersistentEditor(
|
|
|
|
self.model.index(start, 0),
|
|
|
|
self.model.index(end, self.model.columnCount() - 1))
|
|
|
|
|
|
|
|
def updateLayerCombo(self):
|
2016-04-28 14:14:01 +02:00
|
|
|
layers = dataobjects.getTables()
|
2015-02-11 13:47:20 +01:00
|
|
|
layers.sort(key=lambda lay: lay.name())
|
2015-01-22 14:52:52 +01:00
|
|
|
for layer in layers:
|
|
|
|
self.layerCombo.addItem(layer.name(), layer)
|
|
|
|
|
2016-03-14 20:26:58 +01:00
|
|
|
@pyqtSlot(bool, name='on_loadLayerFieldsButton_clicked')
|
2015-01-22 14:52:52 +01:00
|
|
|
def on_loadLayerFieldsButton_clicked(self, checked=False):
|
|
|
|
layer = self.layerCombo.itemData(self.layerCombo.currentIndex())
|
|
|
|
if layer is None:
|
|
|
|
return
|
|
|
|
self.model.loadLayerFields(layer)
|