Fossil SCM
Test of feature branches, do not merge.
Commit
b0f2a0ac53926c9988636f46969f97f4bef0807a
Parent
c1c680eb289550f…
7 files changed
+23
-4
+23
-4
+23
-4
+23
-4
+54
-49
+54
-49
+54
-49
+23
-4
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -317,11 +317,12 @@ | ||
| 317 | 317 | @ WHERE plink.pid=event.objid |
| 318 | 318 | @ AND tagxref.rid=plink.cid |
| 319 | 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | 320 | @ AND tagtype>0), |
| 321 | 321 | @ count(*), |
| 322 | -@ (SELECT uuid FROM blob WHERE rid=tagxref.rid) | |
| 322 | +@ (SELECT uuid FROM blob WHERE rid=tagxref.rid), | |
| 323 | +@ event.bgcolor | |
| 323 | 324 | @ FROM tagxref, tag, event |
| 324 | 325 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | 326 | @ AND tagxref.tagtype>0 |
| 326 | 327 | @ AND tag.tagname='branch' |
| 327 | 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | ||
| 338 | 339 | ** if there are no query parameters. |
| 339 | 340 | */ |
| 340 | 341 | static void new_brlist_page(void){ |
| 341 | 342 | Stmt q; |
| 342 | 343 | double rNow; |
| 344 | + int show_colors = PB("colors"); | |
| 343 | 345 | login_check_credentials(); |
| 344 | 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | 347 | style_header("Branches"); |
| 348 | + style_submenu_element("Timeline", "Timeline", "brtimeline"); | |
| 349 | + style_submenu_element("All", "All", "brlist?all"); | |
| 350 | + style_submenu_element("Closed","Closed","brlist?closed"); | |
| 351 | + style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); | |
| 346 | 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | + style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); | |
| 347 | 354 | login_anonymous_available(); |
| 348 | 355 | |
| 349 | 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | ||
| 361 | 368 | double rMtime = db_column_double(&q, 1); |
| 362 | 369 | int isClosed = db_column_int(&q, 2); |
| 363 | 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | 371 | int nCkin = db_column_int(&q, 4); |
| 365 | 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | + const char *zBgClr = db_column_text(&q, 6); | |
| 366 | 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | - @ <tr> | |
| 377 | + if( zBgClr == 0 ){ | |
| 378 | + if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ | |
| 379 | + zBgClr = 0; | |
| 380 | + }else{ | |
| 381 | + zBgClr = hash_color(zBranch); | |
| 382 | + } | |
| 383 | + } | |
| 384 | + if( show_colors ){ | |
| 385 | + @ <tr style="background-color:%s(zBgClr)"> | |
| 386 | + }else{ | |
| 387 | + @ <tr> | |
| 388 | + } | |
| 370 | 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | 391 | @ <td>%d(nCkin)</td> |
| 373 | 392 | fossil_free(zAge); |
| 374 | 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | ||
| 424 | 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | 444 | showAll ? "All Branches" : "Open Branches"); |
| 426 | 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | 446 | if( showClosed ){ |
| 428 | 447 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | - style_submenu_element("Open","Open","brlist?open"); | |
| 448 | + style_submenu_element("Open","Open","brlist"); | |
| 430 | 449 | }else if( showAll ){ |
| 431 | 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | 451 | style_submenu_element("Open","Open","brlist"); |
| 433 | 452 | }else{ |
| 434 | 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | ||
| 489 | 508 | db_finalize(&q); |
| 490 | 509 | style_footer(); |
| 491 | 510 | } |
| 492 | 511 | |
| 493 | 512 | /* |
| 494 | -** This routine is called while for each check-in that is rendered by | |
| 513 | +** This routine is called for each check-in that is rendered by | |
| 495 | 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | 515 | ** to the end of the line. |
| 497 | 516 | */ |
| 498 | 517 | static void brtimeline_extra(int rid){ |
| 499 | 518 | Stmt q; |
| 500 | 519 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) |
| 323 | @ FROM tagxref, tag, event |
| 324 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | @ AND tagxref.tagtype>0 |
| 326 | @ AND tag.tagname='branch' |
| 327 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 338 | ** if there are no query parameters. |
| 339 | */ |
| 340 | static void new_brlist_page(void){ |
| 341 | Stmt q; |
| 342 | double rNow; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 361 | double rMtime = db_column_double(&q, 1); |
| 362 | int isClosed = db_column_int(&q, 2); |
| 363 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | int nCkin = db_column_int(&q, 4); |
| 365 | const char *zLastCkin = db_column_text(&q, 5); |
| 366 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | @ <tr> |
| 370 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | @ <td>%d(nCkin)</td> |
| 373 | fossil_free(zAge); |
| 374 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 424 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | showAll ? "All Branches" : "Open Branches"); |
| 426 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | if( showClosed ){ |
| 428 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | style_submenu_element("Open","Open","brlist?open"); |
| 430 | }else if( showAll ){ |
| 431 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | style_submenu_element("Open","Open","brlist"); |
| 433 | }else{ |
| 434 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 489 | db_finalize(&q); |
| 490 | style_footer(); |
| 491 | } |
| 492 | |
| 493 | /* |
| 494 | ** This routine is called while for each check-in that is rendered by |
| 495 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | ** to the end of the line. |
| 497 | */ |
| 498 | static void brtimeline_extra(int rid){ |
| 499 | Stmt q; |
| 500 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid), |
| 323 | @ event.bgcolor |
| 324 | @ FROM tagxref, tag, event |
| 325 | @ WHERE tagxref.tagid=tag.tagid |
| 326 | @ AND tagxref.tagtype>0 |
| 327 | @ AND tag.tagname='branch' |
| 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 339 | ** if there are no query parameters. |
| 340 | */ |
| 341 | static void new_brlist_page(void){ |
| 342 | Stmt q; |
| 343 | double rNow; |
| 344 | int show_colors = PB("colors"); |
| 345 | login_check_credentials(); |
| 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 347 | style_header("Branches"); |
| 348 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 349 | style_submenu_element("All", "All", "brlist?all"); |
| 350 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 351 | style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); |
| 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); |
| 354 | login_anonymous_available(); |
| 355 | |
| 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 368 | double rMtime = db_column_double(&q, 1); |
| 369 | int isClosed = db_column_int(&q, 2); |
| 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 371 | int nCkin = db_column_int(&q, 4); |
| 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | const char *zBgClr = db_column_text(&q, 6); |
| 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 377 | if( zBgClr == 0 ){ |
| 378 | if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ |
| 379 | zBgClr = 0; |
| 380 | }else{ |
| 381 | zBgClr = hash_color(zBranch); |
| 382 | } |
| 383 | } |
| 384 | if( show_colors ){ |
| 385 | @ <tr style="background-color:%s(zBgClr)"> |
| 386 | }else{ |
| 387 | @ <tr> |
| 388 | } |
| 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 391 | @ <td>%d(nCkin)</td> |
| 392 | fossil_free(zAge); |
| 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 444 | showAll ? "All Branches" : "Open Branches"); |
| 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 446 | if( showClosed ){ |
| 447 | style_submenu_element("All", "All", "brlist?all"); |
| 448 | style_submenu_element("Open","Open","brlist"); |
| 449 | }else if( showAll ){ |
| 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 451 | style_submenu_element("Open","Open","brlist"); |
| 452 | }else{ |
| 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 508 | db_finalize(&q); |
| 509 | style_footer(); |
| 510 | } |
| 511 | |
| 512 | /* |
| 513 | ** This routine is called for each check-in that is rendered by |
| 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 515 | ** to the end of the line. |
| 516 | */ |
| 517 | static void brtimeline_extra(int rid){ |
| 518 | Stmt q; |
| 519 |
+23
-4
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -317,11 +317,12 @@ | ||
| 317 | 317 | @ WHERE plink.pid=event.objid |
| 318 | 318 | @ AND tagxref.rid=plink.cid |
| 319 | 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | 320 | @ AND tagtype>0), |
| 321 | 321 | @ count(*), |
| 322 | -@ (SELECT uuid FROM blob WHERE rid=tagxref.rid) | |
| 322 | +@ (SELECT uuid FROM blob WHERE rid=tagxref.rid), | |
| 323 | +@ event.bgcolor | |
| 323 | 324 | @ FROM tagxref, tag, event |
| 324 | 325 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | 326 | @ AND tagxref.tagtype>0 |
| 326 | 327 | @ AND tag.tagname='branch' |
| 327 | 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | ||
| 338 | 339 | ** if there are no query parameters. |
| 339 | 340 | */ |
| 340 | 341 | static void new_brlist_page(void){ |
| 341 | 342 | Stmt q; |
| 342 | 343 | double rNow; |
| 344 | + int show_colors = PB("colors"); | |
| 343 | 345 | login_check_credentials(); |
| 344 | 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | 347 | style_header("Branches"); |
| 348 | + style_submenu_element("Timeline", "Timeline", "brtimeline"); | |
| 349 | + style_submenu_element("All", "All", "brlist?all"); | |
| 350 | + style_submenu_element("Closed","Closed","brlist?closed"); | |
| 351 | + style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); | |
| 346 | 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | + style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); | |
| 347 | 354 | login_anonymous_available(); |
| 348 | 355 | |
| 349 | 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | ||
| 361 | 368 | double rMtime = db_column_double(&q, 1); |
| 362 | 369 | int isClosed = db_column_int(&q, 2); |
| 363 | 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | 371 | int nCkin = db_column_int(&q, 4); |
| 365 | 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | + const char *zBgClr = db_column_text(&q, 6); | |
| 366 | 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | - @ <tr> | |
| 377 | + if( zBgClr == 0 ){ | |
| 378 | + if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ | |
| 379 | + zBgClr = 0; | |
| 380 | + }else{ | |
| 381 | + zBgClr = hash_color(zBranch); | |
| 382 | + } | |
| 383 | + } | |
| 384 | + if( show_colors ){ | |
| 385 | + @ <tr style="background-color:%s(zBgClr)"> | |
| 386 | + }else{ | |
| 387 | + @ <tr> | |
| 388 | + } | |
| 370 | 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | 391 | @ <td>%d(nCkin)</td> |
| 373 | 392 | fossil_free(zAge); |
| 374 | 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | ||
| 424 | 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | 444 | showAll ? "All Branches" : "Open Branches"); |
| 426 | 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | 446 | if( showClosed ){ |
| 428 | 447 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | - style_submenu_element("Open","Open","brlist?open"); | |
| 448 | + style_submenu_element("Open","Open","brlist"); | |
| 430 | 449 | }else if( showAll ){ |
| 431 | 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | 451 | style_submenu_element("Open","Open","brlist"); |
| 433 | 452 | }else{ |
| 434 | 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | ||
| 489 | 508 | db_finalize(&q); |
| 490 | 509 | style_footer(); |
| 491 | 510 | } |
| 492 | 511 | |
| 493 | 512 | /* |
| 494 | -** This routine is called while for each check-in that is rendered by | |
| 513 | +** This routine is called for each check-in that is rendered by | |
| 495 | 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | 515 | ** to the end of the line. |
| 497 | 516 | */ |
| 498 | 517 | static void brtimeline_extra(int rid){ |
| 499 | 518 | Stmt q; |
| 500 | 519 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) |
| 323 | @ FROM tagxref, tag, event |
| 324 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | @ AND tagxref.tagtype>0 |
| 326 | @ AND tag.tagname='branch' |
| 327 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 338 | ** if there are no query parameters. |
| 339 | */ |
| 340 | static void new_brlist_page(void){ |
| 341 | Stmt q; |
| 342 | double rNow; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 361 | double rMtime = db_column_double(&q, 1); |
| 362 | int isClosed = db_column_int(&q, 2); |
| 363 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | int nCkin = db_column_int(&q, 4); |
| 365 | const char *zLastCkin = db_column_text(&q, 5); |
| 366 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | @ <tr> |
| 370 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | @ <td>%d(nCkin)</td> |
| 373 | fossil_free(zAge); |
| 374 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 424 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | showAll ? "All Branches" : "Open Branches"); |
| 426 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | if( showClosed ){ |
| 428 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | style_submenu_element("Open","Open","brlist?open"); |
| 430 | }else if( showAll ){ |
| 431 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | style_submenu_element("Open","Open","brlist"); |
| 433 | }else{ |
| 434 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 489 | db_finalize(&q); |
| 490 | style_footer(); |
| 491 | } |
| 492 | |
| 493 | /* |
| 494 | ** This routine is called while for each check-in that is rendered by |
| 495 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | ** to the end of the line. |
| 497 | */ |
| 498 | static void brtimeline_extra(int rid){ |
| 499 | Stmt q; |
| 500 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid), |
| 323 | @ event.bgcolor |
| 324 | @ FROM tagxref, tag, event |
| 325 | @ WHERE tagxref.tagid=tag.tagid |
| 326 | @ AND tagxref.tagtype>0 |
| 327 | @ AND tag.tagname='branch' |
| 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 339 | ** if there are no query parameters. |
| 340 | */ |
| 341 | static void new_brlist_page(void){ |
| 342 | Stmt q; |
| 343 | double rNow; |
| 344 | int show_colors = PB("colors"); |
| 345 | login_check_credentials(); |
| 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 347 | style_header("Branches"); |
| 348 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 349 | style_submenu_element("All", "All", "brlist?all"); |
| 350 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 351 | style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); |
| 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); |
| 354 | login_anonymous_available(); |
| 355 | |
| 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 368 | double rMtime = db_column_double(&q, 1); |
| 369 | int isClosed = db_column_int(&q, 2); |
| 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 371 | int nCkin = db_column_int(&q, 4); |
| 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | const char *zBgClr = db_column_text(&q, 6); |
| 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 377 | if( zBgClr == 0 ){ |
| 378 | if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ |
| 379 | zBgClr = 0; |
| 380 | }else{ |
| 381 | zBgClr = hash_color(zBranch); |
| 382 | } |
| 383 | } |
| 384 | if( show_colors ){ |
| 385 | @ <tr style="background-color:%s(zBgClr)"> |
| 386 | }else{ |
| 387 | @ <tr> |
| 388 | } |
| 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 391 | @ <td>%d(nCkin)</td> |
| 392 | fossil_free(zAge); |
| 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 444 | showAll ? "All Branches" : "Open Branches"); |
| 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 446 | if( showClosed ){ |
| 447 | style_submenu_element("All", "All", "brlist?all"); |
| 448 | style_submenu_element("Open","Open","brlist"); |
| 449 | }else if( showAll ){ |
| 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 451 | style_submenu_element("Open","Open","brlist"); |
| 452 | }else{ |
| 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 508 | db_finalize(&q); |
| 509 | style_footer(); |
| 510 | } |
| 511 | |
| 512 | /* |
| 513 | ** This routine is called for each check-in that is rendered by |
| 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 515 | ** to the end of the line. |
| 516 | */ |
| 517 | static void brtimeline_extra(int rid){ |
| 518 | Stmt q; |
| 519 |
+23
-4
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -317,11 +317,12 @@ | ||
| 317 | 317 | @ WHERE plink.pid=event.objid |
| 318 | 318 | @ AND tagxref.rid=plink.cid |
| 319 | 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | 320 | @ AND tagtype>0), |
| 321 | 321 | @ count(*), |
| 322 | -@ (SELECT uuid FROM blob WHERE rid=tagxref.rid) | |
| 322 | +@ (SELECT uuid FROM blob WHERE rid=tagxref.rid), | |
| 323 | +@ event.bgcolor | |
| 323 | 324 | @ FROM tagxref, tag, event |
| 324 | 325 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | 326 | @ AND tagxref.tagtype>0 |
| 326 | 327 | @ AND tag.tagname='branch' |
| 327 | 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | ||
| 338 | 339 | ** if there are no query parameters. |
| 339 | 340 | */ |
| 340 | 341 | static void new_brlist_page(void){ |
| 341 | 342 | Stmt q; |
| 342 | 343 | double rNow; |
| 344 | + int show_colors = PB("colors"); | |
| 343 | 345 | login_check_credentials(); |
| 344 | 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | 347 | style_header("Branches"); |
| 348 | + style_submenu_element("Timeline", "Timeline", "brtimeline"); | |
| 349 | + style_submenu_element("All", "All", "brlist?all"); | |
| 350 | + style_submenu_element("Closed","Closed","brlist?closed"); | |
| 351 | + style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); | |
| 346 | 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | + style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); | |
| 347 | 354 | login_anonymous_available(); |
| 348 | 355 | |
| 349 | 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | ||
| 361 | 368 | double rMtime = db_column_double(&q, 1); |
| 362 | 369 | int isClosed = db_column_int(&q, 2); |
| 363 | 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | 371 | int nCkin = db_column_int(&q, 4); |
| 365 | 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | + const char *zBgClr = db_column_text(&q, 6); | |
| 366 | 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | - @ <tr> | |
| 377 | + if( zBgClr == 0 ){ | |
| 378 | + if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ | |
| 379 | + zBgClr = 0; | |
| 380 | + }else{ | |
| 381 | + zBgClr = hash_color(zBranch); | |
| 382 | + } | |
| 383 | + } | |
| 384 | + if( show_colors ){ | |
| 385 | + @ <tr style="background-color:%s(zBgClr)"> | |
| 386 | + }else{ | |
| 387 | + @ <tr> | |
| 388 | + } | |
| 370 | 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | 391 | @ <td>%d(nCkin)</td> |
| 373 | 392 | fossil_free(zAge); |
| 374 | 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | ||
| 424 | 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | 444 | showAll ? "All Branches" : "Open Branches"); |
| 426 | 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | 446 | if( showClosed ){ |
| 428 | 447 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | - style_submenu_element("Open","Open","brlist?open"); | |
| 448 | + style_submenu_element("Open","Open","brlist"); | |
| 430 | 449 | }else if( showAll ){ |
| 431 | 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | 451 | style_submenu_element("Open","Open","brlist"); |
| 433 | 452 | }else{ |
| 434 | 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | ||
| 489 | 508 | db_finalize(&q); |
| 490 | 509 | style_footer(); |
| 491 | 510 | } |
| 492 | 511 | |
| 493 | 512 | /* |
| 494 | -** This routine is called while for each check-in that is rendered by | |
| 513 | +** This routine is called for each check-in that is rendered by | |
| 495 | 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | 515 | ** to the end of the line. |
| 497 | 516 | */ |
| 498 | 517 | static void brtimeline_extra(int rid){ |
| 499 | 518 | Stmt q; |
| 500 | 519 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) |
| 323 | @ FROM tagxref, tag, event |
| 324 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | @ AND tagxref.tagtype>0 |
| 326 | @ AND tag.tagname='branch' |
| 327 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 338 | ** if there are no query parameters. |
| 339 | */ |
| 340 | static void new_brlist_page(void){ |
| 341 | Stmt q; |
| 342 | double rNow; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 361 | double rMtime = db_column_double(&q, 1); |
| 362 | int isClosed = db_column_int(&q, 2); |
| 363 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | int nCkin = db_column_int(&q, 4); |
| 365 | const char *zLastCkin = db_column_text(&q, 5); |
| 366 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | @ <tr> |
| 370 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | @ <td>%d(nCkin)</td> |
| 373 | fossil_free(zAge); |
| 374 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 424 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | showAll ? "All Branches" : "Open Branches"); |
| 426 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | if( showClosed ){ |
| 428 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | style_submenu_element("Open","Open","brlist?open"); |
| 430 | }else if( showAll ){ |
| 431 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | style_submenu_element("Open","Open","brlist"); |
| 433 | }else{ |
| 434 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 489 | db_finalize(&q); |
| 490 | style_footer(); |
| 491 | } |
| 492 | |
| 493 | /* |
| 494 | ** This routine is called while for each check-in that is rendered by |
| 495 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | ** to the end of the line. |
| 497 | */ |
| 498 | static void brtimeline_extra(int rid){ |
| 499 | Stmt q; |
| 500 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid), |
| 323 | @ event.bgcolor |
| 324 | @ FROM tagxref, tag, event |
| 325 | @ WHERE tagxref.tagid=tag.tagid |
| 326 | @ AND tagxref.tagtype>0 |
| 327 | @ AND tag.tagname='branch' |
| 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 339 | ** if there are no query parameters. |
| 340 | */ |
| 341 | static void new_brlist_page(void){ |
| 342 | Stmt q; |
| 343 | double rNow; |
| 344 | int show_colors = PB("colors"); |
| 345 | login_check_credentials(); |
| 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 347 | style_header("Branches"); |
| 348 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 349 | style_submenu_element("All", "All", "brlist?all"); |
| 350 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 351 | style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); |
| 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); |
| 354 | login_anonymous_available(); |
| 355 | |
| 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 368 | double rMtime = db_column_double(&q, 1); |
| 369 | int isClosed = db_column_int(&q, 2); |
| 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 371 | int nCkin = db_column_int(&q, 4); |
| 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | const char *zBgClr = db_column_text(&q, 6); |
| 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 377 | if( zBgClr == 0 ){ |
| 378 | if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ |
| 379 | zBgClr = 0; |
| 380 | }else{ |
| 381 | zBgClr = hash_color(zBranch); |
| 382 | } |
| 383 | } |
| 384 | if( show_colors ){ |
| 385 | @ <tr style="background-color:%s(zBgClr)"> |
| 386 | }else{ |
| 387 | @ <tr> |
| 388 | } |
| 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 391 | @ <td>%d(nCkin)</td> |
| 392 | fossil_free(zAge); |
| 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 444 | showAll ? "All Branches" : "Open Branches"); |
| 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 446 | if( showClosed ){ |
| 447 | style_submenu_element("All", "All", "brlist?all"); |
| 448 | style_submenu_element("Open","Open","brlist"); |
| 449 | }else if( showAll ){ |
| 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 451 | style_submenu_element("Open","Open","brlist"); |
| 452 | }else{ |
| 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 508 | db_finalize(&q); |
| 509 | style_footer(); |
| 510 | } |
| 511 | |
| 512 | /* |
| 513 | ** This routine is called for each check-in that is rendered by |
| 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 515 | ** to the end of the line. |
| 516 | */ |
| 517 | static void brtimeline_extra(int rid){ |
| 518 | Stmt q; |
| 519 |
+23
-4
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -317,11 +317,12 @@ | ||
| 317 | 317 | @ WHERE plink.pid=event.objid |
| 318 | 318 | @ AND tagxref.rid=plink.cid |
| 319 | 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | 320 | @ AND tagtype>0), |
| 321 | 321 | @ count(*), |
| 322 | -@ (SELECT uuid FROM blob WHERE rid=tagxref.rid) | |
| 322 | +@ (SELECT uuid FROM blob WHERE rid=tagxref.rid), | |
| 323 | +@ event.bgcolor | |
| 323 | 324 | @ FROM tagxref, tag, event |
| 324 | 325 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | 326 | @ AND tagxref.tagtype>0 |
| 326 | 327 | @ AND tag.tagname='branch' |
| 327 | 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | ||
| 338 | 339 | ** if there are no query parameters. |
| 339 | 340 | */ |
| 340 | 341 | static void new_brlist_page(void){ |
| 341 | 342 | Stmt q; |
| 342 | 343 | double rNow; |
| 344 | + int show_colors = PB("colors"); | |
| 343 | 345 | login_check_credentials(); |
| 344 | 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | 347 | style_header("Branches"); |
| 348 | + style_submenu_element("Timeline", "Timeline", "brtimeline"); | |
| 349 | + style_submenu_element("All", "All", "brlist?all"); | |
| 350 | + style_submenu_element("Closed","Closed","brlist?closed"); | |
| 351 | + style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); | |
| 346 | 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | + style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); | |
| 347 | 354 | login_anonymous_available(); |
| 348 | 355 | |
| 349 | 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | ||
| 361 | 368 | double rMtime = db_column_double(&q, 1); |
| 362 | 369 | int isClosed = db_column_int(&q, 2); |
| 363 | 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | 371 | int nCkin = db_column_int(&q, 4); |
| 365 | 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | + const char *zBgClr = db_column_text(&q, 6); | |
| 366 | 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | - @ <tr> | |
| 377 | + if( zBgClr == 0 ){ | |
| 378 | + if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ | |
| 379 | + zBgClr = 0; | |
| 380 | + }else{ | |
| 381 | + zBgClr = hash_color(zBranch); | |
| 382 | + } | |
| 383 | + } | |
| 384 | + if( show_colors ){ | |
| 385 | + @ <tr style="background-color:%s(zBgClr)"> | |
| 386 | + }else{ | |
| 387 | + @ <tr> | |
| 388 | + } | |
| 370 | 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | 391 | @ <td>%d(nCkin)</td> |
| 373 | 392 | fossil_free(zAge); |
| 374 | 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | ||
| 424 | 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | 444 | showAll ? "All Branches" : "Open Branches"); |
| 426 | 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | 446 | if( showClosed ){ |
| 428 | 447 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | - style_submenu_element("Open","Open","brlist?open"); | |
| 448 | + style_submenu_element("Open","Open","brlist"); | |
| 430 | 449 | }else if( showAll ){ |
| 431 | 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | 451 | style_submenu_element("Open","Open","brlist"); |
| 433 | 452 | }else{ |
| 434 | 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | ||
| 489 | 508 | db_finalize(&q); |
| 490 | 509 | style_footer(); |
| 491 | 510 | } |
| 492 | 511 | |
| 493 | 512 | /* |
| 494 | -** This routine is called while for each check-in that is rendered by | |
| 513 | +** This routine is called for each check-in that is rendered by | |
| 495 | 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | 515 | ** to the end of the line. |
| 497 | 516 | */ |
| 498 | 517 | static void brtimeline_extra(int rid){ |
| 499 | 518 | Stmt q; |
| 500 | 519 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) |
| 323 | @ FROM tagxref, tag, event |
| 324 | @ WHERE tagxref.tagid=tag.tagid |
| 325 | @ AND tagxref.tagtype>0 |
| 326 | @ AND tag.tagname='branch' |
| 327 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 338 | ** if there are no query parameters. |
| 339 | */ |
| 340 | static void new_brlist_page(void){ |
| 341 | Stmt q; |
| 342 | double rNow; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 361 | double rMtime = db_column_double(&q, 1); |
| 362 | int isClosed = db_column_int(&q, 2); |
| 363 | const char *zMergeTo = db_column_text(&q, 3); |
| 364 | int nCkin = db_column_int(&q, 4); |
| 365 | const char *zLastCkin = db_column_text(&q, 5); |
| 366 | char *zAge = human_readable_age(rNow - rMtime); |
| 367 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 368 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 369 | @ <tr> |
| 370 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 371 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 372 | @ <td>%d(nCkin)</td> |
| 373 | fossil_free(zAge); |
| 374 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 424 | style_header("%s", showClosed ? "Closed Branches" : |
| 425 | showAll ? "All Branches" : "Open Branches"); |
| 426 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 427 | if( showClosed ){ |
| 428 | style_submenu_element("All", "All", "brlist?all"); |
| 429 | style_submenu_element("Open","Open","brlist?open"); |
| 430 | }else if( showAll ){ |
| 431 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 432 | style_submenu_element("Open","Open","brlist"); |
| 433 | }else{ |
| 434 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 489 | db_finalize(&q); |
| 490 | style_footer(); |
| 491 | } |
| 492 | |
| 493 | /* |
| 494 | ** This routine is called while for each check-in that is rendered by |
| 495 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 496 | ** to the end of the line. |
| 497 | */ |
| 498 | static void brtimeline_extra(int rid){ |
| 499 | Stmt q; |
| 500 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -317,11 +317,12 @@ | |
| 317 | @ WHERE plink.pid=event.objid |
| 318 | @ AND tagxref.rid=plink.cid |
| 319 | @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch') |
| 320 | @ AND tagtype>0), |
| 321 | @ count(*), |
| 322 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid), |
| 323 | @ event.bgcolor |
| 324 | @ FROM tagxref, tag, event |
| 325 | @ WHERE tagxref.tagid=tag.tagid |
| 326 | @ AND tagxref.tagtype>0 |
| 327 | @ AND tag.tagname='branch' |
| 328 | @ AND event.objid=tagxref.rid |
| @@ -338,14 +339,20 @@ | |
| 339 | ** if there are no query parameters. |
| 340 | */ |
| 341 | static void new_brlist_page(void){ |
| 342 | Stmt q; |
| 343 | double rNow; |
| 344 | int show_colors = PB("colors"); |
| 345 | login_check_credentials(); |
| 346 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 347 | style_header("Branches"); |
| 348 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 349 | style_submenu_element("All", "All", "brlist?all"); |
| 350 | style_submenu_element("Closed","Closed","brlist?closed"); |
| 351 | style_submenu_element("Color-Test", "Color-Test", "brlist?colortest"); |
| 352 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 353 | style_submenu_binary("colors", "Show branch colors", "No branch colors", 0); |
| 354 | login_anonymous_available(); |
| 355 | |
| 356 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 357 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 358 | @ <div class="brlist"><table id="branchlisttable"> |
| @@ -361,14 +368,26 @@ | |
| 368 | double rMtime = db_column_double(&q, 1); |
| 369 | int isClosed = db_column_int(&q, 2); |
| 370 | const char *zMergeTo = db_column_text(&q, 3); |
| 371 | int nCkin = db_column_int(&q, 4); |
| 372 | const char *zLastCkin = db_column_text(&q, 5); |
| 373 | const char *zBgClr = db_column_text(&q, 6); |
| 374 | char *zAge = human_readable_age(rNow - rMtime); |
| 375 | sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0); |
| 376 | if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0; |
| 377 | if( zBgClr == 0 ){ |
| 378 | if( zBranch==0 || strcmp(zBranch,"trunk")==0 ){ |
| 379 | zBgClr = 0; |
| 380 | }else{ |
| 381 | zBgClr = hash_color(zBranch); |
| 382 | } |
| 383 | } |
| 384 | if( show_colors ){ |
| 385 | @ <tr style="background-color:%s(zBgClr)"> |
| 386 | }else{ |
| 387 | @ <tr> |
| 388 | } |
| 389 | @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td> |
| 390 | @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td> |
| 391 | @ <td>%d(nCkin)</td> |
| 392 | fossil_free(zAge); |
| 393 | @ <td>%s(isClosed?"closed":"")</td> |
| @@ -424,11 +443,11 @@ | |
| 443 | style_header("%s", showClosed ? "Closed Branches" : |
| 444 | showAll ? "All Branches" : "Open Branches"); |
| 445 | style_submenu_element("Timeline", "Timeline", "brtimeline"); |
| 446 | if( showClosed ){ |
| 447 | style_submenu_element("All", "All", "brlist?all"); |
| 448 | style_submenu_element("Open","Open","brlist"); |
| 449 | }else if( showAll ){ |
| 450 | style_submenu_element("Closed", "Closed", "brlist?closed"); |
| 451 | style_submenu_element("Open","Open","brlist"); |
| 452 | }else{ |
| 453 | style_submenu_element("All", "All", "brlist?all"); |
| @@ -489,11 +508,11 @@ | |
| 508 | db_finalize(&q); |
| 509 | style_footer(); |
| 510 | } |
| 511 | |
| 512 | /* |
| 513 | ** This routine is called for each check-in that is rendered by |
| 514 | ** the timeline of a "brlist" page. Add some additional hyperlinks |
| 515 | ** to the end of the line. |
| 516 | */ |
| 517 | static void brtimeline_extra(int rid){ |
| 518 | Stmt q; |
| 519 |
+54
-49
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1520,36 +1520,38 @@ | ||
| 1520 | 1520 | }else{ |
| 1521 | 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | 1522 | int n, nBefore, nAfter; |
| 1523 | 1523 | const char *zEType = "timeline item"; |
| 1524 | 1524 | char *zDate; |
| 1525 | + Blob cond; | |
| 1526 | + blob_zero(&cond); | |
| 1525 | 1527 | if( zUses ){ |
| 1526 | - blob_append_sql(&sql, " AND event.objid IN usesfile "); | |
| 1528 | + blob_append_sql(&cond, " AND event.objid IN usesfile "); | |
| 1527 | 1529 | } |
| 1528 | 1530 | if( renameOnly ){ |
| 1529 | - blob_append_sql(&sql, " AND event.objid IN rnfile "); | |
| 1531 | + blob_append_sql(&cond, " AND event.objid IN rnfile "); | |
| 1530 | 1532 | } |
| 1531 | 1533 | if( forkOnly ){ |
| 1532 | - blob_append_sql(&sql, " AND event.objid IN rnfork "); | |
| 1534 | + blob_append_sql(&cond, " AND event.objid IN rnfork "); | |
| 1533 | 1535 | } |
| 1534 | 1536 | if( bisectOnly ){ |
| 1535 | - blob_append_sql(&sql, " AND event.objid IN (SELECT rid FROM bilog) "); | |
| 1537 | + blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) "); | |
| 1536 | 1538 | } |
| 1537 | 1539 | if( zYearMonth ){ |
| 1538 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1540 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1539 | 1541 | zYearMonth); |
| 1540 | 1542 | } |
| 1541 | 1543 | else if( zYearWeek ){ |
| 1542 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1544 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1543 | 1545 | zYearWeek); |
| 1544 | 1546 | } |
| 1545 | 1547 | else if( zDay ){ |
| 1546 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", | |
| 1548 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", | |
| 1547 | 1549 | zDay); |
| 1548 | 1550 | } |
| 1549 | 1551 | if( tagid ){ |
| 1550 | - blob_append_sql(&sql, | |
| 1552 | + blob_append_sql(&cond, | |
| 1551 | 1553 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1552 | 1554 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1553 | 1555 | |
| 1554 | 1556 | if( zBrName ){ |
| 1555 | 1557 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | ||
| 1556 | 1558 | ** are not part of the branch which are parents or children of the |
| 1557 | 1559 | ** branch to be included in the report. This related check-ins are |
| 1558 | 1560 | ** useful in helping to visualize what has happened on a quiescent |
| 1559 | 1561 | ** branch that is infrequently merged with a much more activate branch. |
| 1560 | 1562 | */ |
| 1561 | - blob_append_sql(&sql, | |
| 1563 | + blob_append_sql(&cond, | |
| 1562 | 1564 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1563 | 1565 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1564 | 1566 | tagid |
| 1565 | 1567 | ); |
| 1566 | 1568 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1567 | - blob_append_sql(&sql, | |
| 1569 | + blob_append_sql(&cond, | |
| 1568 | 1570 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1569 | 1571 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1570 | 1572 | TAG_HIDDEN |
| 1571 | 1573 | ); |
| 1572 | 1574 | } |
| 1573 | 1575 | if( P("mionly")==0 ){ |
| 1574 | - blob_append_sql(&sql, | |
| 1576 | + blob_append_sql(&cond, | |
| 1575 | 1577 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1576 | 1578 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1577 | 1579 | tagid |
| 1578 | 1580 | ); |
| 1579 | 1581 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1580 | - blob_append_sql(&sql, | |
| 1582 | + blob_append_sql(&cond, | |
| 1581 | 1583 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1582 | 1584 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1583 | 1585 | TAG_HIDDEN |
| 1584 | 1586 | ); |
| 1585 | 1587 | } |
| 1586 | 1588 | } |
| 1587 | 1589 | } |
| 1588 | - blob_append_sql(&sql, ")"); | |
| 1590 | + blob_append_sql(&cond, ")"); | |
| 1589 | 1591 | } |
| 1590 | 1592 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1591 | 1593 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1592 | 1594 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1593 | 1595 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | ||
| 1596 | 1598 | zType = "all"; |
| 1597 | 1599 | } |
| 1598 | 1600 | if( zType[0]=='a' ){ |
| 1599 | 1601 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1600 | 1602 | char cSep = '('; |
| 1601 | - blob_append_sql(&sql, " AND event.type IN "); | |
| 1603 | + blob_append_sql(&cond, " AND event.type IN "); | |
| 1602 | 1604 | if( g.perm.Read ){ |
| 1603 | - blob_append_sql(&sql, "%c'ci','g'", cSep); | |
| 1605 | + blob_append_sql(&cond, "%c'ci','g'", cSep); | |
| 1604 | 1606 | cSep = ','; |
| 1605 | 1607 | } |
| 1606 | 1608 | if( g.perm.RdWiki ){ |
| 1607 | - blob_append_sql(&sql, "%c'w','e'", cSep); | |
| 1609 | + blob_append_sql(&cond, "%c'w','e'", cSep); | |
| 1608 | 1610 | cSep = ','; |
| 1609 | 1611 | } |
| 1610 | 1612 | if( g.perm.RdTkt ){ |
| 1611 | - blob_append_sql(&sql, "%c't'", cSep); | |
| 1613 | + blob_append_sql(&cond, "%c't'", cSep); | |
| 1612 | 1614 | cSep = ','; |
| 1613 | 1615 | } |
| 1614 | - blob_append_sql(&sql, ")"); | |
| 1616 | + blob_append_sql(&cond, ")"); | |
| 1615 | 1617 | } |
| 1616 | 1618 | }else{ /* zType!="all" */ |
| 1617 | - blob_append_sql(&sql, " AND event.type=%Q", zType); | |
| 1619 | + blob_append_sql(&cond, " AND event.type=%Q", zType); | |
| 1618 | 1620 | if( zType[0]=='c' ){ |
| 1619 | 1621 | zEType = "check-in"; |
| 1620 | 1622 | }else if( zType[0]=='w' ){ |
| 1621 | 1623 | zEType = "wiki edit"; |
| 1622 | 1624 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | ||
| 1632 | 1634 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1633 | 1635 | if( n<=nEntry ){ |
| 1634 | 1636 | zCirca = zBefore = zAfter = 0; |
| 1635 | 1637 | nEntry = -1; |
| 1636 | 1638 | } |
| 1637 | - blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1639 | + blob_append_sql(&cond, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1638 | 1640 | zUser, zUser); |
| 1639 | 1641 | zThisUser = zUser; |
| 1640 | 1642 | } |
| 1641 | 1643 | if( zSearch ){ |
| 1642 | - blob_append_sql(&sql, | |
| 1644 | + blob_append_sql(&cond, | |
| 1643 | 1645 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1644 | 1646 | zSearch, zSearch); |
| 1645 | 1647 | } |
| 1646 | 1648 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1647 | 1649 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1648 | 1650 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1651 | + blob_append_sql(&sql, "%s", blob_sql_text(&cond)); | |
| 1649 | 1652 | if( rAfter>0.0 ){ |
| 1650 | 1653 | if( rBefore>0.0 ){ |
| 1651 | 1654 | blob_append_sql(&sql, |
| 1652 | 1655 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1653 | 1656 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | ||
| 1745 | 1748 | } |
| 1746 | 1749 | if( zSearch ){ |
| 1747 | 1750 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1748 | 1751 | } |
| 1749 | 1752 | if( g.perm.Hyperlink ){ |
| 1750 | - if( zCirca && rCirca ){ | |
| 1751 | - nBefore = db_int(0, | |
| 1752 | - "SELECT count(*) FROM timeline WHERE etype!='div'" | |
| 1753 | - " AND sortby<=%f /*scan*/", rCirca); | |
| 1754 | - nAfter = db_int(0, | |
| 1755 | - "SELECT count(*) FROM timeline WHERE etype!='div'" | |
| 1756 | - " AND sortby>=%f /*scan*/", rCirca); | |
| 1757 | - zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1758 | - if( nBefore>=nEntry ){ | |
| 1759 | - timeline_submenu(&url, "Older", "b", zDate, "c"); | |
| 1760 | - zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "c", 0)); | |
| 1761 | - } | |
| 1762 | - if( nAfter>=nEntry ){ | |
| 1763 | - timeline_submenu(&url, "Newer", "a", zDate, "c"); | |
| 1764 | - } | |
| 1765 | - free(zDate); | |
| 1766 | - }else{ | |
| 1767 | - if( zAfter || n==nEntry ){ | |
| 1768 | - zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1769 | - timeline_submenu(&url, "Older", "b", zDate, "a"); | |
| 1770 | - zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); | |
| 1771 | - free(zDate); | |
| 1772 | - } | |
| 1773 | - if( zBefore || (zAfter && n==nEntry) ){ | |
| 1774 | - zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); | |
| 1775 | - timeline_submenu(&url, "Newer", "a", zDate, "b"); | |
| 1776 | - free(zDate); | |
| 1777 | - } | |
| 1753 | + double rDate; | |
| 1754 | + zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1755 | + if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ | |
| 1756 | + zDate = mprintf("%s", (zAfter ? zAfter : zBefore)); | |
| 1757 | + } | |
| 1758 | + if( zDate ){ | |
| 1759 | + rDate = symbolic_name_to_mtime(zDate); | |
| 1760 | + if( db_int(0, | |
| 1761 | + "SELECT EXISTS (SELECT 1 FROM event WHERE mtime<=%.17g%s)", | |
| 1762 | + rDate-ONE_SECOND, blob_sql_text(&cond)) | |
| 1763 | + ){ | |
| 1764 | + timeline_submenu(&url, "Older", "b", zDate, "a"); | |
| 1765 | + zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); | |
| 1766 | + } | |
| 1767 | + free(zDate); | |
| 1768 | + } | |
| 1769 | + zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); | |
| 1770 | + if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ | |
| 1771 | + zDate = mprintf("%s", (zBefore ? zBefore : zAfter)); | |
| 1772 | + } | |
| 1773 | + if( zDate ){ | |
| 1774 | + rDate = symbolic_name_to_mtime(zDate); | |
| 1775 | + if( db_int(0, | |
| 1776 | + "SELECT EXISTS (SELECT 1 FROM event WHERE mtime>=%.17g%s)", | |
| 1777 | + rDate+ONE_SECOND, blob_sql_text(&cond)) | |
| 1778 | + ){ | |
| 1779 | + timeline_submenu(&url, "Newer", "a", zDate, "b"); | |
| 1780 | + } | |
| 1781 | + free(zDate); | |
| 1778 | 1782 | } |
| 1779 | 1783 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1780 | 1784 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1781 | 1785 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1782 | 1786 | } |
| @@ -1784,10 +1788,11 @@ | ||
| 1784 | 1788 | style_submenu_entry("n","Max:",4,0); |
| 1785 | 1789 | timeline_y_submenu(disableY); |
| 1786 | 1790 | style_submenu_binary("v","With Files","Without Files", |
| 1787 | 1791 | zType[0]!='a' && zType[0]!='c'); |
| 1788 | 1792 | } |
| 1793 | + blob_zero(&cond); | |
| 1789 | 1794 | } |
| 1790 | 1795 | if( PB("showsql") ){ |
| 1791 | 1796 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1792 | 1797 | } |
| 1793 | 1798 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1794 | 1799 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1520,36 +1520,38 @@ | |
| 1520 | }else{ |
| 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | int n, nBefore, nAfter; |
| 1523 | const char *zEType = "timeline item"; |
| 1524 | char *zDate; |
| 1525 | if( zUses ){ |
| 1526 | blob_append_sql(&sql, " AND event.objid IN usesfile "); |
| 1527 | } |
| 1528 | if( renameOnly ){ |
| 1529 | blob_append_sql(&sql, " AND event.objid IN rnfile "); |
| 1530 | } |
| 1531 | if( forkOnly ){ |
| 1532 | blob_append_sql(&sql, " AND event.objid IN rnfork "); |
| 1533 | } |
| 1534 | if( bisectOnly ){ |
| 1535 | blob_append_sql(&sql, " AND event.objid IN (SELECT rid FROM bilog) "); |
| 1536 | } |
| 1537 | if( zYearMonth ){ |
| 1538 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1539 | zYearMonth); |
| 1540 | } |
| 1541 | else if( zYearWeek ){ |
| 1542 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1543 | zYearWeek); |
| 1544 | } |
| 1545 | else if( zDay ){ |
| 1546 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", |
| 1547 | zDay); |
| 1548 | } |
| 1549 | if( tagid ){ |
| 1550 | blob_append_sql(&sql, |
| 1551 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1552 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1553 | |
| 1554 | if( zBrName ){ |
| 1555 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | |
| 1556 | ** are not part of the branch which are parents or children of the |
| 1557 | ** branch to be included in the report. This related check-ins are |
| 1558 | ** useful in helping to visualize what has happened on a quiescent |
| 1559 | ** branch that is infrequently merged with a much more activate branch. |
| 1560 | */ |
| 1561 | blob_append_sql(&sql, |
| 1562 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1563 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1564 | tagid |
| 1565 | ); |
| 1566 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1567 | blob_append_sql(&sql, |
| 1568 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1569 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1570 | TAG_HIDDEN |
| 1571 | ); |
| 1572 | } |
| 1573 | if( P("mionly")==0 ){ |
| 1574 | blob_append_sql(&sql, |
| 1575 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1576 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1577 | tagid |
| 1578 | ); |
| 1579 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1580 | blob_append_sql(&sql, |
| 1581 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1582 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1583 | TAG_HIDDEN |
| 1584 | ); |
| 1585 | } |
| 1586 | } |
| 1587 | } |
| 1588 | blob_append_sql(&sql, ")"); |
| 1589 | } |
| 1590 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1591 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1592 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1593 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | |
| 1596 | zType = "all"; |
| 1597 | } |
| 1598 | if( zType[0]=='a' ){ |
| 1599 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1600 | char cSep = '('; |
| 1601 | blob_append_sql(&sql, " AND event.type IN "); |
| 1602 | if( g.perm.Read ){ |
| 1603 | blob_append_sql(&sql, "%c'ci','g'", cSep); |
| 1604 | cSep = ','; |
| 1605 | } |
| 1606 | if( g.perm.RdWiki ){ |
| 1607 | blob_append_sql(&sql, "%c'w','e'", cSep); |
| 1608 | cSep = ','; |
| 1609 | } |
| 1610 | if( g.perm.RdTkt ){ |
| 1611 | blob_append_sql(&sql, "%c't'", cSep); |
| 1612 | cSep = ','; |
| 1613 | } |
| 1614 | blob_append_sql(&sql, ")"); |
| 1615 | } |
| 1616 | }else{ /* zType!="all" */ |
| 1617 | blob_append_sql(&sql, " AND event.type=%Q", zType); |
| 1618 | if( zType[0]=='c' ){ |
| 1619 | zEType = "check-in"; |
| 1620 | }else if( zType[0]=='w' ){ |
| 1621 | zEType = "wiki edit"; |
| 1622 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | |
| 1632 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1633 | if( n<=nEntry ){ |
| 1634 | zCirca = zBefore = zAfter = 0; |
| 1635 | nEntry = -1; |
| 1636 | } |
| 1637 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1638 | zUser, zUser); |
| 1639 | zThisUser = zUser; |
| 1640 | } |
| 1641 | if( zSearch ){ |
| 1642 | blob_append_sql(&sql, |
| 1643 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1644 | zSearch, zSearch); |
| 1645 | } |
| 1646 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1647 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1648 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1649 | if( rAfter>0.0 ){ |
| 1650 | if( rBefore>0.0 ){ |
| 1651 | blob_append_sql(&sql, |
| 1652 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1653 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | |
| 1745 | } |
| 1746 | if( zSearch ){ |
| 1747 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1748 | } |
| 1749 | if( g.perm.Hyperlink ){ |
| 1750 | if( zCirca && rCirca ){ |
| 1751 | nBefore = db_int(0, |
| 1752 | "SELECT count(*) FROM timeline WHERE etype!='div'" |
| 1753 | " AND sortby<=%f /*scan*/", rCirca); |
| 1754 | nAfter = db_int(0, |
| 1755 | "SELECT count(*) FROM timeline WHERE etype!='div'" |
| 1756 | " AND sortby>=%f /*scan*/", rCirca); |
| 1757 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1758 | if( nBefore>=nEntry ){ |
| 1759 | timeline_submenu(&url, "Older", "b", zDate, "c"); |
| 1760 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "c", 0)); |
| 1761 | } |
| 1762 | if( nAfter>=nEntry ){ |
| 1763 | timeline_submenu(&url, "Newer", "a", zDate, "c"); |
| 1764 | } |
| 1765 | free(zDate); |
| 1766 | }else{ |
| 1767 | if( zAfter || n==nEntry ){ |
| 1768 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1769 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1770 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); |
| 1771 | free(zDate); |
| 1772 | } |
| 1773 | if( zBefore || (zAfter && n==nEntry) ){ |
| 1774 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); |
| 1775 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 1776 | free(zDate); |
| 1777 | } |
| 1778 | } |
| 1779 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1780 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1781 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1782 | } |
| @@ -1784,10 +1788,11 @@ | |
| 1784 | style_submenu_entry("n","Max:",4,0); |
| 1785 | timeline_y_submenu(disableY); |
| 1786 | style_submenu_binary("v","With Files","Without Files", |
| 1787 | zType[0]!='a' && zType[0]!='c'); |
| 1788 | } |
| 1789 | } |
| 1790 | if( PB("showsql") ){ |
| 1791 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1792 | } |
| 1793 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1794 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1520,36 +1520,38 @@ | |
| 1520 | }else{ |
| 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | int n, nBefore, nAfter; |
| 1523 | const char *zEType = "timeline item"; |
| 1524 | char *zDate; |
| 1525 | Blob cond; |
| 1526 | blob_zero(&cond); |
| 1527 | if( zUses ){ |
| 1528 | blob_append_sql(&cond, " AND event.objid IN usesfile "); |
| 1529 | } |
| 1530 | if( renameOnly ){ |
| 1531 | blob_append_sql(&cond, " AND event.objid IN rnfile "); |
| 1532 | } |
| 1533 | if( forkOnly ){ |
| 1534 | blob_append_sql(&cond, " AND event.objid IN rnfork "); |
| 1535 | } |
| 1536 | if( bisectOnly ){ |
| 1537 | blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) "); |
| 1538 | } |
| 1539 | if( zYearMonth ){ |
| 1540 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1541 | zYearMonth); |
| 1542 | } |
| 1543 | else if( zYearWeek ){ |
| 1544 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1545 | zYearWeek); |
| 1546 | } |
| 1547 | else if( zDay ){ |
| 1548 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", |
| 1549 | zDay); |
| 1550 | } |
| 1551 | if( tagid ){ |
| 1552 | blob_append_sql(&cond, |
| 1553 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1554 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1555 | |
| 1556 | if( zBrName ){ |
| 1557 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | |
| 1558 | ** are not part of the branch which are parents or children of the |
| 1559 | ** branch to be included in the report. This related check-ins are |
| 1560 | ** useful in helping to visualize what has happened on a quiescent |
| 1561 | ** branch that is infrequently merged with a much more activate branch. |
| 1562 | */ |
| 1563 | blob_append_sql(&cond, |
| 1564 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1565 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1566 | tagid |
| 1567 | ); |
| 1568 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1569 | blob_append_sql(&cond, |
| 1570 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1571 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1572 | TAG_HIDDEN |
| 1573 | ); |
| 1574 | } |
| 1575 | if( P("mionly")==0 ){ |
| 1576 | blob_append_sql(&cond, |
| 1577 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1578 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1579 | tagid |
| 1580 | ); |
| 1581 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1582 | blob_append_sql(&cond, |
| 1583 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1584 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1585 | TAG_HIDDEN |
| 1586 | ); |
| 1587 | } |
| 1588 | } |
| 1589 | } |
| 1590 | blob_append_sql(&cond, ")"); |
| 1591 | } |
| 1592 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1593 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1594 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1595 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | |
| 1598 | zType = "all"; |
| 1599 | } |
| 1600 | if( zType[0]=='a' ){ |
| 1601 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1602 | char cSep = '('; |
| 1603 | blob_append_sql(&cond, " AND event.type IN "); |
| 1604 | if( g.perm.Read ){ |
| 1605 | blob_append_sql(&cond, "%c'ci','g'", cSep); |
| 1606 | cSep = ','; |
| 1607 | } |
| 1608 | if( g.perm.RdWiki ){ |
| 1609 | blob_append_sql(&cond, "%c'w','e'", cSep); |
| 1610 | cSep = ','; |
| 1611 | } |
| 1612 | if( g.perm.RdTkt ){ |
| 1613 | blob_append_sql(&cond, "%c't'", cSep); |
| 1614 | cSep = ','; |
| 1615 | } |
| 1616 | blob_append_sql(&cond, ")"); |
| 1617 | } |
| 1618 | }else{ /* zType!="all" */ |
| 1619 | blob_append_sql(&cond, " AND event.type=%Q", zType); |
| 1620 | if( zType[0]=='c' ){ |
| 1621 | zEType = "check-in"; |
| 1622 | }else if( zType[0]=='w' ){ |
| 1623 | zEType = "wiki edit"; |
| 1624 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | |
| 1634 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1635 | if( n<=nEntry ){ |
| 1636 | zCirca = zBefore = zAfter = 0; |
| 1637 | nEntry = -1; |
| 1638 | } |
| 1639 | blob_append_sql(&cond, " AND (event.user=%Q OR event.euser=%Q)", |
| 1640 | zUser, zUser); |
| 1641 | zThisUser = zUser; |
| 1642 | } |
| 1643 | if( zSearch ){ |
| 1644 | blob_append_sql(&cond, |
| 1645 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1646 | zSearch, zSearch); |
| 1647 | } |
| 1648 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1649 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1650 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1651 | blob_append_sql(&sql, "%s", blob_sql_text(&cond)); |
| 1652 | if( rAfter>0.0 ){ |
| 1653 | if( rBefore>0.0 ){ |
| 1654 | blob_append_sql(&sql, |
| 1655 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1656 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | |
| 1748 | } |
| 1749 | if( zSearch ){ |
| 1750 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1751 | } |
| 1752 | if( g.perm.Hyperlink ){ |
| 1753 | double rDate; |
| 1754 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1755 | if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ |
| 1756 | zDate = mprintf("%s", (zAfter ? zAfter : zBefore)); |
| 1757 | } |
| 1758 | if( zDate ){ |
| 1759 | rDate = symbolic_name_to_mtime(zDate); |
| 1760 | if( db_int(0, |
| 1761 | "SELECT EXISTS (SELECT 1 FROM event WHERE mtime<=%.17g%s)", |
| 1762 | rDate-ONE_SECOND, blob_sql_text(&cond)) |
| 1763 | ){ |
| 1764 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1765 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); |
| 1766 | } |
| 1767 | free(zDate); |
| 1768 | } |
| 1769 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); |
| 1770 | if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ |
| 1771 | zDate = mprintf("%s", (zBefore ? zBefore : zAfter)); |
| 1772 | } |
| 1773 | if( zDate ){ |
| 1774 | rDate = symbolic_name_to_mtime(zDate); |
| 1775 | if( db_int(0, |
| 1776 | "SELECT EXISTS (SELECT 1 FROM event WHERE mtime>=%.17g%s)", |
| 1777 | rDate+ONE_SECOND, blob_sql_text(&cond)) |
| 1778 | ){ |
| 1779 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 1780 | } |
| 1781 | free(zDate); |
| 1782 | } |
| 1783 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1784 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1785 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1786 | } |
| @@ -1784,10 +1788,11 @@ | |
| 1788 | style_submenu_entry("n","Max:",4,0); |
| 1789 | timeline_y_submenu(disableY); |
| 1790 | style_submenu_binary("v","With Files","Without Files", |
| 1791 | zType[0]!='a' && zType[0]!='c'); |
| 1792 | } |
| 1793 | blob_zero(&cond); |
| 1794 | } |
| 1795 | if( PB("showsql") ){ |
| 1796 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1797 | } |
| 1798 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1799 |
+54
-49
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1520,36 +1520,38 @@ | ||
| 1520 | 1520 | }else{ |
| 1521 | 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | 1522 | int n, nBefore, nAfter; |
| 1523 | 1523 | const char *zEType = "timeline item"; |
| 1524 | 1524 | char *zDate; |
| 1525 | + Blob cond; | |
| 1526 | + blob_zero(&cond); | |
| 1525 | 1527 | if( zUses ){ |
| 1526 | - blob_append_sql(&sql, " AND event.objid IN usesfile "); | |
| 1528 | + blob_append_sql(&cond, " AND event.objid IN usesfile "); | |
| 1527 | 1529 | } |
| 1528 | 1530 | if( renameOnly ){ |
| 1529 | - blob_append_sql(&sql, " AND event.objid IN rnfile "); | |
| 1531 | + blob_append_sql(&cond, " AND event.objid IN rnfile "); | |
| 1530 | 1532 | } |
| 1531 | 1533 | if( forkOnly ){ |
| 1532 | - blob_append_sql(&sql, " AND event.objid IN rnfork "); | |
| 1534 | + blob_append_sql(&cond, " AND event.objid IN rnfork "); | |
| 1533 | 1535 | } |
| 1534 | 1536 | if( bisectOnly ){ |
| 1535 | - blob_append_sql(&sql, " AND event.objid IN (SELECT rid FROM bilog) "); | |
| 1537 | + blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) "); | |
| 1536 | 1538 | } |
| 1537 | 1539 | if( zYearMonth ){ |
| 1538 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1540 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1539 | 1541 | zYearMonth); |
| 1540 | 1542 | } |
| 1541 | 1543 | else if( zYearWeek ){ |
| 1542 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1544 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1543 | 1545 | zYearWeek); |
| 1544 | 1546 | } |
| 1545 | 1547 | else if( zDay ){ |
| 1546 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", | |
| 1548 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", | |
| 1547 | 1549 | zDay); |
| 1548 | 1550 | } |
| 1549 | 1551 | if( tagid ){ |
| 1550 | - blob_append_sql(&sql, | |
| 1552 | + blob_append_sql(&cond, | |
| 1551 | 1553 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1552 | 1554 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1553 | 1555 | |
| 1554 | 1556 | if( zBrName ){ |
| 1555 | 1557 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | ||
| 1556 | 1558 | ** are not part of the branch which are parents or children of the |
| 1557 | 1559 | ** branch to be included in the report. This related check-ins are |
| 1558 | 1560 | ** useful in helping to visualize what has happened on a quiescent |
| 1559 | 1561 | ** branch that is infrequently merged with a much more activate branch. |
| 1560 | 1562 | */ |
| 1561 | - blob_append_sql(&sql, | |
| 1563 | + blob_append_sql(&cond, | |
| 1562 | 1564 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1563 | 1565 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1564 | 1566 | tagid |
| 1565 | 1567 | ); |
| 1566 | 1568 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1567 | - blob_append_sql(&sql, | |
| 1569 | + blob_append_sql(&cond, | |
| 1568 | 1570 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1569 | 1571 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1570 | 1572 | TAG_HIDDEN |
| 1571 | 1573 | ); |
| 1572 | 1574 | } |
| 1573 | 1575 | if( P("mionly")==0 ){ |
| 1574 | - blob_append_sql(&sql, | |
| 1576 | + blob_append_sql(&cond, | |
| 1575 | 1577 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1576 | 1578 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1577 | 1579 | tagid |
| 1578 | 1580 | ); |
| 1579 | 1581 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1580 | - blob_append_sql(&sql, | |
| 1582 | + blob_append_sql(&cond, | |
| 1581 | 1583 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1582 | 1584 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1583 | 1585 | TAG_HIDDEN |
| 1584 | 1586 | ); |
| 1585 | 1587 | } |
| 1586 | 1588 | } |
| 1587 | 1589 | } |
| 1588 | - blob_append_sql(&sql, ")"); | |
| 1590 | + blob_append_sql(&cond, ")"); | |
| 1589 | 1591 | } |
| 1590 | 1592 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1591 | 1593 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1592 | 1594 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1593 | 1595 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | ||
| 1596 | 1598 | zType = "all"; |
| 1597 | 1599 | } |
| 1598 | 1600 | if( zType[0]=='a' ){ |
| 1599 | 1601 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1600 | 1602 | char cSep = '('; |
| 1601 | - blob_append_sql(&sql, " AND event.type IN "); | |
| 1603 | + blob_append_sql(&cond, " AND event.type IN "); | |
| 1602 | 1604 | if( g.perm.Read ){ |
| 1603 | - blob_append_sql(&sql, "%c'ci','g'", cSep); | |
| 1605 | + blob_append_sql(&cond, "%c'ci','g'", cSep); | |
| 1604 | 1606 | cSep = ','; |
| 1605 | 1607 | } |
| 1606 | 1608 | if( g.perm.RdWiki ){ |
| 1607 | - blob_append_sql(&sql, "%c'w','e'", cSep); | |
| 1609 | + blob_append_sql(&cond, "%c'w','e'", cSep); | |
| 1608 | 1610 | cSep = ','; |
| 1609 | 1611 | } |
| 1610 | 1612 | if( g.perm.RdTkt ){ |
| 1611 | - blob_append_sql(&sql, "%c't'", cSep); | |
| 1613 | + blob_append_sql(&cond, "%c't'", cSep); | |
| 1612 | 1614 | cSep = ','; |
| 1613 | 1615 | } |
| 1614 | - blob_append_sql(&sql, ")"); | |
| 1616 | + blob_append_sql(&cond, ")"); | |
| 1615 | 1617 | } |
| 1616 | 1618 | }else{ /* zType!="all" */ |
| 1617 | - blob_append_sql(&sql, " AND event.type=%Q", zType); | |
| 1619 | + blob_append_sql(&cond, " AND event.type=%Q", zType); | |
| 1618 | 1620 | if( zType[0]=='c' ){ |
| 1619 | 1621 | zEType = "check-in"; |
| 1620 | 1622 | }else if( zType[0]=='w' ){ |
| 1621 | 1623 | zEType = "wiki edit"; |
| 1622 | 1624 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | ||
| 1632 | 1634 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1633 | 1635 | if( n<=nEntry ){ |
| 1634 | 1636 | zCirca = zBefore = zAfter = 0; |
| 1635 | 1637 | nEntry = -1; |
| 1636 | 1638 | } |
| 1637 | - blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1639 | + blob_append_sql(&cond, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1638 | 1640 | zUser, zUser); |
| 1639 | 1641 | zThisUser = zUser; |
| 1640 | 1642 | } |
| 1641 | 1643 | if( zSearch ){ |
| 1642 | - blob_append_sql(&sql, | |
| 1644 | + blob_append_sql(&cond, | |
| 1643 | 1645 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1644 | 1646 | zSearch, zSearch); |
| 1645 | 1647 | } |
| 1646 | 1648 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1647 | 1649 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1648 | 1650 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1651 | + blob_append_sql(&sql, "%s", blob_sql_text(&cond)); | |
| 1649 | 1652 | if( rAfter>0.0 ){ |
| 1650 | 1653 | if( rBefore>0.0 ){ |
| 1651 | 1654 | blob_append_sql(&sql, |
| 1652 | 1655 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1653 | 1656 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | ||
| 1745 | 1748 | } |
| 1746 | 1749 | if( zSearch ){ |
| 1747 | 1750 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1748 | 1751 | } |
| 1749 | 1752 | if( g.perm.Hyperlink ){ |
| 1750 | - if( zCirca && rCirca ){ | |
| 1751 | - nBefore = db_int(0, | |
| 1752 | - "SELECT count(*) FROM timeline WHERE etype!='div'" | |
| 1753 | - " AND sortby<=%f /*scan*/", rCirca); | |
| 1754 | - nAfter = db_int(0, | |
| 1755 | - "SELECT count(*) FROM timeline WHERE etype!='div'" | |
| 1756 | - " AND sortby>=%f /*scan*/", rCirca); | |
| 1757 | - zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1758 | - if( nBefore>=nEntry ){ | |
| 1759 | - timeline_submenu(&url, "Older", "b", zDate, "c"); | |
| 1760 | - zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "c", 0)); | |
| 1761 | - } | |
| 1762 | - if( nAfter>=nEntry ){ | |
| 1763 | - timeline_submenu(&url, "Newer", "a", zDate, "c"); | |
| 1764 | - } | |
| 1765 | - free(zDate); | |
| 1766 | - }else{ | |
| 1767 | - if( zAfter || n==nEntry ){ | |
| 1768 | - zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1769 | - timeline_submenu(&url, "Older", "b", zDate, "a"); | |
| 1770 | - zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); | |
| 1771 | - free(zDate); | |
| 1772 | - } | |
| 1773 | - if( zBefore || (zAfter && n==nEntry) ){ | |
| 1774 | - zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); | |
| 1775 | - timeline_submenu(&url, "Newer", "a", zDate, "b"); | |
| 1776 | - free(zDate); | |
| 1777 | - } | |
| 1753 | + double rDate; | |
| 1754 | + zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1755 | + if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ | |
| 1756 | + zDate = mprintf("%s", (zAfter ? zAfter : zBefore)); | |
| 1757 | + } | |
| 1758 | + if( zDate ){ | |
| 1759 | + rDate = symbolic_name_to_mtime(zDate); | |
| 1760 | + if( db_int(0, | |
| 1761 | + "SELECT EXISTS (SELECT 1 FROM event WHERE mtime<=%.17g%s)", | |
| 1762 | + rDate-ONE_SECOND, blob_sql_text(&cond)) | |
| 1763 | + ){ | |
| 1764 | + timeline_submenu(&url, "Older", "b", zDate, "a"); | |
| 1765 | + zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); | |
| 1766 | + } | |
| 1767 | + free(zDate); | |
| 1768 | + } | |
| 1769 | + zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); | |
| 1770 | + if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ | |
| 1771 | + zDate = mprintf("%s", (zBefore ? zBefore : zAfter)); | |
| 1772 | + } | |
| 1773 | + if( zDate ){ | |
| 1774 | + rDate = symbolic_name_to_mtime(zDate); | |
| 1775 | + if( db_int(0, | |
| 1776 | + "SELECT EXISTS (SELECT 1 FROM event WHERE mtime>=%.17g%s)", | |
| 1777 | + rDate+ONE_SECOND, blob_sql_text(&cond)) | |
| 1778 | + ){ | |
| 1779 | + timeline_submenu(&url, "Newer", "a", zDate, "b"); | |
| 1780 | + } | |
| 1781 | + free(zDate); | |
| 1778 | 1782 | } |
| 1779 | 1783 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1780 | 1784 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1781 | 1785 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1782 | 1786 | } |
| @@ -1784,10 +1788,11 @@ | ||
| 1784 | 1788 | style_submenu_entry("n","Max:",4,0); |
| 1785 | 1789 | timeline_y_submenu(disableY); |
| 1786 | 1790 | style_submenu_binary("v","With Files","Without Files", |
| 1787 | 1791 | zType[0]!='a' && zType[0]!='c'); |
| 1788 | 1792 | } |
| 1793 | + blob_zero(&cond); | |
| 1789 | 1794 | } |
| 1790 | 1795 | if( PB("showsql") ){ |
| 1791 | 1796 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1792 | 1797 | } |
| 1793 | 1798 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1794 | 1799 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1520,36 +1520,38 @@ | |
| 1520 | }else{ |
| 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | int n, nBefore, nAfter; |
| 1523 | const char *zEType = "timeline item"; |
| 1524 | char *zDate; |
| 1525 | if( zUses ){ |
| 1526 | blob_append_sql(&sql, " AND event.objid IN usesfile "); |
| 1527 | } |
| 1528 | if( renameOnly ){ |
| 1529 | blob_append_sql(&sql, " AND event.objid IN rnfile "); |
| 1530 | } |
| 1531 | if( forkOnly ){ |
| 1532 | blob_append_sql(&sql, " AND event.objid IN rnfork "); |
| 1533 | } |
| 1534 | if( bisectOnly ){ |
| 1535 | blob_append_sql(&sql, " AND event.objid IN (SELECT rid FROM bilog) "); |
| 1536 | } |
| 1537 | if( zYearMonth ){ |
| 1538 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1539 | zYearMonth); |
| 1540 | } |
| 1541 | else if( zYearWeek ){ |
| 1542 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1543 | zYearWeek); |
| 1544 | } |
| 1545 | else if( zDay ){ |
| 1546 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", |
| 1547 | zDay); |
| 1548 | } |
| 1549 | if( tagid ){ |
| 1550 | blob_append_sql(&sql, |
| 1551 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1552 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1553 | |
| 1554 | if( zBrName ){ |
| 1555 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | |
| 1556 | ** are not part of the branch which are parents or children of the |
| 1557 | ** branch to be included in the report. This related check-ins are |
| 1558 | ** useful in helping to visualize what has happened on a quiescent |
| 1559 | ** branch that is infrequently merged with a much more activate branch. |
| 1560 | */ |
| 1561 | blob_append_sql(&sql, |
| 1562 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1563 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1564 | tagid |
| 1565 | ); |
| 1566 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1567 | blob_append_sql(&sql, |
| 1568 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1569 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1570 | TAG_HIDDEN |
| 1571 | ); |
| 1572 | } |
| 1573 | if( P("mionly")==0 ){ |
| 1574 | blob_append_sql(&sql, |
| 1575 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1576 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1577 | tagid |
| 1578 | ); |
| 1579 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1580 | blob_append_sql(&sql, |
| 1581 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1582 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1583 | TAG_HIDDEN |
| 1584 | ); |
| 1585 | } |
| 1586 | } |
| 1587 | } |
| 1588 | blob_append_sql(&sql, ")"); |
| 1589 | } |
| 1590 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1591 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1592 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1593 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | |
| 1596 | zType = "all"; |
| 1597 | } |
| 1598 | if( zType[0]=='a' ){ |
| 1599 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1600 | char cSep = '('; |
| 1601 | blob_append_sql(&sql, " AND event.type IN "); |
| 1602 | if( g.perm.Read ){ |
| 1603 | blob_append_sql(&sql, "%c'ci','g'", cSep); |
| 1604 | cSep = ','; |
| 1605 | } |
| 1606 | if( g.perm.RdWiki ){ |
| 1607 | blob_append_sql(&sql, "%c'w','e'", cSep); |
| 1608 | cSep = ','; |
| 1609 | } |
| 1610 | if( g.perm.RdTkt ){ |
| 1611 | blob_append_sql(&sql, "%c't'", cSep); |
| 1612 | cSep = ','; |
| 1613 | } |
| 1614 | blob_append_sql(&sql, ")"); |
| 1615 | } |
| 1616 | }else{ /* zType!="all" */ |
| 1617 | blob_append_sql(&sql, " AND event.type=%Q", zType); |
| 1618 | if( zType[0]=='c' ){ |
| 1619 | zEType = "check-in"; |
| 1620 | }else if( zType[0]=='w' ){ |
| 1621 | zEType = "wiki edit"; |
| 1622 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | |
| 1632 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1633 | if( n<=nEntry ){ |
| 1634 | zCirca = zBefore = zAfter = 0; |
| 1635 | nEntry = -1; |
| 1636 | } |
| 1637 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1638 | zUser, zUser); |
| 1639 | zThisUser = zUser; |
| 1640 | } |
| 1641 | if( zSearch ){ |
| 1642 | blob_append_sql(&sql, |
| 1643 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1644 | zSearch, zSearch); |
| 1645 | } |
| 1646 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1647 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1648 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1649 | if( rAfter>0.0 ){ |
| 1650 | if( rBefore>0.0 ){ |
| 1651 | blob_append_sql(&sql, |
| 1652 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1653 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | |
| 1745 | } |
| 1746 | if( zSearch ){ |
| 1747 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1748 | } |
| 1749 | if( g.perm.Hyperlink ){ |
| 1750 | if( zCirca && rCirca ){ |
| 1751 | nBefore = db_int(0, |
| 1752 | "SELECT count(*) FROM timeline WHERE etype!='div'" |
| 1753 | " AND sortby<=%f /*scan*/", rCirca); |
| 1754 | nAfter = db_int(0, |
| 1755 | "SELECT count(*) FROM timeline WHERE etype!='div'" |
| 1756 | " AND sortby>=%f /*scan*/", rCirca); |
| 1757 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1758 | if( nBefore>=nEntry ){ |
| 1759 | timeline_submenu(&url, "Older", "b", zDate, "c"); |
| 1760 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "c", 0)); |
| 1761 | } |
| 1762 | if( nAfter>=nEntry ){ |
| 1763 | timeline_submenu(&url, "Newer", "a", zDate, "c"); |
| 1764 | } |
| 1765 | free(zDate); |
| 1766 | }else{ |
| 1767 | if( zAfter || n==nEntry ){ |
| 1768 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1769 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1770 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); |
| 1771 | free(zDate); |
| 1772 | } |
| 1773 | if( zBefore || (zAfter && n==nEntry) ){ |
| 1774 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); |
| 1775 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 1776 | free(zDate); |
| 1777 | } |
| 1778 | } |
| 1779 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1780 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1781 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1782 | } |
| @@ -1784,10 +1788,11 @@ | |
| 1784 | style_submenu_entry("n","Max:",4,0); |
| 1785 | timeline_y_submenu(disableY); |
| 1786 | style_submenu_binary("v","With Files","Without Files", |
| 1787 | zType[0]!='a' && zType[0]!='c'); |
| 1788 | } |
| 1789 | } |
| 1790 | if( PB("showsql") ){ |
| 1791 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1792 | } |
| 1793 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1794 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1520,36 +1520,38 @@ | |
| 1520 | }else{ |
| 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | int n, nBefore, nAfter; |
| 1523 | const char *zEType = "timeline item"; |
| 1524 | char *zDate; |
| 1525 | Blob cond; |
| 1526 | blob_zero(&cond); |
| 1527 | if( zUses ){ |
| 1528 | blob_append_sql(&cond, " AND event.objid IN usesfile "); |
| 1529 | } |
| 1530 | if( renameOnly ){ |
| 1531 | blob_append_sql(&cond, " AND event.objid IN rnfile "); |
| 1532 | } |
| 1533 | if( forkOnly ){ |
| 1534 | blob_append_sql(&cond, " AND event.objid IN rnfork "); |
| 1535 | } |
| 1536 | if( bisectOnly ){ |
| 1537 | blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) "); |
| 1538 | } |
| 1539 | if( zYearMonth ){ |
| 1540 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1541 | zYearMonth); |
| 1542 | } |
| 1543 | else if( zYearWeek ){ |
| 1544 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1545 | zYearWeek); |
| 1546 | } |
| 1547 | else if( zDay ){ |
| 1548 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", |
| 1549 | zDay); |
| 1550 | } |
| 1551 | if( tagid ){ |
| 1552 | blob_append_sql(&cond, |
| 1553 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1554 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1555 | |
| 1556 | if( zBrName ){ |
| 1557 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | |
| 1558 | ** are not part of the branch which are parents or children of the |
| 1559 | ** branch to be included in the report. This related check-ins are |
| 1560 | ** useful in helping to visualize what has happened on a quiescent |
| 1561 | ** branch that is infrequently merged with a much more activate branch. |
| 1562 | */ |
| 1563 | blob_append_sql(&cond, |
| 1564 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1565 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1566 | tagid |
| 1567 | ); |
| 1568 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1569 | blob_append_sql(&cond, |
| 1570 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1571 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1572 | TAG_HIDDEN |
| 1573 | ); |
| 1574 | } |
| 1575 | if( P("mionly")==0 ){ |
| 1576 | blob_append_sql(&cond, |
| 1577 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1578 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1579 | tagid |
| 1580 | ); |
| 1581 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1582 | blob_append_sql(&cond, |
| 1583 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1584 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1585 | TAG_HIDDEN |
| 1586 | ); |
| 1587 | } |
| 1588 | } |
| 1589 | } |
| 1590 | blob_append_sql(&cond, ")"); |
| 1591 | } |
| 1592 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1593 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1594 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1595 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | |
| 1598 | zType = "all"; |
| 1599 | } |
| 1600 | if( zType[0]=='a' ){ |
| 1601 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1602 | char cSep = '('; |
| 1603 | blob_append_sql(&cond, " AND event.type IN "); |
| 1604 | if( g.perm.Read ){ |
| 1605 | blob_append_sql(&cond, "%c'ci','g'", cSep); |
| 1606 | cSep = ','; |
| 1607 | } |
| 1608 | if( g.perm.RdWiki ){ |
| 1609 | blob_append_sql(&cond, "%c'w','e'", cSep); |
| 1610 | cSep = ','; |
| 1611 | } |
| 1612 | if( g.perm.RdTkt ){ |
| 1613 | blob_append_sql(&cond, "%c't'", cSep); |
| 1614 | cSep = ','; |
| 1615 | } |
| 1616 | blob_append_sql(&cond, ")"); |
| 1617 | } |
| 1618 | }else{ /* zType!="all" */ |
| 1619 | blob_append_sql(&cond, " AND event.type=%Q", zType); |
| 1620 | if( zType[0]=='c' ){ |
| 1621 | zEType = "check-in"; |
| 1622 | }else if( zType[0]=='w' ){ |
| 1623 | zEType = "wiki edit"; |
| 1624 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | |
| 1634 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1635 | if( n<=nEntry ){ |
| 1636 | zCirca = zBefore = zAfter = 0; |
| 1637 | nEntry = -1; |
| 1638 | } |
| 1639 | blob_append_sql(&cond, " AND (event.user=%Q OR event.euser=%Q)", |
| 1640 | zUser, zUser); |
| 1641 | zThisUser = zUser; |
| 1642 | } |
| 1643 | if( zSearch ){ |
| 1644 | blob_append_sql(&cond, |
| 1645 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1646 | zSearch, zSearch); |
| 1647 | } |
| 1648 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1649 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1650 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1651 | blob_append_sql(&sql, "%s", blob_sql_text(&cond)); |
| 1652 | if( rAfter>0.0 ){ |
| 1653 | if( rBefore>0.0 ){ |
| 1654 | blob_append_sql(&sql, |
| 1655 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1656 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | |
| 1748 | } |
| 1749 | if( zSearch ){ |
| 1750 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1751 | } |
| 1752 | if( g.perm.Hyperlink ){ |
| 1753 | double rDate; |
| 1754 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1755 | if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ |
| 1756 | zDate = mprintf("%s", (zAfter ? zAfter : zBefore)); |
| 1757 | } |
| 1758 | if( zDate ){ |
| 1759 | rDate = symbolic_name_to_mtime(zDate); |
| 1760 | if( db_int(0, |
| 1761 | "SELECT EXISTS (SELECT 1 FROM event WHERE mtime<=%.17g%s)", |
| 1762 | rDate-ONE_SECOND, blob_sql_text(&cond)) |
| 1763 | ){ |
| 1764 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1765 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); |
| 1766 | } |
| 1767 | free(zDate); |
| 1768 | } |
| 1769 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); |
| 1770 | if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ |
| 1771 | zDate = mprintf("%s", (zBefore ? zBefore : zAfter)); |
| 1772 | } |
| 1773 | if( zDate ){ |
| 1774 | rDate = symbolic_name_to_mtime(zDate); |
| 1775 | if( db_int(0, |
| 1776 | "SELECT EXISTS (SELECT 1 FROM event WHERE mtime>=%.17g%s)", |
| 1777 | rDate+ONE_SECOND, blob_sql_text(&cond)) |
| 1778 | ){ |
| 1779 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 1780 | } |
| 1781 | free(zDate); |
| 1782 | } |
| 1783 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1784 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1785 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1786 | } |
| @@ -1784,10 +1788,11 @@ | |
| 1788 | style_submenu_entry("n","Max:",4,0); |
| 1789 | timeline_y_submenu(disableY); |
| 1790 | style_submenu_binary("v","With Files","Without Files", |
| 1791 | zType[0]!='a' && zType[0]!='c'); |
| 1792 | } |
| 1793 | blob_zero(&cond); |
| 1794 | } |
| 1795 | if( PB("showsql") ){ |
| 1796 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1797 | } |
| 1798 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1799 |
+54
-49
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1520,36 +1520,38 @@ | ||
| 1520 | 1520 | }else{ |
| 1521 | 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | 1522 | int n, nBefore, nAfter; |
| 1523 | 1523 | const char *zEType = "timeline item"; |
| 1524 | 1524 | char *zDate; |
| 1525 | + Blob cond; | |
| 1526 | + blob_zero(&cond); | |
| 1525 | 1527 | if( zUses ){ |
| 1526 | - blob_append_sql(&sql, " AND event.objid IN usesfile "); | |
| 1528 | + blob_append_sql(&cond, " AND event.objid IN usesfile "); | |
| 1527 | 1529 | } |
| 1528 | 1530 | if( renameOnly ){ |
| 1529 | - blob_append_sql(&sql, " AND event.objid IN rnfile "); | |
| 1531 | + blob_append_sql(&cond, " AND event.objid IN rnfile "); | |
| 1530 | 1532 | } |
| 1531 | 1533 | if( forkOnly ){ |
| 1532 | - blob_append_sql(&sql, " AND event.objid IN rnfork "); | |
| 1534 | + blob_append_sql(&cond, " AND event.objid IN rnfork "); | |
| 1533 | 1535 | } |
| 1534 | 1536 | if( bisectOnly ){ |
| 1535 | - blob_append_sql(&sql, " AND event.objid IN (SELECT rid FROM bilog) "); | |
| 1537 | + blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) "); | |
| 1536 | 1538 | } |
| 1537 | 1539 | if( zYearMonth ){ |
| 1538 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1540 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ", | |
| 1539 | 1541 | zYearMonth); |
| 1540 | 1542 | } |
| 1541 | 1543 | else if( zYearWeek ){ |
| 1542 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1544 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ", | |
| 1543 | 1545 | zYearWeek); |
| 1544 | 1546 | } |
| 1545 | 1547 | else if( zDay ){ |
| 1546 | - blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", | |
| 1548 | + blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", | |
| 1547 | 1549 | zDay); |
| 1548 | 1550 | } |
| 1549 | 1551 | if( tagid ){ |
| 1550 | - blob_append_sql(&sql, | |
| 1552 | + blob_append_sql(&cond, | |
| 1551 | 1553 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1552 | 1554 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1553 | 1555 | |
| 1554 | 1556 | if( zBrName ){ |
| 1555 | 1557 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | ||
| 1556 | 1558 | ** are not part of the branch which are parents or children of the |
| 1557 | 1559 | ** branch to be included in the report. This related check-ins are |
| 1558 | 1560 | ** useful in helping to visualize what has happened on a quiescent |
| 1559 | 1561 | ** branch that is infrequently merged with a much more activate branch. |
| 1560 | 1562 | */ |
| 1561 | - blob_append_sql(&sql, | |
| 1563 | + blob_append_sql(&cond, | |
| 1562 | 1564 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1563 | 1565 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1564 | 1566 | tagid |
| 1565 | 1567 | ); |
| 1566 | 1568 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1567 | - blob_append_sql(&sql, | |
| 1569 | + blob_append_sql(&cond, | |
| 1568 | 1570 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1569 | 1571 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1570 | 1572 | TAG_HIDDEN |
| 1571 | 1573 | ); |
| 1572 | 1574 | } |
| 1573 | 1575 | if( P("mionly")==0 ){ |
| 1574 | - blob_append_sql(&sql, | |
| 1576 | + blob_append_sql(&cond, | |
| 1575 | 1577 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1576 | 1578 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1577 | 1579 | tagid |
| 1578 | 1580 | ); |
| 1579 | 1581 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1580 | - blob_append_sql(&sql, | |
| 1582 | + blob_append_sql(&cond, | |
| 1581 | 1583 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1582 | 1584 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1583 | 1585 | TAG_HIDDEN |
| 1584 | 1586 | ); |
| 1585 | 1587 | } |
| 1586 | 1588 | } |
| 1587 | 1589 | } |
| 1588 | - blob_append_sql(&sql, ")"); | |
| 1590 | + blob_append_sql(&cond, ")"); | |
| 1589 | 1591 | } |
| 1590 | 1592 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1591 | 1593 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1592 | 1594 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1593 | 1595 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | ||
| 1596 | 1598 | zType = "all"; |
| 1597 | 1599 | } |
| 1598 | 1600 | if( zType[0]=='a' ){ |
| 1599 | 1601 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1600 | 1602 | char cSep = '('; |
| 1601 | - blob_append_sql(&sql, " AND event.type IN "); | |
| 1603 | + blob_append_sql(&cond, " AND event.type IN "); | |
| 1602 | 1604 | if( g.perm.Read ){ |
| 1603 | - blob_append_sql(&sql, "%c'ci','g'", cSep); | |
| 1605 | + blob_append_sql(&cond, "%c'ci','g'", cSep); | |
| 1604 | 1606 | cSep = ','; |
| 1605 | 1607 | } |
| 1606 | 1608 | if( g.perm.RdWiki ){ |
| 1607 | - blob_append_sql(&sql, "%c'w','e'", cSep); | |
| 1609 | + blob_append_sql(&cond, "%c'w','e'", cSep); | |
| 1608 | 1610 | cSep = ','; |
| 1609 | 1611 | } |
| 1610 | 1612 | if( g.perm.RdTkt ){ |
| 1611 | - blob_append_sql(&sql, "%c't'", cSep); | |
| 1613 | + blob_append_sql(&cond, "%c't'", cSep); | |
| 1612 | 1614 | cSep = ','; |
| 1613 | 1615 | } |
| 1614 | - blob_append_sql(&sql, ")"); | |
| 1616 | + blob_append_sql(&cond, ")"); | |
| 1615 | 1617 | } |
| 1616 | 1618 | }else{ /* zType!="all" */ |
| 1617 | - blob_append_sql(&sql, " AND event.type=%Q", zType); | |
| 1619 | + blob_append_sql(&cond, " AND event.type=%Q", zType); | |
| 1618 | 1620 | if( zType[0]=='c' ){ |
| 1619 | 1621 | zEType = "check-in"; |
| 1620 | 1622 | }else if( zType[0]=='w' ){ |
| 1621 | 1623 | zEType = "wiki edit"; |
| 1622 | 1624 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | ||
| 1632 | 1634 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1633 | 1635 | if( n<=nEntry ){ |
| 1634 | 1636 | zCirca = zBefore = zAfter = 0; |
| 1635 | 1637 | nEntry = -1; |
| 1636 | 1638 | } |
| 1637 | - blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1639 | + blob_append_sql(&cond, " AND (event.user=%Q OR event.euser=%Q)", | |
| 1638 | 1640 | zUser, zUser); |
| 1639 | 1641 | zThisUser = zUser; |
| 1640 | 1642 | } |
| 1641 | 1643 | if( zSearch ){ |
| 1642 | - blob_append_sql(&sql, | |
| 1644 | + blob_append_sql(&cond, | |
| 1643 | 1645 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1644 | 1646 | zSearch, zSearch); |
| 1645 | 1647 | } |
| 1646 | 1648 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1647 | 1649 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1648 | 1650 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1651 | + blob_append_sql(&sql, "%s", blob_sql_text(&cond)); | |
| 1649 | 1652 | if( rAfter>0.0 ){ |
| 1650 | 1653 | if( rBefore>0.0 ){ |
| 1651 | 1654 | blob_append_sql(&sql, |
| 1652 | 1655 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1653 | 1656 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | ||
| 1745 | 1748 | } |
| 1746 | 1749 | if( zSearch ){ |
| 1747 | 1750 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1748 | 1751 | } |
| 1749 | 1752 | if( g.perm.Hyperlink ){ |
| 1750 | - if( zCirca && rCirca ){ | |
| 1751 | - nBefore = db_int(0, | |
| 1752 | - "SELECT count(*) FROM timeline WHERE etype!='div'" | |
| 1753 | - " AND sortby<=%f /*scan*/", rCirca); | |
| 1754 | - nAfter = db_int(0, | |
| 1755 | - "SELECT count(*) FROM timeline WHERE etype!='div'" | |
| 1756 | - " AND sortby>=%f /*scan*/", rCirca); | |
| 1757 | - zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1758 | - if( nBefore>=nEntry ){ | |
| 1759 | - timeline_submenu(&url, "Older", "b", zDate, "c"); | |
| 1760 | - zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "c", 0)); | |
| 1761 | - } | |
| 1762 | - if( nAfter>=nEntry ){ | |
| 1763 | - timeline_submenu(&url, "Newer", "a", zDate, "c"); | |
| 1764 | - } | |
| 1765 | - free(zDate); | |
| 1766 | - }else{ | |
| 1767 | - if( zAfter || n==nEntry ){ | |
| 1768 | - zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1769 | - timeline_submenu(&url, "Older", "b", zDate, "a"); | |
| 1770 | - zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); | |
| 1771 | - free(zDate); | |
| 1772 | - } | |
| 1773 | - if( zBefore || (zAfter && n==nEntry) ){ | |
| 1774 | - zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); | |
| 1775 | - timeline_submenu(&url, "Newer", "a", zDate, "b"); | |
| 1776 | - free(zDate); | |
| 1777 | - } | |
| 1753 | + double rDate; | |
| 1754 | + zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); | |
| 1755 | + if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ | |
| 1756 | + zDate = mprintf("%s", (zAfter ? zAfter : zBefore)); | |
| 1757 | + } | |
| 1758 | + if( zDate ){ | |
| 1759 | + rDate = symbolic_name_to_mtime(zDate); | |
| 1760 | + if( db_int(0, | |
| 1761 | + "SELECT EXISTS (SELECT 1 FROM event WHERE mtime<=%.17g%s)", | |
| 1762 | + rDate-ONE_SECOND, blob_sql_text(&cond)) | |
| 1763 | + ){ | |
| 1764 | + timeline_submenu(&url, "Older", "b", zDate, "a"); | |
| 1765 | + zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); | |
| 1766 | + } | |
| 1767 | + free(zDate); | |
| 1768 | + } | |
| 1769 | + zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); | |
| 1770 | + if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ | |
| 1771 | + zDate = mprintf("%s", (zBefore ? zBefore : zAfter)); | |
| 1772 | + } | |
| 1773 | + if( zDate ){ | |
| 1774 | + rDate = symbolic_name_to_mtime(zDate); | |
| 1775 | + if( db_int(0, | |
| 1776 | + "SELECT EXISTS (SELECT 1 FROM event WHERE mtime>=%.17g%s)", | |
| 1777 | + rDate+ONE_SECOND, blob_sql_text(&cond)) | |
| 1778 | + ){ | |
| 1779 | + timeline_submenu(&url, "Newer", "a", zDate, "b"); | |
| 1780 | + } | |
| 1781 | + free(zDate); | |
| 1778 | 1782 | } |
| 1779 | 1783 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1780 | 1784 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1781 | 1785 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1782 | 1786 | } |
| @@ -1784,10 +1788,11 @@ | ||
| 1784 | 1788 | style_submenu_entry("n","Max:",4,0); |
| 1785 | 1789 | timeline_y_submenu(disableY); |
| 1786 | 1790 | style_submenu_binary("v","With Files","Without Files", |
| 1787 | 1791 | zType[0]!='a' && zType[0]!='c'); |
| 1788 | 1792 | } |
| 1793 | + blob_zero(&cond); | |
| 1789 | 1794 | } |
| 1790 | 1795 | if( PB("showsql") ){ |
| 1791 | 1796 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1792 | 1797 | } |
| 1793 | 1798 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1794 | 1799 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1520,36 +1520,38 @@ | |
| 1520 | }else{ |
| 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | int n, nBefore, nAfter; |
| 1523 | const char *zEType = "timeline item"; |
| 1524 | char *zDate; |
| 1525 | if( zUses ){ |
| 1526 | blob_append_sql(&sql, " AND event.objid IN usesfile "); |
| 1527 | } |
| 1528 | if( renameOnly ){ |
| 1529 | blob_append_sql(&sql, " AND event.objid IN rnfile "); |
| 1530 | } |
| 1531 | if( forkOnly ){ |
| 1532 | blob_append_sql(&sql, " AND event.objid IN rnfork "); |
| 1533 | } |
| 1534 | if( bisectOnly ){ |
| 1535 | blob_append_sql(&sql, " AND event.objid IN (SELECT rid FROM bilog) "); |
| 1536 | } |
| 1537 | if( zYearMonth ){ |
| 1538 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1539 | zYearMonth); |
| 1540 | } |
| 1541 | else if( zYearWeek ){ |
| 1542 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1543 | zYearWeek); |
| 1544 | } |
| 1545 | else if( zDay ){ |
| 1546 | blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", |
| 1547 | zDay); |
| 1548 | } |
| 1549 | if( tagid ){ |
| 1550 | blob_append_sql(&sql, |
| 1551 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1552 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1553 | |
| 1554 | if( zBrName ){ |
| 1555 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | |
| 1556 | ** are not part of the branch which are parents or children of the |
| 1557 | ** branch to be included in the report. This related check-ins are |
| 1558 | ** useful in helping to visualize what has happened on a quiescent |
| 1559 | ** branch that is infrequently merged with a much more activate branch. |
| 1560 | */ |
| 1561 | blob_append_sql(&sql, |
| 1562 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1563 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1564 | tagid |
| 1565 | ); |
| 1566 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1567 | blob_append_sql(&sql, |
| 1568 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1569 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1570 | TAG_HIDDEN |
| 1571 | ); |
| 1572 | } |
| 1573 | if( P("mionly")==0 ){ |
| 1574 | blob_append_sql(&sql, |
| 1575 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1576 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1577 | tagid |
| 1578 | ); |
| 1579 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1580 | blob_append_sql(&sql, |
| 1581 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1582 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1583 | TAG_HIDDEN |
| 1584 | ); |
| 1585 | } |
| 1586 | } |
| 1587 | } |
| 1588 | blob_append_sql(&sql, ")"); |
| 1589 | } |
| 1590 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1591 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1592 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1593 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | |
| 1596 | zType = "all"; |
| 1597 | } |
| 1598 | if( zType[0]=='a' ){ |
| 1599 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1600 | char cSep = '('; |
| 1601 | blob_append_sql(&sql, " AND event.type IN "); |
| 1602 | if( g.perm.Read ){ |
| 1603 | blob_append_sql(&sql, "%c'ci','g'", cSep); |
| 1604 | cSep = ','; |
| 1605 | } |
| 1606 | if( g.perm.RdWiki ){ |
| 1607 | blob_append_sql(&sql, "%c'w','e'", cSep); |
| 1608 | cSep = ','; |
| 1609 | } |
| 1610 | if( g.perm.RdTkt ){ |
| 1611 | blob_append_sql(&sql, "%c't'", cSep); |
| 1612 | cSep = ','; |
| 1613 | } |
| 1614 | blob_append_sql(&sql, ")"); |
| 1615 | } |
| 1616 | }else{ /* zType!="all" */ |
| 1617 | blob_append_sql(&sql, " AND event.type=%Q", zType); |
| 1618 | if( zType[0]=='c' ){ |
| 1619 | zEType = "check-in"; |
| 1620 | }else if( zType[0]=='w' ){ |
| 1621 | zEType = "wiki edit"; |
| 1622 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | |
| 1632 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1633 | if( n<=nEntry ){ |
| 1634 | zCirca = zBefore = zAfter = 0; |
| 1635 | nEntry = -1; |
| 1636 | } |
| 1637 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1638 | zUser, zUser); |
| 1639 | zThisUser = zUser; |
| 1640 | } |
| 1641 | if( zSearch ){ |
| 1642 | blob_append_sql(&sql, |
| 1643 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1644 | zSearch, zSearch); |
| 1645 | } |
| 1646 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1647 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1648 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1649 | if( rAfter>0.0 ){ |
| 1650 | if( rBefore>0.0 ){ |
| 1651 | blob_append_sql(&sql, |
| 1652 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1653 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | |
| 1745 | } |
| 1746 | if( zSearch ){ |
| 1747 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1748 | } |
| 1749 | if( g.perm.Hyperlink ){ |
| 1750 | if( zCirca && rCirca ){ |
| 1751 | nBefore = db_int(0, |
| 1752 | "SELECT count(*) FROM timeline WHERE etype!='div'" |
| 1753 | " AND sortby<=%f /*scan*/", rCirca); |
| 1754 | nAfter = db_int(0, |
| 1755 | "SELECT count(*) FROM timeline WHERE etype!='div'" |
| 1756 | " AND sortby>=%f /*scan*/", rCirca); |
| 1757 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1758 | if( nBefore>=nEntry ){ |
| 1759 | timeline_submenu(&url, "Older", "b", zDate, "c"); |
| 1760 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "c", 0)); |
| 1761 | } |
| 1762 | if( nAfter>=nEntry ){ |
| 1763 | timeline_submenu(&url, "Newer", "a", zDate, "c"); |
| 1764 | } |
| 1765 | free(zDate); |
| 1766 | }else{ |
| 1767 | if( zAfter || n==nEntry ){ |
| 1768 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1769 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1770 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); |
| 1771 | free(zDate); |
| 1772 | } |
| 1773 | if( zBefore || (zAfter && n==nEntry) ){ |
| 1774 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); |
| 1775 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 1776 | free(zDate); |
| 1777 | } |
| 1778 | } |
| 1779 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1780 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1781 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1782 | } |
| @@ -1784,10 +1788,11 @@ | |
| 1784 | style_submenu_entry("n","Max:",4,0); |
| 1785 | timeline_y_submenu(disableY); |
| 1786 | style_submenu_binary("v","With Files","Without Files", |
| 1787 | zType[0]!='a' && zType[0]!='c'); |
| 1788 | } |
| 1789 | } |
| 1790 | if( PB("showsql") ){ |
| 1791 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1792 | } |
| 1793 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1794 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1520,36 +1520,38 @@ | |
| 1520 | }else{ |
| 1521 | /* Otherwise, a timeline based on a span of time */ |
| 1522 | int n, nBefore, nAfter; |
| 1523 | const char *zEType = "timeline item"; |
| 1524 | char *zDate; |
| 1525 | Blob cond; |
| 1526 | blob_zero(&cond); |
| 1527 | if( zUses ){ |
| 1528 | blob_append_sql(&cond, " AND event.objid IN usesfile "); |
| 1529 | } |
| 1530 | if( renameOnly ){ |
| 1531 | blob_append_sql(&cond, " AND event.objid IN rnfile "); |
| 1532 | } |
| 1533 | if( forkOnly ){ |
| 1534 | blob_append_sql(&cond, " AND event.objid IN rnfork "); |
| 1535 | } |
| 1536 | if( bisectOnly ){ |
| 1537 | blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) "); |
| 1538 | } |
| 1539 | if( zYearMonth ){ |
| 1540 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ", |
| 1541 | zYearMonth); |
| 1542 | } |
| 1543 | else if( zYearWeek ){ |
| 1544 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ", |
| 1545 | zYearWeek); |
| 1546 | } |
| 1547 | else if( zDay ){ |
| 1548 | blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m-%%d',event.mtime) ", |
| 1549 | zDay); |
| 1550 | } |
| 1551 | if( tagid ){ |
| 1552 | blob_append_sql(&cond, |
| 1553 | " AND (EXISTS(SELECT 1 FROM tagxref" |
| 1554 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid); |
| 1555 | |
| 1556 | if( zBrName ){ |
| 1557 | /* The next two blob_appendf() calls add SQL that causes check-ins that |
| @@ -1556,38 +1558,38 @@ | |
| 1558 | ** are not part of the branch which are parents or children of the |
| 1559 | ** branch to be included in the report. This related check-ins are |
| 1560 | ** useful in helping to visualize what has happened on a quiescent |
| 1561 | ** branch that is infrequently merged with a much more activate branch. |
| 1562 | */ |
| 1563 | blob_append_sql(&cond, |
| 1564 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=cid" |
| 1565 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1566 | tagid |
| 1567 | ); |
| 1568 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1569 | blob_append_sql(&cond, |
| 1570 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=cid" |
| 1571 | " WHERE tagid=%d AND tagtype>0 AND pid=blob.rid)\n", |
| 1572 | TAG_HIDDEN |
| 1573 | ); |
| 1574 | } |
| 1575 | if( P("mionly")==0 ){ |
| 1576 | blob_append_sql(&cond, |
| 1577 | " OR EXISTS(SELECT 1 FROM plink CROSS JOIN tagxref ON rid=pid" |
| 1578 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1579 | tagid |
| 1580 | ); |
| 1581 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1582 | blob_append_sql(&cond, |
| 1583 | " AND NOT EXISTS(SELECT 1 FROM plink JOIN tagxref ON rid=pid" |
| 1584 | " WHERE tagid=%d AND tagtype>0 AND cid=blob.rid)\n", |
| 1585 | TAG_HIDDEN |
| 1586 | ); |
| 1587 | } |
| 1588 | } |
| 1589 | } |
| 1590 | blob_append_sql(&cond, ")"); |
| 1591 | } |
| 1592 | if( (zType[0]=='w' && !g.perm.RdWiki) |
| 1593 | || (zType[0]=='t' && !g.perm.RdTkt) |
| 1594 | || (zType[0]=='e' && !g.perm.RdWiki) |
| 1595 | || (zType[0]=='c' && !g.perm.Read) |
| @@ -1596,27 +1598,27 @@ | |
| 1598 | zType = "all"; |
| 1599 | } |
| 1600 | if( zType[0]=='a' ){ |
| 1601 | if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){ |
| 1602 | char cSep = '('; |
| 1603 | blob_append_sql(&cond, " AND event.type IN "); |
| 1604 | if( g.perm.Read ){ |
| 1605 | blob_append_sql(&cond, "%c'ci','g'", cSep); |
| 1606 | cSep = ','; |
| 1607 | } |
| 1608 | if( g.perm.RdWiki ){ |
| 1609 | blob_append_sql(&cond, "%c'w','e'", cSep); |
| 1610 | cSep = ','; |
| 1611 | } |
| 1612 | if( g.perm.RdTkt ){ |
| 1613 | blob_append_sql(&cond, "%c't'", cSep); |
| 1614 | cSep = ','; |
| 1615 | } |
| 1616 | blob_append_sql(&cond, ")"); |
| 1617 | } |
| 1618 | }else{ /* zType!="all" */ |
| 1619 | blob_append_sql(&cond, " AND event.type=%Q", zType); |
| 1620 | if( zType[0]=='c' ){ |
| 1621 | zEType = "check-in"; |
| 1622 | }else if( zType[0]=='w' ){ |
| 1623 | zEType = "wiki edit"; |
| 1624 | }else if( zType[0]=='t' ){ |
| @@ -1632,22 +1634,23 @@ | |
| 1634 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1635 | if( n<=nEntry ){ |
| 1636 | zCirca = zBefore = zAfter = 0; |
| 1637 | nEntry = -1; |
| 1638 | } |
| 1639 | blob_append_sql(&cond, " AND (event.user=%Q OR event.euser=%Q)", |
| 1640 | zUser, zUser); |
| 1641 | zThisUser = zUser; |
| 1642 | } |
| 1643 | if( zSearch ){ |
| 1644 | blob_append_sql(&cond, |
| 1645 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 1646 | zSearch, zSearch); |
| 1647 | } |
| 1648 | rBefore = symbolic_name_to_mtime(zBefore); |
| 1649 | rAfter = symbolic_name_to_mtime(zAfter); |
| 1650 | rCirca = symbolic_name_to_mtime(zCirca); |
| 1651 | blob_append_sql(&sql, "%s", blob_sql_text(&cond)); |
| 1652 | if( rAfter>0.0 ){ |
| 1653 | if( rBefore>0.0 ){ |
| 1654 | blob_append_sql(&sql, |
| 1655 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1656 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| @@ -1745,38 +1748,39 @@ | |
| 1748 | } |
| 1749 | if( zSearch ){ |
| 1750 | blob_appendf(&desc, " matching \"%h\"", zSearch); |
| 1751 | } |
| 1752 | if( g.perm.Hyperlink ){ |
| 1753 | double rDate; |
| 1754 | zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/"); |
| 1755 | if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ |
| 1756 | zDate = mprintf("%s", (zAfter ? zAfter : zBefore)); |
| 1757 | } |
| 1758 | if( zDate ){ |
| 1759 | rDate = symbolic_name_to_mtime(zDate); |
| 1760 | if( db_int(0, |
| 1761 | "SELECT EXISTS (SELECT 1 FROM event WHERE mtime<=%.17g%s)", |
| 1762 | rDate-ONE_SECOND, blob_sql_text(&cond)) |
| 1763 | ){ |
| 1764 | timeline_submenu(&url, "Older", "b", zDate, "a"); |
| 1765 | zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0)); |
| 1766 | } |
| 1767 | free(zDate); |
| 1768 | } |
| 1769 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/"); |
| 1770 | if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){ |
| 1771 | zDate = mprintf("%s", (zBefore ? zBefore : zAfter)); |
| 1772 | } |
| 1773 | if( zDate ){ |
| 1774 | rDate = symbolic_name_to_mtime(zDate); |
| 1775 | if( db_int(0, |
| 1776 | "SELECT EXISTS (SELECT 1 FROM event WHERE mtime>=%.17g%s)", |
| 1777 | rDate+ONE_SECOND, blob_sql_text(&cond)) |
| 1778 | ){ |
| 1779 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 1780 | } |
| 1781 | free(zDate); |
| 1782 | } |
| 1783 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1784 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1785 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1786 | } |
| @@ -1784,10 +1788,11 @@ | |
| 1788 | style_submenu_entry("n","Max:",4,0); |
| 1789 | timeline_y_submenu(disableY); |
| 1790 | style_submenu_binary("v","With Files","Without Files", |
| 1791 | zType[0]!='a' && zType[0]!='c'); |
| 1792 | } |
| 1793 | blob_zero(&cond); |
| 1794 | } |
| 1795 | if( PB("showsql") ){ |
| 1796 | @ <pre>%h(blob_sql_text(&sql))</pre> |
| 1797 | } |
| 1798 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1799 |