#!/usr/bin/python # Created by Matteo Rattotti on 13/03/06. # Copyright (c) 2006 - 2007 Shiny Frog. All rights reserved. # Contact matteo.rattotti@shinyfrog.net for any problem # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from Foundation import * from AppKit import * import DelibarAppDelegate class menuBuilder (NSObject): def initWithMenuStorePrefs_(self, menu, store, prefs): self = super(menuBuilder, self).init() self.menu = menu self.store = store self.prefs = prefs # Initializing icon self.dirIcon = NSImage.alloc().initByReferencingFile_("deliFolder.png") self.urlIcon = NSImage.alloc().initByReferencingFile_("deliUrl.png") self.recentIcon = NSImage.alloc().initByReferencingFile_("deliRecent.png") self.bundleIcon = NSImage.alloc().initByReferencingFile_("deliBundle.png") # Sorting store if self.prefs.sortValue() == "Freq": self.store.sortTagByFreq() else: self.store.sortTagByAlpha() return self def dealloc(self): pass def cleanMenu(self): c = self.menu.itemArray() num = self.menu.numberOfItems() index = 0 for a in c: if index > 1: self.menu.removeItem_(a) index = index + 1 def createMenu(self): self.cleanMenu() self.buildRecentMenu() self.buildBundleMenu() if self.prefs.nestingValue() == "Plain": self.buildPlainMenu() else: self.buildNestedMenu() # shorten the title or the url of a post (for display purpose or menu will become too long) def minimizeTitle(self, title, maxLenght = 50): if len(title) > maxLenght: firstHalf = maxLenght/2 secondHalf = maxLenght - firstHalf title = title[:firstHalf] + " ... " + title[-secondHalf:] # Capitalizing first letter for sorting menu purpose title = title[0].upper() + title[1:] return title def createBookmark(self, post): # Create the menu item with all the bell and whistle label = self.minimizeTitle(post['desc']) bookmark = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(label, DelibarAppDelegate.DelibarAppDelegate.openUrl, "") bookmark.setImage_(self.urlIcon) bookmark.setToolTip_(post['url']) return bookmark def createAltBookmark(self, post): # Create the menu item with all the bell and whistle label = self.minimizeTitle(post['url'])#, len(post['desc'])) bookmark = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(label, DelibarAppDelegate.DelibarAppDelegate.openUrl, "") bookmark.setImage_(self.urlIcon) bookmark.setToolTip_(post['url']) return bookmark def buildRecentMenu(self): recentMItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_("recent posts:", None, "") recentMItem.setImage_(self.recentIcon) recentSubMenu = NSMenu.alloc().initWithTitle_("recent posts:") recentMItem.setSubmenu_(recentSubMenu) self.menu.addItem_(recentMItem) for url in self.store.returnRecent(): subI = self.createBookmark(url) recentSubMenu.addItem_(subI) # Adding Alternate version itemPostAlternate = self.createAltBookmark(url) itemPostAlternate.setAlternate_(1) itemPostAlternate.setKeyEquivalentModifierMask_(NSAlternateKeyMask) recentSubMenu.addItem_(itemPostAlternate) menuSep = NSMenuItem.separatorItem() self.menu.addItem_(menuSep) def buildBundleMenu(self): if len(self.store.returnBundles()) == 0: return bundleLabel = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_("Bundles:", None, "") self.menu.addItem_(bundleLabel) bundles = self.store.returnBundles() for b in bundles: # Setting each bundle menu' menuItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(b, None, "") menuItem.setImage_(self.bundleIcon) self.menu.addItem_(menuItem) subm = NSMenu.alloc().initWithTitle_(b) menuItem.setSubmenu_(subm) # Filling bundle menu' with proper tag, and setting tag as menu for tag in bundles[b]: tagItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(tag, None, "") tagItem.setImage_(self.dirIcon) subm.addItem_(tagItem) tagMenu = NSMenu.alloc().initWithTitle_(tag) tagItem.setSubmenu_(tagMenu) # Creating bookmark in tag menu for url in self.store.__getattr__(tag): subI = self.createBookmark(url) tagMenu.addItem_(subI) # Adding Alternate version itemPostAlternate = self.createAltBookmark(url) itemPostAlternate.setAlternate_(1) itemPostAlternate.setKeyEquivalentModifierMask_(NSAlternateKeyMask) tagMenu.addItem_(itemPostAlternate) menuSep = NSMenuItem.separatorItem() self.menu.addItem_(menuSep) def buildPlainMenu(self): tagLabel = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_("Tags:", None, "") self.menu.addItem_(tagLabel) # Setting max count for tag cloudCount = self.prefs.cloudValue() for tag in self.store.tags: # Checking if n of post is < than user prefs if tag['count'] < cloudCount: continue # creating item and setting image itemTag = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(tag['tag'], None, "") itemTag.setImage_(self.dirIcon) itemTag.setToolTip_("Number of posts: %s" %(tag['count'])) # creating menu tagMenu = NSMenu.alloc().initWithTitle_(tag['tag']) # assign menu to the item itemTag.setSubmenu_(tagMenu) # Populating the menu #for post in self.store.__getattr__(tag['tag']): for post in self.store.returnPostsForTag(tag['tag']): itemPost = self.createBookmark(post) tagMenu.addItem_(itemPost) # Creating alternate bookmarks (shown with ALT key) itemPostAlternate = self.createAltBookmark(post) itemPostAlternate.setAlternate_(1) itemPostAlternate.setKeyEquivalentModifierMask_(NSAlternateKeyMask) #itemPostAlternate.setTarget_(DelibarAppDelegate.DelibarAppDelegate) tagMenu.addItem_(itemPostAlternate) # put the item on the main menu self.menu.addItem_(itemTag) def buildNestedMenu(self): tagLabel = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_("Tags:", None, "") self.menu.addItem_(tagLabel) # Setting max count for tag cloudCount = self.prefs.cloudValue() for tag in self.store.tags: if tag['count'] < cloudCount: continue # creating item and setting image itemTag = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(tag['tag'], None, "") itemTag.setImage_(self.dirIcon) itemTag.setToolTip_("Number of posts: %s" %(tag['count'])) # creating menu tagMenu = NSMenu.alloc().initWithTitle_(tag['tag']) # assign menu to the item itemTag.setSubmenu_(tagMenu) # Scanning post per tag for post in self.store.returnPostsForTag(tag['tag']): tagList = post['tag'].split(" ") # If a post has more than one tag, we'll create submenu if len(tagList) > 1: # One menu for each tag for singleTag in tagList: # We don't need to recreate the same tag if singleTag != tag['tag']: # the post entry itemPost = self.createBookmark(post) # Alternate post itemPostAlternate = self.createAltBookmark(post) itemPostAlternate.setAlternate_(1) itemPostAlternate.setKeyEquivalentModifierMask_(NSAlternateKeyMask) try: # Trying to append directly in menu tagMenu.itemWithTitle_(singleTag).submenu().addItem_(itemPost) tagMenu.itemWithTitle_(singleTag).submenu().addItem_(itemPostAlternate) except: # If desired menu don't exist we'll create one, and we'll append post newMenu = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(singleTag, None, "") newMenu.setImage_(self.dirIcon) newSubMenu = NSMenu.alloc().initWithTitle_(singleTag) newSubMenu.addItem_(itemPost) newSubMenu.addItem_(itemPostAlternate) newMenu.setSubmenu_(newSubMenu) tagMenu.addItem_(newMenu) # if the post has only one tag we'll append directly in the menu else: # the post entry itemPost = self.createBookmark(post) # Alternate post #itemPostAlternate = self.createAltBookmark(post) #itemPostAlternate.setAlternate_(1) #itemPostAlternate.setKeyEquivalentModifierMask_(NSAlternateKeyMask) tagMenu.addItem_(itemPost) #tagMenu.addItem_(itemPostAlternate) # Sorting item, so we have single url before (they are capitalized, so got priority) # then all the submenu in alphabetically order tmpMenu = [] for item in tagMenu.itemArray(): tmpMenu.append(item.title()) finalMenu = NSMenu.alloc().initWithTitle_(tag['tag']) tmpMenu.sort() for item in tmpMenu: tmpItem = tagMenu.itemWithTitle_(item) index = tagMenu.indexOfItem_(tmpItem) tagMenu.removeItem_(tmpItem) finalMenu.addItem_(tmpItem) # Getting desc for creating alternate url = tmpItem.toolTip() if url is not None: post = self.store.returnPostWithUrl(url) itemPostAlternate = self.createAltBookmark(post) itemPostAlternate.setAlternate_(1) itemPostAlternate.setKeyEquivalentModifierMask_(NSAlternateKeyMask) finalMenu.addItem_(itemPostAlternate) # Setting the new ordered submenu itemTag.setSubmenu_(finalMenu) # put the whole tag menu on the main menu self.menu.addItem_(itemTag)