Fossil SCM
At /rptview page show link to /reportslist. If request's query string contains [<b>rvsmpl</b>] parameter then also show an auxiliary link to the page defined by the value of this parameter. Labels and links rendered via %s format specifier because %h and %T did not work properly. In this particular case this seems fine because the values are rendered via %href(). Code review is very welcome though.
Commit
b982c00150e828b578c62880b5573985e0832b5f6089b65ca4a7ae938d1a91c7
Parent
89b724dcfae8a6c…
2 files changed
+14
-4
+20
+14
-4
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -968,14 +968,19 @@ | ||
| 968 | 968 | } |
| 969 | 969 | |
| 970 | 970 | /* |
| 971 | 971 | ** WEBPAGE: rptview |
| 972 | 972 | ** |
| 973 | -** Generate a report. The rn query parameter is the report number | |
| 974 | -** corresponding to REPORTFMT.RN. If the tablist query parameter exists, | |
| 973 | +** Generate a report. The "rn" query parameter is the report number | |
| 974 | +** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists, | |
| 975 | 975 | ** then the output consists of lines of tab-separated fields instead of |
| 976 | -** an HTML table. | |
| 976 | +** an HTML table. If the "rvsmpl" query parameter is set to an ordinary | |
| 977 | +** unfuncy ASCII string (alphanumerics, '_' and '-') then report's | |
| 978 | +** submenu will contain an extra hyperlink that have a value-driven | |
| 979 | +** label and target. | |
| 980 | +** | |
| 981 | +** "rvsmpl" stands for Report View SubMenu's Parametric Link. | |
| 977 | 982 | */ |
| 978 | 983 | void rptview_page(void){ |
| 979 | 984 | int count = 0; |
| 980 | 985 | int rn, rc; |
| 981 | 986 | char *zSql; |
| @@ -984,10 +989,11 @@ | ||
| 984 | 989 | char *zClrKey; |
| 985 | 990 | int tabs; |
| 986 | 991 | Stmt q; |
| 987 | 992 | char *zErr1 = 0; |
| 988 | 993 | char *zErr2 = 0; |
| 994 | + const char *zQS; /* QUERY_STRING */ | |
| 989 | 995 | |
| 990 | 996 | login_check_credentials(); |
| 991 | 997 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 992 | 998 | tabs = P("tablist")!=0; |
| 993 | 999 | db_prepare(&q, |
| @@ -1032,11 +1038,15 @@ | ||
| 1032 | 1038 | if( !tabs ){ |
| 1033 | 1039 | struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 1034 | 1040 | |
| 1035 | 1041 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 1036 | 1042 | style_set_current_feature("report"); |
| 1037 | - style_submenu_element("Raw", "rptview?tablist=1&rn=%d&%h", rn, PD("QUERY_STRING","") ); | |
| 1043 | + zQS = PD("QUERY_STRING",""); | |
| 1044 | + style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS); | |
| 1045 | + style_submenu_element("Reports","%R/reportlist?&%s",zQS); | |
| 1046 | + style_submenu_parametric("rvsmpl"); | |
| 1047 | + | |
| 1038 | 1048 | if( g.perm.Admin |
| 1039 | 1049 | || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ |
| 1040 | 1050 | style_submenu_element("Edit", "rptedit?rn=%d", rn); |
| 1041 | 1051 | } |
| 1042 | 1052 | if( g.perm.TktFmt ){ |
| 1043 | 1053 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -968,14 +968,19 @@ | |
| 968 | } |
| 969 | |
| 970 | /* |
| 971 | ** WEBPAGE: rptview |
| 972 | ** |
| 973 | ** Generate a report. The rn query parameter is the report number |
| 974 | ** corresponding to REPORTFMT.RN. If the tablist query parameter exists, |
| 975 | ** then the output consists of lines of tab-separated fields instead of |
| 976 | ** an HTML table. |
| 977 | */ |
| 978 | void rptview_page(void){ |
| 979 | int count = 0; |
| 980 | int rn, rc; |
| 981 | char *zSql; |
| @@ -984,10 +989,11 @@ | |
| 984 | char *zClrKey; |
| 985 | int tabs; |
| 986 | Stmt q; |
| 987 | char *zErr1 = 0; |
| 988 | char *zErr2 = 0; |
| 989 | |
| 990 | login_check_credentials(); |
| 991 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 992 | tabs = P("tablist")!=0; |
| 993 | db_prepare(&q, |
| @@ -1032,11 +1038,15 @@ | |
| 1032 | if( !tabs ){ |
| 1033 | struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 1034 | |
| 1035 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 1036 | style_set_current_feature("report"); |
| 1037 | style_submenu_element("Raw", "rptview?tablist=1&rn=%d&%h", rn, PD("QUERY_STRING","") ); |
| 1038 | if( g.perm.Admin |
| 1039 | || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ |
| 1040 | style_submenu_element("Edit", "rptedit?rn=%d", rn); |
| 1041 | } |
| 1042 | if( g.perm.TktFmt ){ |
| 1043 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -968,14 +968,19 @@ | |
| 968 | } |
| 969 | |
| 970 | /* |
| 971 | ** WEBPAGE: rptview |
| 972 | ** |
| 973 | ** Generate a report. The "rn" query parameter is the report number |
| 974 | ** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists, |
| 975 | ** then the output consists of lines of tab-separated fields instead of |
| 976 | ** an HTML table. If the "rvsmpl" query parameter is set to an ordinary |
| 977 | ** unfuncy ASCII string (alphanumerics, '_' and '-') then report's |
| 978 | ** submenu will contain an extra hyperlink that have a value-driven |
| 979 | ** label and target. |
| 980 | ** |
| 981 | ** "rvsmpl" stands for Report View SubMenu's Parametric Link. |
| 982 | */ |
| 983 | void rptview_page(void){ |
| 984 | int count = 0; |
| 985 | int rn, rc; |
| 986 | char *zSql; |
| @@ -984,10 +989,11 @@ | |
| 989 | char *zClrKey; |
| 990 | int tabs; |
| 991 | Stmt q; |
| 992 | char *zErr1 = 0; |
| 993 | char *zErr2 = 0; |
| 994 | const char *zQS; /* QUERY_STRING */ |
| 995 | |
| 996 | login_check_credentials(); |
| 997 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 998 | tabs = P("tablist")!=0; |
| 999 | db_prepare(&q, |
| @@ -1032,11 +1038,15 @@ | |
| 1038 | if( !tabs ){ |
| 1039 | struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 1040 | |
| 1041 | db_multi_exec("PRAGMA empty_result_callbacks=ON"); |
| 1042 | style_set_current_feature("report"); |
| 1043 | zQS = PD("QUERY_STRING",""); |
| 1044 | style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS); |
| 1045 | style_submenu_element("Reports","%R/reportlist?&%s",zQS); |
| 1046 | style_submenu_parametric("rvsmpl"); |
| 1047 | |
| 1048 | if( g.perm.Admin |
| 1049 | || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ |
| 1050 | style_submenu_element("Edit", "rptedit?rn=%d", rn); |
| 1051 | } |
| 1052 | if( g.perm.TktFmt ){ |
| 1053 |
+20
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -329,10 +329,30 @@ | ||
| 329 | 329 | aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL; |
| 330 | 330 | aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI; |
| 331 | 331 | nSubmenuCtrl++; |
| 332 | 332 | } |
| 333 | 333 | } |
| 334 | + | |
| 335 | +/* Add submenu hyperlink based on the value of arbitrary parameter | |
| 336 | + * in the request's query string. | |
| 337 | + */ | |
| 338 | +void style_submenu_parametric( | |
| 339 | + const char *zName /* Query parameter name */ | |
| 340 | +){ | |
| 341 | + const char *zV; /* value of the corresponding parameter */ | |
| 342 | + if( zName == 0 || zName[0] == 0 || !fossil_islower(zName[0]) || | |
| 343 | + !fossil_no_strange_characters(zName)) { | |
| 344 | + return; | |
| 345 | + } | |
| 346 | + zV = PD(zName,""); | |
| 347 | + if( zV[0] && fossil_no_strange_characters( zV )){ | |
| 348 | + assert( nSubmenu < count(aSubmenu) ); | |
| 349 | + aSubmenu[nSubmenu].zLabel = mprintf("[ %s ]",zV); /* memory leak? */ | |
| 350 | + aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,PD("QUERY_STRING","")); | |
| 351 | + nSubmenu++; | |
| 352 | + } | |
| 353 | +} | |
| 334 | 354 | |
| 335 | 355 | /* |
| 336 | 356 | ** Disable or enable the submenu |
| 337 | 357 | */ |
| 338 | 358 | void style_submenu_enable(int onOff){ |
| 339 | 359 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -329,10 +329,30 @@ | |
| 329 | aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL; |
| 330 | aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI; |
| 331 | nSubmenuCtrl++; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | /* |
| 336 | ** Disable or enable the submenu |
| 337 | */ |
| 338 | void style_submenu_enable(int onOff){ |
| 339 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -329,10 +329,30 @@ | |
| 329 | aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL; |
| 330 | aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI; |
| 331 | nSubmenuCtrl++; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | /* Add submenu hyperlink based on the value of arbitrary parameter |
| 336 | * in the request's query string. |
| 337 | */ |
| 338 | void style_submenu_parametric( |
| 339 | const char *zName /* Query parameter name */ |
| 340 | ){ |
| 341 | const char *zV; /* value of the corresponding parameter */ |
| 342 | if( zName == 0 || zName[0] == 0 || !fossil_islower(zName[0]) || |
| 343 | !fossil_no_strange_characters(zName)) { |
| 344 | return; |
| 345 | } |
| 346 | zV = PD(zName,""); |
| 347 | if( zV[0] && fossil_no_strange_characters( zV )){ |
| 348 | assert( nSubmenu < count(aSubmenu) ); |
| 349 | aSubmenu[nSubmenu].zLabel = mprintf("[ %s ]",zV); /* memory leak? */ |
| 350 | aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,PD("QUERY_STRING","")); |
| 351 | nSubmenu++; |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | /* |
| 356 | ** Disable or enable the submenu |
| 357 | */ |
| 358 | void style_submenu_enable(int onOff){ |
| 359 |