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

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

Plug in StyledColumn? to Title column; added blur and focus javascript event handlers; added changed/not-changed styles

  • 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="title_changed",
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', "")).strip()
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            data = result[-1]
148            # Process remote URL and collect UIDs
149            if row["link"]:
150                data["url"] = quote(row["link"], safe='?$#@/:=+;$,&%')
151                # if title not set for remote url - set it equals to url
152                if not data["title"]:
153                    data["title"] = row["link"]
154            else:
155                uids[row["uid"]] = data
156        # Process UIDs
157        if uids:
158            brains = catalog(UID=uids.keys())
159            for b in brains:
160                data = uids[b.UID]
161                data["url"] = b.getURL()
162                data["link"] = b.getPath()
163                # If title not set - get it from the brain
164                if not data["title"]:
165                    data["title_changed"] = False
166                    data["title"] = self._brains_title_or_id(b, instance)
167                else:
168                    data["title_changed"] = True
169
170
171        return result
172
173
174registerWidget(
175    ReferenceDataGridWidget,
176    title='DataGrid Reference',
177    used_for=('quintagroup.referencedatagridfield.ReferenceDataGridField',)
178    )
179
180registerField(
181    ReferenceDataGridField,
182    title="DataGrid Reference Field",
183    description=("Reference DataGrid field.")
184    )
Note: See TracBrowser for help on using the repository browser.