#!/usr/bin/env python from gi.repository import Gtk, GdkPixbuf, Gdk 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 glib 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() 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: #[ iconWidth, iconHeight ] = self.getIconSize( iconSize ) if iconSize <= 0: return None if iconName in self.cache and iconSize in self.cache[iconName]: iconFileName = self.cache[iconName][iconSize] elif os.path.isabs( iconName ): iconFileName = iconName else: if iconName[-4:] in [".png", ".xpm", ".svg", ".gif"]: realIconName = iconName[:-4] else: realIconName = iconName tmp = None for theme in self.themes: if theme.has_icon( realIconName ): tmp = theme.lookup_icon( realIconName, iconSize, 0 ) if tmp: break if tmp: iconFileName = tmp.get_filename() else: iconFileName = "" if iconFileName and os.path.exists( iconFileName ): icon = GdkPixbuf.Pixbuf.new_from_file_at_size( iconFileName, iconSize, iconSize ) else: icon = None # 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 if iconName in self.cache: self.cache[iconName][iconSize] = iconFileName else: self.cache[iconName] = { iconSize : iconFileName } return icon 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.set_from_pixbuf( icon ) del icon else: #[ iW, iH ] = iconManager.getIconSize( self.iconSize ) self.buttonImage.set_size_request( self.iconSize, self.iconSize ) self.buttonImage.show() HBox1.pack_start( self.buttonImage, False, False, 5 ) 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()