#!/usr/bin/env python # USP Time Plugin Version 1.0 ##Description:Configurable Date/Time display import gtk from gtk import gdk import gtk.glade import sys import os import gobject from datetime import datetime import math import gconf import pango import commands import cairo from execute import Execute from easygconf import SetGconf from easygconf import WriteGconf supports_alpha = False def screen_changed(widget, old_screen=None): global supports_alpha # To check if the display supports alpha channels, get the colormap screen = widget.get_screen() colormap = screen.get_rgba_colormap() if colormap == None: print 'Your screen does not support alpha channels!' colormap = screen.get_rgb_colormap() supports_alpha = False else: print 'Your screen supports alpha channels!' supports_alpha = True # Now we have a colormap appropriate for the screen, use it widget.set_colormap(colormap) return False class EggClockFace(gtk.DrawingArea): def __init__(self): super(EggClockFace, self).__init__() self.connect("expose_event", self.expose) # make it private self._time = None self.gconf_dir = '/apps/usp/plugins/datetime' self.client = gconf.client_get_default() try: self.backcol = gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/datetime/analog_clock_face_color', "white")) self.forecol = gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/datetime/analog_clock_edge_color', "black")) self.secondcol = gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/datetime/analog_clock_second_color', "red")) self.hidesec = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_hide_seconds', False) except: print "Color Parse Error" self.backcol = gdk.color_parse("white") self.forecol = gdk.color_parse("black") self.secondcol = gdk.color_parse("red") self.update() # update the clock once a second gobject.timeout_add(1000, self.update) def expose(self, widget, event): global supports_alpha context = widget.window.cairo_create() if supports_alpha == True: context.set_source_rgba(1.0, 0.0, 0.0, 0.0) # Transparent else: context.set_source_rgb(1.0, 1.0, 1.0) # Opaque white context.set_operator(cairo.OPERATOR_SOURCE) context.paint() # set a clip region for the expose event context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) context.clip() self.draw(context) return False def draw(self, context): rect = self.get_allocation() x = rect.width / 2.0 y = rect.height / 2.0 #x = rect.x + rect.width / 2.0 #y = rect.y + rect.height / 2.0 radius = min(rect.width / 2.0, rect.height / 2.0) - 20 # clock back context.arc(x, y, radius, 0, 2.0 * math.pi) context.set_source_rgb(self.backcol.red,self.backcol.green,self.backcol.blue) # face colour context.fill_preserve() context.set_source_rgb(self.forecol.red,self.forecol.green,self.forecol.blue) # "numbers" & hands colour context.stroke() # clock ticks for i in xrange(12): context.save() if i % 3 == 0: inset = 0.2 * radius else: inset = 0.1 * radius context.set_line_width(0.7 * context.get_line_width()) context.move_to(x + (radius - inset) * math.cos(i * math.pi / 6.0), y + (radius - inset) * math.sin(i * math.pi / 6.0)) context.line_to(x + radius * math.cos(i * math.pi / 6.0), y + radius * math.sin(i * math.pi / 6.0)) context.stroke() context.restore() # clock hands hours = self._time.hour minutes = self._time.minute seconds = self._time.second # hour hand: # the hour hand is rotated 30 degrees (pi/6 r) per hour + # 1/2 a degree (pi/360) per minute context.save() context.set_line_width(1.5 * context.get_line_width()) context.move_to(x, y) context.line_to(x + radius / 2 * math.sin( math.pi / 6 * hours + math.pi / 360 * minutes), y + radius / 2 * -math.cos( math.pi / 6 * hours + math.pi / 360 * minutes)) context.stroke() context.restore() # minute hand: # the minute hand is rotated 6 degrees (pi/30 r) per minute context.move_to(x, y) context.line_to(x + radius * 0.75 * math.sin(math.pi / 30 * minutes), y + radius * 0.75 * -math.cos(math.pi / 30 * minutes)) context.stroke() # seconds hand: # operates identically to the minute hand if self.hidesec==False: context.save() context.set_source_rgb(self.secondcol.red,self.secondcol.green,self.secondcol.blue) # seconds hand colour context.move_to(x, y) context.line_to(x + radius * 0.9 * math.sin(math.pi / 30 * seconds), y + radius * 0.9 * -math.cos(math.pi / 30 * seconds)) context.stroke() context.restore() def redraw_canvas(self): if self.window: alloc = self.get_allocation() rect = gdk.Rectangle(alloc.x, alloc.y, alloc.width, alloc.height) self.window.invalidate_rect(rect, True) self.window.process_updates(True) def update(self): # update the time self.time = datetime.now() return True # keep running this event # public access to the time member def _get_time(self): return self._time def _set_time(self, datetime): self._time = datetime self.redraw_canvas() time = property(_get_time, _set_time) class pluginclass: TARGET_TYPE_TEXT = 80 toButton = [ ( "text/uri-list", 0, TARGET_TYPE_TEXT ) ] """This is the main class for the plugin""" """It MUST be named pluginclass""" def __init__(self, USPWin): self.USPWin = USPWin #The Glade file for the plugin self.gladefile = os.path.join(os.path.dirname(__file__), "usptime.glade") #Read GLADE file self.wTree = gtk.glade.XML(self.gladefile,"window1") #These properties are NECESSARY to maintain consistency #throughout USP #Set 'window' property for the plugin (Must be the root widget) self.window = self.wTree.get_widget("window1") self.window.set_app_paintable(True) #Set 'heading' property for plugin self.heading = "Date and Time" #This should be the first item added to the window in glade self.content_holder = self.wTree.get_widget("eventbox1") #Specify plugin width self.width = 150 #Plugin icon self.icon = 'gnome-set-time' self.gconf_dir = '/apps/usp/plugins/datetime' self.client = gconf.client_get_default() self.client.add_dir('/apps/usp/plugins/datetime', gconf.CLIENT_PRELOAD_NONE) self.client.notify_add('/apps/usp/plugins/datetime/eu_date_format',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_date_bold',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_date_font_size',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_date_string',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_day_string',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_time_bold',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_time_font_size',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_time_12_hour',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_time_hide_seconds',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/settings_date_sep',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/system_command1',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/analog_clock',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/analog_clock_diameter',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/analog_clock_face_color',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/analog_clock_edge_color',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/analog_clock_seconds_color',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/sticky',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/datetime/icon',self.RegenPlugin) self.RegenPlugin() self.SetupEvents() if self.analog==True: clock=EggClockFace() clock.set_app_paintable(True) self.wTree.get_widget('hbox2').pack_start(clock) self.wTree.get_widget('hbox2').reorder_child(clock,1) self.wTree.get_widget('hbox2').set_size_request(self.diameter,self.diameter) clock.show() self.wTree.get_widget('label2').hide() self.window.connect('expose-event', clock.expose) self.window.connect('screen-changed', screen_changed) screen_changed(self.window) gobject.timeout_add(1000, self.date_time) def RegenPlugin(self, *args, **kargs): self.GetGconfEntries() self.SetSystemStyle(["label1","label2"]) def SetupEvents(self): #Connect event handlers dic = {"on_window1_destroy" : gtk.main_quit, "on_button1_clicked" : (Execute,self.syscommand1)} self.wTree.signal_autoconnect(dic) def GetGconfEntries(self): self.client = gconf.client_get_default() self.eudate = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/eu_date_format', False) self.datebold = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_date_bold', False) self.datestring = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_date_string', False) self.daystring = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_day_string', False) self.datefontsize = SetGconf(self.client,'int','/apps/usp/plugins/datetime/settings_date_font_size', 11) self.timebold = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_bold', False) self.hidesec = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_hide_seconds', False) self.timefontsize = SetGconf(self.client,'int','/apps/usp/plugins/datetime/settings_time_font_size', 11) self.time12 = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_12_hour', False) self.datesep = SetGconf(self.client,'string','/apps/usp/plugins/datetime/settings_date_sep','-') self.syscommand1 = SetGconf(self.client,'string','/apps/usp/plugins/datetime/system_command1','gksu time-admin').split() self.analog = SetGconf(self.client,'bool','/apps/usp/plugins/datetime/analog_clock', False) self.diameter = SetGconf(self.client,'int','/apps/usp/plugins/datetime/analog_clock_diameter', 100) self.sticky = SetGconf( self.client, "bool", "/apps/usp/plugins/datetime/sticky", False ) self.minimized = SetGconf( self.client, "bool", "/apps/usp/plugins/datetime/minimized", False ) self.icon = SetGconf( self.client, "string", "/apps/usp/plugins/datetime/icon", "gnome-set-time" ) def SetHidden( self, state ): if state == True: WriteGconf( self.client, "bool", "/apps/usp/plugins/datetime/minimized", True ) else: WriteGconf( self.client, "bool", "/apps/usp/plugins/datetime/minimized", False ) def SetSystemStyle(self,items): # Set Date styles HeadingStyle = pango.AttrList() attr = pango.AttrSize(self.datefontsize*1000,0,-1) HeadingStyle.insert(attr) if self.datebold == 0: attr = pango.AttrWeight(pango.WEIGHT_NORMAL,0,-1) else: attr = pango.AttrWeight(pango.WEIGHT_BOLD,0,-1) HeadingStyle.insert(attr) self.wTree.get_widget(items[0]).set_attributes(HeadingStyle) # Set Time styles HeadingStyle = pango.AttrList() attr = pango.AttrSize(self.timefontsize*1000,0,-1) HeadingStyle.insert(attr) if self.timebold == 0: attr = pango.AttrWeight(pango.WEIGHT_NORMAL,0,-1) else: attr = pango.AttrWeight(pango.WEIGHT_BOLD,0,-1) HeadingStyle.insert(attr) self.wTree.get_widget(items[1]).set_attributes(HeadingStyle) #Actually do something with the plugin def date_time(self): try: # Sort out how to display Date. Start with a default just in case. datemask="%m-%d-%Y" if self.datestring == 0: if self.eudate == 0: datemask="%m"+self.datesep+"%d"+self.datesep+"%Y" else: datemask="%d"+self.datesep+"%m"+self.datesep+"%Y" else: ending="th" daynum = datetime.today().strftime("%d") if daynum in ('01','21','31'): ending="st" if daynum in ('02','22'): ending="nd" if daynum in ('03','23'): ending="rd" if self.eudate == 0: if self.daystring == 0: datemask="%b %e"+ending+", %Y" else: datemask="%a. %b %e"+ending+", %Y" else: if self.daystring == 0: datemask="%e"+ending+" %b, %Y" else: datemask="%a. %e"+ending+" %b, %Y" self.wTree.get_widget("label1").set_label(datetime.today().strftime(datemask)) # Sort out how to display Time. Start with a default just in case. timemask="%H:%M" if self.time12 == 0: if self.hidesec == 0: timemask="%H:%M:%S" else: #timemask="%r" # This is just because I prefer lowercase. if datetime.today().strftime("%p") == "AM": if self.hidesec==0: timemask="%I:%M:%S am" else: timemask="%I:%M am" elif datetime.today().strftime("%p") == "PM": if self.hidesec==0: timemask="%I:%M:%S pm" else: timemask="%I:%M pm" self.wTree.get_widget("label2").set_label(datetime.today().strftime(timemask)) except: pass return True #---------------------------------------------------------------------------------------# # USPconfig Section Below #---------------------------------------------------------------------------------------# # This is the Config Class it must be called "cfgpluginclass' class cfgpluginclass: def __init__(self): # The Gladefile for the plugins USPconfig Tab self.gladefile = os.path.join(os.path.dirname(__file__), "usptime.glade") # Read GLADE file self.wTree = gtk.glade.XML(self.gladefile,"config") # Set 'window' property for the plugin (Must be the root widget) self.window = self.wTree.get_widget("config") # Set Heading, this will be used for the tab label in USPconfig self.heading = "Date/Time" # Content Place Holder must be eventbox1 self.content_holder = self.wTree.get_widget("eventbox2") # GConf Stuff - This just makes sure a gconf path is there. self.gconf_dir = '/apps/usp/plugins/datetime' self.client = gconf.client_get_default() self.client.add_dir('/apps/usp/plugins/datetime', gconf.CLIENT_PRELOAD_NONE) # Setup the Functions of the Glade files spin controls or entry boxes for Value Changes # Tip: For spinbutton controls use the "_value_changed" event not the "_changed" event. dic = { "on_window1_destroy" : gtk.main_quit, "on_DateSizeSpin_changed" : self.datefontspin, "on_DateBoldChkBtn_toggled" : self.dateboldchk, "on_EUChkBtn_toggled" : self.euchk, "on_DateStrChkBtn_toggled" : self.datestrchk, "on_DayStrChkBtn_toggled" : self.daystrchk, "on_DateSepEntry_changed" : self.datesepset, "on_TimeSizeSpin_changed" : self.timefontspin, "on_TimeBoldChkBtn_toggled" : self.timeboldchk, "on_Time12ChkBtn_toggled" : self.time12chk, "on_HideSecChkBtn_toggled" : self.hidesecchk, "on_AnalogChkBtn_toggled" : self.analogchk, "on_DiameterSpin_changed" : self.diaspin, "on_ClockFaceColBtn_color_set" : self.facecolset, "on_ClockHandsColBtn_color_set" : self.handscolset, "on_ClockSecColBtn_color_set" : self.seccolset, "on_DTIconEntry_changed" : self.dticonchange, "on_StickyChkBtn_toggled" : self.dtsticky} self.wTree.signal_autoconnect(dic) # Read Values from Gconf and Set Default Values if they don't exist. self.wTree.get_widget("DateSizeSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/datetime/settings_date_font_size',11)) self.wTree.get_widget("DateBoldChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_date_bold',False)) self.wTree.get_widget("EUChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/eu_date_format',False)) self.wTree.get_widget("DateStrChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_date_string',False)) self.wTree.get_widget("DayStrChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_day_string',True)) self.wTree.get_widget("DateSepEntry").set_text(SetGconf(self.client,'string','/apps/usp/plugins/datetime/settings_date_sep','-')) self.wTree.get_widget("TimeSizeSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/datetime/settings_time_font_size',9)) self.wTree.get_widget("TimeBoldChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_bold',False)) self.wTree.get_widget("Time12ChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_12_hour',False)) self.wTree.get_widget("HideSecChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/settings_time_hide_seconds',False)) self.wTree.get_widget("AnalogChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/analog_clock',False)) self.wTree.get_widget("DiameterSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/datetime/analog_clock_diameter',100)) self.wTree.get_widget("ClockFaceColBtn").set_color(gtk.gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/datetime/analog_clock_face_color','white'))) self.wTree.get_widget("ClockHandsColBtn").set_color(gtk.gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/datetime/analog_clock_edge_color','black'))) self.wTree.get_widget("ClockSecColBtn").set_color(gtk.gdk.color_parse(SetGconf(self.client,'string','/apps/usp/plugins/datetime/analog_clock_second_color','red'))) self.wTree.get_widget("DTIconEntry").set_text(SetGconf(self.client,'string','/apps/usp/plugins/datetime/icon','gnome-set-time.png')) self.wTree.get_widget("StickyChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/datetime/sticky',False)) # Functions for Changing Values when items checked or altered Section def datefontspin(self, widget, **kargs): self.client.set_int('/apps/usp/plugins/datetime/settings_date_font_size',int(self.wTree.get_widget("DateSizeSpin").get_value())) def dateboldchk(self, widget, **kargs): if self.wTree.get_widget("DateBoldChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/settings_date_bold',True) else: self.client.set_bool('/apps/usp/plugins/datetime/settings_date_bold',False) def euchk(self, widget, **kargs): if self.wTree.get_widget("EUChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/eu_date_format',True) else: self.client.set_bool('/apps/usp/plugins/datetime/eu_date_format',False) def datestrchk(self, widget, **kargs): if self.wTree.get_widget("DateStrChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/settings_date_string',True) else: self.client.set_bool('/apps/usp/plugins/datetime/settings_date_string',False) def daystrchk(self, widget, **kargs): if self.wTree.get_widget("DayStrChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/settings_day_string',True) else: self.client.set_bool('/apps/usp/plugins/datetime/settings_day_string',False) def datesepset(self, widget, **kargs): self.client.set_string('/apps/usp/plugins/datetime/settings_date_sep',self.wTree.get_widget("DateSepEntry").get_text()) def timefontspin(self, widget, **kargs): self.client.set_int('/apps/usp/plugins/datetime/settings_time_font_size',int(self.wTree.get_widget("TimeSizeSpin").get_value())) def timeboldchk(self, widget, **kargs): if self.wTree.get_widget("TimeBoldChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/settings_time_bold',True) else: self.client.set_bool('/apps/usp/plugins/datetime/settings_time_bold',False) def time12chk(self, widget, **kargs): if self.wTree.get_widget("Time12ChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/settings_time_12_hour',True) else: self.client.set_bool('/apps/usp/plugins/datetime/settings_time_12_hour',False) def hidesecchk(self, widget, **kargs): if self.wTree.get_widget("HideSecChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/settings_time_hide_seconds',True) else: self.client.set_bool('/apps/usp/plugins/datetime/settings_time_hide_seconds',False) def analogchk(self, widget, **kargs): if self.wTree.get_widget("AnalogChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/analog_clock',True) else: self.client.set_bool('/apps/usp/plugins/datetime/analog_clock',False) def diaspin(self, widget, **kargs): self.client.set_int('/apps/usp/plugins/datetime/analog_clock_diameter',int(self.wTree.get_widget("DiameterSpin").get_value())) def facecolset(self, widget, **kargs): tcol=self.wTree.get_widget("ClockFaceColBtn").get_color() col_string='#' + (hex(tcol.red)+'0')[2:4]+(hex(tcol.green)+'0')[2:4]+(hex(tcol.blue)+'0')[2:4] self.client.set_string('/apps/usp/plugins/datetime/analog_clock_face_color',col_string) def handscolset(self, widget, **kargs): tcol=self.wTree.get_widget("ClockHandsColBtn").get_color() col_string='#' + (hex(tcol.red)+'0')[2:4]+(hex(tcol.green)+'0')[2:4]+(hex(tcol.blue)+'0')[2:4] self.client.set_string('/apps/usp/plugins/datetime/analog_clock_edge_color',col_string) def seccolset(self, widget, **kargs): tcol=self.wTree.get_widget("ClockSecColBtn").get_color() col_string='#' + (hex(tcol.red)+'0')[2:4]+(hex(tcol.green)+'0')[2:4]+(hex(tcol.blue)+'0')[2:4] self.client.set_string('/apps/usp/plugins/datetime/analog_clock_second_color',col_string) def dticonchange(self, widget, **kargs): self.icon=self.wTree.get_widget("DTIconEntry").get_text() self.client.set_string('/apps/usp/plugins/datetime/icon',self.wTree.get_widget('DTIconEntry').get_text()) def dtsticky(self, widget, **kargs): if self.wTree.get_widget("StickyChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/datetime/sticky',True) else: self.client.set_bool('/apps/usp/plugins/datetime/sticky',False)