Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7912c88
refactor: run pyqt5_to_pyqt6.py migration script
merydian May 12, 2025
3ad44c4
feat: add gui utils
merydian May 9, 2024
f781468
feat: add necessary metadata note for qt6 conformance
merydian May 9, 2024
c590c00
feat: load main gui ui file as needed for qt6
merydian May 9, 2024
ea99ee3
fix: replace old import statement
merydian May 9, 2024
241212d
feat: import ui file like expected in PyQt6
merydian May 9, 2024
cee35e6
fix: add main plugin items like expected in PyQt6
merydian May 9, 2024
2bcbf85
fix: display utility button icons
merydian May 9, 2024
fab63f3
fix: make provider window work again
merydian May 14, 2024
2637088
fix: make processing icon appear agein
merydian May 14, 2024
fe73f21
style: run ruff
merydian May 14, 2024
25a14fb
style: delete UI.py files
merydian May 15, 2024
b7faf16
style: delete resource files
merydian May 15, 2024
dfc328a
fix: remove duplicate method definition
merydian May 12, 2025
37753e9
fix: specify new path of Qt cursorhand form definition
merydian May 12, 2025
0a4b66d
fix: specify new path of Qt clicks
merydian May 12, 2025
398c2b7
fix: remove unnecessary method definition
merydian May 12, 2025
c7a5b5b
fix: import gui
merydian May 12, 2025
40b5b90
fix: coloring of duplicate items in qlistwidget
merydian May 12, 2025
11347e6
fix: switch from QVariant to QMetaType
merydian May 12, 2025
7859918
style: run ruff
merydian May 12, 2025
4f3d3c4
fix: wrong path ov save vertices icon
merydian May 12, 2025
7956675
fix: remove duplicate :: in .ui file
merydian May 12, 2025
510d3bf
fix: introduce wrapper class for QgsField
merydian May 12, 2025
6b17e72
style: run ruff
merydian May 12, 2025
25f5b13
fix: use xvfb-run correctly without DISPLAY override to prevent GUI t…
merydian May 12, 2025
a26a7f7
refactor: remove unused code from utils/gui.py
merydian May 13, 2025
f98bd73
refactor: simplify icon getter code
merydian May 13, 2025
9a11b4a
fix: QgsField wrapper checks wrong type
merydian May 13, 2025
83672ba
fix: Use correct syntax for keys in PyQt6
merydian May 13, 2025
5a5bc75
style: run ruff
merydian May 13, 2025
97567bc
refactor: move global variable to top of file
merydian May 13, 2025
e621982
sytle: readd type hint
merydian May 13, 2025
f22862b
docs: add source of file from other repo
merydian May 13, 2025
e4a6faa
docs: add author of new file
merydian May 13, 2025
608235f
refactor: improve readability of QgsField wrapper
merydian May 13, 2025
b802cd1
style: run ruff
merydian May 13, 2025
27e0682
fix: remove unnecessary size policy in config ui
merydian May 13, 2025
d58ab33
feat: tests for QgsField wrapper
merydian May 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v4
- name: Run test 3.16
run: |
docker run -v ${GITHUB_WORKSPACE}:/src -w /src qgis/qgis:release-3_16 sh -c 'apt-get -y update && apt-get -y install xvfb && export ORS_API_KEY=${{ secrets.ORS_API_KEY }} && export DISPLAY=:0.0 && pip install -U pytest && xvfb-run pytest'
docker run -v ${GITHUB_WORKSPACE}:/src -w /src qgis/qgis:release-3_16 sh -c 'apt-get -y update && apt-get -y install xvfb && export ORS_API_KEY=${{ secrets.ORS_API_KEY }} && pip install -U pytest && xvfb-run -a pytest'
env:
DOCKER_IMAGE: ${{ steps.docker-build.outputs.FULL_IMAGE_NAME }}
test_3_22:
Expand All @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- name: Run test 3.22
run: |
docker run -v ${GITHUB_WORKSPACE}:/src -w /src qgis/qgis:release-3_22 sh -c 'apt-get -y update && apt-get -y install xvfb && export DISPLAY=:0.0 && export ORS_API_KEY=${{ secrets.ORS_API_KEY }} && export DISPLAY=:0.0 && pip install -U pytest && xvfb-run pytest'
docker run -v ${GITHUB_WORKSPACE}:/src -w /src qgis/qgis:release-3_22 sh -c 'apt-get -y update && apt-get -y install xvfb && export ORS_API_KEY=${{ secrets.ORS_API_KEY }} && export DISPLAY=:0.0 && pip install -U pytest && xvfb-run -a pytest'
env:
DOCKER_IMAGE: ${{ steps.docker-build.outputs.FULL_IMAGE_NAME }}
test_latest:
Expand All @@ -30,6 +30,6 @@ jobs:
- uses: actions/checkout@v4
- name: Run test latest
run: |
docker run -v ${GITHUB_WORKSPACE}:/src -w /src qgis/qgis:latest sh -c 'apt-get -y update && apt-get -y install xvfb && export DISPLAY=:0.0 && export ORS_API_KEY=${{ secrets.ORS_API_KEY }} && apt install python3-pytest && xvfb-run pytest'
docker run -v ${GITHUB_WORKSPACE}:/src -w /src qgis/qgis:latest sh -c 'apt-get -y update && apt-get -y install xvfb && export ORS_API_KEY=${{ secrets.ORS_API_KEY }} && apt install python3-pytest && xvfb-run -a pytest'
env:
DOCKER_IMAGE: ${{ steps.docker-build.outputs.FULL_IMAGE_NAME }}
35 changes: 18 additions & 17 deletions ORStools/common/directions_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@
from qgis.core import QgsPoint, QgsPointXY, QgsGeometry, QgsFeature, QgsFields, QgsField
from typing import List, Generator, Tuple, Any, Optional

from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtCore import QMetaType

from ORStools.utils import convert, logger
from ORStools.utils.wrapper import create_qgs_field


def get_request_point_features(route_dict: dict, row_by_row: str) -> Generator[List, Tuple, None]:
Expand Down Expand Up @@ -75,22 +76,22 @@ def get_request_point_features(route_dict: dict, row_by_row: str) -> Generator[L


def get_fields(
from_type: QVariant.Type = QVariant.String,
to_type: QVariant.Type = QVariant.String,
from_type: QMetaType.Type = QMetaType.Type.QString,
to_type: QMetaType.Type = QMetaType.Type.QString,
from_name: str = "FROM_ID",
to_name: str = "TO_ID",
line: bool = False,
extra_info: list = [],
two_layers: bool = False,
) -> QgsFields:
) -> QgsField:
"""
Builds output fields for directions response layer.

:param from_type: field type for 'FROM_ID' field
:type from_type: QVariant enum
:type from_type: QMetaType enum

:param to_type: field type for 'TO_ID' field
:type to_type: QVariant enum
:type to_type: QMetaType enum

:param from_name: field name for 'FROM_ID' field
:type from_name: str
Expand All @@ -107,21 +108,21 @@ def get_fields(

fields = QgsFields()
if not extra_info:
fields.append(QgsField("DIST_KM", QVariant.Double))
fields.append(QgsField("DURATION_H", QVariant.Double))
fields.append(QgsField("PROFILE", QVariant.String))
fields.append(QgsField("PREF", QVariant.String))
fields.append(QgsField("OPTIONS", QVariant.String))
fields.append(QgsField(from_name, from_type))
fields.append(create_qgs_field("DIST_KM", QMetaType.Type.Double))
fields.append(create_qgs_field("DURATION_H", QMetaType.Type.Double))
fields.append(create_qgs_field("PROFILE", QMetaType.Type.QString))
fields.append(create_qgs_field("PREF", QMetaType.Type.QString))
fields.append(create_qgs_field("OPTIONS", QMetaType.Type.QString))
fields.append(create_qgs_field(from_name, from_type))
if not line:
fields.append(QgsField(to_name, to_type))
fields.append(create_qgs_field(to_name, to_type))
if two_layers:
fields.append(QgsField(from_name, from_type))
fields.append(create_qgs_field(from_name, from_type))
for info in extra_info:
field_type = QVariant.Int
field_type = QMetaType.Type.Int
if info in ["waytype", "surface", "waycategory", "roadaccessrestrictions", "steepness"]:
field_type = QVariant.String
fields.append(QgsField(info.upper(), field_type))
field_type = QMetaType.Type.QString
fields.append(create_qgs_field(info.upper(), field_type))

return fields

Expand Down
22 changes: 12 additions & 10 deletions ORStools/common/isochrones_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from qgis.core import (
QgsPointXY,
QgsFeature,
QgsField,
QgsFields,
QgsGeometry,
QgsSymbol,
Expand All @@ -42,9 +41,10 @@
QgsCategorizedSymbolRenderer,
)

from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtCore import QMetaType
from qgis.PyQt.QtGui import QColor

from ORStools.utils.wrapper import create_qgs_field

# import processing

Expand All @@ -67,7 +67,7 @@ def set_parameters(
profile: str,
dimension: str,
factor: int,
id_field_type: QVariant.String = QVariant.String,
id_field_type: QMetaType.Type.QString = QMetaType.Type.QString,
id_field_name: str = "ID",
) -> None:
"""
Expand All @@ -84,7 +84,7 @@ def set_parameters(
:type factor: int

:param id_field_type: field type of ID field
:type id_field_type: QVariant enum
:type id_field_type: QMetaType enum

:param id_field_name: field name of ID field
:type id_field_name: str
Expand All @@ -105,12 +105,14 @@ def get_fields(self) -> QgsFields:
:rtype: QgsFields
"""
fields = QgsFields()
fields.append(QgsField(self.id_field_name, self.id_field_type)) # ID field
fields.append(QgsField("CENTER_LON", QVariant.String))
fields.append(QgsField("CENTER_LAT", QVariant.String))
fields.append(QgsField(self.field_dimension_name, QVariant.Int)) # Dimension field
fields.append(QgsField("AA_MODE", QVariant.String))
fields.append(QgsField("TOTAL_POP", QVariant.String))
fields.append(create_qgs_field(self.id_field_name, self.id_field_type)) # ID field
fields.append(create_qgs_field("CENTER_LON", QMetaType.Type.QString))
fields.append(create_qgs_field("CENTER_LAT", QMetaType.Type.QString))
fields.append(
create_qgs_field(self.field_dimension_name, QMetaType.Type.Int)
) # Dimension field
fields.append(create_qgs_field("AA_MODE", QMetaType.Type.QString))
fields.append(create_qgs_field("TOTAL_POP", QMetaType.Type.QString))

return fields

Expand Down
57 changes: 27 additions & 30 deletions ORStools/gui/ORStoolsDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import os
from typing import Optional

from PyQt5.QtWidgets import QCheckBox
from qgis.PyQt.QtWidgets import QCheckBox

from ..utils.router import route_as_layer

Expand All @@ -41,6 +41,8 @@

import webbrowser

from qgis.PyQt import uic
from qgis._core import Qgis
from qgis.core import (
QgsProject,
QgsVectorLayer,
Expand All @@ -51,26 +53,21 @@
QgsGeometry,
QgsCoordinateReferenceSystem,
QgsSettings,
Qgis,
Qgis, # noqa: F811
QgsAnnotation,
QgsCoordinateTransform,
)
from qgis.gui import QgsMapCanvasAnnotationItem, QgsCollapsibleGroupBox, QgisInterface
from qgis.PyQt.QtCore import QSizeF, QPointF, QCoreApplication
from qgis.PyQt.QtGui import QIcon, QTextDocument, QColor
from qgis.PyQt.QtGui import QTextDocument
from qgis.PyQt.QtWidgets import QAction, QDialog, QApplication, QMenu, QMessageBox, QDialogButtonBox
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtWidgets import (
QAction,
QDialog,
QApplication,
QMenu,
QMessageBox,
QDialogButtonBox,
QWidget,
QRadioButton,
)

from ORStools import (
RESOURCE_PREFIX,
PLUGIN_NAME,
DEFAULT_COLOR,
__version__,
Expand All @@ -82,11 +79,10 @@
PROFILES,
PREFERENCES,
)
from ORStools.utils import maptools, configmanager, transform
from ORStools.utils import maptools, configmanager, transform, gui
from .ORStoolsDialogConfig import ORStoolsDialogConfigMain
from .ORStoolsDialogUI import Ui_ORStoolsDialogBase

from . import resources_rc # noqa: F401
MAIN_WIDGET, _ = uic.loadUiType(gui.GuiUtils.get_ui_file_path("ORStoolsDialogUI.ui"))


def on_config_click(parent):
Expand Down Expand Up @@ -154,19 +150,7 @@ def __init__(self, iface: QgisInterface) -> None:
def initGui(self) -> None:
"""Called when plugin is activated (on QGIS startup or when activated in Plugin Manager)."""

def create_icon(f: str) -> QIcon:
"""
internal function to create action icons

:param f: file name of icon.
:type f: str

:returns: icon object to insert to QAction
:rtype: QIcon
"""
return QIcon(RESOURCE_PREFIX + f)

icon_plugin = create_icon("icon_orstools.png")
icon_plugin = gui.GuiUtils.get_icon("icon_orstools.png")

self.actions = [
QAction(
Expand All @@ -176,14 +160,18 @@ def create_icon(f: str) -> QIcon:
),
# Config dialog
QAction(
create_icon("icon_settings.png"),
gui.GuiUtils.get_icon("icon_settings.png"),
self.tr("Provider Settings"),
self.iface.mainWindow(),
),
# About dialog
QAction(create_icon("icon_about.png"), self.tr("About"), self.iface.mainWindow()),
QAction(
gui.GuiUtils.get_icon("icon_about.png"), self.tr("About"), self.iface.mainWindow()
),
# Help page
QAction(create_icon("icon_help.png"), self.tr("Help"), self.iface.mainWindow()),
QAction(
gui.GuiUtils.get_icon("icon_help.png"), self.tr("Help"), self.iface.mainWindow()
),
]

# Create menu
Expand Down Expand Up @@ -294,7 +282,7 @@ def tr(self, string: str) -> str:
return QCoreApplication.translate(str(self.__class__.__name__), string)


class ORStoolsDialog(QDialog, Ui_ORStoolsDialogBase):
class ORStoolsDialog(QDialog, MAIN_WIDGET):
"""Define the custom behaviour of Dialog"""

def __init__(self, iface: QgisInterface, parent=None) -> None:
Expand Down Expand Up @@ -366,6 +354,15 @@ def __init__(self, iface: QgisInterface, parent=None) -> None:
self.routing_fromline_list.model().rowsMoved.connect(self._reindex_list_items)
self.routing_fromline_list.model().rowsRemoved.connect(self._reindex_list_items)

# Add icons to buttons
self.routing_fromline_map.setIcon(gui.GuiUtils.get_icon("icon_add.png"))
self.routing_fromline_clear.setIcon(gui.GuiUtils.get_icon("icon_clear.png"))
self.save_vertices.setIcon(gui.GuiUtils.get_icon("icon_save.png"))
self.provider_refresh.setIcon(gui.GuiUtils.get_icon("icon_refresh.png"))
self.provider_config.setIcon(gui.GuiUtils.get_icon("icon_settings.png"))
self.about_button.setIcon(gui.GuiUtils.get_icon("icon_about.png"))
self.help_button.setIcon(gui.GuiUtils.get_icon("icon_help.png"))

# Connect signals to the color_duplicate_items function
self.routing_fromline_list.model().rowsRemoved.connect(
lambda: self.color_duplicate_items(self.routing_fromline_list)
Expand Down
15 changes: 7 additions & 8 deletions ORStools/gui/ORStoolsDialogConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

from qgis.gui import QgsCollapsibleGroupBox

from qgis.PyQt import QtWidgets
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import QMetaObject
from qgis.PyQt.QtWidgets import (
QDialog,
Expand All @@ -39,12 +39,13 @@
)
from qgis.PyQt.QtGui import QIntValidator

from ORStools.utils import configmanager
from .ORStoolsDialogConfigUI import Ui_ORStoolsDialogConfigBase
from ORStools.utils import configmanager, gui
from ..proc import ENDPOINTS, DEFAULT_SETTINGS

CONFIG_WIDGET, _ = uic.loadUiType(gui.GuiUtils.get_ui_file_path("ORStoolsDialogConfigUI.ui"))

class ORStoolsDialogConfigMain(QDialog, Ui_ORStoolsDialogConfigBase):

class ORStoolsDialogConfigMain(QDialog, CONFIG_WIDGET):
"""Builds provider config dialog."""

def __init__(self, parent=None) -> None:
Expand All @@ -66,7 +67,7 @@ def __init__(self, parent=None) -> None:
self.provider_remove.clicked.connect(self._remove_provider)

# Change OK to Save in config window
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Save"))
self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(self.tr("Save"))

def accept(self) -> None:
"""When the OK Button is clicked, in-memory temp_config is updated and written to settings"""
Expand All @@ -88,8 +89,7 @@ def accept(self) -> None:

timeout_input = box.findChild(QtWidgets.QLineEdit, box.title() + "_timeout_text")
# https://doc.qt.io/qt-5/qvalidator.html#State-enum

if timeout_input.validator().State() != 2:
if timeout_input.validator().State != 2:
self._adjust_timeout_input(timeout_input)

current_provider["timeout"] = int(timeout_input.text())
Expand Down Expand Up @@ -287,7 +287,6 @@ def _add_box(
gridLayout_3.addLayout(button_layout, 7, 0, 1, 4)

self.verticalLayout.addWidget(provider)
provider.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)

def _reset_endpoints(self) -> None:
"""Resets the endpoints to their original values."""
Expand Down
55 changes: 0 additions & 55 deletions ORStools/gui/ORStoolsDialogConfigUI.py

This file was deleted.

Loading