class LayerSelectionPage(QFrame): #TODO. Filtering, (visible) row selection, multi selection colparams = ((0,65,'Name'), (1,235,'Title'), (2,350,'Keywords')) XFER_BW = 40 def __init__(self, parent=None): super(LayerSelectionPage, self).__init__(parent) self.parent = parent #convenience link self.confconn_link = self.parent.parent.confconn #flag top prevent read read action on keyword delete. New logic makes this redundant #self.keywordbypass = False QToolTip.setFont(QFont('SansSerif', 10)) #label filterlabel = QLabel('Filter') availablelabel = QLabel('Available Layers') selectionlabel = QLabel('Layer Selections') keywordlabel = QLabel('Keyword') explainlabel = QLabel("Edit Group assignments using this dialog or to simply initialise the Layer-Config just click 'Finish'") #selection buttons chooseallbutton = QPushButton('>>') chooseallbutton.setFixedWidth(self.XFER_BW) chooseallbutton.clicked.connect(self.doChooseAllClickAction) choosebutton = QPushButton('>') choosebutton.setFixedWidth(self.XFER_BW) choosebutton.clicked.connect(self.doChooseClickAction) rejectbutton = QPushButton('<') rejectbutton.setFixedWidth(self.XFER_BW) rejectbutton.clicked.connect(self.doRejectClickAction) rejectallbutton = QPushButton('<<') rejectallbutton.setFixedWidth(self.XFER_BW) rejectallbutton.clicked.connect(self.doRejectAllClickAction) #operation buttons finishbutton = QPushButton('Finish') finishbutton.setToolTip('Finish and Close layer selection dialog') finishbutton.clicked.connect(self.parent.close) resetbutton = QPushButton('Reset') resetbutton.font() resetbutton.setToolTip('Read Layer from LDS GetCapabilities request. Overwrites current Layer Config') resetbutton.clicked.connect(self.doResetClickAction) self.available_sfpm = LDSSFPAvailableModel(self) self.selection_sfpm = LDSSFPSelectionModel(self) self.available_sfpm.setSourceModel(self.parent.available_model) self.selection_sfpm.setSourceModel(self.parent.selection_model) #textedits filteredit = QLineEdit('') filteredit.setToolTip('Filter Available-Layers pane (filter operates across Name and Title fields and accepts Regex expressions)') filteredit.textChanged.connect(self.available_sfpm.setActiveFilter) self.keywordcombo = QComboBox() self.keywordcombo.setToolTip('Select or Add a unique identifier to be saved in layer config (keyword)') self.keywordcombo.addItems(list(self.confconn_link.assigned)) self.keywordcombo.setEditable(True) self.keywordcombo.activated.connect(self.doKeyComboChangeAction) lgindex = self.confconn_link.getLayerGroupIndex(self.confconn_link.lgval,col=1) lgentry = self.confconn_link.lglist[lgindex] if LU.assessNone(lgindex) else None #keywordedit = self.keywordcombo.lineEdit().text().toUtf8().data().decode('utf8')# for writing #if no entry or layer indicated then blank self.keywordcombo.lineEdit().setText('' if lgentry is None or lgentry[0]==LORG.LAYER else lgentry[1])#self.confconn_link.lgval)#TODO. group only #header headmodel = QStandardItemModel() headmodel.setHorizontalHeaderLabels([i[2] for i in self.colparams][:self.parent.available_model.columnCount()]) headview1 = QHeaderView(Qt.Horizontal) headview1.setModel(headmodel) headview1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) headview2 = QHeaderView(Qt.Horizontal) headview2.setModel(headmodel) headview2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) #table self.available = QTableView() self.available.setSelectionBehavior(QAbstractItemView.SelectRows) self.available.setSelectionMode(QAbstractItemView.MultiSelection) self.selection = QTableView() self.selection.setSelectionBehavior(QAbstractItemView.SelectRows) self.selection.setSelectionMode(QAbstractItemView.MultiSelection) #interesting, must set model after selection attributes but before headers else row selections/headers don't work properly self.available.setModel(self.available_sfpm) self.selection.setModel(self.selection_sfpm) self.available.setSortingEnabled(True) self.available.setHorizontalHeader(headview1) self.selection.setSortingEnabled(True) self.selection.setHorizontalHeader(headview2) for cp in self.colparams: self.available.setColumnWidth(cp[0],cp[1]) self.selection.setColumnWidth(cp[0],cp[1]) self.available.verticalHeader().setVisible(False) self.available.horizontalHeader().setVisible(True) self.selection.verticalHeader().setVisible(False) self.selection.horizontalHeader().setVisible(True) #layout vbox00 = QVBoxLayout() vbox00.addWidget(availablelabel) vbox00.addWidget(self.available) vbox01 = QVBoxLayout() vbox01.addWidget(chooseallbutton) vbox01.addWidget(choosebutton) vbox01.addWidget(rejectbutton) vbox01.addWidget(rejectallbutton) vbox02 = QVBoxLayout() vbox02.addWidget(selectionlabel) vbox02.addWidget(self.selection) vbox10 = QVBoxLayout() vbox10.addWidget(filterlabel) vbox10.addWidget(filteredit) hbox12 = QHBoxLayout() hbox12.addWidget(keywordlabel) hbox12.addStretch(1) #hbox12.addWidget(inspbutton) #hbox12.addWidget(addbutton) #hbox12.addWidget(delbutton) vbox12 = QVBoxLayout() vbox12.addLayout(hbox12) vbox12.addWidget(self.keywordcombo) #00|01|02 #10|11|12 grid0 = QGridLayout() grid0.addLayout(vbox00,1,0) grid0.addLayout(vbox01,1,1) grid0.addLayout(vbox02,1,2) grid0.addLayout(vbox10,0,0) grid0.addLayout(vbox12,0,2) hbox2 = QHBoxLayout() hbox2.addWidget(resetbutton) hbox2.addStretch(1) hbox2.addWidget(explainlabel) hbox2.addWidget(finishbutton) #gbox1.setLayout(hbox2) vbox3 = QVBoxLayout() vbox3.addLayout(grid0) #vbox3.addLayout(hbox3) #vbox3.addWidget(line0) vbox3.addLayout(hbox2) self.setLayout(vbox3) def doChooseAllClickAction(self): '''Moves the lot to Selected''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.selection_model.mdata += self.parent.available_model.mdata self.parent.selection_model.initData(self.confconn_link.complete) self.parent.available_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.setupAssignedLayerList() if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) def doChooseClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #ktext = str(self.keywordcombo.lineEdit().text()) if not self.checkKeyword(ktext): return #------------------------------ select = self.available.selectionModel() if select.hasSelection(): self.transferSelectedRows(select.selectedRows(),self.available_sfpm,self.selection_sfpm) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.assigned = self.confconn_link.setupAssignedLayerList() # -1 to indicate no index since 0,1,... are valid if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) else: ldslog.warn('L2R > Transfer action without selection') #TRACE# #pdb.set_trace() self.available.clearSelection() def transferSelectedRows(self,indices,from_model,to_model): tlist = [] for proxymodelindex in indices: transfer = from_model.getData(proxymodelindex) tlist.append((proxymodelindex,transfer),) to_model.addData([t[1] for t in tlist]) from_model.delData([t[0] for t in tlist]) return tlist def doRejectClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ select = self.selection.selectionModel() if select.hasSelection(): tlist = self.transferSelectedRows(select.selectedRows(),self.selection_sfpm,self.available_sfpm) #------------------------------ kindex = self.keywordcombo.findText(ktext) remainder = self.parent.deleteKeysFromLayerConfig([ll[1][0] for ll in tlist],ktext) if remainder > 0 and kindex == -1: #items+newkey -> add self.parent.writeKeysToLayerConfig(ktext) self.keywordcombo.addItem(ktext) elif remainder == 0 and kindex > -1: #empty+oldkey -> del self.keywordcombo.removeItem(kindex) self.keywordcombo.clearEditText() else: ldslog.warn('R2L < Transfer action without selection') #TRACE# #pdb.set_trace() self.selection.clearSelection() def doRejectAllClickAction(self): #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.deleteKeysFromLayerConfig([ll[0] for ll in self.parent.selection_model.mdata],ktext) #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.available_model.mdata += self.parent.selection_model.mdata self.parent.available_model.initData(self.confconn_link.complete) self.parent.selection_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ #self.confconn_link.setupAssignedLayerList() #self.keywordbypass = True self.keywordcombo.removeItem(self.keywordcombo.findText(ktext)) self.keywordcombo.clearEditText() def doKeyComboChangeAction(self): '''Reset the available pane and if there is anything in the keyword box use this to init the selection pane''' #HACK #if self.keywordbypass: # self.keywordbypass = False # return #------------------------------ #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #------------------------------ av_sl = self.parent.splitData(ktext,self.confconn_link.complete) #av_sl = self.parent.splitData(ktext,self.confconn_link.complete) self.parent.signalModels(self.parent.STEP.PRE) self.parent.available_model.initData(av_sl[0]) self.parent.selection_model.initData(av_sl[1]) self.parent.signalModels(self.parent.STEP.POST) def doResetClickAction(self): '''Dumps the LC and rebuilds from a fresh read of the caps doc''' #int warning (QWidget parent, QString title, QString text, QString button0Text, QString button1Text = QString(), QString button2Text = QString(), int defaultButtonNumber = 0, int escapeButtonNumber = -1) ans = QMessageBox.warning(self, "Reset","This action will overwrite your Layer Configuration using the current LDS settings (potentially adding new or removing layers). Continue?","Continue","Cancel") if ans: #Cancel ldslog.warn('Cancelling Reset operation') return #Continue ldslog.warn('Reset Layer Config') self.parent.resetLayers() self.keywordcombo.clear() def checkKeyword(self,ktext): '''Checks keyword isn't null and isn't part of the LDS supplied keywords''' if LU.assessNone(ktext) is None: QMessageBox.about(self, "Keyword Required","Please enter a Keyword to assign Layer(s) to") return False if ktext in self.confconn_link.reserved: QMessageBox.about(self, "Reserved Keyword","'{}' is a reserved keyword, please select again".format(ktext)) return False return True
def clearSelection(self): self._selected = [] QTableView.clearSelection(self)
class LayerSelectionPage(QFrame): #TODO. Filtering, (visible) row selection, multi selection colparams = ((0, 65, 'Name'), (1, 235, 'Title'), (2, 350, 'Keywords')) XFER_BW = 40 def __init__(self, parent=None): super(LayerSelectionPage, self).__init__(parent) self.parent = parent #convenience link self.confconn_link = self.parent.parent.confconn #flag top prevent read read action on keyword delete. New logic makes this redundant #self.keywordbypass = False QToolTip.setFont(QFont('SansSerif', 10)) #label filterlabel = QLabel('Filter') availablelabel = QLabel('Available Layers') selectionlabel = QLabel('Layer Selections') keywordlabel = QLabel('Keyword') explainlabel = QLabel( "Edit Group assignments using this dialog or to simply initialise the Layer-Config just click 'Finish'" ) #selection buttons chooseallbutton = QPushButton('>>') chooseallbutton.setFixedWidth(self.XFER_BW) chooseallbutton.clicked.connect(self.doChooseAllClickAction) choosebutton = QPushButton('>') choosebutton.setFixedWidth(self.XFER_BW) choosebutton.clicked.connect(self.doChooseClickAction) rejectbutton = QPushButton('<') rejectbutton.setFixedWidth(self.XFER_BW) rejectbutton.clicked.connect(self.doRejectClickAction) rejectallbutton = QPushButton('<<') rejectallbutton.setFixedWidth(self.XFER_BW) rejectallbutton.clicked.connect(self.doRejectAllClickAction) #operation buttons finishbutton = QPushButton('Finish') finishbutton.setToolTip('Finish and Close layer selection dialog') finishbutton.clicked.connect(self.parent.close) resetbutton = QPushButton('Reset') resetbutton.font() resetbutton.setToolTip( 'Read Layer from LDS GetCapabilities request. Overwrites current Layer Config' ) resetbutton.clicked.connect(self.doResetClickAction) self.available_sfpm = LDSSFPAvailableModel(self) self.selection_sfpm = LDSSFPSelectionModel(self) self.available_sfpm.setSourceModel(self.parent.available_model) self.selection_sfpm.setSourceModel(self.parent.selection_model) #textedits filteredit = QLineEdit('') filteredit.setToolTip( 'Filter Available-Layers pane (filter operates across Name and Title fields and accepts Regex expressions)' ) filteredit.textChanged.connect(self.available_sfpm.setActiveFilter) self.keywordcombo = QComboBox() self.keywordcombo.setToolTip( 'Select or Add a unique identifier to be saved in layer config (keyword)' ) self.keywordcombo.addItems(list(self.confconn_link.assigned)) self.keywordcombo.setEditable(True) self.keywordcombo.activated.connect(self.doKeyComboChangeAction) lgindex = self.confconn_link.getLayerGroupIndex( self.confconn_link.lgval, col=1) lgentry = self.confconn_link.lglist[lgindex] if LU.assessNone( lgindex) else None #keywordedit = self.keywordcombo.lineEdit().text().toUtf8().data().decode('utf8')# for writing #if no entry or layer indicated then blank self.keywordcombo.lineEdit().setText( '' if lgentry is None or lgentry[0] == LORG.LAYER else lgentry[1]) #self.confconn_link.lgval)#TODO. group only #header headmodel = QStandardItemModel() headmodel.setHorizontalHeaderLabels([ i[2] for i in self.colparams ][:self.parent.available_model.columnCount()]) headview1 = QHeaderView(Qt.Horizontal) headview1.setModel(headmodel) headview1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) headview2 = QHeaderView(Qt.Horizontal) headview2.setModel(headmodel) headview2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) #table self.available = QTableView() self.available.setSelectionBehavior(QAbstractItemView.SelectRows) self.available.setSelectionMode(QAbstractItemView.MultiSelection) self.selection = QTableView() self.selection.setSelectionBehavior(QAbstractItemView.SelectRows) self.selection.setSelectionMode(QAbstractItemView.MultiSelection) #interesting, must set model after selection attributes but before headers else row selections/headers don't work properly self.available.setModel(self.available_sfpm) self.selection.setModel(self.selection_sfpm) self.available.setSortingEnabled(True) self.available.setHorizontalHeader(headview1) self.selection.setSortingEnabled(True) self.selection.setHorizontalHeader(headview2) for cp in self.colparams: self.available.setColumnWidth(cp[0], cp[1]) self.selection.setColumnWidth(cp[0], cp[1]) self.available.verticalHeader().setVisible(False) self.available.horizontalHeader().setVisible(True) self.selection.verticalHeader().setVisible(False) self.selection.horizontalHeader().setVisible(True) #layout vbox00 = QVBoxLayout() vbox00.addWidget(availablelabel) vbox00.addWidget(self.available) vbox01 = QVBoxLayout() vbox01.addWidget(chooseallbutton) vbox01.addWidget(choosebutton) vbox01.addWidget(rejectbutton) vbox01.addWidget(rejectallbutton) vbox02 = QVBoxLayout() vbox02.addWidget(selectionlabel) vbox02.addWidget(self.selection) vbox10 = QVBoxLayout() vbox10.addWidget(filterlabel) vbox10.addWidget(filteredit) hbox12 = QHBoxLayout() hbox12.addWidget(keywordlabel) hbox12.addStretch(1) #hbox12.addWidget(inspbutton) #hbox12.addWidget(addbutton) #hbox12.addWidget(delbutton) vbox12 = QVBoxLayout() vbox12.addLayout(hbox12) vbox12.addWidget(self.keywordcombo) #00|01|02 #10|11|12 grid0 = QGridLayout() grid0.addLayout(vbox00, 1, 0) grid0.addLayout(vbox01, 1, 1) grid0.addLayout(vbox02, 1, 2) grid0.addLayout(vbox10, 0, 0) grid0.addLayout(vbox12, 0, 2) hbox2 = QHBoxLayout() hbox2.addWidget(resetbutton) hbox2.addStretch(1) hbox2.addWidget(explainlabel) hbox2.addWidget(finishbutton) #gbox1.setLayout(hbox2) vbox3 = QVBoxLayout() vbox3.addLayout(grid0) #vbox3.addLayout(hbox3) #vbox3.addWidget(line0) vbox3.addLayout(hbox2) self.setLayout(vbox3) def doChooseAllClickAction(self): '''Moves the lot to Selected''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.selection_model.mdata += self.parent.available_model.mdata self.parent.selection_model.initData(self.confconn_link.complete) self.parent.available_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.setupAssignedLayerList() if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) def doChooseClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #ktext = str(self.keywordcombo.lineEdit().text()) if not self.checkKeyword(ktext): return #------------------------------ select = self.available.selectionModel() if select.hasSelection(): self.transferSelectedRows(select.selectedRows(), self.available_sfpm, self.selection_sfpm) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.assigned = self.confconn_link.setupAssignedLayerList() # -1 to indicate no index since 0,1,... are valid if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) else: ldslog.warn('L2R > Transfer action without selection') #TRACE# #pdb.set_trace() self.available.clearSelection() def transferSelectedRows(self, indices, from_model, to_model): tlist = [] for proxymodelindex in indices: transfer = from_model.getData(proxymodelindex) tlist.append((proxymodelindex, transfer), ) to_model.addData([t[1] for t in tlist]) from_model.delData([t[0] for t in tlist]) return tlist def doRejectClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ select = self.selection.selectionModel() if select.hasSelection(): tlist = self.transferSelectedRows(select.selectedRows(), self.selection_sfpm, self.available_sfpm) #------------------------------ kindex = self.keywordcombo.findText(ktext) remainder = self.parent.deleteKeysFromLayerConfig( [ll[1][0] for ll in tlist], ktext) if remainder > 0 and kindex == -1: #items+newkey -> add self.parent.writeKeysToLayerConfig(ktext) self.keywordcombo.addItem(ktext) elif remainder == 0 and kindex > -1: #empty+oldkey -> del self.keywordcombo.removeItem(kindex) self.keywordcombo.clearEditText() else: ldslog.warn('R2L < Transfer action without selection') #TRACE# #pdb.set_trace() self.selection.clearSelection() def doRejectAllClickAction(self): #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.deleteKeysFromLayerConfig( [ll[0] for ll in self.parent.selection_model.mdata], ktext) #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.available_model.mdata += self.parent.selection_model.mdata self.parent.available_model.initData(self.confconn_link.complete) self.parent.selection_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ #self.confconn_link.setupAssignedLayerList() #self.keywordbypass = True self.keywordcombo.removeItem(self.keywordcombo.findText(ktext)) self.keywordcombo.clearEditText() def doKeyComboChangeAction(self): '''Reset the available pane and if there is anything in the keyword box use this to init the selection pane''' #HACK #if self.keywordbypass: # self.keywordbypass = False # return #------------------------------ #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #------------------------------ av_sl = self.parent.splitData(ktext, self.confconn_link.complete) #av_sl = self.parent.splitData(ktext,self.confconn_link.complete) self.parent.signalModels(self.parent.STEP.PRE) self.parent.available_model.initData(av_sl[0]) self.parent.selection_model.initData(av_sl[1]) self.parent.signalModels(self.parent.STEP.POST) def doResetClickAction(self): '''Dumps the LC and rebuilds from a fresh read of the caps doc''' #int warning (QWidget parent, QString title, QString text, QString button0Text, QString button1Text = QString(), QString button2Text = QString(), int defaultButtonNumber = 0, int escapeButtonNumber = -1) ans = QMessageBox.warning( self, "Reset", "This action will overwrite your Layer Configuration using the current LDS settings (potentially adding new or removing layers). Continue?", "Continue", "Cancel") if ans: #Cancel ldslog.warn('Cancelling Reset operation') return #Continue ldslog.warn('Reset Layer Config') self.parent.resetLayers() self.keywordcombo.clear() def checkKeyword(self, ktext): '''Checks keyword isn't null and isn't part of the LDS supplied keywords''' if LU.assessNone(ktext) is None: QMessageBox.about(self, "Keyword Required", "Please enter a Keyword to assign Layer(s) to") return False if ktext in self.confconn_link.reserved: QMessageBox.about( self, "Reserved Keyword", "'{}' is a reserved keyword, please select again".format( ktext)) return False return True
class QgsAttributeTableDialog(QDialog): ''' classdocs ''' def __init__(self, parent, vectorlayer): QDialog.__init__(self, parent) # self.w = QDialog(self) self.baseLayer = vectorlayer self.canChangeAttributes = self.validate( QgsVectorDataProvider.ChangeAttributeValues) self.canDeleteFeatures = self.validate( QgsVectorDataProvider.DeleteFeatures) self.canAddAttributes = self.validate( QgsVectorDataProvider.AddAttributes) self.canDeleteAttributes = self.validate( QgsVectorDataProvider.DeleteAttributes) self.canAddFeatures = self.validate(QgsVectorDataProvider.AddFeatures) gridLayout = QGridLayout(self) self.setLayout(gridLayout) self.setWindowTitle("Attribute Table") self.setFixedSize(QSize(800, 600)) editorToolbar = QToolBar() editorToolbar.setFixedSize(QSize(768, 48)) self.actionToggleEditing = QAction(QIcon("Resource\\edit.png"), "ToggleEditing", self) self.actionToggleEditing.triggered.connect(self.toggleEditing) if (self.canChangeAttributes or self.canDeleteFeatures or self.canAddAttributes or self.canDeleteAttributes or self.canAddFeatures) and (not self.baseLayer.isReadOnly()): self.actionToggleEditing.setEnabled(True) else: self.actionToggleEditing.setEnabled(False) self.actionToggleEditing.setCheckable(True) editorToolbar.addAction(self.actionToggleEditing) self.actionSave = QAction(QIcon("Resource\\filesave.png"), "Save Edits", self) self.actionSave.triggered.connect(self.saveEditing) self.actionSave.setCheckable(False) self.actionSave.setEnabled(False) editorToolbar.addAction(self.actionSave) self.actiondeleteRows = QAction( QIcon("Resource\\mActionDeleteSelected.png"), "Delete selected features", self) self.actiondeleteRows.triggered.connect(self.deleteRows) self.actiondeleteRows.setCheckable(False) self.actiondeleteRows.setEnabled(False) editorToolbar.addAction(self.actiondeleteRows) self.actionUnselectAll = QAction( QIcon("Resource\\mActionDeselectAll.png"), "Unselect All", self) self.actionUnselectAll.triggered.connect(self.unselectAll) self.actionUnselectAll.setCheckable(False) self.actionUnselectAll.setEnabled(True) editorToolbar.addAction(self.actionUnselectAll) self.actionSelectedToZoom = QAction( QIcon("Resource\\mActionZoomToSelected.png"), "Zoom map to the selected rows", self) self.actionSelectedToZoom.triggered.connect(self.selectedToZoom) self.actionSelectedToZoom.setCheckable(False) self.actionSelectedToZoom.setEnabled(True) editorToolbar.addAction(self.actionSelectedToZoom) gridLayout.addWidget(editorToolbar, 0, 0, 1, 1) self.model = QStandardItemModel() # self.model.itemChanged.connect(self.attributeChanged) self.attributeTable = QTableView(self) self.attributeTable.setModel(self.model) self.attributeTable.setColumnWidth(0, 200) self.attributeTable.setColumnWidth(1, 160) self.attributeTable.clicked.connect(self.tableSelectionChanged) self.attributeTable.setSortingEnabled(True) self.changeItemList = [] self.selectRows = [] self.isSave = True self.initTable() gridLayout.addWidget(self.attributeTable, 1, 0, 1, 1) # self.attributeTable.selectionChanged.connect(self.selectFeature) def tableSelectionChanged(self): idxList = self.attributeTable.selectedIndexes() if idxList != None and len(idxList) > 0: self.baseLayer.removeSelection() fidList = [] for idx in idxList: fid = int(self.model.item(idx.row()).text()) fidList.append(fid) self.baseLayer.setSelectedFeatures(fidList) def toggleEditing(self): if self.baseLayer != None: if not self.actionToggleEditing.isChecked(): if self.isSave: self.baseLayer.commitChanges() self.actionSave.setEnabled(False) self.actiondeleteRows.setEnabled(False) self.model.itemChanged.disconnect(self.attributeChanged) self.toggleEditingTable(False) else: button = QMessageBox.warning( self, "Stop Editing", "Do you want to save the changes to layer?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if (button == QMessageBox.Cancel): self.actionToggleEditing.setChecked(True) elif button == QMessageBox.Save: self.saveEditing() self.baseLayer.commitChanges() self.actionSave.setEnabled(False) self.actiondeleteRows.setEnabled(False) self.model.itemChanged.disconnect( self.attributeChanged) self.toggleEditingTable(False) else: self.initTable() self.baseLayer.commitChanges() self.actionSave.setEnabled(False) self.actiondeleteRows.setEnabled(False) self.model.itemChanged.disconnect( self.attributeChanged) self.toggleEditingTable(False) # self.isEditable = False else: self.actionSave.setEnabled(True) self.actiondeleteRows.setEnabled(True) self.baseLayer.startEditing() self.toggleEditingTable(True) self.model.itemChanged.connect(self.attributeChanged) # self.isEditable = True def toggleEditingTable(self, isEditable): columnCount = self.model.columnCount() rowCount = self.model.rowCount() col = 0 while col < columnCount: row = 0 while row < rowCount: self.model.item(row, col).setEditable(isEditable) row += 1 col += 1 def attributeChanged(self, standardItem): self.isSave = False # if not self.isDelete: self.changeItemList.append(standardItem) # featureId = standardItem.row() # self.baseLayer.changeAttributeValue(featureId, # standardItem.column(), standardItem.text()) def saveEditing(self): self.isSave = True if len(self.changeItemList) > 0: for standardItem in self.changeItemList: featureId = standardItem.row() self.baseLayer.changeAttributeValue(featureId, standardItem.column(), standardItem.text()) self.changeItemList = [] if len(self.selectRows) > 0: for id in self.selectRows: self.baseLayer.deleteFeature(id) self.selectRows = [] def initTable(self): self.model.clear() # header = QHeaderView(Qt.Horizontal) # headerModel = QStandardItemModel() layer = self.baseLayer fields = layer.pendingFields() headersList = ["fid"] for field in fields: headersList.append(field.name()) self.model.setHorizontalHeaderLabels(headersList) # headerModel.setHorizontalHeaderLabels(headersList) # header.setModel(headerModel) # self.attributeTable.setHorizontalHeader(header) if len(layer.selectedFeatures()) > 0: features = layer.selectedFeatures() else: features = layer.getFeatures() for feature in features: record = [QStandardItem(str(feature.id()))] for field in feature.fields(): name = field.name() attribute = feature.attribute(name).toString() stdItemValue = QStandardItem(attribute) stdItemValue.setEditable(False) record.append(stdItemValue) self.model.appendRow(record) def deleteRows(self): if len(self.attributeTable.selectedIndexes()) > 0: self.isSave = False selectedIndexs = self.attributeTable.selectedIndexes() k = -1 self.selectRows = [] for index in selectedIndexs: if k != index.row(): k = index.row() self.selectRows.append(k) for row in self.selectRows: self.model.takeRow(row) def unselectAll(self): if len(self.attributeTable.selectedIndexes()) > 0: self.attributeTable.clearSelection() def selectedToZoom(self): if len(self.attributeTable.selectedIndexes()) > 0: self.baseLayer.removeSelection() selectedIndexs = self.attributeTable.selectedIndexes() k = -1 self.selectRows = [] for index in selectedIndexs: if k != index.row(): k = index.row() self.selectRows.append(k) self.baseLayer.setSelectedFeatures(self.selectRows) # for row in self.selectRows: # self.model.takeRow(row) define._canvas.zoomToSelected(self.baseLayer) def validate(self, condition): if self.baseLayer.dataProvider().capabilities() & condition: return True else: return False