source: products/quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/_field.py @ 2300

Last change on this file since 2300 was 2300, checked in by mylan, 14 years ago

Make default value for the Title column take into consideration for exteranl links

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1#from Products.Archetypes import atapi
2import re
3import logging
4import urlparse
5from urllib import quote
6from types import ListType, TupleType
7
8from AccessControl import ClassSecurityInfo
9
10from Products.CMFCore.utils import getToolByName
11from Products.validation import validation #validators import baseValidators
12from Products.Archetypes.Field import encode, ReferenceField
13from Products.Archetypes.Registry import registerField, registerWidget
14
15from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget
16
17from Products.DataGridField.Column import Column
18from Products.DataGridField.DataGridField import DataGridField
19from Products.DataGridField.DataGridWidget import DataGridWidget
20
21from quintagroup.referencedatagridfield.columns import BlockColumn
22from quintagroup.referencedatagridfield.columns import HiddenColumn
23from quintagroup.referencedatagridfield.columns import StyledColumn
24
25# Logger object
26#logger = logging.getLogger('ReferenceDataGridField')
27#logger.debug("ReferenceDataGrid loading")
28
29class ReferenceDataGridWidget(DataGridWidget, ReferenceBrowserWidget):
30    _properties = ReferenceBrowserWidget._properties.copy()
31    _properties.update(DataGridWidget._properties.copy())
32    _properties.update({
33        'macro': "referencedatagridwidget",
34        'helper_css': ('datagridwidget.css','referencedatagridwidget.css'),
35        'helper_js': ('referencebrowser.js', 'datagridwidget.js',),
36        'force_close_on_insert': True,
37        'columns': {
38            'title': StyledColumn("Title", trigger_key="default_title",
39                                  blur_handler="triggerTitleClass",
40                                  focus_handler="triggerOnFocusStyles",
41                                  class_no=None,
42                                  class_changed="changed-title-field",
43                                  class_not_changed="not-changed-title-field"),
44            'link': BlockColumn("Link", column_on_class="hidden-field",
45                                columns=['link','uid'], read_only=True),
46            'uid': HiddenColumn("UID", visible=False)},
47        })
48
49isURL = validation.validatorFor('isURL')
50
51class ReferenceDataGridField(DataGridField, ReferenceField):
52    _properties = ReferenceField._properties.copy()
53    _properties.update(DataGridField._properties.copy())
54    _properties.update({
55        'columns': ('title', 'link', 'uid'),
56        'widget': ReferenceDataGridWidget,
57        'multiValued' : True,
58        })
59
60    security = ClassSecurityInfo()
61
62    security.declarePrivate('isRemoteURL')
63    def isRemoteURL(self, url):
64        return isURL(url) == 1 and True or False
65
66    security.declarePrivate('set')
67    def set(self, instance, value, **kwargs):
68        """
69        The passed in object should be a records object, or a sequence of dictionaries
70        About link data:
71          * interpretations:
72            * if data not starts with standard protocol names (http://, ftp://) than
73              *uid* field data will be used as reference
74          * record removed if:
75            * no data;
76            * data contains UID of not existent object
77        About title:
78          * if there is UID of existent object and record has same title to the original
79            object - title will not be saved.
80        """
81        catalog = getToolByName(instance, "uid_catalog")
82
83        if value is None:
84            value = ()
85
86        if not isinstance(value, (ListType, TupleType)):
87            value = value,
88
89        result = []
90        for row in value:
91            data = {"title":"", "link":"", "uid":""}
92
93            uid = str(row.get("uid", "")).strip()
94            link = str(row.get("link", "")).strip()
95            title = str(row.get('title', ""))
96
97            if not title == "":
98                data["title"] = title
99
100            if link == "":
101                continue
102            elif self.isRemoteURL(link):
103                data["link"] = urlparse.urlunparse(urlparse.urlparse(link))
104            else:
105                if uid == '':
106                    continue
107
108                brains = catalog(UID=uid)
109                if len(brains) == 0:
110                    continue
111                # Found objects with pointed UID
112                brain = brains[0]
113                data["uid"] = uid
114                # Fix title for uid
115                if data['title'] == getattr(brain, "Title", ""):
116                    data['title'] = ""
117            result.append(data)
118
119        DataGridField.set(self, instance, result, **kwargs)
120
121        uids = [r['uid'] for r in result if r['uid']!=""]
122        ReferenceField.set(self, instance, uids, **kwargs)
123       
124    security.declarePrivate('get')
125    def get(self, instance, **kwargs):
126        """ Return DataGridField value
127
128        Value is a list object of rows.
129        Row id dictionary object with standard 'link', 'uid' and 'title' keys
130        plus extra informal *url* and *url_title* keys
131        """
132        purl = getToolByName(instance, "portal_url")
133        # use portal_catalog to hide protected object for the logged in user.
134        catalog = getToolByName(instance, "portal_catalog")
135
136        result = []
137        uids = {}
138        rows = DataGridField.get(self, instance, **kwargs)
139        for row in rows:
140            result.append({
141                # DataGridField row data
142                "uid": row["uid"],
143                "link": row["link"],
144                "title": row["title"],
145                # View data
146                "url": "",
147                "default_title": None})
148            data = result[-1]
149            # Process remote URL and collect UIDs
150            if row["link"]:
151                data["url"] = quote(row["link"], safe='?$#@/:=+;$,&%')
152                data["default_title"] = row["link"]
153                # if title not set for remote url - set it equals to url
154                if not data["title"]:
155                    data["title"] = data["default_title"]
156            else:
157                uids[row["uid"]] = data
158        # Process UIDs
159        if uids:
160            brains = catalog(UID=uids.keys())
161            for b in brains:
162                data = uids[b.UID]
163                data["url"] = b.getURL()
164                data["link"] = b.getPath()
165                data["default_title"] = self._brains_title_or_id(b, instance)
166                # If title not set - get it from the brain
167                if not data["title"]:
168                    data["title"] = data["default_title"]
169
170        return result
171
172
173registerWidget(
174    ReferenceDataGridWidget,
175    title='DataGrid Reference',
176    used_for=('quintagroup.referencedatagridfield.ReferenceDataGridField',)
177    )
178
179registerField(
180    ReferenceDataGridField,
181    title="DataGrid Reference Field",
182    description=("Reference DataGrid field.")
183    )
Note: See TracBrowser for help on using the repository browser.