diff --git a/CHANGELOG.md b/CHANGELOG.md
index ff378dc4..cb459e3b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -45,6 +45,7 @@ RELEASING:
- Additional parameter for the "smoothing factor" to isochrones processing algorithms ([#172](https://github.com/GIScience/orstools-qgis-plugin/issues/172))
- Mention omission of configuration options when using traveling salesman
- option to set location type for isochrones ([#191](https://github.com/GIScience/orstools-qgis-plugin/pull/191))
+- make items in centroid list drag and droppable ([#144](https://github.com/GIScience/orstools-qgis-plugin/issues/144))
## [1.6.0] - 2023-07-25
diff --git a/ORStools/gui/ORStoolsDialog.py b/ORStools/gui/ORStoolsDialog.py
index 39e119b7..0d879c5e 100644
--- a/ORStools/gui/ORStoolsDialog.py
+++ b/ORStools/gui/ORStoolsDialog.py
@@ -31,7 +31,14 @@
import os
import processing
import webbrowser
-from qgis.core import QgsProject, QgsVectorLayer, QgsTextAnnotation, QgsMapLayerProxyModel
+from qgis.core import (
+ QgsProject,
+ QgsVectorLayer,
+ QgsTextAnnotation,
+ QgsMapLayerProxyModel,
+ QgsCoordinateReferenceSystem,
+ QgsPointXY,
+)
from qgis.gui import QgsMapCanvasAnnotationItem
from PyQt5.QtCore import QSizeF, QPointF, QCoreApplication
@@ -422,6 +429,10 @@ def __init__(self, iface, parent=None):
lambda: processing.execAlgorithmDialog(f"{PLUGIN_NAME}:matrix_from_layers")
)
+ # Reset index of list items every time something is moved or deleted
+ self.routing_fromline_list.model().rowsMoved.connect(self._reindex_list_items)
+ self.routing_fromline_list.model().rowsRemoved.connect(self._reindex_list_items)
+
def _on_prov_refresh_click(self):
"""Populates provider dropdown with fresh list from config.yml"""
@@ -445,8 +456,10 @@ def _on_clear_listwidget_click(self):
self.routing_fromline_list.clear()
self._clear_annotations()
- def _linetool_annotate_point(self, point, idx):
- map_crs = self._iface.mapCanvas().mapSettings().destinationCrs()
+ def _linetool_annotate_point(self, point, idx, crs=None):
+ if not crs:
+ crs = self._iface.mapCanvas().mapSettings().destinationCrs()
+
annotation = QgsTextAnnotation()
c = QTextDocument()
@@ -458,7 +471,7 @@ def _linetool_annotate_point(self, point, idx):
annotation.setFrameSizeMm(QSizeF(7, 5))
annotation.setFrameOffsetFromReferencePointMm(QPointF(1.3, 1.3))
annotation.setMapPosition(point)
- annotation.setMapPositionCrs(map_crs)
+ annotation.setMapPositionCrs(crs)
return QgsMapCanvasAnnotationItem(annotation, self._iface.mapCanvas()).annotation()
@@ -495,6 +508,26 @@ def _on_linetool_map_click(self, point, idx):
self.annotations.append(annotation)
self.project.annotationManager().addAnnotation(annotation)
+ def _reindex_list_items(self):
+ """Resets the index when an item in the list is moved"""
+ items = [
+ self.routing_fromline_list.item(x).text()
+ for x in range(self.routing_fromline_list.count())
+ ]
+ self.routing_fromline_list.clear()
+ self._clear_annotations()
+ crs = QgsCoordinateReferenceSystem(f"EPSG:{4326}")
+ for idx, x in enumerate(items):
+ coords = x.split(":")[1]
+ item = f"Point {idx}:{coords}"
+ x, y = (float(i) for i in coords.split(", "))
+ point = QgsPointXY(x, y)
+
+ self.routing_fromline_list.addItem(item)
+ annotation = self._linetool_annotate_point(point, idx, crs)
+ self.annotations.append(annotation)
+ self.project.annotationManager().addAnnotation(annotation)
+
def _on_linetool_map_doubleclick(self):
"""
Populate line list widget with coordinates, end line drawing and show dialog again.
diff --git a/ORStools/gui/ORStoolsDialogUI.py b/ORStools/gui/ORStoolsDialogUI.py
index 2f4f2429..ab727b0e 100644
--- a/ORStools/gui/ORStoolsDialogUI.py
+++ b/ORStools/gui/ORStoolsDialogUI.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file 'ORStoolsDialogUI.ui'
+# Form implementation generated from reading ui file 'ORSToolsDialogUI.ui'
#
-# Created by: PyQt5 UI code generator 5.14.1
+# Created by: PyQt5 UI code generator 5.15.4
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -191,18 +192,19 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_fromline_list.setMinimumSize(QtCore.QSize(0, 0))
self.routing_fromline_list.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.routing_fromline_list.setFrameShadow(QtWidgets.QFrame.Sunken)
+ self.routing_fromline_list.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
self.routing_fromline_list.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
self.routing_fromline_list.setResizeMode(QtWidgets.QListView.Fixed)
self.routing_fromline_list.setObjectName("routing_fromline_list")
self.gridLayout.addWidget(self.routing_fromline_list, 0, 2, 3, 1)
self.verticalLayout_7.addWidget(self.widget)
- self.advances_group = gui.QgsCollapsibleGroupBox(self.qwidget)
+ self.advances_group = QgsCollapsibleGroupBox(self.qwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.advances_group.sizePolicy().hasHeightForWidth())
self.advances_group.setSizePolicy(sizePolicy)
- self.advances_group.setMaximumSize(QtCore.QSize(16777215, 23))
+ self.advances_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.advances_group.setCheckable(False)
self.advances_group.setChecked(False)
self.advances_group.setCollapsed(True)
@@ -211,14 +213,14 @@ def setupUi(self, ORStoolsDialogBase):
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.advances_group)
self.verticalLayout_3.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.verticalLayout_3.setObjectName("verticalLayout_3")
- self.optimization_group = gui.QgsCollapsibleGroupBox(self.advances_group)
+ self.optimization_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.optimization_group.sizePolicy().hasHeightForWidth())
self.optimization_group.setSizePolicy(sizePolicy)
self.optimization_group.setMinimumSize(QtCore.QSize(0, 0))
- self.optimization_group.setMaximumSize(QtCore.QSize(16777215, 23))
+ self.optimization_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.optimization_group.setCheckable(True)
self.optimization_group.setChecked(False)
self.optimization_group.setCollapsed(True)
@@ -255,7 +257,7 @@ def setupUi(self, ORStoolsDialogBase):
self.optimize_button_group.addButton(self.round_trip)
self.gridLayout_2.addWidget(self.round_trip, 2, 0, 1, 1)
self.verticalLayout_3.addWidget(self.optimization_group)
- self.routing_avoid_tags_group = gui.QgsCollapsibleGroupBox(self.advances_group)
+ self.routing_avoid_tags_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@@ -285,13 +287,13 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_avoid_tracks_3.setObjectName("routing_avoid_tracks_3")
self.gridLayout_4.addWidget(self.routing_avoid_tracks_3, 2, 0, 1, 1)
self.verticalLayout_3.addWidget(self.routing_avoid_tags_group)
- self.routing_avoid_countries_group = gui.QgsCollapsibleGroupBox(self.advances_group)
+ self.routing_avoid_countries_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.routing_avoid_countries_group.sizePolicy().hasHeightForWidth())
self.routing_avoid_countries_group.setSizePolicy(sizePolicy)
- self.routing_avoid_countries_group.setMaximumSize(QtCore.QSize(16777215, 23))
+ self.routing_avoid_countries_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.routing_avoid_countries_group.setCheckable(True)
self.routing_avoid_countries_group.setChecked(False)
self.routing_avoid_countries_group.setCollapsed(True)
@@ -299,18 +301,18 @@ def setupUi(self, ORStoolsDialogBase):
self.routing_avoid_countries_group.setObjectName("routing_avoid_countries_group")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.routing_avoid_countries_group)
self.verticalLayout_4.setObjectName("verticalLayout_4")
- self.countries_text = gui.QgsFilterLineEdit(self.routing_avoid_countries_group)
+ self.countries_text = QgsFilterLineEdit(self.routing_avoid_countries_group)
self.countries_text.setProperty("qgisRelation", "")
self.countries_text.setObjectName("countries_text")
self.verticalLayout_4.addWidget(self.countries_text)
self.verticalLayout_3.addWidget(self.routing_avoid_countries_group)
- self.avoidpolygon_group = gui.QgsCollapsibleGroupBox(self.advances_group)
+ self.avoidpolygon_group = QgsCollapsibleGroupBox(self.advances_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.avoidpolygon_group.sizePolicy().hasHeightForWidth())
self.avoidpolygon_group.setSizePolicy(sizePolicy)
- self.avoidpolygon_group.setMaximumSize(QtCore.QSize(16777215, 23))
+ self.avoidpolygon_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.avoidpolygon_group.setCheckable(True)
self.avoidpolygon_group.setChecked(False)
self.avoidpolygon_group.setCollapsed(True)
@@ -318,7 +320,7 @@ def setupUi(self, ORStoolsDialogBase):
self.avoidpolygon_group.setObjectName("avoidpolygon_group")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.avoidpolygon_group)
self.verticalLayout_6.setObjectName("verticalLayout_6")
- self.avoidpolygon_dropdown = gui.QgsMapLayerComboBox(self.avoidpolygon_group)
+ self.avoidpolygon_dropdown = QgsMapLayerComboBox(self.avoidpolygon_group)
self.avoidpolygon_dropdown.setShowCrs(False)
self.avoidpolygon_dropdown.setObjectName("avoidpolygon_dropdown")
self.verticalLayout_6.addWidget(self.avoidpolygon_dropdown)
@@ -381,14 +383,14 @@ def setupUi(self, ORStoolsDialogBase):
self.verticalLayout.addItem(spacerItem)
self.tabWidget.addTab(self.batch_tab, "")
self.verticalLayout_5.addWidget(self.tabWidget)
- self.ors_log_group = gui.QgsCollapsibleGroupBox(ORStoolsDialogBase)
+ self.ors_log_group = QgsCollapsibleGroupBox(ORStoolsDialogBase)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.ors_log_group.sizePolicy().hasHeightForWidth())
self.ors_log_group.setSizePolicy(sizePolicy)
self.ors_log_group.setMinimumSize(QtCore.QSize(0, 0))
- self.ors_log_group.setMaximumSize(QtCore.QSize(16777215, 23))
+ self.ors_log_group.setMaximumSize(QtCore.QSize(16777215, 20))
self.ors_log_group.setFlat(True)
self.ors_log_group.setCollapsed(True)
self.ors_log_group.setSaveCollapsedState(False)
@@ -515,5 +517,7 @@ def retranslateUi(self, ORStoolsDialogBase):
self.debug_text.setPlaceholderText(_translate("ORStoolsDialogBase", "Queries and errors will be printed here."))
self.help_button.setText(_translate("ORStoolsDialogBase", " Help"))
self.about_button.setText(_translate("ORStoolsDialogBase", "About"))
-from qgis import gui
-from . import resources_rc
+from qgscollapsiblegroupbox import QgsCollapsibleGroupBox
+from qgsfilterlineedit import QgsFilterLineEdit
+from qgsmaplayercombobox import QgsMapLayerComboBox
+# import resources_rc
diff --git a/ORStools/gui/ORStoolsDialogUI.ui b/ORStools/gui/ORStoolsDialogUI.ui
index f838897b..b076bd9a 100644
--- a/ORStools/gui/ORStoolsDialogUI.ui
+++ b/ORStools/gui/ORStoolsDialogUI.ui
@@ -330,6 +330,9 @@
QFrame::Sunken
+
+ QAbstractItemView::InternalMove
+
QAbstractItemView::MultiSelection
@@ -352,7 +355,7 @@
16777215
- 23
+ 20
@@ -391,7 +394,7 @@
16777215
- 23
+ 20
@@ -577,7 +580,7 @@ p, li { white-space: pre-wrap; }
16777215
- 23
+ 20
@@ -623,7 +626,7 @@ p, li { white-space: pre-wrap; }
16777215
- 23
+ 20
@@ -789,7 +792,7 @@ p, li { white-space: pre-wrap; }
16777215
- 23
+ 20