From 0e306df1bcc0c0e6126530a28a498073be85898c Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 2 Feb 2017 15:59:09 +0100 Subject: [PATCH] Initial basic version of this feature. CURA-3335 --- cura/CuraApplication.py | 35 +++++++++++++++++++++++++++++++++++ cura_app.py | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index df3f44c14f..7b566c17ac 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1,5 +1,9 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. +import json + +from PyQt5.QtCore import QTextStream +from PyQt5.QtNetwork import QLocalServer from UM.Qt.QtApplication import QtApplication from UM.Scene.SceneNode import SceneNode @@ -420,13 +424,44 @@ class CuraApplication(QtApplication): self._plugins_loaded = True + @classmethod def addCommandLineOptions(self, parser): super().addCommandLineOptions(parser) parser.add_argument("file", nargs="*", help="Files to load after starting the application.") + parser.add_argument("--single-instance", action="store_true", default=False) + + def _setUpSingleInstanceServer(self): + if self.getCommandLineOption("single_instance", False): + self.__single_instance_server = QLocalServer() + self.__single_instance_server.newConnection.connect(self._singleInstanceServerNewConnection) + self.__single_instance_server.listen("ultimaker-cura") + + def _singleInstanceServerNewConnection(self): + Logger.log('d', 'Saw something on the single instance server') + other_cura_connection = self.__single_instance_server.nextPendingConnection() + if other_cura_connection is not None: + def readyRead(): + while other_cura_connection.canReadLine(): + line = other_cura_connection.readLine() + payload = json.loads(str(line, encoding="ASCII").strip()) + command = payload["command"] + if command == "clear-all": + self.deleteAll() + + elif command == "open": + self.deleteAll() + self._openFile(payload["filePath"]) + + elif command == "focus": + self.focusWindow() + + other_cura_connection.readyRead.connect(readyRead) def run(self): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene...")) + self._setUpSingleInstanceServer() + controller = self.getController() controller.setActiveView("SolidView") diff --git a/cura_app.py b/cura_app.py index 5c3ea811b5..c2ee6a72b1 100755 --- a/cura_app.py +++ b/cura_app.py @@ -2,11 +2,14 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. - +import argparse +import json import os import sys import platform +import time +from PyQt5.QtNetwork import QLocalSocket from UM.Platform import Platform #WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 @@ -58,5 +61,36 @@ if Platform.isWindows() and hasattr(sys, "frozen"): # Force an instance of CuraContainerRegistry to be created and reused later. cura.Settings.CuraContainerRegistry.getInstance() +# Peek the arguments and look for the 'single-instance' flag. +parser = argparse.ArgumentParser(prog="cura") # pylint: disable=bad-whitespace +cura.CuraApplication.CuraApplication.addCommandLineOptions(parser) +parsed_command_line = vars(parser.parse_args()) + +if "single_instance" in parsed_command_line and parsed_command_line["single_instance"]: + print("Check for single instance") + single_instance_socket = QLocalSocket() + single_instance_socket.connectToServer("ultimaker-cura") + single_instance_socket.waitForConnected() + if single_instance_socket.state() == QLocalSocket.ConnectedState: + print("Connected to the other Cura instance.") + print(repr(parsed_command_line)) + + payload = {"command": "clear-all"} + single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII")) + + payload = {"command": "focus"} + single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII")) + + if len(parsed_command_line["file"]) != 0: + for filename in parsed_command_line["file"]: + payload = { "command": "open", "filePath": filename } + single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII")) + + single_instance_socket.flush() + + + single_instance_socket.close() + sys.exit(0) + app = cura.CuraApplication.CuraApplication.getInstance() app.run()