Back to index

moin  1.9.0~rc2
browser.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - DataBrowserWidget
00004 
00005     @copyright: 2002 Juergen Hermann <jh@web.de>
00006     @license: GNU GPL, see COPYING for details.
00007 """
00008 
00009 from MoinMoin.widget import base
00010 from MoinMoin import wikiutil
00011 
00012 class DataBrowserWidget(base.Widget):
00013 
00014     def __init__(self, request, show_header=True, **kw):
00015         _ = request.getText
00016         base.Widget.__init__(self, request, **kw)
00017         self.data = None
00018         self.unqual_data_id = 'dbw.'
00019         self.data_id = request.formatter.qualify_id(self.unqual_data_id)
00020         # prefixed with __ are untranslated and to be used in the JS
00021         self._all = _('[all]')
00022         self.__all = '[all]'
00023         self._notempty = _('[not empty]')
00024         self.__notempty = '[notempty]'
00025         self._empty = _('[empty]')
00026         self.__empty = '[empty]'
00027         self._filter = _('filter')
00028         self.__filter = 'filter'
00029         self._show_header = show_header
00030 
00031     def setData(self, dataset):
00032         """ Sets the data for the browser (see MoinMoin.util.dataset).
00033 
00034         @param dataset: dataset containing either ascii, unicode or tuples.
00035                         If a dataset entry contains a tuple then the first
00036                         item in the tuple is displayed and the second item
00037                         is used for autofilters.
00038         """
00039         self.data = dataset
00040         if dataset.data_id:
00041             self.unqual_data_id = 'dbw.%s.' % dataset.data_id
00042             self.data_id = self.request.formatter.qualify_id(self.unqual_data_id)
00043 
00044     def _name(self, elem):
00045         """ return name tag for a HTML element
00046         @param elem: element name, will be prefixed by data id
00047         """
00048         return 'name="%s%s"' % (self.data_id, elem)
00049 
00050     def _makeoption(self, item, selected, ntitem=None):
00051         """ create an option for a <select> form element
00052         @param item: string containing the item name to show
00053         @param selected: indicates whether the item should be default or not
00054         """
00055         if selected:
00056             selected = ' selected'
00057         else:
00058             selected = ''
00059         assert(isinstance(item, basestring))
00060         if ntitem is None:
00061             ntitem = item
00062         return '<option value="%s"%s>%s</option>' % (
00063             wikiutil.escape(ntitem, True),
00064             selected,
00065             wikiutil.escape(item))
00066 
00067     def _filteroptions(self, idx):
00068         """ create options for all elements in the column
00069             given by idx
00070         """
00071         self.data.reset()
00072         row = self.data.next()
00073         # [empty] is a special already
00074         unique = ['']
00075 
00076         value = None
00077         name = '%sfilter%d' % (self.data_id, idx)
00078         if name in self.request.values:
00079             value = self.request.values.getlist(name)
00080         while row:
00081             option = row[idx]
00082             if isinstance(option, tuple):
00083                 option = option[1]
00084             if not option in unique:
00085                 unique.append(option)
00086             row = self.data.next()
00087 
00088         # fill in the empty field we left blank
00089         del unique[0]
00090         unique.sort()
00091         result = [self._makeoption(item, item == value) for item in unique]
00092         common = []
00093         common.append(self._makeoption(self._all, value == self.__all, self.__all))
00094         if '' in unique:
00095             common.extend([
00096                 self._makeoption(self._empty, value == self.__empty, self.__empty),
00097                 self._makeoption(self._notempty, value == self.__notempty, self.__notempty),
00098             ])
00099         return '\n'.join(common + result)
00100 
00101     def _format(self, formatter=None, method=None):
00102         """
00103         does the formatting of the table
00104         @param formatter: formatter
00105         @param method: None is the default and does not create a form
00106                        while "GET" or "POST" will create the form using the given method
00107         """
00108         fmt = formatter or self.request.formatter
00109 
00110         result = []
00111         if method:
00112             result.append(fmt.rawHTML('<form action="%s/%s" method="%s" name="%sform">' % (self.request.script_root, wikiutil.quoteWikinameURL(self.request.page.page_name), method, self.data_id)))
00113         result.append(fmt.div(1))
00114 
00115         havefilters = False
00116         for col in self.data.columns:
00117             if col.autofilter:
00118                 havefilters = True
00119                 break
00120         if havefilters:
00121             result.append(fmt.rawHTML('<input type="submit" value="%s" %s>' % (self._filter, self._name('submit'))))
00122 
00123         result.append(fmt.table(1, id='%stable' % self.unqual_data_id))
00124 
00125         # add header line
00126         if self._show_header:
00127             result.append(fmt.table_row(1))
00128             for idx in range(len(self.data.columns)):
00129                 col = self.data.columns[idx]
00130                 if col.hidden:
00131                     continue
00132                 cell_attrs = {'class': 'hcolumn%d' % idx}
00133                 result.append(fmt.table_cell(1, cell_attrs))
00134                 result.append(fmt.strong(1))
00135                 result.append(col.label or col.name)
00136                 result.append(fmt.strong(0))
00137 
00138                 if col.autofilter:
00139                     result.append(fmt.linebreak(False))
00140                     select = '<select %s onchange="dbw_update_search(\'%s\');">%s</select>' % (
00141                                       self._name('filter%d' % idx),
00142                                       self.data_id,
00143                                       self._filteroptions(idx))
00144                     result.append(fmt.rawHTML(select))
00145 
00146                 result.append(fmt.table_cell(0))
00147             result.append(fmt.table_row(0))
00148 
00149         # add data
00150         self.data.reset()
00151         row = self.data.next()
00152         if row is not None:
00153             filters = [None] * len(row)
00154 
00155             if havefilters:
00156                 for idx in range(len(row)):
00157                     name = '%sfilter%d' % (self.data_id, idx)
00158                     if name in self.request.values:
00159                         filters[idx] = self.request.getlist(name)
00160                         if filters[idx] == self._all:
00161                             filters[idx] = None
00162 
00163         while row:
00164             hidden = False
00165 
00166             if havefilters:
00167                 # check if row needs to be hidden due to filtering
00168                 for idx in range(len(row)):
00169                     if filters[idx]:
00170                         if isinstance(row[idx], tuple):
00171                             data = unicode(row[idx][1])
00172                         else:
00173                             data = unicode(row[idx])
00174                         if data != '' and filters[idx] == self._notempty:
00175                             continue
00176                         if data == '' and filters[idx] == self._empty:
00177                             continue
00178                         if data != filters[idx]:
00179                             hidden = True
00180                             break
00181 
00182             if not hidden:
00183                 result.append(fmt.table_row(1))
00184                 for idx in range(len(row)):
00185                     if self.data.columns[idx].hidden:
00186                         continue
00187                     cell_attrs = {'class': 'column%d' % idx}
00188                     if isinstance(row[idx], tuple):
00189                         result.append(fmt.table_cell(1, cell_attrs, abbr=unicode(row[idx][1])))
00190                         result.append(unicode(row[idx][0]))
00191                     else:
00192                         result.append(fmt.table_cell(1, cell_attrs))
00193                         result.append(unicode(row[idx]))
00194                     result.append(fmt.table_cell(0))
00195                 result.append(fmt.table_row(0))
00196 
00197             row = self.data.next()
00198 
00199         result.append(fmt.table(0))
00200         result.append(fmt.div(0))
00201         if method:
00202             result.append(fmt.rawHTML('</form>'))
00203         return ''.join(result)
00204 
00205     format = _format # DEPRECATED, use render()
00206 
00207     render = _format # Note: in moin <= 1.7.1 render() used request.write(), this was wrong!
00208                      # Now it just returns the result, as the other widgets do.
00209