Code

Saving, running & editing queries.
authorgmcm <gmcm@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 17 Jul 2002 12:39:11 +0000 (12:39 +0000)
committergmcm <gmcm@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 17 Jul 2002 12:39:11 +0000 (12:39 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@884 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/backends/back_metakit.py
roundup/cgi_client.py
roundup/htmltemplate.py
roundup/templates/classic/dbinit.py
roundup/templates/classic/html/query.index [new file with mode: 0755]
roundup/templates/classic/html/query.item [new file with mode: 0755]
roundup/templates/classic/html/user.item

index 19a380f7f2f4b9eb225197bd1fa10ce38f2b298b..be582568c6e447809e02ce5b5d8fabe737ee6088 100755 (executable)
@@ -166,11 +166,11 @@ class _Database(hyperdb.Database):
         return self.__RW == 0
     def getWriteAccess(self):
         if self.journaltag is not None and self.__RW == 0:
-            now = time.time
-            start = now()
+            #now = time.time
+            #start = now()
             self._db = None
             #print "closing the file took %2.2f secs" % (now()-start)
-            start = now()
+            #start = now()
             self._db = metakit.storage(self.dbnm, 1)
             self.__RW = 1
             self.hist = self._db.view('history')
@@ -504,15 +504,18 @@ class Class:    # no, I'm not going to subclass the existing!
         # first setkey for this run
         self.keyname = propname
         iv = self.db._db.view('_%s' % self.classname)
-        if self.db.fastopen or iv.structure():
+        if self.db.fastopen and iv.structure():
             return
         # very first setkey ever
+        self.db.getWriteAccess()
+        self.db.dirty = 1
         iv = self.db._db.getas('_%s[k:S,i:I]' % self.classname)
         iv = iv.ordered(1)
         #XXX
 #        print "setkey building index"
         for row in self.getview():
             iv.append(k=getattr(row, propname), i=row.id)
+        self.db.commit()
     def getkey(self):
         return self.keyname
     def lookup(self, keyvalue):
@@ -601,7 +604,10 @@ class Class:    # no, I'm not going to subclass the existing!
             if self.ruprops.has_key(key):
                 raise ValueError, "%s is already a property of %s" % (key, self.classname)
         self.ruprops.update(properties)
+        self.db.getWriteAccess()
+        self.db.fastopen = 0
         view = self.__getview()
+        self.db.commit()
     # ---- end of ping's spec
     def filter(self, search_matches, filterspec, sort, group):
         # search_matches is None or a set (dict of {nodeid: {propname:[nodeid,...]}})
@@ -821,10 +827,10 @@ class Class:    # no, I'm not going to subclass the existing!
     def __getview(self):
         db = self.db._db
         view = db.view(self.classname)
-        if self.db.fastopen:
+        mkprops = view.structure()
+        if mkprops and self.db.fastopen:
             return view.ordered(1)
         # is the definition the same?
-        mkprops = view.structure()
         for nm, rutyp in self.ruprops.items():
             for mkprop in mkprops:
                 if mkprop.name == nm:
@@ -832,15 +838,16 @@ class Class:    # no, I'm not going to subclass the existing!
             else:
                 mkprop = None
             if mkprop is None:
-                #print "%s missing prop %s (%s)" % (self.classname, nm, rutyp.__class__.__name__)
+                print "%s missing prop %s (%s)" % (self.classname, nm, rutyp.__class__.__name__)
                 break
             if _typmap[rutyp.__class__] != mkprop.type:
-                #print "%s - prop %s (%s) has wrong mktyp (%s)" % (self.classname, nm, rutyp.__class__.__name__, mkprop.type)
+                print "%s - prop %s (%s) has wrong mktyp (%s)" % (self.classname, nm, rutyp.__class__.__name__, mkprop.type)
                 break
         else:
             return view.ordered(1)
         # need to create or restructure the mk view
         # id comes first, so MK will order it for us
+        self.db.getWriteAccess()
         self.db.dirty = 1
         s = ["%s[id:I" % self.classname]
         for nm, rutyp in self.ruprops.items():
@@ -849,7 +856,8 @@ class Class:    # no, I'm not going to subclass the existing!
             if mktyp == 'V':
                 s[-1] += ('[fid:I]')
         s.append('_isdel:I,activity:I,creation:I,creator:I]')
-        v = db.getas(','.join(s))
+        v = self.db._db.getas(','.join(s))
+        self.db.commit()
         return v.ordered(1)
     def getview(self, RW=0):
         if RW and self.db.isReadOnly():
index 3d769eb6d754b2873369c7de65698d5a62cf374e..2bc7922c7c85628af767990a5cf40152436a4754 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: cgi_client.py,v 1.140 2002-07-14 23:17:15 richard Exp $
+# $Id: cgi_client.py,v 1.141 2002-07-17 12:39:10 gmcm Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -193,6 +193,29 @@ function help_window(helpurl, width, height) {
                 _('Unassigned <a href="issue?assignedto=-1&status=-1,unread,deferred,chatting,need-eg,in-progress,testing,done-cbb&:sort=-activity&:filter=status,assignedto&:columns=id,activity,status,title,assignedto&:group=priority&show_customization=1">Issues</a>')
             ]
 
+        if userid:
+            # add any personal queries to the menu
+            try:
+                queries = self.db.getclass('query')
+            except KeyError:
+                # no query class
+                queries = self.instance.dbinit.Class(self.db,
+                                                    "query",
+                                                    klass=hyperdb.String(),
+                                                    name=hyperdb.String(),
+                                                    url=hyperdb.String())
+                queries.setkey('name')
+#queries.disableJournalling()
+            try:
+                qids = self.db.getclass('user').get(userid, 'queries')
+            except KeyError, e:
+                #self.db.getclass('user').addprop(queries=hyperdb.Multilink('query'))
+                qids = []
+            for qid in qids:
+                links.append('<a href=%s?%s>%s</a>' % (queries.get(qid, 'klass'),
+                                                       queries.get(qid, 'url'),
+                                                       queries.get(qid, 'name')))
+                
         # if they're logged in, include links to their information, and the
         # ability to add an issue
         if user_name not in ('', 'anonymous'):
@@ -222,7 +245,7 @@ function help_window(helpurl, width, height) {
         admin_links = ''
         if user_name == 'admin':
             links.append(_('<a href="list_classes">Class List</a>'))
-            links.append(_('<a href="user">User List</a>'))
+            links.append(_('<a href="user?:sort=username">User List</a>'))
             links.append(_('<a href="newuser">Add User</a>'))
 
         # add the search links
@@ -251,11 +274,14 @@ function help_window(helpurl, width, height) {
 <body bgcolor=#ffffff>
 %(message)s
 <table width=100%% border=0 cellspacing=0 cellpadding=2>
-<tr class="location-bar"><td><big><strong>%(title)s</strong></big></td>
-<td align=right valign=bottom>%(user_name)s</td></tr>
-<tr class="location-bar">
-<td align=left>%(links)s</td>
-<td align=right>%(user_info)s</td>
+ <tr class="location-bar">
+  <td><big><strong>%(title)s</strong></big></td>
+  <td align=right valign=bottom>%(user_name)s</td>
+ </tr>
+ <tr class="location-bar">
+  <td align=left>%(links)s</td>
+  <td align=right>%(user_info)s</td>
+ </tr>
 </table><br>
 ''')%locals())
 
@@ -330,14 +356,17 @@ function help_window(helpurl, width, height) {
             x.append('%s%s' % (desc, colnm))
         return x
     
-    def index_filterspec(self, filter):
+    def index_filterspec(self, filter, classname=None):
         ''' pull the index filter spec from the form
 
         Links and multilinks want to be lists - the rest are straight
         strings.
         '''
+        if classname is None:
+            classname = self.classname
+        klass = self.db.getclass(classname)
         filterspec = {}
-        props = self.db.classes[self.classname].getprops()
+        props = klass.getprops()
         for colnm in filter:
             widget = ':%s_fs' % colnm
             try:
@@ -486,6 +515,34 @@ function help_window(helpurl, width, height) {
         else:
             startwith = 0
 
+        if self.form.has_key('Query') and self.form['Query'].value == 'Save':
+            # format a query string
+            qd = {}
+            qd[':sort'] = ','.join(map(urllib.quote, sort))
+            qd[':group'] = ','.join(map(urllib.quote, group))
+            qd[':filter'] = ','.join(map(urllib.quote, filter))
+            qd[':columns'] = ','.join(map(urllib.quote, columns))
+            for k, l in filterspec.items():
+                qd[urllib.quote(k)] = ','.join(map(urllib.quote, l))
+            url = '&'.join([k+'='+v for k,v in qd.items()])
+            url += '&:pagesize=%s' % pagesize
+            if search_text:
+                url += '&search_text=%s' % search_text
+
+            # create a query
+            d = {}
+            d['name'] = self.form[':name'].value
+            d['klass'] = self.form[':classname'].value
+            d['url'] = url
+            qid = self.db.getclass('query').create(**d)
+
+            # and add it to the user's query multilink
+            uid = self.getuid()
+            usercl = self.db.getclass('user')
+            queries = usercl.get(uid, 'queries')
+            queries.append(qid)
+            usercl.set(uid, queries=queries)
+            
         index = htmltemplate.IndexTemplate(self, self.instance.TEMPLATES, cn)
         try:
             index.render(filterspec, search_text, filter, columns, sort, 
@@ -665,6 +722,56 @@ function help_window(helpurl, width, height) {
     showmsg = shownode
     searchissue = searchnode
 
+    def showquery(self):
+        queries = self.db.getclass(self.classname)
+        if self.form.keys():
+            sort = self.index_sort()
+            group = self.index_arg(':group')
+            filter = self.index_arg(':filter')
+            columns = self.index_arg(':columns')
+            filterspec = self.index_filterspec(filter, queries.get(self.nodeid, 'klass'))
+            if self.form.has_key('search_text'):
+                search_text = self.form['search_text'].value
+            else:
+                search_text = ''
+            if self.form.has_key(':pagesize'):
+                pagesize = int(self.form[':pagesize'].value)
+            else:
+                pagesize = 50
+            # format a query string
+            qd = {}
+            qd[':sort'] = ','.join(map(urllib.quote, sort))
+            qd[':group'] = ','.join(map(urllib.quote, group))
+            qd[':filter'] = ','.join(map(urllib.quote, filter))
+            qd[':columns'] = ','.join(map(urllib.quote, columns))
+            for k, l in filterspec.items():
+                qd[urllib.quote(k)] = ','.join(map(urllib.quote, l))
+            url = '&'.join([k+'='+v for k,v in qd.items()])
+            url += '&:pagesize=%s' % pagesize
+            if search_text:
+                url += '&search_text=%s' % search_text
+            qname = self.form['name'].value
+            chgd = []
+            if qname != queries.get(self.nodeid, 'name'):
+                chgd.append('name')
+            if url != queries.get(self.nodeid, 'url'):
+                chgd.append('url')
+            if chgd:
+                queries.set(self.nodeid, name=qname, url=url)
+                message = _('%(changes)s edited ok')%{'changes': ', '.join(chgd)}
+            else:
+                message = _('nothing changed')
+        else:
+            message = None
+        nm = queries.get(self.nodeid, 'name')
+        self.pagehead('%s: %s'%(self.classname.capitalize(), nm), message)
+
+        # use the template to display the item
+        item = htmltemplate.ItemTemplate(self, self.instance.TEMPLATES,
+            self.classname)
+        item.render(self.nodeid)
+        self.pagefoot()
+        
     def _changenode(self, props):
         ''' change the node based on the contents of the form
         '''
@@ -954,7 +1061,7 @@ function help_window(helpurl, width, height) {
 
         if self.user not in ('admin', node_user):
             raise Unauthorised
-
+        
         #
         # perform any editing
         #
@@ -1497,6 +1604,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.140  2002/07/14 23:17:15  richard
+# cleaned up structure
+#
 # Revision 1.139  2002/07/14 06:14:40  richard
 # Some more TODOs
 #
index b6bbb4823ffa1b43e685906096c3e6565fee753e..f7648c136a083f59e5a46be7058a5b1eb60a346c 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: htmltemplate.py,v 1.98 2002-07-10 00:17:46 richard Exp $
+# $Id: htmltemplate.py,v 1.99 2002-07-17 12:39:10 gmcm Exp $
 
 __doc__ = """
 Template engine.
@@ -182,7 +182,6 @@ class TemplateFunctions:
         '''
         if not self.nodeid and self.form is None and self.filterspec is None:
             return _('[Field: not called from item]')
-
         if size is None:
             size = 30
 
@@ -190,7 +189,6 @@ class TemplateFunctions:
 
         # get the value
         value = self.determine_value(property)
-
         # now display
         if (isinstance(propclass, hyperdb.String) or
                 isinstance(propclass, hyperdb.Date) or
@@ -796,6 +794,32 @@ class TemplateFunctions:
             value = cgi.escape(value)
         return value
 
+    def do_filterspec(self, classprop, urlprop):
+        cl = self.db.getclass(self.classname)
+        qs = cl.get(self.nodeid, urlprop)
+        classname = cl.get(self.nodeid, classprop)
+        all_columns = self.db.getclass(classname).getprops().keys()
+        filterspec = {}
+        query = cgi.parse_qs(qs)
+        for k,v in query.items():
+            query[k] = v[0].split(',')
+        pagesize = query.get(':pagesize',['25'])[0]
+        for k,v in query.items():
+            if k[0] != ':':
+                filterspec[k] = v
+        ixtmplt = IndexTemplate(self.client, self.templates, classname)
+        qform = '<form onSubmit="return submit_once()" action="%s%s">\n'%(self.classname,self.nodeid)
+        qform += ixtmplt.filter_form(query.get('search_text', ''),
+                                     query.get(':filter', []),
+                                     query.get(':columns', []),
+                                     query.get(':group', []),
+                                     all_columns,
+                                     query.get(':sort',[]),
+                                     filterspec,
+                                     pagesize)
+        ixtmplt.clear()
+        return qform + '</table>\n'
+        
 
 #
 #   INDEX TEMPLATES
@@ -965,7 +989,7 @@ class IndexTemplate(TemplateFunctions):
                                 l.append(value)
                         w('<tr class="section-bar">'
                         '<td align=middle colspan=%s>'
-                        '<strong>%s</strong></td></tr>'%(
+                        '<strong>%s</strong></td></tr>\n'%(
                             len(columns), ', '.join(l)))
                         old_group = this_group
 
@@ -977,7 +1001,7 @@ class IndexTemplate(TemplateFunctions):
                     self.node_matches(matches[nodeid], len(columns))
                 self.nodeid = None
 
-        w('</table>')
+        w('</table>\n')
         # the previous and next links
         if nodeids:
             baseurl = self.buildurl(filterspec, search_text, filter, columns, sort, group, pagesize)
@@ -991,7 +1015,7 @@ class IndexTemplate(TemplateFunctions):
             else:
                 nexturl = ""
             if prevurl or nexturl:
-                w('<table width="100%%"><tr><td width="50%%" align="center">%s</td><td width="50%%" align="center">%s</td></tr></table>' % (prevurl, nexturl))
+                w('<table width="100%%"><tr><td width="50%%" align="center">%s</td><td width="50%%" align="center">%s</td></tr></table>\n' % (prevurl, nexturl))
 
         # display the filter section
         if (show_display_form and hasattr(self.instance, 'FILTER_POSITION') and
@@ -1018,7 +1042,7 @@ class IndexTemplate(TemplateFunctions):
                 message_links.append('<a href="%(msgpath)s">%(lab)s</a>'
                     %locals())
             w(_('<tr class="row-hilite"><td colspan="%s">'
-                '&nbsp;&nbsp;Matched messages: %s</td></tr>')%(
+                '&nbsp;&nbsp;Matched messages: %s</td></tr>\n')%(
                     colspan, ', '.join(message_links)))
 
         if match.has_key('files'):
@@ -1028,12 +1052,11 @@ class IndexTemplate(TemplateFunctions):
                 file_links.append('<a href="%(filepath)s">%(filename)s</a>'
                     %locals())
             w(_('<tr class="row-hilite"><td colspan="%s">'
-                '&nbsp;&nbsp;Matched files: %s</td></tr>')%(
+                '&nbsp;&nbsp;Matched files: %s</td></tr>\n')%(
                     colspan, ', '.join(file_links)))
 
-
-    def filter_section(self, search_text, filter, columns, group, all_columns, sort, filterspec,
-                       pagesize, startwith):
+    def filter_form(self, search_text, filter, columns, group, all_columns, sort, filterspec,
+                       pagesize):
 
         sortspec = {}
         for i in range(len(sort)):
@@ -1045,57 +1068,57 @@ class IndexTemplate(TemplateFunctions):
             sortspec[colnm] = '%d%s' % (i+1, mod)
             
         startwith = 0
-        w = self.client.write
+        rslt = []
+        w = rslt.append
 
         # display the filter section
-        w(  '<br>\n')
-        w(  '<table border=0 cellspacing=0 cellpadding=0>\n')
-        w(  '<tr class="list-header">\n')
-        w(_(' <th align="left" colspan="7">Filter specification...</th>\n'))
-        w(  '</tr>\n')
+        w(  '<br>')
+        w(  '<table border=0 cellspacing=0 cellpadding=1>')
+        w(  '<tr class="list-header">')
+        w(_(' <th align="left" colspan="7">Filter specification...</th>'))
+        w(  '</tr>')
         # see if we have any indexed properties
         if self.classname in self.db.config.HEADER_SEARCH_LINKS:
         #if self.properties.has_key('messages') or self.properties.has_key('files'):
-            w(  '<tr class="location-bar">\n')
-            w(  ' <td align="right" class="form-label"><b>Search Terms</b></td>\n')
-            w(  ' <td>&nbsp</td>\n')
-            w(  ' <td colspan=5 class="form-text"><input type="text" name="search_text" value="%s" size="50"></td>\n' % search_text)
-            w(  '</tr>\n')
-        w(  '<tr class="location-bar">\n')
-        w(  ' <th align="center" width="20%">&nbsp;</th>\n')
-        w(_(' <th align="center" width="10%">Show</th>\n'))
-        w(_(' <th align="center" width="10%">Group</th>\n'))
-        w(_(' <th align="center" width="10%">Sort</th>\n'))
-        w(_(' <th colspan="3" align="center">Condition</th>\n'))
-        w(  '</tr>\n')
+            w(  '<tr class="location-bar">')
+            w(  ' <td align="right" class="form-label"><b>Search Terms</b></td>')
+            w(  ' <td colspan=6 class="form-text">&nbsp;&nbsp;&nbsp;<input type="text" name="search_text" value="%s" size="50"></td>' % search_text)
+            w(  '</tr>')
+        w(  '<tr class="location-bar">')
+        w(  ' <th align="center" width="20%">&nbsp;</th>')
+        w(_(' <th align="center" width="10%">Show</th>'))
+        w(_(' <th align="center" width="10%">Group</th>'))
+        w(_(' <th align="center" width="10%">Sort</th>'))
+        w(_(' <th colspan="3" align="center">Condition</th>'))
+        w(  '</tr>')
         
         for nm in all_columns:
             propdescr = self.properties.get(nm, None)
             if not propdescr:
                 print "hey sysadmin - %s is not a property of %r" % (nm, self.classname)
                 continue
-            w(  '<tr class="location-bar">\n')
-            w(_(' <td align="right" class="form-label"><b>%s</b></td>\n' % nm.capitalize()))
+            w(  '<tr class="location-bar">')
+            w(_(' <td align="right" class="form-label"><b>%s</b></td>' % nm.capitalize()))
             # show column - can't show multilinks
             if isinstance(propdescr, hyperdb.Multilink):
-                w(' <td></td>\n')
+                w(' <td></td>')
             else:
                 checked = columns and nm in columns or 0
                 checked = ('', 'checked')[checked]
-                w(' <td align="center" class="form-text"><input type="checkbox" name=":columns" value="%s" %s></td>\n' % (nm, checked) )
+                w(' <td align="center" class="form-text"><input type="checkbox" name=":columns" value="%s" %s></td>' % (nm, checked) )
             # can only group on Link 
             if isinstance(propdescr, hyperdb.Link):
                 checked = group and nm in group or 0
                 checked = ('', 'checked')[checked]
-                w(' <td align="center" class="form-text"><input type="checkbox" name=":group" value="%s" %s></td>\n' % (nm, checked) )
+                w(' <td align="center" class="form-text"><input type="checkbox" name=":group" value="%s" %s></td>' % (nm, checked) )
             else:
-                w(' <td></td>\n')
+                w(' <td></td>')
             # sort - no sort on Multilinks
             if isinstance(propdescr, hyperdb.Multilink):
-                w('<td></td>\n')
+                w('<td></td>')
             else:
                 val = sortspec.get(nm, '')
-                w('<td align="center" class="form-text"><input type="text" name=":%s_ss" size="3" value="%s"></td>\n' % (nm,val))
+                w('<td align="center" class="form-text"><input type="text" name=":%s_ss" size="3" value="%s"></td>' % (nm,val))
             # condition
             val = ''
             if isinstance(propdescr, hyperdb.Link):
@@ -1113,27 +1136,55 @@ class IndexTemplate(TemplateFunctions):
                 xtra = ""
                 val = filterspec.get(nm, '')
             else:
-                w('<td></td><td></td><td></td></tr>\n')
+                w('<td></td><td></td><td></td></tr>')
                 continue
             checked = filter and nm in filter or 0
             checked = ('', 'checked')[checked]
-            w(  ' <td class="form-text"><input type="checkbox" name=":filter" value="%s" %s></td>\n' % (nm, checked))
-            w(_(' <td class="form-label" nowrap>%s</td><td class="form-text" nowrap><input type="text" name=":%s_fs" value="%s" size=50>%s</td>\n' % (op, nm, val, xtra)))
-            w(  '</tr>\n')
-        w('<tr class="location-bar">\n')
-       w(' <td colspan=7><hr></td>\n')
-       w('</tr>\n')
-       w('<tr class="location-bar">\n')
-       w(_(' <td align="right" class="form-label">Pagesize</td>\n'))
-       w(' <td colspan=2 align="center" class="form-text"><input type="text" name=":pagesize" size="3" value="%s"></td>\n' % pagesize)
-       w(' <td colspan=4></td>\n')
-       w('</tr>\n')
-       w('<tr class="location-bar">\n')
-       w(_(' <td align="right" class="form-label">Start With</td>\n'))
-       w(' <td colspan=2 align="center" class="form-text"><input type="text" name=":startwith" size="3" value="%s"></td>\n' % startwith)
-       w(' <td colspan=3 align="center" valign="center"><input type="submit" name="Query" value="Redisplay"></td>\n')
-       w(' <td></td>\n')
-       w('</tr>\n')
+            w(  ' <td class="form-text"><input type="checkbox" name=":filter" value="%s" %s></td>' % (nm, checked))
+            w(_(' <td class="form-label" nowrap>%s</td><td class="form-text" nowrap><input type="text" name=":%s_fs" value="%s" size=50>%s</td>' % (op, nm, val, xtra)))
+            w(  '</tr>')
+        w('<tr class="location-bar">')
+        w(' <td colspan=7><hr></td>')
+        w('</tr>')
+        w('<tr class="location-bar">')
+        w(_(' <td align="right" class="form-label">Pagesize</td>'))
+        w(' <td colspan=2 align="center" class="form-text"><input type="text" name=":pagesize" size="3" value="%s"></td>' % pagesize)
+        w(' <td colspan=4></td>')
+        w('</tr>')
+        w('<tr class="location-bar">')
+        w(_(' <td align="right" class="form-label">Start With</td>'))
+        w(' <td colspan=2 align="center" class="form-text"><input type="text" name=":startwith" size="3" value="%s"></td>' % startwith)
+        w(' <td colspan=3></td>')
+        w(' <td></td>')
+        w('</tr>')
+
+        return '\n'.join(rslt)
+    
+    def filter_section(self, search_text, filter, columns, group, all_columns, sort, filterspec,
+                       pagesize, startwith):
+
+        w = self.client.write        
+        w(self.filter_form(search_text, filter, columns, group, all_columns,
+                           sort, filterspec, pagesize))
+        w(' <tr class="location-bar">\n')
+        w('  <td colspan=7><hr></td>\n')
+        w(' </tr>\n')
+        w(' <tr class="location-bar">\n')
+        w('  <td>&nbsp;</td>\n')
+        w('  <td colspan=6><input type="submit" name="Query" value="Redisplay"></td>\n')
+        w(' </tr>\n')
+        if self.db.getclass('user').getprops().has_key('queries'):
+            w(' <tr class="location-bar">\n')
+            w('  <td colspan=7><hr></td>\n')
+            w(' </tr>\n')
+            w(' <tr class="location-bar">\n')
+            w('  <td align=right class="form-label">Name</td>\n')
+            w('  <td colspan=6><input type="text" name=":name" value=""></td>\n')
+            w(' </tr>\n')
+            w(' <tr class="location-bar">\n')
+            w('  <td>&nbsp;</td><input type="hidden" name=":classname" value="%s">\n' % self.classname)
+            w('  <td colspan=6><input type="submit" name="Query" value="Save"></td>\n')
+            w(' </tr>\n')
         w('</table>\n')
 
     def sortby(self, sort_name, filterspec, columns, filter, group, sort, pagesize, startwith):
@@ -1229,7 +1280,7 @@ class ItemTemplate(TemplateFunctions):
         
     def render(self, nodeid):
         self.nodeid = nodeid
-
+        
         if (self.properties.has_key('type') and
                 self.properties.has_key('content')):
             pass
@@ -1290,6 +1341,9 @@ class NewItemTemplate(TemplateFunctions):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.98  2002/07/10 00:17:46  richard
+#  . added sorting of checklist HTML display
+#
 # Revision 1.97  2002/07/09 05:20:09  richard
 #  . added email display function - mangles email addrs so they're not so easily
 #    scraped from the web
index 03fbeac902c44529982c65f6c85b51a1d38fb9dc..1edc2dd1bf73fdfbe68a4026caf1d330692a1703 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: dbinit.py,v 1.19 2002-07-14 02:05:54 richard Exp $
+# $Id: dbinit.py,v 1.20 2002-07-17 12:39:10 gmcm Exp $
 
 import os
 
@@ -50,12 +50,17 @@ def open(name=None):
     keyword = Class(db, "keyword", 
                     name=String())
     keyword.setkey("name")
-
+    
+    query = Class(db, "query",
+                    klass=String(),     name=String(),
+                    url=String())
+    query.setkey("name")
+    
     user = Class(db, "user", 
                     username=String(),   password=Password(),
                     address=String(),    realname=String(), 
                     phone=String(),      organisation=String(),
-                    alternate_addresses=String())
+                    alternate_addresses=String(), queries=Multilink("query"))
     user.setkey("username")
 
     # FileClass automatically gets these properties:
@@ -126,6 +131,9 @@ def init(adminpw):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.19  2002/07/14 02:05:54  richard
+# . all storage-specific code (ie. backend) is now implemented by the backends
+#
 # Revision 1.18  2002/07/09 03:02:53  richard
 # More indexer work:
 # - all String properties may now be indexed too. Currently there's a bit of
diff --git a/roundup/templates/classic/html/query.index b/roundup/templates/classic/html/query.index
new file mode 100755 (executable)
index 0000000..3de3d05
--- /dev/null
@@ -0,0 +1,13 @@
+<tr>\r
+  <td>\r
+    <property name="name">\r
+      <display call="link('name')">\r
+    </property>\r
+  </td>\r
+  <td>\r
+    <property name="klass">\r
+      <display call="plain('klass')">\r
+    </property>\r
+  </td>\r
+</tr>\r
+\r
diff --git a/roundup/templates/classic/html/query.item b/roundup/templates/classic/html/query.item
new file mode 100755 (executable)
index 0000000..ba3c8c2
--- /dev/null
@@ -0,0 +1,25 @@
+<table border=0 cellspacing=0 cellpadding=2>\r
+<tr class="strong-header">\r
+  <td colspan=2>Query</td>\r
+</tr>\r
+\r
+<tr bgcolor="ffffea">\r
+  <td width=1% nowrap class="form-label" align=right>Class</td>\r
+  <td class="form-text"><display call="plain('klass')"></td>\r
+</tr>\r
+\r
+<tr bgcolor="ffffea">\r
+  <td width=1% nowrap class="form-label" align=right>Name</td>\r
+  <td class="form-text"><display call="field('name')"></td>\r
+</tr>\r
+\r
+<tr bgcolor="ffffea">\r
+  <td colspan=2><display call="filterspec('klass','url')"></td>\r
+</tr>\r
+\r
+<tr bgcolor="ffffea">\r
+  <td></td>\r
+  <td class="form-text"><display call="submit()"></td>\r
+</tr>\r
+</table>\r
+\r
index 3443ca2b463ffd61fc2e39424519f76fd379ba0b..e4a4eacfbf2fbd53d94e51ba7e825343fb6a3af1 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: user.item,v 1.3 2002-02-15 07:08:44 richard Exp $-->
+<!-- $Id: user.item,v 1.4 2002-07-17 12:39:11 gmcm Exp $-->
 <table border=0 cellspacing=0 cellpadding=2>
 
 <tr class="strong-header">
     <td class="form-text"><display call="submit()"></td>
 </tr>
 
+<tr class="strong-header">
+    <td colspan=2><b>Queries</b></td>
+</tr>
+<tr>
+    <td colspan=2><display call="list('queries')"></td>
+</tr>
+
 <tr class="strong-header">
     <td colspan=2><b>History</b></td>
 </tr>