# File: TreeVocabulary.py
A Tree Vocabulary is a container for hierachical key/value pairs.
# Copyright (c) 2004-2006 by BlueDynamics Alliance - Klein & Partner KEG, Austria
# BSD-like licence, see LICENCE.txt
__author__ = 'Jens Klein <jens@bluedynamics.com>'
__docformat__ = 'plaintext'
from Products.ATVocabularyManager.config import *
    from Products.LinguaPlone.public import *
    from Products.Archetypes.atapi import *
from AccessControl import ClassSecurityInfo
#from Products.CMFCore.permissions import AddPortalContent
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.utils import base_hasattr
from Products.Archetypes.utils import OrderedDict
    from Products.Archetypes.lib.vocabulary import DisplayList
except ImportError:
    from Products.Archetypes.utils import DisplayList
from Products.ATVocabularyManager.types.simple import SimpleVocabulary
from Products.ATVocabularyManager.config import PROJECTNAME
from Products.ATVocabularyManager import messageFactory as _
schema = SimpleVocabulary.schema + Schema((
        widget = BooleanWidget(
            label = _("label_show_leaves_only",
                      default=u"Show leaves only"),
            description = _("help_show_leaves_only",
                            default=u"Check to show only leaves in this vocabulary."),
class TreeVocabulary(SimpleVocabulary):
    security = ClassSecurityInfo()
    schema = schema
    meta_type = 'TreeVocabulary'
    def getDisplayList(self, instance, display_parents='tree'):
        """ returns an object of class DisplayList as defined in
            The instance of the content class is given as parameter.
        dl = DisplayList()
        self._appendToDisplayList(dl, self.getVocabularyDict(instance), None,
        return dl
    def _appendToDisplayList(self, displaylist, vdict, valueparent,
        """ append subtree to flat display list
        for key in vdict.keys():
            if type(vdict[key]) == type((1, 2)):
                value = vdict[key][0]
                subdict = vdict[key][1] or None
                value = vdict[key]
                subdict = None
            if valueparent and display_parents == 'tree':
                value = '%s - %s' % (valueparent, value)
            if valueparent and display_parents == 'marker':
                # Extract any leading -'s from the parent
                markers = 0
                for char in valueparent:
                    if char == '-':
                        markers += 1
                value = '%s-- %s' % ('-'*markers, value)
            if (not self.showLeafsOnly()) or (not subdict):
                displaylist.add(key, value)
            if subdict:
                self._appendToDisplayList(displaylist, subdict, value,
    def getVocabularyDict(self, instance=None):
        """returns a vocabulary dictionary as defined in the interface
        # see if we simply can return all objects and their
        # subtree, or if we have to use the correct translations
        if self.isLinguaPloneInstalled():
            # find out the currently used Language
                lang = instance.getLanguage()
            except AttributeError:
                # we try to retrieve the current language
                langtool = getToolByName(self, 'portal_languages')
                lang = langtool.getPreferredLanguage()
            return self._getTranslatedVocabularyDict(lang)
            # we don't need to care about languages, and can simply
            # return all contentObjects
            return self._getUntranslatedVocabularyDict()
    def _getTranslatedVocabularyDict(self, lang):
        """returns a vocabulary dict using the titles of the
        translations for language ``lang``
        Only canonical objects are used to build up this
        dictionary. If available, the translation's titles
        are used.
        vdict = OrderedDict()
        for obj in self.contentValues():
            if obj.isCanonical():
                # we only add the canonical objects to this dict
                key = obj.getTermKey()
                # but use the title of the appropriate translation
                # if it is available (getTermValue is LP aware)
                vsubdict = obj._getTranslatedVocabularyDict(lang)
                vdict[key] = (obj.getTermValue(lang=lang), vsubdict)
        return vdict
    def _getUntranslatedVocabularyDict(self):
        """returns a vocabulary dictionary as defined in the interface
        vdict = OrderedDict()
        for obj in self.contentValues():
            vsubdict = obj._getUntranslatedVocabularyDict()
            vdict[obj.getVocabularyKey()] = ( \
                obj.getVocabularyValue(), vsubdict)
        return vdict
    def showLeafsOnly(self):
        """ indicates if only leaves should be shown """
        if base_hasattr(self, 'getShowLeavesOnly'):
            return self.getShowLeavesOnly()
        return None
    def isFlat(self):
        """ indicates if tree or flat """
        return 0
registerType(TreeVocabulary, PROJECTNAME)
# end of class TreeVocabulary