Check-in [3122fc4c7e]
Not logged in
Overview

SHA1 Hash:3122fc4c7ef932bf26200859dae8836c33f3ff89
Date: 2008-02-14 02:49:41
User: drh
Comment:Continuing work on tickets (still not working right.) Improvements to the web pages.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/info.c from [33d2efae51] to [0cbd863b6d].

@@ -21,11 +21,11 @@
 **
 *******************************************************************************
 **
 ** This file contains code to implement the "info" command.  The
 ** "info" command gives command-line access to information about
-** the current tree, or a particular file or version.
+** the current tree, or a particular artifact or baseline.
 */
 #include "config.h"
 #include "info.h"
 #include <assert.h>
 
@@ -106,11 +106,11 @@
     show_common_info(rid, "uuid:", 1);
   }
 }
 
 /*
-** Show information about descendents of a version.  Do this recursively
+** Show information about descendents of a baseline.  Do this recursively
 ** to a depth of N.  Return true if descendents are shown and false if not.
 */
 static int showDescendents(int pid, int depth, const char *zTitle){
   Stmt q;
   int cnt = 0;
@@ -158,11 +158,11 @@
   }
   return cnt;
 }
 
 /*
-** Show information about ancestors of a version.  Do this recursively
+** Show information about ancestors of a baseline.  Do this recursively
 ** to a depth of N.  Return true if ancestors are shown and false if not.
 */
 static void showAncestors(int pid, int depth, const char *zTitle){
   Stmt q;
   int cnt = 0;
@@ -203,11 +203,11 @@
   }
 }
 
 
 /*
-** Show information about versions mentioned in the "leaves" table.
+** Show information about baselines mentioned in the "leaves" table.
 */
 static void showLeaves(void){
   Stmt q;
   int cnt = 0;
   db_prepare(&q,
@@ -240,20 +240,20 @@
 }
 
 /*
 ** Show information about all tags on a given node.
 */
-static void showTags(int rid){
+static void showTags(int rid, const char *zNotGlob){
   Stmt q;
   int cnt = 0;
   db_prepare(&q,
     "SELECT tag.tagid, tagname, srcid, blob.uuid, value,"
     "       datetime(tagxref.mtime,'localtime'), tagtype"
     "  FROM tagxref JOIN tag ON tagxref.tagid=tag.tagid"
     "       LEFT JOIN blob ON blob.rid=tagxref.srcid"
-    " WHERE tagxref.rid=%d"
-    " ORDER BY tagname", rid
+    " WHERE tagxref.rid=%d AND tagname NOT GLOB '%s'"
+    " ORDER BY tagname", rid, zNotGlob
   );
   while( db_step(&q)==SQLITE_ROW ){
     const char *zTagname = db_column_text(&q, 1);
     int srcid = db_column_int(&q, 2);
     const char *zUuid = db_column_text(&q, 3);
@@ -291,11 +291,11 @@
 
 /*
 ** WEBPAGE: vinfo
 ** URL:  /vinfo?name=RID|UUID
 **
-** Return information about a version.
+** Return information about a baseline
 */
 void vinfo_page(void){
   Stmt q;
   int rid;
   int isLeaf;
@@ -317,11 +317,11 @@
      "   AND event.objid=%d",
      rid, rid
   );
   if( db_step(&q)==SQLITE_ROW ){
     const char *zUuid = db_column_text(&q, 0);
-    char *zTitle = mprintf("Version: [%.10s]", zUuid);
+    char *zTitle = mprintf("Baseline [%.10s]", zUuid);
     style_header(zTitle);
     free(zTitle);
     /*@ <h2>Version %s(zUuid)</h2>*/
     @ <div class="section">Overview</div>
     @ <p><table class="label-value">
@@ -335,19 +335,19 @@
     @ </td></tr>
     @ <tr><th>Commands:</th>
     @   <td>
     @     <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a>
     @     | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a>
-    @     | <a href="%s(g.zBaseURL)/fview/%d(rid)">manifest</a>
+    @     | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a>
     @   </td>
     @ </tr>
     @ </table></p>
   }else{
-    style_header("Version Information");
+    style_header("Baseline Information");
   }
   db_finalize(&q);
-  showTags(rid);
+  showTags(rid, "");
   @ <div class="section">Changes</div>
   @ <ul>
   db_prepare(&q,
      "SELECT name, pid, fid"
      "  FROM mlink, filename"
@@ -422,20 +422,37 @@
     }
     @ <tr><th>Original&nbsp;User:</th><td>%s(db_column_text(&q, 3))</td></tr>
     @ <tr><th>Commands:</th>
     @   <td>
 /*    @     <a href="%s(g.zBaseURL)/wdiff/%d(rid)">diff</a> | */
-    @     <a href="%s(g.zBaseURL)/whistory?page=%t(zName)">history</a>
-    @     | <a href="%s(g.zBaseURL)/fview/%d(rid)">raw-text</a>
+    @     <a href="%s(g.zBaseURL)/whistory?name=%t(zName)">history</a>
+    @     | <a href="%s(g.zBaseURL)/artifact/%d(rid)">raw-text</a>
     @   </td>
     @ </tr>
     @ </table></p>
   }else{
     style_header("Wiki Information");
+    rid = 0;
   }
   db_finalize(&q);
-  showTags(rid);
+  showTags(rid, "wiki-*");
+  if( rid ){
+    Blob content;
+    Manifest m;
+    memset(&m, 0, sizeof(m));
+    blob_zero(&m.content);
+    content_get(rid, &content);
+    manifest_parse(&m, &content);
+    if( m.type==CFTYPE_WIKI ){
+      Blob wiki;
+      blob_init(&wiki, m.zWiki, -1);
+      @ <div class="section">Content</div>
+      wiki_convert(&wiki, 0, 0);
+      blob_reset(&wiki);
+    }
+    manifest_clear(&m);
+  }
   style_footer();
 }
 
 /*
 ** WEBPAGE: finfo
@@ -499,11 +516,11 @@
     @ <td width="20"></td>
     @ <td valign="top" align="left">
     hyperlink_to_uuid(zVers);
     @ %h(zCom) (By: %h(zUser))
     @ Id: %s(zUuid)/%d(frid)
-    @ <a href="%s(g.zBaseURL)/fview/%d(frid)">[view]</a>
+    @ <a href="%s(g.zBaseURL)/artifact/%d(frid)">[view]</a>
     if( fpid ){
       @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
     }
     @ <a href="%s(g.zBaseURL)/annotate?mid=%d(mid)&amp;fnid=%d(fnid)">
     @ [annotate]</a>
@@ -541,11 +558,11 @@
   Stmt q;
   char *zUuid;
 
   login_check_credentials();
   if( !g.okHistory ){ login_needed(); return; }
-  style_header("Version Diff");
+  style_header("Baseline Diff");
 
   rid = name_to_rid(PD("name",""));
   if( rid==0 ){
     cgi_redirect("index");
   }
@@ -580,11 +597,11 @@
 **
 ** If the object is a file then mention:
 **
 **     * It's uuid
 **     * All its filenames
-**     * The versions it was checked-in on, with times and users
+**     * The baselines it was checked-in on, with times and users
 **
 ** If the object is a manifest, then mention:
 **
 **     * It's uuid
 **     * date of check-in
@@ -644,11 +661,11 @@
     cnt++;
   }
   db_finalize(&q);
   if( nWiki==0 ){
     db_prepare(&q,
-      "SELECT datetime(mtime), user, comment, uuid"
+      "SELECT datetime(mtime), user, comment, uuid, type"
       "  FROM event, blob"
       " WHERE event.objid=%d"
       "   AND blob.rid=%d",
       rid, rid
     );
@@ -655,11 +672,20 @@
     while( db_step(&q)==SQLITE_ROW ){
       const char *zDate = db_column_text(&q, 0);
       const char *zUuid = db_column_text(&q, 3);
       const char *zUser = db_column_text(&q, 1);
       const char *zCom = db_column_text(&q, 2);
-      @ Manifest of version
+      const char *zType = db_column_text(&q, 4);
+      if( zType[0]=='w' ){
+        @ Wiki edit
+      }else if( zType[0]=='t' ){
+        @ Ticket change
+      }else if( zType[0]=='c' ){
+        @ Manifest of baseline
+      }else{
+        @ Control file referencing
+      }
       hyperlink_to_uuid(zUuid);
       @ %w(zCom) by %h(zUser) on %s(zDate)
       cnt++;
     }
     db_finalize(&q);
@@ -666,11 +692,11 @@
   }
   if( cnt==0 ){
     char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
     @ Control file %s(zUuid).
   }else if( linkToView ){
-    @ <a href="%s(g.zBaseURL)/fview/%d(rid)">[view]</a>
+    @ <a href="%s(g.zBaseURL)/artifact/%d(rid)">[view]</a>
   }
 }
 
 /*
 ** WEBPAGE: fdiff
@@ -707,17 +733,17 @@
   blob_reset(&diff);
   style_footer();
 }
 
 /*
-** WEBPAGE: fview
-** URL: /fview?name=UUID
+** WEBPAGE: artifact
+** URL: /artifact?name=UUID
 **
 ** Show the complete content of a file identified by UUID
 ** as preformatted text.
 */
-void fview_page(void){
+void artifact_page(void){
   int rid;
   Blob content;
 
   rid = name_to_rid(PD("name","0"));
   login_check_credentials();
@@ -731,11 +757,11 @@
     if( db_exists("SELECT 1 FROM plink WHERE cid=%d", rid) ){
       vinfo_page();
       return;
     }
   }
-  style_header("File Content");
+  style_header("Artifact Content");
   @ <h2>Content Of:</h2>
   @ <blockquote>
   object_description(rid, 0);
   @ </blockquote>
   @ <hr>
@@ -750,84 +776,36 @@
 /*
 ** WEBPAGE: info
 ** URL: info/UUID
 **
 ** The argument is a UUID which might be a baseline or a file or
-** a ticket or something else.  It might also be a wiki page name.
-** Figure out what the UUID is an jump to it.  If there is ambiguity,
-** draw a page and let the user select the interpretation.
+** a ticket changes or a wiki editor or something else.
+**
+** Figure out what the UUID is and jump to it.
 */
 void info_page(void){
   const char *zName;
-  int rc = 0, nName, cnt;
-  Stmt q;
+  int rid, nName;
 
   zName = P("name");
   if( zName==0 ) cgi_redirect("index");
   nName = strlen(zName);
   if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
     cgi_redirect("index");
   }
-  db_multi_exec(
-     "CREATE TEMP TABLE refs(type,link);"
-     "INSERT INTO refs "
-     "  SELECT 'f', rid FROM blob WHERE uuid GLOB '%s*'"
-     "  UNION ALL"
-     "  SELECT 'w', substr(tagname,6) FROM tag"
-     "   WHERE tagname='wiki-%q'"
-     /*"  UNION ALL"
-     "  SELECT 't', tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*';"*/,
-     zName, zName, zName
-  );
-  cnt = db_int(0, "SELECT count(*) FROM refs");
-  if( cnt==0 ){
+  rid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%s*'");
+  if( rid==0 ){
     style_header("Broken Link");
     @ <p>No such object: %h(zName)</p>
     style_footer();
     return;
   }
-  db_prepare(&q, "SELECT type, link FROM refs");
-  db_step(&q);
-  if( cnt==1 ){
-    int type = *db_column_text(&q, 0);
-    int rid = db_column_int(&q, 1);
-    db_finalize(&q);
-    if( type=='w' ){
-      wiki_page();
-    }else if( type=='t' ){
-      tktview_page();
-    }else{
-      cgi_replace_parameter("name", mprintf("%d", rid));
-      if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
-        vinfo_page();
-      }else{
-        finfo_page();
-      }
-    }
-    return;
-  }
-  /* Multiple objects */
-  style_header("Ambiguous Link");
-  @ <h2>Ambiguous Link: %h(zName)</h2>
-  @ <ul>
-  while( rc==SQLITE_ROW ){
-    int type = *db_column_text(&q, 0);
-    if( type=='f' ){
-      @ <li><p>
-      object_description(db_column_int(&q, 1), 1);
-      @ </p></li>
-    }else if( type=='w' ){
-      @ <li><p>
-      @ Wiki page <a href="%s(g.zBaseURL)/wiki?name=%s(zName)">%s(zName)</a>.
-      @ </li><p>
-    }else if( type=='t' ){
-      const char *zUuid = db_column_text(&q, 1);
-      @ <li><p>
-      @ Ticket <a href="%s(g.zBaseURL)/tktview?name=%s(zUuid)">%s(zUuid)</a>.
-      @ </li><p>
-    }
-    rc = db_step(&q);
-  }
-  @ </ul>
-  style_footer();
-  db_finalize(&q);
+  if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
+    vinfo_page();
+  }else
+  if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
+    finfo_page();
+  }else
+  {
+    artifact_page();
+  }
 }

Modified src/setup.c from [093a77e546] to [94746ae493].

@@ -645,11 +645,11 @@
   }else{
     textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
   }
   style_header("Edit Page Header");
   @ <form action="%s(g.zBaseURL)/setup_header" method="POST">
-  @ <p>Edit HTML text with embedded subscript that will be used to
+  @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   @ generate the beginning of every page through start of the main
   @ menu.</p>
   textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
   @ <br />
   @ <input type="submit" name="submit" value="Apply Changes">
@@ -678,11 +678,11 @@
   }else{
     textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
   }
   style_header("Edit Page Footer");
   @ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
-  @ <p>Edit HTML text with embedded subscript that will be used to
+  @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   @ generate the end of every page.</p>
   textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
   @ <br />
   @ <input type="submit" name="submit" value="Apply Changes">
   @ <input type="submit" name="clear" value="Revert To Default">
@@ -729,11 +729,11 @@
       @ SCRIPT ERROR: %h(zErr)
       @ </b></font></p>
     }
   }
   @ <form action="%s(g.zBaseURL)/setup_ticket" method="POST">
-  @ <p>Edit the "subscript" script that defines the ticketing
+  @ <p>Edit the TH1 script that defines the ticketing
   @ system setup for this server.</p>
   @ <textarea name="cfg" rows="40" cols="80">%h(zConfig)</textarea>
   @ <br />
   @ <input type="submit" name="submit" value="Apply Changes">
   @ <input type="submit" name="clear" value="Revert To Default">

Modified src/th_main.c from [43919ec3bf] to [7258c955ba].

@@ -158,19 +158,110 @@
   Th_SetResultInt(interp, login_has_capability((char*)argv[1],argl[1]));
   return TH_OK;
 }
 
 /*
+** TH1 command:  combobox NAME TEXT-LIST NUMLINES
+**
+** Generate an HTML combobox.  NAME is both the name of the
+** CGI parameter and the name of a variable that contains the
+** currently selected value.  TEXT-LIST is a list of possible
+** values for the combobox.  NUMLINES is 1 for a true combobox.
+** If NUMLINES is greater than one then the display is a listbox
+** with the number of lines given.
+*/
+static int comboboxCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
+  }
+  if( enableOutput ){
+    int height;
+    Blob list, elem, name;
+    int nValue;
+    const char *zValue;
+    char *z, *zH;
+
+    if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
+    blob_init(&list, (char*)argv[2], argl[2]);
+    blob_init(&name, (char*)argv[1], argl[1]);
+    zValue = Th_Fetch(blob_str(&name), &nValue);
+    z = mprintf("<select name=\"%z\" size=\"%d\">",
+                 htmlize(blob_buffer(&name), blob_size(&name)), height);
+    sendText(z, -1, 0);
+    free(z);
+    blob_reset(&name);
+    while( blob_token(&list, &elem) ){
+      zH = htmlize(blob_buffer(&elem), blob_size(&elem));
+      if( zValue && blob_size(&elem)==nValue
+             && memcmp(zValue, blob_buffer(&elem), nValue)==0 ){
+        z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
+      }else{
+        z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
+      }
+      free(zH);
+      sendText(z, -1, 0);
+      free(z);
+    }
+    sendText("</select>", -1, 0);
+    blob_reset(&list);
+  }
+  return TH_OK;
+}
+
+/*
+** TH1 command:     linecount STRING MAX MIN
+**
+** Return one more than the number of \n characters in STRING.  But
+** never return less than MIN or more than MAX.
+*/
+static int linecntCmd(
+  Th_Interp *interp,
+  void *p,
+  int argc,
+  const unsigned char **argv,
+  int *argl
+){
+  const uchar *z;
+  int size, n, i;
+  int iMin, iMax;
+  if( argc!=4 ){
+    return Th_WrongNumArgs(interp, "linecount STRING MAX MIN");
+  }
+  if( Th_ToInt(interp, argv[2], argl[2], &iMax) ) return TH_ERROR;
+  if( Th_ToInt(interp, argv[3], argl[3], &iMin) ) return TH_ERROR;
+  z = argv[1];
+  size = argl[1];
+  for(n=1, i=0; i<size; i++){
+    if( z[i]=='\n' ){
+      n++;
+      if( n>=iMax ) break;
+    }
+  }
+  if( n<iMin ) n = iMin;
+  if( n>iMax ) n = iMax;
+  Th_SetResultInt(interp, n);
+  return TH_OK;
+}
+
+/*
 ** Make sure the interpreter has been initialized.
 */
 void Th_FossilInit(void){
   static struct _Command {
     const char *zName;
     Th_CommandProc xProc;
     void *pContext;
   } aCommand[] = {
+    {"combobox",      comboboxCmd,          0},
     {"enable_output", enableOutputCmd,      0},
+    {"linecount",     linecntCmd,           0},
     {"hascap",        hascapCmd,            0},
     {"html",          putsCmd,              0},
     {"puts",          putsCmd,       (void*)1},
     {"wiki",          wikiCmd,              0},
   };
@@ -198,13 +289,13 @@
 ** variable exists, return NULL.
 */
 char *Th_Fetch(const char *zName, int *pSize){
   int rc;
   Th_FossilInit();
-  rc = Th_GetVar(g.interp, zName, -1);
+  rc = Th_GetVar(g.interp, (uchar*)zName, -1);
   if( rc==TH_OK ){
-    return Th_GetResult(g.interp, pSize);
+    return (char*)Th_GetResult(g.interp, pSize);
   }else{
     return 0;
   }
 }
 

Modified src/tkt.c from [1502147d4d] to [e7e06add5c].

@@ -252,11 +252,11 @@
 void ticket_init(void){
   char *zConfig;
   Th_FossilInit();
   zConfig = db_text((char*)zDefaultTicketConfig,
              "SELECT value FROM config WHERE name='ticket-configuration'");
-  Th_Eval(g.interp, 0, zConfig, -1);
+  Th_Eval(g.interp, 0, (const uchar*)zConfig, -1);
 }
 
 /*
 ** Recreate the ticket table.
 */
@@ -319,12 +319,10 @@
   zScript = mprintf("%.*s", nScript, zScript);
   Th_Render(zScript);
   style_footer();
 }
 
-
-
 /*
 ** TH command:   append_field FIELD STRING
 **
 ** FIELD is the name of a database column to which we might want
 ** to append text.  STRING is the text to be appended to that
@@ -342,11 +340,11 @@
 
   if( argc!=3 ){
     return Th_WrongNumArgs(interp, "append_field FIELD STRING");
   }
   for(idx=0; idx<nField; idx++){
-    if( strncmp(azField[idx], argv[1], argl[1])==0
+    if( strncmp(azField[idx], (const char*)argv[1], argl[1])==0
         && azField[idx][argl[1]]==0 ){
       break;
     }
   }
   if( idx>=nField ){
@@ -449,10 +447,11 @@
   login_check_credentials();
   if( !g.okNewTkt ){ login_needed(); return; }
   style_header("New Ticket");
   ticket_init();
   getAllTicketFields();
+  initializeVariablesFromDb();
   initializeVariablesFromCGI();
   @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
   zScript = (char*)Th_Fetch("tktnew_template", &nScript);
   zScript = mprintf("%.*s", nScript, zScript);
   Th_Store("login", g.zLogin);
@@ -545,13 +544,13 @@
      "tktview_template",
      "tktedit_template",
   };
 
   Th_FossilInit();
-  rc = Th_Eval(g.interp, 0, zConfig, strlen(zConfig));
+  rc = Th_Eval(g.interp, 0, (const uchar*)zConfig, strlen(zConfig));
   if( rc!=TH_OK ){
-    zErr = Th_TakeResult(g.interp, 0);
+    zErr = (char*)Th_TakeResult(g.interp, 0);
     return zErr;
   }
   for(i=0; i<sizeof(azRequired)/sizeof(azRequired[0]); i++){
     z = Th_Fetch(azRequired[i], &n);
     if( z==0 ){

Modified src/tktconfig.c from [ef74b37d75] to [9beffaf065].

@@ -61,10 +61,11 @@
 @      subsystem TEXT,
 @      priority TEXT,
 @      severity TEXT,
 @      foundin TEXT,
 @      contact TEXT,
+@      resolution TEXT,
 @      title TEXT,
 @      comment TEXT,
 @      -- Do not alter this UNIQUE clause:
 @      UNIQUE(tkt_uuid, tkt_mtime)
 @    );
@@ -144,11 +145,11 @@
 @   <td>In what version or build number do you observer the problem?</td>
 @   </tr>
 @
 @   <tr>
 @   <td align="right">Severity:
-@   <th1>comboboxy severity severity_choices 1</th1>
+@   <th1>combobox severity $severity_choices 1</th1>
 @   </td>
 @   <td>How debilitating is the problem?  How badly does the problem
 @   effect the operation of the product?</td>
 @   </tr>
 @
@@ -250,19 +251,20 @@
 @   <th1>
 @     if {![info exists eall]} {set eall 0}
 @     if {[info exists aonlybtn]} {set eall 0}
 @     if {[info exists eallbtn]} {set eall 1}
 @     if {![hascap w]} {set eall 0}
+@     if {![info exists cmappnd]} {set cmappnd {}}
 @     set nline [linecount $comment 15 10]
 @     enable_output $eall
 @   </th1>
 @     Description And Comments:<br>
 @     <textarea name="comment" cols="80" rows="$nline"
 @      wrap="virtual" class="wikiedit">$<comment></textarea><br>
 @     <input type="hidden" name="eall" value="1">
 @     <input type="submit" name="aonlybtn" value="Append Remark">
-@   <th1>enable_output [expr {!$eall}]</th>
+@   <th1>enable_output [expr {!$eall}]</th1>
 @     Append Remark from
 @     <input type="text" name="username" value="$<username>" size="30">:<br>
 @     <textarea name="cmappnd" cols="80" rows="15"
 @      wrap="virtual" class="wikiedit">$<cmappnd></textarea><br>
 @   <th1>enable_output [expr {[hascap w] && !$eall}]</th1>