diff --git a/panels/system.py b/panels/system.py
index ad9196ee..6bf9a60d 100644
--- a/panels/system.py
+++ b/panels/system.py
@@ -3,7 +3,7 @@ import logging
import os
gi.require_version("Gtk", "3.0")
-from gi.repository import Gtk, Gdk, GLib
+from gi.repository import Gtk, Gdk, GLib, Pango
from datetime import datetime
from ks_includes.KlippyGcodes import KlippyGcodes
@@ -59,13 +59,14 @@ class SystemPanel(ScreenPanel):
scroll = Gtk.ScrolledWindow()
scroll.set_property("overlay-scrolling", False)
scroll.set_vexpand(True)
+ scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
infogrid = Gtk.Grid()
infogrid.get_style_context().add_class("system-program-grid")
update_resp = self._screen.apiclient.send_request("machine/update/status")
self.update_status = False
- if update_resp is False:
+ if not update_resp:
logging.info("No update manager configured")
else:
self.update_status = update_resp['result']
@@ -79,9 +80,7 @@ class SystemPanel(ScreenPanel):
self.labels["%s_status" % prog] = self._gtk.Button()
self.labels["%s_status" % prog].set_hexpand(False)
- self.labels["%s_status" % prog].connect("clicked", self.show_commit_history, prog)
- self.labels["%s_info" % prog] = self._gtk.ButtonImage("info", None, None, .7, .7)
- self.labels["%s_info" % prog].connect("clicked", self.show_commit_history, prog)
+ self.labels["%s_status" % prog].connect("clicked", self.show_update_info, prog)
if prog in ALLOWED_SERVICES:
self.labels["%s_restart" % prog] = self._gtk.ButtonImage("refresh", None, None, .7, .7)
@@ -119,7 +118,7 @@ class SystemPanel(ScreenPanel):
def get_updates(self):
update_resp = self._screen.apiclient.send_request("machine/update/status")
- if update_resp is False:
+ if not update_resp:
logging.info("No update manager configured")
else:
self.update_status = update_resp['result']
@@ -131,14 +130,16 @@ class SystemPanel(ScreenPanel):
def process_update(self, action, data):
if action == "notify_update_response":
logging.info("Update: %s" % data)
- if 'application' in data and data['application'] == self.update_prog:
+ if 'application' in data:
self.labels['update_progress'].set_text(self.labels['update_progress'].get_text().strip() + "\n" +
data['message'] + "\n")
+ self.labels['update_progress'].set_ellipsize(True)
+ self.labels['update_progress'].set_ellipsize(Pango.EllipsizeMode.END)
adjustment = self.labels['update_scroll'].get_vadjustment()
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size())
adjustment = self.labels['update_scroll'].show_all()
- if data['complete'] is True:
+ if data['complete']:
self.update_dialog.set_response_sensitive(Gtk.ResponseType.CANCEL, True)
def restart(self, widget, program):
@@ -148,48 +149,92 @@ class SystemPanel(ScreenPanel):
logging.info("Restarting service: %s" % program)
self._screen._ws.send_method("machine.services.restart", {"service": program})
- def show_commit_history(self, widget, program):
+ def show_update_info(self, widget, program):
_ = self.lang.gettext
- if self.update_status is False or program not in self.update_status['version_info']:
+ if not self.update_status or program not in self.update_status['version_info']:
return
info = self.update_status['version_info'][program]
- if info['version'] == info['remote_version']:
- return
-
- buttons = [
- {"name": _("Update"), "response": Gtk.ResponseType.OK},
- {"name": _("Go Back"), "response": Gtk.ResponseType.CANCEL}
- ]
scroll = Gtk.ScrolledWindow()
+ scroll.set_property("overlay-scrolling", False)
scroll.set_hexpand(True)
scroll.set_vexpand(True)
+ scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
grid = Gtk.Grid()
- grid.set_halign(Gtk.Align.START)
+ grid.set_column_homogeneous(True)
+ grid.set_halign(Gtk.Align.CENTER)
+ grid.set_valign(Gtk.Align.CENTER)
i = 0
- date = ""
- for c in info['commits_behind']:
- ndate = datetime.fromtimestamp(int(c['date'])).strftime("%b %d")
- if date != ndate:
- date = ndate
- label = Gtk.Label("")
- label.set_markup("%s\n" % date)
- label.set_halign(Gtk.Align.START)
+ label = Gtk.Label()
+ if "configured_type" in info:
+ if info['configured_type'] == 'git_repo':
+ if not info['is_valid'] or info['is_dirty']:
+ label.set_markup("Do you want to recover %s?" % program)
+ grid.attach(label, 0, i, 1, 1)
+ scroll.add(grid)
+ recoverybuttons = [
+ {"name": _("Recover Hard"), "response": Gtk.ResponseType.OK},
+ {"name": _("Recover Soft"), "response": Gtk.ResponseType.APPLY},
+ {"name": _("Cancel"), "response": Gtk.ResponseType.CANCEL}
+ ]
+ dialog = self._gtk.Dialog(self._screen, recoverybuttons, scroll, self.reset_confirm, program)
+ return
+ else:
+ if info['version'] == info['remote_version']:
+ return
+ label.set_markup("Outdated by %d commits:\n" % len(info['commits_behind']))
+ grid.attach(label, 0, i, 1, 1)
+ i = i + 1
+ date = ""
+ for c in info['commits_behind']:
+ ndate = datetime.fromtimestamp(int(c['date'])).strftime("%b %d")
+ if date != ndate:
+ date = ndate
+ label = Gtk.Label()
+ label.set_markup("%s\n" % date)
+ label.set_halign(Gtk.Align.START)
+ grid.attach(label, 0, i, 1, 1)
+ i = i + 1
+
+ label = Gtk.Label()
+ label.set_ellipsize(True)
+ label.set_ellipsize(Pango.EllipsizeMode.END)
+ label.set_markup("%s\n%s\n" % (c['subject'], c['author']))
+ label.set_halign(Gtk.Align.START)
+ grid.attach(label, 0, i, 1, 1)
+ i = i + 1
+ else:
+ label.set_markup("%s will be updated to version: %s" % (program.capitalize(),
+ info['remote_version']))
grid.attach(label, 0, i, 1, 1)
i = i + 1
-
- label = Gtk.Label()
- label.set_markup("%s\n%s %s %s\n" % (c['subject'], c['author'], _("Commited"), "2 days ago"))
- label.set_hexpand(True)
- label.set_halign(Gtk.Align.START)
- grid.attach(label, 0, i, 1, 1)
+ if "package_count" in info:
+ label.set_markup("%d Packages will be updated:\n" % info['package_count'])
+ label.set_halign(Gtk.Align.CENTER)
+ grid.attach(label, 0, i, 3, 1)
i = i + 1
+ j = 0
+ for c in info["package_list"]:
+ label = Gtk.Label()
+ label.set_markup(" %s " % c)
+ label.set_halign(Gtk.Align.START)
+ label.set_ellipsize(True)
+ label.set_ellipsize(Pango.EllipsizeMode.END)
+ pos = (j % 3)
+ grid.attach(label, pos, i, 1, 1)
+ j = j + 1
+ if (pos == 2):
+ i = i + 1
scroll.add(grid)
+ buttons = [
+ {"name": _("Update"), "response": Gtk.ResponseType.OK},
+ {"name": _("Cancel"), "response": Gtk.ResponseType.CANCEL}
+ ]
dialog = self._gtk.Dialog(self._screen, buttons, scroll, self.update_confirm, program)
def update_confirm(self, widget, response_id, program):
@@ -198,13 +243,55 @@ class SystemPanel(ScreenPanel):
self.update_program(self, program)
widget.destroy()
+ def reset_confirm(self, widget, response_id, program):
+ if response_id == Gtk.ResponseType.OK:
+ logging.debug("Recovering hard %s" % program)
+ self.reset_repo(self, program, True)
+ if response_id == Gtk.ResponseType.APPLY:
+ logging.debug("Recovering soft %s" % program)
+ self.reset_repo(self, program, False)
+ widget.destroy()
+
+ def reset_repo(self, widget, program, hard):
+ if self._screen.is_updating():
+ return
+
+ _ = self.lang.gettext
+
+ buttons = [
+ {"name": _("Finish"), "response": Gtk.ResponseType.CANCEL}
+ ]
+
+ scroll = Gtk.ScrolledWindow()
+ scroll.set_property("overlay-scrolling", False)
+ scroll.set_hexpand(True)
+ scroll.set_vexpand(True)
+ scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
+
+ self.labels['update_progress'] = Gtk.Label("%s %s..." % (_("Starting recovery for"), program))
+ self.labels['update_progress'].set_halign(Gtk.Align.START)
+ self.labels['update_progress'].set_valign(Gtk.Align.START)
+ scroll.add(self.labels['update_progress'])
+ self.labels['update_scroll'] = scroll
+
+ dialog = self._gtk.Dialog(self._screen, buttons, scroll, self.finish_updating)
+ dialog.set_response_sensitive(Gtk.ResponseType.CANCEL, False)
+
+ self.update_prog = program
+ self.update_dialog = dialog
+
+ logging.info("Sending machine.update.recover name: %s" % program)
+
+ self._screen._ws.send_method("machine.update.recover", {"name": program, "hard": str(hard)})
+ self._screen.set_updating(True)
+
def update_program(self, widget, program):
if self._screen.is_updating():
return
_ = self.lang.gettext
- if self.update_status is False or program not in self.update_status['version_info']:
+ if not self.update_status or program not in self.update_status['version_info']:
return
info = self.update_status['version_info'][program]
@@ -221,10 +308,12 @@ class SystemPanel(ScreenPanel):
]
scroll = Gtk.ScrolledWindow()
+ scroll.set_property("overlay-scrolling", False)
scroll.set_hexpand(True)
scroll.set_vexpand(True)
+ scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
- self.labels['update_progress'] = Gtk.Label("%s %s%s" % (_("Starting update for"), program, _("...")))
+ self.labels['update_progress'] = Gtk.Label("%s %s..." % (_("Starting update for"), program))
self.labels['update_progress'].set_halign(Gtk.Align.START)
self.labels['update_progress'].set_valign(Gtk.Align.START)
scroll.add(self.labels['update_progress'])
@@ -253,17 +342,40 @@ class SystemPanel(ScreenPanel):
info = self.update_status['version_info'][p]
logging.info("%s: %s" % (p, info))
+
if p != "system":
version = (info['full_version_string'] if "full_version_string" in info else info['version'])
-
- if info['version'] == info['remote_version']:
- self.labels[p].set_markup("%s\n%s" % (p, version))
- self.labels["%s_status" % p].set_label(_("Up To Date"))
- self.labels["%s_status" % p].set_sensitive(False)
+ if info['configured_type'] == 'git_repo':
+ if info['is_valid'] and not info['is_dirty']:
+ if info['version'] == info['remote_version']:
+ self.labels[p].set_markup("%s\n%s" % (p, version))
+ self.labels["%s_status" % p].set_label(_("Up To Date"))
+ self.labels["%s_status" % p].get_style_context().remove_class('update')
+ self.labels["%s_status" % p].get_style_context().remove_class('invalid')
+ self.labels["%s_status" % p].set_sensitive(False)
+ else:
+ self.labels[p].set_markup("%s\n%s -> %s" % (p, version, info['remote_version']))
+ self.labels["%s_status" % p].set_label(_("Update"))
+ self.labels["%s_status" % p].get_style_context().add_class('update')
+ self.labels["%s_status" % p].set_sensitive(True)
+ else:
+ self.labels[p].set_markup("%s\n%s" % (p, version))
+ self.labels["%s_status" % p].set_label(_("Invalid"))
+ self.labels["%s_status" % p].get_style_context().add_class('invalid')
+ self.labels["%s_status" % p].set_sensitive(True)
else:
- self.labels[p].set_markup("%s\n%s -> %s" % (p, version, info['remote_version']))
- self.labels["%s_status" % p].set_label(_("Update"))
- self.labels["%s_status" % p].set_sensitive(True)
+ if info['version'] == info['remote_version']:
+ self.labels[p].set_markup("%s\n%s" % (p, version))
+ self.labels["%s_status" % p].set_label(_("Up To Date"))
+ self.labels["%s_status" % p].get_style_context().remove_class('update')
+ self.labels["%s_status" % p].set_sensitive(False)
+ else:
+ self.labels[p].set_markup("%s\n%s -> %s" % (p, version, info['remote_version']))
+ self.labels["%s_status" % p].set_label(_("Update"))
+ self.labels["%s_status" % p].get_style_context().add_class('update')
+ self.labels["%s_status" % p].set_sensitive(True)
+
+
else:
self.labels[p].set_markup("System")
if info['package_count'] == 0:
@@ -271,6 +383,7 @@ class SystemPanel(ScreenPanel):
self.labels["%s_status" % p].set_sensitive(False)
else:
self.labels["%s_status" % p].set_label(_("Update"))
+ self.labels["%s_status" % p].get_style_context().add_class('update')
self.labels["%s_status" % p].set_sensitive(True)
def restart_klippy(self, widget, type=None):
diff --git a/styles/base.css b/styles/base.css
index 55448467..4211100f 100644
--- a/styles/base.css
+++ b/styles/base.css
@@ -56,11 +56,29 @@ button.file-list {
margin: 0;
}
+button.update {
+ background: #009384;
+ border: .4em solid #009384;
+ border-radius: 0.4em;
+ font-weight: bold;
+}
+
+button.invalid {
+ background: #e61e1e;
+ border: .4em solid #e61e1e;
+ border-radius: 0.4em;
+ font-weight: bold;
+}
+
combobox box button {
border: .05em solid #cccccc;
padding: .5em 1em;
}
+combobox arrow {
+ min-width: 1em;
+}
+
entry {
font-size: 1em;
background-color: #20292F;
@@ -112,6 +130,11 @@ scale mark {
color: white;
}
+scale trough slider {
+ min-height: 2em;
+ min-width: 2em;
+}
+
scrollbar, scrollbar button, scrollbar trough {
border: none;
background-color: #13181C;
@@ -354,7 +377,7 @@ trough {
.system-program-grid {
padding: 0.25em;
- padding-right: 1em;
+ padding-right: .5em;
padding-bottom: 0;
}
diff --git a/styles/colorized/style.css b/styles/colorized/style.css
index d1c2113a..c32e9d3c 100644
--- a/styles/colorized/style.css
+++ b/styles/colorized/style.css
@@ -46,7 +46,7 @@ button.color4 {
border-radius: 1em;
}
-button.color1:active, button.color2:active, button.color3:active, button.color4:active {
+button.color1:active, button.color2:active, button.color3:active, button.color4:active, button.update:active, button.invalid:active, .dialog button:active {
border-style: none;
}
@@ -54,15 +54,40 @@ button.active {
background-color: #cb4b16; /*solarized-orange*/
}
+button.update {
+ background-color: #073642; /*base02*/
+ border: 0;
+ border-bottom: .3em solid;
+ border-bottom-color: #859900; /*solarized-green*/
+ border-radius: .75em;
+}
+
+button.invalid {
+ background-color: #073642; /*base02*/
+ border: 0;
+ border-bottom: .3em solid;
+ border-bottom-color: #dc322f; /*solarized-red*/
+ border-radius: .75em;
+}
+
combobox box button {
background-color: #073642; /*base02*/
border-color: #002b36; /*base03*/
}
switch {
- /* background-color: #073642; base02 */
+ background-color: #073642; /* base02 */
+ border-color: #073642; /* base02 */
+ border-radius: 3em;
}
+switch:checked {
+ background-color: #859900; /*solarized-green*/
+}
+
+switch slider {
+ border: 0;
+}
entry {
background-color: #073642; /*base02*/
border-color: #002b36; /*base03*/
@@ -98,7 +123,8 @@ trough highlight, trough progress {
background-color: #6c71c4; /*solarized-violet*/
color: #fdf6e3; /*base3*/
border-color: #002b36; /*base03*/
- border-radius: 1em;
+ border-top-left-radius: 1em;
+ border-bottom-left-radius: 1em;
}
scale-mark {
@@ -110,7 +136,7 @@ scrollbar, scrollbar button, scrollbar trough {
}
scrollbar slider {
- background-color: #586e75; /*base01*/
+ background-color: #073642; /*base02*/
}
textview .time {
@@ -127,9 +153,18 @@ textview .time {
}
.dialog button {
+ background-color: #073642; /*base02*/
border-bottom-color: #268bd2; /*solarized-cyan*/
+ border-radius: .75em;
}
+.dialog button:nth-child(1) {
+ border-bottom-color: #859900; /*solarized-green*/
+}
+
+.dialog button:nth-child(2) {
+ border-bottom-color: #dc322f; /*solarazed-red*/
+}
.tempbutton_top, .tempbutton, .tempbutton_bottom, .distbutton_top, .distbutton, .distbutton_bottom {
border-color: #002b36; /*base03*/
background-color: #073642; /*base02*/
diff --git a/styles/z-bolt/style.css b/styles/z-bolt/style.css
index b1f73f95..78179092 100644
--- a/styles/z-bolt/style.css
+++ b/styles/z-bolt/style.css
@@ -38,6 +38,16 @@ button.active {
background-color: #20303D;
}
+button.update {
+ background: #009384;
+ border-color: #009384;
+}
+
+button.invalid {
+ background: #e61e1e;
+ border-color: #e61e1e;
+}
+
combobox box button {
border-color: #cccccc;
}
@@ -98,8 +108,8 @@ textview .time {
}
.dialog {
- border: black;
- background-color: black;
+ border: #13181C;
+ background-color: #13181C;
}
.dialog button {