Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch click-graph-to-diff Excluding Merge-Ins
This is equivalent to a diff from 3e0f48c76d to 7b3def02ed
2012-11-30
| ||
15:22 | Click on the timeline graph once to select a node. Click on a different node to see a diff between the two nodes. Click on the selected node to unselect it. check-in: 5bff5e5cc5 user: drh tags: trunk | |
14:09 | fix testcase check-in: e08073d333 user: jan.nijtmans tags: trunk | |
13:27 | (experimental) command-line expansion for MinGW-w64. Should work on MSVC as well. Doesn't work with MinGW. check-in: b1036fe5bf user: jan.nijtmans tags: cmdline-expansion | |
12:36 | merge trunk. appears to work well again. check-in: 0c65916136 user: jan.nijtmans tags: ticket-d17d6e5b17 | |
03:33 | Fix the click coordinates so that they work even when the page has been scrolled. Closed-Leaf check-in: 7b3def02ed user: drh tags: click-graph-to-diff | |
03:14 | Fix compiler warning. check-in: 95cce92af0 user: drh tags: click-graph-to-diff | |
03:10 | Click on the timeline graph once to select a node. Click on a different node to see a diff between the two. Click on the selected node to undo the selection. Works with check-in timelines and file timelines. check-in: a7dde41fec user: drh tags: click-graph-to-diff | |
00:40 | Move the new utf8.c file into alphabetical order in the makemake.tcl tool. check-in: 3e0f48c76d user: mistachkin tags: trunk | |
00:38 | Update custom MinGW makefile with recent changes. check-in: 2d754ca84b user: mistachkin tags: trunk | |
Changes to src/finfo.c.
343 343 blob_reset(&sql); 344 344 blob_zero(&title); 345 345 blob_appendf(&title, "History of "); 346 346 hyperlinked_path(zFilename, &title, 0); 347 347 @ <h2>%b(&title)</h2> 348 348 blob_reset(&title); 349 349 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> 351 352 @ <table id="timelineTable" class="timelineTable"> 352 353 while( db_step(&q)==SQLITE_ROW ){ 353 354 const char *zDate = db_column_text(&q, 0); 354 355 const char *zCom = db_column_text(&q, 1); 355 356 const char *zUser = db_column_text(&q, 2); 356 357 int fpid = db_column_int(&q, 3); 357 358 int frid = db_column_int(&q, 4); ................................................................................ 368 369 char zShortCkin[20]; 369 370 if( zBr==0 ) zBr = "trunk"; 370 371 if( uBg ){ 371 372 zBgClr = hash_color(zUser); 372 373 }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ 373 374 zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); 374 375 } 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); 376 378 if( memcmp(zDate, zPrevDate, 10) ){ 377 379 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); 378 380 @ <tr><td> 379 381 @ <div class="divider">%s(zPrevDate)</div> 380 382 @ </td><td></td><td></td></tr> 381 383 } 382 384 memcpy(zTime, &zDate[11], 5); ................................................................................ 444 446 }else{ 445 447 @ <tr><td></td><td> 446 448 @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> 447 449 @ </td><td></td></tr> 448 450 } 449 451 } 450 452 @ </table> 451 - timeline_output_graph_javascript(pGraph, 0); 453 + timeline_output_graph_javascript(pGraph, 0, 1); 452 454 style_footer(); 453 455 }
Changes to src/graph.c.
32 32 */ 33 33 struct GraphRow { 34 34 int rid; /* The rid for the check-in */ 35 35 i8 nParent; /* Number of parents */ 36 36 int *aParent; /* Array of parents. 0 element is primary .*/ 37 37 char *zBranch; /* Branch name */ 38 38 char *zBgClr; /* Background Color */ 39 + char zUuid[17]; /* Check-in for file ID */ 39 40 40 41 GraphRow *pNext; /* Next row down in the list of all rows */ 41 42 GraphRow *pPrev; /* Previous row */ 42 43 43 44 int idx; /* Row index. First is 1. 0 used for "none" */ 44 45 int idxTop; /* Direct descendent highest up on the graph */ 45 46 GraphRow *pChild; /* Child immediately above this node */ ................................................................................ 173 174 int graph_add_row( 174 175 GraphContext *p, /* The context to which the row is added */ 175 176 int rid, /* RID for the check-in */ 176 177 int nParent, /* Number of parents */ 177 178 int *aParent, /* Array of parents */ 178 179 const char *zBranch, /* Branch for this check-in */ 179 180 const char *zBgClr, /* Background color. NULL or "" for white. */ 181 + const char *zUuid, /* SHA1 hash of the object being graphed */ 180 182 int isLeaf /* True if this row is a leaf */ 181 183 ){ 182 184 GraphRow *pRow; 183 185 int nByte; 184 186 185 187 if( p->nErr ) return 0; 186 188 nByte = sizeof(GraphRow); 187 189 nByte += sizeof(pRow->aParent[0])*nParent; 188 190 pRow = (GraphRow*)safeMalloc( nByte ); 189 191 pRow->aParent = (int*)&pRow[1]; 190 192 pRow->rid = rid; 191 193 pRow->nParent = nParent; 192 194 pRow->zBranch = persistBranchName(p, zBranch); 195 + if( zUuid==0 ) zUuid = ""; 196 + sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid); 193 197 pRow->isLeaf = isLeaf; 194 198 memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser)); 195 199 if( zBgClr==0 || zBgClr[0]==0 ) zBgClr = "white"; 196 200 pRow->zBgClr = persistBranchName(p, zBgClr); 197 201 memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent); 198 202 if( p->pFirst==0 ){ 199 203 p->pFirst = pRow;
Changes to src/timeline.c.
209 209 zPrevDate[0] = 0; 210 210 mxWikiLen = db_get_int("timeline-max-comment", 0); 211 211 if( tmFlags & TIMELINE_GRAPH ){ 212 212 pGraph = graph_init(); 213 213 /* style is not moved to css, because this is 214 214 ** a technical div for the timeline graph 215 215 */ 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> 217 218 } 218 219 db_static_prepare(&qbranch, 219 220 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid", 220 221 TAG_BRANCH 221 222 ); 222 223 223 224 @ <table id="timelineTable" class="timelineTable"> ................................................................................ 309 310 " ORDER BY isprim DESC /*sort*/" 310 311 ); 311 312 db_bind_int(&qparent, ":rid", rid); 312 313 while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){ 313 314 aParent[nParent++] = db_column_int(&qparent, 0); 314 315 } 315 316 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); 317 319 db_reset(&qbranch); 318 320 @ <div id="m%d(gidx)"></div> 319 321 } 320 322 @</td> 321 323 if( zBgClr && zBgClr[0] ){ 322 324 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> 323 325 }else{ ................................................................................ 489 491 @ <tr><td></td><td> 490 492 @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div> 491 493 @ </td><td></td></tr> 492 494 } 493 495 } 494 496 @ </table> 495 497 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); 497 499 } 498 500 499 501 /* 500 502 ** Generate all of the necessary javascript to generate a timeline 501 503 ** graph. 502 504 */ 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 +){ 504 510 if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){ 505 511 GraphRow *pRow; 506 512 int i; 507 513 char cSep; 508 514 @ <script type="text/JavaScript"> 509 515 @ /* <![CDATA[ */ 510 516 ................................................................................ 533 539 ** is the rail on which the riser should run and the second integer 534 540 ** is the id of the node upto which the riser should run. 535 541 ** mi: "merge-in". An array of integer x-coordinates from which 536 542 ** merge arrows should be drawn into this node. If the value is 537 543 ** negative, then the x-coordinate is the absolute value of mi[] 538 544 ** and a thin merge-arrow descender is drawn to the bottom of 539 545 ** the screen. 546 + ** h: The SHA1 hash of the object being graphed 540 547 */ 541 548 cgi_printf("var rowinfo = [\n"); 542 549 for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){ 543 550 int mo = pRow->mergeOut; 544 551 if( mo<0 ){ 545 552 mo = 0; 546 553 }else{ ................................................................................ 574 581 int mi = i*20 - 8 + 4*pRow->mergeIn[i]; 575 582 if( pRow->mergeDown & (1<<i) ) mi = -mi; 576 583 cgi_printf("%c%d", cSep, mi); 577 584 cSep = ','; 578 585 } 579 586 } 580 587 if( cSep=='[' ) cgi_printf("["); 581 - cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n"); 588 + cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n"); 582 589 } 583 590 cgi_printf("var nrail = %d\n", pGraph->mxRail+1); 584 591 graph_free(pGraph); 585 592 @ var canvasDiv = gebi("canvas"); 586 593 #if 0 587 594 @ var realCanvas = null; 588 595 #endif ................................................................................ 596 603 @ n.style.overflow = "hidden"; 597 604 @ n.style.left = x0+"px"; 598 605 @ n.style.top = y0+"px"; 599 606 @ n.style.width = w+"px"; 600 607 @ n.style.height = h+"px"; 601 608 @ n.style.backgroundColor = color; 602 609 @ canvasDiv.appendChild(n); 610 + @ return n; 603 611 @ } 604 612 @ function absoluteY(id){ 605 613 @ var obj = gebi(id); 606 614 @ if( !obj ) return; 607 615 @ var top = 0; 608 616 @ if( obj.offsetParent ){ 609 617 @ do{ ................................................................................ 697 705 @ if( mx>p.x ){ 698 706 @ drawThinArrow(y0,mx,p.x+6); 699 707 @ }else{ 700 708 @ drawThinArrow(y0,mx,p.x-5); 701 709 @ } 702 710 @ } 703 711 @ } 712 + @ var selBox = null; 713 + @ var selRow = null; 704 714 @ function renderGraph(){ 705 715 @ var canvasDiv = gebi("canvas"); 706 716 @ while( canvasDiv.hasChildNodes() ){ 707 717 @ canvasDiv.removeChild(canvasDiv.firstChild); 708 718 @ } 709 719 @ var canvasY = absoluteY("timelineTable"); 710 720 @ var left = absoluteX("m"+rowinfo[0].id) - absoluteX("canvas") + 15; ................................................................................ 734 744 @ context.fillStyle = color; 735 745 @ context.fillRect(x0-left+5,y0,x1-x0+1,y1-y0+1); 736 746 @ }; 737 747 @ } 738 748 #endif 739 749 @ for(var i in rowinfo){ 740 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 + } 741 782 @ } 742 783 @ } 743 784 @ var lastId = "m"+rowinfo[rowinfo.length-1].id; 744 785 @ var lastY = 0; 745 786 @ function checkHeight(){ 746 787 @ var h = absoluteY(lastId); 747 788 @ if( h!=lastY ){