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.
Commit
25f43cc634e789d8c0ae7567a02d13cc26b9cfd03db1a1510cd68f80f45f3113
Parent
55dd9896d7973e5…
10 files changed
+8
-7
+8
-7
+22
+22
+6
-3
+6
-3
+7
-1
+39
-4
+39
-4
+12
-2
+8
-7
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -183,11 +183,11 @@ | ||
| 183 | 183 | |
| 184 | 184 | |
| 185 | 185 | /* |
| 186 | 186 | ** WEBPAGE: setup-logmenu |
| 187 | 187 | ** |
| 188 | -** Show a menu of available log renderings accessible to an administrator, | |
| 188 | +** Show a menu of available log renderings accessible to an administrator, | |
| 189 | 189 | ** together with a succinct explanation of each. |
| 190 | 190 | ** |
| 191 | 191 | ** This page is only accessible by administrators. |
| 192 | 192 | */ |
| 193 | 193 | void setup_logmenu_page(void){ |
| @@ -952,11 +952,11 @@ | ||
| 952 | 952 | @ of project-name. This description can be edited in the second entry |
| 953 | 953 | @ box on the <a href="./setup_config">Setup/Configuration page</a>. |
| 954 | 954 | @ |
| 955 | 955 | @ <li><p><b>project-name</b> → |
| 956 | 956 | @ 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 | |
| 958 | 958 | @ <a href="./setup_config">Setup/Configuration page</a>. |
| 959 | 959 | @ |
| 960 | 960 | @ <li><p><b>peer-repo-<i>CODE</i></b> → |
| 961 | 961 | @ <i>CODE</i> is 16-character prefix of the project-code for another |
| 962 | 962 | @ repository that is part of the same login-group. The value is the |
| @@ -1428,21 +1428,22 @@ | ||
| 1428 | 1428 | db_begin_transaction(); |
| 1429 | 1429 | @ <form action="%R/setup_wiki" method="post"><div> |
| 1430 | 1430 | login_insert_csrf_secret(); |
| 1431 | 1431 | @ <input type="submit" name="submit" value="Apply Changes"></p> |
| 1432 | 1432 | @ <hr> |
| 1433 | - onoff_attribute("Associate Wiki Pages With Branches, Tags, or Checkins", | |
| 1433 | + onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins", | |
| 1434 | 1434 | "wiki-about", "wiki-about", 1, 0); |
| 1435 | 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. | |
| 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 | 1440 | @ <ul> |
| 1441 | 1441 | @ <li> <b>branch/</b><i>branch-name</i> |
| 1442 | 1442 | @ <li> <b>checkin/</b><i>full-check-in-hash</i> |
| 1443 | 1443 | @ <li> <b>tag/</b><i>tag-name</i> |
| 1444 | + @ <li> <b>ticket/</b><i>full-ticket-hash</i> | |
| 1444 | 1445 | @ </ul> |
| 1445 | 1446 | @ (Property: "wiki-about")</p> |
| 1446 | 1447 | @ <hr> |
| 1447 | 1448 | entry_attribute("Allow Unsafe HTML In Markdown", 6, |
| 1448 | 1449 | "safe-html", "safe-html", "", 0); |
| 1449 | 1450 |
| --- 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> → |
| 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> → |
| 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> → |
| 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> → |
| 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 @@ | ||
| 183 | 183 | |
| 184 | 184 | |
| 185 | 185 | /* |
| 186 | 186 | ** WEBPAGE: setup-logmenu |
| 187 | 187 | ** |
| 188 | -** Show a menu of available log renderings accessible to an administrator, | |
| 188 | +** Show a menu of available log renderings accessible to an administrator, | |
| 189 | 189 | ** together with a succinct explanation of each. |
| 190 | 190 | ** |
| 191 | 191 | ** This page is only accessible by administrators. |
| 192 | 192 | */ |
| 193 | 193 | void setup_logmenu_page(void){ |
| @@ -952,11 +952,11 @@ | ||
| 952 | 952 | @ of project-name. This description can be edited in the second entry |
| 953 | 953 | @ box on the <a href="./setup_config">Setup/Configuration page</a>. |
| 954 | 954 | @ |
| 955 | 955 | @ <li><p><b>project-name</b> → |
| 956 | 956 | @ 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 | |
| 958 | 958 | @ <a href="./setup_config">Setup/Configuration page</a>. |
| 959 | 959 | @ |
| 960 | 960 | @ <li><p><b>peer-repo-<i>CODE</i></b> → |
| 961 | 961 | @ <i>CODE</i> is 16-character prefix of the project-code for another |
| 962 | 962 | @ repository that is part of the same login-group. The value is the |
| @@ -1428,21 +1428,22 @@ | ||
| 1428 | 1428 | db_begin_transaction(); |
| 1429 | 1429 | @ <form action="%R/setup_wiki" method="post"><div> |
| 1430 | 1430 | login_insert_csrf_secret(); |
| 1431 | 1431 | @ <input type="submit" name="submit" value="Apply Changes"></p> |
| 1432 | 1432 | @ <hr> |
| 1433 | - onoff_attribute("Associate Wiki Pages With Branches, Tags, or Checkins", | |
| 1433 | + onoff_attribute("Associate Wiki Pages With Branches, Tags, Tickets, or Checkins", | |
| 1434 | 1434 | "wiki-about", "wiki-about", 1, 0); |
| 1435 | 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. | |
| 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 | 1440 | @ <ul> |
| 1441 | 1441 | @ <li> <b>branch/</b><i>branch-name</i> |
| 1442 | 1442 | @ <li> <b>checkin/</b><i>full-check-in-hash</i> |
| 1443 | 1443 | @ <li> <b>tag/</b><i>tag-name</i> |
| 1444 | + @ <li> <b>ticket/</b><i>full-ticket-hash</i> | |
| 1444 | 1445 | @ </ul> |
| 1445 | 1446 | @ (Property: "wiki-about")</p> |
| 1446 | 1447 | @ <hr> |
| 1447 | 1448 | entry_attribute("Allow Unsafe HTML In Markdown", 6, |
| 1448 | 1449 | "safe-html", "safe-html", "", 0); |
| 1449 | 1450 |
| --- 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> → |
| 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> → |
| 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> → |
| 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> → |
| 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 |
+22
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -696,10 +696,31 @@ | ||
| 696 | 696 | wiki_convert(&src, 0, flags); |
| 697 | 697 | blob_reset(&src); |
| 698 | 698 | } |
| 699 | 699 | return TH_OK; |
| 700 | 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 | +} | |
| 701 | 722 | |
| 702 | 723 | /* |
| 703 | 724 | ** TH1 command: htmlize STRING |
| 704 | 725 | ** |
| 705 | 726 | ** Escape all characters of STRING which have special meaning in HTML. |
| @@ -2374,10 +2395,11 @@ | ||
| 2374 | 2395 | {"unversioned", unversionedCmd, 0}, |
| 2375 | 2396 | {"utime", utimeCmd, 0}, |
| 2376 | 2397 | {"verifyCsrf", verifyCsrfCmd, 0}, |
| 2377 | 2398 | {"verifyLogin", verifyLoginCmd, 0}, |
| 2378 | 2399 | {"wiki", wikiCmd, (void*)&aFlags[0]}, |
| 2400 | + {"wiki_assoc", wikiAssocCmd, 0}, | |
| 2379 | 2401 | {0, 0, 0} |
| 2380 | 2402 | }; |
| 2381 | 2403 | if( g.thTrace ){ |
| 2382 | 2404 | Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags); |
| 2383 | 2405 | } |
| 2384 | 2406 |
| --- 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 |
+22
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -696,10 +696,31 @@ | ||
| 696 | 696 | wiki_convert(&src, 0, flags); |
| 697 | 697 | blob_reset(&src); |
| 698 | 698 | } |
| 699 | 699 | return TH_OK; |
| 700 | 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 | +} | |
| 701 | 722 | |
| 702 | 723 | /* |
| 703 | 724 | ** TH1 command: htmlize STRING |
| 704 | 725 | ** |
| 705 | 726 | ** Escape all characters of STRING which have special meaning in HTML. |
| @@ -2374,10 +2395,11 @@ | ||
| 2374 | 2395 | {"unversioned", unversionedCmd, 0}, |
| 2375 | 2396 | {"utime", utimeCmd, 0}, |
| 2376 | 2397 | {"verifyCsrf", verifyCsrfCmd, 0}, |
| 2377 | 2398 | {"verifyLogin", verifyLoginCmd, 0}, |
| 2378 | 2399 | {"wiki", wikiCmd, (void*)&aFlags[0]}, |
| 2400 | + {"wiki_assoc", wikiAssocCmd, 0}, | |
| 2379 | 2401 | {0, 0, 0} |
| 2380 | 2402 | }; |
| 2381 | 2403 | if( g.thTrace ){ |
| 2382 | 2404 | Th_Trace("th1-init 0x%x => 0x%x<br>\n", g.th1Flags, flags); |
| 2383 | 2405 | } |
| 2384 | 2406 |
| --- 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 @@ | ||
| 765 | 765 | } |
| 766 | 766 | } |
| 767 | 767 | if( !showTimeline && g.perm.Hyperlink ){ |
| 768 | 768 | style_submenu_element("Timeline", "%R/info/%T", zUuid); |
| 769 | 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 | + } | |
| 770 | 776 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1); |
| 771 | 777 | ticket_init(); |
| 772 | 778 | initializeVariablesFromCGI(); |
| 773 | 779 | getAllTicketFields(); |
| 774 | 780 | initializeVariablesFromDb(); |
| @@ -777,13 +783,10 @@ | ||
| 777 | 783 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1); |
| 778 | 784 | safe_html_context(DOCSRC_TICKET); |
| 779 | 785 | Th_Render(zScript); |
| 780 | 786 | if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1); |
| 781 | 787 | |
| 782 | - zFullName = db_text(0, | |
| 783 | - "SELECT tkt_uuid FROM ticket" | |
| 784 | - " WHERE tkt_uuid GLOB '%q*'", zUuid); | |
| 785 | 788 | if( zFullName ){ |
| 786 | 789 | attachment_list(zFullName, "<h2>Attachments:</h2>", 1); |
| 787 | 790 | } |
| 788 | 791 | |
| 789 | 792 | style_finish_page(); |
| 790 | 793 |
| --- 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 @@ | ||
| 765 | 765 | } |
| 766 | 766 | } |
| 767 | 767 | if( !showTimeline && g.perm.Hyperlink ){ |
| 768 | 768 | style_submenu_element("Timeline", "%R/info/%T", zUuid); |
| 769 | 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 | + } | |
| 770 | 776 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br>\n", -1); |
| 771 | 777 | ticket_init(); |
| 772 | 778 | initializeVariablesFromCGI(); |
| 773 | 779 | getAllTicketFields(); |
| 774 | 780 | initializeVariablesFromDb(); |
| @@ -777,13 +783,10 @@ | ||
| 777 | 783 | if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br>\n", -1); |
| 778 | 784 | safe_html_context(DOCSRC_TICKET); |
| 779 | 785 | Th_Render(zScript); |
| 780 | 786 | if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1); |
| 781 | 787 | |
| 782 | - zFullName = db_text(0, | |
| 783 | - "SELECT tkt_uuid FROM ticket" | |
| 784 | - " WHERE tkt_uuid GLOB '%q*'", zUuid); | |
| 785 | 788 | if( zFullName ){ |
| 786 | 789 | attachment_list(zFullName, "<h2>Attachments:</h2>", 1); |
| 787 | 790 | } |
| 788 | 791 | |
| 789 | 792 | style_finish_page(); |
| 790 | 793 |
| --- 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 @@ | ||
| 505 | 505 | @ </tr> |
| 506 | 506 | @ <tr><td class="tktDspLabel">Version Found In:</td> |
| 507 | 507 | @ <td colspan="3" valign="top" class="tktDspValue"> |
| 508 | 508 | @ $<foundin> |
| 509 | 509 | @ </td></tr> |
| 510 | +@ </table> | |
| 511 | +@ | |
| 512 | +@ <th1> | |
| 513 | +@ wiki_assoc "ticket" $tkt_uuid | |
| 514 | +@ </th1> | |
| 510 | 515 | @ |
| 516 | +@ <table cellpadding="5" style="min-width:100%"> | |
| 511 | 517 | @ <th1> |
| 512 | 518 | @ if {[info exists comment]} { |
| 513 | 519 | @ if {[string length $comment]>10} { |
| 514 | 520 | @ html { |
| 515 | 521 | @ <tr><td class="tktDspLabel">Description:</td></tr> |
| @@ -531,11 +537,11 @@ | ||
| 531 | 537 | @ FROM ticketchng |
| 532 | 538 | @ WHERE tkt_id=$tkt_id AND length(icomment)>0} { |
| 533 | 539 | @ if {$seenRow} { |
| 534 | 540 | @ html "<hr>\n" |
| 535 | 541 | @ } 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" | |
| 537 | 543 | @ html "<tr><td colspan='5' class='tktDspValue'>\n" |
| 538 | 544 | @ set seenRow 1 |
| 539 | 545 | @ } |
| 540 | 546 | @ html "<span class='tktDspCommenter'>" |
| 541 | 547 | @ html "[htmlize $xlogin]" |
| 542 | 548 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -505,11 +505,17 @@ | |
| 505 | @ </tr> |
| 506 | @ <tr><td class="tktDspLabel">Version Found 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 Found 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 @@ | ||
| 410 | 410 | # define WIKITYPE_UNKNOWN (-1) |
| 411 | 411 | # define WIKITYPE_NORMAL 0 |
| 412 | 412 | # define WIKITYPE_BRANCH 1 |
| 413 | 413 | # define WIKITYPE_CHECKIN 2 |
| 414 | 414 | # define WIKITYPE_TAG 3 |
| 415 | +# define WIKITYPE_TICKET 4 | |
| 415 | 416 | #endif |
| 416 | 417 | |
| 417 | 418 | /* |
| 418 | 419 | ** Figure out what type of wiki page we are dealing with. |
| 419 | 420 | */ |
| @@ -429,10 +430,13 @@ | ||
| 429 | 430 | if( sqlite3_strglob("branch/*", zPageName)==0 ){ |
| 430 | 431 | return WIKITYPE_BRANCH; |
| 431 | 432 | }else |
| 432 | 433 | if( sqlite3_strglob("tag/*", zPageName)==0 ){ |
| 433 | 434 | return WIKITYPE_TAG; |
| 435 | + }else | |
| 436 | + if( sqlite3_strglob("ticket/*", zPageName)==0 ){ | |
| 437 | + return WIKITYPE_TICKET; | |
| 434 | 438 | } |
| 435 | 439 | return WIKITYPE_NORMAL; |
| 436 | 440 | } |
| 437 | 441 | |
| 438 | 442 | /* |
| @@ -442,10 +446,11 @@ | ||
| 442 | 446 | const char * wiki_page_type_name(const char *zPageName){ |
| 443 | 447 | switch(wiki_page_type(zPageName)){ |
| 444 | 448 | case WIKITYPE_CHECKIN: return "checkin"; |
| 445 | 449 | case WIKITYPE_BRANCH: return "branch"; |
| 446 | 450 | case WIKITYPE_TAG: return "tag"; |
| 451 | + case WIKITYPE_TICKET: return "ticket"; | |
| 447 | 452 | case WIKITYPE_NORMAL: |
| 448 | 453 | default: return "normal"; |
| 449 | 454 | } |
| 450 | 455 | } |
| 451 | 456 | |
| @@ -501,10 +506,20 @@ | ||
| 501 | 506 | style_header("Notes About Tag %h", zPageName); |
| 502 | 507 | style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName); |
| 503 | 508 | } |
| 504 | 509 | break; |
| 505 | 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 | + } | |
| 506 | 521 | } |
| 507 | 522 | return eType; |
| 508 | 523 | } |
| 509 | 524 | |
| 510 | 525 | /* |
| @@ -516,15 +531,19 @@ | ||
| 516 | 531 | */ |
| 517 | 532 | static int wiki_special_permission(const char *zPageName){ |
| 518 | 533 | if( strncmp(zPageName,"branch/",7)!=0 |
| 519 | 534 | && strncmp(zPageName,"checkin/",8)!=0 |
| 520 | 535 | && strncmp(zPageName,"tag/",4)!=0 |
| 536 | + && strncmp(zPageName,"ticket/",7)!=0 | |
| 521 | 537 | ){ |
| 522 | 538 | return 1; |
| 523 | 539 | } |
| 524 | 540 | if( db_get_boolean("wiki-about",1)==0 ){ |
| 525 | 541 | return 1; |
| 542 | + } | |
| 543 | + if( strncmp(zPageName,"ticket/",7)==0 ){ | |
| 544 | + return g.perm.WrTkt; | |
| 526 | 545 | } |
| 527 | 546 | return g.perm.Write; |
| 528 | 547 | } |
| 529 | 548 | |
| 530 | 549 | /* |
| @@ -1999,11 +2018,13 @@ | ||
| 1999 | 2018 | int wcnt = db_column_int(&q, 4); |
| 2000 | 2019 | char *zWDisplayName; |
| 2001 | 2020 | |
| 2002 | 2021 | if( !showCkBr && |
| 2003 | 2022 | (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) ){ | |
| 2005 | 2026 | continue; |
| 2006 | 2027 | } |
| 2007 | 2028 | if( sqlite3_strglob("checkin/*", zWName)==0 ){ |
| 2008 | 2029 | zWDisplayName = mprintf("%.25s...", zWName); |
| 2009 | 2030 | }else{ |
| @@ -2551,17 +2572,30 @@ | ||
| 2551 | 2572 | } |
| 2552 | 2573 | |
| 2553 | 2574 | /* |
| 2554 | 2575 | ** Add an "Wiki" button in a submenu that links to the read-wiki page. |
| 2555 | 2576 | */ |
| 2556 | -static void wiki_submenu_to_edit_wiki( | |
| 2577 | +static void wiki_submenu_to_read_wiki( | |
| 2557 | 2578 | const char *zPrefix, /* "branch", "tag", or "checkin" */ |
| 2558 | 2579 | const char *zName, /* Name of the object */ |
| 2559 | 2580 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2560 | 2581 | ){ |
| 2561 | 2582 | 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); | |
| 2563 | 2597 | } |
| 2564 | 2598 | } |
| 2565 | 2599 | |
| 2566 | 2600 | /* |
| 2567 | 2601 | ** Check to see if there exists a wiki page with a name zPrefix/zName. |
| @@ -2569,11 +2603,11 @@ | ||
| 2569 | 2603 | ** return true. |
| 2570 | 2604 | ** |
| 2571 | 2605 | ** If there is no such wiki page, return false. |
| 2572 | 2606 | */ |
| 2573 | 2607 | int wiki_render_associated( |
| 2574 | - const char *zPrefix, /* "branch", "tag", or "checkin" */ | |
| 2608 | + const char *zPrefix, /* "branch", "tag", "ticket", or "checkin" */ | |
| 2575 | 2609 | const char *zName, /* Name of the object */ |
| 2576 | 2610 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2577 | 2611 | ){ |
| 2578 | 2612 | int rid; |
| 2579 | 2613 | Manifest *pWiki; |
| @@ -2601,10 +2635,11 @@ | ||
| 2601 | 2635 | if( blob_size(&title) ){ |
| 2602 | 2636 | @ <div class="section accordion">%h(blob_str(&title))</div> |
| 2603 | 2637 | }else{ |
| 2604 | 2638 | wiki_section_label(zPrefix, zName, mFlags); |
| 2605 | 2639 | } |
| 2640 | + wiki_submenu_to_read_wiki(zPrefix, zName, mFlags); | |
| 2606 | 2641 | wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags); |
| 2607 | 2642 | @ <div class="accordion_panel"> |
| 2608 | 2643 | safe_html_context(DOCSRC_WIKI); |
| 2609 | 2644 | safe_html(&tail); |
| 2610 | 2645 | convert_href_and_output(&tail); |
| 2611 | 2646 |
| --- 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 @@ | ||
| 410 | 410 | # define WIKITYPE_UNKNOWN (-1) |
| 411 | 411 | # define WIKITYPE_NORMAL 0 |
| 412 | 412 | # define WIKITYPE_BRANCH 1 |
| 413 | 413 | # define WIKITYPE_CHECKIN 2 |
| 414 | 414 | # define WIKITYPE_TAG 3 |
| 415 | +# define WIKITYPE_TICKET 4 | |
| 415 | 416 | #endif |
| 416 | 417 | |
| 417 | 418 | /* |
| 418 | 419 | ** Figure out what type of wiki page we are dealing with. |
| 419 | 420 | */ |
| @@ -429,10 +430,13 @@ | ||
| 429 | 430 | if( sqlite3_strglob("branch/*", zPageName)==0 ){ |
| 430 | 431 | return WIKITYPE_BRANCH; |
| 431 | 432 | }else |
| 432 | 433 | if( sqlite3_strglob("tag/*", zPageName)==0 ){ |
| 433 | 434 | return WIKITYPE_TAG; |
| 435 | + }else | |
| 436 | + if( sqlite3_strglob("ticket/*", zPageName)==0 ){ | |
| 437 | + return WIKITYPE_TICKET; | |
| 434 | 438 | } |
| 435 | 439 | return WIKITYPE_NORMAL; |
| 436 | 440 | } |
| 437 | 441 | |
| 438 | 442 | /* |
| @@ -442,10 +446,11 @@ | ||
| 442 | 446 | const char * wiki_page_type_name(const char *zPageName){ |
| 443 | 447 | switch(wiki_page_type(zPageName)){ |
| 444 | 448 | case WIKITYPE_CHECKIN: return "checkin"; |
| 445 | 449 | case WIKITYPE_BRANCH: return "branch"; |
| 446 | 450 | case WIKITYPE_TAG: return "tag"; |
| 451 | + case WIKITYPE_TICKET: return "ticket"; | |
| 447 | 452 | case WIKITYPE_NORMAL: |
| 448 | 453 | default: return "normal"; |
| 449 | 454 | } |
| 450 | 455 | } |
| 451 | 456 | |
| @@ -501,10 +506,20 @@ | ||
| 501 | 506 | style_header("Notes About Tag %h", zPageName); |
| 502 | 507 | style_submenu_element("Tag Timeline","%R/timeline?t=%t",zPageName); |
| 503 | 508 | } |
| 504 | 509 | break; |
| 505 | 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 | + } | |
| 506 | 521 | } |
| 507 | 522 | return eType; |
| 508 | 523 | } |
| 509 | 524 | |
| 510 | 525 | /* |
| @@ -516,15 +531,19 @@ | ||
| 516 | 531 | */ |
| 517 | 532 | static int wiki_special_permission(const char *zPageName){ |
| 518 | 533 | if( strncmp(zPageName,"branch/",7)!=0 |
| 519 | 534 | && strncmp(zPageName,"checkin/",8)!=0 |
| 520 | 535 | && strncmp(zPageName,"tag/",4)!=0 |
| 536 | + && strncmp(zPageName,"ticket/",7)!=0 | |
| 521 | 537 | ){ |
| 522 | 538 | return 1; |
| 523 | 539 | } |
| 524 | 540 | if( db_get_boolean("wiki-about",1)==0 ){ |
| 525 | 541 | return 1; |
| 542 | + } | |
| 543 | + if( strncmp(zPageName,"ticket/",7)==0 ){ | |
| 544 | + return g.perm.WrTkt; | |
| 526 | 545 | } |
| 527 | 546 | return g.perm.Write; |
| 528 | 547 | } |
| 529 | 548 | |
| 530 | 549 | /* |
| @@ -1999,11 +2018,13 @@ | ||
| 1999 | 2018 | int wcnt = db_column_int(&q, 4); |
| 2000 | 2019 | char *zWDisplayName; |
| 2001 | 2020 | |
| 2002 | 2021 | if( !showCkBr && |
| 2003 | 2022 | (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) ){ | |
| 2005 | 2026 | continue; |
| 2006 | 2027 | } |
| 2007 | 2028 | if( sqlite3_strglob("checkin/*", zWName)==0 ){ |
| 2008 | 2029 | zWDisplayName = mprintf("%.25s...", zWName); |
| 2009 | 2030 | }else{ |
| @@ -2551,17 +2572,30 @@ | ||
| 2551 | 2572 | } |
| 2552 | 2573 | |
| 2553 | 2574 | /* |
| 2554 | 2575 | ** Add an "Wiki" button in a submenu that links to the read-wiki page. |
| 2555 | 2576 | */ |
| 2556 | -static void wiki_submenu_to_edit_wiki( | |
| 2577 | +static void wiki_submenu_to_read_wiki( | |
| 2557 | 2578 | const char *zPrefix, /* "branch", "tag", or "checkin" */ |
| 2558 | 2579 | const char *zName, /* Name of the object */ |
| 2559 | 2580 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2560 | 2581 | ){ |
| 2561 | 2582 | 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); | |
| 2563 | 2597 | } |
| 2564 | 2598 | } |
| 2565 | 2599 | |
| 2566 | 2600 | /* |
| 2567 | 2601 | ** Check to see if there exists a wiki page with a name zPrefix/zName. |
| @@ -2569,11 +2603,11 @@ | ||
| 2569 | 2603 | ** return true. |
| 2570 | 2604 | ** |
| 2571 | 2605 | ** If there is no such wiki page, return false. |
| 2572 | 2606 | */ |
| 2573 | 2607 | int wiki_render_associated( |
| 2574 | - const char *zPrefix, /* "branch", "tag", or "checkin" */ | |
| 2608 | + const char *zPrefix, /* "branch", "tag", "ticket", or "checkin" */ | |
| 2575 | 2609 | const char *zName, /* Name of the object */ |
| 2576 | 2610 | unsigned int mFlags /* Zero or more WIKIASSOC_* flags */ |
| 2577 | 2611 | ){ |
| 2578 | 2612 | int rid; |
| 2579 | 2613 | Manifest *pWiki; |
| @@ -2601,10 +2635,11 @@ | ||
| 2601 | 2635 | if( blob_size(&title) ){ |
| 2602 | 2636 | @ <div class="section accordion">%h(blob_str(&title))</div> |
| 2603 | 2637 | }else{ |
| 2604 | 2638 | wiki_section_label(zPrefix, zName, mFlags); |
| 2605 | 2639 | } |
| 2640 | + wiki_submenu_to_read_wiki(zPrefix, zName, mFlags); | |
| 2606 | 2641 | wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags); |
| 2607 | 2642 | @ <div class="accordion_panel"> |
| 2608 | 2643 | safe_html_context(DOCSRC_WIKI); |
| 2609 | 2644 | safe_html(&tail); |
| 2610 | 2645 | convert_href_and_output(&tail); |
| 2611 | 2646 |
| --- 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 @@ | ||
| 227 | 227 | * [unversioned list](#unversioned_list) |
| 228 | 228 | * [utime](#utime) |
| 229 | 229 | * [verifyCsrf](#verifyCsrf) |
| 230 | 230 | * [verifyLogin](#verifyLogin) |
| 231 | 231 | * [wiki](#wiki) |
| 232 | + * [wiki_assoc](#wiki_assoc) | |
| 232 | 233 | |
| 233 | 234 | Each of the commands above is documented by a block comment above their |
| 234 | 235 | implementation in the th\_main.c or th\_tcl.c source files. |
| 235 | 236 | |
| 236 | 237 | All commands starting with "tcl", with the exception of "tclReady", |
| @@ -271,11 +272,11 @@ | ||
| 271 | 272 | <a id="bireqjs"></a>TH1 builtin_request_js Command |
| 272 | 273 | -------------------------------------------------- |
| 273 | 274 | |
| 274 | 275 | * builtin_request_js NAME |
| 275 | 276 | |
| 276 | -NAME must be the name of one of the | |
| 277 | +NAME must be the name of one of the | |
| 277 | 278 | [built-in javascript source files](/dir?ci=trunk&type=flat&name=src&re=js$). |
| 278 | 279 | This command causes that javascript file to be appended to the delivered |
| 279 | 280 | document. |
| 280 | 281 | |
| 281 | 282 | |
| @@ -284,11 +285,11 @@ | ||
| 284 | 285 | ----------------------------------------------------- |
| 285 | 286 | |
| 286 | 287 | * capexpr CAPABILITY-EXPR |
| 287 | 288 | |
| 288 | 289 | 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). | |
| 290 | 291 | The overall expression is true if any |
| 291 | 292 | one term is true. A single term is true if all letters within that |
| 292 | 293 | term are true. Or, if the term begins with "!", then the term is true |
| 293 | 294 | if none of the terms are true. Or, if the term begins with "@" then |
| 294 | 295 | the term is true if all of the capability letters in that term are |
| @@ -861,10 +862,19 @@ | ||
| 861 | 862 | ----------------------------------- |
| 862 | 863 | |
| 863 | 864 | * wiki STRING |
| 864 | 865 | |
| 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. | |
| 866 | 876 | |
| 867 | 877 | Tcl Integration Commands |
| 868 | 878 | ------------------------ |
| 869 | 879 | |
| 870 | 880 | When the Tcl integration subsystem is enabled, several commands are added |
| 871 | 881 |
| --- 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 |