| | @@ -306,21 +306,27 @@ |
| 306 | 306 | Blob sql; /* text of SQL used to generate timeline */ |
| 307 | 307 | Blob desc; /* Description of the timeline */ |
| 308 | 308 | int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ |
| 309 | 309 | int p_rid = atoi(PD("p","0")); /* artifact p and its parents */ |
| 310 | 310 | int d_rid = atoi(PD("d","0")); /* artifact d and its descendants */ |
| 311 | | - int tagid = atoi(PD("t","0")); /* Show checkins of a given tag */ |
| 312 | 311 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 313 | 312 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 314 | 313 | const char *zAfter = P("a"); /* Events after this time */ |
| 315 | 314 | const char *zBefore = P("b"); /* Events before this time */ |
| 315 | + const char *zTagName = P("t"); /* Show events with this tag */ |
| 316 | 316 | HQuery url; /* URL for various branch links */ |
| 317 | + int tagid; /* Tag ID */ |
| 317 | 318 | |
| 318 | 319 | /* To view the timeline, must have permission to read project data. |
| 319 | 320 | */ |
| 320 | 321 | login_check_credentials(); |
| 321 | 322 | if( !g.okRead ){ login_needed(); return; } |
| 323 | + if( zTagName ){ |
| 324 | + tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 325 | + }else{ |
| 326 | + tagid = 0; |
| 327 | + } |
| 322 | 328 | |
| 323 | 329 | style_header("Timeline"); |
| 324 | 330 | login_anonymous_available(); |
| 325 | 331 | timeline_temp_table(); |
| 326 | 332 | blob_zero(&sql); |
| | @@ -362,29 +368,24 @@ |
| 362 | 368 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 363 | 369 | g.zBaseURL, zUuid, zUuid); |
| 364 | 370 | }else{ |
| 365 | 371 | blob_appendf(&desc, " of [%.10s]", zUuid); |
| 366 | 372 | } |
| 367 | | - }else if( tagid>0 ){ |
| 368 | | - /* If t= is present, ignore all other parameters. Show everything |
| 369 | | - ** with that tag. */ |
| 370 | | - blob_appendf(&sql, " AND event.type='ci'"); |
| 371 | | - blob_appendf(&sql, " AND EXISTS (SELECT 1 FROM tagxref WHERE tagid=%d" |
| 372 | | - " AND tagtype>0 AND rid=blob.rid)", |
| 373 | | - tagid); |
| 374 | | - db_multi_exec("%s", blob_str(&sql)); |
| 375 | | - blob_appendf(&desc, "All check-ins tagged with \"%h\"", |
| 376 | | - db_text("??", "SELECT substr(tagname,5) FROM tag WHERE tagid=%d", |
| 377 | | - tagid) |
| 378 | | - ); |
| 379 | 373 | }else{ |
| 380 | 374 | int n; |
| 381 | 375 | const char *zEType = "event"; |
| 382 | 376 | char *zDate; |
| 383 | 377 | char *zNEntry = mprintf("%d", nEntry); |
| 384 | 378 | url_initialize(&url, "timeline"); |
| 385 | 379 | url_add_parameter(&url, "n", zNEntry); |
| 380 | + if( tagid>0 ){ |
| 381 | + zType = "ci"; |
| 382 | + url_add_parameter(&url, "t", zTagName); |
| 383 | + blob_appendf(&sql, " AND EXISTS (SELECT 1 FROM tagxref WHERE tagid=%d" |
| 384 | + " AND tagtype>0 AND rid=blob.rid)", |
| 385 | + tagid); |
| 386 | + } |
| 386 | 387 | if( zType[0]!='a' ){ |
| 387 | 388 | blob_appendf(&sql, " AND event.type=%Q", zType); |
| 388 | 389 | url_add_parameter(&url, "y", zType); |
| 389 | 390 | if( zType[0]=='c' ){ |
| 390 | 391 | zEType = "checkin"; |
| | @@ -435,10 +436,13 @@ |
| 435 | 436 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 436 | 437 | } |
| 437 | 438 | if( zUser ){ |
| 438 | 439 | blob_appendf(&desc, " by user %h", zUser); |
| 439 | 440 | } |
| 441 | + if( tagid>0 ){ |
| 442 | + blob_appendf(&desc, " tagged with \"%h\"", zTagName); |
| 443 | + } |
| 440 | 444 | if( zAfter ){ |
| 441 | 445 | blob_appendf(&desc, " occurring on or after %h.<br>", zAfter); |
| 442 | 446 | }else if( zBefore ){ |
| 443 | 447 | blob_appendf(&desc, " occurring on or before %h.<br>", zBefore); |
| 444 | 448 | } |
| | @@ -450,11 +454,11 @@ |
| 450 | 454 | } |
| 451 | 455 | if( zBefore || (zAfter && n==nEntry) ){ |
| 452 | 456 | zDate = db_text(0, "SELECT max(timestamp) FROM timeline"); |
| 453 | 457 | timeline_submenu(&url, "Newer", "a", zDate, "b"); |
| 454 | 458 | free(zDate); |
| 455 | | - }else{ |
| 459 | + }else if( tagid==0 ){ |
| 456 | 460 | if( zType[0]!='a' ){ |
| 457 | 461 | timeline_submenu(&url, "All Types", "y", "all", 0); |
| 458 | 462 | } |
| 459 | 463 | if( zType[0]!='w' ){ |
| 460 | 464 | timeline_submenu(&url, "Wiki Only", "y", "w", 0); |
| 461 | 465 | |