Fossil SCM
Initial sketches for the ability to assign a status=X tag to forum posts, e.g. opened vs resolved. This compiles but does nothing useful.
Commit
025256542f00e1b3e12da50bb148a57c97ab930b5857185b9029289172364c11
Parent
5079ffb0278d122…
2 files changed
+1
+75
-2
+1
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -143,10 +143,11 @@ | ||
| 143 | 143 | { "hash-policy", CONFIGSET_PROJ }, |
| 144 | 144 | { "comment-format", CONFIGSET_PROJ }, |
| 145 | 145 | { "mimetypes", CONFIGSET_PROJ }, |
| 146 | 146 | { "forbid-delta-manifests", CONFIGSET_PROJ }, |
| 147 | 147 | { "mv-rm-files", CONFIGSET_PROJ }, |
| 148 | + { "forum-statuses", CONFIGSET_PROJ }, | |
| 148 | 149 | { "ticket-table", CONFIGSET_TKT }, |
| 149 | 150 | { "ticket-common", CONFIGSET_TKT }, |
| 150 | 151 | { "ticket-change", CONFIGSET_TKT }, |
| 151 | 152 | { "ticket-newpage", CONFIGSET_TKT }, |
| 152 | 153 | { "ticket-viewpage", CONFIGSET_TKT }, |
| 153 | 154 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -143,10 +143,11 @@ | |
| 143 | { "hash-policy", CONFIGSET_PROJ }, |
| 144 | { "comment-format", CONFIGSET_PROJ }, |
| 145 | { "mimetypes", CONFIGSET_PROJ }, |
| 146 | { "forbid-delta-manifests", CONFIGSET_PROJ }, |
| 147 | { "mv-rm-files", CONFIGSET_PROJ }, |
| 148 | { "ticket-table", CONFIGSET_TKT }, |
| 149 | { "ticket-common", CONFIGSET_TKT }, |
| 150 | { "ticket-change", CONFIGSET_TKT }, |
| 151 | { "ticket-newpage", CONFIGSET_TKT }, |
| 152 | { "ticket-viewpage", CONFIGSET_TKT }, |
| 153 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -143,10 +143,11 @@ | |
| 143 | { "hash-policy", CONFIGSET_PROJ }, |
| 144 | { "comment-format", CONFIGSET_PROJ }, |
| 145 | { "mimetypes", CONFIGSET_PROJ }, |
| 146 | { "forbid-delta-manifests", CONFIGSET_PROJ }, |
| 147 | { "mv-rm-files", CONFIGSET_PROJ }, |
| 148 | { "forum-statuses", CONFIGSET_PROJ }, |
| 149 | { "ticket-table", CONFIGSET_TKT }, |
| 150 | { "ticket-common", CONFIGSET_TKT }, |
| 151 | { "ticket-change", CONFIGSET_TKT }, |
| 152 | { "ticket-newpage", CONFIGSET_TKT }, |
| 153 | { "ticket-viewpage", CONFIGSET_TKT }, |
| 154 |
+75
-2
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -61,11 +61,73 @@ | ||
| 61 | 61 | ForumPost *pDisplay; /* Entries in display order */ |
| 62 | 62 | ForumPost *pTail; /* Last on the display list */ |
| 63 | 63 | int mxIndent; /* Maximum indentation level */ |
| 64 | 64 | int nArtifact; /* Number of forum artifacts in this thread */ |
| 65 | 65 | }; |
| 66 | + | |
| 67 | +/* | |
| 68 | +** A single entry from the forum-statuses setting. | |
| 69 | +*/ | |
| 70 | +struct ForumStatus { | |
| 71 | + char *zValue; /* status=X tag value */ | |
| 72 | + char *zLabel; /* Label for the UI */ | |
| 73 | + char *zDescr; /* Brief description */ | |
| 74 | +}; | |
| 75 | + | |
| 76 | +/* | |
| 77 | +** A list of ForumStatus objects. | |
| 78 | +*/ | |
| 79 | +struct ForumStatusList { | |
| 80 | + struct ForumStatus * aStatus; /* List of statuses */ | |
| 81 | + unsigned int n; /* Number of entries */ | |
| 82 | +}; | |
| 66 | 83 | #endif /* INTERFACE */ |
| 84 | + | |
| 85 | +/* | |
| 86 | +** Returns a high-level representation of the forum-statuses setting. | |
| 87 | +** This is a singleton, cached across calls. | |
| 88 | + */ | |
| 89 | +static const ForumStatusList * forum_statuses(void){ | |
| 90 | + static ForumStatusList fses = {0,0}; | |
| 91 | + static int once = 0; | |
| 92 | + if( !once ){ | |
| 93 | + ++once; | |
| 94 | + /* TODO: read `forum-statuses` setting and transform it into the | |
| 95 | + ** fses object. | |
| 96 | + ** | |
| 97 | + ** Maybe: if it's empty, synthesize a length-1 list from | |
| 98 | + ** {value:"default",label:"Default",...}. It's expected that | |
| 99 | + ** usage may be slightly simplified if we always have a non-empty | |
| 100 | + ** list. A length-1 list is, for purposes of the UI, identical to | |
| 101 | + ** an empty one - we cannot change statuses if there's only one | |
| 102 | + ** choice. */ | |
| 103 | + } | |
| 104 | + return &fses; | |
| 105 | +} | |
| 106 | + | |
| 107 | +/* | |
| 108 | +** Search for a ForumStatus object by its tag value. If a match is | |
| 109 | +** found, the corresponding object is returned. If no match is found | |
| 110 | +** then (A) if bFirst is false then 0 is returned, else (B) the first | |
| 111 | +** entry in the list is returned, noting that the list may be empty, | |
| 112 | +** in which case 0 is returned. | |
| 113 | +*/ | |
| 114 | +const ForumStatus * forum_status_by_value(const char *z, int bFirst){ | |
| 115 | + const ForumStatusList * const fses = forum_statuses(); | |
| 116 | + const ForumStatus * fs0 = 0; | |
| 117 | + unsigned int i; | |
| 118 | + if( !fses->n ) return 0; | |
| 119 | + for( i = 0; i < fses->n; ++i ){ | |
| 120 | + const ForumStatus * fs = &fses->aStatus[i]; | |
| 121 | + if( 0==fossil_strcmp(z, fs->zValue) ){ | |
| 122 | + return fs; | |
| 123 | + }else if( !fs0 ){ | |
| 124 | + fs0 = fs; | |
| 125 | + } | |
| 126 | + } | |
| 127 | + return bFirst ? fs0 : 0; | |
| 128 | +} | |
| 67 | 129 | |
| 68 | 130 | /* |
| 69 | 131 | ** Return true if the forum post with the given rid has been |
| 70 | 132 | ** subsequently edited. |
| 71 | 133 | */ |
| @@ -174,12 +236,12 @@ | ||
| 174 | 236 | ** - 0 if no matching tag is found. |
| 175 | 237 | ** |
| 176 | 238 | ** - The tagxref.rowid of the tagxref entry for the closure if rid is |
| 177 | 239 | ** the forum post to which the closure applies. |
| 178 | 240 | ** |
| 179 | -** - (-tagxref.rowid) if the given rid inherits a "closed" tag from an | |
| 180 | -** IRT forum post. | |
| 241 | +** - (-tagxref.rowid) if the given rid inherits the tag from an IRT | |
| 242 | +** forum post. | |
| 181 | 243 | */ |
| 182 | 244 | static int forum_rid_is_tagged(int rid, const char *zTagName, int bCheckIrt){ |
| 183 | 245 | static Stmt qIrt = empty_Stmt_m; |
| 184 | 246 | int rc = 0, i = 0; |
| 185 | 247 | /* TODO: this can probably be turned into a CTE by someone with |
| @@ -1968,10 +2030,21 @@ | ||
| 1968 | 2030 | ** seems more appropriate for the particular usage. |
| 1969 | 2031 | ** |
| 1970 | 2032 | ** SETTING: attachment-size-limit width=16 |
| 1971 | 2033 | ** The maximum number of bytes for an attachment. The default (or 0) is |
| 1972 | 2034 | ** unlimited but a limit may be imposed by the web server or a proxy. |
| 2035 | +** | |
| 2036 | +** SETTING: forum-statuses width=40 block-text | |
| 2037 | +** This JSON5-formatted value defines an array of objects describing | |
| 2038 | +** the available statuses of forum posts. Each entry of the array must | |
| 2039 | +** be an object in the form {label:"X",value:"Y",description:"Z"}. | |
| 2040 | +** The label is used in the UI and value becomes the value of the | |
| 2041 | +** "status" tag on forum posts. Any forum post which has a status | |
| 2042 | +** value which does not appear in this list is treated as if it had | |
| 2043 | +** the first value from this list. If this setting is empty, is | |
| 2044 | +** ill-formed JSON, or has only a single entry then the forum will | |
| 2045 | +** lack the capability of setting and filtering by status. | |
| 1973 | 2046 | */ |
| 1974 | 2047 | |
| 1975 | 2048 | /* |
| 1976 | 2049 | ** WEBPAGE: setup_forum |
| 1977 | 2050 | ** |
| 1978 | 2051 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -61,11 +61,73 @@ | |
| 61 | ForumPost *pDisplay; /* Entries in display order */ |
| 62 | ForumPost *pTail; /* Last on the display list */ |
| 63 | int mxIndent; /* Maximum indentation level */ |
| 64 | int nArtifact; /* Number of forum artifacts in this thread */ |
| 65 | }; |
| 66 | #endif /* INTERFACE */ |
| 67 | |
| 68 | /* |
| 69 | ** Return true if the forum post with the given rid has been |
| 70 | ** subsequently edited. |
| 71 | */ |
| @@ -174,12 +236,12 @@ | |
| 174 | ** - 0 if no matching tag is found. |
| 175 | ** |
| 176 | ** - The tagxref.rowid of the tagxref entry for the closure if rid is |
| 177 | ** the forum post to which the closure applies. |
| 178 | ** |
| 179 | ** - (-tagxref.rowid) if the given rid inherits a "closed" tag from an |
| 180 | ** IRT forum post. |
| 181 | */ |
| 182 | static int forum_rid_is_tagged(int rid, const char *zTagName, int bCheckIrt){ |
| 183 | static Stmt qIrt = empty_Stmt_m; |
| 184 | int rc = 0, i = 0; |
| 185 | /* TODO: this can probably be turned into a CTE by someone with |
| @@ -1968,10 +2030,21 @@ | |
| 1968 | ** seems more appropriate for the particular usage. |
| 1969 | ** |
| 1970 | ** SETTING: attachment-size-limit width=16 |
| 1971 | ** The maximum number of bytes for an attachment. The default (or 0) is |
| 1972 | ** unlimited but a limit may be imposed by the web server or a proxy. |
| 1973 | */ |
| 1974 | |
| 1975 | /* |
| 1976 | ** WEBPAGE: setup_forum |
| 1977 | ** |
| 1978 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -61,11 +61,73 @@ | |
| 61 | ForumPost *pDisplay; /* Entries in display order */ |
| 62 | ForumPost *pTail; /* Last on the display list */ |
| 63 | int mxIndent; /* Maximum indentation level */ |
| 64 | int nArtifact; /* Number of forum artifacts in this thread */ |
| 65 | }; |
| 66 | |
| 67 | /* |
| 68 | ** A single entry from the forum-statuses setting. |
| 69 | */ |
| 70 | struct ForumStatus { |
| 71 | char *zValue; /* status=X tag value */ |
| 72 | char *zLabel; /* Label for the UI */ |
| 73 | char *zDescr; /* Brief description */ |
| 74 | }; |
| 75 | |
| 76 | /* |
| 77 | ** A list of ForumStatus objects. |
| 78 | */ |
| 79 | struct ForumStatusList { |
| 80 | struct ForumStatus * aStatus; /* List of statuses */ |
| 81 | unsigned int n; /* Number of entries */ |
| 82 | }; |
| 83 | #endif /* INTERFACE */ |
| 84 | |
| 85 | /* |
| 86 | ** Returns a high-level representation of the forum-statuses setting. |
| 87 | ** This is a singleton, cached across calls. |
| 88 | */ |
| 89 | static const ForumStatusList * forum_statuses(void){ |
| 90 | static ForumStatusList fses = {0,0}; |
| 91 | static int once = 0; |
| 92 | if( !once ){ |
| 93 | ++once; |
| 94 | /* TODO: read `forum-statuses` setting and transform it into the |
| 95 | ** fses object. |
| 96 | ** |
| 97 | ** Maybe: if it's empty, synthesize a length-1 list from |
| 98 | ** {value:"default",label:"Default",...}. It's expected that |
| 99 | ** usage may be slightly simplified if we always have a non-empty |
| 100 | ** list. A length-1 list is, for purposes of the UI, identical to |
| 101 | ** an empty one - we cannot change statuses if there's only one |
| 102 | ** choice. */ |
| 103 | } |
| 104 | return &fses; |
| 105 | } |
| 106 | |
| 107 | /* |
| 108 | ** Search for a ForumStatus object by its tag value. If a match is |
| 109 | ** found, the corresponding object is returned. If no match is found |
| 110 | ** then (A) if bFirst is false then 0 is returned, else (B) the first |
| 111 | ** entry in the list is returned, noting that the list may be empty, |
| 112 | ** in which case 0 is returned. |
| 113 | */ |
| 114 | const ForumStatus * forum_status_by_value(const char *z, int bFirst){ |
| 115 | const ForumStatusList * const fses = forum_statuses(); |
| 116 | const ForumStatus * fs0 = 0; |
| 117 | unsigned int i; |
| 118 | if( !fses->n ) return 0; |
| 119 | for( i = 0; i < fses->n; ++i ){ |
| 120 | const ForumStatus * fs = &fses->aStatus[i]; |
| 121 | if( 0==fossil_strcmp(z, fs->zValue) ){ |
| 122 | return fs; |
| 123 | }else if( !fs0 ){ |
| 124 | fs0 = fs; |
| 125 | } |
| 126 | } |
| 127 | return bFirst ? fs0 : 0; |
| 128 | } |
| 129 | |
| 130 | /* |
| 131 | ** Return true if the forum post with the given rid has been |
| 132 | ** subsequently edited. |
| 133 | */ |
| @@ -174,12 +236,12 @@ | |
| 236 | ** - 0 if no matching tag is found. |
| 237 | ** |
| 238 | ** - The tagxref.rowid of the tagxref entry for the closure if rid is |
| 239 | ** the forum post to which the closure applies. |
| 240 | ** |
| 241 | ** - (-tagxref.rowid) if the given rid inherits the tag from an IRT |
| 242 | ** forum post. |
| 243 | */ |
| 244 | static int forum_rid_is_tagged(int rid, const char *zTagName, int bCheckIrt){ |
| 245 | static Stmt qIrt = empty_Stmt_m; |
| 246 | int rc = 0, i = 0; |
| 247 | /* TODO: this can probably be turned into a CTE by someone with |
| @@ -1968,10 +2030,21 @@ | |
| 2030 | ** seems more appropriate for the particular usage. |
| 2031 | ** |
| 2032 | ** SETTING: attachment-size-limit width=16 |
| 2033 | ** The maximum number of bytes for an attachment. The default (or 0) is |
| 2034 | ** unlimited but a limit may be imposed by the web server or a proxy. |
| 2035 | ** |
| 2036 | ** SETTING: forum-statuses width=40 block-text |
| 2037 | ** This JSON5-formatted value defines an array of objects describing |
| 2038 | ** the available statuses of forum posts. Each entry of the array must |
| 2039 | ** be an object in the form {label:"X",value:"Y",description:"Z"}. |
| 2040 | ** The label is used in the UI and value becomes the value of the |
| 2041 | ** "status" tag on forum posts. Any forum post which has a status |
| 2042 | ** value which does not appear in this list is treated as if it had |
| 2043 | ** the first value from this list. If this setting is empty, is |
| 2044 | ** ill-formed JSON, or has only a single entry then the forum will |
| 2045 | ** lack the capability of setting and filtering by status. |
| 2046 | */ |
| 2047 | |
| 2048 | /* |
| 2049 | ** WEBPAGE: setup_forum |
| 2050 | ** |
| 2051 |