Commit 28b551e7 authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files

addd Quick Label shortcuts to Attribute Table context menu


Signed-off-by: Benjamin Jakimow's avatarBenjamin Jakimow benjamin.jakimow@geo.hu-berlin.de <benjamin.jakimow@geo.hu-berlin.de>
parent c243afe2
Pipeline #13922 failed with stage
in 34 seconds
......@@ -8,7 +8,7 @@ from qgis.core import QgsMapLayer, QgsRasterLayer, QgsVectorLayer, QgsField, Qgs
from qgis.gui import QgsDockWidget, QgsSpinBox, QgsDoubleSpinBox, \
QgsEditorConfigWidget, QgsEditorWidgetFactory, QgsEditorWidgetWrapper, \
QgsGui, QgsEditorWidgetRegistry, \
QgsDateTimeEdit, QgsDateEdit, QgsTimeEdit
QgsDateTimeEdit, QgsDateEdit, QgsTimeEdit, QgsActionMenu, QgsAttributeTableModel
from eotimeseriesviewer.externals.qps.layerproperties import showLayerPropertiesDialog, AttributeTableWidget
from eotimeseriesviewer.timeseries import TimeSeriesDate, TimeSeriesSource
......@@ -16,7 +16,7 @@ from eotimeseriesviewer import DIR_UI
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from .externals.qps.utils import datetime64, loadUi
from .externals.qps.utils import datetime64, loadUi, SpatialPoint, SpatialExtent
from .externals.qps.classification.classificationscheme import ClassInfo, ClassificationScheme
from .externals.qps.layerproperties import showLayerPropertiesDialog
from .externals.qps.models import Option, OptionListModel
......@@ -295,6 +295,7 @@ def setQuickTSDLabels(vectorLayer: QgsVectorLayer,
vectorLayer.changeAttributeValue(feature.id(), iField, value, oldValue)
vectorLayer.endEditCommand()
vectorLayer.triggerRepaint()
pass
......@@ -671,6 +672,9 @@ def gotoPreviousFeature(layer: QgsVectorLayer, tools: QgsVectorLayerTools):
class LabelWidget(AttributeTableWidget):
sigMoveTo = pyqtSignal([QDateTime],
[QDateTime, object])
def __init__(self, *args, **kwds):
super().__init__(*args, *kwds)
......@@ -740,6 +744,65 @@ class LabelWidget(AttributeTableWidget):
self.btnShowProperties)
self.mLayer.featureAdded.connect(self.onLabelFeatureAdded)
self.mMainView.tableView().willShowContextMenu.connect(self.onShowContextMenu)
def onShowContextMenu(self, menu: QMenu, idx: QModelIndex):
fid = idx.data(QgsAttributeTableModel.FeatureIdRole)
fieldIdx = idx.data(QgsAttributeTableModel.FieldIndexRole)
lyr = self.mLayer
if not isinstance(lyr, QgsVectorLayer):
return
feature: QgsFeature = self.mLayer.getFeature(fid)
if not isinstance(feature, QgsFeature):
return
ACTIONS = dict()
for a in menu.findChildren(QAction):
ACTIONS[a.text()] = a
# todo: connect default options
extent: SpatialExtent = SpatialExtent(lyr.crs(), feature.geometry().boundingBox())
center: SpatialPoint = SpatialPoint(lyr.crs(), feature.geometry().centroid().asPoint())
field = lyr.fields().at(fieldIdx)
if field.type() in [QVariant.Date, QVariant.DateTime]:
if isinstance(feature, QgsFeature):
datetime = feature.attribute(fieldIdx)
try:
datetime = QDateTime(datetime64(datetime).astype(object))
except:
pass
# add temporal options
if isinstance(datetime, QDateTime):
date_string = datetime.toString(Qt.ISODate)
a1 = QAction(f'Move time to', menu)
a1.setToolTip(f'Moves the current date to {date_string}')
a1.triggered.connect(lambda *args, d=datetime:
self.sigMoveTo[QDateTime].emit(d))
a2 = QAction(f'Move time && pan to', menu)
a2.setToolTip(f'Moves the current date to {date_string} and pans to feature {feature.id()}')
a2.triggered.connect(lambda *args, f=feature, d=datetime:
self.sigMoveTo[QDateTime, object].emit(d, center))
a3 = QAction(f'Move time && zoom to', menu)
a2.setToolTip(f'Moves the current date to {date_string} and zooms to feature {feature.id()}')
a3.triggered.connect(lambda *args, f=feature, d=datetime:
self.sigMoveTo[QDateTime, object].emit(d, extent))
menu.insertActions(menu.actions()[0], [a1, a2, a3])
menu.insertSeparator(menu.actions()[3])
def selectBehaviour(self) -> QgsVectorLayer.SelectBehavior:
if self.mOptionSelectionSetSelection.isChecked():
......
......@@ -25,7 +25,8 @@ import re
import typing
import pathlib
import numpy as np
from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot, QObject, QFile, Qt, QSize, QCoreApplication, QVariant
from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot, QObject, QFile, Qt, QSize, QCoreApplication, \
QVariant, QDate, QDateTime
from qgis.PyQt.QtGui import QCloseEvent, QColor, QIcon
from qgis.PyQt.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QGridLayout, QMainWindow, \
QToolButton, QAction, QLabel, QProgressBar, QApplication, QSizePolicy, \
......@@ -110,6 +111,7 @@ class AboutDialogUI(QDialog):
self.setWindowTitle(title)
class EOTimeSeriesViewerUI(QMainWindow):
sigAboutToBeClosed = pyqtSignal()
......@@ -975,6 +977,20 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
# last resort: we need to change the EOTSV Projection
self.setSpatialExtent(tss.spatialExtent())
def moveTo(self, date: QDateTime = None,
geometry: typing.Union[SpatialPoint, SpatialExtent] = None):
# set temporal subset, i.e. current date
if date:
self.setCurrentDate(date)
if isinstance(geometry, SpatialPoint):
self.setSpatialCenter(geometry)
elif isinstance(geometry, SpatialExtent):
self.setSpatialExtent(geometry)
else:
print('Unsupported moveTo action')
def setCurrentDate(self, tsd: TimeSeriesDate):
"""
Moves the viewport of the scroll window to a specific TimeSeriesDate
......@@ -1596,10 +1612,11 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
assert isinstance(lyr, QgsVectorLayer)
# 1. check if this layer is already opened as dock widget
docks: typing.List[QgsDockWidget] = [d for d in self.ui.findChildren(QgsDockWidget)
if isinstance(d, (LabelDockWidget, SpectralLibraryDockWidget))]
docks: typing.List[QgsDockWidget] = self.ui.findChildren(QgsDockWidget)
vectorLayerDocks: typing.List[QgsDockWidget] = [d for d in docks if
isinstance(d, (LabelDockWidget, SpectralLibraryDockWidget))]
for d in docks:
for d in vectorLayerDocks:
if isinstance(d, LabelDockWidget) and d.vectorLayer().id() == lyr.id():
d.show()
return
......@@ -1618,13 +1635,14 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
#dock.SLW.actionSelectProfilesFromMap.triggered.connect(self.activateIdentifySpectralProfileMapTool)
else:
dock = LabelDockWidget(lyr)
dock.mLabelWidget.sigMoveTo[QDateTime].connect(self.setCurrentDate)
dock.mLabelWidget.sigMoveTo[QDateTime, object].connect(self.moveTo)
dock.setObjectName(f'LabelDockWidget{id(dock)}')
dock.setVectorLayerTools(self.vectorLayerTools())
self.ui.addDockWidget(Qt.BottomDockWidgetArea, dock)
self.ui.menuPanels.addAction(dock.toggleViewAction())
if len(docks) > 0:
self.ui.tabifyDockWidget(docks[0], dock)
self.ui.tabifyDockWidget(self.ui.dockTimeSeries, dock)
dock.raise_()
def clearLayoutWidgets(self, L):
......
......@@ -911,6 +911,7 @@ class MapCanvas(QgsMapCanvas):
break
lyrWithSelectedFeatures = [l for l in quickLabelLayers() if l.selectedFeatureCount() > 0]
lyrWithSelectedFeatures = [l for l in lyrWithSelectedFeatures if l in self.layers() and l.isEditable()]
layerNames = ', '.join([l.name() for l in lyrWithSelectedFeatures])
m = menu.addMenu('Quick Labels')
......@@ -1253,15 +1254,15 @@ class MapCanvas(QgsMapCanvas):
self.populateContextMenu(menu, event.pos())
menu.exec_(event.globalPos())
else:
if event.button() == Qt.RightButton:
if bRight:
if isinstance(mt, QgsMapTool):
if bool(mt.flags() & QgsMapTool.ShowContextMenu):
if bool(mt.flags() & QgsMapTool.ShowContextMenu) or bool(modifiers & Qt.ControlModifier):
menu = QMenu()
mt.populateContextMenu(menu)
self.populateContextMenu(menu, event.pos())
menu.exec_(event.globalPos())
return
super().mousePressEvent(event)
if bLeft and not isinstance(mt, (QgsMapToolAddFeature, )):
......
......@@ -49,6 +49,7 @@ try:
except:
pass
from qgis.gui import QgsDockWidget, QgisInterface
from .externals.qps.utils import datetime64
DEFAULT_WKT = QgsCoordinateReferenceSystem('EPSG:4326').toWkt()
......@@ -2379,10 +2380,11 @@ class TimeSeries(QAbstractItemModel):
:param date: numpy.datetime64 | str | TimeSeriesDate
:return: TimeSeriesDate
"""
if isinstance(date, str):
date = np.datetime64(date)
if isinstance(date, TimeSeriesDate):
date = date.date()
else:
date = datetime64(date)
assert isinstance(date, np.datetime64)
if len(self) == 0:
......
......@@ -336,7 +336,7 @@ class TestLabeling(EOTSVTestCase):
EOTSV.loadExampleTimeSeries(10, loadAsync=False)
EOTSV.showAttributeTable(lyr)
EOTSV.mapViews()[0].addLayer(lyr)
EOTSV.onShowLayerProperties(lyr)
#EOTSV.onShowLayerProperties(lyr)
self.assertEqual(1, len(EOTSV.ui.findChildren(LabelDockWidget)))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment