Commit | Line | Data |
76f05423 |
1 | var MARGIN=30; |
2 | var svg_root = null; |
3 | var svg_root_element = null; |
4 | var start_element_height = 0; |
5 | var reltypes = {}; |
5f15640c |
6 | var readingdata = {}; |
76f05423 |
7 | |
a84ca4de |
8 | function arrayUnique(array) { |
9 | var a = array.concat(); |
10 | for(var i=0; i<a.length; ++i) { |
11 | for(var j=i+1; j<a.length; ++j) { |
12 | if(a[i] === a[j]) |
13 | a.splice(j--, 1); |
14 | } |
15 | } |
16 | return a; |
17 | }; |
18 | |
5f15640c |
19 | function getTextURL( which ) { |
3f9d7ae5 |
20 | return basepath + textid + '/' + which; |
5f15640c |
21 | } |
22 | |
23 | function getReadingURL( reading_id ) { |
3f9d7ae5 |
24 | return basepath + textid + '/reading/' + reading_id; |
b28e606e |
25 | } |
26 | |
45ee3b96 |
27 | // Make an XML ID into a valid selector |
28 | function jq(myid) { |
29 | return '#' + myid.replace(/(:|\.)/g,'\\$1'); |
30 | } |
31 | |
065c7cf2 |
32 | // Actions for opening the reading panel |
33 | function node_dblclick_listener( evt ) { |
34 | // Open the reading dialogue for the given node. |
35 | // First get the reading info |
36 | var reading_id = $(this).attr('id'); |
37 | var reading_info = readingdata[reading_id]; |
38 | // and then populate the dialog box with it. |
39 | // Set the easy properties first |
40 | $('#reading-form').dialog( 'option', 'title', 'Reading information for "' + reading_info['text'] + '"' ); |
41 | $('#reading_id').val( reading_id ); |
798fa939 |
42 | toggle_checkbox( $('#reading_is_nonsense'), reading_info['is_nonsense'] ); |
43 | toggle_checkbox( $('#reading_grammar_invalid'), reading_info['grammar_invalid'] ); |
065c7cf2 |
44 | // Use .text as a backup for .normal_form |
45 | var normal_form = reading_info['normal_form']; |
46 | if( !normal_form ) { |
47 | normal_form = reading_info['text']; |
48 | } |
49 | var nfboxsize = 10; |
50 | if( normal_form.length > 9 ) { |
51 | nfboxsize = normal_form.length + 1; |
52 | } |
53 | $('#reading_normal_form').attr( 'size', nfboxsize ) |
54 | $('#reading_normal_form').val( normal_form ); |
5539cba3 |
55 | if( editable ) { |
56 | // Fill in the witnesses for the de-collation box. |
57 | $('#reading_decollate_witnesses').empty(); |
58 | $.each( reading_info['witnesses'], function( idx, wit ) { |
59 | $('#reading_decollate_witnesses').append( $('<option/>').attr( |
60 | 'value', wit ).text( wit ) ); |
61 | }); |
62 | } |
065c7cf2 |
63 | // Now do the morphological properties. |
0dcdd5ec |
64 | morphology_form( reading_info['lexemes'] ); |
065c7cf2 |
65 | // and then open the dialog. |
0dcdd5ec |
66 | $('#reading-form').dialog("open"); |
67 | } |
68 | |
798fa939 |
69 | function toggle_checkbox( box, value ) { |
70 | if( value == null ) { |
71 | value = false; |
72 | } |
73 | box.attr('checked', value ); |
74 | } |
75 | |
0dcdd5ec |
76 | function morphology_form ( lexlist ) { |
487674b9 |
77 | if( lexlist.length ) { |
78 | $('#morph_outer').show(); |
79 | $('#morphology').empty(); |
80 | $.each( lexlist, function( idx, lex ) { |
81 | var morphoptions = []; |
82 | if( 'wordform_matchlist' in lex ) { |
83 | $.each( lex['wordform_matchlist'], function( tdx, tag ) { |
84 | var tagstr = stringify_wordform( tag ); |
85 | morphoptions.push( tagstr ); |
86 | }); |
87 | } |
88 | var formtag = 'morphology_' + idx; |
89 | var formstr = ''; |
90 | if( 'form' in lex ) { |
91 | formstr = stringify_wordform( lex['form'] ); |
92 | } |
93 | var form_morph_elements = morph_elements( |
94 | formtag, lex['string'], formstr, morphoptions ); |
95 | $.each( form_morph_elements, function( idx, el ) { |
96 | $('#morphology').append( el ); |
08f8443a |
97 | }); |
065c7cf2 |
98 | }); |
487674b9 |
99 | } else { |
100 | $('#morph_outer').hide(); |
101 | } |
065c7cf2 |
102 | } |
103 | |
104 | function stringify_wordform ( tag ) { |
08f8443a |
105 | if( tag ) { |
106 | var elements = tag.split(' // '); |
107 | return elements[1] + ' // ' + elements[2]; |
108 | } |
109 | return '' |
065c7cf2 |
110 | } |
111 | |
d1132306 |
112 | function morph_elements ( formtag, formtxt, currform, morphoptions ) { |
113 | var clicktag = '(Click to select)'; |
114 | if ( !currform ) { |
115 | currform = clicktag; |
116 | } |
065c7cf2 |
117 | var formlabel = $('<label/>').attr( 'id', 'label_' + formtag ).attr( |
d1132306 |
118 | 'for', 'reading_' + formtag ).text( formtxt + ': ' ); |
065c7cf2 |
119 | var forminput = $('<input/>').attr( 'id', 'reading_' + formtag ).attr( |
0dcdd5ec |
120 | 'name', 'reading_' + formtag ).attr( 'size', '50' ).attr( |
121 | 'class', 'reading_morphology' ).val( currform ); |
d1132306 |
122 | forminput.autocomplete({ source: morphoptions, minLength: 0 }); |
123 | forminput.focus( function() { |
124 | if( $(this).val() == clicktag ) { |
125 | $(this).val(''); |
126 | } |
127 | $(this).autocomplete('search', '') |
128 | }); |
065c7cf2 |
129 | var morphel = [ formlabel, forminput, $('<br/>') ]; |
130 | return morphel; |
131 | } |
132 | |
4c41c02c |
133 | function color_inactive ( el ) { |
134 | var reading_id = $(el).parent().attr('id'); |
135 | var reading_info = readingdata[reading_id]; |
136 | // If the reading info has any non-disambiguated lexemes, color it yellow; |
137 | // otherwise color it green. |
138 | $(el).attr( {stroke:'green', fill:'#b3f36d'} ); |
bb3230b1 |
139 | if( reading_info ) { |
140 | $.each( reading_info['lexemes'], function ( idx, lex ) { |
141 | if( !lex['is_disambiguated'] || lex['is_disambiguated'] == 0 ) { |
142 | $(el).attr( {stroke:'orange', fill:'#fee233'} ); |
143 | } |
144 | }); |
145 | } |
4c41c02c |
146 | } |
147 | |
997ebe92 |
148 | function relemmatize () { |
149 | // Send the reading for a new lemmatization and reopen the form. |
a0a66634 |
150 | $('#relemmatize_pending').show(); |
997ebe92 |
151 | var reading_id = $('#reading_id').val() |
152 | ncpath = getReadingURL( reading_id ); |
153 | form_values = { |
154 | 'normal_form': $('#reading_normal_form').val(), |
155 | 'relemmatize': 1 }; |
156 | var jqjson = $.post( ncpath, form_values, function( data ) { |
157 | // Update the form with the return |
158 | if( 'id' in data ) { |
159 | // We got back a good answer. Stash it |
160 | readingdata[reading_id] = data; |
161 | // and regenerate the morphology form. |
162 | morphology_form( data['lexemes'] ); |
163 | } else { |
164 | alert("Could not relemmatize as requested: " + data['error']); |
165 | } |
a0a66634 |
166 | $('#relemmatize_pending').hide(); |
997ebe92 |
167 | }); |
168 | } |
169 | |
065c7cf2 |
170 | // Initialize the SVG once it exists |
b28e606e |
171 | function svgEnlargementLoaded() { |
fc018906 |
172 | //Give some visual evidence that we are working |
173 | $('#loading_overlay').show(); |
174 | lo_height = $("#enlargement_container").outerHeight(); |
175 | lo_width = $("#enlargement_container").outerWidth(); |
176 | $("#loading_overlay").height( lo_height ); |
177 | $("#loading_overlay").width( lo_width ); |
178 | $("#loading_overlay").offset( $("#enlargement_container").offset() ); |
179 | $("#loading_message").offset( |
180 | { 'top': lo_height / 2 - $("#loading_message").height() / 2, |
181 | 'left': lo_width / 2 - $("#loading_message").width() / 2 }); |
30d0ba1e |
182 | if( editable ) { |
183 | // Show the update toggle button. |
184 | $('#update_workspace_button').data('locked', false); |
185 | $('#update_workspace_button').css('background-position', '0px 44px'); |
186 | } |
065c7cf2 |
187 | $('#svgenlargement ellipse').parent().dblclick( node_dblclick_listener ); |
9529f69c |
188 | var graph_svg = $('#svgenlargement svg'); |
189 | var svg_g = $('#svgenlargement svg g')[0]; |
76f05423 |
190 | if (!svg_g) return; |
9529f69c |
191 | svg_root = graph_svg.svg().svg('get').root(); |
76f05423 |
192 | |
193 | // Find the real root and ignore any text nodes |
194 | for (i = 0; i < svg_root.childNodes.length; ++i) { |
195 | if (svg_root.childNodes[i].nodeName != '#text') { |
196 | svg_root_element = svg_root.childNodes[i]; |
197 | break; |
198 | } |
199 | } |
200 | |
30d0ba1e |
201 | //Set viewbox width and height to width and height of $('#svgenlargement svg'). |
202 | //This is essential to make sure zooming and panning works properly. |
9529f69c |
203 | svg_root.viewBox.baseVal.width = graph_svg.attr( 'width' ); |
204 | svg_root.viewBox.baseVal.height = graph_svg.attr( 'height' ); |
205 | //Now set scale and translate so svg height is about 150px and vertically centered in viewbox. |
206 | //This is just to create a nice starting enlargement. |
207 | var initial_svg_height = 250; |
208 | var scale = initial_svg_height/graph_svg.attr( 'height' ); |
209 | var additional_translate = (graph_svg.attr( 'height' ) - initial_svg_height)/(2*scale); |
210 | var transform = svg_g.getAttribute('transform'); |
211 | var translate = parseFloat( transform.match( /translate\([^\)]*\)/ )[0].split('(')[1].split(' ')[1].split(')')[0] ); |
212 | translate += additional_translate; |
213 | var transform = 'rotate(0) scale(' + scale + ') translate(4 ' + translate + ')'; |
214 | svg_g.setAttribute('transform', transform); |
215 | //used to calculate min and max zoom level: |
4c41c02c |
216 | start_element_height = $('#__START__').children('ellipse')[0].getBBox().height; |
e538eccb |
217 | //some use of call backs to ensure succesive execution |
218 | add_relations( function() { |
219 | var rdgpath = getTextURL( 'readings' ); |
220 | $.getJSON( rdgpath, function( data ) { |
221 | readingdata = data; |
222 | $('#svgenlargement ellipse').each( function( i, el ) { color_inactive( el ) }); |
223 | }); |
224 | $('#loading_overlay').hide(); |
225 | }); |
c1add777 |
226 | |
227 | //initialize marquee |
228 | marquee = new Marquee(); |
229 | |
6afcd813 |
230 | } |
231 | |
fc018906 |
232 | function add_relations( callback_fn ) { |
56e3972e |
233 | // Add the relationship types to the keymap list |
56e3972e |
234 | $.each( relationship_types, function(index, typedef) { |
671c04b1 |
235 | li_elm = $('<li class="key">').css( "border-color", |
236 | relation_manager.relation_colors[index] ).text(typedef.name); |
237 | li_elm.append( $('<div>').attr('class', 'key_tip_container').append( |
238 | $('<div>').attr('class', 'key_tip').text(typedef.description) ) ); |
cfefd283 |
239 | $('#keymaplist').append( li_elm ); |
56e3972e |
240 | }); |
241 | // Now fetch the relationships themselves and add them to the graph |
242 | var rel_types = $.map( relationship_types, function(t) { return t.name }); |
243 | // Save this list of names to the outer element data so that the relationship |
244 | // factory can access it |
245 | $('#keymap').data('relations', rel_types); |
5f15640c |
246 | var textrelpath = getTextURL( 'relationships' ); |
56e3972e |
247 | $.getJSON( textrelpath, function(data) { |
248 | $.each(data, function( index, rel_info ) { |
249 | var type_index = $.inArray(rel_info.type, rel_types); |
250 | var source_found = get_ellipse( rel_info.source ); |
251 | var target_found = get_ellipse( rel_info.target ); |
252 | if( type_index != -1 && source_found.size() && target_found.size() ) { |
253 | var relation = relation_manager.create( rel_info.source, rel_info.target, type_index ); |
254 | relation.data( 'type', rel_info.type ); |
255 | relation.data( 'scope', rel_info.scope ); |
256 | relation.data( 'note', rel_info.note ); |
30d0ba1e |
257 | if( editable ) { |
258 | var node_obj = get_node_obj(rel_info.source); |
e538eccb |
259 | node_obj.set_selectable( false ); |
30d0ba1e |
260 | node_obj.ellipse.data( 'node_obj', null ); |
261 | node_obj = get_node_obj(rel_info.target); |
e538eccb |
262 | node_obj.set_selectable( false ); |
30d0ba1e |
263 | node_obj.ellipse.data( 'node_obj', null ); |
264 | } |
56e3972e |
265 | } |
266 | }); |
267 | callback_fn.call(); |
268 | }); |
b28e606e |
269 | } |
270 | |
271 | function get_ellipse( node_id ) { |
45ee3b96 |
272 | return $( jq( node_id ) + ' ellipse'); |
b28e606e |
273 | } |
274 | |
275 | function get_node_obj( node_id ) { |
9529f69c |
276 | var node_ellipse = get_ellipse( node_id ); |
277 | if( node_ellipse.data( 'node_obj' ) == null ) { |
278 | node_ellipse.data( 'node_obj', new node_obj(node_ellipse) ); |
279 | }; |
280 | return node_ellipse.data( 'node_obj' ); |
b28e606e |
281 | } |
282 | |
b28e606e |
283 | function node_obj(ellipse) { |
284 | this.ellipse = ellipse; |
285 | var self = this; |
286 | |
287 | this.x = 0; |
288 | this.y = 0; |
289 | this.dx = 0; |
290 | this.dy = 0; |
291 | this.node_elements = node_elements_for(self.ellipse); |
292 | |
293 | this.get_id = function() { |
45ee3b96 |
294 | return $(self.ellipse).parent().attr('id') |
b28e606e |
295 | } |
296 | |
e538eccb |
297 | this.set_selectable = function( clickable ) { |
298 | if( clickable && editable ) { |
299 | $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); |
300 | $(self.ellipse).parent().hover( this.enter_node, this.leave_node ); |
301 | $(self.ellipse).parent().mousedown( function(evt) { evt.stopPropagation() } ); |
302 | $(self.ellipse).parent().click( function(evt) { |
303 | evt.stopPropagation(); |
304 | if( $('ellipse[fill="#9999ff"]').size() > 0 ) { |
305 | $('ellipse[fill="#9999ff"]').each( function() { |
306 | $(this).data( 'node_obj' ).set_draggable( false ); |
307 | } ); |
308 | } |
309 | self.set_draggable( true ) |
310 | }); |
311 | } else { |
312 | $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); |
313 | self.ellipse.siblings('text').attr('class', ''); |
314 | $(self.ellipse).parent().unbind(); |
315 | $('body').unbind('mousemove'); |
316 | $('body').unbind('mouseup'); |
317 | } |
318 | } |
319 | |
b28e606e |
320 | this.set_draggable = function( draggable ) { |
30d0ba1e |
321 | if( draggable && editable ) { |
e538eccb |
322 | $(self.ellipse).attr( {stroke:'black', fill:'#9999ff'} ); |
05485bfd |
323 | $(self.ellipse).parent().mousedown( this.mousedown_listener ); |
e538eccb |
324 | $(self.ellipse).parent().unbind( 'mouseenter' ).unbind( 'mouseleave' ); |
05485bfd |
325 | self.ellipse.siblings('text').attr('class', 'noselect draggable'); |
b28e606e |
326 | } else { |
e538eccb |
327 | $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); |
05485bfd |
328 | self.ellipse.siblings('text').attr('class', ''); |
e538eccb |
329 | $(self.ellipse).parent().unbind( 'mousedown '); |
330 | $(self.ellipse).parent().mousedown( function(evt) { evt.stopPropagation() } ); |
331 | $(self.ellipse).parent().hover( this.enter_node, this.leave_node ); |
b28e606e |
332 | } |
333 | } |
334 | |
335 | this.mousedown_listener = function(evt) { |
336 | evt.stopPropagation(); |
337 | self.x = evt.clientX; |
338 | self.y = evt.clientY; |
339 | $('body').mousemove( self.mousemove_listener ); |
340 | $('body').mouseup( self.mouseup_listener ); |
05485bfd |
341 | $(self.ellipse).parent().unbind('mouseenter').unbind('mouseleave') |
e538eccb |
342 | self.ellipse.attr( 'fill', '#6b6bb2' ); |
b28e606e |
343 | first_node_g_element = $("#svgenlargement g .node" ).filter( ":first" ); |
344 | if( first_node_g_element.attr('id') !== self.get_g().attr('id') ) { self.get_g().insertBefore( first_node_g_element ) }; |
345 | } |
346 | |
347 | this.mousemove_listener = function(evt) { |
9529f69c |
348 | self.dx = (evt.clientX - self.x) / mouse_scale; |
349 | self.dy = (evt.clientY - self.y) / mouse_scale; |
b28e606e |
350 | self.move_elements(); |
05485bfd |
351 | evt.returnValue = false; |
352 | evt.preventDefault(); |
353 | return false; |
b28e606e |
354 | } |
355 | |
356 | this.mouseup_listener = function(evt) { |
357 | if( $('ellipse[fill="#ffccff"]').size() > 0 ) { |
45ee3b96 |
358 | var source_node_id = $(self.ellipse).parent().attr('id'); |
05485bfd |
359 | var source_node_text = self.ellipse.siblings('text').text(); |
45ee3b96 |
360 | var target_node_id = $('ellipse[fill="#ffccff"]').parent().attr('id'); |
05485bfd |
361 | var target_node_text = $('ellipse[fill="#ffccff"]').siblings("text").text(); |
b28e606e |
362 | $('#source_node_id').val( source_node_id ); |
05485bfd |
363 | $('#source_node_text').val( source_node_text ); |
b28e606e |
364 | $('#target_node_id').val( target_node_id ); |
05485bfd |
365 | $('#target_node_text').val( target_node_text ); |
b28e606e |
366 | $('#dialog-form').dialog( 'open' ); |
367 | }; |
368 | $('body').unbind('mousemove'); |
369 | $('body').unbind('mouseup'); |
e538eccb |
370 | self.ellipse.attr( 'fill', '#9999ff' ); |
9529f69c |
371 | self.reset_elements(); |
b28e606e |
372 | } |
f2fb96fc |
373 | |
b28e606e |
374 | this.cpos = function() { |
375 | return { x: self.ellipse.attr('cx'), y: self.ellipse.attr('cy') }; |
376 | } |
377 | |
378 | this.get_g = function() { |
379 | return self.ellipse.parent('g'); |
380 | } |
381 | |
382 | this.enter_node = function(evt) { |
383 | self.ellipse.attr( 'fill', '#ffccff' ); |
384 | } |
385 | |
386 | this.leave_node = function(evt) { |
387 | self.ellipse.attr( 'fill', '#fff' ); |
388 | } |
389 | |
390 | this.greyout_edges = function() { |
391 | $.each( self.node_elements, function(index, value) { |
392 | value.grey_out('.edge'); |
393 | }); |
394 | } |
395 | |
396 | this.ungreyout_edges = function() { |
397 | $.each( self.node_elements, function(index, value) { |
398 | value.un_grey_out('.edge'); |
399 | }); |
400 | } |
401 | |
402 | this.move_elements = function() { |
403 | $.each( self.node_elements, function(index, value) { |
404 | value.move(self.dx,self.dy); |
405 | }); |
406 | } |
407 | |
408 | this.reset_elements = function() { |
409 | $.each( self.node_elements, function(index, value) { |
410 | value.reset(); |
411 | }); |
412 | } |
413 | |
414 | this.update_elements = function() { |
415 | self.node_elements = node_elements_for(self.ellipse); |
416 | } |
417 | |
a84ca4de |
418 | this.get_witnesses = function() { |
419 | return readingdata[self.get_id()].witnesses |
420 | } |
421 | |
e538eccb |
422 | self.set_selectable( true ); |
b28e606e |
423 | } |
424 | |
425 | function svgshape( shape_element ) { |
426 | this.shape = shape_element; |
427 | this.move = function(dx,dy) { |
428 | this.shape.attr( "transform", "translate(" + dx + " " + dy + ")" ); |
429 | } |
430 | this.reset = function() { |
431 | this.shape.attr( "transform", "translate( 0, 0 )" ); |
432 | } |
433 | this.grey_out = function(filter) { |
434 | if( this.shape.parent(filter).size() != 0 ) { |
435 | this.shape.attr({'stroke':'#e5e5e5', 'fill':'#e5e5e5'}); |
436 | } |
437 | } |
438 | this.un_grey_out = function(filter) { |
439 | if( this.shape.parent(filter).size() != 0 ) { |
440 | this.shape.attr({'stroke':'#000000', 'fill':'#000000'}); |
441 | } |
442 | } |
443 | } |
444 | |
445 | function svgpath( path_element, svg_element ) { |
446 | this.svg_element = svg_element; |
447 | this.path = path_element; |
448 | this.x = this.path.x; |
449 | this.y = this.path.y; |
450 | this.move = function(dx,dy) { |
451 | this.path.x = this.x + dx; |
452 | this.path.y = this.y + dy; |
453 | } |
454 | this.reset = function() { |
455 | this.path.x = this.x; |
456 | this.path.y = this.y; |
457 | } |
458 | this.grey_out = function(filter) { |
459 | if( this.svg_element.parent(filter).size() != 0 ) { |
460 | this.svg_element.attr('stroke', '#e5e5e5'); |
461 | this.svg_element.siblings('text').attr('fill', '#e5e5e5'); |
05485bfd |
462 | this.svg_element.siblings('text').attr('class', 'noselect'); |
b28e606e |
463 | } |
464 | } |
465 | this.un_grey_out = function(filter) { |
466 | if( this.svg_element.parent(filter).size() != 0 ) { |
467 | this.svg_element.attr('stroke', '#000000'); |
468 | this.svg_element.siblings('text').attr('fill', '#000000'); |
05485bfd |
469 | this.svg_element.siblings('text').attr('class', ''); |
b28e606e |
470 | } |
471 | } |
472 | } |
473 | |
474 | function node_elements_for( ellipse ) { |
475 | node_elements = get_edge_elements_for( ellipse ); |
476 | node_elements.push( new svgshape( ellipse.siblings('text') ) ); |
477 | node_elements.push( new svgshape( ellipse ) ); |
478 | return node_elements; |
479 | } |
480 | |
481 | function get_edge_elements_for( ellipse ) { |
482 | edge_elements = new Array(); |
45ee3b96 |
483 | node_id = ellipse.parent().attr('id'); |
b28e606e |
484 | edge_in_pattern = new RegExp( node_id + '$' ); |
485 | edge_out_pattern = new RegExp( '^' + node_id ); |
486 | $.each( $('#svgenlargement .edge,#svgenlargement .relation').children('title'), function(index) { |
487 | title = $(this).text(); |
488 | if( edge_in_pattern.test(title) ) { |
489 | polygon = $(this).siblings('polygon'); |
490 | if( polygon.size() > 0 ) { |
491 | edge_elements.push( new svgshape( polygon ) ); |
492 | } |
493 | path_segments = $(this).siblings('path')[0].pathSegList; |
494 | edge_elements.push( new svgpath( path_segments.getItem(path_segments.numberOfItems - 1), $(this).siblings('path') ) ); |
495 | } |
496 | if( edge_out_pattern.test(title) ) { |
497 | path_segments = $(this).siblings('path')[0].pathSegList; |
498 | edge_elements.push( new svgpath( path_segments.getItem(0), $(this).siblings('path') ) ); |
499 | } |
500 | }); |
501 | return edge_elements; |
502 | } |
503 | |
504 | function relation_factory() { |
505 | var self = this; |
506 | this.color_memo = null; |
507 | //TODO: colors hard coded for now |
508 | this.temp_color = '#FFA14F'; |
509 | this.relation_colors = [ "#5CCCCC", "#67E667", "#F9FE72", "#6B90D4", "#FF7673", "#E467B3", "#AA67D5", "#8370D8", "#FFC173" ]; |
510 | |
511 | this.create_temporary = function( source_node_id, target_node_id ) { |
45ee3b96 |
512 | var relation_id = get_relation_id( source_node_id, target_node_id ); |
513 | var relation = $( jq( relation_id ) ); |
9529f69c |
514 | if( relation.size() == 0 ) { |
b28e606e |
515 | draw_relation( source_node_id, target_node_id, self.temp_color ); |
516 | } else { |
517 | self.color_memo = relation.children('path').attr( 'stroke' ); |
518 | relation.children('path').attr( 'stroke', self.temp_color ); |
519 | } |
520 | } |
521 | this.remove_temporary = function() { |
522 | var path_element = $('#svgenlargement .relation').children('path[stroke="' + self.temp_color + '"]'); |
523 | if( self.color_memo != null ) { |
524 | path_element.attr( 'stroke', self.color_memo ); |
525 | self.color_memo = null; |
526 | } else { |
9529f69c |
527 | var temporary = path_element.parent('g').remove(); |
528 | temporary.empty(); |
529 | temporary = null; |
b28e606e |
530 | } |
531 | } |
532 | this.create = function( source_node_id, target_node_id, color_index ) { |
533 | //TODO: Protect from (color_)index out of bound.. |
534 | var relation_color = self.relation_colors[ color_index ]; |
9529f69c |
535 | var relation = draw_relation( source_node_id, target_node_id, relation_color ); |
536 | get_node_obj( source_node_id ).update_elements(); |
537 | get_node_obj( target_node_id ).update_elements(); |
538 | return relation; |
b28e606e |
539 | } |
9529f69c |
540 | this.toggle_active = function( relation_id ) { |
45ee3b96 |
541 | var relation = $( jq( relation_id ) ); |
9529f69c |
542 | var relation_path = relation.children('path'); |
543 | if( !relation.data( 'active' ) ) { |
544 | relation_path.css( {'cursor':'pointer'} ); |
545 | relation_path.mouseenter( function(event) { |
546 | outerTimer = setTimeout( function() { |
547 | timer = setTimeout( function() { |
45ee3b96 |
548 | var related_nodes = get_related_nodes( relation_id ); |
549 | var source_node_id = related_nodes[0]; |
550 | var target_node_id = related_nodes[1]; |
9529f69c |
551 | $('#delete_source_node_id').val( source_node_id ); |
552 | $('#delete_target_node_id').val( target_node_id ); |
553 | self.showinfo(relation); |
554 | }, 500 ) |
555 | }, 1000 ); |
556 | }); |
557 | relation_path.mouseleave( function(event) { |
558 | clearTimeout(outerTimer); |
559 | if( timer != null ) { clearTimeout(timer); } |
560 | }); |
561 | relation.data( 'active', true ); |
562 | } else { |
563 | relation_path.unbind( 'mouseenter' ); |
564 | relation_path.unbind( 'mouseleave' ); |
565 | relation_path.css( {'cursor':'inherit'} ); |
566 | relation.data( 'active', false ); |
567 | } |
568 | } |
569 | this.showinfo = function(relation) { |
088a14af |
570 | $('#delete_relation_type').text( relation.data('type') ); |
571 | $('#delete_relation_scope').text( relation.data('scope') ); |
69a19c91 |
572 | if( relation.data( 'note' ) ) { |
088a14af |
573 | $('#delete_relation_note').text('note: ' + relation.data( 'note' ) ); |
69a19c91 |
574 | } |
9529f69c |
575 | var points = relation.children('path').attr('d').slice(1).replace('C',' ').split(' '); |
576 | var xs = parseFloat( points[0].split(',')[0] ); |
577 | var xe = parseFloat( points[1].split(',')[0] ); |
578 | var ys = parseFloat( points[0].split(',')[1] ); |
579 | var ye = parseFloat( points[3].split(',')[1] ); |
580 | var p = svg_root.createSVGPoint(); |
581 | p.x = xs + ((xe-xs)*1.1); |
582 | p.y = ye - ((ye-ys)/2); |
76f05423 |
583 | var ctm = svg_root_element.getScreenCTM(); |
9529f69c |
584 | var nx = p.matrixTransform(ctm).x; |
585 | var ny = p.matrixTransform(ctm).y; |
586 | var dialog_aria = $ ("div[aria-labelledby='ui-dialog-title-delete-form']"); |
587 | $('#delete-form').dialog( 'open' ); |
588 | dialog_aria.offset({ left: nx, top: ny }); |
589 | } |
590 | this.remove = function( relation_id ) { |
30d0ba1e |
591 | if( !editable ) { |
592 | return; |
593 | } |
45ee3b96 |
594 | var relation = $( jq( relation_id ) ); |
9529f69c |
595 | relation.remove(); |
b28e606e |
596 | } |
597 | } |
598 | |
45ee3b96 |
599 | // Utility function to create/return the ID of a relation link between |
600 | // a source and target. |
601 | function get_relation_id( source_id, target_id ) { |
602 | var idlist = [ source_id, target_id ]; |
603 | idlist.sort(); |
604 | return 'relation-' + idlist[0] + '-...-' + idlist[1]; |
605 | } |
606 | |
607 | function get_related_nodes( relation_id ) { |
608 | var srctotarg = relation_id.substr( 9 ); |
609 | return srctotarg.split('-...-'); |
610 | } |
611 | |
b28e606e |
612 | function draw_relation( source_id, target_id, relation_color ) { |
9529f69c |
613 | var source_ellipse = get_ellipse( source_id ); |
614 | var target_ellipse = get_ellipse( target_id ); |
45ee3b96 |
615 | var relation_id = get_relation_id( source_id, target_id ); |
9529f69c |
616 | var svg = $('#svgenlargement').children('svg').svg().svg('get'); |
617 | var path = svg.createPath(); |
618 | var sx = parseInt( source_ellipse.attr('cx') ); |
619 | var rx = parseInt( source_ellipse.attr('rx') ); |
620 | var sy = parseInt( source_ellipse.attr('cy') ); |
621 | var ex = parseInt( target_ellipse.attr('cx') ); |
622 | var ey = parseInt( target_ellipse.attr('cy') ); |
45ee3b96 |
623 | var relation = svg.group( $("#svgenlargement svg g"), |
624 | { 'class':'relation', 'id':relation_id } ); |
9529f69c |
625 | svg.title( relation, source_id + '->' + target_id ); |
626 | svg.path( relation, path.move( sx, sy ).curveC( sx + (2*rx), sy, ex + (2*rx), ey, ex, ey ), {fill: 'none', stroke: relation_color, strokeWidth: 4}); |
b28e606e |
627 | var relation_element = $('#svgenlargement .relation').filter( ':last' ); |
628 | relation_element.insertBefore( $('#svgenlargement g g').filter(':first') ); |
9529f69c |
629 | return relation_element; |
b28e606e |
630 | } |
631 | |
c1add777 |
632 | function Marquee() { |
633 | |
634 | var self = this; |
635 | |
f6516f22 |
636 | this.x = 0; |
637 | this.y = 0; |
638 | this.dx = 0; |
639 | this.dy = 0; |
c1add777 |
640 | this.enlargementOffset = $('#svgenlargement').offset(); |
641 | this.svg_rect = $('#svgenlargement svg').svg('get'); |
642 | |
643 | this.show = function( event ) { |
644 | // TODO: uncolor possible selected |
645 | // TODO: unless SHIFT? |
f6516f22 |
646 | self.x = event.clientX; |
647 | self.y = event.clientY; |
c1add777 |
648 | p = svg_root.createSVGPoint(); |
649 | p.x = event.clientX - self.enlargementOffset.left; |
650 | p.y = event.clientY - self.enlargementOffset.top; |
c1add777 |
651 | self.svg_rect.rect( p.x, p.y, 0, 0, { fill: 'black', 'fill-opacity': '0.1', stroke: 'black', 'stroke-dasharray': '4,2', strokeWidth: '0.02em', id: 'marquee' } ); |
652 | }; |
653 | |
654 | this.expand = function( event ) { |
f6516f22 |
655 | self.dx = (event.clientX - self.x); |
656 | self.dy = (event.clientY - self.y); |
c1add777 |
657 | var rect = $('#marquee'); |
f6516f22 |
658 | if( rect.length != 0 ) { |
659 | var rect_w = Math.abs( self.dx ); |
660 | var rect_h = Math.abs( self.dy ); |
661 | var rect_x = self.x - self.enlargementOffset.left; |
662 | var rect_y = self.y - self.enlargementOffset.top; |
663 | if( self.dx < 0 ) { rect_x = rect_x - rect_w } |
664 | if( self.dy < 0 ) { rect_y = rect_y - rect_h } |
665 | rect.attr("x", rect_x).attr("y", rect_y).attr("width", rect_w).attr("height", rect_h); |
c1add777 |
666 | } |
667 | }; |
668 | |
a84ca4de |
669 | this.select = function() { |
c1add777 |
670 | var rect = $('#marquee'); |
671 | if( rect.length != 0 ) { |
e538eccb |
672 | //unselect any possible selected first |
673 | if( $('ellipse[fill="#9999ff"]').size() > 0 ) { |
674 | $('ellipse[fill="#9999ff"]').each( function() { |
675 | $(this).data( 'node_obj' ).set_draggable( false ); |
676 | } ); |
677 | } |
678 | //compute dimension of marquee |
c1add777 |
679 | var left = $('#marquee').offset().left; |
680 | var top = $('#marquee').offset().top; |
681 | var right = left + parseInt( $('#marquee').attr( 'width' ) ); |
682 | var bottom = top + parseInt( $('#marquee').attr( 'height' ) ); |
683 | var tf = svg_root_element.getScreenCTM().inverse(); |
684 | var p = svg_root.createSVGPoint(); |
685 | p.x=left; |
686 | p.y=top; |
687 | var cx_min = p.matrixTransform(tf).x; |
688 | var cy_min = p.matrixTransform(tf).y; |
689 | p.x=right; |
690 | p.y=bottom; |
691 | var cx_max = p.matrixTransform(tf).x; |
692 | var cy_max = p.matrixTransform(tf).y; |
e538eccb |
693 | //select any node with its center inside the marquee |
fdb37581 |
694 | var readings = []; |
e538eccb |
695 | //also merge witness sets from nodes |
a84ca4de |
696 | var witnesses = []; |
c1add777 |
697 | $('#svgenlargement ellipse').each( function( index ) { |
698 | var cx = parseInt( $(this).attr('cx') ); |
699 | var cy = parseInt( $(this).attr('cy') ); |
700 | if( cx > cx_min && cx < cx_max) { |
701 | if( cy > cy_min && cy < cy_max) { |
702 | // we actually heve no real 'selected' state for nodes, except coloring |
e538eccb |
703 | $(this).attr( 'fill', '#9999ff' ); |
fdb37581 |
704 | // Take note of the selected reading(s) and applicable witness(es) |
705 | // so we can populate the multipleselect-form |
706 | readings.push( $(this).parent().attr('id') ); |
a84ca4de |
707 | var this_witnesses = $(this).data( 'node_obj' ).get_witnesses(); |
708 | witnesses = arrayUnique( witnesses.concat( this_witnesses ) ); |
c1add777 |
709 | } |
710 | } |
711 | }); |
e538eccb |
712 | if( $('ellipse[fill="#9999ff"]').size() > 0 ) { |
fdb37581 |
713 | //add intersection of witnesses sets to the multi select form and open it |
714 | $('#detach_collated_form').empty(); |
715 | $.each( readings, function( index, value ) { |
716 | $('#detach_collated_form').append( $('<input>').attr( |
717 | "type", "hidden").attr("name", "readings[]").attr( |
718 | "value", value ) ); |
719 | }); |
a84ca4de |
720 | $.each( witnesses, function( index, value ) { |
fdb37581 |
721 | $('#detach_collated_form').append( |
722 | '<input type="checkbox" name="witnesses[]" value="' + value |
723 | + '">' + value + '<br>' ); |
a84ca4de |
724 | }); |
fdb37581 |
725 | $('#multiple_selected_readings').attr('value', readings.join(',') ); |
a84ca4de |
726 | $('#multipleselect-form').dialog( 'open' ); |
727 | } |
c1add777 |
728 | self.svg_rect.remove( $('#marquee') ); |
729 | } |
730 | }; |
731 | |
f6516f22 |
732 | this.unselect = function() { |
e538eccb |
733 | $('ellipse[fill="#9999ff"]').attr( 'fill', '#fff' ); |
f6516f22 |
734 | } |
735 | |
c1add777 |
736 | } |
737 | |
9529f69c |
738 | |
b28e606e |
739 | $(document).ready(function () { |
9529f69c |
740 | |
741 | timer = null; |
b28e606e |
742 | relation_manager = new relation_factory(); |
743 | |
c1add777 |
744 | $('#update_workspace_button').data('locked', false); |
745 | |
9529f69c |
746 | $('#enlargement').mousedown(function (event) { |
b28e606e |
747 | $(this) |
9529f69c |
748 | .data('down', true) |
749 | .data('x', event.clientX) |
750 | .data('y', event.clientY) |
751 | .data('scrollLeft', this.scrollLeft) |
c1add777 |
752 | stateTf = svg_root_element.getCTM().inverse(); |
753 | var p = svg_root.createSVGPoint(); |
754 | p.x = event.clientX; |
755 | p.y = event.clientY; |
756 | stateOrigin = p.matrixTransform(stateTf); |
757 | |
758 | // Activate marquee if in interaction mode |
759 | if( $('#update_workspace_button').data('locked') == true ) { marquee.show( event ) }; |
760 | |
761 | event.returnValue = false; |
762 | event.preventDefault(); |
763 | return false; |
b28e606e |
764 | }).mouseup(function (event) { |
a84ca4de |
765 | marquee.select(); |
c1add777 |
766 | $(this).data('down', false); |
b28e606e |
767 | }).mousemove(function (event) { |
9529f69c |
768 | if( timer != null ) { clearTimeout(timer); } |
769 | if ( ($(this).data('down') == true) && ($('#update_workspace_button').data('locked') == false) ) { |
770 | var p = svg_root.createSVGPoint(); |
771 | p.x = event.clientX; |
772 | p.y = event.clientY; |
773 | p = p.matrixTransform(stateTf); |
774 | var matrix = stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y); |
775 | var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")"; |
76f05423 |
776 | svg_root_element.setAttribute("transform", s); |
b28e606e |
777 | } |
c1add777 |
778 | marquee.expand( event ); |
76f05423 |
779 | event.returnValue = false; |
780 | event.preventDefault(); |
b28e606e |
781 | }).mousewheel(function (event, delta) { |
9529f69c |
782 | event.returnValue = false; |
783 | event.preventDefault(); |
784 | if ( $('#update_workspace_button').data('locked') == false ) { |
76f05423 |
785 | if (!delta || delta == null || delta == 0) delta = event.originalEvent.wheelDelta; |
786 | if (!delta || delta == null || delta == 0) delta = -1 * event.originalEvent.detail; |
9529f69c |
787 | if( delta < -9 ) { delta = -9 }; |
788 | var z = 1 + delta/10; |
76f05423 |
789 | z = delta > 0 ? 1 : -1; |
790 | var g = svg_root_element; |
791 | if (g && ((z<1 && (g.getScreenCTM().a * start_element_height) > 4.0) || (z>=1 && (g.getScreenCTM().a * start_element_height) < 100))) { |
9529f69c |
792 | var root = svg_root; |
793 | var p = root.createSVGPoint(); |
76f05423 |
794 | p.x = event.originalEvent.clientX; |
795 | p.y = event.originalEvent.clientY; |
9529f69c |
796 | p = p.matrixTransform(g.getCTM().inverse()); |
76f05423 |
797 | var scaleLevel = 1+(z/20); |
798 | var k = root.createSVGMatrix().translate(p.x, p.y).scale(scaleLevel).translate(-p.x, -p.y); |
9529f69c |
799 | var matrix = g.getCTM().multiply(k); |
800 | var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")"; |
801 | g.setAttribute("transform", s); |
802 | } |
803 | } |
b28e606e |
804 | }).css({ |
805 | 'overflow' : 'hidden', |
806 | 'cursor' : '-moz-grab' |
807 | }); |
808 | |
c1add777 |
809 | |
30d0ba1e |
810 | if( editable ) { |
811 | $( "#dialog-form" ).dialog({ |
812 | autoOpen: false, |
813 | height: 270, |
814 | width: 290, |
815 | modal: true, |
816 | buttons: { |
817 | "Ok": function( evt ) { |
818 | $(evt.target).button("disable"); |
819 | $('#status').empty(); |
820 | form_values = $('#collapse_node_form').serialize(); |
821 | ncpath = getTextURL( 'relationships' ); |
822 | var jqjson = $.post( ncpath, form_values, function(data) { |
823 | $.each( data, function(item, source_target) { |
824 | var source_found = get_ellipse( source_target[0] ); |
825 | var target_found = get_ellipse( source_target[1] ); |
826 | var relation_found = $.inArray( source_target[2], $('#keymap').data('relations') ); |
827 | if( source_found.size() && target_found.size() && relation_found > -1 ) { |
828 | var relation = relation_manager.create( source_target[0], source_target[1], relation_found ); |
eeea8fb6 |
829 | relation.data( 'type', source_target[2] ); |
7b54e481 |
830 | relation.data( 'scope', $('#scope :selected').text() ); |
831 | relation.data( 'note', $('#note').val() ); |
45ee3b96 |
832 | relation_manager.toggle_active( relation.attr('id') ); |
7b54e481 |
833 | } |
30d0ba1e |
834 | $(evt.target).button("enable"); |
835 | }); |
836 | $( "#dialog-form" ).dialog( "close" ); |
837 | }, 'json' ); |
838 | }, |
839 | Cancel: function() { |
840 | $( this ).dialog( "close" ); |
841 | } |
842 | }, |
843 | create: function(event, ui) { |
844 | $(this).data( 'relation_drawn', false ); |
a166dca8 |
845 | $('#rel_type').data( 'changed_after_open', false ); |
56e3972e |
846 | $.each( relationship_types, function(index, typedef) { |
847 | $('#rel_type').append( $('<option />').attr( "value", typedef.name ).text(typedef.name) ); |
848 | }); |
849 | $.each( relationship_scopes, function(index, value) { |
850 | $('#scope').append( $('<option />').attr( "value", value ).text(value) ); |
a166dca8 |
851 | }); |
852 | // Handler to clear the annotation field, the first time the relationship is |
853 | // changed after opening the form. |
854 | $('#rel_type').change( function () { |
855 | if( !$(this).data( 'changed_after_open' ) ) { |
856 | $('#note').val(''); |
857 | } |
858 | $(this).data( 'changed_after_open', true ); |
859 | }); |
30d0ba1e |
860 | }, |
861 | open: function() { |
862 | relation_manager.create_temporary( $('#source_node_id').val(), $('#target_node_id').val() ); |
863 | $(".ui-widget-overlay").css("background", "none"); |
864 | $("#dialog_overlay").show(); |
865 | $("#dialog_overlay").height( $("#enlargement_container").height() ); |
866 | $("#dialog_overlay").width( $("#enlargement_container").innerWidth() ); |
867 | $("#dialog_overlay").offset( $("#enlargement_container").offset() ); |
a166dca8 |
868 | $('#rel_type').data( 'changed_after_open', false ); |
30d0ba1e |
869 | }, |
870 | close: function() { |
871 | relation_manager.remove_temporary(); |
872 | $( '#status' ).empty(); |
873 | $("#dialog_overlay").hide(); |
874 | } |
875 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
21e6ebc7 |
876 | if( ajaxSettings.url == getTextURL('relationships') |
877 | && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) { |
878 | var error; |
879 | if( jqXHR.responseText.indexOf('do not have permission to modify') > -1 ) { |
880 | error = 'You are not authorized to modify this tradition. (Try logging in again?)'; |
881 | } else { |
882 | try { |
883 | var errobj = jQuery.parseJSON( jqXHR.responseText ); |
884 | error = errobj.error + '</br>The relationship cannot be made.</p>'; |
885 | } catch(e) { |
886 | error = jqXHR.responseText; |
887 | } |
888 | } |
889 | $('#status').append( '<p class="error">Error: ' + error ); |
890 | } |
891 | $(event.target).parent().find('.ui-button').button("enable"); |
30d0ba1e |
892 | } ); |
893 | } |
b28e606e |
894 | |
088a14af |
895 | var deletion_buttonset = { |
896 | cancel: function() { $( this ).dialog( "close" ); }, |
897 | global: function () { delete_relation( true ); }, |
898 | delete: function() { delete_relation( false ); } |
899 | }; |
a84ca4de |
900 | |
9529f69c |
901 | $( "#delete-form" ).dialog({ |
902 | autoOpen: false, |
69a19c91 |
903 | height: 135, |
088a14af |
904 | width: 250, |
9529f69c |
905 | modal: false, |
9529f69c |
906 | create: function(event, ui) { |
30d0ba1e |
907 | // TODO What is this logic doing? |
a84ca4de |
908 | // This scales the buttons in the dialog and makes it look proper |
909 | // Not sure how essential it is, does anything break if it's not here? |
9529f69c |
910 | var buttonset = $(this).parent().find( '.ui-dialog-buttonset' ).css( 'width', '100%' ); |
911 | buttonset.find( "button:contains('Cancel')" ).css( 'float', 'right' ); |
a84ca4de |
912 | // A: This makes sure that the pop up delete relation dialogue for a hovered over |
913 | // relation auto closes if the user doesn't engage (mouseover) with it. |
9529f69c |
914 | var dialog_aria = $("div[aria-labelledby='ui-dialog-title-delete-form']"); |
915 | dialog_aria.mouseenter( function() { |
916 | if( mouseWait != null ) { clearTimeout(mouseWait) }; |
917 | }) |
918 | dialog_aria.mouseleave( function() { |
919 | mouseWait = setTimeout( function() { $("#delete-form").dialog( "close" ) }, 2000 ); |
920 | }) |
921 | }, |
922 | open: function() { |
088a14af |
923 | if( !editable ) { |
924 | $( this ).dialog( "option", "buttons", |
925 | [{ text: "OK", click: deletion_buttonset['cancel'] }] ); |
926 | } else if( $('#delete_relation_scope').text() === 'local' ) { |
927 | $( this ).dialog( "option", "width", 160 ); |
928 | $( this ).dialog( "option", "buttons", |
929 | [{ text: "Delete", click: deletion_buttonset['delete'] }, |
930 | { text: "Cancel", click: deletion_buttonset['cancel'] }] ); |
931 | } else { |
932 | $( this ).dialog( "option", "width", 200 ); |
933 | $( this ).dialog( "option", "buttons", |
934 | [{ text: "Delete", click: deletion_buttonset['delete'] }, |
935 | { text: "Delete all", click: deletion_buttonset['global'] }, |
936 | { text: "Cancel", click: deletion_buttonset['cancel'] }] ); |
937 | } |
938 | |
9529f69c |
939 | mouseWait = setTimeout( function() { $("#delete-form").dialog( "close" ) }, 2000 ); |
940 | }, |
088a14af |
941 | close: function() {} |
9529f69c |
942 | }); |
943 | |
a84ca4de |
944 | $( "#multipleselect-form" ).dialog({ |
945 | autoOpen: false, |
946 | height: 150, |
947 | width: 250, |
948 | modal: true, |
fdb37581 |
949 | buttons: { |
950 | Cancel: function() { $( this ).dialog( "close" ); }, |
951 | Detach: function ( evt ) { |
952 | $(evt.target).button("disable"); |
953 | var form_values = $('#detach_collated_form').serialize(); |
954 | ncpath = getTextURL( 'duplicate' ); |
955 | var jqjson = $.post( ncpath, form_values, function(data) { |
956 | $.each( data, function(reading, newreading) { |
957 | alert( "Would detach reading " + newreading['id'] + " from " + reading ); |
958 | }); |
959 | $(evt.target).button("enable"); |
960 | }); |
961 | } |
962 | }, |
a84ca4de |
963 | create: function(event, ui) { |
964 | var buttonset = $(this).parent().find( '.ui-dialog-buttonset' ).css( 'width', '100%' ); |
965 | buttonset.find( "button:contains('Cancel')" ).css( 'float', 'right' ); |
966 | }, |
967 | open: function() { |
968 | $( this ).dialog( "option", "width", 200 ); |
e538eccb |
969 | $(".ui-widget-overlay").css("background", "none"); |
fdb37581 |
970 | $('#multipleselect-form-status').empty(); |
e538eccb |
971 | $("#dialog_overlay").show(); |
972 | $("#dialog_overlay").height( $("#enlargement_container").height() ); |
973 | $("#dialog_overlay").width( $("#enlargement_container").innerWidth() ); |
974 | $("#dialog_overlay").offset( $("#enlargement_container").offset() ); |
a84ca4de |
975 | }, |
e538eccb |
976 | close: function() { |
977 | marquee.unselect(); |
978 | $("#dialog_overlay").hide(); |
979 | } |
fdb37581 |
980 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
981 | if( ajaxSettings.url == getTextURL('duplicate') |
982 | && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) { |
983 | var error; |
984 | if( jqXHR.responseText.indexOf('do not have permission to modify') > -1 ) { |
985 | error = 'You are not authorized to modify this tradition. (Try logging in again?)'; |
986 | } else { |
987 | try { |
988 | var errobj = jQuery.parseJSON( jqXHR.responseText ); |
989 | error = errobj.error + '</br>The relationship cannot be made.</p>'; |
990 | } catch(e) { |
991 | error = jqXHR.responseText; |
992 | } |
993 | } |
994 | $('#multipleselect-form-status').append( '<p class="error">Error: ' + error ); |
995 | } |
996 | $(event.target).parent().find('.ui-button').button("enable"); |
997 | }); |
998 | |
a84ca4de |
999 | |
088a14af |
1000 | // Helpers for relationship deletion |
1001 | |
1002 | function delete_relation( scopewide ) { |
1003 | form_values = $('#delete_relation_form').serialize(); |
1004 | if( scopewide ) { |
1005 | form_values += "&scopewide=true"; |
1006 | } |
1007 | ncpath = getTextURL( 'relationships' ); |
1008 | var jqjson = $.ajax({ url: ncpath, data: form_values, success: function(data) { |
1009 | $.each( data, function(item, source_target) { |
1010 | relation_manager.remove( get_relation_id( source_target[0], source_target[1] ) ); |
1011 | }); |
1012 | $( "#delete-form" ).dialog( "close" ); |
1013 | }, dataType: 'json', type: 'DELETE' }); |
1014 | } |
1015 | |
1016 | function toggle_relation_active( node_id ) { |
1017 | $('#svgenlargement .relation').find( "title:contains('" + node_id + "')" ).each( function(index) { |
1018 | matchid = new RegExp( "^" + node_id ); |
1019 | if( $(this).text().match( matchid ) != null ) { |
1020 | var relation_id = $(this).parent().attr('id'); |
1021 | relation_manager.toggle_active( relation_id ); |
1022 | }; |
1023 | }); |
1024 | } |
1025 | |
487674b9 |
1026 | // function for reading form dialog should go here; |
1027 | // just hide the element for now if we don't have morphology |
1028 | if( can_morphologize ) { |
5539cba3 |
1029 | if( editable ) { |
1030 | $('#reading_decollate_witnesses').multiselect(); |
1031 | } else { |
1032 | $('#decollation').hide(); |
1033 | } |
487674b9 |
1034 | $('#reading-form').dialog({ |
1035 | autoOpen: false, |
1036 | // height: 400, |
1037 | width: 450, |
1038 | modal: true, |
1039 | buttons: { |
1040 | Cancel: function() { |
1041 | $( this ).dialog( "close" ); |
1042 | }, |
1043 | Update: function( evt ) { |
1044 | // Disable the button |
1045 | $(evt.target).button("disable"); |
1046 | $('#reading_status').empty(); |
1047 | var reading_id = $('#reading_id').val() |
1048 | form_values = { |
1049 | 'id' : reading_id, |
1050 | 'is_nonsense': $('#reading_is_nonsense').is(':checked'), |
1051 | 'grammar_invalid': $('#reading_grammar_invalid').is(':checked'), |
1052 | 'normal_form': $('#reading_normal_form').val() }; |
1053 | // Add the morphology values |
1054 | $('.reading_morphology').each( function() { |
1055 | if( $(this).val() != '(Click to select)' ) { |
1056 | var rmid = $(this).attr('id'); |
1057 | rmid = rmid.substring(8); |
1058 | form_values[rmid] = $(this).val(); |
1059 | } |
45ee3b96 |
1060 | }); |
487674b9 |
1061 | // Make the JSON call |
1062 | ncpath = getReadingURL( reading_id ); |
1063 | var reading_element = readingdata[reading_id]; |
1064 | // $(':button :contains("Update")').attr("disabled", true); |
1065 | var jqjson = $.post( ncpath, form_values, function(data) { |
1066 | $.each( data, function(key, value) { |
1067 | reading_element[key] = value; |
1068 | }); |
1069 | if( $('#update_workspace_button').data('locked') == false ) { |
1070 | color_inactive( get_ellipse( reading_id ) ); |
1071 | } |
1072 | $(evt.target).button("enable"); |
1073 | $( "#reading-form" ).dialog( "close" ); |
1074 | }); |
1075 | // Re-color the node if necessary |
1076 | return false; |
1077 | } |
1078 | }, |
1079 | create: function() { |
30d0ba1e |
1080 | if( !editable ) { |
1081 | // Get rid of the disallowed editing UI bits |
1082 | $( this ).dialog( "option", "buttons", |
1083 | [{ text: "OK", click: function() { $( this ).dialog( "close" ); }}] ); |
1084 | $('#reading_relemmatize').hide(); |
1085 | } |
487674b9 |
1086 | }, |
1087 | open: function() { |
1088 | $(".ui-widget-overlay").css("background", "none"); |
5539cba3 |
1089 | $('#reading_decollate_witnesses').multiselect("refresh"); |
1090 | $('#reading_decollate_witnesses').multiselect("uncheckAll"); |
487674b9 |
1091 | $("#dialog_overlay").show(); |
1092 | $('#reading_status').empty(); |
1093 | $("#dialog_overlay").height( $("#enlargement_container").height() ); |
1094 | $("#dialog_overlay").width( $("#enlargement_container").innerWidth() ); |
1095 | $("#dialog_overlay").offset( $("#enlargement_container").offset() ); |
1096 | $("#reading-form").parent().find('.ui-button').button("enable"); |
1097 | }, |
1098 | close: function() { |
1099 | $("#dialog_overlay").hide(); |
1100 | } |
1101 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
21e6ebc7 |
1102 | if( ajaxSettings.url.lastIndexOf( getReadingURL('') ) > -1 |
487674b9 |
1103 | && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) { |
21e6ebc7 |
1104 | var error; |
1105 | if( jqXHR.responseText.indexOf('do not have permission to modify') > -1 ) { |
1106 | error = 'You are not authorized to modify this tradition. (Try logging in again?)'; |
1107 | } else { |
1108 | try { |
1109 | var errobj = jQuery.parseJSON( jqXHR.responseText ); |
1110 | error = errobj.error + '</br>The relationship cannot be made.</p>'; |
1111 | } catch(e) { |
1112 | error = jqXHR.responseText; |
1113 | } |
1114 | } |
1115 | $('#status').append( '<p class="error">Error: ' + error ); |
1116 | } |
1117 | $(event.target).parent().find('.ui-button').button("enable"); |
487674b9 |
1118 | }); |
1119 | } else { |
1120 | $('#reading-form').hide(); |
45ee3b96 |
1121 | } |
4c41c02c |
1122 | |
76f05423 |
1123 | |
b28e606e |
1124 | $('#update_workspace_button').click( function() { |
30d0ba1e |
1125 | if( !editable ) { |
1126 | return; |
1127 | } |
b28e606e |
1128 | var svg_enlargement = $('#svgenlargement').svg().svg('get').root(); |
76f05423 |
1129 | mouse_scale = svg_root_element.getScreenCTM().a; |
9529f69c |
1130 | if( $(this).data('locked') == true ) { |
1131 | $('#svgenlargement ellipse' ).each( function( index ) { |
1132 | if( $(this).data( 'node_obj' ) != null ) { |
1133 | $(this).data( 'node_obj' ).ungreyout_edges(); |
e538eccb |
1134 | $(this).data( 'node_obj' ).set_selectable( false ); |
1135 | color_inactive( $(this) ); |
9529f69c |
1136 | var node_id = $(this).data( 'node_obj' ).get_id(); |
1137 | toggle_relation_active( node_id ); |
1138 | $(this).data( 'node_obj', null ); |
1139 | } |
b28e606e |
1140 | }) |
b28e606e |
1141 | $(this).data('locked', false); |
9529f69c |
1142 | $(this).css('background-position', '0px 44px'); |
b28e606e |
1143 | } else { |
9529f69c |
1144 | var left = $('#enlargement').offset().left; |
1145 | var right = left + $('#enlargement').width(); |
76f05423 |
1146 | var tf = svg_root_element.getScreenCTM().inverse(); |
9529f69c |
1147 | var p = svg_root.createSVGPoint(); |
1148 | p.x=left; |
1149 | p.y=100; |
1150 | var cx_min = p.matrixTransform(tf).x; |
1151 | p.x=right; |
1152 | var cx_max = p.matrixTransform(tf).x; |
1153 | $('#svgenlargement ellipse').each( function( index ) { |
1154 | var cx = parseInt( $(this).attr('cx') ); |
1155 | if( cx > cx_min && cx < cx_max) { |
1156 | if( $(this).data( 'node_obj' ) == null ) { |
1157 | $(this).data( 'node_obj', new node_obj( $(this) ) ); |
1158 | } else { |
e538eccb |
1159 | $(this).data( 'node_obj' ).set_selectable( true ); |
9529f69c |
1160 | } |
1161 | $(this).data( 'node_obj' ).greyout_edges(); |
1162 | var node_id = $(this).data( 'node_obj' ).get_id(); |
1163 | toggle_relation_active( node_id ); |
b28e606e |
1164 | } |
9529f69c |
1165 | }); |
1166 | $(this).css('background-position', '0px 0px'); |
b28e606e |
1167 | $(this).data('locked', true ); |
b28e606e |
1168 | } |
1169 | }); |
30d0ba1e |
1170 | |
1171 | if( !editable ) { |
1172 | // Hide the unused elements |
1173 | $('#dialog-form').hide(); |
1174 | $('#update_workspace_button').hide(); |
1175 | } |
1176 | |
b28e606e |
1177 | |
e847b186 |
1178 | $('.helptag').popupWindow({ |
1179 | height:500, |
1180 | width:800, |
1181 | top:50, |
1182 | left:50, |
1183 | scrollbars:1 |
1184 | }); |
1185 | |
76f05423 |
1186 | expandFillPageClients(); |
1187 | $(window).resize(function() { |
1188 | expandFillPageClients(); |
1189 | }); |
1190 | |
9529f69c |
1191 | }); |
b28e606e |
1192 | |
1193 | |
76f05423 |
1194 | function expandFillPageClients() { |
1195 | $('.fillPage').each(function () { |
1196 | $(this).height($(window).height() - $(this).offset().top - MARGIN); |
1197 | }); |
1198 | } |
1199 | |
1200 | function loadSVG(svgData) { |
1201 | var svgElement = $('#svgenlargement'); |
1202 | |
1203 | $(svgElement).svg('destroy'); |
1204 | |
1205 | $(svgElement).svg({ |
1206 | loadURL: svgData, |
1207 | onLoad : svgEnlargementLoaded |
1208 | }); |
1209 | } |
1210 | |
1211 | |
c1add777 |
1212 | |
76f05423 |
1213 | /* OS Gadget stuff |
1214 | |
1215 | function svg_select_callback(topic, data, subscriberData) { |
1216 | svgData = data; |
1217 | loadSVG(svgData); |
1218 | } |
1219 | |
1220 | function loaded() { |
1221 | var prefs = new gadgets.Prefs(); |
1222 | var preferredHeight = parseInt(prefs.getString('height')); |
1223 | if (gadgets.util.hasFeature('dynamic-height')) gadgets.window.adjustHeight(preferredHeight); |
1224 | expandFillPageClients(); |
1225 | } |
1226 | |
1227 | if (gadgets.util.hasFeature('pubsub-2')) { |
1228 | gadgets.HubSettings.onConnect = function(hum, suc, err) { |
1229 | subId = gadgets.Hub.subscribe("interedition.svg.selected", svg_select_callback); |
1230 | loaded(); |
1231 | }; |
1232 | } |
1233 | else gadgets.util.registerOnLoadHandler(loaded); |
1234 | */ |