Skip to content

Commit

Permalink
Merge pull request #219 from geotribu/feature/send-crs
Browse files Browse the repository at this point in the history
feature(qchat): send and receive a crs message
  • Loading branch information
gounux authored Nov 14, 2024
2 parents 4971448 + cd6b089 commit 1876302
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 4 deletions.
1 change: 1 addition & 0 deletions qtribu/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,4 @@ def local_path(self, base_path: Path = Path().home() / ".geotribu/cdn/") -> Path
QCHAT_MESSAGE_TYPE_EXITER = "exiter"
QCHAT_MESSAGE_TYPE_LIKE = "like"
QCHAT_MESSAGE_TYPE_GEOJSON = "geojson"
QCHAT_MESSAGE_TYPE_CRS = "crs"
36 changes: 32 additions & 4 deletions qtribu/gui/dck_qchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# PyQGIS
from PyQt5 import QtWebSockets # noqa QGS103
from qgis.core import Qgis, QgsApplication, QgsJsonExporter, QgsMapLayer
from qgis.core import Qgis, QgsApplication, QgsJsonExporter, QgsMapLayer, QgsProject
from qgis.gui import QgisInterface, QgsDockWidget
from qgis.PyQt import uic
from qgis.PyQt.QtCore import QPoint, Qt
Expand All @@ -31,6 +31,7 @@
CHEATCODE_IAMAROBOT,
CHEATCODE_QGIS_PRO_LICENSE,
CHEATCODES,
QCHAT_MESSAGE_TYPE_CRS,
QCHAT_MESSAGE_TYPE_GEOJSON,
QCHAT_MESSAGE_TYPE_IMAGE,
QCHAT_MESSAGE_TYPE_LIKE,
Expand All @@ -41,12 +42,14 @@
from qtribu.gui.qchat_tree_widget_items import (
MESSAGE_COLUMN,
QChatAdminTreeWidgetItem,
QChatCrsTreeWidgetItem,
QChatGeojsonTreeWidgetItem,
QChatImageTreeWidgetItem,
QChatTextTreeWidgetItem,
)
from qtribu.logic.qchat_api_client import QChatApiClient
from qtribu.logic.qchat_messages import (
QChatCrsMessage,
QChatExiterMessage,
QChatGeojsonMessage,
QChatImageMessage,
Expand Down Expand Up @@ -165,6 +168,7 @@ def __init__(
self.qchat_ws.exiter_message_received.connect(self.on_exiter_message_received)
self.qchat_ws.like_message_received.connect(self.on_like_message_received)
self.qchat_ws.geojson_message_received.connect(self.on_geojson_message_received)
self.qchat_ws.crs_message_received.connect(self.on_crs_message_received)

# send message signal listener
self.lne_message.returnPressed.connect(self.on_send_button_clicked)
Expand Down Expand Up @@ -565,6 +569,13 @@ def on_geojson_message_received(self, message: QChatGeojsonMessage) -> None:
item = QChatGeojsonTreeWidgetItem(self.twg_chat, message)
self.add_tree_widget_item(item)

def on_crs_message_received(self, message: QChatCrsMessage) -> None:
"""
Launched when a CRS message is received from the websocket
"""
item = QChatCrsTreeWidgetItem(self.twg_chat, message)
self.add_tree_widget_item(item)

# endregion

def on_message_clicked(self, item: QTreeWidgetItem, column: int) -> None:
Expand Down Expand Up @@ -606,17 +617,26 @@ def on_custom_context_menu_requested(self, point: QPoint) -> None:

menu = QMenu(self.tr("QChat Menu"), self)

# if this is a geojson
# if this is a geojson message
if type(item) is QChatGeojsonTreeWidgetItem:
load_geojson_action = QAction(
QgsApplication.getThemeIcon("mActionAddLayer.svg"),
self.tr("Load geojson in QGIS"),
self.tr("Load layer in QGIS"),
)
load_geojson_action.triggered.connect(
partial(item.on_click, MESSAGE_COLUMN)
)
menu.addAction(load_geojson_action)

# if this is a crs message
if type(item) is QChatCrsTreeWidgetItem:
set_crs_action = QAction(
QgsApplication.getThemeIcon("mActionSetProjection.svg"),
self.tr("Set current project CRS"),
)
set_crs_action.triggered.connect(partial(item.on_click, MESSAGE_COLUMN))
menu.addAction(set_crs_action)

# like message action if possible
if item.can_be_liked:
like_action = QAction(
Expand Down Expand Up @@ -791,7 +811,15 @@ def on_send_crs_button_clicked(self) -> None:
"""
Action called when the Send CRS button is clicked
"""
QMessageBox.critical(self, self.tr("Send CRS"), self.tr("Not implemented yet"))
crs = QgsProject.instance().crs()
message = QChatCrsMessage(
type=QCHAT_MESSAGE_TYPE_CRS,
author=self.settings.author_nickname,
avatar=self.settings.author_avatar,
crs_wkt=crs.toWkt(),
crs_authid=crs.authid(),
)
self.qchat_ws.send_message(message)

def add_admin_message(self, text: str) -> None:
"""
Expand Down
31 changes: 31 additions & 0 deletions qtribu/gui/qchat_tree_widget_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from qtribu.constants import ADMIN_MESSAGES_AVATAR, ADMIN_MESSAGES_NICKNAME
from qtribu.logic.qchat_messages import (
QChatCrsMessage,
QChatGeojsonMessage,
QChatImageMessage,
QChatTextMessage,
Expand Down Expand Up @@ -238,3 +239,33 @@ def can_be_copied_to_clipboard(self) -> bool:

def copy_to_clipboard(self) -> None:
QgsApplication.instance().clipboard().setText(json.dumps(self.message.geojson))


class QChatCrsTreeWidgetItem(QChatTreeWidgetItem):
def __init__(self, parent: QTreeWidget, message: QChatCrsMessage):
super().__init__(parent, QTime.currentTime(), message.author, message.avatar)
self.message = message
self.init_time_and_author()
self.setText(MESSAGE_COLUMN, self.liked_message)
self.setToolTip(MESSAGE_COLUMN, self.liked_message)

# set foreground color if sent by user
if message.author == self.settings.author_nickname:
self.set_foreground_color(self.settings.qchat_color_self)

def on_click(self, column: int) -> None:
if column == MESSAGE_COLUMN:
# set current QGIS project CRS to the message one
crs = QgsCoordinateReferenceSystem.fromWkt(self.message.crs_wkt)
QgsProject.instance().setCrs(crs)

@property
def liked_message(self) -> str:
return f"<CRS {self.message.crs_authid}>"

@property
def can_be_copied_to_clipboard(self) -> bool:
return True

def copy_to_clipboard(self) -> None:
QgsApplication.instance().clipboard().setText(json.dumps(self.message.crs_wkt))
8 changes: 8 additions & 0 deletions qtribu/logic/qchat_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,11 @@ class QChatGeojsonMessage(QChatMessage):
crs_wkt: str
crs_authid: str
geojson: dict


@dataclass(init=True, frozen=True)
class QChatCrsMessage(QChatMessage):
author: str
avatar: Optional[str]
crs_wkt: str
crs_authid: str
5 changes: 5 additions & 0 deletions qtribu/logic/qchat_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from qgis.PyQt.QtCore import QObject, QUrl, pyqtSignal

from qtribu.constants import (
QCHAT_MESSAGE_TYPE_CRS,
QCHAT_MESSAGE_TYPE_EXITER,
QCHAT_MESSAGE_TYPE_GEOJSON,
QCHAT_MESSAGE_TYPE_IMAGE,
Expand All @@ -17,6 +18,7 @@
QCHAT_MESSAGE_TYPE_UNCOMPLIANT,
)
from qtribu.logic.qchat_messages import (
QChatCrsMessage,
QChatExiterMessage,
QChatGeojsonMessage,
QChatImageMessage,
Expand Down Expand Up @@ -69,6 +71,7 @@ def __init__(self):
exiter_message_received = pyqtSignal(QChatExiterMessage)
like_message_received = pyqtSignal(QChatLikeMessage)
geojson_message_received = pyqtSignal(QChatGeojsonMessage)
crs_message_received = pyqtSignal(QChatCrsMessage)

def open(self, qchat_instance_uri: str, room: str) -> None:
"""
Expand Down Expand Up @@ -131,3 +134,5 @@ def on_message_received(self, text: str) -> None:
self.like_message_received.emit(QChatLikeMessage(**message))
elif msg_type == QCHAT_MESSAGE_TYPE_GEOJSON:
self.geojson_message_received.emit(QChatGeojsonMessage(**message))
elif msg_type == QCHAT_MESSAGE_TYPE_CRS:
self.crs_message_received.emit(QChatCrsMessage(**message))

0 comments on commit 1876302

Please sign in to comment.