3 Commits

Author SHA1 Message Date
  Thomas Buck de7020a3cf added ability to list and print recent files. added actions to webcam window. 2 years ago
  Thomas Buck 45c343da22 update status with every 2nd webcam image. don't allow setting 0 delay for webcam / status. 2 years ago
  Thomas Buck 3e39a38fa8 support running in window, without system tray 2 years ago
2 changed files with 315 additions and 26 deletions
  1. 3
    1
      README.md
  2. 312
    25
      src/octotray.py

+ 3
- 1
README.md View File

9
 
9
 
10
 For more [take a look at OctoTray on my website](https://www.xythobuz.de/octotray.html).
10
 For more [take a look at OctoTray on my website](https://www.xythobuz.de/octotray.html).
11
 
11
 
12
-## Building
12
+If the system tray is not available (or when passing the '-w' parameter) the main menu will instead be shown in a window.
13
+
14
+## Building / Running
13
 
15
 
14
 You have different options of building and running OctoTray:
16
 You have different options of building and running OctoTray:
15
 
17
 

+ 312
- 25
src/octotray.py View File

16
 import string
16
 import string
17
 import urllib.parse
17
 import urllib.parse
18
 import urllib.request
18
 import urllib.request
19
+import signal
20
+import operator
21
+import socket
19
 from os import path
22
 from os import path
20
 from PyQt5 import QtWidgets, QtGui, QtCore, QtNetwork
23
 from PyQt5 import QtWidgets, QtGui, QtCore, QtNetwork
21
-from PyQt5.QtWidgets import QSystemTrayIcon, QAction, QMenu, QMessageBox, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QDesktopWidget, QSizePolicy, QSlider, QLayout, QTableWidget, QTableWidgetItem, QPushButton, QApplication
22
-from PyQt5.QtGui import QIcon, QPixmap, QImageReader, QDesktopServices, QFontDatabase, QCursor
24
+from PyQt5.QtWidgets import QSystemTrayIcon, QAction, QMenu, QMessageBox, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QDesktopWidget, QSizePolicy, QSlider, QLayout, QTableWidget, QTableWidgetItem, QPushButton, QApplication, QLineEdit, QGridLayout
25
+from PyQt5.QtGui import QIcon, QPixmap, QImageReader, QDesktopServices, QFontDatabase, QCursor, QIntValidator
23
 from PyQt5.QtCore import QCoreApplication, QSettings, QUrl, QTimer, QSize, Qt, QSettings
26
 from PyQt5.QtCore import QCoreApplication, QSettings, QUrl, QTimer, QSize, Qt, QSettings
24
 
27
 
25
 class SettingsWindow(QWidget):
28
 class SettingsWindow(QWidget):
33
         self.setWindowTitle(parent.name + " Settings")
36
         self.setWindowTitle(parent.name + " Settings")
34
         self.setWindowIcon(parent.icon)
37
         self.setWindowIcon(parent.icon)
35
 
38
 
39
+
36
         box = QVBoxLayout()
40
         box = QVBoxLayout()
37
         self.setLayout(box)
41
         self.setLayout(box)
38
 
42
 
43
+        staticSettings = QGridLayout()
44
+        box.addLayout(staticSettings, 0)
45
+
46
+        self.jogSpeedText = QLabel("Jog Speed")
47
+        staticSettings.addWidget(self.jogSpeedText, 0, 0)
48
+
49
+        self.jogSpeed = QLineEdit(str(self.parent.jogMoveSpeed))
50
+        self.jogSpeed.setValidator(QIntValidator(1, 6000))
51
+        staticSettings.addWidget(self.jogSpeed, 0, 1)
52
+
53
+        self.jogSpeedUnitText = QLabel("mm/min")
54
+        staticSettings.addWidget(self.jogSpeedUnitText, 0, 2)
55
+
56
+        self.jogLengthText = QLabel("Jog Length")
57
+        staticSettings.addWidget(self.jogLengthText, 1, 0)
58
+
59
+        self.jogLength = QLineEdit(str(self.parent.jogMoveLength))
60
+        self.jogLength.setValidator(QIntValidator(1, 100))
61
+        staticSettings.addWidget(self.jogLength, 1, 1)
62
+
63
+        self.jogLengthUnitText = QLabel("mm")
64
+        staticSettings.addWidget(self.jogLengthUnitText, 1, 2)
65
+
39
         helpText = "Usage:\n"
66
         helpText = "Usage:\n"
40
         helpText += "1st Column: Printer Hostname or IP address\n"
67
         helpText += "1st Column: Printer Hostname or IP address\n"
41
         helpText += "2nd Column: OctoPrint API Key (32 char hexadecimal)\n"
68
         helpText += "2nd Column: OctoPrint API Key (32 char hexadecimal)\n"
124
                     s = "0"
151
                     s = "0"
125
                 if (len(s) < 1) or (len(s) > 3) or not all(c in string.digits for c in s):
152
                 if (len(s) < 1) or (len(s) > 3) or not all(c in string.digits for c in s):
126
                     return (False, "Temperature not a number from 0...999")
153
                     return (False, "Temperature not a number from 0...999")
154
+
155
+        js = int(self.jogSpeed.text())
156
+        if (js < 1) or (js > 6000):
157
+            return (False, "Jog Speed not a number from 1...6000")
158
+
159
+        jl = int(self.jogLength.text())
160
+        if (jl < 1) or (jl > 100):
161
+            return (False, "Jog Length not a number from 1...100")
162
+
127
         return (True, "")
163
         return (True, "")
128
 
164
 
129
     def closeEvent(self, event):
165
     def closeEvent(self, event):
140
                 self.parent.removeSettingsWindow()
176
                 self.parent.removeSettingsWindow()
141
                 return
177
                 return
142
 
178
 
143
-        if oldPrinters != newPrinters:
144
-            r = self.parent.showDialog(self.parent.name + " Settings Changed", "Do you want to save the new list of printers?", "This will restart the application!", True, False, False)
179
+        js = int(self.jogSpeed.text())
180
+        jl = int(self.jogLength.text())
181
+
182
+        if (oldPrinters != newPrinters) or (js != self.parent.jogMoveSpeed) or (jl != self.parent.jogMoveLength):
183
+            r = self.parent.showDialog(self.parent.name + " Settings Changed", "Do you want to save the new configuration?", "This will restart the application!", True, False, False)
145
             if r == True:
184
             if r == True:
185
+                self.parent.jogMoveSpeed = js
186
+                self.parent.jogMoveLength = jl
146
                 self.parent.writeSettings(newPrinters)
187
                 self.parent.writeSettings(newPrinters)
147
                 self.parent.restartApp()
188
                 self.parent.restartApp()
148
 
189
 
226
 
267
 
227
 class CamWindow(QWidget):
268
 class CamWindow(QWidget):
228
     reloadDelayDefault = 1000 # in ms
269
     reloadDelayDefault = 1000 # in ms
229
-    statusDelay = 5 * 1000 # in ms
270
+    statusDelayFactor = 2
230
     reloadOn = True
271
     reloadOn = True
231
     sliderFactor = 100
272
     sliderFactor = 100
232
 
273
 
250
         box.addWidget(label, 0)
291
         box.addWidget(label, 0)
251
         box.setAlignment(label, Qt.AlignHCenter)
292
         box.setAlignment(label, Qt.AlignHCenter)
252
 
293
 
253
-        self.img = AspectRatioPixmapLabel()
254
-        self.img.setPixmap(QPixmap(640, 480))
255
-        box.addWidget(self.img, 1)
256
-
257
         slide = QHBoxLayout()
294
         slide = QHBoxLayout()
258
         box.addLayout(slide, 0)
295
         box.addLayout(slide, 0)
259
 
296
 
297
+        self.slideStaticLabel = QLabel("Refresh")
298
+        slide.addWidget(self.slideStaticLabel, 0)
299
+
260
         self.slider = QSlider(Qt.Horizontal)
300
         self.slider = QSlider(Qt.Horizontal)
261
-        self.slider.setMinimum(int(0 / self.sliderFactor))
301
+        self.slider.setMinimum(int(100 / self.sliderFactor))
262
         self.slider.setMaximum(int(2000 / self.sliderFactor))
302
         self.slider.setMaximum(int(2000 / self.sliderFactor))
263
         self.slider.setTickInterval(int(100 / self.sliderFactor))
303
         self.slider.setTickInterval(int(100 / self.sliderFactor))
264
         self.slider.setPageStep(int(100 / self.sliderFactor))
304
         self.slider.setPageStep(int(100 / self.sliderFactor))
271
         self.slideLabel = QLabel(str(self.reloadDelayDefault) + "ms")
311
         self.slideLabel = QLabel(str(self.reloadDelayDefault) + "ms")
272
         slide.addWidget(self.slideLabel, 0)
312
         slide.addWidget(self.slideLabel, 0)
273
 
313
 
314
+        self.img = AspectRatioPixmapLabel()
315
+        self.img.setPixmap(QPixmap(640, 480))
316
+        box.addWidget(self.img, 1)
317
+
274
         self.statusLabel = QLabel("Status: unavailable")
318
         self.statusLabel = QLabel("Status: unavailable")
275
         box.addWidget(self.statusLabel, 0)
319
         box.addWidget(self.statusLabel, 0)
276
-        box.setAlignment(label, Qt.AlignHCenter)
320
+        box.setAlignment(self.statusLabel, Qt.AlignHCenter)
321
+
322
+        self.method = self.parent.getMethod(self.printer[0], self.printer[1])
323
+        if self.method != "unknown":
324
+            controls_power = QHBoxLayout()
325
+            box.addLayout(controls_power, 0)
326
+
327
+            self.turnOnButton = QPushButton("Turn O&n")
328
+            self.turnOnButton.clicked.connect(self.turnOn)
329
+            controls_power.addWidget(self.turnOnButton)
330
+
331
+            self.turnOffButton = QPushButton("Turn O&ff")
332
+            self.turnOffButton.clicked.connect(self.turnOff)
333
+            controls_power.addWidget(self.turnOffButton)
334
+
335
+        controls_temp = QHBoxLayout()
336
+        box.addLayout(controls_temp, 0)
337
+
338
+        self.cooldownButton = QPushButton("&Cooldown")
339
+        self.cooldownButton.clicked.connect(self.cooldown)
340
+        controls_temp.addWidget(self.cooldownButton)
341
+
342
+        self.preheatToolButton = QPushButton("Preheat &Tool")
343
+        self.preheatToolButton.clicked.connect(self.preheatTool)
344
+        controls_temp.addWidget(self.preheatToolButton)
345
+
346
+        self.preheatBedButton = QPushButton("Preheat &Bed")
347
+        self.preheatBedButton.clicked.connect(self.preheatBed)
348
+        controls_temp.addWidget(self.preheatBedButton)
349
+
350
+        controls_home = QHBoxLayout()
351
+        box.addLayout(controls_home, 0)
352
+
353
+        self.homeAllButton = QPushButton("Home &All")
354
+        self.homeAllButton.clicked.connect(self.homeAll)
355
+        controls_home.addWidget(self.homeAllButton, 1)
356
+
357
+        self.homeXButton = QPushButton("Home &X")
358
+        self.homeXButton.clicked.connect(self.homeX)
359
+        controls_home.addWidget(self.homeXButton, 0)
360
+
361
+        self.homeYButton = QPushButton("Home &Y")
362
+        self.homeYButton.clicked.connect(self.homeY)
363
+        controls_home.addWidget(self.homeYButton, 0)
364
+
365
+        self.homeZButton = QPushButton("Home &Z")
366
+        self.homeZButton.clicked.connect(self.homeZ)
367
+        controls_home.addWidget(self.homeZButton, 0)
368
+
369
+        controls_move = QHBoxLayout()
370
+        box.addLayout(controls_move, 0)
371
+
372
+        self.XPButton = QPushButton("X+")
373
+        self.XPButton.clicked.connect(self.moveXP)
374
+        controls_move.addWidget(self.XPButton)
375
+
376
+        self.XMButton = QPushButton("X-")
377
+        self.XMButton.clicked.connect(self.moveXM)
378
+        controls_move.addWidget(self.XMButton)
379
+
380
+        self.YPButton = QPushButton("Y+")
381
+        self.YPButton.clicked.connect(self.moveYP)
382
+        controls_move.addWidget(self.YPButton)
383
+
384
+        self.YMButton = QPushButton("Y-")
385
+        self.YMButton.clicked.connect(self.moveYM)
386
+        controls_move.addWidget(self.YMButton)
387
+
388
+        self.ZPButton = QPushButton("Z+")
389
+        self.ZPButton.clicked.connect(self.moveZP)
390
+        controls_move.addWidget(self.ZPButton)
391
+
392
+        self.ZMButton = QPushButton("Z-")
393
+        self.ZMButton.clicked.connect(self.moveZM)
394
+        controls_move.addWidget(self.ZMButton)
277
 
395
 
278
         self.loadImage()
396
         self.loadImage()
279
         self.loadStatus()
397
         self.loadStatus()
280
 
398
 
399
+    def moveXP(self):
400
+        self.parent.printerMoveAction(self.printer, "x", int(self.parent.jogMoveLength), True)
401
+
402
+    def moveXM(self):
403
+        self.parent.printerMoveAction(self.printer, "x", -1 * int(self.parent.jogMoveLength), True)
404
+
405
+    def moveYP(self):
406
+        self.parent.printerMoveAction(self.printer, "y", int(self.parent.jogMoveLength), True)
407
+
408
+    def moveYM(self):
409
+        self.parent.printerMoveAction(self.printer, "y", -1 * int(self.parent.jogMoveLength), True)
410
+
411
+    def moveZP(self):
412
+        self.parent.printerMoveAction(self.printer, "z", int(self.parent.jogMoveLength), True)
413
+
414
+    def moveZM(self):
415
+        self.parent.printerMoveAction(self.printer, "z", -1 * int(self.parent.jogMoveLength), True)
416
+
417
+    def homeX(self):
418
+        self.parent.printerHomingAction(self.printer, "x")
419
+
420
+    def homeY(self):
421
+        self.parent.printerHomingAction(self.printer, "y")
422
+
423
+    def homeZ(self):
424
+        self.parent.printerHomingAction(self.printer, "z")
425
+
426
+    def homeAll(self):
427
+        self.parent.printerHomingAction(self.printer, "xyz")
428
+
429
+    def turnOn(self):
430
+        if self.method == "psucontrol":
431
+            self.parent.printerOnAction(self.printer)
432
+        elif self.method == "system":
433
+            cmds = self.parent.getSystemCommands(self.printer[0], self.printer[1])
434
+            for cmd in cmds:
435
+                if "on" in cmd:
436
+                    self.parent.setSystemCommand(self.printer[0], self.printer[1], cmd)
437
+                    break
438
+
439
+    def turnOff(self):
440
+        if self.method == "psucontrol":
441
+            self.parent.printerOffAction(self.printer)
442
+        elif self.method == "system":
443
+            cmds = self.parent.getSystemCommands(self.printer[0], self.printer[1])
444
+            for cmd in cmds:
445
+                if "off" in cmd:
446
+                    self.parent.setSystemCommand(self.printer[0], self.printer[1], cmd)
447
+                    break
448
+
449
+    def cooldown(self):
450
+        self.parent.printerCooldown(self.printer)
451
+
452
+    def preheatTool(self):
453
+        self.parent.printerHeatTool(self.printer)
454
+
455
+    def preheatBed(self):
456
+        self.parent.printerHeatBed(self.printer)
457
+
281
     def getHost(self):
458
     def getHost(self):
282
         return self.host
459
         return self.host
283
 
460
 
295
 
472
 
296
     def scheduleLoadStatus(self):
473
     def scheduleLoadStatus(self):
297
         if self.reloadOn:
474
         if self.reloadOn:
298
-            QTimer.singleShot(self.statusDelay, self.loadStatus)
475
+            QTimer.singleShot(self.slider.value() * self.sliderFactor * self.statusDelayFactor, self.loadStatus)
299
 
476
 
300
     def loadImage(self):
477
     def loadImage(self):
301
         url = QUrl(self.url)
478
         url = QUrl(self.url)
337
             else:
514
             else:
338
                 print("Error loading image: " + reply.errorString())
515
                 print("Error loading image: " + reply.errorString())
339
 
516
 
517
+class MainWindow(QWidget):
518
+    def __init__(self, parent, *args, **kwargs):
519
+        super(MainWindow, self).__init__(*args, **kwargs)
520
+        self.parent = parent
521
+
522
+        self.mainLayout = QVBoxLayout()
523
+        self.setLayout(self.mainLayout)
524
+        self.mainLayout.addWidget(self.parent.menu)
525
+
526
+        self.parent.menu.aboutToHide.connect(self.aboutToHide)
527
+
528
+    def aboutToHide(self):
529
+        self.parent.menu.show()
530
+
531
+    def closeEvent(self, event):
532
+        self.parent.exit()
533
+        event.accept()
534
+
340
 class OctoTray():
535
 class OctoTray():
341
     name = "OctoTray"
536
     name = "OctoTray"
342
     vendor = "xythobuz"
537
     vendor = "xythobuz"
367
     camWindows = []
562
     camWindows = []
368
     settingsWindow = None
563
     settingsWindow = None
369
 
564
 
370
-    def __init__(self, app):
565
+    # default, can be overridden in config
566
+    jogMoveSpeed = 10 * 60 # in mm/min
567
+    jogMoveLength = 10 # in mm
568
+
569
+    def __init__(self, app, inSysTray):
371
         QCoreApplication.setApplicationName(self.name)
570
         QCoreApplication.setApplicationName(self.name)
372
         self.app = app
571
         self.app = app
373
-
374
-        if not QSystemTrayIcon.isSystemTrayAvailable():
375
-            self.showDialog("OctoTray Error", "System Tray is not available on this platform!", "", False, False, True)
376
-            sys.exit(0)
572
+        self.inSysTray = inSysTray
377
 
573
 
378
         self.manager = QtNetwork.QNetworkAccessManager()
574
         self.manager = QtNetwork.QNetworkAccessManager()
379
         self.menu = QMenu()
575
         self.menu = QMenu()
440
 
636
 
441
             menu.addSeparator()
637
             menu.addSeparator()
442
 
638
 
639
+            fileMenu = QMenu("Recent Files")
640
+            p.append(fileMenu)
641
+            menu.addMenu(fileMenu)
642
+
643
+            files = self.getRecentFiles(p[0], p[1], 10)
644
+            for f in files:
645
+                fileName, filePath = f
646
+                action = QAction(fileName)
647
+                action.triggered.connect(lambda chk, x=p, y=filePath: self.printerFilePrint(x, y))
648
+                p.append(action)
649
+                fileMenu.addAction(action)
650
+
443
             action = QAction("Get Status")
651
             action = QAction("Get Status")
444
             action.triggered.connect(lambda chk, x=p: self.printerStatusAction(x))
652
             action.triggered.connect(lambda chk, x=p: self.printerStatusAction(x))
445
             p.append(action)
653
             p.append(action)
483
         self.pic.load(self.iconPathName)
691
         self.pic.load(self.iconPathName)
484
         self.icon = QIcon(self.pic)
692
         self.icon = QIcon(self.pic)
485
 
693
 
486
-        self.trayIcon = QSystemTrayIcon(self.icon)
487
-        self.trayIcon.setToolTip(self.name + " " + self.version)
488
-        self.trayIcon.setContextMenu(self.menu)
489
-        self.trayIcon.activated.connect(self.showHide)
490
-        self.trayIcon.setVisible(True)
694
+        if self.inSysTray:
695
+            self.trayIcon = QSystemTrayIcon(self.icon)
696
+            self.trayIcon.setToolTip(self.name + " " + self.version)
697
+            self.trayIcon.setContextMenu(self.menu)
698
+            self.trayIcon.activated.connect(self.showHide)
699
+            self.trayIcon.setVisible(True)
700
+        else:
701
+            self.mainWindow = MainWindow(self)
702
+            self.mainWindow.show()
703
+            self.mainWindow.activateWindow()
704
+            screenGeometry = QDesktopWidget().screenGeometry()
705
+            x = (screenGeometry.width() - self.mainWindow.width()) / 2
706
+            y = (screenGeometry.height() - self.mainWindow.height()) / 2
707
+            x += screenGeometry.x()
708
+            y += screenGeometry.y()
709
+            self.mainWindow.setGeometry(int(x), int(y), int(self.mainWindow.width()), int(self.mainWindow.height()))
491
 
710
 
492
     def showHide(self, activationReason):
711
     def showHide(self, activationReason):
493
         if activationReason == QSystemTrayIcon.Trigger:
712
         if activationReason == QSystemTrayIcon.Trigger:
494
             self.menu.popup(QCursor.pos())
713
             self.menu.popup(QCursor.pos())
714
+        elif activationReason == QSystemTrayIcon.MiddleClick:
715
+            if len(self.printers) > 0:
716
+                self.printerWebcamAction(self.printers[0])
495
 
717
 
496
     def readSettings(self):
718
     def readSettings(self):
497
         settings = QSettings(self.vendor, self.name)
719
         settings = QSettings(self.vendor, self.name)
720
+
721
+        js = settings.value("jog_speed")
722
+        if js != None:
723
+            self.jogMoveSpeed = int(js)
724
+
725
+        jl = settings.value("jog_length")
726
+        if jl != None:
727
+            self.jogMoveLength = int(jl)
728
+
498
         printers = []
729
         printers = []
499
         l = settings.beginReadArray("printers")
730
         l = settings.beginReadArray("printers")
500
         for i in range(0, l):
731
         for i in range(0, l):
510
 
741
 
511
     def writeSettings(self, printers):
742
     def writeSettings(self, printers):
512
         settings = QSettings(self.vendor, self.name)
743
         settings = QSettings(self.vendor, self.name)
744
+
745
+        settings.setValue("jog_speed", self.jogMoveSpeed)
746
+        settings.setValue("jog_length", self.jogMoveLength)
747
+
513
         settings.remove("printers")
748
         settings.remove("printers")
514
         settings.beginWriteArray("printers")
749
         settings.beginWriteArray("printers")
515
         for i in range(0, len(printers)):
750
         for i in range(0, len(printers)):
677
             pass
912
             pass
678
         return host
913
         return host
679
 
914
 
915
+    def getRecentFiles(self, host, key, count):
916
+        r = self.sendGetRequest(host, key, "files?recursive=true")
917
+        files = []
918
+        try:
919
+            rd = json.loads(r)
920
+            if "files" in rd:
921
+                t = [f for f in rd["files"] if "date" in f]
922
+                fs = sorted(t, key=operator.itemgetter("date"), reverse=True)
923
+                for f in fs[:count]:
924
+                    files.append((f["name"], f["origin"] + "/" + f["path"]))
925
+        except json.JSONDecodeError:
926
+            pass
927
+        return files
928
+
680
     def getMethod(self, host, key):
929
     def getMethod(self, host, key):
681
         r = self.sendGetRequest(host, key, "plugin/psucontrol")
930
         r = self.sendGetRequest(host, key, "plugin/psucontrol")
682
         if r == "timeout":
931
         if r == "timeout":
766
 
1015
 
767
         self.setPSUControl(item[0], item[1], False)
1016
         self.setPSUControl(item[0], item[1], False)
768
 
1017
 
1018
+    def printerHomingAction(self, item, axes = "xyz"):
1019
+        state = self.getState(item[0], item[1])
1020
+        if state in self.statesWithWarning:
1021
+            if self.showDialog("OctoTray Warning", "The printer seems to be running currently!", "Do you really want to home it?", True, True) == False:
1022
+                return
1023
+
1024
+        axes_string = ''
1025
+        for i in range(0, len(axes)):
1026
+            axes_string += '"' + str(axes[i]) + '"'
1027
+            if i < (len(axes) - 1):
1028
+                axes_string += ', '
1029
+
1030
+        self.sendPostRequest(item[0], item[1], "printer/printhead", '{ "command": "home", "axes": [' + axes_string + '] }')
1031
+
1032
+    def printerMoveAction(self, printer, axis, dist, relative = True):
1033
+        state = self.getState(printer[0], printer[1])
1034
+        if state in self.statesWithWarning:
1035
+            if self.showDialog("OctoTray Warning", "The printer seems to be running currently!", "Do you really want to move it?", True, True) == False:
1036
+                return
1037
+
1038
+        absolute = ''
1039
+        if relative == False:
1040
+            absolute = ', "absolute": true'
1041
+
1042
+        self.sendPostRequest(printer[0], printer[1], "printer/printhead", '{ "command": "jog", "' + str(axis) + '": ' + str(dist) + ', "speed": ' + str(self.jogMoveSpeed) + absolute + ' }')
1043
+
769
     def printerWebAction(self, item):
1044
     def printerWebAction(self, item):
770
         self.openBrowser(item[0])
1045
         self.openBrowser(item[0])
771
 
1046
 
787
             s += "\n" + t
1062
             s += "\n" + t
788
         self.showDialog("OctoTray Status", s, None, False, warning)
1063
         self.showDialog("OctoTray Status", s, None, False, warning)
789
 
1064
 
1065
+    def printerFilePrint(self, item, path):
1066
+        self.sendPostRequest(item[0], item[1], "files/" + path, '{ "command": "select", "print": true }')
1067
+
790
     def setTemperature(self, host, key, what, temp):
1068
     def setTemperature(self, host, key, what, temp):
791
         path = "printer/bed"
1069
         path = "printer/bed"
792
         s = "{\"command\": \"target\", \"target\": " + temp + "}"
1070
         s = "{\"command\": \"target\", \"target\": " + temp + "}"
868
         if self.settingsWindow != None:
1146
         if self.settingsWindow != None:
869
             self.settingsWindow.close()
1147
             self.settingsWindow.close()
870
 
1148
 
871
-        self.trayIcon.setVisible(False)
1149
+        if self.inSysTray:
1150
+            self.trayIcon.setVisible(False)
1151
+        else:
1152
+            self.mainWindow.setVisible(False)
872
 
1153
 
873
 if __name__ == "__main__":
1154
 if __name__ == "__main__":
874
     app = QApplication(sys.argv)
1155
     app = QApplication(sys.argv)
875
     app.setQuitOnLastWindowClosed(False)
1156
     app.setQuitOnLastWindowClosed(False)
876
 
1157
 
877
-    tray = OctoTray(app)
1158
+    signal.signal(signal.SIGINT, signal.SIG_DFL)
1159
+
1160
+    inSysTray = QSystemTrayIcon.isSystemTrayAvailable()
1161
+    if ("windowed" in sys.argv) or ("--windowed" in sys.argv) or ("-w" in sys.argv):
1162
+        inSysTray = False
1163
+
1164
+    tray = OctoTray(app, inSysTray)
878
     rc = app.exec_()
1165
     rc = app.exec_()
879
 
1166
 
880
     while rc == 42:
1167
     while rc == 42:
881
         tray.closeAll()
1168
         tray.closeAll()
882
-        tray = OctoTray(app)
1169
+        tray = OctoTray(app, inSysTray)
883
         rc = app.exec_()
1170
         rc = app.exec_()
884
 
1171
 
885
     sys.exit(rc)
1172
     sys.exit(rc)

Loading…
Cancel
Save