Fossil

Check-in [86ed68ba]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the "Bugs" menu element on the default header. Progress on implementing bug tracking.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 86ed68ba348bd71c9b50f57f9ce4116b50ef50af
User & Date: drh 2008-05-17 21:15:24
Context
2008-05-17
22:18
Begin adding code to the sync logic to transfer configuration options upon request. check-in: a241c811 user: drh tags: trunk
21:15
Add the "Bugs" menu element on the default header. Progress on implementing bug tracking. check-in: 86ed68ba user: drh tags: trunk
20:32
Documentation tweaks. check-in: 06689854 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/report.c.

32
33
34
35
36
37
38

39
40







41
42


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67






68
69
70
71
72
73
74
...
642
643
644
645
646
647
648
649
650




651
652
653
654
655
656
657
...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676



677
678
679
680
681
682

683
684
685
686
687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720


721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
static void report_format_hints(void);

/*
** WEBPAGE: /reportlist
*/
void view_list(void){
  Stmt q;


  login_check_credentials();







  if( !g.okRdTkt ){ login_needed(); return; }
  style_header("Available Report Formats");


  db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title");
  @ <p>Choose a report format from the following list:</p>
  @ <ol>
  while( db_step(&q)==SQLITE_ROW ){
    int rn = db_column_int(&q, 0);
    const char *zTitle = db_column_text(&q, 1);
    const char *zOwner = db_column_text(&q, 2);
    @ <li><a href="rptview?rn=%d(rn)"
    @        rel="nofollow">%h(zTitle)</a>&nbsp;&nbsp;&nbsp;
    if( g.okWrite && zOwner && zOwner[0] ){
      @ (by <i>%h(zOwner)</i>)
    }
    if( g.okWrTkt ){
      @ [<a href="rptedit?rn=%d(rn)&amp;copy=1" rel="nofollow">copy</a>]
    }
    if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){
      @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>]
    }
    @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>]
    @ </li>
  }
  if( g.okWrTkt ){
    @ <li><a href="rptnew">Create a new report format</a></li>
  }
  @ </ol>






  style_footer();
}

/*
** Remove whitespace from both ends of a string.
*/
char *trim_string(const char *zOrig){
................................................................................
  }
}

/*
** The state of the report generation.
*/
struct GenerateHTML {
  int rn;        /* Report number */
  int nCount;    /* Row number */




};

/*
** The callback function for db_query
*/
static int generate_html(
  void *pUser,     /* Pointer to output state */
................................................................................
  char **azArg,    /* Text of data in all columns */
  char **azName    /* Names of the columns */
){
  struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
  int i;
  int tn;            /* Ticket number.  (value of column named '#') */
  int rn;            /* Report number */
  int ncol;          /* Number of columns in the table */
  int multirow;      /* True if multiple table rows per line of data */
  int newrowidx;     /* Index of first column that goes on a separate row */
  int iBg = -1;      /* Index of column that determines background color */
  char *zBg = 0;     /* Use this background color */
  char zPage[30];    /* Text version of the ticket number */

  /* Get the report number
  */
  rn = pState->rn;




  /* Figure out the number of columns, the column that determines background
  ** color, and whether or not this row of data is represented by multiple
  ** rows in the table.
  */
  ncol = 0;
  multirow = 0;

  newrowidx = -1;
  for(i=0; i<nArg; i++){
    if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){
      zBg = azArg ? azArg[i] : 0;
      iBg = i;
      continue;
    }
    if( g.okWrite && azName[i][0]=='#' ){
      ncol++;
    }
    if( !multirow ){
      if( azName[i][0]=='_' ){
        multirow = 1;
        newrowidx = i;

      }else{
        ncol++;
      }
    }
  }

  /* The first time this routine is called, output a table header
  */
  if( pState->nCount==0 ){
    @ <tr>
    tn = -1;
    for(i=0; i<nArg; i++){
      char *zName = azName[i];
      if( i==iBg ) continue;
      if( newrowidx>=0 && i>=newrowidx ){
        if( g.okWrite && tn>=0 ){
          @ <th>&nbsp;</th>
          tn = -1;
        }
        if( zName[0]=='_' ) zName++;
        @ </tr><tr><th colspan=%d(ncol)>%h(zName)</th>
      }else{
        if( zName[0]=='#' ){
          tn = i;


        }
      }
    }
    if( g.okWrite && tn>=0 ){
      @ <th>&nbsp;</th>
    }
    @ </tr>
  }
  if( azArg==0 ){
    @ <tr><td colspan="%d(ncol)">
    @ <i>No records match the report criteria</i>
    @ </td></tr>
    return 0;
  }
  ++pState->nCount;

  /* Output the separator above each entry in a table which has multiple lines
  ** per database entry.
  */
  if( newrowidx>=0 ){
    @ <tr><td colspan=%d(ncol)><font size=1>&nbsp;</font></td></tr>
  }

  /* Output the data for this entry from the database
  */

  if( zBg==0 ) zBg = "white";
  @ <tr bgcolor="%h(zBg)">
  tn = 0;
  zPage[0] = 0;
  for(i=0; i<nArg; i++){
    char *zData;
    if( i==iBg ) continue;
    zData = azArg[i];
    if( zData==0 ) zData = "";
    if( newrowidx>=0 && i>=newrowidx ){
      if( tn>0 && g.okWrite ){
        @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td>
        tn = 0;
      }
      if( zData[0] ){
        @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(ncol)>
        @ %h(zData)
      }
    }else if( azName[i][0]=='#' ){
      tn = atoi(zData);
      @ <td valign="top"><a href="tktview?tn=%d(tn),%d(rn)">%h(zData)</a></td>
    }else if( zData[0]==0 ){
      @ <td valign="top">&nbsp;</td>







>


>
>
>
>
>
>
>
|
<
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<


>
>
>
>
>
>







 







|
|
>
>
>
>







 







<
<
<
<







>
>
>
|
|
|
|
|
|
>
|
|
|
<
|
|
|
|
|
|
|
|
|
<
>
|
|
|
|
|

|
|
<




|
|





|



>
>









|









|
|




>






|


|





|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
...
676
677
678
679
680
681
682




683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710
711

712
713
714
715
716
717
718
719
720

721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
static void report_format_hints(void);

/*
** WEBPAGE: /reportlist
*/
void view_list(void){
  Stmt q;
  int rn = 0;

  login_check_credentials();
  if( !g.okRdTkt && !g.okNewTkt ){ login_needed(); return; }
  style_header("Bug Report Main Menu");
  if( g.okNewTkt ){
    @ <p>Enter a new bug report:</p>
    @ <ol><li value="0"><a href="tktnew">New bug report</a></li></ol>
    @
  }
  if( !g.okRdTkt ){

    @ <p>You are not authorized to view existing bug reports.</p>
  }else{
    db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title");
    @ <p>Choose a report format from the following list:</p>
    @ <ol>
    while( db_step(&q)==SQLITE_ROW ){
      rn = db_column_int(&q, 0);
      const char *zTitle = db_column_text(&q, 1);
      const char *zOwner = db_column_text(&q, 2);
      @ <li value="%d(rn)"><a href="rptview?rn=%d(rn)"
      @        rel="nofollow">%h(zTitle)</a>&nbsp;&nbsp;&nbsp;
      if( g.okWrite && zOwner && zOwner[0] ){
        @ (by <i>%h(zOwner)</i>)
      }
      if( g.okWrTkt ){
        @ [<a href="rptedit?rn=%d(rn)&amp;copy=1" rel="nofollow">copy</a>]
      }
      if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){
        @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>]
      }
      @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>]
      @ </li>
    }


  }
  @ </ol>
  if( g.okWrTkt ){
    @ <p>Create a new bug report display format:</p>
    @ <ol>
    @ <li value="%d(rn+1)"><a href="rptnew">New report format</a></li>
    @ </ol>
  }
  style_footer();
}

/*
** Remove whitespace from both ends of a string.
*/
char *trim_string(const char *zOrig){
................................................................................
  }
}

/*
** The state of the report generation.
*/
struct GenerateHTML {
  int rn;          /* Report number */
  int nCount;      /* Row number */
  int nCol;        /* Number of columns */
  int isMultirow;  /* True if multiple table rows per query result row */
  int iNewRow;     /* Index of first column that goes on separate row */
  int iBg;         /* Index of column that defines background color */
};

/*
** The callback function for db_query
*/
static int generate_html(
  void *pUser,     /* Pointer to output state */
................................................................................
  char **azArg,    /* Text of data in all columns */
  char **azName    /* Names of the columns */
){
  struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
  int i;
  int tn;            /* Ticket number.  (value of column named '#') */
  int rn;            /* Report number */




  char *zBg = 0;     /* Use this background color */
  char zPage[30];    /* Text version of the ticket number */

  /* Get the report number
  */
  rn = pState->rn;

  /* Do initialization
  */
  if( pState->nCount==0 ){
    /* Figure out the number of columns, the column that determines background
    ** color, and whether or not this row of data is represented by multiple
    ** rows in the table.
    */
    pState->nCol = 0;
    pState->isMultirow = 0;
    pState->iNewRow = -1;
    pState->iBg = -1;
    for(i=0; i<nArg; i++){
      if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){

        pState->iBg = i;
        continue;
      }
      if( g.okWrite && azName[i][0]=='#' ){
        pState->nCol++;
      }
      if( !pState->isMultirow ){
        if( azName[i][0]=='_' ){
          pState->isMultirow = 1;

          pState->iNewRow = i;
        }else{
          pState->nCol++;
        }
      }
    }

    /* The first time this routine is called, output a table header
    */

    @ <tr>
    tn = -1;
    for(i=0; i<nArg; i++){
      char *zName = azName[i];
      if( i==pState->iBg ) continue;
      if( pState->iNewRow>=0 && i>=pState->iNewRow ){
        if( g.okWrite && tn>=0 ){
          @ <th>&nbsp;</th>
          tn = -1;
        }
        if( zName[0]=='_' ) zName++;
        @ </tr><tr><th colspan=%d(pState->nCol)>%h(zName)</th>
      }else{
        if( zName[0]=='#' ){
          tn = i;
        }else{
          @ <th>%h(zName)</th>
        }
      }
    }
    if( g.okWrite && tn>=0 ){
      @ <th>&nbsp;</th>
    }
    @ </tr>
  }
  if( azArg==0 ){
    @ <tr><td colspan="%d(pState->nCol)">
    @ <i>No records match the report criteria</i>
    @ </td></tr>
    return 0;
  }
  ++pState->nCount;

  /* Output the separator above each entry in a table which has multiple lines
  ** per database entry.
  */
  if( pState->iNewRow>=0 ){
    @ <tr><td colspan=%d(pState->nCol)><font size=1>&nbsp;</font></td></tr>
  }

  /* Output the data for this entry from the database
  */
  zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0;
  if( zBg==0 ) zBg = "white";
  @ <tr bgcolor="%h(zBg)">
  tn = 0;
  zPage[0] = 0;
  for(i=0; i<nArg; i++){
    char *zData;
    if( i==pState->iBg ) continue;
    zData = azArg[i];
    if( zData==0 ) zData = "";
    if( pState->iNewRow>=0 && i>=pState->iNewRow ){
      if( tn>0 && g.okWrite ){
        @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td>
        tn = 0;
      }
      if( zData[0] ){
        @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(pState->nCol)>
        @ %h(zData)
      }
    }else if( azName[i][0]=='#' ){
      tn = atoi(zData);
      @ <td valign="top"><a href="tktview?tn=%d(tn),%d(rn)">%h(zData)</a></td>
    }else if( zData[0]==0 ){
      @ <td valign="top">&nbsp;</td>

Changes to src/style.c.

169
170
171
172
173
174
175
176



177
178
179
180
181
182
183
@ html "<a href='$baseurl$index_page'>Home</a>"
@ if {[hascap h]} {
@   html "<a href='$baseurl/dir'>Files</a>"
@ }
@ if {[hascap o]} {
@   html "<a href='$baseurl/leaves'>Leaves</a>"
@   html "<a href='$baseurl/timeline'>Timeline</a>"
@   html "<a href='$baseurl/tagview'>Tags</a>"



@ }
@ if {[hascap j]} {
@   html "<a href='$baseurl/wiki'>Wiki</a>"
@ }
@ if {[hascap s]} {
@   html "<a href='$baseurl/setup'>Setup</a>"
@ }







|
>
>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
@ html "<a href='$baseurl$index_page'>Home</a>"
@ if {[hascap h]} {
@   html "<a href='$baseurl/dir'>Files</a>"
@ }
@ if {[hascap o]} {
@   html "<a href='$baseurl/leaves'>Leaves</a>"
@   html "<a href='$baseurl/timeline'>Timeline</a>"
@   # html "<a href='$baseurl/tagview'>Tags</a>"
@ }
@ if {[hascap hr]} {
@   html "<a href='$baseurl/reportlist'>Bugs</a>"
@ }
@ if {[hascap j]} {
@   html "<a href='$baseurl/wiki'>Wiki</a>"
@ }
@ if {[hascap s]} {
@   html "<a href='$baseurl/setup'>Setup</a>"
@ }