1#!/usr/local/bin/python3.8 2 3from gi.repository import CinnamonDesktop, GLib, Gtk, Gio, Pango 4 5from util import utils, trackers, settings 6from baseWindow import BaseWindow 7from floating import Floating 8 9MAX_WIDTH = 320 10MAX_WIDTH_LOW_RES = 200 11 12class ClockWidget(Floating, BaseWindow): 13 """ 14 ClockWidget displays the time and away message on the screen. 15 16 It is a child of the Stage's GtkOverlay, and its placement is 17 controlled by the overlay's child positioning function. 18 19 When not Awake, it positions itself around all monitors 20 using a timer which randomizes its halign and valign properties 21 as well as its current monitor. 22 """ 23 def __init__(self, away_message=None, initial_monitor=0, low_res=False): 24 super(ClockWidget, self).__init__(initial_monitor) 25 self.get_style_context().add_class("clock") 26 self.set_halign(Gtk.Align.START) 27 28 self.set_property("margin", 6) 29 30 self.clock = None 31 self.low_res = low_res 32 33 if not settings.get_show_clock(): 34 return 35 36 self.away_message = away_message 37 38 box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) 39 self.add(box) 40 box.show() 41 42 self.label = Gtk.Label() 43 self.label.show() 44 self.label.set_line_wrap(True) 45 self.label.set_alignment(0.5, 0.5) 46 47 box.pack_start(self.label, True, False, 6) 48 49 self.msg_label = Gtk.Label() 50 self.msg_label.show() 51 self.msg_label.set_line_wrap(True) 52 self.msg_label.set_alignment(0.5, 0.5) 53 54 if self.low_res: 55 self.msg_label.set_max_width_chars(50) 56 else: 57 self.msg_label.set_max_width_chars(80) 58 59 box.pack_start(self.msg_label, True, True, 6) 60 61 self.clock = CinnamonDesktop.WallClock() 62 self.set_clock_format() 63 64 trackers.con_tracker_get().connect(self.clock, 65 "notify::clock", 66 self.on_clock_changed) 67 68 tz = Gio.File.new_for_path(path="/etc/localtime") 69 self.tz_monitor = tz.monitor_file(0, None) 70 71 trackers.con_tracker_get().connect(self.tz_monitor, 72 "changed", 73 self.on_tz_changed) 74 75 trackers.con_tracker_get().connect(self, 76 "destroy", 77 self.on_destroy) 78 79 self.update_clock() 80 81 def set_clock_format(self): 82 date_format = "" 83 time_format = "" 84 85 if settings.get_use_custom_format(): 86 date_format = settings.get_custom_date_format() 87 time_format = settings.get_custom_time_format() 88 else: 89 date_format = self.clock.get_default_date_format() 90 time_format = self.clock.get_default_time_format() 91 92 # %l is 12-hr hours, but it adds a space to 0-9, which looks bad here. 93 # The '-' modifier tells the GDateTime formatter not to pad the value. 94 time_format = time_format.replace('%l', '%-l') 95 96 time_font = Pango.FontDescription.from_string(settings.get_time_font()) 97 date_font = Pango.FontDescription.from_string(settings.get_date_font()) 98 99 if self.low_res: 100 time_size = time_font.get_size() * .66 101 date_size = date_font.get_size() * .66 102 time_font.set_size(int(time_size)) 103 date_font.set_size(int(date_size)) 104 105 time_format = ('<b><span font_desc=\"%s\" foreground=\"#FFFFFF\">%s</span></b>\n' + \ 106 '<b><span font_desc=\"%s\" foreground=\"#FFFFFF\">%s</span></b>') \ 107 % (time_font.to_string(), time_format, date_font.to_string(), date_format) 108 109 self.clock.set_format_string(time_format) 110 111 def on_clock_changed(self, clock, pspec): 112 self.update_clock() 113 114 def on_tz_changed(self, monitor, file, other, event): 115 self.update_clock() 116 117 def update_clock(self): 118 default_message = GLib.markup_escape_text (settings.get_default_away_message(), -1) 119 font_message = Pango.FontDescription.from_string(settings.get_message_font()) 120 121 if self.low_res: 122 msg_size = font_message.get_size() * .66 123 font_message.set_size(int(msg_size)) 124 125 if self.away_message and self.away_message != "": 126 user_name = utils.get_user_display_name() 127 markup = ('<span font_desc=\"{0}\">' 128 + '<b><span foreground=\"#CCCCCC\">{1}</span></b>' 129 + '\n<b><span font_size=\"smaller\" foreground=\"#ACACAC\"> ~ {2}</span></b>' 130 + '</span>\n ').format( 131 font_message.to_string(), self.away_message, user_name) 132 else: 133 markup = '<b><span font_desc=\"%s\" foreground=\"#CCCCCC\">%s</span></b>\n ' %\ 134 (font_message.to_string(), default_message) 135 136 self.label.set_markup(self.clock.get_clock()) 137 self.msg_label.set_markup(markup) 138 139 def set_message(self, msg=""): 140 if not self.clock: 141 return 142 143 self.away_message = msg 144 self.update_clock() 145 146 def on_destroy(self, data=None): 147 trackers.con_tracker_get().disconnect(self.clock, 148 "notify::clock", 149 self.on_clock_changed) 150 151 trackers.con_tracker_get().disconnect(self.tz_monitor, 152 "changed", 153 self.on_tz_changed) 154 155 trackers.con_tracker_get().disconnect(self, 156 "destroy", 157 self.on_destroy) 158 159 self.clock = None 160 self.tz_monitor = None 161