source: products/qPloneDropDownMenu/branches/0.2/DropDownMenuTool.py @ 463

Last change on this file since 463 was 1, checked in by myroslav, 18 years ago

Building directory structure

File size: 13.0 KB
Line 
1import os
2from cStringIO import StringIO
3
4from Globals import InitializeClass
5from Globals import package_home
6from Persistence import PersistentMapping
7try:
8    from ZODB.PersistentList import PersistentList
9except ImportError:
10    from persistent.list import PersistentList
11
12from OFS.SimpleItem import SimpleItem
13from AccessControl import ClassSecurityInfo
14
15from Products.PageTemplates.PageTemplateFile import PageTemplateFile
16from Products.CMFCore.utils import getToolByName, UniqueObject
17from Products.CMFCore.Expression import Expression, createExprContext
18from Products.CMFCore.CMFCorePermissions import ManagePortal, View
19
20from config import UNIQUE_ID
21
22from zLOG import LOG
23
24_wwwdir = os.path.join(package_home(globals()), 'www')
25
26class MenuItem(SimpleItem):
27    """ Element for displaying item in portal tab submenu """
28
29    security = ClassSecurityInfo()
30
31    def __init__(self, title, url=None):
32        """ Initialize """
33        self._title = title
34        self._url = url
35        self._menu_items = PersistentList()
36
37    security.declarePublic('getTitle')
38    def getTitle(self):
39        """ Simple accessor. """
40        return self._title
41
42    security.declareProtected(ManagePortal, 'setTitle')
43    def setTitle(self, title):
44        """ Set menu item's title """
45        self._title = title
46
47    security.declarePublic('getUrl')
48    def getUrl(self):
49        """ Simple accessor. """
50        return self._url
51
52    security.declareProtected(ManagePortal, 'setUrl')
53    def setUrl(self, url):
54        """ Set menu item's url """
55        self._url = url
56
57    security.declarePublic('listMenuItems')
58    def listMenuItems(self):
59        """Get all the menu items in subMenu. """
60        return [x.__of__(self) for x in self._menu_items] or []
61
62    security.declareProtected(ManagePortal, 'setSubMenu')
63    def setMenuItems(self, items):
64        """ Set menu item's subMenu object """
65        self._menu_items = PersistentList(items)
66
67    security.declareProtected(ManagePortal, 'addItem')
68    def addItem(self, item):
69        """ Add MenuItem to _menu_items list """
70        self._menu_items.append(item)
71
72    security.declareProtected(ManagePortal, 'deleteItem')
73    def deleteItem(self, idx):
74        """ Delete MenuItem from _menu_items list """
75        return self._menu_items.pop(idx)
76
77
78InitializeClass(MenuItem)
79
80class DropDownMenuTool(UniqueObject, SimpleItem):
81
82    meta_type = 'DropDownMenu Tool'
83    id = UNIQUE_ID
84    title="DropDown Menu Tool"
85
86    _submenu_mapping = PersistentMapping()
87
88    security = ClassSecurityInfo()
89
90    manage_options = ({'label' : 'Sub Menus',
91                       'action' : 'manage_editSubMenus'},) + SimpleItem.manage_options
92
93    security.declareProtected(ManagePortal, 'manage_editSubMenus')
94    manage_editSubMenus = PageTemplateFile('editSubMenus', _wwwdir)
95
96    security.declareProtected(ManagePortal, 'manage_editMenuItems')
97    manage_editMenuItems = PageTemplateFile('editMenuItems', _wwwdir)
98
99    security.declareProtected(ManagePortal, 'listPortalTabActions')
100    def listPortalTabActions(self):
101        """ Return all portal actions with 'portal_tabs' category. """
102        result = []
103        pu = getToolByName(self, 'plone_utils')
104        if hasattr(pu, 'createTopLevelTabs'):
105            pactions = getToolByName(self, 'portal_actions').listFilteredActionsFor(self)
106            tl_tabs = pu.createTopLevelTabs(pactions)
107            for act in tl_tabs:
108                data = {'title': act['name'],
109                        'id':act['id'],
110                        'actionExpression': act['url']}
111                result.append(data)
112        else:
113            portal = getToolByName(self, 'portal_url').getPortalObject()
114            portal_act = getToolByName(self, 'portal_actions')
115            actions = portal_act._cloneActions()
116
117            for act in actions:
118                if act.category == 'portal_tabs':
119                    data = {'title': act.title,
120                             'id': act.id,
121                             'actionExpression': \
122                             Expression(act.getActionExpression())(createExprContext(portal, portal, portal))}
123                    result.append(data)
124        return result
125
126    security.declareProtected(ManagePortal, 'generateSubMenuMapping')
127    def generateSubMenuMapping(self):
128        """  Create top-level subMenu mapping. """
129        mapping = self._submenu_mapping
130        #for item in mapping.keys():
131            #for tab in self.listPortalTabActions():
132                #if item == tab['title']:
133                    #present = True
134                    #break
135                #else: present = False
136            #if not present: del mapping[item]
137        for tab in self.listPortalTabActions():
138            if tab['title'] not in mapping.keys():
139                mapping[tab['title']] = PersistentList()
140        self._submenu_mapping = mapping
141        return self._submenu_mapping
142
143    security.declareProtected('View', 'getValueByKey')
144    def getValueByKey(self, key):
145        """  Return value from _submenu_mapping for given key """
146        try:
147            return [item.__of__(self) for item in self._submenu_mapping[key]]
148        except KeyError:
149            return None
150
151    security.declareProtected(ManagePortal, 'validateTitle')
152    def validateTitle(self, title):
153        """ Safeguard against empty (later duplicate ;) title. """
154        if not title:
155            raise ValueError, 'Please, enter title'
156        else: return 1
157
158    security.declareProtected(ManagePortal, 'getSubMenuByPath')
159    def getSubMenuByPath(self, submenu_path):
160        """ Return submenu for a given submenu_path """
161        if submenu_path in self._submenu_mapping.keys():
162            return self.getValueByKey(submenu_path)
163        else:
164            #LOG('getSubMenuByPath', 111, 'afterElseSubmenuPath', str(submenu_path))
165            return self.getMenuItemByPath(submenu_path).listMenuItems()
166
167    security.declareProtected(ManagePortal, 'getMenuItemByPath')
168    def getMenuItemByPath(self, submenu_path):
169        """ Return menuitem for a given submenu_path """
170        path = submenu_path.strip().split('/')
171        menuitem = self.getValueByKey(path[0])[int(path[1])]
172        for i in path[2:]:
173            menuitem = menuitem.listMenuItems()[int(i)]
174        return menuitem
175
176    security.declareProtected(ManagePortal, 'getBreadcrumbs')
177    def getBreadcrumbs(self, submenu_path):
178        """ Return breadcrumbs dictionary for listMenuItems form """
179        path = submenu_path.split('/')
180        result  = [{'title' : path[0],
181                    'url'   : '%s/manage_editMenuItems?submenu_path=%s'%(self.absolute_url(), path[0])},]
182        for i in range(len(path[1:])):
183            temp_path = '/'.join(path[:i+2])
184            result.append({'title' : self.getMenuItemByPath(temp_path).getTitle(),
185                            'url'   : '%s/manage_editMenuItems?submenu_path=%s'%(self.absolute_url(), temp_path)})
186        return result
187
188    #security.declareProtected(ManagePortal, 'getLevel')
189    #def getLevel(self, submenu, space, lst):
190        #if submenu != None:
191    ##        if submenu.listMenuItems() != ():
192            #space += '    '
193            #for menuitem in submenu.listMenuItems():
194                #lst += space + menuitem.getTitle() + '  ==  ' + str(menuitem.getSubMenu()) + '\n'
195                #lst = str(self.getLevel(menuitem.getSubMenu(), space, lst))
196            #return lst
197        #else: return lst
198
199    #security.declareProtected(ManagePortal, 'getMenuTree')
200    #def getMenuTree(self):
201        #""" Return all submenu with it's menuitems """
202        #out = '\n'
203        #mapping = self._submenu_mapping
204        #for item in mapping.items():
205            #space = ''
206            #out += space + item[0] + '  ---  ' + str(item[1]) + '\n'
207            #if item[1] != '':
208                #out += space + str(self.getValueByKey(item[0])) + '\n' + str(self.getLevel(self.getValueByKey(item[0]), space, lst=''))
209        #return out
210
211    security.declareProtected(ManagePortal, 'manage_addMenuItem')
212    def manage_addMenuItem(self, submenu_path, title, url=None, REQUEST=None):
213        """ Add MenuItem via ZMI """
214        self.validateTitle(title)
215        if submenu_path in self._submenu_mapping.keys():
216            self._submenu_mapping[submenu_path].append(MenuItem(title, url))
217        else:
218            self.getMenuItemByPath(submenu_path).addItem(MenuItem(title, url))
219
220        if REQUEST:
221            REQUEST['RESPONSE'].redirect( '%s/manage_editMenuItems'
222                                          '?submenu_path=%s&manage_tabs_message=MenuItem+\'%s\'+added.'
223                                        % (self.absolute_url(), submenu_path, title))
224
225    security.declareProtected(ManagePortal, 'manage_removeMenuItem')
226    def manage_removeMenuItem(self, submenu_path, REQUEST=None):
227        """ Remove MenuItem via ZMI """
228        path = submenu_path.strip().split('/')
229        if len(path)==2:
230            self._submenu_mapping[path[0]].pop(int(path[1]))
231        elif len(path)>2:
232            self.getMenuItemByPath('/'.join(path[:-1])).deleteItem(int(path[-1]))
233
234        if REQUEST:
235            REQUEST['RESPONSE'].redirect( '%s/manage_editMenuItems'
236                                          '?submenu_path=%s&manage_tabs_message=MenuItem+removed.'
237                                        % (self.absolute_url(), '/'.join(path[:-1])))
238
239    security.declareProtected(ManagePortal, 'manage_saveMenuItems')
240    def manage_saveMenuItems(self, submenu_path, REQUEST=None):
241        """  Save MenuItems for given subMenu via ZMI. """
242        records = REQUEST.get('menuitems')
243        if submenu_path in self._submenu_mapping.keys():
244            submenu = self._submenu_mapping[submenu_path]
245        else:
246            submenu = self.getSubMenuByPath(submenu_path)
247        if records and len(records) == len(submenu):
248             for i in range(len(submenu)):
249                 if records[i].get('title'): submenu[i].setTitle(records[i].get('title'))
250                 submenu[i].setUrl(records[i].get('url'))
251
252        if REQUEST:
253            REQUEST['RESPONSE'].redirect('%s/manage_editMenuItems'
254                                         '?&submenu_path=%s&manage_tabs_message=MenuItems+updated.'
255                                        % (self.absolute_url(), submenu_path))
256
257    security.declareProtected(ManagePortal, 'manage_moveMenuItemDown')
258    def manage_moveMenuItemDown(self, submenu_path, REQUEST=None):
259        """ Move the MenuItem down via ZMI """
260        path = submenu_path.strip().split('/')
261        if len(path)==2:
262            self._submenu_mapping[path[0]] = PersistentList(self.moveItem(path[1], int(path[1])+1, self._submenu_mapping[path[0]]))
263        elif len(path)>2:
264            menuitem = self.getMenuItemByPath('/'.join(path[:-1]))
265            menuitem.setMenuItems(list(self.moveItem(path[-1], int(path[-1])+1, menuitem.listMenuItems())))
266
267        if REQUEST:
268            REQUEST['RESPONSE'].redirect('%s/manage_editMenuItems'
269                                         '?&submenu_path=%s&manage_tabs_message=MenuItem+moved+up.'
270                                        % (self.absolute_url(), '/'.join(path[:-1])))
271
272    security.declareProtected(ManagePortal, 'manage_moveMenuItemUp')
273    def manage_moveMenuItemUp(self, submenu_path, REQUEST=None):
274        """ Move the MenuItem up via ZMI """
275        path = submenu_path.strip().split('/')
276        if len(path)==2:
277            self._submenu_mapping[path[0]] = PersistentList(self.moveItem(path[1], int(path[1])-1, self._submenu_mapping[path[0]]))
278        elif len(path)>2:
279            menuitem = self.getMenuItemByPath('/'.join(path[:-1]))
280            menuitem.setMenuItems(list(self.moveItem(path[-1], int(path[-1])-1, menuitem.listMenuItems())))
281
282        if REQUEST:
283            REQUEST['RESPONSE'].redirect('%s/manage_editMenuItems'
284                                         '?&submenu_path=%s&manage_tabs_message=MenuItem+moved+up.'
285                                        % (self.absolute_url(), '/'.join(path[:-1])))
286
287    security.declareProtected(ManagePortal, 'moveItem')
288    def moveItem(self, index, position, menuitems):
289        """ Move an item to the given position."""
290        if index == position:
291            return
292        elif position < 0:
293            position = 0
294        menuitems = list(menuitems)
295        menuitem = menuitems.pop(int(index))
296        menuitems.insert(int(position), menuitem)
297        return menuitems
298
299    security.declareProtected(ManagePortal, 'manage_reorderItems')
300    def manage_reorderItems(self, idxs, submenu_path):
301        """ Reorder menu items of the same submenu in given order """
302        path = submenu_path.strip().split('/')
303        submenu = self.reorderItems(idxs, self.getSubMenuByPath(submenu_path))
304        if len(path) == 1:
305            self._submenu_mapping[path[0]] = PersistentList(submenu)
306        elif len(path) > 1:
307            menuitem = self.getMenuItemByPath(submenu_path)
308            menuitem.setMenuItems(submenu)
309
310    security.declareProtected(ManagePortal, 'reorderItems')
311    def reorderItems(self, idxs, submenu):
312        """ Return list in given order """
313        idxs = list(map(int,idxs))
314        #if len(idxs) != len(submenu): return False
315        return [submenu[idx] for idx in idxs]
316
317InitializeClass(DropDownMenuTool)
Note: See TracBrowser for help on using the repository browser.