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) (side-by-side diff)
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
@@ -91,179 +91,194 @@ int is_in_url(struct cgit_repo *repo)
return 1;
return 0;
}
void print_sort_header(const char *title, const char *sort)
{
htmlf("<th class='left'><a href='./?s=%s", sort);
if (ctx.qry.search) {
html("&q=");
html_url_arg(ctx.qry.search);
}
htmlf("'>%s</a></th>", title);
}
void print_header(int columns)
{
html("<tr class='nohover'>");
print_sort_header("Name", "name");
print_sort_header("Description", "desc");
print_sort_header("Owner", "owner");
print_sort_header("Idle", "idle");
if (ctx.cfg.enable_index_links)
html("<th class='left'>Links</th>");
html("</tr>\n");
}
void print_pager(int items, int pagelen, char *search)
{
int i;
html("<div class='pager'>");
for(i = 0; i * pagelen < items; i++)
cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), NULL,
search, i * pagelen);
html("</div>");
}
static int cmp(const char *s1, const char *s2)
{
if (s1 && s2)
return strcmp(s1, s2);
if (s1 && !s2)
return -1;
if (s2 && !s1)
return 1;
return 0;
}
+static int sort_section(const void *a, const void *b)
+{
+ const struct cgit_repo *r1 = a;
+ const struct cgit_repo *r2 = b;
+ int result;
+
+ result = cmp(r1->section, r2->section);
+ if (!result)
+ result = cmp(r1->name, r2->name);
+ return result;
+}
+
static int sort_name(const void *a, const void *b)
{
const struct cgit_repo *r1 = a;
const struct cgit_repo *r2 = b;
return cmp(r1->name, r2->name);
}
static int sort_desc(const void *a, const void *b)
{
const struct cgit_repo *r1 = a;
const struct cgit_repo *r2 = b;
return cmp(r1->desc, r2->desc);
}
static int sort_owner(const void *a, const void *b)
{
const struct cgit_repo *r1 = a;
const struct cgit_repo *r2 = b;
return cmp(r1->owner, r2->owner);
}
static int sort_idle(const void *a, const void *b)
{
const struct cgit_repo *r1 = a;
const struct cgit_repo *r2 = b;
time_t t1, t2;
t1 = t2 = 0;
get_repo_modtime(r1, &t1);
get_repo_modtime(r2, &t2);
return t2 - t1;
}
struct sortcolumn {
const char *name;
int (*fn)(const void *a, const void *b);
};
struct sortcolumn sortcolumn[] = {
+ {"section", sort_section},
{"name", sort_name},
{"desc", sort_desc},
{"owner", sort_owner},
{"idle", sort_idle},
{NULL, NULL}
};
int sort_repolist(char *field)
{
struct sortcolumn *column;
for (column = &sortcolumn[0]; column->name; column++) {
if (strcmp(field, column->name))
continue;
qsort(cgit_repolist.repos, cgit_repolist.count,
sizeof(struct cgit_repo), column->fn);
return 1;
}
return 0;
}
void cgit_print_repolist()
{
int i, columns = 4, hits = 0, header = 0;
char *last_section = NULL;
int sorted = 0;
if (ctx.cfg.enable_index_links)
columns++;
ctx.page.title = ctx.cfg.root_title;
cgit_print_http_headers(&ctx);
cgit_print_docstart(&ctx);
cgit_print_pageheader(&ctx);
if (ctx.cfg.index_header)
html_include(ctx.cfg.index_header);
if(ctx.qry.sort)
sorted = sort_repolist(ctx.qry.sort);
+ else
+ sort_repolist("section");
html("<table summary='repository list' class='list nowrap'>");
for (i=0; i<cgit_repolist.count; i++) {
ctx.repo = &cgit_repolist.repos[i];
if (!(is_match(ctx.repo) && is_in_url(ctx.repo)))
continue;
hits++;
if (hits <= ctx.qry.ofs)
continue;
if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count)
continue;
if (!header++)
print_header(columns);
if (!sorted &&
((last_section == NULL && ctx.repo->section != NULL) ||
(last_section != NULL && ctx.repo->section == NULL) ||
(last_section != NULL && ctx.repo->section != NULL &&
strcmp(ctx.repo->section, last_section)))) {
htmlf("<tr class='nohover'><td colspan='%d' class='reposection'>",
columns);
html_txt(ctx.repo->section);
html("</td></tr>");
last_section = ctx.repo->section;
}
htmlf("<tr><td class='%s'>",
!sorted && ctx.repo->section ? "sublevel-repo" : "toplevel-repo");
cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL);
html("</td><td>");
html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL);
html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc);
html_link_close();
html("</td><td>");
html_txt(ctx.repo->owner);
html("</td><td>");
print_modtime(ctx.repo);
html("</td>");
if (ctx.cfg.enable_index_links) {
html("<td>");
cgit_summary_link("summary", NULL, "button", NULL);
cgit_log_link("log", NULL, "button", NULL, NULL, NULL,
0, NULL, NULL, ctx.qry.showmsg);
cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
html("</td>");
}
html("</tr>\n");
}
html("</table>");
if (!hits)