DrawioFile.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. // $Id = DrawioFile.js,v 1.12 2010-01-02 09 =45 =14 gaudenz Exp $
  2. // Copyright (c) 2006-2014, JGraph Ltd
  3. /**
  4. * Constructs a new point for the optional x and y coordinates. If no
  5. * coordinates are given, then the default values for <x> and <y> are used.
  6. * @constructor
  7. * @class Implements a basic 2D point. Known subclassers = {@link mxRectangle}.
  8. * @param {number} x X-coordinate of the point.
  9. * @param {number} y Y-coordinate of the point.
  10. */
  11. DrawioFile = function(ui, data)
  12. {
  13. mxEventSource.call(this);
  14. /**
  15. * Holds the x-coordinate of the point.
  16. * @type number
  17. * @default 0
  18. */
  19. this.ui = ui;
  20. /**
  21. * Holds the x-coordinate of the point.
  22. * @type number
  23. * @default 0
  24. */
  25. this.data = data || '';
  26. };
  27. //Extends mxEventSource
  28. mxUtils.extend(DrawioFile, mxEventSource);
  29. /**
  30. * Sets the delay for autosave in milliseconds. Default is 1500.
  31. */
  32. DrawioFile.prototype.autosaveDelay = 1500;
  33. /**
  34. * Sets the delay for autosave in milliseconds. Default is 30000.
  35. */
  36. DrawioFile.prototype.maxAutosaveDelay = 30000;
  37. /**
  38. * Sets the delay for autosave in milliseconds. Default is 2000.
  39. */
  40. DrawioFile.prototype.autosaveThread = null;
  41. /**
  42. * Sets the delay for autosave in milliseconds. Default is 500.
  43. */
  44. DrawioFile.prototype.lastAutosave = null;
  45. /**
  46. * Sets the delay for autosave in milliseconds. Default is 1500.
  47. */
  48. DrawioFile.prototype.modified = false;
  49. /**
  50. * Specifies if the graph change listener is enabled. Default is true.
  51. */
  52. DrawioFile.prototype.changeListenerEnabled = true;
  53. /**
  54. * Sets the delay for autosave in milliseconds. Default is 1500.
  55. */
  56. DrawioFile.prototype.lastAutosaveRevision = null;
  57. /**
  58. * Sets the delay for autosave in milliseconds. Default is 1000.
  59. */
  60. DrawioFile.prototype.maxAutosaveRevisionDelay = 1800000;
  61. /**
  62. * Translates this point by the given vector.
  63. *
  64. * @param {number} dx X-coordinate of the translation.
  65. * @param {number} dy Y-coordinate of the translation.
  66. */
  67. DrawioFile.prototype.descriptorChanged = function()
  68. {
  69. this.fireEvent(new mxEventObject('descriptorChanged'));
  70. };
  71. /**
  72. * Translates this point by the given vector.
  73. *
  74. * @param {number} dx X-coordinate of the translation.
  75. * @param {number} dy Y-coordinate of the translation.
  76. */
  77. DrawioFile.prototype.contentChanged = function()
  78. {
  79. this.fireEvent(new mxEventObject('contentChanged'));
  80. };
  81. /**
  82. * Adds the listener for automatically saving the diagram for local changes.
  83. */
  84. DrawioFile.prototype.save = function(revision, success, error, unloading)
  85. {
  86. this.updateFileData();
  87. this.clearAutosave();
  88. };
  89. /**
  90. * Translates this point by the given vector.
  91. *
  92. * @param {number} dx X-coordinate of the translation.
  93. * @param {number} dy Y-coordinate of the translation.
  94. */
  95. DrawioFile.prototype.updateFileData = function()
  96. {
  97. this.setData(this.ui.getFileData());
  98. };
  99. /**
  100. * Translates this point by the given vector.
  101. *
  102. * @param {number} dx X-coordinate of the translation.
  103. * @param {number} dy Y-coordinate of the translation.
  104. */
  105. DrawioFile.prototype.saveAs = function(filename, success, error) { };
  106. /**
  107. * Translates this point by the given vector.
  108. *
  109. * @param {number} dx X-coordinate of the translation.
  110. * @param {number} dy Y-coordinate of the translation.
  111. */
  112. DrawioFile.prototype.saveFile = function(title, revision, success, error) { };
  113. /**
  114. * Returns true if copy, export and print are not allowed for this file.
  115. */
  116. DrawioFile.prototype.isRestricted = function()
  117. {
  118. return false;
  119. };
  120. /**
  121. * Translates this point by the given vector.
  122. *
  123. * @param {number} dx X-coordinate of the translation.
  124. * @param {number} dy Y-coordinate of the translation.
  125. */
  126. DrawioFile.prototype.isModified = function()
  127. {
  128. return this.modified;
  129. };
  130. /**
  131. * Translates this point by the given vector.
  132. *
  133. * @param {number} dx X-coordinate of the translation.
  134. * @param {number} dy Y-coordinate of the translation.
  135. */
  136. DrawioFile.prototype.setModified = function(value)
  137. {
  138. this.modified = value;
  139. };
  140. /**
  141. * Specifies if the autosave checkbox should be shown in the document
  142. * properties dialog. Default is false.
  143. */
  144. DrawioFile.prototype.isAutosaveOptional = function()
  145. {
  146. return false;
  147. };
  148. /**
  149. * Translates this point by the given vector.
  150. *
  151. * @param {number} dx X-coordinate of the translation.
  152. * @param {number} dy Y-coordinate of the translation.
  153. */
  154. DrawioFile.prototype.isAutosave = function()
  155. {
  156. return this.ui.editor.autosave;
  157. };
  158. /**
  159. * Translates this point by the given vector.
  160. *
  161. * @param {number} dx X-coordinate of the translation.
  162. * @param {number} dy Y-coordinate of the translation.
  163. */
  164. DrawioFile.prototype.isRenamable = function()
  165. {
  166. return false;
  167. };
  168. /**
  169. * Translates this point by the given vector.
  170. *
  171. * @param {number} dx X-coordinate of the translation.
  172. * @param {number} dy Y-coordinate of the translation.
  173. */
  174. DrawioFile.prototype.rename = function(title, success, error) { };
  175. /**
  176. * Translates this point by the given vector.
  177. *
  178. * @param {number} dx X-coordinate of the translation.
  179. * @param {number} dy Y-coordinate of the translation.
  180. */
  181. DrawioFile.prototype.isMovable = function()
  182. {
  183. return false;
  184. };
  185. /**
  186. * Translates this point by the given vector.
  187. *
  188. * @param {number} dx X-coordinate of the translation.
  189. * @param {number} dy Y-coordinate of the translation.
  190. */
  191. DrawioFile.prototype.move = function(folderId, success, error) { };
  192. /**
  193. * Translates this point by the given vector.
  194. *
  195. * @param {number} dx X-coordinate of the translation.
  196. * @param {number} dy Y-coordinate of the translation.
  197. */
  198. DrawioFile.prototype.getHash = function()
  199. {
  200. return '';
  201. };
  202. /**
  203. * Translates this point by the given vector.
  204. *
  205. * @param {number} dx X-coordinate of the translation.
  206. * @param {number} dy Y-coordinate of the translation.
  207. */
  208. DrawioFile.prototype.getId = function()
  209. {
  210. return '';
  211. };
  212. /**
  213. * Translates this point by the given vector.
  214. *
  215. * @param {number} dx X-coordinate of the translation.
  216. * @param {number} dy Y-coordinate of the translation.
  217. */
  218. DrawioFile.prototype.isEditable = function()
  219. {
  220. return !this.ui.editor.chromeless;
  221. };
  222. /**
  223. * Returns the location as a new object.
  224. * @type mx.Point
  225. */
  226. DrawioFile.prototype.getUi = function()
  227. {
  228. return this.ui;
  229. };
  230. /**
  231. * Translates this point by the given vector.
  232. *
  233. * @param {number} dx X-coordinate of the translation.
  234. * @param {number} dy Y-coordinate of the translation.
  235. */
  236. DrawioFile.prototype.getTitle = function()
  237. {
  238. return '';
  239. };
  240. /**
  241. * Sets the location of this point.
  242. *
  243. * @param {number} x New X-coordinate of the point.
  244. * @param {number} y New Y-coordinate of the point.
  245. */
  246. DrawioFile.prototype.setData = function(data)
  247. {
  248. this.data = data;
  249. };
  250. /**
  251. * Returns the location as a new object.
  252. * @type mx.Point
  253. */
  254. DrawioFile.prototype.getData = function()
  255. {
  256. return this.data;
  257. };
  258. /**
  259. * Returns the location as a new object.
  260. * @type mx.Point
  261. */
  262. DrawioFile.prototype.open = function()
  263. {
  264. this.ui.setFileData(this.getData());
  265. this.changeListener = mxUtils.bind(this, function(sender, eventObject)
  266. {
  267. var edit = (eventObject != null) ? eventObject.getProperty('edit') : null;
  268. if (this.changeListenerEnabled && this.isEditable() &&
  269. (edit == null || !edit.ignoreEdit))
  270. {
  271. this.setModified(true);
  272. if (this.isAutosave())
  273. {
  274. this.ui.editor.setStatus(mxResources.get('saving') + '...');
  275. this.autosave(this.autosaveDelay, this.maxAutosaveDelay, mxUtils.bind(this, function(resp)
  276. {
  277. // Does not update status if another autosave was scheduled
  278. if (this.autosaveThread == null && this.ui.getCurrentFile() == this && !this.isModified())
  279. {
  280. this.ui.editor.setStatus(mxResources.get('allChangesSaved'));
  281. }
  282. }), mxUtils.bind(this, function(resp)
  283. {
  284. if (this.ui.getCurrentFile() == this)
  285. {
  286. this.addUnsavedStatus(resp);
  287. }
  288. }));
  289. }
  290. else
  291. {
  292. this.addUnsavedStatus();
  293. }
  294. }
  295. });
  296. this.ui.editor.graph.model.addListener(mxEvent.CHANGE, this.changeListener);
  297. // Some options trigger autosave
  298. this.ui.editor.graph.addListener('gridSizeChanged', this.changeListener);
  299. this.ui.editor.graph.addListener('shadowVisibleChanged', this.changeListener);
  300. this.ui.addListener('pageFormatChanged', this.changeListener);
  301. this.ui.addListener('pageScaleChanged', this.changeListener);
  302. this.ui.addListener('backgroundColorChanged', this.changeListener);
  303. this.ui.addListener('backgroundImageChanged', this.changeListener);
  304. this.ui.addListener('foldingEnabledChanged', this.changeListener);
  305. this.ui.addListener('mathEnabledChanged', this.changeListener);
  306. this.ui.addListener('gridEnabledChanged', this.changeListener);
  307. this.ui.addListener('guidesEnabledChanged', this.changeListener);
  308. this.ui.addListener('pageViewChanged', this.changeListener);
  309. };
  310. /**
  311. * Adds the listener for automatically saving the diagram for local changes.
  312. */
  313. DrawioFile.prototype.addUnsavedStatus = function(err)
  314. {
  315. if (err instanceof Error && err.message != null)
  316. {
  317. this.ui.editor.setStatus('<div class="geStatusAlert" style="cursor:pointer;">' +
  318. mxResources.get('unsavedChanges') + ' (' + err.message + ')</div>');
  319. }
  320. else
  321. {
  322. // FIXME: Handle multiple tabs
  323. // if (this.ui.mode == null && urlParams['splash'] == '0')
  324. // {
  325. // try
  326. // {
  327. // this.ui.updateDraft();
  328. // this.setModified(false);
  329. // }
  330. // catch (e)
  331. // {
  332. // // Keeps modified flag unchanged
  333. // }
  334. // }
  335. this.ui.editor.setStatus('<div class="geStatusMessage" style="cursor:pointer;">' +
  336. mxResources.get('unsavedChangesClickHereToSave') + '</div>');
  337. // Installs click handler for saving
  338. if (this.ui.statusContainer != null)
  339. {
  340. var links = this.ui.statusContainer.getElementsByTagName('div');
  341. if (links.length > 0)
  342. {
  343. mxEvent.addListener(links[0], 'click', mxUtils.bind(this, function()
  344. {
  345. this.ui.actions.get((this.ui.mode == null) ? 'saveAs' : 'save').funct();
  346. }));
  347. }
  348. }
  349. }
  350. };
  351. /**
  352. * Adds the listener for automatically saving the diagram for local changes.
  353. */
  354. DrawioFile.prototype.autosave = function(delay, maxDelay, success, error)
  355. {
  356. if (this.lastAutosave == null)
  357. {
  358. this.lastAutosave = new Date().getTime();
  359. }
  360. var tmp = (new Date().getTime() - this.lastAutosave < maxDelay) ? delay : 0;
  361. this.clearAutosave();
  362. // Starts new timer or executes immediately if not unsaved for maxDelay
  363. this.autosaveThread = window.setTimeout(mxUtils.bind(this, function()
  364. {
  365. this.autosaveThread = null;
  366. this.lastAutosave = null;
  367. // Workaround for duplicate save if UI is blocking
  368. // after save while pending autosave triggers
  369. if (this.isModified() && this.isAutosaveNow())
  370. {
  371. var rev = this.isAutosaveRevision();
  372. if (rev)
  373. {
  374. this.lastAutosaveRevision = new Date().getTime();
  375. }
  376. this.save(rev, mxUtils.bind(this, function(resp)
  377. {
  378. this.autosaveCompleted();
  379. if (success != null)
  380. {
  381. success(resp);
  382. }
  383. }), mxUtils.bind(this, function(resp)
  384. {
  385. if (error != null)
  386. {
  387. error(resp);
  388. }
  389. }));
  390. }
  391. else
  392. {
  393. if (success != null)
  394. {
  395. success(null);
  396. }
  397. }
  398. }), tmp);
  399. };
  400. /**
  401. * Returns true if an autosave is required at the time of execution.
  402. * This implementation returns true.
  403. */
  404. DrawioFile.prototype.isAutosaveNow = function()
  405. {
  406. return true;
  407. };
  408. /**
  409. * Hooks for subclassers after the autosave has completed.
  410. */
  411. DrawioFile.prototype.autosaveCompleted = function() { };
  412. /**
  413. * Adds the listener for automatically saving the diagram for local changes.
  414. */
  415. DrawioFile.prototype.clearAutosave = function()
  416. {
  417. if (this.autosaveThread != null)
  418. {
  419. window.clearTimeout(this.autosaveThread);
  420. this.autosaveThread = null;
  421. }
  422. };
  423. /**
  424. * Returns the location as a new object.
  425. * @type mx.Point
  426. */
  427. DrawioFile.prototype.isAutosaveRevision = function()
  428. {
  429. var now = new Date().getTime();
  430. return (this.lastAutosaveRevision == null) || (now - this.lastAutosaveRevision) > this.maxAutosaveRevisionDelay;
  431. };
  432. /**
  433. * Returns the location as a new object.
  434. */
  435. DrawioFile.prototype.close = function(unloading)
  436. {
  437. if (this.isAutosave() && this.isModified())
  438. {
  439. this.save(this.isAutosaveRevision(), null, null, unloading);
  440. }
  441. this.destroy();
  442. };
  443. /**
  444. * Returns the location as a new object.
  445. */
  446. DrawioFile.prototype.hasSameExtension = function(title, newTitle)
  447. {
  448. if (title != null && newTitle != null)
  449. {
  450. var dot = title.lastIndexOf('.');
  451. var ext = (dot > 0) ? title.substring(dot) : '';
  452. dot = newTitle.lastIndexOf('.');
  453. return ext === ((dot > 0) ? newTitle.substring(dot) : '');
  454. }
  455. return title == newTitle;
  456. };
  457. /**
  458. * Stops any pending autosaves and removes all listeners.
  459. */
  460. DrawioFile.prototype.destroy = function()
  461. {
  462. this.clearAutosave();
  463. if (this.changeListener != null)
  464. {
  465. this.ui.editor.graph.model.removeListener(this.changeListener);
  466. this.ui.editor.graph.removeListener(this.changeListener);
  467. this.ui.removeListener(this.changeListener);
  468. this.changeListener = null;
  469. }
  470. };