summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2009-08-23 21:09:31 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2009-08-24 08:22:58 (UTC)
commit63816ec59748c622623f20e653a7bed87f4f05a4 (patch) (unidiff)
treea2dfcc17487d41d0f585eb8fd56b7e4ee6387c8a
parent39398545787179bc8075d64a443f9da3845c4f67 (diff)
downloadcgit-63816ec59748c622623f20e653a7bed87f4f05a4.zip
cgit-63816ec59748c622623f20e653a7bed87f4f05a4.tar.gz
cgit-63816ec59748c622623f20e653a7bed87f4f05a4.tar.bz2
ui-repolist.c: sort by section name, repo name as default
When no sorting is requested by the client, cgit will now sort by section name followed by repo name. This allows repos to be registered/ discovered independently of their display order. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ui-repolist.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/ui-repolist.c b/ui-repolist.c
index 4dea3b3..d56654d 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -115,131 +115,146 @@ void print_header(int columns)
115} 115}
116 116
117 117
118void print_pager(int items, int pagelen, char *search) 118void print_pager(int items, int pagelen, char *search)
119{ 119{
120 int i; 120 int i;
121 html("<div class='pager'>"); 121 html("<div class='pager'>");
122 for(i = 0; i * pagelen < items; i++) 122 for(i = 0; i * pagelen < items; i++)
123 cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), NULL, 123 cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), NULL,
124 search, i * pagelen); 124 search, i * pagelen);
125 html("</div>"); 125 html("</div>");
126} 126}
127 127
128static int cmp(const char *s1, const char *s2) 128static int cmp(const char *s1, const char *s2)
129{ 129{
130 if (s1 && s2) 130 if (s1 && s2)
131 return strcmp(s1, s2); 131 return strcmp(s1, s2);
132 if (s1 && !s2) 132 if (s1 && !s2)
133 return -1; 133 return -1;
134 if (s2 && !s1) 134 if (s2 && !s1)
135 return 1; 135 return 1;
136 return 0; 136 return 0;
137} 137}
138 138
139static int sort_section(const void *a, const void *b)
140{
141 const struct cgit_repo *r1 = a;
142 const struct cgit_repo *r2 = b;
143 int result;
144
145 result = cmp(r1->section, r2->section);
146 if (!result)
147 result = cmp(r1->name, r2->name);
148 return result;
149}
150
139static int sort_name(const void *a, const void *b) 151static int sort_name(const void *a, const void *b)
140{ 152{
141 const struct cgit_repo *r1 = a; 153 const struct cgit_repo *r1 = a;
142 const struct cgit_repo *r2 = b; 154 const struct cgit_repo *r2 = b;
143 155
144 return cmp(r1->name, r2->name); 156 return cmp(r1->name, r2->name);
145} 157}
146 158
147static int sort_desc(const void *a, const void *b) 159static int sort_desc(const void *a, const void *b)
148{ 160{
149 const struct cgit_repo *r1 = a; 161 const struct cgit_repo *r1 = a;
150 const struct cgit_repo *r2 = b; 162 const struct cgit_repo *r2 = b;
151 163
152 return cmp(r1->desc, r2->desc); 164 return cmp(r1->desc, r2->desc);
153} 165}
154 166
155static int sort_owner(const void *a, const void *b) 167static int sort_owner(const void *a, const void *b)
156{ 168{
157 const struct cgit_repo *r1 = a; 169 const struct cgit_repo *r1 = a;
158 const struct cgit_repo *r2 = b; 170 const struct cgit_repo *r2 = b;
159 171
160 return cmp(r1->owner, r2->owner); 172 return cmp(r1->owner, r2->owner);
161} 173}
162 174
163static int sort_idle(const void *a, const void *b) 175static int sort_idle(const void *a, const void *b)
164{ 176{
165 const struct cgit_repo *r1 = a; 177 const struct cgit_repo *r1 = a;
166 const struct cgit_repo *r2 = b; 178 const struct cgit_repo *r2 = b;
167 time_t t1, t2; 179 time_t t1, t2;
168 180
169 t1 = t2 = 0; 181 t1 = t2 = 0;
170 get_repo_modtime(r1, &t1); 182 get_repo_modtime(r1, &t1);
171 get_repo_modtime(r2, &t2); 183 get_repo_modtime(r2, &t2);
172 return t2 - t1; 184 return t2 - t1;
173} 185}
174 186
175struct sortcolumn { 187struct sortcolumn {
176 const char *name; 188 const char *name;
177 int (*fn)(const void *a, const void *b); 189 int (*fn)(const void *a, const void *b);
178}; 190};
179 191
180struct sortcolumn sortcolumn[] = { 192struct sortcolumn sortcolumn[] = {
193 {"section", sort_section},
181 {"name", sort_name}, 194 {"name", sort_name},
182 {"desc", sort_desc}, 195 {"desc", sort_desc},
183 {"owner", sort_owner}, 196 {"owner", sort_owner},
184 {"idle", sort_idle}, 197 {"idle", sort_idle},
185 {NULL, NULL} 198 {NULL, NULL}
186}; 199};
187 200
188int sort_repolist(char *field) 201int sort_repolist(char *field)
189{ 202{
190 struct sortcolumn *column; 203 struct sortcolumn *column;
191 204
192 for (column = &sortcolumn[0]; column->name; column++) { 205 for (column = &sortcolumn[0]; column->name; column++) {
193 if (strcmp(field, column->name)) 206 if (strcmp(field, column->name))
194 continue; 207 continue;
195 qsort(cgit_repolist.repos, cgit_repolist.count, 208 qsort(cgit_repolist.repos, cgit_repolist.count,
196 sizeof(struct cgit_repo), column->fn); 209 sizeof(struct cgit_repo), column->fn);
197 return 1; 210 return 1;
198 } 211 }
199 return 0; 212 return 0;
200} 213}
201 214
202 215
203void cgit_print_repolist() 216void cgit_print_repolist()
204{ 217{
205 int i, columns = 4, hits = 0, header = 0; 218 int i, columns = 4, hits = 0, header = 0;
206 char *last_section = NULL; 219 char *last_section = NULL;
207 int sorted = 0; 220 int sorted = 0;
208 221
209 if (ctx.cfg.enable_index_links) 222 if (ctx.cfg.enable_index_links)
210 columns++; 223 columns++;
211 224
212 ctx.page.title = ctx.cfg.root_title; 225 ctx.page.title = ctx.cfg.root_title;
213 cgit_print_http_headers(&ctx); 226 cgit_print_http_headers(&ctx);
214 cgit_print_docstart(&ctx); 227 cgit_print_docstart(&ctx);
215 cgit_print_pageheader(&ctx); 228 cgit_print_pageheader(&ctx);
216 229
217 if (ctx.cfg.index_header) 230 if (ctx.cfg.index_header)
218 html_include(ctx.cfg.index_header); 231 html_include(ctx.cfg.index_header);
219 232
220 if(ctx.qry.sort) 233 if(ctx.qry.sort)
221 sorted = sort_repolist(ctx.qry.sort); 234 sorted = sort_repolist(ctx.qry.sort);
235 else
236 sort_repolist("section");
222 237
223 html("<table summary='repository list' class='list nowrap'>"); 238 html("<table summary='repository list' class='list nowrap'>");
224 for (i=0; i<cgit_repolist.count; i++) { 239 for (i=0; i<cgit_repolist.count; i++) {
225 ctx.repo = &cgit_repolist.repos[i]; 240 ctx.repo = &cgit_repolist.repos[i];
226 if (!(is_match(ctx.repo) && is_in_url(ctx.repo))) 241 if (!(is_match(ctx.repo) && is_in_url(ctx.repo)))
227 continue; 242 continue;
228 hits++; 243 hits++;
229 if (hits <= ctx.qry.ofs) 244 if (hits <= ctx.qry.ofs)
230 continue; 245 continue;
231 if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) 246 if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count)
232 continue; 247 continue;
233 if (!header++) 248 if (!header++)
234 print_header(columns); 249 print_header(columns);
235 if (!sorted && 250 if (!sorted &&
236 ((last_section == NULL && ctx.repo->section != NULL) || 251 ((last_section == NULL && ctx.repo->section != NULL) ||
237 (last_section != NULL && ctx.repo->section == NULL) || 252 (last_section != NULL && ctx.repo->section == NULL) ||
238 (last_section != NULL && ctx.repo->section != NULL && 253 (last_section != NULL && ctx.repo->section != NULL &&
239 strcmp(ctx.repo->section, last_section)))) { 254 strcmp(ctx.repo->section, last_section)))) {
240 htmlf("<tr class='nohover'><td colspan='%d' class='reposection'>", 255 htmlf("<tr class='nohover'><td colspan='%d' class='reposection'>",
241 columns); 256 columns);
242 html_txt(ctx.repo->section); 257 html_txt(ctx.repo->section);
243 html("</td></tr>"); 258 html("</td></tr>");
244 last_section = ctx.repo->section; 259 last_section = ctx.repo->section;
245 } 260 }