Fossil

Check-in [4932465e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add a "Show/Hide Files" button under the "Context" section of the check-in page.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | context-show-files
Files: files | file ages | folders
SHA1:4932465eccfe6fae9b6f5b33d9456927bb8515f7
User & Date: drh 2015-02-09 20:53:25
Context
2015-02-09
20:53
Add a "Show/Hide Files" button under the "Context" section of the check-in page. Leaf check-in: 4932465e user: drh tags: context-show-files
12:18
Add mime-types for openoffice documents. Cherry-picked from viric_flavour branch. Thanks! check-in: 04e6a82e user: jan.nijtmans tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/info.c.

262
263
264
265
266
267
268

269
270
271
272
273
274
275
...
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317


318











319
320
321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
...
523
524
525
526
527
528
529

530
531
532
533
534
535
536
...
574
575
576
577
578
579
580

581
582
583
584
585
586
587
...
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701






702
703
704
705
706
707
708
...
724
725
726
727
728
729
730
731

732
733
734
735
736
737
738
...
751
752
753
754
755
756
757

758
759
760
761
762
763
764
...
809
810
811
812
813
814
815

816
817
818
819
820
821
822
...
835
836
837
838
839
840
841

842
843
844

845
846
847
848
849
850
851
852
853

854
855
856
857

858
859

860
861
862
863
864
865
866
....
1955
1956
1957
1958
1959
1960
1961

1962
1963
1964
1965
1966
1967
1968
1969
....
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987

1988
1989
1990
1991
1992
1993
1994
1995
1996

1997
1998
1999
2000
2001

2002
2003
2004
2005
2006
2007
2008
    const char *zValue = db_column_text(&q, 3);
    const char *zDate = db_column_text(&q, 4);
    int tagtype = db_column_int(&q, 5);
    const char *zOrigUuid = db_column_text(&q, 6);
    cnt++;
    if( cnt==1 ){
      @ <div class="section">Tags And Properties</div>

      @ <ul>
    }
    @ <li>
    if( tagtype==0 ){
      @ <span class="infoTagCancelled">%h(zTagname)</span> cancelled
    }else if( zValue ){
      @ <span class="infoTag">%h(zTagname)=%h(zValue)</span>
................................................................................
      hyperlink_to_date(zDate,0);
    }
    @ </li>
  }
  db_finalize(&q);
  if( cnt ){
    @ </ul>

  }
}

/*
** Show the context graph (immediate parents and children) for
** check-in rid.
*/
static void showContext(int rid){
  Blob sql;
  Stmt q;


  @ <div class="section">Context</div>











  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_www(), -1);
  db_multi_exec(
     "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
     "INSERT INTO ok VALUES(%d);"
     "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
     "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
     rid, rid, rid
  );
  blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
  db_prepare(&q, "%s", blob_sql_text(&sql));
  www_print_timeline(&q, TIMELINE_DISJOINT|TIMELINE_GRAPH, 0, 0, rid, 0);
  db_finalize(&q);

}


/*
** Append the difference between artifacts to the output
*/
static void append_diff(
................................................................................
  const char *zUuid;   /* UUID of zName */
  const char *zParent; /* UUID of the parent checkin (if any) */
  const char *zRe;     /* regex parameter */
  ReCompiled *pRe = 0; /* regex */
  const char *zW;      /* URL param for ignoring whitespace */
  const char *zPage = "vinfo";  /* Page that shows diffs */
  const char *zPageHide = "ci"; /* Page that hides diffs */


  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  zName = P("name");
  rid = name_to_rid_www("name");
  if( rid==0 ){
    style_header("Check-in Information Error");
................................................................................
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);
    zUser = db_column_text(&q1, 2);
    zComment = db_column_text(&q1, 3);
    zDate = db_column_text(&q1,1);
    zOrigDate = db_column_text(&q1, 4);
    @ <div class="section">Overview</div>

    @ <table class="label-value">
    @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
    if( g.perm.Setup ){
      @ (Record ID: %d(rid))
    }
    @ </td></tr>
    @ <tr><th>Date:</th><td>
................................................................................
      if( g.perm.Write ){
        @   | %z(href("%R/ci_edit?r=%S",zUuid))edit</a>
      }
      @   </td>
      @ </tr>
      blob_reset(&projName);
    }
    @ </table>
  }else{
    style_header("Check-in Information");
    login_anonymous_available();
  }
  db_finalize(&q1);
  showTags(rid);
  showContext(rid);
  @ <div class="section">Changes</div>
  @ <div class="sectionmenu">
  verboseFlag = g.zPath[0]!='c';
  if( db_get_boolean("show-version-diffs", 0)==0 ){
    verboseFlag = !verboseFlag;
    zPage = "ci";
    zPageHide = "vinfo";
  }






  diffFlags = construct_diff_flags(verboseFlag, sideBySide);
  zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
  if( verboseFlag ){
    @ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
    @ Hide&nbsp;Diffs</a>
    if( sideBySide ){
      @ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
................................................................................
    @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName))
    @ Show&nbsp;Side-by-Side&nbsp;Diffs</a>
  }
  if( zParent ){
    @ %z(xhref("class='button'","%R/vpatch?from=%s&to=%s",zParent,zUuid))
    @ Patch</a>
  }
  @</div>

  if( pRe ){
    @ <p><b>Only differences that match regular expression "%h(zRe)"
    @ are shown.</b></p>
  }
  db_prepare(&q3,
    "SELECT name,"
    "       mperm,"
................................................................................
    int mperm = db_column_int(&q3, 1);
    const char *zOld = db_column_text(&q3,2);
    const char *zNew = db_column_text(&q3,3);
    const char *zOldName = db_column_text(&q3, 4);
    append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
  }
  db_finalize(&q3);

  append_diff_javascript(sideBySide);
  style_footer();
}

/*
** WEBPAGE: winfo
** URL:  /winfo?name=UUID
................................................................................
  style_submenu_element("Raw", "Raw", "artifact/%s", zUuid);
  style_submenu_element("History", "History", "whistory?name=%t",
                        pWiki->zWikiTitle);
  style_submenu_element("Page", "Page", "wiki?name=%t",
                        pWiki->zWikiTitle);
  login_anonymous_available();
  @ <div class="section">Overview</div>

  @ <p><table class="label-value">
  @ <tr><th>Artifact&nbsp;ID:</th>
  @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
  if( g.perm.Setup ){
    @ (%d(rid))
  }
  modPending = moderation_pending(rid);
................................................................................
    for(i=0; i<pWiki->nParent; i++){
      char *zParent = pWiki->azParent[i];
      @ %z(href("info/%s",zParent))%s(zParent)</a>
    }
    @ </td></tr>
  }
  @ </table>


  if( g.perm.ModWiki && modPending ){
    @ <div class="section">Moderation</div>

    @ <blockquote>
    @ <form method="POST" action="%R/winfo/%s(zUuid)">
    @ <label><input type="radio" name="modaction" value="delete">
    @ Delete this change</label><br />
    @ <label><input type="radio" name="modaction" value="approve">
    @ Approve this change</label><br />
    @ <input type="submit" value="Submit">
    @ </form>
    @ </blockquote>

  }


  @ <div class="section">Content</div>

  blob_init(&wiki, pWiki->zWiki, -1);
  wiki_convert(&wiki, 0, 0);

  blob_reset(&wiki);
  manifest_destroy(pWiki);
  style_footer();
}

/*
** Show a webpage error message
................................................................................
    style_submenu_element("Formatted", "Formatted", "%R/info/%s", zUuid);
  }else{
    style_submenu_element("Plaintext", "Plaintext",
                          "%R/info/%s?plaintext", zUuid);
  }

  @ <div class="section">Overview</div>

  @ <p><table class="label-value">
  @ <tr><th>Artifact&nbsp;ID:</th>
  @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
  if( g.perm.Setup ){
    @ (%d(rid))
  }
  modPending = moderation_pending(rid);
  if( modPending ){
................................................................................
  }
  @</td></tr>
  @ <tr><th>Date:</th><td>
  hyperlink_to_date(zDate, "</td></tr>");
  @ <tr><th>User:</th><td>
  hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
  @ </table>

  free(zDate);
  free(zTktTitle);

  if( g.perm.ModTkt && modPending ){
    @ <div class="section">Moderation</div>

    @ <blockquote>
    @ <form method="POST" action="%R/tinfo/%s(zUuid)">
    @ <label><input type="radio" name="modaction" value="delete">
    @ Delete this change</label><br />
    @ <label><input type="radio" name="modaction" value="approve">
    @ Approve this change</label><br />
    @ <input type="submit" value="Submit">
    @ </form>
    @ </blockquote>

  }

  @ <div class="section">Changes</div>
  @ <p>
  ticket_output_change_artifact(pTktChng, 0);

  manifest_destroy(pTktChng);
  style_footer();
}


/*
** WEBPAGE: info







>







 







>







|


>
>

>
>
>
>
>
>
>
>
>
>
>











|

>







 







>







 







>







 







|





<
<
<
<






>
>
>
>
>
>







 







|
>







 







>







 







>







 







>



>









>




>


>







 







>
|







 







>





>









>



|

>







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
...
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
...
697
698
699
700
701
702
703
704
705
706
707
708
709




710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
...
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
...
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
....
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
....
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
    const char *zValue = db_column_text(&q, 3);
    const char *zDate = db_column_text(&q, 4);
    int tagtype = db_column_int(&q, 5);
    const char *zOrigUuid = db_column_text(&q, 6);
    cnt++;
    if( cnt==1 ){
      @ <div class="section">Tags And Properties</div>
      @ <div class="sectionbody">
      @ <ul>
    }
    @ <li>
    if( tagtype==0 ){
      @ <span class="infoTagCancelled">%h(zTagname)</span> cancelled
    }else if( zValue ){
      @ <span class="infoTag">%h(zTagname)=%h(zValue)</span>
................................................................................
      hyperlink_to_date(zDate,0);
    }
    @ </li>
  }
  db_finalize(&q);
  if( cnt ){
    @ </ul>
    @ </div>
  }
}

/*
** Show the context graph (immediate parents and children) for
** check-in rid.
*/
static void showContext(int rid, HQuery *pUrl){
  Blob sql;
  Stmt q;
  int tmFlags = TIMELINE_DISJOINT | TIMELINE_GRAPH;
  char *zLink;
  @ <div class="section">Context</div>
  @ <div class="sectionmenu">
  if( PB("v") ){
    tmFlags |= TIMELINE_FCHANGES;
    zLink = xhref("class='button'", "%s", url_render(pUrl,"v",0,0,0));
    @ %z(zLink)Omit Files</a>
  }else{
    zLink = xhref("class='button'", "%s", url_render(pUrl,"v","1",0,0));
    @ %z(zLink)Show Files</a>
  }
  @ </div>
  @ <div class="sectionbody">
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_www(), -1);
  db_multi_exec(
     "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
     "INSERT INTO ok VALUES(%d);"
     "INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
     "INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
     rid, rid, rid
  );
  blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
  db_prepare(&q, "%s", blob_sql_text(&sql));
  www_print_timeline(&q, tmFlags, 0, 0, rid, 0);
  db_finalize(&q);
  @ </div>
}


/*
** Append the difference between artifacts to the output
*/
static void append_diff(
................................................................................
  const char *zUuid;   /* UUID of zName */
  const char *zParent; /* UUID of the parent checkin (if any) */
  const char *zRe;     /* regex parameter */
  ReCompiled *pRe = 0; /* regex */
  const char *zW;      /* URL param for ignoring whitespace */
  const char *zPage = "vinfo";  /* Page that shows diffs */
  const char *zPageHide = "ci"; /* Page that hides diffs */
  HQuery url;	

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  zName = P("name");
  rid = name_to_rid_www("name");
  if( rid==0 ){
    style_header("Check-in Information Error");
................................................................................
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);
    zUser = db_column_text(&q1, 2);
    zComment = db_column_text(&q1, 3);
    zDate = db_column_text(&q1,1);
    zOrigDate = db_column_text(&q1, 4);
    @ <div class="section">Overview</div>
    @ <div class="sectionbody">
    @ <table class="label-value">
    @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
    if( g.perm.Setup ){
      @ (Record ID: %d(rid))
    }
    @ </td></tr>
    @ <tr><th>Date:</th><td>
................................................................................
      if( g.perm.Write ){
        @   | %z(href("%R/ci_edit?r=%S",zUuid))edit</a>
      }
      @   </td>
      @ </tr>
      blob_reset(&projName);
    }
    @ </table></div>
  }else{
    style_header("Check-in Information");
    login_anonymous_available();
  }
  db_finalize(&q1);




  verboseFlag = g.zPath[0]!='c';
  if( db_get_boolean("show-version-diffs", 0)==0 ){
    verboseFlag = !verboseFlag;
    zPage = "ci";
    zPageHide = "vinfo";
  }
  showTags(rid);
  url_initialize(&url, zPage);
  cgi_query_parameters_to_url(&url);
  showContext(rid, &url);
  @ <div class="section">Changes</div>
  @ <div class="sectionmenu">
  diffFlags = construct_diff_flags(verboseFlag, sideBySide);
  zW = (diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
  if( verboseFlag ){
    @ %z(xhref("class='button'","%R/%s/%T",zPageHide,zName))
    @ Hide&nbsp;Diffs</a>
    if( sideBySide ){
      @ %z(xhref("class='button'","%R/%s/%T?sbs=0%s",zPage,zName,zW))
................................................................................
    @ %z(xhref("class='button'","%R/%s/%T?sbs=1",zPage,zName))
    @ Show&nbsp;Side-by-Side&nbsp;Diffs</a>
  }
  if( zParent ){
    @ %z(xhref("class='button'","%R/vpatch?from=%s&to=%s",zParent,zUuid))
    @ Patch</a>
  }
  @ </div>
  @ <div class="sectionbody">
  if( pRe ){
    @ <p><b>Only differences that match regular expression "%h(zRe)"
    @ are shown.</b></p>
  }
  db_prepare(&q3,
    "SELECT name,"
    "       mperm,"
................................................................................
    int mperm = db_column_int(&q3, 1);
    const char *zOld = db_column_text(&q3,2);
    const char *zNew = db_column_text(&q3,3);
    const char *zOldName = db_column_text(&q3, 4);
    append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
  }
  db_finalize(&q3);
  @ </div>
  append_diff_javascript(sideBySide);
  style_footer();
}

/*
** WEBPAGE: winfo
** URL:  /winfo?name=UUID
................................................................................
  style_submenu_element("Raw", "Raw", "artifact/%s", zUuid);
  style_submenu_element("History", "History", "whistory?name=%t",
                        pWiki->zWikiTitle);
  style_submenu_element("Page", "Page", "wiki?name=%t",
                        pWiki->zWikiTitle);
  login_anonymous_available();
  @ <div class="section">Overview</div>
  @ <div class="sectionbody">
  @ <p><table class="label-value">
  @ <tr><th>Artifact&nbsp;ID:</th>
  @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
  if( g.perm.Setup ){
    @ (%d(rid))
  }
  modPending = moderation_pending(rid);
................................................................................
    for(i=0; i<pWiki->nParent; i++){
      char *zParent = pWiki->azParent[i];
      @ %z(href("info/%s",zParent))%s(zParent)</a>
    }
    @ </td></tr>
  }
  @ </table>
  @ </div>

  if( g.perm.ModWiki && modPending ){
    @ <div class="section">Moderation</div>
    @ <div class="sectionbody">
    @ <blockquote>
    @ <form method="POST" action="%R/winfo/%s(zUuid)">
    @ <label><input type="radio" name="modaction" value="delete">
    @ Delete this change</label><br />
    @ <label><input type="radio" name="modaction" value="approve">
    @ Approve this change</label><br />
    @ <input type="submit" value="Submit">
    @ </form>
    @ </blockquote>
    @ </div>
  }


  @ <div class="section">Content</div>
  @ <div class="sectionbody">
  blob_init(&wiki, pWiki->zWiki, -1);
  wiki_convert(&wiki, 0, 0);
  @ </div>
  blob_reset(&wiki);
  manifest_destroy(pWiki);
  style_footer();
}

/*
** Show a webpage error message
................................................................................
    style_submenu_element("Formatted", "Formatted", "%R/info/%s", zUuid);
  }else{
    style_submenu_element("Plaintext", "Plaintext",
                          "%R/info/%s?plaintext", zUuid);
  }

  @ <div class="section">Overview</div>
  @ <div class="sectionbody">
  @ <table class="label-value">
  @ <tr><th>Artifact&nbsp;ID:</th>
  @ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
  if( g.perm.Setup ){
    @ (%d(rid))
  }
  modPending = moderation_pending(rid);
  if( modPending ){
................................................................................
  }
  @</td></tr>
  @ <tr><th>Date:</th><td>
  hyperlink_to_date(zDate, "</td></tr>");
  @ <tr><th>User:</th><td>
  hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
  @ </table>
  @ </div>
  free(zDate);
  free(zTktTitle);

  if( g.perm.ModTkt && modPending ){
    @ <div class="section">Moderation</div>
    @ <div class="sectionbody">
    @ <blockquote>
    @ <form method="POST" action="%R/tinfo/%s(zUuid)">
    @ <label><input type="radio" name="modaction" value="delete">
    @ Delete this change</label><br />
    @ <label><input type="radio" name="modaction" value="approve">
    @ Approve this change</label><br />
    @ <input type="submit" value="Submit">
    @ </form>
    @ </blockquote>
    @ </div>
  }

  @ <div class="section">Changes</div>
  @ <div class="sectionbody">
  ticket_output_change_artifact(pTktChng, 0);
  @ </div>
  manifest_destroy(pTktChng);
  style_footer();
}


/*
** WEBPAGE: info