Fossil SCM

Merge updates from trunk.

mistachkin 2013-10-22 08:34 tkt-change-hook merge
Commit 0943f372461494f805b3fc6c5a5a3add515566c7
+1 -1
--- src/allrepo.c
+++ src/allrepo.c
@@ -103,11 +103,11 @@
103103
** subsequent clean, extra, list, pull, push, rebuild, and
104104
** sync operations. The -c|--ckout option causes the listed
105105
** local checkouts to be ignored instead.
106106
**
107107
** list | ls Display the location of all repositories. The -c|--ckout
108
-** option causes all local checkouts to be list instead.
108
+** option causes all local checkouts to be listed instead.
109109
**
110110
** pull Run a "pull" operation on all repositories. Only the
111111
** --verbose option is supported.
112112
**
113113
** push Run a "push" on all repositories. Only the --verbose
114114
--- src/allrepo.c
+++ src/allrepo.c
@@ -103,11 +103,11 @@
103 ** subsequent clean, extra, list, pull, push, rebuild, and
104 ** sync operations. The -c|--ckout option causes the listed
105 ** local checkouts to be ignored instead.
106 **
107 ** list | ls Display the location of all repositories. The -c|--ckout
108 ** option causes all local checkouts to be list instead.
109 **
110 ** pull Run a "pull" operation on all repositories. Only the
111 ** --verbose option is supported.
112 **
113 ** push Run a "push" on all repositories. Only the --verbose
114
--- src/allrepo.c
+++ src/allrepo.c
@@ -103,11 +103,11 @@
103 ** subsequent clean, extra, list, pull, push, rebuild, and
104 ** sync operations. The -c|--ckout option causes the listed
105 ** local checkouts to be ignored instead.
106 **
107 ** list | ls Display the location of all repositories. The -c|--ckout
108 ** option causes all local checkouts to be listed instead.
109 **
110 ** pull Run a "pull" operation on all repositories. Only the
111 ** --verbose option is supported.
112 **
113 ** push Run a "push" on all repositories. Only the --verbose
114
+41
--- src/setup.c
+++ src/setup.c
@@ -850,10 +850,37 @@
850850
@ <span class="textareaLabel">%s(zLabel)</span>
851851
}
852852
}
853853
}
854854
855
+/*
856
+** Generate a text box for an attribute.
857
+*/
858
+static void multiple_choice_attribute(
859
+ const char *zLabel, /* The text label on the menu */
860
+ const char *zVar, /* The corresponding row in the VAR table */
861
+ const char *zQP, /* The query parameter */
862
+ const char *zDflt, /* Default value if VAR table entry does not exist */
863
+ int nChoice, /* Number of choices */
864
+ const char **azChoice /* Choices. 2 per choice: (VAR value, Display) */
865
+){
866
+ const char *z = db_get(zVar, (char*)zDflt);
867
+ const char *zQ = P(zQP);
868
+ int i;
869
+ if( zQ && fossil_strcmp(zQ,z)!=0){
870
+ login_verify_csrf_secret();
871
+ db_set(zVar, zQ, 0);
872
+ z = zQ;
873
+ }
874
+ @ <select size="1" name="%s(zQP)" id="id%s(zQP)">
875
+ for(i=0; i<nChoice*2; i+=2){
876
+ const char *zSel = fossil_strcmp(azChoice[i],z)==0 ? " selected" : "";
877
+ @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
878
+ }
879
+ @ </select>
880
+}
881
+
855882
856883
/*
857884
** WEBPAGE: setup_access
858885
*/
859886
void setup_access(void){
@@ -1124,10 +1151,16 @@
11241151
** WEBPAGE: setup_timeline
11251152
*/
11261153
void setup_timeline(void){
11271154
double tmDiff;
11281155
char zTmDiff[20];
1156
+ static const char *azTimeFormats[] = {
1157
+ "0", "HH:MM",
1158
+ "1", "HH:MM:SS",
1159
+ "2", "YYYY-MM-DD HH:MM",
1160
+ "3", "YYMMDD HH:MM"
1161
+ };
11291162
login_check_credentials();
11301163
if( !g.perm.Setup ){
11311164
login_needed();
11321165
}
11331166
@@ -1167,10 +1200,18 @@
11671200
@ %s(zTmDiff) hours behind UTC.</p>
11681201
}else{
11691202
@ %s(zTmDiff) hours ahead of UTC.</p>
11701203
}
11711204
1205
+ @ <hr />
1206
+ multiple_choice_attribute("Per-Item Time Format", "timeline-date-format", "tdf", "0",
1207
+ 4, azTimeFormats);
1208
+ @ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown
1209
+ @ in a separate box (using CSS class "timelineDate") whenever the date changes.
1210
+ @ With the "YYYY-MM-DD&nbsp;HH:MM" and "YYMMDD ..." formats, the complete date
1211
+ @ and time is shown on every timeline entry (using the CSS class "timelineTime").</p>
1212
+
11721213
@ <hr />
11731214
onoff_attribute("Show version differences by default",
11741215
"show-version-diffs", "vdiff", 0, 0);
11751216
@ <p>On the version-information pages linked from the timeline can either
11761217
@ show complete diffs of all file changes, or can just list the names of
11771218
--- src/setup.c
+++ src/setup.c
@@ -850,10 +850,37 @@
850 @ <span class="textareaLabel">%s(zLabel)</span>
851 }
852 }
853 }
854
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
856 /*
857 ** WEBPAGE: setup_access
858 */
859 void setup_access(void){
@@ -1124,10 +1151,16 @@
1124 ** WEBPAGE: setup_timeline
1125 */
1126 void setup_timeline(void){
1127 double tmDiff;
1128 char zTmDiff[20];
 
 
 
 
 
 
1129 login_check_credentials();
1130 if( !g.perm.Setup ){
1131 login_needed();
1132 }
1133
@@ -1167,10 +1200,18 @@
1167 @ %s(zTmDiff) hours behind UTC.</p>
1168 }else{
1169 @ %s(zTmDiff) hours ahead of UTC.</p>
1170 }
1171
 
 
 
 
 
 
 
 
1172 @ <hr />
1173 onoff_attribute("Show version differences by default",
1174 "show-version-diffs", "vdiff", 0, 0);
1175 @ <p>On the version-information pages linked from the timeline can either
1176 @ show complete diffs of all file changes, or can just list the names of
1177
--- src/setup.c
+++ src/setup.c
@@ -850,10 +850,37 @@
850 @ <span class="textareaLabel">%s(zLabel)</span>
851 }
852 }
853 }
854
855 /*
856 ** Generate a text box for an attribute.
857 */
858 static void multiple_choice_attribute(
859 const char *zLabel, /* The text label on the menu */
860 const char *zVar, /* The corresponding row in the VAR table */
861 const char *zQP, /* The query parameter */
862 const char *zDflt, /* Default value if VAR table entry does not exist */
863 int nChoice, /* Number of choices */
864 const char **azChoice /* Choices. 2 per choice: (VAR value, Display) */
865 ){
866 const char *z = db_get(zVar, (char*)zDflt);
867 const char *zQ = P(zQP);
868 int i;
869 if( zQ && fossil_strcmp(zQ,z)!=0){
870 login_verify_csrf_secret();
871 db_set(zVar, zQ, 0);
872 z = zQ;
873 }
874 @ <select size="1" name="%s(zQP)" id="id%s(zQP)">
875 for(i=0; i<nChoice*2; i+=2){
876 const char *zSel = fossil_strcmp(azChoice[i],z)==0 ? " selected" : "";
877 @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
878 }
879 @ </select>
880 }
881
882
883 /*
884 ** WEBPAGE: setup_access
885 */
886 void setup_access(void){
@@ -1124,10 +1151,16 @@
1151 ** WEBPAGE: setup_timeline
1152 */
1153 void setup_timeline(void){
1154 double tmDiff;
1155 char zTmDiff[20];
1156 static const char *azTimeFormats[] = {
1157 "0", "HH:MM",
1158 "1", "HH:MM:SS",
1159 "2", "YYYY-MM-DD HH:MM",
1160 "3", "YYMMDD HH:MM"
1161 };
1162 login_check_credentials();
1163 if( !g.perm.Setup ){
1164 login_needed();
1165 }
1166
@@ -1167,10 +1200,18 @@
1200 @ %s(zTmDiff) hours behind UTC.</p>
1201 }else{
1202 @ %s(zTmDiff) hours ahead of UTC.</p>
1203 }
1204
1205 @ <hr />
1206 multiple_choice_attribute("Per-Item Time Format", "timeline-date-format", "tdf", "0",
1207 4, azTimeFormats);
1208 @ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown
1209 @ in a separate box (using CSS class "timelineDate") whenever the date changes.
1210 @ With the "YYYY-MM-DD&nbsp;HH:MM" and "YYMMDD ..." formats, the complete date
1211 @ and time is shown on every timeline entry (using the CSS class "timelineTime").</p>
1212
1213 @ <hr />
1214 onoff_attribute("Show version differences by default",
1215 "show-version-diffs", "vdiff", 0, 0);
1216 @ <p>On the version-information pages linked from the timeline can either
1217 @ show complete diffs of all file changes, or can just list the names of
1218
--- src/style.c
+++ src/style.c
@@ -686,10 +686,11 @@
686686
},
687687
{ "td.timelineTime",
688688
"the format for the timeline time display",
689689
@ vertical-align: top;
690690
@ text-align: right;
691
+ @ white-space: nowrap;
691692
},
692693
{ "td.timelineGraph",
693694
"the format for the grap placeholder cells in timelines",
694695
@ width: 20px;
695696
@ text-align: left;
696697
--- src/style.c
+++ src/style.c
@@ -686,10 +686,11 @@
686 },
687 { "td.timelineTime",
688 "the format for the timeline time display",
689 @ vertical-align: top;
690 @ text-align: right;
 
691 },
692 { "td.timelineGraph",
693 "the format for the grap placeholder cells in timelines",
694 @ width: 20px;
695 @ text-align: left;
696
--- src/style.c
+++ src/style.c
@@ -686,10 +686,11 @@
686 },
687 { "td.timelineTime",
688 "the format for the timeline time display",
689 @ vertical-align: top;
690 @ text-align: right;
691 @ white-space: nowrap;
692 },
693 { "td.timelineGraph",
694 "the format for the grap placeholder cells in timelines",
695 @ width: 20px;
696 @ text-align: left;
697
+43 -16
--- src/timeline.c
+++ src/timeline.c
@@ -246,16 +246,20 @@
246246
int fchngQueryInit = 0; /* True if fchngQuery is initialized */
247247
Stmt fchngQuery; /* Query for file changes on check-ins */
248248
static Stmt qbranch;
249249
int pendingEndTr = 0; /* True if a </td></tr> is needed */
250250
int vid = 0; /* Current checkout version */
251
+ int dateFormat = 0; /* 0: HH:MM 1: HH:MM:SS
252
+ 2: YYYY-MM-DD HH:MM
253
+ 3: YYMMDD HH:MM */
251254
252255
if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
253256
vid = db_lget_int("checkout", 0);
254257
}
255258
zPrevDate[0] = 0;
256259
mxWikiLen = db_get_int("timeline-max-comment", 0);
260
+ dateFormat = db_get_int("timeline-date-format", 0);
257261
if( tmFlags & TIMELINE_GRAPH ){
258262
pGraph = graph_init();
259263
/* style is not moved to css, because this is
260264
** a technical div for the timeline graph
261265
*/
@@ -282,11 +286,11 @@
282286
int tagid = db_column_int(pQuery, 9);
283287
const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
284288
const char *zBr = 0; /* Branch */
285289
int commentColumn = 3; /* Column containing comment text */
286290
int modPending; /* Pending moderation */
287
- char zTime[8];
291
+ char zTime[20];
288292
289293
modPending = moderation_pending(rid);
290294
if( tagid ){
291295
if( modPending ) tagid = -tagid;
292296
if( tagid==prevTagid ){
@@ -314,18 +318,34 @@
314318
}
315319
prevWasDivider = 1;
316320
continue;
317321
}
318322
prevWasDivider = 0;
319
- if( memcmp(zDate, zPrevDate, 10) ){
320
- sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
321
- @ <tr><td>
322
- @ <div class="divider">%s(zPrevDate)</div>
323
- @ </td><td></td><td></td></tr>
324
- }
325
- memcpy(zTime, &zDate[11], 5);
326
- zTime[5] = 0;
323
+ if( dateFormat<2 ){
324
+ if( memcmp(zDate, zPrevDate, 10) ){
325
+ sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
326
+ @ <tr><td>
327
+ @ <div class="divider timelineDate">%s(zPrevDate)</div>
328
+ @ </td><td></td><td></td></tr>
329
+ }
330
+ memcpy(zTime, &zDate[11], 5+dateFormat*3);
331
+ zTime[5+dateFormat*3] = 0;
332
+ }else if(3==dateFormat){
333
+ /* YYMMDD HH:MM */
334
+ int pos = 0;
335
+ zTime[pos++] = zDate[2]; zTime[pos++] = zDate[3]; /* YY */
336
+ zTime[pos++] = zDate[5]; zTime[pos++] = zDate[6]; /* MM */
337
+ zTime[pos++] = zDate[8]; zTime[pos++] = zDate[9]; /* DD */
338
+ zTime[pos++] = ' ';
339
+ zTime[pos++] = zDate[11]; zTime[pos++] = zDate[12]; /* HH */
340
+ zTime[pos++] = ':';
341
+ zTime[pos++] = zDate[14]; zTime[pos++] = zDate[15]; /* MM */
342
+ zTime[pos++] = 0;
343
+ }else{
344
+ /* YYYY-MM-DD HH:MM */
345
+ sqlite3_snprintf(sizeof(zTime), zTime, "%.16s", zDate);
346
+ }
327347
if( rid == vid ){
328348
@ <tr class="timelineCurrent">
329349
}else {
330350
@ <tr>
331351
}
@@ -1474,11 +1494,14 @@
14741494
14751495
/*
14761496
** The input query q selects various records. Print a human-readable
14771497
** summary of those records.
14781498
**
1479
-** Limit the number of entries printed to nLine.
1499
+** Limit the number of lines printed to mxLine. If mxLine is zero or
1500
+** negative there is no limit. The line limit is approximate because
1501
+** it is only checked on a per-entry basis. In verbose mode, the file
1502
+** name details are considered to be part of the entry.
14801503
**
14811504
** The query should return these columns:
14821505
**
14831506
** 0. rid
14841507
** 1. uuid
@@ -1500,11 +1523,11 @@
15001523
if( g.localOpen ){
15011524
int rid = db_lget_int("checkout", 0);
15021525
zCurrentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
15031526
}
15041527
1505
- while( db_step(q)==SQLITE_ROW && nLine<=mxLine ){
1528
+ while( db_step(q)==SQLITE_ROW && (mxLine<=0 || nLine<=mxLine) ){
15061529
int rid = db_column_int(q, 0);
15071530
const char *zId = db_column_text(q, 1);
15081531
const char *zDate = db_column_text(q, 2);
15091532
const char *zCom = db_column_text(q, 3);
15101533
int nChild = db_column_int(q, 4);
@@ -1516,11 +1539,11 @@
15161539
15171540
sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId);
15181541
if( memcmp(zDate, zPrevDate, 10) ){
15191542
fossil_print("=== %.10s ===\n", zDate);
15201543
memcpy(zPrevDate, zDate, 10);
1521
- nLine++;
1544
+ nLine++; /* record another line */
15221545
}
15231546
if( zCom==0 ) zCom = "";
15241547
fossil_print("%.8s ", &zDate[11]);
15251548
zPrefix[0] = 0;
15261549
if( nParent>1 ){
@@ -1540,11 +1563,11 @@
15401563
if( fossil_strcmp(zCurrentUuid,zId)==0 ){
15411564
sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* ");
15421565
n += strlen(zPrefix);
15431566
}
15441567
zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom);
1545
- nLine += comment_print(zFree, 9, 79);
1568
+ nLine += comment_print(zFree, 9, 79); /* record another X lines */
15461569
sqlite3_free(zFree);
15471570
15481571
if(verboseFlag){
15491572
if( !fchngQueryInit ){
15501573
db_prepare(&fchngQuery,
@@ -1569,10 +1592,11 @@
15691592
}else if( isDel ){
15701593
fossil_print(" DELETED %s\n",zFilename);
15711594
}else{
15721595
fossil_print(" EDITED %s\n", zFilename);
15731596
}
1597
+ nLine++; /* record another line */
15741598
}
15751599
db_reset(&fchngQuery);
15761600
}
15771601
}
15781602
if( fchngQueryInit ) db_finalize(&fchngQuery);
@@ -2097,14 +2121,15 @@
20972121
}
20982122
db_reset(&query);
20992123
while( SQLITE_ROW == db_step(&query) ){
21002124
const char * zTimeframe = db_column_text(&query, 0);
21012125
const int nCount = db_column_int(&query, 1);
2102
- const int nSize = nCount
2126
+ int nSize = nCount
21032127
? (int)(100 * nCount / nMaxEvents)
21042128
: 1;
21052129
showYearTotal = 0;
2130
+ if(!nSize) nSize = 1;
21062131
if(includeMonth){
21072132
/* For Month/year view, add a separator for each distinct year. */
21082133
if(!*zPrevYear ||
21092134
(0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
21102135
showYearTotal = *zPrevYear;
@@ -2231,14 +2256,15 @@
22312256
}
22322257
db_reset(&query);
22332258
while( SQLITE_ROW == db_step(&query) ){
22342259
const char * zUser = db_column_text(&query, 0);
22352260
const int nCount = db_column_int(&query, 1);
2236
- const int nSize = nCount
2261
+ int nSize = nCount
22372262
? (int)(100 * nCount / nMaxEvents)
22382263
: 0;
22392264
if(!nCount) continue /* arguable! Possible? */;
2265
+ else if(!nSize) nSize = 1;
22402266
rowClass = ++nRowNumber % 2;
22412267
nEventTotal += nCount;
22422268
@<tr class='row%d(rowClass)'>
22432269
@ <td>
22442270
@ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
@@ -2347,13 +2373,14 @@
23472373
}
23482374
db_reset(&stWeek);
23492375
while( SQLITE_ROW == db_step(&stWeek) ){
23502376
const char * zWeek = db_column_text(&stWeek,0);
23512377
const int nCount = db_column_int(&stWeek,1);
2352
- const int nSize = nCount
2378
+ int nSize = nCount
23532379
? (int)(100 * nCount / nMaxEvents)
23542380
: 0;
2381
+ if(!nSize) nSize = 1;
23552382
total += nCount;
23562383
cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
23572384
cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s",
23582385
g.zTop, zYear, zWeek, nCount,
23592386
statsReportTimelineYFlag);
23602387
--- src/timeline.c
+++ src/timeline.c
@@ -246,16 +246,20 @@
246 int fchngQueryInit = 0; /* True if fchngQuery is initialized */
247 Stmt fchngQuery; /* Query for file changes on check-ins */
248 static Stmt qbranch;
249 int pendingEndTr = 0; /* True if a </td></tr> is needed */
250 int vid = 0; /* Current checkout version */
 
 
 
251
252 if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
253 vid = db_lget_int("checkout", 0);
254 }
255 zPrevDate[0] = 0;
256 mxWikiLen = db_get_int("timeline-max-comment", 0);
 
257 if( tmFlags & TIMELINE_GRAPH ){
258 pGraph = graph_init();
259 /* style is not moved to css, because this is
260 ** a technical div for the timeline graph
261 */
@@ -282,11 +286,11 @@
282 int tagid = db_column_int(pQuery, 9);
283 const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
284 const char *zBr = 0; /* Branch */
285 int commentColumn = 3; /* Column containing comment text */
286 int modPending; /* Pending moderation */
287 char zTime[8];
288
289 modPending = moderation_pending(rid);
290 if( tagid ){
291 if( modPending ) tagid = -tagid;
292 if( tagid==prevTagid ){
@@ -314,18 +318,34 @@
314 }
315 prevWasDivider = 1;
316 continue;
317 }
318 prevWasDivider = 0;
319 if( memcmp(zDate, zPrevDate, 10) ){
320 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
321 @ <tr><td>
322 @ <div class="divider">%s(zPrevDate)</div>
323 @ </td><td></td><td></td></tr>
324 }
325 memcpy(zTime, &zDate[11], 5);
326 zTime[5] = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327 if( rid == vid ){
328 @ <tr class="timelineCurrent">
329 }else {
330 @ <tr>
331 }
@@ -1474,11 +1494,14 @@
1474
1475 /*
1476 ** The input query q selects various records. Print a human-readable
1477 ** summary of those records.
1478 **
1479 ** Limit the number of entries printed to nLine.
 
 
 
1480 **
1481 ** The query should return these columns:
1482 **
1483 ** 0. rid
1484 ** 1. uuid
@@ -1500,11 +1523,11 @@
1500 if( g.localOpen ){
1501 int rid = db_lget_int("checkout", 0);
1502 zCurrentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1503 }
1504
1505 while( db_step(q)==SQLITE_ROW && nLine<=mxLine ){
1506 int rid = db_column_int(q, 0);
1507 const char *zId = db_column_text(q, 1);
1508 const char *zDate = db_column_text(q, 2);
1509 const char *zCom = db_column_text(q, 3);
1510 int nChild = db_column_int(q, 4);
@@ -1516,11 +1539,11 @@
1516
1517 sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId);
1518 if( memcmp(zDate, zPrevDate, 10) ){
1519 fossil_print("=== %.10s ===\n", zDate);
1520 memcpy(zPrevDate, zDate, 10);
1521 nLine++;
1522 }
1523 if( zCom==0 ) zCom = "";
1524 fossil_print("%.8s ", &zDate[11]);
1525 zPrefix[0] = 0;
1526 if( nParent>1 ){
@@ -1540,11 +1563,11 @@
1540 if( fossil_strcmp(zCurrentUuid,zId)==0 ){
1541 sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* ");
1542 n += strlen(zPrefix);
1543 }
1544 zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom);
1545 nLine += comment_print(zFree, 9, 79);
1546 sqlite3_free(zFree);
1547
1548 if(verboseFlag){
1549 if( !fchngQueryInit ){
1550 db_prepare(&fchngQuery,
@@ -1569,10 +1592,11 @@
1569 }else if( isDel ){
1570 fossil_print(" DELETED %s\n",zFilename);
1571 }else{
1572 fossil_print(" EDITED %s\n", zFilename);
1573 }
 
1574 }
1575 db_reset(&fchngQuery);
1576 }
1577 }
1578 if( fchngQueryInit ) db_finalize(&fchngQuery);
@@ -2097,14 +2121,15 @@
2097 }
2098 db_reset(&query);
2099 while( SQLITE_ROW == db_step(&query) ){
2100 const char * zTimeframe = db_column_text(&query, 0);
2101 const int nCount = db_column_int(&query, 1);
2102 const int nSize = nCount
2103 ? (int)(100 * nCount / nMaxEvents)
2104 : 1;
2105 showYearTotal = 0;
 
2106 if(includeMonth){
2107 /* For Month/year view, add a separator for each distinct year. */
2108 if(!*zPrevYear ||
2109 (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
2110 showYearTotal = *zPrevYear;
@@ -2231,14 +2256,15 @@
2231 }
2232 db_reset(&query);
2233 while( SQLITE_ROW == db_step(&query) ){
2234 const char * zUser = db_column_text(&query, 0);
2235 const int nCount = db_column_int(&query, 1);
2236 const int nSize = nCount
2237 ? (int)(100 * nCount / nMaxEvents)
2238 : 0;
2239 if(!nCount) continue /* arguable! Possible? */;
 
2240 rowClass = ++nRowNumber % 2;
2241 nEventTotal += nCount;
2242 @<tr class='row%d(rowClass)'>
2243 @ <td>
2244 @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
@@ -2347,13 +2373,14 @@
2347 }
2348 db_reset(&stWeek);
2349 while( SQLITE_ROW == db_step(&stWeek) ){
2350 const char * zWeek = db_column_text(&stWeek,0);
2351 const int nCount = db_column_int(&stWeek,1);
2352 const int nSize = nCount
2353 ? (int)(100 * nCount / nMaxEvents)
2354 : 0;
 
2355 total += nCount;
2356 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2357 cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s",
2358 g.zTop, zYear, zWeek, nCount,
2359 statsReportTimelineYFlag);
2360
--- src/timeline.c
+++ src/timeline.c
@@ -246,16 +246,20 @@
246 int fchngQueryInit = 0; /* True if fchngQuery is initialized */
247 Stmt fchngQuery; /* Query for file changes on check-ins */
248 static Stmt qbranch;
249 int pendingEndTr = 0; /* True if a </td></tr> is needed */
250 int vid = 0; /* Current checkout version */
251 int dateFormat = 0; /* 0: HH:MM 1: HH:MM:SS
252 2: YYYY-MM-DD HH:MM
253 3: YYMMDD HH:MM */
254
255 if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
256 vid = db_lget_int("checkout", 0);
257 }
258 zPrevDate[0] = 0;
259 mxWikiLen = db_get_int("timeline-max-comment", 0);
260 dateFormat = db_get_int("timeline-date-format", 0);
261 if( tmFlags & TIMELINE_GRAPH ){
262 pGraph = graph_init();
263 /* style is not moved to css, because this is
264 ** a technical div for the timeline graph
265 */
@@ -282,11 +286,11 @@
286 int tagid = db_column_int(pQuery, 9);
287 const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
288 const char *zBr = 0; /* Branch */
289 int commentColumn = 3; /* Column containing comment text */
290 int modPending; /* Pending moderation */
291 char zTime[20];
292
293 modPending = moderation_pending(rid);
294 if( tagid ){
295 if( modPending ) tagid = -tagid;
296 if( tagid==prevTagid ){
@@ -314,18 +318,34 @@
318 }
319 prevWasDivider = 1;
320 continue;
321 }
322 prevWasDivider = 0;
323 if( dateFormat<2 ){
324 if( memcmp(zDate, zPrevDate, 10) ){
325 sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
326 @ <tr><td>
327 @ <div class="divider timelineDate">%s(zPrevDate)</div>
328 @ </td><td></td><td></td></tr>
329 }
330 memcpy(zTime, &zDate[11], 5+dateFormat*3);
331 zTime[5+dateFormat*3] = 0;
332 }else if(3==dateFormat){
333 /* YYMMDD HH:MM */
334 int pos = 0;
335 zTime[pos++] = zDate[2]; zTime[pos++] = zDate[3]; /* YY */
336 zTime[pos++] = zDate[5]; zTime[pos++] = zDate[6]; /* MM */
337 zTime[pos++] = zDate[8]; zTime[pos++] = zDate[9]; /* DD */
338 zTime[pos++] = ' ';
339 zTime[pos++] = zDate[11]; zTime[pos++] = zDate[12]; /* HH */
340 zTime[pos++] = ':';
341 zTime[pos++] = zDate[14]; zTime[pos++] = zDate[15]; /* MM */
342 zTime[pos++] = 0;
343 }else{
344 /* YYYY-MM-DD HH:MM */
345 sqlite3_snprintf(sizeof(zTime), zTime, "%.16s", zDate);
346 }
347 if( rid == vid ){
348 @ <tr class="timelineCurrent">
349 }else {
350 @ <tr>
351 }
@@ -1474,11 +1494,14 @@
1494
1495 /*
1496 ** The input query q selects various records. Print a human-readable
1497 ** summary of those records.
1498 **
1499 ** Limit the number of lines printed to mxLine. If mxLine is zero or
1500 ** negative there is no limit. The line limit is approximate because
1501 ** it is only checked on a per-entry basis. In verbose mode, the file
1502 ** name details are considered to be part of the entry.
1503 **
1504 ** The query should return these columns:
1505 **
1506 ** 0. rid
1507 ** 1. uuid
@@ -1500,11 +1523,11 @@
1523 if( g.localOpen ){
1524 int rid = db_lget_int("checkout", 0);
1525 zCurrentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1526 }
1527
1528 while( db_step(q)==SQLITE_ROW && (mxLine<=0 || nLine<=mxLine) ){
1529 int rid = db_column_int(q, 0);
1530 const char *zId = db_column_text(q, 1);
1531 const char *zDate = db_column_text(q, 2);
1532 const char *zCom = db_column_text(q, 3);
1533 int nChild = db_column_int(q, 4);
@@ -1516,11 +1539,11 @@
1539
1540 sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId);
1541 if( memcmp(zDate, zPrevDate, 10) ){
1542 fossil_print("=== %.10s ===\n", zDate);
1543 memcpy(zPrevDate, zDate, 10);
1544 nLine++; /* record another line */
1545 }
1546 if( zCom==0 ) zCom = "";
1547 fossil_print("%.8s ", &zDate[11]);
1548 zPrefix[0] = 0;
1549 if( nParent>1 ){
@@ -1540,11 +1563,11 @@
1563 if( fossil_strcmp(zCurrentUuid,zId)==0 ){
1564 sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* ");
1565 n += strlen(zPrefix);
1566 }
1567 zFree = sqlite3_mprintf("[%.10s] %s%s", zUuid, zPrefix, zCom);
1568 nLine += comment_print(zFree, 9, 79); /* record another X lines */
1569 sqlite3_free(zFree);
1570
1571 if(verboseFlag){
1572 if( !fchngQueryInit ){
1573 db_prepare(&fchngQuery,
@@ -1569,10 +1592,11 @@
1592 }else if( isDel ){
1593 fossil_print(" DELETED %s\n",zFilename);
1594 }else{
1595 fossil_print(" EDITED %s\n", zFilename);
1596 }
1597 nLine++; /* record another line */
1598 }
1599 db_reset(&fchngQuery);
1600 }
1601 }
1602 if( fchngQueryInit ) db_finalize(&fchngQuery);
@@ -2097,14 +2121,15 @@
2121 }
2122 db_reset(&query);
2123 while( SQLITE_ROW == db_step(&query) ){
2124 const char * zTimeframe = db_column_text(&query, 0);
2125 const int nCount = db_column_int(&query, 1);
2126 int nSize = nCount
2127 ? (int)(100 * nCount / nMaxEvents)
2128 : 1;
2129 showYearTotal = 0;
2130 if(!nSize) nSize = 1;
2131 if(includeMonth){
2132 /* For Month/year view, add a separator for each distinct year. */
2133 if(!*zPrevYear ||
2134 (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
2135 showYearTotal = *zPrevYear;
@@ -2231,14 +2256,15 @@
2256 }
2257 db_reset(&query);
2258 while( SQLITE_ROW == db_step(&query) ){
2259 const char * zUser = db_column_text(&query, 0);
2260 const int nCount = db_column_int(&query, 1);
2261 int nSize = nCount
2262 ? (int)(100 * nCount / nMaxEvents)
2263 : 0;
2264 if(!nCount) continue /* arguable! Possible? */;
2265 else if(!nSize) nSize = 1;
2266 rowClass = ++nRowNumber % 2;
2267 nEventTotal += nCount;
2268 @<tr class='row%d(rowClass)'>
2269 @ <td>
2270 @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
@@ -2347,13 +2373,14 @@
2373 }
2374 db_reset(&stWeek);
2375 while( SQLITE_ROW == db_step(&stWeek) ){
2376 const char * zWeek = db_column_text(&stWeek,0);
2377 const int nCount = db_column_int(&stWeek,1);
2378 int nSize = nCount
2379 ? (int)(100 * nCount / nMaxEvents)
2380 : 0;
2381 if(!nSize) nSize = 1;
2382 total += nCount;
2383 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2384 cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s",
2385 g.zTop, zYear, zWeek, nCount,
2386 statsReportTimelineYFlag);
2387
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -79,11 +79,11 @@
7979
8080
<h3>2.1 Identification Of Artifacts</h3>
8181
8282
A particular version of a particular file is called an "artifact".
8383
Each artifact has a universally unique name which is the
84
-<a href="http://en.wikipedia.org/wiki/SHA">SHA1</a> hash of the content
84
+<a href="http://en.wikipedia.org/wiki/SHA1">SHA1</a> hash of the content
8585
of that file expressed as 40 characters of lower-case hexadecimal. Such
8686
a hash is referred to as the Artifact Identifier or Artifact ID
8787
for the artifact. The SHA1 algorithm is created with the purpose of
8888
providing a highly forgery-resistant identifier for a file. Given any
8989
file it is simple to find the artifact ID for that file. But given a
9090
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -79,11 +79,11 @@
79
80 <h3>2.1 Identification Of Artifacts</h3>
81
82 A particular version of a particular file is called an "artifact".
83 Each artifact has a universally unique name which is the
84 <a href="http://en.wikipedia.org/wiki/SHA">SHA1</a> hash of the content
85 of that file expressed as 40 characters of lower-case hexadecimal. Such
86 a hash is referred to as the Artifact Identifier or Artifact ID
87 for the artifact. The SHA1 algorithm is created with the purpose of
88 providing a highly forgery-resistant identifier for a file. Given any
89 file it is simple to find the artifact ID for that file. But given a
90
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -79,11 +79,11 @@
79
80 <h3>2.1 Identification Of Artifacts</h3>
81
82 A particular version of a particular file is called an "artifact".
83 Each artifact has a universally unique name which is the
84 <a href="http://en.wikipedia.org/wiki/SHA1">SHA1</a> hash of the content
85 of that file expressed as 40 characters of lower-case hexadecimal. Such
86 a hash is referred to as the Artifact Identifier or Artifact ID
87 for the artifact. The SHA1 algorithm is created with the purpose of
88 providing a highly forgery-resistant identifier for a file. Given any
89 file it is simple to find the artifact ID for that file. But given a
90

Keyboard Shortcuts

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