| | @@ -791,10 +791,95 @@ |
| 791 | 791 | @ %h(blob_str(&content)) |
| 792 | 792 | @ </pre></blockquote> |
| 793 | 793 | blob_reset(&content); |
| 794 | 794 | style_footer(); |
| 795 | 795 | } |
| 796 | + |
| 797 | +/* |
| 798 | +** Return TRUE if the given BLOB contains a newline character. |
| 799 | +*/ |
| 800 | +static int contains_newline(Blob *p){ |
| 801 | + const char *z = blob_str(p); |
| 802 | + while( *z ){ |
| 803 | + if( *z=='\n' ) return 1; |
| 804 | + z++; |
| 805 | + } |
| 806 | + return 0; |
| 807 | +} |
| 808 | + |
| 809 | +/* |
| 810 | +** WEBPAGE: tinfo |
| 811 | +** URL: /tinfo?name=UUID |
| 812 | +** |
| 813 | +** Show the details of a ticket change control artifact. |
| 814 | +*/ |
| 815 | +void tinfo_page(void){ |
| 816 | + int rid; |
| 817 | + Blob content; |
| 818 | + char *zDate; |
| 819 | + int i; |
| 820 | + const char *zUuid; |
| 821 | + char zTktName[20]; |
| 822 | + const char *z; |
| 823 | + Manifest m; |
| 824 | + |
| 825 | + login_check_credentials(); |
| 826 | + if( !g.okRdTkt ){ login_needed(); return; } |
| 827 | + rid = name_to_rid(PD("name","0")); |
| 828 | + if( rid==0 ){ fossil_redirect_home(); } |
| 829 | + zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 830 | + if( g.okAdmin ){ |
| 831 | + if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){ |
| 832 | + style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1", |
| 833 | + g.zTop, zUuid); |
| 834 | + }else{ |
| 835 | + style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun", |
| 836 | + g.zTop, zUuid); |
| 837 | + } |
| 838 | + } |
| 839 | + content_get(rid, &content); |
| 840 | + if( manifest_parse(&m, &content)==0 ){ |
| 841 | + fossil_redirect_home(); |
| 842 | + } |
| 843 | + if( m.type!=CFTYPE_TICKET ){ |
| 844 | + fossil_redirect_home(); |
| 845 | + } |
| 846 | + style_header("Ticket Change Details"); |
| 847 | + zDate = db_text(0, "SELECT datetime(%.12f)", m.rDate); |
| 848 | + memcpy(zTktName, m.zTicketUuid, 10); |
| 849 | + zTktName[10] = 0; |
| 850 | + @ <h2>Changes to ticket <a href="%s(m.zTicketUuid)">%s(zTktName)</a></h2> |
| 851 | + @ |
| 852 | + @ <p>By %h(m.zUser) on %s(zDate). See also: |
| 853 | + @ <a href="%s(g.zTop)/artifact/%T(zUuid)">artifact content</a>, and |
| 854 | + @ <a href="%s(g.zTop)/tkthistory/%s(m.zTicketUuid)">ticket history</a> |
| 855 | + @ </p> |
| 856 | + @ |
| 857 | + @ <ol> |
| 858 | + free(zDate); |
| 859 | + for(i=0; i<m.nField; i++){ |
| 860 | + Blob val; |
| 861 | + z = m.aField[i].zName; |
| 862 | + blob_set(&val, m.aField[i].zValue); |
| 863 | + if( z[0]=='+' ){ |
| 864 | + @ <li><p>Appended to %h(&z[1]):</p><blockquote> |
| 865 | + wiki_convert(&val, 0, 0); |
| 866 | + @ </blockquote></li> |
| 867 | + }else if( blob_size(&val)<=50 && contains_newline(&val) ){ |
| 868 | + @ <li><p>Change %h(z) to:</p><blockquote> |
| 869 | + wiki_convert(&val, 0, 0); |
| 870 | + @ </blockquote></li> |
| 871 | + }else{ |
| 872 | + @ <li><p>Change %h(z) to "%h(blob_str(&val))"</p></li> |
| 873 | + } |
| 874 | + blob_reset(&val); |
| 875 | + } |
| 876 | + manifest_clear(&m); |
| 877 | + @ </ol> |
| 878 | + style_footer(); |
| 879 | +} |
| 880 | + |
| 796 | 881 | |
| 797 | 882 | /* |
| 798 | 883 | ** WEBPAGE: info |
| 799 | 884 | ** URL: info/UUID |
| 800 | 885 | ** |
| | @@ -831,10 +916,14 @@ |
| 831 | 916 | finfo_page(); |
| 832 | 917 | }else |
| 833 | 918 | if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" |
| 834 | 919 | " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){ |
| 835 | 920 | winfo_page(); |
| 921 | + }else |
| 922 | + if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" |
| 923 | + " WHERE rid=%d AND tagname LIKE 'tkt-%%'", rid) ){ |
| 924 | + tinfo_page(); |
| 836 | 925 | }else |
| 837 | 926 | { |
| 838 | 927 | artifact_page(); |
| 839 | 928 | } |
| 840 | 929 | } |
| 841 | 930 | |