Fossil SCM

Merge the ticket-wiki branch into trunk: add the ability to associate a wiki page with a ticket, similar to how can be done for a branch or check-in.

stephan 2025-02-26 17:54 trunk merge
Commit 25f43cc634e789d8c0ae7567a02d13cc26b9cfd03db1a1510cd68f80f45f3113
+8 -7
--- src/setup.c
+++ src/setup.c
@@ -183,11 +183,11 @@
183183
184184
185185
/*
186186
** WEBPAGE: setup-logmenu
187187
**
188
-** Show a menu of available log renderings accessible to an administrator,
188
+** Show a menu of available log renderings accessible to an administrator,
189189
** together with a succinct explanation of each.
190190
**
191191
** This page is only accessible by administrators.
192192
*/
193193
void setup_logmenu_page(void){
@@ -952,11 +952,11 @@
952952
@ of project-name. This description can be edited in the second entry
953953
@ box on the <a href="./setup_config">Setup/Configuration page</a>.
954954
@
955955
@ <li><p><b>project-name</b> &rarr;
956956
@ The human-readable name for the project. The project-name can be
957
- @ modified in the first entry on the
957
+ @ modified in the first entry on the
958958
@ <a href="./setup_config">Setup/Configuration page</a>.
959959
@
960960
@ <li><p><b>peer-repo-<i>CODE</i></b> &rarr;
961961
@ <i>CODE</i> is 16-character prefix of the project-code for another
962962
@ repository that is part of the same login-group. The value is the
@@ -1428,21 +1428,22 @@
14281428
db_begin_transaction();
14291429
@ <form action="%R/setup_wiki" method="post"><div>
14301430
login_insert_csrf_secret();
14311431
@ <input type="submit" name="submit" value="Apply Changes"></p>
14321432
@ <hr>
1433
- onoff_attribute("Associate Wiki Pages With Branches, Tags, or Checkins",
1433
+ onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins",
14341434
"wiki-about", "wiki-about", 1, 0);
14351435
@ <p>
1436
- @ Associate wiki pages with branches, tags, or checkins, based on
1437
- @ the wiki page name. Wiki pages that begin with "branch/", "checkin/"
1438
- @ or "tag/" and which continue with the name of an existing branch, check-in
1439
- @ or tag are treated specially when this feature is enabled.
1436
+ @ Associate wiki pages with branches, tags, tickets, or checkins, based on
1437
+ @ the wiki page name. Wiki pages that begin with "branch/", "checkin/",
1438
+ @ "tag/" or "ticket" and which continue with the name of an existing branch,
1439
+ @ check-in, tag or ticket are treated specially when this feature is enabled.
14401440
@ <ul>
14411441
@ <li> <b>branch/</b><i>branch-name</i>
14421442
@ <li> <b>checkin/</b><i>full-check-in-hash</i>
14431443
@ <li> <b>tag/</b><i>tag-name</i>
1444
+ @ <li> <b>ticket/</b><i>full-ticket-hash</i>
14441445
@ </ul>
14451446
@ (Property: "wiki-about")</p>
14461447
@ <hr>
14471448
entry_attribute("Allow Unsafe HTML In Markdown", 6,
14481449
"safe-html", "safe-html", "", 0);
14491450
--- src/setup.c
+++ src/setup.c
@@ -183,11 +183,11 @@
183
184
185 /*
186 ** WEBPAGE: setup-logmenu
187 **
188 ** Show a menu of available log renderings accessible to an administrator,
189 ** together with a succinct explanation of each.
190 **
191 ** This page is only accessible by administrators.
192 */
193 void setup_logmenu_page(void){
@@ -952,11 +952,11 @@
952 @ of project-name. This description can be edited in the second entry
953 @ box on the <a href="./setup_config">Setup/Configuration page</a>.
954 @
955 @ <li><p><b>project-name</b> &rarr;
956 @ The human-readable name for the project. The project-name can be
957 @ modified in the first entry on the
958 @ <a href="./setup_config">Setup/Configuration page</a>.
959 @
960 @ <li><p><b>peer-repo-<i>CODE</i></b> &rarr;
961 @ <i>CODE</i> is 16-character prefix of the project-code for another
962 @ repository that is part of the same login-group. The value is the
@@ -1428,21 +1428,22 @@
1428 db_begin_transaction();
1429 @ <form action="%R/setup_wiki" method="post"><div>
1430 login_insert_csrf_secret();
1431 @ <input type="submit" name="submit" value="Apply Changes"></p>
1432 @ <hr>
1433 onoff_attribute("Associate Wiki Pages With Branches, Tags, or Checkins",
1434 "wiki-about", "wiki-about", 1, 0);
1435 @ <p>
1436 @ Associate wiki pages with branches, tags, or checkins, based on
1437 @ the wiki page name. Wiki pages that begin with "branch/", "checkin/"
1438 @ or "tag/" and which continue with the name of an existing branch, check-in
1439 @ or tag are treated specially when this feature is enabled.
1440 @ <ul>
1441 @ <li> <b>branch/</b><i>branch-name</i>
1442 @ <li> <b>checkin/</b><i>full-check-in-hash</i>
1443 @ <li> <b>tag/</b><i>tag-name</i>
 
1444 @ </ul>
1445 @ (Property: "wiki-about")</p>
1446 @ <hr>
1447 entry_attribute("Allow Unsafe HTML In Markdown", 6,
1448 "safe-html", "safe-html", "", 0);
1449
--- src/setup.c
+++ src/setup.c
@@ -183,11 +183,11 @@
183
184
185 /*
186 ** WEBPAGE: setup-logmenu
187 **
188 ** Show a menu of available log renderings accessible to an administrator,
189 ** together with a succinct explanation of each.
190 **
191 ** This page is only accessible by administrators.
192 */
193 void setup_logmenu_page(void){
@@ -952,11 +952,11 @@
952 @ of project-name. This description can be edited in the second entry
953 @ box on the <a href="./setup_config">Setup/Configuration page</a>.
954 @
955 @ <li><p><b>project-name</b> &rarr;
956 @ The human-readable name for the project. The project-name can be
957 @ modified in the first entry on the
958 @ <a href="./setup_config">Setup/Configuration page</a>.
959 @
960 @ <li><p><b>peer-repo-<i>CODE</i></b> &rarr;
961 @ <i>CODE</i> is 16-character prefix of the project-code for another
962 @ repository that is part of the same login-group. The value is the
@@ -1428,21 +1428,22 @@
1428 db_begin_transaction();
1429 @ <form action="%R/setup_wiki" method="post"><div>
1430 login_insert_csrf_secret();
1431 @ <input type="submit" name="submit" value="Apply Changes"></p>
1432 @ <hr>
1433 onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins",
1434 "wiki-about", "wiki-about", 1, 0);
1435 @ <p>
1436 @ Associate wiki pages with branches, tags, tickets, or checkins, based on
1437 @ the wiki page name. Wiki pages that begin with "branch/", "checkin/",
1438 @ "tag/" or "ticket" and which continue with the name of an existing branch,
1439 @ check-in, tag or ticket are treated specially when this feature is enabled.
1440 @ <ul>
1441 @ <li> <b>branch/</b><i>branch-name</i>
1442 @ <li> <b>checkin/</b><i>full-check-in-hash</i>
1443 @ <li> <b>tag/</b><i>tag-name</i>
1444 @ <li> <b>ticket/</b><i>full-ticket-hash</i>
1445 @ </ul>
1446 @ (Property: "wiki-about")</p>
1447 @ <hr>
1448 entry_attribute("Allow Unsafe HTML In Markdown", 6,
1449 "safe-html", "safe-html", "", 0);
1450
+8 -7
--- src/setup.c
+++ src/setup.c
@@ -183,11 +183,11 @@
183183
184184
185185
/*
186186
** WEBPAGE: setup-logmenu
187187
**
188
-** Show a menu of available log renderings accessible to an administrator,
188
+** Show a menu of available log renderings accessible to an administrator,
189189
** together with a succinct explanation of each.
190190
**
191191
** This page is only accessible by administrators.
192192
*/
193193
void setup_logmenu_page(void){
@@ -952,11 +952,11 @@
952952
@ of project-name. This description can be edited in the second entry
953953
@ box on the <a href="./setup_config">Setup/Configuration page</a>.
954954
@
955955
@ <li><p><b>project-name</b> &rarr;
956956
@ The human-readable name for the project. The project-name can be
957
- @ modified in the first entry on the
957
+ @ modified in the first entry on the
958958
@ <a href="./setup_config">Setup/Configuration page</a>.
959959
@
960960
@ <li><p><b>peer-repo-<i>CODE</i></b> &rarr;
961961
@ <i>CODE</i> is 16-character prefix of the project-code for another
962962
@ repository that is part of the same login-group. The value is the
@@ -1428,21 +1428,22 @@
14281428
db_begin_transaction();
14291429
@ <form action="%R/setup_wiki" method="post"><div>
14301430
login_insert_csrf_secret();
14311431
@ <input type="submit" name="submit" value="Apply Changes"></p>
14321432
@ <hr>
1433
- onoff_attribute("Associate Wiki Pages With Branches, Tags, or Checkins",
1433
+ onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins",
14341434
"wiki-about", "wiki-about", 1, 0);
14351435
@ <p>
1436
- @ Associate wiki pages with branches, tags, or checkins, based on
1437
- @ the wiki page name. Wiki pages that begin with "branch/", "checkin/"
1438
- @ or "tag/" and which continue with the name of an existing branch, check-in
1439
- @ or tag are treated specially when this feature is enabled.
1436
+ @ Associate wiki pages with branches, tags, tickets, or checkins, based on
1437
+ @ the wiki page name. Wiki pages that begin with "branch/", "checkin/",
1438
+ @ "tag/" or "ticket" and which continue with the name of an existing branch,
1439
+ @ check-in, tag or ticket are treated specially when this feature is enabled.
14401440
@ <ul>
14411441
@ <li> <b>branch/</b><i>branch-name</i>
14421442
@ <li> <b>checkin/</b><i>full-check-in-hash</i>
14431443
@ <li> <b>tag/</b><i>tag-name</i>
1444
+ @ <li> <b>ticket/</b><i>full-ticket-hash</i>
14441445
@ </ul>
14451446
@ (Property: "wiki-about")</p>
14461447
@ <hr>
14471448
entry_attribute("Allow Unsafe HTML In Markdown", 6,
14481449
"safe-html", "safe-html", "", 0);
14491450
--- src/setup.c
+++ src/setup.c
@@ -183,11 +183,11 @@
183
184
185 /*
186 ** WEBPAGE: setup-logmenu
187 **
188 ** Show a menu of available log renderings accessible to an administrator,
189 ** together with a succinct explanation of each.
190 **
191 ** This page is only accessible by administrators.
192 */
193 void setup_logmenu_page(void){
@@ -952,11 +952,11 @@
952 @ of project-name. This description can be edited in the second entry
953 @ box on the <a href="./setup_config">Setup/Configuration page</a>.
954 @
955 @ <li><p><b>project-name</b> &rarr;
956 @ The human-readable name for the project. The project-name can be
957 @ modified in the first entry on the
958 @ <a href="./setup_config">Setup/Configuration page</a>.
959 @
960 @ <li><p><b>peer-repo-<i>CODE</i></b> &rarr;
961 @ <i>CODE</i> is 16-character prefix of the project-code for another
962 @ repository that is part of the same login-group. The value is the
@@ -1428,21 +1428,22 @@
1428 db_begin_transaction();
1429 @ <form action="%R/setup_wiki" method="post"><div>
1430 login_insert_csrf_secret();
1431 @ <input type="submit" name="submit" value="Apply Changes"></p>
1432 @ <hr>
1433 onoff_attribute("Associate Wiki Pages With Branches, Tags, or Checkins",
1434 "wiki-about", "wiki-about", 1, 0);
1435 @ <p>
1436 @ Associate wiki pages with branches, tags, or checkins, based on
1437 @ the wiki page name. Wiki pages that begin with "branch/", "checkin/"
1438 @ or "tag/" and which continue with the name of an existing branch, check-in
1439 @ or tag are treated specially when this feature is enabled.
1440 @ <ul>
1441 @ <li> <b>branch/</b><i>branch-name</i>
1442 @ <li> <b>checkin/</b><i>full-check-in-hash</i>
1443 @ <li> <b>tag/</b><i>tag-name</i>
 
1444 @ </ul>
1445 @ (Property: "wiki-about")</p>
1446 @ <hr>
1447 entry_attribute("Allow Unsafe HTML In Markdown", 6,
1448 "safe-html", "safe-html", "", 0);
1449
--- src/setup.c
+++ src/setup.c
@@ -183,11 +183,11 @@
183
184
185 /*
186 ** WEBPAGE: setup-logmenu
187 **
188 ** Show a menu of available log renderings accessible to an administrator,
189 ** together with a succinct explanation of each.
190 **
191 ** This page is only accessible by administrators.
192 */
193 void setup_logmenu_page(void){
@@ -952,11 +952,11 @@
952 @ of project-name. This description can be edited in the second entry
953 @ box on the <a href="./setup_config">Setup/Configuration page</a>.
954 @
955 @ <li><p><b>project-name</b> &rarr;
956 @ The human-readable name for the project. The project-name can be
957 @ modified in the first entry on the
958 @ <a href="./setup_config">Setup/Configuration page</a>.
959 @
960 @ <li><p><b>peer-repo-<i>CODE</i></b> &rarr;
961 @ <i>CODE</i> is 16-character prefix of the project-code for another
962 @ repository that is part of the same login-group. The value is the
@@ -1428,21 +1428,22 @@
1428 db_begin_transaction();
1429 @ <form action="%R/setup_wiki" method="post"><div>
1430 login_insert_csrf_secret();
1431 @ <input type="submit" name="submit" value="Apply Changes"></p>
1432 @ <hr>
1433 onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins",
1434 "wiki-about", "wiki-about", 1, 0);
1435 @ <p>
1436 @ Associate wiki pages with branches, tags, tickets, or checkins, based on
1437 @ the wiki page name. Wiki pages that begin with "branch/", "checkin/",
1438 @ "tag/" or "ticket" and which continue with the name of an existing branch,
1439 @ check-in, tag or ticket are treated specially when this feature is enabled.
1440 @ <ul>
1441 @ <li> <b>branch/</b><i>branch-name</i>
1442 @ <li> <b>checkin/</b><i>full-check-in-hash</i>
1443 @ <li> <b>tag/</b><i>tag-name</i>
1444 @ <li> <b>ticket/</b><i>full-ticket-hash</i>
1445 @ </ul>
1446 @ (Property: "wiki-about")</p>
1447 @ <hr>
1448 entry_attribute("Allow Unsafe HTML In Markdown", 6,
1449 "safe-html", "safe-html", "", 0);
1450
--- src/th_main.c
+++ src/th_main.c
@@ -696,10 +696,31 @@
696696
wiki_convert(&src, 0, flags);
697697
blob_reset(&src);
698698
}
699699
return TH_OK;
700700
}
701
+
702
+/*
703
+** TH1 command: wiki_assoc STRING STRING
704
+**
705
+** Render an associated wiki page. The first string is the namespace
706
+** (e.g. "checkin", "branch", "ticket"). The second is the ID of the
707
+** associated object. See wiki_render_associated().
708
+*/
709
+static int wikiAssocCmd(
710
+ Th_Interp *interp,
711
+ void *p,
712
+ int argc,
713
+ const char **argv,
714
+ int *argl
715
+){
716
+ if( argc!=3 ){
717
+ return Th_WrongNumArgs(interp, "wiki_assoc STRING STRING");
718
+ }
719
+ wiki_render_associated((char*)argv[1], (char*)argv[2], WIKIASSOC_FULL_TITLE);
720
+ return TH_OK;
721
+}
701722
702723
/*
703724
** TH1 command: htmlize STRING
704725
**
705726
** Escape all characters of STRING which have special meaning in HTML.
@@ -2374,10 +2395,11 @@
23742395
{"unversioned", unversionedCmd, 0},
23752396
{"utime", utimeCmd, 0},
23762397
{"verifyCsrf", verifyCsrfCmd, 0},
23772398
{"verifyLogin", verifyLoginCmd, 0},
23782399
{"wiki", wikiCmd, (void*)&aFlags[0]},
2400
+ {"wiki_assoc", wikiAssocCmd, 0},
23792401
{0, 0, 0}
23802402
};
23812403
if( g.thTrace ){
23822404
Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags);
23832405
}
23842406
--- src/th_main.c
+++ src/th_main.c
@@ -696,10 +696,31 @@
696 wiki_convert(&src, 0, flags);
697 blob_reset(&src);
698 }
699 return TH_OK;
700 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
701
702 /*
703 ** TH1 command: htmlize STRING
704 **
705 ** Escape all characters of STRING which have special meaning in HTML.
@@ -2374,10 +2395,11 @@
2374 {"unversioned", unversionedCmd, 0},
2375 {"utime", utimeCmd, 0},
2376 {"verifyCsrf", verifyCsrfCmd, 0},
2377 {"verifyLogin", verifyLoginCmd, 0},
2378 {"wiki", wikiCmd, (void*)&aFlags[0]},
 
2379 {0, 0, 0}
2380 };
2381 if( g.thTrace ){
2382 Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags);
2383 }
2384
--- src/th_main.c
+++ src/th_main.c
@@ -696,10 +696,31 @@
696 wiki_convert(&src, 0, flags);
697 blob_reset(&src);
698 }
699 return TH_OK;
700 }
701
702 /*
703 ** TH1 command: wiki_assoc STRING STRING
704 **
705 ** Render an associated wiki page. The first string is the namespace
706 ** (e.g. "checkin", "branch", "ticket"). The second is the ID of the
707 ** associated object. See wiki_render_associated().
708 */
709 static int wikiAssocCmd(
710 Th_Interp *interp,
711 void *p,
712 int argc,
713 const char **argv,
714 int *argl
715 ){
716 if( argc!=3 ){
717 return Th_WrongNumArgs(interp, "wiki_assoc STRING STRING");
718 }
719 wiki_render_associated((char*)argv[1], (char*)argv[2], WIKIASSOC_FULL_TITLE);
720 return TH_OK;
721 }
722
723 /*
724 ** TH1 command: htmlize STRING
725 **
726 ** Escape all characters of STRING which have special meaning in HTML.
@@ -2374,10 +2395,11 @@
2395 {"unversioned", unversionedCmd, 0},
2396 {"utime", utimeCmd, 0},
2397 {"verifyCsrf", verifyCsrfCmd, 0},
2398 {"verifyLogin", verifyLoginCmd, 0},
2399 {"wiki", wikiCmd, (void*)&aFlags[0]},
2400 {"wiki_assoc", wikiAssocCmd, 0},
2401 {0, 0, 0}
2402 };
2403 if( g.thTrace ){
2404 Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags);
2405 }
2406
--- src/th_main.c
+++ src/th_main.c
@@ -696,10 +696,31 @@
696696
wiki_convert(&src, 0, flags);
697697
blob_reset(&src);
698698
}
699699
return TH_OK;
700700
}
701
+
702
+/*
703
+** TH1 command: wiki_assoc STRING STRING
704
+**
705
+** Render an associated wiki page. The first string is the namespace
706
+** (e.g. "checkin", "branch", "ticket"). The second is the ID of the
707
+** associated object. See wiki_render_associated().
708
+*/
709
+static int wikiAssocCmd(
710
+ Th_Interp *interp,
711
+ void *p,
712
+ int argc,
713
+ const char **argv,
714
+ int *argl
715
+){
716
+ if( argc!=3 ){
717
+ return Th_WrongNumArgs(interp, "wiki_assoc STRING STRING");
718
+ }
719
+ wiki_render_associated((char*)argv[1], (char*)argv[2], WIKIASSOC_FULL_TITLE);
720
+ return TH_OK;
721
+}
701722
702723
/*
703724
** TH1 command: htmlize STRING
704725
**
705726
** Escape all characters of STRING which have special meaning in HTML.
@@ -2374,10 +2395,11 @@
23742395
{"unversioned", unversionedCmd, 0},
23752396
{"utime", utimeCmd, 0},
23762397
{"verifyCsrf", verifyCsrfCmd, 0},
23772398
{"verifyLogin", verifyLoginCmd, 0},
23782399
{"wiki", wikiCmd, (void*)&aFlags[0]},
2400
+ {"wiki_assoc", wikiAssocCmd, 0},
23792401
{0, 0, 0}
23802402
};
23812403
if( g.thTrace ){
23822404
Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags);
23832405
}
23842406
--- src/th_main.c
+++ src/th_main.c
@@ -696,10 +696,31 @@
696 wiki_convert(&src, 0, flags);
697 blob_reset(&src);
698 }
699 return TH_OK;
700 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
701
702 /*
703 ** TH1 command: htmlize STRING
704 **
705 ** Escape all characters of STRING which have special meaning in HTML.
@@ -2374,10 +2395,11 @@
2374 {"unversioned", unversionedCmd, 0},
2375 {"utime", utimeCmd, 0},
2376 {"verifyCsrf", verifyCsrfCmd, 0},
2377 {"verifyLogin", verifyLoginCmd, 0},
2378 {"wiki", wikiCmd, (void*)&aFlags[0]},
 
2379 {0, 0, 0}
2380 };
2381 if( g.thTrace ){
2382 Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags);
2383 }
2384
--- src/th_main.c
+++ src/th_main.c
@@ -696,10 +696,31 @@
696 wiki_convert(&src, 0, flags);
697 blob_reset(&src);
698 }
699 return TH_OK;
700 }
701
702 /*
703 ** TH1 command: wiki_assoc STRING STRING
704 **
705 ** Render an associated wiki page. The first string is the namespace
706 ** (e.g. "checkin", "branch", "ticket"). The second is the ID of the
707 ** associated object. See wiki_render_associated().
708 */
709 static int wikiAssocCmd(
710 Th_Interp *interp,
711 void *p,
712 int argc,
713 const char **argv,
714 int *argl
715 ){
716 if( argc!=3 ){
717 return Th_WrongNumArgs(interp, "wiki_assoc STRING STRING");
718 }
719 wiki_render_associated((char*)argv[1], (char*)argv[2], WIKIASSOC_FULL_TITLE);
720 return TH_OK;
721 }
722
723 /*
724 ** TH1 command: htmlize STRING
725 **
726 ** Escape all characters of STRING which have special meaning in HTML.
@@ -2374,10 +2395,11 @@
2395 {"unversioned", unversionedCmd, 0},
2396 {"utime", utimeCmd, 0},
2397 {"verifyCsrf", verifyCsrfCmd, 0},
2398 {"verifyLogin", verifyLoginCmd, 0},
2399 {"wiki", wikiCmd, (void*)&aFlags[0]},
2400 {"wiki_assoc", wikiAssocCmd, 0},
2401 {0, 0, 0}
2402 };
2403 if( g.thTrace ){
2404 Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags);
2405 }
2406
+6 -3
--- src/tkt.c
+++ src/tkt.c
@@ -765,10 +765,16 @@
765765
}
766766
}
767767
if( !showTimeline && g.perm.Hyperlink ){
768768
style_submenu_element("Timeline", "%R/info/%T", zUuid);
769769
}
770
+ zFullName = db_text(0,
771
+ "SELECT tkt_uuid FROM ticket"
772
+ " WHERE tkt_uuid GLOB '%q*'", zUuid);
773
+ if( g.perm.WrWiki && g.perm.WrTkt ){
774
+ style_submenu_element("Edit Description", "%R/wikiedit?name=ticket/%T", zFullName);
775
+ }
770776
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
771777
ticket_init();
772778
initializeVariablesFromCGI();
773779
getAllTicketFields();
774780
initializeVariablesFromDb();
@@ -777,13 +783,10 @@
777783
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1);
778784
safe_html_context(DOCSRC_TICKET);
779785
Th_Render(zScript);
780786
if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
781787
782
- zFullName = db_text(0,
783
- "SELECT tkt_uuid FROM ticket"
784
- " WHERE tkt_uuid GLOB '%q*'", zUuid);
785788
if( zFullName ){
786789
attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
787790
}
788791
789792
style_finish_page();
790793
--- src/tkt.c
+++ src/tkt.c
@@ -765,10 +765,16 @@
765 }
766 }
767 if( !showTimeline && g.perm.Hyperlink ){
768 style_submenu_element("Timeline", "%R/info/%T", zUuid);
769 }
 
 
 
 
 
 
770 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
771 ticket_init();
772 initializeVariablesFromCGI();
773 getAllTicketFields();
774 initializeVariablesFromDb();
@@ -777,13 +783,10 @@
777 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1);
778 safe_html_context(DOCSRC_TICKET);
779 Th_Render(zScript);
780 if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
781
782 zFullName = db_text(0,
783 "SELECT tkt_uuid FROM ticket"
784 " WHERE tkt_uuid GLOB '%q*'", zUuid);
785 if( zFullName ){
786 attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
787 }
788
789 style_finish_page();
790
--- src/tkt.c
+++ src/tkt.c
@@ -765,10 +765,16 @@
765 }
766 }
767 if( !showTimeline && g.perm.Hyperlink ){
768 style_submenu_element("Timeline", "%R/info/%T", zUuid);
769 }
770 zFullName = db_text(0,
771 "SELECT tkt_uuid FROM ticket"
772 " WHERE tkt_uuid GLOB '%q*'", zUuid);
773 if( g.perm.WrWiki && g.perm.WrTkt ){
774 style_submenu_element("Edit Description", "%R/wikiedit?name=ticket/%T", zFullName);
775 }
776 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
777 ticket_init();
778 initializeVariablesFromCGI();
779 getAllTicketFields();
780 initializeVariablesFromDb();
@@ -777,13 +783,10 @@
783 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1);
784 safe_html_context(DOCSRC_TICKET);
785 Th_Render(zScript);
786 if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
787
 
 
 
788 if( zFullName ){
789 attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
790 }
791
792 style_finish_page();
793
+6 -3
--- src/tkt.c
+++ src/tkt.c
@@ -765,10 +765,16 @@
765765
}
766766
}
767767
if( !showTimeline && g.perm.Hyperlink ){
768768
style_submenu_element("Timeline", "%R/info/%T", zUuid);
769769
}
770
+ zFullName = db_text(0,
771
+ "SELECT tkt_uuid FROM ticket"
772
+ " WHERE tkt_uuid GLOB '%q*'", zUuid);
773
+ if( g.perm.WrWiki && g.perm.WrTkt ){
774
+ style_submenu_element("Edit Description", "%R/wikiedit?name=ticket/%T", zFullName);
775
+ }
770776
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
771777
ticket_init();
772778
initializeVariablesFromCGI();
773779
getAllTicketFields();
774780
initializeVariablesFromDb();
@@ -777,13 +783,10 @@
777783
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1);
778784
safe_html_context(DOCSRC_TICKET);
779785
Th_Render(zScript);
780786
if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
781787
782
- zFullName = db_text(0,
783
- "SELECT tkt_uuid FROM ticket"
784
- " WHERE tkt_uuid GLOB '%q*'", zUuid);
785788
if( zFullName ){
786789
attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
787790
}
788791
789792
style_finish_page();
790793
--- src/tkt.c
+++ src/tkt.c
@@ -765,10 +765,16 @@
765 }
766 }
767 if( !showTimeline && g.perm.Hyperlink ){
768 style_submenu_element("Timeline", "%R/info/%T", zUuid);
769 }
 
 
 
 
 
 
770 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
771 ticket_init();
772 initializeVariablesFromCGI();
773 getAllTicketFields();
774 initializeVariablesFromDb();
@@ -777,13 +783,10 @@
777 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1);
778 safe_html_context(DOCSRC_TICKET);
779 Th_Render(zScript);
780 if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
781
782 zFullName = db_text(0,
783 "SELECT tkt_uuid FROM ticket"
784 " WHERE tkt_uuid GLOB '%q*'", zUuid);
785 if( zFullName ){
786 attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
787 }
788
789 style_finish_page();
790
--- src/tkt.c
+++ src/tkt.c
@@ -765,10 +765,16 @@
765 }
766 }
767 if( !showTimeline && g.perm.Hyperlink ){
768 style_submenu_element("Timeline", "%R/info/%T", zUuid);
769 }
770 zFullName = db_text(0,
771 "SELECT tkt_uuid FROM ticket"
772 " WHERE tkt_uuid GLOB '%q*'", zUuid);
773 if( g.perm.WrWiki && g.perm.WrTkt ){
774 style_submenu_element("Edit Description", "%R/wikiedit?name=ticket/%T", zFullName);
775 }
776 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1);
777 ticket_init();
778 initializeVariablesFromCGI();
779 getAllTicketFields();
780 initializeVariablesFromDb();
@@ -777,13 +783,10 @@
783 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1);
784 safe_html_context(DOCSRC_TICKET);
785 Th_Render(zScript);
786 if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
787
 
 
 
788 if( zFullName ){
789 attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
790 }
791
792 style_finish_page();
793
+7 -1
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -505,11 +505,17 @@
505505
@ </tr>
506506
@ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td>
507507
@ <td colspan="3" valign="top" class="tktDspValue">
508508
@ $<foundin>
509509
@ </td></tr>
510
+@ </table>
511
+@
512
+@ <th1>
513
+@ wiki_assoc "ticket" $tkt_uuid
514
+@ </th1>
510515
@
516
+@ <table cellpadding="5" style="min-width:100%">
511517
@ <th1>
512518
@ if {[info exists comment]} {
513519
@ if {[string length $comment]>10} {
514520
@ html {
515521
@ <tr><td class="tktDspLabel">Description:</td></tr>
@@ -531,11 +537,11 @@
531537
@ FROM ticketchng
532538
@ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
533539
@ if {$seenRow} {
534540
@ html "<hr>\n"
535541
@ } else {
536
-@ html "<tr><td class='tktDspLabel'>User Comments:</td></tr>\n"
542
+@ html "<tr><td class='tktDspLabel' style='text-align:left'>User Comments:</td></tr>\n"
537543
@ html "<tr><td colspan='5' class='tktDspValue'>\n"
538544
@ set seenRow 1
539545
@ }
540546
@ html "<span class='tktDspCommenter'>"
541547
@ html "[htmlize $xlogin]"
542548
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -505,11 +505,17 @@
505 @ </tr>
506 @ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td>
507 @ <td colspan="3" valign="top" class="tktDspValue">
508 @ $<foundin>
509 @ </td></tr>
 
 
 
 
 
510 @
 
511 @ <th1>
512 @ if {[info exists comment]} {
513 @ if {[string length $comment]>10} {
514 @ html {
515 @ <tr><td class="tktDspLabel">Description:</td></tr>
@@ -531,11 +537,11 @@
531 @ FROM ticketchng
532 @ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
533 @ if {$seenRow} {
534 @ html "<hr>\n"
535 @ } else {
536 @ html "<tr><td class='tktDspLabel'>User Comments:</td></tr>\n"
537 @ html "<tr><td colspan='5' class='tktDspValue'>\n"
538 @ set seenRow 1
539 @ }
540 @ html "<span class='tktDspCommenter'>"
541 @ html "[htmlize $xlogin]"
542
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -505,11 +505,17 @@
505 @ </tr>
506 @ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td>
507 @ <td colspan="3" valign="top" class="tktDspValue">
508 @ $<foundin>
509 @ </td></tr>
510 @ </table>
511 @
512 @ <th1>
513 @ wiki_assoc "ticket" $tkt_uuid
514 @ </th1>
515 @
516 @ <table cellpadding="5" style="min-width:100%">
517 @ <th1>
518 @ if {[info exists comment]} {
519 @ if {[string length $comment]>10} {
520 @ html {
521 @ <tr><td class="tktDspLabel">Description:</td></tr>
@@ -531,11 +537,11 @@
537 @ FROM ticketchng
538 @ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
539 @ if {$seenRow} {
540 @ html "<hr>\n"
541 @ } else {
542 @ html "<tr><td class='tktDspLabel' style='text-align:left'>User Comments:</td></tr>\n"
543 @ html "<tr><td colspan='5' class='tktDspValue'>\n"
544 @ set seenRow 1
545 @ }
546 @ html "<span class='tktDspCommenter'>"
547 @ html "[htmlize $xlogin]"
548
+39 -4
--- src/wiki.c
+++ src/wiki.c
@@ -410,10 +410,11 @@
410410
# define WIKITYPE_UNKNOWN (-1)
411411
# define WIKITYPE_NORMAL 0
412412
# define WIKITYPE_BRANCH 1
413413
# define WIKITYPE_CHECKIN 2
414414
# define WIKITYPE_TAG 3
415
+# define WIKITYPE_TICKET 4
415416
#endif
416417
417418
/*
418419
** Figure out what type of wiki page we are dealing with.
419420
*/
@@ -429,10 +430,13 @@
429430
if( sqlite3_strglob("branch/*", zPageName)==0 ){
430431
return WIKITYPE_BRANCH;
431432
}else
432433
if( sqlite3_strglob("tag/*", zPageName)==0 ){
433434
return WIKITYPE_TAG;
435
+ }else
436
+ if( sqlite3_strglob("ticket/*", zPageName)==0 ){
437
+ return WIKITYPE_TICKET;
434438
}
435439
return WIKITYPE_NORMAL;
436440
}
437441
438442
/*
@@ -442,10 +446,11 @@
442446
const char * wiki_page_type_name(const char *zPageName){
443447
switch(wiki_page_type(zPageName)){
444448
case WIKITYPE_CHECKIN: return "checkin";
445449
case WIKITYPE_BRANCH: return "branch";
446450
case WIKITYPE_TAG: return "tag";
451
+ case WIKITYPE_TICKET: return "ticket";
447452
case WIKITYPE_NORMAL:
448453
default: return "normal";
449454
}
450455
}
451456
@@ -501,10 +506,20 @@
501506
style_header("Notes About Tag %h", zPageName);
502507
style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
503508
}
504509
break;
505510
}
511
+ case WIKITYPE_TICKET: {
512
+ zPageName += 7;
513
+ if( zExtra[0]==0 && !P("p") ){
514
+ cgi_redirectf("%R/tktview/%s",zPageName);
515
+ }else{
516
+ style_header("Notes About Ticket %h", zPageName);
517
+ style_submenu_element("Ticket","%R/tktview/%s",zPageName);
518
+ }
519
+ break;
520
+ }
506521
}
507522
return eType;
508523
}
509524
510525
/*
@@ -516,15 +531,19 @@
516531
*/
517532
static int wiki_special_permission(const char *zPageName){
518533
if( strncmp(zPageName,"branch/",7)!=0
519534
&& strncmp(zPageName,"checkin/",8)!=0
520535
&& strncmp(zPageName,"tag/",4)!=0
536
+ && strncmp(zPageName,"ticket/",7)!=0
521537
){
522538
return 1;
523539
}
524540
if( db_get_boolean("wiki-about",1)==0 ){
525541
return 1;
542
+ }
543
+ if( strncmp(zPageName,"ticket/",7)==0 ){
544
+ return g.perm.WrTkt;
526545
}
527546
return g.perm.Write;
528547
}
529548
530549
/*
@@ -1999,11 +2018,13 @@
19992018
int wcnt = db_column_int(&q, 4);
20002019
char *zWDisplayName;
20012020
20022021
if( !showCkBr &&
20032022
(sqlite3_strglob("checkin/*", zWName)==0 ||
2004
- sqlite3_strglob("branch/*", zWName)==0) ){
2023
+ sqlite3_strglob("branch/*", zWName)==0 ||
2024
+ sqlite3_strglob("tag/*", zWName)==0 ||
2025
+ sqlite3_strglob("ticket/*", zWName)==0) ){
20052026
continue;
20062027
}
20072028
if( sqlite3_strglob("checkin/*", zWName)==0 ){
20082029
zWDisplayName = mprintf("%.25s...", zWName);
20092030
}else{
@@ -2551,17 +2572,30 @@
25512572
}
25522573
25532574
/*
25542575
** Add an "Wiki" button in a submenu that links to the read-wiki page.
25552576
*/
2556
-static void wiki_submenu_to_edit_wiki(
2577
+static void wiki_submenu_to_read_wiki(
25572578
const char *zPrefix, /* "branch", "tag", or "checkin" */
25582579
const char *zName, /* Name of the object */
25592580
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
25602581
){
25612582
if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
2562
- style_submenu_element("Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
2583
+ style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
2584
+ }
2585
+}
2586
+
2587
+/*
2588
+** Add an "Edit Wiki" button in a submenu that links to the edit-wiki page.
2589
+*/
2590
+static void wiki_submenu_to_edit_wiki(
2591
+ const char *zPrefix, /* "branch", "tag", or "checkin" */
2592
+ const char *zName, /* Name of the object */
2593
+ unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2594
+){
2595
+ if( g.perm.WrWiki && (mFlags & WIKIASSOC_MENU_WRITE)!=0 ){
2596
+ style_submenu_element("Edit Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
25632597
}
25642598
}
25652599
25662600
/*
25672601
** Check to see if there exists a wiki page with a name zPrefix/zName.
@@ -2569,11 +2603,11 @@
25692603
** return true.
25702604
**
25712605
** If there is no such wiki page, return false.
25722606
*/
25732607
int wiki_render_associated(
2574
- const char *zPrefix, /* "branch", "tag", or "checkin" */
2608
+ const char *zPrefix, /* "branch", "tag", "ticket", or "checkin" */
25752609
const char *zName, /* Name of the object */
25762610
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
25772611
){
25782612
int rid;
25792613
Manifest *pWiki;
@@ -2601,10 +2635,11 @@
26012635
if( blob_size(&title) ){
26022636
@ <div class="section accordion">%h(blob_str(&title))</div>
26032637
}else{
26042638
wiki_section_label(zPrefix, zName, mFlags);
26052639
}
2640
+ wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
26062641
wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
26072642
@ <div class="accordion_panel">
26082643
safe_html_context(DOCSRC_WIKI);
26092644
safe_html(&tail);
26102645
convert_href_and_output(&tail);
26112646
--- src/wiki.c
+++ src/wiki.c
@@ -410,10 +410,11 @@
410 # define WIKITYPE_UNKNOWN (-1)
411 # define WIKITYPE_NORMAL 0
412 # define WIKITYPE_BRANCH 1
413 # define WIKITYPE_CHECKIN 2
414 # define WIKITYPE_TAG 3
 
415 #endif
416
417 /*
418 ** Figure out what type of wiki page we are dealing with.
419 */
@@ -429,10 +430,13 @@
429 if( sqlite3_strglob("branch/*", zPageName)==0 ){
430 return WIKITYPE_BRANCH;
431 }else
432 if( sqlite3_strglob("tag/*", zPageName)==0 ){
433 return WIKITYPE_TAG;
 
 
 
434 }
435 return WIKITYPE_NORMAL;
436 }
437
438 /*
@@ -442,10 +446,11 @@
442 const char * wiki_page_type_name(const char *zPageName){
443 switch(wiki_page_type(zPageName)){
444 case WIKITYPE_CHECKIN: return "checkin";
445 case WIKITYPE_BRANCH: return "branch";
446 case WIKITYPE_TAG: return "tag";
 
447 case WIKITYPE_NORMAL:
448 default: return "normal";
449 }
450 }
451
@@ -501,10 +506,20 @@
501 style_header("Notes About Tag %h", zPageName);
502 style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
503 }
504 break;
505 }
 
 
 
 
 
 
 
 
 
 
506 }
507 return eType;
508 }
509
510 /*
@@ -516,15 +531,19 @@
516 */
517 static int wiki_special_permission(const char *zPageName){
518 if( strncmp(zPageName,"branch/",7)!=0
519 && strncmp(zPageName,"checkin/",8)!=0
520 && strncmp(zPageName,"tag/",4)!=0
 
521 ){
522 return 1;
523 }
524 if( db_get_boolean("wiki-about",1)==0 ){
525 return 1;
 
 
 
526 }
527 return g.perm.Write;
528 }
529
530 /*
@@ -1999,11 +2018,13 @@
1999 int wcnt = db_column_int(&q, 4);
2000 char *zWDisplayName;
2001
2002 if( !showCkBr &&
2003 (sqlite3_strglob("checkin/*", zWName)==0 ||
2004 sqlite3_strglob("branch/*", zWName)==0) ){
 
 
2005 continue;
2006 }
2007 if( sqlite3_strglob("checkin/*", zWName)==0 ){
2008 zWDisplayName = mprintf("%.25s...", zWName);
2009 }else{
@@ -2551,17 +2572,30 @@
2551 }
2552
2553 /*
2554 ** Add an "Wiki" button in a submenu that links to the read-wiki page.
2555 */
2556 static void wiki_submenu_to_edit_wiki(
2557 const char *zPrefix, /* "branch", "tag", or "checkin" */
2558 const char *zName, /* Name of the object */
2559 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2560 ){
2561 if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
2562 style_submenu_element("Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
 
 
 
 
 
 
 
 
 
 
 
 
 
2563 }
2564 }
2565
2566 /*
2567 ** Check to see if there exists a wiki page with a name zPrefix/zName.
@@ -2569,11 +2603,11 @@
2569 ** return true.
2570 **
2571 ** If there is no such wiki page, return false.
2572 */
2573 int wiki_render_associated(
2574 const char *zPrefix, /* "branch", "tag", or "checkin" */
2575 const char *zName, /* Name of the object */
2576 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2577 ){
2578 int rid;
2579 Manifest *pWiki;
@@ -2601,10 +2635,11 @@
2601 if( blob_size(&title) ){
2602 @ <div class="section accordion">%h(blob_str(&title))</div>
2603 }else{
2604 wiki_section_label(zPrefix, zName, mFlags);
2605 }
 
2606 wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
2607 @ <div class="accordion_panel">
2608 safe_html_context(DOCSRC_WIKI);
2609 safe_html(&tail);
2610 convert_href_and_output(&tail);
2611
--- src/wiki.c
+++ src/wiki.c
@@ -410,10 +410,11 @@
410 # define WIKITYPE_UNKNOWN (-1)
411 # define WIKITYPE_NORMAL 0
412 # define WIKITYPE_BRANCH 1
413 # define WIKITYPE_CHECKIN 2
414 # define WIKITYPE_TAG 3
415 # define WIKITYPE_TICKET 4
416 #endif
417
418 /*
419 ** Figure out what type of wiki page we are dealing with.
420 */
@@ -429,10 +430,13 @@
430 if( sqlite3_strglob("branch/*", zPageName)==0 ){
431 return WIKITYPE_BRANCH;
432 }else
433 if( sqlite3_strglob("tag/*", zPageName)==0 ){
434 return WIKITYPE_TAG;
435 }else
436 if( sqlite3_strglob("ticket/*", zPageName)==0 ){
437 return WIKITYPE_TICKET;
438 }
439 return WIKITYPE_NORMAL;
440 }
441
442 /*
@@ -442,10 +446,11 @@
446 const char * wiki_page_type_name(const char *zPageName){
447 switch(wiki_page_type(zPageName)){
448 case WIKITYPE_CHECKIN: return "checkin";
449 case WIKITYPE_BRANCH: return "branch";
450 case WIKITYPE_TAG: return "tag";
451 case WIKITYPE_TICKET: return "ticket";
452 case WIKITYPE_NORMAL:
453 default: return "normal";
454 }
455 }
456
@@ -501,10 +506,20 @@
506 style_header("Notes About Tag %h", zPageName);
507 style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
508 }
509 break;
510 }
511 case WIKITYPE_TICKET: {
512 zPageName += 7;
513 if( zExtra[0]==0 && !P("p") ){
514 cgi_redirectf("%R/tktview/%s",zPageName);
515 }else{
516 style_header("Notes About Ticket %h", zPageName);
517 style_submenu_element("Ticket","%R/tktview/%s",zPageName);
518 }
519 break;
520 }
521 }
522 return eType;
523 }
524
525 /*
@@ -516,15 +531,19 @@
531 */
532 static int wiki_special_permission(const char *zPageName){
533 if( strncmp(zPageName,"branch/",7)!=0
534 && strncmp(zPageName,"checkin/",8)!=0
535 && strncmp(zPageName,"tag/",4)!=0
536 && strncmp(zPageName,"ticket/",7)!=0
537 ){
538 return 1;
539 }
540 if( db_get_boolean("wiki-about",1)==0 ){
541 return 1;
542 }
543 if( strncmp(zPageName,"ticket/",7)==0 ){
544 return g.perm.WrTkt;
545 }
546 return g.perm.Write;
547 }
548
549 /*
@@ -1999,11 +2018,13 @@
2018 int wcnt = db_column_int(&q, 4);
2019 char *zWDisplayName;
2020
2021 if( !showCkBr &&
2022 (sqlite3_strglob("checkin/*", zWName)==0 ||
2023 sqlite3_strglob("branch/*", zWName)==0 ||
2024 sqlite3_strglob("tag/*", zWName)==0 ||
2025 sqlite3_strglob("ticket/*", zWName)==0) ){
2026 continue;
2027 }
2028 if( sqlite3_strglob("checkin/*", zWName)==0 ){
2029 zWDisplayName = mprintf("%.25s...", zWName);
2030 }else{
@@ -2551,17 +2572,30 @@
2572 }
2573
2574 /*
2575 ** Add an "Wiki" button in a submenu that links to the read-wiki page.
2576 */
2577 static void wiki_submenu_to_read_wiki(
2578 const char *zPrefix, /* "branch", "tag", or "checkin" */
2579 const char *zName, /* Name of the object */
2580 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2581 ){
2582 if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
2583 style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
2584 }
2585 }
2586
2587 /*
2588 ** Add an "Edit Wiki" button in a submenu that links to the edit-wiki page.
2589 */
2590 static void wiki_submenu_to_edit_wiki(
2591 const char *zPrefix, /* "branch", "tag", or "checkin" */
2592 const char *zName, /* Name of the object */
2593 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2594 ){
2595 if( g.perm.WrWiki && (mFlags & WIKIASSOC_MENU_WRITE)!=0 ){
2596 style_submenu_element("Edit Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
2597 }
2598 }
2599
2600 /*
2601 ** Check to see if there exists a wiki page with a name zPrefix/zName.
@@ -2569,11 +2603,11 @@
2603 ** return true.
2604 **
2605 ** If there is no such wiki page, return false.
2606 */
2607 int wiki_render_associated(
2608 const char *zPrefix, /* "branch", "tag", "ticket", or "checkin" */
2609 const char *zName, /* Name of the object */
2610 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2611 ){
2612 int rid;
2613 Manifest *pWiki;
@@ -2601,10 +2635,11 @@
2635 if( blob_size(&title) ){
2636 @ <div class="section accordion">%h(blob_str(&title))</div>
2637 }else{
2638 wiki_section_label(zPrefix, zName, mFlags);
2639 }
2640 wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
2641 wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
2642 @ <div class="accordion_panel">
2643 safe_html_context(DOCSRC_WIKI);
2644 safe_html(&tail);
2645 convert_href_and_output(&tail);
2646
+39 -4
--- src/wiki.c
+++ src/wiki.c
@@ -410,10 +410,11 @@
410410
# define WIKITYPE_UNKNOWN (-1)
411411
# define WIKITYPE_NORMAL 0
412412
# define WIKITYPE_BRANCH 1
413413
# define WIKITYPE_CHECKIN 2
414414
# define WIKITYPE_TAG 3
415
+# define WIKITYPE_TICKET 4
415416
#endif
416417
417418
/*
418419
** Figure out what type of wiki page we are dealing with.
419420
*/
@@ -429,10 +430,13 @@
429430
if( sqlite3_strglob("branch/*", zPageName)==0 ){
430431
return WIKITYPE_BRANCH;
431432
}else
432433
if( sqlite3_strglob("tag/*", zPageName)==0 ){
433434
return WIKITYPE_TAG;
435
+ }else
436
+ if( sqlite3_strglob("ticket/*", zPageName)==0 ){
437
+ return WIKITYPE_TICKET;
434438
}
435439
return WIKITYPE_NORMAL;
436440
}
437441
438442
/*
@@ -442,10 +446,11 @@
442446
const char * wiki_page_type_name(const char *zPageName){
443447
switch(wiki_page_type(zPageName)){
444448
case WIKITYPE_CHECKIN: return "checkin";
445449
case WIKITYPE_BRANCH: return "branch";
446450
case WIKITYPE_TAG: return "tag";
451
+ case WIKITYPE_TICKET: return "ticket";
447452
case WIKITYPE_NORMAL:
448453
default: return "normal";
449454
}
450455
}
451456
@@ -501,10 +506,20 @@
501506
style_header("Notes About Tag %h", zPageName);
502507
style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
503508
}
504509
break;
505510
}
511
+ case WIKITYPE_TICKET: {
512
+ zPageName += 7;
513
+ if( zExtra[0]==0 && !P("p") ){
514
+ cgi_redirectf("%R/tktview/%s",zPageName);
515
+ }else{
516
+ style_header("Notes About Ticket %h", zPageName);
517
+ style_submenu_element("Ticket","%R/tktview/%s",zPageName);
518
+ }
519
+ break;
520
+ }
506521
}
507522
return eType;
508523
}
509524
510525
/*
@@ -516,15 +531,19 @@
516531
*/
517532
static int wiki_special_permission(const char *zPageName){
518533
if( strncmp(zPageName,"branch/",7)!=0
519534
&& strncmp(zPageName,"checkin/",8)!=0
520535
&& strncmp(zPageName,"tag/",4)!=0
536
+ && strncmp(zPageName,"ticket/",7)!=0
521537
){
522538
return 1;
523539
}
524540
if( db_get_boolean("wiki-about",1)==0 ){
525541
return 1;
542
+ }
543
+ if( strncmp(zPageName,"ticket/",7)==0 ){
544
+ return g.perm.WrTkt;
526545
}
527546
return g.perm.Write;
528547
}
529548
530549
/*
@@ -1999,11 +2018,13 @@
19992018
int wcnt = db_column_int(&q, 4);
20002019
char *zWDisplayName;
20012020
20022021
if( !showCkBr &&
20032022
(sqlite3_strglob("checkin/*", zWName)==0 ||
2004
- sqlite3_strglob("branch/*", zWName)==0) ){
2023
+ sqlite3_strglob("branch/*", zWName)==0 ||
2024
+ sqlite3_strglob("tag/*", zWName)==0 ||
2025
+ sqlite3_strglob("ticket/*", zWName)==0) ){
20052026
continue;
20062027
}
20072028
if( sqlite3_strglob("checkin/*", zWName)==0 ){
20082029
zWDisplayName = mprintf("%.25s...", zWName);
20092030
}else{
@@ -2551,17 +2572,30 @@
25512572
}
25522573
25532574
/*
25542575
** Add an "Wiki" button in a submenu that links to the read-wiki page.
25552576
*/
2556
-static void wiki_submenu_to_edit_wiki(
2577
+static void wiki_submenu_to_read_wiki(
25572578
const char *zPrefix, /* "branch", "tag", or "checkin" */
25582579
const char *zName, /* Name of the object */
25592580
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
25602581
){
25612582
if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
2562
- style_submenu_element("Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
2583
+ style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
2584
+ }
2585
+}
2586
+
2587
+/*
2588
+** Add an "Edit Wiki" button in a submenu that links to the edit-wiki page.
2589
+*/
2590
+static void wiki_submenu_to_edit_wiki(
2591
+ const char *zPrefix, /* "branch", "tag", or "checkin" */
2592
+ const char *zName, /* Name of the object */
2593
+ unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2594
+){
2595
+ if( g.perm.WrWiki && (mFlags & WIKIASSOC_MENU_WRITE)!=0 ){
2596
+ style_submenu_element("Edit Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
25632597
}
25642598
}
25652599
25662600
/*
25672601
** Check to see if there exists a wiki page with a name zPrefix/zName.
@@ -2569,11 +2603,11 @@
25692603
** return true.
25702604
**
25712605
** If there is no such wiki page, return false.
25722606
*/
25732607
int wiki_render_associated(
2574
- const char *zPrefix, /* "branch", "tag", or "checkin" */
2608
+ const char *zPrefix, /* "branch", "tag", "ticket", or "checkin" */
25752609
const char *zName, /* Name of the object */
25762610
unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
25772611
){
25782612
int rid;
25792613
Manifest *pWiki;
@@ -2601,10 +2635,11 @@
26012635
if( blob_size(&title) ){
26022636
@ <div class="section accordion">%h(blob_str(&title))</div>
26032637
}else{
26042638
wiki_section_label(zPrefix, zName, mFlags);
26052639
}
2640
+ wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
26062641
wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
26072642
@ <div class="accordion_panel">
26082643
safe_html_context(DOCSRC_WIKI);
26092644
safe_html(&tail);
26102645
convert_href_and_output(&tail);
26112646
--- src/wiki.c
+++ src/wiki.c
@@ -410,10 +410,11 @@
410 # define WIKITYPE_UNKNOWN (-1)
411 # define WIKITYPE_NORMAL 0
412 # define WIKITYPE_BRANCH 1
413 # define WIKITYPE_CHECKIN 2
414 # define WIKITYPE_TAG 3
 
415 #endif
416
417 /*
418 ** Figure out what type of wiki page we are dealing with.
419 */
@@ -429,10 +430,13 @@
429 if( sqlite3_strglob("branch/*", zPageName)==0 ){
430 return WIKITYPE_BRANCH;
431 }else
432 if( sqlite3_strglob("tag/*", zPageName)==0 ){
433 return WIKITYPE_TAG;
 
 
 
434 }
435 return WIKITYPE_NORMAL;
436 }
437
438 /*
@@ -442,10 +446,11 @@
442 const char * wiki_page_type_name(const char *zPageName){
443 switch(wiki_page_type(zPageName)){
444 case WIKITYPE_CHECKIN: return "checkin";
445 case WIKITYPE_BRANCH: return "branch";
446 case WIKITYPE_TAG: return "tag";
 
447 case WIKITYPE_NORMAL:
448 default: return "normal";
449 }
450 }
451
@@ -501,10 +506,20 @@
501 style_header("Notes About Tag %h", zPageName);
502 style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
503 }
504 break;
505 }
 
 
 
 
 
 
 
 
 
 
506 }
507 return eType;
508 }
509
510 /*
@@ -516,15 +531,19 @@
516 */
517 static int wiki_special_permission(const char *zPageName){
518 if( strncmp(zPageName,"branch/",7)!=0
519 && strncmp(zPageName,"checkin/",8)!=0
520 && strncmp(zPageName,"tag/",4)!=0
 
521 ){
522 return 1;
523 }
524 if( db_get_boolean("wiki-about",1)==0 ){
525 return 1;
 
 
 
526 }
527 return g.perm.Write;
528 }
529
530 /*
@@ -1999,11 +2018,13 @@
1999 int wcnt = db_column_int(&q, 4);
2000 char *zWDisplayName;
2001
2002 if( !showCkBr &&
2003 (sqlite3_strglob("checkin/*", zWName)==0 ||
2004 sqlite3_strglob("branch/*", zWName)==0) ){
 
 
2005 continue;
2006 }
2007 if( sqlite3_strglob("checkin/*", zWName)==0 ){
2008 zWDisplayName = mprintf("%.25s...", zWName);
2009 }else{
@@ -2551,17 +2572,30 @@
2551 }
2552
2553 /*
2554 ** Add an "Wiki" button in a submenu that links to the read-wiki page.
2555 */
2556 static void wiki_submenu_to_edit_wiki(
2557 const char *zPrefix, /* "branch", "tag", or "checkin" */
2558 const char *zName, /* Name of the object */
2559 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2560 ){
2561 if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
2562 style_submenu_element("Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
 
 
 
 
 
 
 
 
 
 
 
 
 
2563 }
2564 }
2565
2566 /*
2567 ** Check to see if there exists a wiki page with a name zPrefix/zName.
@@ -2569,11 +2603,11 @@
2569 ** return true.
2570 **
2571 ** If there is no such wiki page, return false.
2572 */
2573 int wiki_render_associated(
2574 const char *zPrefix, /* "branch", "tag", or "checkin" */
2575 const char *zName, /* Name of the object */
2576 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2577 ){
2578 int rid;
2579 Manifest *pWiki;
@@ -2601,10 +2635,11 @@
2601 if( blob_size(&title) ){
2602 @ <div class="section accordion">%h(blob_str(&title))</div>
2603 }else{
2604 wiki_section_label(zPrefix, zName, mFlags);
2605 }
 
2606 wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
2607 @ <div class="accordion_panel">
2608 safe_html_context(DOCSRC_WIKI);
2609 safe_html(&tail);
2610 convert_href_and_output(&tail);
2611
--- src/wiki.c
+++ src/wiki.c
@@ -410,10 +410,11 @@
410 # define WIKITYPE_UNKNOWN (-1)
411 # define WIKITYPE_NORMAL 0
412 # define WIKITYPE_BRANCH 1
413 # define WIKITYPE_CHECKIN 2
414 # define WIKITYPE_TAG 3
415 # define WIKITYPE_TICKET 4
416 #endif
417
418 /*
419 ** Figure out what type of wiki page we are dealing with.
420 */
@@ -429,10 +430,13 @@
430 if( sqlite3_strglob("branch/*", zPageName)==0 ){
431 return WIKITYPE_BRANCH;
432 }else
433 if( sqlite3_strglob("tag/*", zPageName)==0 ){
434 return WIKITYPE_TAG;
435 }else
436 if( sqlite3_strglob("ticket/*", zPageName)==0 ){
437 return WIKITYPE_TICKET;
438 }
439 return WIKITYPE_NORMAL;
440 }
441
442 /*
@@ -442,10 +446,11 @@
446 const char * wiki_page_type_name(const char *zPageName){
447 switch(wiki_page_type(zPageName)){
448 case WIKITYPE_CHECKIN: return "checkin";
449 case WIKITYPE_BRANCH: return "branch";
450 case WIKITYPE_TAG: return "tag";
451 case WIKITYPE_TICKET: return "ticket";
452 case WIKITYPE_NORMAL:
453 default: return "normal";
454 }
455 }
456
@@ -501,10 +506,20 @@
506 style_header("Notes About Tag %h", zPageName);
507 style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName);
508 }
509 break;
510 }
511 case WIKITYPE_TICKET: {
512 zPageName += 7;
513 if( zExtra[0]==0 && !P("p") ){
514 cgi_redirectf("%R/tktview/%s",zPageName);
515 }else{
516 style_header("Notes About Ticket %h", zPageName);
517 style_submenu_element("Ticket","%R/tktview/%s",zPageName);
518 }
519 break;
520 }
521 }
522 return eType;
523 }
524
525 /*
@@ -516,15 +531,19 @@
531 */
532 static int wiki_special_permission(const char *zPageName){
533 if( strncmp(zPageName,"branch/",7)!=0
534 && strncmp(zPageName,"checkin/",8)!=0
535 && strncmp(zPageName,"tag/",4)!=0
536 && strncmp(zPageName,"ticket/",7)!=0
537 ){
538 return 1;
539 }
540 if( db_get_boolean("wiki-about",1)==0 ){
541 return 1;
542 }
543 if( strncmp(zPageName,"ticket/",7)==0 ){
544 return g.perm.WrTkt;
545 }
546 return g.perm.Write;
547 }
548
549 /*
@@ -1999,11 +2018,13 @@
2018 int wcnt = db_column_int(&q, 4);
2019 char *zWDisplayName;
2020
2021 if( !showCkBr &&
2022 (sqlite3_strglob("checkin/*", zWName)==0 ||
2023 sqlite3_strglob("branch/*", zWName)==0 ||
2024 sqlite3_strglob("tag/*", zWName)==0 ||
2025 sqlite3_strglob("ticket/*", zWName)==0) ){
2026 continue;
2027 }
2028 if( sqlite3_strglob("checkin/*", zWName)==0 ){
2029 zWDisplayName = mprintf("%.25s...", zWName);
2030 }else{
@@ -2551,17 +2572,30 @@
2572 }
2573
2574 /*
2575 ** Add an "Wiki" button in a submenu that links to the read-wiki page.
2576 */
2577 static void wiki_submenu_to_read_wiki(
2578 const char *zPrefix, /* "branch", "tag", or "checkin" */
2579 const char *zName, /* Name of the object */
2580 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2581 ){
2582 if( g.perm.RdWiki && (mFlags & WIKIASSOC_MENU_READ)!=0 ){
2583 style_submenu_element("Wiki", "%R/wiki?name=%s/%t", zPrefix, zName);
2584 }
2585 }
2586
2587 /*
2588 ** Add an "Edit Wiki" button in a submenu that links to the edit-wiki page.
2589 */
2590 static void wiki_submenu_to_edit_wiki(
2591 const char *zPrefix, /* "branch", "tag", or "checkin" */
2592 const char *zName, /* Name of the object */
2593 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2594 ){
2595 if( g.perm.WrWiki && (mFlags & WIKIASSOC_MENU_WRITE)!=0 ){
2596 style_submenu_element("Edit Wiki", "%R/wikiedit?name=%s/%t", zPrefix, zName);
2597 }
2598 }
2599
2600 /*
2601 ** Check to see if there exists a wiki page with a name zPrefix/zName.
@@ -2569,11 +2603,11 @@
2603 ** return true.
2604 **
2605 ** If there is no such wiki page, return false.
2606 */
2607 int wiki_render_associated(
2608 const char *zPrefix, /* "branch", "tag", "ticket", or "checkin" */
2609 const char *zName, /* Name of the object */
2610 unsigned int mFlags /* Zero or more WIKIASSOC_* flags */
2611 ){
2612 int rid;
2613 Manifest *pWiki;
@@ -2601,10 +2635,11 @@
2635 if( blob_size(&title) ){
2636 @ <div class="section accordion">%h(blob_str(&title))</div>
2637 }else{
2638 wiki_section_label(zPrefix, zName, mFlags);
2639 }
2640 wiki_submenu_to_read_wiki(zPrefix, zName, mFlags);
2641 wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
2642 @ <div class="accordion_panel">
2643 safe_html_context(DOCSRC_WIKI);
2644 safe_html(&tail);
2645 convert_href_and_output(&tail);
2646
+12 -2
--- www/th1.md
+++ www/th1.md
@@ -227,10 +227,11 @@
227227
* [unversioned list](#unversioned_list)
228228
* [utime](#utime)
229229
* [verifyCsrf](#verifyCsrf)
230230
* [verifyLogin](#verifyLogin)
231231
* [wiki](#wiki)
232
+ * [wiki_assoc](#wiki_assoc)
232233
233234
Each of the commands above is documented by a block comment above their
234235
implementation in the th\_main.c or th\_tcl.c source files.
235236
236237
All commands starting with "tcl", with the exception of "tclReady",
@@ -271,11 +272,11 @@
271272
<a id="bireqjs"></a>TH1 builtin_request_js Command
272273
--------------------------------------------------
273274
274275
* builtin_request_js NAME
275276
276
-NAME must be the name of one of the
277
+NAME must be the name of one of the
277278
[built-in javascript source files](/dir?ci=trunk&type=flat&name=src&re=js$).
278279
This command causes that javascript file to be appended to the delivered
279280
document.
280281
281282
@@ -284,11 +285,11 @@
284285
-----------------------------------------------------
285286
286287
* capexpr CAPABILITY-EXPR
287288
288289
The capability expression is a list. Each term of the list is a
289
-cluster of [capability letters](./caps/ref.html).
290
+cluster of [capability letters](./caps/ref.html).
290291
The overall expression is true if any
291292
one term is true. A single term is true if all letters within that
292293
term are true. Or, if the term begins with "!", then the term is true
293294
if none of the terms are true. Or, if the term begins with "@" then
294295
the term is true if all of the capability letters in that term are
@@ -861,10 +862,19 @@
861862
-----------------------------------
862863
863864
* wiki STRING
864865
865866
Renders STRING as wiki content.
867
+
868
+<a id="wiki_assoc"></a>TH1 wiki_assoc Command
869
+-----------------------------------
870
+
871
+ * wiki_assoc STRING STRING
872
+
873
+Renders the special wiki. The first string refers to the namespace
874
+(checkin, branch, tag, ticket). The second string specifies the
875
+concrete wiki page to be rendered.
866876
867877
Tcl Integration Commands
868878
------------------------
869879
870880
When the Tcl integration subsystem is enabled, several commands are added
871881
--- www/th1.md
+++ www/th1.md
@@ -227,10 +227,11 @@
227 * [unversioned list](#unversioned_list)
228 * [utime](#utime)
229 * [verifyCsrf](#verifyCsrf)
230 * [verifyLogin](#verifyLogin)
231 * [wiki](#wiki)
 
232
233 Each of the commands above is documented by a block comment above their
234 implementation in the th\_main.c or th\_tcl.c source files.
235
236 All commands starting with "tcl", with the exception of "tclReady",
@@ -271,11 +272,11 @@
271 <a id="bireqjs"></a>TH1 builtin_request_js Command
272 --------------------------------------------------
273
274 * builtin_request_js NAME
275
276 NAME must be the name of one of the
277 [built-in javascript source files](/dir?ci=trunk&type=flat&name=src&re=js$).
278 This command causes that javascript file to be appended to the delivered
279 document.
280
281
@@ -284,11 +285,11 @@
284 -----------------------------------------------------
285
286 * capexpr CAPABILITY-EXPR
287
288 The capability expression is a list. Each term of the list is a
289 cluster of [capability letters](./caps/ref.html).
290 The overall expression is true if any
291 one term is true. A single term is true if all letters within that
292 term are true. Or, if the term begins with "!", then the term is true
293 if none of the terms are true. Or, if the term begins with "@" then
294 the term is true if all of the capability letters in that term are
@@ -861,10 +862,19 @@
861 -----------------------------------
862
863 * wiki STRING
864
865 Renders STRING as wiki content.
 
 
 
 
 
 
 
 
 
866
867 Tcl Integration Commands
868 ------------------------
869
870 When the Tcl integration subsystem is enabled, several commands are added
871
--- www/th1.md
+++ www/th1.md
@@ -227,10 +227,11 @@
227 * [unversioned list](#unversioned_list)
228 * [utime](#utime)
229 * [verifyCsrf](#verifyCsrf)
230 * [verifyLogin](#verifyLogin)
231 * [wiki](#wiki)
232 * [wiki_assoc](#wiki_assoc)
233
234 Each of the commands above is documented by a block comment above their
235 implementation in the th\_main.c or th\_tcl.c source files.
236
237 All commands starting with "tcl", with the exception of "tclReady",
@@ -271,11 +272,11 @@
272 <a id="bireqjs"></a>TH1 builtin_request_js Command
273 --------------------------------------------------
274
275 * builtin_request_js NAME
276
277 NAME must be the name of one of the
278 [built-in javascript source files](/dir?ci=trunk&type=flat&name=src&re=js$).
279 This command causes that javascript file to be appended to the delivered
280 document.
281
282
@@ -284,11 +285,11 @@
285 -----------------------------------------------------
286
287 * capexpr CAPABILITY-EXPR
288
289 The capability expression is a list. Each term of the list is a
290 cluster of [capability letters](./caps/ref.html).
291 The overall expression is true if any
292 one term is true. A single term is true if all letters within that
293 term are true. Or, if the term begins with "!", then the term is true
294 if none of the terms are true. Or, if the term begins with "@" then
295 the term is true if all of the capability letters in that term are
@@ -861,10 +862,19 @@
862 -----------------------------------
863
864 * wiki STRING
865
866 Renders STRING as wiki content.
867
868 <a id="wiki_assoc"></a>TH1 wiki_assoc Command
869 -----------------------------------
870
871 * wiki_assoc STRING STRING
872
873 Renders the special wiki. The first string refers to the namespace
874 (checkin, branch, tag, ticket). The second string specifies the
875 concrete wiki page to be rendered.
876
877 Tcl Integration Commands
878 ------------------------
879
880 When the Tcl integration subsystem is enabled, several commands are added
881

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button