Fossil SCM
Add the m= query parameter to /timeline. Disable the y= selection box on /timeline for cases where other parameters only allow checkins. Further work needed on the a= and b= query parameters to get them working with all combinations of other parameters.
Commit
45127a7236e4c34ecac670b6ee0645c1bcf77c20
Parent
dd94e596f4bc6e4…
1 file changed
+25
-12
+25
-12
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1033,11 +1033,11 @@ | ||
| 1033 | 1033 | /* |
| 1034 | 1034 | ** Add the select/option box to the timeline submenu that is used to |
| 1035 | 1035 | ** set the y= parameter that determines which elements to display |
| 1036 | 1036 | ** on the timeline. |
| 1037 | 1037 | */ |
| 1038 | -static void timeline_y_submenu(void){ | |
| 1038 | +static void timeline_y_submenu(int isDisabled){ | |
| 1039 | 1039 | static int i = 0; |
| 1040 | 1040 | static const char *az[12]; |
| 1041 | 1041 | if( i==0 ){ |
| 1042 | 1042 | az[0] = "all"; |
| 1043 | 1043 | az[1] = "Any Type"; |
| @@ -1061,11 +1061,11 @@ | ||
| 1061 | 1061 | az[i++] = "Wiki"; |
| 1062 | 1062 | } |
| 1063 | 1063 | assert( i<=ArraySize(az) ); |
| 1064 | 1064 | } |
| 1065 | 1065 | if( i>2 ){ |
| 1066 | - style_submenu_multichoice("y", i/2, az, 0); | |
| 1066 | + style_submenu_multichoice("y", i/2, az, isDisabled); | |
| 1067 | 1067 | } |
| 1068 | 1068 | } |
| 1069 | 1069 | |
| 1070 | 1070 | /* |
| 1071 | 1071 | ** WEBPAGE: timeline |
| @@ -1073,10 +1073,11 @@ | ||
| 1073 | 1073 | ** Query parameters: |
| 1074 | 1074 | ** |
| 1075 | 1075 | ** a=TIMEORTAG after this event |
| 1076 | 1076 | ** b=TIMEORTAG before this event |
| 1077 | 1077 | ** c=TIMEORTAG "circa" this event |
| 1078 | +** m=TIMEORTAG mark this event | |
| 1078 | 1079 | ** n=COUNT max number of events in output |
| 1079 | 1080 | ** p=UUID artifact and up to COUNT parents and ancestors |
| 1080 | 1081 | ** d=UUID artifact and up to COUNT descendants |
| 1081 | 1082 | ** dp=UUID The same as d=UUID&p=UUID |
| 1082 | 1083 | ** t=TAGID show only check-ins with the given tagid |
| @@ -1099,14 +1100,14 @@ | ||
| 1099 | 1100 | ** datefmt=N Override the date format |
| 1100 | 1101 | ** |
| 1101 | 1102 | ** p= and d= can appear individually or together. If either p= or d= |
| 1102 | 1103 | ** appear, then u=, y=, a=, and b= are ignored. |
| 1103 | 1104 | ** |
| 1104 | -** If a= and b= appear, only a= is used. If neither appear, the most | |
| 1105 | -** recent events are chosen. | |
| 1105 | +** If both a= and b= appear then both upper and lower bounds are honored. | |
| 1106 | 1106 | ** |
| 1107 | -** If n= is missing, the default count is 20. | |
| 1107 | +** If n= is missing, the default count is 50 for most queries but | |
| 1108 | +** drops to 11 for c= queries. | |
| 1108 | 1109 | */ |
| 1109 | 1110 | void page_timeline(void){ |
| 1110 | 1111 | Stmt q; /* Query used to generate the timeline */ |
| 1111 | 1112 | Blob sql; /* text of SQL used to generate timeline */ |
| 1112 | 1113 | Blob desc; /* Description of the timeline */ |
| @@ -1117,10 +1118,11 @@ | ||
| 1117 | 1118 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 1118 | 1119 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 1119 | 1120 | const char *zAfter = P("a"); /* Events after this time */ |
| 1120 | 1121 | const char *zBefore = P("b"); /* Events before this time */ |
| 1121 | 1122 | const char *zCirca = P("c"); /* Events near this time */ |
| 1123 | + const char *zMark = P("m"); /* Mark this event or an event this time */ | |
| 1122 | 1124 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 1123 | 1125 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 1124 | 1126 | const char *zSearch = P("s"); /* Search string */ |
| 1125 | 1127 | const char *zUses = P("uf"); /* Only show checkins hold this file */ |
| 1126 | 1128 | const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */ |
| @@ -1140,10 +1142,11 @@ | ||
| 1140 | 1142 | int pd_rid; |
| 1141 | 1143 | double rBefore, rAfter, rCirca; /* Boundary times */ |
| 1142 | 1144 | const char *z; |
| 1143 | 1145 | char *zOlderButton = 0; /* URL for Older button at the bottom */ |
| 1144 | 1146 | int selectedRid = -9999999; /* Show a highlight on this RID */ |
| 1147 | + int disableY = 0; /* Disable type selector on submenu */ | |
| 1145 | 1148 | |
| 1146 | 1149 | /* Set number of rows to display */ |
| 1147 | 1150 | z = P("n"); |
| 1148 | 1151 | if( z ){ |
| 1149 | 1152 | if( fossil_strcmp(z,"all")==0 ){ |
| @@ -1183,14 +1186,18 @@ | ||
| 1183 | 1186 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 1184 | 1187 | zThisTag = zBrName; |
| 1185 | 1188 | }else{ |
| 1186 | 1189 | tagid = 0; |
| 1187 | 1190 | } |
| 1191 | + if( zMark && zMark[0]==0 ){ | |
| 1192 | + if( zAfter ) zMark = zAfter; | |
| 1193 | + if( zBefore ) zMark = zBefore; | |
| 1194 | + if( zCirca ) zMark = zCirca; | |
| 1195 | + } | |
| 1188 | 1196 | if( tagid>0 |
| 1189 | 1197 | && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry |
| 1190 | 1198 | ){ |
| 1191 | - zCirca = zBefore = zAfter = 0; | |
| 1192 | 1199 | nEntry = -1; |
| 1193 | 1200 | } |
| 1194 | 1201 | if( zType[0]=='a' ){ |
| 1195 | 1202 | tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH; |
| 1196 | 1203 | }else{ |
| @@ -1213,10 +1220,11 @@ | ||
| 1213 | 1220 | if( ufid ){ |
| 1214 | 1221 | zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid); |
| 1215 | 1222 | db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)"); |
| 1216 | 1223 | compute_uses_file("usesfile", ufid, 0); |
| 1217 | 1224 | zType = "ci"; |
| 1225 | + disableY = 1; | |
| 1218 | 1226 | }else{ |
| 1219 | 1227 | zUses = 0; |
| 1220 | 1228 | } |
| 1221 | 1229 | } |
| 1222 | 1230 | if( renameOnly ){ |
| @@ -1223,10 +1231,11 @@ | ||
| 1223 | 1231 | db_multi_exec( |
| 1224 | 1232 | "CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);" |
| 1225 | 1233 | "INSERT OR IGNORE INTO rnfile" |
| 1226 | 1234 | " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;" |
| 1227 | 1235 | ); |
| 1236 | + disableY = 1; | |
| 1228 | 1237 | } |
| 1229 | 1238 | |
| 1230 | 1239 | style_header("Timeline"); |
| 1231 | 1240 | login_anonymous_available(); |
| 1232 | 1241 | timeline_temp_table(); |
| @@ -1317,11 +1326,11 @@ | ||
| 1317 | 1326 | /* If both p= and d= are set, we don't have the uuid of d yet. */ |
| 1318 | 1327 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid); |
| 1319 | 1328 | } |
| 1320 | 1329 | } |
| 1321 | 1330 | style_submenu_entry("n","Max:",1,0); |
| 1322 | - timeline_y_submenu(); | |
| 1331 | + timeline_y_submenu(1); | |
| 1323 | 1332 | style_submenu_binary("v","With Files","Without Files", |
| 1324 | 1333 | zType[0]!='a' && zType[0]!='c'); |
| 1325 | 1334 | }else if( f_rid && g.perm.Read ){ |
| 1326 | 1335 | /* If f= is present, ignore all other parameters other than n= */ |
| 1327 | 1336 | char *zUuid; |
| @@ -1494,23 +1503,23 @@ | ||
| 1494 | 1503 | blob_append_sql(&sql, |
| 1495 | 1504 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 1496 | 1505 | rCirca |
| 1497 | 1506 | ); |
| 1498 | 1507 | nEntry -= (nEntry+1)/2; |
| 1508 | + if( zMark==0 ) zMark = zCirca; | |
| 1499 | 1509 | }else{ |
| 1500 | 1510 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1501 | 1511 | } |
| 1502 | 1512 | if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry); |
| 1503 | 1513 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1504 | - if( zCirca && useDividers ) selectedRid = timeline_add_divider(rCirca); | |
| 1505 | 1514 | |
| 1506 | 1515 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1507 | 1516 | if( zYearMonth ){ |
| 1508 | 1517 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1509 | 1518 | }else if( zYearWeek ){ |
| 1510 | 1519 | blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek); |
| 1511 | - }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){ | |
| 1520 | + }else if( zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){ | |
| 1512 | 1521 | blob_appendf(&desc, "%d most recent %ss", n, zEType); |
| 1513 | 1522 | }else{ |
| 1514 | 1523 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1515 | 1524 | } |
| 1516 | 1525 | if( zUses ){ |
| @@ -1565,22 +1574,26 @@ | ||
| 1565 | 1574 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1566 | 1575 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1567 | 1576 | } |
| 1568 | 1577 | } |
| 1569 | 1578 | style_submenu_entry("n","Max:",1,0); |
| 1570 | - if( zUses==0 ) timeline_y_submenu(); | |
| 1579 | + timeline_y_submenu(disableY); | |
| 1571 | 1580 | style_submenu_binary("v","With Files","Without Files", |
| 1572 | 1581 | zType[0]!='a' && zType[0]!='c'); |
| 1573 | 1582 | } |
| 1574 | 1583 | } |
| 1575 | - if( P("showsql") ){ | |
| 1584 | + if( PB("showsql") ){ | |
| 1576 | 1585 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1577 | 1586 | } |
| 1578 | 1587 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1579 | 1588 | style_submenu_element("Search", 0, "%R/search?y=c"); |
| 1580 | 1589 | } |
| 1581 | - if( P("showid") ) tmFlags |= TIMELINE_SHOWRID; | |
| 1590 | + if( PB("showid") ) tmFlags |= TIMELINE_SHOWRID; | |
| 1591 | + if( useDividers && zMark && zMark[0] ){ | |
| 1592 | + double r = symbolic_name_to_mtime(zMark); | |
| 1593 | + if( r>0.0 ) selectedRid = timeline_add_divider(r); | |
| 1594 | + } | |
| 1582 | 1595 | blob_zero(&sql); |
| 1583 | 1596 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1584 | 1597 | @ <h2>%b(&desc)</h2> |
| 1585 | 1598 | blob_reset(&desc); |
| 1586 | 1599 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, selectedRid, 0); |
| 1587 | 1600 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1033,11 +1033,11 @@ | |
| 1033 | /* |
| 1034 | ** Add the select/option box to the timeline submenu that is used to |
| 1035 | ** set the y= parameter that determines which elements to display |
| 1036 | ** on the timeline. |
| 1037 | */ |
| 1038 | static void timeline_y_submenu(void){ |
| 1039 | static int i = 0; |
| 1040 | static const char *az[12]; |
| 1041 | if( i==0 ){ |
| 1042 | az[0] = "all"; |
| 1043 | az[1] = "Any Type"; |
| @@ -1061,11 +1061,11 @@ | |
| 1061 | az[i++] = "Wiki"; |
| 1062 | } |
| 1063 | assert( i<=ArraySize(az) ); |
| 1064 | } |
| 1065 | if( i>2 ){ |
| 1066 | style_submenu_multichoice("y", i/2, az, 0); |
| 1067 | } |
| 1068 | } |
| 1069 | |
| 1070 | /* |
| 1071 | ** WEBPAGE: timeline |
| @@ -1073,10 +1073,11 @@ | |
| 1073 | ** Query parameters: |
| 1074 | ** |
| 1075 | ** a=TIMEORTAG after this event |
| 1076 | ** b=TIMEORTAG before this event |
| 1077 | ** c=TIMEORTAG "circa" this event |
| 1078 | ** n=COUNT max number of events in output |
| 1079 | ** p=UUID artifact and up to COUNT parents and ancestors |
| 1080 | ** d=UUID artifact and up to COUNT descendants |
| 1081 | ** dp=UUID The same as d=UUID&p=UUID |
| 1082 | ** t=TAGID show only check-ins with the given tagid |
| @@ -1099,14 +1100,14 @@ | |
| 1099 | ** datefmt=N Override the date format |
| 1100 | ** |
| 1101 | ** p= and d= can appear individually or together. If either p= or d= |
| 1102 | ** appear, then u=, y=, a=, and b= are ignored. |
| 1103 | ** |
| 1104 | ** If a= and b= appear, only a= is used. If neither appear, the most |
| 1105 | ** recent events are chosen. |
| 1106 | ** |
| 1107 | ** If n= is missing, the default count is 20. |
| 1108 | */ |
| 1109 | void page_timeline(void){ |
| 1110 | Stmt q; /* Query used to generate the timeline */ |
| 1111 | Blob sql; /* text of SQL used to generate timeline */ |
| 1112 | Blob desc; /* Description of the timeline */ |
| @@ -1117,10 +1118,11 @@ | |
| 1117 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 1118 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 1119 | const char *zAfter = P("a"); /* Events after this time */ |
| 1120 | const char *zBefore = P("b"); /* Events before this time */ |
| 1121 | const char *zCirca = P("c"); /* Events near this time */ |
| 1122 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 1123 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 1124 | const char *zSearch = P("s"); /* Search string */ |
| 1125 | const char *zUses = P("uf"); /* Only show checkins hold this file */ |
| 1126 | const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */ |
| @@ -1140,10 +1142,11 @@ | |
| 1140 | int pd_rid; |
| 1141 | double rBefore, rAfter, rCirca; /* Boundary times */ |
| 1142 | const char *z; |
| 1143 | char *zOlderButton = 0; /* URL for Older button at the bottom */ |
| 1144 | int selectedRid = -9999999; /* Show a highlight on this RID */ |
| 1145 | |
| 1146 | /* Set number of rows to display */ |
| 1147 | z = P("n"); |
| 1148 | if( z ){ |
| 1149 | if( fossil_strcmp(z,"all")==0 ){ |
| @@ -1183,14 +1186,18 @@ | |
| 1183 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 1184 | zThisTag = zBrName; |
| 1185 | }else{ |
| 1186 | tagid = 0; |
| 1187 | } |
| 1188 | if( tagid>0 |
| 1189 | && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry |
| 1190 | ){ |
| 1191 | zCirca = zBefore = zAfter = 0; |
| 1192 | nEntry = -1; |
| 1193 | } |
| 1194 | if( zType[0]=='a' ){ |
| 1195 | tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH; |
| 1196 | }else{ |
| @@ -1213,10 +1220,11 @@ | |
| 1213 | if( ufid ){ |
| 1214 | zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid); |
| 1215 | db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)"); |
| 1216 | compute_uses_file("usesfile", ufid, 0); |
| 1217 | zType = "ci"; |
| 1218 | }else{ |
| 1219 | zUses = 0; |
| 1220 | } |
| 1221 | } |
| 1222 | if( renameOnly ){ |
| @@ -1223,10 +1231,11 @@ | |
| 1223 | db_multi_exec( |
| 1224 | "CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);" |
| 1225 | "INSERT OR IGNORE INTO rnfile" |
| 1226 | " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;" |
| 1227 | ); |
| 1228 | } |
| 1229 | |
| 1230 | style_header("Timeline"); |
| 1231 | login_anonymous_available(); |
| 1232 | timeline_temp_table(); |
| @@ -1317,11 +1326,11 @@ | |
| 1317 | /* If both p= and d= are set, we don't have the uuid of d yet. */ |
| 1318 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid); |
| 1319 | } |
| 1320 | } |
| 1321 | style_submenu_entry("n","Max:",1,0); |
| 1322 | timeline_y_submenu(); |
| 1323 | style_submenu_binary("v","With Files","Without Files", |
| 1324 | zType[0]!='a' && zType[0]!='c'); |
| 1325 | }else if( f_rid && g.perm.Read ){ |
| 1326 | /* If f= is present, ignore all other parameters other than n= */ |
| 1327 | char *zUuid; |
| @@ -1494,23 +1503,23 @@ | |
| 1494 | blob_append_sql(&sql, |
| 1495 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 1496 | rCirca |
| 1497 | ); |
| 1498 | nEntry -= (nEntry+1)/2; |
| 1499 | }else{ |
| 1500 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1501 | } |
| 1502 | if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry); |
| 1503 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1504 | if( zCirca && useDividers ) selectedRid = timeline_add_divider(rCirca); |
| 1505 | |
| 1506 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1507 | if( zYearMonth ){ |
| 1508 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1509 | }else if( zYearWeek ){ |
| 1510 | blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek); |
| 1511 | }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){ |
| 1512 | blob_appendf(&desc, "%d most recent %ss", n, zEType); |
| 1513 | }else{ |
| 1514 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1515 | } |
| 1516 | if( zUses ){ |
| @@ -1565,22 +1574,26 @@ | |
| 1565 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1566 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1567 | } |
| 1568 | } |
| 1569 | style_submenu_entry("n","Max:",1,0); |
| 1570 | if( zUses==0 ) timeline_y_submenu(); |
| 1571 | style_submenu_binary("v","With Files","Without Files", |
| 1572 | zType[0]!='a' && zType[0]!='c'); |
| 1573 | } |
| 1574 | } |
| 1575 | if( P("showsql") ){ |
| 1576 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1577 | } |
| 1578 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1579 | style_submenu_element("Search", 0, "%R/search?y=c"); |
| 1580 | } |
| 1581 | if( P("showid") ) tmFlags |= TIMELINE_SHOWRID; |
| 1582 | blob_zero(&sql); |
| 1583 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1584 | @ <h2>%b(&desc)</h2> |
| 1585 | blob_reset(&desc); |
| 1586 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, selectedRid, 0); |
| 1587 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1033,11 +1033,11 @@ | |
| 1033 | /* |
| 1034 | ** Add the select/option box to the timeline submenu that is used to |
| 1035 | ** set the y= parameter that determines which elements to display |
| 1036 | ** on the timeline. |
| 1037 | */ |
| 1038 | static void timeline_y_submenu(int isDisabled){ |
| 1039 | static int i = 0; |
| 1040 | static const char *az[12]; |
| 1041 | if( i==0 ){ |
| 1042 | az[0] = "all"; |
| 1043 | az[1] = "Any Type"; |
| @@ -1061,11 +1061,11 @@ | |
| 1061 | az[i++] = "Wiki"; |
| 1062 | } |
| 1063 | assert( i<=ArraySize(az) ); |
| 1064 | } |
| 1065 | if( i>2 ){ |
| 1066 | style_submenu_multichoice("y", i/2, az, isDisabled); |
| 1067 | } |
| 1068 | } |
| 1069 | |
| 1070 | /* |
| 1071 | ** WEBPAGE: timeline |
| @@ -1073,10 +1073,11 @@ | |
| 1073 | ** Query parameters: |
| 1074 | ** |
| 1075 | ** a=TIMEORTAG after this event |
| 1076 | ** b=TIMEORTAG before this event |
| 1077 | ** c=TIMEORTAG "circa" this event |
| 1078 | ** m=TIMEORTAG mark this event |
| 1079 | ** n=COUNT max number of events in output |
| 1080 | ** p=UUID artifact and up to COUNT parents and ancestors |
| 1081 | ** d=UUID artifact and up to COUNT descendants |
| 1082 | ** dp=UUID The same as d=UUID&p=UUID |
| 1083 | ** t=TAGID show only check-ins with the given tagid |
| @@ -1099,14 +1100,14 @@ | |
| 1100 | ** datefmt=N Override the date format |
| 1101 | ** |
| 1102 | ** p= and d= can appear individually or together. If either p= or d= |
| 1103 | ** appear, then u=, y=, a=, and b= are ignored. |
| 1104 | ** |
| 1105 | ** If both a= and b= appear then both upper and lower bounds are honored. |
| 1106 | ** |
| 1107 | ** If n= is missing, the default count is 50 for most queries but |
| 1108 | ** drops to 11 for c= queries. |
| 1109 | */ |
| 1110 | void page_timeline(void){ |
| 1111 | Stmt q; /* Query used to generate the timeline */ |
| 1112 | Blob sql; /* text of SQL used to generate timeline */ |
| 1113 | Blob desc; /* Description of the timeline */ |
| @@ -1117,10 +1118,11 @@ | |
| 1118 | const char *zUser = P("u"); /* All entries by this user if not NULL */ |
| 1119 | const char *zType = PD("y","all"); /* Type of events. All if NULL */ |
| 1120 | const char *zAfter = P("a"); /* Events after this time */ |
| 1121 | const char *zBefore = P("b"); /* Events before this time */ |
| 1122 | const char *zCirca = P("c"); /* Events near this time */ |
| 1123 | const char *zMark = P("m"); /* Mark this event or an event this time */ |
| 1124 | const char *zTagName = P("t"); /* Show events with this tag */ |
| 1125 | const char *zBrName = P("r"); /* Show events related to this tag */ |
| 1126 | const char *zSearch = P("s"); /* Search string */ |
| 1127 | const char *zUses = P("uf"); /* Only show checkins hold this file */ |
| 1128 | const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */ |
| @@ -1140,10 +1142,11 @@ | |
| 1142 | int pd_rid; |
| 1143 | double rBefore, rAfter, rCirca; /* Boundary times */ |
| 1144 | const char *z; |
| 1145 | char *zOlderButton = 0; /* URL for Older button at the bottom */ |
| 1146 | int selectedRid = -9999999; /* Show a highlight on this RID */ |
| 1147 | int disableY = 0; /* Disable type selector on submenu */ |
| 1148 | |
| 1149 | /* Set number of rows to display */ |
| 1150 | z = P("n"); |
| 1151 | if( z ){ |
| 1152 | if( fossil_strcmp(z,"all")==0 ){ |
| @@ -1183,14 +1186,18 @@ | |
| 1186 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 1187 | zThisTag = zBrName; |
| 1188 | }else{ |
| 1189 | tagid = 0; |
| 1190 | } |
| 1191 | if( zMark && zMark[0]==0 ){ |
| 1192 | if( zAfter ) zMark = zAfter; |
| 1193 | if( zBefore ) zMark = zBefore; |
| 1194 | if( zCirca ) zMark = zCirca; |
| 1195 | } |
| 1196 | if( tagid>0 |
| 1197 | && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry |
| 1198 | ){ |
| 1199 | nEntry = -1; |
| 1200 | } |
| 1201 | if( zType[0]=='a' ){ |
| 1202 | tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH; |
| 1203 | }else{ |
| @@ -1213,10 +1220,11 @@ | |
| 1220 | if( ufid ){ |
| 1221 | zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid); |
| 1222 | db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)"); |
| 1223 | compute_uses_file("usesfile", ufid, 0); |
| 1224 | zType = "ci"; |
| 1225 | disableY = 1; |
| 1226 | }else{ |
| 1227 | zUses = 0; |
| 1228 | } |
| 1229 | } |
| 1230 | if( renameOnly ){ |
| @@ -1223,10 +1231,11 @@ | |
| 1231 | db_multi_exec( |
| 1232 | "CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);" |
| 1233 | "INSERT OR IGNORE INTO rnfile" |
| 1234 | " SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;" |
| 1235 | ); |
| 1236 | disableY = 1; |
| 1237 | } |
| 1238 | |
| 1239 | style_header("Timeline"); |
| 1240 | login_anonymous_available(); |
| 1241 | timeline_temp_table(); |
| @@ -1317,11 +1326,11 @@ | |
| 1326 | /* If both p= and d= are set, we don't have the uuid of d yet. */ |
| 1327 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", d_rid); |
| 1328 | } |
| 1329 | } |
| 1330 | style_submenu_entry("n","Max:",1,0); |
| 1331 | timeline_y_submenu(1); |
| 1332 | style_submenu_binary("v","With Files","Without Files", |
| 1333 | zType[0]!='a' && zType[0]!='c'); |
| 1334 | }else if( f_rid && g.perm.Read ){ |
| 1335 | /* If f= is present, ignore all other parameters other than n= */ |
| 1336 | char *zUuid; |
| @@ -1494,23 +1503,23 @@ | |
| 1503 | blob_append_sql(&sql, |
| 1504 | " AND event.mtime>=%f ORDER BY event.mtime ASC", |
| 1505 | rCirca |
| 1506 | ); |
| 1507 | nEntry -= (nEntry+1)/2; |
| 1508 | if( zMark==0 ) zMark = zCirca; |
| 1509 | }else{ |
| 1510 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1511 | } |
| 1512 | if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry); |
| 1513 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1514 | |
| 1515 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1516 | if( zYearMonth ){ |
| 1517 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1518 | }else if( zYearWeek ){ |
| 1519 | blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek); |
| 1520 | }else if( zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){ |
| 1521 | blob_appendf(&desc, "%d most recent %ss", n, zEType); |
| 1522 | }else{ |
| 1523 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1524 | } |
| 1525 | if( zUses ){ |
| @@ -1565,22 +1574,26 @@ | |
| 1574 | if( (tmFlags & TIMELINE_UNHIDE)==0 ){ |
| 1575 | timeline_submenu(&url, "Unhide", "unhide", "", 0); |
| 1576 | } |
| 1577 | } |
| 1578 | style_submenu_entry("n","Max:",1,0); |
| 1579 | timeline_y_submenu(disableY); |
| 1580 | style_submenu_binary("v","With Files","Without Files", |
| 1581 | zType[0]!='a' && zType[0]!='c'); |
| 1582 | } |
| 1583 | } |
| 1584 | if( PB("showsql") ){ |
| 1585 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1586 | } |
| 1587 | if( search_restrict(SRCH_CKIN)!=0 ){ |
| 1588 | style_submenu_element("Search", 0, "%R/search?y=c"); |
| 1589 | } |
| 1590 | if( PB("showid") ) tmFlags |= TIMELINE_SHOWRID; |
| 1591 | if( useDividers && zMark && zMark[0] ){ |
| 1592 | double r = symbolic_name_to_mtime(zMark); |
| 1593 | if( r>0.0 ) selectedRid = timeline_add_divider(r); |
| 1594 | } |
| 1595 | blob_zero(&sql); |
| 1596 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1597 | @ <h2>%b(&desc)</h2> |
| 1598 | blob_reset(&desc); |
| 1599 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, selectedRid, 0); |
| 1600 |