add index page link to stexaminer and relmapper
[scpubgit/stemmaweb.git] / root / src / index.tt
index 13b612d..53bf324 100644 (file)
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-  <head>
-    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <link type="text/css" href="[% c.uri_for('css/cupertino/jquery-ui-1.8.13.custom.css') %]" rel="stylesheet" />
-    <link type="text/css" href="[% c.uri_for('css/style.css') %]" rel="stylesheet" />
-    <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
-    <script type="text/javascript" src="js/jquery-ui-1.8.10.custom.min.js"></script>
-    <script type="text/javascript" src="js/interaction.js"></script>
-    <title>Text tradition tools</title>
-  </head>
-  <body>
-[% content %]
-  </body>
-</html>
+[% WRAPPER header.tt
+       pagetitle = "Stemmaweb - Text tradition tools"
+       applicationjs = c.uri_for( 'js/componentload.js' )
+%]
+    <script type="text/javascript">
+var basepath = window.location.pathname
+if( basepath.lastIndexOf('/') == basepath.length - 1 ) { 
+       basepath = basepath.slice( 0, basepath.length - 1) 
+};
+var textOnLoad = "[% withtradition %]";
+var selectedTextID;
+var selectedTextInfo;
+var selectedStemmaID = -1;
+var stemmata = [];
+
+function refreshDirectory () {
+       var lmesg = $('#loading_message').clone();
+       $('#directory').empty().append( lmesg.contents() );
+    $('#directory').load( "[% c.uri_for( 'directory' ) %]", 
+       function(response, status, xhr) {
+                       if (status == "error") {
+                               var msg = "An error occurred: ";
+                               $("#directory").html(msg + xhr.status + " " + xhr.statusText);
+                       } else {
+                               if( textOnLoad != "" ) {
+                                       // Call the click callback for the relevant text, if it is
+                                       // in the page.
+                                       $('#'+textOnLoad).click();
+                                       textOnLoad = "";
+                               }
+                       }
+               }
+       );
+}
+
+function start_upload_dialog() {
+    if( typeof uploader != 'undefined' ){ uploader.destroy() };
+    $('#upload-collation-dialog').dialog('option', 'attach_uploader')();
+    $('#upload_status').empty();
+    $('#upload_button').button('disable');
+    $('#upload-collation-dialog').dialog('open');
+}
+
+$(document).ready( function() {
+    // call out to load the directory div
+    $('#textinfo_container').hide();
+    $('#textinfo_waitbox').hide();
+       refreshDirectory();
+       
+       // Set up the textinfo edit dialog
+       $('#textinfo-edit-dialog').dialog({
+               autoOpen: false,
+               height: 200,
+               width: 300,
+               modal: true,
+               buttons: {
+                       Save: function (evt) {
+                               $("#edit_textinfo_status").empty();
+                               $(evt.target).button("disable");
+                               var requrl = "[% c.uri_for( '/textinfo' ) %]/" + selectedTextID;
+                               var reqparam = $('#edit_textinfo').serialize();
+                               $.post( requrl, reqparam, function (data) {
+                                       // Reload the selected text fields
+                                       selectedTextInfo = data;
+                                       load_textinfo();
+                                       // Reenable the button and close the form
+                                       $(evt.target).button("enable");
+                                       $('#textinfo-edit-dialog').dialog('close');
+                               }, 'json' );
+                       },
+                       Cancel: function() {
+                               $('#textinfo-edit-dialog').dialog('close');
+                       }
+               },
+               open: function() {
+                       $("#edit_textinfo_status").empty();
+                       // Populate the form fields with the current values
+                       // edit_(name, language, public, owner)
+                       $.each([ 'name', 'language', 'owner' ], function( idx, k ) {
+                               var fname = '#edit_' + k;
+                               // Special case: language Default is basically language null
+                               if( k == 'language' && selectedTextInfo[k] == 'Default' ) {
+                                       $(fname).val( "" );
+                               } else {
+                                       $(fname).val( selectedTextInfo[k] );
+                               }
+                       });
+                       if( selectedTextInfo['public'] == true ) {
+                               $('#edit_public').attr('checked','true');
+                       } else {
+                               $('#edit_public').removeAttr('checked');
+                       }
+               },
+       }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
+               $(event.target).parent().find('.ui-button').button("enable");
+       if( ajaxSettings.url.indexOf( 'textinfo' ) > -1 
+               && ajaxSettings.type == 'POST' ) {
+                       display_error( jqXHR, $("#edit_textinfo_status") );
+       }
+       });
+
+       
+       // Set up the stemma editor dialog
+       $('#stemma-edit-dialog').dialog({
+               autoOpen: false,
+               height: 700,
+               width: 600,
+               modal: true,
+               buttons: {
+                       Save: function (evt) {
+                               $("#edit_stemma_status").empty();
+                               $(evt.target).button("disable");
+                               var stemmaseq = $('#stemmaseq').val();
+                               var requrl = "[% c.uri_for( '/stemma' ) %]/" + selectedTextID + "/" + stemmaseq;
+                               var reqparam = { 'dot': $('#dot_field').val() };
+                               // TODO We need to stash the literal SVG string in stemmata
+                               // somehow. Implement accept header on server side to decide
+                               // whether to send application/json or application/xml?
+                               $.post( requrl, reqparam, function (data) {
+                                       // We received a stemma SVG string in return. 
+                                       // Update the current stemma sequence number
+                                       selectedStemmaID = data.stemmaid;
+                                       // Stash the answer in our SVG array
+                                       stemmata[selectedStemmaID] = data.stemmasvg;
+                                       // Display the new stemma
+                                       load_stemma( selectedStemmaID );
+                                       // Reenable the button and close the form
+                                       $(evt.target).button("enable");
+                                       $('#stemma-edit-dialog').dialog('close');
+                               }, 'json' );
+                       },
+                       Cancel: function() {
+                               $('#stemma-edit-dialog').dialog('close');
+                       }
+               },
+               open: function(evt) {
+                       $("#edit_stemma_status").empty();
+                       var stemmaseq = $('#stemmaseq').val();
+                       if( stemmaseq == 'n' ) {
+                               // If we are creating a new stemma, populate the textarea with a
+                               // bare digraph.
+                               $(evt.target).dialog('option', 'title', 'Add a new stemma')
+                               $('#dot_field').val( "digraph stemma {\n\n}" );
+                       } else {
+                               // If we are editing a stemma, grab its stemmadot and populate the
+                               // textarea with that.
+                               $(evt.target).dialog('option', 'title', 'Edit selected stemma')
+                               $('#dot_field').val( 'Loading, please wait...' );
+                               var doturl = "[% c.uri_for( '/stemmadot' ) %]/" + selectedTextID + "/" + stemmaseq;
+                               $.getJSON( doturl, function (data) {
+                                       // Re-insert the line breaks
+                                       var dotstring = data.dot.replace(/\|n/gm, "\n");                                        
+                                       $('#dot_field').val( dotstring );
+                               });
+                       }
+               },
+       }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
+               $(event.target).parent().find('.ui-button').button("enable");
+       if( ajaxSettings.url.indexOf( 'stemma' ) > -1 
+               && ajaxSettings.type == 'POST' ) {
+                       display_error( jqXHR, $("#edit_stemma_status") );
+       }
+       });
+               
+       $('#upload-collation-dialog').dialog({
+               autoOpen: false,
+               height: 325,
+               width: 480,
+               modal: true,
+               buttons: {
+                 pick: {
+                   text: "Pick File",
+                   id: "pick_uploadfile_button",
+                   click: function() {}       
+                 },
+                 upload: {
+                   text: 'Upload',
+                   id: 'upload_button',
+                   click: function() {
+                           $('#upload_status').empty();
+                uploader.start();
+                return false;
+            }
+                 },
+                 Cancel: function() {
+                   $('#upload-collation-dialog').dialog('close');
+                 }
+               },
+               attach_uploader: function() {
+                   create_uploader( "[% c.uri_for ( '/newtradition' ) %]" );
+                   $('#filelist').empty().html( 'Use the \'Pick\' button to choose a source file…' );
+               }
+       });
+       
+       $('#stemma_graph').mousedown( function(evt) {
+        evt.stopPropagation();
+        $('#stemma_graph').data( 'mousedown_xy', [evt.clientX, evt.clientY] );
+        $('body').mousemove( function(evt) {
+            mouse_scale = 1; // for now, was:  mouse_scale = svg_root_element.getScreenCTM().a;
+            dx = (evt.clientX - $('#stemma_graph').data( 'mousedown_xy' )[0]) / mouse_scale;
+            dy = (evt.clientY - $('#stemma_graph').data( 'mousedown_xy' )[1]) / mouse_scale;
+            $('#stemma_graph').data( 'mousedown_xy', [evt.clientX, evt.clientY] );
+            var svg_root = $('#stemma_graph svg').svg().svg('get').root();
+            var g = $('g.graph', svg_root).get(0);
+            current_translate = g.getAttribute( 'transform' ).split(/translate\(/)[1].split(')',1)[0].split(' ');
+            new_transform = g.getAttribute( 'transform' ).replace( /translate\([^\)]*\)/, 'translate(' + (parseFloat(current_translate[0]) + dx) + ' ' + (parseFloat(current_translate[1]) + dy) + ')' );
+            g.setAttribute( 'transform', new_transform );
+            evt.returnValue = false;
+            evt.preventDefault();
+            return false;
+        });
+        $('body').mouseup( function(evt) {
+            $('body').unbind('mousemove');
+            $('body').unbind('mouseup');
+        });
+       });
+        
+       $('#stemma_graph').mousewheel(function (event, delta) {
+        event.returnValue = false;
+        event.preventDefault();
+        if (!delta || delta == null || delta == 0) delta = event.originalEvent.wheelDelta;
+        if (!delta || delta == null || delta == 0) delta = -1 * event.originalEvent.detail;
+        if( delta < -9 ) { delta = -9 }; 
+        var z = 1 + delta/10;
+        z = delta > 0 ? 1 : -1;
+        var svg_root = $('#stemma_graph svg').svg().svg('get').root();
+        var g = $('g.graph', svg_root).get(0);
+        if (g && ((z<1 && (g.getScreenCTM().a * start_element_height) > 4.0) || (z>=1 && (g.getScreenCTM().a * start_element_height) < 1000))) {
+            var scaleLevel = z/10;
+            current_scale = parseFloat( g.getAttribute( 'transform' ).split(/scale\(/)[1].split(')',1)[0].split(' ')[0] );
+            new_transform = g.getAttribute( 'transform' ).replace( /scale\([^\)]*\)/, 'scale(' + (current_scale + scaleLevel) + ')' );
+            g.setAttribute( 'transform', new_transform );
+        }
+    });
+    
+});
+    </script>
+
+[% END %]
+
+    <div id="topbanner">
+      <h1>Stemmaweb - a collection of tools for analysis of collated texts</h1>
+      <span class="mainnav">[% IF c.user_exists %]Hello! [% c.user.get_object.email %] <a class="navlink" href="[% c.uri_for( '/logout' ) %]">Sign out</a> | [% ELSE %]<a class="navlink" onclick="window.open('[% c.uri_for( '/login' ) %]', 'loginwindow', 'height=385,width=445')">Login</a> | [% END %]<a class="navlink" href="[% c.uri_for( 'about.html' ) %]">About</a> </span>
+    </div>
+    <div id="directory_container">
+      <h2>Text directory</h2>
+      <div id="directory"></div>
+[% IF c.user_exists -%]
+         <div class="button" id="new_trad_button" onClick="start_upload_dialog();">
+           <span>Add a new text tradition</span>
+         </div>
+[% END %]
+    </div>
+    <div id="textinfo_waitbox">
+       <h3>Loading tradition information, please wait...</h3>
+       <img src="[% c.uri_for( 'images', 'ajax-loader.gif' ) %]" alt="Loading tradition info..." />
+    </div>
+    <div id="textinfo_container">
+      <div id="textinfo_load_status"></div>
+      <h2>Text <span class="texttitle"></span></h2>
+      <form id="open_textinfo_edit" action="" method="GET" name="edit_textinfo">
+        <div class="button" id="edit_textinfo_button"
+               onClick="$('#textinfo-edit-dialog').dialog('open')">
+         <span>Modify information about this tradition</span>
+        </div>
+      </form>
+      <ul>
+         <li>is owned by <span id="owner_id"></span></li>
+         <li>is <span id="not_public"></span>public</li>
+         <li>has <span id="marked_language"></span> as its primary language</li>
+             <li>has <span id="witness_num"></span> witnesses: <span id="witness_list"></span></li>
+      </ul>
+      
+      <div id="textinfo_container_buttons">
+          <form id="stemma_pager" action="" method="GET" name="stemma_pager">
+            <div id="stemma_pager_buttons">
+              <div class="pager_left_button" id="stemma_pager_left_button"></div>
+              <div class="pager_right_button" id="stemma_pager_right_button"></div>
+            </div>
+          </form>
+          <form id="open_stemma_add" action="" method="GET" name="add_new_stemma">
+            <div class="button" id="stemma_add_button" 
+               onClick="$('#stemmaseq').val('n'); $('#stemma-edit-dialog').dialog('open');">
+                 <span>Add a new stemma</span>
+            </div>
+          </form>
+          <form id="open_stemma_edit" action="" method="GET" name="edit_current_stemma">
+            <div class="button" id="stemma_edit_button" 
+               onClick="$('#stemmaseq').val(selectedStemmaID); $('#stemma-edit-dialog').dialog('open');">
+                 <span>Edit this stemma</span>
+            </div>
+          </form>
+          <form id="run_stexaminer" action="" method="GET" name="run_stexaminer">
+            <div class="button" id="stexaminer_button" onClick="$('#run_stexaminer').submit()">
+                 <span>Examine variants against this stemma</span>
+            </div>
+          </form>
+          <form id="run_relater" action="" method="GET" name="run_relater">
+            <div class="button" id="relater_button" onClick="$('#run_relater').submit()">
+              <span>Run relationship mapper</span>
+            </div>
+          </form>
+      </div>
+      <div id="stemma_graph"></div>
+    </div>
+
+    <!-- Interim 'loading' message for directory box -->
+    <div id="loading_message">
+       <h3>Loading texts, please wait...</h3>
+       <img src="[% c.uri_for( 'images', 'ajax-loader.gif' ) %]" alt="Loading tradition list..."/>
+    </div>
+    
+    <!-- Textinfo editor dialog -->
+    <div id="textinfo-edit-dialog" title="Edit information about this tradition">
+      <div id="textinfo_edit_container">
+       <form id="edit_textinfo">
+               <label for="edit_name">Tradition name: </label>
+               <input id="edit_name" type="text" size="30" name="name"/><br/>
+               <label for="edit_language">Language: </label>
+               <input id="edit_language" type="text" size="12" name="language"/>
+               <label for="edit_public">Publicly viewable: </label>
+               <input id="edit_public" type="checkbox" name="public"/><br/>
+[% IF c.user_exists -%]
+[% IF c.user.get_object.is_admin -%]
+               <label for="edit_owner">Tradition owner: </label>
+               <input id="edit_owner" type="text" size="30" name="owner"/><br/>
+[% END -%]
+[% END -%]
+               </form>
+               <div id="edit_textinfo_status"></div>
+         </div>
+    </div>
+    
+    <!-- Stemma dot editor dialog, simple textarea for now -->
+    <div id="stemma-edit-dialog">
+      <div id="stemma_edit_container">
+       <form id="edit_stemma">
+               <label for="dot_field">Dot definition for this stemma: </label><br/>
+               <textarea id="dot_field" rows="30" cols="40"></textarea>
+               <input id="stemmaseq" type="hidden" name="stemmaseq" val="n"/>
+                       <div id="edit_instructions">
+                               <p>All definitions begin with the line
+                                       <pre>digraph stemma {</pre>
+                               and end with the line 
+                                       <pre>}</pre>Please do not change these lines.</p>
+                               <p>First list each witness in your stemma, whether extant or lost /
+                               reconstructed / hypothetical, and assign them a class of either "extant"
+                               or "hypothetical". For example:</p><pre>  
+       α [ class=hypothetical ]
+       C [ class=extant ]
+                               </pre>
+                               <p>Next, list the direct links between witnesses, one per line. For example, if 
+                               witness C descends directly from witness α, note it as follows:</p><pre>
+       α -> C
+                               </pre>
+                               <p>A witness may be the exemplar for any number of other witnesses, whether 
+                               extant or not; likewise, a witness may inherit from any number of other 
+                               witnesses. Use as may "A -> B" pairings as necessary to describe the links.</p>
+                       </div>
+       </form>
+       <div id="edit_stemma_status"></div>
+      </div>
+    </div>
+
+    <!-- File upload dialog box -->
+    <div id="upload-collation-dialog" title="Upload a collation">
+      <div id="upload_container">
+        <form id="new_tradition">
+            <label for="new_name">Name of this text / tradition: </label>
+            <input id="new_name" type="text" name="name" size="40"/><br/>
+            <label for="new_lang">Primary language of the text: </label>
+            <input id="new_lang" type="text" name="language" size="20"/><br/>
+            <label for="new_public">Allow public display: </label>
+            <input id="new_public" name="public" type="checkbox"/><br/>
+            <div id="filelist"></div>
+        <form>
+        <div id="upload_status"></div>
+       <div>
+         <h4>Supported file types / extensions:</h4>
+         <ul>
+           <li>*.txt - spreadsheet collation, tab-separated values</li>
+           <li>*.csv - spreadsheet collation, comma-separated values</li>
+           <li>*.xls - spreadsheet collation, Excel 97-2004 format</li>
+           <li>*.xlsx - spreadsheet collation, Excel 2007 XML format</li>
+           <li>*.xml - TEI XML parallel segmentation format</li>
+           <li>*.xml - TEI XML export from Classical Text Editor</li>
+           <li>*.xml - GraphML export from the CollateX tool</li>
+         </ul>
+         <p>All spreadsheet collations should be arranged with the witness sigla in the first row, and the words aligned by row each in its correct witness column.</p>
+       </div>
+      </div>
+    </div>    
+[% PROCESS footer.tt %]
\ No newline at end of file