Browse Source

Settings now stored in QtSettings. Added settings window. Re-starts on config changes. Allow running with empty config. Fixed windows not being centered and having the wrong size after opening.

Thomas Buck 3 years ago
parent
commit
3c2b46da95
2 changed files with 171 additions and 41 deletions
  1. 0
    1
      README.md
  2. 171
    40
      octotray

+ 0
- 1
README.md View File

@@ -12,4 +12,3 @@ Or on all other linux distros:
12 12
 	sudo cp de.xythobuz.octotray.desktop /usr/share/applications/de.xythobuz.octotray.desktop
13 13
 
14 14
 Then run it from your desktop environment menu or even add it to the autostart there.
15
-

+ 171
- 40
octotray View File

@@ -16,9 +16,74 @@ import time
16 16
 import urllib.parse
17 17
 import urllib.request
18 18
 from PyQt5 import QtWidgets, QtGui, QtCore, QtNetwork
19
-from PyQt5.QtWidgets import QSystemTrayIcon, QAction, QMenu, QMessageBox, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QDesktopWidget, QSizePolicy, QSlider, QLayout
19
+from PyQt5.QtWidgets import QSystemTrayIcon, QAction, QMenu, QMessageBox, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QDesktopWidget, QSizePolicy, QSlider, QLayout, QTableWidget, QTableWidgetItem, QPushButton
20 20
 from PyQt5.QtGui import QIcon, QPixmap, QImageReader, QDesktopServices
21
-from PyQt5.QtCore import QCoreApplication, QSettings, QUrl, QTimer, QSize, Qt
21
+from PyQt5.QtCore import QCoreApplication, QSettings, QUrl, QTimer, QSize, Qt, QSettings
22
+
23
+class SettingsWindow(QWidget):
24
+    def __init__(self, parent, *args, **kwargs):
25
+        super(SettingsWindow, self).__init__(*args, **kwargs)
26
+        self.parent = parent
27
+
28
+        self.setWindowTitle(parent.name + " Settings")
29
+        self.setWindowIcon(parent.icon)
30
+
31
+        box = QVBoxLayout()
32
+        self.setLayout(box)
33
+
34
+        buttons = QHBoxLayout()
35
+        box.addLayout(buttons, 0)
36
+
37
+        self.add = QPushButton("&Add Printer")
38
+        self.add.clicked.connect(self.addPrinter)
39
+        buttons.addWidget(self.add)
40
+
41
+        self.remove = QPushButton("&Remove Printer")
42
+        self.remove.clicked.connect(self.removePrinter)
43
+        buttons.addWidget(self.remove)
44
+
45
+        printers = self.parent.readSettings()
46
+        self.rows = len(printers)
47
+        self.table = QTableWidget(self.rows, 2)
48
+        box.addWidget(self.table, 1)
49
+
50
+        for i in range(0, self.rows):
51
+            p = printers[i]
52
+            for j in range(0, 2):
53
+                item = QTableWidgetItem(p[j])
54
+                self.table.setItem(i, j, item)
55
+
56
+        self.table.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
57
+        self.table.resizeColumnsToContents()
58
+
59
+    def tableToList(self):
60
+        printers = []
61
+        for i in range(0, self.rows):
62
+            p = [self.table.item(i, 0).text(), self.table.item(i, 1).text()]
63
+            printers.append(p)
64
+        return printers
65
+
66
+    def closeEvent(self, event):
67
+        oldPrinters = [item[0:2] for item in self.parent.printers]
68
+        newPrinters = self.tableToList()
69
+        if oldPrinters != newPrinters:
70
+            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)
71
+            if r == True:
72
+                self.parent.writeSettings(newPrinters)
73
+                QCoreApplication.exit(42)
74
+        self.parent.removeSettingsWindow()
75
+
76
+    def addPrinter(self):
77
+        self.rows += 1
78
+        self.table.setRowCount(self.rows)
79
+        self.table.setItem(self.rows - 1, 0, QTableWidgetItem("HOSTNAME"))
80
+        self.table.setItem(self.rows - 1, 1, QTableWidgetItem("API_KEY"))
81
+
82
+    def removePrinter(self):
83
+        r = self.table.currentRow()
84
+        if (r >= 0) and (r < self.rows):
85
+            self.rows -= 1
86
+            self.table.removeRow(r)
22 87
 
23 88
 class AspectRatioPixmapLabel(QLabel):
24 89
     def __init__(self, *args, **kwargs):
@@ -54,18 +119,18 @@ class CamWindow(QWidget):
54 119
     addSize = 100
55 120
     reloadOn = True
56 121
 
57
-    def __init__(self, parent, name, icon, app, manager, printer, *args, **kwargs):
122
+    def __init__(self, parent, printer, *args, **kwargs):
58 123
         super(CamWindow, self).__init__(*args, **kwargs)
59
-        self.app = app
60
-        self.manager = manager
124
+        self.app = parent.app
125
+        self.manager = parent.manager
61 126
         self.manager.finished.connect(self.handleResponse)
62 127
         self.parent = parent
63 128
         self.printer = printer
64 129
         self.host = self.printer[0]
65 130
         self.url = "http://" + self.host + ":8080/?action=snapshot"
66 131
 
67
-        self.setWindowTitle(name + " Webcam Stream")
68
-        self.setWindowIcon(icon)
132
+        self.setWindowTitle(parent.name + " Webcam Stream")
133
+        self.setWindowIcon(parent.icon)
69 134
 
70 135
         box = QVBoxLayout()
71 136
         self.setLayout(box)
@@ -173,21 +238,22 @@ class OctoTray():
173 238
     iconPath = "/usr/share/pixmaps/"
174 239
     iconName = "octotray_icon.png"
175 240
 
176
-    # 0=host, 1=key
177
-    # (2=system-commands, 3=menu, 4...=actions)
178
-    printers = [
179
-        [ "PRINTER_HOST_HERE", "PRINTER_API_KEY_HERE" ]
180
-    ]
241
+    networkTimeout = 2.0 # in s
242
+
243
+    # list of lists, inner lists contain printer data:
244
+    # 0=host 1=key (2=system-commands 3=menu 4+=actions)
245
+    printers = []
181 246
     
182 247
     statesWithWarning = [
183 248
         "Printing", "Pausing", "Paused"
184 249
     ]
185 250
 
186 251
     camWindows = []
252
+    settingsWindow = None
187 253
 
188
-    def __init__(self):
189
-        self.app = QtWidgets.QApplication(sys.argv)
254
+    def __init__(self, app):
190 255
         QCoreApplication.setApplicationName(self.name)
256
+        self.app = app
191 257
 
192 258
         if not QSystemTrayIcon.isSystemTrayAvailable():
193 259
             self.showDialog("OctoTray Error", "System Tray is not available on this platform!", "", False, False, True)
@@ -195,6 +261,7 @@ class OctoTray():
195 261
 
196 262
         self.manager = QtNetwork.QNetworkAccessManager()
197 263
         self.menu = QMenu()
264
+        self.printers = self.readSettings()
198 265
 
199 266
         unknownCount = 0
200 267
         for p in self.printers:
@@ -243,34 +310,57 @@ class OctoTray():
243 310
             p.append(action)
244 311
             menu.addAction(action)
245 312
 
246
-        if (len(self.printers) <= 0) or (unknownCount >= len(self.printers)):
247
-            self.showDialog("OctoTray Error", "No printers available!", "", False, False, True)
248
-            sys.exit(0)
313
+        self.settingsAction = QAction("&Settings")
314
+        self.settingsAction.triggered.connect(self.showSettingsAction)
315
+        self.menu.addAction(self.settingsAction)
249 316
 
250 317
         self.quitAction = QAction("&Quit")
251 318
         self.quitAction.triggered.connect(self.exit)
252 319
         self.menu.addAction(self.quitAction)
253 320
 
254
-        iconPathName = ""
321
+        self.iconPathName = ""
255 322
         if os.path.isfile(self.iconName):
256
-            iconPathName = self.iconName
323
+            self.iconPathName = self.iconName
257 324
         elif os.path.isfile(self.iconPath + self.iconName):
258
-            iconPathName = self.iconPath + self.iconName
325
+            self.iconPathName = self.iconPath + self.iconName
259 326
         else:
260 327
             self.showDialog("OctoTray Error", "Icon file has not been found! found", "", False, False, True)
261 328
             sys.exit(0)
262 329
 
263 330
         self.icon = QIcon()
264
-        pic = QPixmap(32, 32)
265
-        pic.load(iconPathName)
266
-        self.icon = QIcon(pic)
267
-
268
-        trayIcon = QSystemTrayIcon(self.icon)
269
-        trayIcon.setToolTip(self.name + " " + self.version)
270
-        trayIcon.setContextMenu(self.menu)
271
-        trayIcon.setVisible(True)
272
-
273
-        sys.exit(self.app.exec_())
331
+        self.pic = QPixmap(32, 32)
332
+        self.pic.load(self.iconPathName)
333
+        self.icon = QIcon(self.pic)
334
+
335
+        self.trayIcon = QSystemTrayIcon(self.icon)
336
+        self.trayIcon.setToolTip(self.name + " " + self.version)
337
+        self.trayIcon.setContextMenu(self.menu)
338
+        self.trayIcon.setVisible(True)
339
+
340
+    def readSettings(self):
341
+        settings = QSettings(self.vendor, self.name)
342
+        printers = []
343
+        l = settings.beginReadArray("printers")
344
+        for i in range(0, l):
345
+            settings.setArrayIndex(i)
346
+            p = []
347
+            p.append(settings.value("host"))
348
+            p.append(settings.value("key"))
349
+            printers.append(p)
350
+        settings.endArray()
351
+        return printers
352
+
353
+    def writeSettings(self, printers):
354
+        settings = QSettings(self.vendor, self.name)
355
+        settings.remove("printers")
356
+        settings.beginWriteArray("printers")
357
+        for i in range(0, len(printers)):
358
+            p = printers[i]
359
+            settings.setArrayIndex(i)
360
+            settings.setValue("host", p[0])
361
+            settings.setValue("key", p[1])
362
+        settings.endArray()
363
+        del settings
274 364
 
275 365
     def openBrowser(self, url):
276 366
         QDesktopServices.openUrl(QUrl("http://" + url))
@@ -312,9 +402,11 @@ class OctoTray():
312 402
             data = content.encode('ascii')
313 403
             request = urllib.request.Request(url, data, headers)
314 404
         try:
315
-            with urllib.request.urlopen(request, None, 1.0) as response:
405
+            with urllib.request.urlopen(request, None, self.networkTimeout) as response:
316 406
                 text = response.read()
317 407
                 return text
408
+        except urllib.error.URLError:
409
+            pass
318 410
         except urllib.error.HTTPError:
319 411
             pass
320 412
         return ""
@@ -508,21 +600,60 @@ class OctoTray():
508 600
                 cw.activateWindow()
509 601
                 return
510 602
 
511
-        window = CamWindow(self, self.name, self.icon, self.app, self.manager, item)
603
+        window = CamWindow(self, item)
512 604
         self.camWindows.append(window)
513 605
 
514
-        screenGeometry = QDesktopWidget().screenGeometry()
515
-        width = screenGeometry.width()
516
-        height = screenGeometry.height()
517
-        x = (width - window.width()) / 2
518
-        y = (height - window.height()) / 2
519
-        window.setGeometry(int(x), int(y), int(window.width()), int(window.height()))
520
-
521 606
         window.show()
522 607
         window.activateWindow()
523 608
 
609
+        screenGeometry = QDesktopWidget().screenGeometry()
610
+        x = (screenGeometry.width() - window.width()) / 2
611
+        y = (screenGeometry.height() - window.height()) / 2
612
+        x += screenGeometry.x()
613
+        y += screenGeometry.y()
614
+        window.setGeometry(int(x), int(y), int(window.width()), int(window.height()))
615
+
524 616
     def removeWebcamWindow(self, window):
525 617
         self.camWindows.remove(window)
526 618
 
619
+    def showSettingsAction(self):
620
+        if self.settingsWindow != None:
621
+            self.settingsWindow.show()
622
+            self.settingsWindow.activateWindow()
623
+            return
624
+
625
+        self.settingsWindow = SettingsWindow(self)
626
+        self.settingsWindow.show()
627
+        self.settingsWindow.activateWindow()
628
+
629
+        screenGeometry = QDesktopWidget().screenGeometry()
630
+        x = (screenGeometry.width() - self.settingsWindow.width()) / 2
631
+        y = (screenGeometry.height() - self.settingsWindow.height()) / 2
632
+        x += screenGeometry.x()
633
+        y += screenGeometry.y()
634
+        self.settingsWindow.setGeometry(int(x), int(y), int(self.settingsWindow.width()), int(self.settingsWindow.height()))
635
+
636
+    def removeSettingsWindow(self):
637
+        self.settingsWindow = None
638
+
639
+    def closeAll(self):
640
+        for cw in self.camWindows:
641
+            cw.close()
642
+
643
+        if self.settingsWindow != None:
644
+            self.settingsWindow.close()
645
+
646
+        self.trayIcon.setVisible(False)
647
+
527 648
 if __name__ == "__main__":
528
-    tray = OctoTray()
649
+    app = QtWidgets.QApplication(sys.argv)
650
+
651
+    tray = OctoTray(app)
652
+    rc = app.exec_()
653
+
654
+    while rc == 42:
655
+        tray.closeAll()
656
+        tray = OctoTray(app)
657
+        rc = app.exec_()
658
+
659
+    sys.exit(rc)

Loading…
Cancel
Save