Passed
Push — 2.x ( e94308...699219 )
by Jordi
09:28
created

senaite.core.behaviors.label   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 94
dl 0
loc 125
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A LabelSchema.getLabels() 0 3 1
A LabelSchema.setLabels() 0 4 1
A LabelBehaviorAssignable.supports() 0 5 3
A LabelBehaviorAssignable.enumerateBehaviors() 0 12 4
A LabelSchema.__init__() 0 2 1
A LabelBehaviorAssignable.label_registration() 0 8 1
A LabelBehaviorAssignable.__init__() 0 2 1
1
# -*- coding: utf-8 -*-
2
3
from AccessControl import ClassSecurityInfo
4
from bika.lims import senaiteMessageFactory as _
5
from plone.autoform import directives
6
from plone.autoform.interfaces import IFormFieldProvider
7
from plone.behavior.interfaces import IBehaviorAssignable
8
from plone.behavior.registration import BehaviorRegistration
9
from plone.dexterity.behavior import DexterityBehaviorAssignable
10
from plone.dexterity.schema import SCHEMA_CACHE
11
from plone.supermodel import model
12
from plone.supermodel.directives import fieldset
13
from Products.CMFCore import permissions
14
from senaite.core.api import label as label_api
15
from senaite.core.catalog import SETUP_CATALOG
16
from senaite.core.interfaces import ICanHaveLabels
17
from senaite.core.z3cform.widgets.queryselect import QuerySelectWidgetFactory
18
from zope import schema
19
from zope.component import adapter
20
from zope.interface import implementer
21
from zope.interface import provider
22
23
24
@implementer(IBehaviorAssignable)
25
@adapter(ICanHaveLabels)
26
class LabelBehaviorAssignable(DexterityBehaviorAssignable):
27
    """Extend label behavior if the context provides the interface `ICanHaveLabels`
28
    """
29
    def __init__(self, context):
30
        self.context = context
31
32
    def supports(self, behavior_interface):
33
        for behavior in self.enumerateBehaviors():
34
            if behavior_interface in behavior.interface._implied:
35
                return True
36
        return False
37
38
    def enumerateBehaviors(self):
39
        portal_type = self.context.portal_type
40
        behaviors = SCHEMA_CACHE.behavior_registrations(portal_type)
41
        registered = False
42
        for behavior in behaviors:
43
            if behavior.marker == ICanHaveLabels:
44
                registered = True
45
            yield behavior
46
        # additionally yield the schema registration if it was not already
47
        # registered via the FTI
48
        if not registered:
49
            yield self.label_registration
50
51
    @property
52
    def label_registration(self):
53
        return BehaviorRegistration(
54
            title="Label schema extender",
55
            description="Adds the ability to add/remove labels",
56
            interface=ILabelSchema,
57
            marker=ICanHaveLabels,
58
            factory=LabelSchema,
59
        )
60
61
62
@provider(IFormFieldProvider)
63
class ILabelSchema(model.Schema):
64
    """Behavior with schema fields to allow to add/remove labels
65
    """
66
    fieldset(
67
        "labels",
68
        label=u"Labels",
69
        fields=["Labels"])
70
71
    directives.widget(
72
        "Labels",
73
        QuerySelectWidgetFactory,
74
        catalog=SETUP_CATALOG,
75
        search_index="Title",
76
        value_key="title",
77
        search_wildcard=True,
78
        multi_valued=True,
79
        allow_user_value=True,
80
        hide_input_after_select=False,
81
        query={
82
            "portal_type": "Label",
83
            "is_active": True,
84
            "sort_on": "title",
85
        },
86
        columns=[
87
            {
88
                "name": "title",
89
                "width": "100",
90
                "align": "left",
91
                "label": _(u"Label"),
92
            },
93
        ],
94
        display_template="<a href='${url}'>${title}</a>",
95
        limit=5,
96
    )
97
    Labels = schema.List(
98
        title=_(u"label_Labels", default=u"Labels"),
99
        description=_(u"description_Labels", default=u"Attached labels"),
100
        value_type=schema.TextLine(title=u"Label"),
101
        required=False,
102
    )
103
104
105
@implementer(ILabelSchema)
106
@adapter(ICanHaveLabels)
107
class LabelSchema(object):
108
    """Factory that provides the extended label fields
109
    """
110
    security = ClassSecurityInfo()
111
112
    def __init__(self, context):
113
        self.context = context
114
115
    @security.protected(permissions.View)
116
    def getLabels(self):
117
        return label_api.get_obj_labels(self.context)
118
119
    @security.protected(permissions.ModifyPortalContent)
120
    def setLabels(self, value):
121
        labels = label_api.to_labels(value)
122
        return label_api.set_obj_labels(self.context, labels)
123
124
    Labels = property(getLabels, setLabels)
125