all-zutai.js 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055
  1. Ext.ns('App');
  2. App = {
  3. webforms: {},
  4. init: function() {
  5. Ext.QuickTips.init();
  6. this.propertyManager = new App.property.PropertyManager();
  7. var viewport = new Ext.Viewport({
  8. layout: 'border',
  9. items: [
  10. this.createNorth(),
  11. this.createSouth(),
  12. this.createWest(),
  13. this.createEast(),
  14. this.createCenter()
  15. ]
  16. });
  17. this.initEditor();
  18. setTimeout(function() {
  19. Ext.get('loading').remove();
  20. Ext.get('loading-mask').fadeOut({remove:true});
  21. }, 100);
  22. },
  23. initEditor: function() {
  24. var xml = "<?xml version='1.0' encoding='UTF-8'?>"
  25. + "<process></process>";
  26. var editor = new Gef.jbs.ExtEditor();
  27. var input = new Gef.jbs.JBSEditorInput();
  28. input.readXml(xml);
  29. var workbenchWindow = new Gef.ui.support.DefaultWorkbenchWindow();
  30. workbenchWindow.getActivePage().openEditor(editor, input);
  31. workbenchWindow.render();
  32. Gef.activeEditor = editor;
  33. this.propertyManager.initSelectionListener(editor);
  34. },
  35. getProcessModel: function() {
  36. var viewer = Gef.activeEditor.getGraphicalViewer();
  37. var processEditPart = viewer.getContents();
  38. return processEditPart.model;
  39. },
  40. createNorth: function() {
  41. var p = null;
  42. if (Gef.MODE_DEMO === true) {
  43. p = new Ext.Panel({
  44. region: 'north'
  45. });
  46. } else {
  47. p = new Ext.Panel({
  48. region: 'north',
  49. html: '<h1 id="pageh1">Web户型图设计器 - 多比图形控件演示<h1>'
  50. });
  51. }
  52. App.northPanel = p;
  53. return p;
  54. },
  55. createSouth: function() {
  56. var p = this.propertyManager.getBottom();
  57. return p;
  58. },
  59. createWest: function() {
  60. var p = new App.PalettePanel({
  61. collapsible: true
  62. });
  63. App.westPanel = p;
  64. return p;
  65. },
  66. createEast: function() {
  67. var p = this.propertyManager.getRight();
  68. return p;
  69. },
  70. createCenter: function() {
  71. var p = new App.CanvasPanel();
  72. App.centerPanel = p;
  73. return p;
  74. },
  75. getSelectionListener: function() {
  76. if (!this.selectionListener) {
  77. this.selectionListener = new Gef.jbs.ExtSelectionListener(null);
  78. }
  79. return this.selectionListener;
  80. }
  81. };
  82. /*
  83. Gef.override(App.PalettePanel, {
  84. configItems: function() {
  85. this.html = 'sdfasfdfdsa';
  86. }
  87. });
  88. */
  89. //Gef.PALETTE_TYPE = 'plain';
  90. Gef.PALETTE_TYPE = 'accordion';
  91. Ext.onReady(App.init, App);
  92. App.CanvasPanel = Ext.extend(Ext.Panel, {
  93. initComponent: function() {
  94. //this.on('bodyresize', function(p, w, h) {
  95. // var b = p.body.getBox();
  96. //});
  97. this.region = 'center';
  98. this.autoScroll = true;
  99. this.tbar = new Ext.Toolbar([{
  100. text: '新建',
  101. iconCls: 'tb-new',
  102. handler: function() {
  103. Gef.activeEditor.reset();
  104. }
  105. }, {
  106. text: '导入',
  107. iconCls: 'tb-webform',
  108. handler: function() {
  109. var xml = Gef.activeEditor.serial();
  110. if (!this.openWin) {
  111. this.openWin = new Ext.Window({
  112. title: 'xml',
  113. layout: 'fit',
  114. width: 500,
  115. height: 300,
  116. closeAction: 'hide',
  117. modal: true,
  118. items: [{
  119. id: '__gef_jbpm4_xml_import__',
  120. xtype: 'textarea'
  121. }],
  122. buttons: [{
  123. text: '导入',
  124. handler: function() {
  125. var xml = Ext.getDom('__gef_jbpm4_xml_import__').value;
  126. Gef.activeEditor.resetAndOpen(xml);
  127. this.openWin.hide();
  128. },
  129. scope: this
  130. }, {
  131. text: '取消',
  132. handler: function() {
  133. this.openWin.hide();
  134. },
  135. scope: this
  136. }]
  137. });
  138. this.openWin.on('show', function() {
  139. Gef.activeEditor.disable();
  140. });
  141. this.openWin.on('hide', function() {
  142. Gef.activeEditor.enable();
  143. });
  144. }
  145. this.openWin.show(null, function() {
  146. Ext.getDom('__gef_jbpm4_xml_import__').value = xml;
  147. });
  148. }
  149. }, {
  150. text: '导出',
  151. iconCls: 'tb-prop',
  152. handler: function() {
  153. var xml = Gef.activeEditor.serial();
  154. if (!this.openWin) {
  155. this.openWin = new Ext.Window({
  156. title: 'xml',
  157. layout: 'fit',
  158. width: 500,
  159. height: 300,
  160. closeAction: 'hide',
  161. modal: true,
  162. items: [{
  163. id: '__gef_jbpm4_xml_export__',
  164. xtype: 'textarea'
  165. }],
  166. buttons: [{
  167. text: '关闭',
  168. handler: function() {
  169. this.openWin.hide();
  170. },
  171. scope: this
  172. }]
  173. });
  174. this.openWin.on('show', function() {
  175. Gef.activeEditor.disable();
  176. });
  177. this.openWin.on('hide', function() {
  178. Gef.activeEditor.enable();
  179. });
  180. }
  181. this.openWin.show(null, function() {
  182. Ext.getDom('__gef_jbpm4_xml_export__').value = xml;
  183. });
  184. }
  185. }, {
  186. text: '保存',
  187. iconCls: 'tb-save',
  188. handler: function() {
  189. var editor = Gef.activeEditor;
  190. var xml = editor.serial();
  191. var name = editor.getGraphicalViewer().getContents().getModel().text;
  192. Ext.Msg.wait('正在保存');
  193. Ext.Ajax.request({
  194. method: 'post',
  195. url: Gef.SAVE_URL,
  196. success: function(response) {
  197. try {
  198. var o = Ext.decode(response.responseText);
  199. if (o.success === true) {
  200. Ext.Msg.alert('信息', '操作成功');
  201. } else {
  202. Ext.Msg.alert('错误', o.errors.msg);
  203. }
  204. } catch(e) {
  205. Ext.Msg.alert('系统错误', response.responseText);
  206. }
  207. },
  208. failure: function(response) {
  209. Ext.Msg.alert('系统错误', response.responseText);
  210. },
  211. params: {
  212. id: Gef.PROCESS_ID,
  213. processName: name,
  214. xml: xml
  215. }
  216. });
  217. }
  218. }, {
  219. text: '发布',
  220. iconCls: 'tb-deploy',
  221. handler: function() {
  222. var editor = Gef.activeEditor;
  223. var isValid = new Validation(editor).validate();
  224. if (!isValid) {
  225. return false;
  226. }
  227. var xml = editor.serial();
  228. var model = editor.getGraphicalViewer().getContents().getModel();
  229. var name = model.text;
  230. Ext.Msg.wait('正在发布');
  231. Ext.Ajax.request({
  232. method: 'post',
  233. url: Gef.DEPLOY_URL,
  234. success: function(response) {
  235. try {
  236. var o = Ext.decode(response.responseText);
  237. if (o.success === true) {
  238. Ext.Msg.alert('信息', '操作成功');
  239. } else {
  240. Ext.Msg.alert('错误', o.errors.msg);
  241. }
  242. } catch(e) {
  243. Ext.Msg.alert('系统错误', response.responseText);
  244. }
  245. },
  246. failure: function(response) {
  247. Ext.Msg.alert('系统错误', response.responseText);
  248. },
  249. params: {
  250. id: Gef.PROCESS_ID,
  251. procCatId: model.procCatId,
  252. procDefName: model.procDefName,
  253. procDefCode: model.procDefCode,
  254. procVerName: model.procVerName,
  255. xml: xml
  256. }
  257. });
  258. }
  259. }, {
  260. text: '清空',
  261. iconCls: 'tb-clear',
  262. handler: function() {
  263. Gef.activeEditor.clear();
  264. }
  265. }, {
  266. text: '撤销',
  267. iconCls: 'tb-undo',
  268. handler: function() {
  269. var viewer = Gef.activeEditor.getGraphicalViewer();
  270. var browserListener = viewer.getBrowserListener();
  271. var selectionManager = browserListener.getSelectionManager();
  272. selectionManager.clearAll();
  273. var commandStack = viewer.getEditDomain().getCommandStack();
  274. commandStack.undo();
  275. },
  276. scope: this
  277. }, {
  278. text: '重做',
  279. iconCls: 'tb-redo',
  280. handler: function() {
  281. var viewer = Gef.activeEditor.getGraphicalViewer();
  282. var browserListener = viewer.getBrowserListener();
  283. var selectionManager = browserListener.getSelectionManager();
  284. selectionManager.clearAll();
  285. var commandStack = viewer.getEditDomain().getCommandStack();
  286. commandStack.redo();
  287. },
  288. scope: this
  289. }, {
  290. text: '布局',
  291. iconCls: 'tb-activity',
  292. handler: function() {
  293. var viewer = Gef.activeEditor.getGraphicalViewer();
  294. var browserListener = viewer.getBrowserListener();
  295. var selectionManager = browserListener.getSelectionManager();
  296. selectionManager.clearAll();
  297. new Layout(Gef.activeEditor).doLayout();
  298. },
  299. scope: this
  300. }, {
  301. text: '删除',
  302. iconCls: 'tb-delete',
  303. handler: this.removeSelected,
  304. scope: this
  305. }]);
  306. App.CanvasPanel.superclass.initComponent.call(this);
  307. },
  308. afterRender: function() {
  309. App.CanvasPanel.superclass.afterRender.call(this);
  310. var width = 1500;
  311. var height = 1000;
  312. Ext.DomHelper.append(this.body, [{
  313. id: '__gef_jbs__',
  314. tag: 'div',
  315. style: 'width:' + (width + 10) + 'px;height:' + (height + 10) + 'px;',
  316. children: [{
  317. id: '__gef_jbs_center__',
  318. tag: 'div',
  319. style: 'width:' + width + 'px;height:' + height + 'px;float:left;'
  320. }, {
  321. id: '__gef_jbs_right__',
  322. tag: 'div',
  323. style: 'width:10px;height:' + height + 'px;float:left;background-color:#EEEEEE;cursor:pointer;'
  324. }, {
  325. id: '__gef_jbs_bottom__',
  326. tag: 'div',
  327. style: 'width:' + (width + 10) + 'px;height:10px;float:left;background-color:#EEEEEE;cursor:pointer;'
  328. }]
  329. }]);
  330. var rightEl = Ext.fly('__gef_jbs_right__');
  331. rightEl.on('mouseover', function(e) {
  332. var t = e.getTarget();
  333. t.style.backgroundColor = 'yellow';
  334. t.style.backgroundImage = 'url(images/arrow/arrow-right.png)';
  335. });
  336. rightEl.on('mouseout', function(e) {
  337. var t = e.getTarget();
  338. t.style.backgroundColor = '#EEEEEE';
  339. t.style.backgroundImage = '';
  340. });
  341. rightEl.on('click', function(e) {
  342. Ext.fly('__gef_jbs__').setWidth(Ext.fly('__gef_jbs__').getWidth() + 100);
  343. Ext.fly('__gef_jbs_center__').setWidth(Ext.fly('__gef_jbs_center__').getWidth() + 100);
  344. Ext.fly('__gef_jbs_bottom__').setWidth(Ext.fly('__gef_jbs_bottom__').getWidth() + 100);
  345. Gef.activeEditor.addWidth(100);
  346. });
  347. var bottomEl = Ext.fly('__gef_jbs_bottom__');
  348. bottomEl.on('mouseover', function(e) {
  349. var t = e.getTarget();
  350. t.style.backgroundColor = 'yellow';
  351. t.style.backgroundImage = 'url(images/arrow/arrow-bottom.png)';
  352. });
  353. bottomEl.on('mouseout', function(e) {
  354. var t = e.getTarget();
  355. t.style.backgroundColor = '#EEEEEE';
  356. t.style.backgroundImage = '';
  357. });
  358. rightEl.on('click', function(e) {
  359. Ext.fly('__gef_jbs__').setHeight(Ext.fly('__gef_jbs__').getHeight() + 100);
  360. Ext.fly('__gef_jbs_center__').setHeight(Ext.fly('__gef_jbs_center__').getHeight() + 100);
  361. Ext.fly('__gef_jbs_right__').setHeight(Ext.fly('__gef_jbs_right__').getHeight() + 100);
  362. Gef.activeEditor.addHeight(100);
  363. });
  364. this.body.on('contextmenu', this.onContextMenu, this);
  365. },
  366. onContextMenu: function(e) {
  367. if (!this.contextMenu) {
  368. this.contextMenu = new Ext.menu.Menu({
  369. items: [{
  370. text: '详细配置',
  371. iconCls: 'tb-prop',
  372. handler: this.showWindow,
  373. scope: this
  374. }, {
  375. text: '删除',
  376. iconCls: 'tb-remove',
  377. handler: this.removeSelected,
  378. scope: this
  379. }]
  380. });
  381. }
  382. e.preventDefault();
  383. this.contextMenu.showAt(e.getXY());
  384. },
  385. showWindow: function() {
  386. App.propertyManager.changePropertyStatus('max');
  387. },
  388. removeSelected: function() {
  389. var viewer = Gef.activeEditor.getGraphicalViewer();
  390. var browserListener = viewer.getBrowserListener();
  391. var selectionManager = browserListener.getSelectionManager();
  392. var edge = selectionManager.selectedConnection;
  393. var nodes = selectionManager.items;
  394. var request = {};
  395. if (edge != null) {
  396. request.role = {
  397. name: 'REMOVE_EDGE'
  398. };
  399. this.executeCommand(edge, request);
  400. selectionManager.removeSelectedConnection();
  401. } else if (nodes.length > 0) {
  402. request.role = {
  403. name: 'REMOVE_NODES',
  404. nodes: nodes
  405. };
  406. this.executeCommand(viewer.getContents(), request);
  407. selectionManager.clearAll();
  408. }
  409. },
  410. executeCommand: function(editPart, request) {
  411. var command = editPart.getCommand(request);
  412. if (command != null) {
  413. Gef.activeEditor.getGraphicalViewer().getEditDomain().getCommandStack().execute(command);
  414. }
  415. }
  416. });
  417. /*
  418. * Compressed by JSA(www.xidea.org)
  419. */
  420. Layout = function(editor) {
  421. this.editor = editor;
  422. this.processEditPart = editor.getGraphicalViewer().getContents();
  423. this.processModel = this.processEditPart.getModel();
  424. };
  425. Layout.prototype = {
  426. doLayout: function() {
  427. var diagram = new Diagram();
  428. diagram.init(this.processModel);
  429. var sorter = new TopologicalSorter(diagram);
  430. var sortedElements = sorter.getSortedElements();
  431. var sortedIds = [];
  432. for (var i = 0; i < sortedElements.length; i++) {
  433. sortedIds.push(sortedElements[i].id);
  434. }
  435. //console.info(sortedIds);
  436. var layouter = new LeftToRightGridLayouter(diagram, sortedIds);
  437. layouter.doLayout();
  438. var edgeMap = diagram.getEdgeMap();
  439. for (var edgeId in edgeMap) {
  440. var edge = edgeMap[edgeId];
  441. new EdgeLayouter(layouter.grid, edge);
  442. }
  443. diagram.updateModel();
  444. }
  445. };
  446. ;
  447. Diagram = function() {
  448. };
  449. Diagram.prototype = {
  450. getNodeMap: function() {
  451. return this.nodeMap;
  452. },
  453. getEdgeMap: function() {
  454. return this.edgeMap;
  455. },
  456. init: function(process) {
  457. this.process = process;
  458. this.nodeMap = {};
  459. this.edgeMap = {};
  460. for (var i = 0; i < this.process.children.length; i++) {
  461. var child = process.children[i];
  462. var node = new Node();
  463. node.id = child.text;
  464. node.type = child.type;
  465. node.x = child.x;
  466. node.y = child.y;
  467. node.w = child.w;
  468. node.h = child.h;
  469. this.nodeMap[node.id] = node;
  470. }
  471. for (var i = 0; i < this.process.children.length; i++) {
  472. var child = process.children[i];
  473. for (var j = 0; j < child.getOutgoingConnections().length; j++) {
  474. var connection = child.getOutgoingConnections()[j];
  475. this.createEdge(connection);
  476. }
  477. }
  478. },
  479. createEdge: function(connection) {
  480. var connectionId = connection.getSource().text + '_' + connection.getTarget().text;
  481. var edge = this.edgeMap[connectionId];
  482. if (!edge) {
  483. edge = new Edge();
  484. edge.id = connectionId;
  485. edge.name = connection.text;
  486. edge.source = this.nodeMap[connection.getSource().text];
  487. edge.target = this.nodeMap[connection.getTarget().text];
  488. edge.source.outgoingLinks.push(edge);
  489. edge.target.incomingLinks.push(edge);
  490. this.edgeMap[connectionId] = edge;
  491. }
  492. },
  493. updateModel: function() {
  494. for (var nodeId in this.nodeMap) {
  495. var item = this.nodeMap[nodeId];
  496. var model = this.getModel(nodeId);
  497. model.x = item.x;
  498. model.y = item.y;
  499. model.getEditPart().getFigure().x = model.x;
  500. model.getEditPart().getFigure().y = model.y;
  501. for (var i = 0; i < item.outgoingLinks.length; i++) {
  502. var connection = item.outgoingLinks[i];
  503. var connectionModel = this.getConnectionModel(model, connection);
  504. if (connectionModel == null) {
  505. continue;
  506. }
  507. connectionModel.innerPoints = typeof connection.innerPoints == 'undefined' ? []
  508. : connection.innerPoints;
  509. connectionModel.textX = 0;
  510. connectionModel.textY = 0;
  511. connectionModel.getEditPart().getFigure().innerPoints = connectionModel.innerPoints;
  512. connectionModel.getEditPart().getFigure().textX = connectionModel.textX;
  513. connectionModel.getEditPart().getFigure().textY = connectionModel.textY;
  514. }
  515. }
  516. this.process.getEditPart().refresh();
  517. },
  518. getModel: function(name) {
  519. var model = null;
  520. Gef.each(this.process.children, function(item) {
  521. if (item.text == name) {
  522. model = item;
  523. return false;
  524. }
  525. });
  526. return model;
  527. },
  528. getConnectionModel: function(nodeModel, edge) {
  529. var model = null;
  530. Gef.each(nodeModel.getOutgoingConnections(), function(item) {
  531. if (item.getTarget().text == edge.getTarget().id) {
  532. model = item;
  533. return false;
  534. }
  535. });
  536. return model;
  537. }
  538. };
  539. ;
  540. // should be change name to LayoutingElement
  541. Node = function() {
  542. this.incomingLinks = [];
  543. this.outgoingLinks = [];
  544. };
  545. Node.prototype = {
  546. getIncomingLinks: function() {
  547. return this.incomingLinks;
  548. },
  549. getOutgoingLinks: function() {
  550. return this.outgoingLinks;
  551. },
  552. getPrecedingElements: function() {
  553. var previousElements = [];
  554. for (var i = 0; i < this.incomingLinks.length; i++) {
  555. previousElements.push(this.incomingLinks[i].source);
  556. }
  557. return previousElements;
  558. },
  559. getFollowingElements: function() {
  560. var followingElements = [];
  561. for (var i = 0; i < this.outgoingLinks.length; i++) {
  562. followingElements.push(this.outgoingLinks[i].target);
  563. }
  564. return followingElements;
  565. },
  566. isJoin: function() {
  567. return this.incomingLinks.length > 1;
  568. },
  569. isSplit: function() {
  570. return this.outgoingLinks.length > 1;
  571. },
  572. prevSplit: function() {
  573. var distance = 1000;
  574. var candidateDistance = 0;
  575. var split = null;
  576. var candidate = null;
  577. var precedingElements = this.getPrecedingElements();
  578. for (var i = 0; i < precedingElements.length; i++) {
  579. var elem = precedingElements[i];
  580. if (elem.isSplit()) {
  581. return elem;
  582. }
  583. candidate = elem.prevSplit();
  584. if (this.isJoin()) {
  585. // if this is not a join, we have only one precedingElement.
  586. candidateDistance = elem.backwardDistanceTo(candidate);
  587. }
  588. if (candidateDistance < distance) {
  589. split = candidate;
  590. distance = candidateDistance;
  591. }
  592. }
  593. return split;
  594. },
  595. backwardDistanceTo: function(other) {
  596. return this._backwardDistanceTo(other, []);
  597. },
  598. _backwardDistanceTo: function(other, historyElements) {
  599. if (other == this) {
  600. return 0;
  601. }
  602. if (historyElements.indexOf(this) != -1) {
  603. return 1000;
  604. }
  605. var d = 1000;
  606. var newHistory = [];
  607. newHistory.push(this);
  608. var precedingElements = this.getPrecedingElements();
  609. for (var i = 0; i < precedingElements.length; i++) {
  610. var el = precedingElements[i];
  611. d = Math.min(d, el._backwardDistanceTo(other, newHistory));
  612. }
  613. return d == 1000 ? d : d + 1;
  614. }
  615. };
  616. ;
  617. Edge = function() {
  618. this.source = null;
  619. this.target = null;
  620. };
  621. Edge.prototype = {
  622. getSource: function() {
  623. return this.source;
  624. },
  625. getTarget: function() {
  626. return this.target;
  627. },
  628. reverseOutgoingAndIncoming: function() {
  629. var index = 0;
  630. var oldSource = this.source;
  631. var oldTarget = this.target;
  632. index = oldSource.outgoingLinks.indexOf(this);
  633. oldSource.outgoingLinks.splice(index, 1);
  634. index = oldTarget.incomingLinks.indexOf(this);
  635. oldTarget.incomingLinks.splice(index, 1);
  636. var newSource = oldTarget;
  637. var newTarget = oldSource;
  638. newSource.outgoingLinks.push(this);
  639. newTarget.incomingLinks.push(this);
  640. this.source = newSource;
  641. this.target = newTarget;
  642. }
  643. };
  644. ;
  645. TopologicalSorter = function(diagram) {
  646. this.diagram = diagram;
  647. this.prepareDataAndSort(true);
  648. this.prepareDataAndSort(false);
  649. };
  650. TopologicalSorter.prototype = {
  651. getSortedElements: function() {
  652. return this.sortedElements;
  653. },
  654. prepareDataAndSort: function(shouldBackpatch) {
  655. this.sortedElements = [];
  656. this.elementsToSort = {};
  657. this.backwardsEdges = [];
  658. this.elementsToSortCount = 0;
  659. this.addAllChildren();
  660. this.topologicalSort();
  661. if (shouldBackpatch === true) {
  662. this.backpatchBackwardsEdges();
  663. }
  664. this.reverseBackwardsEdges();
  665. },
  666. addAllChildren: function() {
  667. for (var nodeId in this.diagram.nodeMap) {
  668. var node = this.diagram.nodeMap[nodeId];
  669. this.elementsToSort[nodeId] = new SortableLayoutingElement(node);
  670. this.elementsToSortCount++;
  671. }
  672. },
  673. topologicalSort: function() {
  674. var count = 0;
  675. var oldCount = 0;
  676. while (this.elementsToSortCount > 0) {
  677. var freeElements = this.getFreeElements();
  678. if (freeElements.length > 0) {
  679. for (var i = 0; i < freeElements.length; i++) {
  680. var freeElement = freeElements[i];
  681. this.sortedElements.push(freeElement.node);
  682. this.freeElementsFrom(freeElement);
  683. delete this.elementsToSort[freeElement.node.id];
  684. }
  685. } else {
  686. var entry = this.getLoopEntryPoint();
  687. for (var i = 0; i < entry.incomingLinks.length; i++) {
  688. var backId = entry.incomingLinks[i];
  689. entry.reverseIncomingLinkFrom(backId);
  690. var elem = this.elementsToSort[backId];
  691. elem.reverseOutgoingLinkTo(entry.node.id);
  692. this.backwardsEdges.push(new BackwardsEdge(backId, entry.node.id));
  693. }
  694. }
  695. }
  696. },
  697. backpatchBackwardsEdges: function() {
  698. var newBackwardsEdges = [];
  699. for (var i = 0; i < this.backwardsEdges.length; i++) {
  700. newBackwardsEdges.push(this.backwardsEdges[i]);
  701. }
  702. for (var i = 0; i < this.backwardsEdges.length; i++) {
  703. var edge = this.backwardsEdges[i];
  704. var sourceId = edge.getSource();
  705. var targetId = edge.getTarget();
  706. var sourceElement = this.diagram.nodeMap[sourceId];
  707. while (!(sourceElement.isJoin() || sourceElement.isSplit())) {
  708. var newSourceElement = sourceElement.getPrecedingElements()[0];
  709. targetId = newSourceElement.id;
  710. newBackwardsEdges.push(new BackwardsEdge(targetId, sourceId));
  711. sourceElement = newSourceElement;
  712. sourceId = targetId;
  713. }
  714. }
  715. this.backwardsEdges = newBackwardsEdges;
  716. },
  717. reverseBackwardsEdges: function() {
  718. var edgeMap = this.diagram.edgeMap;
  719. for (var i = 0; i < this.backwardsEdges.length; i++) {
  720. var backwardsEdge = this.backwardsEdges[i];
  721. var sourceId = backwardsEdge.getSource();
  722. var targetId = backwardsEdge.getTarget();
  723. var sourceElement = this.diagram.nodeMap[sourceId];
  724. var targetElement = this.diagram.nodeMap[targetId];
  725. var edge = this.getEdge(edgeMap, sourceElement, targetElement);
  726. backwardsEdge.setEdge(edge);
  727. if (edge) {
  728. // reverse edge outgoing and incoming
  729. edge.reverseOutgoingAndIncoming();
  730. }
  731. }
  732. },
  733. getFreeElements: function() {
  734. var freeElements = [];
  735. for (var nodeId in this.elementsToSort) {
  736. var elem = this.elementsToSort[nodeId];
  737. if (elem.isFree()) {
  738. freeElements.push(elem);
  739. }
  740. }
  741. return freeElements;
  742. },
  743. freeElementsFrom: function(freeElement) {
  744. for (var i = 0; i < freeElement.outgoingLinks.length; i++) {
  745. var id = freeElement.outgoingLinks[i];
  746. var targetElement = this.elementsToSort[id];
  747. if (targetElement) {
  748. targetElement.removeIncomingLinkFrom(freeElement.node.id);
  749. }
  750. }
  751. this.elementsToSortCount--;
  752. },
  753. getLoopEntryPoint: function() {
  754. for (var nodeId in this.elementsToSort) {
  755. var candidate = this.elementsToSort[nodeId];
  756. if (candidate.oldInCount > 1
  757. && candidate.oldInCount > candidate.incomingLinks.length) {
  758. return candidate;
  759. }
  760. }
  761. throw new Error('Could not find a valid loop entry point');
  762. },
  763. getEdge: function(edgeMap, sourceElement, targetElement) {
  764. for (var i = 0; i < sourceElement.outgoingLinks.length; i++) {
  765. var edge = sourceElement.outgoingLinks[i];
  766. if (edge.getTarget().id == targetElement.id) {
  767. return edge;
  768. }
  769. }
  770. return null;
  771. }
  772. };
  773. ;
  774. SortableLayoutingElement = function(node) {
  775. this.node = node;
  776. this.incomingLinks = [];
  777. this.outgoingLinks = [];
  778. for (var i = 0; i < node.incomingLinks.length; i++) {
  779. this.incomingLinks.push(node.incomingLinks[i].source.id);
  780. }
  781. for (var i = 0; i < node.outgoingLinks.length; i++) {
  782. this.outgoingLinks.push(node.outgoingLinks[i].target.id);
  783. }
  784. this.oldInCount = this.incomingLinks.length;
  785. this.isJoin = node.isJoin();
  786. };
  787. SortableLayoutingElement.prototype = {
  788. isFree: function() {
  789. return this.incomingLinks.length == 0;
  790. },
  791. removeIncomingLinkFrom: function(sourceId) {
  792. var index = this.incomingLinks.indexOf(sourceId);
  793. this.incomingLinks.splice(index, 1);
  794. },
  795. reverseIncomingLinkFrom: function(id) {
  796. this.removeIncomingLinkFrom(id);
  797. this.outgoingLinks.push(id);
  798. },
  799. reverseOutgoingLinkTo: function(id) {
  800. var index = this.outgoingLinks.indexOf(id);
  801. this.outgoingLinks.splice(index, 1);
  802. this.incomingLinks.push(id);
  803. }
  804. };
  805. ;
  806. BackwardsEdge = function(source, target) {
  807. this.source = source;
  808. this.target = target;
  809. };
  810. BackwardsEdge.prototype = {
  811. getEdge: function() {
  812. return this.edge;
  813. },
  814. setEdge: function(edge) {
  815. this.edge = edge;
  816. },
  817. getSource: function() {
  818. return this.source;
  819. },
  820. getTarget: function() {
  821. return this.target;
  822. }
  823. };
  824. ;
  825. LeftToRightGridLayouter = function(diagram, sortedIds) {
  826. this.diagram = diagram;
  827. this.sortedIds = sortedIds;
  828. };
  829. LeftToRightGridLayouter.prototype = {
  830. doLayout: function() {
  831. this.grid = new Grid();
  832. this.layoutElements();
  833. this.calcGeometry(this.grid);
  834. this.writeGeometry(this.grid);
  835. this.diagram.updateModel();
  836. },
  837. layoutElements: function() {
  838. for (var i = 0; i < this.sortedIds.length; i++) {
  839. var sortedId = this.sortedIds[i];
  840. var currentElement = this.diagram.nodeMap[sortedId];
  841. var precedingElements = currentElement.getPrecedingElements();
  842. var cellOfElement = this.placeElement(currentElement, precedingElements);
  843. if (currentElement.isJoin() && precedingElements.length != 0) {
  844. // there is an edge hitting us left, so lets forbid
  845. // interleaving to use the left cell, if this is empty
  846. cellOfElement.getPrevCell().setPackable(false);
  847. }
  848. if (currentElement.isSplit()) {
  849. this.prelayoutSuccessors(currentElement, cellOfElement);
  850. }
  851. }
  852. },
  853. placeElement: function(currentElement, precedingElements) {
  854. var newCell = null;
  855. if (precedingElements.length == 0) {
  856. this.grid.startCell.value = currentElement;
  857. newCell = this.grid.startCell;
  858. } else {
  859. var leftCell = null;
  860. var newCell = this.grid.getCellOfItem(currentElement);
  861. if (currentElement.isJoin()) {
  862. var splitFound = false;
  863. var split = currentElement.prevSplit();
  864. if (split != null) {
  865. var splits = new PriorityQueue(currentElement);
  866. splits.add(split);
  867. for (var i = 0; i < precedingElements.length; i++) {
  868. var elem = precedingElements[i];
  869. split = elem.prevSplit();
  870. if (split != null && !splits.contains(split)) {
  871. splits.add(split);
  872. //console.info(splits.items);
  873. }
  874. }
  875. split = null;
  876. // get split with most connections
  877. var maxCon = 0;
  878. for (var i = 0; i < splits.items.length; i++) {
  879. var target = splits.items[i];
  880. if (target == currentElement) {
  881. continue;
  882. }
  883. // current connections
  884. var curCon = 0;
  885. for (var j = 0; j < precedingElements.length; j++) {
  886. var elem = precedingElements[j];
  887. if (elem.backwardDistanceTo(target) < 1000) {
  888. curCon++;
  889. }
  890. }
  891. if (curCon > maxCon) {
  892. maxCon = curCon;
  893. split = target;
  894. }
  895. }
  896. splitFound = split != null;
  897. }
  898. // current cell position
  899. var x = 0;
  900. var yAcc = 0;
  901. var yCnt = 0;
  902. for (var i = 0; i < precedingElements.length; i++) {
  903. var elem = precedingElements[i];
  904. var tmp = this.grid.getCellOfItem(elem);
  905. if (tmp == null) {
  906. tmp = {
  907. getColIndex: function() {
  908. return 0;
  909. }
  910. };
  911. } else {
  912. yAcc += tmp.getRowIndex();
  913. yCnt++;
  914. }
  915. x = Math.max(x, tmp.getColIndex());
  916. }
  917. // farthest to the right
  918. if (splitFound) {
  919. leftCell = this.grid.getCellOfItem(split).row.cells[x];
  920. // set path to split unpackable
  921. for (var c = leftCell; c.value != split; c = c.getPrevCell()) {
  922. c.setPackable(false);
  923. }
  924. } else {
  925. if (yCnt == 0) {
  926. leftCell = this.grid.rows[0].above().cells[x];
  927. } else {
  928. leftCell = this.grid.rows[yAcc / yCnt].cells[x];
  929. }
  930. }
  931. if (newCell != null && newCell.value == currentElement) {
  932. newCell.value = null;
  933. }
  934. newCell = leftCell.after();
  935. // set all incoming pathes unpackable
  936. for (var i = 0; i < precedingElements.length; i++) {
  937. var el = precedingElements[i];
  938. var target = this.grid.getCellOfItem(el);
  939. if (target == null) {
  940. continue;
  941. }
  942. var start = target.row.cells[x + 1];
  943. for (var c = start; c != target; c = c.getPrevCell()) {
  944. c.setPackable(false);
  945. }
  946. }
  947. } else if (newCell == null) {
  948. // if not preLayouted
  949. var preElem = precedingElements[0];
  950. leftCell = this.grid.getCellOfItem(preElem);
  951. newCell = leftCell.after();
  952. }
  953. if (newCell.isFilled() && newCell.value != currentElement) {
  954. newCell.row.insertRowBeneath();
  955. newCell = newCell.beneath();
  956. }
  957. newCell.value = currentElement;
  958. newCell.getPrevCell().setPackable(false);
  959. }
  960. return newCell;
  961. },
  962. prelayoutSuccessors: function(currentElement, cellOfElement) {
  963. var baseCell = cellOfElement.after();
  964. var topCell = baseCell;
  965. var followingElements = currentElement.getFollowingElements();
  966. // heuristic for direct connection to join
  967. var directJoin = null;
  968. for (var i = 0; i < followingElements.length; i++) {
  969. var possibleJoin = followingElements[i];
  970. if (possibleJoin.isJoin()) {
  971. directJoin = possibleJoin;
  972. }
  973. }
  974. if (directJoin != null) {
  975. // put in the middle
  976. var index = followingElements.indexOf(directJoin);
  977. // remove
  978. followingElements.splice(index, 1);
  979. var position = parseInt(followingElements.length / 2, 10);
  980. // insert
  981. followingElements.splice(position, 0, directJoin);
  982. }
  983. // normal preLayout following elements
  984. var follow = parseInt(followingElements.length / 2, 10);
  985. for (var i = 0; i < follow; i++) {
  986. topCell.row.insertRowAbove();
  987. baseCell.row.insertRowBeneath();
  988. topCell = topCell.above();
  989. }
  990. for (var i = 0; i < followingElements.length; i++) {
  991. var newElem = followingElements[i];
  992. if (this.grid.getCellOfItem(newElem)) {
  993. continue;
  994. }
  995. topCell.value = newElem;
  996. topCell = topCell.beneath();
  997. if (topCell == baseCell && followingElements.length % 2 == 0) {
  998. topCell = topCell.beneath();
  999. }
  1000. }
  1001. },
  1002. calcGeometry: function(grid) {
  1003. grid.pack();
  1004. var heightOfRow = [];
  1005. for (var i = 0; i < grid.rowCount; i++) {
  1006. heightOfRow.push(0);
  1007. }
  1008. var widthOfColumn = [];
  1009. for (var i = 0; i < grid.colCount; i++) {
  1010. widthOfColumn.push(0);
  1011. }
  1012. for (var i = 0; i < grid.rowCount; i++) {
  1013. var row = grid.rows[i];
  1014. for (var j = 0; j < grid.colCount; j++) {
  1015. var cell = row.cells[j];
  1016. if (cell.isFilled()) {
  1017. var elem = cell.value;
  1018. widthOfColumn[j] = Math.max(widthOfColumn[j], elem.w + 30);
  1019. heightOfRow[i] = Math.max(heightOfRow[i], elem.h + 30);
  1020. }
  1021. }
  1022. }
  1023. this.heightOfRow = heightOfRow;
  1024. this.widthOfColumn = widthOfColumn;
  1025. this.totalWidth = 0;
  1026. this.totalHeight = 0;
  1027. for (var i = 0; i < grid.colCount; i++) {
  1028. this.totalWidth += widthOfColumn[i];
  1029. }
  1030. for (var i = 0; i < grid.rowCount; i++) {
  1031. this.totalHeight += heightOfRow[i];
  1032. }
  1033. },
  1034. writeGeometry: function(grid) {
  1035. var x = 0;
  1036. var y = 0;
  1037. for (var i = 0; i < grid.rowCount; i++) {
  1038. var row = grid.rows[i];
  1039. var cellHeight = this.heightOfRow[i];
  1040. for (var j = 0; j < grid.colCount; j++) {
  1041. var cell = row.cells[j];
  1042. var cellWidth = this.widthOfColumn[j];
  1043. if (cell.isFilled()) {
  1044. var elem = cell.value;
  1045. var newX = x + cellWidth / 2 - elem.w / 2;
  1046. var newY = y + cellHeight / 2 - elem.h / 2;
  1047. elem.x = newX;
  1048. elem.y = newY;
  1049. }
  1050. x += cellWidth;
  1051. }
  1052. x = 0;
  1053. y += cellHeight;
  1054. }
  1055. }
  1056. };
  1057. ;
  1058. Grid = function() {
  1059. var cell = new Cell();
  1060. var row = new Row();
  1061. row.grid = this;
  1062. row.addCell(cell);
  1063. this.rows = [row];
  1064. this.startCell = cell;
  1065. this.colCount = 1;
  1066. this.rowCount = this.rows.length;
  1067. };
  1068. Grid.prototype = {
  1069. addFirstRow: function() {
  1070. var row = new Row();
  1071. row.grid = this;
  1072. for (var i = 0; i < this.rolCount; i++) {
  1073. var cell = new Cell();
  1074. row.addCell(cell);
  1075. }
  1076. this.rows.unshift(row);
  1077. this.rowCount = this.rows.length;
  1078. },
  1079. addLastRow: function() {
  1080. var row = new Row();
  1081. row.grid = this;
  1082. for (var i = 0; i < this.rolCount; i++) {
  1083. row.addCell(new Cell());
  1084. }
  1085. this.rows.push(row);
  1086. this.rowCount = this.rows.length;
  1087. },
  1088. addLastCol: function() {
  1089. for (var i = 0; i < this.rowCount; i++) {
  1090. var row = this.rows[i];
  1091. row.addCell(new Cell());
  1092. }
  1093. this.colCount++;
  1094. },
  1095. getCellOfItem: function(elem) {
  1096. for (var i = 0; i < this.rowCount; i++) {
  1097. var row = this.rows[i];
  1098. for (var j = 0; j < this.colCount; j++) {
  1099. var cell = row.cells[j];
  1100. if (cell.value == elem) {
  1101. return cell;
  1102. }
  1103. }
  1104. }
  1105. return null;
  1106. },
  1107. pack: function() {
  1108. var changed = false;
  1109. do {
  1110. changed = false;
  1111. for (var i = 0; i < this.rows.length; i++) {
  1112. var row = this.rows[i];
  1113. changed |= row.tryInterleaveWith(row.getPrevRow());
  1114. }
  1115. for (var i = 0; i < this.rows.length; i++) {
  1116. var row = this.rows[i];
  1117. changed |= row.tryInterleaveWith(row.getNextRow());
  1118. }
  1119. } while (changed);
  1120. },
  1121. info: function() {
  1122. var value = '';
  1123. for (var i = 0; i < this.rows.length; i++) {
  1124. var row = this.rows[i];
  1125. for (var j = 0; j < row.cells.length; j++) {
  1126. var cell = row.cells[j];
  1127. var id = '[ ]';
  1128. if (cell.isFilled()) {
  1129. id = cell.value.id;
  1130. } else if (cell.packable === false) {
  1131. id = '[ p ]';
  1132. }
  1133. value += id;
  1134. }
  1135. value += '\n'
  1136. }
  1137. return value;
  1138. }
  1139. };
  1140. ;
  1141. Cell = function() {
  1142. this.packable = true;
  1143. };
  1144. Cell.prototype = {
  1145. isFilled: function() {
  1146. return typeof this.value != 'undefined' && this.value != null;
  1147. },
  1148. isUnpackable: function() {
  1149. return this.isFilled() || (this.packable === false);
  1150. },
  1151. setPackable: function(packable) {
  1152. this.packable = packable;
  1153. },
  1154. getRowIndex: function() {
  1155. return this.row.getIndex();
  1156. },
  1157. getColIndex: function() {
  1158. for (var i = 0; i < this.row.cells.length; i++) {
  1159. if (this.row.cells[i] == this) {
  1160. return i;
  1161. }
  1162. }
  1163. },
  1164. after: function() {
  1165. var colIndex = this.getColIndex();
  1166. if (colIndex == this.row.cells.length - 1) {
  1167. this.grid.addLastCol();
  1168. }
  1169. return this.row.cells[colIndex + 1];
  1170. },
  1171. above: function() {
  1172. var rowIndex = this.getRowIndex();
  1173. var colIndex = this.getColIndex();
  1174. if (rowIndex == 0) {
  1175. this.row.insertRowAbove();
  1176. }
  1177. return this.grid.rows[rowIndex - 1].cells[colIndex];
  1178. },
  1179. beneath: function() {
  1180. var rowIndex = this.getRowIndex();
  1181. var colIndex = this.getColIndex();
  1182. if (rowIndex == this.grid.rowCount - 1) {
  1183. this.row.insertRowBeneath();
  1184. }
  1185. return this.grid.rows[rowIndex + 1].cells[colIndex];
  1186. },
  1187. getPrevCell: function() {
  1188. var index = this.getColIndex();
  1189. return this.row.cells[index - 1];
  1190. },
  1191. getNextCell: function() {
  1192. var index = this.getColIndex();
  1193. return this.row.cells[index + 1];
  1194. }
  1195. };
  1196. ;
  1197. Row = function() {
  1198. this.cells = [];
  1199. };
  1200. Row.prototype = {
  1201. addCell: function(cell) {
  1202. cell.row = this;
  1203. cell.grid = this.grid;
  1204. this.cells.push(cell);
  1205. },
  1206. getIndex: function() {
  1207. for (var i = 0; i < this.grid.rows.length; i++) {
  1208. if (this.grid.rows[i] == this) {
  1209. return i;
  1210. }
  1211. }
  1212. },
  1213. insertRowBeneath: function() {
  1214. var row = new Row();
  1215. row.grid = this.grid;
  1216. for (var i = 0; i < this.grid.colCount; i++) {
  1217. row.addCell(new Cell());
  1218. }
  1219. var rowIndex = this.getIndex();
  1220. var rows = this.grid.rows;
  1221. if (rowIndex == rows.length - 1) {
  1222. rows.push(row);
  1223. } else {
  1224. rows.splice(rowIndex + 1, 0, row);
  1225. }
  1226. this.grid.rowCount = rows.length;
  1227. },
  1228. insertRowAbove: function() {
  1229. var row = new Row();
  1230. row.grid = this.grid;
  1231. for (var i = 0; i < this.grid.colCount; i++) {
  1232. row.addCell(new Cell());
  1233. }
  1234. var rowIndex = this.getIndex();
  1235. var rows = this.grid.rows;
  1236. if (rowIndex == 0) {
  1237. rows.unshift(row);
  1238. } else {
  1239. rows.splice(rowIndex, 0, row);
  1240. }
  1241. this.grid.rowCount = rows.length;
  1242. },
  1243. getPrevRow: function() {
  1244. var index = this.getIndex();
  1245. if (index > 0) {
  1246. return this.grid.rows[index - 1];
  1247. } else {
  1248. return null;
  1249. }
  1250. },
  1251. getNextRow: function() {
  1252. var index = this.getIndex();
  1253. if (index < this.grid.rows.length) {
  1254. return this.grid.rows[index + 1];
  1255. } else {
  1256. return null;
  1257. }
  1258. },
  1259. tryInterleaveWith: function(other) {
  1260. if (!this.isInterleaveWith(other)) {
  1261. return false;
  1262. }
  1263. for (var i = 0; i < this.cells.length; i++) {
  1264. var cell = this.cells[i];
  1265. var otherCell = other.cells[i];
  1266. if (cell.isFilled()) {
  1267. other.cells[i] = cell;
  1268. } else if (cell.isUnpackable()) {
  1269. otherCell.setPackable(false);
  1270. }
  1271. }
  1272. this._remove();
  1273. return true;
  1274. },
  1275. isInterleaveWith: function(other) {
  1276. if (other == null || other == this) {
  1277. return false;
  1278. } else if (other.getPrevRow() != this && other.getNextRow() != this) {
  1279. return false;
  1280. }
  1281. for (var i = 0; i < this.cells.length; i++) {
  1282. var cell = this.cells[i];
  1283. var otherCell = other.cells[i];
  1284. if (cell.isUnpackable() && otherCell.isUnpackable()) {
  1285. return false;
  1286. }
  1287. }
  1288. return true;
  1289. },
  1290. _remove: function() {
  1291. var index = this.getIndex();
  1292. this.grid.rows.splice(index, 1);
  1293. this.grid.rowCount--;
  1294. }
  1295. };
  1296. ;
  1297. PriorityQueue = function(center) {
  1298. this.ce = center;
  1299. this.items = [];
  1300. };
  1301. PriorityQueue.prototype = {
  1302. add: function(element) {
  1303. this.items.push(element);
  1304. var len = this.items.length;
  1305. for (var i = 0; i < len; i++) {
  1306. for (var j = i; j < len; j++) {
  1307. var elem1 = this.items[i];
  1308. var elem2 = this.items[j];
  1309. if (this.compareTo(elem1, elem2) > 0) {
  1310. this.items[i] = elem2;
  1311. this.items[j] = elem1;
  1312. }
  1313. }
  1314. }
  1315. },
  1316. compareTo: function(elem1, elem2) {
  1317. return this.ce.backwardDistanceTo(elem1) - this.ce.backwardDistanceTo(elem2);
  1318. },
  1319. contains: function(element) {
  1320. return this.items.indexOf(element) != -1;
  1321. }
  1322. };
  1323. ;
  1324. EdgeLayouter = function(grid, edge) {
  1325. this.grid = grid;
  1326. this.edge = edge;
  1327. edge.innerPoints = [];
  1328. this.calculateGlobals();
  1329. this.pickLayoutForEdge();
  1330. };
  1331. EdgeLayouter.prototype = {
  1332. calculateGlobals: function() {
  1333. this.source = this.edge.source;
  1334. this.target = this.edge.target;
  1335. this.sourceRelativeCenterX = this.source.w / 2;
  1336. this.sourceRelativeCenterY = this.source.h / 2;
  1337. this.targetRelativeCenterX = this.target.w / 2;
  1338. this.targetRelativeCenterY = this.target.h / 2;
  1339. this.sourceAbsoluteCenterX = this.source.x + this.sourceRelativeCenterX;
  1340. this.sourceAbsoluteCenterY = this.source.y + this.sourceRelativeCenterY;
  1341. this.targetAbsoluteCenterX = this.target.x + this.targetRelativeCenterX;
  1342. this.targetAbsoluteCenterY = this.target.y + this.targetRelativeCenterY;
  1343. this.sourceAbsoluteX = this.source.x;
  1344. this.sourceAbsoluteY = this.source.y;
  1345. this.sourceAbsoluteX2 = this.source.x + this.source.w;
  1346. this.sourceAbsoluteY2 = this.source.y + this.source.h;
  1347. this.targetAbsoluteX = this.target.x;
  1348. this.targetAbsoluteY = this.target.y;
  1349. this.targetAbsoluteX2 = this.target.x + this.target.w;
  1350. this.targetAbsoluteY2 = this.target.y + this.target.h;
  1351. this.sourceJoin = this.source.isJoin();
  1352. this.sourceSplit = this.source.isSplit();
  1353. this.targetJoin = this.target.isJoin();
  1354. this.targetSplit = this.target.isSplit();
  1355. this.backwards = this.sourceAbsoluteCenterX > this.targetAbsoluteCenterX;
  1356. },
  1357. pickLayoutForEdge: function() {
  1358. // sourceX == targetX, up and down
  1359. if (this.sourceAbsoluteCenterX == this.targetAbsoluteCenterX) {
  1360. this.setEdgeDirectCenter();
  1361. return;
  1362. } else if (this.sourceAbsoluteCenterY == this.targetAbsoluteCenterY) {
  1363. if (this.areCellsHorizontalFree()) {
  1364. this.setEdgeDirectCenter();
  1365. } else {
  1366. this.setEdgeAroundTheCorner(true);
  1367. }
  1368. return;
  1369. }
  1370. if (this.sourceAbsoluteCenterX <= this.targetAbsoluteCenterX
  1371. && this.sourceAbsoluteCenterY <= this.targetAbsoluteCenterY) {
  1372. // target is right under
  1373. if (this.sourcejoin && this.sourceSplit) {
  1374. this.setEdgeStepRight();
  1375. return;
  1376. } else if (this.sourceSplit) {
  1377. this.setEdge90DegreeRightUnderAntiClockwise();
  1378. return;
  1379. } else if (this.targetJoin) {
  1380. this.setEdge90DegreeRightUnderClockwise();
  1381. return;
  1382. }
  1383. } else if (this.sourceAbsoluteCenterX <= this.targetAbsoluteCenterX
  1384. && this.sourceAbsoluteCenterY > this.targetAbsoluteCenterY) {
  1385. // target is right above
  1386. if (this.sourcejoin && this.sourceSplit) {
  1387. this.setEdgeStepRight();
  1388. return;
  1389. } else if (this.sourceSplit) {
  1390. this.setEdge90DegreeRightAboveClockwise();
  1391. return;
  1392. } else if (this.targetJoin) {
  1393. this.setEdge90DegreeRightAboveAntiClockwise();
  1394. return;
  1395. }
  1396. }
  1397. if (this.sourceJoin && sourceSplit && (!this.backwards)) {
  1398. this.setEdgeStepRight();
  1399. return;
  1400. }
  1401. if (this.sourceJoin && sourceSplit) {
  1402. this.setEdgeAroundTheCorner(true);
  1403. return;
  1404. }
  1405. this.setEdgeDirectCenter();
  1406. },
  1407. areCellsHorizontalFree: function() {
  1408. var fromCell = null;
  1409. var toCell = null;
  1410. if (this.sourceAbsoluteCenterX < this.targetAbsoluteCenterX) {
  1411. fromCell = this.grid.getCellOfItem(this.source);
  1412. toCell = this.grid.getCellOfItem(this.target);
  1413. } else {
  1414. fromCell = this.grid.getCellOfItem(this.target);
  1415. toCell = this.grid.getCellOfItem(this.source);
  1416. }
  1417. fromCell = fromCell.getNextCell();
  1418. while (fromCell != toCell) {
  1419. if (fromCell == null || fromCell.isFilled()) {
  1420. return false;
  1421. }
  1422. fromCell = fromCell.getNextCell();
  1423. }
  1424. return true;
  1425. },
  1426. setEdgeDirectCenter: function() {
  1427. var boundsMinX = Math.min(this.sourceAbsoluteCenterX,
  1428. this.targetAbsoluteCenterX);
  1429. var boundsMinY = Math.min(this.sourceAbsoluteCenterY,
  1430. this.targetAbsoluteCenterY);
  1431. var boundsMaxX = Math.max(this.sourceAbsoluteCenterX,
  1432. this.targetAbsoluteCenterX);
  1433. var boundsMaxY = Math.max(this.sourceAbsoluteCenterY,
  1434. this.targetAbsoluteCenterY);
  1435. // this.edge.innerPoints = [];
  1436. },
  1437. setEdge90DegreeRightAboveClockwise: function() {
  1438. this.edge.innerPoints = [
  1439. [this.sourceAbsoluteCenterX, this.targetAbsoluteCenterY]
  1440. ];
  1441. },
  1442. setEdge90DegreeRightAboveAntiClockwise: function() {
  1443. this.edge.innerPoints = [
  1444. [this.targetAbsoluteCenterX, this.sourceAbsoluteCenterY]
  1445. ];
  1446. },
  1447. setEdge90DegreeRightUnderClockwise: function() {
  1448. this.edge.innerPoints = [
  1449. [this.targetAbsoluteCenterX, this.sourceAbsoluteCenterY]
  1450. ];
  1451. },
  1452. setEdge90DegreeRightUnderAntiClockwise: function() {
  1453. this.edge.innerPoints = [
  1454. [this.sourceAbsoluteCenterX, this.targetAbsoluteCenterY]
  1455. ];
  1456. },
  1457. setEdgeAroundTheCorner: function(down) {
  1458. var height = Math.max(this.source.h / 2, this.target.h / 2) + 20;
  1459. if (down) {
  1460. height *= -1;
  1461. }
  1462. this.edge.innerPoints = [
  1463. [this.sourceAbsoluteCenterX, this.sourceAbsoluteCenterY + height],
  1464. [this.targetAbsoluteCenterX, this.sourceAbsoluteCenterY + height]
  1465. ];
  1466. }
  1467. };
  1468. Ext.ux.OneCombo = Ext.extend(Ext.form.ComboBox, {
  1469. initComponent: function() {
  1470. this.readOnly = true;
  1471. this.displayField = 'text';
  1472. this.valueField = 'text';
  1473. this.triggerAction = 'all';
  1474. this.mode = 'local';
  1475. this.emptyText = 'Please Select...';
  1476. this.store = new Ext.data.SimpleStore({
  1477. expandData: true,
  1478. fields: ['text']
  1479. });
  1480. this.store.loadData(this.data);
  1481. Ext.ux.OneCombo.superclass.initComponent.call(this);
  1482. }
  1483. });
  1484. Ext.reg('onecombo', Ext.ux.OneCombo);
  1485. Gef.ns("Gef.planner");
  1486. Gef.ns("Gef.planner.model");
  1487. Gef.ns("Gef.planner.figure");
  1488. Gef.ns("Gef.planner.editpart");
  1489. function registerClass(type, name, url, w, h){
  1490. function capitaliseFirstLetter(string)
  1491. {
  1492. return string.charAt(0).toUpperCase() + string.slice(1);
  1493. }
  1494. var preType = type;
  1495. Gef.planner.model[preType+"Model"] = Gef.extend(Gef.jbs.model.GenericImageModel, {
  1496. type: preType,
  1497. url: url,
  1498. constructor: function(conf) {
  1499. Gef.planner.model[preType+"Model"].superclass.constructor.call(this, conf);
  1500. this.w = w;
  1501. this.h = h;
  1502. }
  1503. });
  1504. Gef.planner.figure[preType+"Figure"] = Gef.extend(Gef.jbs.figure.GenericImageFigure, {
  1505. });
  1506. Gef.planner.editpart[preType+"EditPart"] = Gef.extend(Gef.jbs.editpart.GenericImageEditPart, {
  1507. _figureClassName: "Gef.planner.figure." + preType + "Figure"
  1508. });
  1509. Gef.jbs.JBSModelFactory.registerModel(type, "Gef.planner.model." + preType + "Model");
  1510. Gef.jbs.JBSEditPartFactory.registerEditPart(type, "Gef.planner.editpart." + preType + "EditPart");
  1511. }
  1512. var tpls = [
  1513. ["exchange", "exchange", "images/stenciles/huagong/huagong1/exchange.png", 37, 27],
  1514. ["fah", "fah", "images/stenciles/huagong/huagong1/fah.png",23,14],
  1515. ["fav", "fav", "images/stenciles/huagong/huagong1/fav.png",14,23],
  1516. ["guan", "guan", "images/stenciles/huagong/huagong1/guan.png",36,45],
  1517. ["lu", "lu", "images/stenciles/huagong/huagong1/lu.png",157,240],
  1518. ["meter", "meter", "images/stenciles/huagong/huagong1/meter.png",75,46],
  1519. ["motor", "motor", "images/stenciles/huagong/huagong1/motor.png",43,41],
  1520. ["motor2", "motor2", "images/stenciles/huagong/huagong1/motor2.png",43,41],
  1521. ["pressure", "pressure", "images/stenciles/huagong/huagong1/pressure.png",35,30],
  1522. ["wendu", "wendu", "images/stenciles/huagong/huagong1/wendu.png",35,30]
  1523. ];
  1524. (function regClasses(arr){
  1525. for(var i=0;i<tpls.length;i++){
  1526. registerClass.apply(this, tpls[i]);
  1527. }
  1528. })(tpls);
  1529. function makePaletteArray(arr){
  1530. var ret = [
  1531. {name: 'select', image: 'scripts/gef/images/activities/select32.png', title: '选择'},
  1532. {name: 'transition', image: 'scripts/gef/images/activities/32/flow_sequence.png', title: '连线'},
  1533. {name: 'rect', image: 'scripts/gef/images/activities/draw_rectangle.png', title: '矩形'},
  1534. {name: 'ellipse', image: 'scripts/gef/images/activities/draw_ellipse.png', title: '椭圆'}
  1535. ];
  1536. for(var i=0;i<tpls.length;i++){
  1537. ret.push({name: tpls[i][0], image: tpls[i][2], title: tpls[i][1]});
  1538. }
  1539. return ret;
  1540. }
  1541. function makeModelArray(arr){
  1542. var ret = {
  1543. select: {
  1544. text: 'select',
  1545. creatable: false
  1546. },
  1547. transition: {
  1548. text: 'transition',
  1549. creatable: false,
  1550. isConnection: true
  1551. },rect: {
  1552. text: 'rect',
  1553. w: 80,
  1554. h: 60
  1555. },
  1556. ellipse: {
  1557. text: 'ellipse',
  1558. w: 80,
  1559. h: 60
  1560. }
  1561. };
  1562. for(var i=0;i<tpls.length;i++){
  1563. ret[tpls[i][0]] = {
  1564. text: tpls[i][0],
  1565. w: tpls[i][3],
  1566. h: tpls[i][4]
  1567. };
  1568. }
  1569. return ret;
  1570. }
  1571. Gef.jbs.ExtPaletteHelper = Gef.extend(Gef.jbs.JBSPaletteHelper, {
  1572. createSource: function() {
  1573. return makeModelArray();
  1574. },
  1575. getSource: function() {
  1576. if (!this.source) {
  1577. this.source = this.createSource();
  1578. }
  1579. return this.source;
  1580. },
  1581. render: Gef.emptyFn,
  1582. changeActivePalette: function(paletteConfig) {
  1583. var el = null;
  1584. if (this.getActivePalette()) {
  1585. var oldActivePaletteId = this.getActivePalette().text;
  1586. el = document.getElementById(oldActivePaletteId + '-img');
  1587. el.style.border = '';
  1588. }
  1589. this.setActivePalette(paletteConfig);
  1590. el = document.getElementById(paletteConfig.text + '-img');
  1591. el.style.border = '1px dotted black';
  1592. },
  1593. resetActivePalette: function() {
  1594. this.changeActivePalette({
  1595. text: 'select'
  1596. });
  1597. },
  1598. getPaletteConfig: function(p, t) {
  1599. var id = t.parentNode.id;
  1600. if (!id) {
  1601. return null;
  1602. }
  1603. var source = this.getSource();
  1604. var paletteConfig = this.getSource()[id];
  1605. if (!paletteConfig) {
  1606. return null;
  1607. }
  1608. this.changeActivePalette(paletteConfig);
  1609. if (paletteConfig.creatable === false) {
  1610. return null;
  1611. }
  1612. return paletteConfig;
  1613. }
  1614. });
  1615. App.PalettePanel = Ext.extend(Ext.Panel, {
  1616. initComponent: function() {
  1617. this.region = 'west';
  1618. this.title = '图元库';
  1619. this.iconCls = 'tb-activity';
  1620. this.width = 110;
  1621. this.initPalette();
  1622. App.PalettePanel.superclass.initComponent.call(this);
  1623. },
  1624. initPalette: function() {
  1625. var paletteType = null;
  1626. if (!Gef.PALETTE_TYPE) {
  1627. paletteType = 'accordion';
  1628. } else {
  1629. paletteType = Gef.PALETTE_TYPE;
  1630. }
  1631. this.configLayout(paletteType);
  1632. this.configItems(paletteType);
  1633. },
  1634. createHtml: function(array, divId) {
  1635. if (divId) {
  1636. var html = '<div id="' + divId + '" unselectable="on">';
  1637. } else {
  1638. var html = '<div unselectable="on">';
  1639. }
  1640. for (var i = 0; i < array.length; i++) {
  1641. var item = array[i];
  1642. html += '<div id="' + item.name + '" class="paletteItem-' + item.name
  1643. + '" style="text-align:center;font-size:12px;cursor:pointer;" unselectable="on"><img width="32" height="32" id="'
  1644. + item.name + '-img" class="paletteItem-' + item.name
  1645. + '" src="' + item.image + '" unselectable="on"><br>'
  1646. + item.title + '</div>';
  1647. }
  1648. html += '</div>';
  1649. return html;
  1650. },
  1651. /**
  1652. * this.layout = 'accordion';
  1653. */
  1654. configLayout: function(type) {
  1655. if (!type || type == 'plain') {
  1656. //
  1657. } else if (type && type == 'accordion') {
  1658. this.layout = 'accordion';
  1659. }
  1660. },
  1661. configItems: function(type) {
  1662. if (type && type == 'accordion') {
  1663. this.createItemsForAccordion();
  1664. } else if (!type || type == 'plain') {
  1665. this.createItemsForHtml();
  1666. }
  1667. },
  1668. createItemsForAccordion: function() {
  1669. this.id = '__gef_jbs_palette__';
  1670. this.items = [{
  1671. title: '基础图元',
  1672. iconCls: 'tb-activity',
  1673. autoScroll: true,
  1674. html: this.createHtml(makePaletteArray(tpls))
  1675. }, {
  1676. title: '高级图元',
  1677. iconCls: 'tb-activity',
  1678. autoScroll: true,
  1679. html: ''
  1680. }];
  1681. },
  1682. createItemsForHtml: function() {
  1683. this.autoScroll = true;
  1684. this.html = this.createHtml([
  1685. {name: 'select', image: 'select32', title: '选择'},
  1686. {name: 'transition', image: '32/flow_sequence', title: '连线'},
  1687. {name: 'start', image: '32/start_event_empty', title: '开始'},
  1688. {name: 'end', image: '32/end_event_terminate', title: '结束'},
  1689. {name: 'cancel', image: '32/end_event_cancel', title: '取消'},
  1690. {name: 'error', image: '32/end_event_error', title: '错误'},
  1691. {name: 'state', image: '32/task_wait', title: '等待'},
  1692. {name: 'task', image: '32/task_empty', title: '任务'},
  1693. {name: 'decision', image: '32/gateway_exclusive', title: '决策'},
  1694. {name: 'fork', image: '32/gateway_parallel', title: '并行'},
  1695. {name: 'join', image: '32/gateway_parallel', title: '汇聚'},
  1696. {name: 'java', image: '32/task_java', title: 'JAVA'},
  1697. {name: 'script', image: '32/task_java', title: '脚本'},
  1698. {name: 'hql', image: '32/task_hql', title: 'HQL'},
  1699. {name: 'sql', image: '32/task_sql', title: 'SQL'},
  1700. {name: 'mail', image: '32/task_empty', title: '邮件'},
  1701. {name: 'custom', image: '32/task_empty', title: '自定义'},
  1702. {name: 'subProcess', image: '32/task_empty', title: '子流程'},
  1703. {name: 'jms', image: '32/task_empty', title: 'JMS'},
  1704. {name: 'ruleDecision', image: '32/gateway_exclusive', title: '规则决策'},
  1705. {name: 'rules', image: '32/task_empty', title: '规则'},
  1706. {name: 'human', image: '32/task_empty', title: '人工节点'},
  1707. {name: 'auto', image: '32/task_empty', title: '自动节点'},
  1708. {name: 'counter-sign', image: '32/task_empty', title: '会签节点'}
  1709. ], '__gef_jbs_palette__');
  1710. }
  1711. });
  1712. Ext.ux.TwoCombo = Ext.extend(Ext.form.ComboBox, {
  1713. initComponent: function() {
  1714. this.readOnly = true;
  1715. this.displayField = 'text';
  1716. this.valueField = 'value';
  1717. this.triggerAction = 'all';
  1718. this.mode = 'local';
  1719. this.emptyText = 'Please Select...';
  1720. this.store = new Ext.data.SimpleStore({
  1721. fields: ['value', 'text']
  1722. });
  1723. this.store.loadData(this.data);
  1724. Ext.ux.TwoCombo.superclass.initComponent.call(this);
  1725. }
  1726. });
  1727. Ext.reg('twocombo', Ext.ux.TwoCombo);