diff --git a/SettingsUi.py b/SettingsUi.py new file mode 100644 index 0000000..c0bf689 --- /dev/null +++ b/SettingsUi.py @@ -0,0 +1,221 @@ +import os +import shlex +from datetime import datetime +from subprocess import call + +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + + +class Form(): + def __init__(self, window, page, devices): + self.devices = devices + self.window = window + + self.infoLabel = Gtk.Label("This action may require root privileges") + + self.deviceCombo = Gtk.ComboBoxText() + self.deviceCombo.set_entry_text_column(0) + self.deviceCombo.connect("changed", self.deviceComboChanged) + for name, device in devices.items(): + self.deviceCombo.append_text(name) + self.lineDevice = line("Device:", self.deviceCombo) + + self.modeCombo = Gtk.ComboBoxText() + self.modeCombo.set_entry_text_column(0) + self.lineMode = line("Mode:", self.modeCombo) + + clockModes = ["default", "local", "UTC"] + self.clockCombo = Gtk.ComboBoxText() + self.clockCombo.set_entry_text_column(0) + for mode in clockModes: + self.clockCombo.append_text(mode) + self.clockCombo.set_active(0) + self.lineClock = line("RTC clock:", self.clockCombo) + + self.dateEntry = Gtk.Entry(placeholder_text="HH:MM mm/dd/YYYY") + self.dateEntry.set_alignment(1) + + self.dateCal = Gtk.Button.new_with_label("CAL") + self.dateCal.connect("clicked", self.onDateEntryClick) + + self.dateBox = Gtk.Box(spacing=4) + self.pack(self.dateBox, self.dateEntry) + self.pack(self.dateBox, self.dateCal) + + self.lineDate = line("Date:", self.dateBox) + + createButton = Gtk.Button.new_with_label("Create") + createButton.connect("clicked", self.onCreateButtonClick) + + self.pack(page, self.infoLabel) + self.pack(page, self.lineDevice.box) + self.pack(page, self.lineMode.box) + self.pack(page, self.lineClock.box) + self.pack(page, self.lineDate.box) + self.pack(page, createButton) + + def deviceComboChanged(self, combo): + text = combo.get_active_text() + if text != None: + self.setModes(text) + + def onDateEntryClick(self, button): + dialog = DateDialog(self.window) + response = dialog.run() + cal = {} + + if response == Gtk.ResponseType.OK: + calendar = dialog.calendar.get_date() + cal["day"] = str(calendar.day) + cal["month"] = str(calendar.month + 1) + cal["year"] = str(calendar.year) + + if len(cal["day"]) < 2: + cal["day"] = "0" + cal["day"] + if len(cal["month"]) < 2: + cal["month"] = "0" + cal["month"] + + hour = str(dialog.hoursButton.get_value_as_int()) + minute = str(dialog.minutesButton.get_value_as_int()) + + if len(hour) < 2: + hour = "0" + hour + if len(minute) < 2: + minute = "0" + minute + + date = hour + ":" + minute + " " + cal["month"] + "/" + cal["day"] + "/" + cal["year"] + self.dateEntry.set_text(date) + + elif response == Gtk.ResponseType.CANCEL: + print("The Cancel button was clicked") + + dialog.destroy() + + def onCreateButtonClick(self, button): + device = self.deviceCombo.get_active_text() + mode = self.modeCombo.get_active_text() + clock = self.clockCombo.get_active_text() + dateText = self.dateEntry.get_text() + + message = "" + error = False + + if device == None: + error = True + message += "Select device" + if mode == None: + if error: + message += "\n" + else: + error = True + message += "Select mode" + if len(dateText) > 0: + now = datetime.now() + + date = datetime.strptime(dateText, "%H:%M %m/%d/%Y") + time = int(date.timestamp()) + + if now.timestamp() >= time: + if error: + message += "\n" + else: + error = True + message += "Date can't be set to the past" + else: + if error: + message += "\n" + else: + error = True + message += "Select date" + + if len(message) > 0 and error: + dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.INFO, + Gtk.ButtonsType.OK, "Wrong settings") + dialog.format_secondary_text(message) + dialog.run() + dialog.destroy() + else: + times = { + "default" : "-a", + "local" : "-l", + "UTC" : "-u" + } + + cmd = "rtcwake " + times[clock] + " -m " + mode + " -d " + device + " -t " + str(time) + call(shlex.split(cmd)) + + + def setModes(self, device): + self.modeCombo.remove_all() + + for mode in self.devices[device].modes: + self.modeCombo.append_text(mode) + + def pack(self, page, box): + page.pack_start(box, False, True, 0) + +class DateDialog(Gtk.Dialog): + def __init__(self, parent): + Gtk.Dialog.__init__(self, "Select date and time", parent, 0, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OK, Gtk.ResponseType.OK), resizable=False) + + self.set_default_size(150, 100) + + box = self.get_content_area() + box.set_spacing(5) + + labelDate = Gtk.Label("Date") + self.pack(box, labelDate) + + self.calendar = Gtk.Calendar() + self.pack(box, self.calendar) + + labelTime = Gtk.Label("Time") + self.pack(box, labelTime) + + self.hbox = Gtk.Box(spacing=5) + + now = datetime.now() + + adjustmentHours = Gtk.Adjustment(0, 0, 23, 1, 10, 0) + self.hoursButton = Gtk.SpinButton() + self.hoursButton.set_numeric(True) + self.hoursButton.set_adjustment(adjustmentHours) + self.hoursButton.set_value(float(now.hour)) + + self.hrbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL ,spacing=5) + self.pack(self.hrbox, Gtk.Label("Hour")) + self.pack(self.hrbox, self.hoursButton) + + adjustmentMins = Gtk.Adjustment(0, 0, 59, 1, 10, 0) + self.minutesButton = Gtk.SpinButton() + self.minutesButton.set_numeric(True) + self.minutesButton.set_adjustment(adjustmentMins) + self.minutesButton.set_value(float(now.minute)) + + self.minbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL ,spacing=5) + self.pack(self.minbox, Gtk.Label("Minute")) + self.pack(self.minbox, self.minutesButton) + + self.pack(self.hbox, self.hrbox) + self.pack(self.hbox, self.minbox) + + self.pack(box, self.hbox) + + self.show_all() + + def pack(self, box, item): + box.pack_start(item, False, False, 0) + +class line(): + def __init__(self, name, item2): + self.box = Gtk.Box(spacing=10) + + self.item1 = Gtk.Label(name, halign=Gtk.Align.START) + self.item2 = item2 + + self.box.pack_start(self.item1, True, True, 0) + self.box.pack_start(self.item2, True, True, 0) diff --git a/StatusUi.py b/StatusUi.py index 31f9122..f46c8ea 100644 --- a/StatusUi.py +++ b/StatusUi.py @@ -2,7 +2,6 @@ import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk -import rtc class StatusDevice(): device = "" @@ -45,7 +44,7 @@ class line(): def __init__(self, name, value): self.box = Gtk.Box(spacing=10) self.label = Gtk.Label(name, halign=Gtk.Align.START) - self.value = Gtk.Label(value, halign=Gtk.Align.END) + self.value = Gtk.Label(value, halign=Gtk.Align.END, selectable=True) self.box.pack_start(self.label, True, True, 0) self.box.pack_start(self.value, True, True, 0) diff --git a/rtc.py b/rtc.py index a1840a3..5f6eb4a 100644 --- a/rtc.py +++ b/rtc.py @@ -41,7 +41,9 @@ class RtcDevice(): (output, err) = process.communicate() exit_code = process.wait() - self.modes = shlex.split(str(output)) + output = output.decode() + + self.modes = output.split() def status(self): cmd = "rtcwake -m show -d " + self.name diff --git a/rtcwake_gui.py b/rtcwake_gui.py old mode 100644 new mode 100755 index 6f50bc3..c35173c --- a/rtcwake_gui.py +++ b/rtcwake_gui.py @@ -1,4 +1,4 @@ -#!/usr/bit/python +#!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') @@ -6,13 +6,7 @@ from gi.repository import Gtk import rtc import StatusUi - -def readFile(path): - file = open(path) - value = file.read() - file.close() - - return value.rstrip() +import SettingsUi class MyWindow(Gtk.Window): devices = {} @@ -27,7 +21,7 @@ class MyWindow(Gtk.Window): self.devices[device] = rtc.RtcDevice(name=device) def initUI(self): - Gtk.Window.__init__(self, title="RTCwake GUI") + Gtk.Window.__init__(self, title="RTCwake GUI", resizable=False) self.set_border_width(3) self.notebook = Gtk.Notebook() @@ -47,9 +41,17 @@ class MyWindow(Gtk.Window): self.notebook.append_page(self.pageStatus, Gtk.Label('Status')) + self.pageSettings = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) + self.pageSettings.set_border_width(10) + + self.settingUi = SettingsUi.Form(self, self.pageSettings, self.devices) + + self.notebook.append_page(self.pageSettings, Gtk.Label('Settings')) + + self.pageAbout = Gtk.Box() self.pageAbout.set_border_width(10) - self.pageAbout.pack_start(Gtk.Label('Simple GUI for rtcwake.'), True, True, 0) + self.pageAbout.pack_start(Gtk.Label('Simple GUI for rtcwake.', selectable=True), True, True, 0) self.notebook.append_page(self.pageAbout, Gtk.Label('About'))