Fossil SCM
Add the "Bugs" menu element on the default header. Progress on implementing bug tracking.
Commit
86ed68ba348bd71c9b50f57f9ce4116b50ef50af
Parent
06689854aee0564…
2 files changed
+87
-69
+4
-1
+87
-69
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -34,39 +34,52 @@ | ||
| 34 | 34 | /* |
| 35 | 35 | ** WEBPAGE: /reportlist |
| 36 | 36 | */ |
| 37 | 37 | void view_list(void){ |
| 38 | 38 | Stmt q; |
| 39 | + int rn = 0; | |
| 39 | 40 | |
| 40 | 41 | login_check_credentials(); |
| 41 | - if( !g.okRdTkt ){ login_needed(); return; } | |
| 42 | - style_header("Available Report Formats"); | |
| 43 | - db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title"); | |
| 44 | - @ <p>Choose a report format from the following list:</p> | |
| 45 | - @ <ol> | |
| 46 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 47 | - int rn = db_column_int(&q, 0); | |
| 48 | - const char *zTitle = db_column_text(&q, 1); | |
| 49 | - const char *zOwner = db_column_text(&q, 2); | |
| 50 | - @ <li><a href="rptview?rn=%d(rn)" | |
| 51 | - @ rel="nofollow">%h(zTitle)</a> | |
| 52 | - if( g.okWrite && zOwner && zOwner[0] ){ | |
| 53 | - @ (by <i>%h(zOwner)</i>) | |
| 54 | - } | |
| 55 | - if( g.okWrTkt ){ | |
| 56 | - @ [<a href="rptedit?rn=%d(rn)&copy=1" rel="nofollow">copy</a>] | |
| 57 | - } | |
| 58 | - if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){ | |
| 59 | - @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>] | |
| 60 | - } | |
| 61 | - @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>] | |
| 62 | - @ </li> | |
| 63 | - } | |
| 64 | - if( g.okWrTkt ){ | |
| 65 | - @ <li><a href="rptnew">Create a new report format</a></li> | |
| 42 | + if( !g.okRdTkt && !g.okNewTkt ){ login_needed(); return; } | |
| 43 | + style_header("Bug Report Main Menu"); | |
| 44 | + if( g.okNewTkt ){ | |
| 45 | + @ <p>Enter a new bug report:</p> | |
| 46 | + @ <ol><li value="0"><a href="tktnew">New bug report</a></li></ol> | |
| 47 | + @ | |
| 48 | + } | |
| 49 | + if( !g.okRdTkt ){ | |
| 50 | + @ <p>You are not authorized to view existing bug reports.</p> | |
| 51 | + }else{ | |
| 52 | + db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title"); | |
| 53 | + @ <p>Choose a report format from the following list:</p> | |
| 54 | + @ <ol> | |
| 55 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 56 | + rn = db_column_int(&q, 0); | |
| 57 | + const char *zTitle = db_column_text(&q, 1); | |
| 58 | + const char *zOwner = db_column_text(&q, 2); | |
| 59 | + @ <li value="%d(rn)"><a href="rptview?rn=%d(rn)" | |
| 60 | + @ rel="nofollow">%h(zTitle)</a> | |
| 61 | + if( g.okWrite && zOwner && zOwner[0] ){ | |
| 62 | + @ (by <i>%h(zOwner)</i>) | |
| 63 | + } | |
| 64 | + if( g.okWrTkt ){ | |
| 65 | + @ [<a href="rptedit?rn=%d(rn)&copy=1" rel="nofollow">copy</a>] | |
| 66 | + } | |
| 67 | + if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){ | |
| 68 | + @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>] | |
| 69 | + } | |
| 70 | + @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>] | |
| 71 | + @ </li> | |
| 72 | + } | |
| 66 | 73 | } |
| 67 | 74 | @ </ol> |
| 75 | + if( g.okWrTkt ){ | |
| 76 | + @ <p>Create a new bug report display format:</p> | |
| 77 | + @ <ol> | |
| 78 | + @ <li value="%d(rn+1)"><a href="rptnew">New report format</a></li> | |
| 79 | + @ </ol> | |
| 80 | + } | |
| 68 | 81 | style_footer(); |
| 69 | 82 | } |
| 70 | 83 | |
| 71 | 84 | /* |
| 72 | 85 | ** Remove whitespace from both ends of a string. |
| @@ -644,12 +657,16 @@ | ||
| 644 | 657 | |
| 645 | 658 | /* |
| 646 | 659 | ** The state of the report generation. |
| 647 | 660 | */ |
| 648 | 661 | struct GenerateHTML { |
| 649 | - int rn; /* Report number */ | |
| 650 | - int nCount; /* Row number */ | |
| 662 | + int rn; /* Report number */ | |
| 663 | + int nCount; /* Row number */ | |
| 664 | + int nCol; /* Number of columns */ | |
| 665 | + int isMultirow; /* True if multiple table rows per query result row */ | |
| 666 | + int iNewRow; /* Index of first column that goes on separate row */ | |
| 667 | + int iBg; /* Index of column that defines background color */ | |
| 651 | 668 | }; |
| 652 | 669 | |
| 653 | 670 | /* |
| 654 | 671 | ** The callback function for db_query |
| 655 | 672 | */ |
| @@ -661,106 +678,107 @@ | ||
| 661 | 678 | ){ |
| 662 | 679 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 663 | 680 | int i; |
| 664 | 681 | int tn; /* Ticket number. (value of column named '#') */ |
| 665 | 682 | int rn; /* Report number */ |
| 666 | - int ncol; /* Number of columns in the table */ | |
| 667 | - int multirow; /* True if multiple table rows per line of data */ | |
| 668 | - int newrowidx; /* Index of first column that goes on a separate row */ | |
| 669 | - int iBg = -1; /* Index of column that determines background color */ | |
| 670 | 683 | char *zBg = 0; /* Use this background color */ |
| 671 | 684 | char zPage[30]; /* Text version of the ticket number */ |
| 672 | 685 | |
| 673 | 686 | /* Get the report number |
| 674 | 687 | */ |
| 675 | 688 | rn = pState->rn; |
| 676 | 689 | |
| 677 | - /* Figure out the number of columns, the column that determines background | |
| 678 | - ** color, and whether or not this row of data is represented by multiple | |
| 679 | - ** rows in the table. | |
| 680 | - */ | |
| 681 | - ncol = 0; | |
| 682 | - multirow = 0; | |
| 683 | - newrowidx = -1; | |
| 684 | - for(i=0; i<nArg; i++){ | |
| 685 | - if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ | |
| 686 | - zBg = azArg ? azArg[i] : 0; | |
| 687 | - iBg = i; | |
| 688 | - continue; | |
| 689 | - } | |
| 690 | - if( g.okWrite && azName[i][0]=='#' ){ | |
| 691 | - ncol++; | |
| 692 | - } | |
| 693 | - if( !multirow ){ | |
| 694 | - if( azName[i][0]=='_' ){ | |
| 695 | - multirow = 1; | |
| 696 | - newrowidx = i; | |
| 697 | - }else{ | |
| 698 | - ncol++; | |
| 699 | - } | |
| 700 | - } | |
| 701 | - } | |
| 702 | - | |
| 703 | - /* The first time this routine is called, output a table header | |
| 704 | - */ | |
| 705 | - if( pState->nCount==0 ){ | |
| 690 | + /* Do initialization | |
| 691 | + */ | |
| 692 | + if( pState->nCount==0 ){ | |
| 693 | + /* Figure out the number of columns, the column that determines background | |
| 694 | + ** color, and whether or not this row of data is represented by multiple | |
| 695 | + ** rows in the table. | |
| 696 | + */ | |
| 697 | + pState->nCol = 0; | |
| 698 | + pState->isMultirow = 0; | |
| 699 | + pState->iNewRow = -1; | |
| 700 | + pState->iBg = -1; | |
| 701 | + for(i=0; i<nArg; i++){ | |
| 702 | + if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ | |
| 703 | + pState->iBg = i; | |
| 704 | + continue; | |
| 705 | + } | |
| 706 | + if( g.okWrite && azName[i][0]=='#' ){ | |
| 707 | + pState->nCol++; | |
| 708 | + } | |
| 709 | + if( !pState->isMultirow ){ | |
| 710 | + if( azName[i][0]=='_' ){ | |
| 711 | + pState->isMultirow = 1; | |
| 712 | + pState->iNewRow = i; | |
| 713 | + }else{ | |
| 714 | + pState->nCol++; | |
| 715 | + } | |
| 716 | + } | |
| 717 | + } | |
| 718 | + | |
| 719 | + /* The first time this routine is called, output a table header | |
| 720 | + */ | |
| 706 | 721 | @ <tr> |
| 707 | 722 | tn = -1; |
| 708 | 723 | for(i=0; i<nArg; i++){ |
| 709 | 724 | char *zName = azName[i]; |
| 710 | - if( i==iBg ) continue; | |
| 711 | - if( newrowidx>=0 && i>=newrowidx ){ | |
| 725 | + if( i==pState->iBg ) continue; | |
| 726 | + if( pState->iNewRow>=0 && i>=pState->iNewRow ){ | |
| 712 | 727 | if( g.okWrite && tn>=0 ){ |
| 713 | 728 | @ <th> </th> |
| 714 | 729 | tn = -1; |
| 715 | 730 | } |
| 716 | 731 | if( zName[0]=='_' ) zName++; |
| 717 | - @ </tr><tr><th colspan=%d(ncol)>%h(zName)</th> | |
| 732 | + @ </tr><tr><th colspan=%d(pState->nCol)>%h(zName)</th> | |
| 718 | 733 | }else{ |
| 719 | 734 | if( zName[0]=='#' ){ |
| 720 | 735 | tn = i; |
| 736 | + }else{ | |
| 737 | + @ <th>%h(zName)</th> | |
| 721 | 738 | } |
| 722 | 739 | } |
| 723 | 740 | } |
| 724 | 741 | if( g.okWrite && tn>=0 ){ |
| 725 | 742 | @ <th> </th> |
| 726 | 743 | } |
| 727 | 744 | @ </tr> |
| 728 | 745 | } |
| 729 | 746 | if( azArg==0 ){ |
| 730 | - @ <tr><td colspan="%d(ncol)"> | |
| 747 | + @ <tr><td colspan="%d(pState->nCol)"> | |
| 731 | 748 | @ <i>No records match the report criteria</i> |
| 732 | 749 | @ </td></tr> |
| 733 | 750 | return 0; |
| 734 | 751 | } |
| 735 | 752 | ++pState->nCount; |
| 736 | 753 | |
| 737 | 754 | /* Output the separator above each entry in a table which has multiple lines |
| 738 | 755 | ** per database entry. |
| 739 | 756 | */ |
| 740 | - if( newrowidx>=0 ){ | |
| 741 | - @ <tr><td colspan=%d(ncol)><font size=1> </font></td></tr> | |
| 757 | + if( pState->iNewRow>=0 ){ | |
| 758 | + @ <tr><td colspan=%d(pState->nCol)><font size=1> </font></td></tr> | |
| 742 | 759 | } |
| 743 | 760 | |
| 744 | 761 | /* Output the data for this entry from the database |
| 745 | 762 | */ |
| 763 | + zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; | |
| 746 | 764 | if( zBg==0 ) zBg = "white"; |
| 747 | 765 | @ <tr bgcolor="%h(zBg)"> |
| 748 | 766 | tn = 0; |
| 749 | 767 | zPage[0] = 0; |
| 750 | 768 | for(i=0; i<nArg; i++){ |
| 751 | 769 | char *zData; |
| 752 | - if( i==iBg ) continue; | |
| 770 | + if( i==pState->iBg ) continue; | |
| 753 | 771 | zData = azArg[i]; |
| 754 | 772 | if( zData==0 ) zData = ""; |
| 755 | - if( newrowidx>=0 && i>=newrowidx ){ | |
| 773 | + if( pState->iNewRow>=0 && i>=pState->iNewRow ){ | |
| 756 | 774 | if( tn>0 && g.okWrite ){ |
| 757 | 775 | @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td> |
| 758 | 776 | tn = 0; |
| 759 | 777 | } |
| 760 | 778 | if( zData[0] ){ |
| 761 | - @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(ncol)> | |
| 779 | + @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(pState->nCol)> | |
| 762 | 780 | @ %h(zData) |
| 763 | 781 | } |
| 764 | 782 | }else if( azName[i][0]=='#' ){ |
| 765 | 783 | tn = atoi(zData); |
| 766 | 784 | @ <td valign="top"><a href="tktview?tn=%d(tn),%d(rn)">%h(zData)</a></td> |
| 767 | 785 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -34,39 +34,52 @@ | |
| 34 | /* |
| 35 | ** WEBPAGE: /reportlist |
| 36 | */ |
| 37 | void view_list(void){ |
| 38 | Stmt q; |
| 39 | |
| 40 | login_check_credentials(); |
| 41 | if( !g.okRdTkt ){ login_needed(); return; } |
| 42 | style_header("Available Report Formats"); |
| 43 | db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title"); |
| 44 | @ <p>Choose a report format from the following list:</p> |
| 45 | @ <ol> |
| 46 | while( db_step(&q)==SQLITE_ROW ){ |
| 47 | int rn = db_column_int(&q, 0); |
| 48 | const char *zTitle = db_column_text(&q, 1); |
| 49 | const char *zOwner = db_column_text(&q, 2); |
| 50 | @ <li><a href="rptview?rn=%d(rn)" |
| 51 | @ rel="nofollow">%h(zTitle)</a> |
| 52 | if( g.okWrite && zOwner && zOwner[0] ){ |
| 53 | @ (by <i>%h(zOwner)</i>) |
| 54 | } |
| 55 | if( g.okWrTkt ){ |
| 56 | @ [<a href="rptedit?rn=%d(rn)&copy=1" rel="nofollow">copy</a>] |
| 57 | } |
| 58 | if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){ |
| 59 | @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>] |
| 60 | } |
| 61 | @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>] |
| 62 | @ </li> |
| 63 | } |
| 64 | if( g.okWrTkt ){ |
| 65 | @ <li><a href="rptnew">Create a new report format</a></li> |
| 66 | } |
| 67 | @ </ol> |
| 68 | style_footer(); |
| 69 | } |
| 70 | |
| 71 | /* |
| 72 | ** Remove whitespace from both ends of a string. |
| @@ -644,12 +657,16 @@ | |
| 644 | |
| 645 | /* |
| 646 | ** The state of the report generation. |
| 647 | */ |
| 648 | struct GenerateHTML { |
| 649 | int rn; /* Report number */ |
| 650 | int nCount; /* Row number */ |
| 651 | }; |
| 652 | |
| 653 | /* |
| 654 | ** The callback function for db_query |
| 655 | */ |
| @@ -661,106 +678,107 @@ | |
| 661 | ){ |
| 662 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 663 | int i; |
| 664 | int tn; /* Ticket number. (value of column named '#') */ |
| 665 | int rn; /* Report number */ |
| 666 | int ncol; /* Number of columns in the table */ |
| 667 | int multirow; /* True if multiple table rows per line of data */ |
| 668 | int newrowidx; /* Index of first column that goes on a separate row */ |
| 669 | int iBg = -1; /* Index of column that determines background color */ |
| 670 | char *zBg = 0; /* Use this background color */ |
| 671 | char zPage[30]; /* Text version of the ticket number */ |
| 672 | |
| 673 | /* Get the report number |
| 674 | */ |
| 675 | rn = pState->rn; |
| 676 | |
| 677 | /* Figure out the number of columns, the column that determines background |
| 678 | ** color, and whether or not this row of data is represented by multiple |
| 679 | ** rows in the table. |
| 680 | */ |
| 681 | ncol = 0; |
| 682 | multirow = 0; |
| 683 | newrowidx = -1; |
| 684 | for(i=0; i<nArg; i++){ |
| 685 | if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ |
| 686 | zBg = azArg ? azArg[i] : 0; |
| 687 | iBg = i; |
| 688 | continue; |
| 689 | } |
| 690 | if( g.okWrite && azName[i][0]=='#' ){ |
| 691 | ncol++; |
| 692 | } |
| 693 | if( !multirow ){ |
| 694 | if( azName[i][0]=='_' ){ |
| 695 | multirow = 1; |
| 696 | newrowidx = i; |
| 697 | }else{ |
| 698 | ncol++; |
| 699 | } |
| 700 | } |
| 701 | } |
| 702 | |
| 703 | /* The first time this routine is called, output a table header |
| 704 | */ |
| 705 | if( pState->nCount==0 ){ |
| 706 | @ <tr> |
| 707 | tn = -1; |
| 708 | for(i=0; i<nArg; i++){ |
| 709 | char *zName = azName[i]; |
| 710 | if( i==iBg ) continue; |
| 711 | if( newrowidx>=0 && i>=newrowidx ){ |
| 712 | if( g.okWrite && tn>=0 ){ |
| 713 | @ <th> </th> |
| 714 | tn = -1; |
| 715 | } |
| 716 | if( zName[0]=='_' ) zName++; |
| 717 | @ </tr><tr><th colspan=%d(ncol)>%h(zName)</th> |
| 718 | }else{ |
| 719 | if( zName[0]=='#' ){ |
| 720 | tn = i; |
| 721 | } |
| 722 | } |
| 723 | } |
| 724 | if( g.okWrite && tn>=0 ){ |
| 725 | @ <th> </th> |
| 726 | } |
| 727 | @ </tr> |
| 728 | } |
| 729 | if( azArg==0 ){ |
| 730 | @ <tr><td colspan="%d(ncol)"> |
| 731 | @ <i>No records match the report criteria</i> |
| 732 | @ </td></tr> |
| 733 | return 0; |
| 734 | } |
| 735 | ++pState->nCount; |
| 736 | |
| 737 | /* Output the separator above each entry in a table which has multiple lines |
| 738 | ** per database entry. |
| 739 | */ |
| 740 | if( newrowidx>=0 ){ |
| 741 | @ <tr><td colspan=%d(ncol)><font size=1> </font></td></tr> |
| 742 | } |
| 743 | |
| 744 | /* Output the data for this entry from the database |
| 745 | */ |
| 746 | if( zBg==0 ) zBg = "white"; |
| 747 | @ <tr bgcolor="%h(zBg)"> |
| 748 | tn = 0; |
| 749 | zPage[0] = 0; |
| 750 | for(i=0; i<nArg; i++){ |
| 751 | char *zData; |
| 752 | if( i==iBg ) continue; |
| 753 | zData = azArg[i]; |
| 754 | if( zData==0 ) zData = ""; |
| 755 | if( newrowidx>=0 && i>=newrowidx ){ |
| 756 | if( tn>0 && g.okWrite ){ |
| 757 | @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td> |
| 758 | tn = 0; |
| 759 | } |
| 760 | if( zData[0] ){ |
| 761 | @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(ncol)> |
| 762 | @ %h(zData) |
| 763 | } |
| 764 | }else if( azName[i][0]=='#' ){ |
| 765 | tn = atoi(zData); |
| 766 | @ <td valign="top"><a href="tktview?tn=%d(tn),%d(rn)">%h(zData)</a></td> |
| 767 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -34,39 +34,52 @@ | |
| 34 | /* |
| 35 | ** WEBPAGE: /reportlist |
| 36 | */ |
| 37 | void view_list(void){ |
| 38 | Stmt q; |
| 39 | int rn = 0; |
| 40 | |
| 41 | login_check_credentials(); |
| 42 | if( !g.okRdTkt && !g.okNewTkt ){ login_needed(); return; } |
| 43 | style_header("Bug Report Main Menu"); |
| 44 | if( g.okNewTkt ){ |
| 45 | @ <p>Enter a new bug report:</p> |
| 46 | @ <ol><li value="0"><a href="tktnew">New bug report</a></li></ol> |
| 47 | @ |
| 48 | } |
| 49 | if( !g.okRdTkt ){ |
| 50 | @ <p>You are not authorized to view existing bug reports.</p> |
| 51 | }else{ |
| 52 | db_prepare(&q, "SELECT rn, title, owner FROM reportfmt ORDER BY title"); |
| 53 | @ <p>Choose a report format from the following list:</p> |
| 54 | @ <ol> |
| 55 | while( db_step(&q)==SQLITE_ROW ){ |
| 56 | rn = db_column_int(&q, 0); |
| 57 | const char *zTitle = db_column_text(&q, 1); |
| 58 | const char *zOwner = db_column_text(&q, 2); |
| 59 | @ <li value="%d(rn)"><a href="rptview?rn=%d(rn)" |
| 60 | @ rel="nofollow">%h(zTitle)</a> |
| 61 | if( g.okWrite && zOwner && zOwner[0] ){ |
| 62 | @ (by <i>%h(zOwner)</i>) |
| 63 | } |
| 64 | if( g.okWrTkt ){ |
| 65 | @ [<a href="rptedit?rn=%d(rn)&copy=1" rel="nofollow">copy</a>] |
| 66 | } |
| 67 | if( g.okAdmin || (g.okWrTkt && zOwner && strcmp(g.zLogin,zOwner)==0) ){ |
| 68 | @ [<a href="rptedit?rn=%d(rn)" rel="nofollow">edit</a>] |
| 69 | } |
| 70 | @ [<a href="rptsql?rn=%d(rn)" rel="nofollow">sql</a>] |
| 71 | @ </li> |
| 72 | } |
| 73 | } |
| 74 | @ </ol> |
| 75 | if( g.okWrTkt ){ |
| 76 | @ <p>Create a new bug report display format:</p> |
| 77 | @ <ol> |
| 78 | @ <li value="%d(rn+1)"><a href="rptnew">New report format</a></li> |
| 79 | @ </ol> |
| 80 | } |
| 81 | style_footer(); |
| 82 | } |
| 83 | |
| 84 | /* |
| 85 | ** Remove whitespace from both ends of a string. |
| @@ -644,12 +657,16 @@ | |
| 657 | |
| 658 | /* |
| 659 | ** The state of the report generation. |
| 660 | */ |
| 661 | struct GenerateHTML { |
| 662 | int rn; /* Report number */ |
| 663 | int nCount; /* Row number */ |
| 664 | int nCol; /* Number of columns */ |
| 665 | int isMultirow; /* True if multiple table rows per query result row */ |
| 666 | int iNewRow; /* Index of first column that goes on separate row */ |
| 667 | int iBg; /* Index of column that defines background color */ |
| 668 | }; |
| 669 | |
| 670 | /* |
| 671 | ** The callback function for db_query |
| 672 | */ |
| @@ -661,106 +678,107 @@ | |
| 678 | ){ |
| 679 | struct GenerateHTML *pState = (struct GenerateHTML*)pUser; |
| 680 | int i; |
| 681 | int tn; /* Ticket number. (value of column named '#') */ |
| 682 | int rn; /* Report number */ |
| 683 | char *zBg = 0; /* Use this background color */ |
| 684 | char zPage[30]; /* Text version of the ticket number */ |
| 685 | |
| 686 | /* Get the report number |
| 687 | */ |
| 688 | rn = pState->rn; |
| 689 | |
| 690 | /* Do initialization |
| 691 | */ |
| 692 | if( pState->nCount==0 ){ |
| 693 | /* Figure out the number of columns, the column that determines background |
| 694 | ** color, and whether or not this row of data is represented by multiple |
| 695 | ** rows in the table. |
| 696 | */ |
| 697 | pState->nCol = 0; |
| 698 | pState->isMultirow = 0; |
| 699 | pState->iNewRow = -1; |
| 700 | pState->iBg = -1; |
| 701 | for(i=0; i<nArg; i++){ |
| 702 | if( azName[i][0]=='b' && strcmp(azName[i],"bgcolor")==0 ){ |
| 703 | pState->iBg = i; |
| 704 | continue; |
| 705 | } |
| 706 | if( g.okWrite && azName[i][0]=='#' ){ |
| 707 | pState->nCol++; |
| 708 | } |
| 709 | if( !pState->isMultirow ){ |
| 710 | if( azName[i][0]=='_' ){ |
| 711 | pState->isMultirow = 1; |
| 712 | pState->iNewRow = i; |
| 713 | }else{ |
| 714 | pState->nCol++; |
| 715 | } |
| 716 | } |
| 717 | } |
| 718 | |
| 719 | /* The first time this routine is called, output a table header |
| 720 | */ |
| 721 | @ <tr> |
| 722 | tn = -1; |
| 723 | for(i=0; i<nArg; i++){ |
| 724 | char *zName = azName[i]; |
| 725 | if( i==pState->iBg ) continue; |
| 726 | if( pState->iNewRow>=0 && i>=pState->iNewRow ){ |
| 727 | if( g.okWrite && tn>=0 ){ |
| 728 | @ <th> </th> |
| 729 | tn = -1; |
| 730 | } |
| 731 | if( zName[0]=='_' ) zName++; |
| 732 | @ </tr><tr><th colspan=%d(pState->nCol)>%h(zName)</th> |
| 733 | }else{ |
| 734 | if( zName[0]=='#' ){ |
| 735 | tn = i; |
| 736 | }else{ |
| 737 | @ <th>%h(zName)</th> |
| 738 | } |
| 739 | } |
| 740 | } |
| 741 | if( g.okWrite && tn>=0 ){ |
| 742 | @ <th> </th> |
| 743 | } |
| 744 | @ </tr> |
| 745 | } |
| 746 | if( azArg==0 ){ |
| 747 | @ <tr><td colspan="%d(pState->nCol)"> |
| 748 | @ <i>No records match the report criteria</i> |
| 749 | @ </td></tr> |
| 750 | return 0; |
| 751 | } |
| 752 | ++pState->nCount; |
| 753 | |
| 754 | /* Output the separator above each entry in a table which has multiple lines |
| 755 | ** per database entry. |
| 756 | */ |
| 757 | if( pState->iNewRow>=0 ){ |
| 758 | @ <tr><td colspan=%d(pState->nCol)><font size=1> </font></td></tr> |
| 759 | } |
| 760 | |
| 761 | /* Output the data for this entry from the database |
| 762 | */ |
| 763 | zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0; |
| 764 | if( zBg==0 ) zBg = "white"; |
| 765 | @ <tr bgcolor="%h(zBg)"> |
| 766 | tn = 0; |
| 767 | zPage[0] = 0; |
| 768 | for(i=0; i<nArg; i++){ |
| 769 | char *zData; |
| 770 | if( i==pState->iBg ) continue; |
| 771 | zData = azArg[i]; |
| 772 | if( zData==0 ) zData = ""; |
| 773 | if( pState->iNewRow>=0 && i>=pState->iNewRow ){ |
| 774 | if( tn>0 && g.okWrite ){ |
| 775 | @ <td valign="top"><a href="tktedit?tn=%d(tn),%d(rn)">edit</a></td> |
| 776 | tn = 0; |
| 777 | } |
| 778 | if( zData[0] ){ |
| 779 | @ </tr><tr bgcolor="%h(zBg)"><td colspan=%d(pState->nCol)> |
| 780 | @ %h(zData) |
| 781 | } |
| 782 | }else if( azName[i][0]=='#' ){ |
| 783 | tn = atoi(zData); |
| 784 | @ <td valign="top"><a href="tktview?tn=%d(tn),%d(rn)">%h(zData)</a></td> |
| 785 |
+4
-1
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -171,11 +171,14 @@ | ||
| 171 | 171 | @ html "<a href='$baseurl/dir'>Files</a>" |
| 172 | 172 | @ } |
| 173 | 173 | @ if {[hascap o]} { |
| 174 | 174 | @ html "<a href='$baseurl/leaves'>Leaves</a>" |
| 175 | 175 | @ html "<a href='$baseurl/timeline'>Timeline</a>" |
| 176 | -@ html "<a href='$baseurl/tagview'>Tags</a>" | |
| 176 | +@ # html "<a href='$baseurl/tagview'>Tags</a>" | |
| 177 | +@ } | |
| 178 | +@ if {[hascap hr]} { | |
| 179 | +@ html "<a href='$baseurl/reportlist'>Bugs</a>" | |
| 177 | 180 | @ } |
| 178 | 181 | @ if {[hascap j]} { |
| 179 | 182 | @ html "<a href='$baseurl/wiki'>Wiki</a>" |
| 180 | 183 | @ } |
| 181 | 184 | @ if {[hascap s]} { |
| 182 | 185 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -171,11 +171,14 @@ | |
| 171 | @ html "<a href='$baseurl/dir'>Files</a>" |
| 172 | @ } |
| 173 | @ if {[hascap o]} { |
| 174 | @ html "<a href='$baseurl/leaves'>Leaves</a>" |
| 175 | @ html "<a href='$baseurl/timeline'>Timeline</a>" |
| 176 | @ html "<a href='$baseurl/tagview'>Tags</a>" |
| 177 | @ } |
| 178 | @ if {[hascap j]} { |
| 179 | @ html "<a href='$baseurl/wiki'>Wiki</a>" |
| 180 | @ } |
| 181 | @ if {[hascap s]} { |
| 182 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -171,11 +171,14 @@ | |
| 171 | @ html "<a href='$baseurl/dir'>Files</a>" |
| 172 | @ } |
| 173 | @ if {[hascap o]} { |
| 174 | @ html "<a href='$baseurl/leaves'>Leaves</a>" |
| 175 | @ html "<a href='$baseurl/timeline'>Timeline</a>" |
| 176 | @ # html "<a href='$baseurl/tagview'>Tags</a>" |
| 177 | @ } |
| 178 | @ if {[hascap hr]} { |
| 179 | @ html "<a href='$baseurl/reportlist'>Bugs</a>" |
| 180 | @ } |
| 181 | @ if {[hascap j]} { |
| 182 | @ html "<a href='$baseurl/wiki'>Wiki</a>" |
| 183 | @ } |
| 184 | @ if {[hascap s]} { |
| 185 |