class ConflictWindow(QMainWindow): mergeCompleted = pyqtSignal() def __init__(self, layer, type='conflict', parent=None): QMainWindow.__init__(self) self.iface = parent.iface self.layer = layer self.parent = parent self.layer_list = parent.layer_list settings = QSettings() self.tools = PgVersionTools(self) # Restore Window Settings settings = QSettings() try: self.restoreGeometry( pybytearray(settings.value("/pgVersion/geometry"))) self.restoreState( pybytearray(settings.value("/pgVersion/windowState"))) except: pass settings = QSettings() self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) self.canvas.enableAntiAliasing( settings.value("/qgis/enable_anti_aliasing", True, type=bool)) self.canvas.useImageToRender( settings.value("/qgis/use_qimage_to_render", True, type=bool)) action = pyint(settings.value("/qgis/wheel_action", 0)) zoomFactor = pyint(settings.value("/qgis/zoom_factor", 2)) self.canvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) QgsMapLayerRegistry.instance().addMapLayer(layer) self.canvas.setExtent(layer.extent()) self.canvas.setLayerSet([QgsMapCanvasLayer(layer)]) self.canvas.zoomToFullExtent() self.setCentralWidget(self.canvas) actionZoomIn = QAction(QIcon(":/plugins/pgversion/icons/ZoomIn.png"), pystring("Zoom in"), self) actionZoomOut = QAction(QIcon(":/plugins/pgversion/icons/ZoomOut.png"), pystring("Zoom out"), self) actionZoomFull = QAction( QIcon(":/plugins/pgversion/icons/ZoomFullExtent.png"), pystring("Fullextent"), self) actionPan = QAction(QIcon(":/plugins/pgversion/icons/Pan.png"), pystring("Pan"), self) actionZoomIn.setCheckable(True) actionZoomOut.setCheckable(True) actionPan.setCheckable(True) actionZoomIn.triggered.connect(self.zoomIn) actionZoomOut.triggered.connect(self.zoomOut) actionZoomFull.triggered.connect(self.zoomFull) actionPan.triggered.connect(self.pan) self.toolbar = self.addToolBar("Canvas actions") self.toolbar.addAction(actionPan) self.toolbar.addAction(actionZoomIn) self.toolbar.addAction(actionZoomOut) self.toolbar.addAction(actionZoomFull) self.dockWidget = QDockWidget() self.dockWidget.setWidget(QTableWidget()) self.addDockWidget(Qt.BottomDockWidgetArea, self.dockWidget) self.tabView = self.dockWidget.widget() # create the map tools self.toolPan = QgsMapToolPan(self.canvas) self.toolPan.setAction(actionPan) self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in self.toolZoomIn.setAction(actionZoomIn) self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out self.toolZoomOut.setAction(actionZoomOut) self.pan() self.conflictLayerList = [] if type == 'conflict': self.cmbMerge = QComboBox() self.cmbMerge.addItems(self.tools.confRecords(self.layer)) self.btnMerge = QPushButton() self.cmbMerge.currentIndexChanged.connect(self.toggleBtnMerge) self.btnMerge.setText(self.tr('solve conflict')) self.toolbar.addWidget(self.cmbMerge) self.toolbar.addWidget(self.btnMerge) self.manageConflicts() self.btnMerge.clicked.connect(self.runMerge) self.tabView.itemSelectionChanged.connect(self.showConfObject) self.rBand = QgsRubberBand(self.canvas, False) def toggleBtnMerge(self): # if not self.btnMerge.isEnabled(): # self.btnMerge.setEnabled(False) # else: # self.btnMerge.setEnabled(True) return def toggleBtnCommit(self): # if not self.btnMerge.isEnabled(): # self.btnMerge.setEnabled(False) # else: # self.btnMerge.setEnabled(True) return def zoomIn(self): self.canvas.setMapTool(self.toolZoomIn) def zoomOut(self): self.canvas.setMapTool(self.toolZoomOut) def zoomFull(self): self.canvas.zoomToFullExtent() def pan(self): self.canvas.setMapTool(self.toolPan) def closeEvent(self, e): """ save window state """ # settings = QSettings() # settings.setValue("/pgVersion/windowState", pybytearray(self.saveState())) # settings.setValue("/pgVersion/geometry", pybytearray(self.saveGeometry())) QgsMapLayerRegistry.instance().removeMapLayer( self.tools.conflictLayer(self.layer).id()) self.close() def showDiffs(self): pass def showConfObject(self): myProject = self.tabView.item(self.tabView.currentRow(), 0).text() myId = self.tabView.item(self.tabView.currentRow(), 3).text() confLayer = self.tools.conflictLayer(self.layer) self.conflictLayerList.append(confLayer) self.rBand.reset() self.rBand.setColor(QColor(0, 0, 255)) self.rBand.setWidth(5) if confLayer.isValid(): iter = confLayer.getFeatures() for feature in iter: geom = feature.geometry() attrs = feature.attributes() if str(attrs[0]) == myId and attrs[len(attrs) - 5] == myProject: self.rBand.addGeometry(geom, None) return def manageConflicts(self): QApplication.setOverrideCursor(Qt.WaitCursor) vLayer = self.tools.conflictLayer(self.layer) if vLayer == None: return vLayerList = [vLayer, self.layer] QgsMapLayerRegistry.instance().addMapLayers(vLayerList, False) self.vLayerId = vLayer.id() self.canvas.setExtent(vLayer.extent()) self.canvas.refresh() vLayer.triggerRepaint() tabData = self.tools.tableRecords(self.layer) if tabData <> None: self.tools.createGridView(self.tabView, tabData[0], tabData[1], 100, 10) else: QApplication.restoreOverrideCursor() self.mergeCompleted.emit() QApplication.restoreOverrideCursor() def runMerge(self): QApplication.setOverrideCursor(Qt.WaitCursor) currentLayer = self.layer object = self.cmbMerge.currentText() if currentLayer == None: QMessageBox.information( None, self.tr('Notice'), self.tr('Please select a versioned layer for committing')) return else: myDb = self.tools.layerDB('Merge', currentLayer) mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer).replace( "_version", "") objectArray = object.split(" - ") if len(objectArray) == 1: return elif 'Commit all' in objectArray[0]: projectName = objectArray[1].strip() sql = "select objectkey from versions.pgvscheck('%s.%s') \ where myuser = '******' or conflict_user = '******' \ order by objectkey" % (mySchema, myTable, projectName, projectName) result = myDb.read(sql) for i in range(len(result['OBJECTKEY'])): sql = "select versions.pgvsmerge('%s.%s',%s,'%s')" % ( mySchema, myTable, result['OBJECTKEY'][i], projectName) myDb.run(sql) else: projectName = objectArray[1].strip() sql = "select versions.pgvsmerge('%s.%s',%s,'%s')" % ( mySchema, myTable, objectArray[0], projectName) myDb.run(sql) self.canvas.refresh() self.layer.triggerRepaint() self.cmbMerge.clear() QApplication.restoreOverrideCursor() if self.tools.confRecords(self.layer) == None: self.tabView.clear() self.tools.setModified(self.parent.layer_list) self.close() else: self.cmbMerge.addItems(self.tools.confRecords(self.layer)) tabData = self.tools.tableRecords(self.layer) self.tools.createGridView(self.tabView, tabData[0], tabData[1], 100, 10) self.manageConflicts() def loadLayer(self, layer): provider = layer.dataProvider() uri = provider.dataSourceUri() mySchema = self.tools.layerSchema(layer) myHost = self.tools.layerHost(layer) myDatabase = self.tools.layerDB(layer) myPassword = self.tools.layerPassword(layer) myPort = self.tools.layerPort(layer) myUsername = self.tools.layerUsername(layer) myGeometryColumn = self.tools.layerGeomCol(layer) myTable = myTable.replace("_version", "") myUri = QgsDataSourceURI() myUri.setConnection(myHost, myPort, myDatabase, myUsername, myPassword) myUri.setDataSource(mySchema, myTable, myGeometryColumn) myLayer = QgsVectorLayer(myUri.uri(), "", "postgres") QgsMapLayerRegistry.instance().addMapLayer(myLayer, False) # self.canvas.setExtent(myLayer.extent()) self.canvas.setLayerSet([QgsMapCanvasLayer(myLayer)]) self.canvas.refresh()
class PgVersion(QObject): def __init__(self, iface): QObject.__init__(self) # Save reference to the QGIS interface self.iface = iface self.w = None self.vsCheck = None self.layer_list = [] self.tools = PgVersionTools(self) #Initialise thetranslation environment self.plugin_path = QDir.cleanPath( os.path.abspath(os.path.dirname(__file__))) myLocaleName = QLocale.system().name() myLocale = myLocaleName[0:2] if QFileInfo(self.plugin_path).exists(): localePath = self.plugin_path + "/i18n/pgVersion_" + myLocale + ".qm" if QFileInfo(localePath).exists(): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # QgsMapLayerRegistry.instance().layerWasAdded.connect(self.add_layer) # QgsMapLayerRegistry.instance().layerWillBeRemoved.connect(self.remove_layer) def initGui(self): self.helpDialog = HelpDialog() self.LogViewDialog = LogView(self) self.toolBar = self.iface.addToolBar("PG Version") self.toolBar.setObjectName("PG Version") self.actionInit = QAction( QIcon(":/plugins/pgversion/icons/pgversion-init.png"), self.tr("Prepare Layer for Versioning"), self.iface.mainWindow()) self.actionLoad = QAction( QIcon(":/plugins/pgversion/icons/pgversion-commit.png"), self.tr("Load Versioned Layer"), self.iface.mainWindow()) self.actionCommit = QAction( QIcon(":/plugins/pgversion/icons/pgversion-load.png"), self.tr("Commit Changes"), self.iface.mainWindow()) self.actionRevert = QAction( QIcon(":/plugins/pgversion/icons/pgversion-revert.png"), self.tr("Revert to HEAD Revision"), self.iface.mainWindow()) self.actionLogView = QAction( QIcon(":/plugins/pgversion/icons/pgversion-logview.png"), self.tr("Show Logs"), self.iface.mainWindow()) self.actionDiff = QAction( QIcon(":/plugins/pgversion/icons/pgversion-diff.png"), self.tr("Show Diffs"), self.iface.mainWindow()) # self.actionCommit.setEnabled(False) self.actionDrop = QAction( QIcon(":/plugins/pgversion/icons/pgversion-drop.png"), self.tr("Drop Versioning from Layer"), self.iface.mainWindow()) self.actionHelp = QAction(QIcon(""), self.tr("Help"), self.iface.mainWindow()) self.actionAbout = QAction(QIcon(""), self.tr("About"), self.iface.mainWindow()) self.actionDelete = QAction( QIcon(":/plugins/pgversion/icons/pgversion-drop.png"), self.tr("Bulk delete directly in the database"), self.iface.mainWindow()) self.actionDelete.setEnabled(False) self.actionList = [ self.actionInit, self.actionLoad, self.actionCommit, self.actionDiff, self.actionRevert, self.actionLogView, self.actionDrop, self.actionLogView, self.actionDelete, self.actionHelp, self.actionAbout ] # self.actionList = [ self.actionInit,self.actionLoad,self.actionCommit,self.actionRevert, self.actionLogView, self.actionDrop, self.actionLogView, self.actionHelp, self.actionAbout] self.toolBar.addAction(self.actionInit) self.toolBar.addAction(self.actionLoad) self.toolBar.addAction(self.actionCommit) self.toolBar.addAction(self.actionRevert) self.toolBar.addAction(self.actionDiff) self.toolBar.addAction(self.actionLogView) self.toolBar.addAction(self.actionDelete) # Add the Menubar into the new Database Main Menue starting with QGIS1.7 try: for a in self.actionList: self.iface.addPluginToDatabaseMenu("PG Version", a) except AttributeError: # For former QGIS Versions use the old Main Menue self.menu = QMenu() self.menu.setTitle("PG Version") self.menu.addActions(self.actionList) self.menuBar = self.iface.mainWindow().menuBar() self.menuBar.addMenu(self.menu) # connect the action to the run method self.actionInit.triggered.connect(self.doInit) self.actionLoad.triggered.connect(self.doLoad) self.actionDiff.triggered.connect(self.doDiff) self.actionCommit.triggered.connect(self.doCommit) self.actionRevert.triggered.connect(self.doRevert) self.actionLogView.triggered.connect(self.doLogView) self.actionDrop.triggered.connect(self.doDrop) self.actionHelp.triggered.connect(self.doHelp) self.actionAbout.triggered.connect(self.doAbout) self.actionDelete.triggered.connect(self.doDelete) self.LogViewDialog.diffLayer.connect(self.doDiff) self.LogViewDialog.rollbackLayer.connect(self.doRollback) self.LogViewDialog.checkoutLayer.connect(self.doCheckout) self.LogViewDialog.checkoutTag.connect(self.doCheckout) for a in self.iface.digitizeToolBar().actions(): if a.objectName() == 'mActionToggleEditing': a.triggered.connect(self.onSelectionChanged) self.iface.mapCanvas().selectionChanged.connect( self.onSelectionChanged) QgsMapLayerRegistry.instance().layerWasAdded.connect(self.add_layer) QgsMapLayerRegistry.instance().layerWillBeRemoved.connect( self.remove_layer) def onSelectionChanged(self): current_layer = self.iface.mapCanvas().currentLayer() if current_layer.selectedFeatureCount() == 0: self.actionDelete.setEnabled(False) else: if self.tools.hasVersion(current_layer): print current_layer.isEditable() if current_layer.isEditable(): self.actionDelete.setEnabled(True) # true else: self.actionDelete.setEnabled(False) else: self.actionDelete.setEnabled(False) # true def add_layer(self, l): if self.tools.hasVersion(l): if l.id not in self.layer_list: l.editingStopped.connect(lambda my_list=self.layer_list: self. tools.setModified(my_list)) self.layer_list.append(l.id()) self.tools.setModified(self.layer_list) def remove_layer(self, id): self.layer_list = list(set(self.layer_list)) if id in set(self.layer_list): self.layer_list.remove(id) def unload(self): # remove menubar try: for a in self.actionList: self.iface.removePluginDatabaseMenu("PG Version", a) except: del self.menuBar del self.toolBar def doDelete(self): res = QMessageBox.question( None, self.tr("Question"), self. tr("Are you sure to delete all selected features. You cannot undo this action!" ), QMessageBox.StandardButtons(QMessageBox.No | QMessageBox.Yes)) if res == QMessageBox.Yes: QApplication.restoreOverrideCursor() canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer) myPkey = QgsDataSourceURI( currentLayer.dataProvider().dataSourceUri()).keyColumn() myDb = self.tools.layerDB('doInit', currentLayer) selectedFeatures = currentLayer.selectedFeatures() delete_list = "(" if currentLayer.selectedFeatureCount() > 0: for feature in selectedFeatures: delete_list += str(feature.attributes()[0]) + ", " delete_list = delete_list[:-2] delete_list += ")" sql = "delete from \"%s\".\"%s\" where \"%s\" in %s" % ( mySchema, myTable, myPkey, delete_list) QApplication.setOverrideCursor(Qt.WaitCursor) myDb.run(sql) QApplication.restoreOverrideCursor() currentLayer.removeSelection() currentLayer.triggerRepaint() self.tools.setModified(self.layer_list) # self.actionDelete.setEnabled(false) def doInit(self): canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information( None, '', self.tr('Please select a layer for versioning')) return elif self.tools.hasVersion(currentLayer): QMessageBox.warning( None, self.tr('Warning'), self.tr('The selected layer is already under versioning!')) return else: mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer) myDb = self.tools.layerDB('doInit', currentLayer) if not self.tools.check_PGVS_revision(myDb): return if not self.tools.versionExists(currentLayer): answer = QMessageBox.question( None, '', self. tr('Do you want to create the version environment for the table {0}' ).format(mySchema + '.' + myTable), self.tr('Yes'), self.tr('No')) QApplication.setOverrideCursor(Qt.WaitCursor) sql = "select * from versions.pgvsinit('%s.%s')" % (mySchema, myTable) result = myDb.runError(sql) if result == ' ': QMessageBox.information( None, 'Init', self.tr('Init was successful!\n\n\ Please set the user permissions for table {0} and reload it via Database -> PG Version!' ).format(myTable)) QgsMapLayerRegistry.instance().removeMapLayer( currentLayer.id()) QApplication.restoreOverrideCursor() else: self.iface.messageBar().pushMessage( self.tr('Init Error'), self.tr( 'Versioning envoronment for table {0} already exsists!' ).format(mySchema + "." + myTable), level=QgsMessageBar.CRITICAL, duration=3) def doLoad(self): self.dlg = PgVersionLoadDialog(self) self.dlg.show() def doRollback(self, item): if item == None: QMessageBox.information(None, self.tr('Error'), self.tr('Please select a valid revision')) return revision = item.text(0) canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', self.tr('Please select a versioned layer')) return else: answer = QMessageBox.question( None, '', self.tr('Are you sure to rollback to revision {0}?').format( revision), self.tr('Yes'), self.tr('No')) if answer == 0: if self.tools.isModified(currentLayer): answer = QMessageBox.question(None, '', \ self.tr('Layer {0} has modifications which will be lost after rollback! \ If you want to keep this modifications please commit them. \ Are you sure to rollback to revision {1}?' ).format(currentLayer.name(), revision), self.tr('Yes'), self.tr('No')) if answer == 1: return QApplication.setOverrideCursor(Qt.WaitCursor) provider = currentLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('doRollback', currentLayer) if not self.tools.check_PGVS_revision(myDb): return mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() sql = "select * from versions.pgvsrollback('" + mySchema + "." + myTable.replace( '_version', '') + "'," + revision + ")" myDb.run(sql) myDb.close() self.LogViewDialog.close() currentLayer.triggerRepaint() QApplication.restoreOverrideCursor() self.tools.setModified(self.layer_list) self.iface.messageBar().pushMessage( 'INFO', self.tr('Rollback to revision {0} was successful!').format( revision), level=QgsMessageBar.INFO, duration=3) return def doCommit(self): canvas = self.iface.mapCanvas() if canvas.currentLayer() == None: self.iface.messageBar().pushMessage( 'Error', self.tr('Please select a versioned layer for committing'), level=QgsMessageBar.CRITICAL, duration=3) return canvas = self.iface.mapCanvas() theLayer = canvas.currentLayer() mySchema = self.tools.layerSchema(theLayer) myTable = self.tools.layerTable(theLayer).replace('_version', '') if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, self.tr('Warning'), self.tr('Please select a versioned layer!')) else: if self.tools.isModified(theLayer): confRecords = self.tools.confRecords(theLayer) if confRecords == None: # show the dialog self.dlgCommitMessage = CommitMessageDialog() self.dlgCommitMessage.show() result = self.dlgCommitMessage.exec_() if result == QDialog.Accepted: QApplication.setOverrideCursor(Qt.WaitCursor) sql = "select * from versions.pgvscommit('%s.%s','%s')" % ( mySchema, myTable, self.dlgCommitMessage.textEdit.toPlainText()) myDB = self.tools.layerDB('commit', theLayer) myDB.run(sql) myDB.close() self.tools.layerRepaint() self.iface.messageBar().pushMessage( "Info", self.tr('Commit of your changes was successful'), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(self.layer_list) QApplication.restoreOverrideCursor() else: if self.w != None: self.w = None self.w = ConflictWindow(theLayer, 'conflict', self) self.w.mergeCompleted.connect(self.doCommit) self.w.show() self.tools.setModified(self.layer_list) else: self.iface.messageBar().pushMessage( 'INFO', self.tr( 'No layer changes for committing, everything is OK'), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(self.layer_list) def doCheckout(self, revision, tag=None): if revision == None: QMessageBox.information(None, self.tr('Error'), self.tr('Please select a valid revision')) return # revision = item.text(0) canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', self.tr('Please select a versioned layer')) return else: answer = QMessageBox.question( None, '', self.tr('Are you sure to checkout the layer to revision {0}?'). format(revision), self.tr('Yes'), self.tr('No')) if answer == 0: QApplication.setOverrideCursor(Qt.WaitCursor) provider = currentLayer.dataProvider() uri = provider.dataSourceUri() uniqueCol = QgsDataSourceURI(uri).keyColumn() geomCol = QgsDataSourceURI(uri).geometryColumn() geometryType = currentLayer.geometryType() mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select * from versions.pgvscheckout(NULL::\"" + mySchema + "\".\"" + myTable.replace( '_version', '') + "\", " + revision + ")" myUri = QgsDataSourceURI(uri) myUri.setDataSource("", u"(%s\n)" % (sql), geomCol, "", uniqueCol) layer = None if tag: table_ext = " (Tag: %s)" % tag else: table_ext = " (Revision: %s)" % revision layer = QgsVectorLayer(myUri.uri(), myTable + table_ext, "postgres") QgsMapLayerRegistry.instance().addMapLayer(layer) QApplication.restoreOverrideCursor() if layer.isValid(): self.iface.messageBar().pushMessage( 'INFO', self.tr('Checkout to revision {0} was successful!' ).format(revision), level=QgsMessageBar.INFO, duration=3) layer.triggerRepaint() else: self.iface.messageBar().pushMessage( 'INFO', self. tr('Something went wrong during checkout to revision {0}!' ).format(revision), level=QgsMessageBar.INFO, duration=3) self.LogViewDialog.close() return def doRevert(self): canvas = self.iface.mapCanvas() theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('revert', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, self.tr('Warning'), self.tr('Please select a versioned layer!')) else: if len(mySchema) == 1: mySchema = 'public' answer = QMessageBox.question( None, '', self.tr('are you sure to revert to the HEAD revision?'), self.tr('Yes'), self.tr('No')) if answer == 0: sql = "select * from versions.pgvsrevert('" + mySchema + "." + myTable.replace( '_version', '') + "')" result = myDb.read(sql) if len(result) > 1: QMessageBox.information(None, '', result) else: self.iface.messageBar().pushMessage( "Info", self. tr('All changes are set back to the HEAD revision: {0}' ).format(str(result["PGVSREVERT"][0])), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(self.layer_list) theLayer.triggerRepaint() myDb.close() pass def doLogView(self): canvas = self.iface.mapCanvas() theLayer = self.iface.activeLayer() if theLayer <> None: if not self.tools.hasVersion(theLayer): QMessageBox.warning( None, self.tr('Warning'), self.tr('Please select a versioned layer!')) else: provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('logview', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select * from versions.pgvslogview('" + mySchema + "." + myTable.replace( '_version', '') + "') order by revision desc" result = myDb.read(sql) logHTML = "<html><head></head><body><Table>" self.LogViewDialog.setLayer(theLayer) self.LogViewDialog.createTagList() self.LogViewDialog.treeWidget.clear() itemList = [] for i in range(len(result["PROJECT"])): myItem = QTreeWidgetItem() myItem.setText(0, result["REVISION"][i]) myItem.setText(1, result["DATUM"][i]) myItem.setText(2, result["PROJECT"][i]) myItem.setText(3, result["LOGMSG"][i]) itemList.append(myItem) self.LogViewDialog.treeWidget.addTopLevelItems(itemList) self.LogViewDialog.show() myDb.close() canvas.refresh() if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, self.tr('Warning'), self.tr('Please select a versioned layer!')) else: provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('logview', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select * from versions.pgvslogview('" + mySchema + "." + myTable.replace( '_version', '') + "') order by revision desc" result = myDb.read(sql) logHTML = "<html><head></head><body><Table>" self.LogViewDialog.setLayer(theLayer) self.LogViewDialog.createTagList() self.LogViewDialog.treeWidget.clear() itemList = [] for i in range(len(result["PROJECT"])): myItem = QTreeWidgetItem() myItem.setText(0, result["REVISION"][i]) myItem.setText(1, result["DATUM"][i]) myItem.setText(2, result["PROJECT"][i]) myItem.setText(3, result["LOGMSG"][i]) itemList.append(myItem) self.LogViewDialog.treeWidget.addTopLevelItems(itemList) self.LogViewDialog.show() myDb.close() canvas.refresh() pass def doDiff(self): canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() myDb = self.tools.layerDB('logview', currentLayer) if currentLayer == None: QMessageBox.information(None, '', self.tr('Please select a versioned layer')) return else: # answer = QMessageBox.question(None, '', self.tr('Are you sure to checkout diffs to HEAD revision?'), self.tr('Yes'), self.tr('No')) answer = 0 if answer == 0: QApplication.setOverrideCursor(Qt.WaitCursor) uniqueCol = self.tools.layerKeyCol(currentLayer) geomCol = self.tools.layerGeomCol(currentLayer) geometryType = self.tools.layerGeometryType(currentLayer) mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer) if len(mySchema) == 0: mySchema = 'public' sql = u"select * from \"%s\".\"%s\" limit 0" % (mySchema, myTable) cols = myDb.cols(sql) myCols = ', '.join(cols) + ', st_asewkb("' + geomCol + '")' extent = self.iface.mapCanvas().extent().toString().replace( ':', ',') authority, crs = currentLayer.crs().authid().split(':') geo_idx = '%s && ST_MakeEnvelope(%s,%s)' % (geomCol, extent, crs) sql = ("with \ head as (select max(revision) as head from versions.\"{schema}_{origin}_version_log\"), \ delete as (\ select 'delete'::varchar as action, * \ from (\ select * from versions.pgvscheckout(NULL::\"{schema}\".\"{origin}\",(select * from head), \'{geo_idx}\') \ except \ select * from \"{schema}\".\"{origin}_version\" where {geo_idx}\ ) as foo \ ), \ insert as (\ select 'insert'::varchar as action, * \ from ( \ select * from \"{schema}\".\"{origin}_version\" where {geo_idx} \ except \ select * from versions.pgvscheckout(NULL::\"{schema}\".\"{origin}\",(select * from head), \'{geo_idx}\') \ ) as foo) \ \ select row_number() OVER () AS rownum, * \ from \ (\ select * from delete \ union \ select * from insert) as foo").format(schema=mySchema, table=myTable, origin=myTable.replace('_version', ''), geo_idx=geo_idx) myUri = QgsDataSourceURI(self.tools.layerUri(currentLayer)) myUri.setDataSource("", u"(%s\n)" % sql, geomCol, "", "rownum") layer_name = myTable + " (Diff to HEAD Revision)" layer = QgsVectorLayer(myUri.uri(), layer_name, "postgres") mem_layer = self.tools.create_memory_layer(layer, layer_name) if not mem_layer.isValid(): self.iface.messageBar().pushMessage( 'WARNING', self. tr('No diffs to HEAD detected! Layer could not be loaded.' ), level=QgsMessageBar.INFO, duration=3) else: userPluginPath = QFileInfo( QgsApplication.qgisUserDbFilePath()).path( ) + "/python/plugins/pgversion" mem_layer.setRendererV2(None) if geometryType == 0: mem_layer.loadNamedStyle(userPluginPath + "/legends/diff_point.qml") elif geometryType == 1: mem_layer.loadNamedStyle( userPluginPath + "/legends/diff_linestring.qml") elif geometryType == 2: mem_layer.loadNamedStyle(userPluginPath + "/legends/diff_polygon.qml") QgsMapLayerRegistry.instance().addMapLayer(mem_layer) self.iface.messageBar().pushMessage( 'INFO', self.tr('Diff to HEAD revision was successful!'), level=QgsMessageBar.INFO, duration=3) QApplication.restoreOverrideCursor() self.LogViewDialog.close() return def doDrop(self): # try: theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() if theLayer == None: QMessageBox.information( None, '', self.tr('Please select a layer for versioning')) return else: answer = QMessageBox.question( None, '', self.tr('are you sure to to drop pgvs from the table {0}?'). format(mySchema + "." + myTable.replace('_version', '')), self.tr('Yes'), self.tr('No')) if answer == 0: if self.tools.isModified(theLayer): QMessageBox.warning(None, self.tr('Warning'), \ self.tr('Layer %s has uncommited changes, please commit them or revert to HEAD revision' % (theLayer.name()))) else: myDb = self.tools.layerDB('doDrop', theLayer) sql = "select versions.pgvsdrop('" + mySchema + "." + myTable.replace( '_version', '') + "')" result = myDb.read(sql) myDb.close() layer_name = theLayer.name() QgsMapLayerRegistry.instance().removeMapLayer( theLayer.id()) self.iface.messageBar().pushMessage( 'INFO', self.tr('Versioning for layer {0} dropped!').format( layer_name), level=QgsMessageBar.INFO, duration=3) def doHelp(self): helpUrl = QUrl() helpUrl.setUrl('file://' + self.plugin_path + '/docs/help.html') self.helpDialog.webView.load(helpUrl) self.helpDialog.show() pass def doAbout(self): self.about = DlgAbout(self.plugin_path) self.about.show()
class PgVersion: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface self.tools = PgVersionTools(self.iface) self.w = None self.vsCheck = None #Initialise thetranslation environment userPluginPath = QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/pgversion" systemPluginPath = QgsApplication.prefixPath()+"/share/qgis/python/plugins/pgversion" myLocaleName = QLocale.system().name() myLocale = myLocaleName[0:2] if QFileInfo(userPluginPath).exists(): pluginPath = userPluginPath localePath = userPluginPath+"/i18n/pgVersion_"+myLocale+".qm" elif QFileInfo(systemPluginPath).exists(): pluginPath = systemPluginPath localePath = systemPluginPath+"/i18n/pgVersion_"+myLocale+".qm" if QFileInfo(localePath).exists(): translator = QTranslator() translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(translator) self.plugin_dir = pystring(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()) + "/python/plugins/pgversion" self.iface.projectRead.connect(self.layersInit) def initGui(self): self.helpDialog = HelpDialog() self.LogViewDialog = LogView(self.iface) self.toolBar = self.iface.addToolBar("PG Version") self.toolBar.setObjectName("PG Version") self.actionInit = QAction(QIcon(":/plugins/pgversion/icons/pgversion-init.png"), QCoreApplication.translate("PgVersion","Prepare Layer for Versioning"), self.iface.mainWindow()) self.actionLoad = QAction(QIcon(":/plugins/pgversion/icons/pgversion-commit.png"), QCoreApplication.translate("PgVersion","Load Versioned Layer"), self.iface.mainWindow()) self.actionCommit = QAction(QIcon(":/plugins/pgversion/icons/pgversion-load.png"), QCoreApplication.translate("PgVersion","Commit Changes"), self.iface.mainWindow()) self.actionRevert = QAction(QIcon(":/plugins/pgversion/icons/pgversion-revert.png"), QCoreApplication.translate("PgVersion","Revert to HEAD Revision"), self.iface.mainWindow()) self.actionLogView = QAction(QIcon(":/plugins/pgversion/icons/pgversion-logview.png"), QCoreApplication.translate("PgVersion","Show Logs"), self.iface.mainWindow()) self.actionDiff = QAction(QIcon(":/plugins/pgversion/icons/pgversion-diff.png"), QCoreApplication.translate("PgVersion","Show Diffs"), self.iface.mainWindow()) # self.actionCommit.setEnabled(False) self.actionDrop = QAction(QIcon(":/plugins/pgversion/icons/pgversion-drop.png"), QCoreApplication.translate("PgVersion","Drop Versioning from Layer"), self.iface.mainWindow()) self.actionHelp = QAction(QIcon(""), QCoreApplication.translate("PgVersion","Help"), self.iface.mainWindow()) self.actionAbout = QAction(QIcon(""), QCoreApplication.translate("PgVersion","About"), self.iface.mainWindow()) self.actionDelete = QAction(QIcon(":/plugins/pgversion/icons/pgversion-drop.png"), QCoreApplication.translate("PgVersion","Bulk delete directly in the database"), self.iface.mainWindow()) self.actionDelete.setEnabled(False) self.actionList = [ self.actionInit,self.actionLoad, self.actionCommit, self.actionDiff, self.actionRevert, self.actionLogView, self.actionDrop, self.actionLogView, self.actionDelete, self.actionHelp, self.actionAbout] # self.actionList = [ self.actionInit,self.actionLoad,self.actionCommit,self.actionRevert, self.actionLogView, self.actionDrop, self.actionLogView, self.actionHelp, self.actionAbout] self.toolBar.addAction(self.actionInit) self.toolBar.addAction(self.actionLoad) self.toolBar.addAction(self.actionCommit) self.toolBar.addAction(self.actionRevert) self.toolBar.addAction(self.actionDiff) self.toolBar.addAction(self.actionLogView) self.toolBar.addAction(self.actionDelete) # Add the Menubar into the new Database Main Menue starting with QGIS1.7 try: for a in self.actionList: self.iface.addPluginToDatabaseMenu("PG Version", a) except AttributeError: # For former QGIS Versions use the old Main Menue self.menu = QMenu() self.menu.setTitle( "PG Version" ) self.menu.addActions(self.actionList) self.menuBar = self.iface.mainWindow().menuBar() self.menuBar.addMenu(self.menu) # connect the action to the run method self.actionInit.triggered.connect(self.doInit) self.actionLoad.triggered.connect(self.doLoad) self.actionDiff.triggered.connect(self.doDiff) self.actionCommit.triggered.connect(self.doCommit) self.actionRevert.triggered.connect(self.doRevert) self.actionLogView.triggered.connect(self.doLogView) self.actionDrop.triggered.connect(self.doDrop) self.actionHelp.triggered.connect(self.doHelp) self.actionAbout.triggered.connect(self.doAbout) self.actionDelete.triggered.connect(self.doDelete) self.LogViewDialog.diffLayer.connect(self.doDiff) self.LogViewDialog.rollbackLayer.connect(self.doRollback) self.LogViewDialog.checkoutLayer.connect(self.doCheckout) self.LogViewDialog.checkoutTag.connect(self.doCheckout) for a in self.iface.digitizeToolBar().actions(): if a.objectName() == 'mActionToggleEditing': a.triggered.connect(self.onSelectionChanged) self.iface.mapCanvas().selectionChanged.connect(self.onSelectionChanged) def onSelectionChanged(self): current_layer = self.iface.mapCanvas().currentLayer() if current_layer.selectedFeatureCount() == 0: self.actionDelete.setEnabled(False) else: if self.tools.hasVersion(current_layer): print current_layer.isEditable() if current_layer.isEditable(): self.actionDelete.setEnabled(True) # true else: self.actionDelete.setEnabled(False) else: self.actionDelete.setEnabled(False) # true def layersInit(self): canvas = self.iface.mapCanvas() layerList = canvas.layers() for l in layerList: if l.type() == QgsMapLayer.VectorLayer and l.providerType() == 'postgres' and self.tools.isModified(l): l.editingStopped.connect(self.tools.setModified) self.tools.setModified(l) def unload(self): # remove menubar try: for a in self.actionList: self.iface.removePluginDatabaseMenu("PG Version", a) except: del self.menuBar del self.toolBar def doDelete(self): res = QMessageBox.question( None, QCoreApplication.translate('PgVersion',"Question"), QCoreApplication.translate('PgVersion',"Are you sure to delete all selected features. You cannot undo this action!"), QMessageBox.StandardButtons( QMessageBox.No | QMessageBox.Yes)) if res == QMessageBox.Yes: QApplication.restoreOverrideCursor() canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer) myPkey = QgsDataSourceURI(currentLayer.dataProvider().dataSourceUri()).keyColumn() myDb = self.tools.layerDB('doInit',currentLayer) selectedFeatures = currentLayer.selectedFeatures() delete_list = "(" if currentLayer.selectedFeatureCount() > 0: for feature in selectedFeatures: delete_list += str(feature.attributes()[0])+", " delete_list = delete_list[:-2] delete_list += ")" sql = "delete from %s.%s where %s in %s" % (mySchema, myTable, myPkey, delete_list) QApplication.setOverrideCursor(Qt.WaitCursor) myDb.run(sql) QApplication.restoreOverrideCursor() currentLayer.removeSelection() currentLayer.triggerRepaint() self.tools.setModified() # self.actionDelete.setEnabled(false) def doInit(self): canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a layer for versioning')) return elif self.tools.hasVersion(currentLayer): QMessageBox.warning(None, QCoreApplication.translate('PgVersion','Warning'), QCoreApplication.translate('PgVersion','The selected layer is already under versioning!')) return else: mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer) myDb = self.tools.layerDB('doInit',currentLayer) if not self.tools.checkPGVSRevision(myDb): return if not self.tools.versionExists(currentLayer): answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','Do you want to create the version environment for the table {0}').format(mySchema+'.'+myTable), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) QApplication.setOverrideCursor(Qt.WaitCursor) sql = "select * from versions.pgvsinit('%s.%s')" % (mySchema, myTable) result = myDb.runError(sql) if result == ' ': QMessageBox. information(None, 'Init', QCoreApplication.translate('PgVersion', 'Init was successful!\n\n\ Please set the user permissions for table {0} and reload it via Database -> PG Version!').format(myTable)) QgsMapLayerRegistry.instance().removeMapLayer(currentLayer.id()) QApplication.restoreOverrideCursor() else: self.iface.messageBar().pushMessage(QCoreApplication.translate('PgVersion','Init Error'), QCoreApplication.translate('PgVersion','Versioning envoronment for table {0} already exsists!').format(mySchema+"."+myTable), level=QgsMessageBar.CRITICAL, duration=3) def doLoad(self): self.dlg = PgVersionLoadDialog(self.iface) self.dlg.show() def doRollback(self, item): if item == None: QMessageBox.information(None, QCoreApplication.translate('PgVersion','Error'), QCoreApplication.translate('PgVersion','Please select a valid revision')) return revision = item.text(0) canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a versioned layer')) return else: answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','Are you sure to rollback to revision {0}?').format(revision), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: if self.tools.isModified(currentLayer): answer = QMessageBox.question(None, '', \ QCoreApplication.translate('PgVersion','Layer {0} has modifications which will be lost after rollback! \ If you want to keep this modifications please commit them. \ Are you sure to rollback to revision {1}?').format(currentLayer.name(), revision), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 1: return QApplication.setOverrideCursor(Qt.WaitCursor) provider = currentLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('doRollback',currentLayer) if not self.tools.checkPGVSRevision(myDb): return mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() sql = "select * from versions.pgvsrollback('"+mySchema+"."+myTable.replace('_version', '')+"',"+revision+")" myDb.run(sql) myDb.close() self.LogViewDialog.close() currentLayer.triggerRepaint() QApplication.restoreOverrideCursor() self.tools.setModified(currentLayer) self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','Rollback to revision {0} was successful!').format(revision), level=QgsMessageBar.INFO, duration=3) return def doCommit(self): canvas = self.iface.mapCanvas() if canvas.currentLayer() == None: self.iface.messageBar().pushMessage('Error', QCoreApplication.translate('PgVersion','Please select a versioned layer for committing'), level=QgsMessageBar.CRITICAL, duration=3) return canvas = self.iface.mapCanvas() theLayer = canvas.currentLayer() mySchema = self.tools.layerSchema(theLayer) myTable = self.tools.layerTable(theLayer).replace('_version', '') if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, QCoreApplication.translate('PgVersion','Warning'), QCoreApplication.translate('PgVersion','Please select a versioned layer!')) else: if self.tools.isModified(theLayer): confRecords = self.tools.confRecords(theLayer) if confRecords == None: # show the dialog self.dlgCommitMessage = CommitMessageDialog() self.dlgCommitMessage.show() result = self.dlgCommitMessage.exec_() if result == QDialog.Accepted: QApplication.setOverrideCursor(Qt.WaitCursor) sql = "select * from versions.pgvscommit('%s.%s','%s')" % (mySchema, myTable, self.dlgCommitMessage.textEdit.toPlainText()) myDB = self.tools.layerDB('commit', theLayer) myDB.run(sql) myDB.close() self.tools.layerRepaint() self.iface.messageBar().pushMessage("Info", QCoreApplication.translate('PgVersion','Commit of your changes was successful'), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(None, True) QApplication.restoreOverrideCursor() else: if self.w != None: self.w = None self.w = ConflictWindow(self.iface, theLayer, 'conflict', self) self.w.mergeCompleted.connect(self.doCommit) self.w.show() self.tools.setModified(None, True) else: self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','No layer changes for committing, everything is OK'), level=QgsMessageBar.INFO, duration=3) def doCheckout(self, revision, tag=None): print "Revision: %s" % (revision) if revision == None: QMessageBox.information(None, QCoreApplication.translate('PgVersion','Error'), QCoreApplication.translate('PgVersion','Please select a valid revision')) return # revision = item.text(0) canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a versioned layer')) return else: answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','Are you sure to checkout the layer to revision {0}?').format(revision), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: QApplication.setOverrideCursor(Qt.WaitCursor) provider = currentLayer.dataProvider() uri = provider.dataSourceUri() uniqueCol = QgsDataSourceURI(uri).keyColumn() geomCol = QgsDataSourceURI(uri).geometryColumn() geometryType = currentLayer.geometryType() mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select v.* \ from versions.pgvscheckout('"+mySchema+"."+myTable.replace('_version', '')+"', "+revision+") as c, \ versions."+mySchema+"_"+myTable+"_log as v \ where c.log_id = v."+uniqueCol+" \ and c.systime = v.systime " myUri = QgsDataSourceURI(uri) myUri.setDataSource("", u"(%s\n)" % (sql), geomCol, "", uniqueCol) layer = None if tag: table_ext = " (Tag: %s)" % tag else: table_ext = " (Revision: %s)" % revision layer = QgsVectorLayer(myUri.uri(), myTable+table_ext, "postgres") QgsMapLayerRegistry.instance().addMapLayer(layer) QApplication.restoreOverrideCursor() if layer.isValid(): self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','Checkout to revision {0} was successful!').format(revision), level=QgsMessageBar.INFO, duration=3) layer.triggerRepaint() else: self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','Something went wrong during checkout to revision {0}!').format(revision), level=QgsMessageBar.INFO, duration=3) self.LogViewDialog.close() return def doRevert(self): canvas = self.iface.mapCanvas() theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('revert', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, QCoreApplication.translate('PgVersion','Warning'), QCoreApplication.translate('PgVersion','Please select a versioned layer!')) else: if len(mySchema) == 1: mySchema = 'public' answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','are you sure to revert to the HEAD revision?'), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: sql = "select * from versions.pgvsrevert('"+mySchema+"."+myTable.replace('_version', '')+"')" result = myDb.read(sql) if len(result)>1: QMessageBox.information(None, '',result) else: self.iface.messageBar().pushMessage("Info", QCoreApplication.translate('PgVersion','All changes are set back to the HEAD revision: {0}').format(str(result["PGVSREVERT"][0])), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(None, True) theLayer.triggerRepaint() myDb.close() pass def doLogView(self): canvas = self.iface.mapCanvas() theLayer = self.iface.activeLayer() if theLayer <> None: if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, QCoreApplication.translate('PgVersion','Warning'), QCoreApplication.translate('PgVersion','Please select a versioned layer!')) else: provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('logview', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select * from versions.pgvslogview('"+mySchema+"."+myTable.replace('_version', '')+"') order by revision desc" result = myDb.read(sql) logHTML = "<html><head></head><body><Table>" self.LogViewDialog.setLayer(theLayer) self.LogViewDialog.createTagList() self.LogViewDialog.treeWidget.clear() itemList = [] for i in range(len(result["PROJECT"])): myItem = QTreeWidgetItem() myItem.setText(0, result["REVISION"][i]) myItem.setText(1, result["DATUM"][i]) myItem.setText(2, result["PROJECT"][i]) myItem.setText(3, result["LOGMSG"][i]) itemList.append(myItem) self.LogViewDialog.treeWidget.addTopLevelItems(itemList) self.LogViewDialog.show() myDb.close() canvas.refresh() if not self.tools.hasVersion(theLayer): QMessageBox.warning(None, QCoreApplication.translate('PgVersion','Warning'), QCoreApplication.translate('PgVersion','Please select a versioned layer!')) else: provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('logview', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select * from versions.pgvslogview('"+mySchema+"."+myTable.replace('_version', '')+"') order by revision desc" result = myDb.read(sql) logHTML = "<html><head></head><body><Table>" self.LogViewDialog.setLayer(theLayer) self.LogViewDialog.createTagList() self.LogViewDialog.treeWidget.clear() itemList = [] for i in range(len(result["PROJECT"])): myItem = QTreeWidgetItem() myItem.setText(0, result["REVISION"][i]) myItem.setText(1, result["DATUM"][i]) myItem.setText(2, result["PROJECT"][i]) myItem.setText(3, result["LOGMSG"][i]) itemList.append(myItem) self.LogViewDialog.treeWidget.addTopLevelItems(itemList) self.LogViewDialog.show() myDb.close() canvas.refresh() pass def doDiff(self): canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() myDb = self.tools.layerDB('logview', currentLayer) if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a versioned layer')) return else: # answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','Are you sure to checkout diffs to HEAD revision?'), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) answer = 0 if answer == 0: QApplication.setOverrideCursor(Qt.WaitCursor) uniqueCol = self.tools.layerKeyCol(currentLayer) geomCol = self.tools.layerGeomCol(currentLayer) geometryType = self.tools.layerGeometryType(currentLayer) mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer) if len(mySchema) == 0: mySchema = 'public' sql = u"select * from \"%s\".\"%s\" limit 0" % (mySchema, myTable) cols = myDb.cols(sql) myCols = ', '.join(cols)+', st_asewkb("'+geomCol+'")' extent = self.iface.mapCanvas().extent().toString().replace(':',',') authority, crs = currentLayer.crs().authid().split(':') geo_idx = '%s && ST_MakeEnvelope(%s,%s)' % (geomCol, extent, crs) sql = ("with \ head as (select max(revision) as head from versions.\"{schema}_{table}_log\"), \ checkout as (select v.{cols} \ from versions.pgvscheckout('{schema}.{origin}', (select * from head)) as c, versions.\"{schema}_{table}_log\" as v \ where {geo_idx} \ and c.log_id = v.{uniqueCol} \ and c.systime = v.systime), \ \ version as (select v.{cols} \ from \"{schema}\".\"{table}\" as v \ where {geo_idx}) \ \ select row_number() OVER () AS rownum, * \ from (select *, 'delete'::varchar as action, head as revision from head, ( \ (select * from checkout \ except \ select * from version) \ ) as foo \ union all \ select *, 'insert'::varchar as action, head.head as revision \ from head, ( \ select * from version \ except \ select * from checkout) as foo1 \ ) as foo ").format(schema = mySchema, table=myTable, origin=myTable.replace('_version', ''), cols = myCols, uniqueCol = uniqueCol, geo_idx = geo_idx ) print sql myUri = QgsDataSourceURI(self.tools.layerUri(currentLayer)) myUri.setDataSource("", u"(%s\n)" % sql, geomCol, "", "rownum") layer = QgsVectorLayer(myUri.uri(), myTable+" (Diff to HEAD Revision)", "postgres") # defult_tmp_dir = tempfile._get_default_tempdir() # temp_name = defult_tmp_dir+"/"+next(tempfile._get_candidate_names())+".shp" # # QgsVectorFileWriter.writeAsVectorFormat(QgsVectorLayer(myUri.uri(), myTable+" (Diff to HEAD Revision)", "postgres") , temp_name, "utf-8", None, "ESRI Shapefile") # layer_ = QgsVectorLayer(temp_name, myTable+" (Diff to HEAD Revision)", "ogr") # if not layer.isValid(): self.iface.messageBar().pushMessage('WARNING', QCoreApplication.translate('PgVersion','No diffs to HEAD detected! Layer could not be loaded.'), level=QgsMessageBar.INFO, duration=3) else: userPluginPath = QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/pgversion" layer.setRendererV2(None) if geometryType == 0: layer.loadNamedStyle(userPluginPath+"/legends/diff_point.qml") elif geometryType == 1: layer.loadNamedStyle(userPluginPath+"/legends/diff_linestring.qml") elif geometryType == 2: layer.loadNamedStyle(userPluginPath+"/legends/diff_polygon.qml") QgsMapLayerRegistry.instance().addMapLayer(layer) self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','Diff to HEAD revision was successful!'), level=QgsMessageBar.INFO, duration=3) QApplication.restoreOverrideCursor() self.LogViewDialog.close() return def doDrop(self): # try: theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() if theLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a layer for versioning')) return else: answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','are you sure to to drop pgvs from the table {0}?').format(mySchema+"."+myTable.replace('_version', '')), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: if self.tools.isModified(theLayer): QMessageBox.warning(None, QCoreApplication.translate('PgVersion','Warning'), \ QCoreApplication.translate('PgVersion','Layer %s has uncommited changes, please commit them or revert to HEAD revision' % (theLayer.name()))) else: myDb = self.tools.layerDB('doDrop',theLayer) sql = "select versions.pgvsdrop('"+mySchema+"."+myTable.replace('_version', '')+"')" result = myDb.read(sql) myDb.close() layer_name = theLayer.name() QgsMapLayerRegistry.instance().removeMapLayer(theLayer.id()) self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','Versioning for layer {0} dropped!').format(layer_name), level=QgsMessageBar.INFO, duration=3) def doHelp(self): helpUrl = QUrl() helpUrl.setUrl('file://'+self.plugin_dir+'/docs/help.html') self.helpDialog.webView.load(helpUrl) self.helpDialog.show() pass def doAbout(self): self.about = DlgAbout(self.plugin_dir) self.about.show()
class ConflictWindow(QMainWindow): mergeCompleted = pyqtSignal() def __init__(self, iface, layer, type='conflict', parent=None): QMainWindow.__init__(self) self.iface = iface self.tools = PgVersionTools(iface) self.layer = layer self.parent = parent settings = QSettings() # Restore Window Settings settings = QSettings() try: self.restoreGeometry(pybytearray(settings.value("/pgVersion/geometry"))) self.restoreState(pybytearray(settings.value("/pgVersion/windowState"))) except: pass settings = QSettings() self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) self.canvas.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing",True, type=bool) ) self.canvas.useImageToRender( settings.value( "/qgis/use_qimage_to_render", True, type=bool) ) action = pyint(settings.value( "/qgis/wheel_action", 0 ) ) zoomFactor = pyint(settings.value( "/qgis/zoom_factor", 2) ) self.canvas.setWheelAction( QgsMapCanvas.WheelAction(action), zoomFactor ) QgsMapLayerRegistry.instance().addMapLayer(layer) self.canvas.setExtent(layer.extent()) self.canvas.setLayerSet( [ QgsMapCanvasLayer(layer) ] ) self.canvas.zoomToFullExtent() self.setCentralWidget(self.canvas) actionZoomIn = QAction(QIcon(":/plugins/pgversion/icons/ZoomIn.png"), pystring("Zoom in"), self) actionZoomOut = QAction(QIcon(":/plugins/pgversion/icons/ZoomOut.png"),pystring("Zoom out"), self) actionZoomFull = QAction(QIcon(":/plugins/pgversion/icons/ZoomFullExtent.png"),pystring("Fullextent"), self) actionPan = QAction(QIcon(":/plugins/pgversion/icons/Pan.png"),pystring("Pan"), self) actionZoomIn.setCheckable(True) actionZoomOut.setCheckable(True) actionPan.setCheckable(True) actionZoomIn.triggered.connect(self.zoomIn) actionZoomOut.triggered.connect(self.zoomOut) actionZoomFull.triggered.connect(self.zoomFull) actionPan.triggered.connect(self.pan) self.toolbar = self.addToolBar("Canvas actions") self.toolbar.addAction(actionPan) self.toolbar.addAction(actionZoomIn) self.toolbar.addAction(actionZoomOut) self.toolbar.addAction(actionZoomFull) self.dockWidget = QDockWidget() self.dockWidget.setWidget(QTableWidget()) self.addDockWidget(Qt.BottomDockWidgetArea, self.dockWidget) self.tabView = self.dockWidget.widget() # create the map tools self.toolPan = QgsMapToolPan(self.canvas) self.toolPan.setAction(actionPan) self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in self.toolZoomIn.setAction(actionZoomIn) self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out self.toolZoomOut.setAction(actionZoomOut) self.pan() self.conflictLayerList = [] if type=='conflict': self.cmbMerge = QComboBox() self.cmbMerge.addItems(self.tools.confRecords(self.layer)) self.btnMerge = QPushButton() self.cmbMerge.currentIndexChanged.connect(self.toggleBtnMerge) self.btnMerge.setText(QCoreApplication.translate('ManagerWindow','solve conflict')) self.toolbar.addWidget(self.cmbMerge) self.toolbar.addWidget(self.btnMerge) self.manageConflicts() self.btnMerge.clicked.connect(self.runMerge) self.tabView.itemSelectionChanged.connect(self.showConfObject) self.rBand = QgsRubberBand(self.canvas, False) def toggleBtnMerge(self): # if not self.btnMerge.isEnabled(): # self.btnMerge.setEnabled(False) # else: # self.btnMerge.setEnabled(True) return def toggleBtnCommit(self): # if not self.btnMerge.isEnabled(): # self.btnMerge.setEnabled(False) # else: # self.btnMerge.setEnabled(True) return def zoomIn(self): self.canvas.setMapTool(self.toolZoomIn) def zoomOut(self): self.canvas.setMapTool(self.toolZoomOut) def zoomFull(self): self.canvas.zoomToFullExtent() def pan(self): self.canvas.setMapTool(self.toolPan) def closeEvent(self, e): """ save window state """ # settings = QSettings() # settings.setValue("/pgVersion/windowState", pybytearray(self.saveState())) # settings.setValue("/pgVersion/geometry", pybytearray(self.saveGeometry())) QgsMapLayerRegistry.instance().removeMapLayer(self.tools.conflictLayer(self.layer).id()) self.close() def showDiffs(self): pass def showConfObject(self): myProject = self.tabView.item(self.tabView.currentRow(), 0).text() myId = self.tabView.item(self.tabView.currentRow(), 3).text() confLayer = self.tools.conflictLayer(self.layer) self.conflictLayerList.append(confLayer) self.rBand.reset() self.rBand.setColor(QColor(0, 0, 255)) self.rBand.setWidth(5) if confLayer.isValid(): iter = confLayer.getFeatures() for feature in iter: geom = feature.geometry() attrs = feature.attributes() if str(attrs[0]) == myId and attrs[len(attrs)-5] == myProject: self.rBand.addGeometry(geom, None) return def manageConflicts(self): QApplication.setOverrideCursor(Qt.WaitCursor) vLayer = self.tools.conflictLayer(self.layer) if vLayer == None: return vLayerList = [vLayer, self.layer] QgsMapLayerRegistry.instance().addMapLayers(vLayerList, False) self.vLayerId = vLayer.id() self.canvas.setExtent(vLayer.extent()) self.canvas.refresh() vLayer.triggerRepaint() tabData = self.tools.tableRecords(self.layer) if tabData <> None: self.tools.createGridView(self.tabView, tabData[0], tabData[1], 100, 10) else: self.mergeCompleted.emit() QApplication.restoreOverrideCursor() def runMerge(self): QApplication.setOverrideCursor(Qt.WaitCursor) currentLayer = self.layer object = self.cmbMerge.currentText() if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('ManagerWindow','Please select a versioned layer for committing')) return else: myDb = self.tools.layerDB('Merge', currentLayer) mySchema = self.tools.layerSchema(currentLayer) myTable = self.tools.layerTable(currentLayer).replace("_version", "") objectArray = object.split(" - ") if len(objectArray)==1: return elif 'Commit all' in objectArray[0]: projectName = objectArray[1].strip() sql = "select objectkey from versions.pgvscheck('%s.%s') \ where myuser = '******' or conflict_user = '******' \ order by objectkey" % (mySchema, myTable, projectName, projectName) result = myDb.read(sql) for i in range(len(result['OBJECTKEY'])): sql ="select versions.pgvsmerge('%s.%s',%s,'%s')" % (mySchema, myTable, result['OBJECTKEY'][i], projectName) myDb.run(sql) else: projectName = objectArray[1].strip() sql ="select versions.pgvsmerge('%s.%s',%s,'%s')" % (mySchema, myTable, objectArray[0], projectName) myDb.run(sql) self.canvas.refresh() self.layer.triggerRepaint() self.cmbMerge.clear() QApplication.restoreOverrideCursor() if self.tools.confRecords(self.layer) == None: self.tabView.clear() self.tools.setModified(self.layer) self.close() else: self.cmbMerge.addItems(self.tools.confRecords(self.layer)) tabData = self.tools.tableRecords(self.layer) self.tools.createGridView(self.tabView, tabData[0], tabData[1], 100, 10) self.manageConflicts() def loadLayer(self, layer): provider = layer.dataProvider() uri = provider.dataSourceUri() mySchema = self.tools.layerSchema(layer) myHost = self.tools.layerHost(layer) myDatabase = self.tools.layerDB(layer) myPassword = self.tools.layerPassword(layer) myPort = self.tools.layerPort(layer) myUsername = self.tools.layerUsername(layer) myGeometryColumn = self.tools.layerGeomCol(layer) myTable = myTable.replace("_version", "") myUri = QgsDataSourceURI() myUri.setConnection(myHost, myPort, myDatabase, myUsername, myPassword) myUri.setDataSource(mySchema, myTable, myGeometryColumn) myLayer = QgsVectorLayer(myUri.uri(), "", "postgres") QgsMapLayerRegistry.instance().addMapLayer(myLayer, False) # self.canvas.setExtent(myLayer.extent()) self.canvas.setLayerSet([QgsMapCanvasLayer(myLayer)]) self.canvas.refresh()
class PgVersion: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface self.dlgCommitMessage = CommitMessageDialog() self.tools = PgVersionTools(self.iface) self.w = None self.vsCheck = None #Initialise thetranslation environment userPluginPath = QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/pgversion" systemPluginPath = QgsApplication.prefixPath()+"/share/qgis/python/plugins/pgversion" myLocaleName = QLocale.system().name() myLocale = myLocaleName[0:2] if QFileInfo(userPluginPath).exists(): pluginPath = userPluginPath localePath = userPluginPath+"/i18n/pgVersion_"+myLocale+".qm" elif QFileInfo(systemPluginPath).exists(): pluginPath = systemPluginPath localePath = systemPluginPath+"/i18n/pgVersion_"+myLocale+".qm" if QFileInfo(localePath).exists(): translator = QTranslator() translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(translator) self.plugin_dir = pystring(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()) + "/python/plugins/pgversion" self.iface.projectRead.connect(self.layersInit) def initGui(self): self.helpDialog = HelpDialog() self.LogViewDialog = LogView() self.toolBar = self.iface.addToolBar("PG Version") self.toolBar.setObjectName("PG Version") self.actionInit = QAction(QIcon(":/plugins/pgversion/icons/pgversion-init.png"), QCoreApplication.translate("PgVersion","Prepare Layer for Versioning"), self.iface.mainWindow()) self.actionLoad = QAction(QIcon(":/plugins/pgversion/icons/pgversion-commit.png"), QCoreApplication.translate("PgVersion","Load Versioned Layer"), self.iface.mainWindow()) self.actionCommit = QAction(QIcon(":/plugins/pgversion/icons/pgversion-load.png"), QCoreApplication.translate("PgVersion","Commit Changes"), self.iface.mainWindow()) self.actionRevert = QAction(QIcon(":/plugins/pgversion/icons/pgversion-revert.png"), QCoreApplication.translate("PgVersion","Revert to HEAD Revision"), self.iface.mainWindow()) self.actionLogView = QAction(QIcon(":/plugins/pgversion/icons/pgversion-logview.png"), QCoreApplication.translate("PgVersion","Show Logs"), self.iface.mainWindow()) self.actionDiff = QAction(QIcon(":/plugins/pgversion/icons/pgversion-diff.png"), QCoreApplication.translate("PgVersion","Show Diffs"), self.iface.mainWindow()) # self.actionCommit.setEnabled(False) self.actionDrop = QAction(QIcon(":/plugins/pgversion/icons/pgversion-drop.png"), QCoreApplication.translate("PgVersion","Drop Versioning from Layer"), self.iface.mainWindow()) self.actionHelp = QAction(QIcon(""), QCoreApplication.translate("PgVersion","Help"), self.iface.mainWindow()) self.actionAbout = QAction(QIcon(""), QCoreApplication.translate("PgVersion","About"), self.iface.mainWindow()) # self.actionList = [ self.actionInit,self.actionLoad, self.actionCommit, self.actionDiff, self.actionRevert, self.actionLogView, self.actionDrop, self.actionLogView, self.actionHelp] self.actionList = [ self.actionInit,self.actionLoad,self.actionCommit,self.actionRevert, self.actionLogView, self.actionDrop, self.actionLogView, self.actionHelp, self.actionAbout] self.toolBar.addAction(self.actionInit) self.toolBar.addAction(self.actionLoad) self.toolBar.addAction(self.actionCommit) self.toolBar.addAction(self.actionRevert) # self.toolBar.addAction(self.actionDiff) self.toolBar.addAction(self.actionLogView) # Add the Menubar into the new Database Main Menue starting with QGIS1.7 try: for a in self.actionList: self.iface.addPluginToDatabaseMenu("PG Version", a) except AttributeError: # For former QGIS Versions use the old Main Menue self.menu = QMenu() self.menu.setTitle( "PG Version" ) self.menu.addActions(self.actionList) self.menuBar = self.iface.mainWindow().menuBar() self.menuBar.addMenu(self.menu) # connect the action to the run method self.actionInit.triggered.connect(self.doInit) self.actionLoad.triggered.connect(self.doLoad) self.actionDiff.triggered.connect(self.doDiff) self.actionCommit.triggered.connect(self.doCommit) self.actionRevert.triggered.connect(self.doRevert) self.actionLogView.triggered.connect(self.doLogView) self.actionDrop.triggered.connect(self.doDrop) self.actionHelp.triggered.connect(self.doHelp) self.actionAbout.triggered.connect(self.doAbout) self.LogViewDialog.rollbackLayer.connect(self.doRollback) self.LogViewDialog.checkoutLayer.connect(self.doCheckout) def layersInit(self): canvas = self.iface.mapCanvas() layerList = canvas.layers() for l in layerList: if l.type() == QgsMapLayer.VectorLayer and l.providerType() == 'postgres': # self.tools.setModified(l) l.editingStopped.connect(self.tools.setModified) def unload(self): # remove menubar try: for a in self.actionList: self.iface.removePluginDatabaseMenu("PG Version", a) except: del self.menuBar del self.toolBar def doInit(self): canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a layer for versioning')) return else: provider = currentLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('doInit',currentLayer) if not self.tools.checkPGVSRevision(myDb): return mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() if not self.tools.versionExists(currentLayer): myExtent = canvas.extent() answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','Do you want to create the version environment for the table {0}').format(mySchema+'.'+myTable), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) QApplication.setOverrideCursor(Qt.WaitCursor) if answer == 0: sql = "select * from versions.pgvsinit('"+mySchema+"."+myTable+"')" result = myDb.runError(sql) myDb.close() QMessageBox. information(None, 'Init', QCoreApplication.translate('PgVersion', 'Init was successful!\n\n\ Please set the user permissions for table {0} and reload it via Database -> PG Version!').format(myTable)) # vUri = QgsDataSourceURI(provider.dataSourceUri() ) # vUri.setDataSource(mySchema, myTable+'_version', QgsDataSourceURI(uri).geometryColumn()) # # vLayer = QgsVectorLayer(vUri.uri(), myTable+'_version', 'postgres') QgsMapLayerRegistry.instance().removeMapLayer(currentLayer.id()) # QgsMapLayerRegistry.instance().addMapLayer(vLayer) # canvas.setExtent(myExtent) # canvas.zoomToPreviousExtent() QApplication.restoreOverrideCursor() else: self.iface.messageBar().pushMessage(QCoreApplication.translate('PgVersion','Init Error'), QCoreApplication.translate('PgVersion','Versioning envoronment for table {0} already exsists!').format(mySchema+"."+myTable), level=QgsMessageBar.CRITICAL, duration=3) def doLoad(self): self.dlg = PgVersionLoadDialog(self.iface) self.dlg.show() def doRollback(self, item): if item == None: QMessageBox.information(None, QCoreApplication.translate('PgVersion','Error'), QCoreApplication.translate('PgVersion','Please select a valid revision')) return revision = item.text(0) canvas = self.iface.mapCanvas() currentLayer = canvas.currentLayer() if currentLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a versioned layer')) return else: answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','Are you sure to rollback to revision {0}?').format(revision), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: if self.tools.isModified(currentLayer): answer = QMessageBox.question(None, '', \ QCoreApplication.translate('PgVersion','Layer {0} has modifications which will be lost after rollback! \ If you want to keep this modifications please commit them. \ Are you sure to rollback to revision {1}?').format(currentLayer.name(), revision), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 1: return QApplication.setOverrideCursor(Qt.WaitCursor) provider = currentLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('doRollback',currentLayer) if not self.tools.checkPGVSRevision(myDb): return mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() sql = "select * from versions.pgvsrollback('"+mySchema+"."+myTable.replace('_version', '')+"',"+revision+")" myDb.run(sql) myDb.close() self.LogViewDialog.close() canvas.refresh() QApplication.restoreOverrideCursor() self.tools.setModified(currentLayer) self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','Rollback to revision {0} was successful!').format(revision), level=QgsMessageBar.INFO, duration=3) return def doCommit(self): canvas = self.iface.mapCanvas() if canvas.currentLayer() == None: self.iface.messageBar().pushMessage('Error', QCoreApplication.translate('PgVersion','Please select a versioned layer for committing'), level=QgsMessageBar.CRITICAL, duration=3) return canvas = self.iface.mapCanvas() theLayer = canvas.currentLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('commit', theLayer) mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() # if theLayer == None: # self.iface.messageBar().pushMessage('Error', QCoreApplication.translate('PgVersion','Please select a versioned layer for committing'), level=QgsMessageBar.ERROR, duration=3) # return if self.tools.isModified(theLayer): confRecords = self.tools.confRecords(theLayer) if confRecords == None: # show the dialog self.dlgCommitMessage.show() result = self.dlgCommitMessage.exec_() if result == QDialog.Accepted: QApplication.setOverrideCursor(Qt.WaitCursor) sql = "select * from versions.pgvscommit('"+mySchema+"."+myTable.replace('_version', '')+"','"+self.dlgCommitMessage.textEdit.toPlainText()+"')" myDb.run(sql) canvas.refresh() self.iface.messageBar().pushMessage("Info", QCoreApplication.translate('PgVersion','Commit of your changes was successful'), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(None, True) QApplication.restoreOverrideCursor() else: if self.w != None: self.w = None self.w = ConflictWindow(self.iface, theLayer, 'conflict', self) self.w.mergeCompleted.connect(self.doCommit) self.w.show() myDb.close() self.tools.setModified(None, True) else: self.iface.messageBar().pushMessage('INFO', QCoreApplication.translate('PgVersion','No layer changes for committing, everything is OK'), level=QgsMessageBar.INFO, duration=3) def doCheckout(self, item): revision = item.text(0) self.LogViewDialog.btnClose.setEnabled(False) QApplication.setOverrideCursor(Qt.WaitCursor) if revision == '-----': QMessageBox.information(None, 'Error', 'Please select a valid revision') return theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() myCrs = provider.crs() uri = provider.dataSourceUri() myDb = self.tools.layerDB('checkout', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() myKeyColumn = QgsDataSourceURI(uri).keyColumn() numFeat = provider.featureCount() if len(mySchema) == 0: mySchema = 'public' sql = " select "+myKeyColumn+", revision, action \ from versions."+mySchema+"_"+myTable+"_log \ where revision > "+revision+" \ order by revision desc " QMessageBox.information(None, '', sql) pass result = myDb.read(sql) # Load the LOG-Table for further usage logUri = QgsDataSourceURI() logUri.setConnection(QgsDataSourceURI(uri).host(), QgsDataSourceURI(uri).port(), QgsDataSourceURI(uri).database(),QgsDataSourceURI(uri).username() , QgsDataSourceURI(uri).password()) logUri.setDataSource("versions", mySchema+"_"+myTable+"_log", QgsDataSourceURI(uri).geometryColumn(), "revision > "+revision) logUri.setKeyColumn(QgsDataSourceURI(uri).keyColumn()) logLayer = QgsVectorLayer(logUri.uri(), "dummy", "postgres") logProvider = logLayer.dataProvider() if theLayer.geometryType() == 0: myGeometry = "Point" elif theLayer.geometryType() == 1: myGeometry = "Linestring" elif theLayer.geometryType() == 2: myGeometry = "Polygon" revLayer = QgsVectorLayer(myGeometry, myTable.replace('_version', '')+"_rev_"+revision, "memory") revLayer.setCrs(myCrs) revProvider = revLayer.dataProvider() mLogLayer = QgsVectorLayer(myGeometry, myTable.replace('_version', '')+"_rev_"+revision, "memory") mLogLayer.setCrs(myCrs) mLogProvider = mLogLayer.dataProvider() myFieldList = self.tools.getFieldList(logLayer) myFieldDefList = [] # for (k, attr) in myFieldList.iteritems(): # myFieldDefList.append(attr) for attr in mLogProvider.fields(): myFieldDefList.append(attr) mLogProvider.addAttributes( myFieldDefList) feat = QgsFeature() allAttrs = logProvider.attributeIndexes() # logProvider.select(allAttrs) numFeat = numFeat + logProvider.featureCount() self.LogViewDialog.progressBar.setMinimum(0) self.LogViewDialog.progressBar.setRange(0, 100) self.LogViewDialog.progressBar.setValue(50) count = 1 mIter = mLogLayer.getFeatures() for feat in mIter: mFeat = QgsFeature() mFeat.setGeometry(feat.geometry()) mFeat.setAttributeMap(feat.attributeMap()) mLogProvider.addFeatures( [mFeat] ) self.LogViewDialog.progressBar.setValue(float(count)/float(numFeat)*100.0) count = count + 1 mLogLayer.startEditing() numFields = mLogProvider.fields().count() for i in range(numFields-1): mLogLayer.deleteAttribute(numFields-i) mLogLayer.commitChanges() QgsMapLayerRegistry.instance().addMapLayer(revLayer) # myFieldList = self.tools.getFieldList(theLayer) myFieldDefList = [] for attr in provider.fields(): myFieldDefList.append(attr) revProvider.addAttributes( myFieldDefList) myFeatList = [] feat = QgsFeature() # allAttrs = provider.attributeIndexes() # start data retreival: fetch geometry and all attributes for each feature # provider.select(allAttrs) # attrs = feat.attributeMap() iter = theLayer.getFeatures() for feat in iter: if str(feat.id()) not in result[str(myKeyColumn.upper())]: revFeat = QgsFeature() revFeat.setGeometry(feat.geometry()) revFeat.setAttributes(feat.attributes()) myFeatList.append(revFeat) revProvider.addFeatures( [revFeat] ) self.LogViewDialog.progressBar.setValue(float(count)/float(numFeat)*100.0) count = count + 1 for feat in mIter: attrs = feat.attributeMap() actionFieldId = len(attrs)-5 if attrs[actionFieldId].toString() == 'delete': revFeat = QgsFeature() revFeat.setGeometry(feat.geometry()) revFeat.setAttributes(feat.attributeMap()) myFeatList.append(revFeat) revProvider.addFeatures( [revFeat] ) self.LogViewDialog.progressBar.setValue(float(count)/float(numFeat)*100.0) count = count + 1 revLayer.startEditing() revLayer.commitChanges() self.LogViewDialog.progressBar.setValue(100.0) self.LogViewDialog.btnClose.setEnabled(True) QApplication.restoreOverrideCursor() QApplication.setOverrideCursor(Qt.ArrowCursor) self.iface.mapCanvas().refresh() pass def doRevert(self): try: canvas = self.iface.mapCanvas() theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('revert', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 1: mySchema = 'public' except: self.iface.messageBar().pushMessage('Error', QCoreApplication.translate('PgVersion','Please select a versioned layer for reverting'), level=QgsMessageBar.CRITICAL, duration=3) return answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','are you sure to revert to the HEAD revision?'), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: sql = "select * from versions.pgvsrevert('"+mySchema+"."+myTable.replace('_version', '')+"')" result = myDb.read(sql) if len(result)>1: QMessageBox.information(None, '',result) else: self.iface.messageBar().pushMessage("Info", QCoreApplication.translate('PgVersion','All changes are set back to the HEAD revision: {0}').format(str(result["PGVSREVERT"][0])), level=QgsMessageBar.INFO, duration=3) self.tools.setModified(None, True) canvas.refresh() myDb.close() pass def doLogView(self): # try: canvas = self.iface.mapCanvas() theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() myDb = self.tools.layerDB('logview', theLayer) mySchema = QgsDataSourceURI(uri).schema() myTable = QgsDataSourceURI(uri).table() if len(mySchema) == 0: mySchema = 'public' sql = "select * from versions.pgvslogview('"+mySchema+"."+myTable.replace('_version', '')+"') order by revision desc" result = myDb.read(sql) logHTML = "<html><head></head><body><Table>" self.LogViewDialog.treeWidget.clear() itemList = [] for i in range(len(result["PROJECT"])): myItem = QTreeWidgetItem() myItem.setText(0, result["REVISION"][i]) myItem.setText(1, result["DATUM"][i]) myItem.setText(2, result["PROJECT"][i]) myItem.setText(3, result["LOGMSG"][i]) itemList.append(myItem) self.LogViewDialog.treeWidget.addTopLevelItems(itemList) self.LogViewDialog.show() myDb.close() canvas.refresh() # except: # return pass def doDiff(self): # QMessageBox.information(None, 'Message', 'Diff is not implemented yet!') # try: canvas = self.iface.mapCanvas() theLayer = canvas.currentLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() # myDb = self.tools.layerDB('commit', theLayer) type='diff' self.diff = DiffDlg(self.iface) self.diff.show() # except: # QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a layer to show the diffs to HEAD')) def doDrop(self): # try: theLayer = self.iface.activeLayer() provider = theLayer.dataProvider() uri = provider.dataSourceUri() mySchema = QgsDataSourceURI(uri).schema() if len(mySchema) == 0: mySchema = 'public' myTable = QgsDataSourceURI(uri).table() if theLayer == None: QMessageBox.information(None, '', QCoreApplication.translate('PgVersion','Please select a layer for versioning')) return else: answer = QMessageBox.question(None, '', QCoreApplication.translate('PgVersion','are you sure to to drop pgvs from the table {0}?').format(mySchema+"."+myTable.replace('_version', '')), QCoreApplication.translate('PgVersion','Yes'), QCoreApplication.translate('PgVersion','No')) if answer == 0: myDb = self.tools.layerDB('doDrop',theLayer) sql = "select * from versions.pgvsdrop('"+mySchema+"."+myTable.replace('_version', '')+"')" result = myDb.read(sql) myDb.close() QgsMapLayerRegistry.instance().removeMapLayer(theLayer.id()) # except: # QMessageBox.information(None, QCoreApplication.translate('PgVersion','Error'), QCoreApplication.translate('PgVersion','Please select a versionied layer for dropping')) else: QMessageBox.information(None, '', 'hallo') def doHelp(self): helpUrl = QUrl() helpUrl.setUrl('file://'+self.plugin_dir+'/docs/help.html') self.helpDialog.webView.load(helpUrl) self.helpDialog.show() pass def doMessage(self): QMessageBox.information(None, '', 'Hallo') def doAbout(self): self.about = DlgAbout(self.plugin_dir) self.about.show()