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
RevLine 
[2259]1#from Products.Archetypes import atapi
[2263]2import re
[2260]3import logging
[2263]4import urlparse
5from urllib import quote
6from types import ListType, TupleType
7
[2260]8from AccessControl import ClassSecurityInfo
[2263]9
10from Products.CMFCore.utils import getToolByName
11from Products.validation import validation #validators import baseValidators
[2266]12from Products.Archetypes.Field import encode, ReferenceField
[2259]13from Products.Archetypes.Registry import registerField, registerWidget
14
[2266]15from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget
16
[2282]17from Products.DataGridField.Column import Column
[2259]18from Products.DataGridField.DataGridField import DataGridField
19from Products.DataGridField.DataGridWidget import DataGridWidget
20
[2287]21from quintagroup.referencedatagridfield.columns import BlockColumn
22from quintagroup.referencedatagridfield.columns import HiddenColumn
[2291]23from quintagroup.referencedatagridfield.columns import StyledColumn
[2263]24
[2260]25# Logger object
26#logger = logging.getLogger('ReferenceDataGridField')
27#logger.debug("ReferenceDataGrid loading")
28
[2266]29class ReferenceDataGridWidget(DataGridWidget, ReferenceBrowserWidget):
30    _properties = ReferenceBrowserWidget._properties.copy()
31    _properties.update(DataGridWidget._properties.copy())
[2260]32    _properties.update({
[2266]33        'macro': "referencedatagridwidget",
[2287]34        'helper_css': ('datagridwidget.css','referencedatagridwidget.css'),
[2266]35        'helper_js': ('referencebrowser.js', 'datagridwidget.js',),
[2274]36        'force_close_on_insert': True,
[2282]37        'columns': {
[2300]38            'title': StyledColumn("Title", trigger_key="default_title",
[2291]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"),
[2287]44            'link': BlockColumn("Link", column_on_class="hidden-field",
45                                columns=['link','uid'], read_only=True),
[2282]46            'uid': HiddenColumn("UID", visible=False)},
[2260]47        })
[2259]48
[2263]49isURL = validation.validatorFor('isURL')
50
[2266]51class ReferenceDataGridField(DataGridField, ReferenceField):
52    _properties = ReferenceField._properties.copy()
53    _properties.update(DataGridField._properties.copy())
[2259]54    _properties.update({
[2278]55        'columns': ('title', 'link', 'uid'),
[2259]56        'widget': ReferenceDataGridWidget,
[2274]57        'multiValued' : True,
[2259]58        })
59
[2263]60    security = ClassSecurityInfo()
61
62    security.declarePrivate('isRemoteURL')
63    def isRemoteURL(self, url):
[2264]64        return isURL(url) == 1 and True or False
[2263]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
[2278]70        About link data:
[2263]71          * interpretations:
[2278]72            * if data not starts with standard protocol names (http://, ftp://) than
73              *uid* field data will be used as reference
[2263]74          * record removed if:
75            * no data;
76            * data contains UID of not existent object
77        About title:
[2278]78          * if there is UID of existent object and record has same title to the original
79            object - title will not be saved.
[2263]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:
[2278]91            data = {"title":"", "link":"", "uid":""}
[2263]92
[2278]93            uid = str(row.get("uid", "")).strip()
94            link = str(row.get("link", "")).strip()
[2299]95            title = str(row.get('title', ""))
[2278]96
[2263]97            if not title == "":
98                data["title"] = title
99
[2278]100            if link == "":
[2263]101                continue
[2278]102            elif self.isRemoteURL(link):
103                data["link"] = urlparse.urlunparse(urlparse.urlparse(link))
[2263]104            else:
[2278]105                if uid == '':
106                    continue
107
108                brains = catalog(UID=uid)
[2263]109                if len(brains) == 0:
110                    continue
[2274]111                # Found objects with pointed UID
112                brain = brains[0]
[2278]113                data["uid"] = uid
114                # Fix title for uid
115                if data['title'] == getattr(brain, "Title", ""):
116                    data['title'] = ""
[2263]117            result.append(data)
118
119        DataGridField.set(self, instance, result, **kwargs)
[2278]120
121        uids = [r['uid'] for r in result if r['uid']!=""]
[2274]122        ReferenceField.set(self, instance, uids, **kwargs)
123       
[2263]124    security.declarePrivate('get')
125    def get(self, instance, **kwargs):
126        """ Return DataGridField value
127
128        Value is a list object of rows.
[2278]129        Row id dictionary object with standard 'link', 'uid' and 'title' keys
130        plus extra informal *url* and *url_title* keys
[2263]131        """
132        purl = getToolByName(instance, "portal_url")
[2278]133        # use portal_catalog to hide protected object for the logged in user.
[2275]134        catalog = getToolByName(instance, "portal_catalog")
[2263]135
136        result = []
[2275]137        uids = {}
[2263]138        rows = DataGridField.get(self, instance, **kwargs)
139        for row in rows:
[2276]140            result.append({
141                # DataGridField row data
[2278]142                "uid": row["uid"],
143                "link": row["link"],
[2276]144                "title": row["title"],
145                # View data
[2300]146                "url": "",
147                "default_title": None})
[2275]148            data = result[-1]
149            # Process remote URL and collect UIDs
[2278]150            if row["link"]:
151                data["url"] = quote(row["link"], safe='?$#@/:=+;$,&%')
[2300]152                data["default_title"] = row["link"]
[2275]153                # if title not set for remote url - set it equals to url
[2281]154                if not data["title"]:
[2300]155                    data["title"] = data["default_title"]
[2263]156            else:
[2278]157                uids[row["uid"]] = data
[2275]158        # Process UIDs
159        if uids:
160            brains = catalog(UID=uids.keys())
161            for b in brains:
162                data = uids[b.UID]
[2278]163                data["url"] = b.getURL()
[2281]164                data["link"] = b.getPath()
[2300]165                data["default_title"] = self._brains_title_or_id(b, instance)
[2275]166                # If title not set - get it from the brain
[2281]167                if not data["title"]:
[2300]168                    data["title"] = data["default_title"]
[2263]169
170        return result
171
[2274]172
[2259]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.