def __init__(self, parent, repo, refa, refb): super(DiffViewerDialog, self).__init__(parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.repo = repo self.setupUi(self) self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) self.featuresTree.currentItemChanged.connect(self.treeItemChanged) self.featuresTree.header().hide() self.computeDiffs() self.groupBox.adjustSize()
class DiffViewerDialog(WIDGET, BASE): def __init__(self, parent, repo, refa, refb): super(DiffViewerDialog, self).__init__(parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.repo = repo self.setupUi(self) self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) self.featuresTree.currentItemChanged.connect(self.treeItemChanged) self.featuresTree.header().hide() self.computeDiffs() self.groupBox.adjustSize() def refsHaveChanged(self): self.computeDiffs() def treeItemChanged(self, current, previous): qgsgeom1 = None qgsgeom2 = None crs = "EPSG:4326" if not isinstance(current, FeatureItem): self.attributesTable.clear() self.attributesTable.setRowCount(0) return color = {"MODIFIED": QColor(255, 170, 0), "ADDED":Qt.green, "REMOVED":Qt.red , "NO_CHANGE":Qt.white} path = current.layername + "/" + current.featureid featurediff = self.changes[path].featurediff() self.attributesTable.clear() self.attributesTable.verticalHeader().show() self.attributesTable.horizontalHeader().show() self.attributesTable.setRowCount(len(featurediff)) self.attributesTable.setVerticalHeaderLabels([a["attributename"] for a in featurediff]) self.attributesTable.setHorizontalHeaderLabels(["Old value", "New value", "Change type"]) for i, attrib in enumerate(featurediff): try: if attrib["changetype"] == "MODIFIED": oldvalue = attrib["oldvalue"] newvalue = attrib["newvalue"] elif attrib["changetype"] == "ADDED": newvalue = attrib["newvalue"] oldvalue = "" elif attrib["changetype"] == "REMOVED": oldvalue = attrib["oldvalue"] newvalue = "" else: oldvalue = newvalue = attrib["oldvalue"] except: oldvalue = newvalue = "" self.attributesTable.setItem(i, 0, DiffItem(oldvalue)) self.attributesTable.setItem(i, 1, DiffItem(newvalue)) try: self.attributesTable.setItem(i, 2, QTableWidgetItem("")) if qgsgeom1 is None or qgsgeom2 is None: if "crs" in attrib: crs = attrib["crs"] qgsgeom1 = QgsGeometry.fromWkt(oldvalue) qgsgeom2 = QgsGeometry.fromWkt(newvalue) if qgsgeom1 is not None and qgsgeom2 is not None: widget = QWidget() btn = QPushButton() btn.setText("View detail") btn.clicked.connect(lambda: self.viewGeometryChanges(qgsgeom1, qgsgeom2, crs)) label = QLabel() label.setText(attrib["changetype"]) layout = QHBoxLayout(widget) layout.addWidget(label); layout.addWidget(btn); layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) self.attributesTable.setCellWidget(i, 2, widget) else: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) else: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) except: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) for col in range(3): self.attributesTable.item(i, col).setBackgroundColor(color[attrib["changetype"]]); self.attributesTable.resizeColumnsToContents() self.attributesTable.horizontalHeader().setResizeMode(QHeaderView.Stretch) def viewGeometryChanges(self, g1, g2, crs): dlg = GeometryDiffViewerDialog([g1, g2], QgsCoordinateReferenceSystem(crs)) dlg.exec_() def computeDiffs(self): self.commit1 = self.commit1Panel.getRef() self.commit2 = self.commit2Panel.getRef() self.featuresTree.clear() changes = execute(lambda: self.repo.diff(self.commit1.commitid, self.commit2.commitid)) layerItems = {} layerSubItems = {} self.changes = {} for c in changes: self.changes[c.path] = c layername = c.path.split("/")[0] featureid = c.path.split("/")[-1] if layername not in layerItems: item = QTreeWidgetItem() item.setText(0, layername) item.setIcon(0, layerIcon) layerItems[layername] = item addedItem = QTreeWidgetItem() addedItem.setText(0, "Added") addedItem.setIcon(0, addedIcon) removedItem = QTreeWidgetItem() removedItem.setText(0, "Removed") removedItem.setIcon(0, removedIcon) modifiedItem = QTreeWidgetItem() modifiedItem.setText(0, "Modified") modifiedItem.setIcon(0, modifiedIcon) layerSubItems[layername] = {FEATURE_ADDED: addedItem, FEATURE_REMOVED: removedItem, FEATURE_MODIFIED:modifiedItem} item = FeatureItem(layername, featureid) layerSubItems[layername][c.changetype].addChild(item) for layername, item in layerItems.iteritems(): for i in [FEATURE_ADDED, FEATURE_REMOVED, FEATURE_MODIFIED]: subItem = layerSubItems[layername][i] item.addChild(subItem) subItem.setText(0, "%s [%i features]" % (subItem.text(0), subItem.childCount())) self.featuresTree.addTopLevelItem(item) self.attributesTable.clear() self.attributesTable.verticalHeader().hide() self.attributesTable.horizontalHeader().hide() self.featuresTree.expandAll() def reject(self): QDialog.reject(self)
class DiffViewerDialog(WIDGET, BASE): def __init__(self, parent, repo, refa, refb): super(DiffViewerDialog, self).__init__(parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.repo = repo self.setupUi(self) self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb) layout = QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) self.featuresTree.currentItemChanged.connect(self.treeItemChanged) self.featuresTree.header().hide() self.computeDiffs() self.groupBox.adjustSize() def refsHaveChanged(self): self.computeDiffs() def treeItemChanged(self, current, previous): qgsgeom1 = None qgsgeom2 = None crs = "EPSG:4326" if not isinstance(current, FeatureItem): self.attributesTable.clear() self.attributesTable.setRowCount(0) return color = {"MODIFIED": QColor(255, 170, 0), "ADDED":Qt.green, "REMOVED":Qt.red , "NO_CHANGE":Qt.white} path = current.layername + "/" + current.featureid featurediff = self.changes[path].featurediff() self.attributesTable.clear() self.attributesTable.verticalHeader().show() self.attributesTable.horizontalHeader().show() self.attributesTable.setRowCount(len(featurediff)) self.attributesTable.setVerticalHeaderLabels([a["attributename"] for a in featurediff]) self.attributesTable.setHorizontalHeaderLabels(["Old value", "New value", "Change type"]) for i, attrib in enumerate(featurediff): try: if attrib["changetype"] == "MODIFIED": oldvalue = attrib["oldvalue"] newvalue = attrib["newvalue"] elif attrib["changetype"] == "ADDED": newvalue = attrib["newvalue"] oldvalue = "" elif attrib["changetype"] == "REMOVED": oldvalue = attrib["oldvalue"] newvalue = "" else: oldvalue = newvalue = attrib["oldvalue"] except: oldvalue = newvalue = "" self.attributesTable.setItem(i, 0, DiffItem(oldvalue)) self.attributesTable.setItem(i, 1, DiffItem(newvalue)) try: self.attributesTable.setItem(i, 2, QTableWidgetItem("")) if qgsgeom1 is None or qgsgeom2 is None: if "crs" in attrib: crs = attrib["crs"] qgsgeom1 = QgsGeometry.fromWkt(oldvalue) qgsgeom2 = QgsGeometry.fromWkt(newvalue) if qgsgeom1 is not None and qgsgeom2 is not None: widget = QWidget() btn = QPushButton() btn.setText("View detail") btn.clicked.connect(lambda: self.viewGeometryChanges(qgsgeom1, qgsgeom2, crs)) label = QLabel() label.setText(attrib["changetype"]) layout = QHBoxLayout(widget) layout.addWidget(label); layout.addWidget(btn); layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) self.attributesTable.setCellWidget(i, 2, widget) else: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) else: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) except: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) for col in range(3): self.attributesTable.item(i, col).setBackgroundColor(color[attrib["changetype"]]); self.attributesTable.resizeColumnsToContents() self.attributesTable.horizontalHeader().setResizeMode(QHeaderView.Stretch) def viewGeometryChanges(self, g1, g2, crs): dlg = GeometryDiffViewerDialog([g1, g2], QgsCoordinateReferenceSystem(crs)) dlg.exec_() def computeDiffs(self): self.commit1 = self.commit1Panel.getRef() self.commit2 = self.commit2Panel.getRef() self.featuresTree.clear() changes = execute(lambda: self.repo.diff(self.commit1.commitid, self.commit2.commitid)) layerItems = {} layerSubItems = {} self.changes = {} for c in changes: self.changes[c.path] = c layername = c.path.split("/")[0] featureid = c.path.split("/")[-1] if layername not in layerItems: item = QTreeWidgetItem() item.setText(0, layername) item.setIcon(0, layerIcon) layerItems[layername] = item addedItem = QTreeWidgetItem() addedItem.setText(0, "Added") addedItem.setIcon(0, addedIcon) removedItem = QTreeWidgetItem() removedItem.setText(0, "Removed") removedItem.setIcon(0, removedIcon) modifiedItem = QTreeWidgetItem() modifiedItem.setText(0, "Modified") modifiedItem.setIcon(0, modifiedIcon) layerSubItems[layername] = {FEATURE_ADDED: addedItem, FEATURE_REMOVED: removedItem, FEATURE_MODIFIED:modifiedItem} item = FeatureItem(layername, featureid) layerSubItems[layername][c.changetype].addChild(item) for layername, item in layerItems.iteritems(): for i in [FEATURE_ADDED, FEATURE_REMOVED, FEATURE_MODIFIED]: subItem = layerSubItems[layername][i] item.addChild(subItem) subItem.setText(0, "%s [%i features]" % (subItem.text(0), subItem.childCount())) self.featuresTree.addTopLevelItem(item) self.attributesTable.clear() self.attributesTable.verticalHeader().hide() self.attributesTable.horizontalHeader().hide() for item in layerItems.values(): item.setExpanded(True) def reject(self): QDialog.reject(self)
def __init__(self, parent, repo, refa, refb): QtGui.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.repo = repo self.layers = [] self.allchanges = {} self.currentPath = None if (isinstance(refa, Commit) and isinstance(refb, Commit) and refa.committerdate > refb.committerdate): refa, refb = refb, refa self.ui = Ui_DiffViewerDialog() self.ui.setupUi(self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMinMaxButtonsHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa, onlyCommits = False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.ui.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb, onlyCommits = False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.ui.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) horizontalLayout = QtGui.QHBoxLayout() horizontalLayout.setSpacing(0) horizontalLayout.setMargin(0) self.mapCanvas = QgsMapCanvas() self.mapCanvas.setCanvasColor(QtCore.Qt.white) settings = QtCore.QSettings() self.mapCanvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.mapCanvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.mapCanvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) horizontalLayout.addWidget(self.mapCanvas) self.ui.mapContainer.setLayout(horizontalLayout) self.panAndSelectTool = MapToolPanAndSelect(self.mapCanvas, self) self.mapCanvas.setMapTool(self.panAndSelectTool) self.ui.attributesTable.horizontalHeader().sectionClicked.connect(self.sortByColumn) self.ui.attributesTable.customContextMenuRequested.connect(self.showContextMenu) self.ui.layerCombo.currentIndexChanged.connect(self.layerChanged) def _zoomToFullExtent(): extent = self.getFullExtent() self.mapCanvas.setExtent(extent) self.mapCanvas.refresh() self.ui.zoomToExtentButton.clicked.connect(_zoomToFullExtent) self.ui.baseLayerCheck.setChecked(True) self.ui.compareLayerCheck.setChecked(True) self.computeDiffs() self.ui.baseLayerCheck.stateChanged.connect(self.showLayers) self.ui.compareLayerCheck.stateChanged.connect(self.showLayers) self.showMaximized()
class DiffViewerDialog(QtGui.QDialog): def __init__(self, parent, repo, refa, refb): QtGui.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.repo = repo self.layers = [] self.allchanges = {} self.currentPath = None if (isinstance(refa, Commit) and isinstance(refb, Commit) and refa.committerdate > refb.committerdate): refa, refb = refb, refa self.ui = Ui_DiffViewerDialog() self.ui.setupUi(self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMinMaxButtonsHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa, onlyCommits = False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.ui.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb, onlyCommits = False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.ui.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) horizontalLayout = QtGui.QHBoxLayout() horizontalLayout.setSpacing(0) horizontalLayout.setMargin(0) self.mapCanvas = QgsMapCanvas() self.mapCanvas.setCanvasColor(QtCore.Qt.white) settings = QtCore.QSettings() self.mapCanvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.mapCanvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.mapCanvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) horizontalLayout.addWidget(self.mapCanvas) self.ui.mapContainer.setLayout(horizontalLayout) self.panAndSelectTool = MapToolPanAndSelect(self.mapCanvas, self) self.mapCanvas.setMapTool(self.panAndSelectTool) self.ui.attributesTable.horizontalHeader().sectionClicked.connect(self.sortByColumn) self.ui.attributesTable.customContextMenuRequested.connect(self.showContextMenu) self.ui.layerCombo.currentIndexChanged.connect(self.layerChanged) def _zoomToFullExtent(): extent = self.getFullExtent() self.mapCanvas.setExtent(extent) self.mapCanvas.refresh() self.ui.zoomToExtentButton.clicked.connect(_zoomToFullExtent) self.ui.baseLayerCheck.setChecked(True) self.ui.compareLayerCheck.setChecked(True) self.computeDiffs() self.ui.baseLayerCheck.stateChanged.connect(self.showLayers) self.ui.compareLayerCheck.stateChanged.connect(self.showLayers) self.showMaximized() def refsHaveChanged(self): self.computeDiffs() def showContextMenu(self, point): row = self.ui.attributesTable.selectionModel().currentIndex().row() model = self.ui.attributesTable.model() index = model.index(row, self.geogigIdx) geogigid = model.data(index) menu = QtGui.QMenu() zoomAction = QtGui.QAction("Zoom to this feature", None) zoomAction.triggered.connect(lambda: self.zoomToFeature(geogigid)) menu.addAction(zoomAction) viewAction = QtGui.QAction("View geometry changes...", None) viewAction.triggered.connect(lambda: self.viewGeometryChanges(geogigid)) menu.addAction(viewAction) globalPoint = self.ui.attributesTable.mapToGlobal(point) menu.exec_(globalPoint) def zoomToFeature(self, geogigid): geometries = [g for g in self.features[geogigid][GEOMETRY_FIELD] if g is not None] extent = geometries[0].boundingBox() for geom in geometries: extent.combineExtentWith(geom.boundingBox()) self.mapCanvas.setExtent(extent) self.mapCanvas.refresh() def viewGeometryChanges(self, geogigid): geometries = self.features[geogigid][GEOMETRY_FIELD] dlg = GeometryDiffViewerDialog(geometries, self.layers[0].crs()) dlg.exec_() def sortByColumn(self, col): self.ui.attributesTable.sortByColumn(col, QtCore.Qt.DescendingOrder) def getFullExtent(self): layers = [lay for lay in self.layers if lay is not None] extent = layers[0].extent() for layer in layers: extent.combineExtentWith(layer.extent()) return extent def selectionChanged(self): row = self.ui.attributesTable.selectionModel().currentIndex().row() model = self.ui.attributesTable.model() index = model.index(row, self.geogigIdx) geogigid = model.data(index) def _filter(feature): return feature["geogigid"] == geogigid for layer in self.layers: if layer is not None: features = filter(_filter, layer.getFeatures()) layer.setSelectedFeatures([feature.id() for feature in features]) self.mapCanvas.refresh() def createTableDataFromLayers(self): self.attribs = [] self.features = {} for layer in self.layers: if layer is not None: fields = layer.pendingFields().toList() for f in fields: if f.name() not in self.attribs: self.attribs.append(f.name()) self.attribs.remove("changetype") self.attribs.insert(0, "changetype") if self.layers[0] is not None: layer = self.layers[0] fields = [f.name() for f in layer.pendingFields().toList()] features = layer.getFeatures() geogigidIdx = fields.index("geogigid") for feature in features: attrs = feature.attributes() geogigid = attrs[geogigidIdx] if not isinstance(geogigid, QtCore.QPyNullVariant): featuredict = {} for field in self.attribs: try: idx = fields.index(field) value = attrs[idx] except ValueError: value = None featuredict[field] = [value, None] featuredict[GEOMETRY_FIELD] = [QgsGeometry(feature.geometry()), None] self.features[geogigid] = featuredict if self.layers[1] is not None: layer = self.layers[1] fields = [f.name() for f in layer.pendingFields().toList()] features = layer.getFeatures() geogigidIdx = fields.index("geogigid") for feature in features: attrs = feature.attributes() geogigid = attrs[geogigidIdx] if not isinstance(geogigid, QtCore.QPyNullVariant): if geogigid not in self.features: self.features[geogigid] = {attr: [None, None] for attr in self.attribs} self.features[geogigid][GEOMETRY_FIELD] = [None, None] featuredict = self.features[geogigid] for field in self.attribs: try: idx = fields.index(field) value = attrs[idx] featuredict[field][1] = value except ValueError: pass featuredict[GEOMETRY_FIELD][1] = QgsGeometry(feature.geometry()) self.attribs.insert(1, GEOMETRY_FIELD) self.geogigIdx = self.attribs.index("geogigid") def layerChanged(self): layername = self.ui.layerCombo.currentText() self.computeLayerDiffs(layername) def computeDiffs(self): self.commit1 = self.commit1Panel.getRef() self.commit2 = self.commit2Panel.getRef() self.unloadLayers() allchanges = exportVersionDiffs(self.commit1, self.commit2) self.allchanges = {} for path, layers in allchanges.iteritems(): self.allchanges[path] = layers for layer in layers: if layer is not None: QgsMapLayerRegistry.instance().addMapLayer(layer, False) if self.allchanges: self.layers = self.allchanges.values()[0] self.ui.layerCombo.blockSignals(True) self.ui.layerCombo.clear() self.ui.layerCombo.addItems(self.allchanges.keys()) self.ui.layerCombo.blockSignals(False) self.computeLayerDiffs(self.allchanges.keys()[0]) else: self.mapCanvas.clear() self.proxyModel.deleteLater() def computeLayerDiffs(self, layername): def _computeLayerDiff(): self.layers = self.allchanges[layername] self.createTableDataFromLayers() self.geogigidIdx = self.attribs.index("geogigid") self.changeTypeIdx = self.attribs.index("changetype") model = DiffTableModel(self.attribs, self.features) self.proxyModel = QtGui.QSortFilterProxyModel(); self.proxyModel.setSourceModel(model) self.ui.attributesTable.setModel(self.proxyModel) self.ui.attributesTable.selectionModel().selectionChanged.connect(self.selectionChanged) self.ui.attributesTable.setColumnHidden(self.geogigidIdx, True) self.ui.attributesTable.resizeColumnsToContents() self.ui.attributesTable.setVisible(False) vporig = self.ui.attributesTable.viewport().geometry() vpnew = vporig; vpnew.setWidth(10000); self.ui.attributesTable.viewport().setGeometry(vpnew); self.ui.attributesTable.resizeRowsToContents() self.ui.attributesTable.viewport().setGeometry(vporig); self.ui.attributesTable.setVisible(True) self.showLayers() execute(_computeLayerDiff) def showLayers(self): layers = [lay for lay in self.layers if lay is not None] self.mapCanvas.setDestinationCrs(layers[0].crs()) extent = self.getFullExtent() self.mapCanvas.setRenderFlag(False) self.mapCanvas.clear() visibility = [self.ui.compareLayerCheck.isChecked(), self.ui.baseLayerCheck.isChecked()] mapLayers = [QgsMapCanvasLayer(lay) for i, lay in enumerate(reversed(self.layers)) if visibility[i]] self.mapCanvas.setLayerSet(mapLayers) self.mapCanvas.setRenderFlag(True) self.mapCanvas.refresh() self.mapCanvas.setExtent(extent) def reject(self): QtGui.QDialog.reject(self) self.unloadLayers() def unloadLayers(self): for layers in self.allchanges.values(): for layer in layers: if layer is not None: QgsMapLayerRegistry.instance().removeMapLayer(layer.id())
def __init__(self, parent, repo, refa, refb): QtGui.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.repo = repo self.layers = [] self.allchanges = {} self.currentPath = None if isinstance(refa, Commit) and isinstance(refb, Commit) and refa.committerdate > refb.committerdate: refa, refb = refb, refa self.ui = Ui_DiffViewerDialog() self.ui.setupUi(self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMinMaxButtonsHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa, onlyCommits=False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.ui.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb, onlyCommits=False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.ui.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) horizontalLayout = QtGui.QHBoxLayout() horizontalLayout.setSpacing(0) horizontalLayout.setMargin(0) self.mapCanvas = QgsMapCanvas() self.mapCanvas.setCanvasColor(QtCore.Qt.white) settings = QtCore.QSettings() self.mapCanvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type=bool)) self.mapCanvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type=bool)) action = settings.value("/qgis/wheel_action", 0, type=float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type=float) self.mapCanvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) horizontalLayout.addWidget(self.mapCanvas) self.ui.mapContainer.setLayout(horizontalLayout) self.panAndSelectTool = MapToolPanAndSelect(self.mapCanvas, self) self.mapCanvas.setMapTool(self.panAndSelectTool) self.ui.attributesTable.horizontalHeader().sectionClicked.connect(self.sortByColumn) self.ui.attributesTable.customContextMenuRequested.connect(self.showContextMenu) self.ui.layerCombo.currentIndexChanged.connect(self.layerChanged) def _zoomToFullExtent(): extent = self.getFullExtent() self.mapCanvas.setExtent(extent) self.mapCanvas.refresh() self.ui.zoomToExtentButton.clicked.connect(_zoomToFullExtent) self.ui.baseLayerCheck.setChecked(True) self.ui.compareLayerCheck.setChecked(True) self.computeDiffs() self.ui.baseLayerCheck.stateChanged.connect(self.showLayers) self.ui.compareLayerCheck.stateChanged.connect(self.showLayers) self.showMaximized()
class DiffViewerDialog(QtGui.QDialog): def __init__(self, parent, repo, refa, refb): QtGui.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.repo = repo self.layers = [] self.allchanges = {} self.currentPath = None if isinstance(refa, Commit) and isinstance(refb, Commit) and refa.committerdate > refb.committerdate: refa, refb = refb, refa self.ui = Ui_DiffViewerDialog() self.ui.setupUi(self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMinMaxButtonsHint) self.commit1 = refa self.commit1Panel = RefPanel(self.repo, refa, onlyCommits=False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit1Panel) self.ui.commit1Widget.setLayout(layout) self.commit2 = refb self.commit2Panel = RefPanel(self.repo, refb, onlyCommits=False) layout = QtGui.QHBoxLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.commit2Panel) self.ui.commit2Widget.setLayout(layout) self.commit1Panel.refChanged.connect(self.refsHaveChanged) self.commit2Panel.refChanged.connect(self.refsHaveChanged) horizontalLayout = QtGui.QHBoxLayout() horizontalLayout.setSpacing(0) horizontalLayout.setMargin(0) self.mapCanvas = QgsMapCanvas() self.mapCanvas.setCanvasColor(QtCore.Qt.white) settings = QtCore.QSettings() self.mapCanvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type=bool)) self.mapCanvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type=bool)) action = settings.value("/qgis/wheel_action", 0, type=float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type=float) self.mapCanvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) horizontalLayout.addWidget(self.mapCanvas) self.ui.mapContainer.setLayout(horizontalLayout) self.panAndSelectTool = MapToolPanAndSelect(self.mapCanvas, self) self.mapCanvas.setMapTool(self.panAndSelectTool) self.ui.attributesTable.horizontalHeader().sectionClicked.connect(self.sortByColumn) self.ui.attributesTable.customContextMenuRequested.connect(self.showContextMenu) self.ui.layerCombo.currentIndexChanged.connect(self.layerChanged) def _zoomToFullExtent(): extent = self.getFullExtent() self.mapCanvas.setExtent(extent) self.mapCanvas.refresh() self.ui.zoomToExtentButton.clicked.connect(_zoomToFullExtent) self.ui.baseLayerCheck.setChecked(True) self.ui.compareLayerCheck.setChecked(True) self.computeDiffs() self.ui.baseLayerCheck.stateChanged.connect(self.showLayers) self.ui.compareLayerCheck.stateChanged.connect(self.showLayers) self.showMaximized() def refsHaveChanged(self): self.computeDiffs() def showContextMenu(self, point): row = self.ui.attributesTable.selectionModel().currentIndex().row() model = self.ui.attributesTable.model() index = model.index(row, self.geogigIdx) geogigid = model.data(index) menu = QtGui.QMenu() zoomAction = QtGui.QAction("Zoom to this feature", None) zoomAction.triggered.connect(lambda: self.zoomToFeature(geogigid)) menu.addAction(zoomAction) viewAction = QtGui.QAction("View geometry changes...", None) viewAction.triggered.connect(lambda: self.viewGeometryChanges(geogigid)) menu.addAction(viewAction) globalPoint = self.ui.attributesTable.mapToGlobal(point) menu.exec_(globalPoint) def zoomToFeature(self, geogigid): geometries = [g for g in self.features[geogigid][GEOMETRY_FIELD] if g is not None] extent = geometries[0].boundingBox() for geom in geometries: extent.combineExtentWith(geom.boundingBox()) self.mapCanvas.setExtent(extent) self.mapCanvas.refresh() def viewGeometryChanges(self, geogigid): geometries = self.features[geogigid][GEOMETRY_FIELD] dlg = GeometryDiffViewerDialog(geometries, self.layers[0].crs()) dlg.exec_() def sortByColumn(self, col): self.ui.attributesTable.sortByColumn(col, QtCore.Qt.DescendingOrder) def getFullExtent(self): layers = [lay for lay in self.layers if lay is not None] extent = layers[0].extent() for layer in layers: extent.combineExtentWith(layer.extent()) return extent def selectionChanged(self): row = self.ui.attributesTable.selectionModel().currentIndex().row() model = self.ui.attributesTable.model() index = model.index(row, self.geogigIdx) geogigid = model.data(index) def _filter(feature): return feature["geogigid"] == geogigid for layer in self.layers: if layer is not None: features = filter(_filter, layer.getFeatures()) layer.setSelectedFeatures([feature.id() for feature in features]) self.mapCanvas.refresh() def createTableDataFromLayers(self): self.attribs = [] self.features = {} for layer in self.layers: if layer is not None: fields = layer.pendingFields().toList() for f in fields: if f.name() not in self.attribs: self.attribs.append(f.name()) self.attribs.remove("changetype") self.attribs.insert(0, "changetype") if self.layers[0] is not None: layer = self.layers[0] fields = [f.name() for f in layer.pendingFields().toList()] features = layer.getFeatures() geogigidIdx = fields.index("geogigid") for feature in features: attrs = feature.attributes() geogigid = attrs[geogigidIdx] if not isinstance(geogigid, QtCore.QPyNullVariant): featuredict = {} for field in self.attribs: try: idx = fields.index(field) value = attrs[idx] except ValueError: value = None featuredict[field] = [value, None] featuredict[GEOMETRY_FIELD] = [QgsGeometry(feature.geometry()), None] self.features[geogigid] = featuredict if self.layers[1] is not None: layer = self.layers[1] fields = [f.name() for f in layer.pendingFields().toList()] features = layer.getFeatures() geogigidIdx = fields.index("geogigid") for feature in features: attrs = feature.attributes() geogigid = attrs[geogigidIdx] if not isinstance(geogigid, QtCore.QPyNullVariant): if geogigid not in self.features: self.features[geogigid] = {attr: [None, None] for attr in self.attribs} self.features[geogigid][GEOMETRY_FIELD] = [None, None] featuredict = self.features[geogigid] for field in self.attribs: try: idx = fields.index(field) value = attrs[idx] featuredict[field][1] = value except ValueError: pass featuredict[GEOMETRY_FIELD][1] = QgsGeometry(feature.geometry()) self.attribs.insert(1, GEOMETRY_FIELD) self.geogigIdx = self.attribs.index("geogigid") def layerChanged(self): layername = self.ui.layerCombo.currentText() self.computeLayerDiffs(layername) def computeDiffs(self): self.commit1 = self.commit1Panel.getRef() self.commit2 = self.commit2Panel.getRef() self.unloadLayers() allchanges = exportVersionDiffs(self.commit1, self.commit2) self.allchanges = {} for path, layers in allchanges.iteritems(): self.allchanges[path] = layers for layer in layers: if layer is not None: QgsMapLayerRegistry.instance().addMapLayer(layer, False) if self.allchanges: self.layers = self.allchanges.values()[0] self.ui.layerCombo.blockSignals(True) self.ui.layerCombo.clear() self.ui.layerCombo.addItems(self.allchanges.keys()) self.ui.layerCombo.blockSignals(False) self.computeLayerDiffs(self.allchanges.keys()[0]) else: self.mapCanvas.clear() self.proxyModel.deleteLater() def computeLayerDiffs(self, layername): def _computeLayerDiff(): self.layers = self.allchanges[layername] self.createTableDataFromLayers() self.geogigidIdx = self.attribs.index("geogigid") self.changeTypeIdx = self.attribs.index("changetype") model = DiffTableModel(self.attribs, self.features) self.proxyModel = QtGui.QSortFilterProxyModel() self.proxyModel.setSourceModel(model) self.ui.attributesTable.setModel(self.proxyModel) self.ui.attributesTable.selectionModel().selectionChanged.connect(self.selectionChanged) self.ui.attributesTable.setColumnHidden(self.geogigidIdx, True) self.ui.attributesTable.resizeColumnsToContents() self.ui.attributesTable.setVisible(False) vporig = self.ui.attributesTable.viewport().geometry() vpnew = vporig vpnew.setWidth(10000) self.ui.attributesTable.viewport().setGeometry(vpnew) self.ui.attributesTable.resizeRowsToContents() self.ui.attributesTable.viewport().setGeometry(vporig) self.ui.attributesTable.setVisible(True) self.showLayers() execute(_computeLayerDiff) def showLayers(self): layers = [lay for lay in self.layers if lay is not None] self.mapCanvas.setDestinationCrs(layers[0].crs()) extent = self.getFullExtent() self.mapCanvas.setRenderFlag(False) self.mapCanvas.clear() visibility = [self.ui.compareLayerCheck.isChecked(), self.ui.baseLayerCheck.isChecked()] mapLayers = [QgsMapCanvasLayer(lay) for i, lay in enumerate(reversed(self.layers)) if visibility[i]] self.mapCanvas.setLayerSet(mapLayers) self.mapCanvas.setRenderFlag(True) self.mapCanvas.refresh() self.mapCanvas.setExtent(extent) def reject(self): QtGui.QDialog.reject(self) self.unloadLayers() def unloadLayers(self): for layers in self.allchanges.values(): for layer in layers: if layer is not None: QgsMapLayerRegistry.instance().removeMapLayer(layer.id())