#!/usr/bin/env python from gi.repository import Gtk, GdkPixbuf, Gdk, GLib from gi.repository import Pango #import matedesktop from gi.repository import GObject import os.path import shutil import re from execute import * import xdg.DesktopEntry import xdg.Menu from filemonitor import monitor as filemonitor import ctypes from ctypes import * gtk = CDLL("libgtk-x11-2.0.so.0") class IconManager(GObject.GObject): __gsignals__ = { "changed" : (GObject.SignalFlags.RUN_LAST, None, () ) } def __init__( self ): GObject.GObject.__init__( self ) self.icons = { } self.count = 0 # Some apps don't put a default icon in the default theme folder, so we will search all themes def createTheme( d ): theme = Gtk.IconTheme() theme.set_custom_theme( d ) return theme # This takes to much time and there are only a very few applications that use icons from different themes #self.themes = map( createTheme, [ d for d in os.listdir( "/usr/share/icons" ) if os.path.isdir( os.path.join( "/usr/share/icons", d ) ) ] ) defaultTheme = Gtk.IconTheme.get_default() defaultKdeTheme = createTheme( "kde.default" ) # Themes with the same content as the default them aren't needed #self.themes = [ theme for theme in self.themes if theme.list_icons() != defaultTheme.list_icons() ] self.themes = [ defaultTheme, defaultKdeTheme ] self.cache = {} # Listen for changes in the themes for theme in self.themes: theme.connect("changed", self.themeChanged ) def getIcon( self, iconName, iconSize ): if not iconName: return None try: iconFileName = "" canSetByName = True #[ iconWidth, iconHeight ] = self.getIconSize( iconSize ) if iconSize <= 0: return None elif os.path.isabs( iconName ): iconFileName = iconName canSetByName = False else: if iconName[-4:] in [".png", ".xpm", ".svg", ".gif"]: realIconName = iconName[:-4] else: realIconName = iconName if iconFileName and not canSetByName and os.path.exists( iconFileName ): icon = GdkPixbuf.Pixbuf.new_from_file_at_size( iconFileName, iconSize, iconSize ) # if the actual icon size is to far from the desired size resize it if icon and (( icon.get_width() - iconSize ) > 5 or ( icon.get_height() - iconSize ) > 5): if icon.get_width() > icon.get_height(): newIcon = icon.scale_simple( iconSize, icon.get_height() * iconSize / icon.get_width(), GdkPixbuf.InterpType.BILINEAR ) else: newIcon = icon.scale_simple( icon.get_width() * iconSize / icon.get_height(), iconSize, GdkPixbuf.InterpType.BILINEAR ) del icon icon = newIcon image = Gtk.Image.new_from_pixbuf(icon) elif canSetByName: image = Gtk.Image() icon_found = False for theme in self.themes: if theme.has_icon( realIconName ): icon_found = True break if icon_found: image.set_from_icon_name(realIconName, Gtk.IconSize.DND) image.set_pixel_size(iconSize) else: image = None else: image = None return image except Exception, e: print "Exception " + e.__class__.__name__ + ": " + e.message return None def themeChanged( self, theme ): self.cache = { } self.emit( "changed" ) GObject.type_register(IconManager) class easyButton( Gtk.Button ): def __init__( self, iconName, iconSize, labels = None, buttonWidth = -1, buttonHeight = -1 ): GObject.GObject.__init__( self ) self.connections = [ ] self.iconName = iconName self.iconSize = iconSize self.showIcon = True self.set_relief( Gtk.ReliefStyle.NONE ) self.set_size_request( buttonWidth, buttonHeight ) Align1 = Gtk.Alignment.new( 0, 0.5, 1.0, 0 ) HBox1 = Gtk.HBox() self.labelBox = Gtk.VBox( False, 2 ) self.buttonImage = Gtk.Image() icon = self.getIcon( self.iconSize ) if icon: self.buttonImage = icon else: #[ iW, iH ] = iconManager.getIconSize( self.iconSize ) self.buttonImage.set_size_request( self.iconSize, self.iconSize ) self.image_box = Gtk.HBox() self.image_box.pack_start(self.buttonImage, False, False, 5) self.image_box.show_all() HBox1.pack_start( self.image_box, False, False, 0 ) if labels: for label in labels: if isinstance( label, basestring ): self.addLabel( label ) elif isinstance( label, list ): self.addLabel( label[0], label[1] ) self.labelBox.show() HBox1.pack_start( self.labelBox , True, True, 0) HBox1.show() Align1.add( HBox1 ) Align1.show() self.add( Align1 ) self.connectSelf( "destroy", self.onDestroy ) self.connect( "released", self.onRelease ) # Reload icons when the theme changed self.themeChangedHandlerId = iconManager.connect("changed", self.themeChanged ) def connectSelf( self, event, callback ): self.connections.append( self.connect( event, callback ) ) def onRelease( self, widget ): widget.set_state(Gtk.StateType.NORMAL) def onDestroy( self, widget ): self.buttonImage.clear() iconManager.disconnect( self.themeChangedHandlerId ) for connection in self.connections: self.disconnect( connection ) del self.connections def addLabel( self, text, styles = None ): label = Gtk.Label() if "" in text or " 0 and color[0] == "#": #appName = "%s" % (color, appName); #appComment = "%s" % (color, appComment); #appName = "%s" % (appName); #appComment = "%s" % (appComment); #else: #appName = "%s" % (appName); #appComment = "%s" % (appComment); appName = "%s" % (appName); appComment = "%s" % (appComment); except Exception, detail: print detail pass if self.showComment and self.appComment != "": if self.iconSize <= 2: self.addLabel( '%s' % appName) self.addLabel( '%s' % appComment) else: self.addLabel( appName ) self.addLabel( '%s' % appComment) else: self.addLabel( appName ) def execute( self, *args ): self.highlight = False for child in self.labelBox: child.destroy() self.setupLabels() return super(MenuApplicationLauncher, self).execute(*args) def setShowComment( self, showComment ): self.showComment = showComment for child in self.labelBox: child.destroy() self.setupLabels() class FavApplicationLauncher( ApplicationLauncher ): def __init__( self, desktopFile, iconSize, swapGeneric = False ): self.swapGeneric = swapGeneric ApplicationLauncher.__init__( self, desktopFile, iconSize ) def setupLabels( self ): if self.appGenericName: if self.swapGeneric: self.addLabel( '%s' % self.appName ) self.addLabel( self.appGenericName ) else: self.addLabel( '%s' % self.appGenericName ) self.addLabel( self.appName ) else: self.addLabel( '%s' % self.appName ) if self.appComment != "": self.addLabel( self.appComment ) else: self.addLabel ( "" ) def setSwapGeneric( self, swapGeneric ): self.swapGeneric = swapGeneric for child in self.labelBox: child.destroy() self.setupLabels() class CategoryButton( easyButton ): def __init__( self, iconName, iconSize, labels , f ): easyButton.__init__( self, iconName, iconSize, labels ) self.filter = f iconManager = IconManager()