From ec963baeab201319f35f38b82b4e7898184c86a3 Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Mon, 13 Sep 2010 15:54:23 +0100 Subject: [PATCH] Highlight newly installed applications --- debian/changelog | 1 + .../mintMenu/plugins/applications.py | 54 +- .../linuxmint/mintMenu/plugins/easybuttons.py | 916 +++++++++--------- 3 files changed, 487 insertions(+), 484 deletions(-) diff --git a/debian/changelog b/debian/changelog index 664500b..f7141dd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ mintmenu (5.0.6) julia; urgency=low * 150ms default hover delay * Fixed empty application list bug * Fixed mouse grab issue + * Highlights newly installed applications -- Clement Lefebvre Mon, 13 Sep 2010 12:09:00 +0000 diff --git a/usr/lib/linuxmint/mintMenu/plugins/applications.py b/usr/lib/linuxmint/mintMenu/plugins/applications.py index 232b842..e0ebf8d 100755 --- a/usr/lib/linuxmint/mintMenu/plugins/applications.py +++ b/usr/lib/linuxmint/mintMenu/plugins/applications.py @@ -221,8 +221,7 @@ class pluginclass( object ): fromFav = [ ( "FAVORITES", gtk.TARGET_SAME_APP, TARGET_TYPE_FAV ) ] @print_timing - def __init__( self, mintMenuWin, toggleButton ): - os.system("echo `date` > /var/tmp/mintmenu.log") + def __init__( self, mintMenuWin, toggleButton ): self.apt_cache = None try: self.apt_cache = apt.Cache() @@ -586,8 +585,7 @@ class pluginclass( object ): self.searchEntry.grab_focus() self.searchEntry.select_region( sel[0], sel[1] ) - def buildButtonList( self ): - os.system("echo buildButtonList >> /var/tmp/mintmenu.log") + def buildButtonList( self ): if self.buildingButtonList: self.stopBuildingButtonList = True gobject.timeout_add( 100, self.buildButtonList ) @@ -595,7 +593,7 @@ class pluginclass( object ): self.stopBuildingButtonList = False - self.updateBoxes() + self.updateBoxes(False) def categoryBtnFocus( self, widget, event, category ): self.scrollItemIntoView( widget ) @@ -1556,34 +1554,28 @@ class pluginclass( object ): if self.menuChangedTimer: gobject.source_remove( self.menuChangedTimer ) - self.menuChangedTimer = gobject.timeout_add( 100, self.updateBoxes ) + self.menuChangedTimer = gobject.timeout_add( 100, self.updateBoxes, True ) - def updateBoxes( self ): - os.system("echo updateboxes >> /var/tmp/mintmenu.log") + def updateBoxes( self, menu_has_changed ): # FIXME: This is really bad! - if self.rebuildLock: - os.system("echo rebuildLock >> /var/tmp/mintmenu.log") + if self.rebuildLock: return self.rebuildLock = True self.menuChangedTimer = None - - os.system("echo step1 >> /var/tmp/mintmenu.log") + self.loadMenuFiles() - os.system("echo step2 >> /var/tmp/mintmenu.log") + # Find added and removed categories than update the category list newCategoryList = self.buildCategoryList() - os.system("echo \"%d categories\" >> /var/tmp/mintmenu.log" % len(newCategoryList)) addedCategories = [] removedCategories = [] # TODO: optimize this!!! if not self.categoryList: - os.system("echo a >> /var/tmp/mintmenu.log") addedCategories = newCategoryList else: - os.system("echo b >> /var/tmp/mintmenu.log") for item in newCategoryList: found = False for item2 in self.categoryList: @@ -1611,17 +1603,12 @@ class pluginclass( object ): else: categoryIconSize = 0 - os.system("echo c >> /var/tmp/mintmenu.log") - for key in removedCategories: self.categoryList[key]["button"].destroy() del self.categoryList[key] - os.system("echo d >> /var/tmp/mintmenu.log") - if addedCategories: sortedCategoryList = [] - os.system("echo e >> /var/tmp/mintmenu.log") for item in self.categoryList: self.categoriesBox.remove( item["button"] ) sortedCategoryList.append( ( str(item["index"]) + item["name"], item["button"] ) ) @@ -1642,10 +1629,8 @@ class pluginclass( object ): self.categoryList.append( item ) sortedCategoryList.append( ( str(item["index"]) + item["name"], item["button"] ) ) - os.system("echo f >> /var/tmp/mintmenu.log") sortedCategoryList.sort() - os.system("echo g >> /var/tmp/mintmenu.log") for item in sortedCategoryList: self.categoriesBox.pack_start( item[1], False ) @@ -1654,14 +1639,11 @@ class pluginclass( object ): newApplicationList = self.buildApplicationList() addedApplications = [] removedApplications = [] - - os.system("echo h >> /var/tmp/mintmenu.log") + # TODO: optimize this!!! if not self.applicationList: - os.system("echo i >> /var/tmp/mintmenu.log") addedApplications = newApplicationList else: - os.system("echo j >> /var/tmp/mintmenu.log") for item in newApplicationList: found = False for item2 in self.applicationList: @@ -1685,25 +1667,22 @@ class pluginclass( object ): # because when it is removed the index of all later items is # going to be decreased key += 1 - os.system("echo k >> /var/tmp/mintmenu.log") + for key in removedApplications: self.applicationList[key]["button"].destroy() - del self.applicationList[key] - os.system("echo l >> /var/tmp/mintmenu.log") + del self.applicationList[key] if addedApplications: sortedApplicationList = [] for item in self.applicationList: self.applicationsBox.remove( item["button"] ) sortedApplicationList.append( ( item["button"].appName, item["button"] ) ) - os.system("echo \"%d added apps\" >> /var/tmp/mintmenu.log" % len(addedApplications)) for item in addedApplications: - item["button"] = MenuApplicationLauncher( item["entry"].get_desktop_file_path(), self.iconSize, item["category"], self.showapplicationcomments ) + item["button"] = MenuApplicationLauncher( item["entry"].get_desktop_file_path(), self.iconSize, item["category"], self.showapplicationcomments, highlight=(True and menu_has_changed) ) if item["button"].appExec: self.mintMenuWin.setTooltip( item["button"], item["button"].getTooltip() ) item["button"].connect( "button-release-event", self.menuPopup ) item["button"].connect( "focus-in-event", self.scrollItemIntoView ) - item["button"].connect( "clicked", lambda w: self.mintMenuWin.hide() ) - os.system("echo \"%s '%s' filter\" >> /var/tmp/mintmenu.log" % (self.activeFilter[0], self.activeFilter[1])) + item["button"].connect( "clicked", lambda w: self.mintMenuWin.hide() ) if self.activeFilter[0] == 0: item["button"].filterText( self.activeFilter[1] ) else: @@ -1714,14 +1693,11 @@ class pluginclass( object ): item["button"].destroy() - sortedApplicationList.sort() - os.system("echo \"%d apps\" >> /var/tmp/mintmenu.log" % len(sortedApplicationList)) + sortedApplicationList.sort() for item in sortedApplicationList: self.applicationsBox.pack_start( item[1], False ) - self.rebuildLock = False - os.system("echo fin >> /var/tmp/mintmenu.log") - + self.rebuildLock = False # Reload the menufiles from the filesystem def loadMenuFiles( self ): diff --git a/usr/lib/linuxmint/mintMenu/plugins/easybuttons.py b/usr/lib/linuxmint/mintMenu/plugins/easybuttons.py index cc4a3ff..c664fbd 100755 --- a/usr/lib/linuxmint/mintMenu/plugins/easybuttons.py +++ b/usr/lib/linuxmint/mintMenu/plugins/easybuttons.py @@ -12,543 +12,569 @@ from execute import * import xdg.DesktopEntry import xdg.Menu from filemonitor import monitor as filemonitor - +import glib class IconManager(gobject.GObject): - __gsignals__ = { - "changed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ) - } + __gsignals__ = { + "changed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, () ) + } - def __init__( self ): - gobject.GObject.__init__( self ) - self.icons = { } - self.count = 0 + 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 + # 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.icon_theme_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 ] + # 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 ) ) ] ) - self.cache = {} + defaultTheme = gtk.icon_theme_get_default() + defaultKdeTheme = createTheme( "kde.default" ) - # Listen for changes in the themes - for theme in self.themes: - theme.connect("changed", self.themeChanged ) + # 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 + def getIcon( self, iconName, iconSize ): + if not iconName: + return None - try: - [ iconWidth, iconHeight ] = self.getIconSize( iconSize ) - if iconWidth <= 0 or iconHeight <= 0: - return None + try: + [ iconWidth, iconHeight ] = self.getIconSize( iconSize ) + if iconWidth <= 0 or iconHeight <= 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, iconWidth, 0 ) - if tmp: - break + 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, iconWidth, 0 ) + if tmp: + break - if tmp: - iconFileName = tmp.get_filename() - else: - iconFileName = "" + if tmp: + iconFileName = tmp.get_filename() + else: + iconFileName = "" - if iconFileName and os.path.exists( iconFileName ): - icon = gtk.gdk.pixbuf_new_from_file_at_size( iconFileName, iconWidth, iconHeight ) - else: - icon = None + if iconFileName and os.path.exists( iconFileName ): + icon = gtk.gdk.pixbuf_new_from_file_at_size( iconFileName, iconWidth, iconHeight ) + else: + icon = None - # if the actual icon size is to far from the desired size resize it - if icon and (( icon.get_width() - iconWidth ) > 5 or ( icon.get_height() - iconHeight ) > 5): - if icon.get_width() > icon.get_height(): - newIcon = icon.scale_simple( iconWidth, icon.get_height() * iconWidth / icon.get_width(), gtk.gdk.INTERP_BILINEAR ) - else: - newIcon = icon.scale_simple( icon.get_width() * iconHeight / icon.get_height(), iconWidth, gtk.gdk.INTERP_BILINEAR ) - del icon - icon = newIcon + # if the actual icon size is to far from the desired size resize it + if icon and (( icon.get_width() - iconWidth ) > 5 or ( icon.get_height() - iconHeight ) > 5): + if icon.get_width() > icon.get_height(): + newIcon = icon.scale_simple( iconWidth, icon.get_height() * iconWidth / icon.get_width(), gtk.gdk.INTERP_BILINEAR ) + else: + newIcon = icon.scale_simple( icon.get_width() * iconHeight / icon.get_height(), iconWidth, gtk.gdk.INTERP_BILINEAR ) + del icon + icon = newIcon - if iconName in self.cache: - self.cache[iconName][iconSize] = iconFileName - else: - self.cache[iconName] = { iconSize : iconFileName } + if iconName in self.cache: + self.cache[iconName][iconSize] = iconFileName + else: + self.cache[iconName] = { iconSize : iconFileName } - return icon - except Exception, e: - print "Excpetion " + e.__class__.__name__ + ": " + e.message - return None - - def getIconSize( self, iconSize ): - if isinstance(iconSize, int): - if iconSize >= 4: - iconSize = gtk.ICON_SIZE_DIALOG - elif iconSize == 3: - iconSize = gtk.ICON_SIZE_DND - elif iconSize == 2: - iconSize = gtk.ICON_SIZE_BUTTON - elif iconSize == 1: - iconSize = gtk.ICON_SIZE_MENU - elif iconSize <= 0: - return ( 0, 0 ) + return icon + except Exception, e: + print "Exception " + e.__class__.__name__ + ": " + e.message + return None - return gtk.icon_size_lookup( iconSize ) + def getIconSize( self, iconSize ): + if isinstance(iconSize, int): + if iconSize >= 4: + iconSize = gtk.ICON_SIZE_DIALOG + elif iconSize == 3: + iconSize = gtk.ICON_SIZE_DND + elif iconSize == 2: + iconSize = gtk.ICON_SIZE_BUTTON + elif iconSize == 1: + iconSize = gtk.ICON_SIZE_MENU + elif iconSize <= 0: + return ( 0, 0 ) - def themeChanged( self, theme ): - self.cache = { } - self.emit( "changed" ) + return gtk.icon_size_lookup( iconSize ) -gobject.type_register(IconManager) + 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 ): - gtk.Button.__init__( self ) - self.connections = [ ] - self.iconName = iconName - self.iconSize = iconSize - self.showIcon = True + def __init__( self, iconName, iconSize, labels = None, buttonWidth = -1, buttonHeight = -1 ): + gtk.Button.__init__( self ) + self.connections = [ ] + self.iconName = iconName + self.iconSize = iconSize + self.showIcon = True - self.set_relief( gtk.RELIEF_NONE ) - self.set_size_request( buttonWidth, buttonHeight ) + self.set_relief( gtk.RELIEF_NONE ) + self.set_size_request( buttonWidth, buttonHeight ) - Align1 = gtk.Alignment( 0, 0.5, 1.0, 0 ) - HBox1 = gtk.HBox() - self.labelBox = gtk.VBox( False, 2 ) + Align1 = gtk.Alignment( 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( iW, iH ) - self.buttonImage.show() - HBox1.pack_start( self.buttonImage, False, False, 5 ) - + 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( iW, iH ) + 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] ) + 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 ) - HBox1.show() - Align1.add( HBox1 ) - Align1.show() - self.add( Align1 ) + self.labelBox.show() + HBox1.pack_start( self.labelBox ) + 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 ) + 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 connectSelf( self, event, callback ): + self.connections.append( self.connect( event, callback ) ) - def onRelease( self, widget ): - widget.set_state(gtk.STATE_NORMAL) + def onRelease( self, widget ): + widget.set_state(gtk.STATE_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( text ) - - if styles: - labelStyle = pango.AttrList() - for attr in styles: - labelStyle.insert( attr ) - label.set_attributes( labelStyle ) - - label.set_ellipsize( pango.ELLIPSIZE_END ) - label.set_alignment( 0.0, 1.0 ) - label.show() - self.labelBox.pack_start( label ) + def onDestroy( self, widget ): + self.buttonImage.clear() + iconManager.disconnect( self.themeChangedHandlerId ) + for connection in self.connections: + self.disconnect( connection ) + del self.connections - def getIcon ( self, iconSize ): - if not self.iconName: - return None + def addLabel( self, text, styles = None ): + label = gtk.Label() + if "" in text: + label.set_markup(text) # don't remove our pango + else: + label.set_markup(glib.markup_escape_text(text)) - icon = iconManager.getIcon( self.iconName, iconSize ) - if not icon: - icon = iconManager.getIcon( "application-default-icon", iconSize ) + if styles: + labelStyle = pango.AttrList() + for attr in styles: + labelStyle.insert( attr ) + label.set_attributes( labelStyle ) - return icon + label.set_ellipsize( pango.ELLIPSIZE_END ) + label.set_alignment( 0.0, 1.0 ) + label.show() + self.labelBox.pack_start( label ) - def setIcon ( self, iconName ): - self.iconName = iconName - self.iconChanged() - # IconTheme changed, setup new button icons - def themeChanged( self, theme ): - self.iconChanged() - - def iconChanged( self ): - icon = self.getIcon( self.iconSize ) - self.buttonImage.clear() - if icon: - self.buttonImage.set_from_pixbuf( icon ) - self.buttonImage.set_size_request( -1, -1 ) - del icon - else: - [iW, iH ] = iconManager.getIconSize( self.iconSize ) - self.buttonImage.set_size_request( iW, iH ) - - def setIconSize( self, size ): - self.iconSize = size - icon = self.getIcon( self.iconSize ) - self.buttonImage.clear() - if icon: - self.buttonImage.set_from_pixbuf( icon ) - self.buttonImage.set_size_request( -1, -1 ) - del icon - elif self.iconSize: - [ iW, iH ] = iconManager.getIconSize( self.iconSize ) - self.buttonImage.set_size_request( iW, iH ) + def getIcon ( self, iconSize ): + if not self.iconName: + return None + + icon = iconManager.getIcon( self.iconName, iconSize ) + if not icon: + icon = iconManager.getIcon( "application-default-icon", iconSize ) + + return icon + + def setIcon ( self, iconName ): + self.iconName = iconName + self.iconChanged() + + # IconTheme changed, setup new button icons + def themeChanged( self, theme ): + self.iconChanged() + + def iconChanged( self ): + icon = self.getIcon( self.iconSize ) + self.buttonImage.clear() + if icon: + self.buttonImage.set_from_pixbuf( icon ) + self.buttonImage.set_size_request( -1, -1 ) + del icon + else: + [iW, iH ] = iconManager.getIconSize( self.iconSize ) + self.buttonImage.set_size_request( iW, iH ) + + def setIconSize( self, size ): + self.iconSize = size + icon = self.getIcon( self.iconSize ) + self.buttonImage.clear() + if icon: + self.buttonImage.set_from_pixbuf( icon ) + self.buttonImage.set_size_request( -1, -1 ) + del icon + elif self.iconSize: + [ iW, iH ] = iconManager.getIconSize( self.iconSize ) + self.buttonImage.set_size_request( iW, iH ) class ApplicationLauncher( easyButton ): - def __init__( self, desktopFile, iconSize ): + def __init__( self, desktopFile, iconSize): - if isinstance( desktopFile, xdg.Menu.MenuEntry ): - desktopItem = desktopFile.DesktopEntry - desktopFile = desktopItem.filename - self.appDirs = desktop.desktopFile.AppDirs - elif isinstance( desktopFile, xdg.Menu.DesktopEntry ): - desktopItem = desktopFile - desktopFile = desktopItem.filename - self.appDirs = [ os.path.dirname( desktopItem.filename ) ] - else: - desktopItem = xdg.DesktopEntry.DesktopEntry( desktopFile ) - self.appDirs = [ os.path.dirname( desktopFile ) ] + if isinstance( desktopFile, xdg.Menu.MenuEntry ): + desktopItem = desktopFile.DesktopEntry + desktopFile = desktopItem.filename + self.appDirs = desktop.desktopFile.AppDirs + elif isinstance( desktopFile, xdg.Menu.DesktopEntry ): + desktopItem = desktopFile + desktopFile = desktopItem.filename + self.appDirs = [ os.path.dirname( desktopItem.filename ) ] + else: + desktopItem = xdg.DesktopEntry.DesktopEntry( desktopFile ) + self.appDirs = [ os.path.dirname( desktopFile ) ] - self.desktopFile = desktopFile - self.startupMonitorId = 0 - - self.loadDesktopEntry( desktopItem ) - - self.desktopEntryMonitors = [] + self.desktopFile = desktopFile + self.startupMonitorId = 0 - base = os.path.basename( self.desktopFile ) - for dir in self.appDirs: - self.desktopEntryMonitors.append( filemonitor.addMonitor( os.path.join(dir, base) , self.onDesktopEntryFileChanged ) ) - - easyButton.__init__( self, self.appIconName, iconSize ) - self.setupLabels() + self.loadDesktopEntry( desktopItem ) - # Drag and Drop - self.connectSelf( "drag_data_get", self.dragDataGet ) - self.drag_source_set( gtk.gdk.BUTTON1_MASK , [ ( "text/plain", 0, 100 ), ( "text/uri-list", 0, 101 ) ], gtk.gdk.ACTION_COPY ) + self.desktopEntryMonitors = [] - icon = self.getIcon( gtk.ICON_SIZE_DND ) - if icon: - self.drag_source_set_icon_pixbuf( icon ) - del icon + base = os.path.basename( self.desktopFile ) + for dir in self.appDirs: + self.desktopEntryMonitors.append( filemonitor.addMonitor( os.path.join(dir, base) , self.onDesktopEntryFileChanged ) ) - self.connectSelf( "focus-in-event", self.onFocusIn ) - self.connectSelf( "focus-out-event", self.onFocusOut ) - self.connectSelf( "enter-notify-event", self.onEnterNotify ) - self.connectSelf( "clicked", self.execute ) - + easyButton.__init__( self, self.appIconName, iconSize ) + self.setupLabels() + + # Drag and Drop + self.connectSelf( "drag_data_get", self.dragDataGet ) + self.drag_source_set( gtk.gdk.BUTTON1_MASK , [ ( "text/plain", 0, 100 ), ( "text/uri-list", 0, 101 ) ], gtk.gdk.ACTION_COPY ) + + icon = self.getIcon( gtk.ICON_SIZE_DND ) + if icon: + self.drag_source_set_icon_pixbuf( icon ) + del icon + + self.connectSelf( "focus-in-event", self.onFocusIn ) + self.connectSelf( "focus-out-event", self.onFocusOut ) + self.connectSelf( "enter-notify-event", self.onEnterNotify ) + self.connectSelf( "clicked", self.execute ) - def loadDesktopEntry( self, desktopItem ): - try: - self.appName = desktopItem.getName() - self.appGenericName = desktopItem.getGenericName() - self.appComment = desktopItem.getComment() - self.appExec = desktopItem.getExec() - self.appIconName = desktopItem.getIcon() - self.appCategories = desktopItem.getCategories() - self.appGnomeDocPath = desktopItem.get( "X-GNOME-DocPath" ) or "" - self.useTerminal = desktopItem.getTerminal() - if not self.appGnomeDocPath: - self.appKdeDocPath = desktopItem.getDocPath() or "" + def loadDesktopEntry( self, desktopItem ): + try: + self.appName = desktopItem.getName() + self.appGenericName = desktopItem.getGenericName() + self.appComment = desktopItem.getComment() + self.appExec = desktopItem.getExec() + self.appIconName = desktopItem.getIcon() + self.appCategories = desktopItem.getCategories() + self.appGnomeDocPath = desktopItem.get( "X-GNOME-DocPath" ) or "" + self.useTerminal = desktopItem.getTerminal() - self.appName = self.appName.strip() - self.appGenericName = self.appGenericName.strip() - self.appComment = self.appComment.strip() - - basename = os.path.basename( self.desktopFile ) - self.startupFilePath = os.path.join( os.path.expanduser("~"), ".config", "autostart", basename ) - if self.startupMonitorId: - filemonitor.removeMonitor( self.startupMonitorId ) - self.startupMonitorId = filemonitor.addMonitor( self.startupFilePath, self.startupFileChanged ) - #self.inStartup = os.path.exists( self.startupFilePath ) + if not self.appGnomeDocPath: + self.appKdeDocPath = desktopItem.getDocPath() or "" - except Exception, e: - print e - self.appName = "" - self.appGenericName = "" - self.appComment = "" - self.appExec = "" - self.appIconName = "" - self.appCategories = "" - self.appDocPath = "" - self.startupMonitorId = 0 + self.appName = self.appName.strip() + self.appGenericName = self.appGenericName.strip() + self.appComment = self.appComment.strip() + + basename = os.path.basename( self.desktopFile ) + self.startupFilePath = os.path.join( os.path.expanduser("~"), ".config", "autostart", basename ) + if self.startupMonitorId: + filemonitor.removeMonitor( self.startupMonitorId ) + self.startupMonitorId = filemonitor.addMonitor( self.startupFilePath, self.startupFileChanged ) + #self.inStartup = os.path.exists( self.startupFilePath ) + + except Exception, e: + print e + self.appName = "" + self.appGenericName = "" + self.appComment = "" + self.appExec = "" + self.appIconName = "" + self.appCategories = "" + self.appDocPath = "" + self.startupMonitorId = 0 - def onFocusIn( self, widget, event ): - self.set_relief( gtk.RELIEF_HALF ) - - def onFocusOut( self, widget, event ): - self.set_relief( gtk.RELIEF_NONE ) + def onFocusIn( self, widget, event ): + self.set_relief( gtk.RELIEF_HALF ) - def onEnterNotify( self, widget, event ): - self.grab_focus() + def onFocusOut( self, widget, event ): + self.set_relief( gtk.RELIEF_NONE ) - def setupLabels( self ): - self.addLabel( self.appName ) + def onEnterNotify( self, widget, event ): + self.grab_focus() - def filterText( self, text ): - keywords = text.lower().split() - appName = self.strip_accents(self.appName.lower()) - appGenericName = self.strip_accents(self.appGenericName.lower()) - appComment = self.strip_accents(self.appComment.lower()) - appExec = self.strip_accents(self.appExec.lower()) - for keyword in keywords: - keyw = self.strip_accents(keyword) - if keyw != "" and appName.find( keyw ) == -1 and appGenericName.find( keyw ) == -1 and appComment.find( keyw ) == -1 and appExec.find( keyw ) == -1: - self.hide() - return False - - self.show() - return True + def setupLabels( self ): + self.addLabel( self.appName ) + + def filterText( self, text ): + keywords = text.lower().split() + appName = self.strip_accents(self.appName.lower()) + appGenericName = self.strip_accents(self.appGenericName.lower()) + appComment = self.strip_accents(self.appComment.lower()) + appExec = self.strip_accents(self.appExec.lower()) + for keyword in keywords: + keyw = self.strip_accents(keyword) + if keyw != "" and appName.find( keyw ) == -1 and appGenericName.find( keyw ) == -1 and appComment.find( keyw ) == -1 and appExec.find( keyw ) == -1: + self.hide() + return False - def strip_accents(self, string): - import unicodedata - return unicodedata.normalize('NFKD', unicode(string)).encode('ASCII', 'ignore') + self.show() + return True + + def strip_accents(self, string): + import unicodedata + return unicodedata.normalize('NFKD', unicode(string)).encode('ASCII', 'ignore') - def getTooltip( self ): - tooltip = self.appName - if self.appComment != "" and self.appComment != self.appName: - tooltip = tooltip + "\n" + self.appComment + def getTooltip( self ): + tooltip = self.appName + if self.appComment != "" and self.appComment != self.appName: + tooltip = tooltip + "\n" + self.appComment - return tooltip + return tooltip - - def dragDataGet( self, widget, context, selection, targetType, eventTime ): - if targetType == 100: # text/plain - selection.set_text( "'" + self.desktopFile + "'", -1 ) - elif targetType == 101: # text/uri-list - if self.desktopFile[0:7] == "file://": - selection.set_uris( [ self.desktopFile ] ) - else: - selection.set_uris( [ "file://" + self.desktopFile ] ) - def execute( self, *args ): - if self.appExec: - if self.useTerminal: - cmd = "x-terminal-emulator -e \"" + self.appExec + "\"" - Execute(cmd) - else: - Execute(self.appExec) + def dragDataGet( self, widget, context, selection, targetType, eventTime ): + if targetType == 100: # text/plain + selection.set_text( "'" + self.desktopFile + "'", -1 ) + elif targetType == 101: # text/uri-list + if self.desktopFile[0:7] == "file://": + selection.set_uris( [ self.desktopFile ] ) + else: + selection.set_uris( [ "file://" + self.desktopFile ] ) - def uninstall (self, *args ): - Execute("gksu /usr/lib/linuxmint/mintMenu/mintRemove.py " + self.desktopFile) + def execute( self, *args ): + if self.appExec: + if self.useTerminal: + cmd = "x-terminal-emulator -e \"" + self.appExec + "\"" + Execute(cmd) + else: + Execute(self.appExec) - # IconTheme changed, setup new icons for button and drag 'n drop - def iconChanged( self ): - easyButton.iconChanged( self ) - - icon = self.getIcon( gtk.ICON_SIZE_DND ) - if icon: - self.drag_source_set_icon_pixbuf( icon ) - del icon + def uninstall (self, *args ): + Execute("gksu /usr/lib/linuxmint/mintMenu/mintRemove.py " + self.desktopFile) - def startupFileChanged( self, *args ): - self.inStartup = os.path.exists( self.startupFilePath ) - - def addToStartup( self ): - startupDir = os.path.join( os.path.expanduser("~"), ".config", "autostart" ); - if not os.path.exists( startupDir ): - os.makedirs( startupDir ) + # IconTheme changed, setup new icons for button and drag 'n drop + def iconChanged( self ): + easyButton.iconChanged( self ) - shutil.copyfile( self.desktopFile, self.startupFilePath ) + icon = self.getIcon( gtk.ICON_SIZE_DND ) + if icon: + self.drag_source_set_icon_pixbuf( icon ) + del icon - # Remove %u, etc. from Exec entry, because gnome will not replace them when it starts the app - item = gnomedesktop.item_new_from_uri( self.startupFilePath, gnomedesktop.LOAD_ONLY_IF_EXISTS ) - if item: - r = re.compile("%[A-Za-z]"); - tmp = r.sub("", item.get_string( gnomedesktop.KEY_EXEC ) ).strip() - item.set_string( gnomedesktop.KEY_EXEC, tmp ) - item.save( self.startupFilePath, 0 ) - - def removeFromStartup( self ): - if os.path.exists( self.startupFilePath ): - os.remove( self.startupFilePath ) - - def addToFavourites( self ): - favouritesDir = os.path.join( os.path.expanduser("~"), ".linuxmint", "mintMenu", "applications" ); - if not os.path.exists( favouritesDir ): - os.makedirs( favouritesDir ) - - shutil.copyfile( self.desktopFile, self.favouritesFilePath ) - - def removeFromFavourites( self ): - if os.path.exists( self.favouritesFilePath ): - os.remove( self.favouritesFilePath ) - - def isInStartup( self ): - #return self.inStartup - return os.path.exists( self.startupFilePath ) - - def hasHelp( self ): - return self.appGnomeDocPath or self.appKdeDocPath - - def launchHelp( self ): - if self.appGnomeDocPath: - bn = os.path.basename( self.appGnomeDocPath ) - dn = os.path.dirname( self.appGnomeDocPath ) - if self.appGnomeDocPath[0:6] != "ghelp:": - self.appGnomeDocPath = "ghelp:" + self.appGnomeDocPath - gnomevfs.url_show( self.appGnomeDocPath ) - elif self.appKdeDocPath: - if self.appKdeDocPath[0:6] != "help:/" and self.appKdeDocPath[0:6] != "file:/": - self.appKdeDocPath = "help:/" + self.appKdeDocPath - if self.appKdeDocPath[0:6] == "file:/": - gnomevfs.url_show( self.appKdeDocPath ) - else: - Execute( [ "khelpcenter", self.appKdeDocPath ] ) + def startupFileChanged( self, *args ): + self.inStartup = os.path.exists( self.startupFilePath ) - def onDestroy( self, widget ): - easyButton.onDestroy( self, widget ) - if self.startupMonitorId: - filemonitor.removeMonitor( self.startupMonitorId ) - for id in self.desktopEntryMonitors: - filemonitor.removeMonitor( id ) + def addToStartup( self ): + startupDir = os.path.join( os.path.expanduser("~"), ".config", "autostart" ); + if not os.path.exists( startupDir ): + os.makedirs( startupDir ) - def onDesktopEntryFileChanged( self ): - exists = False - base = os.path.basename( self.desktopFile ) - for dir in self.appDirs: - if os.path.exists( os.path.join( dir, base ) ): - print os.path.join( dir, base ), self.desktopFile - self.loadDesktopEntry( xdg.DesktopEntry.DesktopEntry( os.path.join( dir, base ) ) ) - for child in self.labelBox: - child.destroy() - - self.iconName = self.appIconName - - self.setupLabels() - self.iconChanged() - exists = True - break - - if not exists: - # FIXME: What to do in this case? - self.destroy() + shutil.copyfile( self.desktopFile, self.startupFilePath ) + + # Remove %u, etc. from Exec entry, because gnome will not replace them when it starts the app + item = gnomedesktop.item_new_from_uri( self.startupFilePath, gnomedesktop.LOAD_ONLY_IF_EXISTS ) + if item: + r = re.compile("%[A-Za-z]"); + tmp = r.sub("", item.get_string( gnomedesktop.KEY_EXEC ) ).strip() + item.set_string( gnomedesktop.KEY_EXEC, tmp ) + item.save( self.startupFilePath, 0 ) + + def removeFromStartup( self ): + if os.path.exists( self.startupFilePath ): + os.remove( self.startupFilePath ) + + def addToFavourites( self ): + favouritesDir = os.path.join( os.path.expanduser("~"), ".linuxmint", "mintMenu", "applications" ); + if not os.path.exists( favouritesDir ): + os.makedirs( favouritesDir ) + + shutil.copyfile( self.desktopFile, self.favouritesFilePath ) + + def removeFromFavourites( self ): + if os.path.exists( self.favouritesFilePath ): + os.remove( self.favouritesFilePath ) + + def isInStartup( self ): + #return self.inStartup + return os.path.exists( self.startupFilePath ) + + def hasHelp( self ): + return self.appGnomeDocPath or self.appKdeDocPath + + def launchHelp( self ): + if self.appGnomeDocPath: + bn = os.path.basename( self.appGnomeDocPath ) + dn = os.path.dirname( self.appGnomeDocPath ) + if self.appGnomeDocPath[0:6] != "ghelp:": + self.appGnomeDocPath = "ghelp:" + self.appGnomeDocPath + gnomevfs.url_show( self.appGnomeDocPath ) + elif self.appKdeDocPath: + if self.appKdeDocPath[0:6] != "help:/" and self.appKdeDocPath[0:6] != "file:/": + self.appKdeDocPath = "help:/" + self.appKdeDocPath + if self.appKdeDocPath[0:6] == "file:/": + gnomevfs.url_show( self.appKdeDocPath ) + else: + Execute( [ "khelpcenter", self.appKdeDocPath ] ) + + def onDestroy( self, widget ): + easyButton.onDestroy( self, widget ) + if self.startupMonitorId: + filemonitor.removeMonitor( self.startupMonitorId ) + for id in self.desktopEntryMonitors: + filemonitor.removeMonitor( id ) + + def onDesktopEntryFileChanged( self ): + exists = False + base = os.path.basename( self.desktopFile ) + for dir in self.appDirs: + if os.path.exists( os.path.join( dir, base ) ): + print os.path.join( dir, base ), self.desktopFile + self.loadDesktopEntry( xdg.DesktopEntry.DesktopEntry( os.path.join( dir, base ) ) ) + for child in self.labelBox: + child.destroy() + + self.iconName = self.appIconName + + self.setupLabels() + self.iconChanged() + exists = True + break + + if not exists: + # FIXME: What to do in this case? + self.destroy() class MenuApplicationLauncher( ApplicationLauncher ): - def __init__( self, desktopFile, iconSize, category, showComment ): + def __init__( self, desktopFile, iconSize, category, showComment, highlight=False ): - self.showComment = showComment - self.appCategory = category + self.showComment = showComment + self.appCategory = category + self.highlight = highlight - ApplicationLauncher.__init__( self, desktopFile, iconSize ) + ApplicationLauncher.__init__( self, desktopFile, iconSize ) - def filterCategory( self, category ): - if self.appCategory == category or category == "": - self.show() - else: - self.hide() + def filterCategory( self, category ): + if self.appCategory == category or category == "": + self.show() + else: + self.hide() - def setupLabels( self ): - if self.showComment and self.appComment != "": - if self.iconSize <= 2: - self.addLabel( self.appName, [ pango.AttrScale( pango.SCALE_SMALL, 0, -1 ) ] ) - self.addLabel( self.appComment, [ pango.AttrScale( pango.SCALE_X_SMALL, 0, -1 ) ] ) - else: - self.addLabel( self.appName ) - self.addLabel( self.appComment, [ pango.AttrScale( pango.SCALE_SMALL, 0, -1 ) ] ) - else: - self.addLabel( self.appName ) - - def setShowComment( self, showComment ): - self.showComment = showComment - for child in self.labelBox: - child.destroy() - self.setupLabels() + def setupLabels( self ): + appName = self.appName + appComment = self.appComment + if self.highlight: + try: + color = self.labelBox.rc_get_style().fg[ gtk.STATE_SELECTED ].to_string() + if len(color) > 0 and color[0] == "#": + appName = "%s" % (color, appName); + appComment = "%s" % (color, appComment); + else: + appName = "%s" % (appName); + appComment = "%s" % (appComment); + except Exception, detail: + print detail + pass + + if self.showComment and self.appComment != "": + if self.iconSize <= 2: + self.addLabel( appName, [ pango.AttrScale( pango.SCALE_SMALL, 0, -1 ) ] ) + self.addLabel( appComment, [ pango.AttrScale( pango.SCALE_X_SMALL, 0, -1 ) ] ) + else: + self.addLabel( appName ) + self.addLabel( appComment, [ pango.AttrScale( pango.SCALE_SMALL, 0, -1 ) ] ) + 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 ): + def __init__( self, desktopFile, iconSize, swapGeneric = False ): - self.swapGeneric = swapGeneric + self.swapGeneric = swapGeneric - ApplicationLauncher.__init__( self, desktopFile, iconSize ) + ApplicationLauncher.__init__( self, desktopFile, iconSize ) - def setupLabels( self ): - if self.appGenericName: - if self.swapGeneric: - self.addLabel( self.appName, [ pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) ] ) - self.addLabel( self.appGenericName ) - else: - self.addLabel( self.appGenericName, [ pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) ] ) - self.addLabel( self.appName ) - else: - if self.appComment != "": - self.addLabel( self.appName, [ pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) ] ) - self.addLabel( self.appComment ) - else: - self.addLabel( self.appName ) + def setupLabels( self ): + if self.appGenericName: + if self.swapGeneric: + self.addLabel( self.appName, [ pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) ] ) + self.addLabel( self.appGenericName ) + else: + self.addLabel( self.appGenericName, [ pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) ] ) + self.addLabel( self.appName ) + else: + if self.appComment != "": + self.addLabel( self.appName, [ pango.AttrWeight( pango.WEIGHT_BOLD, 0, -1 ) ] ) + self.addLabel( self.appComment ) + else: + self.addLabel( self.appName ) - def setSwapGeneric( self, swapGeneric ): - self.swapGeneric = swapGeneric - for child in self.labelBox: - child.destroy() - - self.setupLabels() + 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 + + def __init__( self, iconName, iconSize, labels , f ): + easyButton.__init__( self, iconName, iconSize, labels ) + self.filter = f iconManager = IconManager()