Digital Office Automation System
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. * Activiti Modeler component part of the Activiti project
  3. * Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. 'use strict';
  19. var activitiModeler = angular.module('activitiModeler', [
  20. 'ngCookies',
  21. 'ngResource',
  22. 'ngSanitize',
  23. 'ngRoute',
  24. 'ngDragDrop',
  25. 'mgcrea.ngStrap',
  26. 'ngGrid',
  27. 'ngAnimate',
  28. 'pascalprecht.translate',
  29. 'duScroll'
  30. ]);
  31. var activitiModule = activitiModeler;
  32. activitiModeler
  33. // Initialize routes
  34. .config(['$selectProvider', '$translateProvider', function ($selectProvider, $translateProvider) {
  35. // Override caret for bs-select directive
  36. angular.extend($selectProvider.defaults, {
  37. caretHtml: '&nbsp;<i class="icon icon-caret-down"></i>'
  38. });
  39. // Initialize angular-translate
  40. $translateProvider.useStaticFilesLoader({
  41. prefix: './editor-app/i18n/',
  42. suffix: '.json'
  43. });
  44. // $translateProvider.preferredLanguage('en');
  45. // 多语言支持
  46. if("zh-CN" == navigator.language){
  47. $translateProvider.preferredLanguage('zh-CN');
  48. }else {
  49. $translateProvider.preferredLanguage('en');
  50. }
  51. // remember language
  52. $translateProvider.useCookieStorage();
  53. }])
  54. .run(['$rootScope', '$timeout', '$modal', '$translate', '$location', '$window', '$http', '$q',
  55. function($rootScope, $timeout, $modal, $translate, $location, $window, $http, $q) {
  56. $rootScope.config = ACTIVITI.CONFIG;
  57. $rootScope.editorInitialized = false;
  58. $rootScope.editorFactory = $q.defer();
  59. $rootScope.forceSelectionRefresh = false;
  60. $rootScope.ignoreChanges = false; // by default never ignore changes
  61. $rootScope.validationErrors = [];
  62. $rootScope.staticIncludeVersion = Date.now();
  63. /**
  64. * A 'safer' apply that avoids concurrent updates (which $apply allows).
  65. */
  66. $rootScope.safeApply = function(fn) {
  67. var phase = this.$root.$$phase;
  68. if(phase == '$apply' || phase == '$digest') {
  69. if(fn && (typeof(fn) === 'function')) {
  70. fn();
  71. }
  72. } else {
  73. this.$apply(fn);
  74. }
  75. };
  76. /**
  77. * Initialize the event bus: couple all Oryx events with a dispatch of the
  78. * event of the event bus. This way, it gets much easier to attach custom logic
  79. * to any event.
  80. */
  81. /* Helper method to fetch model from server (always needed) */
  82. function fetchModel(modelId) {
  83. var modelUrl = KISBPM.URL.getModel(modelId);
  84. $http({method: 'GET', url: modelUrl}).
  85. success(function (data, status, headers, config) {
  86. $rootScope.editor = new ORYX.Editor(data);
  87. $rootScope.modelData = angular.fromJson(data);
  88. $rootScope.editorFactory.resolve();
  89. }).
  90. error(function (data, status, headers, config) {
  91. console.log('Error loading model with id ' + modelId + ' ' + data);
  92. });
  93. }
  94. function initScrollHandling() {
  95. var canvasSection = jQuery('#canvasSection');
  96. canvasSection.scroll(function() {
  97. // Hides the resizer and quick menu items during scrolling
  98. var selectedElements = $rootScope.editor.selection;
  99. var subSelectionElements = $rootScope.editor._subSelection;
  100. $rootScope.selectedElements = selectedElements;
  101. $rootScope.subSelectionElements = subSelectionElements;
  102. if (selectedElements && selectedElements.length > 0) {
  103. $rootScope.selectedElementBeforeScrolling = selectedElements[0];
  104. }
  105. jQuery('.Oryx_button').each(function(i, obj) {
  106. $rootScope.orginalOryxButtonStyle = obj.style.display;
  107. obj.style.display = 'none';
  108. });
  109. jQuery('.resizer_southeast').each(function(i, obj) {
  110. $rootScope.orginalResizerSEStyle = obj.style.display;
  111. obj.style.display = 'none';
  112. });
  113. jQuery('.resizer_northwest').each(function(i, obj) {
  114. $rootScope.orginalResizerNWStyle = obj.style.display;
  115. obj.style.display = 'none';
  116. });
  117. $rootScope.editor.handleEvents({type:ORYX.CONFIG.EVENT_CANVAS_SCROLL});
  118. });
  119. canvasSection.scrollStopped(function(){
  120. // Puts the quick menu items and resizer back when scroll is stopped.
  121. $rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
  122. $rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
  123. $rootScope.selectedElements = undefined;
  124. $rootScope.subSelectionElements = undefined;
  125. function handleDisplayProperty(obj) {
  126. if (jQuery(obj).position().top > 0) {
  127. obj.style.display = 'block';
  128. } else {
  129. obj.style.display = 'none';
  130. }
  131. }
  132. jQuery('.Oryx_button').each(function(i, obj) {
  133. handleDisplayProperty(obj);
  134. });
  135. jQuery('.resizer_southeast').each(function(i, obj) {
  136. handleDisplayProperty(obj);
  137. });
  138. jQuery('.resizer_northwest').each(function(i, obj) {
  139. handleDisplayProperty(obj);
  140. });
  141. });
  142. }
  143. /**
  144. * Initialize the Oryx Editor when the content has been loaded
  145. */
  146. $rootScope.$on('$includeContentLoaded', function (event) {
  147. if (!$rootScope.editorInitialized) {
  148. ORYX._loadPlugins();
  149. var modelId = EDITOR.UTIL.getParameterByName('modelId');
  150. fetchModel(modelId);
  151. $rootScope.window = {};
  152. var updateWindowSize = function() {
  153. $rootScope.window.width = $window.innerWidth;
  154. $rootScope.window.height = $window.innerHeight;
  155. };
  156. // Window resize hook
  157. angular.element($window).bind('resize', function() {
  158. $rootScope.safeApply(updateWindowSize());
  159. });
  160. $rootScope.$watch('window.forceRefresh', function(newValue) {
  161. if(newValue) {
  162. $timeout(function() {
  163. updateWindowSize();
  164. $rootScope.window.forceRefresh = false;
  165. });
  166. }
  167. });
  168. updateWindowSize();
  169. // Hook in resizing of main panels when window resizes
  170. // TODO: perhaps move to a separate JS-file?
  171. jQuery(window).resize(function () {
  172. // Calculate the offset based on the bottom of the module header
  173. var offset = jQuery("#editor-header").offset();
  174. var propSectionHeight = jQuery('#propertySection').height();
  175. var canvas = jQuery('#canvasSection');
  176. var mainHeader = jQuery('#main-header');
  177. if (offset == undefined || offset === null
  178. || propSectionHeight === undefined || propSectionHeight === null
  179. || canvas === undefined || canvas === null || mainHeader === null) {
  180. return;
  181. }
  182. if ($rootScope.editor)
  183. {
  184. var selectedElements = $rootScope.editor.selection;
  185. var subSelectionElements = $rootScope.editor._subSelection;
  186. $rootScope.selectedElements = selectedElements;
  187. $rootScope.subSelectionElements = subSelectionElements;
  188. if (selectedElements && selectedElements.length > 0)
  189. {
  190. $rootScope.selectedElementBeforeScrolling = selectedElements[0];
  191. $rootScope.editor.setSelection([]); // needed cause it checks for element changes and does nothing if the elements are the same
  192. $rootScope.editor.setSelection($rootScope.selectedElements, $rootScope.subSelectionElements);
  193. $rootScope.selectedElements = undefined;
  194. $rootScope.subSelectionElements = undefined;
  195. }
  196. }
  197. var totalAvailable = jQuery(window).height() - offset.top - mainHeader.height() - 21;
  198. canvas.height(totalAvailable - propSectionHeight);
  199. jQuery('#paletteSection').height(totalAvailable);
  200. // Update positions of the resize-markers, according to the canvas
  201. var actualCanvas = null;
  202. if (canvas && canvas[0].children[1]) {
  203. actualCanvas = canvas[0].children[1];
  204. }
  205. var canvasTop = canvas.position().top;
  206. var canvasLeft = canvas.position().left;
  207. var canvasHeight = canvas[0].clientHeight;
  208. var canvasWidth = canvas[0].clientWidth;
  209. var iconCenterOffset = 8;
  210. var widthDiff = 0;
  211. var actualWidth = 0;
  212. if(actualCanvas) {
  213. // In some browsers, the SVG-element clientwidth isn't available, so we revert to the parent
  214. actualWidth = actualCanvas.clientWidth || actualCanvas.parentNode.clientWidth;
  215. }
  216. if(actualWidth < canvas[0].clientWidth) {
  217. widthDiff = actualWidth - canvas[0].clientWidth;
  218. // In case the canvas is smaller than the actual viewport, the resizers should be moved
  219. canvasLeft -= widthDiff / 2;
  220. canvasWidth += widthDiff;
  221. }
  222. var iconWidth = 17;
  223. var iconOffset = 20;
  224. var north = jQuery('#canvas-grow-N');
  225. north.css('top', canvasTop + iconOffset + 'px');
  226. north.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
  227. var south = jQuery('#canvas-grow-S');
  228. south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) + 'px');
  229. south.css('left', canvasLeft - 10 + (canvasWidth - iconWidth) / 2 + 'px');
  230. var east = jQuery('#canvas-grow-E');
  231. east.css('top', canvasTop - 10 + (canvasHeight - iconWidth) / 2 + 'px');
  232. east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
  233. var west = jQuery('#canvas-grow-W');
  234. west.css('top', canvasTop -10 + (canvasHeight - iconWidth) / 2 + 'px');
  235. west.css('left', canvasLeft + iconOffset + 'px');
  236. north = jQuery('#canvas-shrink-N');
  237. north.css('top', canvasTop + iconOffset + 'px');
  238. north.css('left', canvasLeft + 10 + (canvasWidth - iconWidth) / 2 + 'px');
  239. south = jQuery('#canvas-shrink-S');
  240. south.css('top', (canvasTop + canvasHeight - iconOffset - iconCenterOffset) + 'px');
  241. south.css('left', canvasLeft +10 + (canvasWidth - iconWidth) / 2 + 'px');
  242. east = jQuery('#canvas-shrink-E');
  243. east.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
  244. east.css('left', (canvasLeft + canvasWidth - iconOffset - iconCenterOffset) + 'px');
  245. west = jQuery('#canvas-shrink-W');
  246. west.css('top', canvasTop + 10 + (canvasHeight - iconWidth) / 2 + 'px');
  247. west.css('left', canvasLeft + iconOffset + 'px');
  248. });
  249. jQuery(window).trigger('resize');
  250. jQuery.fn.scrollStopped = function(callback) {
  251. jQuery(this).scroll(function(){
  252. var self = this, $this = jQuery(self);
  253. if ($this.data('scrollTimeout')) {
  254. clearTimeout($this.data('scrollTimeout'));
  255. }
  256. $this.data('scrollTimeout', setTimeout(callback,50,self));
  257. });
  258. };
  259. // Always needed, cause the DOM element on which the scroll event listeners are attached are changed for every new model
  260. initScrollHandling();
  261. $rootScope.editorInitialized = true;
  262. }
  263. });
  264. /**
  265. * Initialize the event bus: couple all Oryx events with a dispatch of the
  266. * event of the event bus. This way, it gets much easier to attach custom logic
  267. * to any event.
  268. */
  269. $rootScope.editorFactory.promise.then(function() {
  270. KISBPM.eventBus.editor = $rootScope.editor;
  271. var eventMappings = [
  272. { oryxType : ORYX.CONFIG.EVENT_SELECTION_CHANGED, kisBpmType : KISBPM.eventBus.EVENT_TYPE_SELECTION_CHANGE },
  273. { oryxType : ORYX.CONFIG.EVENT_DBLCLICK, kisBpmType : KISBPM.eventBus.EVENT_TYPE_DOUBLE_CLICK },
  274. { oryxType : ORYX.CONFIG.EVENT_MOUSEOUT, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OUT },
  275. { oryxType : ORYX.CONFIG.EVENT_MOUSEOVER, kisBpmType : KISBPM.eventBus.EVENT_TYPE_MOUSE_OVER }
  276. ];
  277. eventMappings.forEach(function(eventMapping) {
  278. $rootScope.editor.registerOnEvent(eventMapping.oryxType, function(event) {
  279. KISBPM.eventBus.dispatch(eventMapping.kisBpmType, event);
  280. });
  281. });
  282. $rootScope.editor.registerOnEvent(ORYX.CONFIG.EVENT_SHAPEREMOVED, function (event) {
  283. var validateButton = document.getElementById(event.shape.resourceId + "-validate-button");
  284. if (validateButton)
  285. {
  286. validateButton.style.display = 'none';
  287. }
  288. });
  289. // The Oryx canvas is ready (we know since we're in this promise callback) and the
  290. // event bus is ready. The editor is now ready for use
  291. KISBPM.eventBus.dispatch(KISBPM.eventBus.EVENT_TYPE_EDITOR_READY, {type : KISBPM.eventBus.EVENT_TYPE_EDITOR_READY});
  292. });
  293. // Alerts
  294. $rootScope.alerts = {
  295. queue: []
  296. };
  297. $rootScope.showAlert = function(alert) {
  298. if(alert.queue.length > 0) {
  299. alert.current = alert.queue.shift();
  300. // Start timout for message-pruning
  301. alert.timeout = $timeout(function() {
  302. if (alert.queue.length == 0) {
  303. alert.current = undefined;
  304. alert.timeout = undefined;
  305. } else {
  306. $rootScope.showAlert(alert);
  307. }
  308. }, (alert.current.type == 'error' ? 5000 : 1000));
  309. } else {
  310. $rootScope.alerts.current = undefined;
  311. }
  312. };
  313. $rootScope.addAlert = function(message, type) {
  314. var newAlert = {message: message, type: type};
  315. if (!$rootScope.alerts.timeout) {
  316. // Timeout for message queue is not running, start one
  317. $rootScope.alerts.queue.push(newAlert);
  318. $rootScope.showAlert($rootScope.alerts);
  319. } else {
  320. $rootScope.alerts.queue.push(newAlert);
  321. }
  322. };
  323. $rootScope.dismissAlert = function() {
  324. if (!$rootScope.alerts.timeout) {
  325. $rootScope.alerts.current = undefined;
  326. } else {
  327. $timeout.cancel($rootScope.alerts.timeout);
  328. $rootScope.alerts.timeout = undefined;
  329. $rootScope.showAlert($rootScope.alerts);
  330. }
  331. };
  332. $rootScope.addAlertPromise = function(promise, type) {
  333. if (promise) {
  334. promise.then(function(data) {
  335. $rootScope.addAlert(data, type);
  336. });
  337. }
  338. };
  339. }
  340. ])
  341. // Moment-JS date-formatting filter
  342. .filter('dateformat', function() {
  343. return function(date, format) {
  344. if (date) {
  345. if (format) {
  346. return moment(date).format(format);
  347. } else {
  348. return moment(date).calendar();
  349. }
  350. }
  351. return '';
  352. };
  353. });