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()