Skip to content

Commit

Permalink
Merge pull request #18253 from Ultimaker/CURA-11596-open-url-singlein…
Browse files Browse the repository at this point in the history
…stance

Cura 11596 open url singleinstance
  • Loading branch information
casperlamboo authored Feb 8, 2024
2 parents a991177 + 84ecf8e commit 8b8d519
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
7 changes: 5 additions & 2 deletions cura/CuraApplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def __init__(self, *args, **kwargs):

# Variables set from CLI
self._files_to_open = []
self._urls_to_open = []
self._use_single_instance = False

self._single_instance = None
Expand Down Expand Up @@ -334,7 +335,7 @@ def parseCliOptions(self):
for filename in self._cli_args.file:
url = QUrl(filename)
if url.scheme() in self._supported_url_schemes:
self._open_url_queue.append(url)
self._urls_to_open.append(url)
else:
self._files_to_open.append(os.path.abspath(filename))

Expand All @@ -357,7 +358,7 @@ def initialize(self) -> None:
self._machine_action_manager.initialize()

def __sendCommandToSingleInstance(self):
self._single_instance = SingleInstance(self, self._files_to_open)
self._single_instance = SingleInstance(self, self._files_to_open, self._urls_to_open)

# If we use single instance, try to connect to the single instance server, send commands, and then exit.
# If we cannot find an existing single instance server, this is the only instance, so just keep going.
Expand Down Expand Up @@ -963,6 +964,8 @@ def _onPostStart(self):
self.callLater(self._openFile, file_name)
for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading.
self.callLater(self._openFile, file_name)
for url in self._urls_to_open:
self.callLater(self._openUrl, url)
for url in self._open_url_queue:
self.callLater(self._openUrl, url)

Expand Down
26 changes: 19 additions & 7 deletions cura/SingleInstance.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
import os
from typing import List, Optional

from PyQt6.QtCore import QUrl
from PyQt6.QtNetwork import QLocalServer, QLocalSocket

from UM.Qt.QtApplication import QtApplication #For typing.
from UM.Qt.QtApplication import QtApplication # For typing.
from UM.Logger import Logger


class SingleInstance:
def __init__(self, application: QtApplication, files_to_open: Optional[List[str]]) -> None:
def __init__(self, application: QtApplication, files_to_open: Optional[List[str]], url_to_open: Optional[List[str]]) -> None:
self._application = application
self._files_to_open = files_to_open
self._url_to_open = url_to_open

self._single_instance_server = None

Expand All @@ -33,7 +35,7 @@ def startClient(self) -> bool:
return False

# We only send the files that need to be opened.
if not self._files_to_open:
if not self._files_to_open and not self._url_to_open:
Logger.log("i", "No file need to be opened, do nothing.")
return True

Expand All @@ -55,8 +57,12 @@ def startClient(self) -> bool:
payload = {"command": "open", "filePath": os.path.abspath(filename)}
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))

for url in self._url_to_open:
payload = {"command": "open-url", "urlPath": url.toString()}
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ascii"))

payload = {"command": "close-connection"}
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ascii"))

single_instance_socket.flush()
single_instance_socket.waitForDisconnected()
Expand All @@ -72,7 +78,7 @@ def startServer(self) -> None:

def _onClientConnected(self) -> None:
Logger.log("i", "New connection received on our single-instance server")
connection = None #type: Optional[QLocalSocket]
connection = None # type: Optional[QLocalSocket]
if self._single_instance_server:
connection = self._single_instance_server.nextPendingConnection()

Expand All @@ -81,7 +87,7 @@ def _onClientConnected(self) -> None:

def __readCommands(self, connection: QLocalSocket) -> None:
line = connection.readLine()
while len(line) != 0: # There is also a .canReadLine()
while len(line) != 0: # There is also a .canReadLine()
try:
payload = json.loads(str(line, encoding = "ascii").strip())
command = payload["command"]
Expand All @@ -94,13 +100,19 @@ def __readCommands(self, connection: QLocalSocket) -> None:
elif command == "open":
self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f))

#command: Load a url link in Cura
elif command == "open-url":
url = QUrl(payload["urlPath"])
self._application.callLater(lambda: self._application._openUrl(url))


# Command: Activate the window and bring it to the top.
elif command == "focus":
# Operating systems these days prevent windows from moving around by themselves.
# 'alert' or flashing the icon in the taskbar is the best thing we do now.
main_window = self._application.getMainWindow()
if main_window is not None:
self._application.callLater(lambda: main_window.alert(0)) # type: ignore # I don't know why MyPy complains here
self._application.callLater(lambda: main_window.alert(0)) # type: ignore # I don't know why MyPy complains here

# Command: Close the socket connection. We're done.
elif command == "close-connection":
Expand Down
2 changes: 2 additions & 0 deletions resources/qml/Preferences/GeneralPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ UM.PreferencesPage
UM.TooltipArea
{
width: childrenRect.width
// Mac only allows applications to run as a single instance, so providing the option for this os doesn't make much sense
visible: Qt.platform.os !== "osx"
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","Should opening files from the desktop or external applications open in the same instance of Cura?")

Expand Down

0 comments on commit 8b8d519

Please sign in to comment.