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 | |
9529f69c |
8 | function getRelativePath() { |
3f9d7ae5 |
9 | return basepath; |
9529f69c |
10 | } |
11 | |
5f15640c |
12 | function getTextURL( which ) { |
3f9d7ae5 |
13 | return basepath + textid + '/' + which; |
5f15640c |
14 | } |
15 | |
16 | function getReadingURL( reading_id ) { |
3f9d7ae5 |
17 | return basepath + textid + '/reading/' + reading_id; |
b28e606e |
18 | } |
19 | |
45ee3b96 |
20 | // Make an XML ID into a valid selector |
21 | function jq(myid) { |
22 | return '#' + myid.replace(/(:|\.)/g,'\\$1'); |
23 | } |
24 | |
065c7cf2 |
25 | // Actions for opening the reading panel |
26 | function node_dblclick_listener( evt ) { |
27 | // Open the reading dialogue for the given node. |
28 | // First get the reading info |
29 | var reading_id = $(this).attr('id'); |
30 | var reading_info = readingdata[reading_id]; |
31 | // and then populate the dialog box with it. |
32 | // Set the easy properties first |
33 | $('#reading-form').dialog( 'option', 'title', 'Reading information for "' + reading_info['text'] + '"' ); |
34 | $('#reading_id').val( reading_id ); |
798fa939 |
35 | toggle_checkbox( $('#reading_is_nonsense'), reading_info['is_nonsense'] ); |
36 | toggle_checkbox( $('#reading_grammar_invalid'), reading_info['grammar_invalid'] ); |
065c7cf2 |
37 | // Use .text as a backup for .normal_form |
38 | var normal_form = reading_info['normal_form']; |
39 | if( !normal_form ) { |
40 | normal_form = reading_info['text']; |
41 | } |
42 | var nfboxsize = 10; |
43 | if( normal_form.length > 9 ) { |
44 | nfboxsize = normal_form.length + 1; |
45 | } |
46 | $('#reading_normal_form').attr( 'size', nfboxsize ) |
47 | $('#reading_normal_form').val( normal_form ); |
48 | // Now do the morphological properties. |
0dcdd5ec |
49 | morphology_form( reading_info['lexemes'] ); |
065c7cf2 |
50 | // and then open the dialog. |
0dcdd5ec |
51 | $('#reading-form').dialog("open"); |
52 | } |
53 | |
798fa939 |
54 | function toggle_checkbox( box, value ) { |
55 | if( value == null ) { |
56 | value = false; |
57 | } |
58 | box.attr('checked', value ); |
59 | } |
60 | |
0dcdd5ec |
61 | function morphology_form ( lexlist ) { |
065c7cf2 |
62 | $('#morphology').empty(); |
0dcdd5ec |
63 | $.each( lexlist, function( idx, lex ) { |
065c7cf2 |
64 | var morphoptions = []; |
08f8443a |
65 | if( 'wordform_matchlist' in lex ) { |
66 | $.each( lex['wordform_matchlist'], function( tdx, tag ) { |
67 | var tagstr = stringify_wordform( tag ); |
68 | morphoptions.push( tagstr ); |
69 | }); |
70 | } |
065c7cf2 |
71 | var formtag = 'morphology_' + idx; |
d1132306 |
72 | var formstr = ''; |
08f8443a |
73 | if( 'form' in lex ) { |
d1132306 |
74 | formstr = stringify_wordform( lex['form'] ); |
065c7cf2 |
75 | } |
d1132306 |
76 | var form_morph_elements = morph_elements( |
77 | formtag, lex['string'], formstr, morphoptions ); |
065c7cf2 |
78 | $.each( form_morph_elements, function( idx, el ) { |
79 | $('#morphology').append( el ); |
80 | }); |
81 | }); |
065c7cf2 |
82 | } |
83 | |
84 | function stringify_wordform ( tag ) { |
08f8443a |
85 | if( tag ) { |
86 | var elements = tag.split(' // '); |
87 | return elements[1] + ' // ' + elements[2]; |
88 | } |
89 | return '' |
065c7cf2 |
90 | } |
91 | |
d1132306 |
92 | function morph_elements ( formtag, formtxt, currform, morphoptions ) { |
93 | var clicktag = '(Click to select)'; |
94 | if ( !currform ) { |
95 | currform = clicktag; |
96 | } |
065c7cf2 |
97 | var formlabel = $('<label/>').attr( 'id', 'label_' + formtag ).attr( |
d1132306 |
98 | 'for', 'reading_' + formtag ).text( formtxt + ': ' ); |
065c7cf2 |
99 | var forminput = $('<input/>').attr( 'id', 'reading_' + formtag ).attr( |
0dcdd5ec |
100 | 'name', 'reading_' + formtag ).attr( 'size', '50' ).attr( |
101 | 'class', 'reading_morphology' ).val( currform ); |
d1132306 |
102 | forminput.autocomplete({ source: morphoptions, minLength: 0 }); |
103 | forminput.focus( function() { |
104 | if( $(this).val() == clicktag ) { |
105 | $(this).val(''); |
106 | } |
107 | $(this).autocomplete('search', '') |
108 | }); |
065c7cf2 |
109 | var morphel = [ formlabel, forminput, $('<br/>') ]; |
110 | return morphel; |
111 | } |
112 | |
4c41c02c |
113 | function color_inactive ( el ) { |
114 | var reading_id = $(el).parent().attr('id'); |
115 | var reading_info = readingdata[reading_id]; |
116 | // If the reading info has any non-disambiguated lexemes, color it yellow; |
117 | // otherwise color it green. |
118 | $(el).attr( {stroke:'green', fill:'#b3f36d'} ); |
bb3230b1 |
119 | if( reading_info ) { |
120 | $.each( reading_info['lexemes'], function ( idx, lex ) { |
121 | if( !lex['is_disambiguated'] || lex['is_disambiguated'] == 0 ) { |
122 | $(el).attr( {stroke:'orange', fill:'#fee233'} ); |
123 | } |
124 | }); |
125 | } |
4c41c02c |
126 | } |
127 | |
997ebe92 |
128 | function relemmatize () { |
129 | // Send the reading for a new lemmatization and reopen the form. |
a0a66634 |
130 | $('#relemmatize_pending').show(); |
997ebe92 |
131 | var reading_id = $('#reading_id').val() |
132 | ncpath = getReadingURL( reading_id ); |
133 | form_values = { |
134 | 'normal_form': $('#reading_normal_form').val(), |
135 | 'relemmatize': 1 }; |
136 | var jqjson = $.post( ncpath, form_values, function( data ) { |
137 | // Update the form with the return |
138 | if( 'id' in data ) { |
139 | // We got back a good answer. Stash it |
140 | readingdata[reading_id] = data; |
141 | // and regenerate the morphology form. |
142 | morphology_form( data['lexemes'] ); |
143 | } else { |
144 | alert("Could not relemmatize as requested: " + data['error']); |
145 | } |
a0a66634 |
146 | $('#relemmatize_pending').hide(); |
997ebe92 |
147 | }); |
148 | } |
149 | |
065c7cf2 |
150 | // Initialize the SVG once it exists |
b28e606e |
151 | function svgEnlargementLoaded() { |
fc018906 |
152 | //Give some visual evidence that we are working |
153 | $('#loading_overlay').show(); |
154 | lo_height = $("#enlargement_container").outerHeight(); |
155 | lo_width = $("#enlargement_container").outerWidth(); |
156 | $("#loading_overlay").height( lo_height ); |
157 | $("#loading_overlay").width( lo_width ); |
158 | $("#loading_overlay").offset( $("#enlargement_container").offset() ); |
159 | $("#loading_message").offset( |
160 | { 'top': lo_height / 2 - $("#loading_message").height() / 2, |
161 | 'left': lo_width / 2 - $("#loading_message").width() / 2 }); |
9529f69c |
162 | //Set viewbox widht and height to widht and height of $('#svgenlargement svg'). |
76f05423 |
163 | $('#update_workspace_button').data('locked', false); |
164 | $('#update_workspace_button').css('background-position', '0px 44px'); |
9529f69c |
165 | //This is essential to make sure zooming and panning works properly. |
4c41c02c |
166 | var rdgpath = getTextURL( 'readings' ); |
167 | $.getJSON( rdgpath, function( data ) { |
168 | readingdata = data; |
169 | $('#svgenlargement ellipse').each( function( i, el ) { color_inactive( el ) }); |
170 | }); |
065c7cf2 |
171 | $('#svgenlargement ellipse').parent().dblclick( node_dblclick_listener ); |
9529f69c |
172 | var graph_svg = $('#svgenlargement svg'); |
173 | var svg_g = $('#svgenlargement svg g')[0]; |
76f05423 |
174 | if (!svg_g) return; |
9529f69c |
175 | svg_root = graph_svg.svg().svg('get').root(); |
76f05423 |
176 | |
177 | // Find the real root and ignore any text nodes |
178 | for (i = 0; i < svg_root.childNodes.length; ++i) { |
179 | if (svg_root.childNodes[i].nodeName != '#text') { |
180 | svg_root_element = svg_root.childNodes[i]; |
181 | break; |
182 | } |
183 | } |
184 | |
9529f69c |
185 | svg_root.viewBox.baseVal.width = graph_svg.attr( 'width' ); |
186 | svg_root.viewBox.baseVal.height = graph_svg.attr( 'height' ); |
187 | //Now set scale and translate so svg height is about 150px and vertically centered in viewbox. |
188 | //This is just to create a nice starting enlargement. |
189 | var initial_svg_height = 250; |
190 | var scale = initial_svg_height/graph_svg.attr( 'height' ); |
191 | var additional_translate = (graph_svg.attr( 'height' ) - initial_svg_height)/(2*scale); |
192 | var transform = svg_g.getAttribute('transform'); |
193 | var translate = parseFloat( transform.match( /translate\([^\)]*\)/ )[0].split('(')[1].split(' ')[1].split(')')[0] ); |
194 | translate += additional_translate; |
195 | var transform = 'rotate(0) scale(' + scale + ') translate(4 ' + translate + ')'; |
196 | svg_g.setAttribute('transform', transform); |
197 | //used to calculate min and max zoom level: |
4c41c02c |
198 | start_element_height = $('#__START__').children('ellipse')[0].getBBox().height; |
fc018906 |
199 | add_relations( function() { $('#loading_overlay').hide(); }); |
6afcd813 |
200 | } |
201 | |
fc018906 |
202 | function add_relations( callback_fn ) { |
9529f69c |
203 | var basepath = getRelativePath(); |
5f15640c |
204 | var textrelpath = getTextURL( 'relationships' ); |
3f9d7ae5 |
205 | $.getJSON( basepath + 'definitions', function(data) { |
6afcd813 |
206 | var rel_types = data.types.sort(); |
9529f69c |
207 | $.getJSON( textrelpath, |
6afcd813 |
208 | function(data) { |
209 | $.each(data, function( index, rel_info ) { |
210 | var type_index = $.inArray(rel_info.type, rel_types); |
13aa153c |
211 | var source_found = get_ellipse( rel_info.source ); |
212 | var target_found = get_ellipse( rel_info.target ); |
213 | if( type_index != -1 && source_found.size() && target_found.size() ) { |
9529f69c |
214 | var relation = relation_manager.create( rel_info.source, rel_info.target, type_index ); |
215 | relation.data( 'type', rel_info.type ); |
216 | relation.data( 'scope', rel_info.scope ); |
69a19c91 |
217 | relation.data( 'note', rel_info.note ); |
9529f69c |
218 | var node_obj = get_node_obj(rel_info.source); |
219 | node_obj.set_draggable( false ); |
220 | node_obj.ellipse.data( 'node_obj', null ); |
221 | node_obj = get_node_obj(rel_info.target); |
222 | node_obj.set_draggable( false ); |
223 | node_obj.ellipse.data( 'node_obj', null ); |
6afcd813 |
224 | } |
fc018906 |
225 | }); |
226 | callback_fn.call(); |
9529f69c |
227 | }); |
6afcd813 |
228 | }); |
b28e606e |
229 | } |
230 | |
231 | function get_ellipse( node_id ) { |
45ee3b96 |
232 | return $( jq( node_id ) + ' ellipse'); |
b28e606e |
233 | } |
234 | |
235 | function get_node_obj( node_id ) { |
9529f69c |
236 | var node_ellipse = get_ellipse( node_id ); |
237 | if( node_ellipse.data( 'node_obj' ) == null ) { |
238 | node_ellipse.data( 'node_obj', new node_obj(node_ellipse) ); |
239 | }; |
240 | return node_ellipse.data( 'node_obj' ); |
b28e606e |
241 | } |
242 | |
b28e606e |
243 | function node_obj(ellipse) { |
244 | this.ellipse = ellipse; |
245 | var self = this; |
246 | |
247 | this.x = 0; |
248 | this.y = 0; |
249 | this.dx = 0; |
250 | this.dy = 0; |
251 | this.node_elements = node_elements_for(self.ellipse); |
252 | |
253 | this.get_id = function() { |
45ee3b96 |
254 | return $(self.ellipse).parent().attr('id') |
b28e606e |
255 | } |
256 | |
257 | this.set_draggable = function( draggable ) { |
258 | if( draggable ) { |
05485bfd |
259 | $(self.ellipse).attr( {stroke:'black', fill:'#fff'} ); |
260 | $(self.ellipse).parent().mousedown( this.mousedown_listener ); |
261 | $(self.ellipse).parent().hover( this.enter_node, this.leave_node ); |
262 | self.ellipse.siblings('text').attr('class', 'noselect draggable'); |
b28e606e |
263 | } else { |
05485bfd |
264 | self.ellipse.siblings('text').attr('class', ''); |
4c41c02c |
265 | $(self.ellipse).parent().unbind( 'mouseenter' ).unbind( 'mouseleave' ).unbind( 'mousedown' ); |
266 | color_inactive( self.ellipse ); |
b28e606e |
267 | } |
268 | } |
269 | |
270 | this.mousedown_listener = function(evt) { |
271 | evt.stopPropagation(); |
272 | self.x = evt.clientX; |
273 | self.y = evt.clientY; |
274 | $('body').mousemove( self.mousemove_listener ); |
275 | $('body').mouseup( self.mouseup_listener ); |
05485bfd |
276 | $(self.ellipse).parent().unbind('mouseenter').unbind('mouseleave') |
b28e606e |
277 | self.ellipse.attr( 'fill', '#ff66ff' ); |
278 | first_node_g_element = $("#svgenlargement g .node" ).filter( ":first" ); |
279 | if( first_node_g_element.attr('id') !== self.get_g().attr('id') ) { self.get_g().insertBefore( first_node_g_element ) }; |
280 | } |
281 | |
282 | this.mousemove_listener = function(evt) { |
9529f69c |
283 | self.dx = (evt.clientX - self.x) / mouse_scale; |
284 | self.dy = (evt.clientY - self.y) / mouse_scale; |
b28e606e |
285 | self.move_elements(); |
05485bfd |
286 | evt.returnValue = false; |
287 | evt.preventDefault(); |
288 | return false; |
b28e606e |
289 | } |
290 | |
291 | this.mouseup_listener = function(evt) { |
292 | if( $('ellipse[fill="#ffccff"]').size() > 0 ) { |
45ee3b96 |
293 | var source_node_id = $(self.ellipse).parent().attr('id'); |
05485bfd |
294 | var source_node_text = self.ellipse.siblings('text').text(); |
45ee3b96 |
295 | var target_node_id = $('ellipse[fill="#ffccff"]').parent().attr('id'); |
05485bfd |
296 | var target_node_text = $('ellipse[fill="#ffccff"]').siblings("text").text(); |
b28e606e |
297 | $('#source_node_id').val( source_node_id ); |
05485bfd |
298 | $('#source_node_text').val( source_node_text ); |
b28e606e |
299 | $('#target_node_id').val( target_node_id ); |
05485bfd |
300 | $('#target_node_text').val( target_node_text ); |
b28e606e |
301 | $('#dialog-form').dialog( 'open' ); |
302 | }; |
303 | $('body').unbind('mousemove'); |
304 | $('body').unbind('mouseup'); |
305 | self.ellipse.attr( 'fill', '#fff' ); |
05485bfd |
306 | $(self.ellipse).parent().hover( self.enter_node, self.leave_node ); |
9529f69c |
307 | self.reset_elements(); |
b28e606e |
308 | } |
f2fb96fc |
309 | |
b28e606e |
310 | this.cpos = function() { |
311 | return { x: self.ellipse.attr('cx'), y: self.ellipse.attr('cy') }; |
312 | } |
313 | |
314 | this.get_g = function() { |
315 | return self.ellipse.parent('g'); |
316 | } |
317 | |
318 | this.enter_node = function(evt) { |
319 | self.ellipse.attr( 'fill', '#ffccff' ); |
320 | } |
321 | |
322 | this.leave_node = function(evt) { |
323 | self.ellipse.attr( 'fill', '#fff' ); |
324 | } |
325 | |
326 | this.greyout_edges = function() { |
327 | $.each( self.node_elements, function(index, value) { |
328 | value.grey_out('.edge'); |
329 | }); |
330 | } |
331 | |
332 | this.ungreyout_edges = function() { |
333 | $.each( self.node_elements, function(index, value) { |
334 | value.un_grey_out('.edge'); |
335 | }); |
336 | } |
337 | |
338 | this.move_elements = function() { |
339 | $.each( self.node_elements, function(index, value) { |
340 | value.move(self.dx,self.dy); |
341 | }); |
342 | } |
343 | |
344 | this.reset_elements = function() { |
345 | $.each( self.node_elements, function(index, value) { |
346 | value.reset(); |
347 | }); |
348 | } |
349 | |
350 | this.update_elements = function() { |
351 | self.node_elements = node_elements_for(self.ellipse); |
352 | } |
353 | |
354 | self.set_draggable( true ); |
355 | } |
356 | |
357 | function svgshape( shape_element ) { |
358 | this.shape = shape_element; |
359 | this.move = function(dx,dy) { |
360 | this.shape.attr( "transform", "translate(" + dx + " " + dy + ")" ); |
361 | } |
362 | this.reset = function() { |
363 | this.shape.attr( "transform", "translate( 0, 0 )" ); |
364 | } |
365 | this.grey_out = function(filter) { |
366 | if( this.shape.parent(filter).size() != 0 ) { |
367 | this.shape.attr({'stroke':'#e5e5e5', 'fill':'#e5e5e5'}); |
368 | } |
369 | } |
370 | this.un_grey_out = function(filter) { |
371 | if( this.shape.parent(filter).size() != 0 ) { |
372 | this.shape.attr({'stroke':'#000000', 'fill':'#000000'}); |
373 | } |
374 | } |
375 | } |
376 | |
377 | function svgpath( path_element, svg_element ) { |
378 | this.svg_element = svg_element; |
379 | this.path = path_element; |
380 | this.x = this.path.x; |
381 | this.y = this.path.y; |
382 | this.move = function(dx,dy) { |
383 | this.path.x = this.x + dx; |
384 | this.path.y = this.y + dy; |
385 | } |
386 | this.reset = function() { |
387 | this.path.x = this.x; |
388 | this.path.y = this.y; |
389 | } |
390 | this.grey_out = function(filter) { |
391 | if( this.svg_element.parent(filter).size() != 0 ) { |
392 | this.svg_element.attr('stroke', '#e5e5e5'); |
393 | this.svg_element.siblings('text').attr('fill', '#e5e5e5'); |
05485bfd |
394 | this.svg_element.siblings('text').attr('class', 'noselect'); |
b28e606e |
395 | } |
396 | } |
397 | this.un_grey_out = function(filter) { |
398 | if( this.svg_element.parent(filter).size() != 0 ) { |
399 | this.svg_element.attr('stroke', '#000000'); |
400 | this.svg_element.siblings('text').attr('fill', '#000000'); |
05485bfd |
401 | this.svg_element.siblings('text').attr('class', ''); |
b28e606e |
402 | } |
403 | } |
404 | } |
405 | |
406 | function node_elements_for( ellipse ) { |
407 | node_elements = get_edge_elements_for( ellipse ); |
408 | node_elements.push( new svgshape( ellipse.siblings('text') ) ); |
409 | node_elements.push( new svgshape( ellipse ) ); |
410 | return node_elements; |
411 | } |
412 | |
413 | function get_edge_elements_for( ellipse ) { |
414 | edge_elements = new Array(); |
45ee3b96 |
415 | node_id = ellipse.parent().attr('id'); |
b28e606e |
416 | edge_in_pattern = new RegExp( node_id + '$' ); |
417 | edge_out_pattern = new RegExp( '^' + node_id ); |
418 | $.each( $('#svgenlargement .edge,#svgenlargement .relation').children('title'), function(index) { |
419 | title = $(this).text(); |
420 | if( edge_in_pattern.test(title) ) { |
421 | polygon = $(this).siblings('polygon'); |
422 | if( polygon.size() > 0 ) { |
423 | edge_elements.push( new svgshape( polygon ) ); |
424 | } |
425 | path_segments = $(this).siblings('path')[0].pathSegList; |
426 | edge_elements.push( new svgpath( path_segments.getItem(path_segments.numberOfItems - 1), $(this).siblings('path') ) ); |
427 | } |
428 | if( edge_out_pattern.test(title) ) { |
429 | path_segments = $(this).siblings('path')[0].pathSegList; |
430 | edge_elements.push( new svgpath( path_segments.getItem(0), $(this).siblings('path') ) ); |
431 | } |
432 | }); |
433 | return edge_elements; |
434 | } |
435 | |
436 | function relation_factory() { |
437 | var self = this; |
438 | this.color_memo = null; |
439 | //TODO: colors hard coded for now |
440 | this.temp_color = '#FFA14F'; |
441 | this.relation_colors = [ "#5CCCCC", "#67E667", "#F9FE72", "#6B90D4", "#FF7673", "#E467B3", "#AA67D5", "#8370D8", "#FFC173" ]; |
442 | |
443 | this.create_temporary = function( source_node_id, target_node_id ) { |
45ee3b96 |
444 | var relation_id = get_relation_id( source_node_id, target_node_id ); |
445 | var relation = $( jq( relation_id ) ); |
9529f69c |
446 | if( relation.size() == 0 ) { |
b28e606e |
447 | draw_relation( source_node_id, target_node_id, self.temp_color ); |
448 | } else { |
449 | self.color_memo = relation.children('path').attr( 'stroke' ); |
450 | relation.children('path').attr( 'stroke', self.temp_color ); |
451 | } |
452 | } |
453 | this.remove_temporary = function() { |
454 | var path_element = $('#svgenlargement .relation').children('path[stroke="' + self.temp_color + '"]'); |
455 | if( self.color_memo != null ) { |
456 | path_element.attr( 'stroke', self.color_memo ); |
457 | self.color_memo = null; |
458 | } else { |
9529f69c |
459 | var temporary = path_element.parent('g').remove(); |
460 | temporary.empty(); |
461 | temporary = null; |
b28e606e |
462 | } |
463 | } |
464 | this.create = function( source_node_id, target_node_id, color_index ) { |
465 | //TODO: Protect from (color_)index out of bound.. |
466 | var relation_color = self.relation_colors[ color_index ]; |
9529f69c |
467 | var relation = draw_relation( source_node_id, target_node_id, relation_color ); |
468 | get_node_obj( source_node_id ).update_elements(); |
469 | get_node_obj( target_node_id ).update_elements(); |
470 | return relation; |
b28e606e |
471 | } |
9529f69c |
472 | this.toggle_active = function( relation_id ) { |
45ee3b96 |
473 | var relation = $( jq( relation_id ) ); |
9529f69c |
474 | var relation_path = relation.children('path'); |
475 | if( !relation.data( 'active' ) ) { |
476 | relation_path.css( {'cursor':'pointer'} ); |
477 | relation_path.mouseenter( function(event) { |
478 | outerTimer = setTimeout( function() { |
479 | timer = setTimeout( function() { |
45ee3b96 |
480 | var related_nodes = get_related_nodes( relation_id ); |
481 | var source_node_id = related_nodes[0]; |
482 | var target_node_id = related_nodes[1]; |
9529f69c |
483 | $('#delete_source_node_id').val( source_node_id ); |
484 | $('#delete_target_node_id').val( target_node_id ); |
485 | self.showinfo(relation); |
486 | }, 500 ) |
487 | }, 1000 ); |
488 | }); |
489 | relation_path.mouseleave( function(event) { |
490 | clearTimeout(outerTimer); |
491 | if( timer != null ) { clearTimeout(timer); } |
492 | }); |
493 | relation.data( 'active', true ); |
494 | } else { |
495 | relation_path.unbind( 'mouseenter' ); |
496 | relation_path.unbind( 'mouseleave' ); |
497 | relation_path.css( {'cursor':'inherit'} ); |
498 | relation.data( 'active', false ); |
499 | } |
500 | } |
501 | this.showinfo = function(relation) { |
69a19c91 |
502 | var htmlstr = 'type: ' + relation.data( 'type' ) + '<br/>scope: ' + relation.data( 'scope' ); |
503 | if( relation.data( 'note' ) ) { |
504 | htmlstr = htmlstr + '<br/>note: ' + relation.data( 'note' ); |
505 | } |
506 | $('#delete-form-text').html( htmlstr ); |
9529f69c |
507 | var points = relation.children('path').attr('d').slice(1).replace('C',' ').split(' '); |
508 | var xs = parseFloat( points[0].split(',')[0] ); |
509 | var xe = parseFloat( points[1].split(',')[0] ); |
510 | var ys = parseFloat( points[0].split(',')[1] ); |
511 | var ye = parseFloat( points[3].split(',')[1] ); |
512 | var p = svg_root.createSVGPoint(); |
513 | p.x = xs + ((xe-xs)*1.1); |
514 | p.y = ye - ((ye-ys)/2); |
76f05423 |
515 | var ctm = svg_root_element.getScreenCTM(); |
9529f69c |
516 | var nx = p.matrixTransform(ctm).x; |
517 | var ny = p.matrixTransform(ctm).y; |
518 | var dialog_aria = $ ("div[aria-labelledby='ui-dialog-title-delete-form']"); |
519 | $('#delete-form').dialog( 'open' ); |
520 | dialog_aria.offset({ left: nx, top: ny }); |
521 | } |
522 | this.remove = function( relation_id ) { |
45ee3b96 |
523 | var relation = $( jq( relation_id ) ); |
9529f69c |
524 | relation.remove(); |
b28e606e |
525 | } |
526 | } |
527 | |
45ee3b96 |
528 | // Utility function to create/return the ID of a relation link between |
529 | // a source and target. |
530 | function get_relation_id( source_id, target_id ) { |
531 | var idlist = [ source_id, target_id ]; |
532 | idlist.sort(); |
533 | return 'relation-' + idlist[0] + '-...-' + idlist[1]; |
534 | } |
535 | |
536 | function get_related_nodes( relation_id ) { |
537 | var srctotarg = relation_id.substr( 9 ); |
538 | return srctotarg.split('-...-'); |
539 | } |
540 | |
b28e606e |
541 | function draw_relation( source_id, target_id, relation_color ) { |
9529f69c |
542 | var source_ellipse = get_ellipse( source_id ); |
543 | var target_ellipse = get_ellipse( target_id ); |
45ee3b96 |
544 | var relation_id = get_relation_id( source_id, target_id ); |
9529f69c |
545 | var svg = $('#svgenlargement').children('svg').svg().svg('get'); |
546 | var path = svg.createPath(); |
547 | var sx = parseInt( source_ellipse.attr('cx') ); |
548 | var rx = parseInt( source_ellipse.attr('rx') ); |
549 | var sy = parseInt( source_ellipse.attr('cy') ); |
550 | var ex = parseInt( target_ellipse.attr('cx') ); |
551 | var ey = parseInt( target_ellipse.attr('cy') ); |
45ee3b96 |
552 | var relation = svg.group( $("#svgenlargement svg g"), |
553 | { 'class':'relation', 'id':relation_id } ); |
9529f69c |
554 | svg.title( relation, source_id + '->' + target_id ); |
555 | 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 |
556 | var relation_element = $('#svgenlargement .relation').filter( ':last' ); |
557 | relation_element.insertBefore( $('#svgenlargement g g').filter(':first') ); |
9529f69c |
558 | return relation_element; |
b28e606e |
559 | } |
560 | |
9529f69c |
561 | |
b28e606e |
562 | $(document).ready(function () { |
9529f69c |
563 | |
564 | timer = null; |
b28e606e |
565 | relation_manager = new relation_factory(); |
9529f69c |
566 | $('#update_workspace_button').data('locked', false); |
b28e606e |
567 | |
9529f69c |
568 | $('#enlargement').mousedown(function (event) { |
b28e606e |
569 | $(this) |
9529f69c |
570 | .data('down', true) |
571 | .data('x', event.clientX) |
572 | .data('y', event.clientY) |
573 | .data('scrollLeft', this.scrollLeft) |
76f05423 |
574 | stateTf = svg_root_element.getCTM().inverse(); |
9529f69c |
575 | var p = svg_root.createSVGPoint(); |
576 | p.x = event.clientX; |
577 | p.y = event.clientY; |
578 | stateOrigin = p.matrixTransform(stateTf); |
76f05423 |
579 | event.returnValue = false; |
580 | event.preventDefault(); |
9529f69c |
581 | return false; |
b28e606e |
582 | }).mouseup(function (event) { |
9529f69c |
583 | $(this).data('down', false); |
b28e606e |
584 | }).mousemove(function (event) { |
9529f69c |
585 | if( timer != null ) { clearTimeout(timer); } |
586 | if ( ($(this).data('down') == true) && ($('#update_workspace_button').data('locked') == false) ) { |
587 | var p = svg_root.createSVGPoint(); |
588 | p.x = event.clientX; |
589 | p.y = event.clientY; |
590 | p = p.matrixTransform(stateTf); |
591 | var matrix = stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y); |
592 | var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")"; |
76f05423 |
593 | svg_root_element.setAttribute("transform", s); |
b28e606e |
594 | } |
76f05423 |
595 | event.returnValue = false; |
596 | event.preventDefault(); |
b28e606e |
597 | }).mousewheel(function (event, delta) { |
9529f69c |
598 | event.returnValue = false; |
599 | event.preventDefault(); |
600 | if ( $('#update_workspace_button').data('locked') == false ) { |
76f05423 |
601 | if (!delta || delta == null || delta == 0) delta = event.originalEvent.wheelDelta; |
602 | if (!delta || delta == null || delta == 0) delta = -1 * event.originalEvent.detail; |
9529f69c |
603 | if( delta < -9 ) { delta = -9 }; |
604 | var z = 1 + delta/10; |
76f05423 |
605 | z = delta > 0 ? 1 : -1; |
606 | var g = svg_root_element; |
607 | if (g && ((z<1 && (g.getScreenCTM().a * start_element_height) > 4.0) || (z>=1 && (g.getScreenCTM().a * start_element_height) < 100))) { |
9529f69c |
608 | var root = svg_root; |
609 | var p = root.createSVGPoint(); |
76f05423 |
610 | p.x = event.originalEvent.clientX; |
611 | p.y = event.originalEvent.clientY; |
9529f69c |
612 | p = p.matrixTransform(g.getCTM().inverse()); |
76f05423 |
613 | var scaleLevel = 1+(z/20); |
614 | var k = root.createSVGMatrix().translate(p.x, p.y).scale(scaleLevel).translate(-p.x, -p.y); |
9529f69c |
615 | var matrix = g.getCTM().multiply(k); |
616 | var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")"; |
617 | g.setAttribute("transform", s); |
618 | } |
619 | } |
b28e606e |
620 | }).css({ |
621 | 'overflow' : 'hidden', |
622 | 'cursor' : '-moz-grab' |
623 | }); |
624 | |
625 | |
626 | $( "#dialog-form" ).dialog({ |
627 | autoOpen: false, |
628 | height: 270, |
629 | width: 290, |
630 | modal: true, |
631 | buttons: { |
77121e3f |
632 | "Ok": function( evt ) { |
633 | $(evt.target).button("disable"); |
b28e606e |
634 | $('#status').empty(); |
76f05423 |
635 | form_values = $('#collapse_node_form').serialize(); |
5f15640c |
636 | ncpath = getTextURL( 'relationships' ); |
b28e606e |
637 | var jqjson = $.post( ncpath, form_values, function(data) { |
638 | $.each( data, function(item, source_target) { |
7b54e481 |
639 | var source_found = get_ellipse( source_target[0] ); |
640 | var target_found = get_ellipse( source_target[1] ); |
641 | if( source_found.size() && target_found.size() ) { |
45ee3b96 |
642 | var relation = relation_manager.create( source_target[0], source_target[1], $('#rel_type')[0].selectedIndex-1 ); |
7b54e481 |
643 | relation.data( 'type', $('#rel_type :selected').text() ); |
644 | relation.data( 'scope', $('#scope :selected').text() ); |
645 | relation.data( 'note', $('#note').val() ); |
45ee3b96 |
646 | relation_manager.toggle_active( relation.attr('id') ); |
7b54e481 |
647 | } |
77121e3f |
648 | $(evt.target).button("enable"); |
649 | }); |
b28e606e |
650 | $( "#dialog-form" ).dialog( "close" ); |
9529f69c |
651 | }, 'json' ); |
b28e606e |
652 | }, |
653 | Cancel: function() { |
b28e606e |
654 | $( this ).dialog( "close" ); |
655 | } |
656 | }, |
657 | create: function(event, ui) { |
658 | $(this).data( 'relation_drawn', false ); |
659 | //TODO? Err handling? |
9529f69c |
660 | var basepath = getRelativePath(); |
661 | var jqjson = $.getJSON( basepath + '/definitions', function(data) { |
b28e606e |
662 | var types = data.types.sort(); |
663 | $.each( types, function(index, value) { |
76f05423 |
664 | $('#rel_type').append( $('<option />').attr( "value", value ).text(value) ); |
b28e606e |
665 | $('#keymaplist').append( $('<li>').css( "border-color", relation_manager.relation_colors[index] ).text(value) ); |
666 | }); |
667 | var scopes = data.scopes; |
668 | $.each( scopes, function(index, value) { |
76f05423 |
669 | $('#scope').append( $('<option />').attr( "value", value ).text(value) ); |
b28e606e |
670 | }); |
671 | }); |
672 | }, |
673 | open: function() { |
674 | relation_manager.create_temporary( $('#source_node_id').val(), $('#target_node_id').val() ); |
9529f69c |
675 | $(".ui-widget-overlay").css("background", "none"); |
676 | $("#dialog_overlay").show(); |
677 | $("#dialog_overlay").height( $("#enlargement_container").height() ); |
fc018906 |
678 | $("#dialog_overlay").width( $("#enlargement_container").innerWidth() ); |
9529f69c |
679 | $("#dialog_overlay").offset( $("#enlargement_container").offset() ); |
b28e606e |
680 | }, |
681 | close: function() { |
9529f69c |
682 | relation_manager.remove_temporary(); |
b28e606e |
683 | $( '#status' ).empty(); |
684 | $("#dialog_overlay").hide(); |
685 | } |
686 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
6666d111 |
687 | if( ajaxSettings.url == getTextURL('relationships') |
688 | && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) { |
9529f69c |
689 | var errobj = jQuery.parseJSON( jqXHR.responseText ); |
690 | $('#status').append( '<p class="error">Error: ' + errobj.error + '</br>The relationship cannot be made.</p>' ); |
b28e606e |
691 | } |
aafcb75b |
692 | $(event.target).parent().find('.ui-button').button("enable"); |
b28e606e |
693 | } ); |
694 | |
9529f69c |
695 | $( "#delete-form" ).dialog({ |
696 | autoOpen: false, |
69a19c91 |
697 | height: 135, |
9529f69c |
698 | width: 160, |
699 | modal: false, |
700 | buttons: { |
701 | Cancel: function() { |
702 | $( this ).dialog( "close" ); |
703 | }, |
704 | Delete: function() { |
5f15640c |
705 | form_values = $('#delete_relation_form').serialize(); |
706 | ncpath = getTextURL( 'relationships' ); |
9529f69c |
707 | var jqjson = $.ajax({ url: ncpath, data: form_values, success: function(data) { |
708 | $.each( data, function(item, source_target) { |
45ee3b96 |
709 | relation_manager.remove( get_relation_id( source_target[0], source_target[1] ) ); |
9529f69c |
710 | }); |
711 | $( "#delete-form" ).dialog( "close" ); |
712 | }, dataType: 'json', type: 'DELETE' }); |
713 | } |
714 | }, |
715 | create: function(event, ui) { |
716 | var buttonset = $(this).parent().find( '.ui-dialog-buttonset' ).css( 'width', '100%' ); |
717 | buttonset.find( "button:contains('Cancel')" ).css( 'float', 'right' ); |
718 | var dialog_aria = $("div[aria-labelledby='ui-dialog-title-delete-form']"); |
719 | dialog_aria.mouseenter( function() { |
720 | if( mouseWait != null ) { clearTimeout(mouseWait) }; |
721 | }) |
722 | dialog_aria.mouseleave( function() { |
723 | mouseWait = setTimeout( function() { $("#delete-form").dialog( "close" ) }, 2000 ); |
724 | }) |
725 | }, |
726 | open: function() { |
727 | mouseWait = setTimeout( function() { $("#delete-form").dialog( "close" ) }, 2000 ); |
728 | }, |
729 | close: function() { |
730 | } |
731 | }); |
732 | |
76f05423 |
733 | // function for reading form dialog should go here; for now hide the element |
45ee3b96 |
734 | $('#reading-form').dialog({ |
735 | autoOpen: false, |
736 | height: 400, |
f2fb96fc |
737 | width: 600, |
45ee3b96 |
738 | modal: true, |
739 | buttons: { |
740 | Cancel: function() { |
741 | $( this ).dialog( "close" ); |
742 | }, |
a0a66634 |
743 | Update: function( evt ) { |
744 | // Disable the button |
745 | $(evt.target).button("disable"); |
6666d111 |
746 | $('#reading_status').empty(); |
0dcdd5ec |
747 | var reading_id = $('#reading_id').val() |
748 | form_values = { |
749 | 'id' : reading_id, |
997ebe92 |
750 | 'is_nonsense': $('#reading_is_nonsense').is(':checked'), |
751 | 'grammar_invalid': $('#reading_grammar_invalid').is(':checked'), |
0dcdd5ec |
752 | 'normal_form': $('#reading_normal_form').val() }; |
753 | // Add the morphology values |
754 | $('.reading_morphology').each( function() { |
465848bc |
755 | if( $(this).val() != '(Click to select)' ) { |
756 | var rmid = $(this).attr('id'); |
757 | rmid = rmid.substring(8); |
758 | form_values[rmid] = $(this).val(); |
759 | } |
0dcdd5ec |
760 | }); |
761 | // Make the JSON call |
762 | ncpath = getReadingURL( reading_id ); |
763 | var reading_element = readingdata[reading_id]; |
a0a66634 |
764 | // $(':button :contains("Update")').attr("disabled", true); |
45ee3b96 |
765 | var jqjson = $.post( ncpath, form_values, function(data) { |
766 | $.each( data, function(key, value) { |
0dcdd5ec |
767 | reading_element[key] = value; |
45ee3b96 |
768 | }); |
0dcdd5ec |
769 | if( $('#update_workspace_button').data('locked') == false ) { |
770 | color_inactive( get_ellipse( reading_id ) ); |
771 | } |
a0a66634 |
772 | $(evt.target).button("enable"); |
45ee3b96 |
773 | $( "#reading-form" ).dialog( "close" ); |
774 | }); |
0dcdd5ec |
775 | // Re-color the node if necessary |
776 | return false; |
45ee3b96 |
777 | } |
778 | }, |
0dcdd5ec |
779 | create: function() { |
0dcdd5ec |
780 | }, |
f2fb96fc |
781 | open: function() { |
782 | $(".ui-widget-overlay").css("background", "none"); |
783 | $("#dialog_overlay").show(); |
6666d111 |
784 | $('#reading_status').empty(); |
f2fb96fc |
785 | $("#dialog_overlay").height( $("#enlargement_container").height() ); |
786 | $("#dialog_overlay").width( $("#enlargement_container").innerWidth() ); |
787 | $("#dialog_overlay").offset( $("#enlargement_container").offset() ); |
465848bc |
788 | $("#reading-form").parent().find('.ui-button').button("enable"); |
f2fb96fc |
789 | }, |
45ee3b96 |
790 | close: function() { |
791 | $("#dialog_overlay").hide(); |
792 | } |
6666d111 |
793 | }).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { |
794 | if( ajaxSettings.url.lastIndexOf( getReadingURL('') ) > -1 |
795 | && ajaxSettings.type == 'POST' && jqXHR.status == 403 ) { |
796 | var errobj = jQuery.parseJSON( jqXHR.responseText ); |
797 | $('#reading_status').append( '<p class="error">Error: ' + errobj.error + '</p>' ); |
798 | } |
aafcb75b |
799 | $(event.target).parent().find('.ui-button').button("enable"); |
45ee3b96 |
800 | }); |
4c41c02c |
801 | |
76f05423 |
802 | |
b28e606e |
803 | $('#update_workspace_button').click( function() { |
804 | var svg_enlargement = $('#svgenlargement').svg().svg('get').root(); |
76f05423 |
805 | mouse_scale = svg_root_element.getScreenCTM().a; |
9529f69c |
806 | if( $(this).data('locked') == true ) { |
807 | $('#svgenlargement ellipse' ).each( function( index ) { |
808 | if( $(this).data( 'node_obj' ) != null ) { |
809 | $(this).data( 'node_obj' ).ungreyout_edges(); |
810 | $(this).data( 'node_obj' ).set_draggable( false ); |
811 | var node_id = $(this).data( 'node_obj' ).get_id(); |
812 | toggle_relation_active( node_id ); |
813 | $(this).data( 'node_obj', null ); |
814 | } |
b28e606e |
815 | }) |
b28e606e |
816 | $(this).data('locked', false); |
9529f69c |
817 | $(this).css('background-position', '0px 44px'); |
b28e606e |
818 | } else { |
9529f69c |
819 | var left = $('#enlargement').offset().left; |
820 | var right = left + $('#enlargement').width(); |
76f05423 |
821 | var tf = svg_root_element.getScreenCTM().inverse(); |
9529f69c |
822 | var p = svg_root.createSVGPoint(); |
823 | p.x=left; |
824 | p.y=100; |
825 | var cx_min = p.matrixTransform(tf).x; |
826 | p.x=right; |
827 | var cx_max = p.matrixTransform(tf).x; |
828 | $('#svgenlargement ellipse').each( function( index ) { |
829 | var cx = parseInt( $(this).attr('cx') ); |
830 | if( cx > cx_min && cx < cx_max) { |
831 | if( $(this).data( 'node_obj' ) == null ) { |
832 | $(this).data( 'node_obj', new node_obj( $(this) ) ); |
833 | } else { |
834 | $(this).data( 'node_obj' ).set_draggable( true ); |
835 | } |
836 | $(this).data( 'node_obj' ).greyout_edges(); |
837 | var node_id = $(this).data( 'node_obj' ).get_id(); |
838 | toggle_relation_active( node_id ); |
b28e606e |
839 | } |
9529f69c |
840 | }); |
841 | $(this).css('background-position', '0px 0px'); |
b28e606e |
842 | $(this).data('locked', true ); |
b28e606e |
843 | } |
844 | }); |
845 | |
e847b186 |
846 | $('.helptag').popupWindow({ |
847 | height:500, |
848 | width:800, |
849 | top:50, |
850 | left:50, |
851 | scrollbars:1 |
852 | }); |
853 | |
854 | |
9529f69c |
855 | function toggle_relation_active( node_id ) { |
856 | $('#svgenlargement .relation').find( "title:contains('" + node_id + "')" ).each( function(index) { |
857 | matchid = new RegExp( "^" + node_id ); |
858 | if( $(this).text().match( matchid ) != null ) { |
45ee3b96 |
859 | var relation_id = $(this).parent().attr('id'); |
860 | relation_manager.toggle_active( relation_id ); |
9529f69c |
861 | }; |
862 | }); |
b28e606e |
863 | } |
b28e606e |
864 | |
76f05423 |
865 | expandFillPageClients(); |
866 | $(window).resize(function() { |
867 | expandFillPageClients(); |
868 | }); |
869 | |
9529f69c |
870 | }); |
b28e606e |
871 | |
872 | |
76f05423 |
873 | function expandFillPageClients() { |
874 | $('.fillPage').each(function () { |
875 | $(this).height($(window).height() - $(this).offset().top - MARGIN); |
876 | }); |
877 | } |
878 | |
879 | function loadSVG(svgData) { |
880 | var svgElement = $('#svgenlargement'); |
881 | |
882 | $(svgElement).svg('destroy'); |
883 | |
884 | $(svgElement).svg({ |
885 | loadURL: svgData, |
886 | onLoad : svgEnlargementLoaded |
887 | }); |
888 | } |
889 | |
890 | |
891 | /* OS Gadget stuff |
892 | |
893 | function svg_select_callback(topic, data, subscriberData) { |
894 | svgData = data; |
895 | loadSVG(svgData); |
896 | } |
897 | |
898 | function loaded() { |
899 | var prefs = new gadgets.Prefs(); |
900 | var preferredHeight = parseInt(prefs.getString('height')); |
901 | if (gadgets.util.hasFeature('dynamic-height')) gadgets.window.adjustHeight(preferredHeight); |
902 | expandFillPageClients(); |
903 | } |
904 | |
905 | if (gadgets.util.hasFeature('pubsub-2')) { |
906 | gadgets.HubSettings.onConnect = function(hum, suc, err) { |
907 | subId = gadgets.Hub.subscribe("interedition.svg.selected", svg_select_callback); |
908 | loaded(); |
909 | }; |
910 | } |
911 | else gadgets.util.registerOnLoadHandler(loaded); |
912 | */ |