#!/usr/bin/env python try: import sys import gtk import gtk.glade import pango import os import gnomeapplet import gettext import gnomevfs import traceback import time import gc import xdg.Config import pygtk pygtk.require( "2.0" ) except Exception, e: print e sys.exit( 1 ) global mbindkey # Load the key binding lib (developped by deskbar-applet, copied into mintMenu so we don't end up with an unnecessary dependency) try: from deskbar.core.keybinder import tomboy_keybinder_bind as bind_key except Exception, cause: print "*********** Keybind Driver Load Failure **************" print "Error Report : ", str(cause) pass # Rename the process try: import dl libc = dl.open( "/lib/libc.so.6" ) libc.call( "prctl", 15, "mintmenu", 0, 0, 0 ) libc.close() except ImportError: pass # i18n gettext.install("mintmenu", "/usr/share/linuxmint/locale") NAME = _("Menu") PATH = os.path.abspath( os.path.dirname( sys.argv[0] ) ) ICON = "/usr/lib/linuxmint/mintMenu/mintMenu.png" sys.path.append( os.path.join( PATH , "plugins") ) # FIXME: Get the windowmanager from somewhere, don't take GNOME for granted xdg.Config.setWindowManager( "GNOME" ) from easybuttons import iconManager from easygconf import EasyGConf from execute import * class MainWindow( object ): """This is the main class for the application""" def __init__( self, toggleButton ): self.path = PATH sys.path.append( os.path.join( self.path, "plugins") ) self.icon = ICON self.toggle = toggleButton # Load glade file and extract widgets gladefile = os.path.join( self.path, "mintMenu.glade" ) wTree = gtk.glade.XML( gladefile, "mainWindow" ) self.window = wTree.get_widget( "mainWindow" ) self.paneholder = wTree.get_widget( "paneholder" ) self.border = wTree.get_widget( "border" ) self.panesToColor = [ ] self.headingsToColor = [ ] self.window.connect( "map-event", self.onMap ) self.window.connect( "show", self.onShow ) self.window.connect( "unmap-event", self.onUnmap ) self.window.connect( "button-press-event", self.onButtonPress ) self.window.connect( "key-press-event", self.onKeyPress ) self.window.connect( "grab-broken-event", self.onGrabBroken ) self.window.stick() plugindir = os.path.join( os.path.expanduser( "~" ), ".linuxmint/mintMenu/plugins" ) sys.path.append( plugindir ) dic = {"on_window1_destroy" : self.quit_cb} wTree.signal_autoconnect( dic ) self.gconf = EasyGConf( "/apps/mintMenu/" ) self.gconftheme = EasyGConf( "/desktop/gnome/interface/" ) self.getSetGconfEntries() self.SetupMintMenuBorder() self.SetupMintMenuOpacity() self.tooltips = gtk.Tooltips() if self.globalEnableTooltips and self.enableTooltips: self.tooltips.enable() else: self.tooltips.disable() self.PopulatePlugins(); self.gconf.notifyAdd( "plugins_list", self.RegenPlugins ) self.gconftheme.notifyAdd( "gtk_theme", self.RegenPlugins ) self.gconf.notifyAdd( "start_with_favorites", self.toggleStartWithFavorites ) self.gconf.notifyAdd( "/apps/panel/global/tooltips_enabled", self.toggleTooltipsEnabled ) self.gconf.notifyAdd( "tooltips_enabled", self.toggleTooltipsEnabled ) self.gconf.notifyAdd( "use_custom_color", self.toggleUseCustomColor ) self.gconf.notifyAdd( "custom_border_color", self.toggleCustomBorderColor ) self.gconf.notifyAdd( "custom_heading_color", self.toggleCustomHeadingColor ) self.gconf.notifyAdd( "custom_color", self.toggleCustomBackgroundColor ) self.gconf.notifyAdd( "border_width", self.toggleBorderWidth ) self.gconf.notifyAdd( "opacity", self.toggleOpacity ) def quit_cb (self): gtk.main_quit() sys.exit(0) def wakePlugins( self ): # Call each plugin and let them know we're showing up for plugin in self.plugins.values(): if hasattr( plugin, "destroy" ): plugin.wake() def toggleTooltipsEnabled( self, client, connection_id, entry, args ): if entry.get_key() == "/apps/panel/global/tooltips_enabled": self.globalEnableTooltips = entry.get_value().get_bool() else: self.enableTooltips = entry.get_value().get_bool() if self.globalEnableTooltips and self.enableTooltips: self.tooltips.enable() else: self.tooltips.disable() def toggleStartWithFavorites( self, client, connection_id, entry, args ): self.startWithFavorites = entry.get_value().get_bool() def toggleBorderWidth( self, client, connection_id, entry, args ): self.borderwidth = entry.get_value().get_int() self.SetupMintMenuBorder() def toggleOpacity( self, client, connection_id, entry, args ): self.opacity = entry.get_value().get_int() self.SetupMintMenuOpacity() def toggleUseCustomColor( self, client, connection_id, entry, args ): self.usecustomcolor = entry.get_value().get_bool() self.SetupMintMenuBorder() self.SetPaneColors( self.panesToColor ) self.SetHeadingStyle( self.headingsToColor ) def toggleCustomBorderColor( self, client, connection_id, entry, args ): self.custombordercolor = entry.get_value().get_string() self.SetupMintMenuBorder() def toggleCustomBackgroundColor( self, client, connection_id, entry, args ): self.customcolor = entry.get_value().get_string() self.SetPaneColors( self.panesToColor ) def toggleCustomHeadingColor( self, client, connection_id, entry, args ): self.customheadingcolor = entry.get_value().get_string() self.SetHeadingStyle( self.headingsToColor ) def getSetGconfEntries( self ): self.pluginlist = self.gconf.get( "list-string", "plugins_list",['places', 'system_management', 'newpane', 'applications'] ) self.dottedfile = os.path.join( self.path, "dotted.png") self.usecustomcolor = self.gconf.get( "bool", "use_custom_color", False ) self.customcolor = self.gconf.get( "color", "custom_color", "#EEEEEE" ) self.customheadingcolor = self.gconf.get( "color", "custom_heading_color", "#001155" ) self.custombordercolor = self.gconf.get( "color", "custom_border_color", "#001155" ) self.borderwidth = self.gconf.get( "int", "border_width", 1 ) self.opacity = self.gconf.get( "int", "opacity", 100 ) self.offset = self.gconf.get( "int", "mintMenu_offset", 0 ) self.enableTooltips = self.gconf.get( "bool", "tooltips_enabled", True ) self.globalEnableTooltips = self.gconf.get( "bool", "/apps/panel/global/tooltips_enabled", True ) self.startWithFavorites = self.gconf.get( "bool", "start_with_favorites", False ) def SetupMintMenuBorder( self ): if self.usecustomcolor: self.window.modify_bg( gtk.STATE_NORMAL, gtk.gdk.color_parse( self.custombordercolor ) ) else: self.window.modify_bg( gtk.STATE_NORMAL, self.window.rc_get_style().bg[ gtk.STATE_SELECTED ] ) self.border.set_padding( self.borderwidth, self.borderwidth, self.borderwidth, self.borderwidth ) def SetupMintMenuOpacity( self ): print "Opacity is: " + str(self.opacity) opacity = float(self.opacity) / float(100) print "Setting opacity to: " + str(opacity) self.window.set_opacity(opacity) def PopulatePlugins( self ): self.panesToColor = [ ] self.headingsToColor = [ ] start = time.time() PluginPane = gtk.EventBox() PluginPane.show() PaneLadder = gtk.VBox( False, 0 ) PluginPane.add( PaneLadder ) self.SetPaneColors( [ PluginPane ] ) ImageBox = gtk.EventBox() self.SetPaneColors( [ ImageBox ] ) ImageBox.show() seperatorImage = gtk.gdk.pixbuf_new_from_file( self.dottedfile ) self.plugins = {} for plugin in self.pluginlist: if plugin in self.plugins: print u"Duplicate plugin in list: ", plugin continue if plugin != "newpane": try: X = __import__( plugin ) # If no parameter passed to plugin it is autonomous if X.pluginclass.__init__.func_code.co_argcount == 1: MyPlugin = X.pluginclass() else: # pass mintMenu and togglebutton instance so that the plugin can use it MyPlugin = X.pluginclass( self, self.toggle ) if not MyPlugin.icon: MyPlugin.icon = "gnome-logo-icon.png" #if hasattr( MyPlugin, "hideseparator" ) and not MyPlugin.hideseparator: # Image1 = gtk.Image() # Image1.set_from_pixbuf( seperatorImage ) # if not ImageBox.get_child(): # ImageBox.add( Image1 ) # Image1.show() #print u"Loading plugin '" + plugin + "' : sucessful" except Exception, e: MyPlugin = gtk.EventBox() #Fake class for MyPlugin MyPlugin.heading = _("Couldn't load plugin:") + " " + plugin MyPlugin.content_holder = gtk.EventBox() # create traceback info = sys.exc_info() errorLabel = gtk.Label( "\n".join(traceback.format_exception( info[0], info[1], info[2] )).replace("\\n", "\n") ) errorLabel.set_selectable( True ) errorLabel.set_line_wrap( True ) errorLabel.set_alignment( 0.0, 0.0 ) errorLabel.set_padding( 5, 5 ) errorLabel.show() MyPlugin.content_holder.add( errorLabel ) MyPlugin.add( MyPlugin.content_holder ) MyPlugin.width = 270 MyPlugin.icon = 'gnome-logo-icon.png' print u"Unable to load " + plugin + " plugin :-(" self.SetPaneColors( [MyPlugin.content_holder] ) MyPlugin.content_holder.show() VBox1 = gtk.VBox( False, 0 ) if MyPlugin.heading != "": Label1 = gtk.Label( MyPlugin.heading ) Align1 = gtk.Alignment( 0, 0, 0, 0 ) Align1.set_padding( 10, 5, 10, 0 ) Align1.add( Label1 ) self.SetHeadingStyle( [Label1] ) Align1.show() Label1.show() if not hasattr( MyPlugin, 'sticky' ) or MyPlugin.sticky == True: heading = gtk.EventBox() Align1.set_padding( 0, 0, 10, 0 ) self.SetPaneColors( [heading] ) heading.set_size_request( MyPlugin.width, 30 ) else: heading = gtk.HBox() #heading.set_relief( gtk.RELIEF_NONE ) heading.set_size_request( MyPlugin.width, -1 ) #heading.set_sensitive(False) #heading.connect( "button_press_event", self.TogglePluginView, VBox1, MyPlugin.icon, MyPlugin.heading, MyPlugin ) heading.add( Align1 ) heading.show() VBox1.pack_start( heading, False ) VBox1.show() MyPlugin.container = VBox1 #Add plugin to Plugin Box under heading button MyPlugin.content_holder.reparent( VBox1 ) #Add plugin to main window PaneLadder.pack_start( VBox1 ) PaneLadder.show() if MyPlugin.window: MyPlugin.window.destroy() try: if hasattr( MyPlugin, 'do_plugin' ): MyPlugin.do_plugin() if hasattr( MyPlugin, 'height' ): MyPlugin.content_holder.set_size_request( -1, MyPlugin.height ) if hasattr( MyPlugin, 'itemstocolor' ): self.SetPaneColors( MyPlugin.itemstocolor ) except: # create traceback info = sys.exc_info() error = _("Couldn't initialize plugin") + " " + plugin + " : " + "\n".join(traceback.format_exception( info[0], info[1], info[2] )).replace("\\n", "\n") msgDlg = gtk.MessageDialog( None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, error ) msgDlg.run(); msgDlg.destroy(); self.plugins[plugin] = MyPlugin else: self.paneholder.pack_start( ImageBox, False, False, 0 ) self.paneholder.pack_start( PluginPane, False, False, 0 ) PluginPane = gtk.EventBox() PaneLadder = gtk.VBox( False, 0 ) PluginPane.add( PaneLadder ) self.SetPaneColors( [PluginPane] ) ImageBox = gtk.EventBox() self.SetPaneColors( [ImageBox] ) ImageBox.show() PluginPane.show_all() if self.plugins and hasattr( MyPlugin, 'hideseparator' ) and not MyPlugin.hideseparator: Image1 = gtk.Image() Image1.set_from_pixbuf( seperatorImage ) Image1.show() #ImageBox.add( Image1 ) Align1 = gtk.Alignment() Align1.set_padding( 0, 0, 6, 6 ) Align1.add(Image1) ImageBox.add(Align1) ImageBox.show_all() self.paneholder.pack_start( ImageBox, False, False, 0 ) self.paneholder.pack_start( PluginPane, False, False, 0 ) self.tooltips.disable() #print u"Loading", (time.time() - start), "s" def SetPaneColors( self, items ): for item in items: if item not in self.panesToColor: self.panesToColor.append( item ) if self.usecustomcolor: for item in items: item.modify_bg( gtk.STATE_NORMAL, gtk.gdk.color_parse( self.customcolor ) ) else: for item in items: item.modify_bg( gtk.STATE_NORMAL, self.paneholder.rc_get_style().bg[ gtk.STATE_NORMAL ] ) def SetHeadingStyle( self, items ): for item in items: if item not in self.headingsToColor: self.headingsToColor.append( item ) HeadingStyle = pango.AttrList() attr = pango.AttrSize( 12000, 0, -1 ) HeadingStyle.insert( attr ) if self.usecustomcolor: headingcolor = gtk.gdk.color_parse( self.customheadingcolor ) attr = pango.AttrForeground( headingcolor.red, headingcolor.green, headingcolor.blue, 0, -1 ) HeadingStyle.insert( attr ) # else: # headingcolor = self.window.rc_get_style().bg[ gtk.STATE_SELECTED ] attr = pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) HeadingStyle.insert( attr ) for item in items: item.set_attributes( HeadingStyle ) def setTooltip( self, widget, tip, tipPrivate = None ): self.tooltips.set_tip( widget, tip, tipPrivate ) def RegenPlugins( self, *args, **kargs ): #print #print u"Reloading Plugins..." for item in self.paneholder: item.destroy() for plugin in self.plugins.values(): if hasattr( plugin, "destroy" ): plugin.destroy() try: del plugin except: pass try: del self.plugins except: pass gc.collect() self.getSetGconfEntries() self.PopulatePlugins() #print NAME+u" reloaded" def show( self ): self.window.present() if ( "applications" in self.plugins ) and ( hasattr( self.plugins["applications"], "focusSearchEntry" ) ): if (self.startWithFavorites): self.plugins["applications"].changeTab(0) self.plugins["applications"].focusSearchEntry() def grab( self ): gtk.gdk.pointer_grab( self.window.window, True, gtk.gdk.BUTTON_PRESS_MASK ) gtk.gdk.keyboard_grab( self.window.window, False ) self.window.grab_add() def ungrab( self ): self.window.grab_remove() self.window.hide() gtk.gdk.pointer_ungrab() gtk.gdk.keyboard_ungrab() def onMap( self, widget, event ): self.grab() def onShow( self, widget ): for plugin in self.plugins.values(): if hasattr( plugin, "onShowMenu" ): plugin.onShowMenu() def onUnmap( self, widget, event ): self.ungrab() for plugin in self.plugins.values(): if hasattr( plugin, "onHideMenu" ): plugin.onHideMenu() def onKeyPress( self, widget, event ): if event.keyval == gtk.keysyms.Escape or event.keyval == gtk.keysyms.Super_L: self.hide() return False def onButtonPress( self, widget, event ): # Check if the pointer is within the menu, else hide the menu winatptr = gtk.gdk.window_at_pointer() if winatptr: win = winatptr[0] while win: if win == self.window.window: break win = win.get_parent() if not win: self.hide( True ) else: self.hide( True ) return True def onGrabBroken( self, widget, event ): if event.grab_window: try: theft = event.grab_window.get_user_data() theft.connect( "event", self.onGrabTheftEvent ) except: self.window.hide( True ) def onGrabTheftEvent( self, widget, event ): if event.type == gtk.gdk.UNMAP or event.type == gtk.gdk.SELECTION_CLEAR: self.grab() def hide(self, forceHide = False): self.window.hide() class MenuWin( object ): def __init__( self, applet, iid ): self.applet = applet self.gconf = EasyGConf( "/apps/mintMenu/" ) self.gconf.notifyAdd( "applet_text", self.gconfEntriesChanged ) self.gconf.notifyAdd( "theme_name", self.changeTheme ) self.gconf.notifyAdd( "hot_key", self.gconfEntriesChanged ) self.gconf.notifyAdd( "applet_icon", self.gconfEntriesChanged ) self.gconf.notifyAdd( "hide_applet_icon", self.gconfEntriesChanged ) self.gconf.notifyAdd( "applet_icon_size", self.gconfEntriesChanged ) self.getGconfEntries() self.createPanelButton() self.applet.set_applet_flags( gnomeapplet.EXPAND_MINOR ) self.applet.connect( "button-press-event", self.showMenu ) self.applet.connect( "change-orient", self.changeOrientation ) self.applet.connect( "change-background", self.changeBackground ) self.applet.connect("enter-notify-event", self.enter_notify) self.applet.connect("leave-notify-event", self.leave_notify) self.mainwin = MainWindow( self.button_box ) self.mainwin.window.connect( "map-event", lambda *args: self.applet.set_state( gtk.STATE_SELECTED ) ) self.mainwin.window.connect( "unmap-event", lambda *args: self.applet.set_state( gtk.STATE_NORMAL ) ) self.mainwin.window.connect( "size-allocate", lambda *args: self.positionMenu() ) icon = iconManager.getIcon( self.mainwin.icon, 1 ) if icon: gtk.window_set_default_icon( icon ) self.propxml = """ """ % ( _("Preferences"), _("Edit menu"), _("Reload plugins"), _("About") ) self.verbs = [ ("Preferences", self.showPreferences), ("Edit", self.showMenuEditor), ("About", self.showAboutDialog), ("Reload",self.mainwin.RegenPlugins) ] self.bind_hot_key() def onBindingPress(self): try: if self.mainwin.window.flags() & gtk.VISIBLE: self.mainwin.window.hide() self.mainwin.toggle.set_active(False) else: MenuWin.showMenu(self,self.mainwin.toggle) self.mainwin.window.show() #self.mainwin.wTree.get_widget( 'PluginTabs' ).set_curremenu_editor = SetGconf( self.client, "string", "/apps/usp/menu_editor", "alacarte" ) except Exception, cause: print cause def enter_notify(self, applet, event): self.do_image(self.buttonIcon, True) def leave_notify(self, applet, event): self.do_image(self.buttonIcon, False) def do_image(self, image_file, saturate): pixbuf = gtk.gdk.pixbuf_new_from_file(image_file) if saturate: gtk.gdk.Pixbuf.saturate_and_pixelate(pixbuf, pixbuf, 1.5, False) self.button_icon.set_from_pixbuf(pixbuf) def createPanelButton( self ): self.button_icon = gtk.image_new_from_file( self.buttonIcon ) self.systemlabel = gtk.Label( self.buttonText ) if os.path.exists("/etc/linuxmint/info"): import commands tooltip = commands.getoutput("cat /etc/linuxmint/info | grep DESCRIPTION") tooltip = tooltip.replace("DESCRIPTION", "") tooltip = tooltip.replace("=", "") tooltip = tooltip.replace("\"", "") self.systemlabel.set_tooltip_text(tooltip) self.button_icon.set_tooltip_text(tooltip) if self.applet.get_orient() == gnomeapplet.ORIENT_UP or self.applet.get_orient() == gnomeapplet.ORIENT_DOWN: self.button_box = gtk.HBox() self.button_box.pack_start( self.button_icon, False, False ) self.button_box.pack_start( self.systemlabel, False, False ) self.button_icon.set_padding( 5, 0 ) # if we have a vertical panel elif self.applet.get_orient() == gnomeapplet.ORIENT_LEFT: self.button_box = gtk.VBox() self.systemlabel.set_angle( 270 ) self.button_box.pack_start( self.systemlabel ) self.button_box.pack_start( self.button_icon ) self.button_icon.set_padding( 5, 0 ) elif self.applet.get_orient() == gnomeapplet.ORIENT_RIGHT: self.button_box = gtk.VBox() self.systemlabel.set_angle( 90 ) self.button_box.pack_start( self.button_icon ) self.button_box.pack_start( self.systemlabel ) self.button_icon.set_padding( 0, 5 ) self.button_box.set_homogeneous( False ) self.button_box.show_all() self.sizeButton() self.applet.add( self.button_box ) def getGconfEntries( self, *args, **kargs ): self.hideIcon = self.gconf.get( "bool", "hide_applet_icon", False ) self.buttonText = self.gconf.get( "string", "applet_text", "Menu" ) self.theme_name = self.gconf.get( "string", "theme_name", "default" ) self.hotkeyText = self.gconf.get( "string", "hot_key", "Super_L" ) self.buttonIcon = self.gconf.get( "string", "applet_icon", ICON ) self.setIconSize( self.gconf.get( "int", "applet_icon_size", 2 ) ) def setIconSize( self, icon_size): if icon_size >= 4: self.iconSize = gtk.ICON_SIZE_DIALOG elif icon_size == 3: self.iconSize = gtk.ICON_SIZE_DND elif icon_size == 2: self.iconSize = gtk.ICON_SIZE_BUTTON else: self.iconSize = gtk.ICON_SIZE_MENU def changeBackground( self, applet, type, color, pixmap ): self.applyTheme() # get reset style self.applet.set_style(None) rc_style = gtk.RcStyle() self.applet.modify_style(rc_style) if gnomeapplet.COLOR_BACKGROUND == type: applet.modify_bg( gtk.STATE_NORMAL, color ) elif gnomeapplet.PIXMAP_BACKGROUND == type: style = applet.style style.bg_pixmap[ gtk.STATE_NORMAL ] = pixmap applet.set_style( style ) def changeTheme(self, *args): self.gconfEntriesChanged() self.applyTheme() self.mainwin.RegenPlugins() def applyTheme(self): style_settings = gtk.settings_get_default() desktop_theme = self.gconf.get( "string", '/desktop/gnome/interface/gtk_theme', "") if self.theme_name == "default": style_settings.set_property("gtk-theme-name", desktop_theme) else: try: style_settings.set_property("gtk-theme-name", self.theme_name) except: style_settings.set_property("gtk-theme-name", desktop_theme) def changeOrientation( self, *args, **kargs ): if self.applet.get_orient() == gnomeapplet.ORIENT_UP or self.applet.get_orient() == gnomeapplet.ORIENT_DOWN: tmpbox = gtk.HBox() self.systemlabel.set_angle( 0 ) self.button_box.reorder_child( self.button_icon, 0 ) self.button_icon.set_padding( 5, 0 ) elif self.applet.get_orient() == gnomeapplet.ORIENT_LEFT: tmpbox = gtk.VBox() self.systemlabel.set_angle( 270 ) self.button_box.reorder_child( self.button_icon, 1 ) self.button_icon.set_padding( 0, 5 ) elif self.applet.get_orient() == gnomeapplet.ORIENT_RIGHT: tmpbox = gtk.VBox() self.systemlabel.set_angle( 90 ) self.button_box.reorder_child( self.button_icon, 0 ) self.button_icon.set_padding( 0, 5 ) tmpbox.set_homogeneous( False ) # reparent all the hboxes to the new tmpbox for i in self.button_box: i.reparent( tmpbox ) self.button_box.destroy() self.button_box = tmpbox self.button_box.show() # this call makes sure width stays intact self.updateButton() self.applet.add( self.button_box ) def updateButton( self ): self.systemlabel.set_text( self.buttonText ) self.button_icon.clear() self.button_icon.set_from_file( self.buttonIcon ) self.sizeButton() def bind_hot_key (self): try: # Binding menu to hotkey print "Binding to Hot Key: " + self.hotkeyText bind_key( self.hotkeyText, self.onBindingPress ) except Exception, cause: print "** WARNING ** - Menu Hotkey Binding Error" print "Error Report :\n", str(cause) pass def sizeButton( self ): if self.hideIcon: self.button_icon.hide() else: self.button_icon.show() # This code calculates width and height for the button_box # and takes the orientation in account if self.applet.get_orient() == gnomeapplet.ORIENT_UP or self.applet.get_orient() == gnomeapplet.ORIENT_DOWN: if self.hideIcon: self.applet.set_size_request( self.systemlabel.size_request()[0] + 2, -1 ) else: self.applet.set_size_request( self.systemlabel.size_request()[0] + self.button_icon.size_request()[0] + 5, self.button_icon.size_request()[1] ) else: if self.hideIcon: self.applet.set_size_request( self.button_icon.size_request()[0], self.systemlabel.size_request()[1] + 2 ) else: self.applet.set_size_request( self.button_icon.size_request()[0], self.systemlabel.size_request()[1] + self.button_icon.size_request()[1] + 5 ) def gconfEntriesChanged( self, *args ): self.getGconfEntries() self.updateButton() def showAboutDialog( self, uicomponent, verb ): gtk.about_dialog_set_email_hook( lambda dialog, mail: gnomevfs.url_show( "mailto:" + mail ) ) gtk.about_dialog_set_url_hook( lambda dialog, url: gnomevfs.url_show( url ) ) about = gtk.AboutDialog() about.set_name("mintMenu") import commands version = commands.getoutput("/usr/lib/linuxmint/common/version.py mintmenu") about.set_version(version) try: h = open('/usr/share/common-licenses/GPL','r') s = h.readlines() gpl = "" for line in s: gpl += line h.close() about.set_license(gpl) except Exception, detail: print detail about.set_comments( _("Advanced Gnome Menu") ) about.set_authors( ["Clement Lefebvre ", "Lars-Peter Clausen "] ) about.set_translator_credits(("translator-credits") ) about.set_copyright( _("Based on USP from S.Chanderbally") ) about.set_logo( gtk.gdk.pixbuf_new_from_file("/usr/lib/linuxmint/mintMenu/icon.svg") ) about.connect( "response", lambda dialog, r: dialog.destroy() ) about.show() def showPreferences( self, uicomponent, verb ): # Execute( "gconf-editor /apps/mintMenu" ) Execute( os.path.join( PATH, "mintMenuConfig.py" ) ) def showMenuEditor( self, uicomponent, verb ): Execute( "alacarte" ) def showMenu( self, widget=None, event=None ): if event == None or event.button == 1: self.toggleMenu() # show right click menu elif event.button == 3: self.create_menu() # allow middle click and drag elif event.button == 2: self.mainwin.hide( True ) def toggleMenu( self ): if self.applet.state & gtk.STATE_SELECTED: self.mainwin.hide( True ) else: self.positionMenu() self.mainwin.show() self.wakePlugins() def wakePlugins( self ): self.mainwin.wakePlugins() def positionMenu( self ): # Get our own dimensions & position ourWidth = self.mainwin.window.get_size()[0] ourHeight = self.mainwin.window.get_size()[1] + self.mainwin.offset # Get the dimensions/position of the widgetToAlignWith entryX, entryY = self.applet.window.get_origin() entryWidth, entryHeight = self.applet.get_allocation().width, self.applet.get_allocation().height entryHeight = entryHeight + self.mainwin.offset # Get the screen dimensions screenHeight = gtk.gdk.screen_height() screenWidth = gtk.gdk.screen_width() if self.applet.get_orient() == gnomeapplet.ORIENT_UP or self.applet.get_orient() == gnomeapplet.ORIENT_DOWN: if entryX + ourWidth < screenWidth or entryX + entryWidth / 2 < screenWidth / 2: # Align to the left of the entry newX = entryX else: # Align to the right of the entry newX = entryX + entryWidth - ourWidth if entryY + entryHeight / 2 < screenHeight / 2: # Align to the bottom of the entry newY = entryY + entryHeight else: newY = entryY - ourHeight else: if entryX + entryWidth / 2 < screenWidth / 2: # Align to the left of the entry newX = entryX + entryWidth else: # Align to the right of the entry newX = entryX - ourWidth if entryY + ourHeight < screenHeight or entryY + entryHeight / 2 < screenHeight / 2: # Align to the bottom of the entry newY = entryY else: newY = entryY - ourHeight + entryHeight # -"Move window" self.mainwin.window.move( newX, newY ) # this callback is to create a context menu def create_menu(self): self.applet.setup_menu(self.propxml, self.verbs, None) def menu_factory( applet, iid ): MenuWin( applet, iid ) applet.show() return True def quit_all(widget): gtk.main_quit() sys.exit(0) if len(sys.argv) == 2 and sys.argv[1] == "run-in-window": gtk.gdk.threads_init() main_window = gtk.Window( gtk.WINDOW_TOPLEVEL ) main_window.set_title( NAME ) main_window.connect( "destroy", quit_all ) app = gnomeapplet.Applet() menu_factory( app, None ) app.reparent( main_window ) main_window.show() gtk.gdk.threads_enter() gtk.main() gtk.gdk.threads_leave() else: gnomeapplet.bonobo_factory("OAFIID:GNOME_mintMenu_Factory", gnomeapplet.Applet.__gtype__, "mintMenu", "0", menu_factory)