Fossil SCM
New "By Day" report format.
Commit
31da5e3db7b8e428a08e7341503a9de7d65703b1f54bdfff084589e7db345836
Parent
68414a41171e766…
2 files changed
+110
-3
+7
-1
+110
-3
| --- src/statrep.c | ||
| +++ src/statrep.c | ||
| @@ -663,12 +663,14 @@ | ||
| 663 | 663 | db_finalize(&query); |
| 664 | 664 | } |
| 665 | 665 | |
| 666 | 666 | |
| 667 | 667 | /* |
| 668 | -** Helper for stats_report_by_month_year(), which generates a list of | |
| 669 | -** week numbers. The "y" query parameter is the year in format YYYY. | |
| 668 | +** Generator for the by-week report (RPT_BYWEEK). | |
| 669 | +** | |
| 670 | +** The "y" query parameter is the year in format YYYY. | |
| 671 | +** | |
| 670 | 672 | ** If zUserName is not NULL then the report is restricted to events |
| 671 | 673 | ** created by the named user account. |
| 672 | 674 | */ |
| 673 | 675 | static void stats_report_year_weeks(const char *zUserName){ |
| 674 | 676 | const char *zYear = P("y"); /* Year for which report shown */ |
| @@ -788,10 +790,109 @@ | ||
| 788 | 790 | "Average per active week: %d</div>", |
| 789 | 791 | total, nAvg); |
| 790 | 792 | } |
| 791 | 793 | } |
| 792 | 794 | |
| 795 | +/* | |
| 796 | +** Generator for the by-day report (RPT_BYDAY). | |
| 797 | +** | |
| 798 | +** The "y" query parameter is the year in format YYYY. | |
| 799 | +** | |
| 800 | +** If zUserName is not NULL then the report is restricted to events | |
| 801 | +** created by the named user account. | |
| 802 | +*/ | |
| 803 | +static void stats_report_year_days(const char *zUserName){ | |
| 804 | + const char *zYear = P("y"); /* Year for which report shown */ | |
| 805 | + Stmt q; | |
| 806 | + int nMaxEvents = 1; /* max number of events for | |
| 807 | + all rows. */ | |
| 808 | + int iterations = 0; /* # of active time periods. */ | |
| 809 | + int rowCount = 0; | |
| 810 | + int total = 0; | |
| 811 | + | |
| 812 | + stats_report_init_view(); | |
| 813 | + style_submenu_sql("y", "Year:", | |
| 814 | + "WITH RECURSIVE a(b) AS (" | |
| 815 | + " SELECT substr(date('now'),1,4) UNION ALL" | |
| 816 | + " SELECT b-1 FROM a" | |
| 817 | + " WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)" | |
| 818 | + ") SELECT b, b FROM a ORDER BY b DESC"); | |
| 819 | + if( zYear==0 || strlen(zYear)!=4 ){ | |
| 820 | + zYear = db_text("1970","SELECT substr(date('now'),1,4);"); | |
| 821 | + } | |
| 822 | + cgi_printf("<br>\n"); | |
| 823 | + db_prepare(&q, | |
| 824 | + "SELECT DISTINCT strftime('%%w',mtime) AS wkday, " | |
| 825 | + " date(mtime) AS date," | |
| 826 | + " count(*) AS n " | |
| 827 | + " FROM v_reports" | |
| 828 | + " WHERE %Q=substr(date(mtime),1,4) " | |
| 829 | + " AND mtime < current_timestamp " | |
| 830 | + " AND ifnull(coalesce(euser,user,'')=%Q,1)" | |
| 831 | + " GROUP BY date ORDER BY date DESC", zYear, zUserName); | |
| 832 | + @ <h1>Timeline events (%h(stats_report_label_for_type())) | |
| 833 | + @ for each day of %h(zYear) | |
| 834 | + if( zUserName ){ | |
| 835 | + @ for user %h(zUserName) | |
| 836 | + } | |
| 837 | + @ </h1> | |
| 838 | + style_table_sorter(); | |
| 839 | + cgi_printf("<table class='statistics-report-table-events sortable' " | |
| 840 | + "border='0' cellpadding='2' width='100%%' " | |
| 841 | + "cellspacing='0' data-column-types='tnx' data-init-sort='0'>\n"); | |
| 842 | + cgi_printf("<thead><tr>" | |
| 843 | + "<th>Date</th>" | |
| 844 | + "<th>Events</th>" | |
| 845 | + "<th width='90%%'><!-- relative commits graph --></th>" | |
| 846 | + "</tr></thead>\n" | |
| 847 | + "<tbody>\n"); | |
| 848 | + while( SQLITE_ROW == db_step(&q) ){ | |
| 849 | + int nCount = db_column_int(&q, 2); | |
| 850 | + if(nCount>nMaxEvents){ | |
| 851 | + nMaxEvents = nCount; | |
| 852 | + } | |
| 853 | + ++iterations; | |
| 854 | + } | |
| 855 | + db_reset(&q); | |
| 856 | + while( SQLITE_ROW == db_step(&q) ){ | |
| 857 | + static const char *azDayName[] = { | |
| 858 | + "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" | |
| 859 | + }; | |
| 860 | + int dayOfWeek = db_column_int(&q,0); | |
| 861 | + const char *zDate = db_column_text(&q,1); | |
| 862 | + const int nCount = db_column_int(&q,2); | |
| 863 | + int nSize = (nCount>0 && nMaxEvents>0) | |
| 864 | + ? (int)(100 * nCount / nMaxEvents) | |
| 865 | + : 0; | |
| 866 | + if(!nSize) nSize = 1; | |
| 867 | + total += nCount; | |
| 868 | + cgi_printf("<tr class='row%d'>", ++rowCount % 2 ); | |
| 869 | + cgi_printf("<td><a href='%R/timeline?ymd=%s&y=%s", | |
| 870 | + zDate, statsReportTimelineYFlag); | |
| 871 | + if( zUserName ){ | |
| 872 | + cgi_printf("&u=%t",zUserName); | |
| 873 | + } | |
| 874 | + cgi_printf("'>%s (%s)</a></td>",zDate, azDayName[dayOfWeek]); | |
| 875 | + | |
| 876 | + cgi_printf("<td>%d</td>",nCount); | |
| 877 | + cgi_printf("<td style='white-space: nowrap;'>"); | |
| 878 | + if( nCount ){ | |
| 879 | + @ <div class='statistics-report-graph-line' \ | |
| 880 | + @ style='width:%d(nSize)%%;'> </div> \ | |
| 881 | + } | |
| 882 | + cgi_printf("</td></tr>\n"); | |
| 883 | + } | |
| 884 | + db_finalize(&q); | |
| 885 | + cgi_printf("</tbody></table>"); | |
| 886 | + if(total){ | |
| 887 | + int nAvg = iterations ? (total/iterations) : 0; | |
| 888 | + cgi_printf("<br><div>Total events: %d<br>" | |
| 889 | + "Average per active day: %d</div>", | |
| 890 | + total, nAvg); | |
| 891 | + } | |
| 892 | +} | |
| 893 | + | |
| 793 | 894 | |
| 794 | 895 | /* |
| 795 | 896 | ** Generate a report that shows the most recent change for each user. |
| 796 | 897 | */ |
| 797 | 898 | static void stats_report_last_change(void){ |
| @@ -843,10 +944,11 @@ | ||
| 843 | 944 | #define RPT_BYWEEK 4 |
| 844 | 945 | #define RPT_BYWEEKDAY 5 |
| 845 | 946 | #define RPT_BYYEAR 6 |
| 846 | 947 | #define RPT_LASTCHNG 7 /* Last change made for each user */ |
| 847 | 948 | #define RPT_BYHOUR 8 /* hour-of-day */ |
| 949 | +#define RPT_BYDAY 9 | |
| 848 | 950 | #define RPT_NONE 0 /* None of the above */ |
| 849 | 951 | |
| 850 | 952 | /* |
| 851 | 953 | ** WEBPAGE: reports |
| 852 | 954 | ** |
| @@ -856,10 +958,11 @@ | ||
| 856 | 958 | ** |
| 857 | 959 | ** view=REPORT_NAME Valid REPORT_NAME values: |
| 858 | 960 | ** * byyear |
| 859 | 961 | ** * bymonth |
| 860 | 962 | ** * byweek |
| 963 | +** * byday | |
| 861 | 964 | ** * byweekday |
| 862 | 965 | ** * byhour |
| 863 | 966 | ** * byuser |
| 864 | 967 | ** * byfile |
| 865 | 968 | ** * lastchng |
| @@ -889,11 +992,11 @@ | ||
| 889 | 992 | void stats_report_page(){ |
| 890 | 993 | const char *zView = P("view"); /* Which view/report to show. */ |
| 891 | 994 | int eType = RPT_NONE; /* Numeric code for view/report to show */ |
| 892 | 995 | int i; /* Loop counter */ |
| 893 | 996 | const char *zUserName; /* Name of user */ |
| 894 | - const char *azView[16]; /* Drop-down menu of view types */ | |
| 997 | + const char *azView[24]; /* Drop-down menu of view types */ | |
| 895 | 998 | static const struct { |
| 896 | 999 | const char *zName; /* Name of view= screen type */ |
| 897 | 1000 | const char *zVal; /* Value of view= query parameter */ |
| 898 | 1001 | int eType; /* Corresponding RPT_* define */ |
| 899 | 1002 | } aViewType[] = { |
| @@ -900,10 +1003,11 @@ | ||
| 900 | 1003 | { "File Changes","byfile", RPT_BYFILE }, |
| 901 | 1004 | { "Last Change", "lastchng", RPT_LASTCHNG }, |
| 902 | 1005 | { "By Month", "bymonth", RPT_BYMONTH }, |
| 903 | 1006 | { "By User", "byuser", RPT_BYUSER }, |
| 904 | 1007 | { "By Week", "byweek", RPT_BYWEEK }, |
| 1008 | + { "By Day", "byday", RPT_BYDAY }, | |
| 905 | 1009 | { "By Weekday", "byweekday", RPT_BYWEEKDAY }, |
| 906 | 1010 | { "By Year", "byyear", RPT_BYYEAR }, |
| 907 | 1011 | { "By Hour", "byhour", RPT_BYHOUR }, |
| 908 | 1012 | }; |
| 909 | 1013 | static const char *const azType[] = { |
| @@ -965,10 +1069,13 @@ | ||
| 965 | 1069 | stats_report_by_month_year(1, zUserName); |
| 966 | 1070 | break; |
| 967 | 1071 | case RPT_BYWEEK: |
| 968 | 1072 | stats_report_year_weeks(zUserName); |
| 969 | 1073 | break; |
| 1074 | + case RPT_BYDAY: | |
| 1075 | + stats_report_year_days(zUserName); | |
| 1076 | + break; | |
| 970 | 1077 | default: |
| 971 | 1078 | case RPT_BYUSER: |
| 972 | 1079 | stats_report_by_user(); |
| 973 | 1080 | break; |
| 974 | 1081 | case RPT_BYWEEKDAY: |
| 975 | 1082 |
| --- src/statrep.c | |
| +++ src/statrep.c | |
| @@ -663,12 +663,14 @@ | |
| 663 | db_finalize(&query); |
| 664 | } |
| 665 | |
| 666 | |
| 667 | /* |
| 668 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 669 | ** week numbers. The "y" query parameter is the year in format YYYY. |
| 670 | ** If zUserName is not NULL then the report is restricted to events |
| 671 | ** created by the named user account. |
| 672 | */ |
| 673 | static void stats_report_year_weeks(const char *zUserName){ |
| 674 | const char *zYear = P("y"); /* Year for which report shown */ |
| @@ -788,10 +790,109 @@ | |
| 788 | "Average per active week: %d</div>", |
| 789 | total, nAvg); |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | |
| 794 | /* |
| 795 | ** Generate a report that shows the most recent change for each user. |
| 796 | */ |
| 797 | static void stats_report_last_change(void){ |
| @@ -843,10 +944,11 @@ | |
| 843 | #define RPT_BYWEEK 4 |
| 844 | #define RPT_BYWEEKDAY 5 |
| 845 | #define RPT_BYYEAR 6 |
| 846 | #define RPT_LASTCHNG 7 /* Last change made for each user */ |
| 847 | #define RPT_BYHOUR 8 /* hour-of-day */ |
| 848 | #define RPT_NONE 0 /* None of the above */ |
| 849 | |
| 850 | /* |
| 851 | ** WEBPAGE: reports |
| 852 | ** |
| @@ -856,10 +958,11 @@ | |
| 856 | ** |
| 857 | ** view=REPORT_NAME Valid REPORT_NAME values: |
| 858 | ** * byyear |
| 859 | ** * bymonth |
| 860 | ** * byweek |
| 861 | ** * byweekday |
| 862 | ** * byhour |
| 863 | ** * byuser |
| 864 | ** * byfile |
| 865 | ** * lastchng |
| @@ -889,11 +992,11 @@ | |
| 889 | void stats_report_page(){ |
| 890 | const char *zView = P("view"); /* Which view/report to show. */ |
| 891 | int eType = RPT_NONE; /* Numeric code for view/report to show */ |
| 892 | int i; /* Loop counter */ |
| 893 | const char *zUserName; /* Name of user */ |
| 894 | const char *azView[16]; /* Drop-down menu of view types */ |
| 895 | static const struct { |
| 896 | const char *zName; /* Name of view= screen type */ |
| 897 | const char *zVal; /* Value of view= query parameter */ |
| 898 | int eType; /* Corresponding RPT_* define */ |
| 899 | } aViewType[] = { |
| @@ -900,10 +1003,11 @@ | |
| 900 | { "File Changes","byfile", RPT_BYFILE }, |
| 901 | { "Last Change", "lastchng", RPT_LASTCHNG }, |
| 902 | { "By Month", "bymonth", RPT_BYMONTH }, |
| 903 | { "By User", "byuser", RPT_BYUSER }, |
| 904 | { "By Week", "byweek", RPT_BYWEEK }, |
| 905 | { "By Weekday", "byweekday", RPT_BYWEEKDAY }, |
| 906 | { "By Year", "byyear", RPT_BYYEAR }, |
| 907 | { "By Hour", "byhour", RPT_BYHOUR }, |
| 908 | }; |
| 909 | static const char *const azType[] = { |
| @@ -965,10 +1069,13 @@ | |
| 965 | stats_report_by_month_year(1, zUserName); |
| 966 | break; |
| 967 | case RPT_BYWEEK: |
| 968 | stats_report_year_weeks(zUserName); |
| 969 | break; |
| 970 | default: |
| 971 | case RPT_BYUSER: |
| 972 | stats_report_by_user(); |
| 973 | break; |
| 974 | case RPT_BYWEEKDAY: |
| 975 |
| --- src/statrep.c | |
| +++ src/statrep.c | |
| @@ -663,12 +663,14 @@ | |
| 663 | db_finalize(&query); |
| 664 | } |
| 665 | |
| 666 | |
| 667 | /* |
| 668 | ** Generator for the by-week report (RPT_BYWEEK). |
| 669 | ** |
| 670 | ** The "y" query parameter is the year in format YYYY. |
| 671 | ** |
| 672 | ** If zUserName is not NULL then the report is restricted to events |
| 673 | ** created by the named user account. |
| 674 | */ |
| 675 | static void stats_report_year_weeks(const char *zUserName){ |
| 676 | const char *zYear = P("y"); /* Year for which report shown */ |
| @@ -788,10 +790,109 @@ | |
| 790 | "Average per active week: %d</div>", |
| 791 | total, nAvg); |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | /* |
| 796 | ** Generator for the by-day report (RPT_BYDAY). |
| 797 | ** |
| 798 | ** The "y" query parameter is the year in format YYYY. |
| 799 | ** |
| 800 | ** If zUserName is not NULL then the report is restricted to events |
| 801 | ** created by the named user account. |
| 802 | */ |
| 803 | static void stats_report_year_days(const char *zUserName){ |
| 804 | const char *zYear = P("y"); /* Year for which report shown */ |
| 805 | Stmt q; |
| 806 | int nMaxEvents = 1; /* max number of events for |
| 807 | all rows. */ |
| 808 | int iterations = 0; /* # of active time periods. */ |
| 809 | int rowCount = 0; |
| 810 | int total = 0; |
| 811 | |
| 812 | stats_report_init_view(); |
| 813 | style_submenu_sql("y", "Year:", |
| 814 | "WITH RECURSIVE a(b) AS (" |
| 815 | " SELECT substr(date('now'),1,4) UNION ALL" |
| 816 | " SELECT b-1 FROM a" |
| 817 | " WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)" |
| 818 | ") SELECT b, b FROM a ORDER BY b DESC"); |
| 819 | if( zYear==0 || strlen(zYear)!=4 ){ |
| 820 | zYear = db_text("1970","SELECT substr(date('now'),1,4);"); |
| 821 | } |
| 822 | cgi_printf("<br>\n"); |
| 823 | db_prepare(&q, |
| 824 | "SELECT DISTINCT strftime('%%w',mtime) AS wkday, " |
| 825 | " date(mtime) AS date," |
| 826 | " count(*) AS n " |
| 827 | " FROM v_reports" |
| 828 | " WHERE %Q=substr(date(mtime),1,4) " |
| 829 | " AND mtime < current_timestamp " |
| 830 | " AND ifnull(coalesce(euser,user,'')=%Q,1)" |
| 831 | " GROUP BY date ORDER BY date DESC", zYear, zUserName); |
| 832 | @ <h1>Timeline events (%h(stats_report_label_for_type())) |
| 833 | @ for each day of %h(zYear) |
| 834 | if( zUserName ){ |
| 835 | @ for user %h(zUserName) |
| 836 | } |
| 837 | @ </h1> |
| 838 | style_table_sorter(); |
| 839 | cgi_printf("<table class='statistics-report-table-events sortable' " |
| 840 | "border='0' cellpadding='2' width='100%%' " |
| 841 | "cellspacing='0' data-column-types='tnx' data-init-sort='0'>\n"); |
| 842 | cgi_printf("<thead><tr>" |
| 843 | "<th>Date</th>" |
| 844 | "<th>Events</th>" |
| 845 | "<th width='90%%'><!-- relative commits graph --></th>" |
| 846 | "</tr></thead>\n" |
| 847 | "<tbody>\n"); |
| 848 | while( SQLITE_ROW == db_step(&q) ){ |
| 849 | int nCount = db_column_int(&q, 2); |
| 850 | if(nCount>nMaxEvents){ |
| 851 | nMaxEvents = nCount; |
| 852 | } |
| 853 | ++iterations; |
| 854 | } |
| 855 | db_reset(&q); |
| 856 | while( SQLITE_ROW == db_step(&q) ){ |
| 857 | static const char *azDayName[] = { |
| 858 | "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" |
| 859 | }; |
| 860 | int dayOfWeek = db_column_int(&q,0); |
| 861 | const char *zDate = db_column_text(&q,1); |
| 862 | const int nCount = db_column_int(&q,2); |
| 863 | int nSize = (nCount>0 && nMaxEvents>0) |
| 864 | ? (int)(100 * nCount / nMaxEvents) |
| 865 | : 0; |
| 866 | if(!nSize) nSize = 1; |
| 867 | total += nCount; |
| 868 | cgi_printf("<tr class='row%d'>", ++rowCount % 2 ); |
| 869 | cgi_printf("<td><a href='%R/timeline?ymd=%s&y=%s", |
| 870 | zDate, statsReportTimelineYFlag); |
| 871 | if( zUserName ){ |
| 872 | cgi_printf("&u=%t",zUserName); |
| 873 | } |
| 874 | cgi_printf("'>%s (%s)</a></td>",zDate, azDayName[dayOfWeek]); |
| 875 | |
| 876 | cgi_printf("<td>%d</td>",nCount); |
| 877 | cgi_printf("<td style='white-space: nowrap;'>"); |
| 878 | if( nCount ){ |
| 879 | @ <div class='statistics-report-graph-line' \ |
| 880 | @ style='width:%d(nSize)%%;'> </div> \ |
| 881 | } |
| 882 | cgi_printf("</td></tr>\n"); |
| 883 | } |
| 884 | db_finalize(&q); |
| 885 | cgi_printf("</tbody></table>"); |
| 886 | if(total){ |
| 887 | int nAvg = iterations ? (total/iterations) : 0; |
| 888 | cgi_printf("<br><div>Total events: %d<br>" |
| 889 | "Average per active day: %d</div>", |
| 890 | total, nAvg); |
| 891 | } |
| 892 | } |
| 893 | |
| 894 | |
| 895 | /* |
| 896 | ** Generate a report that shows the most recent change for each user. |
| 897 | */ |
| 898 | static void stats_report_last_change(void){ |
| @@ -843,10 +944,11 @@ | |
| 944 | #define RPT_BYWEEK 4 |
| 945 | #define RPT_BYWEEKDAY 5 |
| 946 | #define RPT_BYYEAR 6 |
| 947 | #define RPT_LASTCHNG 7 /* Last change made for each user */ |
| 948 | #define RPT_BYHOUR 8 /* hour-of-day */ |
| 949 | #define RPT_BYDAY 9 |
| 950 | #define RPT_NONE 0 /* None of the above */ |
| 951 | |
| 952 | /* |
| 953 | ** WEBPAGE: reports |
| 954 | ** |
| @@ -856,10 +958,11 @@ | |
| 958 | ** |
| 959 | ** view=REPORT_NAME Valid REPORT_NAME values: |
| 960 | ** * byyear |
| 961 | ** * bymonth |
| 962 | ** * byweek |
| 963 | ** * byday |
| 964 | ** * byweekday |
| 965 | ** * byhour |
| 966 | ** * byuser |
| 967 | ** * byfile |
| 968 | ** * lastchng |
| @@ -889,11 +992,11 @@ | |
| 992 | void stats_report_page(){ |
| 993 | const char *zView = P("view"); /* Which view/report to show. */ |
| 994 | int eType = RPT_NONE; /* Numeric code for view/report to show */ |
| 995 | int i; /* Loop counter */ |
| 996 | const char *zUserName; /* Name of user */ |
| 997 | const char *azView[24]; /* Drop-down menu of view types */ |
| 998 | static const struct { |
| 999 | const char *zName; /* Name of view= screen type */ |
| 1000 | const char *zVal; /* Value of view= query parameter */ |
| 1001 | int eType; /* Corresponding RPT_* define */ |
| 1002 | } aViewType[] = { |
| @@ -900,10 +1003,11 @@ | |
| 1003 | { "File Changes","byfile", RPT_BYFILE }, |
| 1004 | { "Last Change", "lastchng", RPT_LASTCHNG }, |
| 1005 | { "By Month", "bymonth", RPT_BYMONTH }, |
| 1006 | { "By User", "byuser", RPT_BYUSER }, |
| 1007 | { "By Week", "byweek", RPT_BYWEEK }, |
| 1008 | { "By Day", "byday", RPT_BYDAY }, |
| 1009 | { "By Weekday", "byweekday", RPT_BYWEEKDAY }, |
| 1010 | { "By Year", "byyear", RPT_BYYEAR }, |
| 1011 | { "By Hour", "byhour", RPT_BYHOUR }, |
| 1012 | }; |
| 1013 | static const char *const azType[] = { |
| @@ -965,10 +1069,13 @@ | |
| 1069 | stats_report_by_month_year(1, zUserName); |
| 1070 | break; |
| 1071 | case RPT_BYWEEK: |
| 1072 | stats_report_year_weeks(zUserName); |
| 1073 | break; |
| 1074 | case RPT_BYDAY: |
| 1075 | stats_report_year_days(zUserName); |
| 1076 | break; |
| 1077 | default: |
| 1078 | case RPT_BYUSER: |
| 1079 | stats_report_by_user(); |
| 1080 | break; |
| 1081 | case RPT_BYWEEKDAY: |
| 1082 |
+7
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1720,11 +1720,11 @@ | ||
| 1720 | 1720 | ** mionly Show related parents but not related children. |
| 1721 | 1721 | ** nowiki Do not show wiki associated with branch or tag |
| 1722 | 1722 | ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob", |
| 1723 | 1723 | ** "like", or "regexp". |
| 1724 | 1724 | ** u=USER Only show items associated with USER |
| 1725 | -** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', or 'all'. | |
| 1725 | +** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', 'h', or 'all'. | |
| 1726 | 1726 | ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar", |
| 1727 | 1727 | ** x: "Classic". |
| 1728 | 1728 | ** advm Use the "Advanced" or "Busy" menu design. |
| 1729 | 1729 | ** ng No Graph. |
| 1730 | 1730 | ** ncp Omit cherrypick merges |
| @@ -2944,10 +2944,11 @@ | ||
| 2944 | 2944 | || (zType[0]=='n' && !g.perm.RdTkt) |
| 2945 | 2945 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 2946 | 2946 | || (zType[0]=='c' && !g.perm.Read) |
| 2947 | 2947 | || (zType[0]=='g' && !g.perm.Read) |
| 2948 | 2948 | || (zType[0]=='f' && !g.perm.RdForum) |
| 2949 | + || (zType[0]=='h' && !g.perm.RdForum) | |
| 2949 | 2950 | ){ |
| 2950 | 2951 | zType = "all"; |
| 2951 | 2952 | } |
| 2952 | 2953 | if( zType[0]=='a' ){ |
| 2953 | 2954 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| @@ -2973,10 +2974,13 @@ | ||
| 2973 | 2974 | } |
| 2974 | 2975 | }else{ /* zType!="all" */ |
| 2975 | 2976 | if( zType[0]=='n' ){ |
| 2976 | 2977 | blob_append_sql(&cond, |
| 2977 | 2978 | " AND event.type='t' AND event.comment GLOB 'New ticket*'"); |
| 2979 | + }else if( zType[0]=='h' ){ | |
| 2980 | + blob_append_sql(&cond, | |
| 2981 | + " AND event.type='f' AND event.comment GLOB 'Post:*'"); | |
| 2978 | 2982 | }else{ |
| 2979 | 2983 | blob_append_sql(&cond, " AND event.type=%Q", zType); |
| 2980 | 2984 | } |
| 2981 | 2985 | if( zType[0]=='c' ){ |
| 2982 | 2986 | zEType = "check-in"; |
| @@ -2990,10 +2994,12 @@ | ||
| 2990 | 2994 | zEType = "technical note"; |
| 2991 | 2995 | }else if( zType[0]=='g' ){ |
| 2992 | 2996 | zEType = "tag"; |
| 2993 | 2997 | }else if( zType[0]=='f' ){ |
| 2994 | 2998 | zEType = "forum post"; |
| 2999 | + }else if( zType[0]=='h' ){ | |
| 3000 | + zEType = "new forum thread"; | |
| 2995 | 3001 | } |
| 2996 | 3002 | } |
| 2997 | 3003 | if( zUser ){ |
| 2998 | 3004 | int n = db_int(0,"SELECT count(*) FROM event" |
| 2999 | 3005 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 3000 | 3006 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1720,11 +1720,11 @@ | |
| 1720 | ** mionly Show related parents but not related children. |
| 1721 | ** nowiki Do not show wiki associated with branch or tag |
| 1722 | ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob", |
| 1723 | ** "like", or "regexp". |
| 1724 | ** u=USER Only show items associated with USER |
| 1725 | ** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', or 'all'. |
| 1726 | ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar", |
| 1727 | ** x: "Classic". |
| 1728 | ** advm Use the "Advanced" or "Busy" menu design. |
| 1729 | ** ng No Graph. |
| 1730 | ** ncp Omit cherrypick merges |
| @@ -2944,10 +2944,11 @@ | |
| 2944 | || (zType[0]=='n' && !g.perm.RdTkt) |
| 2945 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 2946 | || (zType[0]=='c' && !g.perm.Read) |
| 2947 | || (zType[0]=='g' && !g.perm.Read) |
| 2948 | || (zType[0]=='f' && !g.perm.RdForum) |
| 2949 | ){ |
| 2950 | zType = "all"; |
| 2951 | } |
| 2952 | if( zType[0]=='a' ){ |
| 2953 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| @@ -2973,10 +2974,13 @@ | |
| 2973 | } |
| 2974 | }else{ /* zType!="all" */ |
| 2975 | if( zType[0]=='n' ){ |
| 2976 | blob_append_sql(&cond, |
| 2977 | " AND event.type='t' AND event.comment GLOB 'New ticket*'"); |
| 2978 | }else{ |
| 2979 | blob_append_sql(&cond, " AND event.type=%Q", zType); |
| 2980 | } |
| 2981 | if( zType[0]=='c' ){ |
| 2982 | zEType = "check-in"; |
| @@ -2990,10 +2994,12 @@ | |
| 2990 | zEType = "technical note"; |
| 2991 | }else if( zType[0]=='g' ){ |
| 2992 | zEType = "tag"; |
| 2993 | }else if( zType[0]=='f' ){ |
| 2994 | zEType = "forum post"; |
| 2995 | } |
| 2996 | } |
| 2997 | if( zUser ){ |
| 2998 | int n = db_int(0,"SELECT count(*) FROM event" |
| 2999 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 3000 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1720,11 +1720,11 @@ | |
| 1720 | ** mionly Show related parents but not related children. |
| 1721 | ** nowiki Do not show wiki associated with branch or tag |
| 1722 | ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob", |
| 1723 | ** "like", or "regexp". |
| 1724 | ** u=USER Only show items associated with USER |
| 1725 | ** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', 'h', or 'all'. |
| 1726 | ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar", |
| 1727 | ** x: "Classic". |
| 1728 | ** advm Use the "Advanced" or "Busy" menu design. |
| 1729 | ** ng No Graph. |
| 1730 | ** ncp Omit cherrypick merges |
| @@ -2944,10 +2944,11 @@ | |
| 2944 | || (zType[0]=='n' && !g.perm.RdTkt) |
| 2945 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 2946 | || (zType[0]=='c' && !g.perm.Read) |
| 2947 | || (zType[0]=='g' && !g.perm.Read) |
| 2948 | || (zType[0]=='f' && !g.perm.RdForum) |
| 2949 | || (zType[0]=='h' && !g.perm.RdForum) |
| 2950 | ){ |
| 2951 | zType = "all"; |
| 2952 | } |
| 2953 | if( zType[0]=='a' ){ |
| 2954 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| @@ -2973,10 +2974,13 @@ | |
| 2974 | } |
| 2975 | }else{ /* zType!="all" */ |
| 2976 | if( zType[0]=='n' ){ |
| 2977 | blob_append_sql(&cond, |
| 2978 | " AND event.type='t' AND event.comment GLOB 'New ticket*'"); |
| 2979 | }else if( zType[0]=='h' ){ |
| 2980 | blob_append_sql(&cond, |
| 2981 | " AND event.type='f' AND event.comment GLOB 'Post:*'"); |
| 2982 | }else{ |
| 2983 | blob_append_sql(&cond, " AND event.type=%Q", zType); |
| 2984 | } |
| 2985 | if( zType[0]=='c' ){ |
| 2986 | zEType = "check-in"; |
| @@ -2990,10 +2994,12 @@ | |
| 2994 | zEType = "technical note"; |
| 2995 | }else if( zType[0]=='g' ){ |
| 2996 | zEType = "tag"; |
| 2997 | }else if( zType[0]=='f' ){ |
| 2998 | zEType = "forum post"; |
| 2999 | }else if( zType[0]=='h' ){ |
| 3000 | zEType = "new forum thread"; |
| 3001 | } |
| 3002 | } |
| 3003 | if( zUser ){ |
| 3004 | int n = db_int(0,"SELECT count(*) FROM event" |
| 3005 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 3006 |