Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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()
Ejemplo n.º 5
0
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()