summaryrefslogtreecommitdiffabout
path: root/ui-commit.c
authorLars Hjemli <hjemli@gmail.com>2007-05-15 00:13:11 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-05-15 07:09:42 (UTC)
commite903011c4457c24c0095f270ca5e78c40729434f (patch) (unidiff)
tree255f128dfaf81f2fd03bb2216039bbf8f38ef167 /ui-commit.c
parentcfd2aa079770ddb4c93d5995b2cd7b5f25da3681 (diff)
downloadcgit-e903011c4457c24c0095f270ca5e78c40729434f.zip
cgit-e903011c4457c24c0095f270ca5e78c40729434f.tar.gz
cgit-e903011c4457c24c0095f270ca5e78c40729434f.tar.bz2
Use tables and css to create the diffstat graph, fix scaling
There was no need to use image-files for the graphs, so lets drop them. At the same time, fix scaling of the graphs so that the full width is used only if atleast 100 LOC are changed in one of the files. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'ui-commit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-commit.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/ui-commit.c b/ui-commit.c
index b6a106f..8011dfc 100644
--- a/ui-commit.c
+++ b/ui-commit.c
@@ -1,158 +1,154 @@
1/* ui-commit.c: generate commit view 1/* ui-commit.c: generate commit view
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10 10
11static int files, slots; 11static int files, slots;
12static int total_adds, total_rems, max_changes; 12static int total_adds, total_rems, max_changes;
13static int lines_added, lines_removed; 13static int lines_added, lines_removed;
14 14
15static struct fileinfo { 15static struct fileinfo {
16 char status; 16 char status;
17 unsigned char old_sha1[20]; 17 unsigned char old_sha1[20];
18 unsigned char new_sha1[20]; 18 unsigned char new_sha1[20];
19 unsigned short old_mode; 19 unsigned short old_mode;
20 unsigned short new_mode; 20 unsigned short new_mode;
21 char *old_path; 21 char *old_path;
22 char *new_path; 22 char *new_path;
23 unsigned int added; 23 unsigned int added;
24 unsigned int removed; 24 unsigned int removed;
25} *items; 25} *items;
26 26
27 27
28void print_fileinfo(struct fileinfo *info) 28void print_fileinfo(struct fileinfo *info)
29{ 29{
30 char *query, *query2; 30 char *query, *query2;
31 char *class; 31 char *class;
32 double width;
33 32
34 switch (info->status) { 33 switch (info->status) {
35 case DIFF_STATUS_ADDED: 34 case DIFF_STATUS_ADDED:
36 class = "add"; 35 class = "add";
37 break; 36 break;
38 case DIFF_STATUS_COPIED: 37 case DIFF_STATUS_COPIED:
39 class = "cpy"; 38 class = "cpy";
40 break; 39 break;
41 case DIFF_STATUS_DELETED: 40 case DIFF_STATUS_DELETED:
42 class = "del"; 41 class = "del";
43 break; 42 break;
44 case DIFF_STATUS_MODIFIED: 43 case DIFF_STATUS_MODIFIED:
45 class = "upd"; 44 class = "upd";
46 break; 45 break;
47 case DIFF_STATUS_RENAMED: 46 case DIFF_STATUS_RENAMED:
48 class = "mov"; 47 class = "mov";
49 break; 48 break;
50 case DIFF_STATUS_TYPE_CHANGED: 49 case DIFF_STATUS_TYPE_CHANGED:
51 class = "typ"; 50 class = "typ";
52 break; 51 break;
53 case DIFF_STATUS_UNKNOWN: 52 case DIFF_STATUS_UNKNOWN:
54 class = "unk"; 53 class = "unk";
55 break; 54 break;
56 case DIFF_STATUS_UNMERGED: 55 case DIFF_STATUS_UNMERGED:
57 class = "stg"; 56 class = "stg";
58 break; 57 break;
59 default: 58 default:
60 die("bug: unhandled diff status %c", info->status); 59 die("bug: unhandled diff status %c", info->status);
61 } 60 }
62 61
63 html("<tr>"); 62 html("<tr>");
64 htmlf("<td class='mode'>"); 63 htmlf("<td class='mode'>");
65 if (is_null_sha1(info->new_sha1)) { 64 if (is_null_sha1(info->new_sha1)) {
66 html_filemode(info->old_mode); 65 html_filemode(info->old_mode);
67 } else { 66 } else {
68 html_filemode(info->new_mode); 67 html_filemode(info->new_mode);
69 } 68 }
70 69
71 if (info->old_mode != info->new_mode && 70 if (info->old_mode != info->new_mode &&
72 !is_null_sha1(info->old_sha1) && 71 !is_null_sha1(info->old_sha1) &&
73 !is_null_sha1(info->new_sha1)) { 72 !is_null_sha1(info->new_sha1)) {
74 html("<span class='modechange'>["); 73 html("<span class='modechange'>[");
75 html_filemode(info->old_mode); 74 html_filemode(info->old_mode);
76 html("]</span>"); 75 html("]</span>");
77 } 76 }
78 htmlf("</td><td class='%s'>", class); 77 htmlf("</td><td class='%s'>", class);
79 query = fmt("id=%s&id2=%s&path=%s", sha1_to_hex(info->old_sha1), 78 query = fmt("id=%s&id2=%s&path=%s", sha1_to_hex(info->old_sha1),
80 sha1_to_hex(info->new_sha1), info->new_path); 79 sha1_to_hex(info->new_sha1), info->new_path);
81 html_link_open(cgit_pageurl(cgit_query_repo, "diff", query), 80 html_link_open(cgit_pageurl(cgit_query_repo, "diff", query),
82 NULL, NULL); 81 NULL, NULL);
83 if (info->status == DIFF_STATUS_COPIED || 82 if (info->status == DIFF_STATUS_COPIED ||
84 info->status == DIFF_STATUS_RENAMED) { 83 info->status == DIFF_STATUS_RENAMED) {
85 html_txt(info->new_path); 84 html_txt(info->new_path);
86 htmlf("</a> (%s from ", info->status == DIFF_STATUS_COPIED ? 85 htmlf("</a> (%s from ", info->status == DIFF_STATUS_COPIED ?
87 "copied" : "renamed"); 86 "copied" : "renamed");
88 query2 = fmt("id=%s", sha1_to_hex(info->old_sha1)); 87 query2 = fmt("id=%s", sha1_to_hex(info->old_sha1));
89 html_link_open(cgit_pageurl(cgit_query_repo, "view", query2), 88 html_link_open(cgit_pageurl(cgit_query_repo, "view", query2),
90 NULL, NULL); 89 NULL, NULL);
91 html_txt(info->old_path); 90 html_txt(info->old_path);
92 html("</a>)"); 91 html("</a>)");
93 } else { 92 } else {
94 html_txt(info->new_path); 93 html_txt(info->new_path);
95 html("</a>"); 94 html("</a>");
96 } 95 }
97 html("</td><td class='right'>"); 96 html("</td><td class='right'>");
98 htmlf("%d", info->added + info->removed); 97 htmlf("%d", info->added + info->removed);
99
100 html("</td><td class='graph'>"); 98 html("</td><td class='graph'>");
101 width = (info->added + info->removed) * 100.0 / max_changes; 99 htmlf("<table width='%d%%'><tr>", (max_changes > 100 ? 100 : max_changes));
102 if (width < 0.1) 100 htmlf("<td class='add' style='width: %.1f%%;'/>",
103 width = 0.1; 101 info->added * 100.0 / max_changes);
104 html_link_open(cgit_pageurl(cgit_query_repo, "diff", query), 102 htmlf("<td class='rem' style='width: %.1f%%;'/>",
105 NULL, NULL); 103 info->removed * 100.0 / max_changes);
106 htmlf("<img src='/cgit/add.png' style='width: %.1f%%;'/>", 104 htmlf("<td class='none' style='width: %.1f%%;'/>",
107 info->added * width / (info->added + info->removed)); 105 (max_changes - info->removed - info->added) * 100.0 / max_changes);
108 htmlf("<img src='/cgit/del.png' style='width: %.1f%%;'/>", 106 html("</tr></table></a></td></tr>\n");
109 info->removed * width / (info->added + info->removed));
110 html("</a></td></tr>\n");
111} 107}
112 108
113void cgit_count_diff_lines(char *line, int len) 109void cgit_count_diff_lines(char *line, int len)
114{ 110{
115 if (line && (len > 0)) { 111 if (line && (len > 0)) {
116 if (line[0] == '+') 112 if (line[0] == '+')
117 lines_added++; 113 lines_added++;
118 else if (line[0] == '-') 114 else if (line[0] == '-')
119 lines_removed++; 115 lines_removed++;
120 } 116 }
121} 117}
122 118
123void inspect_filepair(struct diff_filepair *pair) 119void inspect_filepair(struct diff_filepair *pair)
124{ 120{
125 files++; 121 files++;
126 lines_added = 0; 122 lines_added = 0;
127 lines_removed = 0; 123 lines_removed = 0;
128 cgit_diff_files(pair->one->sha1, pair->two->sha1, cgit_count_diff_lines); 124 cgit_diff_files(pair->one->sha1, pair->two->sha1, cgit_count_diff_lines);
129 if (files >= slots) { 125 if (files >= slots) {
130 if (slots == 0) 126 if (slots == 0)
131 slots = 4; 127 slots = 4;
132 else 128 else
133 slots = slots * 2; 129 slots = slots * 2;
134 items = xrealloc(items, slots * sizeof(struct fileinfo)); 130 items = xrealloc(items, slots * sizeof(struct fileinfo));
135 } 131 }
136 items[files-1].status = pair->status; 132 items[files-1].status = pair->status;
137 hashcpy(items[files-1].old_sha1, pair->one->sha1); 133 hashcpy(items[files-1].old_sha1, pair->one->sha1);
138 hashcpy(items[files-1].new_sha1, pair->two->sha1); 134 hashcpy(items[files-1].new_sha1, pair->two->sha1);
139 items[files-1].old_mode = pair->one->mode; 135 items[files-1].old_mode = pair->one->mode;
140 items[files-1].new_mode = pair->two->mode; 136 items[files-1].new_mode = pair->two->mode;
141 items[files-1].old_path = xstrdup(pair->one->path); 137 items[files-1].old_path = xstrdup(pair->one->path);
142 items[files-1].new_path = xstrdup(pair->two->path); 138 items[files-1].new_path = xstrdup(pair->two->path);
143 items[files-1].added = lines_added; 139 items[files-1].added = lines_added;
144 items[files-1].removed = lines_removed; 140 items[files-1].removed = lines_removed;
145 if (lines_added + lines_removed > max_changes) 141 if (lines_added + lines_removed > max_changes)
146 max_changes = lines_added + lines_removed; 142 max_changes = lines_added + lines_removed;
147 total_adds += lines_added; 143 total_adds += lines_added;
148 total_rems += lines_removed; 144 total_rems += lines_removed;
149} 145}
150 146
151 147
152void cgit_print_commit(const char *hex) 148void cgit_print_commit(const char *hex)
153{ 149{
154 struct commit *commit, *parent; 150 struct commit *commit, *parent;
155 struct commitinfo *info; 151 struct commitinfo *info;
156 struct commit_list *p; 152 struct commit_list *p;
157 unsigned char sha1[20]; 153 unsigned char sha1[20];
158 char *query; 154 char *query;