mintmenu/usr/lib/linuxmint/mintMenu/mintMenu.py

874 lines
34 KiB
Python
Raw Permalink Normal View History

2009-07-27 11:45:34 +01:00
#!/usr/bin/env python
2013-03-01 16:56:54 +00:00
import gi
gi.require_version("Gtk", "2.0")
from gi.repository import Gtk, GdkPixbuf, Gdk, GObject
2013-03-01 16:56:54 +00:00
from gi.repository import MatePanelApplet
2013-03-04 15:01:20 +00:00
from gi.repository import Gio
2013-03-01 16:56:54 +00:00
2009-07-27 11:45:34 +01:00
try:
2010-09-13 12:10:43 +01:00
import sys
2013-03-04 12:57:17 +00:00
from gi.repository import Pango
2010-09-13 12:10:43 +01:00
import os
import commands
2010-09-13 12:10:43 +01:00
import gettext
import traceback
import time
import gc
2013-03-06 02:56:17 +00:00
import ctypes
from ctypes import *
import capi
2010-09-13 12:10:43 +01:00
import xdg.Config
2013-03-09 19:26:22 +00:00
import keybinding
2009-07-27 11:45:34 +01:00
except Exception, e:
2010-09-13 12:10:43 +01:00
print e
sys.exit( 1 )
2009-07-27 11:45:34 +01:00
GObject.threads_init()
2013-03-06 02:56:17 +00:00
gtk = CDLL("libgtk-x11-2.0.so.0")
gdk = CDLL("libgdk-x11-2.0.so.0")
2009-07-27 11:45:34 +01:00
# Rename the process
architecture = commands.getoutput("uname -a")
if (architecture.find("x86_64") >= 0):
import ctypes
libc = ctypes.CDLL('libc.so.6')
libc.prctl(15, 'mintmenu', 0, 0, 0)
else:
2010-09-13 12:10:43 +01:00
import dl
if os.path.exists('/lib/libc.so.6'):
libc = dl.open('/lib/libc.so.6')
libc.call('prctl', 15, 'mintmenu', 0, 0, 0)
elif os.path.exists('/lib/i386-linux-gnu/libc.so.6'):
libc = dl.open('/lib/i386-linux-gnu/libc.so.6')
libc.call('prctl', 15, 'mintmenu', 0, 0, 0)
2009-07-27 11:45:34 +01:00
2009-07-29 21:50:43 +01:00
# i18n
2009-11-03 11:29:52 +00:00
gettext.install("mintmenu", "/usr/share/linuxmint/locale")
2009-07-27 11:45:34 +01:00
2009-07-29 21:50:43 +01:00
NAME = _("Menu")
2009-07-27 11:45:34 +01:00
PATH = os.path.abspath( os.path.dirname( sys.argv[0] ) )
2009-07-27 11:45:34 +01:00
sys.path.append( os.path.join( PATH , "plugins") )
windowManager = os.getenv("DESKTOP_SESSION")
if not windowManager:
windowManager = "MATE"
xdg.Config.setWindowManager( windowManager.upper() )
2009-07-27 11:45:34 +01:00
2013-03-04 16:50:14 +00:00
from easybuttons import iconManager
2013-03-07 03:08:11 +00:00
from execute import *
2009-07-27 11:45:34 +01:00
class MainWindow( object ):
2010-09-13 12:10:43 +01:00
"""This is the main class for the application"""
def __init__( self, toggleButton, settings, keybinder ):
2013-03-04 15:01:20 +00:00
self.settings = settings
self.keybinder = keybinder
2010-09-13 12:10:43 +01:00
self.path = PATH
sys.path.append( os.path.join( self.path, "plugins") )
self.detect_desktop_environment()
2013-03-04 15:01:20 +00:00
self.icon = "/usr/lib/linuxmint/mintMenu/visualisation-logo.png"
2010-09-13 12:10:43 +01:00
self.toggle = toggleButton
2013-03-04 16:50:14 +00:00
# Load UI file and extract widgets
builder = Gtk.Builder()
builder.add_from_file(os.path.join( self.path, "mintMenu.ui" ))
self.window = builder.get_object( "mainWindow" )
self.paneholder = builder.get_object( "paneholder" )
self.border = builder.get_object( "border" )
builder.connect_signals(self)
2010-09-13 12:10:43 +01:00
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 )
2013-03-04 16:50:14 +00:00
2013-03-09 02:29:49 +00:00
self.getSetGSettingEntries()
2010-09-13 12:10:43 +01:00
self.SetupMintMenuBorder()
self.SetupMintMenuOpacity()
2013-03-04 12:57:17 +00:00
self.tooltips = Gtk.Tooltips()
2010-09-13 12:10:43 +01:00
if self.globalEnableTooltips and self.enableTooltips:
self.tooltips.enable()
else:
self.tooltips.disable()
self.PopulatePlugins();
2013-03-09 16:43:54 +00:00
self.settings.connect( "changed::plugins-list", self.RegenPlugins )
2013-03-09 16:43:54 +00:00
self.settings.connect( "changed::start-with-favorites", self.toggleStartWithFavorites )
2013-03-09 00:31:58 +00:00
globalsettings = Gio.Settings.new("org.mate.panel")
globalsettings.connect( "changed::tooltips-enabled", self.toggleTooltipsEnabled )
2013-03-09 16:43:54 +00:00
self.settings.connect( "changed::tooltips-enabled", self.toggleTooltipsEnabled )
2010-09-13 12:10:43 +01:00
2013-03-09 16:43:54 +00:00
self.settings.connect( "changed::use-custom-color", self.toggleUseCustomColor )
self.settings.connect( "changed::custom-border-color", self.toggleCustomBorderColor )
self.settings.connect( "changed::custom-heading-color", self.toggleCustomHeadingColor )
self.settings.connect( "changed::custom-color", self.toggleCustomBackgroundColor )
self.settings.connect( "changed::border-width", self.toggleBorderWidth )
2013-03-04 15:01:20 +00:00
self.settings.connect( "changed::opacity", self.toggleOpacity )
2010-09-13 12:10:43 +01:00
2013-03-04 16:50:14 +00:00
def on_window1_destroy (self, widget, data=None):
2013-03-04 12:57:17 +00:00
Gtk.main_quit()
2010-09-13 12:10:43 +01:00
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()
2013-03-09 00:31:58 +00:00
def toggleTooltipsEnabled( self, settings, key, args = None):
if key == "tooltips-enabled":
self.globalEnableTooltips = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
else:
2013-03-09 00:31:58 +00:00
self.enableTooltips = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
if self.globalEnableTooltips and self.enableTooltips:
self.tooltips.enable()
else:
self.tooltips.disable()
2013-03-09 00:31:58 +00:00
def toggleStartWithFavorites( self, settings, key, args = None ):
self.startWithFavorites = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
2013-03-09 00:31:58 +00:00
def toggleBorderWidth( self, settings, key, args = None ):
self.borderwidth = settings.get_int(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuBorder()
2013-03-09 00:31:58 +00:00
def toggleOpacity( self, settings, key, args = None ):
self.opacity = settings.get_int(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuOpacity()
2013-03-09 00:31:58 +00:00
def toggleUseCustomColor( self, settings, key, args = None ):
self.usecustomcolor = settings.get_boolean(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuBorder()
self.SetPaneColors( self.panesToColor )
self.SetHeadingStyle( self.headingsToColor )
2013-03-09 00:31:58 +00:00
def toggleCustomBorderColor( self, settings, key, args = None ):
self.custombordercolor = settings.get_string(key)
2010-09-13 12:10:43 +01:00
self.SetupMintMenuBorder()
2013-03-09 00:31:58 +00:00
def toggleCustomBackgroundColor( self, settings, key, args = None):
self.customcolor = settings.get_string(key)
2010-09-13 12:10:43 +01:00
self.SetPaneColors( self.panesToColor )
2013-03-09 00:31:58 +00:00
def toggleCustomHeadingColor( self, settings, key, args = None ):
self.customheadingcolor = settings.get_string(key)
2010-09-13 12:10:43 +01:00
self.SetHeadingStyle( self.headingsToColor )
2013-03-09 02:29:49 +00:00
def getSetGSettingEntries( self ):
2010-09-13 12:10:43 +01:00
self.dottedfile = os.path.join( self.path, "dotted.png")
2013-03-04 15:01:20 +00:00
self.pluginlist = self.settings.get_strv( "plugins-list" )
self.usecustomcolor = self.settings.get_boolean( "use-custom-color" )
self.customcolor = self.settings.get_string( "custom-color" )
self.customheadingcolor = self.settings.get_string( "custom-heading-color" )
self.custombordercolor = self.settings.get_string( "custom-border-color" )
self.borderwidth = self.settings.get_int( "border-width" )
self.opacity = self.settings.get_int( "opacity" )
self.offset = self.settings.get_int( "offset" )
self.enableTooltips = self.settings.get_boolean( "tooltips-enabled" )
self.startWithFavorites = self.settings.get_boolean( "start-with-favorites" )
mate_settings = Gio.Settings.new("org.mate.panel")
self.globalEnableTooltips = mate_settings.get_boolean( "tooltips-enabled" )
2010-09-13 12:10:43 +01:00
def SetupMintMenuBorder( self ):
2013-03-09 00:31:58 +00:00
if self.usecustomcolor:
self.window.modify_bg( Gtk.StateType.NORMAL, Gdk.color_parse( self.custombordercolor ) )
# else:
# self.window.modify_bg( Gtk.StateType.NORMAL, self.window.rc_get_style().bg[ Gtk.StateType.SELECTED ] )
2010-09-13 12:10:43 +01:00
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 detect_desktop_environment (self):
self.de = "mate"
try:
de = os.environ["DESKTOP_SESSION"]
if de in ["gnome", "gnome-shell", "mate", "kde", "xfce"]:
self.de = de
2012-06-28 13:26:15 +01:00
else:
if os.path.exists("/usr/bin/caja"):
self.de = "mate"
elif os.path.exists("/usr/bin/thunar"):
self.de = "xfce"
except Exception, detail:
print detail
2010-09-13 12:10:43 +01:00
def PopulatePlugins( self ):
self.panesToColor = [ ]
self.headingsToColor = [ ]
start = time.time()
2013-03-04 12:57:17 +00:00
PluginPane = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
PluginPane.show()
2013-03-04 12:57:17 +00:00
PaneLadder = Gtk.VBox( False, 0 )
2010-09-13 12:10:43 +01:00
PluginPane.add( PaneLadder )
self.SetPaneColors( [ PluginPane ] )
2013-03-04 12:57:17 +00:00
ImageBox = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
self.SetPaneColors( [ ImageBox ] )
ImageBox.show()
2013-03-04 12:57:17 +00:00
seperatorImage = GdkPixbuf.Pixbuf.new_from_file( self.dottedfile )
2010-09-13 12:10:43 +01:00
self.plugins = {}
2013-03-04 16:50:14 +00:00
for plugin in self.pluginlist:
2010-09-13 12:10:43 +01:00
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, self.de )
2010-09-13 12:10:43 +01:00
if not MyPlugin.icon:
MyPlugin.icon = "mate-logo-icon.png"
2010-09-13 12:10:43 +01:00
#if hasattr( MyPlugin, "hideseparator" ) and not MyPlugin.hideseparator:
2013-03-04 12:57:17 +00:00
# Image1 = Gtk.Image()
2010-09-13 12:10:43 +01:00
# Image1.set_from_pixbuf( seperatorImage )
# if not ImageBox.get_child():
# ImageBox.add( Image1 )
# Image1.show()
#print u"Loading plugin '" + plugin + "' : sucessful"
except Exception, e:
2013-03-04 12:57:17 +00:00
MyPlugin = Gtk.EventBox() #Fake class for MyPlugin
2010-09-13 12:10:43 +01:00
MyPlugin.heading = _("Couldn't load plugin:") + " " + plugin
2013-03-04 12:57:17 +00:00
MyPlugin.content_holder = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
# create traceback
info = sys.exc_info()
2013-03-04 12:57:17 +00:00
errorLabel = Gtk.Label( "\n".join(traceback.format_exception( info[0], info[1], info[2] )).replace("\\n", "\n") )
2010-09-13 12:10:43 +01:00
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 = 'mate-logo-icon.png'
2010-09-13 12:10:43 +01:00
print u"Unable to load " + plugin + " plugin :-("
self.SetPaneColors( [MyPlugin.content_holder] )
MyPlugin.content_holder.show()
2013-03-04 12:57:17 +00:00
VBox1 = Gtk.VBox( False, 0 )
2010-09-13 12:10:43 +01:00
if MyPlugin.heading != "":
2013-03-04 12:57:17 +00:00
Label1 = Gtk.Label(label= MyPlugin.heading )
Align1 = Gtk.Alignment.new( 0, 0, 0, 0 )
2010-09-13 12:10:43 +01:00
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:
2013-03-04 12:57:17 +00:00
heading = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
Align1.set_padding( 0, 0, 10, 0 )
self.SetPaneColors( [heading] )
heading.set_size_request( MyPlugin.width, 30 )
else:
2013-03-04 12:57:17 +00:00
heading = Gtk.HBox()
#heading.set_relief( Gtk.ReliefStyle.NONE )
2010-09-13 12:10:43 +01:00
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()
2013-03-05 02:56:18 +00:00
VBox1.pack_start( heading, False, False, 0 )
2010-09-13 12:10:43 +01:00
VBox1.show()
#Add plugin to Plugin Box under heading button
MyPlugin.content_holder.reparent( VBox1 )
#Add plugin to main window
2013-03-04 12:57:17 +00:00
PaneLadder.pack_start( VBox1 , True, True, 0)
2010-09-13 12:10:43 +01:00
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' ):
2010-09-13 16:57:13 +01:00
self.SetPaneColors( MyPlugin.itemstocolor )
2010-09-13 12:10:43 +01:00
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")
2013-03-04 12:57:17 +00:00
msgDlg = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, error )
2010-09-13 12:10:43 +01:00
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 )
2013-03-04 12:57:17 +00:00
PluginPane = Gtk.EventBox()
PaneLadder = Gtk.VBox( False, 0 )
2010-09-13 12:10:43 +01:00
PluginPane.add( PaneLadder )
self.SetPaneColors( [PluginPane] )
2013-03-04 12:57:17 +00:00
ImageBox = Gtk.EventBox()
2010-09-13 12:10:43 +01:00
self.SetPaneColors( [ImageBox] )
ImageBox.show()
PluginPane.show_all()
if self.plugins and hasattr( MyPlugin, 'hideseparator' ) and not MyPlugin.hideseparator:
2013-03-04 12:57:17 +00:00
Image1 = Gtk.Image()
2010-09-13 12:10:43 +01:00
Image1.set_from_pixbuf( seperatorImage )
Image1.show()
#ImageBox.add( Image1 )
2013-03-05 02:56:18 +00:00
Align1 = Gtk.Alignment.new(0, 0, 0, 0)
2010-09-13 12:10:43 +01:00
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 ):
2013-03-09 00:31:58 +00:00
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.StateType.NORMAL, Gdk.color_parse( self.customcolor ) )
# else:
# for item in items:
# item.modify_bg( Gtk.StateType.NORMAL, self.paneholder.rc_get_style().bg[ Gtk.StateType.NORMAL ] )
2010-09-13 12:10:43 +01:00
def SetHeadingStyle( self, items ):
for item in items:
if item not in self.headingsToColor:
self.headingsToColor.append( item )
if self.usecustomcolor:
2013-03-09 00:31:58 +00:00
color = self.customheadingcolor
else:
color = None
2010-09-13 12:10:43 +01:00
for item in items:
2013-03-09 00:31:58 +00:00
item.set_use_markup(True)
text = item.get_text()
if color == None:
markup = '<span size="12000" weight="bold">%s</span>' % (text)
else:
markup = '<span size="12000" weight="bold" color="%s">%s</span>' % (color, text)
item.set_markup( markup )
2010-09-13 12:10:43 +01:00
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()
2013-03-09 02:29:49 +00:00
self.getSetGSettingEntries()
2010-09-13 12:10:43 +01:00
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 ):
2013-03-06 23:57:06 +00:00
gdk.gdk_pointer_grab (hash(self.window.window), True, Gdk.EventMask.BUTTON_PRESS_MASK, None, None, 0)
2013-03-06 23:23:28 +00:00
Gdk.keyboard_grab( self.window.window, False, Gdk.CURRENT_TIME )
2013-03-08 00:25:41 +00:00
Gtk.grab_add(self.window)
2010-09-13 12:10:43 +01:00
def ungrab( self ):
2013-03-08 00:25:41 +00:00
Gtk.grab_remove(self.window)
2010-09-13 12:10:43 +01:00
self.window.hide()
2013-03-06 23:23:28 +00:00
Gdk.pointer_ungrab(Gdk.CURRENT_TIME)
Gdk.keyboard_ungrab(Gdk.CURRENT_TIME)
2010-09-13 12:10:43 +01:00
def onMap( self, widget, event ):
2013-03-06 23:23:28 +00:00
self.grab()
2010-09-13 12:10:43 +01:00
def onShow( self, widget ):
for plugin in self.plugins.values():
if hasattr( plugin, "onShowMenu" ):
plugin.onShowMenu()
def onUnmap( self, widget, event ):
2013-03-06 23:23:28 +00:00
self.ungrab()
2010-09-13 12:10:43 +01:00
for plugin in self.plugins.values():
if hasattr( plugin, "onHideMenu" ):
plugin.onHideMenu()
def onKeyPress( self, widget, event ):
if event.keyval == Gdk.KEY_Escape or self.keybinder.is_hotkey(event.keyval, event.get_state()):
2010-09-13 12:10:43 +01:00
self.hide()
return True
2010-09-13 12:10:43 +01:00
return False
def onButtonPress( self, widget, event ):
# Check if the pointer is within the menu, else hide the menu
2013-03-04 12:57:17 +00:00
winatptr = Gdk.window_at_pointer()
2010-09-13 12:10:43 +01:00
if winatptr:
win = winatptr[0]
while win:
if win == self.window.window:
break
2013-03-06 02:56:17 +00:00
win = capi.get_widget(gdk.gdk_window_get_parent (hash(win)))
2010-09-13 12:10:43 +01:00
if not win:
self.hide( True )
else:
self.hide( True )
return True
def onGrabBroken( self, widget, event ):
2013-03-06 23:23:28 +00:00
if event.grab_broken.grab_window:
2010-09-13 12:10:43 +01:00
try:
win = event.grab_broken.grab_window
data = c_void_p()
gdk.gdk_window_get_user_data(hash(win), byref(data))
theft = capi.get_widget(ctypes.cast(data, POINTER(capi._PyGObject_Functions)))
2010-09-13 12:10:43 +01:00
theft.connect( "event", self.onGrabTheftEvent )
2013-03-08 00:25:41 +00:00
except Exception, detail:
print detail
self.window.hide()
2010-09-13 12:10:43 +01:00
def onGrabTheftEvent( self, widget, event ):
if event.type == Gdk.EventType.UNMAP or event.type == Gdk.EventType.SELECTION_CLEAR:
2010-09-13 12:10:43 +01:00
self.grab()
def hide(self, forceHide = False):
self.window.hide()
2009-07-27 11:45:34 +01:00
class MenuWin( object ):
2010-09-13 12:10:43 +01:00
def __init__( self, applet, iid ):
2013-03-04 15:01:20 +00:00
self.applet = applet
2013-03-04 16:50:14 +00:00
self.settings = Gio.Settings.new("com.linuxmint.mintmenu")
self.keybinder = keybinding.GlobalKeyBinding()
2013-03-09 02:52:47 +00:00
self.settings.connect( "changed::applet-text", self.reloadSettings )
self.settings.connect( "changed::theme-name", self.changeTheme )
self.settings.connect( "changed::hot-key", self.reloadSettings )
self.settings.connect( "changed::applet-icon", self.reloadSettings )
2013-03-04 15:01:20 +00:00
self.settings.connect( "changed::hide-applet-icon", self.reloadSettings )
2013-03-09 02:52:47 +00:00
self.settings.connect( "changed::applet-icon-size", self.reloadSettings )
self.settings.connect( "changed::hot-key", self.hotkeyChanged )
2013-03-04 15:01:20 +00:00
self.loadSettings()
mate_settings = Gio.Settings.new("org.mate.interface")
mate_settings.connect( "changed::gtk-theme", self.changeTheme )
2010-09-13 12:10:43 +01:00
self.createPanelButton()
2013-03-04 15:01:20 +00:00
self.applet.set_flags( MatePanelApplet.AppletFlags.EXPAND_MINOR )
2010-09-13 12:10:43 +01:00
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.settings, self.keybinder )
2013-03-04 12:57:17 +00:00
self.mainwin.window.connect( "map-event", lambda *args: self.applet.set_state( Gtk.StateType.SELECTED ) )
self.mainwin.window.connect( "unmap-event", lambda *args: self.applet.set_state( Gtk.StateType.NORMAL ) )
2010-09-13 12:10:43 +01:00
self.mainwin.window.connect( "size-allocate", lambda *args: self.positionMenu() )
2010-09-17 14:55:03 +01:00
self.mainwin.window.set_name("mintmenu") # Name used in Gtk RC files
if self.mainwin.icon:
Gtk.Window.set_default_icon_name( self.mainwin.icon )
2010-09-13 12:10:43 +01:00
self.bind_hot_key()
2013-03-10 00:43:27 +00:00
def onBindingPress(self, binder):
2010-09-13 12:10:43 +01:00
try:
2013-03-10 00:43:27 +00:00
if self.mainwin.window.get_visible():
2010-09-13 12:10:43 +01:00
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", "mozo" )
2010-09-13 12:10:43 +01:00
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):
2013-03-04 12:57:17 +00:00
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_file)
2010-09-13 12:10:43 +01:00
if saturate:
2013-03-04 12:57:17 +00:00
GdkPixbuf.Pixbuf.saturate_and_pixelate(pixbuf, pixbuf, 1.5, False)
2010-09-13 12:10:43 +01:00
self.button_icon.set_from_pixbuf(pixbuf)
def createPanelButton( self ):
2013-03-04 15:01:20 +00:00
self.button_icon = Gtk.Image.new_from_file( self.buttonIcon )
2013-03-04 12:57:17 +00:00
self.systemlabel = Gtk.Label(label= self.buttonText )
2010-09-13 12:10:43 +01:00
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)
2013-03-04 15:01:20 +00:00
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
2013-03-04 12:57:17 +00:00
self.button_box = Gtk.HBox()
2013-03-04 15:01:20 +00:00
self.button_box.pack_start( self.button_icon, False, False, 0 )
self.button_box.pack_start( self.systemlabel, False, False, 0 )
2010-09-13 12:10:43 +01:00
self.button_icon.set_padding( 5, 0 )
# if we have a vertical panel
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
2013-03-04 12:57:17 +00:00
self.button_box = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 270 )
2013-03-04 12:57:17 +00:00
self.button_box.pack_start( self.systemlabel , True, True, 0)
self.button_box.pack_start( self.button_icon , True, True, 0)
2010-09-13 12:10:43 +01:00
self.button_icon.set_padding( 5, 0 )
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
2013-03-04 12:57:17 +00:00
self.button_box = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 90 )
2013-03-04 12:57:17 +00:00
self.button_box.pack_start( self.button_icon , True, True, 0)
self.button_box.pack_start( self.systemlabel , True, True, 0)
2010-09-13 12:10:43 +01:00
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 )
2013-03-04 15:01:20 +00:00
def loadSettings( self, *args, **kargs ):
self.hideIcon = self.settings.get_boolean( "hide-applet-icon" )
self.buttonText = self.settings.get_string( "applet-text" )
self.theme_name = self.settings.get_string( "theme-name" )
self.hotkeyText = self.settings.get_string( "hot-key" )
self.buttonIcon = self.settings.get_string( "applet-icon" )
self.iconSize = self.settings.get_int( "applet-icon-size" )
2010-09-13 12:10:43 +01:00
def changeBackground( self, applet, type, color, pixmap ):
self.applyTheme()
2010-09-13 12:10:43 +01:00
# get reset style
self.applet.set_style(None)
2013-03-04 12:57:17 +00:00
rc_style = Gtk.RcStyle()
2010-09-13 12:10:43 +01:00
self.applet.modify_style(rc_style)
2013-03-04 15:01:20 +00:00
if MatePanelApplet.AppletBackgroundType.COLOR_BACKGROUND == type:
2013-03-04 12:57:17 +00:00
applet.modify_bg( Gtk.StateType.NORMAL, color )
2013-03-04 15:01:20 +00:00
elif MatePanelApplet.AppletBackgroundType.PIXMAP_BACKGROUND == type:
2010-09-13 12:10:43 +01:00
style = applet.style
2013-03-04 12:57:17 +00:00
style.bg_pixmap[ Gtk.StateType.NORMAL ] = pixmap
2010-09-13 12:10:43 +01:00
applet.set_style( style )
def changeTheme(self, *args):
2013-03-04 15:01:20 +00:00
self.reloadSettings()
self.applyTheme()
self.mainwin.RegenPlugins()
def applyTheme(self):
2013-03-04 12:57:17 +00:00
style_settings = Gtk.Settings.get_default()
2013-03-04 15:01:20 +00:00
mate_settings = Gio.Settings.new("org.mate.interface")
desktop_theme = mate_settings.get_string('gtk-theme')
if self.theme_name == "default":
2010-09-17 14:55:03 +01:00
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)
2010-09-13 12:10:43 +01:00
def changeOrientation( self, *args, **kargs ):
2013-03-04 15:01:20 +00:00
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
2013-03-04 12:57:17 +00:00
tmpbox = Gtk.HBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 0 )
self.button_box.reorder_child( self.button_icon, 0 )
self.button_icon.set_padding( 5, 0 )
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.LEFT:
2013-03-04 12:57:17 +00:00
tmpbox = Gtk.VBox()
2010-09-13 12:10:43 +01:00
self.systemlabel.set_angle( 270 )
self.button_box.reorder_child( self.button_icon, 1 )
self.button_icon.set_padding( 0, 5 )
2013-03-04 15:01:20 +00:00
elif self.applet.get_orient() == MatePanelApplet.AppletOrient.RIGHT:
2013-03-04 12:57:17 +00:00
tmpbox = Gtk.VBox()
2010-09-13 12:10:43 +01:00
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):
2013-03-09 19:26:22 +00:00
try:
if self.hotkeyText != "":
self.keybinder.grab( self.hotkeyText )
2013-03-10 00:43:27 +00:00
self.keybinder.connect("activate", self.onBindingPress)
self.keybinder.start()
2013-03-09 19:26:22 +00:00
# Binding menu to hotkey
print "Binding to Hot Key: " + self.hotkeyText
except Exception, cause:
print "** WARNING ** - Menu Hotkey Binding Error"
print "Error Report :\n", str(cause)
pass
2010-09-13 12:10:43 +01:00
def hotkeyChanged (self, schema, key):
self.keybinder.ungrab()
self.hotkeyText = self.settings.get_string( "hot-key" )
if self.hotkeyText != "":
self.keybinder.grab(self.hotkeyText)
2010-09-13 12:10:43 +01:00
def sizeButton( self ):
if self.hideIcon:
self.button_icon.hide()
else:
self.button_icon.show()
2013-03-06 23:23:28 +00:00
# This code calculates width and height for the button_box
# and takes the orientation in account
sl_req = Gtk.Requisition()
bi_req = Gtk.Requisition()
self.button_icon.size_request(bi_req)
self.systemlabel.size_request(sl_req)
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
if self.hideIcon:
self.systemlabel.size_request(sl_req)
self.applet.set_size_request( sl_req.width + 2, -1 )
else:
self.applet.set_size_request( sl_req.width + bi_req.width + 5, bi_req.height )
else:
if self.hideIcon:
self.applet.set_size_request( bi_req.width, sl_req.height + 2 )
else:
self.applet.set_size_request( bi_req.width, sl_req.height + bi_req.height + 5 )
2013-03-04 15:01:20 +00:00
def reloadSettings( self, *args ):
self.loadSettings()
self.updateButton()
2010-09-13 12:10:43 +01:00
2013-03-07 03:08:11 +00:00
def showAboutDialog( self, action, userdata = None ):
2010-09-13 12:10:43 +01:00
2013-03-04 12:57:17 +00:00
about = Gtk.AboutDialog()
2010-09-13 12:10:43 +01:00
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") )
2013-03-07 03:08:11 +00:00
# about.set_authors( ["Clement Lefebvre <clem@linuxmint.com>", "Lars-Peter Clausen <lars@laprican.de>"] )
2010-09-13 12:10:43 +01:00
about.set_translator_credits(("translator-credits") )
#about.set_copyright( _("Based on USP from S.Chanderbally") )
2013-03-04 12:57:17 +00:00
about.set_logo( GdkPixbuf.Pixbuf.new_from_file("/usr/lib/linuxmint/mintMenu/icon.svg") )
2010-09-13 12:10:43 +01:00
about.connect( "response", lambda dialog, r: dialog.destroy() )
about.show()
2013-03-07 01:16:45 +00:00
def showPreferences( self, action, userdata = None ):
# Execute( "mateconf-editor /apps/mintMenu" )
2010-09-13 12:10:43 +01:00
Execute( os.path.join( PATH, "mintMenuConfig.py" ) )
2013-03-07 01:16:45 +00:00
def showMenuEditor( self, action, userdata = None ):
Execute( "mozo" )
2010-09-13 12:10:43 +01:00
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 ):
2013-03-04 12:57:17 +00:00
if self.applet.state & Gtk.StateType.SELECTED:
2010-09-13 12:10:43 +01:00
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
2013-03-06 23:39:13 +00:00
x = c_int()
y = c_int()
2010-09-13 12:10:43 +01:00
# Get the dimensions/position of the widgetToAlignWith
2013-03-06 23:39:13 +00:00
gdk.gdk_window_get_origin(hash(self.applet.window), byref(x), byref(y))
entryX = x.value
entryY = y.value
2010-09-13 12:10:43 +01:00
entryWidth, entryHeight = self.applet.get_allocation().width, self.applet.get_allocation().height
entryHeight = entryHeight + self.mainwin.offset
# Get the screen dimensions
2013-03-04 12:57:17 +00:00
screenHeight = Gdk.Screen.height()
screenWidth = Gdk.Screen.width()
2013-03-04 15:01:20 +00:00
if self.applet.get_orient() == MatePanelApplet.AppletOrient.UP or self.applet.get_orient() == MatePanelApplet.AppletOrient.DOWN:
2010-09-13 12:10:43 +01:00
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):
2013-03-07 01:16:45 +00:00
action_group = Gtk.ActionGroup("context-menu")
action = Gtk.Action("MintMenuPrefs", _("Preferences"), None, "gtk-preferences")
action.connect("activate", self.showPreferences)
action_group.add_action(action)
action = Gtk.Action("MintMenuEdit", _("Edit menu"), None, "gtk-edit")
action.connect("activate", self.showMenuEditor)
action_group.add_action(action)
action = Gtk.Action("MintMenuReload", _("Reload plugins"), None, "gtk-refresh")
action.connect("activate", self.mainwin.RegenPlugins)
action_group.add_action(action)
action = Gtk.Action("MintMenuAbout", _("About"), None, "gtk-about")
action.connect("activate", self.showAboutDialog)
action_group.add_action(action)
action_group.set_translation_domain ("mintmenu")
2013-03-09 01:06:06 +00:00
xml = os.path.join( os.path.join( os.path.dirname( __file__ )), "popup.xml" )
2013-03-07 01:16:45 +00:00
self.applet.setup_menu_from_file(xml, action_group)
2009-07-27 11:45:34 +01:00
2013-03-01 16:56:54 +00:00
def applet_factory( applet, iid, data ):
2010-09-13 12:10:43 +01:00
MenuWin( applet, iid )
applet.show()
return True
2009-07-27 11:45:34 +01:00
def quit_all(widget):
2013-03-04 12:57:17 +00:00
Gtk.main_quit()
2010-09-13 12:10:43 +01:00
sys.exit(0)
2009-07-27 11:45:34 +01:00
2013-03-01 16:56:54 +00:00
MatePanelApplet.Applet.factory_main("MintMenuAppletFactory", True,
MatePanelApplet.Applet.__gtype__,
applet_factory, None)