123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #!/usr/bin/env python3
-
- # OctoTray Linux Qt System Tray OctoPrint client
- #
- # SettingsWindow.py
- #
- # UI for changes to application configuration.
-
- import string
- from PyQt5 import QtWidgets
- from PyQt5.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem, QPushButton, QLineEdit, QGridLayout
- from PyQt5.QtGui import QFontDatabase, QIntValidator
- from PyQt5.QtCore import Qt
-
- class Printer(object):
- pass
-
- class SettingsWindow(QWidget):
- columns = [ "Hostname", "API Key", "Tool Preheat", "Bed Preheat" ]
- presets = [ "octopi.local", "000000000_API_KEY_HERE_000000000", "0", "0" ]
-
- def __init__(self, parent, *args, **kwargs):
- super(SettingsWindow, self).__init__(*args, **kwargs)
- self.parent = parent
-
- self.setWindowTitle(parent.name + " Settings")
- self.setWindowIcon(parent.icon)
-
- box = QVBoxLayout()
- self.setLayout(box)
-
- staticSettings = QGridLayout()
- box.addLayout(staticSettings, 0)
-
- self.jogSpeedText = QLabel("Jog Speed")
- staticSettings.addWidget(self.jogSpeedText, 0, 0)
-
- self.jogSpeed = QLineEdit(str(self.parent.jogMoveSpeed))
- self.jogSpeed.setValidator(QIntValidator(1, 6000))
- staticSettings.addWidget(self.jogSpeed, 0, 1)
-
- self.jogSpeedUnitText = QLabel("mm/min")
- staticSettings.addWidget(self.jogSpeedUnitText, 0, 2)
-
- self.jogLengthText = QLabel("Jog Length")
- staticSettings.addWidget(self.jogLengthText, 1, 0)
-
- self.jogLength = QLineEdit(str(self.parent.jogMoveLength))
- self.jogLength.setValidator(QIntValidator(1, 100))
- staticSettings.addWidget(self.jogLength, 1, 1)
-
- self.jogLengthUnitText = QLabel("mm")
- staticSettings.addWidget(self.jogLengthUnitText, 1, 2)
-
- helpText = "Usage:\n"
- helpText += "1st Column: Printer Hostname or IP address\n"
- helpText += "2nd Column: OctoPrint API Key (32 char hexadecimal)\n"
- helpText += "3rd Column: Tool Preheat Temperature (0 to disable)\n"
- helpText += "4th Column: Bed Preheat Temperature (0 to disable)"
- self.helpText = QLabel(helpText)
- box.addWidget(self.helpText, 0)
- box.setAlignment(self.helpText, Qt.AlignHCenter)
-
- buttons = QHBoxLayout()
- box.addLayout(buttons, 0)
-
- self.add = QPushButton("&Add Printer")
- self.add.clicked.connect(self.addPrinter)
- buttons.addWidget(self.add)
-
- self.remove = QPushButton("&Remove Printer")
- self.remove.clicked.connect(self.removePrinter)
- buttons.addWidget(self.remove)
-
- printers = self.parent.readSettings()
- self.rows = len(printers)
- self.table = QTableWidget(self.rows, len(self.columns))
- box.addWidget(self.table, 1)
-
- for i in range(0, self.rows):
- p = printers[i]
-
- item = QTableWidgetItem(p.host)
- self.table.setItem(i, 0, item)
-
- item = QTableWidgetItem(p.key)
- self.table.setItem(i, 1, item)
- font = item.font()
- font.setFamily(QFontDatabase.systemFont(QFontDatabase.FixedFont).family())
- item.setFont(font)
-
- if p.tempTool == None:
- item = QTableWidgetItem("0")
- else:
- item = QTableWidgetItem(p.tempTool)
- self.table.setItem(i, 2, item)
-
- if p.tempBed == None:
- item = QTableWidgetItem("0")
- else:
- item = QTableWidgetItem(p.tempBed)
- self.table.setItem(i, 3, item)
-
- buttons2 = QHBoxLayout()
- box.addLayout(buttons2, 0)
-
- self.up = QPushButton("Move &Up")
- self.up.clicked.connect(self.moveUp)
- buttons2.addWidget(self.up)
-
- self.down = QPushButton("Move &Down")
- self.down.clicked.connect(self.moveDown)
- buttons2.addWidget(self.down)
-
- self.openWeb = QPushButton("&Open Web UI of selected")
- self.openWeb.clicked.connect(self.openWebUI)
- box.addWidget(self.openWeb, 0)
-
- self.table.setHorizontalHeaderLabels(self.columns)
- self.table.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
- self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows);
- self.table.resizeColumnsToContents()
-
- if self.rows <= 0:
- self.addPrinter()
-
- def tableToList(self):
- printers = []
- for i in range(0, self.rows):
- p = Printer()
-
- p.host = self.table.item(i, 0).text()
- p.key = self.table.item(i, 1).text()
- p.tempTool = self.table.item(i, 2).text()
- p.tempBed = self.table.item(i, 3).text()
-
- if p.tempTool == "0":
- p.tempTool = None
-
- if p.tempBed == "0":
- p.tempBed = None
-
- printers.append(p)
- return printers
-
- def settingsValid(self, printers):
- for p in printers:
- # p.host needs to be valid hostname or IP
- # TODO
-
- # p.key needs to be valid API key (hexadecimal, 32 chars)
- if (len(p.key) != 32) or not all(c in string.hexdigits for c in p.key):
- return (False, "API Key not 32-digit hexadecimal")
-
- # p.tempTool and p.tempBed need to be integer temperatures (0...999)
- for s in [ p.tempTool, p.tempBed ]:
- if s == None:
- s = "0"
- if (len(s) < 1) or (len(s) > 3) or not all(c in string.digits for c in s):
- return (False, "Temperature not a number from 0...999")
-
- js = int(self.jogSpeed.text())
- if (js < 1) or (js > 6000):
- return (False, "Jog Speed not a number from 1...6000")
-
- jl = int(self.jogLength.text())
- if (jl < 1) or (jl > 100):
- return (False, "Jog Length not a number from 1...100")
-
- return (True, "")
-
- def printerDiffers(self, a, b):
- if (a.host != b.host) or (a.key != b.key) or (a.tempTool != b.tempTool) or (a.tempBed != b.tempBed):
- return True
- return False
-
- def printersDiffer(self, a, b):
- if (len(a) != len(b)):
- return True
-
- for i in range(0, len(a)):
- if self.printerDiffers(a[i], b[i]):
- return True
-
- return False
-
- def closeEvent(self, event):
- oldPrinters = self.parent.printers
- newPrinters = self.tableToList()
-
- valid, errorText = self.settingsValid(newPrinters)
- if valid == False:
- r = self.parent.showDialog(self.parent.name + " Settings Invalid", errorText + "!", "Do you want to edit it again?", True, True, False)
- if r == True:
- event.ignore()
- return
- else:
- self.parent.removeSettingsWindow()
- return
-
- js = int(self.jogSpeed.text())
- jl = int(self.jogLength.text())
-
- if self.printersDiffer(oldPrinters, newPrinters) or (js != self.parent.jogMoveSpeed) or (jl != self.parent.jogMoveLength):
- 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)
- if r == True:
- self.parent.jogMoveSpeed = js
- self.parent.jogMoveLength = jl
- self.parent.writeSettings(newPrinters)
- self.parent.restartApp()
-
- self.parent.removeSettingsWindow()
-
- def addPrinter(self):
- self.rows += 1
- self.table.setRowCount(self.rows)
- for i in range(0, len(self.columns)):
- item = QTableWidgetItem(self.presets[i])
- self.table.setItem(self.rows - 1, i, item)
- if i == 1:
- font = item.font()
- font.setFamily(QFontDatabase.systemFont(QFontDatabase.FixedFont).family())
- item.setFont(font)
- self.table.resizeColumnsToContents()
- self.table.setCurrentItem(self.table.item(self.rows - 1, 0))
-
- def removePrinter(self):
- r = self.table.currentRow()
- if (r >= 0) and (r < self.rows):
- self.rows -= 1
- self.table.removeRow(r)
- self.table.setCurrentItem(self.table.item(min(r, self.rows - 1), 0))
-
- def moveUp(self):
- i = self.table.currentRow()
- if i <= 0:
- return
- host = self.table.item(i, 0).text()
- key = self.table.item(i, 1).text()
- self.table.item(i, 0).setText(self.table.item(i - 1, 0).text())
- self.table.item(i, 1).setText(self.table.item(i - 1, 1).text())
- self.table.item(i - 1, 0).setText(host)
- self.table.item(i - 1, 1).setText(key)
- self.table.setCurrentItem(self.table.item(i - 1, 0))
-
- def moveDown(self):
- i = self.table.currentRow()
- if i >= (self.rows - 1):
- return
- host = self.table.item(i, 0).text()
- key = self.table.item(i, 1).text()
- self.table.item(i, 0).setText(self.table.item(i + 1, 0).text())
- self.table.item(i, 1).setText(self.table.item(i + 1, 1).text())
- self.table.item(i + 1, 0).setText(host)
- self.table.item(i + 1, 1).setText(key)
- self.table.setCurrentItem(self.table.item(i + 1, 0))
-
- def openWebUI(self):
- host = self.table.item(self.table.currentRow(), 0).text()
- self.parent.openBrowser(host)
|