source: products/quintagroup.dropdownmenu/trunk/quintagroup/dropdownmenu/browser/viewlets.py @ 2658

Last change on this file since 2658 was 2658, checked in by fenix, 10 years ago

fixed bug

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1# -*- coding: utf-8 -*-
2from Acquisition import aq_inner
3
4from zope.component import getMultiAdapter, getUtility
5
6from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
7from Products.CMFCore.utils import getToolByName
8from Products.CMFCore.interfaces import IAction, IActionCategory
9from Products.CMFCore.ActionInformation import ActionInfo
10from Products.CMFPlone.utils import versionTupleFromString
11
12from plone.memoize.instance import memoize
13from plone.app.layout.viewlets import common
14from plone.app.layout.navigation.navtree import buildFolderTree
15from plone.app.layout.navigation.interfaces import INavtreeStrategy
16from plone.app.layout.navigation.interfaces import INavigationQueryBuilder
17
18from quintagroup.dropdownmenu.interfaces import IDropDownMenuSettings
19from quintagroup.dropdownmenu.browser.menu import DropDownMenuQueryBuilder
20from quintagroup.dropdownmenu.util import getDropDownMenuSettings
21
22
23class GlobalSectionsViewlet(common.GlobalSectionsViewlet):
24    index = ViewPageTemplateFile('templates/sections.pt')
25    recurse = ViewPageTemplateFile('templates/sections_recurse.pt')
26
27    def update(self):
28        # we may need some previously defined variables
29        #super(GlobalSectionsViewlet, self).update()
30
31        # prepare to gather portal tabs
32        tabs = []
33        context = aq_inner(self.context)
34        self.conf = conf = self._settings()
35        self.tool = getToolByName(context, 'portal_actions')
36
37        # fetch actions-based tabs?
38        if conf.show_actions_tabs:
39            tabs.extend(self._actions_tabs())
40
41        # fetch content structure-based tabs?
42        if conf.show_content_tabs:
43            # put content-based actions before content structure-based ones?
44            if conf.content_before_actions_tabs:
45                tabs = self._content_tabs() + tabs
46            else:
47                tabs.extend(self._content_tabs())
48
49        # assign collected tabs eventually
50        self.portal_tabs = tabs
51
52    def _actions_tabs(self):
53        """Return tree of tabs based on portal_actions tool configuration"""
54        conf = self.conf
55        tool = self.tool
56        context = aq_inner(self.context)
57
58        # check if we have required root actions category inside tool
59        if conf.actions_category not in tool.objectIds():
60            return []
61
62        #category_ids = category.objectIds()
63        #selectedTabs = self.context.restrictedTraverse('selectedTabs')
64        ## try to find out selected subtab
65        #if tab['id'] == self.selected_portal_tab:
66            #selection = selectedTabs(None, None, tab['subtabs'])
67            #self.selected_sub_tab = selection['portal']
68        return self._subactions(tool._getOb(conf.actions_category), context)
69
70    def _subactions(self, category, object, level=0):
71        tabs = []
72        currentParentId = -1
73        index = -1
74        currentParent = False
75        for info in self._actionInfos(category, object):
76            # prepare data for action
77            # TODO: implement current element functionality, maybe should be
78            #       done on a template level because of separate content and
79            #       actions tabs are rendered separately
80            currentItem = False
81
82            index += 1
83            icon = info['icon'] and '<img src="%s" />' % info['icon'] or ''
84
85            # look up children for a given action
86            children = []
87            bottomLevel = self.conf.actions_tabs_level
88            if bottomLevel < 1 or level < bottomLevel:
89                # try to find out appropriate subcategory
90                subcat_id = info['id']
91                if self.conf.nested_category_sufix is not None:
92                    subcat_id += self.conf.nested_category_sufix
93                if self.conf.nested_category_prefix is not None:
94                    subcat_id = self.conf.nested_category_prefix + subcat_id
95                if subcat_id != info['id'] and \
96                   subcat_id in category.objectIds():
97                    subcat = category._getOb(subcat_id)
98                    if IActionCategory.providedBy(subcat):
99                        children = self._subactions(subcat, object, level+1)
100
101            url = self.context.absolute_url()       
102            if url.startswith(info['url']):
103                if currentParentId > -1:
104                    if len(tabs[currentParentId]['getURL']) < len(info['url']): 
105                        currentParentId = index
106                else:
107                    currentParentId = index
108            if url == info['url']:
109                currentItem = True
110            # make up final tab dictionary
111            tab = {'Title': info['title'],
112                   'Description': info['description'],
113                   'getURL': info['url'],
114                   'show_children': len(children) > 0,
115                   'children': children,
116                   'currentItem': currentItem,
117                   'currentParent': currentParent,
118                   'item_icon': {'html_tag': icon},
119                   'normalized_review_state': 'visible'}
120            tabs.append(tab)
121        if currentParentId > -1:
122            tabs[currentParentId]['currentParent'] = True
123        return tabs
124
125    def _actionInfos(self, category, object, check_visibility=1,
126                     check_permissions=1, check_condition=1, max=-1):
127        """Return action infos for a given category"""
128        context = aq_inner(self.context)
129        ec = self.tool._getExprContext(object)
130        actions = [ActionInfo(action, ec) for action in category.objectValues()
131                    if IAction.providedBy(action)]
132
133        action_infos = []
134        for ai in actions:
135            if check_visibility and not ai['visible']:
136                continue
137            if check_permissions and not ai['allowed']:
138                continue
139            if check_condition and not ai['available']:
140                continue
141            action_infos.append(ai)
142            if max + 1 and len(action_infos) >= max:
143                break
144        return action_infos
145
146    def _content_tabs(self):
147        """Return tree of tabs based on content structure"""
148        context = aq_inner(self.context)
149
150        queryBuilder = DropDownMenuQueryBuilder(context)
151        strategy = getMultiAdapter((context, None), INavtreeStrategy)
152        # XXX This works around a bug in plone.app.portlets which was
153        # fixed in http://dev.plone.org/svn/plone/changeset/18836
154        # When a release with that fix is made this workaround can be
155        # removed and the plone.app.portlets requirement in setup.py
156        # be updated.
157        if strategy.rootPath is not None and strategy.rootPath.endswith("/"):
158            strategy.rootPath = strategy.rootPath[:-1]
159
160        return buildFolderTree(context, obj=context, query=queryBuilder(),
161                               strategy=strategy).get('children', [])
162
163    @memoize
164    def _settings(self):
165        """Fetch dropdown menu settings registry"""
166        return getDropDownMenuSettings(self.context)
167
168    def createMenu(self):
169        return self.recurse(children=self.portal_tabs, level=1)
170
171    def _old_update(self):
172        context_state = getMultiAdapter((self.context, self.request),
173                                        name=u'plone_context_state')
174        actions = context_state.actions()
175        portal_tabs_view = getMultiAdapter((self.context, self.request),
176                                           name='portal_tabs_view')
177        self.portal_tabs = portal_tabs_view.topLevelTabs(actions=actions)
178
179        selectedTabs = self.context.restrictedTraverse('selectedTabs')
180        self.selected_tabs = selectedTabs('index_html',
181                                          self.context,
182                                          self.portal_tabs)
183        self.selected_portal_tab = self.selected_tabs['portal']
184
185    @memoize
186    def is_plone_four(self):
187        """Indicates if we are in plone 4.
188       
189        """
190        pm = getToolByName(aq_inner(self.context), 'portal_migration') 
191        try:
192            version = versionTupleFromString(pm.getSoftwareVersion())
193        except AttributeError:
194            version = versionTupleFromString(pm.getFileSystemVersion())
195
196        if version:
197            return version[0] == 4
198
Note: See TracBrowser for help on using the repository browser.