Fossil SCM
Enhancements to "divider" processing in web timelines. Only show a single divider if two or more occur beside each other. Add the "nd" query parameter to suppress all dividers.
Commit
c89200831173ed8dbfc255c347bae4c0107a872a
Parent
3c62ea139ab9792…
1 file changed
+23
-18
+23
-18
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -180,10 +180,11 @@ | ||
| 180 | 180 | Blob comment; |
| 181 | 181 | int prevTagid = 0; |
| 182 | 182 | int suppressCnt = 0; |
| 183 | 183 | char zPrevDate[20]; |
| 184 | 184 | GraphContext *pGraph = 0; |
| 185 | + int prevWasDivider = 0; /* True if previous output row was <hr> */ | |
| 185 | 186 | |
| 186 | 187 | zPrevDate[0] = 0; |
| 187 | 188 | mxWikiLen = db_get_int("timeline-max-comment", 0); |
| 188 | 189 | if( db_get_boolean("timeline-block-markup", 0) ){ |
| 189 | 190 | wikiFlags = WIKI_INLINE; |
| @@ -228,13 +229,17 @@ | ||
| 228 | 229 | @ <span class="timelineDisabled">... %d(suppressCnt) similar |
| 229 | 230 | @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> |
| 230 | 231 | suppressCnt = 0; |
| 231 | 232 | } |
| 232 | 233 | if( fossil_strcmp(zType,"div")==0 ){ |
| 233 | - @ <tr><td colspan="3"><hr /></td></tr> | |
| 234 | + if( !prevWasDivider ){ | |
| 235 | + @ <tr><td colspan="3"><hr /></td></tr> | |
| 236 | + } | |
| 237 | + prevWasDivider = 1; | |
| 234 | 238 | continue; |
| 235 | 239 | } |
| 240 | + prevWasDivider = 0; | |
| 236 | 241 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 237 | 242 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 238 | 243 | @ <tr><td> |
| 239 | 244 | @ <div class="divider">%s(zPrevDate)</div> |
| 240 | 245 | @ </td></tr> |
| @@ -655,13 +660,21 @@ | ||
| 655 | 660 | |
| 656 | 661 | |
| 657 | 662 | /* |
| 658 | 663 | ** zDate is a localtime date. Insert records into the |
| 659 | 664 | ** "timeline" table to cause <hr> to be inserted before and after |
| 660 | -** entries of that date. | |
| 665 | +** entries of that date. If zDate==NULL then put dividers around | |
| 666 | +** the event identified by rid. | |
| 661 | 667 | */ |
| 662 | -static void timeline_add_dividers(const char *zDate){ | |
| 668 | +static void timeline_add_dividers(const char *zDate, int rid){ | |
| 669 | + char *zToDel = 0; | |
| 670 | + if( zDate==0 ){ | |
| 671 | + zToDel = db_text(0,"SELECT datetime(mtime,'localtime') FROM event" | |
| 672 | + " WHERE objid=%d", rid); | |
| 673 | + zDate = zToDel; | |
| 674 | + if( zDate==0 ) zDate = "1"; | |
| 675 | + } | |
| 663 | 676 | db_multi_exec( |
| 664 | 677 | "INSERT INTO timeline(rid,sortby,etype)" |
| 665 | 678 | "VALUES(-1,julianday(%Q,'utc')-5.0e-6,'div')", |
| 666 | 679 | zDate |
| 667 | 680 | ); |
| @@ -668,10 +681,11 @@ | ||
| 668 | 681 | db_multi_exec( |
| 669 | 682 | "INSERT INTO timeline(rid,sortby,etype)" |
| 670 | 683 | "VALUES(-2,julianday(%Q,'utc')+5.0e-6,'div')", |
| 671 | 684 | zDate |
| 672 | 685 | ); |
| 686 | + fossil_free(zToDel); | |
| 673 | 687 | } |
| 674 | 688 | |
| 675 | 689 | |
| 676 | 690 | /* |
| 677 | 691 | ** WEBPAGE: timeline |
| @@ -688,10 +702,11 @@ | ||
| 688 | 702 | ** r=TAGID show check-ins related to tagid |
| 689 | 703 | ** u=USER only if belonging to this user |
| 690 | 704 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 691 | 705 | ** s=TEXT string search (comment and brief) |
| 692 | 706 | ** ng Suppress the graph if present |
| 707 | +** nd Suppress "divider" lines | |
| 693 | 708 | ** f=RID Show family (immediate parents and children) of RID |
| 694 | 709 | ** |
| 695 | 710 | ** p= and d= can appear individually or together. If either p= or d= |
| 696 | 711 | ** appear, then u=, y=, a=, and b= are ignored. |
| 697 | 712 | ** |
| @@ -714,10 +729,11 @@ | ||
| 714 | 729 | const char *zBefore = P("b"); /* Events before this time */ |
| 715 | 730 | const char *zCirca = P("c"); /* Events near this time */ |
| 716 | 731 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 717 | 732 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 718 | 733 | const char *zSearch = P("s"); /* Search string */ |
| 734 | + int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */ | |
| 719 | 735 | HQuery url; /* URL for various branch links */ |
| 720 | 736 | int tagid; /* Tag ID */ |
| 721 | 737 | int tmFlags; /* Timeline flags */ |
| 722 | 738 | |
| 723 | 739 | /* To view the timeline, must have permission to read project data. |
| @@ -768,14 +784,11 @@ | ||
| 768 | 784 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 769 | 785 | if( nd>=0 ){ |
| 770 | 786 | db_multi_exec("%s", blob_str(&sql)); |
| 771 | 787 | blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 772 | 788 | } |
| 773 | - timeline_add_dividers( | |
| 774 | - db_text("1","SELECT datetime(mtime,'localtime') FROM event" | |
| 775 | - " WHERE objid=%d", d_rid) | |
| 776 | - ); | |
| 789 | + if( useDividers ) timeline_add_dividers(0, d_rid); | |
| 777 | 790 | db_multi_exec("DELETE FROM ok"); |
| 778 | 791 | } |
| 779 | 792 | if( p_rid ){ |
| 780 | 793 | compute_ancestors(p_rid, nEntry+1); |
| 781 | 794 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| @@ -782,16 +795,11 @@ | ||
| 782 | 795 | if( np>0 ){ |
| 783 | 796 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 784 | 797 | blob_appendf(&desc, "%d ancestors", np); |
| 785 | 798 | db_multi_exec("%s", blob_str(&sql)); |
| 786 | 799 | } |
| 787 | - if( d_rid==0 ){ | |
| 788 | - timeline_add_dividers( | |
| 789 | - db_text("1","SELECT datetime(mtime,'localtime') FROM event" | |
| 790 | - " WHERE objid=%d", p_rid) | |
| 791 | - ); | |
| 792 | - } | |
| 800 | + if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); | |
| 793 | 801 | } |
| 794 | 802 | if( g.okHistory ){ |
| 795 | 803 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 796 | 804 | g.zTop, zUuid, zUuid); |
| 797 | 805 | }else{ |
| @@ -807,14 +815,11 @@ | ||
| 807 | 815 | "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;", |
| 808 | 816 | f_rid, f_rid, f_rid |
| 809 | 817 | ); |
| 810 | 818 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 811 | 819 | db_multi_exec("%s", blob_str(&sql)); |
| 812 | - timeline_add_dividers( | |
| 813 | - db_text("1","SELECT datetime(mtime,'localtime') FROM event" | |
| 814 | - " WHERE objid=%d", f_rid) | |
| 815 | - ); | |
| 820 | + if( useDividers ) timeline_add_dividers(0, f_rid); | |
| 816 | 821 | blob_appendf(&desc, "Parents and children of check-in "); |
| 817 | 822 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 818 | 823 | if( g.okHistory ){ |
| 819 | 824 | blob_appendf(&desc, "<a href='%s/info/%s'>[%.10s]</a>", |
| 820 | 825 | g.zTop, zUuid, zUuid); |
| @@ -936,11 +941,11 @@ | ||
| 936 | 941 | blob_appendf(&sql, |
| 937 | 942 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 938 | 943 | rCirca |
| 939 | 944 | ); |
| 940 | 945 | nEntry -= (nEntry+1)/2; |
| 941 | - timeline_add_dividers(zCirca); | |
| 946 | + if( useDividers ) timeline_add_dividers(zCirca, 0); | |
| 942 | 947 | url_add_parameter(&url, "c", zCirca); |
| 943 | 948 | }else{ |
| 944 | 949 | zCirca = 0; |
| 945 | 950 | } |
| 946 | 951 | }else{ |
| 947 | 952 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -180,10 +180,11 @@ | |
| 180 | Blob comment; |
| 181 | int prevTagid = 0; |
| 182 | int suppressCnt = 0; |
| 183 | char zPrevDate[20]; |
| 184 | GraphContext *pGraph = 0; |
| 185 | |
| 186 | zPrevDate[0] = 0; |
| 187 | mxWikiLen = db_get_int("timeline-max-comment", 0); |
| 188 | if( db_get_boolean("timeline-block-markup", 0) ){ |
| 189 | wikiFlags = WIKI_INLINE; |
| @@ -228,13 +229,17 @@ | |
| 228 | @ <span class="timelineDisabled">... %d(suppressCnt) similar |
| 229 | @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> |
| 230 | suppressCnt = 0; |
| 231 | } |
| 232 | if( fossil_strcmp(zType,"div")==0 ){ |
| 233 | @ <tr><td colspan="3"><hr /></td></tr> |
| 234 | continue; |
| 235 | } |
| 236 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 237 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 238 | @ <tr><td> |
| 239 | @ <div class="divider">%s(zPrevDate)</div> |
| 240 | @ </td></tr> |
| @@ -655,13 +660,21 @@ | |
| 655 | |
| 656 | |
| 657 | /* |
| 658 | ** zDate is a localtime date. Insert records into the |
| 659 | ** "timeline" table to cause <hr> to be inserted before and after |
| 660 | ** entries of that date. |
| 661 | */ |
| 662 | static void timeline_add_dividers(const char *zDate){ |
| 663 | db_multi_exec( |
| 664 | "INSERT INTO timeline(rid,sortby,etype)" |
| 665 | "VALUES(-1,julianday(%Q,'utc')-5.0e-6,'div')", |
| 666 | zDate |
| 667 | ); |
| @@ -668,10 +681,11 @@ | |
| 668 | db_multi_exec( |
| 669 | "INSERT INTO timeline(rid,sortby,etype)" |
| 670 | "VALUES(-2,julianday(%Q,'utc')+5.0e-6,'div')", |
| 671 | zDate |
| 672 | ); |
| 673 | } |
| 674 | |
| 675 | |
| 676 | /* |
| 677 | ** WEBPAGE: timeline |
| @@ -688,10 +702,11 @@ | |
| 688 | ** r=TAGID show check-ins related to tagid |
| 689 | ** u=USER only if belonging to this user |
| 690 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 691 | ** s=TEXT string search (comment and brief) |
| 692 | ** ng Suppress the graph if present |
| 693 | ** f=RID Show family (immediate parents and children) of RID |
| 694 | ** |
| 695 | ** p= and d= can appear individually or together. If either p= or d= |
| 696 | ** appear, then u=, y=, a=, and b= are ignored. |
| 697 | ** |
| @@ -714,10 +729,11 @@ | |
| 714 | const char *zBefore = P("b"); /* Events before this time */ |
| 715 | const char *zCirca = P("c"); /* Events near this time */ |
| 716 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 717 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 718 | const char *zSearch = P("s"); /* Search string */ |
| 719 | HQuery url; /* URL for various branch links */ |
| 720 | int tagid; /* Tag ID */ |
| 721 | int tmFlags; /* Timeline flags */ |
| 722 | |
| 723 | /* To view the timeline, must have permission to read project data. |
| @@ -768,14 +784,11 @@ | |
| 768 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 769 | if( nd>=0 ){ |
| 770 | db_multi_exec("%s", blob_str(&sql)); |
| 771 | blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 772 | } |
| 773 | timeline_add_dividers( |
| 774 | db_text("1","SELECT datetime(mtime,'localtime') FROM event" |
| 775 | " WHERE objid=%d", d_rid) |
| 776 | ); |
| 777 | db_multi_exec("DELETE FROM ok"); |
| 778 | } |
| 779 | if( p_rid ){ |
| 780 | compute_ancestors(p_rid, nEntry+1); |
| 781 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| @@ -782,16 +795,11 @@ | |
| 782 | if( np>0 ){ |
| 783 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 784 | blob_appendf(&desc, "%d ancestors", np); |
| 785 | db_multi_exec("%s", blob_str(&sql)); |
| 786 | } |
| 787 | if( d_rid==0 ){ |
| 788 | timeline_add_dividers( |
| 789 | db_text("1","SELECT datetime(mtime,'localtime') FROM event" |
| 790 | " WHERE objid=%d", p_rid) |
| 791 | ); |
| 792 | } |
| 793 | } |
| 794 | if( g.okHistory ){ |
| 795 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 796 | g.zTop, zUuid, zUuid); |
| 797 | }else{ |
| @@ -807,14 +815,11 @@ | |
| 807 | "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;", |
| 808 | f_rid, f_rid, f_rid |
| 809 | ); |
| 810 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 811 | db_multi_exec("%s", blob_str(&sql)); |
| 812 | timeline_add_dividers( |
| 813 | db_text("1","SELECT datetime(mtime,'localtime') FROM event" |
| 814 | " WHERE objid=%d", f_rid) |
| 815 | ); |
| 816 | blob_appendf(&desc, "Parents and children of check-in "); |
| 817 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 818 | if( g.okHistory ){ |
| 819 | blob_appendf(&desc, "<a href='%s/info/%s'>[%.10s]</a>", |
| 820 | g.zTop, zUuid, zUuid); |
| @@ -936,11 +941,11 @@ | |
| 936 | blob_appendf(&sql, |
| 937 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 938 | rCirca |
| 939 | ); |
| 940 | nEntry -= (nEntry+1)/2; |
| 941 | timeline_add_dividers(zCirca); |
| 942 | url_add_parameter(&url, "c", zCirca); |
| 943 | }else{ |
| 944 | zCirca = 0; |
| 945 | } |
| 946 | }else{ |
| 947 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -180,10 +180,11 @@ | |
| 180 | Blob comment; |
| 181 | int prevTagid = 0; |
| 182 | int suppressCnt = 0; |
| 183 | char zPrevDate[20]; |
| 184 | GraphContext *pGraph = 0; |
| 185 | int prevWasDivider = 0; /* True if previous output row was <hr> */ |
| 186 | |
| 187 | zPrevDate[0] = 0; |
| 188 | mxWikiLen = db_get_int("timeline-max-comment", 0); |
| 189 | if( db_get_boolean("timeline-block-markup", 0) ){ |
| 190 | wikiFlags = WIKI_INLINE; |
| @@ -228,13 +229,17 @@ | |
| 229 | @ <span class="timelineDisabled">... %d(suppressCnt) similar |
| 230 | @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr> |
| 231 | suppressCnt = 0; |
| 232 | } |
| 233 | if( fossil_strcmp(zType,"div")==0 ){ |
| 234 | if( !prevWasDivider ){ |
| 235 | @ <tr><td colspan="3"><hr /></td></tr> |
| 236 | } |
| 237 | prevWasDivider = 1; |
| 238 | continue; |
| 239 | } |
| 240 | prevWasDivider = 0; |
| 241 | if( memcmp(zDate, zPrevDate, 10) ){ |
| 242 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 243 | @ <tr><td> |
| 244 | @ <div class="divider">%s(zPrevDate)</div> |
| 245 | @ </td></tr> |
| @@ -655,13 +660,21 @@ | |
| 660 | |
| 661 | |
| 662 | /* |
| 663 | ** zDate is a localtime date. Insert records into the |
| 664 | ** "timeline" table to cause <hr> to be inserted before and after |
| 665 | ** entries of that date. If zDate==NULL then put dividers around |
| 666 | ** the event identified by rid. |
| 667 | */ |
| 668 | static void timeline_add_dividers(const char *zDate, int rid){ |
| 669 | char *zToDel = 0; |
| 670 | if( zDate==0 ){ |
| 671 | zToDel = db_text(0,"SELECT datetime(mtime,'localtime') FROM event" |
| 672 | " WHERE objid=%d", rid); |
| 673 | zDate = zToDel; |
| 674 | if( zDate==0 ) zDate = "1"; |
| 675 | } |
| 676 | db_multi_exec( |
| 677 | "INSERT INTO timeline(rid,sortby,etype)" |
| 678 | "VALUES(-1,julianday(%Q,'utc')-5.0e-6,'div')", |
| 679 | zDate |
| 680 | ); |
| @@ -668,10 +681,11 @@ | |
| 681 | db_multi_exec( |
| 682 | "INSERT INTO timeline(rid,sortby,etype)" |
| 683 | "VALUES(-2,julianday(%Q,'utc')+5.0e-6,'div')", |
| 684 | zDate |
| 685 | ); |
| 686 | fossil_free(zToDel); |
| 687 | } |
| 688 | |
| 689 | |
| 690 | /* |
| 691 | ** WEBPAGE: timeline |
| @@ -688,10 +702,11 @@ | |
| 702 | ** r=TAGID show check-ins related to tagid |
| 703 | ** u=USER only if belonging to this user |
| 704 | ** y=TYPE 'ci', 'w', 't', 'e' |
| 705 | ** s=TEXT string search (comment and brief) |
| 706 | ** ng Suppress the graph if present |
| 707 | ** nd Suppress "divider" lines |
| 708 | ** f=RID Show family (immediate parents and children) of RID |
| 709 | ** |
| 710 | ** p= and d= can appear individually or together. If either p= or d= |
| 711 | ** appear, then u=, y=, a=, and b= are ignored. |
| 712 | ** |
| @@ -714,10 +729,11 @@ | |
| 729 | const char *zBefore = P("b"); /* Events before this time */ |
| 730 | const char *zCirca = P("c"); /* Events near this time */ |
| 731 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 732 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 733 | const char *zSearch = P("s"); /* Search string */ |
| 734 | int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */ |
| 735 | HQuery url; /* URL for various branch links */ |
| 736 | int tagid; /* Tag ID */ |
| 737 | int tmFlags; /* Timeline flags */ |
| 738 | |
| 739 | /* To view the timeline, must have permission to read project data. |
| @@ -768,14 +784,11 @@ | |
| 784 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 785 | if( nd>=0 ){ |
| 786 | db_multi_exec("%s", blob_str(&sql)); |
| 787 | blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 788 | } |
| 789 | if( useDividers ) timeline_add_dividers(0, d_rid); |
| 790 | db_multi_exec("DELETE FROM ok"); |
| 791 | } |
| 792 | if( p_rid ){ |
| 793 | compute_ancestors(p_rid, nEntry+1); |
| 794 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| @@ -782,16 +795,11 @@ | |
| 795 | if( np>0 ){ |
| 796 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 797 | blob_appendf(&desc, "%d ancestors", np); |
| 798 | db_multi_exec("%s", blob_str(&sql)); |
| 799 | } |
| 800 | if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); |
| 801 | } |
| 802 | if( g.okHistory ){ |
| 803 | blob_appendf(&desc, " of <a href='%s/info/%s'>[%.10s]</a>", |
| 804 | g.zTop, zUuid, zUuid); |
| 805 | }else{ |
| @@ -807,14 +815,11 @@ | |
| 815 | "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;", |
| 816 | f_rid, f_rid, f_rid |
| 817 | ); |
| 818 | blob_appendf(&sql, " AND event.objid IN ok"); |
| 819 | db_multi_exec("%s", blob_str(&sql)); |
| 820 | if( useDividers ) timeline_add_dividers(0, f_rid); |
| 821 | blob_appendf(&desc, "Parents and children of check-in "); |
| 822 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid); |
| 823 | if( g.okHistory ){ |
| 824 | blob_appendf(&desc, "<a href='%s/info/%s'>[%.10s]</a>", |
| 825 | g.zTop, zUuid, zUuid); |
| @@ -936,11 +941,11 @@ | |
| 941 | blob_appendf(&sql, |
| 942 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 943 | rCirca |
| 944 | ); |
| 945 | nEntry -= (nEntry+1)/2; |
| 946 | if( useDividers ) timeline_add_dividers(zCirca, 0); |
| 947 | url_add_parameter(&url, "c", zCirca); |
| 948 | }else{ |
| 949 | zCirca = 0; |
| 950 | } |
| 951 | }else{ |
| 952 |