Fossil

Check-in [f4e299d0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:On timelines, to show the "selected" entry, give the row some vertical space between the previous and following rows, a yellow background, a gray border, and a shadow-box (all adjustable via CSS). For the c=TIME "circa" query parameter, highlight the nearest entry.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:f4e299d0e5602c3fa4c505e10346f15629aae40e
User & Date: drh 2015-02-09 04:10:52
Context
2015-02-09
04:46
Add the "Context" subsection to the /info page for check-ins that shows a graph of all immediate ancestors and descendents of the check-in. check-in: b709be65 user: drh tags: trunk
04:10
On timelines, to show the "selected" entry, give the row some vertical space between the previous and following rows, a yellow background, a gray border, and a shadow-box (all adjustable via CSS). For the c=TIME "circa" query parameter, highlight the nearest entry. check-in: f4e299d0 user: drh tags: trunk
2015-02-08
22:26
Fix the socket_open() routine so that it returns a non-zero error code if it fails to connect. check-in: aee65577 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to skins/eagle/css.txt.

157
158
159
160
161
162
163

164
165
166
167
168
169
170

/* the format for the timeline data table */
table.timelineTable {
  cellspacing: 0;
  border: 0;
  cellpadding: 0;
  font-family: "courier new";

}

/* Side-by-side diff */
table.sbsdiff {
  background-color: #485D7B;
  font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
  font-size: 8pt;







>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

/* the format for the timeline data table */
table.timelineTable {
  cellspacing: 0;
  border: 0;
  cellpadding: 0;
  font-family: "courier new";
  border-collapse: collapse;
}

/* Side-by-side diff */
table.sbsdiff {
  background-color: #485D7B;
  font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
  font-size: 8pt;

Changes to src/branch.c.

525
526
527
528
529
530
531
532
533
534
535
  @ <h2>The initial check-in for each branch:</h2>
  db_prepare(&q,
    "%s AND blob.rid IN (SELECT rid FROM tagxref"
    "                     WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www(), TAG_BRANCH
  );
  www_print_timeline(&q, 0, 0, 0, brtimeline_extra);
  db_finalize(&q);
  style_footer();
}







|



525
526
527
528
529
530
531
532
533
534
535
  @ <h2>The initial check-in for each branch:</h2>
  db_prepare(&q,
    "%s AND blob.rid IN (SELECT rid FROM tagxref"
    "                     WHERE tagtype>0 AND tagid=%d AND srcid!=0)"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www(), TAG_BRANCH
  );
  www_print_timeline(&q, 0, 0, 0, 0, brtimeline_extra);
  db_finalize(&q);
  style_footer();
}

Changes to src/descendants.c.

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  if( showClosed ){
    blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
  blob_reset(&sql);
  www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
  db_finalize(&q);
  @ <br />
  style_footer();
}

#if INTERFACE
/* Flag parameters to compute_uses_file() */







|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  if( showClosed ){
    blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
  blob_reset(&sql);
  www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0, 0);
  db_finalize(&q);
  @ <br />
  style_footer();
}

#if INTERFACE
/* Flag parameters to compute_uses_file() */

Changes to src/moderate.c.

152
153
154
155
156
157
158
159
160
161
162
163
  if( moderation_table_exists() ){
    blob_init(&sql, timeline_query_for_www(), -1);
    blob_append_sql(&sql,
        " AND event.objid IN (SELECT objid FROM modreq)"
        " ORDER BY event.mtime DESC"
    );
    db_prepare(&q, "%s", blob_sql_text(&sql));
    www_print_timeline(&q, 0, 0, 0, 0);
    db_finalize(&q);
  }
  style_footer();
}







|




152
153
154
155
156
157
158
159
160
161
162
163
  if( moderation_table_exists() ){
    blob_init(&sql, timeline_query_for_www(), -1);
    blob_append_sql(&sql,
        " AND event.objid IN (SELECT objid FROM modreq)"
        " ORDER BY event.mtime DESC"
    );
    db_prepare(&q, "%s", blob_sql_text(&sql));
    www_print_timeline(&q, 0, 0, 0, 0, 0);
    db_finalize(&q);
  }
  style_footer();
}

Changes to src/style.c.

661
662
663
664
665
666
667

668
669
670
671
672
673
674
675
676
677











678
679
680
681
682
683
684
    "The suppressed duplicates lines in timeline, ..",
    @   font-style: italic;
    @   font-size: small;
  },
  { "table.timelineTable",
    "the format for the timeline data table",
    @   border: 0;

  },
  { "td.timelineTableCell",
    "the format for the timeline data cells",
    @   vertical-align: top;
    @   text-align: left;
  },
  { "tr.timelineCurrent td.timelineTableCell",
    "the format for the timeline data cell of the current checkout",
    @   padding: .1em .2em;
    @   border: 1px dashed #446979;











  },
  { "span.timelineLeaf",
    "the format for the timeline leaf marks",
    @   font-weight: bold;
  },
  { "a.timelineHistLink",
    "the format for the timeline version links",







>










>
>
>
>
>
>
>
>
>
>
>







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
    "The suppressed duplicates lines in timeline, ..",
    @   font-style: italic;
    @   font-size: small;
  },
  { "table.timelineTable",
    "the format for the timeline data table",
    @   border: 0;
    @   border-collapse: collapse;
  },
  { "td.timelineTableCell",
    "the format for the timeline data cells",
    @   vertical-align: top;
    @   text-align: left;
  },
  { "tr.timelineCurrent td.timelineTableCell",
    "the format for the timeline data cell of the current checkout",
    @   padding: .1em .2em;
    @   border: 1px dashed #446979;
  },
  { "tr.timelineSelected",
    "The row in the timeline table that contains the entry of interest",
    @   padding: .1em .2em;
    @   border: 2px solid lightgray;
    @   background-color: #ffc;
    @   box-shadow: 4px 4px 2px #888;
  },
  { "tr.timelineSpacer",
    "An extra row inserted to give vertical space between two rows",
    @   height: 1ex;
  },
  { "span.timelineLeaf",
    "the format for the timeline leaf marks",
    @   font-weight: bold;
  },
  { "a.timelineHistLink",
    "the format for the timeline version links",

Changes to src/tag.c.

592
593
594
595
596
597
598
599
600
601
602
603
    "%s AND blob.rid IN (SELECT rid FROM tagxref"
    "                     WHERE tagtype=1 AND srcid>0"
    "                       AND tagid IN (SELECT tagid FROM tag "
    "                                      WHERE tagname GLOB 'sym-*'))"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www()
  );
  www_print_timeline(&q, 0, 0, 0, 0);
  db_finalize(&q);
  @ <br />
  style_footer();
}







|




592
593
594
595
596
597
598
599
600
601
602
603
    "%s AND blob.rid IN (SELECT rid FROM tagxref"
    "                     WHERE tagtype=1 AND srcid>0"
    "                       AND tagid IN (SELECT tagid FROM tag "
    "                                      WHERE tagname GLOB 'sym-*'))"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www()
  );
  www_print_timeline(&q, 0, 0, 0, 0, 0);
  db_finalize(&q);
  @ <br />
  style_footer();
}

Changes to src/timeline.c.

19
20
21
22
23
24
25





26
27
28
29
30
31
32
...
207
208
209
210
211
212
213

214
215
216
217
218
219
220
...
287
288
289
290
291
292
293



294
295
296
297
298
299
300
301
302
303
304
305
...
330
331
332
333
334
335
336





337
338
339
340
341
342
343
344
...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998



999

1000
1001
1002
1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
....
1137
1138
1139
1140
1141
1142
1143

1144
1145
1146
1147
1148
1149
1150
....
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
....
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
....
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499

1500
1501
1502
1503
1504
1505
1506
....
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
**
*/
#include "config.h"
#include <string.h>
#include <time.h>
#include "timeline.h"






/*
** Add an appropriate tag to the output if "rid" is unpublished (private)
*/
#define UNPUB_TAG "<em>(unpublished)</em>"
void tag_private_status(int rid){
  if( content_is_private(rid) ){
    cgi_printf("%s", UNPUB_TAG);
................................................................................
**   10.  Short comment to user for repeated tickets and wiki
*/
void www_print_timeline(
  Stmt *pQuery,          /* Query to implement the timeline */
  int tmFlags,           /* Flags controlling display behavior */
  const char *zThisUser, /* Suppress links to this user */
  const char *zThisTag,  /* Suppress links to this tag */

  void (*xExtra)(int)    /* Routine to call on each line of display */
){
  int mxWikiLen;
  Blob comment;
  int prevTagid = 0;
  int suppressCnt = 0;
  char zPrevDate[20];
................................................................................
    if( suppressCnt ){
      @ <span class="timelineDisabled">... %d(suppressCnt) similar
      @ event%s(suppressCnt>1?"s":"") omitted.</span>
      suppressCnt = 0;
    }
    if( pendingEndTr ){
      @ </td></tr>



      pendingEndTr = 0;
    }
    if( fossil_strcmp(zType,"div")==0 ){
      if( !prevWasDivider ){
        @ <tr><td colspan="3"><hr /></td></tr>
      }
      prevWasDivider = 1;
      continue;
    }
    prevWasDivider = 0;
    /* Date format codes:
    **   (0)  HH:MM
................................................................................
      zTime[pos++] = zDate[11]; zTime[pos++] = zDate[12]; /* HH */
      zTime[pos++] = ':';
      zTime[pos++] = zDate[14]; zTime[pos++] = zDate[15]; /* MM */
      zTime[pos++] = 0;
    }else{
      zTime[0] = 0;
    }





    if( rid == vid ){
      @ <tr class="timelineCurrent">
    }else {
      @ <tr>
    }
    @ <td class="timelineTime">%s(zTime)</td>
    @ <td class="timelineGraph">
    if( tmFlags & TIMELINE_UCOLOR )  zBgClr = zUser ? hash_color(zUser) : 0;
................................................................................
      db_reset(&qparent);
      gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
                           zUuid, isLeaf);
      db_reset(&qbranch);
      @ <div id="m%d(gidx)"></div>
    }
    @</td>
    if( zBgClr && zBgClr[0] ){
      @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
    }else{
      @ <td class="timelineTableCell">
    }
    if( pGraph && zType[0]!='c' ){
      @ &bull;
    }
................................................................................
        }
      }
      db_reset(&fchngQuery);
      if( inUl ){
        @ </ul>
      }
    }
    pendingEndTr = 1;
  }
  if( suppressCnt ){
    @ <span class="timelineDisabled">... %d(suppressCnt) similar
    @ event%s(suppressCnt>1?"s":"") omitted.</span>
    suppressCnt = 0;
  }
  if( pendingEndTr ){
................................................................................
        "   AND event.objid=tagxref.rid",
        z
    );
  }
  return mtime;
}

/*
** The value of one second in julianday notation
*/
#define ONE_SECOND (1.0/86400.0)

/*
** zDate is a localtime date.  Insert records into the
** "timeline" table to cause <hr> to be inserted before and after
** entries of that date.  If zDate==NULL then put dividers around
** the event identified by rid.
*/
static void timeline_add_dividers(double rDate, int rid){
  char *zToDel = 0;
  if( rDate==0 ){
    rDate = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
  }
  db_multi_exec(
    "INSERT INTO timeline(rid,sortby,etype)"
    "VALUES(-1,%.16g,'div')",
    rDate-ONE_SECOND



  );

  db_multi_exec(
    "INSERT INTO timeline(rid,sortby,etype)"
    "VALUES(-2,%.17g,'div')",
    rDate+ONE_SECOND
  );
  fossil_free(zToDel);

}

/*
** Return all possible names for file zUuid.
*/
char *names_of_file(const char *zUuid){
  Stmt q;
................................................................................
  int noMerge = P("shortest")==0;           /* Follow merge links if shorter */
  int me_rid = name_to_typed_rid(P("me"),"ci");  /* me= for common ancestory */
  int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
  int pd_rid;
  double rBefore, rAfter, rCirca;     /* Boundary times */
  const char *z;
  char *zOlderButton = 0;             /* URL for Older button at the bottom */


  /* Set number of rows to display */
  z = P("n");
  if( z ){
    if( fossil_strcmp(z,"all")==0 ){
      nEntry = 0;
    }else{
................................................................................
    blob_append_sql(&sql, " AND event.objid IN ok");
    nd = 0;
    if( d_rid ){
      compute_descendants(d_rid, nEntry+1);
      nd = db_int(0, "SELECT count(*)-1 FROM ok");
      if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
      if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
      if( useDividers ) timeline_add_dividers(0, d_rid);
      db_multi_exec("DELETE FROM ok");
    }
    if( p_rid ){
      compute_ancestors(p_rid, nEntry+1, 0);
      np = db_int(0, "SELECT count(*)-1 FROM ok");
      if( np>0 ){
        if( nd>0 ) blob_appendf(&desc, " and ");
        blob_appendf(&desc, "%d ancestors", np);
        db_multi_exec("%s", blob_sql_text(&sql));
      }
      if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
    }
    blob_appendf(&desc, " of %z[%S]</a>",
                   href("%R/info/%s", zUuid), zUuid);
    if( d_rid ){
      if( p_rid ){
        /* If both p= and d= are set, we don't have the uuid of d yet. */
        zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid);
................................................................................
       "INSERT INTO ok VALUES(%d);"
       "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
       "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
       f_rid, f_rid, f_rid
    );
    blob_append_sql(&sql, " AND event.objid IN ok");
    db_multi_exec("%s", blob_sql_text(&sql));
    if( useDividers ) timeline_add_dividers(0, f_rid);
    blob_appendf(&desc, "Parents and children of check-in ");
    zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
    blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
    tmFlags |= TIMELINE_DISJOINT;
    style_submenu_binary("v","With Files","Without Files",
                         zType[0]!='a' && zType[0]!='c');
    if( (tmFlags & TIMELINE_UNHIDE)==0 ){
................................................................................
      db_multi_exec("%s", blob_sql_text(&sql2));
      blob_reset(&sql2);
      blob_append_sql(&sql,
          " AND event.mtime>=%f ORDER BY event.mtime ASC",
          rCirca
      );
      nEntry -= (nEntry+1)/2;
      if( useDividers ) timeline_add_dividers(rCirca, 0);
    }else{
      blob_append_sql(&sql, " ORDER BY event.mtime DESC");
    }
    if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry);
    db_multi_exec("%s", blob_sql_text(&sql));


    n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
    if( zYearMonth ){
      blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
    }else if( zYearWeek ){
      blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
    }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){
................................................................................
    style_submenu_element("Search", 0, "%R/search?y=c");
  }
  if( P("showid") ) tmFlags |= TIMELINE_SHOWRID;
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
  db_finalize(&q);
  if( zOlderButton ){
    @ %z(xhref("class='button'","%z",zOlderButton))Older</a>
  }
  style_footer();
}








>
>
>
>
>







 







>







 







>
>
>




|







 







>
>
>
>
>
|







 







|







 







<







 








<
<
<
<
<

|
<
<

<
<
<
<
<
<
<
<
<
>
>
>

>

|
<
|

<
>







 







>







 







|










|







 







|







 







<





>







 







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
...
562
563
564
565
566
567
568

569
570
571
572
573
574
575
...
985
986
987
988
989
990
991
992





993
994


995









996
997
998
999
1000
1001
1002

1003
1004

1005
1006
1007
1008
1009
1010
1011
1012
....
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
....
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
....
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
....
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
....
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
**
*/
#include "config.h"
#include <string.h>
#include <time.h>
#include "timeline.h"

/*
** The value of one second in julianday notation
*/
#define ONE_SECOND (1.0/86400.0)

/*
** Add an appropriate tag to the output if "rid" is unpublished (private)
*/
#define UNPUB_TAG "<em>(unpublished)</em>"
void tag_private_status(int rid){
  if( content_is_private(rid) ){
    cgi_printf("%s", UNPUB_TAG);
................................................................................
**   10.  Short comment to user for repeated tickets and wiki
*/
void www_print_timeline(
  Stmt *pQuery,          /* Query to implement the timeline */
  int tmFlags,           /* Flags controlling display behavior */
  const char *zThisUser, /* Suppress links to this user */
  const char *zThisTag,  /* Suppress links to this tag */
  int selectedRid,       /* Highlight the line with this RID value */
  void (*xExtra)(int)    /* Routine to call on each line of display */
){
  int mxWikiLen;
  Blob comment;
  int prevTagid = 0;
  int suppressCnt = 0;
  char zPrevDate[20];
................................................................................
    if( suppressCnt ){
      @ <span class="timelineDisabled">... %d(suppressCnt) similar
      @ event%s(suppressCnt>1?"s":"") omitted.</span>
      suppressCnt = 0;
    }
    if( pendingEndTr ){
      @ </td></tr>
      if( pendingEndTr>1 ){
        @ <tr class="timelineSpacer"></tr>
      }
      pendingEndTr = 0;
    }
    if( fossil_strcmp(zType,"div")==0 ){
      if( !prevWasDivider ){
        @ <tr><td colspan="3"><hr class="timelineMarker"/></td></tr>
      }
      prevWasDivider = 1;
      continue;
    }
    prevWasDivider = 0;
    /* Date format codes:
    **   (0)  HH:MM
................................................................................
      zTime[pos++] = zDate[11]; zTime[pos++] = zDate[12]; /* HH */
      zTime[pos++] = ':';
      zTime[pos++] = zDate[14]; zTime[pos++] = zDate[15]; /* MM */
      zTime[pos++] = 0;
    }else{
      zTime[0] = 0;
    }
    pendingEndTr = 1;
    if( rid==selectedRid ){
      @ <tr class="timelineSpacer"></tr>
      @ <tr class="timelineSelected">
      pendingEndTr = 2;
    }else if( rid==vid ){
      @ <tr class="timelineCurrent">
    }else {
      @ <tr>
    }
    @ <td class="timelineTime">%s(zTime)</td>
    @ <td class="timelineGraph">
    if( tmFlags & TIMELINE_UCOLOR )  zBgClr = zUser ? hash_color(zUser) : 0;
................................................................................
      db_reset(&qparent);
      gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
                           zUuid, isLeaf);
      db_reset(&qbranch);
      @ <div id="m%d(gidx)"></div>
    }
    @</td>
    if( zBgClr && zBgClr[0] && rid!=selectedRid ){
      @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
    }else{
      @ <td class="timelineTableCell">
    }
    if( pGraph && zType[0]!='c' ){
      @ &bull;
    }
................................................................................
        }
      }
      db_reset(&fchngQuery);
      if( inUl ){
        @ </ul>
      }
    }

  }
  if( suppressCnt ){
    @ <span class="timelineDisabled">... %d(suppressCnt) similar
    @ event%s(suppressCnt>1?"s":"") omitted.</span>
    suppressCnt = 0;
  }
  if( pendingEndTr ){
................................................................................
        "   AND event.objid=tagxref.rid",
        z
    );
  }
  return mtime;
}

/*





** zDate is a localtime date.  Insert records into the
** "timeline" table to cause <hr> to be inserted on zDate.


*/









static int timeline_add_divider(double rDate){
  int rid = db_int(-1,
    "SELECT rid FROM timeline ORDER BY abs(sortby-%.16g) LIMIT 1", rDate
  );
  if( rid>0 ) return rid;
  db_multi_exec(
    "INSERT INTO timeline(rid,sortby,etype) VALUES(-1,%.16g,'div')",

    rDate
  );

  return -1;
}

/*
** Return all possible names for file zUuid.
*/
char *names_of_file(const char *zUuid){
  Stmt q;
................................................................................
  int noMerge = P("shortest")==0;           /* Follow merge links if shorter */
  int me_rid = name_to_typed_rid(P("me"),"ci");  /* me= for common ancestory */
  int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
  int pd_rid;
  double rBefore, rAfter, rCirca;     /* Boundary times */
  const char *z;
  char *zOlderButton = 0;             /* URL for Older button at the bottom */
  int selectedRid = -9999999;         /* Show a highlight on this RID */

  /* Set number of rows to display */
  z = P("n");
  if( z ){
    if( fossil_strcmp(z,"all")==0 ){
      nEntry = 0;
    }else{
................................................................................
    blob_append_sql(&sql, " AND event.objid IN ok");
    nd = 0;
    if( d_rid ){
      compute_descendants(d_rid, nEntry+1);
      nd = db_int(0, "SELECT count(*)-1 FROM ok");
      if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
      if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
      if( useDividers ) selectedRid = d_rid;
      db_multi_exec("DELETE FROM ok");
    }
    if( p_rid ){
      compute_ancestors(p_rid, nEntry+1, 0);
      np = db_int(0, "SELECT count(*)-1 FROM ok");
      if( np>0 ){
        if( nd>0 ) blob_appendf(&desc, " and ");
        blob_appendf(&desc, "%d ancestors", np);
        db_multi_exec("%s", blob_sql_text(&sql));
      }
      if( useDividers ) selectedRid = p_rid;
    }
    blob_appendf(&desc, " of %z[%S]</a>",
                   href("%R/info/%s", zUuid), zUuid);
    if( d_rid ){
      if( p_rid ){
        /* If both p= and d= are set, we don't have the uuid of d yet. */
        zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid);
................................................................................
       "INSERT INTO ok VALUES(%d);"
       "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
       "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
       f_rid, f_rid, f_rid
    );
    blob_append_sql(&sql, " AND event.objid IN ok");
    db_multi_exec("%s", blob_sql_text(&sql));
    if( useDividers ) selectedRid = f_rid;
    blob_appendf(&desc, "Parents and children of check-in ");
    zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
    blob_appendf(&desc, "%z[%S]</a>", href("%R/info/%s", zUuid), zUuid);
    tmFlags |= TIMELINE_DISJOINT;
    style_submenu_binary("v","With Files","Without Files",
                         zType[0]!='a' && zType[0]!='c');
    if( (tmFlags & TIMELINE_UNHIDE)==0 ){
................................................................................
      db_multi_exec("%s", blob_sql_text(&sql2));
      blob_reset(&sql2);
      blob_append_sql(&sql,
          " AND event.mtime>=%f ORDER BY event.mtime ASC",
          rCirca
      );
      nEntry -= (nEntry+1)/2;

    }else{
      blob_append_sql(&sql, " ORDER BY event.mtime DESC");
    }
    if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry);
    db_multi_exec("%s", blob_sql_text(&sql));
    if( zCirca && useDividers ) selectedRid = timeline_add_divider(rCirca);

    n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
    if( zYearMonth ){
      blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
    }else if( zYearWeek ){
      blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
    }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){
................................................................................
    style_submenu_element("Search", 0, "%R/search?y=c");
  }
  if( P("showid") ) tmFlags |= TIMELINE_SHOWRID;
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, selectedRid, 0);
  db_finalize(&q);
  if( zOlderButton ){
    @ %z(xhref("class='button'","%z",zOlderButton))Older</a>
  }
  style_footer();
}

Changes to src/tkt.c.

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
                  " WHERE target=%Q) "
         "ORDER BY mtime DESC",
         timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
    );
  }
  db_prepare(&q, "%z", zSQL/*safe-for-%s*/);
  www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
                     0, 0, 0);
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: tkthistory
** URL: /tkthistory?name=TICKETUUID







|







891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
                  " WHERE target=%Q) "
         "ORDER BY mtime DESC",
         timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
    );
  }
  db_prepare(&q, "%z", zSQL/*safe-for-%s*/);
  www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
                     0, 0, 0, 0);
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: tkthistory
** URL: /tkthistory?name=TICKETUUID

Changes to src/wiki.c.

850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
                 "  (SELECT rid FROM tagxref WHERE tagid="
                       "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
                 "   UNION SELECT attachid FROM attachment"
                          " WHERE target=%Q)"
                 "ORDER BY mtime DESC",
                 timeline_query_for_www(), zPageName, zPageName);
  zWikiPageName = zPageName;
  www_print_timeline(&q, TIMELINE_ARTID, 0, 0, wiki_history_extra);
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: wdiff
** URL: /whistory?name=PAGENAME&a=RID1&b=RID2







|







850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
                 "  (SELECT rid FROM tagxref WHERE tagid="
                       "(SELECT tagid FROM tag WHERE tagname='wiki-%q')"
                 "   UNION SELECT attachid FROM attachment"
                          " WHERE target=%Q)"
                 "ORDER BY mtime DESC",
                 timeline_query_for_www(), zPageName, zPageName);
  zWikiPageName = zPageName;
  www_print_timeline(&q, TIMELINE_ARTID, 0, 0, 0, wiki_history_extra);
  db_finalize(&q);
  style_footer();
}

/*
** WEBPAGE: wdiff
** URL: /whistory?name=PAGENAME&a=RID1&b=RID2