tintwizard.py 108 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211
  1. #!/usr/bin/env python
  2. #**************************************************************************
  3. # Tintwizard
  4. #
  5. # Copyright (C) 2009 Euan Freeman <euan04@gmail.com>
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU General Public License version 3
  9. # as published by the Free Software Foundation.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. #*************************************************************************/
  19. # Last modified: 14th June 2010
  20. import pygtk
  21. pygtk.require('2.0')
  22. import gtk
  23. import os
  24. import sys
  25. import signal
  26. import webbrowser
  27. import math
  28. import shutil
  29. # Project information
  30. NAME = "tintwizard"
  31. AUTHORS = ["Euan Freeman <euan04@gmail.com>"]
  32. VERSION = "0.3.4"
  33. COMMENTS = "tintwizard generates config files for the lightweight panel replacement tint2"
  34. WEBSITE = "http://code.google.com/p/tintwizard/"
  35. # Default values for text entry fields
  36. BG_ROUNDING = "0"
  37. BG_BORDER = "0"
  38. PANEL_SIZE_X = "0"
  39. PANEL_SIZE_Y = "40"
  40. PANEL_MARGIN_X = "0"
  41. PANEL_MARGIN_Y = "0"
  42. PANEL_PADDING_X = "0"
  43. PANEL_PADDING_Y = "0"
  44. PANEL_MONITOR = "all"
  45. PANEL_AUTOHIDE_SHOW = "0.0"
  46. PANEL_AUTOHIDE_HIDE = "0.0"
  47. PANEL_AUTOHIDE_HEIGHT = "0"
  48. TASKBAR_PADDING_X = "0"
  49. TASKBAR_PADDING_Y = "0"
  50. TASKBAR_SPACING = "0"
  51. TASK_BLINKS = "7"
  52. TASK_MAXIMUM_SIZE_X = "200"
  53. TASK_MAXIMUM_SIZE_Y = "32"
  54. TASK_PADDING_X = "0"
  55. TASK_PADDING_Y = "0"
  56. TASK_SPACING = "0"
  57. TRAY_PADDING_X = "0"
  58. TRAY_PADDING_Y = "0"
  59. TRAY_SPACING = "0"
  60. TRAY_MAX_ICON_SIZE = "0"
  61. TRAY_ICON_ALPHA = "100"
  62. TRAY_ICON_SAT = "0"
  63. TRAY_ICON_BRI = "0"
  64. ICON_ALPHA = "100"
  65. ICON_SAT = "0"
  66. ICON_BRI = "0"
  67. ACTIVE_ICON_ALPHA = "100"
  68. ACTIVE_ICON_SAT = "0"
  69. ACTIVE_ICON_BRI = "0"
  70. URGENT_ICON_ALPHA = "100"
  71. URGENT_ICON_SAT = "0"
  72. URGENT_ICON_BRI = "0"
  73. ICONIFIED_ICON_ALPHA = "100"
  74. ICONIFIED_ICON_SAT = "0"
  75. ICONIFIED_ICON_BRI = "0"
  76. CLOCK_FMT_1 = "%H:%M"
  77. CLOCK_FMT_2 = "%a %d %b"
  78. CLOCK_TOOLTIP = ""
  79. CLOCK_TIME1_TIMEZONE = ""
  80. CLOCK_TIME2_TIMEZONE = ""
  81. CLOCK_TOOLTIP_TIMEZONE = ""
  82. CLOCK_PADDING_X = "0"
  83. CLOCK_PADDING_Y = "0"
  84. CLOCK_LCLICK = ""
  85. CLOCK_RCLICK = ""
  86. TOOLTIP_PADDING_X = "0"
  87. TOOLTIP_PADDING_Y = "0"
  88. TOOLTIP_SHOW_TIMEOUT = "0"
  89. TOOLTIP_HIDE_TIMEOUT = "0"
  90. BATTERY_LOW = "20"
  91. BATTERY_HIDE = "90"
  92. BATTERY_ACTION = 'notify-send "battery low"'
  93. BATTERY_PADDING_X = "0"
  94. BATTERY_PADDING_Y = "0"
  95. class TintWizardPrefGUI(gtk.Window):
  96. """The dialog window which lets the user change the default preferences."""
  97. def __init__(self, tw):
  98. """Create and shows the window."""
  99. self.tw = tw
  100. # Create top-level window
  101. gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
  102. self.set_title("Preferences")
  103. self.connect("delete_event", self.quit)
  104. self.layout = gtk.Table(2, 2, False)
  105. self.table = gtk.Table(5, 2, False)
  106. self.table.set_row_spacings(5)
  107. self.table.set_col_spacings(5)
  108. createLabel(self.table, text="Default Font", gridX=0, gridY=0)
  109. self.font = gtk.FontButton(self.tw.defaults["font"])
  110. self.font.set_alignment(0, 0.5)
  111. self.table.attach(self.font, 1, 2, 0, 1, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
  112. createLabel(self.table, text="Default Background Color", gridX=0, gridY=1)
  113. self.bgColor = gtk.ColorButton(gtk.gdk.color_parse(self.tw.defaults["bgColor"]))
  114. self.bgColor.set_alignment(0, 0.5)
  115. self.table.attach(self.bgColor, 1, 2, 1, 2, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
  116. createLabel(self.table, text="Default Foreground Color", gridX=0, gridY=2)
  117. self.fgColor = gtk.ColorButton(gtk.gdk.color_parse(self.tw.defaults["fgColor"]))
  118. self.fgColor.set_alignment(0, 0.5)
  119. self.table.attach(self.fgColor, 1, 2, 2, 3, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
  120. createLabel(self.table, text="Default Border Color", gridX=0, gridY=3)
  121. self.borderColor = gtk.ColorButton(gtk.gdk.color_parse(self.tw.defaults["borderColor"]))
  122. self.borderColor.set_alignment(0, 0.5)
  123. self.table.attach(self.borderColor, 1, 2, 3, 4, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
  124. createLabel(self.table, text="Number of background styles", gridX=0, gridY=4)
  125. self.bgCount = createEntry(self.table, maxSize=6, width=8, text=str(self.tw.defaults["bgCount"]), gridX=1, gridY=4, xExpand=True, yExpand=True)
  126. self.layout.attach(self.table, 0, 2, 0, 1, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND, xpadding=20, ypadding=5)
  127. createButton(self.layout, text="Save", stock=gtk.STOCK_SAVE, name="save", gridX=0, gridY=1, xExpand=True, yExpand=True, handler=self.save)
  128. createButton(self.layout, text="Cancel", stock=gtk.STOCK_CANCEL, name="cancel", gridX=1, gridY=1, xExpand=True, yExpand=True, handler=self.quit)
  129. self.add(self.layout)
  130. self.show_all()
  131. def quit(self, widget=None, event=None):
  132. """Destroys the window."""
  133. self.destroy()
  134. def save(self, action=None):
  135. """Called when the Save button is clicked."""
  136. if confirmDialog(self, "Overwrite configuration file?") == gtk.RESPONSE_YES:
  137. self.tw.defaults["font"] = self.font.get_font_name()
  138. self.tw.defaults["bgColor"] = rgbToHex(self.bgColor.get_color().red, self.bgColor.get_color().green, self.bgColor.get_color().blue)
  139. self.tw.defaults["fgColor"] = rgbToHex(self.fgColor.get_color().red, self.fgColor.get_color().green, self.fgColor.get_color().blue)
  140. self.tw.defaults["borderColor"] = rgbToHex(self.borderColor.get_color().red, self.borderColor.get_color().green, self.borderColor.get_color().blue)
  141. try:
  142. self.tw.defaults["bgCount"] = int(self.bgCount.get_text())
  143. except:
  144. errorDialog(self, "Invalid value for background count")
  145. return
  146. self.tw.writeConf()
  147. self.quit()
  148. class TintWizardGUI(gtk.Window):
  149. """The main window for the application."""
  150. def __init__(self):
  151. """Create and show the window."""
  152. self.filename = None
  153. self.curDir = None
  154. self.toSave = False
  155. if len(sys.argv) > 1:
  156. self.filename = sys.argv[1]
  157. self.oneConfigFile = True
  158. else:
  159. self.oneConfigFile = False
  160. # Read conf file and set default values
  161. self.readConf()
  162. if self.defaults["bgColor"] in [None, "None"]:
  163. self.defaults["bgColor"] = "#000000"
  164. if self.defaults["fgColor"] in [None, "None"]:
  165. self.defaults["fgColor"] = "#ffffff"
  166. if self.defaults["borderColor"] in [None, "None"]:
  167. self.defaults["borderColor"] = "#ffffff"
  168. if os.path.exists(os.path.expandvars("${HOME}") + "/.config/tint2"):
  169. self.curDir = os.path.expandvars("${HOME}") + "/.config/tint2"
  170. else:
  171. errorDialog("$HOME/.config/tint2/ directory not found! Is tint2 installed correctly?")
  172. Sys.exit(1)
  173. try:
  174. self.defaults["bgCount"] = int(self.defaults["bgCount"])
  175. except:
  176. self.defaults["bgCount"] = 2
  177. # Get the full location of the tint2 binary
  178. which = os.popen('which tint2')
  179. self.tint2Bin = which.readline().strip()
  180. which.close()
  181. if len(self.tint2Bin) == 0:
  182. errorDialog(self, "tint2 could not be found. Are you sure it is installed?")
  183. sys.exit(1)
  184. # Create top-level window
  185. gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
  186. self.set_title("tintwizard")
  187. self.connect("delete_event", self.quit)
  188. # self.table is our main layout manager
  189. self.table = gtk.Table(4, 1, False)
  190. # Set up the dictionary to hold all registered widgets
  191. self.propUI = {}
  192. # Create menus and toolbar items
  193. ui = """
  194. <ui>
  195. <menubar name="MenuBar">
  196. <menu action="File">
  197. <menuitem action="New" />
  198. <menuitem action="Open" />
  199. <separator />
  200. <menuitem action="Save" />
  201. <menuitem action="Save As..." />
  202. <separator />
  203. <menuitem action="Quit" />
  204. </menu>
  205. <menu action="Tint2">
  206. <menuitem action="OpenDefault" />
  207. <menuitem action="SaveDefault" />
  208. <separator />
  209. <menuitem action="Apply" />
  210. </menu>
  211. <menu action="Tools">
  212. <menuitem action="FontChange" />
  213. <separator />
  214. <menuitem action="Defaults" />
  215. </menu>
  216. <menu action="HelpMenu">
  217. <menuitem action="Help" />
  218. <menuitem action="Report Bug" />
  219. <separator />
  220. <menuitem action="About" />
  221. </menu>
  222. </menubar>
  223. <toolbar name="ToolBar">
  224. <toolitem action="New" />
  225. <toolitem action="Open" />
  226. <toolitem action="Save" />
  227. <separator />
  228. <toolitem action="Apply" />
  229. </toolbar>
  230. </ui>
  231. """
  232. # Set up UI manager
  233. self.uiManager = gtk.UIManager()
  234. accelGroup = self.uiManager.get_accel_group()
  235. self.add_accel_group(accelGroup)
  236. self.ag = gtk.ActionGroup("File")
  237. self.ag.add_actions([("File", None, "_File"),
  238. ("New",gtk.STOCK_NEW, "_New", None, "Create a new config", self.new),
  239. ("Open", gtk.STOCK_OPEN, "_Open", None, "Open an existing config", self.openFile),
  240. ("Save", gtk.STOCK_SAVE, "_Save", None, "Save the current config", self.save),
  241. ("Save As...", gtk.STOCK_SAVE_AS, "Save As", None, "Save the current config as...", self.saveAs),
  242. ("SaveDefault", None, "Save As tint2 Default", None, "Save the current config as the tint2 default", self.saveAsDef),
  243. ("OpenDefault", None, "Open tint2 Default", None, "Open the current tint2 default config", self.openDef),
  244. ("Apply", gtk.STOCK_APPLY, "Apply Config", None, "Apply the current config to tint2", self.apply),
  245. ("Quit", gtk.STOCK_QUIT, "_Quit", None, "Quit the program", self.quit),
  246. ("Tools", None, "_Tools"),
  247. ("Tint2", None, "Tint_2"),
  248. ("HelpMenu", None, "_Help"),
  249. ("FontChange",gtk.STOCK_SELECT_FONT, "Change All Fonts", None, "Change all fonts at once.", self.changeAllFonts),
  250. ("Defaults",gtk.STOCK_PREFERENCES, "Change Defaults", None, "Change tintwizard defaults.", self.changeDefaults),
  251. ("Help",gtk.STOCK_HELP, "_Help", None, "Get help with tintwizard", self.help),
  252. ("Report Bug",None, "Report Bug", None, "Report a problem with tintwizard", self.reportBug),
  253. ("About",gtk.STOCK_ABOUT, "_About Tint Wizard", None, "Find out more about Tint Wizard", self.about)])
  254. # Add main UI
  255. self.uiManager.insert_action_group(self.ag, -1)
  256. self.uiManager.add_ui_from_string(ui)
  257. if not self.oneConfigFile:
  258. # Attach menubar and toolbar to main window
  259. self.table.attach(self.uiManager.get_widget("/MenuBar"), 0, 4, 0, 1)
  260. self.table.attach(self.uiManager.get_widget("/ToolBar"), 0, 4, 1, 2)
  261. # Create notebook
  262. self.notebook = gtk.Notebook()
  263. self.notebook.set_tab_pos(gtk.POS_TOP)
  264. # Create notebook pages
  265. # Background Options
  266. self.tableBgs = gtk.Table(rows=1, columns=1, homogeneous=False)
  267. self.tableBgs.set_row_spacings(5)
  268. self.tableBgs.set_col_spacings(5)
  269. self.bgNotebook = gtk.Notebook()
  270. self.bgNotebook.set_scrollable(True)
  271. self.tableBgs.attach(self.bgNotebook, 0, 2, 0, 1)
  272. self.bgs = []
  273. # Add buttons for adding/deleting background styles
  274. createButton(self.tableBgs, text="New Background", stock=gtk.STOCK_NEW, name="addBg", gridX=0, gridY=1, xExpand=True, yExpand=True, handler=self.addBgClick)
  275. createButton(self.tableBgs, text="Delete Background", stock=gtk.STOCK_DELETE, name="delBg", gridX=1, gridY=1, xExpand=True, yExpand=True, handler=self.delBgClick)
  276. # Panel
  277. self.createPanelDisplayWidgets()
  278. self.createPanelSettingsWidgets()
  279. self.createPanelAutohideWidgets()
  280. # Taskbar
  281. self.createTaskbarWidgets()
  282. # Tasks
  283. self.createTaskSettingsWidgets()
  284. self.createNormalTasksWidgets()
  285. self.createActiveTasksWidgets()
  286. self.createUrgentTasksWidgets()
  287. self.createIconifiedTasksWidgets()
  288. # System Tray
  289. self.createSystemTrayWidgets()
  290. # Clock
  291. self.createClockDisplayWidgets()
  292. self.createClockSettingsWidgets()
  293. # Mouse
  294. self.createMouseWidgets()
  295. # Tooltips
  296. self.createTooltipsWidgets()
  297. # Battery
  298. self.createBatteryWidgets()
  299. # View Config
  300. self.configArea = gtk.ScrolledWindow()
  301. self.configBuf = gtk.TextBuffer()
  302. self.configTextView = gtk.TextView(self.configBuf)
  303. self.configArea.add_with_viewport(self.configTextView)
  304. # Add backgrounds to notebooks
  305. for i in range(self.defaults["bgCount"]):
  306. self.addBgClick(None, init=True)
  307. self.bgNotebook.set_current_page(0)
  308. # Create sub-notebooks
  309. self.panelNotebook = gtk.Notebook()
  310. self.panelNotebook.set_tab_pos(gtk.POS_TOP)
  311. self.panelNotebook.set_current_page(0)
  312. self.panelNotebook.append_page(self.tablePanelDisplay, gtk.Label("Panel Display"))
  313. self.panelNotebook.append_page(self.tablePanelSettings, gtk.Label("Panel Settings"))
  314. self.panelNotebook.append_page(self.tablePanelAutohide, gtk.Label("Panel Autohide"))
  315. self.taskNotebook = gtk.Notebook()
  316. self.taskNotebook.set_tab_pos(gtk.POS_TOP)
  317. self.taskNotebook.set_current_page(0)
  318. self.taskNotebook.append_page(self.tableTask, gtk.Label("Task Settings"))
  319. self.taskNotebook.append_page(self.tableTaskDefault, gtk.Label("Normal Tasks"))
  320. self.taskNotebook.append_page(self.tableTaskActive, gtk.Label("Active Tasks"))
  321. self.taskNotebook.append_page(self.tableTaskUrgent, gtk.Label("Urgent Tasks"))
  322. self.taskNotebook.append_page(self.tableTaskIconified, gtk.Label("Iconified Tasks"))
  323. self.clockNotebook = gtk.Notebook()
  324. self.clockNotebook.set_tab_pos(gtk.POS_TOP)
  325. self.clockNotebook.set_current_page(0)
  326. self.clockNotebook.append_page(self.tableClockDisplays, gtk.Label("Clock Display"))
  327. self.clockNotebook.append_page(self.tableClockSettings, gtk.Label("Clock Settings"))
  328. # Add pages to notebook
  329. self.notebook.append_page(self.tableBgs, gtk.Label("Backgrounds"))
  330. self.notebook.append_page(self.panelNotebook, gtk.Label("Panel"))
  331. self.notebook.append_page(self.tableTaskbar, gtk.Label("Taskbar"))
  332. self.notebook.append_page(self.taskNotebook, gtk.Label("Tasks"))
  333. self.notebook.append_page(self.tableTray, gtk.Label("System Tray"))
  334. self.notebook.append_page(self.clockNotebook, gtk.Label("Clock"))
  335. self.notebook.append_page(self.tableMouse, gtk.Label("Mouse"))
  336. self.notebook.append_page(self.tableTooltip, gtk.Label("Tooltips"))
  337. self.notebook.append_page(self.tableBattery, gtk.Label("Battery"))
  338. self.notebook.append_page(self.configArea, gtk.Label("View Config"))
  339. self.notebook.connect("switch-page", self.switchPage)
  340. # Add notebook to window and show
  341. self.table.attach(self.notebook, 0, 4, 2, 3, xpadding=5, ypadding=5)
  342. if self.oneConfigFile:
  343. # Add button Apply and Close
  344. self.box1 = gtk.HBox(False, 20)
  345. self.table.attach(self.box1, 0, 4, 3, 4, xpadding=5, ypadding=5)
  346. temp = gtk.Button("Apply", gtk.STOCK_APPLY)
  347. temp.set_name("applyBg")
  348. temp.connect("clicked", self.apply)
  349. self.box1.pack_start(temp, True, True, 0)
  350. temp = gtk.Button("Close", gtk.STOCK_CLOSE)
  351. temp.set_name("closeBg")
  352. temp.connect("clicked", self.quit)
  353. self.box1.pack_start(temp, True, True, 0)
  354. # Create and add the status bar to the bottom of the main window
  355. self.statusBar = gtk.Statusbar()
  356. self.statusBar.set_has_resize_grip(True)
  357. self.updateStatusBar("New Config File [*]")
  358. self.table.attach(self.statusBar, 0, 4, 4, 5)
  359. self.add(self.table)
  360. self.show_all()
  361. # If tintwizard was launched with a tint2 config filename
  362. # as an argument, load that config.
  363. if self.oneConfigFile:
  364. self.readTint2Config()
  365. self.generateConfig()
  366. def createPanelDisplayWidgets(self):
  367. """Create the Panel Display widgets."""
  368. self.tablePanelDisplay = gtk.Table(rows=6, columns=3, homogeneous=False)
  369. self.tablePanelDisplay.set_row_spacings(5)
  370. self.tablePanelDisplay.set_col_spacings(5)
  371. createLabel(self.tablePanelDisplay, text="Position", gridX=0, gridY=0, xPadding=10)
  372. self.panelPosY = createComboBox(self.tablePanelDisplay, ["bottom", "top", "center"], gridX=1, gridY=0, handler=self.changeOccurred)
  373. self.panelPosX = createComboBox(self.tablePanelDisplay, ["left", "right", "center"], gridX=2, gridY=0, handler=self.changeOccurred)
  374. # Note: registered below
  375. createLabel(self.tablePanelDisplay, text="Panel Orientation", gridX=0, gridY=1, xPadding=10)
  376. self.panelOrientation = createComboBox(self.tablePanelDisplay, ["horizontal", "vertical"], gridX=1, gridY=1, handler=self.changeOccurred)
  377. self.registerComponent("panel_position", (self.panelPosY, self.panelPosX, self.panelOrientation))
  378. self.panelSizeLabel = createLabel(self.tablePanelDisplay, text="Size (width, height)", gridX=0, gridY=2, xPadding=10)
  379. self.panelSizeX = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=PANEL_SIZE_X, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  380. self.panelSizeY = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=PANEL_SIZE_Y, gridX=2, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  381. self.registerComponent("panel_size", (self.panelSizeX, self.panelSizeY))
  382. createLabel(self.tablePanelDisplay, text="Margin (x, y)", gridX=0, gridY=3, xPadding=10)
  383. self.panelMarginX = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=PANEL_MARGIN_X, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  384. self.panelMarginY = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=PANEL_MARGIN_Y, gridX=2, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  385. self.registerComponent("panel_margin", (self.panelMarginX, self.panelMarginY))
  386. createLabel(self.tablePanelDisplay, text="Padding (x, y)", gridX=0, gridY=4, xPadding=10)
  387. self.panelPadX = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=PANEL_PADDING_X, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  388. self.panelPadY = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=PANEL_PADDING_Y, gridX=2, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  389. # Note: added below
  390. createLabel(self.tablePanelDisplay, text="Horizontal Spacing", gridX=0, gridY=5, xPadding=10)
  391. self.panelSpacing = createEntry(self.tablePanelDisplay, maxSize=6, width=8, text=TASKBAR_SPACING, gridX=1, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  392. self.registerComponent("panel_padding", (self.panelPadX, self.panelPadY, self.panelSpacing))
  393. createLabel(self.tablePanelDisplay, text="Panel Background ID", gridX=0, gridY=6, xPadding=10)
  394. self.panelBg = createComboBox(self.tablePanelDisplay, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=6, handler=self.changeOccurred)
  395. self.registerComponent("panel_background_id", self.panelBg)
  396. def createPanelSettingsWidgets(self):
  397. """Create the Panel Settings widgets."""
  398. self.tablePanelSettings = gtk.Table(rows=5, columns=3, homogeneous=False)
  399. self.tablePanelSettings.set_row_spacings(5)
  400. self.tablePanelSettings.set_col_spacings(5)
  401. createLabel(self.tablePanelSettings, text="Window Manager Menu", gridX=0, gridY=0, xPadding=10)
  402. self.panelMenu = createCheckButton(self.tablePanelSettings, active=False, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  403. self.registerComponent("wm_menu", self.panelMenu)
  404. createLabel(self.tablePanelSettings, text="Place In Window Manager Dock", gridX=0, gridY=1, xPadding=10)
  405. self.panelDock = createCheckButton(self.tablePanelSettings, active=False, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  406. self.registerComponent("panel_dock", self.panelDock)
  407. createLabel(self.tablePanelSettings, text="Panel Layer", gridX=0, gridY=2, xPadding=10)
  408. self.panelLayer = createComboBox(self.tablePanelSettings, ["bottom", "top", "normal"], gridX=1, gridY=2, handler=self.changeOccurred)
  409. self.registerComponent("panel_layer", self.panelLayer)
  410. createLabel(self.tablePanelSettings, text="Strut Policy", gridX=0, gridY=3, xPadding=10)
  411. self.panelAutohideStrut = createComboBox(self.tablePanelSettings, ["none", "minimum", "follow_size"], gridX=1, gridY=3, handler=self.changeOccurred)
  412. self.registerComponent("strut_policy", self.panelAutohideStrut)
  413. createLabel(self.tablePanelSettings, text="Panel Monitor (all, 1, 2, ...)", gridX=0, gridY=4, xPadding=10)
  414. self.panelMonitor = createEntry(self.tablePanelSettings, maxSize=6, width=8, text=PANEL_MONITOR, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  415. self.registerComponent("panel_monitor", self.panelMonitor)
  416. def createPanelAutohideWidgets(self):
  417. """Create the Panel Autohide widgets."""
  418. self.tablePanelAutohide = gtk.Table(rows=4, columns=3, homogeneous=False)
  419. self.tablePanelAutohide.set_row_spacings(5)
  420. self.tablePanelAutohide.set_col_spacings(5)
  421. createLabel(self.tablePanelAutohide, text="Autohide Panel", gridX=0, gridY=0, xPadding=10)
  422. self.panelAutohide = createCheckButton(self.tablePanelAutohide, active=False, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  423. self.registerComponent("autohide", self.panelAutohide)
  424. createLabel(self.tablePanelAutohide, text="Autohide Show Timeout (seconds)", gridX=0, gridY=1, xPadding=10)
  425. self.panelAutohideShow = createEntry(self.tablePanelAutohide, maxSize=6, width=8, text=PANEL_AUTOHIDE_SHOW, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  426. self.registerComponent("autohide_show_timeout", self.panelAutohideShow)
  427. createLabel(self.tablePanelAutohide, text="Autohide Hide Timeout (seconds)", gridX=0, gridY=2, xPadding=10)
  428. self.panelAutohideHide = createEntry(self.tablePanelAutohide, maxSize=6, width=8, text=PANEL_AUTOHIDE_HIDE, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  429. self.registerComponent("autohide_hide_timeout", self.panelAutohideHide)
  430. createLabel(self.tablePanelAutohide, text="Autohide Hidden Height", gridX=0, gridY=3, xPadding=10)
  431. self.panelAutohideHeight = createEntry(self.tablePanelAutohide, maxSize=6, width=8, text=PANEL_AUTOHIDE_HEIGHT, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  432. self.registerComponent("autohide_height", self.panelAutohideHeight)
  433. def createTaskbarWidgets(self):
  434. """Create the Taskbar widgets."""
  435. self.tableTaskbar = gtk.Table(rows=5, columns=3, homogeneous=False)
  436. self.tableTaskbar.set_row_spacings(5)
  437. self.tableTaskbar.set_col_spacings(5)
  438. createLabel(self.tableTaskbar, text="Taskbar Mode", gridX=0, gridY=0, xPadding=10)
  439. self.taskbarMode = createComboBox(self.tableTaskbar, ["single_desktop", "multi_desktop"], gridX=1, gridY=0, handler=self.changeOccurred)
  440. self.registerComponent("taskbar_mode", self.taskbarMode)
  441. createLabel(self.tableTaskbar, text="Padding (x, y)", gridX=0, gridY=1, xPadding=10)
  442. self.taskbarPadX = createEntry(self.tableTaskbar, maxSize=6, width=8, text=TASKBAR_PADDING_X, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  443. self.taskbarPadY = createEntry(self.tableTaskbar, maxSize=6, width=8, text=TASKBAR_PADDING_Y, gridX=2, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  444. # Note: added below
  445. createLabel(self.tableTaskbar, text="Horizontal Spacing", gridX=0, gridY=2, xPadding=10)
  446. self.taskbarSpacing = createEntry(self.tableTaskbar, maxSize=6, width=8, text=TASK_SPACING, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  447. self.registerComponent("taskbar_padding", (self.taskbarPadX, self.taskbarPadY, self.taskbarSpacing))
  448. createLabel(self.tableTaskbar, text="Taskbar Background ID", gridX=0, gridY=3, xPadding=10)
  449. self.taskbarBg = createComboBox(self.tableTaskbar, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=3, handler=self.changeOccurred)
  450. self.registerComponent("taskbar_background_id", self.taskbarBg)
  451. createLabel(self.tableTaskbar, text="Active Taskbar Background ID", gridX=0, gridY=4, xPadding=10)
  452. self.taskbarActiveBg = createComboBox(self.tableTaskbar, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=4, handler=self.changeOccurred)
  453. self.taskbarActiveBgEnable = createCheckButton(self.tableTaskbar, text="Enable", active=False, gridX=2, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  454. self.registerComponent("taskbar_active_background_id", self.taskbarActiveBg)
  455. def createTaskSettingsWidgets(self):
  456. """Create the Task Settings widgets."""
  457. self.tableTask = gtk.Table(rows=12, columns=3, homogeneous=False)
  458. self.tableTask.set_row_spacings(5)
  459. self.tableTask.set_col_spacings(5)
  460. createLabel(self.tableTask, text="Number of 'Blinks' on Urgent Event", gridX=0, gridY=0, xPadding=10)
  461. self.taskBlinks = createEntry(self.tableTask, maxSize=6, width=8, text=TASK_BLINKS, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  462. self.registerComponent("urgent_nb_of_blink", self.taskBlinks)
  463. createLabel(self.tableTask, text="Show Icons", gridX=0, gridY=1, xPadding=10)
  464. self.taskIconCheckButton = createCheckButton(self.tableTask, active=True, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  465. self.registerComponent("task_icon", self.taskIconCheckButton)
  466. createLabel(self.tableTask, text="Show Text", gridX=0, gridY=2, xPadding=10)
  467. self.taskTextCheckButton = createCheckButton(self.tableTask, active=True, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  468. self.registerComponent("task_text", self.taskTextCheckButton)
  469. createLabel(self.tableTask, text="Centre Text", gridX=0, gridY=3, xPadding=10)
  470. self.taskCentreCheckButton = createCheckButton(self.tableTask, active=True, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  471. self.registerComponent("task_centered", self.taskCentreCheckButton)
  472. createLabel(self.tableTask, text="Font", gridX=0, gridY=4, xPadding=10)
  473. self.fontButton = gtk.FontButton()
  474. if self.defaults["font"] in [None, "None"]: # If there was no font specified in the config file
  475. self.defaults["font"] = self.fontButton.get_font_name() # Use the gtk default
  476. self.fontButton = createFontButton(self.tableTask, font=self.defaults["font"], gridX=1, gridY=4, handler=self.changeOccurred)
  477. self.registerComponent("task_font", self.fontButton)
  478. createLabel(self.tableTask, text="Show Font Shadow", gridX=0, gridY=5, xPadding=10)
  479. self.fontShadowCheckButton = createCheckButton(self.tableTask, active=False, gridX=1, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  480. self.registerComponent("font_shadow", self.fontShadowCheckButton)
  481. createLabel(self.tableTask, text="Maximum Size (x, y)", gridX=0, gridY=6, xPadding=10)
  482. self.taskMaxSizeX = createEntry(self.tableTask, maxSize=6, width=8, text=TASK_MAXIMUM_SIZE_X, gridX=1, gridY=6, xExpand=True, yExpand=False, handler=self.changeOccurred)
  483. self.taskMaxSizeY = createEntry(self.tableTask, maxSize=6, width=8, text=TASK_MAXIMUM_SIZE_Y, gridX=2, gridY=6, xExpand=True, yExpand=False, handler=self.changeOccurred)
  484. self.registerComponent("task_maximum_size", (self.taskMaxSizeX, self.taskMaxSizeY))
  485. createLabel(self.tableTask, text="Padding (x, y)", gridX=0, gridY=7, xPadding=10)
  486. self.taskPadX = createEntry(self.tableTask, maxSize=6, width=8, text=TASK_PADDING_X, gridX=1, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  487. self.taskPadY = createEntry(self.tableTask, maxSize=6, width=8, text=TASK_PADDING_Y, gridX=2, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  488. self.registerComponent("task_padding", (self.taskPadX, self.taskPadY))
  489. def createNormalTasksWidgets(self):
  490. """Create the Normal Tasks widgets."""
  491. self.tableTaskDefault = gtk.Table(rows=6, columns=3, homogeneous=False)
  492. self.tableTaskDefault.set_row_spacings(5)
  493. self.tableTaskDefault.set_col_spacings(5)
  494. createLabel(self.tableTaskDefault, text="Normal Task Background ID", gridX=0, gridY=0, xPadding=10)
  495. self.taskBg = createComboBox(self.tableTaskDefault, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=0, handler=self.changeOccurred)
  496. self.registerComponent("task_background_id", self.taskBg)
  497. createLabel(self.tableTaskDefault, text="Note: Default values of 0 for each of these settings leaves icons unchanged!", gridX=0, gridY=1, sizeX=3, xPadding=10)
  498. createLabel(self.tableTaskDefault, text="Normal Icon Alpha (0 to 100)", gridX=0, gridY=2, xPadding=10)
  499. self.iconHue = createEntry(self.tableTaskDefault, maxSize=6, width=8, text=ICON_ALPHA, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  500. # Note: added below
  501. createLabel(self.tableTaskDefault, text="Normal Icon Saturation (-100 to 100)", gridX=0, gridY=3, xPadding=10)
  502. self.iconSat = createEntry(self.tableTaskDefault, maxSize=6, width=8, text=ICON_SAT, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  503. # Note: added below
  504. createLabel(self.tableTaskDefault, text="Normal Icon Brightness (-100 to 100)", gridX=0, gridY=4, xPadding=10)
  505. self.iconBri = createEntry(self.tableTaskDefault, maxSize=6, width=8, text=ICON_BRI, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  506. self.registerComponent("task_icon_asb", (self.iconHue, self.iconSat, self.iconBri))
  507. createLabel(self.tableTaskDefault, text="Normal Font Color", gridX=0, gridY=5, xPadding=10)
  508. self.fontCol = createEntry(self.tableTaskDefault, maxSize=7, width=9, text="", gridX=1, gridY=5, xExpand=True, yExpand=False, handler=None, name="fontCol")
  509. self.fontCol.connect("activate", self.colorTyped)
  510. self.fontColButton = createColorButton(self.tableTaskDefault, color=self.defaults["fgColor"], useAlpha=True, name="fontCol", gridX=2, gridY=5, handler=self.colorChange)
  511. self.fontCol.set_text(self.defaults["fgColor"])
  512. # Add this AFTER we set color to avoid "changed" event
  513. self.fontCol.connect("changed", self.changeOccurred)
  514. self.registerComponent("task_font_color", (self.fontCol, self.fontColButton))
  515. def createActiveTasksWidgets(self):
  516. """Create the Active Tasks widgets."""
  517. self.tableTaskActive = gtk.Table(rows=6, columns=3, homogeneous=False)
  518. self.tableTaskActive.set_row_spacings(5)
  519. self.tableTaskActive.set_col_spacings(5)
  520. createLabel(self.tableTaskActive, text="Active Task Background ID", gridX=0, gridY=0, xPadding=10)
  521. self.taskActiveBg = createComboBox(self.tableTaskActive, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=0, handler=self.changeOccurred)
  522. self.registerComponent("task_active_background_id", self.taskActiveBg)
  523. createLabel(self.tableTaskActive, text="Note: Default values of 0 for each of these settings leaves icons unchanged!", gridX=0, gridY=1, sizeX=3, xPadding=10)
  524. createLabel(self.tableTaskActive, text="Active Icon Alpha (0 to 100)", gridX=0, gridY=2, xPadding=10)
  525. self.activeIconHue = createEntry(self.tableTaskActive, maxSize=6, width=8, text=ACTIVE_ICON_ALPHA, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  526. # Note: added below
  527. createLabel(self.tableTaskActive, text="Active Icon Saturation (-100 to 100)", gridX=0, gridY=3, xPadding=10)
  528. self.activeIconSat = createEntry(self.tableTaskActive, maxSize=6, width=8, text=ACTIVE_ICON_SAT, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  529. # Note: added below
  530. createLabel(self.tableTaskActive, text="Active Icon Brightness (-100 to 100)", gridX=0, gridY=4, xPadding=10)
  531. self.activeIconBri = createEntry(self.tableTaskActive, maxSize=6, width=8, text=ACTIVE_ICON_BRI, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  532. self.registerComponent("task_active_icon_asb", (self.activeIconHue, self.activeIconSat, self.activeIconBri))
  533. createLabel(self.tableTaskActive, text="Active Font Color", gridX=0, gridY=5, xPadding=10)
  534. self.fontActiveCol = createEntry(self.tableTaskActive, maxSize=7, width=9, text="", gridX=1, gridY=5, xExpand=True, yExpand=False, handler=None, name="fontActiveCol")
  535. self.fontActiveCol.connect("activate", self.colorTyped)
  536. self.fontActiveColButton = createColorButton(self.tableTaskActive, color=self.defaults["fgColor"], useAlpha=True, name="fontActiveCol", gridX=2, gridY=5, handler=self.colorChange)
  537. self.fontActiveCol.set_text(self.defaults["fgColor"])
  538. # Add this AFTER we set color to avoid "changed" event
  539. self.fontActiveCol.connect("changed", self.changeOccurred)
  540. self.registerComponent("task_active_font_color", (self.fontActiveCol, self.fontActiveColButton))
  541. def createUrgentTasksWidgets(self):
  542. """Create the Urgent Tasks widgets."""
  543. self.tableTaskUrgent = gtk.Table(rows=6, columns=3, homogeneous=False)
  544. self.tableTaskUrgent.set_row_spacings(5)
  545. self.tableTaskUrgent.set_col_spacings(5)
  546. createLabel(self.tableTaskUrgent, text="Urgent Task Background ID", gridX=0, gridY=0, xPadding=10)
  547. self.taskUrgentBg = createComboBox(self.tableTaskUrgent, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=0, handler=self.changeOccurred)
  548. self.registerComponent("task_urgent_background_id", self.taskUrgentBg)
  549. createLabel(self.tableTaskUrgent, text="Note: Default values of 0 for each of these settings leaves icons unchanged!", gridX=0, gridY=1, sizeX=3, xPadding=10)
  550. createLabel(self.tableTaskUrgent, text="Urgent Icon Alpha (0 to 100)", gridX=0, gridY=2, xPadding=10)
  551. self.urgentIconHue = createEntry(self.tableTaskUrgent, maxSize=6, width=8, text=URGENT_ICON_ALPHA, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  552. # Note: added below
  553. createLabel(self.tableTaskUrgent, text="Urgent Icon Saturation (-100 to 100)", gridX=0, gridY=3, xPadding=10)
  554. self.urgentIconSat = createEntry(self.tableTaskUrgent, maxSize=6, width=8, text=URGENT_ICON_SAT, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  555. # Note: added below
  556. createLabel(self.tableTaskUrgent, text="Urgent Icon Brightness (-100 to 100)", gridX=0, gridY=4, xPadding=10)
  557. self.urgentIconBri = createEntry(self.tableTaskUrgent, maxSize=6, width=8, text=URGENT_ICON_BRI, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  558. self.registerComponent("task_urgent_icon_asb", (self.urgentIconHue, self.urgentIconSat, self.urgentIconBri))
  559. createLabel(self.tableTaskUrgent, text="Urgent Font Color", gridX=0, gridY=5, xPadding=10)
  560. self.fontUrgentCol = createEntry(self.tableTaskUrgent, maxSize=7, width=9, text="", gridX=1, gridY=5, xExpand=True, yExpand=False, handler=None, name="fontUrgentCol")
  561. self.fontUrgentCol.connect("activate", self.colorTyped)
  562. self.fontUrgentColButton = createColorButton(self.tableTaskUrgent, color=self.defaults["fgColor"], useAlpha=True, name="fontUrgentCol", gridX=2, gridY=5, handler=self.colorChange)
  563. self.fontUrgentCol.set_text(self.defaults["fgColor"])
  564. # Add this AFTER we set color to avoid "changed" event
  565. self.fontUrgentCol.connect("changed", self.changeOccurred)
  566. self.registerComponent("task_urgent_font_color", (self.fontUrgentCol, self.fontUrgentColButton))
  567. def createIconifiedTasksWidgets(self):
  568. """Create the Iconified Tasks widgets."""
  569. self.tableTaskIconified = gtk.Table(rows=6, columns=3, homogeneous=False)
  570. self.tableTaskIconified.set_row_spacings(5)
  571. self.tableTaskIconified.set_col_spacings(5)
  572. createLabel(self.tableTaskIconified, text="Iconified Task Background ID", gridX=0, gridY=0, xPadding=10)
  573. self.taskIconifiedBg = createComboBox(self.tableTaskIconified, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=0, handler=self.changeOccurred)
  574. self.registerComponent("task_iconified_background_id", self.taskIconifiedBg)
  575. createLabel(self.tableTaskIconified, text="Note: Default values of 0 for each of these settings leaves icons unchanged!", gridX=0, gridY=1, sizeX=3, xPadding=10)
  576. createLabel(self.tableTaskIconified, text="Iconified Icon Alpha (0 to 100)", gridX=0, gridY=2, xPadding=10)
  577. self.iconifiedIconHue = createEntry(self.tableTaskIconified, maxSize=6, width=8, text=ICONIFIED_ICON_ALPHA, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  578. # Note: added below
  579. createLabel(self.tableTaskIconified, text="Iconified Icon Saturation (-100 to 100)", gridX=0, gridY=3, xPadding=10)
  580. self.iconifiedIconSat = createEntry(self.tableTaskIconified, maxSize=6, width=8, text=ICONIFIED_ICON_SAT, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  581. # Note: added below
  582. createLabel(self.tableTaskIconified, text="Iconified Icon Brightness (-100 to 100)", gridX=0, gridY=4, xPadding=10)
  583. self.iconifiedIconBri = createEntry(self.tableTaskIconified, maxSize=6, width=8, text=ICONIFIED_ICON_BRI, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  584. self.registerComponent("task_iconified_icon_asb", (self.iconifiedIconHue, self.iconifiedIconSat, self.iconifiedIconBri))
  585. createLabel(self.tableTaskIconified, text="Iconified Font Color", gridX=0, gridY=5, xPadding=10)
  586. self.fontIconifiedCol = createEntry(self.tableTaskIconified, maxSize=7, width=9, text="", gridX=1, gridY=5, xExpand=True, yExpand=False, handler=None, name="fontIconifiedCol")
  587. self.fontIconifiedCol.connect("activate", self.colorTyped)
  588. self.fontIconifiedColButton = createColorButton(self.tableTaskIconified, color=self.defaults["fgColor"], useAlpha=True, name="fontIconifiedCol", gridX=2, gridY=5, handler=self.colorChange)
  589. self.fontIconifiedCol.set_text(self.defaults["fgColor"])
  590. # Add this AFTER we set color to avoid "changed" event
  591. self.fontIconifiedCol.connect("changed", self.changeOccurred)
  592. self.registerComponent("task_iconified_font_color", (self.fontIconifiedCol, self.fontIconifiedColButton))
  593. def createSystemTrayWidgets(self):
  594. """Create the System Tray widgets."""
  595. self.tableTray = gtk.Table(rows=9, columns=3, homogeneous=False)
  596. self.tableTray.set_row_spacings(5)
  597. self.tableTray.set_col_spacings(5)
  598. createLabel(self.tableTray, text="Show System Tray", gridX=0, gridY=0, xPadding=10)
  599. self.trayShow = createCheckButton(self.tableTray, active=True, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  600. self.registerComponent("systray", self.trayShow)
  601. createLabel(self.tableTray, text="Padding (x, y)", gridX=0, gridY=1, xPadding=10)
  602. self.trayPadX = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_PADDING_X, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  603. self.trayPadY = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_PADDING_Y, gridX=2, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  604. # Note: added below
  605. createLabel(self.tableTray, text="Horizontal Spacing", gridX=0, gridY=2, xPadding=10)
  606. self.traySpacing = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_SPACING, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  607. self.registerComponent("systray_padding", (self.trayPadX, self.trayPadY, self.traySpacing))
  608. createLabel(self.tableTray, text="System Tray Background ID", gridX=0, gridY=3, xPadding=10)
  609. self.trayBg = createComboBox(self.tableTray, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=3, handler=self.changeOccurred)
  610. self.registerComponent("systray_background_id", self.trayBg)
  611. createLabel(self.tableTray, text="Icon Ordering", gridX=0, gridY=4, xPadding=10)
  612. self.trayOrder = createComboBox(self.tableTray, ["ascending", "descending", "left2right", "right2left"], gridX=1, gridY=4, handler=self.changeOccurred)
  613. self.registerComponent("systray_sort", self.trayOrder)
  614. createLabel(self.tableTray, text="Maximum Icon Size (0 for automatic size)", gridX=0, gridY=5, xPadding=10)
  615. self.trayMaxIconSize = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_MAX_ICON_SIZE, gridX=1, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  616. self.registerComponent("systray_icon_size", self.trayMaxIconSize)
  617. createLabel(self.tableTray, text="System Tray Icon Alpha (0 to 100)", gridX=0, gridY=6, xPadding=10)
  618. self.trayIconHue = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_ICON_ALPHA, gridX=1, gridY=6, xExpand=True, yExpand=False, handler=self.changeOccurred)
  619. # Note: added below
  620. createLabel(self.tableTray, text="System Tray Icon Saturation (-100 to 100)", gridX=0, gridY=7, xPadding=10)
  621. self.trayIconSat = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_ICON_SAT, gridX=1, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  622. # Note: added below
  623. createLabel(self.tableTray, text="System Tray Icon Brightness (-100 to 100)", gridX=0, gridY=8, xPadding=10)
  624. self.trayIconBri = createEntry(self.tableTray, maxSize=6, width=8, text=TRAY_ICON_BRI, gridX=1, gridY=8, xExpand=True, yExpand=False, handler=self.changeOccurred)
  625. self.registerComponent("systray_icon_asb", (self.trayIconHue, self.trayIconSat, self.trayIconBri))
  626. def createClockDisplayWidgets(self):
  627. """Create the Clock Display widgets."""
  628. self.tableClockDisplays = gtk.Table(rows=3, columns=3, homogeneous=False)
  629. self.tableClockDisplays.set_row_spacings(5)
  630. self.tableClockDisplays.set_col_spacings(5)
  631. createLabel(self.tableClockDisplays, text="Show", gridX=0, gridY=0, xPadding=10)
  632. self.clockCheckButton = createCheckButton(self.tableClockDisplays, active=True, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  633. createLabel(self.tableClockDisplays, text="Time 1 Format", gridX=0, gridY=1, xPadding=10)
  634. self.clock1Format = createEntry(self.tableClockDisplays, maxSize=50, width=20, text=CLOCK_FMT_1, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  635. self.clock1CheckButton = createCheckButton(self.tableClockDisplays, text="Show", active=True, gridX=2, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  636. self.registerComponent("time1_format", self.clock1Format)
  637. createLabel(self.tableClockDisplays, text="Time 1 Font", gridX=0, gridY=2, xPadding=10)
  638. self.clock1FontButton = createFontButton(self.tableClockDisplays, font=self.defaults["font"], gridX=1, gridY=2, handler=self.changeOccurred)
  639. self.registerComponent("time1_font", self.clock1FontButton)
  640. createLabel(self.tableClockDisplays, text="Time 2 Format", gridX=0, gridY=3, xPadding=10)
  641. self.clock2Format = createEntry(self.tableClockDisplays, maxSize=50, width=20, text=CLOCK_FMT_2, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  642. self.clock2CheckButton = createCheckButton(self.tableClockDisplays, text="Show", active=True, gridX=2, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  643. self.registerComponent("time2_format", self.clock2Format)
  644. createLabel(self.tableClockDisplays, text="Time 2 Font", gridX=0, gridY=4, xPadding=10)
  645. self.clock2FontButton = createFontButton(self.tableClockDisplays, font=self.defaults["font"], gridX=1, gridY=4, handler=self.changeOccurred)
  646. self.registerComponent("time2_font", self.clock2FontButton)
  647. createLabel(self.tableClockDisplays, text="Tooltip Format", gridX=0, gridY=5, xPadding=10)
  648. self.clockTooltipFormat = createEntry(self.tableClockDisplays, maxSize=50, width=20, text=CLOCK_TOOLTIP, gridX=1, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  649. self.clockTooltipCheckButton = createCheckButton(self.tableClockDisplays, text="Show", active=True, gridX=2, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  650. self.registerComponent("clock_tooltip", self.clockTooltipFormat)
  651. self.clockArea = gtk.ScrolledWindow()
  652. self.clockBuf = gtk.TextBuffer()
  653. self.clockTextView = gtk.TextView(self.clockBuf)
  654. self.clockBuf.insert_at_cursor("%H 00-23 (24-hour) %I 01-12 (12-hour) %l 1-12 (12-hour) %M 00-59 (minutes)\n%S 00-59 (seconds) %P am/pm %b Jan-Dec %B January-December\n%a Sun-Sat %A Sunday-Saturday %d 01-31 (day) %e 1-31 (day)\n%y 2 digit year, e.g. 09 %Y 4 digit year, e.g. 2009")
  655. self.clockTextView.set_editable(False)
  656. self.clockArea.add_with_viewport(self.clockTextView)
  657. self.tableClockDisplays.attach(self.clockArea, 0, 3, 6, 7, xpadding=10)
  658. def createClockSettingsWidgets(self):
  659. """Create the Clock Settings widgets."""
  660. self.tableClockSettings = gtk.Table(rows=3, columns=3, homogeneous=False)
  661. self.tableClockSettings.set_row_spacings(5)
  662. self.tableClockSettings.set_col_spacings(5)
  663. createLabel(self.tableClockSettings, text="Clock Font Color", gridX=0, gridY=0, xPadding=10)
  664. self.clockFontCol = createEntry(self.tableClockSettings, maxSize=7, width=9, text="", gridX=1, gridY=0, xExpand=True, yExpand=False, handler=None, name="clockFontCol")
  665. self.clockFontCol.connect("activate", self.colorTyped)
  666. self.clockFontColButton = createColorButton(self.tableClockSettings, color=self.defaults["fgColor"], useAlpha=True, name="clockFontCol", gridX=2, gridY=0, handler=self.colorChange)
  667. self.clockFontCol.set_text(self.defaults["fgColor"])
  668. # Add this AFTER we set color to avoid "changed" event
  669. self.clockFontCol.connect("changed", self.changeOccurred)
  670. self.registerComponent("clock_font_color", (self.clockFontCol, self.clockFontColButton))
  671. createLabel(self.tableClockSettings, text="Padding (x, y)", gridX=0, gridY=1, xPadding=10)
  672. self.clockPadX = createEntry(self.tableClockSettings, maxSize=6, width=8, text=CLOCK_PADDING_X, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  673. self.clockPadY = createEntry(self.tableClockSettings, maxSize=6, width=8, text=CLOCK_PADDING_Y, gridX=2, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  674. self.registerComponent("clock_padding", (self.clockPadX, self.clockPadY))
  675. createLabel(self.tableClockSettings, text="Clock Background ID", gridX=0, gridY=2, xPadding=10)
  676. self.clockBg = createComboBox(self.tableClockSettings, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=2, handler=self.changeOccurred)
  677. self.registerComponent("clock_background_id", self.clockBg)
  678. createLabel(self.tableClockSettings, text="Left Click Command", gridX=0, gridY=3, xPadding=10)
  679. self.clockLClick = createEntry(self.tableClockSettings, maxSize=50, width=20, text=CLOCK_LCLICK, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  680. self.registerComponent("clock_lclick_command", self.clockLClick)
  681. createLabel(self.tableClockSettings, text="Right Click Command", gridX=0, gridY=4, xPadding=10)
  682. self.clockRClick = createEntry(self.tableClockSettings, maxSize=50, width=20, text=CLOCK_RCLICK, gridX=1, gridY=4, xExpand=True, yExpand=False, handler=self.changeOccurred)
  683. self.registerComponent("clock_rclick_command", self.clockRClick)
  684. createLabel(self.tableClockSettings, text="Time 1 Timezone", gridX=0, gridY=5, xPadding=10)
  685. self.clockTime1Timezone = createEntry(self.tableClockSettings, maxSize=50, width=20, text=CLOCK_TIME1_TIMEZONE, gridX=1, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  686. self.clockTimezone1CheckButton = createCheckButton(self.tableClockSettings, text="Enable", active=False, gridX=2, gridY=5, xExpand=True, yExpand=False, handler=self.changeOccurred)
  687. self.registerComponent("time1_timezone", self.clockTime1Timezone)
  688. createLabel(self.tableClockSettings, text="Time 2 Timezone", gridX=0, gridY=6, xPadding=10)
  689. self.clockTime2Timezone = createEntry(self.tableClockSettings, maxSize=50, width=20, text=CLOCK_TIME2_TIMEZONE, gridX=1, gridY=6, xExpand=True, yExpand=False, handler=self.changeOccurred)
  690. self.clockTimezone2CheckButton = createCheckButton(self.tableClockSettings, text="Enable", active=False, gridX=2, gridY=6, xExpand=True, yExpand=False, handler=self.changeOccurred)
  691. self.registerComponent("time2_timezone", self.clockTime2Timezone)
  692. createLabel(self.tableClockSettings, text="Tooltip Timezone", gridX=0, gridY=7, xPadding=10)
  693. self.clockTooltipTimezone = createEntry(self.tableClockSettings, maxSize=50, width=20, text=CLOCK_TOOLTIP_TIMEZONE, gridX=1, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  694. self.clockTimezoneTooltipCheckButton = createCheckButton(self.tableClockSettings, text="Enable", active=False, gridX=2, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  695. self.registerComponent("clock_tooltip_timezone", self.clockTooltipTimezone)
  696. def createMouseWidgets(self):
  697. """Creates the Mouse widgets."""
  698. self.tableMouse = gtk.Table(rows=4, columns=3, homogeneous=False)
  699. self.tableMouse.set_row_spacings(5)
  700. self.tableMouse.set_col_spacings(5)
  701. mouseCmds = ["none", "close", "toggle", "iconify", "shade", "toggle_iconify", "maximize_restore", "desktop_left", "desktop_right", "next_task", "prev_task"]
  702. createLabel(self.tableMouse, text="Middle Mouse Click Action", gridX=0, gridY=0, xPadding=10)
  703. self.mouseMiddle = createComboBox(self.tableMouse, mouseCmds, gridX=1, gridY=0, handler=self.changeOccurred)
  704. self.registerComponent("mouse_middle", self.mouseMiddle)
  705. createLabel(self.tableMouse, text="Right Mouse Click Action", gridX=0, gridY=1, xPadding=10)
  706. self.mouseRight = createComboBox(self.tableMouse, mouseCmds, gridX=1, gridY=1, handler=self.changeOccurred)
  707. self.registerComponent("mouse_right", self.mouseRight)
  708. createLabel(self.tableMouse, text="Mouse Wheel Scroll Up Action", gridX=0, gridY=2, xPadding=10)
  709. self.mouseUp = createComboBox(self.tableMouse, mouseCmds, gridX=1, gridY=2, handler=self.changeOccurred)
  710. self.registerComponent("mouse_scroll_up", self.mouseUp)
  711. createLabel(self.tableMouse, text="Mouse Wheel Scroll Down Action", gridX=0, gridY=3, xPadding=10)
  712. self.mouseDown = createComboBox(self.tableMouse, mouseCmds, gridX=1, gridY=3, handler=self.changeOccurred)
  713. self.registerComponent("mouse_scroll_down", self.mouseDown)
  714. def createTooltipsWidgets(self):
  715. """Creates the Tooltips widgets."""
  716. self.tableTooltip = gtk.Table(rows=7, columns=3, homogeneous=False)
  717. self.tableTooltip.set_row_spacings(5)
  718. self.tableTooltip.set_col_spacings(5)
  719. createLabel(self.tableTooltip, text="Show Tooltips", gridX=0, gridY=0, xPadding=10)
  720. self.tooltipShow = createCheckButton(self.tableTooltip, active=False, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  721. self.registerComponent("tooltip", self.tooltipShow)
  722. createLabel(self.tableTooltip, text="Padding (x, y)", gridX=0, gridY=1, xPadding=10)
  723. self.tooltipPadX = createEntry(self.tableTooltip, maxSize=6, width=8, text=TOOLTIP_PADDING_X, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  724. self.tooltipPadY = createEntry(self.tableTooltip, maxSize=6, width=8, text=TOOLTIP_PADDING_Y, gridX=2, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  725. self.registerComponent("tooltip_padding", (self.tooltipPadX, self.tooltipPadY))
  726. createLabel(self.tableTooltip, text="Tooltip Show Timeout (seconds)", gridX=0, gridY=2, xPadding=10)
  727. self.tooltipShowTime = createEntry(self.tableTooltip, maxSize=6, width=8, text=TOOLTIP_SHOW_TIMEOUT, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  728. self.registerComponent("tooltip_show_timeout", self.tooltipShowTime)
  729. createLabel(self.tableTooltip, text="Tooltip Hide Timeout (seconds)", gridX=0, gridY=3, xPadding=10)
  730. self.tooltipHideTime = createEntry(self.tableTooltip, maxSize=6, width=8, text=TOOLTIP_HIDE_TIMEOUT, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  731. self.registerComponent("tooltip_hide_timeout", self.tooltipHideTime)
  732. createLabel(self.tableTooltip, text="Tooltip Background ID", gridX=0, gridY=4, xPadding=10)
  733. self.tooltipBg = createComboBox(self.tableTooltip, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=4, handler=self.changeOccurred)
  734. self.registerComponent("tooltip_background_id", self.tooltipBg)
  735. createLabel(self.tableTooltip, text="Tooltip Font", gridX=0, gridY=5, xPadding=10)
  736. self.tooltipFont = createFontButton(self.tableTooltip, font=self.defaults["font"], gridX=1, gridY=5, handler=self.changeOccurred)
  737. self.registerComponent("tooltip_font", self.tooltipFont)
  738. createLabel(self.tableTooltip, text="Tooltip Font Color", gridX=0, gridY=6, xPadding=10)
  739. self.tooltipFontCol = createEntry(self.tableTooltip, maxSize=7, width=9, text="", gridX=1, gridY=6, xExpand=True, yExpand=False, handler=None, name="tooltipFontCol")
  740. self.tooltipFontCol.connect("activate", self.colorTyped)
  741. self.tooltipFontColButton = createColorButton(self.tableTooltip, color=self.defaults["fgColor"], useAlpha=True, name="tooltipFontCol", gridX=2, gridY=6, handler=self.colorChange)
  742. self.tooltipFontCol.set_text(self.defaults["fgColor"])
  743. # Add this AFTER we set color to avoid "changed" event
  744. self.tooltipFontCol.connect("changed", self.changeOccurred)
  745. self.registerComponent("tooltip_font_color", (self.tooltipFontCol, self.tooltipFontColButton))
  746. def createBatteryWidgets(self):
  747. """Creates the Battery widgets."""
  748. self.tableBattery = gtk.Table(rows=8, columns=3, homogeneous=False)
  749. self.tableBattery.set_row_spacings(5)
  750. self.tableBattery.set_col_spacings(5)
  751. createLabel(self.tableBattery, text="Show Battery Applet", gridX=0, gridY=0, xPadding=10)
  752. self.batteryCheckButton = createCheckButton(self.tableBattery, active=False, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred)
  753. self.registerComponent("battery", self.batteryCheckButton)
  754. createLabel(self.tableBattery, text="Battery Low Status (%)", gridX=0, gridY=1, xPadding=10)
  755. self.batteryLow = createEntry(self.tableBattery, maxSize=6, width=8, text=BATTERY_LOW, gridX=1, gridY=1, xExpand=True, yExpand=False, handler=self.changeOccurred)
  756. self.registerComponent("battery_low_status", self.batteryLow)
  757. createLabel(self.tableBattery, text="Battery Low Action", gridX=0, gridY=2, xPadding=10)
  758. self.batteryLowAction = createEntry(self.tableBattery, maxSize=150, width=32, text=BATTERY_ACTION, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred)
  759. self.registerComponent("battery_low_cmd", self.batteryLowAction)
  760. createLabel(self.tableBattery, text="Battery Hide (0 to 100)", gridX=0, gridY=3, xPadding=10)
  761. self.batteryHide = createEntry(self.tableBattery, maxSize=6, width=8, text=BATTERY_HIDE, gridX=1, gridY=3, xExpand=True, yExpand=False, handler=self.changeOccurred)
  762. self.registerComponent("battery_hide", self.batteryHide)
  763. createLabel(self.tableBattery, text="Battery 1 Font", gridX=0, gridY=4, xPadding=10)
  764. self.bat1FontButton = createFontButton(self.tableBattery, font=self.defaults["font"], gridX=1, gridY=4, handler=self.changeOccurred)
  765. self.registerComponent("bat1_font", self.bat1FontButton)
  766. createLabel(self.tableBattery, text="Battery 2 Font", gridX=0, gridY=5, xPadding=10)
  767. self.bat2FontButton = createFontButton(self.tableBattery, font=self.defaults["font"], gridX=1, gridY=5, handler=self.changeOccurred)
  768. self.registerComponent("bat2_font", self.bat2FontButton)
  769. createLabel(self.tableBattery, text="Battery Font Color", gridX=0, gridY=6, xPadding=10)
  770. self.batteryFontCol = createEntry(self.tableBattery, maxSize=7, width=9, text="", gridX=1, gridY=6, xExpand=True, yExpand=False, handler=None, name="batteryFontCol")
  771. self.batteryFontCol.connect("activate", self.colorTyped)
  772. self.batteryFontColButton = createColorButton(self.tableBattery, color=self.defaults["fgColor"], useAlpha=True, name="batteryFontCol", gridX=2, gridY=6, handler=self.colorChange)
  773. self.batteryFontCol.set_text(self.defaults["fgColor"])
  774. # Add this AFTER we set color to avoid "changed" event
  775. self.batteryFontCol.connect("changed", self.changeOccurred)
  776. self.registerComponent("battery_font_color", (self.batteryFontCol, self.batteryFontColButton))
  777. createLabel(self.tableBattery, text="Padding (x, y)", gridX=0, gridY=7, xPadding=10)
  778. self.batteryPadX = createEntry(self.tableBattery, maxSize=6, width=8, text=BATTERY_PADDING_X, gridX=1, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  779. self.batteryPadY = createEntry(self.tableBattery, maxSize=6, width=8, text=BATTERY_PADDING_Y, gridX=2, gridY=7, xExpand=True, yExpand=False, handler=self.changeOccurred)
  780. self.registerComponent("battery_padding", (self.batteryPadX, self.batteryPadY))
  781. createLabel(self.tableBattery, text="Battery Background ID", gridX=0, gridY=8, xPadding=10)
  782. self.batteryBg = createComboBox(self.tableBattery, ["0 (fully transparent)"] + range(1, len(self.bgs)), gridX=1, gridY=8, handler=self.changeOccurred)
  783. self.registerComponent("battery_background_id", self.batteryBg)
  784. def registerComponent(self, configProperty, component):
  785. """Registers a component with a particular property from
  786. a tint2 config. Note: a component may be a double or
  787. triple if that property has more than one value associated
  788. with it."""
  789. self.propUI[configProperty] = component
  790. def getComponent(self, configProperty):
  791. """Fetches the component associated with a tint2 property."""
  792. return self.propUI[configProperty] if configProperty in self.propUI else None
  793. def about(self, action=None):
  794. """Displays the About dialog."""
  795. about = gtk.AboutDialog()
  796. about.set_program_name(NAME)
  797. about.set_version(VERSION)
  798. about.set_authors(AUTHORS)
  799. about.set_comments(COMMENTS)
  800. about.set_website(WEBSITE)
  801. gtk.about_dialog_set_url_hook(self.aboutLinkCallback)
  802. about.run()
  803. about.destroy()
  804. def aboutLinkCallback(dialog, link, data=None):
  805. """Callback for when a URL is clicked in an About dialog."""
  806. try:
  807. webbrowser.open(link)
  808. except:
  809. errorDialog(self, "Your default web-browser could not be opened.\nPlease visit %s" % link)
  810. def addBg(self):
  811. """Adds a new background to the list of backgrounds."""
  812. self.bgs += [gtk.Table(4, 3, False)]
  813. createLabel(self.bgs[-1], text="Corner Rounding (px)", gridX=0, gridY=0, xPadding=10)
  814. createEntry(self.bgs[-1], maxSize=7, width=9, text=BG_ROUNDING, gridX=1, gridY=0, xExpand=True, yExpand=False, handler=self.changeOccurred, name="rounded")
  815. createLabel(self.bgs[-1], text="Background Color", gridX=0, gridY=1, xPadding=10)
  816. temp = gtk.Entry(7)
  817. temp.set_width_chars(9)
  818. temp.set_name("bgColEntry")
  819. temp.set_text(self.defaults["bgColor"])
  820. temp.connect("changed", self.changeOccurred)
  821. temp.connect("activate", self.colorTyped)
  822. self.bgs[-1].attach(temp, 1, 2, 1, 2, xoptions=gtk.EXPAND)
  823. temp = gtk.ColorButton(gtk.gdk.color_parse(self.defaults["bgColor"]))
  824. temp.set_use_alpha(True)
  825. temp.set_name("bgCol")
  826. temp.connect("color-set", self.colorChange)
  827. self.bgs[-1].attach(temp, 2, 3, 1, 2, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
  828. createLabel(self.bgs[-1], text="Border Width (px)", gridX=0, gridY=2, xPadding=10)
  829. createEntry(self.bgs[-1], maxSize=7, width=9, text=BG_BORDER, gridX=1, gridY=2, xExpand=True, yExpand=False, handler=self.changeOccurred, name="border")
  830. createLabel(self.bgs[-1], text="Border Color", gridX=0, gridY=3, xPadding=10)
  831. temp = gtk.Entry(7)
  832. temp.set_width_chars(9)
  833. temp.set_name("borderColEntry")
  834. temp.connect("activate", self.colorTyped)
  835. temp.set_text(self.defaults["borderColor"])
  836. temp.connect("changed", self.changeOccurred)
  837. self.bgs[-1].attach(temp, 1, 2, 3, 4, xoptions=gtk.EXPAND)
  838. temp = gtk.ColorButton(gtk.gdk.color_parse(self.defaults["borderColor"]))
  839. temp.set_use_alpha(True)
  840. temp.set_name("borderCol")
  841. temp.connect("color-set", self.colorChange)
  842. self.bgs[-1].attach(temp, 2, 3, 3, 4, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND)
  843. # Note: Only set init to True when initialising background styles.
  844. # This prevents unwanted calls to changeOccurred()
  845. def addBgClick(self, widget=None, init=False):
  846. """Creates a new background and adds a new tab to the notebook."""
  847. n = self.bgNotebook.get_n_pages()
  848. if n > (self.defaults["bgCount"] + 2):
  849. if confirmDialog(self, "You already have %d background styles. Are you sure you would like another?" % n) == gtk.RESPONSE_NO:
  850. return
  851. self.addBg()
  852. newId = len(self.bgs)
  853. self.bgNotebook.append_page(self.bgs[newId-1], gtk.Label("Background ID %d" % (newId)))
  854. self.bgNotebook.show_all()
  855. self.updateComboBoxes(n, "add")
  856. self.bgNotebook.set_current_page(n)
  857. if not init:
  858. self.changeOccurred()
  859. def addBgDefs(self, bgDefs):
  860. """Add interface elements for a list of background style definitions. bgDefs
  861. should be a list containing dictionaries with the following keys: rounded,
  862. border_width, background_color, border_color"""
  863. for d in bgDefs:
  864. self.addBg()
  865. for child in self.bgs[-1].get_children():
  866. if child.get_name() == "rounded":
  867. child.set_text(d["rounded"])
  868. elif child.get_name() == "border":
  869. child.set_text(d["border_width"])
  870. elif child.get_name() == "bgColEntry":
  871. child.set_text(d["background_color"].split(" ")[0].strip())
  872. child.activate()
  873. elif child.get_name() == "borderColEntry":
  874. child.set_text(d["border_color"].split(" ")[0].strip())
  875. child.activate()
  876. elif child.get_name() == "bgCol":
  877. list = d["background_color"].split(" ")
  878. if len(list) > 1:
  879. child.set_alpha(int(int(list[1].strip()) * 65535 / 100.0))
  880. else:
  881. child.set_alpha(65535)
  882. elif child.get_name() == "borderCol":
  883. list = d["border_color"].split(" ")
  884. if len(list) > 1:
  885. child.set_alpha(int(int(list[1].strip()) * 65535 / 100.0))
  886. else:
  887. child.set_alpha(65535)
  888. newId = len(self.bgs)
  889. self.bgNotebook.append_page(self.bgs[newId-1], gtk.Label("Background ID %d" % (newId)))
  890. self.bgNotebook.show_all()
  891. self.updateComboBoxes(newId-1, "add")
  892. self.bgNotebook.set_current_page(newId)
  893. def apply(self, widget, event=None, confirmChange=True):
  894. """Applies the current config to tint2."""
  895. # Check if tint2 is running
  896. procs = os.popen('pgrep -x "tint2"') # Check list of active processes for tint2
  897. pids = [] # List of process ids for tint2
  898. for proc in procs.readlines():
  899. pids += [int(proc.strip().split(" ")[0])]
  900. procs.close()
  901. if self.oneConfigFile:
  902. # Save and copy as default
  903. self.save()
  904. tmpSrc = self.filename
  905. tmpDest = os.path.expandvars("${HOME}") + "/.config/tint2/tint2rc"
  906. try:
  907. shutil.copyfile(tmpSrc, tmpDest)
  908. except shutil.Error:
  909. pass
  910. # Ask tint2 to reload config
  911. for pid in pids:
  912. os.kill(pid, signal.SIGUSR1)
  913. else:
  914. if confirmDialog(self, "This will terminate all currently running instances of tint2 before applying config. Continue?") == gtk.RESPONSE_YES:
  915. if not self.save():
  916. return
  917. #shutil.copyfile(self.filename, self.filename+".backup") # Create backup
  918. # If it is - kill it
  919. for pid in pids:
  920. os.kill(pid, signal.SIGTERM)
  921. # Lastly, start it
  922. os.spawnv(os.P_NOWAIT, self.tint2Bin, [self.tint2Bin, "-c", self.filename])
  923. if confirmChange and self.filename != (os.path.expandvars("${HOME}") + "/.config/tint2/tint2rc") and confirmDialog(self, "Use this as default tint2 config?") == gtk.RESPONSE_YES:
  924. tmp = self.filename
  925. self.filename = os.path.expandvars("${HOME}") + "/.config/tint2/tint2rc"
  926. try:
  927. shutil.copyfile(tmp, self.filename)
  928. except shutil.Error:
  929. pass
  930. #if confirmChange and confirmDialog(self, "Keep this config?") == gtk.RESPONSE_NO:
  931. # shutil.copyfile(self.filename+".backup", self.filename) # Create backup
  932. # self.apply(widget, event, False)
  933. def changeAllFonts(self, widget):
  934. """Changes all fonts at once."""
  935. dialog = gtk.FontSelectionDialog("Select Font")
  936. dialog.set_font_name(self.defaults["font"])
  937. if dialog.run() == gtk.RESPONSE_OK:
  938. newFont = dialog.get_font_name()
  939. self.clock1FontButton.set_font_name(newFont)
  940. self.clock2FontButton.set_font_name(newFont)
  941. self.bat1FontButton.set_font_name(newFont)
  942. self.bat2FontButton.set_font_name(newFont)
  943. self.fontButton.set_font_name(newFont)
  944. dialog.destroy()
  945. self.generateConfig()
  946. self.changeOccurred()
  947. def changeDefaults(self, widget=None):
  948. """Shows the style preferences widget."""
  949. TintWizardPrefGUI(self)
  950. def changeOccurred(self, widget=None):
  951. """Called when the user changes something, i.e. entry value"""
  952. self.toSave = True
  953. self.updateStatusBar(change=True)
  954. if widget == self.panelOrientation:
  955. if self.panelOrientation.get_active_text() == "horizontal":
  956. self.panelSizeLabel.set_text("Size (width, height)")
  957. else:
  958. self.panelSizeLabel.set_text("Size (height, width)")
  959. def colorChange(self, widget):
  960. """Update the text entry when a color button is updated."""
  961. r = widget.get_color().red
  962. g = widget.get_color().green
  963. b = widget.get_color().blue
  964. label = self.getColorLabel(widget)
  965. # No label found
  966. if not label:
  967. return
  968. label.set_text(rgbToHex(r, g, b))
  969. self.changeOccurred()
  970. def colorTyped(self, widget):
  971. """Update the color button when a valid value is typed into the entry."""
  972. s = widget.get_text()
  973. # The color button associated with this widget.
  974. colorButton = self.getColorButton(widget)
  975. # Just a precautionary check - this situation should never arise.
  976. if not colorButton:
  977. #print "Error in colorTyped() -- unrecognised entry widget."
  978. return
  979. # If the entered value is invalid, set textbox to the current
  980. # hex value of the associated color button.
  981. buttonHex = self.getHexFromWidget(colorButton)
  982. if len(s) != 7:
  983. errorDialog(self, "Invalid color specification: [%s]" % s)
  984. widget.set_text(buttonHex)
  985. return
  986. try:
  987. col = gtk.gdk.Color(s)
  988. except:
  989. errorDialog(self, "Invalid color specification: [%s]" % s)
  990. widget.set_text(buttonHex)
  991. return
  992. colorButton.set_color(col)
  993. # Note: only set init to True when removing backgrounds for a new config
  994. # This prevents unwanted calls to changeOccurred()
  995. def delBgClick(self, widget=None, prompt=True, init=False):
  996. """Deletes the selected background after confirming with the user."""
  997. selected = self.bgNotebook.get_current_page()
  998. if selected == -1: # Nothing to remove
  999. return
  1000. if prompt:
  1001. if confirmDialog(self, "Remove this background?") != gtk.RESPONSE_YES:
  1002. return
  1003. self.bgNotebook.remove_page(selected)
  1004. self.bgs.pop(selected)
  1005. for i in range(self.bgNotebook.get_n_pages()):
  1006. self.bgNotebook.set_tab_label_text(self.bgNotebook.get_nth_page(i), "Background ID %d" % (i+1))
  1007. self.bgNotebook.show_all()
  1008. self.updateComboBoxes(len(self.bgs) + 1, "remove")
  1009. if not init:
  1010. self.changeOccurred()
  1011. def generateConfig(self):
  1012. """Reads values from each widget and generates a config."""
  1013. self.configBuf.delete(self.configBuf.get_start_iter(), self.configBuf.get_end_iter())
  1014. self.configBuf.insert(self.configBuf.get_end_iter(), "# Tint2 config file\n")
  1015. self.configBuf.insert(self.configBuf.get_end_iter(), "# Generated by tintwizard (http://code.google.com/p/tintwizard/)\n")
  1016. self.configBuf.insert(self.configBuf.get_end_iter(), "# For information on manually configuring tint2 see http://code.google.com/p/tint2/wiki/Configure\n\n")
  1017. if not self.oneConfigFile:
  1018. self.configBuf.insert(self.configBuf.get_end_iter(), "# To use this as default tint2 config: save as $HOME/.config/tint2/tint2rc\n\n")
  1019. self.configBuf.insert(self.configBuf.get_end_iter(), "# Background definitions\n")
  1020. for i in range(len(self.bgs)):
  1021. self.configBuf.insert(self.configBuf.get_end_iter(), "# ID %d\n" % (i + 1))
  1022. for child in self.bgs[i].get_children():
  1023. if child.get_name() == "rounded":
  1024. rounded = child.get_text() if child.get_text() else BG_ROUNDING
  1025. elif child.get_name() == "border":
  1026. borderW = child.get_text() if child.get_text() else BG_BORDER
  1027. elif child.get_name() == "bgCol":
  1028. bgCol = self.getHexFromWidget(child)
  1029. bgAlpha = int(child.get_alpha() / 65535.0 * 100)
  1030. elif child.get_name() == "borderCol":
  1031. borderCol = self.getHexFromWidget(child)
  1032. borderAlpha = int(child.get_alpha() / 65535.0 * 100)
  1033. self.configBuf.insert(self.configBuf.get_end_iter(), "rounded = %s\n" % (rounded))
  1034. self.configBuf.insert(self.configBuf.get_end_iter(), "border_width = %s\n" % (borderW))
  1035. self.configBuf.insert(self.configBuf.get_end_iter(), "background_color = %s %d\n" % (bgCol, bgAlpha))
  1036. self.configBuf.insert(self.configBuf.get_end_iter(), "border_color = %s %d\n\n" % (borderCol, borderAlpha))
  1037. self.configBuf.insert(self.configBuf.get_end_iter(), "# Panel\n")
  1038. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_monitor = %s\n" % (self.panelMonitor.get_text() if self.panelMonitor.get_text() else PANEL_MONITOR))
  1039. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_position = %s %s %s\n" % (self.panelPosY.get_active_text(), self.panelPosX.get_active_text(), self.panelOrientation.get_active_text()))
  1040. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_size = %s %s\n" % (self.panelSizeX.get_text() if self.panelSizeX.get_text() else PANEL_SIZE_X,
  1041. self.panelSizeY.get_text() if self.panelSizeY.get_text() else PANEL_SIZE_Y))
  1042. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_margin = %s %s\n" % (self.panelMarginX.get_text() if self.panelMarginX.get_text() else PANEL_MARGIN_X,
  1043. self.panelMarginY.get_text() if self.panelMarginY.get_text() else PANEL_MARGIN_Y))
  1044. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_padding = %s %s %s\n" % (self.panelPadX.get_text() if self.panelPadX.get_text() else PANEL_PADDING_X,
  1045. self.panelPadY.get_text() if self.panelPadY.get_text() else PANEL_PADDING_Y,
  1046. self.panelSpacing.get_text() if self.panelSpacing.get_text() else TASKBAR_SPACING))
  1047. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_dock = %s\n" % int(self.panelDock.get_active()))
  1048. self.configBuf.insert(self.configBuf.get_end_iter(), "wm_menu = %s\n" % int(self.panelMenu.get_active()))
  1049. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_layer = %s\n" % (self.panelLayer.get_active_text()))
  1050. self.configBuf.insert(self.configBuf.get_end_iter(), "panel_background_id = %s\n" % (self.panelBg.get_active()))
  1051. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Panel Autohide\n")
  1052. self.configBuf.insert(self.configBuf.get_end_iter(), "autohide = %s\n" % int(self.panelAutohide.get_active()))
  1053. self.configBuf.insert(self.configBuf.get_end_iter(), "autohide_show_timeout = %s\n" % (self.panelAutohideShow.get_text() if self.panelAutohideShow.get_text() else PANEL_AUTOHIDE_SHOW))
  1054. self.configBuf.insert(self.configBuf.get_end_iter(), "autohide_hide_timeout = %s\n" % (self.panelAutohideHide.get_text() if self.panelAutohideHide.get_text() else PANEL_AUTOHIDE_HIDE))
  1055. self.configBuf.insert(self.configBuf.get_end_iter(), "autohide_height = %s\n" % (self.panelAutohideHeight.get_text() if self.panelAutohideHeight.get_text() else PANEL_AUTOHIDE_HEIGHT))
  1056. self.configBuf.insert(self.configBuf.get_end_iter(), "strut_policy = %s\n" % (self.panelAutohideStrut.get_active_text() if self.panelAutohideStrut.get_active_text() else PANEL_AUTOHIDE_STRUT))
  1057. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Taskbar\n")
  1058. self.configBuf.insert(self.configBuf.get_end_iter(), "taskbar_mode = %s\n" % (self.taskbarMode.get_active_text()))
  1059. self.configBuf.insert(self.configBuf.get_end_iter(), "taskbar_padding = %s %s %s\n" % (self.taskbarPadX.get_text() if self.taskbarPadX.get_text() else TASKBAR_PADDING_X,
  1060. self.taskbarPadY.get_text() if self.taskbarPadY.get_text() else TASKBAR_PADDING_X,
  1061. self.taskbarSpacing.get_text() if self.taskbarSpacing.get_text() else TASK_SPACING))
  1062. self.configBuf.insert(self.configBuf.get_end_iter(), "taskbar_background_id = %s\n" % (self.taskbarBg.get_active()))
  1063. # Comment out the taskbar_active_background_id if user has "disabled" it
  1064. if self.taskbarActiveBgEnable.get_active() == 0:
  1065. self.configBuf.insert(self.configBuf.get_end_iter(), "#")
  1066. self.configBuf.insert(self.configBuf.get_end_iter(), "taskbar_active_background_id = %s\n" % (self.taskbarActiveBg.get_active()))
  1067. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Tasks\n")
  1068. self.configBuf.insert(self.configBuf.get_end_iter(), "urgent_nb_of_blink = %s\n" % (self.taskBlinks.get_text() if self.taskBlinks.get_text() else TASK_BLINKS))
  1069. self.configBuf.insert(self.configBuf.get_end_iter(), "task_icon = %s\n" % int(self.taskIconCheckButton.get_active()))
  1070. self.configBuf.insert(self.configBuf.get_end_iter(), "task_text = %s\n" % int(self.taskTextCheckButton.get_active()))
  1071. self.configBuf.insert(self.configBuf.get_end_iter(), "task_centered = %s\n" % int(self.taskCentreCheckButton.get_active()))
  1072. self.configBuf.insert(self.configBuf.get_end_iter(), "task_maximum_size = %s %s\n" % (self.taskMaxSizeX.get_text() if self.taskMaxSizeX.get_text() else TASK_MAXIMUM_SIZE_X, self.taskMaxSizeY.get_text() if self.taskMaxSizeY.get_text() else TASK_MAXIMUM_SIZE_Y))
  1073. self.configBuf.insert(self.configBuf.get_end_iter(), "task_padding = %s %s\n" % (self.taskPadX.get_text() if self.taskPadX.get_text() else TASK_PADDING_X,
  1074. self.taskPadY.get_text() if self.taskPadY.get_text() else TASK_PADDING_Y))
  1075. self.configBuf.insert(self.configBuf.get_end_iter(), "task_background_id = %s\n" % (self.taskBg.get_active()))
  1076. self.configBuf.insert(self.configBuf.get_end_iter(), "task_active_background_id = %s\n" % (self.taskActiveBg.get_active()))
  1077. self.configBuf.insert(self.configBuf.get_end_iter(), "task_urgent_background_id = %s\n" % (self.taskUrgentBg.get_active()))
  1078. self.configBuf.insert(self.configBuf.get_end_iter(), "task_iconified_background_id = %s\n" % (self.taskIconifiedBg.get_active()))
  1079. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Task Icons\n")
  1080. self.configBuf.insert(self.configBuf.get_end_iter(), "task_icon_asb = %s %s %s\n" % (self.iconHue.get_text() if self.iconHue.get_text() else ICON_ALPHA,
  1081. self.iconSat.get_text() if self.iconSat.get_text() else ICON_SAT,
  1082. self.iconBri.get_text() if self.iconBri.get_text() else ICON_BRI))
  1083. self.configBuf.insert(self.configBuf.get_end_iter(), "task_active_icon_asb = %s %s %s\n" % (self.activeIconHue.get_text() if self.activeIconHue.get_text() else ACTIVE_ICON_ALPHA,
  1084. self.activeIconSat.get_text() if self.activeIconSat.get_text() else ACTIVE_ICON_SAT,
  1085. self.activeIconBri.get_text() if self.activeIconBri.get_text() else ACTIVE_ICON_BRI))
  1086. self.configBuf.insert(self.configBuf.get_end_iter(), "task_urgent_icon_asb = %s %s %s\n" % (self.urgentIconHue.get_text() if self.urgentIconHue.get_text() else URGENT_ICON_ALPHA,
  1087. self.urgentIconSat.get_text() if self.urgentIconSat.get_text() else URGENT_ICON_SAT,
  1088. self.urgentIconBri.get_text() if self.urgentIconBri.get_text() else URGENT_ICON_BRI))
  1089. self.configBuf.insert(self.configBuf.get_end_iter(), "task_iconified_icon_asb = %s %s %s\n" % (self.iconifiedIconHue.get_text() if self.iconifiedIconHue.get_text() else ICONIFIED_ICON_ALPHA,
  1090. self.iconifiedIconSat.get_text() if self.iconifiedIconSat.get_text() else ICONIFIED_ICON_SAT,
  1091. self.iconifiedIconBri.get_text() if self.iconifiedIconBri.get_text() else ICONIFIED_ICON_BRI))
  1092. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Fonts\n")
  1093. self.configBuf.insert(self.configBuf.get_end_iter(), "task_font = %s\n" % (self.fontButton.get_font_name()))
  1094. self.configBuf.insert(self.configBuf.get_end_iter(), "task_font_color = %s %s\n" % (self.getHexFromWidget(self.fontColButton),
  1095. int(self.fontColButton.get_alpha() / 65535.0 * 100)))
  1096. self.configBuf.insert(self.configBuf.get_end_iter(), "task_active_font_color = %s %s\n" % (self.getHexFromWidget(self.fontActiveColButton),
  1097. int(self.fontActiveColButton.get_alpha() / 65535.0 * 100)))
  1098. self.configBuf.insert(self.configBuf.get_end_iter(), "task_urgent_font_color = %s %s\n" % (self.getHexFromWidget(self.fontUrgentColButton),
  1099. int(self.fontUrgentColButton.get_alpha() / 65535.0 * 100)))
  1100. self.configBuf.insert(self.configBuf.get_end_iter(), "task_iconified_font_color = %s %s\n" % (self.getHexFromWidget(self.fontIconifiedColButton),
  1101. int(self.fontIconifiedColButton.get_alpha() / 65535.0 * 100)))
  1102. self.configBuf.insert(self.configBuf.get_end_iter(), "font_shadow = %s\n" % int(self.fontShadowCheckButton.get_active()))
  1103. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# System Tray\n")
  1104. self.configBuf.insert(self.configBuf.get_end_iter(), "systray = %s\n" % int(self.trayShow.get_active()))
  1105. self.configBuf.insert(self.configBuf.get_end_iter(), "systray_padding = %s %s %s\n" % (self.trayPadX.get_text() if self.trayPadX.get_text() else TRAY_PADDING_X,
  1106. self.trayPadY.get_text() if self.trayPadY.get_text() else TRAY_PADDING_Y,
  1107. self.traySpacing.get_text() if self.traySpacing.get_text() else TRAY_SPACING))
  1108. self.configBuf.insert(self.configBuf.get_end_iter(), "systray_sort = %s\n" % (self.trayOrder.get_active_text()))
  1109. self.configBuf.insert(self.configBuf.get_end_iter(), "systray_background_id = %s\n" % (self.trayBg.get_active()))
  1110. self.configBuf.insert(self.configBuf.get_end_iter(), "systray_icon_size = %s\n" % (self.trayMaxIconSize.get_text() if self.trayMaxIconSize.get_text() else TRAY_MAX_ICON_SIZE))
  1111. self.configBuf.insert(self.configBuf.get_end_iter(), "systray_icon_asb = %s %s %s\n" % (self.trayIconHue.get_text() if self.trayIconHue.get_text() else TRAY_ICON_ALPHA,
  1112. self.trayIconSat.get_text() if self.trayIconSat.get_text() else TRAY_ICON_SAT,
  1113. self.trayIconBri.get_text() if self.trayIconBri.get_text() else TRAY_ICON_BRI))
  1114. if self.clockCheckButton.get_active():
  1115. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Clock\n")
  1116. if self.clock1CheckButton.get_active():
  1117. self.configBuf.insert(self.configBuf.get_end_iter(), "time1_format = %s\n" % (self.clock1Format.get_text() if self.clock1Format.get_text() else CLOCK_FMT_1))
  1118. self.configBuf.insert(self.configBuf.get_end_iter(), "time1_font = %s\n" % (self.clock1FontButton.get_font_name()))
  1119. if self.clock2CheckButton.get_active():
  1120. self.configBuf.insert(self.configBuf.get_end_iter(), "time2_format = %s\n" % (self.clock2Format.get_text() if self.clock2Format.get_text() else CLOCK_FMT_2))
  1121. self.configBuf.insert(self.configBuf.get_end_iter(), "time2_font = %s\n" % (self.clock2FontButton.get_font_name()))
  1122. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_font_color = %s %s\n" % (self.getHexFromWidget(self.clockFontColButton),
  1123. int(self.clockFontColButton.get_alpha() / 65535.0 * 100)))
  1124. if self.clockTooltipCheckButton.get_active():
  1125. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_tooltip = %s\n" % (self.clockTooltipFormat.get_text() if self.clockTooltipFormat.get_text() else CLOCK_TOOLTIP))
  1126. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_padding = %s %s\n" % (self.clockPadX.get_text() if self.clockPadX.get_text() else CLOCK_PADDING_X,
  1127. self.clockPadY.get_text() if self.clockPadY.get_text() else CLOCK_PADDING_Y))
  1128. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_background_id = %s\n" % (self.clockBg.get_active()))
  1129. if self.clockLClick.get_text():
  1130. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_lclick_command = %s\n" % (self.clockLClick.get_text()))
  1131. if self.clockRClick.get_text():
  1132. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_rclick_command = %s\n" % (self.clockRClick.get_text()))
  1133. if self.clockTimezone1CheckButton.get_active():
  1134. self.configBuf.insert(self.configBuf.get_end_iter(), "time1_timezone = %s\n" % (self.clockTime1Timezone.get_text() if self.clockTime1Timezone.get_text() else CLOCK_TIME1_TIMEZONE))
  1135. if self.clockTimezone2CheckButton.get_active():
  1136. self.configBuf.insert(self.configBuf.get_end_iter(), "time2_timezone = %s\n" % (self.clockTime2Timezone.get_text() if self.clockTime2Timezone.get_text() else CLOCK_TIME2_TIMEZONE))
  1137. if self.clockTimezoneTooltipCheckButton.get_active():
  1138. self.configBuf.insert(self.configBuf.get_end_iter(), "clock_tooltip_timezone = %s\n" % (self.clockTooltipTimezone.get_text() if self.clockTooltipTimezone.get_text() else CLOCK_TOOLTIP_TIMEZONE))
  1139. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Tooltips\n")
  1140. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip = %s\n" % int(self.tooltipShow.get_active()))
  1141. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip_padding = %s %s\n" % (self.tooltipPadX.get_text() if self.tooltipPadX.get_text() else TOOLTIP_PADDING_Y,
  1142. self.tooltipPadY.get_text() if self.tooltipPadY.get_text() else TOOLTIP_PADDING_Y))
  1143. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip_show_timeout = %s\n" % (self.tooltipShowTime.get_text() if self.tooltipShowTime.get_text() else TOOLTIP_SHOW_TIMEOUT))
  1144. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip_hide_timeout = %s\n" % (self.tooltipHideTime.get_text() if self.tooltipHideTime.get_text() else TOOLTIP_HIDE_TIMEOUT))
  1145. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip_background_id = %s\n" % (self.tooltipBg.get_active()))
  1146. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip_font = %s\n" % (self.tooltipFont.get_font_name()))
  1147. self.configBuf.insert(self.configBuf.get_end_iter(), "tooltip_font_color = %s %s\n" % (self.getHexFromWidget(self.tooltipFontColButton),
  1148. int(self.tooltipFontColButton.get_alpha() / 65535.0 * 100)))
  1149. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Mouse\n")
  1150. self.configBuf.insert(self.configBuf.get_end_iter(), "mouse_middle = %s\n" % (self.mouseMiddle.get_active_text()))
  1151. self.configBuf.insert(self.configBuf.get_end_iter(), "mouse_right = %s\n" % (self.mouseRight.get_active_text()))
  1152. self.configBuf.insert(self.configBuf.get_end_iter(), "mouse_scroll_up = %s\n" % (self.mouseUp.get_active_text()))
  1153. self.configBuf.insert(self.configBuf.get_end_iter(), "mouse_scroll_down = %s\n" % (self.mouseDown.get_active_text()))
  1154. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# Battery\n")
  1155. self.configBuf.insert(self.configBuf.get_end_iter(), "battery = %s\n" % int(self.batteryCheckButton.get_active()))
  1156. self.configBuf.insert(self.configBuf.get_end_iter(), "battery_low_status = %s\n" % (self.batteryLow.get_text() if self.batteryLow.get_text() else BATTERY_LOW))
  1157. self.configBuf.insert(self.configBuf.get_end_iter(), "battery_low_cmd = %s\n" % (self.batteryLowAction.get_text() if self.batteryLowAction.get_text() else BATTERY_ACTION))
  1158. self.configBuf.insert(self.configBuf.get_end_iter(), "battery_hide = %s\n" % (self.batteryHide.get_text() if self.batteryHide.get_text() else BATTERY_HIDE))
  1159. self.configBuf.insert(self.configBuf.get_end_iter(), "bat1_font = %s\n" % (self.bat1FontButton.get_font_name()))
  1160. self.configBuf.insert(self.configBuf.get_end_iter(), "bat2_font = %s\n" % (self.bat2FontButton.get_font_name()))
  1161. self.configBuf.insert(self.configBuf.get_end_iter(), "battery_font_color = %s %s\n" % (self.getHexFromWidget(self.batteryFontColButton),
  1162. int(self.batteryFontColButton.get_alpha() / 65535.0 * 100)))
  1163. self.configBuf.insert(self.configBuf.get_end_iter(), "battery_padding = %s %s\n" % (self.batteryPadX.get_text() if self.batteryPadX.get_text() else BATTERY_PADDING_Y,
  1164. self.batteryPadY.get_text() if self.batteryPadY.get_text() else BATTERY_PADDING_Y))
  1165. self.configBuf.insert(self.configBuf.get_end_iter(), "battery_background_id = %s\n" % (self.batteryBg.get_active()))
  1166. self.configBuf.insert(self.configBuf.get_end_iter(), "\n# End of config")
  1167. def getColorButton(self, widget):
  1168. """Returns the color button associated with widget."""
  1169. if widget.get_name() == "fontCol":
  1170. return self.fontColButton
  1171. elif widget.get_name() == "fontActiveCol":
  1172. return self.fontActiveColButton
  1173. elif widget.get_name() == "fontUrgentCol":
  1174. return self.fontUrgentColButton
  1175. elif widget.get_name() == "fontIconifiedCol":
  1176. return self.fontIconifiedColButton
  1177. elif widget.get_name() == "clockFontCol":
  1178. return self.clockFontColButton
  1179. elif widget.get_name() == "batteryFontCol":
  1180. return self.batteryFontColButton
  1181. elif widget.get_name() == "tooltipFontCol":
  1182. return self.tooltipFontColButton
  1183. elif widget.get_name() == "bgColEntry":
  1184. bgID = self.bgNotebook.get_current_page()
  1185. for child in self.bgs[bgID].get_children():
  1186. if child.get_name() == "bgCol":
  1187. return child
  1188. elif widget.get_name() == "borderColEntry":
  1189. bgID = self.bgNotebook.get_current_page()
  1190. for child in self.bgs[bgID].get_children():
  1191. if child.get_name() == "borderCol":
  1192. return child
  1193. # No button found which matches label
  1194. return None
  1195. def getColorLabel(self, widget):
  1196. """Gets the color label associated with a color button."""
  1197. if widget.get_name() == "fontCol":
  1198. return self.fontCol
  1199. elif widget.get_name() == "fontActiveCol":
  1200. return self.fontActiveCol
  1201. elif widget.get_name() == "fontUrgentCol":
  1202. return self.fontUrgentCol
  1203. elif widget.get_name() == "fontIconifiedCol":
  1204. return self.fontIconifiedCol
  1205. elif widget.get_name() == "clockFontCol":
  1206. return self.clockFontCol
  1207. elif widget.get_name() == "batteryFontCol":
  1208. return self.batteryFontCol
  1209. elif widget.get_name() == "tooltipFontCol":
  1210. return self.tooltipFontCol
  1211. elif widget.get_name() == "bgCol":
  1212. bgID = self.bgNotebook.get_current_page()
  1213. for child in self.bgs[bgID].get_children():
  1214. if child.get_name() == "bgColEntry":
  1215. return child
  1216. elif widget.get_name() == "borderCol":
  1217. bgID = self.bgNotebook.get_current_page()
  1218. for child in self.bgs[bgID].get_children():
  1219. if child.get_name() == "borderColEntry":
  1220. return child
  1221. # No label found which matches color button
  1222. return None
  1223. def getHexFromWidget(self, widget):
  1224. """Returns the #RRGGBB value of a widget."""
  1225. r = widget.get_color().red
  1226. g = widget.get_color().green
  1227. b = widget.get_color().blue
  1228. return rgbToHex(r, g, b)
  1229. def help(self, action=None):
  1230. """Opens the Help wiki page in the default web browser."""
  1231. try:
  1232. webbrowser.open("http://code.google.com/p/tintwizard/wiki/Help")
  1233. except:
  1234. errorDialog(self, "Your default web-browser could not be opened.\nPlease visit http://code.google.com/p/tintwizard/wiki/Help")
  1235. def main(self):
  1236. """Enters the main loop."""
  1237. gtk.main()
  1238. def new(self, action=None):
  1239. """Prepares a new config."""
  1240. if self.toSave:
  1241. self.savePrompt()
  1242. self.toSave = True
  1243. self.filename = None
  1244. self.resetConfig()
  1245. self.generateConfig()
  1246. self.updateStatusBar("New Config File [*]")
  1247. def openDef(self, widget=None):
  1248. """Opens the default tint2 config."""
  1249. self.openFile(default=True)
  1250. def openFile(self, widget=None, default=False):
  1251. """Reads from a config file. If default=True, open the tint2 default config."""
  1252. self.new()
  1253. if not default:
  1254. chooser = gtk.FileChooserDialog("Open Config File", self, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
  1255. chooser.set_default_response(gtk.RESPONSE_OK)
  1256. if self.curDir != None:
  1257. chooser.set_current_folder(self.curDir)
  1258. chooserFilter = gtk.FileFilter()
  1259. chooserFilter.set_name("All files")
  1260. chooserFilter.add_pattern("*")
  1261. chooser.add_filter(chooserFilter)
  1262. chooser.show()
  1263. response = chooser.run()
  1264. if response == gtk.RESPONSE_OK:
  1265. self.filename = chooser.get_filename()
  1266. self.curDir = os.path.dirname(self.filename)
  1267. else:
  1268. chooser.destroy()
  1269. return
  1270. chooser.destroy()
  1271. else:
  1272. self.filename = os.path.expandvars("$HOME/.config/tint2/tint2rc")
  1273. self.curDir = os.path.expandvars("$HOME/.config/tint2")
  1274. self.readTint2Config()
  1275. self.generateConfig()
  1276. self.updateStatusBar()
  1277. def parseBgs(self, string):
  1278. """Parses the background definitions from a string."""
  1279. s = string.split("\n")
  1280. bgDefs = []
  1281. cur = -1
  1282. bgKeys = ["border_width", "background_color", "border_color"]
  1283. newString = ""
  1284. for line in s:
  1285. data = [token.strip() for token in line.split("=")]
  1286. if data[0] == "rounded": # It may be considered bad practice to
  1287. bgDefs += [{"rounded": data[1]}] # find each style definition with an
  1288. elif data[0] in bgKeys: # arbitrary value, but tint2 does the same.
  1289. bgDefs[cur][data[0]] = data[1] # This means that any existing configs must
  1290. else: # start with 'rounded'.
  1291. newString += "%s\n" % line
  1292. self.addBgDefs(bgDefs)
  1293. return newString
  1294. def parseConfig(self, string):
  1295. """Parses the contents of a config file."""
  1296. for line in string.split("\n"):
  1297. s = line.split("=") # Create a list with KEY and VALUE
  1298. e = s[0].strip() # Strip whitespace from KEY
  1299. if e == "time1_format": # Set the VALUE of KEY
  1300. self.parseProp(self.getComponent(e), s[1], True, "time1")
  1301. elif e == "time2_format":
  1302. self.parseProp(self.getComponent(e), s[1], True, "time2")
  1303. elif e == "clock_tooltip":
  1304. self.parseProp(self.getComponent(e), s[1], True, "clock_tooltip")
  1305. elif e == "time1_timezone":
  1306. self.parseProp(self.getComponent(e), s[1], True, "time1_timezone")
  1307. elif e == "time2_timezone":
  1308. self.parseProp(self.getComponent(e), s[1], True, "time2_timezone")
  1309. elif e == "clock_tooltip_timezone":
  1310. self.parseProp(self.getComponent(e), s[1], True, "tooltip_timezone")
  1311. elif e == "systray_padding":
  1312. self.parseProp(self.getComponent(e), s[1], True, "tray")
  1313. elif e == "taskbar_active_background_id":
  1314. self.parseProp(self.getComponent(e), s[1], True, "activeBg")
  1315. else:
  1316. component = self.getComponent(e)
  1317. if component != None:
  1318. self.parseProp(self.getComponent(e), s[1])
  1319. def parseProp(self, prop, string, special=False, propType=""):
  1320. """Parses a variable definition from the conf file and updates the correct UI widget."""
  1321. string = string.strip() # Remove whitespace from the VALUE
  1322. eType = type(prop) # Get widget type
  1323. if special: # 'Special' properties are those which are optional
  1324. if propType == "time1":
  1325. self.clockCheckButton.set_active(True)
  1326. self.clock1CheckButton.set_active(True)
  1327. elif propType == "time2":
  1328. self.clockCheckButton.set_active(True)
  1329. self.clock2CheckButton.set_active(True)
  1330. elif propType == "clock_tooltip":
  1331. self.clockCheckButton.set_active(True)
  1332. self.clockTooltipCheckButton.set_active(True)
  1333. elif propType == "time1_timezone":
  1334. self.clockTimezone1CheckButton.set_active(True)
  1335. elif propType == "time2_timezone":
  1336. self.clockTimezone2CheckButton.set_active(True)
  1337. elif propType == "tooltip_timezone":
  1338. self.clockTimezoneTooltipCheckButton.set_active(True)
  1339. elif propType == "tray":
  1340. self.trayShow.set_active(True)
  1341. elif propType == "activeBg":
  1342. self.taskbarActiveBgEnable.set_active(True)
  1343. if eType == gtk.Entry:
  1344. prop.set_text(string)
  1345. prop.activate()
  1346. elif eType == gtk.ComboBox:
  1347. # This allows us to select the correct combo-box value.
  1348. if string in ["bottom", "top", "left", "right", "center", "single_desktop", "multi_desktop", "single_monitor",
  1349. "none", "close", "shade", "iconify", "toggle", "toggle_iconify", "maximize_restore",
  1350. "desktop_left", "desktop_right", "horizontal", "vertical", "ascending", "descending",
  1351. "left2right", "right2left", "next_task", "prev_task", "minimum", "follow_size", "normal"]:
  1352. if string in ["bottom", "left", "single_desktop", "none", "horizontal", "ascending"]:
  1353. i = 0
  1354. elif string in ["top", "right", "multi_desktop", "close", "vertical", "descending", "minimum"]:
  1355. i = 1
  1356. elif string in ["center", "single_monitor", "toggle", "left2right", "follow_size", "normal"]:
  1357. i = 2
  1358. elif string in ["right2left"]:
  1359. i = 3
  1360. else:
  1361. i = ["none", "close", "toggle", "iconify", "shade", "toggle_iconify", "maximize_restore",
  1362. "desktop_left", "desktop_right", "next_task", "prev_task"].index(string)
  1363. prop.set_active(i)
  1364. else:
  1365. prop.set_active(int(string))
  1366. elif eType == gtk.CheckButton:
  1367. prop.set_active(bool(int(string)))
  1368. elif eType == gtk.FontButton:
  1369. prop.set_font_name(string)
  1370. elif eType == gtk.ColorButton:
  1371. prop.set_alpha(int(int(string) * 65535 / 100.0))
  1372. elif eType == tuple: # If a property has more than 1 value, for example the x and y co-ords
  1373. s = string.split(" ") # of the padding properties, then just we use recursion to set the
  1374. for i in range(len(prop)): # value of each associated widget.
  1375. if i >= len(s):
  1376. self.parseProp(prop[i], "0")
  1377. else:
  1378. self.parseProp(prop[i], s[i])
  1379. def quit(self, widget, event=None):
  1380. """Asks if user would like to save file before quitting, then quits the program."""
  1381. if self.toSave:
  1382. if self.oneConfigFile:
  1383. response = gtk.RESPONSE_YES
  1384. else:
  1385. dialog = gtk.Dialog("Save config?", self, gtk.DIALOG_MODAL, (gtk.STOCK_YES, gtk.RESPONSE_YES, gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
  1386. dialog.get_content_area().add(gtk.Label("Save config before quitting?"))
  1387. dialog.get_content_area().set_size_request(300, 100)
  1388. dialog.show_all()
  1389. response = dialog.run()
  1390. dialog.destroy()
  1391. if response == gtk.RESPONSE_CANCEL:
  1392. return True # Return True to stop it quitting when we hit "Cancel"
  1393. elif response == gtk.RESPONSE_NO:
  1394. gtk.main_quit()
  1395. elif response == gtk.RESPONSE_YES:
  1396. self.save()
  1397. gtk.main_quit()
  1398. else:
  1399. gtk.main_quit()
  1400. def readConf(self):
  1401. """Reads the tintwizard configuration file - NOT tint2 config files."""
  1402. self.defaults = {"font": None, "bgColor": None, "fgColor": None, "borderColor": None, "bgCount": None}
  1403. if self.oneConfigFile:
  1404. # don't need tintwizard.conf
  1405. return
  1406. pathName = os.path.expandvars("${HOME}") + "/.config/tint2/"
  1407. if not os.path.exists(pathName + "tintwizard.conf"):
  1408. self.writeConf()
  1409. return
  1410. f = open(pathName + "tintwizard.conf", "r")
  1411. for line in f:
  1412. if "=" in line:
  1413. l = line.split("=")
  1414. if self.defaults.has_key(l[0].strip()):
  1415. self.defaults[l[0].strip()] = l[1].strip()
  1416. def readTint2Config(self):
  1417. """Reads in from a config file."""
  1418. f = open(self.filename, "r")
  1419. string = ""
  1420. for line in f:
  1421. if (line[0] != "#") and (len(line) > 2):
  1422. string += line
  1423. f.close()
  1424. # Deselect the optional stuff, and we'll re-check them if the config has them enabled
  1425. self.clockCheckButton.set_active(False)
  1426. self.clock1CheckButton.set_active(False)
  1427. self.clock2CheckButton.set_active(False)
  1428. self.clockTooltipCheckButton.set_active(False)
  1429. self.clockTimezone1CheckButton.set_active(False)
  1430. self.clockTimezone2CheckButton.set_active(False)
  1431. self.clockTimezoneTooltipCheckButton.set_active(False)
  1432. self.trayShow.set_active(False)
  1433. self.taskbarActiveBgEnable.set_active(False)
  1434. # Remove all background styles so we can create new ones as we read them
  1435. for i in range(len(self.bgs)):
  1436. self.delBgClick(None, False)
  1437. # As we parse background definitions, we build a new string
  1438. # without the background related stuff. This means we don't
  1439. # have to read through background defs AGAIN when parsing
  1440. # the other stuff.
  1441. noBgDefs = self.parseBgs(string)
  1442. self.parseConfig(noBgDefs)
  1443. def reportBug(self, action=None):
  1444. """Opens the bug report page in the default web browser."""
  1445. try:
  1446. webbrowser.open("http://code.google.com/p/tintwizard/issues/entry")
  1447. except:
  1448. errorDialog(self, "Your default web-browser could not be opened.\nPlease visit http://code.google.com/p/tintwizard/issues/entry")
  1449. def resetConfig(self):
  1450. """Resets all the widgets to their default values."""
  1451. # Backgrounds
  1452. for i in range(len(self.bgs)):
  1453. self.delBgClick(prompt=False, init=True)
  1454. for i in range(self.defaults["bgCount"]):
  1455. self.addBgClick(init=True)
  1456. self.bgNotebook.set_current_page(0)
  1457. # Panel
  1458. self.panelPosY.set_active(0)
  1459. self.panelPosX.set_active(0)
  1460. self.panelOrientation.set_active(0)
  1461. self.panelSizeX.set_text(PANEL_SIZE_X)
  1462. self.panelSizeY.set_text(PANEL_SIZE_Y)
  1463. self.panelMarginX.set_text(PANEL_MARGIN_X)
  1464. self.panelMarginY.set_text(PANEL_MARGIN_Y)
  1465. self.panelPadX.set_text(PANEL_PADDING_Y)
  1466. self.panelPadY.set_text(PANEL_PADDING_Y)
  1467. self.panelSpacing.set_text(TASKBAR_SPACING)
  1468. self.panelBg.set_active(0)
  1469. self.panelMenu.set_active(0)
  1470. self.panelDock.set_active(0)
  1471. self.panelLayer.set_active(0)
  1472. self.panelMonitor.set_text(PANEL_MONITOR)
  1473. self.panelAutohide.set_active(0)
  1474. self.panelAutohideShow.set_text(PANEL_AUTOHIDE_SHOW)
  1475. self.panelAutohideHide.set_text(PANEL_AUTOHIDE_HIDE)
  1476. self.panelAutohideHeight.set_text(PANEL_AUTOHIDE_HEIGHT)
  1477. self.panelAutohideStrut.set_active(0)
  1478. # Taskbar
  1479. self.taskbarMode.set_active(0)
  1480. self.taskbarPadX.set_text(TASKBAR_PADDING_X)
  1481. self.taskbarPadY.set_text(TASKBAR_PADDING_Y)
  1482. self.taskbarSpacing.set_text(TASK_SPACING)
  1483. self.taskbarBg.set_active(0)
  1484. self.taskbarActiveBg.set_active(0)
  1485. self.taskbarActiveBgEnable.set_active(0)
  1486. # Tasks
  1487. self.taskBlinks.set_text(TASK_BLINKS)
  1488. self.taskCentreCheckButton.set_active(True)
  1489. self.taskTextCheckButton.set_active(True)
  1490. self.taskIconCheckButton.set_active(True)
  1491. self.taskMaxSizeX.set_text(TASK_MAXIMUM_SIZE_X)
  1492. self.taskMaxSizeY.set_text(TASK_MAXIMUM_SIZE_Y)
  1493. self.taskPadX.set_text(TASK_PADDING_X)
  1494. self.taskPadY.set_text(TASK_PADDING_Y)
  1495. self.taskBg.set_active(0)
  1496. self.taskActiveBg.set_active(0)
  1497. self.taskUrgentBg.set_active(0)
  1498. self.taskIconifiedBg.set_active(0)
  1499. # Icons
  1500. self.iconHue.set_text(ICON_ALPHA)
  1501. self.iconSat.set_text(ICON_SAT)
  1502. self.iconBri.set_text(ICON_BRI)
  1503. self.activeIconHue.set_text(ACTIVE_ICON_ALPHA)
  1504. self.activeIconSat.set_text(ACTIVE_ICON_SAT)
  1505. self.activeIconBri.set_text(ACTIVE_ICON_BRI)
  1506. self.urgentIconHue.set_text(URGENT_ICON_ALPHA)
  1507. self.urgentIconSat.set_text(URGENT_ICON_SAT)
  1508. self.urgentIconBri.set_text(URGENT_ICON_BRI)
  1509. self.iconifiedIconHue.set_text(ICONIFIED_ICON_ALPHA)
  1510. self.iconifiedIconSat.set_text(ICONIFIED_ICON_SAT)
  1511. self.iconifiedIconBri.set_text(ICONIFIED_ICON_BRI)
  1512. # Fonts
  1513. self.fontButton.set_font_name(self.defaults["font"])
  1514. self.fontColButton.set_alpha(65535)
  1515. self.fontColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1516. self.fontCol.set_text(self.defaults["fgColor"])
  1517. self.fontActiveColButton.set_alpha(65535)
  1518. self.fontActiveColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1519. self.fontActiveCol.set_text(self.defaults["fgColor"])
  1520. self.fontUrgentColButton.set_alpha(65535)
  1521. self.fontUrgentColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1522. self.fontUrgentCol.set_text(self.defaults["fgColor"])
  1523. self.fontIconifiedColButton.set_alpha(65535)
  1524. self.fontIconifiedColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1525. self.fontIconifiedCol.set_text(self.defaults["fgColor"])
  1526. self.fontShadowCheckButton.set_active(False)
  1527. # System Tray
  1528. self.trayShow.set_active(True)
  1529. self.trayPadX.set_text(TRAY_PADDING_X)
  1530. self.trayPadY.set_text(TRAY_PADDING_X)
  1531. self.traySpacing.set_text(TRAY_SPACING)
  1532. self.trayOrder.set_active(0)
  1533. self.trayBg.set_active(0)
  1534. self.trayMaxIconSize.set_text(TRAY_MAX_ICON_SIZE)
  1535. self.trayIconHue.set_text(TRAY_ICON_ALPHA)
  1536. self.trayIconSat.set_text(TRAY_ICON_SAT)
  1537. self.trayIconBri.set_text(TRAY_ICON_BRI)
  1538. # Clock
  1539. self.clockCheckButton.set_active(True)
  1540. self.clock1Format.set_text(CLOCK_FMT_1)
  1541. self.clock1CheckButton.set_active(True)
  1542. self.clock1FontButton.set_font_name(self.defaults["font"])
  1543. self.clock2Format.set_text(CLOCK_FMT_2)
  1544. self.clock2CheckButton.set_active(True)
  1545. self.clockTooltipFormat.set_text(CLOCK_TOOLTIP)
  1546. self.clockTooltipCheckButton.set_active(False)
  1547. self.clock2FontButton.set_font_name(self.defaults["font"])
  1548. self.clockFontColButton.set_alpha(65535)
  1549. self.clockFontColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1550. self.clockFontCol.set_text(self.defaults["fgColor"])
  1551. self.clockPadX.set_text(CLOCK_PADDING_X)
  1552. self.clockPadY.set_text(CLOCK_PADDING_Y)
  1553. self.clockBg.set_active(0)
  1554. self.clockLClick.set_text(CLOCK_LCLICK)
  1555. self.clockRClick.set_text(CLOCK_RCLICK)
  1556. self.clockTime1Timezone.set_text(CLOCK_TIME1_TIMEZONE)
  1557. self.clockTimezone1CheckButton.set_active(False)
  1558. self.clockTime2Timezone.set_text(CLOCK_TIME2_TIMEZONE)
  1559. self.clockTimezone2CheckButton.set_active(False)
  1560. self.clockTooltipTimezone.set_text(CLOCK_TOOLTIP_TIMEZONE)
  1561. self.clockTimezoneTooltipCheckButton.set_active(False)
  1562. # Tooltips
  1563. self.tooltipShow.set_active(False)
  1564. self.tooltipPadX.set_text(TOOLTIP_PADDING_X)
  1565. self.tooltipPadY.set_text(TOOLTIP_PADDING_Y)
  1566. self.tooltipShowTime.set_text(TOOLTIP_SHOW_TIMEOUT)
  1567. self.tooltipHideTime.set_text(TOOLTIP_HIDE_TIMEOUT)
  1568. self.tooltipBg.set_active(0)
  1569. self.tooltipFont.set_font_name(self.defaults["font"])
  1570. self.tooltipFontColButton.set_alpha(65535)
  1571. self.tooltipFontColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1572. self.tooltipFontCol.set_text(self.defaults["fgColor"])
  1573. # Mouse
  1574. self.mouseMiddle.set_active(0)
  1575. self.mouseRight.set_active(0)
  1576. self.mouseUp.set_active(0)
  1577. self.mouseDown.set_active(0)
  1578. # Battery
  1579. self.batteryCheckButton.set_active(False)
  1580. self.batteryLow.set_text(BATTERY_LOW)
  1581. self.batteryLowAction.set_text(BATTERY_ACTION)
  1582. self.batteryHide.set_text(BATTERY_HIDE)
  1583. self.bat1FontButton.set_font_name(self.defaults["font"])
  1584. self.bat2FontButton.set_font_name(self.defaults["font"])
  1585. self.batteryFontColButton.set_alpha(65535)
  1586. self.batteryFontColButton.set_color(gtk.gdk.color_parse(self.defaults["fgColor"]))
  1587. self.batteryFontCol.set_text(self.defaults["fgColor"])
  1588. self.batteryPadX.set_text(BATTERY_PADDING_Y)
  1589. self.batteryPadY.set_text(BATTERY_PADDING_Y)
  1590. self.batteryBg.set_active(0)
  1591. def save(self, widget=None, event=None):
  1592. """Saves the generated config file."""
  1593. # This function returns the boolean status of whether or not the
  1594. # file saved, so that the apply() function knows if it should
  1595. # kill the tint2 process and apply the new config.
  1596. # If no file has been selected, force the user to "Save As..."
  1597. if self.filename == None:
  1598. return self.saveAs()
  1599. else:
  1600. self.generateConfig()
  1601. self.writeFile()
  1602. return True
  1603. def saveAs(self, widget=None, event=None):
  1604. """Prompts the user to select a file and then saves the generated config file."""
  1605. self.generateConfig()
  1606. chooser = gtk.FileChooserDialog("Save Config File As...", self, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
  1607. chooser.set_default_response(gtk.RESPONSE_OK)
  1608. if self.curDir != None:
  1609. chooser.set_current_folder(self.curDir)
  1610. chooserFilter = gtk.FileFilter()
  1611. chooserFilter.set_name("All files")
  1612. chooserFilter.add_pattern("*")
  1613. chooser.add_filter(chooserFilter)
  1614. chooser.show()
  1615. response = chooser.run()
  1616. if response == gtk.RESPONSE_OK:
  1617. self.filename = chooser.get_filename()
  1618. if os.path.exists(self.filename):
  1619. overwrite = confirmDialog(self, "This file already exists. Overwrite this file?")
  1620. if overwrite == gtk.RESPONSE_YES:
  1621. self.writeFile()
  1622. chooser.destroy()
  1623. return True
  1624. else:
  1625. self.filename = None
  1626. chooser.destroy()
  1627. return False
  1628. else:
  1629. self.writeFile()
  1630. chooser.destroy()
  1631. return True
  1632. else:
  1633. self.filename = None
  1634. chooser.destroy()
  1635. return False
  1636. def saveAsDef(self, widget=None, event=None):
  1637. """Saves the config as the default tint2 config."""
  1638. if confirmDialog(self, "Overwrite current tint2 default config?") == gtk.RESPONSE_YES:
  1639. self.filename = os.path.expandvars("${HOME}") + "/.config/tint2/tint2rc"
  1640. self.curDir = os.path.expandvars("${HOME}") + "/.config/tint2"
  1641. # If, for whatever reason, tint2 has no default config - create one.
  1642. if not os.path.isfile(self.filename):
  1643. f = open(self.filename, "w")
  1644. f.write("# tint2rc")
  1645. f.close()
  1646. self.generateConfig()
  1647. self.writeFile()
  1648. return True
  1649. def savePrompt(self):
  1650. """Prompt the user to save before creating a new file."""
  1651. if confirmDialog(self, "Save current config?") == gtk.RESPONSE_YES:
  1652. self.save(None)
  1653. def switchPage(self, notebook, page, page_num):
  1654. """Handles notebook page switch events."""
  1655. # If user selects the 'View Config' tab, update the textarea within this tab.
  1656. if notebook.get_tab_label_text(notebook.get_nth_page(page_num)) == "View Config":
  1657. self.generateConfig()
  1658. def updateComboBoxes(self, i, action="add"):
  1659. """Updates the contents of a combo box when a background style has been added/removed."""
  1660. cbs = [self.batteryBg, self.clockBg, self.taskbarBg, self.taskbarActiveBg, self.trayBg, self.taskActiveBg, self.taskBg, self.panelBg, self.tooltipBg, self.taskUrgentBg, self.taskIconifiedBg]
  1661. if action == "add":
  1662. for cb in cbs:
  1663. cb.append_text(str(i+1))
  1664. else:
  1665. for cb in cbs:
  1666. if cb.get_active() == i: # If background is selected, set to a different value
  1667. cb.set_active(0)
  1668. cb.remove_text(i)
  1669. def updateStatusBar(self, message="", change=False):
  1670. """Updates the message on the statusbar. A message can be provided,
  1671. and if change is set to True (i.e. something has been modified) then
  1672. an appropriate symbol [*] is shown beside filename."""
  1673. contextID = self.statusBar.get_context_id("")
  1674. self.statusBar.pop(contextID)
  1675. if not message:
  1676. message = "%s %s" % (self.filename or "New Config File", "[*]" if change else "")
  1677. self.statusBar.push(contextID, message)
  1678. def writeConf(self):
  1679. """Writes the tintwizard configuration file."""
  1680. confStr = "#Start\n[defaults]\n"
  1681. for key in self.defaults:
  1682. confStr += "%s = %s\n" % (key, str(self.defaults[key]))
  1683. confStr += "#End\n"
  1684. pathName = os.path.expandvars("${HOME}") + "/.config/tint2/"
  1685. f = open(pathName+"tintwizard.conf", "w")
  1686. f.write(confStr)
  1687. f.close()
  1688. def writeFile(self):
  1689. """Writes the contents of the config text buffer to file."""
  1690. try:
  1691. f = open(self.filename, "w")
  1692. f.write(self.configBuf.get_text(self.configBuf.get_start_iter(), self.configBuf.get_end_iter()))
  1693. f.close()
  1694. self.toSave = False
  1695. self.curDir = os.path.dirname(self.filename)
  1696. self.updateStatusBar()
  1697. except IOError:
  1698. errorDialog(self, "Could not save file")
  1699. # General use functions
  1700. def createLabel(parent, text="", gridX=0, gridY=0, sizeX=1, sizeY=1, xPadding=0):
  1701. """Creates a label and adds it to a parent widget."""
  1702. temp = gtk.Label(text)
  1703. temp.set_alignment(0, 0.5)
  1704. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xpadding=xPadding)
  1705. return temp
  1706. def createComboBox(parent, choices=["null"], active=0, gridX=0, gridY=0, sizeX=1, sizeY=1, xExpand=True, yExpand=True, handler=None):
  1707. """Creates a combo box with text choices and adds it to a parent widget."""
  1708. temp = gtk.combo_box_new_text()
  1709. for choice in choices:
  1710. temp.append_text(choice)
  1711. temp.set_active(active)
  1712. if handler != None:
  1713. temp.connect("changed", handler)
  1714. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xoptions=gtk.EXPAND if xExpand else 0, yoptions=gtk.EXPAND if yExpand else 0)
  1715. return temp
  1716. def createEntry(parent, maxSize, width, text="", gridX=0, gridY=0, sizeX=1, sizeY=1, xExpand=True, yExpand=True, handler=None, name=""):
  1717. """Creates a text entry widget and adds it to a parent widget."""
  1718. temp = gtk.Entry(maxSize)
  1719. temp.set_width_chars(width)
  1720. temp.set_text(text)
  1721. temp.set_name(name)
  1722. if handler != None:
  1723. temp.connect("changed", handler)
  1724. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xoptions=gtk.EXPAND if xExpand else 0, yoptions=gtk.EXPAND if yExpand else 0)
  1725. return temp
  1726. def createCheckButton(parent, text="", active=False, gridX=0, gridY=0, sizeX=1, sizeY=1, xExpand=True, yExpand=True, handler=None):
  1727. """Creates a checkbox widget and adds it to a parent widget."""
  1728. temp = gtk.CheckButton(text if text != "" else None)
  1729. temp.set_active(active)
  1730. temp.connect("toggled", handler)
  1731. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xoptions=gtk.EXPAND if xExpand else 0, yoptions=gtk.EXPAND if yExpand else 0)
  1732. return temp
  1733. def createButton(parent, text="", stock=None, name="", gridX=0, gridY=0, sizeX=1, sizeY=1, xExpand=True, yExpand=True, handler=None):
  1734. """Creates a button widget and adds it to a parent widget."""
  1735. if stock:
  1736. temp = gtk.Button(text, stock)
  1737. else:
  1738. temp = gtk.Button(text)
  1739. temp.set_name(name)
  1740. temp.connect("clicked", handler)
  1741. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xoptions=gtk.EXPAND if xExpand else 0, yoptions=gtk.EXPAND if yExpand else 0)
  1742. return temp
  1743. def createFontButton(parent, font, gridX=0, gridY=0, sizeX=1, sizeY=1, xExpand=True, yExpand=True, handler=None):
  1744. """Creates a font button widget and adds it to a parent widget."""
  1745. temp = gtk.FontButton()
  1746. temp.set_font_name(font)
  1747. temp.connect("font-set", handler)
  1748. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xoptions=gtk.EXPAND if xExpand else 0, yoptions=gtk.EXPAND if yExpand else 0)
  1749. return temp
  1750. def createColorButton(parent, color="#000000", useAlpha=True, name="", gridX=0, gridY=0, sizeX=1, sizeY=1, xExpand=True, yExpand=True, handler=None):
  1751. temp = gtk.ColorButton(gtk.gdk.color_parse(color))
  1752. temp.set_use_alpha(useAlpha)
  1753. temp.set_name(name)
  1754. temp.connect("color-set", handler)
  1755. parent.attach(temp, gridX, gridX+sizeX, gridY, gridY+sizeY, xoptions=gtk.EXPAND if xExpand else 0, yoptions=gtk.EXPAND if yExpand else 0)
  1756. return temp
  1757. def confirmDialog(parent, message):
  1758. """Creates a confirmation dialog and returns the response."""
  1759. dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, message)
  1760. dialog.show()
  1761. response = dialog.run()
  1762. dialog.destroy()
  1763. return response
  1764. def errorDialog(parent=None, message="An error has occured!"):
  1765. """Creates an error dialog."""
  1766. dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, message)
  1767. dialog.show()
  1768. dialog.run()
  1769. dialog.destroy()
  1770. def numToHex(n):
  1771. """Convert integer n in range [0, 15] to hex."""
  1772. try:
  1773. return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"][n]
  1774. except:
  1775. return -1
  1776. def rgbToHex(r, g, b):
  1777. """Constructs a 6 digit hex representation of color (r, g, b)."""
  1778. r2 = trunc(r / 65535.0 * 255)
  1779. g2 = trunc(g / 65535.0 * 255)
  1780. b2 = trunc(b / 65535.0 * 255)
  1781. return "#%s%s%s%s%s%s" % (numToHex(r2 / 16), numToHex(r2 % 16), numToHex(g2 / 16), numToHex(g2 % 16), numToHex(b2 / 16), numToHex(b2 % 16))
  1782. def trunc(n):
  1783. """Truncate a floating point number, rounding up or down appropriately."""
  1784. c = math.fabs(math.ceil(n) - n)
  1785. f = math.fabs(math.floor(n) - n)
  1786. if c < f:
  1787. return int(math.ceil(n))
  1788. else:
  1789. return int(math.floor(n))
  1790. # Direct execution of application
  1791. if __name__ == "__main__":
  1792. if len(sys.argv) > 1 and sys.argv[1] == "-version":
  1793. print NAME, VERSION
  1794. exit()
  1795. tw = TintWizardGUI()
  1796. tw.main()