Overview
SHA1 Hash: | b3ee50c9463214942d0af7055f4a06e2353f631c |
---|---|
Date: | 2008-07-15 19:03:42 |
User: | drh |
Comment: | Implement history display for tickets. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/info.c from [de0ea7fc4a] to [737ba1d6c6].
@@ -793,10 +793,95 @@ blob_reset(&content); style_footer(); } /* +** Return TRUE if the given BLOB contains a newline character. +*/ +static int contains_newline(Blob *p){ + const char *z = blob_str(p); + while( *z ){ + if( *z=='\n' ) return 1; + z++; + } + return 0; +} + +/* +** WEBPAGE: tinfo +** URL: /tinfo?name=UUID +** +** Show the details of a ticket change control artifact. +*/ +void tinfo_page(void){ + int rid; + Blob content; + char *zDate; + int i; + const char *zUuid; + char zTktName[20]; + const char *z; + Manifest m; + + login_check_credentials(); + if( !g.okRdTkt ){ login_needed(); return; } + rid = name_to_rid(PD("name","0")); + if( rid==0 ){ fossil_redirect_home(); } + zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); + if( g.okAdmin ){ + if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ + style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", + g.zTop, zUuid); + }else{ + style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", + g.zTop, zUuid); + } + } + content_get(rid, &content); + if( manifest_parse(&m, &content)==0 ){ + fossil_redirect_home(); + } + if( m.type!=CFTYPE_TICKET ){ + fossil_redirect_home(); + } + style_header("Ticket Change Details"); + zDate = db_text(0, "SELECT datetime(%.12f)", m.rDate); + memcpy(zTktName, m.zTicketUuid, 10); + zTktName[10] = 0; + @ <h2>Changes to ticket <a href="%s(m.zTicketUuid)">%s(zTktName)</a></h2> + @ + @ <p>By %h(m.zUser) on %s(zDate). See also: + @ <a href="%s(g.zTop)/artifact/%T(zUuid)">artifact content</a>, and + @ <a href="%s(g.zTop)/tkthistory/%s(m.zTicketUuid)">ticket history</a> + @ </p> + @ + @ <ol> + free(zDate); + for(i=0; i<m.nField; i++){ + Blob val; + z = m.aField[i].zName; + blob_set(&val, m.aField[i].zValue); + if( z[0]=='+' ){ + @ <li><p>Appended to %h(&z[1]):</p><blockquote> + wiki_convert(&val, 0, 0); + @ </blockquote></li> + }else if( blob_size(&val)<=50 && contains_newline(&val) ){ + @ <li><p>Change %h(z) to:</p><blockquote> + wiki_convert(&val, 0, 0); + @ </blockquote></li> + }else{ + @ <li><p>Change %h(z) to "%h(blob_str(&val))"</p></li> + } + blob_reset(&val); + } + manifest_clear(&m); + @ </ol> + style_footer(); +} + + +/* ** WEBPAGE: info ** URL: info/UUID ** ** The argument is a UUID which might be a baseline or a file or ** a ticket changes or a wiki editor or something else. @@ -831,10 +916,14 @@ finfo_page(); }else if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){ winfo_page(); + }else + if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" + " WHERE rid=%d AND tagname LIKE 'tkt-%%'", rid) ){ + tinfo_page(); }else { artifact_page(); } }
Modified src/manifest.c from [b69e148aae] to [5e75594729].
@@ -893,23 +893,53 @@ ); free(zComment); } if( m.type==CFTYPE_TICKET ){ char *zTag; - char *zComment; + Blob comment; + int i; ticket_insert(&m, 1, 1); zTag = mprintf("tkt-%s", m.zTicketUuid); tag_insert(zTag, 1, 0, rid, m.rDate, rid); free(zTag); - zComment = mprintf("Changes to ticket [%.10s]", m.zTicketUuid); + blob_zero(&comment); + if( m.nField==1 ){ + if( m.aField[0].zName[0]=='+' ){ + blob_appendf(&comment, + "Appended to %h in ticket [%.10s]", + &m.aField[0].zName[1], m.zTicketUuid + ); + }else if( strlen(m.aField[0].zValue)<40 ){ + blob_appendf(&comment, + "Changed %h to \"%h\" in ticket [%.10s]", + m.aField[0].zName, m.aField[0].zValue, m.zTicketUuid + ); + }else{ + blob_appendf(&comment, + "Changed %h in ticket [%.10s]", + m.aField[0].zName, m.zTicketUuid + ); + } + }else{ + const char *z; + const char *zSep = " "; + blob_appendf(&comment, "%d changes to ticket [%.10s]:", + m.nField, m.zTicketUuid); + for(i=0; i<m.nField; i++){ + z = m.aField[i].zName; + if( z[0]=='+' ) z++; + blob_appendf(&comment, "%s%h", zSep, z); + zSep = ", "; + } + } db_multi_exec( "REPLACE INTO event(type,mtime,objid,user,comment)" "VALUES('t',%.17g,%d,%Q,%Q)", - m.rDate, rid, m.zUser, zComment + m.rDate, rid, m.zUser, blob_str(&comment) ); - free(zComment); + blob_reset(&comment); } db_end_transaction(0); manifest_clear(&m); return 1; }
Modified src/tkt.c from [486a2a67ca] to [6ac9641c6a].
@@ -304,10 +304,14 @@ if( !g.okRdTkt ){ login_needed(); return; } if( g.okWrTkt ){ style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", g.zTop, PD("name","")); } + if( g.okHistory ){ + style_submenu_element("History", "History Of This Ticket", + "%s/tkthistory/%T", g.zTop, PD("name","")); + } style_header("View Ticket"); ticket_init(); initializeVariablesFromDb(); zScript = ticket_viewpage_code(); Th_Render(zScript); @@ -546,6 +550,43 @@ "containing all required fields"); return zErr; } } return 0; +} + +/* +** WEBPAGE: tkthistory +** URL: /tkthistory?name=TICKETUUID +** +** Show the complete change history for a single ticket +*/ +void tkthistory_page(void){ + Stmt q; + char *zTitle; + char *zSQL; + const char *zUuid; + int tagid; + + login_check_credentials(); + if( !g.okHistory || !g.okRdTkt ){ login_needed(); return; } + zUuid = PD("name",""); + zTitle = mprintf("History Of Ticket %h", zUuid); + style_header(zTitle); + free(zTitle); + + tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid); + if( tagid==0 ){ + @ No such ticket: %h(zUuid) + style_footer(); + return; + } + zSQL = mprintf("%s AND event.objid IN " + " (SELECT rid FROM tagxref WHERE tagid=%d) " + "ORDER BY mtime DESC", + timeline_query_for_www(), tagid); + db_prepare(&q, zSQL); + free(zSQL); + www_print_timeline(&q); + db_finalize(&q); + style_footer(); }