| | @@ -149,10 +149,12 @@ |
| 149 | 149 | ** 10. Short comment to user for repeated tickets and wiki |
| 150 | 150 | */ |
| 151 | 151 | void www_print_timeline( |
| 152 | 152 | Stmt *pQuery, /* Query to implement the timeline */ |
| 153 | 153 | int tmFlags, /* Flags controlling display behavior */ |
| 154 | + const char *zThisUser, /* Suppress links to this user */ |
| 155 | + const char *zThisTag, /* Suppress links to this tag */ |
| 154 | 156 | void (*xExtra)(int) /* Routine to call on each line of display */ |
| 155 | 157 | ){ |
| 156 | 158 | int wikiFlags; |
| 157 | 159 | int mxWikiLen; |
| 158 | 160 | Blob comment; |
| | @@ -290,15 +292,54 @@ |
| 290 | 292 | blob_reset(&truncated); |
| 291 | 293 | }else{ |
| 292 | 294 | wiki_convert(&comment, 0, wikiFlags); |
| 293 | 295 | } |
| 294 | 296 | blob_reset(&comment); |
| 295 | | - if( zTagList && zTagList[0] ){ |
| 296 | | - @ (user: %h(zUser), tags: %h(zTagList)) |
| 297 | + |
| 298 | + /* Generate the "user: USERNAME" at the end of the comment, together |
| 299 | + ** with a hyperlink to another timeline for that user. |
| 300 | + */ |
| 301 | + if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 302 | + if( g.okHistory && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 303 | + char *zLink = mprintf("%s/timeline?u=%h&c=%t&nd", |
| 304 | + g.zTop, zUser, zDate); |
| 305 | + @ (user: <a href="%s(zLink)">%h(zUser)</a>%s(zTagList?",":"\051") |
| 306 | + fossil_free(zLink); |
| 297 | 307 | }else{ |
| 298 | | - @ (user: %h(zUser)) |
| 308 | + @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 309 | + } |
| 310 | + |
| 311 | + /* Generate the "tags: TAGLIST" at the end of the comment, together |
| 312 | + ** with hyperlinks to the tag list. |
| 313 | + */ |
| 314 | + if( zTagList ){ |
| 315 | + if( g.okHistory ){ |
| 316 | + int i; |
| 317 | + const char *z = zTagList; |
| 318 | + Blob links; |
| 319 | + blob_zero(&links); |
| 320 | + while( z && z[0] ){ |
| 321 | + for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 322 | + if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 323 | + blob_appendf(&links, |
| 324 | + "<a href=\"%s/timeline?r=%.*t&nd&c=%s\">%.*h</a>%.2s", |
| 325 | + g.zTop, i, z, zDate, i, z, &z[i] |
| 326 | + ); |
| 327 | + }else{ |
| 328 | + blob_appendf(&links, "%.*h", i+2, z); |
| 329 | + } |
| 330 | + if( z[i]==0 ) break; |
| 331 | + z += i+2; |
| 332 | + } |
| 333 | + @ tags: %s(blob_str(&links))) |
| 334 | + blob_reset(&links); |
| 335 | + }else{ |
| 336 | + @ tags: %h(zTagList)) |
| 337 | + } |
| 299 | 338 | } |
| 339 | + |
| 340 | + /* Generate extra hyperlinks at the end of the comment */ |
| 300 | 341 | if( xExtra ){ |
| 301 | 342 | xExtra(rid); |
| 302 | 343 | } |
| 303 | 344 | @ </td></tr> |
| 304 | 345 | } |
| | @@ -708,22 +749,26 @@ |
| 708 | 749 | const char *zCirca = P("c"); /* Events near this time */ |
| 709 | 750 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 710 | 751 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 711 | 752 | const char *zSearch = P("s"); /* Search string */ |
| 712 | 753 | int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */ |
| 713 | | - HQuery url; /* URL for various branch links */ |
| 714 | 754 | int tagid; /* Tag ID */ |
| 715 | 755 | int tmFlags; /* Timeline flags */ |
| 756 | + const char *zThisTag = 0; /* Suppress links to this tag */ |
| 757 | + const char *zThisUser = 0; /* Suppress links to this user */ |
| 758 | + HQuery url; /* URL for various branch links */ |
| 716 | 759 | |
| 717 | 760 | /* To view the timeline, must have permission to read project data. |
| 718 | 761 | */ |
| 719 | 762 | login_check_credentials(); |
| 720 | 763 | if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ login_needed(); return; } |
| 721 | 764 | if( zTagName && g.okRead ){ |
| 722 | 765 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
| 766 | + zThisTag = zTagName; |
| 723 | 767 | }else if( zBrName && g.okRead ){ |
| 724 | 768 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 769 | + zThisTag = zBrName; |
| 725 | 770 | }else{ |
| 726 | 771 | tagid = 0; |
| 727 | 772 | } |
| 728 | 773 | if( zType[0]=='a' ){ |
| 729 | 774 | tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH; |
| | @@ -739,10 +784,12 @@ |
| 739 | 784 | timeline_temp_table(); |
| 740 | 785 | blob_zero(&sql); |
| 741 | 786 | blob_zero(&desc); |
| 742 | 787 | blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1); |
| 743 | 788 | blob_append(&sql, timeline_query_for_www(), -1); |
| 789 | + url_initialize(&url, "timeline"); |
| 790 | + if( !useDividers ) url_add_parameter(&url, "nd", 0); |
| 744 | 791 | if( (p_rid || d_rid) && g.okRead ){ |
| 745 | 792 | /* If p= or d= is present, ignore all other parameters other than n= */ |
| 746 | 793 | char *zUuid; |
| 747 | 794 | int np, nd; |
| 748 | 795 | |
| | @@ -807,11 +854,10 @@ |
| 807 | 854 | }else{ |
| 808 | 855 | int n; |
| 809 | 856 | const char *zEType = "timeline item"; |
| 810 | 857 | char *zDate; |
| 811 | 858 | char *zNEntry = mprintf("%d", nEntry); |
| 812 | | - url_initialize(&url, "timeline"); |
| 813 | 859 | url_add_parameter(&url, "n", zNEntry); |
| 814 | 860 | if( tagid>0 ){ |
| 815 | 861 | blob_appendf(&sql, |
| 816 | 862 | "AND (EXISTS(SELECT 1 FROM tagxref" |
| 817 | 863 | " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid); |
| | @@ -874,10 +920,11 @@ |
| 874 | 920 | } |
| 875 | 921 | } |
| 876 | 922 | if( zUser ){ |
| 877 | 923 | blob_appendf(&sql, " AND event.user=%Q", zUser); |
| 878 | 924 | url_add_parameter(&url, "u", zUser); |
| 925 | + zThisUser = zUser; |
| 879 | 926 | } |
| 880 | 927 | if ( zSearch ){ |
| 881 | 928 | blob_appendf(&sql, |
| 882 | 929 | " AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')", |
| 883 | 930 | zSearch, zSearch); |
| | @@ -1002,11 +1049,11 @@ |
| 1002 | 1049 | } |
| 1003 | 1050 | blob_zero(&sql); |
| 1004 | 1051 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1005 | 1052 | @ <h2>%b(&desc)</h2> |
| 1006 | 1053 | blob_reset(&desc); |
| 1007 | | - www_print_timeline(&q, tmFlags, 0); |
| 1054 | + www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0); |
| 1008 | 1055 | db_finalize(&q); |
| 1009 | 1056 | style_footer(); |
| 1010 | 1057 | } |
| 1011 | 1058 | |
| 1012 | 1059 | /* |
| 1013 | 1060 | |