#!/usr/bin/env python # coding= UTF-8 # # wbar configuration gui v0.5 # # Created by # Mika Hynnä # # Copyright 2008 Mika Hynnä # This program is distributed under the terms of the GNU General Public License # For more info see http://www.gnu.org/licenses/gpl.txt # # # Requires # * >=python-2.4 # * >=pygtk-2.10 # import os import pygtk pygtk.require('2.0') import gtk import gobject if gtk.pygtk_version < (2,3,90): print "PyGtk 2.3.90 or later required" raise SystemExit wbarversion="0.5" ITEM_ID = 0 ITEM_ICON = 1 ITEM_COMMAND = 2 ITEM_TITLE = 3 ITEM_IMAGE = 4 PLACE_ID=0 PLACE_IMAGE=1 PLACE_TITLE=2 PLACE_COMMAND=3 PLACE_ICON=4 def readconf(): lines=0 lastemptyline=0 items=list() id=0 userconf = os.path.expanduser('~') + '/.wbar' if (os.path.exists(userconf)): print "User configuration file found: ~/.wbar" conf = userconf elif os.path.exists('/usr/share/wbar/dot.wbar'): conf = '/usr/share/wbar/dot.wbar' print "Shared configuration found: /usr/share/wbar/dot.wbar" elif os.path.exists('/usr/local/share/wbar/dot.wbar'): conf = '/usr/local/share/wbar/dot.wbar' print "Shared configuration found: /usr/local/share/wbar/dot.wbar" else: print "No configuration file found, defaulting.." icons=[] titles=[] commands=[] ids=[] item_count=0 try: file = open(conf, "r") for line in file: line=line.replace('\n','') line=line.strip() if not line.startswith('#'): if (len(line) > 1): twofirst = line[0:2] ids.append(item_count) ids.append(item_count) if (twofirst == "i:"): item_count+=1 icons.append(line[3:].strip()) elif (twofirst == "c:"): commands.append(line[3:].strip()) elif (twofirst == "t:"): titles.append(line[3:].strip()) except: if file.closed == False: file.close() if file.closed == False: file.close() print "Config file read" configuration = [] try: for i in range(0,item_count): configuration.append([0, icons[i], commands[i], titles[i]]) except: print "Configuration parse error: trying to continue.." return configuration def saveconf(conf): print "Saving in ~/.wbar ...\n" try: cfile = open(os.path.expanduser('~') + "/.wbar","w") cfile.write("# The Bar && Font") for object in conf: cfile.write("\n") num=0 for item in object: num=num+1 if (num == 2): cfile.write("i: "+str(item)+"\n") if (num == 3): cfile.write("c: "+str(item)+"\n") if (num == 4): cfile.write("t: "+str(item)+"\n") print "Saved!" except: print "Saving failed." if (cfile.closed == False): cfile.close() if (cfile.closed == False): cfile.close() class WbarGui: configuration = [] current_selection = 0 def delete_event(self, widget, event, data=None): print "Delete event: deleting gui\n" return False def destroy(self, widget, data=None): print "Quiting...\n" gtk.main_quit() def buttonSaveClicked(self, widget): print "Save pressed!" del self.configuration[1:] model = self.treeview.get_model() try: iter = model.get_iter(0) except ValueError: message = gtk.MessageDialog(self.window, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK , "Icon list is empty!\n Not saving, sorry!") message.set_title("Empty icon list") message.set_position(gtk.WIN_POS_CENTER) message.run() message.destroy() return while iter: icon = model.get_value(iter, PLACE_ICON) title = model.get_value(iter, PLACE_TITLE) command = model.get_value(iter, PLACE_COMMAND) self.configuration.append([1,icon,command,title]) iter = model.iter_next(iter) # print str(self.configuration) saveconf(self.configuration) notice = gtk.MessageDialog(self.window, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Settings saved!") notice.set_title("Saving changes") notice.set_position(gtk.WIN_POS_CENTER) notice.run() notice.destroy() def __init__(self): #Load configuration self.configuration = readconf() #Create window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_resizable(True) self.window.set_default_size(500,300) self.window.set_title(u"wbar configuration gui") self.window.set_position(gtk.WIN_POS_CENTER) self.window.connect("destroy", self.destroy) self.window.connect("delete_event", self.delete_event) #Containers self.VBoxBase = gtk.VBox() self.VBoxBase.set_spacing(5) self.HBoxButtons = gtk.HBox() self.HBoxControls = gtk.HBox() self.VBoxBase.add(self.HBoxControls) self.VBoxList = gtk.VBox() self.VboxListControls = gtk.HBox() self.VboxListControls.show() self.VBoxList.show() self.HBoxControls.pack_start(self.VBoxList, False) self.HBoxControls.set_spacing(5) self.VBoxEdits = gtk.VBox() self.VboxListControls.set_spacing(5) #Icon ListStore self.treeview = gtk.TreeView() model = gtk.ListStore(gobject.TYPE_INT, gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.treeview.set_model(model) cell_id = gtk.CellRendererText() col_id = gtk.TreeViewColumn("id", cell_id, text=PLACE_ID) col_id.set_visible(False) self.treeview.append_column(col_id) cell_img = gtk.CellRendererPixbuf() col_img = gtk.TreeViewColumn("Icon", cell_img, pixbuf = PLACE_IMAGE) self.treeview.append_column(col_img) cell_text = gtk.CellRendererText() col_text = gtk.TreeViewColumn("Title", cell_text, text = PLACE_TITLE) self.treeview.append_column(col_text) cell_command = gtk.CellRendererText() col_command = gtk.TreeViewColumn("command", cell_command, text=PLACE_COMMAND) col_command.set_visible(False) self.treeview.append_column(col_command) cell_icon = gtk.CellRendererText() col_icon = gtk.TreeViewColumn("icon path", cell_icon, text=PLACE_ICON) col_icon.set_visible(False) self.treeview.append_column(col_icon) skipfirst=False for wbar_item in self.configuration: #Lets skip first entry because it contains other than icon information if (skipfirst == True): item = model.append(None) model.set_value(item, PLACE_ID, int(wbar_item[ITEM_ID])) try: model.set_value(item, PLACE_IMAGE, gtk.gdk.pixbuf_new_from_file_at_size(str(wbar_item[ITEM_ICON]),32,32) ) except: print "Warning: Core melting!!!" model.set_value(item, PLACE_TITLE, str(wbar_item[ITEM_TITLE]) ) model.set_value(item, PLACE_COMMAND, str(wbar_item[ITEM_COMMAND])) model.set_value(item, PLACE_ICON, str(wbar_item[ITEM_ICON])) else: skipfirst = True self.treeview.connect("cursor-changed", self.ListItemClicked) self.treeview.set_tooltip_text("Drag and Drop to change order") # self.treeview.show() self.treeview.set_reorderable(True) self.scrolled = gtk.ScrolledWindow() self.scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.scrolled.add(self.treeview) self.scrolled.set_size_request(100,250) self.VBoxList.pack_start(self.scrolled) self.VBoxList.pack_start(self.VboxListControls, False) self.HBoxControls.pack_start(self.VBoxEdits) self.VBoxList.set_spacing(5) #Control buttons for list: new, delete and such #Add new self.button_control_new = gtk.Button("Add new", gtk.STOCK_ADD) self.button_control_new.connect("clicked", self.button_control_new_clicked) self.button_control_new.show() self.VboxListControls.pack_start(self.button_control_new, False) #Delete selected self.button_control_delete = gtk.Button("Delete selected", gtk.STOCK_REMOVE) self.button_control_delete.connect("clicked", self.button_control_delete_clicked) self.button_control_delete.show() self.VboxListControls.pack_start(self.button_control_delete, False) #Down arrow self.button_control_down = gtk.Button("Up", gtk.STOCK_GO_DOWN) self.button_control_down.connect("clicked", self.button_control_down_clicked) self.VboxListControls.pack_end(self.button_control_down, False) #Up arrow self.button_control_up = gtk.Button("Up", gtk.STOCK_GO_UP) self.button_control_up.connect("clicked", self.button_control_up_clicked) self.VboxListControls.pack_end(self.button_control_up, False) #Font options #lets first try parse the configuration for fonts... font = self.configuration[0][ITEM_TITLE] try: fonti = font.rindex('/') size = int(font[fonti+1:]) font = font[:fonti] except: size = 12 self.VBoxEditsFont = gtk.VBox() self.VBoxEdits.add(self.VBoxEditsFont) label_font = gtk.Label() label_font.set_label("Font:") label_font.show() self.VBoxEditsFont.pack_start(label_font,False) HBoxFont = gtk.HBox() self.VBoxEditsFont.pack_start(HBoxFont, False) self.text_font = gtk.Entry() self.text_font.insert_text(str(font)) self.text_font.connect("changed", self.text_font_change) HBoxFont.pack_start(self.text_font) self.text_font.set_tooltip_text("full font path") button_font = gtk.Button("...") button_font.connect("clicked", self.button_font_clicked) button_font.set_tooltip_text("Open font file selection dialog") HBoxFont.pack_start(button_font, False) self.button_font_size = gtk.SpinButton(gtk.Adjustment(size,1,99,1), 1,0) self.button_font_size.set_range(1,100) self.button_font_size.connect("value-changed", self.button_font_size_callback) HBoxFont.pack_start(self.button_font_size, False) #Background options self.VBoxEditsBG = gtk.VBox() self.VBoxEdits.add(self.VBoxEditsBG) label_bg = gtk.Label() label_bg.set_label("Background image:") label_bg.show() self.VBoxEditsBG.pack_start(label_bg, False) HBoxBackground = gtk.HBox() self.VBoxEditsBG.pack_start(HBoxBackground, False) self.text_bg = gtk.Entry() self.text_bg.insert_text(str(self.configuration[0][1])) self.text_bg.show() self.text_bg.connect("changed", self.text_bg_change) HBoxBackground.pack_start(self.text_bg) self.button_bg = gtk.Button("...") self.button_bg.connect("clicked", self.button_background_clicked) self.button_bg.set_tooltip_text("Open file selection dialog") HBoxBackground.pack_start(self.button_bg, False) # Frame for object's options self.frame = gtk.Frame() self.VBoxEdits.pack_start(self.frame) self.frame_inner = gtk.VBox() self.frame.add(self.frame_inner) self.frame_inner.set_spacing(10) #Title options self.VBoxEdits.set_border_width(2) self.label_title = gtk.Label() self.label_title.set_label("Title:") self.label_title.show() self.text_title = gtk.Entry() self.text_title.show() self.text_title.connect("changed", self.text_title_change) #Command options label_command = gtk.Label() label_command.set_label("Command:") label_command.show() self.text_command = gtk.Entry() self.text_command.show() self.text_command.connect("changed", self.text_command_change) self.button_command = gtk.Button("...") self.button_command.show() self.button_command.connect("clicked", self.button_command_clicked) self.button_command.set_tooltip_text("Open selection dialog") #Icon options label_icon = gtk.Label() label_icon.set_label("Icon:") self.text_icon = gtk.Entry() self.text_icon.connect("changed", self.text_icon_change) self.button_icon = gtk.Button("...") self.button_icon.connect("clicked", self.button_icon_clicked) self.button_icon.set_tooltip_text("Open icon file selection dialog") #Icon image in the frame: self.icon_image = gtk.Image() self.icon_image.set_size_request(96,96) self.frame_inner.add(self.icon_image) self.icon_image.set_from_stock(gtk.STOCK_MISSING_IMAGE, gtk.ICON_SIZE_DIALOG) ################################################################# #Table container inside frame table = gtk.Table(4,3) b = gtk.Button() table.attach(self.label_title,0,1,0,1, gtk.SHRINK) table.attach(self.text_title,1,3,0,1) table.attach(label_command,0,1,1,2, gtk.SHRINK) table.attach(self.text_command,1,3,1,2) table.attach(self.button_command,3,4,1,2, gtk.SHRINK, gtk.SHRINK) table.attach(label_icon,0,1,2,3, gtk.SHRINK) table.attach(self.text_icon,1,3,2,3) table.attach(self.button_icon,3,4,2,3, gtk.SHRINK, gtk.SHRINK) self.frame_inner.add(table) ################################################################# #Button Save self.button_save = gtk.Button(" Save",gtk.STOCK_SAVE) self.button_save.connect("clicked", self.buttonSaveClicked) # self.HBoxButtons.add(self.button_save) #Button Exit self.button_exit = gtk.Button("Close", gtk.STOCK_CLOSE) self.button_exit.connect("clicked", self.destroy) # self.HBoxButtons.add(self.button_exit) self.HBoxButtons.pack_end(self.button_exit, False, False, 10) self.HBoxButtons.pack_end(self.button_save, False, False, 10) self.VBoxBase.pack_start(self.HBoxButtons, False) self.window.add(self.VBoxBase) #Show main window frame and all content print "All inits ok so far, showing main window." self.window.show_all() ################################################################# ################################################################# # EVENTS BEGIN def button_control_up_clicked(self, n): print "up" try: cursor = self.treeview.get_cursor()[0][0] model = self.treeview.get_model() model.move_before(model.get_iter(cursor), model.get_iter(cursor-1)) except ValueError: print "End Reached" except TypeError: self.treeview.grab_focus() print "Empty list" def button_control_down_clicked(self, n): print "down" try: cursor = self.treeview.get_cursor()[0][0] model = self.treeview.get_model() model.move_after(model.get_iter(cursor), model.get_iter(cursor+1)) except ValueError: print "End Reached" except TypeError: self.treeview.grab_focus() print "Empty List" def UpdateFontInformationInConf(self): font = self.text_font.get_text() size = self.button_font_size.get_value_as_int() self.configuration[0][ITEM_TITLE] = font+"/"+str(size) def button_font_size_callback(self,n): #Lets update font data self.UpdateFontInformationInConf() def ClearObjectFields(self): self.text_command.set_text("") self.text_title.set_text("") self.text_icon.set_text("") def ListItemClicked(self, n): try: nsel = n.get_cursor() selection = nsel[0][0] if (selection is not None): model = self.treeview.get_model() self.text_title.set_text(model.get_value(model.get_iter(selection), PLACE_TITLE) ) self.text_command.set_text(model.get_value(model.get_iter(selection), PLACE_COMMAND) ) self.text_icon.set_text( model.get_value( model.get_iter(selection), PLACE_ICON ) ) self.frame.set_label(model.get_value(model.get_iter(selection), PLACE_TITLE)) except TypeError: self.ClearObjectFields() def button_icon_clicked(self, n): dialog = gtk.FileChooserDialog("Select image file..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("Images") filter.add_mime_type("image/svg") filter.add_mime_type("image/png") filter.add_mime_type("image/jpeg") filter.add_mime_type("image/gif") filter.add_pattern("*.svg") filter.add_pattern("*.png") filter.add_pattern("*.jpg") filter.add_pattern("*.gif") filter.add_pattern("*.tif") filter.add_pattern("*.xpm") dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) dialog.set_current_folder('/usr/share/icons/') response = dialog.run() if response == gtk.RESPONSE_OK: #Set new icon information in place self.text_icon.set_text(dialog.get_filename()) elif response == gtk.RESPONSE_CANCEL: print 'Closed, no files selected' dialog.destroy() def button_font_clicked(self, n): dialog = gtk.FileChooserDialog("Select font file..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) dialog.set_current_folder('/usr/share/fonts/') response = dialog.run() if response == gtk.RESPONSE_OK: #Set new icon information in place self.text_font.set_text(dialog.get_filename()) elif response == gtk.RESPONSE_CANCEL: print 'Closed, no files selected' dialog.destroy() def button_background_clicked(self, n): dialog = gtk.FileChooserDialog("Select background image file..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("Images") filter.add_mime_type("image/svg") filter.add_mime_type("image/png") filter.add_mime_type("image/jpeg") filter.add_mime_type("image/gif") filter.add_pattern("*.svg") filter.add_pattern("*.png") filter.add_pattern("*.jpg") filter.add_pattern("*.gif") filter.add_pattern("*.tif") filter.add_pattern("*.xpm") dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) dialog.set_current_folder(os.path.expanduser('~')) response = dialog.run() if response == gtk.RESPONSE_OK: #Set new icon information in place self.text_bg.set_text(dialog.get_filename()) elif response == gtk.RESPONSE_CANCEL: print 'Closed, no files selected' dialog.destroy() def text_icon_change(self, n): #Replace icon to be displayed try: image = gtk.Image() self.icon_image.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(str(n.get_text()),64,64)) except: print "No icon image "+ n.get_text()+" found..." self.icon_image.set_from_stock(gtk.STOCK_MISSING_IMAGE, gtk.ICON_SIZE_DIALOG) #Try to upgrade the icon in list and ignore if error occurs try: selection=self.treeview.get_cursor()[0][0] model = self.treeview.get_model() model.set_value(model.get_iter(selection), PLACE_ICON, str(n.get_text())) model.set_value(model.get_iter(selection) , PLACE_IMAGE, gtk.gdk.pixbuf_new_from_file_at_size(str(n.get_text()),32,32)) except TypeError: print "Empty fields" except: print "Another error.." model.set_value(model.get_iter(selection) , PLACE_IMAGE, None) def text_title_change(self, n): #Update Icon file in configuration try: model = self.treeview.get_model() model.set_value(model.get_iter(self.treeview.get_cursor()[0][0]), PLACE_TITLE, str(n.get_text())) model.set_value(model.get_iter(self.treeview.get_cursor()[0][0]) , 2, n.get_text()) except TypeError: print "Empty fields" def text_command_change(self, n): try: model = self.treeview.get_model() model.set_value(model.get_iter(self.treeview.get_cursor()[0][0]), PLACE_COMMAND, str(n.get_text())) except TypeError: print "Empty fields" def button_command_clicked(self, n): dialog = gtk.FileChooserDialog("Select command..", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) response = dialog.run() if response == gtk.RESPONSE_OK: #Set new icon information in place self.text_command.set_text(dialog.get_filename()) elif response == gtk.RESPONSE_CANCEL: print 'Closed, no files selected' dialog.destroy() def text_bg_change(self, n): self.configuration[0][ITEM_ICON] = str(n.get_text()) def text_font_change(self, n): self.UpdateFontInformationInConf() def button_control_new_clicked(self, n): model = self.treeview.get_model() #item = model.append(None) try: iter = model.get_iter(self.treeview.get_cursor()[0][0]) item = model.insert_after(iter) except TypeError: item = model.append(None) self.treeview.grab_focus() model.set_value(item, PLACE_ID, 0) model.set_value(item, PLACE_IMAGE, None ) model.set_value(item, PLACE_TITLE, "New object") model.set_value(item, PLACE_COMMAND, "command") model.set_value(item, PLACE_ICON, "icon.png") def button_control_delete_clicked(self, n): #remove item from configuration try: pos = self.treeview.get_cursor()[0][0] model = self.treeview.get_model() model.remove(model.get_iter(pos)) if pos < 1: pos = 1 self.treeview.set_cursor(pos-1) except TypeError: print "Empty fields, nothing to delete" def main(self): gtk.main() if __name__ == "__main__": print "wbar configuration gui" print "Copyright 2008 Mika Hynnä " print "\nthis program is distributed under the terms of the GNU General Public License\n" gui = WbarGui() gui.main()