123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /* This file is part of AToMPM - A Tool for Multi-Paradigm Modelling
- * Copyright 2011 by the AToMPM team and licensed under the LGPL
- * See COPYING.lesser and README.md in the root of this project for full details
- */
- // DEPRECATED FUNCTIONS
- ///////////////////////////////////////////////////////////////////////////////
- function _copy(){
- AtomPMClient.alertDeprecatedFunctionCall("_copy");
- EditUtils.copy();
- }
- function _paste(){
- AtomPMClient.alertDeprecatedFunctionCall("_paste");
- EditUtils.paste();
- }
- function _redo(){
- AtomPMClient.alertDeprecatedFunctionCall("_redo");
- EditUtils.redo();
- }
- function _undo(){
- AtomPMClient.alertDeprecatedFunctionCall("_undo");
- EditUtils.undo();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // DEPRECATED FUNCTIONS
- ///////////////////////////////////////////////////////////////////////////////
- /* copies the full AS and CS of selected icons into a cross-tab/window storage
- area
-
- NOTE: the use of window.localStorage enables copy-pasting across atompm
- instances... this could also have been accomplished via cookies albeit
- less efficiently since cookies are logged around during every backend
- request/response */
- EditUtils = function(){
-
- /**
- * This copies the currently selected element(s) to the local
- * clipboard object
- */
- this.copy = function() {
- if( __selection == undefined || __selection['items'].length == 0 )
- return;
- else if( ! GeometryUtils.areTransformationsAllowed() )
- {
- console.warn('copy-pasting is only enabled if all of the ends of selected'
- +' edges are also selected, and if the geometry controls are'
- +' inactive');
- return;
- }
-
- var icons =
- __selection['items'].filter( function(it) {return it in __icons;} ),
- todo = icons.length,
- cpdata = {};
- icons.forEach(
- function(uri)
- {
- if( cpdata == undefined )
- return;
- HttpUtils.httpReq(
- 'GET',
- HttpUtils.url(uri,__NO_USERNAME),
- '&full=1',
- function(statusCode,resp)
- {
- if( ! utils.isHttpSuccessCode(statusCode) )
- {
- WindowManagement.openDialog(_ERROR,'failed to retrieve copy data :: '+resp);
- cpdata = undefined;
- return;
- }
- else
- {
- var data = utils.jsonp(resp)['data'],
- cs = utils.jsonp(data['cs']),
- as = utils.jsonp(data['as']),
- csattrs = {},
- asattrs = {};
- for( var attr in cs )
- csattrs[attr] = cs[attr]['value'];
- for( var attr in as )
- asattrs[attr] = as[attr]['value'];
- delete csattrs['$type'];
- delete csattrs['$asuri'];
- delete asattrs['$type'];
- cpdata[uri] = {'cs':csattrs,'as':asattrs};
- }
-
- if( --todo == 0 )
- window.localStorage.setItem('clipboard',utils.jsons(cpdata));
- });
- });
- };
-
- /* paste clipboard contents by building [and sending] batchEdit query filled
- with node creation/connection requests
- 0. produce metamodel loading requests for missing clipboard entry metamodels,
- if any
- 1. sort contents such that non-Links get handled first... this is merely an
- optimization that optimizes step 2.
- 2. while clipboard items remain,
- .) shift first item
- a) if item is a non-connection type, produce a creation request for it
- and remember its index in 'it2creq'
- a) otherwise,
- i. if both connection ends have entries in 'it2creq', produce a
- creation request for item and remember its index in 'it2creq'
- i. otherwise, push item at the end of the list of remaining items
- clipboard data for the given item is used to populate the request's
- 'attrs', ['src', 'dest'] and 'hitchhiker.clone' parameters
- 3. send off the batchEdit request
- 4. on completion, select newly created nodes and edges
- NOTE 1:: to connect to-be created nodes and to select them, we need their ids
- ... unfortunately, the csworker can not return the csid of a newly
- requested node (this csid will only come to be when the csworker
- handles the asworker's MKNODE)... for this reason, paste batchEdits
- are directed to our asworker (who responds to creation requests with
- the asids of newly created nodes)
- NOTE 2:: the 'it2creq' data structure is used to remember which request is
- associated to which to-be node... this is needed for connection
- requests with parameterized source and destination ids
- NOTE 3:: a limitation of the current implementation (which could fairly
- easily be overcome) is that Link '$segments' are expected to always
- contain exactly 2 entries
- NOTE 4:: selection of pasted elements requires that all icons be created...
- the batchEdit response only indicates that all asworker entities
- have been created: their associated icons might not all exist yet...
- to this end, a timed-loop checks for all the icons to be created
- before triggering selection... this works but it isn't perfect for
- 3 reasons
- 1. there might be a visible lag before selecting
- 2. a malicious user could cause the timed-loop to run forever
- by deleting pasted entities before the loop detects their
- creation
- 3. the loop almost always runs in O(||__icons||) */
- /**
- * Pastes the current contents of the clipboard.
- */
- this.paste = function() {
- var clipboard = utils.jsonp(window.localStorage.getItem('clipboard'));
- if( clipboard == null )
- {
- console.warn('clipboard is empty');
- return;
- }
-
- var toload = {},
- requests = [],
- it2creq = {},
- tmpasuri =
- function(csuri,reqi)
- {
- var matches = csuri.match(
- /^(.*)\..*Icons(\.pattern){0,1}(\/.*)Link\/[a-zA-Z0-9]*\.instance$/) ||
- csuri.match(
- /^(.*)\..*Icons(\.pattern){0,1}(\/.*)Icon\/[a-zA-Z0-9]*\.instance$/);
- return matches[1]+
- (matches[2] || '')+
- matches[3]+'/$'+reqi+'$.instance';
- },
- cburis = utils.keys(clipboard);
-
- cburis.forEach(
- function(uri)
- {
- var imm = __getMetamodel(uri)+'.metamodel',
- asmm = __iconMetamodelToMetamodel(imm);
- if( (!(asmm in __loadedToolbars) || !(imm in __loadedToolbars)) &&
- !(imm in toload) )
- {
- requests.push(
- {'method':'PUT',
- 'uri':HttpUtils.url('/current.metamodels', __NO_USERNAME+__NO_WID),
- 'reqData':
- {'mm':HttpUtils.url(asmm,__NO_WID),
- 'hitchhiker':{'path':HttpUtils.url(imm,__NO_WID)}}});
- toload[imm] = 1;
- }
- });
-
- cburis.sort( function(a,b) {return (__isConnectionType(a) ? 1 : -1);} );
- while( cburis.length > 0 )
- {
- var uri = cburis.shift(),
- matches = uri.match(
- /^(.*)\..*Icons(\.pattern){0,1}(\/.*)Link\/[a-zA-Z0-9]*\.instance$/) ||
- uri.match(
- /^(.*)\..*Icons(\.pattern){0,1}(\/.*)Icon\/[a-zA-Z0-9]*\.instance$/),
- type = matches[1]+(matches[2] || '')+matches[3]+'.type';
-
- if( ! __isConnectionType(uri) )
- {
- it2creq[uri] = requests.length;
- requests.push(
- {'method':'POST',
- 'uri':HttpUtils.url(type,__NO_USERNAME+__NO_WID),
- 'reqData':
- {'attrs':clipboard[uri]['as'],
- 'hitchhiker':{'clone':clipboard[uri]['cs']}}});
- }
- else
- {
- var segments = clipboard[uri]['cs']['$segments'],
- src = undefined,
- dest = undefined,
- asSrc,
- asDest;
-
- for( var edgeId in segments )
- {
- var ends = __edgeId2ends(edgeId);
- if( ends[0] == uri )
- dest = ends[1];
- else
- src = ends[0];
- }
- src = (src || uri);
- dest = (dest || uri);
-
- if( it2creq[src] == undefined || it2creq[dest] == undefined )
- cburis.push(uri);
- else
- {
- delete clipboard[uri]['cs']['$segments'];
- it2creq[uri] = requests.length;
- asSrc = tmpasuri(src,it2creq[src]);
- asDest = tmpasuri(dest,it2creq[dest]);
- requests.push(
- {'method':'POST',
- 'uri':HttpUtils.url(type,__NO_USERNAME+__NO_WID),
- 'reqData':
- {'attrs':clipboard[uri]['as'],
- 'src': asSrc,
- 'dest': asDest,
- 'hitchhiker':
- {'clone':clipboard[uri]['cs'],
- 'asSrc':asSrc,
- 'asDest':asDest,
- 'segments':
- [segments[src+'--'+uri],
- segments[uri+'--'+dest]]}}});
- }
- }
- }
-
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url('/batchEdit',__NO_USERNAME+__NO_WID)+'?wid='+__aswid,
- requests,
- function(statusCode,resp)
- {
- if( ! utils.isHttpSuccessCode(statusCode) )
- {
- WindowManagement.openDialog(_ERROR, 'paste failed on :: '+resp);
- return;
- }
-
- var results = utils.jsonp(resp)['data']['results'],
- asids = results.filter(function(r) {return 'data' in r;}).
- map(function(r) {return ''+r['data'];}),
- csuris = [],
- selectResults =
- function()
- {
- for( var uri in __icons )
- {
- var id = __icons[uri]['icon'].getAttr('__asuri').
- match(/.*\/(.*)\.instance/)[1];
-
- if( (idx=asids.indexOf(id)) > -1 )
- {
- if( __isConnectionType(uri) )
- csuris = csuris.concat(
- __icons[uri]['edgesIn'],__icons[uri]['edgesOut']);
- csuris.push(uri);
- asids.splice(idx,1);
- }
-
- if( asids.length == 0 )
- return BehaviorManager.handleUserEvent(__EVENT_CODED_SELECTION,csuris);
- }
- window.setTimeout(selectResults,100);
- };
- selectResults();
- });
- };
-
- /**
- * Redo the last undone action
- */
- this.redo = function(){
- BehaviorManager.handleUserEvent(__EVENT_CODED_CANVAS_EDIT);
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url('/redo',__NO_USERNAME));
- };
-
- /**
- * Undo the last performed action
- */
- this.undo = function() {
- BehaviorManager.handleUserEvent(__EVENT_CODED_CANVAS_EDIT);
- HttpUtils.httpReq(
- 'POST',
- HttpUtils.url('/undo',__NO_USERNAME));
- };
-
- return this;
- }();
|