Fossil SCM
Add additional hyperlinking of dates and userids. For a "circa" timeline, show the "circa" point in the timeline listing.
Commit
b5f4f910b72477f3a61b1ea0d65e2059b7f76664
Parent
713b8be852b99fe…
2 files changed
+27
-203
+39
-7
+27
-203
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -21,11 +21,11 @@ | ||
| 21 | 21 | ** |
| 22 | 22 | ******************************************************************************* |
| 23 | 23 | ** |
| 24 | 24 | ** This file contains code to implement the "info" command. The |
| 25 | 25 | ** "info" command gives command-line access to information about |
| 26 | -** the current tree, or a particular artifact or baseline. | |
| 26 | +** the current tree, or a particular artifact or check-in. | |
| 27 | 27 | */ |
| 28 | 28 | #include "config.h" |
| 29 | 29 | #include "info.h" |
| 30 | 30 | #include <assert.h> |
| 31 | 31 | |
| @@ -144,145 +144,10 @@ | ||
| 144 | 144 | } |
| 145 | 145 | show_common_info(rid, "uuid:", 1); |
| 146 | 146 | } |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | -/* | |
| 150 | -** Show information about descendants of a baseline. Do this recursively | |
| 151 | -** to a depth of N. Return true if descendants are shown and false if not. | |
| 152 | -*/ | |
| 153 | -static int showDescendants(int pid, int depth, const char *zTitle){ | |
| 154 | - Stmt q; | |
| 155 | - int cnt = 0; | |
| 156 | - db_prepare(&q, | |
| 157 | - "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime')," | |
| 158 | - " coalesce(event.euser,event.user)," | |
| 159 | - " coalesce(event.ecomment,event.comment)" | |
| 160 | - " FROM plink, blob, event" | |
| 161 | - " WHERE plink.pid=%d" | |
| 162 | - " AND blob.rid=plink.cid" | |
| 163 | - " AND event.objid=plink.cid" | |
| 164 | - " ORDER BY plink.mtime ASC", | |
| 165 | - pid | |
| 166 | - ); | |
| 167 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 168 | - int n; | |
| 169 | - int cid = db_column_int(&q, 0); | |
| 170 | - const char *zUuid = db_column_text(&q, 1); | |
| 171 | - const char *zDate = db_column_text(&q, 2); | |
| 172 | - const char *zUser = db_column_text(&q, 3); | |
| 173 | - const char *zCom = db_column_text(&q, 4); | |
| 174 | - cnt++; | |
| 175 | - if( cnt==1 ){ | |
| 176 | - if( zTitle ){ | |
| 177 | - @ <div class="section">%s(zTitle)</div> | |
| 178 | - } | |
| 179 | - @ <ul> | |
| 180 | - } | |
| 181 | - @ <li> | |
| 182 | - hyperlink_to_uuid(zUuid); | |
| 183 | - @ %w(zCom) (by %s(zUser) on %s(zDate)) | |
| 184 | - if( depth ){ | |
| 185 | - n = showDescendants(cid, depth-1, 0); | |
| 186 | - }else{ | |
| 187 | - n = db_int(0, "SELECT 1 FROM plink WHERE pid=%d", cid); | |
| 188 | - } | |
| 189 | - if( n==0 ){ | |
| 190 | - db_multi_exec("DELETE FROM leaves WHERE rid=%d", cid); | |
| 191 | - @ <b>leaf</b> | |
| 192 | - } | |
| 193 | - } | |
| 194 | - db_finalize(&q); | |
| 195 | - if( cnt ){ | |
| 196 | - @ </ul> | |
| 197 | - } | |
| 198 | - return cnt; | |
| 199 | -} | |
| 200 | - | |
| 201 | -/* | |
| 202 | -** Show information about ancestors of a baseline. Do this recursively | |
| 203 | -** to a depth of N. Return true if ancestors are shown and false if not. | |
| 204 | -*/ | |
| 205 | -static void showAncestors(int pid, int depth, const char *zTitle){ | |
| 206 | - Stmt q; | |
| 207 | - int cnt = 0; | |
| 208 | - db_prepare(&q, | |
| 209 | - "SELECT plink.pid, blob.uuid, datetime(event.mtime, 'localtime')," | |
| 210 | - " coalesce(event.euser,event.user)," | |
| 211 | - " coalesce(event.ecomment,event.comment)" | |
| 212 | - " FROM plink, blob, event" | |
| 213 | - " WHERE plink.cid=%d" | |
| 214 | - " AND blob.rid=plink.pid" | |
| 215 | - " AND event.objid=plink.pid" | |
| 216 | - " ORDER BY event.mtime DESC", | |
| 217 | - pid | |
| 218 | - ); | |
| 219 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 220 | - int cid = db_column_int(&q, 0); | |
| 221 | - const char *zUuid = db_column_text(&q, 1); | |
| 222 | - const char *zDate = db_column_text(&q, 2); | |
| 223 | - const char *zUser = db_column_text(&q, 3); | |
| 224 | - const char *zCom = db_column_text(&q, 4); | |
| 225 | - cnt++; | |
| 226 | - if( cnt==1 ){ | |
| 227 | - if( zTitle ){ | |
| 228 | - @ <div class="section">%s(zTitle)</div> | |
| 229 | - } | |
| 230 | - @ <ul> | |
| 231 | - } | |
| 232 | - @ <li> | |
| 233 | - hyperlink_to_uuid(zUuid); | |
| 234 | - @ %w(zCom) (by %s(zUser) on %s(zDate)) | |
| 235 | - if( depth ){ | |
| 236 | - showAncestors(cid, depth-1, 0); | |
| 237 | - } | |
| 238 | - } | |
| 239 | - db_finalize(&q); | |
| 240 | - if( cnt ){ | |
| 241 | - @ </ul> | |
| 242 | - } | |
| 243 | -} | |
| 244 | - | |
| 245 | - | |
| 246 | -#if 0 /* NOT USED */ | |
| 247 | -/* | |
| 248 | -** Show information about baselines mentioned in the "leaves" table. | |
| 249 | -*/ | |
| 250 | -static void showLeaves(int rid){ | |
| 251 | - Stmt q; | |
| 252 | - int cnt = 0; | |
| 253 | - db_prepare(&q, | |
| 254 | - "SELECT blob.uuid, datetime(event.mtime, 'localtime')," | |
| 255 | - " coalesce(event.euser, event.user)," | |
| 256 | - " coalesce(event.ecomment,event.comment)" | |
| 257 | - " FROM leaves, blob, event" | |
| 258 | - " WHERE blob.rid=leaves.rid AND blob.rid!=%d" | |
| 259 | - " AND event.objid=leaves.rid" | |
| 260 | - " ORDER BY event.mtime DESC", | |
| 261 | - rid | |
| 262 | - ); | |
| 263 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 264 | - const char *zUuid = db_column_text(&q, 0); | |
| 265 | - const char *zDate = db_column_text(&q, 1); | |
| 266 | - const char *zUser = db_column_text(&q, 2); | |
| 267 | - const char *zCom = db_column_text(&q, 3); | |
| 268 | - cnt++; | |
| 269 | - if( cnt==1 ){ | |
| 270 | - @ <div class="section">Leaves</div> | |
| 271 | - @ <ul> | |
| 272 | - } | |
| 273 | - @ <li> | |
| 274 | - hyperlink_to_uuid(zUuid); | |
| 275 | - @ %w(zCom) (by %s(zUser) on %s(zDate)) | |
| 276 | - } | |
| 277 | - db_finalize(&q); | |
| 278 | - if( cnt ){ | |
| 279 | - @ </ul> | |
| 280 | - } | |
| 281 | -} | |
| 282 | -#endif | |
| 283 | - | |
| 284 | 149 | /* |
| 285 | 150 | ** Show information about all tags on a given node. |
| 286 | 151 | */ |
| 287 | 152 | static void showTags(int rid, const char *zNotGlob){ |
| 288 | 153 | Stmt q; |
| @@ -329,11 +194,12 @@ | ||
| 329 | 194 | @ by |
| 330 | 195 | }else{ |
| 331 | 196 | @ added by |
| 332 | 197 | } |
| 333 | 198 | hyperlink_to_uuid(zSrcUuid); |
| 334 | - @ on %s(zDate) | |
| 199 | + @ on | |
| 200 | + hyperlink_to_date(zDate,0); | |
| 335 | 201 | } |
| 336 | 202 | } |
| 337 | 203 | db_finalize(&q); |
| 338 | 204 | if( cnt ){ |
| 339 | 205 | @ </ul> |
| @@ -390,10 +256,11 @@ | ||
| 390 | 256 | const char *zUuid = db_column_text(&q, 0); |
| 391 | 257 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 392 | 258 | char *zEUser, *zEComment; |
| 393 | 259 | const char *zUser; |
| 394 | 260 | const char *zComment; |
| 261 | + const char *zDate; | |
| 395 | 262 | style_header(zTitle); |
| 396 | 263 | login_anonymous_available(); |
| 397 | 264 | free(zTitle); |
| 398 | 265 | zEUser = db_text(0, |
| 399 | 266 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| @@ -401,23 +268,28 @@ | ||
| 401 | 268 | zEComment = db_text(0, |
| 402 | 269 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 403 | 270 | TAG_COMMENT, rid); |
| 404 | 271 | zUser = db_column_text(&q, 2); |
| 405 | 272 | zComment = db_column_text(&q, 3); |
| 273 | + zDate = db_column_text(&q,1); | |
| 406 | 274 | @ <div class="section">Overview</div> |
| 407 | 275 | @ <p><table class="label-value"> |
| 408 | 276 | @ <tr><th>SHA1 Hash:</th><td>%s(zUuid) |
| 409 | 277 | if( g.okSetup ){ |
| 410 | 278 | @ (Record ID: %d(rid)) |
| 411 | 279 | } |
| 412 | 280 | @ </td></tr> |
| 413 | - @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr> | |
| 281 | + @ <tr><th>Date:</th><td> | |
| 282 | + hyperlink_to_date(zDate, "</td></tr>"); | |
| 414 | 283 | if( zEUser ){ |
| 415 | - @ <tr><th>Edited User:</td><td>%h(zEUser)</td></tr> | |
| 416 | - @ <tr><th>Original User:</th><td>%h(zUser)</td></tr> | |
| 284 | + @ <tr><th>Edited User:</td><td> | |
| 285 | + hyperlink_to_user(zEUser,zDate,"</td></tr>"); | |
| 286 | + @ <tr><th>Original User:</th><td> | |
| 287 | + hyperlink_to_user(zUser,zDate,"</td></tr>"); | |
| 417 | 288 | }else{ |
| 418 | - @ <tr><th>User:</td><td>%h(zUser)</td></tr> | |
| 289 | + @ <tr><th>User:</td><td> | |
| 290 | + hyperlink_to_user(zUser,zDate,"</td></tr>"); | |
| 419 | 291 | } |
| 420 | 292 | if( zEComment ){ |
| 421 | 293 | @ <tr><th>Edited Comment:</th><td>%w(zEComment)</td></tr> |
| 422 | 294 | @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> |
| 423 | 295 | }else{ |
| @@ -509,65 +381,10 @@ | ||
| 509 | 381 | @ <blockquote><pre> |
| 510 | 382 | append_diff(pid, fid); |
| 511 | 383 | @ </pre></blockquote> |
| 512 | 384 | } |
| 513 | 385 | db_finalize(&q); |
| 514 | - | |
| 515 | -#if 0 | |
| 516 | - @ <ul> | |
| 517 | - db_prepare(&q, | |
| 518 | - "SELECT a.name, b.name" | |
| 519 | - " FROM mlink, filename AS a, filename AS b" | |
| 520 | - " WHERE mid=%d" | |
| 521 | - " AND a.fnid=mlink.fnid" | |
| 522 | - " AND b.fnid=mlink.pfnid", | |
| 523 | - rid | |
| 524 | - ); | |
| 525 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 526 | - const char *zName = db_column_text(&q, 0); | |
| 527 | - const char *zPrior = db_column_text(&q, 1); | |
| 528 | - @ <li><b>Renamed:</b> | |
| 529 | - if( g.okHistory ){ | |
| 530 | - @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zPrior)</a> to | |
| 531 | - @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> | |
| 532 | - }else{ | |
| 533 | - @ %h(zPrior) to %h(zName)</li> | |
| 534 | - } | |
| 535 | - } | |
| 536 | - db_finalize(&q); | |
| 537 | - db_prepare(&q, | |
| 538 | - "SELECT name, pid, fid " | |
| 539 | - " FROM mlink, filename" | |
| 540 | - " WHERE mid=%d" | |
| 541 | - " AND fid!=pid" | |
| 542 | - " AND filename.fnid=mlink.fnid", | |
| 543 | - rid | |
| 544 | - ); | |
| 545 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 546 | - const char *zName = db_column_text(&q, 0); | |
| 547 | - int pid = db_column_int(&q, 1); | |
| 548 | - int fid = db_column_int(&q, 2); | |
| 549 | - if( pid && fid ){ | |
| 550 | - @ <li><b>Modified:</b> | |
| 551 | - }else if( fid ){ | |
| 552 | - @ <li><b>Added:</b> | |
| 553 | - }else if( pid ){ | |
| 554 | - @ <li><b>Deleted:</b> | |
| 555 | - } | |
| 556 | - if( g.okHistory ){ | |
| 557 | - @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> | |
| 558 | - }else{ | |
| 559 | - @ %h(zName)</li> | |
| 560 | - } | |
| 561 | - } | |
| 562 | - @ </ul> | |
| 563 | - compute_leaves(rid, 0); | |
| 564 | - showDescendants(rid, 2, "Descendants"); | |
| 565 | - showLeaves(rid); | |
| 566 | - showAncestors(rid, 2, "Ancestors"); | |
| 567 | -#endif | |
| 568 | - | |
| 569 | 386 | style_footer(); |
| 570 | 387 | } |
| 571 | 388 | |
| 572 | 389 | /* |
| 573 | 390 | ** WEBPAGE: winfo |
| @@ -758,12 +575,13 @@ | ||
| 758 | 575 | while( db_step(&q)==SQLITE_ROW ){ |
| 759 | 576 | const char *zDate = db_column_text(&q, 0); |
| 760 | 577 | const char *zUser = db_column_text(&q, 2); |
| 761 | 578 | const char *zComment = db_column_text(&q, 1); |
| 762 | 579 | @ <h2>Check-in %s(zUuid)</h2> |
| 763 | - @ <p>Made by %h(zUser) on | |
| 764 | - link_to_date(zDate, ":"); | |
| 580 | + @ <p>Made by | |
| 581 | + hyperlink_to_user(zUser,zDate," on"); | |
| 582 | + hyperlink_to_date(zDate, ":"); | |
| 765 | 583 | @ %w(zComment). <a href="%s(g.zBaseURL)/ci/%s(zUuid)">[details]</a></p> |
| 766 | 584 | @ <hr> |
| 767 | 585 | } |
| 768 | 586 | db_finalize(&q); |
| 769 | 587 | db_prepare(&q, |
| @@ -792,11 +610,11 @@ | ||
| 792 | 610 | ** |
| 793 | 611 | ** If the object is a file then mention: |
| 794 | 612 | ** |
| 795 | 613 | ** * It's artifact ID |
| 796 | 614 | ** * All its filenames |
| 797 | -** * The baselines it was checked-in on, with times and users | |
| 615 | +** * The check-in it was part of, with times and users | |
| 798 | 616 | ** |
| 799 | 617 | ** If the object is a manifest, then mention: |
| 800 | 618 | ** |
| 801 | 619 | ** * It's artifact ID |
| 802 | 620 | ** * date of check-in |
| @@ -836,11 +654,13 @@ | ||
| 836 | 654 | @ File |
| 837 | 655 | } |
| 838 | 656 | @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a> |
| 839 | 657 | @ artifact %s(zFuuid) part of check-in |
| 840 | 658 | hyperlink_to_uuid(zVers); |
| 841 | - @ - %w(zCom) by %h(zUser) on %s(zDate). | |
| 659 | + @ - %w(zCom) by | |
| 660 | + hyperlink_to_user(zUser,zDate," on"); | |
| 661 | + hyperlink_to_date(zDate,"."); | |
| 842 | 662 | cnt++; |
| 843 | 663 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 844 | 664 | blob_append(pDownloadName, zName, -1); |
| 845 | 665 | } |
| 846 | 666 | } |
| @@ -865,11 +685,13 @@ | ||
| 865 | 685 | @ Also wiki page |
| 866 | 686 | }else{ |
| 867 | 687 | @ Wiki page |
| 868 | 688 | } |
| 869 | 689 | @ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>] |
| 870 | - @ artifact %s(zUuid) by %h(zUser) on %s(zDate). | |
| 690 | + @ artifact %s(zUuid) by | |
| 691 | + hyperlink_to_user(zUser,zDate," on"); | |
| 692 | + hyperlink_to_date(zDate,"."); | |
| 871 | 693 | nWiki++; |
| 872 | 694 | cnt++; |
| 873 | 695 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 874 | 696 | blob_append(pDownloadName, zPagename, -1); |
| 875 | 697 | } |
| @@ -895,16 +717,18 @@ | ||
| 895 | 717 | if( zType[0]=='w' ){ |
| 896 | 718 | @ Wiki edit |
| 897 | 719 | }else if( zType[0]=='t' ){ |
| 898 | 720 | @ Ticket change |
| 899 | 721 | }else if( zType[0]=='c' ){ |
| 900 | - @ Manifest of baseline | |
| 722 | + @ Manifest of check-in | |
| 901 | 723 | }else{ |
| 902 | 724 | @ Control file referencing |
| 903 | 725 | } |
| 904 | 726 | hyperlink_to_uuid(zUuid); |
| 905 | - @ - %w(zCom) by %h(zUser) on %s(zDate). | |
| 727 | + @ - %w(zCom) by | |
| 728 | + hyperlink_to_user(zUser,zDate," on"); | |
| 729 | + hyperlink_to_date(zDate, "."); | |
| 906 | 730 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 907 | 731 | blob_append(pDownloadName, zUuid, -1); |
| 908 | 732 | } |
| 909 | 733 | cnt++; |
| 910 | 734 | } |
| 911 | 735 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -21,11 +21,11 @@ | |
| 21 | ** |
| 22 | ******************************************************************************* |
| 23 | ** |
| 24 | ** This file contains code to implement the "info" command. The |
| 25 | ** "info" command gives command-line access to information about |
| 26 | ** the current tree, or a particular artifact or baseline. |
| 27 | */ |
| 28 | #include "config.h" |
| 29 | #include "info.h" |
| 30 | #include <assert.h> |
| 31 | |
| @@ -144,145 +144,10 @@ | |
| 144 | } |
| 145 | show_common_info(rid, "uuid:", 1); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | ** Show information about descendants of a baseline. Do this recursively |
| 151 | ** to a depth of N. Return true if descendants are shown and false if not. |
| 152 | */ |
| 153 | static int showDescendants(int pid, int depth, const char *zTitle){ |
| 154 | Stmt q; |
| 155 | int cnt = 0; |
| 156 | db_prepare(&q, |
| 157 | "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime')," |
| 158 | " coalesce(event.euser,event.user)," |
| 159 | " coalesce(event.ecomment,event.comment)" |
| 160 | " FROM plink, blob, event" |
| 161 | " WHERE plink.pid=%d" |
| 162 | " AND blob.rid=plink.cid" |
| 163 | " AND event.objid=plink.cid" |
| 164 | " ORDER BY plink.mtime ASC", |
| 165 | pid |
| 166 | ); |
| 167 | while( db_step(&q)==SQLITE_ROW ){ |
| 168 | int n; |
| 169 | int cid = db_column_int(&q, 0); |
| 170 | const char *zUuid = db_column_text(&q, 1); |
| 171 | const char *zDate = db_column_text(&q, 2); |
| 172 | const char *zUser = db_column_text(&q, 3); |
| 173 | const char *zCom = db_column_text(&q, 4); |
| 174 | cnt++; |
| 175 | if( cnt==1 ){ |
| 176 | if( zTitle ){ |
| 177 | @ <div class="section">%s(zTitle)</div> |
| 178 | } |
| 179 | @ <ul> |
| 180 | } |
| 181 | @ <li> |
| 182 | hyperlink_to_uuid(zUuid); |
| 183 | @ %w(zCom) (by %s(zUser) on %s(zDate)) |
| 184 | if( depth ){ |
| 185 | n = showDescendants(cid, depth-1, 0); |
| 186 | }else{ |
| 187 | n = db_int(0, "SELECT 1 FROM plink WHERE pid=%d", cid); |
| 188 | } |
| 189 | if( n==0 ){ |
| 190 | db_multi_exec("DELETE FROM leaves WHERE rid=%d", cid); |
| 191 | @ <b>leaf</b> |
| 192 | } |
| 193 | } |
| 194 | db_finalize(&q); |
| 195 | if( cnt ){ |
| 196 | @ </ul> |
| 197 | } |
| 198 | return cnt; |
| 199 | } |
| 200 | |
| 201 | /* |
| 202 | ** Show information about ancestors of a baseline. Do this recursively |
| 203 | ** to a depth of N. Return true if ancestors are shown and false if not. |
| 204 | */ |
| 205 | static void showAncestors(int pid, int depth, const char *zTitle){ |
| 206 | Stmt q; |
| 207 | int cnt = 0; |
| 208 | db_prepare(&q, |
| 209 | "SELECT plink.pid, blob.uuid, datetime(event.mtime, 'localtime')," |
| 210 | " coalesce(event.euser,event.user)," |
| 211 | " coalesce(event.ecomment,event.comment)" |
| 212 | " FROM plink, blob, event" |
| 213 | " WHERE plink.cid=%d" |
| 214 | " AND blob.rid=plink.pid" |
| 215 | " AND event.objid=plink.pid" |
| 216 | " ORDER BY event.mtime DESC", |
| 217 | pid |
| 218 | ); |
| 219 | while( db_step(&q)==SQLITE_ROW ){ |
| 220 | int cid = db_column_int(&q, 0); |
| 221 | const char *zUuid = db_column_text(&q, 1); |
| 222 | const char *zDate = db_column_text(&q, 2); |
| 223 | const char *zUser = db_column_text(&q, 3); |
| 224 | const char *zCom = db_column_text(&q, 4); |
| 225 | cnt++; |
| 226 | if( cnt==1 ){ |
| 227 | if( zTitle ){ |
| 228 | @ <div class="section">%s(zTitle)</div> |
| 229 | } |
| 230 | @ <ul> |
| 231 | } |
| 232 | @ <li> |
| 233 | hyperlink_to_uuid(zUuid); |
| 234 | @ %w(zCom) (by %s(zUser) on %s(zDate)) |
| 235 | if( depth ){ |
| 236 | showAncestors(cid, depth-1, 0); |
| 237 | } |
| 238 | } |
| 239 | db_finalize(&q); |
| 240 | if( cnt ){ |
| 241 | @ </ul> |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | |
| 246 | #if 0 /* NOT USED */ |
| 247 | /* |
| 248 | ** Show information about baselines mentioned in the "leaves" table. |
| 249 | */ |
| 250 | static void showLeaves(int rid){ |
| 251 | Stmt q; |
| 252 | int cnt = 0; |
| 253 | db_prepare(&q, |
| 254 | "SELECT blob.uuid, datetime(event.mtime, 'localtime')," |
| 255 | " coalesce(event.euser, event.user)," |
| 256 | " coalesce(event.ecomment,event.comment)" |
| 257 | " FROM leaves, blob, event" |
| 258 | " WHERE blob.rid=leaves.rid AND blob.rid!=%d" |
| 259 | " AND event.objid=leaves.rid" |
| 260 | " ORDER BY event.mtime DESC", |
| 261 | rid |
| 262 | ); |
| 263 | while( db_step(&q)==SQLITE_ROW ){ |
| 264 | const char *zUuid = db_column_text(&q, 0); |
| 265 | const char *zDate = db_column_text(&q, 1); |
| 266 | const char *zUser = db_column_text(&q, 2); |
| 267 | const char *zCom = db_column_text(&q, 3); |
| 268 | cnt++; |
| 269 | if( cnt==1 ){ |
| 270 | @ <div class="section">Leaves</div> |
| 271 | @ <ul> |
| 272 | } |
| 273 | @ <li> |
| 274 | hyperlink_to_uuid(zUuid); |
| 275 | @ %w(zCom) (by %s(zUser) on %s(zDate)) |
| 276 | } |
| 277 | db_finalize(&q); |
| 278 | if( cnt ){ |
| 279 | @ </ul> |
| 280 | } |
| 281 | } |
| 282 | #endif |
| 283 | |
| 284 | /* |
| 285 | ** Show information about all tags on a given node. |
| 286 | */ |
| 287 | static void showTags(int rid, const char *zNotGlob){ |
| 288 | Stmt q; |
| @@ -329,11 +194,12 @@ | |
| 329 | @ by |
| 330 | }else{ |
| 331 | @ added by |
| 332 | } |
| 333 | hyperlink_to_uuid(zSrcUuid); |
| 334 | @ on %s(zDate) |
| 335 | } |
| 336 | } |
| 337 | db_finalize(&q); |
| 338 | if( cnt ){ |
| 339 | @ </ul> |
| @@ -390,10 +256,11 @@ | |
| 390 | const char *zUuid = db_column_text(&q, 0); |
| 391 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 392 | char *zEUser, *zEComment; |
| 393 | const char *zUser; |
| 394 | const char *zComment; |
| 395 | style_header(zTitle); |
| 396 | login_anonymous_available(); |
| 397 | free(zTitle); |
| 398 | zEUser = db_text(0, |
| 399 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| @@ -401,23 +268,28 @@ | |
| 401 | zEComment = db_text(0, |
| 402 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 403 | TAG_COMMENT, rid); |
| 404 | zUser = db_column_text(&q, 2); |
| 405 | zComment = db_column_text(&q, 3); |
| 406 | @ <div class="section">Overview</div> |
| 407 | @ <p><table class="label-value"> |
| 408 | @ <tr><th>SHA1 Hash:</th><td>%s(zUuid) |
| 409 | if( g.okSetup ){ |
| 410 | @ (Record ID: %d(rid)) |
| 411 | } |
| 412 | @ </td></tr> |
| 413 | @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr> |
| 414 | if( zEUser ){ |
| 415 | @ <tr><th>Edited User:</td><td>%h(zEUser)</td></tr> |
| 416 | @ <tr><th>Original User:</th><td>%h(zUser)</td></tr> |
| 417 | }else{ |
| 418 | @ <tr><th>User:</td><td>%h(zUser)</td></tr> |
| 419 | } |
| 420 | if( zEComment ){ |
| 421 | @ <tr><th>Edited Comment:</th><td>%w(zEComment)</td></tr> |
| 422 | @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> |
| 423 | }else{ |
| @@ -509,65 +381,10 @@ | |
| 509 | @ <blockquote><pre> |
| 510 | append_diff(pid, fid); |
| 511 | @ </pre></blockquote> |
| 512 | } |
| 513 | db_finalize(&q); |
| 514 | |
| 515 | #if 0 |
| 516 | @ <ul> |
| 517 | db_prepare(&q, |
| 518 | "SELECT a.name, b.name" |
| 519 | " FROM mlink, filename AS a, filename AS b" |
| 520 | " WHERE mid=%d" |
| 521 | " AND a.fnid=mlink.fnid" |
| 522 | " AND b.fnid=mlink.pfnid", |
| 523 | rid |
| 524 | ); |
| 525 | while( db_step(&q)==SQLITE_ROW ){ |
| 526 | const char *zName = db_column_text(&q, 0); |
| 527 | const char *zPrior = db_column_text(&q, 1); |
| 528 | @ <li><b>Renamed:</b> |
| 529 | if( g.okHistory ){ |
| 530 | @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zPrior)</a> to |
| 531 | @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> |
| 532 | }else{ |
| 533 | @ %h(zPrior) to %h(zName)</li> |
| 534 | } |
| 535 | } |
| 536 | db_finalize(&q); |
| 537 | db_prepare(&q, |
| 538 | "SELECT name, pid, fid " |
| 539 | " FROM mlink, filename" |
| 540 | " WHERE mid=%d" |
| 541 | " AND fid!=pid" |
| 542 | " AND filename.fnid=mlink.fnid", |
| 543 | rid |
| 544 | ); |
| 545 | while( db_step(&q)==SQLITE_ROW ){ |
| 546 | const char *zName = db_column_text(&q, 0); |
| 547 | int pid = db_column_int(&q, 1); |
| 548 | int fid = db_column_int(&q, 2); |
| 549 | if( pid && fid ){ |
| 550 | @ <li><b>Modified:</b> |
| 551 | }else if( fid ){ |
| 552 | @ <li><b>Added:</b> |
| 553 | }else if( pid ){ |
| 554 | @ <li><b>Deleted:</b> |
| 555 | } |
| 556 | if( g.okHistory ){ |
| 557 | @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> |
| 558 | }else{ |
| 559 | @ %h(zName)</li> |
| 560 | } |
| 561 | } |
| 562 | @ </ul> |
| 563 | compute_leaves(rid, 0); |
| 564 | showDescendants(rid, 2, "Descendants"); |
| 565 | showLeaves(rid); |
| 566 | showAncestors(rid, 2, "Ancestors"); |
| 567 | #endif |
| 568 | |
| 569 | style_footer(); |
| 570 | } |
| 571 | |
| 572 | /* |
| 573 | ** WEBPAGE: winfo |
| @@ -758,12 +575,13 @@ | |
| 758 | while( db_step(&q)==SQLITE_ROW ){ |
| 759 | const char *zDate = db_column_text(&q, 0); |
| 760 | const char *zUser = db_column_text(&q, 2); |
| 761 | const char *zComment = db_column_text(&q, 1); |
| 762 | @ <h2>Check-in %s(zUuid)</h2> |
| 763 | @ <p>Made by %h(zUser) on |
| 764 | link_to_date(zDate, ":"); |
| 765 | @ %w(zComment). <a href="%s(g.zBaseURL)/ci/%s(zUuid)">[details]</a></p> |
| 766 | @ <hr> |
| 767 | } |
| 768 | db_finalize(&q); |
| 769 | db_prepare(&q, |
| @@ -792,11 +610,11 @@ | |
| 792 | ** |
| 793 | ** If the object is a file then mention: |
| 794 | ** |
| 795 | ** * It's artifact ID |
| 796 | ** * All its filenames |
| 797 | ** * The baselines it was checked-in on, with times and users |
| 798 | ** |
| 799 | ** If the object is a manifest, then mention: |
| 800 | ** |
| 801 | ** * It's artifact ID |
| 802 | ** * date of check-in |
| @@ -836,11 +654,13 @@ | |
| 836 | @ File |
| 837 | } |
| 838 | @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a> |
| 839 | @ artifact %s(zFuuid) part of check-in |
| 840 | hyperlink_to_uuid(zVers); |
| 841 | @ - %w(zCom) by %h(zUser) on %s(zDate). |
| 842 | cnt++; |
| 843 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 844 | blob_append(pDownloadName, zName, -1); |
| 845 | } |
| 846 | } |
| @@ -865,11 +685,13 @@ | |
| 865 | @ Also wiki page |
| 866 | }else{ |
| 867 | @ Wiki page |
| 868 | } |
| 869 | @ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>] |
| 870 | @ artifact %s(zUuid) by %h(zUser) on %s(zDate). |
| 871 | nWiki++; |
| 872 | cnt++; |
| 873 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 874 | blob_append(pDownloadName, zPagename, -1); |
| 875 | } |
| @@ -895,16 +717,18 @@ | |
| 895 | if( zType[0]=='w' ){ |
| 896 | @ Wiki edit |
| 897 | }else if( zType[0]=='t' ){ |
| 898 | @ Ticket change |
| 899 | }else if( zType[0]=='c' ){ |
| 900 | @ Manifest of baseline |
| 901 | }else{ |
| 902 | @ Control file referencing |
| 903 | } |
| 904 | hyperlink_to_uuid(zUuid); |
| 905 | @ - %w(zCom) by %h(zUser) on %s(zDate). |
| 906 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 907 | blob_append(pDownloadName, zUuid, -1); |
| 908 | } |
| 909 | cnt++; |
| 910 | } |
| 911 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -21,11 +21,11 @@ | |
| 21 | ** |
| 22 | ******************************************************************************* |
| 23 | ** |
| 24 | ** This file contains code to implement the "info" command. The |
| 25 | ** "info" command gives command-line access to information about |
| 26 | ** the current tree, or a particular artifact or check-in. |
| 27 | */ |
| 28 | #include "config.h" |
| 29 | #include "info.h" |
| 30 | #include <assert.h> |
| 31 | |
| @@ -144,145 +144,10 @@ | |
| 144 | } |
| 145 | show_common_info(rid, "uuid:", 1); |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | ** Show information about all tags on a given node. |
| 151 | */ |
| 152 | static void showTags(int rid, const char *zNotGlob){ |
| 153 | Stmt q; |
| @@ -329,11 +194,12 @@ | |
| 194 | @ by |
| 195 | }else{ |
| 196 | @ added by |
| 197 | } |
| 198 | hyperlink_to_uuid(zSrcUuid); |
| 199 | @ on |
| 200 | hyperlink_to_date(zDate,0); |
| 201 | } |
| 202 | } |
| 203 | db_finalize(&q); |
| 204 | if( cnt ){ |
| 205 | @ </ul> |
| @@ -390,10 +256,11 @@ | |
| 256 | const char *zUuid = db_column_text(&q, 0); |
| 257 | char *zTitle = mprintf("Check-in [%.10s]", zUuid); |
| 258 | char *zEUser, *zEComment; |
| 259 | const char *zUser; |
| 260 | const char *zComment; |
| 261 | const char *zDate; |
| 262 | style_header(zTitle); |
| 263 | login_anonymous_available(); |
| 264 | free(zTitle); |
| 265 | zEUser = db_text(0, |
| 266 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| @@ -401,23 +268,28 @@ | |
| 268 | zEComment = db_text(0, |
| 269 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 270 | TAG_COMMENT, rid); |
| 271 | zUser = db_column_text(&q, 2); |
| 272 | zComment = db_column_text(&q, 3); |
| 273 | zDate = db_column_text(&q,1); |
| 274 | @ <div class="section">Overview</div> |
| 275 | @ <p><table class="label-value"> |
| 276 | @ <tr><th>SHA1 Hash:</th><td>%s(zUuid) |
| 277 | if( g.okSetup ){ |
| 278 | @ (Record ID: %d(rid)) |
| 279 | } |
| 280 | @ </td></tr> |
| 281 | @ <tr><th>Date:</th><td> |
| 282 | hyperlink_to_date(zDate, "</td></tr>"); |
| 283 | if( zEUser ){ |
| 284 | @ <tr><th>Edited User:</td><td> |
| 285 | hyperlink_to_user(zEUser,zDate,"</td></tr>"); |
| 286 | @ <tr><th>Original User:</th><td> |
| 287 | hyperlink_to_user(zUser,zDate,"</td></tr>"); |
| 288 | }else{ |
| 289 | @ <tr><th>User:</td><td> |
| 290 | hyperlink_to_user(zUser,zDate,"</td></tr>"); |
| 291 | } |
| 292 | if( zEComment ){ |
| 293 | @ <tr><th>Edited Comment:</th><td>%w(zEComment)</td></tr> |
| 294 | @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> |
| 295 | }else{ |
| @@ -509,65 +381,10 @@ | |
| 381 | @ <blockquote><pre> |
| 382 | append_diff(pid, fid); |
| 383 | @ </pre></blockquote> |
| 384 | } |
| 385 | db_finalize(&q); |
| 386 | style_footer(); |
| 387 | } |
| 388 | |
| 389 | /* |
| 390 | ** WEBPAGE: winfo |
| @@ -758,12 +575,13 @@ | |
| 575 | while( db_step(&q)==SQLITE_ROW ){ |
| 576 | const char *zDate = db_column_text(&q, 0); |
| 577 | const char *zUser = db_column_text(&q, 2); |
| 578 | const char *zComment = db_column_text(&q, 1); |
| 579 | @ <h2>Check-in %s(zUuid)</h2> |
| 580 | @ <p>Made by |
| 581 | hyperlink_to_user(zUser,zDate," on"); |
| 582 | hyperlink_to_date(zDate, ":"); |
| 583 | @ %w(zComment). <a href="%s(g.zBaseURL)/ci/%s(zUuid)">[details]</a></p> |
| 584 | @ <hr> |
| 585 | } |
| 586 | db_finalize(&q); |
| 587 | db_prepare(&q, |
| @@ -792,11 +610,11 @@ | |
| 610 | ** |
| 611 | ** If the object is a file then mention: |
| 612 | ** |
| 613 | ** * It's artifact ID |
| 614 | ** * All its filenames |
| 615 | ** * The check-in it was part of, with times and users |
| 616 | ** |
| 617 | ** If the object is a manifest, then mention: |
| 618 | ** |
| 619 | ** * It's artifact ID |
| 620 | ** * date of check-in |
| @@ -836,11 +654,13 @@ | |
| 654 | @ File |
| 655 | } |
| 656 | @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a> |
| 657 | @ artifact %s(zFuuid) part of check-in |
| 658 | hyperlink_to_uuid(zVers); |
| 659 | @ - %w(zCom) by |
| 660 | hyperlink_to_user(zUser,zDate," on"); |
| 661 | hyperlink_to_date(zDate,"."); |
| 662 | cnt++; |
| 663 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 664 | blob_append(pDownloadName, zName, -1); |
| 665 | } |
| 666 | } |
| @@ -865,11 +685,13 @@ | |
| 685 | @ Also wiki page |
| 686 | }else{ |
| 687 | @ Wiki page |
| 688 | } |
| 689 | @ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>] |
| 690 | @ artifact %s(zUuid) by |
| 691 | hyperlink_to_user(zUser,zDate," on"); |
| 692 | hyperlink_to_date(zDate,"."); |
| 693 | nWiki++; |
| 694 | cnt++; |
| 695 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 696 | blob_append(pDownloadName, zPagename, -1); |
| 697 | } |
| @@ -895,16 +717,18 @@ | |
| 717 | if( zType[0]=='w' ){ |
| 718 | @ Wiki edit |
| 719 | }else if( zType[0]=='t' ){ |
| 720 | @ Ticket change |
| 721 | }else if( zType[0]=='c' ){ |
| 722 | @ Manifest of check-in |
| 723 | }else{ |
| 724 | @ Control file referencing |
| 725 | } |
| 726 | hyperlink_to_uuid(zUuid); |
| 727 | @ - %w(zCom) by |
| 728 | hyperlink_to_user(zUser,zDate," on"); |
| 729 | hyperlink_to_date(zDate, "."); |
| 730 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 731 | blob_append(pDownloadName, zUuid, -1); |
| 732 | } |
| 733 | cnt++; |
| 734 | } |
| 735 |
+39
-7
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -73,10 +73,40 @@ | ||
| 73 | 73 | }else{ |
| 74 | 74 | @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> |
| 75 | 75 | } |
| 76 | 76 | } |
| 77 | 77 | } |
| 78 | + | |
| 79 | +/* | |
| 80 | +** Generate a hyperlink to a date & time. | |
| 81 | +*/ | |
| 82 | +void hyperlink_to_date(const char *zDate, const char *zSuffix){ | |
| 83 | + if( zSuffix==0 ) zSuffix = ""; | |
| 84 | + if( g.okHistory ){ | |
| 85 | + @ <a href="%s(g.zTop)/timeline?c=%T(zDate)">%s(zDate)</a>%s(zSuffix) | |
| 86 | + }else{ | |
| 87 | + @ %s(zDate)%s(zSuffix) | |
| 88 | + } | |
| 89 | +} | |
| 90 | + | |
| 91 | +/* | |
| 92 | +** Generate a hyperlink to a user. This will link to a timeline showing | |
| 93 | +** events by that user. If the date+time is specified, then the timeline | |
| 94 | +** is centered on that date+time. | |
| 95 | +*/ | |
| 96 | +void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ | |
| 97 | + if( zSuf==0 ) zSuf = ""; | |
| 98 | + if( g.okHistory ){ | |
| 99 | + if( zD && zD[0] ){ | |
| 100 | + @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) | |
| 101 | + }else{ | |
| 102 | + @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) | |
| 103 | + } | |
| 104 | + }else{ | |
| 105 | + @ %s(zU) | |
| 106 | + } | |
| 107 | +} | |
| 78 | 108 | |
| 79 | 109 | /* |
| 80 | 110 | ** Count the number of primary non-branch children for the given check-in. |
| 81 | 111 | ** |
| 82 | 112 | ** A primary child is one where the parent is the primary parent, not |
| @@ -155,10 +185,14 @@ | ||
| 155 | 185 | const char *zBgClr = db_column_text(pQuery, 8); |
| 156 | 186 | const char *zDate = db_column_text(pQuery, 2); |
| 157 | 187 | const char *zType = db_column_text(pQuery, 9); |
| 158 | 188 | const char *zUser = db_column_text(pQuery, 4); |
| 159 | 189 | const char *zTagList = db_column_text(pQuery, 10); |
| 190 | + if( strcmp(zType,"div")==0 ){ | |
| 191 | + @ <tr><td colspan=3><hr></td></tr> | |
| 192 | + continue; | |
| 193 | + } | |
| 160 | 194 | db_multi_exec("INSERT OR IGNORE INTO seen VALUES(%d)", rid); |
| 161 | 195 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 162 | 196 | sprintf(zPrevDate, "%.10s", zDate); |
| 163 | 197 | @ <tr><td colspan=3> |
| 164 | 198 | @ <div class="divider">%s(zPrevDate)</div> |
| @@ -461,10 +495,15 @@ | ||
| 461 | 495 | blob_appendf(&sql, |
| 462 | 496 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 463 | 497 | rCirca |
| 464 | 498 | ); |
| 465 | 499 | nEntry -= (nEntry+1)/2; |
| 500 | + db_multi_exec( | |
| 501 | + "INSERT OR IGNORE INTO timeline(timestamp,etype)" | |
| 502 | + "VALUES(datetime(%f,'localtime'),'div')", | |
| 503 | + rCirca | |
| 504 | + ); | |
| 466 | 505 | url_add_parameter(&url, "c", zCirca); |
| 467 | 506 | }else{ |
| 468 | 507 | zCirca = 0; |
| 469 | 508 | } |
| 470 | 509 | }else{ |
| @@ -627,17 +666,10 @@ | ||
| 627 | 666 | @ } |
| 628 | 667 | @ </script> |
| 629 | 668 | style_footer(); |
| 630 | 669 | } |
| 631 | 670 | |
| 632 | -/* | |
| 633 | -** Render the date string given as a hyperlink to a "circa" timeline. | |
| 634 | -*/ | |
| 635 | -void link_to_date(const char *zDate, const char *zSuffix){ | |
| 636 | - @ <a href="%s(g.zBaseURL)/timeline?c=%t(zDate)">%h(zDate)</a>%s(zSuffix) | |
| 637 | -} | |
| 638 | - | |
| 639 | 671 | /* |
| 640 | 672 | ** The input query q selects various records. Print a human-readable |
| 641 | 673 | ** summary of those records. |
| 642 | 674 | ** |
| 643 | 675 | ** Limit the number of entries printed to nLine. |
| 644 | 676 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -73,10 +73,40 @@ | |
| 73 | }else{ |
| 74 | @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | /* |
| 80 | ** Count the number of primary non-branch children for the given check-in. |
| 81 | ** |
| 82 | ** A primary child is one where the parent is the primary parent, not |
| @@ -155,10 +185,14 @@ | |
| 155 | const char *zBgClr = db_column_text(pQuery, 8); |
| 156 | const char *zDate = db_column_text(pQuery, 2); |
| 157 | const char *zType = db_column_text(pQuery, 9); |
| 158 | const char *zUser = db_column_text(pQuery, 4); |
| 159 | const char *zTagList = db_column_text(pQuery, 10); |
| 160 | db_multi_exec("INSERT OR IGNORE INTO seen VALUES(%d)", rid); |
| 161 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 162 | sprintf(zPrevDate, "%.10s", zDate); |
| 163 | @ <tr><td colspan=3> |
| 164 | @ <div class="divider">%s(zPrevDate)</div> |
| @@ -461,10 +495,15 @@ | |
| 461 | blob_appendf(&sql, |
| 462 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 463 | rCirca |
| 464 | ); |
| 465 | nEntry -= (nEntry+1)/2; |
| 466 | url_add_parameter(&url, "c", zCirca); |
| 467 | }else{ |
| 468 | zCirca = 0; |
| 469 | } |
| 470 | }else{ |
| @@ -627,17 +666,10 @@ | |
| 627 | @ } |
| 628 | @ </script> |
| 629 | style_footer(); |
| 630 | } |
| 631 | |
| 632 | /* |
| 633 | ** Render the date string given as a hyperlink to a "circa" timeline. |
| 634 | */ |
| 635 | void link_to_date(const char *zDate, const char *zSuffix){ |
| 636 | @ <a href="%s(g.zBaseURL)/timeline?c=%t(zDate)">%h(zDate)</a>%s(zSuffix) |
| 637 | } |
| 638 | |
| 639 | /* |
| 640 | ** The input query q selects various records. Print a human-readable |
| 641 | ** summary of those records. |
| 642 | ** |
| 643 | ** Limit the number of entries printed to nLine. |
| 644 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -73,10 +73,40 @@ | |
| 73 | }else{ |
| 74 | @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a> |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | /* |
| 80 | ** Generate a hyperlink to a date & time. |
| 81 | */ |
| 82 | void hyperlink_to_date(const char *zDate, const char *zSuffix){ |
| 83 | if( zSuffix==0 ) zSuffix = ""; |
| 84 | if( g.okHistory ){ |
| 85 | @ <a href="%s(g.zTop)/timeline?c=%T(zDate)">%s(zDate)</a>%s(zSuffix) |
| 86 | }else{ |
| 87 | @ %s(zDate)%s(zSuffix) |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 93 | ** events by that user. If the date+time is specified, then the timeline |
| 94 | ** is centered on that date+time. |
| 95 | */ |
| 96 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 97 | if( zSuf==0 ) zSuf = ""; |
| 98 | if( g.okHistory ){ |
| 99 | if( zD && zD[0] ){ |
| 100 | @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 101 | }else{ |
| 102 | @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf) |
| 103 | } |
| 104 | }else{ |
| 105 | @ %s(zU) |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | /* |
| 110 | ** Count the number of primary non-branch children for the given check-in. |
| 111 | ** |
| 112 | ** A primary child is one where the parent is the primary parent, not |
| @@ -155,10 +185,14 @@ | |
| 185 | const char *zBgClr = db_column_text(pQuery, 8); |
| 186 | const char *zDate = db_column_text(pQuery, 2); |
| 187 | const char *zType = db_column_text(pQuery, 9); |
| 188 | const char *zUser = db_column_text(pQuery, 4); |
| 189 | const char *zTagList = db_column_text(pQuery, 10); |
| 190 | if( strcmp(zType,"div")==0 ){ |
| 191 | @ <tr><td colspan=3><hr></td></tr> |
| 192 | continue; |
| 193 | } |
| 194 | db_multi_exec("INSERT OR IGNORE INTO seen VALUES(%d)", rid); |
| 195 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 196 | sprintf(zPrevDate, "%.10s", zDate); |
| 197 | @ <tr><td colspan=3> |
| 198 | @ <div class="divider">%s(zPrevDate)</div> |
| @@ -461,10 +495,15 @@ | |
| 495 | blob_appendf(&sql, |
| 496 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 497 | rCirca |
| 498 | ); |
| 499 | nEntry -= (nEntry+1)/2; |
| 500 | db_multi_exec( |
| 501 | "INSERT OR IGNORE INTO timeline(timestamp,etype)" |
| 502 | "VALUES(datetime(%f,'localtime'),'div')", |
| 503 | rCirca |
| 504 | ); |
| 505 | url_add_parameter(&url, "c", zCirca); |
| 506 | }else{ |
| 507 | zCirca = 0; |
| 508 | } |
| 509 | }else{ |
| @@ -627,17 +666,10 @@ | |
| 666 | @ } |
| 667 | @ </script> |
| 668 | style_footer(); |
| 669 | } |
| 670 | |
| 671 | /* |
| 672 | ** The input query q selects various records. Print a human-readable |
| 673 | ** summary of those records. |
| 674 | ** |
| 675 | ** Limit the number of entries printed to nLine. |
| 676 |