$tradition->name( $newname );
$changed = 1;
} catch {
- return _json_error( $c, 500, "Error setting name to $newname" );
+ return _json_error( $c, 500, "Error setting name to $newname: $@" );
}
}
}
$tradition->language( $langval );
$changed = 1;
} catch {
- return _json_error( $c, 500, "Error setting language to $langval" );
+ return _json_error( $c, 500, "Error setting language to $langval: $@" );
}
}
owner => $tradition->user ? $tradition->user->email : undef,
witnesses => [ map { $_->sigil } $tradition->witnesses ],
};
+ ## TODO Make these into callbacks in the other controllers maybe?
if( $tradition->can('language') ) {
$textinfo->{'language'} = $tradition->language;
}
if( $tradition->can('stemweb_jobid') ) {
$textinfo->{'stemweb_jobid'} = $tradition->stemweb_jobid || 0;
}
- my @stemmasvg = map { {
- name => $_->identifier,
- directed => _json_bool( !$_->is_undirected ),
- svg => $_->as_svg() } }
- $tradition->stemmata;
- map { $_ =~ s/\n/ /mg } @stemmasvg;
+ my @stemmasvg = map { _stemma_info( $_ ) } $tradition->stemmata;
$textinfo->{stemmata} = \@stemmasvg;
$c->stash->{'result'} = $textinfo;
$c->forward('View::JSON');
$c->stash->{'result'} = $collation->as_svg;
$c->forward('View::SVG');
}
+
+sub _stemma_info {
+ my( $stemma, $sid ) = @_;
+ my $ssvg = $stemma->as_svg();
+ $ssvg =~ s/\n/ /mg;
+ my $sinfo = {
+ name => $stemma->identifier,
+ directed => _json_bool( !$stemma->is_undirected ),
+ svg => $ssvg };
+ if( $sid ) {
+ $sinfo->{stemmaid} = $sid;
+ }
+ return $sinfo;
+}
+
+## TODO Separate stemma manipulation functionality into its own controller.
=head2 stemma
if( !$stemma && $tradition->stemma_count > $stemmaid ) {
$stemma = $tradition->stemma( $stemmaid );
}
- my $stemma_xml = $stemma ? $stemma->as_svg() : '';
# What was requested, XML or JSON?
my $return_view = 'SVG';
if( my $accept_header = $c->req->header('Accept') ) {
}
}
if( $return_view eq 'SVG' ) {
- $c->stash->{'result'} = $stemma_xml;
+ $c->stash->{'result'} = $stemma->as_svg();
$c->forward('View::SVG');
} else { # JSON
- $stemma_xml =~ s/\n/ /mg;
- $c->stash->{'result'} = {
- 'stemmaid' => $stemmaid,
- 'name' => $stemma->identifier,
- 'directed' => _json_bool( !$stemma->is_undirected ),
- 'svg' => $stemma_xml };
+ $c->stash->{'result'} = { _stemma_info( $stemma, $stemmaid ) };
$c->forward('View::JSON');
}
}
$c->forward('View::JSON');
}
+=head2 stemmaroot
+
+ POST /stemmaroot/$textid/$stemmaseq, { root: <root node ID> }
+
+Orients the given stemma so that the given node is the root (archetype). Returns the
+information structure for the new stemma.
+
+=cut
+
+sub stemmaroot :Local :Args(2) {
+ my( $self, $c, $textid, $stemmaid ) = @_;
+ my $m = $c->model('Directory');
+ my $tradition = $m->tradition( $textid );
+ unless( $tradition ) {
+ return _json_error( $c, 404, "No tradition with ID $textid" );
+ }
+ my $ok = _check_permission( $c, $tradition );
+ if( $ok eq 'full' ) {
+ my $stemma = $tradition->stemma( $stemmaid );
+ try {
+ $stemma->root_graph( $c->req->param('root') );
+ $m->save( $tradition );
+ } catch( Text::Tradition::Error $e ) {
+ return _json_error( $c, 400, $e->message );
+ } catch {
+ return _json_error( $c, 500, "Error re-rooting stemma: $@" );
+ }
+ $c->stash->{'result'} = _stemma_info( $stemma );
+ $c->forward('View::JSON');
+ } else {
+ return _json_error( $c, 403,
+ 'You do not have permission to update stemmata for this tradition' );
+ }
+}
+
=head2 download
GET /download/$textid
// Global state variables
var selectedTextID;
var selectedTextInfo;
+var selectedTextEditable;
var selectedStemmaID = -1;
var stemmata = [];
// view pane. Calls load_textinfo.
function loadTradition( textid, textname, editable ) {
selectedTextID = textid;
+ selectedTextEditable = editable;
// First insert the placeholder image and register an error handler
$('#textinfo_load_status').empty();
$('#stemma_graph').empty();
} else {
selectedStemmaID = -1;
}
- load_stemma( selectedStemmaID, editable );
+ load_stemma( selectedStemmaID );
// Set up the relationship mapper button
$('#run_relater').attr( 'action', _get_url([ "relation", textid ]) );
// Set up the download button
}
// Enable / disable the appropriate buttons for paging through the stemma.
-function show_stemmapager ( editable ) {
+function show_stemmapager () {
$('.pager_left_button').unbind('click').addClass( 'greyed_out' );
$('.pager_right_button').unbind('click').addClass( 'greyed_out' );
if( selectedStemmaID > 0 ) {
$('.pager_left_button').click( function () {
- load_stemma( selectedStemmaID - 1, editable );
+ load_stemma( selectedStemmaID - 1, selectedTextEditable );
}).removeClass( 'greyed_out' );
}
if( selectedStemmaID + 1 < stemmata.length ) {
$('.pager_right_button').click( function () {
- load_stemma( selectedStemmaID + 1, editable );
+ load_stemma( selectedStemmaID + 1, selectedTextEditable );
}).removeClass( 'greyed_out' );
}
}
// Load a given stemma SVG into the stemmagraph box.
-function load_stemma( idx, editable ) {
+function load_stemma( idx ) {
// Load the stemma at idx
selectedStemmaID = idx;
- show_stemmapager( editable );
+ show_stemmapager( selectedTextEditable );
$('#open_stemma_edit').hide();
$('#run_stexaminer').hide();
$('#stemma_identifier').empty();
// Add the relevant Stemweb functionality
- if( editable ) {
+ if( selectedTextEditable ) {
if( selectedTextInfo.stemweb_jobid == 0 ) {
$('#open_stemweb_ui').show();
$('#query_stemweb_ui').hide();
if( idx > -1 ) {
// Load the stemma and its properties
var stemmadata = stemmata[idx];
- if( editable ) {
+ if( selectedTextEditable ) {
$('#open_stemma_edit').show();
}
if( stemmadata.directed ) {
}
function set_stemma_interactive( svg_element ) {
- $( "#root_tree_dialog_button_ok" ).click( function() {
- // AJAX call goes here
- } );
- $.each( $( 'ellipse', svg_element ), function(index) {
- var ellipse = $(this);
- var g = ellipse.parent( 'g' );
- g.click( function(evt) {
- if( typeof root_tree_dialog_timeout !== 'undefined' ) { clearTimeout( root_tree_dialog_timeout ) };
- g.unbind( 'mouseleave' );
- var dialog = $( '#root_tree_dialog' );
- dialog.hide();
- dialog.css( 'top', evt.pageY + 3 );
- dialog.css( 'left', evt.pageX + 3 );
- dialog.show();
- root_tree_dialog_timeout = setTimeout( function() {
- $( '#root_tree_dialog' ).hide();
- ellipse.removeClass( 'stemma_node_highlight' );
- g.mouseleave( function() { ellipse.removeClass( 'stemma_node_highlight' ) } );
- }, 3000 );
- } );
- g.mouseenter( function() {
- $( 'ellipse.stemma_node_highlight' ).removeClass( 'stemma_node_highlight' );
- ellipse.addClass( 'stemma_node_highlight' )
- } );
- g.mouseleave( function() { ellipse.removeClass( 'stemma_node_highlight' ) } );
- } );
+ if( selectedTextEditable ) {
+ $( "#root_tree_dialog_button_ok" ).click( function() {
+ var requrl = _get_url([ "stemmaroot", selectedTextID, selectedStemmaID ]);
+ var targetnode = $('ellipse.stemma_node_highlight').parent().attr('id');
+ $.post( requrl, { root: targetnode }, function (data) {
+ // Reload the new stemma
+ stemmata[selectedStemmaID] = data;
+ load_stemma( selectedStemmaID );
+ // Put away the dialog
+ $('#root_tree_dialog').hide();
+ } );
+ } ).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) {
+ if( ajaxSettings.url.indexOf( 'stemmaroot' ) > -1
+ && ajaxSettings.type == 'POST' ) {
+ display_error( jqXHR, $("#stemma_load_status") );
+ }
+ } );
+ // TODO Clear error at some appropriate point
+ $.each( $( 'ellipse', svg_element ), function(index) {
+ var ellipse = $(this);
+ var g = ellipse.parent( 'g' );
+ g.click( function(evt) {
+ if( typeof root_tree_dialog_timeout !== 'undefined' ) { clearTimeout( root_tree_dialog_timeout ) };
+ g.unbind( 'mouseleave' );
+ var dialog = $( '#root_tree_dialog' );
+ dialog.hide();
+ dialog.css( 'top', evt.pageY + 3 );
+ dialog.css( 'left', evt.pageX + 3 );
+ dialog.show();
+ root_tree_dialog_timeout = setTimeout( function() {
+ $( '#root_tree_dialog' ).hide();
+ ellipse.removeClass( 'stemma_node_highlight' );
+ g.mouseleave( function() { ellipse.removeClass( 'stemma_node_highlight' ) } );
+ }, 3000 );
+ } );
+ g.mouseenter( function() {
+ $( 'ellipse.stemma_node_highlight' ).removeClass( 'stemma_node_highlight' );
+ ellipse.addClass( 'stemma_node_highlight' )
+ } );
+ g.mouseleave( function() { ellipse.removeClass( 'stemma_node_highlight' ) } );
+ } );
+ }
}
// General-purpose error-handling function.
return basepath + els.join('/');
}
-
+// TODO Attach unified ajaxError handler to document
$(document).ready( function() {
// See if we have the browser functionality we need
// TODO Also think of a test for SVG readiness