Fossil SCM

merge trunk

jan.nijtmans 2012-11-30 16:09 ticket-d17d6e5b17 merge
Commit 380ad5312a13062a2a2ac6e08205976cc7cb9437
+5 -3
--- src/finfo.c
+++ src/finfo.c
@@ -345,11 +345,12 @@
345345
blob_appendf(&title, "History of ");
346346
hyperlinked_path(zFilename, &title, 0);
347347
@ <h2>%b(&title)</h2>
348348
blob_reset(&title);
349349
pGraph = graph_init();
350
- @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
350
+ @ <div id="canvas" style="position:relative;width:1px;height:1px;"
351
+ @ onclick="clickOnGraph(event)"></div>
351352
@ <table id="timelineTable" class="timelineTable">
352353
while( db_step(&q)==SQLITE_ROW ){
353354
const char *zDate = db_column_text(&q, 0);
354355
const char *zCom = db_column_text(&q, 1);
355356
const char *zUser = db_column_text(&q, 2);
@@ -370,11 +371,12 @@
370371
if( uBg ){
371372
zBgClr = hash_color(zUser);
372373
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
373374
zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
374375
}
375
- gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, 0);
376
+ gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr,
377
+ zUuid, 0);
376378
if( memcmp(zDate, zPrevDate, 10) ){
377379
sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
378380
@ <tr><td>
379381
@ <div class="divider">%s(zPrevDate)</div>
380382
@ </td><td></td><td></td></tr>
@@ -446,8 +448,8 @@
446448
@ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div>
447449
@ </td><td></td></tr>
448450
}
449451
}
450452
@ </table>
451
- timeline_output_graph_javascript(pGraph, 0);
453
+ timeline_output_graph_javascript(pGraph, 0, 1);
452454
style_footer();
453455
}
454456
--- src/finfo.c
+++ src/finfo.c
@@ -345,11 +345,12 @@
345 blob_appendf(&title, "History of ");
346 hyperlinked_path(zFilename, &title, 0);
347 @ <h2>%b(&title)</h2>
348 blob_reset(&title);
349 pGraph = graph_init();
350 @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
 
351 @ <table id="timelineTable" class="timelineTable">
352 while( db_step(&q)==SQLITE_ROW ){
353 const char *zDate = db_column_text(&q, 0);
354 const char *zCom = db_column_text(&q, 1);
355 const char *zUser = db_column_text(&q, 2);
@@ -370,11 +371,12 @@
370 if( uBg ){
371 zBgClr = hash_color(zUser);
372 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
373 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
374 }
375 gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, 0);
 
376 if( memcmp(zDate, zPrevDate, 10) ){
377 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
378 @ <tr><td>
379 @ <div class="divider">%s(zPrevDate)</div>
380 @ </td><td></td><td></td></tr>
@@ -446,8 +448,8 @@
446 @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div>
447 @ </td><td></td></tr>
448 }
449 }
450 @ </table>
451 timeline_output_graph_javascript(pGraph, 0);
452 style_footer();
453 }
454
--- src/finfo.c
+++ src/finfo.c
@@ -345,11 +345,12 @@
345 blob_appendf(&title, "History of ");
346 hyperlinked_path(zFilename, &title, 0);
347 @ <h2>%b(&title)</h2>
348 blob_reset(&title);
349 pGraph = graph_init();
350 @ <div id="canvas" style="position:relative;width:1px;height:1px;"
351 @ onclick="clickOnGraph(event)"></div>
352 @ <table id="timelineTable" class="timelineTable">
353 while( db_step(&q)==SQLITE_ROW ){
354 const char *zDate = db_column_text(&q, 0);
355 const char *zCom = db_column_text(&q, 1);
356 const char *zUser = db_column_text(&q, 2);
@@ -370,11 +371,12 @@
371 if( uBg ){
372 zBgClr = hash_color(zUser);
373 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
374 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr);
375 }
376 gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr,
377 zUuid, 0);
378 if( memcmp(zDate, zPrevDate, 10) ){
379 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
380 @ <tr><td>
381 @ <div class="divider">%s(zPrevDate)</div>
382 @ </td><td></td><td></td></tr>
@@ -446,8 +448,8 @@
448 @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div>
449 @ </td><td></td></tr>
450 }
451 }
452 @ </table>
453 timeline_output_graph_javascript(pGraph, 0, 1);
454 style_footer();
455 }
456
--- src/graph.c
+++ src/graph.c
@@ -34,10 +34,11 @@
3434
int rid; /* The rid for the check-in */
3535
i8 nParent; /* Number of parents */
3636
int *aParent; /* Array of parents. 0 element is primary .*/
3737
char *zBranch; /* Branch name */
3838
char *zBgClr; /* Background Color */
39
+ char zUuid[17]; /* Check-in for file ID */
3940
4041
GraphRow *pNext; /* Next row down in the list of all rows */
4142
GraphRow *pPrev; /* Previous row */
4243
4344
int idx; /* Row index. First is 1. 0 used for "none" */
@@ -175,10 +176,11 @@
175176
int rid, /* RID for the check-in */
176177
int nParent, /* Number of parents */
177178
int *aParent, /* Array of parents */
178179
const char *zBranch, /* Branch for this check-in */
179180
const char *zBgClr, /* Background color. NULL or "" for white. */
181
+ const char *zUuid, /* SHA1 hash of the object being graphed */
180182
int isLeaf /* True if this row is a leaf */
181183
){
182184
GraphRow *pRow;
183185
int nByte;
184186
@@ -188,10 +190,12 @@
188190
pRow = (GraphRow*)safeMalloc( nByte );
189191
pRow->aParent = (int*)&pRow[1];
190192
pRow->rid = rid;
191193
pRow->nParent = nParent;
192194
pRow->zBranch = persistBranchName(p, zBranch);
195
+ if( zUuid==0 ) zUuid = "";
196
+ sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
193197
pRow->isLeaf = isLeaf;
194198
memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
195199
if( zBgClr==0 || zBgClr[0]==0 ) zBgClr = "white";
196200
pRow->zBgClr = persistBranchName(p, zBgClr);
197201
memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
198202
--- src/graph.c
+++ src/graph.c
@@ -34,10 +34,11 @@
34 int rid; /* The rid for the check-in */
35 i8 nParent; /* Number of parents */
36 int *aParent; /* Array of parents. 0 element is primary .*/
37 char *zBranch; /* Branch name */
38 char *zBgClr; /* Background Color */
 
39
40 GraphRow *pNext; /* Next row down in the list of all rows */
41 GraphRow *pPrev; /* Previous row */
42
43 int idx; /* Row index. First is 1. 0 used for "none" */
@@ -175,10 +176,11 @@
175 int rid, /* RID for the check-in */
176 int nParent, /* Number of parents */
177 int *aParent, /* Array of parents */
178 const char *zBranch, /* Branch for this check-in */
179 const char *zBgClr, /* Background color. NULL or "" for white. */
 
180 int isLeaf /* True if this row is a leaf */
181 ){
182 GraphRow *pRow;
183 int nByte;
184
@@ -188,10 +190,12 @@
188 pRow = (GraphRow*)safeMalloc( nByte );
189 pRow->aParent = (int*)&pRow[1];
190 pRow->rid = rid;
191 pRow->nParent = nParent;
192 pRow->zBranch = persistBranchName(p, zBranch);
 
 
193 pRow->isLeaf = isLeaf;
194 memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
195 if( zBgClr==0 || zBgClr[0]==0 ) zBgClr = "white";
196 pRow->zBgClr = persistBranchName(p, zBgClr);
197 memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
198
--- src/graph.c
+++ src/graph.c
@@ -34,10 +34,11 @@
34 int rid; /* The rid for the check-in */
35 i8 nParent; /* Number of parents */
36 int *aParent; /* Array of parents. 0 element is primary .*/
37 char *zBranch; /* Branch name */
38 char *zBgClr; /* Background Color */
39 char zUuid[17]; /* Check-in for file ID */
40
41 GraphRow *pNext; /* Next row down in the list of all rows */
42 GraphRow *pPrev; /* Previous row */
43
44 int idx; /* Row index. First is 1. 0 used for "none" */
@@ -175,10 +176,11 @@
176 int rid, /* RID for the check-in */
177 int nParent, /* Number of parents */
178 int *aParent, /* Array of parents */
179 const char *zBranch, /* Branch for this check-in */
180 const char *zBgClr, /* Background color. NULL or "" for white. */
181 const char *zUuid, /* SHA1 hash of the object being graphed */
182 int isLeaf /* True if this row is a leaf */
183 ){
184 GraphRow *pRow;
185 int nByte;
186
@@ -188,10 +190,12 @@
190 pRow = (GraphRow*)safeMalloc( nByte );
191 pRow->aParent = (int*)&pRow[1];
192 pRow->rid = rid;
193 pRow->nParent = nParent;
194 pRow->zBranch = persistBranchName(p, zBranch);
195 if( zUuid==0 ) zUuid = "";
196 sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
197 pRow->isLeaf = isLeaf;
198 memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
199 if( zBgClr==0 || zBgClr[0]==0 ) zBgClr = "white";
200 pRow->zBgClr = persistBranchName(p, zBgClr);
201 memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
202
+67 -4
--- src/report.c
+++ src/report.c
@@ -694,11 +694,11 @@
694694
}
695695
}
696696
697697
/* The first time this routine is called, output a table header
698698
*/
699
- @ <tr>
699
+ @ <thead><tr>
700700
zTid = 0;
701701
for(i=0; i<nArg; i++){
702702
char *zName = azName[i];
703703
if( i==pState->iBg ) continue;
704704
if( pState->iNewRow>=0 && i>=pState->iNewRow ){
@@ -716,11 +716,11 @@
716716
}
717717
}
718718
if( g.perm.Write && zTid ){
719719
@ <th>&nbsp;</th>
720720
}
721
- @ </tr>
721
+ @ </tr></thead><tbody>
722722
}
723723
if( azArg==0 ){
724724
@ <tr><td colspan="%d(pState->nCol)">
725725
@ <i>No records match the report criteria</i>
726726
@ </td></tr>
@@ -914,10 +914,71 @@
914914
rc = sqlite3_finalize(pStmt);
915915
fossil_free(azVals);
916916
return rc;
917917
}
918918
919
+/*
920
+** Output Javascript code that will enables sorting of the table with
921
+** the id zTableId by clicking.
922
+**
923
+** The javascript is derived from:
924
+**
925
+** http://www.webtoolkit.info/sortable-html-table.html
926
+**
927
+*/
928
+static void output_table_sorting_javascript(const char *zTableId){
929
+ @ <script>
930
+ @ function SortableTable(tableEl){
931
+ @ this.tbody = tableEl.getElementsByTagName('tbody');
932
+ @ this.sort = function (cell) {
933
+ @ var column = cell.cellIndex;
934
+ @ this.sortIndex = column;
935
+ @ var newRows = new Array();
936
+ @ for (j = 0; j < this.tbody[0].rows.length; j++) {
937
+ @ newRows[j] = this.tbody[0].rows[j];
938
+ @ }
939
+ @ newRows.sort(this.sortText);
940
+ @ if (cell.getAttribute("sortdir") == 'down') {
941
+ @ newRows.reverse();
942
+ @ cell.setAttribute('sortdir','up');
943
+ @ } else {
944
+ @ cell.setAttribute('sortdir','down');
945
+ @ }
946
+ @ for (i=0;i<newRows.length;i++) {
947
+ @ this.tbody[0].appendChild(newRows[i]);
948
+ @ }
949
+ @ }
950
+ @ this.sortText = function(a,b) {
951
+ @ var i = thisObject.sortIndex;
952
+ @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
953
+ @ bb = b.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
954
+ @ if(aa==bb) return 0;
955
+ @ if(aa<bb) return -1;
956
+ @ return 1;
957
+ @ }
958
+ @ var thisObject = this;
959
+ @ var x = tableEl.getElementsByTagName('thead');
960
+ @ if(!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length>0)){
961
+ @ return;
962
+ @ }
963
+ @ if(x && x[0].rows && x[0].rows.length > 0) {
964
+ @ var sortRow = x[0].rows[0];
965
+ @ } else {
966
+ @ return;
967
+ @ }
968
+ @ for (var i=0; i<sortRow.cells.length; i++) {
969
+ @ sortRow.cells[i].sTable = this;
970
+ @ sortRow.cells[i].onclick = function () {
971
+ @ this.sTable.sort(this);
972
+ @ return false;
973
+ @ }
974
+ @ }
975
+ @ }
976
+ @ var t = new SortableTable(gebi("%s(zTableId)"));
977
+ @ </script>
978
+}
979
+
919980
920981
/*
921982
** WEBPAGE: /rptview
922983
**
923984
** Generate a report. The rn query parameter is the report number
@@ -992,22 +1053,24 @@
9921053
"%s/tktnew", g.zTop);
9931054
}
9941055
style_header(zTitle);
9951056
output_color_key(zClrKey, 1,
9961057
"border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
997
- @ <table border="1" cellpadding="2" cellspacing="0" class="report">
1058
+ @ <table border="1" cellpadding="2" cellspacing="0" class="report"
1059
+ @ id="reportTable">
9981060
sState.rn = rn;
9991061
sState.nCount = 0;
10001062
report_restrict_sql(&zErr1);
10011063
sqlite3_exec_readonly(g.db, zSql, generate_html, &sState, &zErr2);
10021064
report_unrestrict_sql();
1003
- @ </table>
1065
+ @ </tbody></table>
10041066
if( zErr1 ){
10051067
@ <p class="reportError">Error: %h(zErr1)</p>
10061068
}else if( zErr2 ){
10071069
@ <p class="reportError">Error: %h(zErr2)</p>
10081070
}
1071
+ output_table_sorting_javascript("reportTable");
10091072
style_footer();
10101073
}else{
10111074
report_restrict_sql(&zErr1);
10121075
sqlite3_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
10131076
report_unrestrict_sql();
10141077
--- src/report.c
+++ src/report.c
@@ -694,11 +694,11 @@
694 }
695 }
696
697 /* The first time this routine is called, output a table header
698 */
699 @ <tr>
700 zTid = 0;
701 for(i=0; i<nArg; i++){
702 char *zName = azName[i];
703 if( i==pState->iBg ) continue;
704 if( pState->iNewRow>=0 && i>=pState->iNewRow ){
@@ -716,11 +716,11 @@
716 }
717 }
718 if( g.perm.Write && zTid ){
719 @ <th>&nbsp;</th>
720 }
721 @ </tr>
722 }
723 if( azArg==0 ){
724 @ <tr><td colspan="%d(pState->nCol)">
725 @ <i>No records match the report criteria</i>
726 @ </td></tr>
@@ -914,10 +914,71 @@
914 rc = sqlite3_finalize(pStmt);
915 fossil_free(azVals);
916 return rc;
917 }
918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
919
920 /*
921 ** WEBPAGE: /rptview
922 **
923 ** Generate a report. The rn query parameter is the report number
@@ -992,22 +1053,24 @@
992 "%s/tktnew", g.zTop);
993 }
994 style_header(zTitle);
995 output_color_key(zClrKey, 1,
996 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
997 @ <table border="1" cellpadding="2" cellspacing="0" class="report">
 
998 sState.rn = rn;
999 sState.nCount = 0;
1000 report_restrict_sql(&zErr1);
1001 sqlite3_exec_readonly(g.db, zSql, generate_html, &sState, &zErr2);
1002 report_unrestrict_sql();
1003 @ </table>
1004 if( zErr1 ){
1005 @ <p class="reportError">Error: %h(zErr1)</p>
1006 }else if( zErr2 ){
1007 @ <p class="reportError">Error: %h(zErr2)</p>
1008 }
 
1009 style_footer();
1010 }else{
1011 report_restrict_sql(&zErr1);
1012 sqlite3_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
1013 report_unrestrict_sql();
1014
--- src/report.c
+++ src/report.c
@@ -694,11 +694,11 @@
694 }
695 }
696
697 /* The first time this routine is called, output a table header
698 */
699 @ <thead><tr>
700 zTid = 0;
701 for(i=0; i<nArg; i++){
702 char *zName = azName[i];
703 if( i==pState->iBg ) continue;
704 if( pState->iNewRow>=0 && i>=pState->iNewRow ){
@@ -716,11 +716,11 @@
716 }
717 }
718 if( g.perm.Write && zTid ){
719 @ <th>&nbsp;</th>
720 }
721 @ </tr></thead><tbody>
722 }
723 if( azArg==0 ){
724 @ <tr><td colspan="%d(pState->nCol)">
725 @ <i>No records match the report criteria</i>
726 @ </td></tr>
@@ -914,10 +914,71 @@
914 rc = sqlite3_finalize(pStmt);
915 fossil_free(azVals);
916 return rc;
917 }
918
919 /*
920 ** Output Javascript code that will enables sorting of the table with
921 ** the id zTableId by clicking.
922 **
923 ** The javascript is derived from:
924 **
925 ** http://www.webtoolkit.info/sortable-html-table.html
926 **
927 */
928 static void output_table_sorting_javascript(const char *zTableId){
929 @ <script>
930 @ function SortableTable(tableEl){
931 @ this.tbody = tableEl.getElementsByTagName('tbody');
932 @ this.sort = function (cell) {
933 @ var column = cell.cellIndex;
934 @ this.sortIndex = column;
935 @ var newRows = new Array();
936 @ for (j = 0; j < this.tbody[0].rows.length; j++) {
937 @ newRows[j] = this.tbody[0].rows[j];
938 @ }
939 @ newRows.sort(this.sortText);
940 @ if (cell.getAttribute("sortdir") == 'down') {
941 @ newRows.reverse();
942 @ cell.setAttribute('sortdir','up');
943 @ } else {
944 @ cell.setAttribute('sortdir','down');
945 @ }
946 @ for (i=0;i<newRows.length;i++) {
947 @ this.tbody[0].appendChild(newRows[i]);
948 @ }
949 @ }
950 @ this.sortText = function(a,b) {
951 @ var i = thisObject.sortIndex;
952 @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
953 @ bb = b.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
954 @ if(aa==bb) return 0;
955 @ if(aa<bb) return -1;
956 @ return 1;
957 @ }
958 @ var thisObject = this;
959 @ var x = tableEl.getElementsByTagName('thead');
960 @ if(!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length>0)){
961 @ return;
962 @ }
963 @ if(x && x[0].rows && x[0].rows.length > 0) {
964 @ var sortRow = x[0].rows[0];
965 @ } else {
966 @ return;
967 @ }
968 @ for (var i=0; i<sortRow.cells.length; i++) {
969 @ sortRow.cells[i].sTable = this;
970 @ sortRow.cells[i].onclick = function () {
971 @ this.sTable.sort(this);
972 @ return false;
973 @ }
974 @ }
975 @ }
976 @ var t = new SortableTable(gebi("%s(zTableId)"));
977 @ </script>
978 }
979
980
981 /*
982 ** WEBPAGE: /rptview
983 **
984 ** Generate a report. The rn query parameter is the report number
@@ -992,22 +1053,24 @@
1053 "%s/tktnew", g.zTop);
1054 }
1055 style_header(zTitle);
1056 output_color_key(zClrKey, 1,
1057 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1058 @ <table border="1" cellpadding="2" cellspacing="0" class="report"
1059 @ id="reportTable">
1060 sState.rn = rn;
1061 sState.nCount = 0;
1062 report_restrict_sql(&zErr1);
1063 sqlite3_exec_readonly(g.db, zSql, generate_html, &sState, &zErr2);
1064 report_unrestrict_sql();
1065 @ </tbody></table>
1066 if( zErr1 ){
1067 @ <p class="reportError">Error: %h(zErr1)</p>
1068 }else if( zErr2 ){
1069 @ <p class="reportError">Error: %h(zErr2)</p>
1070 }
1071 output_table_sorting_javascript("reportTable");
1072 style_footer();
1073 }else{
1074 report_restrict_sql(&zErr1);
1075 sqlite3_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
1076 report_unrestrict_sql();
1077
+46 -5
--- src/timeline.c
+++ src/timeline.c
@@ -211,11 +211,12 @@
211211
if( tmFlags & TIMELINE_GRAPH ){
212212
pGraph = graph_init();
213213
/* style is not moved to css, because this is
214214
** a technical div for the timeline graph
215215
*/
216
- @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
216
+ @ <div id="canvas" style="position:relative;width:1px;height:1px;"
217
+ @ onclick="clickOnGraph(event)"></div>
217218
}
218219
db_static_prepare(&qbranch,
219220
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
220221
TAG_BRANCH
221222
);
@@ -311,11 +312,12 @@
311312
db_bind_int(&qparent, ":rid", rid);
312313
while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){
313314
aParent[nParent++] = db_column_int(&qparent, 0);
314315
}
315316
db_reset(&qparent);
316
- gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr, isLeaf);
317
+ gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
318
+ zUuid, isLeaf);
317319
db_reset(&qbranch);
318320
@ <div id="m%d(gidx)"></div>
319321
}
320322
@</td>
321323
if( zBgClr && zBgClr[0] ){
@@ -491,18 +493,22 @@
491493
@ </td><td></td></tr>
492494
}
493495
}
494496
@ </table>
495497
if( fchngQueryInit ) db_finalize(&fchngQuery);
496
- timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
498
+ timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0, 0);
497499
}
498500
499501
/*
500502
** Generate all of the necessary javascript to generate a timeline
501503
** graph.
502504
*/
503
-void timeline_output_graph_javascript(GraphContext *pGraph, int omitDescenders){
505
+void timeline_output_graph_javascript(
506
+ GraphContext *pGraph, /* The graph to be displayed */
507
+ int omitDescenders, /* True to omit descenders */
508
+ int fileDiff /* True for file diff. False for check-in diff */
509
+){
504510
if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){
505511
GraphRow *pRow;
506512
int i;
507513
char cSep;
508514
@ <script type="text/JavaScript">
@@ -535,10 +541,11 @@
535541
** mi: "merge-in". An array of integer x-coordinates from which
536542
** merge arrows should be drawn into this node. If the value is
537543
** negative, then the x-coordinate is the absolute value of mi[]
538544
** and a thin merge-arrow descender is drawn to the bottom of
539545
** the screen.
546
+ ** h: The SHA1 hash of the object being graphed
540547
*/
541548
cgi_printf("var rowinfo = [\n");
542549
for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
543550
int mo = pRow->mergeOut;
544551
if( mo<0 ){
@@ -576,11 +583,11 @@
576583
cgi_printf("%c%d", cSep, mi);
577584
cSep = ',';
578585
}
579586
}
580587
if( cSep=='[' ) cgi_printf("[");
581
- cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
588
+ cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
582589
}
583590
cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
584591
graph_free(pGraph);
585592
@ var canvasDiv = gebi("canvas");
586593
#if 0
@@ -598,10 +605,11 @@
598605
@ n.style.top = y0+"px";
599606
@ n.style.width = w+"px";
600607
@ n.style.height = h+"px";
601608
@ n.style.backgroundColor = color;
602609
@ canvasDiv.appendChild(n);
610
+ @ return n;
603611
@ }
604612
@ function absoluteY(id){
605613
@ var obj = gebi(id);
606614
@ if( !obj ) return;
607615
@ var top = 0;
@@ -699,10 +707,12 @@
699707
@ }else{
700708
@ drawThinArrow(y0,mx,p.x-5);
701709
@ }
702710
@ }
703711
@ }
712
+ @ var selBox = null;
713
+ @ var selRow = null;
704714
@ function renderGraph(){
705715
@ var canvasDiv = gebi("canvas");
706716
@ while( canvasDiv.hasChildNodes() ){
707717
@ canvasDiv.removeChild(canvasDiv.firstChild);
708718
@ }
@@ -736,10 +746,41 @@
736746
@ };
737747
@ }
738748
#endif
739749
@ for(var i in rowinfo){
740750
@ drawNode(rowinfo[i], left, btm);
751
+ @ }
752
+ @ if( selRow!=null ) clickOnRow(selRow);
753
+ @ }
754
+ @ function clickOnGraph(event){
755
+ @ var x=event.clientX-absoluteX("canvas")+window.pageXOffset;
756
+ @ var y=event.clientY-absoluteY("canvas")+window.pageYOffset;
757
+ @ for(var i in rowinfo){
758
+ @ p = rowinfo[i];
759
+ @ if( p.y<y-10 ) continue;
760
+ @ if( p.y>y+10 ) break;
761
+ @ if( p.x>x-10 && p.x<x+10 ){
762
+ @ clickOnRow(p);
763
+ @ break;
764
+ @ }
765
+ @ }
766
+ @ }
767
+ @ function clickOnRow(p){
768
+ @ if( selRow==null ){
769
+ @ selBox = drawBox("red",p.x-2,p.y-2,p.x+3,p.y+3);
770
+ @ selRow = p;
771
+ @ }else if( selRow==p ){
772
+ @ var canvasDiv = gebi("canvas");
773
+ @ canvasDiv.removeChild(selBox);
774
+ @ selBox = null;
775
+ @ selRow = null;
776
+ @ }else{
777
+ if( fileDiff ){
778
+ @ location.href="%R/fdiff?v1="+selRow.h+"&v2="+p.h;
779
+ }else{
780
+ @ location.href="%R/vdiff?from="+selRow.h+"&to="+p.h;
781
+ }
741782
@ }
742783
@ }
743784
@ var lastId = "m"+rowinfo[rowinfo.length-1].id;
744785
@ var lastY = 0;
745786
@ function checkHeight(){
746787
--- src/timeline.c
+++ src/timeline.c
@@ -211,11 +211,12 @@
211 if( tmFlags & TIMELINE_GRAPH ){
212 pGraph = graph_init();
213 /* style is not moved to css, because this is
214 ** a technical div for the timeline graph
215 */
216 @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
 
217 }
218 db_static_prepare(&qbranch,
219 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
220 TAG_BRANCH
221 );
@@ -311,11 +312,12 @@
311 db_bind_int(&qparent, ":rid", rid);
312 while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){
313 aParent[nParent++] = db_column_int(&qparent, 0);
314 }
315 db_reset(&qparent);
316 gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr, isLeaf);
 
317 db_reset(&qbranch);
318 @ <div id="m%d(gidx)"></div>
319 }
320 @</td>
321 if( zBgClr && zBgClr[0] ){
@@ -491,18 +493,22 @@
491 @ </td><td></td></tr>
492 }
493 }
494 @ </table>
495 if( fchngQueryInit ) db_finalize(&fchngQuery);
496 timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
497 }
498
499 /*
500 ** Generate all of the necessary javascript to generate a timeline
501 ** graph.
502 */
503 void timeline_output_graph_javascript(GraphContext *pGraph, int omitDescenders){
 
 
 
 
504 if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){
505 GraphRow *pRow;
506 int i;
507 char cSep;
508 @ <script type="text/JavaScript">
@@ -535,10 +541,11 @@
535 ** mi: "merge-in". An array of integer x-coordinates from which
536 ** merge arrows should be drawn into this node. If the value is
537 ** negative, then the x-coordinate is the absolute value of mi[]
538 ** and a thin merge-arrow descender is drawn to the bottom of
539 ** the screen.
 
540 */
541 cgi_printf("var rowinfo = [\n");
542 for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
543 int mo = pRow->mergeOut;
544 if( mo<0 ){
@@ -576,11 +583,11 @@
576 cgi_printf("%c%d", cSep, mi);
577 cSep = ',';
578 }
579 }
580 if( cSep=='[' ) cgi_printf("[");
581 cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
582 }
583 cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
584 graph_free(pGraph);
585 @ var canvasDiv = gebi("canvas");
586 #if 0
@@ -598,10 +605,11 @@
598 @ n.style.top = y0+"px";
599 @ n.style.width = w+"px";
600 @ n.style.height = h+"px";
601 @ n.style.backgroundColor = color;
602 @ canvasDiv.appendChild(n);
 
603 @ }
604 @ function absoluteY(id){
605 @ var obj = gebi(id);
606 @ if( !obj ) return;
607 @ var top = 0;
@@ -699,10 +707,12 @@
699 @ }else{
700 @ drawThinArrow(y0,mx,p.x-5);
701 @ }
702 @ }
703 @ }
 
 
704 @ function renderGraph(){
705 @ var canvasDiv = gebi("canvas");
706 @ while( canvasDiv.hasChildNodes() ){
707 @ canvasDiv.removeChild(canvasDiv.firstChild);
708 @ }
@@ -736,10 +746,41 @@
736 @ };
737 @ }
738 #endif
739 @ for(var i in rowinfo){
740 @ drawNode(rowinfo[i], left, btm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
741 @ }
742 @ }
743 @ var lastId = "m"+rowinfo[rowinfo.length-1].id;
744 @ var lastY = 0;
745 @ function checkHeight(){
746
--- src/timeline.c
+++ src/timeline.c
@@ -211,11 +211,12 @@
211 if( tmFlags & TIMELINE_GRAPH ){
212 pGraph = graph_init();
213 /* style is not moved to css, because this is
214 ** a technical div for the timeline graph
215 */
216 @ <div id="canvas" style="position:relative;width:1px;height:1px;"
217 @ onclick="clickOnGraph(event)"></div>
218 }
219 db_static_prepare(&qbranch,
220 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
221 TAG_BRANCH
222 );
@@ -311,11 +312,12 @@
312 db_bind_int(&qparent, ":rid", rid);
313 while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){
314 aParent[nParent++] = db_column_int(&qparent, 0);
315 }
316 db_reset(&qparent);
317 gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
318 zUuid, isLeaf);
319 db_reset(&qbranch);
320 @ <div id="m%d(gidx)"></div>
321 }
322 @</td>
323 if( zBgClr && zBgClr[0] ){
@@ -491,18 +493,22 @@
493 @ </td><td></td></tr>
494 }
495 }
496 @ </table>
497 if( fchngQueryInit ) db_finalize(&fchngQuery);
498 timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0, 0);
499 }
500
501 /*
502 ** Generate all of the necessary javascript to generate a timeline
503 ** graph.
504 */
505 void timeline_output_graph_javascript(
506 GraphContext *pGraph, /* The graph to be displayed */
507 int omitDescenders, /* True to omit descenders */
508 int fileDiff /* True for file diff. False for check-in diff */
509 ){
510 if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){
511 GraphRow *pRow;
512 int i;
513 char cSep;
514 @ <script type="text/JavaScript">
@@ -535,10 +541,11 @@
541 ** mi: "merge-in". An array of integer x-coordinates from which
542 ** merge arrows should be drawn into this node. If the value is
543 ** negative, then the x-coordinate is the absolute value of mi[]
544 ** and a thin merge-arrow descender is drawn to the bottom of
545 ** the screen.
546 ** h: The SHA1 hash of the object being graphed
547 */
548 cgi_printf("var rowinfo = [\n");
549 for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
550 int mo = pRow->mergeOut;
551 if( mo<0 ){
@@ -576,11 +583,11 @@
583 cgi_printf("%c%d", cSep, mi);
584 cSep = ',';
585 }
586 }
587 if( cSep=='[' ) cgi_printf("[");
588 cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
589 }
590 cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
591 graph_free(pGraph);
592 @ var canvasDiv = gebi("canvas");
593 #if 0
@@ -598,10 +605,11 @@
605 @ n.style.top = y0+"px";
606 @ n.style.width = w+"px";
607 @ n.style.height = h+"px";
608 @ n.style.backgroundColor = color;
609 @ canvasDiv.appendChild(n);
610 @ return n;
611 @ }
612 @ function absoluteY(id){
613 @ var obj = gebi(id);
614 @ if( !obj ) return;
615 @ var top = 0;
@@ -699,10 +707,12 @@
707 @ }else{
708 @ drawThinArrow(y0,mx,p.x-5);
709 @ }
710 @ }
711 @ }
712 @ var selBox = null;
713 @ var selRow = null;
714 @ function renderGraph(){
715 @ var canvasDiv = gebi("canvas");
716 @ while( canvasDiv.hasChildNodes() ){
717 @ canvasDiv.removeChild(canvasDiv.firstChild);
718 @ }
@@ -736,10 +746,41 @@
746 @ };
747 @ }
748 #endif
749 @ for(var i in rowinfo){
750 @ drawNode(rowinfo[i], left, btm);
751 @ }
752 @ if( selRow!=null ) clickOnRow(selRow);
753 @ }
754 @ function clickOnGraph(event){
755 @ var x=event.clientX-absoluteX("canvas")+window.pageXOffset;
756 @ var y=event.clientY-absoluteY("canvas")+window.pageYOffset;
757 @ for(var i in rowinfo){
758 @ p = rowinfo[i];
759 @ if( p.y<y-10 ) continue;
760 @ if( p.y>y+10 ) break;
761 @ if( p.x>x-10 && p.x<x+10 ){
762 @ clickOnRow(p);
763 @ break;
764 @ }
765 @ }
766 @ }
767 @ function clickOnRow(p){
768 @ if( selRow==null ){
769 @ selBox = drawBox("red",p.x-2,p.y-2,p.x+3,p.y+3);
770 @ selRow = p;
771 @ }else if( selRow==p ){
772 @ var canvasDiv = gebi("canvas");
773 @ canvasDiv.removeChild(selBox);
774 @ selBox = null;
775 @ selRow = null;
776 @ }else{
777 if( fileDiff ){
778 @ location.href="%R/fdiff?v1="+selRow.h+"&v2="+p.h;
779 }else{
780 @ location.href="%R/vdiff?from="+selRow.h+"&to="+p.h;
781 }
782 @ }
783 @ }
784 @ var lastId = "m"+rowinfo[rowinfo.length-1].id;
785 @ var lastY = 0;
786 @ function checkHeight(){
787
--- test/cmdline.test
+++ test/cmdline.test
@@ -20,11 +20,11 @@
2020
2121
proc cmd-line {testname args} {
2222
set i 1
2323
foreach {cmdline result} $args {
2424
fossil test-echo $cmdline
25
- test cmd-line-$testname.$i {[lrange [split $::RESULT \n] 2 end]=="\{argv\[2\] = \[$result\]\}"}
25
+ test cmd-line-$testname.$i {[lrange [split $::RESULT \n] 3 end]=="\{argv\[2\] = \[$result\]\}"}
2626
incr i
2727
}
2828
}
2929
cmd-line 100 abc abc a\"bc a\"bc \"abc\" \"abc\"
3030
cmd-line 101 * * *.* *.*
3131
--- test/cmdline.test
+++ test/cmdline.test
@@ -20,11 +20,11 @@
20
21 proc cmd-line {testname args} {
22 set i 1
23 foreach {cmdline result} $args {
24 fossil test-echo $cmdline
25 test cmd-line-$testname.$i {[lrange [split $::RESULT \n] 2 end]=="\{argv\[2\] = \[$result\]\}"}
26 incr i
27 }
28 }
29 cmd-line 100 abc abc a\"bc a\"bc \"abc\" \"abc\"
30 cmd-line 101 * * *.* *.*
31
--- test/cmdline.test
+++ test/cmdline.test
@@ -20,11 +20,11 @@
20
21 proc cmd-line {testname args} {
22 set i 1
23 foreach {cmdline result} $args {
24 fossil test-echo $cmdline
25 test cmd-line-$testname.$i {[lrange [split $::RESULT \n] 3 end]=="\{argv\[2\] = \[$result\]\}"}
26 incr i
27 }
28 }
29 cmd-line 100 abc abc a\"bc a\"bc \"abc\" \"abc\"
30 cmd-line 101 * * *.* *.*
31

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button