| | @@ -246,16 +246,20 @@ |
| 246 | 246 | int fchngQueryInit = 0; /* True if fchngQuery is initialized */ |
| 247 | 247 | Stmt fchngQuery; /* Query for file changes on check-ins */ |
| 248 | 248 | static Stmt qbranch; |
| 249 | 249 | int pendingEndTr = 0; /* True if a </td></tr> is needed */ |
| 250 | 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 */ |
| 251 | 254 | |
| 252 | 255 | if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){ |
| 253 | 256 | vid = db_lget_int("checkout", 0); |
| 254 | 257 | } |
| 255 | 258 | zPrevDate[0] = 0; |
| 256 | 259 | mxWikiLen = db_get_int("timeline-max-comment", 0); |
| 260 | + dateFormat = db_get_int("timeline-date-format", 0); |
| 257 | 261 | if( tmFlags & TIMELINE_GRAPH ){ |
| 258 | 262 | pGraph = graph_init(); |
| 259 | 263 | /* style is not moved to css, because this is |
| 260 | 264 | ** a technical div for the timeline graph |
| 261 | 265 | */ |
| | @@ -282,11 +286,11 @@ |
| 282 | 286 | int tagid = db_column_int(pQuery, 9); |
| 283 | 287 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 284 | 288 | const char *zBr = 0; /* Branch */ |
| 285 | 289 | int commentColumn = 3; /* Column containing comment text */ |
| 286 | 290 | int modPending; /* Pending moderation */ |
| 287 | | - char zTime[8]; |
| 291 | + char zTime[20]; |
| 288 | 292 | |
| 289 | 293 | modPending = moderation_pending(rid); |
| 290 | 294 | if( tagid ){ |
| 291 | 295 | if( modPending ) tagid = -tagid; |
| 292 | 296 | if( tagid==prevTagid ){ |
| | @@ -314,18 +318,34 @@ |
| 314 | 318 | } |
| 315 | 319 | prevWasDivider = 1; |
| 316 | 320 | continue; |
| 317 | 321 | } |
| 318 | 322 | 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 | + } |
| 327 | 347 | if( rid == vid ){ |
| 328 | 348 | @ <tr class="timelineCurrent"> |
| 329 | 349 | }else { |
| 330 | 350 | @ <tr> |
| 331 | 351 | } |
| | @@ -1474,11 +1494,14 @@ |
| 1474 | 1494 | |
| 1475 | 1495 | /* |
| 1476 | 1496 | ** The input query q selects various records. Print a human-readable |
| 1477 | 1497 | ** summary of those records. |
| 1478 | 1498 | ** |
| 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. |
| 1480 | 1503 | ** |
| 1481 | 1504 | ** The query should return these columns: |
| 1482 | 1505 | ** |
| 1483 | 1506 | ** 0. rid |
| 1484 | 1507 | ** 1. uuid |
| | @@ -1500,11 +1523,11 @@ |
| 1500 | 1523 | if( g.localOpen ){ |
| 1501 | 1524 | int rid = db_lget_int("checkout", 0); |
| 1502 | 1525 | zCurrentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1503 | 1526 | } |
| 1504 | 1527 | |
| 1505 | | - while( db_step(q)==SQLITE_ROW && nLine<=mxLine ){ |
| 1528 | + while( db_step(q)==SQLITE_ROW && (mxLine<=0 || nLine<=mxLine) ){ |
| 1506 | 1529 | int rid = db_column_int(q, 0); |
| 1507 | 1530 | const char *zId = db_column_text(q, 1); |
| 1508 | 1531 | const char *zDate = db_column_text(q, 2); |
| 1509 | 1532 | const char *zCom = db_column_text(q, 3); |
| 1510 | 1533 | int nChild = db_column_int(q, 4); |
| | @@ -1516,11 +1539,11 @@ |
| 1516 | 1539 | |
| 1517 | 1540 | sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); |
| 1518 | 1541 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 1519 | 1542 | fossil_print("=== %.10s ===\n", zDate); |
| 1520 | 1543 | memcpy(zPrevDate, zDate, 10); |
| 1521 | | - nLine++; |
| 1544 | + nLine++; /* record another line */ |
| 1522 | 1545 | } |
| 1523 | 1546 | if( zCom==0 ) zCom = ""; |
| 1524 | 1547 | fossil_print("%.8s ", &zDate[11]); |
| 1525 | 1548 | zPrefix[0] = 0; |
| 1526 | 1549 | if( nParent>1 ){ |
| | @@ -1540,11 +1563,11 @@ |
| 1540 | 1563 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1541 | 1564 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1542 | 1565 | n += strlen(zPrefix); |
| 1543 | 1566 | } |
| 1544 | 1567 | 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 */ |
| 1546 | 1569 | sqlite3_free(zFree); |
| 1547 | 1570 | |
| 1548 | 1571 | if(verboseFlag){ |
| 1549 | 1572 | if( !fchngQueryInit ){ |
| 1550 | 1573 | db_prepare(&fchngQuery, |
| | @@ -1569,10 +1592,11 @@ |
| 1569 | 1592 | }else if( isDel ){ |
| 1570 | 1593 | fossil_print(" DELETED %s\n",zFilename); |
| 1571 | 1594 | }else{ |
| 1572 | 1595 | fossil_print(" EDITED %s\n", zFilename); |
| 1573 | 1596 | } |
| 1597 | + nLine++; /* record another line */ |
| 1574 | 1598 | } |
| 1575 | 1599 | db_reset(&fchngQuery); |
| 1576 | 1600 | } |
| 1577 | 1601 | } |
| 1578 | 1602 | if( fchngQueryInit ) db_finalize(&fchngQuery); |
| | @@ -2097,14 +2121,15 @@ |
| 2097 | 2121 | } |
| 2098 | 2122 | db_reset(&query); |
| 2099 | 2123 | while( SQLITE_ROW == db_step(&query) ){ |
| 2100 | 2124 | const char * zTimeframe = db_column_text(&query, 0); |
| 2101 | 2125 | const int nCount = db_column_int(&query, 1); |
| 2102 | | - const int nSize = nCount |
| 2126 | + int nSize = nCount |
| 2103 | 2127 | ? (int)(100 * nCount / nMaxEvents) |
| 2104 | 2128 | : 1; |
| 2105 | 2129 | showYearTotal = 0; |
| 2130 | + if(!nSize) nSize = 1; |
| 2106 | 2131 | if(includeMonth){ |
| 2107 | 2132 | /* For Month/year view, add a separator for each distinct year. */ |
| 2108 | 2133 | if(!*zPrevYear || |
| 2109 | 2134 | (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){ |
| 2110 | 2135 | showYearTotal = *zPrevYear; |
| | @@ -2231,14 +2256,15 @@ |
| 2231 | 2256 | } |
| 2232 | 2257 | db_reset(&query); |
| 2233 | 2258 | while( SQLITE_ROW == db_step(&query) ){ |
| 2234 | 2259 | const char * zUser = db_column_text(&query, 0); |
| 2235 | 2260 | const int nCount = db_column_int(&query, 1); |
| 2236 | | - const int nSize = nCount |
| 2261 | + int nSize = nCount |
| 2237 | 2262 | ? (int)(100 * nCount / nMaxEvents) |
| 2238 | 2263 | : 0; |
| 2239 | 2264 | if(!nCount) continue /* arguable! Possible? */; |
| 2265 | + else if(!nSize) nSize = 1; |
| 2240 | 2266 | rowClass = ++nRowNumber % 2; |
| 2241 | 2267 | nEventTotal += nCount; |
| 2242 | 2268 | @<tr class='row%d(rowClass)'> |
| 2243 | 2269 | @ <td> |
| 2244 | 2270 | @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a> |
| | @@ -2347,13 +2373,14 @@ |
| 2347 | 2373 | } |
| 2348 | 2374 | db_reset(&stWeek); |
| 2349 | 2375 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2350 | 2376 | const char * zWeek = db_column_text(&stWeek,0); |
| 2351 | 2377 | const int nCount = db_column_int(&stWeek,1); |
| 2352 | | - const int nSize = nCount |
| 2378 | + int nSize = nCount |
| 2353 | 2379 | ? (int)(100 * nCount / nMaxEvents) |
| 2354 | 2380 | : 0; |
| 2381 | + if(!nSize) nSize = 1; |
| 2355 | 2382 | total += nCount; |
| 2356 | 2383 | cgi_printf("<tr class='row%d'>", ++rowCount % 2 ); |
| 2357 | 2384 | cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s", |
| 2358 | 2385 | g.zTop, zYear, zWeek, nCount, |
| 2359 | 2386 | statsReportTimelineYFlag); |
| 2360 | 2387 | |