#!/usr/bin/env python # USP Calculator Plugin Version 1.0 ##Description:A Simple Calculator import gtk import gtk.glade import sys import os import gobject import gconf import math from easygconf import * 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__),"calculator.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") #Set 'heading' property for plugin self.heading = "Calculator" #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-calculator.png' self.gconf_dir = '/apps/usp/plugins/calc' self.client = gconf.client_get_default() self.client.add_dir( '/apps/usp/plugins/calc', gconf.CLIENT_PRELOAD_NONE ) self.client.notify_add('/apps/usp/plugins/calc/sticky',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/calc/icon',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/calc/width',self.RegenPlugin) self.client.notify_add('/apps/usp/plugins/calc/height',self.RegenPlugin) self.clearbox = 1 self.RegenPlugin() #Connect event handlers dic = { "on_window1_destroy" : gtk.main_quit, "on_0Btn_clicked" : (self.enter_number, '0'), "on_1Btn_clicked" : (self.enter_number, '1'), "on_2Btn_clicked" : (self.enter_number, '2'), "on_3Btn_clicked" : (self.enter_number, '3'), "on_4Btn_clicked" : (self.enter_number, '4'), "on_5Btn_clicked" : (self.enter_number, '5'), "on_6Btn_clicked" : (self.enter_number, '6'), "on_7Btn_clicked" : (self.enter_number, '7'), "on_8Btn_clicked" : (self.enter_number, '8'), "on_9Btn_clicked" : (self.enter_number, '9'), "on_PntBtn_clicked" : (self.switch, '.'), "on_EqualsBtn_clicked" : (self.calculate), "on_PlusBtn_clicked" : (self.switch, '+'), "on_MinusBtn_clicked" : (self.switch, '-'), "on_MultBtn_clicked" : (self.switch, '*'), "on_DivBtn_clicked" : (self.switch, '/'), "on_SinBtn_clicked" : (self.switch, 'sin'), "on_CosBtn_clicked" : (self.switch, 'cos'), "on_TanBtn_clicked" : (self.switch, 'tan'), "on_LogBtn_clicked" : (self.switch, 'log'), "on_MinPlusBtn_clicked" : (self.switch, '-/+'), "on_1OverBtn_clicked" : (self.switch, '1/x'), "on_PowerBtn_clicked" : (self.switch, 'x^y'), "on_PIBtn_clicked" : (self.switch, 'PI'), "on_MStrBtn_clicked" : (self.switch, 'MStr'), "on_MRclBtn_clicked" : (self.switch, 'MRcl'), "on_ClrBtn_clicked" : (self.clear_all), "on_MClrBtn_clicked" : (self.switch, 'MClr')} self.wTree.signal_autoconnect(dic) self.wTree.get_widget("NumField").set_text("0.") def RegenPlugin(self, *args, **kargs): self.GetGconfEntries() self.wTree.get_widget("vbox1").set_size_request(self.width, self.height) #self.wTree.get_widget("table1").set_size_request(-1, self.height) def GetGconfEntries(self): self.client = gconf.client_get_default() self.sticky = SetGconf( self.client, "bool", "/apps/usp/plugins/calc/sticky", False ) self.minimized = SetGconf( self.client, "bool", "/apps/usp/plugins/calc/minimized", False ) self.icon = SetGconf( self.client, "string", "/apps/usp/plugins/calc/icon", 'gnome-calculator.png' ) self.width = SetGconf( self.client, "int", "/apps/usp/plugins/calc/width", 150 ) self.height = SetGconf( self.client, "int", "/apps/usp/plugins/calc/height", 150 ) def SetHidden( self, state ): if state == True: WriteGconf( self.client, "bool", "/apps/usp/plugins/calc/minimized", True ) else: WriteGconf( self.client, "bool", "/apps/usp/plugins/calc/minimized", False ) def calculate(self, widget, value=None): self.do_calculate() def clear_all(self, widget, value=None): self.do_clear() def switch(self, widget, value): if value in ['+', '-', '*', '/', 'x^y']: if (self.wTree.get_widget("NumField").get_text() != ""): try: self.firstoperand = float(self.wTree.get_widget("NumField").get_text()) self.clearbox = 1 except ValueError: self.firstoperand = 0.0 self.wTree.get_widget("NumField").set_text("0.") self.operator = value elif value in ['sin', 'log', 'tan', 'cos', '1/x', 'PI']: """ PI obviously isn't a function, but we're using it in same way """ self.do_function(value) elif value == '.': value = self.wTree.get_widget("NumField").get_text() if '.' in value: pass # already exists... else: self.wTree.get_widget("NumField").set_text(value + '.') elif value == 'MStr': try: self.memstore = float(self.wTree.get_widget("NumField").get_text()) self.clearbox = 1 except ValueError: self.memstore = 0.0 elif value == 'MRcl': self.wTree.get_widget("NumField").set_text(str(self.memstore)) elif value == 'MClr': self.memstore=0.0 elif value == '-/+': value = self.wTree.get_widget("NumField").get_text() if value[0] == '-': value = value[1:] else: value = '-' + value self.wTree.get_widget("NumField").set_text(value) def do_calculate(self): try: secondoperand = float(self.wTree.get_widget("NumField").get_text()) if self.operator == '+': self.firstoperand = self.firstoperand + secondoperand elif self.operator == '-': self.firstoperand = self.firstoperand - secondoperand elif self.operator == '*': self.firstoperand = self.firstoperand * secondoperand elif self.operator == '/': try: self.firstoperand = self.firstoperand / secondoperand except ZeroDivisionError: self.firstoperand = 0.0 self.wTree.get_widget("NumField").set_text("ERR") return elif self.operator == 'x^y': self.firstoperand = self.firstoperand ** secondoperand self.wTree.get_widget("NumField").set_text(str(self.firstoperand)) except ValueError: self.wTree.get_widget("NumField").set_text("ERR") def do_function(self, func): try: self.firstoperand = float(self.wTree.get_widget("NumField").get_text()) if func == 'sin': self.firstoperand = math.sin(self.firstoperand) elif func == 'cos': self.firstoperand = math.cos(self.firstoperand) elif func == 'tan': self.firstoperand = math.tan(self.firstoperand) elif func == 'log': self.firstoperand = math.log(self.firstoperand) elif func == '1/x': try: self.firstoperand = 1.0 / self.firstoperand except ZeroDivisionError: self.wTree.get_widget("NumField").set_text("ERR") self.clearbox = 1 self.firstoperand = 0.0 return elif func == 'PI': self.firstoperand = math.pi self.wTree.get_widget("NumField").set_text(`self.firstoperand`) except ValueError: self.do_clear() def do_clear(self): self.operator = ' ' self.wTree.get_widget("NumField").set_text("0.") self.firstoperand = 0.0 self.clearbox = 1 def enter_number(self, widget, value): if self.clearbox: self.wTree.get_widget("NumField").set_text("") self.clearbox = None self.wTree.get_widget("NumField").set_text(self.wTree.get_widget("NumField").get_text() + value) #---------------------------------------------------------------------------------------# # 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__), "calculator.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") # Content Place Holder must be eventbox2 self.content_holder = self.wTree.get_widget("eventbox2") # Set Heading, this will be used for the tab label in USPconfig self.heading = "Calculator" # GConf Stuff - This just makes sure a gconf path is there. self.gconf_dir = '/apps/usp/plugins/calc' self.client = gconf.client_get_default() self.client.add_dir('/apps/usp/plugins/calc', 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_window2_destroy" : gtk.main_quit, "on_StickyChkBtn_toggled" : self.sticky, "on_CalcIconEntry_changed" : self.icon_changed, "on_CalcWSpin_changed" : self.calcwspin, "on_CalcHSpin_changed" : self.calchspin} self.wTree.signal_autoconnect(dic) # Read Values from GConf for USPconfig Tab and Set Default Values in GConf if they don't exist. self.wTree.get_widget("StickyChkBtn").set_active(SetGconf(self.client,'bool','/apps/usp/plugins/calc/sticky',False)) self.wTree.get_widget("CalcIconEntry").set_text(SetGconf( self.client, "string", '/apps/usp/plugins/calc/icon', "calculator.png")) self.wTree.get_widget("CalcWSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/calc/width',150)) self.wTree.get_widget("CalcHSpin").set_value(SetGconf(self.client,'int','/apps/usp/plugins/calc/height',150)) # Functions for Changing Values when items checked or altered. def sticky(self, *args, **kargs): if self.wTree.get_widget("StickyChkBtn").get_active() == True: self.client.set_bool('/apps/usp/plugins/calc/sticky',True) else: self.client.set_bool('/apps/usp/plugins/calc/sticky',False) def icon_changed(self, *args, **kargs): self.client.set_string('/apps/usp/plugins/calc/icon',self.wTree.get_widget("CalcIconEntry").get_text()) def calcwspin(self, widget, **kargs): self.client.set_int('/apps/usp/plugins/calc/width',int(self.wTree.get_widget("CalcWSpin").get_value())) def calchspin(self, widget, **kargs): self.client.set_int('/apps/usp/plugins/calc/height',int(self.wTree.get_widget("CalcHSpin").get_value()))