Fossil SCM
Add a selection widget for status filtering. Now how to make the setting sticky?
Commit
4c87c5690c18cfb527535fefb1aa02d89f9fa6ad4f1dc4634a081e61bfc03e9a
Parent
52ac6bc1b2c720f…
1 file changed
+36
-4
+36
-4
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -2417,10 +2417,36 @@ | ||
| 2417 | 2417 | @ </form> |
| 2418 | 2418 | } |
| 2419 | 2419 | |
| 2420 | 2420 | style_finish_page(); |
| 2421 | 2421 | } |
| 2422 | + | |
| 2423 | +/* | |
| 2424 | +** If the forum-statuses setting is active and has 2 or more entries, | |
| 2425 | +** this adds a submenu for selecting the status filter, else it emits | |
| 2426 | +** nothing. | |
| 2427 | +*/ | |
| 2428 | +static void forum_status_submenu(void){ | |
| 2429 | + const ForumStatusList * const fss = forum_statuses(); | |
| 2430 | + static int i = 0; | |
| 2431 | + static const char **az; | |
| 2432 | + if( i==0 && fss->n>1 ){ | |
| 2433 | + unsigned j; | |
| 2434 | + az = fossil_malloc(sizeof(az[0]) * ((1 + fss->n) * 2)); | |
| 2435 | + az[i++] = "*"; | |
| 2436 | + az[i++] = "Any status"; | |
| 2437 | + for( j = 0; j < fss->n; ++j ){ | |
| 2438 | + const ForumStatus * fs = &fss->aStatus[j]; | |
| 2439 | + az[i++] = fs->zValue; | |
| 2440 | + az[i++] = fs->zLabel; | |
| 2441 | + } | |
| 2442 | + //assert( i==(1+fss->n)*2 ); | |
| 2443 | + } | |
| 2444 | + if( i ){ | |
| 2445 | + style_submenu_multichoice("status", i/2, az, 0); | |
| 2446 | + } | |
| 2447 | +} | |
| 2422 | 2448 | |
| 2423 | 2449 | /* |
| 2424 | 2450 | ** WEBPAGE: forummain |
| 2425 | 2451 | ** WEBPAGE: forum |
| 2426 | 2452 | ** |
| @@ -2439,10 +2465,11 @@ | ||
| 2439 | 2465 | int iLimit = 0, iOfst, iCnt; |
| 2440 | 2466 | int srchFlags; |
| 2441 | 2467 | const int isSearch = P("s")!=0; |
| 2442 | 2468 | const char *zStatusFilter = P("status"); |
| 2443 | 2469 | char const *zLimit = 0; |
| 2470 | + const int bHasStatus = forum_statuses()->n>1; | |
| 2444 | 2471 | |
| 2445 | 2472 | login_check_credentials(); |
| 2446 | 2473 | srchFlags = search_restrict(SRCH_FORUM); |
| 2447 | 2474 | if( !g.perm.RdForum ){ |
| 2448 | 2475 | login_needed(g.anon.RdForum); |
| @@ -2484,15 +2511,18 @@ | ||
| 2484 | 2511 | cgi_replace_query_parameter("n", fossil_strdup("25")) |
| 2485 | 2512 | /*for the sake of Max, below*/; |
| 2486 | 2513 | iLimit = 25; |
| 2487 | 2514 | } |
| 2488 | 2515 | style_submenu_entry("n","Max:",4,0); |
| 2516 | + forum_status_submenu(); | |
| 2489 | 2517 | iOfst = atoi(PD("x","0")); |
| 2490 | 2518 | iCnt = 0; |
| 2491 | - if( zStatusFilter && !*zStatusFilter ) zStatusFilter = 0; | |
| 2519 | + if( zStatusFilter && | |
| 2520 | + (!*zStatusFilter || 0==fossil_strcmp("*",zStatusFilter)) ){ | |
| 2521 | + zStatusFilter = 0; | |
| 2522 | + } | |
| 2492 | 2523 | if( db_table_exists("repository","forumpost") ){ |
| 2493 | - const int bHasStatus = forum_statuses()->n>1; | |
| 2494 | 2524 | db_prepare(&q, |
| 2495 | 2525 | "WITH " |
| 2496 | 2526 | "root(id,pinned,status,statlbl) AS (" |
| 2497 | 2527 | /* FIXME: the status/statlbl columns are running the same query |
| 2498 | 2528 | ** to get two adjacent columns. Certainly this query can be |
| @@ -2500,10 +2530,11 @@ | ||
| 2500 | 2530 | " SELECT froot id," |
| 2501 | 2531 | " (SELECT 1 FROM tagxref ref, tag t" |
| 2502 | 2532 | " WHERE ref.rid=x.fpid AND ref.tagtype>0" |
| 2503 | 2533 | " AND ref.tagid=t.tagid" |
| 2504 | 2534 | " AND t.tagname='pinned') pinned," |
| 2535 | + /* Status value: */ | |
| 2505 | 2536 | " CASE WHEN %d /*bHasStatus*/ THEN coalesce(" |
| 2506 | 2537 | " (SELECT ref.value FROM tagxref ref, tag t, forumstatus fs" |
| 2507 | 2538 | " WHERE ref.rid=x.froot AND ref.tagtype>0" |
| 2508 | 2539 | " AND ref.tagid=t.tagid" |
| 2509 | 2540 | " AND t.tagname='status'" |
| @@ -2510,10 +2541,11 @@ | ||
| 2510 | 2541 | " AND ref.value=fs.value" |
| 2511 | 2542 | " ORDER BY ref.mtime desc" |
| 2512 | 2543 | " )," |
| 2513 | 2544 | " (SELECT value FROM forumstatus WHERE ord=1)" |
| 2514 | 2545 | " ) ELSE NULL END status," |
| 2546 | + /* Status label: */ | |
| 2515 | 2547 | " CASE WHEN %d /*bHasStatus*/ THEN coalesce(" |
| 2516 | 2548 | " (SELECT fs.label FROM tagxref ref, tag t, forumstatus fs" |
| 2517 | 2549 | " WHERE ref.rid=x.froot AND ref.tagtype>0" |
| 2518 | 2550 | " AND ref.tagid=t.tagid" |
| 2519 | 2551 | " AND t.tagname='status'" |
| @@ -2520,11 +2552,11 @@ | ||
| 2520 | 2552 | " AND ref.value=fs.value" |
| 2521 | 2553 | " ORDER BY ref.mtime desc" |
| 2522 | 2554 | " )," |
| 2523 | 2555 | " (SELECT label FROM forumstatus WHERE ord=1)" |
| 2524 | 2556 | " ) ELSE NULL END statlbl" |
| 2525 | - " FROM forumpost x WHERE firt IS NULL AND fprev IS NULL" | |
| 2557 | + " FROM forumpost x WHERE firt IS NULL" /*??? AND fprev IS NULL*/ | |
| 2526 | 2558 | ")," |
| 2527 | 2559 | " thread(age,duration,cnt,root,last,pinned,status,statlbl)" |
| 2528 | 2560 | " AS (" |
| 2529 | 2561 | " SELECT" |
| 2530 | 2562 | " julianday('now') - max(fmtime)," |
| @@ -2552,11 +2584,11 @@ | ||
| 2552 | 2584 | " thread.status," /* 7 */ |
| 2553 | 2585 | " thread.statlbl" /* 8 */ |
| 2554 | 2586 | " FROM thread, blob, event" |
| 2555 | 2587 | " WHERE blob.rid=thread.last" |
| 2556 | 2588 | " AND event.objid=thread.last" |
| 2557 | - " ORDER BY 7 DESC, 1;", | |
| 2589 | + " ORDER BY 7/*pinned*/ DESC, 1;", | |
| 2558 | 2590 | bHasStatus, bHasStatus, |
| 2559 | 2591 | g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/, |
| 2560 | 2592 | g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/, |
| 2561 | 2593 | !!zStatusFilter, zStatusFilter, |
| 2562 | 2594 | iLimit+1, iOfst |
| 2563 | 2595 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -2417,10 +2417,36 @@ | |
| 2417 | @ </form> |
| 2418 | } |
| 2419 | |
| 2420 | style_finish_page(); |
| 2421 | } |
| 2422 | |
| 2423 | /* |
| 2424 | ** WEBPAGE: forummain |
| 2425 | ** WEBPAGE: forum |
| 2426 | ** |
| @@ -2439,10 +2465,11 @@ | |
| 2439 | int iLimit = 0, iOfst, iCnt; |
| 2440 | int srchFlags; |
| 2441 | const int isSearch = P("s")!=0; |
| 2442 | const char *zStatusFilter = P("status"); |
| 2443 | char const *zLimit = 0; |
| 2444 | |
| 2445 | login_check_credentials(); |
| 2446 | srchFlags = search_restrict(SRCH_FORUM); |
| 2447 | if( !g.perm.RdForum ){ |
| 2448 | login_needed(g.anon.RdForum); |
| @@ -2484,15 +2511,18 @@ | |
| 2484 | cgi_replace_query_parameter("n", fossil_strdup("25")) |
| 2485 | /*for the sake of Max, below*/; |
| 2486 | iLimit = 25; |
| 2487 | } |
| 2488 | style_submenu_entry("n","Max:",4,0); |
| 2489 | iOfst = atoi(PD("x","0")); |
| 2490 | iCnt = 0; |
| 2491 | if( zStatusFilter && !*zStatusFilter ) zStatusFilter = 0; |
| 2492 | if( db_table_exists("repository","forumpost") ){ |
| 2493 | const int bHasStatus = forum_statuses()->n>1; |
| 2494 | db_prepare(&q, |
| 2495 | "WITH " |
| 2496 | "root(id,pinned,status,statlbl) AS (" |
| 2497 | /* FIXME: the status/statlbl columns are running the same query |
| 2498 | ** to get two adjacent columns. Certainly this query can be |
| @@ -2500,10 +2530,11 @@ | |
| 2500 | " SELECT froot id," |
| 2501 | " (SELECT 1 FROM tagxref ref, tag t" |
| 2502 | " WHERE ref.rid=x.fpid AND ref.tagtype>0" |
| 2503 | " AND ref.tagid=t.tagid" |
| 2504 | " AND t.tagname='pinned') pinned," |
| 2505 | " CASE WHEN %d /*bHasStatus*/ THEN coalesce(" |
| 2506 | " (SELECT ref.value FROM tagxref ref, tag t, forumstatus fs" |
| 2507 | " WHERE ref.rid=x.froot AND ref.tagtype>0" |
| 2508 | " AND ref.tagid=t.tagid" |
| 2509 | " AND t.tagname='status'" |
| @@ -2510,10 +2541,11 @@ | |
| 2510 | " AND ref.value=fs.value" |
| 2511 | " ORDER BY ref.mtime desc" |
| 2512 | " )," |
| 2513 | " (SELECT value FROM forumstatus WHERE ord=1)" |
| 2514 | " ) ELSE NULL END status," |
| 2515 | " CASE WHEN %d /*bHasStatus*/ THEN coalesce(" |
| 2516 | " (SELECT fs.label FROM tagxref ref, tag t, forumstatus fs" |
| 2517 | " WHERE ref.rid=x.froot AND ref.tagtype>0" |
| 2518 | " AND ref.tagid=t.tagid" |
| 2519 | " AND t.tagname='status'" |
| @@ -2520,11 +2552,11 @@ | |
| 2520 | " AND ref.value=fs.value" |
| 2521 | " ORDER BY ref.mtime desc" |
| 2522 | " )," |
| 2523 | " (SELECT label FROM forumstatus WHERE ord=1)" |
| 2524 | " ) ELSE NULL END statlbl" |
| 2525 | " FROM forumpost x WHERE firt IS NULL AND fprev IS NULL" |
| 2526 | ")," |
| 2527 | " thread(age,duration,cnt,root,last,pinned,status,statlbl)" |
| 2528 | " AS (" |
| 2529 | " SELECT" |
| 2530 | " julianday('now') - max(fmtime)," |
| @@ -2552,11 +2584,11 @@ | |
| 2552 | " thread.status," /* 7 */ |
| 2553 | " thread.statlbl" /* 8 */ |
| 2554 | " FROM thread, blob, event" |
| 2555 | " WHERE blob.rid=thread.last" |
| 2556 | " AND event.objid=thread.last" |
| 2557 | " ORDER BY 7 DESC, 1;", |
| 2558 | bHasStatus, bHasStatus, |
| 2559 | g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/, |
| 2560 | g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/, |
| 2561 | !!zStatusFilter, zStatusFilter, |
| 2562 | iLimit+1, iOfst |
| 2563 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -2417,10 +2417,36 @@ | |
| 2417 | @ </form> |
| 2418 | } |
| 2419 | |
| 2420 | style_finish_page(); |
| 2421 | } |
| 2422 | |
| 2423 | /* |
| 2424 | ** If the forum-statuses setting is active and has 2 or more entries, |
| 2425 | ** this adds a submenu for selecting the status filter, else it emits |
| 2426 | ** nothing. |
| 2427 | */ |
| 2428 | static void forum_status_submenu(void){ |
| 2429 | const ForumStatusList * const fss = forum_statuses(); |
| 2430 | static int i = 0; |
| 2431 | static const char **az; |
| 2432 | if( i==0 && fss->n>1 ){ |
| 2433 | unsigned j; |
| 2434 | az = fossil_malloc(sizeof(az[0]) * ((1 + fss->n) * 2)); |
| 2435 | az[i++] = "*"; |
| 2436 | az[i++] = "Any status"; |
| 2437 | for( j = 0; j < fss->n; ++j ){ |
| 2438 | const ForumStatus * fs = &fss->aStatus[j]; |
| 2439 | az[i++] = fs->zValue; |
| 2440 | az[i++] = fs->zLabel; |
| 2441 | } |
| 2442 | //assert( i==(1+fss->n)*2 ); |
| 2443 | } |
| 2444 | if( i ){ |
| 2445 | style_submenu_multichoice("status", i/2, az, 0); |
| 2446 | } |
| 2447 | } |
| 2448 | |
| 2449 | /* |
| 2450 | ** WEBPAGE: forummain |
| 2451 | ** WEBPAGE: forum |
| 2452 | ** |
| @@ -2439,10 +2465,11 @@ | |
| 2465 | int iLimit = 0, iOfst, iCnt; |
| 2466 | int srchFlags; |
| 2467 | const int isSearch = P("s")!=0; |
| 2468 | const char *zStatusFilter = P("status"); |
| 2469 | char const *zLimit = 0; |
| 2470 | const int bHasStatus = forum_statuses()->n>1; |
| 2471 | |
| 2472 | login_check_credentials(); |
| 2473 | srchFlags = search_restrict(SRCH_FORUM); |
| 2474 | if( !g.perm.RdForum ){ |
| 2475 | login_needed(g.anon.RdForum); |
| @@ -2484,15 +2511,18 @@ | |
| 2511 | cgi_replace_query_parameter("n", fossil_strdup("25")) |
| 2512 | /*for the sake of Max, below*/; |
| 2513 | iLimit = 25; |
| 2514 | } |
| 2515 | style_submenu_entry("n","Max:",4,0); |
| 2516 | forum_status_submenu(); |
| 2517 | iOfst = atoi(PD("x","0")); |
| 2518 | iCnt = 0; |
| 2519 | if( zStatusFilter && |
| 2520 | (!*zStatusFilter || 0==fossil_strcmp("*",zStatusFilter)) ){ |
| 2521 | zStatusFilter = 0; |
| 2522 | } |
| 2523 | if( db_table_exists("repository","forumpost") ){ |
| 2524 | db_prepare(&q, |
| 2525 | "WITH " |
| 2526 | "root(id,pinned,status,statlbl) AS (" |
| 2527 | /* FIXME: the status/statlbl columns are running the same query |
| 2528 | ** to get two adjacent columns. Certainly this query can be |
| @@ -2500,10 +2530,11 @@ | |
| 2530 | " SELECT froot id," |
| 2531 | " (SELECT 1 FROM tagxref ref, tag t" |
| 2532 | " WHERE ref.rid=x.fpid AND ref.tagtype>0" |
| 2533 | " AND ref.tagid=t.tagid" |
| 2534 | " AND t.tagname='pinned') pinned," |
| 2535 | /* Status value: */ |
| 2536 | " CASE WHEN %d /*bHasStatus*/ THEN coalesce(" |
| 2537 | " (SELECT ref.value FROM tagxref ref, tag t, forumstatus fs" |
| 2538 | " WHERE ref.rid=x.froot AND ref.tagtype>0" |
| 2539 | " AND ref.tagid=t.tagid" |
| 2540 | " AND t.tagname='status'" |
| @@ -2510,10 +2541,11 @@ | |
| 2541 | " AND ref.value=fs.value" |
| 2542 | " ORDER BY ref.mtime desc" |
| 2543 | " )," |
| 2544 | " (SELECT value FROM forumstatus WHERE ord=1)" |
| 2545 | " ) ELSE NULL END status," |
| 2546 | /* Status label: */ |
| 2547 | " CASE WHEN %d /*bHasStatus*/ THEN coalesce(" |
| 2548 | " (SELECT fs.label FROM tagxref ref, tag t, forumstatus fs" |
| 2549 | " WHERE ref.rid=x.froot AND ref.tagtype>0" |
| 2550 | " AND ref.tagid=t.tagid" |
| 2551 | " AND t.tagname='status'" |
| @@ -2520,11 +2552,11 @@ | |
| 2552 | " AND ref.value=fs.value" |
| 2553 | " ORDER BY ref.mtime desc" |
| 2554 | " )," |
| 2555 | " (SELECT label FROM forumstatus WHERE ord=1)" |
| 2556 | " ) ELSE NULL END statlbl" |
| 2557 | " FROM forumpost x WHERE firt IS NULL" /*??? AND fprev IS NULL*/ |
| 2558 | ")," |
| 2559 | " thread(age,duration,cnt,root,last,pinned,status,statlbl)" |
| 2560 | " AS (" |
| 2561 | " SELECT" |
| 2562 | " julianday('now') - max(fmtime)," |
| @@ -2552,11 +2584,11 @@ | |
| 2584 | " thread.status," /* 7 */ |
| 2585 | " thread.statlbl" /* 8 */ |
| 2586 | " FROM thread, blob, event" |
| 2587 | " WHERE blob.rid=thread.last" |
| 2588 | " AND event.objid=thread.last" |
| 2589 | " ORDER BY 7/*pinned*/ DESC, 1;", |
| 2590 | bHasStatus, bHasStatus, |
| 2591 | g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/, |
| 2592 | g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/, |
| 2593 | !!zStatusFilter, zStatusFilter, |
| 2594 | iLimit+1, iOfst |
| 2595 |