PageRenderTime 221ms CodeModel.GetById 37ms RepoModel.GetById 25ms app.codeStats 2ms

/cwxeditor_src/cwx/editor/gui/dwt/eventtreeview.d

https://bitbucket.org/k4nagatsuki/cwxeditor
D | 4480 lines | 4321 code | 119 blank | 40 comment | 947 complexity | c54f495b05096e1b3e361e95702bf5da MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. module cwx.editor.gui.dwt.eventtreeview;
  2. import cwx.event;
  3. import cwx.summary;
  4. import cwx.flag;
  5. import cwx.area;
  6. import cwx.card;
  7. import cwx.utils;
  8. import cwx.types;
  9. import cwx.skin;
  10. import cwx.usecounter;
  11. import cwx.background;
  12. import cwx.path;
  13. import cwx.script;
  14. import cwx.structs;
  15. import cwx.menu;
  16. import cwx.types;
  17. import cwx.xml;
  18. import cwx.msgutils;
  19. import cwx.system;
  20. import cwx.warning;
  21. import cwx.editor.gui.dwt.dutils;
  22. import cwx.editor.gui.dwt.dprops;
  23. import cwx.editor.gui.dwt.dskin;
  24. import cwx.editor.gui.dwt.commons;
  25. import cwx.editor.gui.dwt.eventdialog;
  26. import cwx.editor.gui.dwt.messageutils;
  27. import cwx.editor.gui.dwt.xmlbytestransfer;
  28. import cwx.editor.gui.dwt.undo;
  29. import cwx.editor.gui.dwt.properties;
  30. import cwx.editor.gui.dwt.absdialog;
  31. import cwx.editor.gui.dwt.centerlayout;
  32. import cwx.editor.gui.dwt.scripterrordialog;
  33. import cwx.editor.gui.dwt.textdialog;
  34. import cwx.editor.gui.dwt.dmenu;
  35. import cwx.editor.gui.dwt.smalldialogs;
  36. import cwx.editor.gui.dwt.eventeditor;
  37. import std.ascii;
  38. import std.algorithm;
  39. import std.conv;
  40. import std.string;
  41. import std.datetime;
  42. import org.eclipse.swt.all;
  43. import java.lang.all;
  44. public:
  45. struct Warning {
  46. Rectangle rect;
  47. string[] warnings;
  48. }
  49. /// ?????????????
  50. class EventTreeView : TCPD {
  51. private:
  52. string _id = "";
  53. Composite _contentsBoxArea;
  54. Composite _comp;
  55. TreeViewWrapper _tree;
  56. Color _grayFont;
  57. int _readOnly = 0;
  58. Props _prop;
  59. Commons _comm;
  60. Summary _summ;
  61. EventTree _et;
  62. ContentsToolBox _box;
  63. Menu _createM = null;
  64. Menu _convM = null;
  65. Menu _evTemplM = null;
  66. Converter[CType] _conts;
  67. bool _showEventTreeDetail = false;
  68. void delegate(size_t[]) _forceSel;
  69. void delegate() _refreshTopStart;
  70. Warning[] _warningRects;
  71. string _statusLine;
  72. Item _clickStart = null;
  73. bool _arrowMode = true;
  74. CType _cType = CType.START;
  75. Skin _summSkin;
  76. @property
  77. Skin summSkin() { mixin(S_TRACE);
  78. return _summSkin ? _summSkin : _comm.skin;
  79. }
  80. private void initConvMenu() { mixin(S_TRACE);
  81. if (!_conts.length) return;
  82. if (!_createM) return;
  83. if (!_convM) return;
  84. foreach (cGrp, cs; CTYPE_GROUP) { mixin(S_TRACE);
  85. auto create = cTypeGroupMenu(_createM, cGrp);
  86. auto conv = cTypeGroupMenu(_convM, cGrp);
  87. foreach (i, cType; cs) { mixin(S_TRACE);
  88. string mnemonic;
  89. if (i + 1 < 10) {
  90. mnemonic = .format("%s", i + 1);
  91. } else {
  92. mnemonic = .format("%s", cast(char)('A' + (i + 1 - 10)));
  93. }
  94. auto text = MenuProps.buildMenu(_prop.msgs.contentName(cType), mnemonic, "", false);
  95. auto img = _prop.images.content(cType);
  96. initCreateMenu(cType, create, text, img);
  97. initConvMenu(cType, cType is CType.START ? _convM : conv, text, img);
  98. }
  99. }
  100. refreshConvMenu();
  101. }
  102. private void initCreateMenu(CType type, Menu menu, string text, Image img) {
  103. createMenuItem2(_comm, menu, text, img, {
  104. if (!_box) return;
  105. auto itm = selection;
  106. bool insert = _box && _box._shiftDown;
  107. auto oldType = _box._cType;
  108. _box._cType = type;
  109. scope (exit) _box._cType = oldType;
  110. auto oldMode = _box._putMode;
  111. _box._putMode = MenuID.PutQuick;
  112. scope (exit) _box._putMode = oldMode;
  113. create(insert ? itm : null);
  114. }, () => _et !is null);
  115. }
  116. private void initConvMenu(CType type, Menu convMenu, string text, Image img) { mixin(S_TRACE);
  117. auto ce = _conts[type];
  118. if (type != CType.START) { mixin(S_TRACE);
  119. ce.convMenuItem = createMenuItem2(_comm, convMenu, text, img, &ce.convert, null);
  120. ce.convMenuItem.setEnabled(false);
  121. }
  122. }
  123. private bool canConvTerminal() { mixin(S_TRACE);
  124. auto itm = selection;
  125. if (!itm) return false;
  126. auto evt = cast(Content) itm.getData();
  127. return !evt.next.length;
  128. }
  129. private Menu cTypeGroupMenu(Menu menu, CTypeGroup g) { mixin(S_TRACE);
  130. void delegate() dlg = null;
  131. auto mi = createMenuItem(_comm, menu, cTypeGroupToMenuID(g), dlg, g is CTypeGroup.Terminal ? &canConvTerminal : null, SWT.CASCADE);
  132. auto m = new Menu(_tree.control.getShell(), SWT.DROP_DOWN);
  133. mi.setMenu(m);
  134. return m;
  135. }
  136. private void refreshConvMenu() { mixin(S_TRACE);
  137. if (_readOnly) return;
  138. if (!_et || !selection) { mixin(S_TRACE);
  139. foreach (ce; _conts.values) { mixin(S_TRACE);
  140. if (ce.convMenuItem) ce.convMenuItem.setEnabled(false);
  141. }
  142. } else { mixin(S_TRACE);
  143. auto c = cast(Content) selection.getData();
  144. foreach (ce; _conts.values) { mixin(S_TRACE);
  145. if (ce.convMenuItem) ce.convMenuItem.setEnabled(c.canConvert(ce.type));
  146. }
  147. }
  148. }
  149. private class Converter {
  150. CType type;
  151. MenuItem convMenuItem;
  152. Cursor cursor;
  153. this (CType type) { mixin(S_TRACE);
  154. this.type = type;
  155. this.cursor = _prop.images.cursor(type);
  156. }
  157. void convert() { mixin(S_TRACE);
  158. auto sel = selection;
  159. if (!sel) return;
  160. auto c = cast(Content) sel.getData();
  161. if (c.type == type) return;
  162. store(c);
  163. _comm.delContent.call(c);
  164. assert (c.canConvert(type), "convert menu item enabled");
  165. auto oldd = c.detail;
  166. c.convertType(type, _prop.parent);
  167. auto newd = c.detail;
  168. if (newd.use(CArg.BG_IMAGES) && !oldd.use(CArg.BG_IMAGES)) { mixin(S_TRACE);
  169. c.backs = createBgImages(summSkin, _prop.var.etc.bgImagesDefault);
  170. }
  171. if (newd.use(CArg.DIALOGS) && !oldd.use(CArg.DIALOGS)) { mixin(S_TRACE);
  172. c.dialogs = [new SDialog];
  173. }
  174. sel.setImage(_prop.images.content(type));
  175. foreach (itm; _tree.getItems(sel)) { mixin(S_TRACE);
  176. itm.setText(eventText(c, cast(Content) itm.getData()));
  177. procTreeItem(itm);
  178. }
  179. procTreeItem(sel);
  180. refreshStatusLine();
  181. redraw();
  182. _comm.refUseCount.call();
  183. _comm.refreshToolBar();
  184. }
  185. }
  186. @property
  187. Item selection() { mixin(S_TRACE);
  188. if (!_tree.control || _tree.control.isDisposed()) return null;
  189. auto sels = _tree.getSelection();
  190. if (sels.length > 0) { mixin(S_TRACE);
  191. return sels[0];
  192. }
  193. return null;
  194. }
  195. class EditL : MouseAdapter, KeyListener {
  196. private void __edit() { mixin(S_TRACE);
  197. if (_readOnly) return;
  198. edit();
  199. }
  200. override void keyPressed(KeyEvent e) { mixin(S_TRACE);
  201. if (e.character == SWT.CR) { mixin(S_TRACE);
  202. __edit();
  203. }
  204. }
  205. override void keyReleased(KeyEvent e) {}
  206. override void mouseDoubleClick(MouseEvent e) { mixin(S_TRACE);
  207. if (e.button == 1 && !_tree.control.getCursor()) { mixin(S_TRACE);
  208. __edit();
  209. }
  210. }
  211. override void mouseUp(MouseEvent e) { mixin(S_TRACE);
  212. if (e.button == 1 && _clickStart) { mixin(S_TRACE);
  213. __edit();
  214. }
  215. }
  216. }
  217. class CreateL : MouseAdapter {
  218. override void mouseUp(MouseEvent e) { mixin(S_TRACE);
  219. if (!_box) return;
  220. if (_readOnly) return;
  221. if (_box._putMode is MenuID.PutQuick) return;
  222. if (e.button == 1) { mixin(S_TRACE);
  223. create(null);
  224. } else if (e.button == 2 && !_box._arrowMode) { mixin(S_TRACE);
  225. auto itm = _tree.getItem(new Point(e.x, e.y));
  226. if (itm && CDetail.fromType(_box._cType).owner) { mixin(S_TRACE);
  227. auto c = cast(Content) itm.getData();
  228. if (c.parent) { mixin(S_TRACE);
  229. _tree.setSelection([itm]);
  230. create(itm);
  231. _comm.refreshToolBar();
  232. }
  233. }
  234. } else if (e.button == 3) { mixin(S_TRACE);
  235. _box.arrow();
  236. _comm.refreshToolBar();
  237. }
  238. }
  239. }
  240. class MouseMove : MouseTrackAdapter, MouseMoveListener {
  241. override void mouseMove(MouseEvent e) { mixin(S_TRACE);
  242. if (!_box) return;
  243. _clickStart = null;
  244. if (!_readOnly && _box._arrowMode && _prop.var.etc.clickIconIsStartEdit) { mixin(S_TRACE);
  245. auto itm = _tree.getItem(new Point(e.x, e.y));
  246. if (itm) { mixin(S_TRACE);
  247. auto c = cast(Content)itm.getData();
  248. auto d = _tree.control.getDisplay();
  249. auto hand = d.getSystemCursor(SWT.CURSOR_HAND);
  250. if (_tree.getImageBounds(itm).contains(e.x, e.y) && hasDialog(c.type) && checkOpenDialog(c.type)) { mixin(S_TRACE);
  251. _clickStart = itm;
  252. if (_tree.editor) { mixin(S_TRACE);
  253. _tree.control.setCursor(hand);
  254. }
  255. } else { mixin(S_TRACE);
  256. if (_tree.editor && _tree.control.getCursor() is hand) { mixin(S_TRACE);
  257. _tree.control.setCursor(null);
  258. }
  259. }
  260. }
  261. }
  262. updateToolTip();
  263. }
  264. override void mouseExit(MouseEvent e) { mixin(S_TRACE);
  265. clearClickStart();
  266. }
  267. }
  268. void clearClickStart() { mixin(S_TRACE);
  269. auto d = _tree.control.getDisplay();
  270. auto hand = d.getSystemCursor(SWT.CURSOR_HAND);
  271. if (_clickStart && _tree.editor && _tree.editor && _tree.control.getCursor() is hand) { mixin(S_TRACE);
  272. _tree.control.setCursor(null);
  273. }
  274. }
  275. void updateToolTip() { mixin(S_TRACE);
  276. if (!_tree.tree) return;
  277. auto p = _tree.control.getDisplay().getCursorLocation();
  278. p = _tree.control.toControl(p);
  279. string toolTip = "";
  280. if (_tree.control.getClientArea().contains(p)) { mixin(S_TRACE);
  281. foreach (warn; _warningRects) { mixin(S_TRACE);
  282. if (warn.rect.contains(p)) { mixin(S_TRACE);
  283. toolTip = std.string.join(warn.warnings, .newline);
  284. break;
  285. }
  286. }
  287. }
  288. if (_tree.control.getToolTipText() != toolTip) { mixin(S_TRACE);
  289. _tree.control.setToolTipText(toolTip);
  290. }
  291. }
  292. UndoManager _undo;
  293. abstract static class ETVUndo : Undo {
  294. private size_t[] _etPath;
  295. private size_t[] _selPath = null, _selPath2 = null;
  296. protected EventTree et;
  297. protected Commons comm;
  298. protected Props prop;
  299. protected Summary summ;
  300. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et) { mixin(S_TRACE);
  301. this.et = et;
  302. this.comm = comm;
  303. this.prop = prop;
  304. this.summ = summ;
  305. _etPath = et.areaPath;
  306. if (v) { mixin(S_TRACE);
  307. auto sel = v.selection;
  308. _selPath = sel ? (cast(Content) sel.getData()).ctPath : null;
  309. }
  310. }
  311. void udb(EventTreeView v) { mixin(S_TRACE);
  312. if (!v) return;
  313. .forceFocus(v._tree.control, false);
  314. v._forceSel(_etPath);
  315. auto sel = v.selection;
  316. _selPath2 = sel ? (cast(Content) sel.getData()).ctPath : null;
  317. }
  318. void uda(EventTreeView v) { mixin(S_TRACE);
  319. scope (exit) comm.refreshToolBar();
  320. if (!v) return;
  321. if (_selPath) v._tree.select(v.fromPath(_selPath));
  322. _selPath = _selPath2;
  323. v.refreshStatusLine();
  324. }
  325. EventTreeView view() { mixin(S_TRACE);
  326. return comm.eventTreeViewFrom(et.cwxPath(true), false);
  327. }
  328. abstract override void undo();
  329. abstract override void redo();
  330. abstract override void dispose();
  331. }
  332. private static void insertStart(EventTreeView v, Commons comm, EventTree et, int index, Content c) { mixin(S_TRACE);
  333. if (v) v._tree.control.setRedraw(false);
  334. scope (exit) if (v) v._tree.control.setRedraw(true);
  335. bool empty = et.owner.isEmpty;
  336. scope (exit) {
  337. if (empty != et.owner.isEmpty) comm.refEventTree.call(et);
  338. }
  339. et.insert(index, c);
  340. if (v) { mixin(S_TRACE);
  341. if (v._tree.tree) { mixin(S_TRACE);
  342. auto itm = createTreeItem(v._tree.tree, c, c.name, v._prop.images.content(c.type), index);
  343. v.createChilds(itm, c);
  344. v._tree.setExpanded(itm, true);
  345. } else { mixin(S_TRACE);
  346. v._tree.editor.updateEventTree();
  347. }
  348. v.refreshStatusLine();
  349. v._refreshTopStart();
  350. v.redraw();
  351. }
  352. comm.refContent.call(c);
  353. comm.refUseCount.call();
  354. }
  355. static class UndoContent : ETVUndo {
  356. private size_t[][] _path;
  357. private Content[] _c;
  358. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et, Content[] cs) { mixin(S_TRACE);
  359. super (v, comm, prop, summ, et);
  360. foreach (c; cs) { mixin(S_TRACE);
  361. _path ~= c.ctPath;
  362. _c ~= c.dup;
  363. _c[$ - 1].setUseCounter(summ.useCounter.sub);
  364. }
  365. }
  366. private void impl() { mixin(S_TRACE);
  367. auto v = view();
  368. udb(v);
  369. scope (exit) uda(v);
  370. bool empty = et.owner.isEmpty;
  371. scope (exit) {
  372. if (empty != et.owner.isEmpty) comm.refEventTree.call(et);
  373. }
  374. foreach (i, c; _c.dup) { mixin(S_TRACE);
  375. int index = _path[i][$ - 1];
  376. auto tc = et.fromPath(_path[i]);
  377. if (c.type == CType.START) { mixin(S_TRACE);
  378. et.startUseCounter.change(tc.name, c.name);
  379. }
  380. _c[i] = tc.dup;
  381. _c[i].setUseCounter(summ.useCounter.sub);
  382. auto pc = tc.parent;
  383. string text;
  384. if (pc) { mixin(S_TRACE);
  385. pc.insert(prop.parent, index, c);
  386. text = .eventText(comm, summ, pc, c, false);
  387. } else { mixin(S_TRACE);
  388. et.insert(index, c);
  389. text = c.name;
  390. }
  391. if (v) v._tree.control.setRedraw(false);
  392. scope (exit) if (v) v._tree.control.setRedraw(true);
  393. if (v) { mixin(S_TRACE);
  394. if (v._tree.tree) { mixin(S_TRACE);
  395. auto now = cast(TreeItem)v.fromPath(_path[i]);
  396. auto par = now.getParentItem();
  397. TreeItem itm;
  398. if (par) { mixin(S_TRACE);
  399. itm = createTreeItem(par, c, text, prop.images.content(c.type), index);
  400. } else { mixin(S_TRACE);
  401. itm = createTreeItem(v._tree.tree, c, text, prop.images.content(c.type), index);
  402. }
  403. v.procTreeItem(itm);
  404. v.createChilds(itm, c);
  405. v._tree.setExpanded(itm, true);
  406. } else { mixin(S_TRACE);
  407. v._tree.editor.updateEventTree();
  408. }
  409. }
  410. delImpl(v, comm, et, tc);
  411. if (v && !pc) { mixin(S_TRACE);
  412. v._refreshTopStart();
  413. }
  414. }
  415. if (v) v.refreshStatusLine();
  416. comm.refUseCount.call();
  417. }
  418. override void undo() {impl();}
  419. override void redo() {impl();}
  420. override void dispose() { mixin(S_TRACE);
  421. foreach (c; _c) { mixin(S_TRACE);
  422. c.removeUseCounter();
  423. }
  424. }
  425. }
  426. void store(Content[] evt ...) { mixin(S_TRACE);
  427. _undo ~= new UndoContent(this, _comm, _prop, _summ, _et, evt);
  428. }
  429. static class UndoSwap : ETVUndo {
  430. private int _upIndex;
  431. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et, int swapIndex1, int swapIndex2) { mixin(S_TRACE);
  432. super (v, comm, prop, summ, et);
  433. _upIndex = swapIndex1 > swapIndex2 ? swapIndex1 : swapIndex2;
  434. }
  435. private void impl() { mixin(S_TRACE);
  436. auto v = view();
  437. udb(v);
  438. scope (exit) uda(v);
  439. udImpl!(-1)(v, comm, et, et.starts[_upIndex], false);
  440. }
  441. override void undo() {impl();}
  442. override void redo() {impl();}
  443. override void dispose() {}
  444. }
  445. void storeSwap(int swapIndex1, int swapIndex2) { mixin(S_TRACE);
  446. _undo ~= new UndoSwap(this, _comm, _prop, _summ, _et, swapIndex1, swapIndex2);
  447. }
  448. static class UndoInsert : ETVUndo {
  449. private int _index;
  450. private size_t _count;
  451. private Content[] _c;
  452. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et, int index, size_t count) { mixin(S_TRACE);
  453. super (v, comm, prop, summ, et);
  454. _index = index;
  455. _count = count;
  456. }
  457. override void undo() { mixin(S_TRACE);
  458. auto v = view();
  459. udb(v);
  460. scope (exit) uda(v);
  461. if (v) v._tree.control.setRedraw(false);
  462. scope (exit) if (v) v._tree.control.setRedraw(true);
  463. for (size_t i = 0; i < _count; i++) { mixin(S_TRACE);
  464. auto node = et.starts[_index].toNode(new XMLOption(prop.sys));
  465. auto ver = new XMLInfo(prop.sys, LATEST_VERSION);
  466. auto c = Content.createFromNode(node, ver);
  467. c.setUseCounter(summ.useCounter.sub);
  468. _c ~= c;
  469. delImpl(v, comm, et, et.starts[_index]);
  470. }
  471. comm.refUseCount.call();
  472. if (v) { mixin(S_TRACE);
  473. v.refreshStatusLine();
  474. v._refreshTopStart();
  475. }
  476. }
  477. override void redo() { mixin(S_TRACE);
  478. auto v = view();
  479. udb(v);
  480. scope (exit) uda(v);
  481. foreach_reverse (c; _c) { mixin(S_TRACE);
  482. insertStart(v, comm, et, _index, c);
  483. }
  484. _c = [];
  485. }
  486. override void dispose() { mixin(S_TRACE);
  487. foreach (c; _c) { mixin(S_TRACE);
  488. c.removeUseCounter();
  489. }
  490. }
  491. }
  492. void storeInsert(int insertIndex, size_t count = 1) { mixin(S_TRACE);
  493. _undo ~= new UndoInsert(this, _comm, _prop, _summ, _et, insertIndex, count);
  494. }
  495. static class UndoDelete : ETVUndo {
  496. private int _index;
  497. private Content _c;
  498. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et, int index, Content del) { mixin(S_TRACE);
  499. super (v, comm, prop, summ, et);
  500. _index = index;
  501. auto node = del.toNode(new XMLOption(prop.sys));
  502. auto ver = new XMLInfo(prop.sys, LATEST_VERSION);
  503. _c = Content.createFromNode(node, ver);
  504. _c.setUseCounter(summ.useCounter.sub);
  505. }
  506. override void undo() { mixin(S_TRACE);
  507. auto v = view();
  508. udb(v);
  509. scope (exit) uda(v);
  510. insertStart(v, comm, et, _index, _c);
  511. }
  512. override void redo() { mixin(S_TRACE);
  513. auto v = view();
  514. udb(v);
  515. scope (exit) uda(v);
  516. if (v) v._tree.control.setRedraw(false);
  517. scope (exit) if (v) v._tree.control.setRedraw(true);
  518. delImpl(v, comm, et, et.starts[_index]);
  519. comm.refUseCount.call();
  520. if (v) { mixin(S_TRACE);
  521. v.refreshStatusLine();
  522. v._refreshTopStart();
  523. }
  524. }
  525. override void dispose() { mixin(S_TRACE);
  526. _c.removeUseCounter();
  527. }
  528. }
  529. void storeDelete(int index, Content del) { mixin(S_TRACE);
  530. _undo ~= new UndoDelete(this, _comm, _prop, _summ, _et, index, del);
  531. }
  532. private Item fromPath(string cwxPath) { mixin(S_TRACE);
  533. return fromPathImpl(_tree, cwxPath);
  534. }
  535. private Item fromPathImpl(T)(T tree, string cwxPath) { mixin(S_TRACE);
  536. if (cpempty(cwxPath)) return null;
  537. string cate = cpcategory(cwxPath);
  538. while ("" != cate) { mixin(S_TRACE);
  539. cwxPath = cpbottom(cwxPath);
  540. if (cpempty(cwxPath)) return null;
  541. cate = cpcategory(cwxPath);
  542. }
  543. auto itm = _tree.getItem(tree, cpindex(cwxPath));
  544. cwxPath = cpbottom(cwxPath);
  545. if (cpempty(cwxPath)) return itm;
  546. return fromPathImpl(itm, cwxPath);
  547. }
  548. private Item fromPath(size_t[] path) { mixin(S_TRACE);
  549. return fromPathImpl(_tree, path);
  550. }
  551. private Item fromPathImpl(T)(T tree, size_t[] path) { mixin(S_TRACE);
  552. if (!path.length) return null;
  553. auto itm = _tree.getItem(tree, path[0]);
  554. if (path.length == 1) return itm;
  555. return fromPathImpl(itm, path[1 .. $]);
  556. }
  557. static class UndoCP : Undo {
  558. private UndoContent _undoC;
  559. private UndoDelete _undoD;
  560. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et, Content[] conts, int index, Content start) { mixin(S_TRACE);
  561. _undoC = new UndoContent(v, comm, prop, summ, et, conts);
  562. _undoD = new UndoDelete(v, comm, prop, summ, et, index, start);
  563. }
  564. override void undo() { mixin(S_TRACE);
  565. _undoD.undo();
  566. _undoC.undo();
  567. }
  568. override void redo() { mixin(S_TRACE);
  569. _undoC.redo();
  570. _undoD.redo();
  571. }
  572. override void dispose() { mixin(S_TRACE);
  573. _undoC.dispose();
  574. _undoD.dispose();
  575. }
  576. }
  577. static class UndoContentAndInsert : ETVUndo {
  578. private UndoContent _undoC;
  579. private UndoInsert _undoI;
  580. this (EventTreeView v, Commons comm, Props prop, Summary summ, EventTree et, Content owner, int insertIndex, int count) { mixin(S_TRACE);
  581. super (v, comm, prop, summ, et);
  582. _undoC = new UndoContent(v, comm, prop, summ, et, [owner]);
  583. _undoI = new UndoInsert(v, comm, prop, summ, et, insertIndex, count);
  584. }
  585. override void undo() { mixin(S_TRACE);
  586. _undoI.undo();
  587. _undoC.undo();
  588. }
  589. override void redo() { mixin(S_TRACE);
  590. _undoC.redo();
  591. _undoI.redo();
  592. }
  593. override void dispose() { mixin(S_TRACE);
  594. _undoC.dispose();
  595. _undoI.dispose();
  596. }
  597. }
  598. void storeContentAndInsert(Content owner, int insertIndex, int count) { mixin(S_TRACE);
  599. _undo ~= new UndoContentAndInsert(this, _comm, _prop, _summ, _et, owner, insertIndex, count);
  600. }
  601. private EventDialog[Content] _editDlgs;
  602. void appliedEdit(UndoContent undo, Content c) { mixin(S_TRACE);
  603. _undo ~= undo;
  604. auto itm = fromPath(c.cwxPath(true));
  605. assert (c is itm.getData());
  606. foreach (childItm; _tree.getItems(itm)) { mixin(S_TRACE);
  607. auto par = cast(Content)itm.getData();
  608. assert (par.detail.owner);
  609. childItm.setText(eventText(par, cast(Content) childItm.getData()));
  610. procTreeItem(childItm);
  611. }
  612. procTreeItem(itm);
  613. _tree.select(itm);
  614. .forceFocus(_tree.control, false);
  615. redraw();
  616. _comm.refContent.call(c);
  617. _comm.refUseCount.call();
  618. refreshStatusLine();
  619. _comm.refreshToolBar();
  620. }
  621. void editM() {edit();}
  622. public EventDialog edit() { mixin(S_TRACE);
  623. if (_readOnly) return null;
  624. auto sels = _tree.getSelection();
  625. if (sels.length > 0) { mixin(S_TRACE);
  626. auto c = cast(Content) sels[0].getData();
  627. return edit(c);
  628. }
  629. return null;
  630. }
  631. void create(Item insertTo) { mixin(S_TRACE);
  632. if (!_box) return;
  633. if (_readOnly) return;
  634. if (!_tree.getItemCount()) return;
  635. if (!_box._arrowMode || _box._putMode is MenuID.PutQuick) { mixin(S_TRACE);
  636. _tree.control.setRedraw(false);
  637. scope (exit) _tree.control.setRedraw(true);
  638. if (_box._cType == CType.START) { mixin(S_TRACE);
  639. if (insertTo) return;
  640. create(null, _box._cType, "", (Content evt) { mixin(S_TRACE);
  641. assert (evt);
  642. bool empty = _et.owner.isEmpty;
  643. scope (exit) {
  644. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  645. }
  646. auto sel = selection;
  647. int index;
  648. if (sel) { mixin(S_TRACE);
  649. index = _tree.indexOf(_tree.topItem(sel)) + 1;
  650. } else { mixin(S_TRACE);
  651. index = -1;
  652. }
  653. storeInsert(index);
  654. _et.insert(index, cast(Content)evt);
  655. Item sItm;
  656. if (_tree.tree) { mixin(S_TRACE);
  657. sItm = createTreeItem(_tree.tree, evt, evt.name, _prop.images.content(CType.START), index);
  658. } else { mixin(S_TRACE);
  659. _tree.editor.updateEventTree();
  660. sItm = EventEditorItem.valueOf(_tree.editor, evt);
  661. }
  662. _tree.select(sItm);
  663. _tree.showSelection();
  664. .forceFocus(_tree.control, false);
  665. _comm.refContent.call(evt);
  666. refreshStatusLine();
  667. if (_box._putMode !is MenuID.PutContinue) _box.arrow();
  668. _comm.refreshToolBar();
  669. });
  670. } else { mixin(S_TRACE);
  671. if (insertTo && !CDetail.fromType(_box._cType).owner) return;
  672. auto sel = selection;
  673. if (!sel) return;
  674. if (!insertTo && sel && !(cast(Content)sel.getData()).detail.owner) { mixin(S_TRACE);
  675. sel = _tree.getParentItem(sel);
  676. if (!sel) return;
  677. }
  678. if (insertTo || (sel && (cast(Content)sel.getData()).detail.owner)) { mixin(S_TRACE);
  679. Item oItm;
  680. int insertIndex = -1;
  681. if (insertTo) { mixin(S_TRACE);
  682. oItm = _tree.getParentItem(insertTo);
  683. if (!oItm) return;
  684. insertIndex = _tree.indexOf(oItm, insertTo);
  685. } else { mixin(S_TRACE);
  686. oItm = sel;
  687. }
  688. auto owner = cast(Content) oItm.getData();
  689. void applied(Content evt) { mixin(S_TRACE);
  690. bool empty = _et.owner.isEmpty;
  691. scope (exit) {
  692. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  693. }
  694. store(owner);
  695. if (insertIndex == -1) { mixin(S_TRACE);
  696. if (_box._insertFirst) { mixin(S_TRACE);
  697. owner.insert(_prop.parent, 0, evt);
  698. } else { mixin(S_TRACE);
  699. owner.add(_prop.parent, evt);
  700. }
  701. } else { mixin(S_TRACE);
  702. owner.insert(_prop.parent, insertIndex, evt);
  703. }
  704. Item itm;
  705. if (_tree.tree) { mixin(S_TRACE);
  706. itm = createTreeItem(cast(TreeItem)oItm, evt, eventText(owner, evt), _prop.images.content(evt.type), insertIndex);
  707. _tree.setExpanded(oItm, true);
  708. } else { mixin(S_TRACE);
  709. _tree.editor.updateEventTree();
  710. itm = EventEditorItem.valueOf(_tree.editor, evt);
  711. }
  712. _tree.setSelection([itm]);
  713. if (insertTo) { mixin(S_TRACE);
  714. auto ic = cast(Content) insertTo.getData();
  715. _comm.delContent.call(ic);
  716. ic.parent.remove(ic);
  717. if (_prop.var.etc.adjustContentName) { mixin(S_TRACE);
  718. ic.setName(_prop.parent, "");
  719. }
  720. if (_box._insertFirst) { mixin(S_TRACE);
  721. evt.insert(_prop.parent, 0, ic);
  722. } else { mixin(S_TRACE);
  723. evt.add(_prop.parent, ic);
  724. }
  725. insertTo.dispose();
  726. createChilds(itm, evt);
  727. _tree.setExpanded(itm, true);
  728. }
  729. procTreeItem(itm);
  730. _tree.showSelection();
  731. .forceFocus(_tree.control, false);
  732. _comm.refContent.call(evt);
  733. _comm.refUseCount.call();
  734. refreshStatusLine();
  735. if (_box._putMode !is MenuID.PutContinue) _box.arrow();
  736. _comm.refreshToolBar();
  737. }
  738. if (insertTo) { mixin(S_TRACE);
  739. create(owner, _box._cType, (cast(Content) insertTo.getData()).name, &applied);
  740. } else { mixin(S_TRACE);
  741. create(owner, _box._cType, "", &applied);
  742. }
  743. }
  744. }
  745. }
  746. }
  747. bool hasDialog(CType type) { mixin(S_TRACE);
  748. switch (type) {
  749. case CType.START:
  750. case CType.END_BAD_END:
  751. case CType.EFFECT_BREAK:
  752. case CType.ELAPSE_TIME:
  753. case CType.BRANCH_AREA:
  754. case CType.BRANCH_BATTLE:
  755. case CType.BRANCH_IS_BATTLE:
  756. case CType.SHOW_PARTY:
  757. case CType.HIDE_PARTY:
  758. return false;
  759. default:
  760. return true;
  761. }
  762. }
  763. bool checkOpenDialog(CType type) { mixin(S_TRACE);
  764. if (_readOnly) return false;
  765. switch (type) {
  766. case CType.START_BATTLE: { mixin(S_TRACE);
  767. return _summ.battles.length > 0;
  768. } case CType.CHANGE_AREA: { mixin(S_TRACE);
  769. return _summ.areas.length > 0;
  770. } case CType.LINK_PACKAGE, CType.CALL_PACKAGE: { mixin(S_TRACE);
  771. return _summ.packages.length > 0;
  772. } case CType.BRANCH_FLAG, CType.SET_FLAG, CType.REVERSE_FLAG, CType.CHECK_FLAG, CType.SUBSTITUTE_FLAG, CType.BRANCH_FLAG_CMP: { mixin(S_TRACE);
  773. return _summ.flagDirRoot.allFlags.length > 0;
  774. } case CType.BRANCH_MULTI_STEP, CType.BRANCH_STEP, CType.SET_STEP, CType.SET_STEP_UP, CType.SET_STEP_DOWN, CType.SUBSTITUTE_STEP, CType.BRANCH_STEP_CMP: { mixin(S_TRACE);
  775. return _summ.flagDirRoot.allSteps.length > 0;
  776. } case CType.BRANCH_CAST, CType.GET_CAST, CType.LOSE_CAST: { mixin(S_TRACE);
  777. return _summ.casts.length > 0;
  778. } case CType.BRANCH_ITEM, CType.GET_ITEM, CType.LOSE_ITEM: { mixin(S_TRACE);
  779. return _summ.items.length > 0;
  780. } case CType.BRANCH_SKILL, CType.GET_SKILL, CType.LOSE_SKILL: { mixin(S_TRACE);
  781. return _summ.skills.length > 0;
  782. } case CType.BRANCH_INFO, CType.GET_INFO, CType.LOSE_INFO: { mixin(S_TRACE);
  783. return _summ.infos.length > 0;
  784. } case CType.BRANCH_BEAST, CType.GET_BEAST, CType.LOSE_BEAST: { mixin(S_TRACE);
  785. return _summ.beasts.length > 0;
  786. } case CType.REDISPLAY: { mixin(S_TRACE);
  787. return !_summ.legacy;
  788. } default: { mixin(S_TRACE);
  789. return true;
  790. }
  791. }
  792. }
  793. void create(Content parent, CType type, string name, void delegate(Content) applied) { mixin(S_TRACE);
  794. if (!_box) return;
  795. if (_readOnly) return;
  796. assert (parent is null || parent.detail.owner);
  797. if (_box._putMode !is MenuID.PutContinue) { mixin(S_TRACE);
  798. _box.arrow();
  799. _comm.refreshToolBar();
  800. }
  801. void initial(Content c) { mixin(S_TRACE);
  802. if (type is CType.CHANGE_BG_IMAGE) { mixin(S_TRACE);
  803. c.backs = createBgImages(summSkin, _prop.var.etc.bgImagesDefault);
  804. } else if (type is CType.TALK_DIALOG) { mixin(S_TRACE);
  805. c.dialogs = [new SDialog];
  806. } else if (type is CType.BRANCH_SKILL || type is CType.BRANCH_ITEM || type is CType.BRANCH_BEAST) { mixin(S_TRACE);
  807. c.range = Range.FIELD;
  808. } else if (type is CType.LOSE_SKILL || type is CType.LOSE_ITEM || type is CType.LOSE_BEAST) { mixin(S_TRACE);
  809. c.range = Range.FIELD;
  810. }
  811. }
  812. if (hasDialog(type)) { mixin(S_TRACE);
  813. if (!_box._autoOpen || !checkOpenDialog(type)) { mixin(S_TRACE);
  814. auto c = new Content(type, name);
  815. initial(c);
  816. applied(c);
  817. return;
  818. }
  819. } else { mixin(S_TRACE);
  820. if (type is CType.START) { mixin(S_TRACE);
  821. string startName = _prop.msgs.defaultStartName;
  822. auto sel = selection;
  823. if (_prop.var.etc.useCurrentStartName && sel) { mixin(S_TRACE);
  824. if (auto s = (cast(Content)sel.getData()).parentStart) { mixin(S_TRACE);
  825. startName = s.name;
  826. }
  827. }
  828. name = createNewName(startName, (string name) { mixin(S_TRACE);
  829. foreach (start; _et.starts) { mixin(S_TRACE);
  830. if (icmp(start.name, name) == 0) return false;
  831. }
  832. return true;
  833. });
  834. }
  835. applied(new Content(type, name));
  836. return;
  837. }
  838. auto evt = new Content(type, name);
  839. initial(evt);
  840. auto dlg = createEventDialog(evt, parent, true);
  841. assert (applied);
  842. dlg.appliedEvent ~= { mixin(S_TRACE);
  843. auto evt = dlg.event;
  844. applied(evt);
  845. auto undo = new UndoContent(this, _comm, _prop, _summ, _et, [evt]);
  846. dlg.appliedEvent.length = 0;
  847. dlg.appliedEvent ~= { mixin(S_TRACE);
  848. appliedEdit(undo, evt);
  849. undo = new UndoContent(this, _comm, _prop, _summ, _et, [evt]);
  850. };
  851. };
  852. _editDlgs[evt] = dlg;
  853. dlg.closeEvent ~= { mixin(S_TRACE);
  854. _editDlgs.remove(evt);
  855. };
  856. dlg.open();
  857. }
  858. @property
  859. public bool canEdit() { mixin(S_TRACE);
  860. if (_readOnly) return false;
  861. auto itm = selection;
  862. if (!itm) return false;
  863. auto evt = cast(Content) itm.getData();
  864. return hasDialog(evt.type) && checkOpenDialog(evt.type);
  865. }
  866. EventDialog edit(Content evt) { mixin(S_TRACE);
  867. if (_readOnly) return null;
  868. if (!hasDialog(evt.type) || !checkOpenDialog(evt.type)) return null;
  869. auto p = evt in _editDlgs;
  870. if (p) { mixin(S_TRACE);
  871. p.active();
  872. return *p;
  873. }
  874. auto dlg = createEventDialog(evt, evt.parent, false);
  875. auto undo = new UndoContent(this, _comm, _prop, _summ, _et, [evt]);
  876. dlg.appliedEvent ~= { mixin(S_TRACE);
  877. appliedEdit(undo, evt);
  878. undo = new UndoContent(this, _comm, _prop, _summ, _et, [evt]);
  879. };
  880. _editDlgs[evt] = dlg;
  881. dlg.closeEvent ~= { mixin(S_TRACE);
  882. _editDlgs.remove(evt);
  883. };
  884. dlg.open();
  885. return dlg;
  886. }
  887. EventDialog createEventDialog(Content evt, Content parent, bool create) {
  888. EventDialog dlg;
  889. switch (evt.type) {
  890. case CType.START_BATTLE: { mixin(S_TRACE);
  891. dlg = new AreaSelectDialog!(CType.START_BATTLE, Battle, "summary.battles")
  892. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  893. break;
  894. } case CType.END: { mixin(S_TRACE);
  895. dlg = new ClearEventDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  896. break;
  897. } case CType.CHANGE_AREA: { mixin(S_TRACE);
  898. dlg = new AreaSelectDialog!(CType.CHANGE_AREA, Area, "summary.areas")
  899. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  900. break;
  901. } case CType.CHANGE_BG_IMAGE: { mixin(S_TRACE);
  902. if (create) { mixin(S_TRACE);
  903. evt.backs = createBgImages(summSkin, _prop.var.etc.bgImagesDefault);
  904. }
  905. dlg = new BgImagesDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, refTarget, CType.CHANGE_BG_IMAGE);
  906. break;
  907. } case CType.EFFECT: { mixin(S_TRACE);
  908. dlg = new EffectDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  909. break;
  910. } case CType.LINK_START: { mixin(S_TRACE);
  911. dlg = new StartSelectDialog!(CType.LINK_START)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  912. break;
  913. } case CType.LINK_PACKAGE: { mixin(S_TRACE);
  914. dlg = new AreaSelectDialog!(CType.LINK_PACKAGE, Package, "summary.packages")
  915. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  916. break;
  917. } case CType.TALK_MESSAGE: { mixin(S_TRACE);
  918. dlg = new MessageDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  919. break;
  920. } case CType.TALK_DIALOG: { mixin(S_TRACE);
  921. dlg = new SpeakDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  922. break;
  923. } case CType.PLAY_BGM: { mixin(S_TRACE);
  924. dlg = new BgmDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  925. break;
  926. } case CType.PLAY_SOUND: { mixin(S_TRACE);
  927. dlg = new SeDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  928. break;
  929. } case CType.WAIT: { mixin(S_TRACE);
  930. dlg = new WaitEventDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  931. break;
  932. } case CType.CALL_START: { mixin(S_TRACE);
  933. dlg = new StartSelectDialog!(CType.CALL_START)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  934. break;
  935. } case CType.CALL_PACKAGE: { mixin(S_TRACE);
  936. dlg = new AreaSelectDialog!(CType.CALL_PACKAGE, Package, "summary.packages")
  937. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  938. break;
  939. } case CType.BRANCH_FLAG: { mixin(S_TRACE);
  940. dlg = new BrFlagDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  941. break;
  942. } case CType.BRANCH_MULTI_STEP: { mixin(S_TRACE);
  943. dlg = new BrStepNDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  944. break;
  945. } case CType.BRANCH_STEP: { mixin(S_TRACE);
  946. dlg = new BrStepULDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  947. break;
  948. } case CType.BRANCH_SELECT: { mixin(S_TRACE);
  949. dlg = new BrMemberDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  950. break;
  951. } case CType.BRANCH_ABILITY: { mixin(S_TRACE);
  952. dlg = new BrPowerDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  953. break;
  954. } case CType.BRANCH_RANDOM: { mixin(S_TRACE);
  955. dlg = new BrRandomEventDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  956. break;
  957. } case CType.BRANCH_LEVEL: { mixin(S_TRACE);
  958. dlg = new BrLevelDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  959. break;
  960. } case CType.BRANCH_STATUS: { mixin(S_TRACE);
  961. dlg = new BrStateDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  962. break;
  963. } case CType.BRANCH_PARTY_NUMBER: { mixin(S_TRACE);
  964. dlg = new BrNumEventDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  965. break;
  966. } case CType.BRANCH_CAST: { mixin(S_TRACE);
  967. dlg = new AreaSelectDialog!(CType.BRANCH_CAST, CastCard, "summary.casts")
  968. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  969. break;
  970. } case CType.BRANCH_ITEM: { mixin(S_TRACE);
  971. dlg = new BrItemDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  972. break;
  973. } case CType.BRANCH_SKILL: { mixin(S_TRACE);
  974. dlg = new BrSkillDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  975. break;
  976. } case CType.BRANCH_INFO: { mixin(S_TRACE);
  977. dlg = new AreaSelectDialog!(CType.BRANCH_INFO, InfoCard, "summary.infos")
  978. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  979. break;
  980. } case CType.BRANCH_BEAST: { mixin(S_TRACE);
  981. dlg = new BrBeastDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  982. break;
  983. } case CType.BRANCH_MONEY: { mixin(S_TRACE);
  984. dlg = new MoneyEventDialog!(CType.BRANCH_MONEY)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  985. break;
  986. } case CType.BRANCH_COUPON: { mixin(S_TRACE);
  987. dlg = new BranchCouponDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  988. break;
  989. } case CType.BRANCH_COMPLETE_STAMP: { mixin(S_TRACE);
  990. dlg = new EndEventDialog!(CType.BRANCH_COMPLETE_STAMP)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  991. break;
  992. } case CType.BRANCH_GOSSIP: { mixin(S_TRACE);
  993. dlg = new GossipEventDialog!(CType.BRANCH_GOSSIP)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  994. break;
  995. } case CType.SET_FLAG: { mixin(S_TRACE);
  996. dlg = new FlagSetDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  997. break;
  998. } case CType.SET_STEP: { mixin(S_TRACE);
  999. dlg = new StepSetDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1000. break;
  1001. } case CType.SET_STEP_UP: { mixin(S_TRACE);
  1002. dlg = new StepPlusDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1003. break;
  1004. } case CType.SET_STEP_DOWN: { mixin(S_TRACE);
  1005. dlg = new StepMinusDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1006. break;
  1007. } case CType.REVERSE_FLAG: { mixin(S_TRACE);
  1008. dlg = new FlagRDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1009. break;
  1010. } case CType.CHECK_FLAG: { mixin(S_TRACE);
  1011. dlg = new FlagJudgeDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1012. break;
  1013. } case CType.GET_CAST: { mixin(S_TRACE);
  1014. dlg = new AreaSelectDialog!(CType.GET_CAST, CastCard, "summary.casts")
  1015. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1016. break;
  1017. } case CType.GET_ITEM: { mixin(S_TRACE);
  1018. dlg = new GetItemDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1019. break;
  1020. } case CType.GET_SKILL: { mixin(S_TRACE);
  1021. dlg = new GetSkillDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1022. break;
  1023. } case CType.GET_INFO: { mixin(S_TRACE);
  1024. dlg = new AreaSelectDialog!(CType.GET_INFO, InfoCard, "summary.infos")
  1025. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1026. break;
  1027. } case CType.GET_BEAST: { mixin(S_TRACE);
  1028. dlg = new GetBeastDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1029. break;
  1030. } case CType.GET_MONEY: { mixin(S_TRACE);
  1031. dlg = new MoneyEventDialog!(CType.GET_MONEY)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1032. break;
  1033. } case CType.GET_COUPON: { mixin(S_TRACE);
  1034. dlg = new GetCouponDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1035. break;
  1036. } case CType.GET_COMPLETE_STAMP: { mixin(S_TRACE);
  1037. dlg = new EndEventDialog!(CType.GET_COMPLETE_STAMP)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1038. break;
  1039. } case CType.GET_GOSSIP: { mixin(S_TRACE);
  1040. dlg = new GossipEventDialog!(CType.GET_GOSSIP)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1041. break;
  1042. } case CType.LOSE_CAST: { mixin(S_TRACE);
  1043. dlg = new AreaSelectDialog!(CType.LOSE_CAST, CastCard, "summary.casts")
  1044. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1045. break;
  1046. } case CType.LOSE_ITEM: { mixin(S_TRACE);
  1047. dlg = new LostItemDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1048. break;
  1049. } case CType.LOSE_SKILL: { mixin(S_TRACE);
  1050. dlg = new LostSkillDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1051. break;
  1052. } case CType.LOSE_INFO: { mixin(S_TRACE);
  1053. dlg = new AreaSelectDialog!(CType.LOSE_INFO, InfoCard, "summary.infos")
  1054. (_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1055. break;
  1056. } case CType.LOSE_BEAST: { mixin(S_TRACE);
  1057. dlg = new LostBeastDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1058. break;
  1059. } case CType.LOSE_MONEY: { mixin(S_TRACE);
  1060. dlg = new MoneyEventDialog!(CType.LOSE_MONEY)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1061. break;
  1062. } case CType.LOSE_COUPON: { mixin(S_TRACE);
  1063. dlg = new LoseCouponDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1064. break;
  1065. } case CType.LOSE_COMPLETE_STAMP: { mixin(S_TRACE);
  1066. dlg = new EndEventDialog!(CType.LOSE_COMPLETE_STAMP)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1067. break;
  1068. } case CType.LOSE_GOSSIP: { mixin(S_TRACE);
  1069. dlg = new GossipEventDialog!(CType.LOSE_GOSSIP)(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1070. break;
  1071. } case CType.REDISPLAY: { mixin(S_TRACE);
  1072. dlg = new RefreshDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1073. break;
  1074. } case CType.SUBSTITUTE_STEP: { mixin(S_TRACE);
  1075. dlg = new SubstituteStepDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1076. break;
  1077. } case CType.SUBSTITUTE_FLAG: { mixin(S_TRACE);
  1078. dlg = new SubstituteFlagDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1079. break;
  1080. } case CType.BRANCH_STEP_CMP: { mixin(S_TRACE);
  1081. dlg = new BrStepCmpDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1082. break;
  1083. } case CType.BRANCH_FLAG_CMP: { mixin(S_TRACE);
  1084. dlg = new BrFlagCmpDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1085. break;
  1086. } case CType.BRANCH_RANDOM_SELECT: { mixin(S_TRACE);
  1087. dlg = new BrRandomSelectDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1088. break;
  1089. } case CType.BRANCH_KEY_CODE: { mixin(S_TRACE);
  1090. dlg = new BrKeyCodeDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1091. break;
  1092. } case CType.CHECK_STEP: { mixin(S_TRACE);
  1093. dlg = new CheckStepDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, _summ.flagDirRoot);
  1094. break;
  1095. } case CType.BRANCH_ROUND: { mixin(S_TRACE);
  1096. dlg = new BranchRoundDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1097. break;
  1098. } case CType.MOVE_BG_IMAGE: { mixin(S_TRACE);
  1099. dlg = new MoveBgImageDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1100. break;
  1101. } case CType.REPLACE_BG_IMAGE: { mixin(S_TRACE);
  1102. dlg = new BgImagesDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt, refTarget, CType.REPLACE_BG_IMAGE);
  1103. break;
  1104. } case CType.LOSE_BG_IMAGE: { mixin(S_TRACE);
  1105. dlg = new LoseBgImageDialog(_comm, _prop, _tree.control.getShell(), _summ, parent, evt);
  1106. break;
  1107. } default: assert (0);
  1108. }
  1109. return dlg;
  1110. }
  1111. @property
  1112. AbstractArea refTarget() { mixin(S_TRACE);
  1113. if (_et && _et.owner) { mixin(S_TRACE);
  1114. auto a = cast(Area) _et.owner;
  1115. if (a) return a;
  1116. auto b = cast(Battle) _et.owner;
  1117. if (b) return b;
  1118. auto m = cast(MenuCard) _et.owner;
  1119. if (m) return m.owner;
  1120. auto e = cast(EnemyCard) _et.owner;
  1121. if (e) return e.owner;
  1122. }
  1123. return null;
  1124. }
  1125. void refreshStatusLine() { mixin(S_TRACE);
  1126. auto itm = selection;
  1127. if (itm) { mixin(S_TRACE);
  1128. _statusLine = .contentText(_comm, cast(Content) itm.getData());
  1129. } else { mixin(S_TRACE);
  1130. _statusLine = "";
  1131. }
  1132. _comm.setStatusLine(_tree.control, _statusLine);
  1133. }
  1134. class TListener : TreeListener {
  1135. override void treeCollapsed(TreeEvent e) { mixin(S_TRACE);
  1136. _comm.refreshToolBar();
  1137. }
  1138. override void treeExpanded(TreeEvent e) { mixin(S_TRACE);
  1139. _comm.refreshToolBar();
  1140. }
  1141. }
  1142. class SListener : SelectionAdapter {
  1143. public override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  1144. assert (cast(Content) e.item.getData());
  1145. refreshStatusLine();
  1146. _comm.refreshToolBar();
  1147. }
  1148. }
  1149. private Item _dragItm = null;
  1150. class EventDragSource : DragSourceListener {
  1151. private:
  1152. Item _parItm;
  1153. Item _targ;
  1154. public:
  1155. override void dragStart(DragSourceEvent e) { mixin(S_TRACE);
  1156. auto itm = selection;
  1157. e.doit = !_readOnly && itm && (cast(Content) itm.getData()).type != CType.START
  1158. && (cast(DragSource) e.getSource()).getControl().isFocusControl();
  1159. if (e.doit) { mixin(S_TRACE);
  1160. _targ = itm;
  1161. _parItm = _tree.getParentItem(itm);
  1162. _dragItm = _targ;
  1163. }
  1164. }
  1165. override void dragSetData(DragSourceEvent e) { mixin(S_TRACE);
  1166. auto itm = selection;
  1167. if (itm && XMLBytesTransfer.getInstance().isSupportedType(e.dataType)) { mixin(S_TRACE);
  1168. e.data = bytesFromXML(toXML((cast(Content)itm.getData())));
  1169. }
  1170. }
  1171. override void dragFinished(DragSourceEvent e) { mixin(S_TRACE);
  1172. _dragItm = null;
  1173. auto itm = _targ;
  1174. if (itm && e.detail == DND.DROP_MOVE) { mixin(S_TRACE);
  1175. bool empty = _et.owner.isEmpty;
  1176. scope (exit) {
  1177. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  1178. }
  1179. auto c = cast(Content) itm.getData();
  1180. _comm.delContent.call(c);
  1181. if (_parItm) { mixin(S_TRACE);
  1182. assert (_parItm.getData());
  1183. assert (itm.getData());
  1184. assert ((cast(Content) _parItm.getData()).detail.owner);
  1185. assert (cast(Content) itm.getData());
  1186. (cast(Content) _parItm.getData()).remove(c);
  1187. } else { mixin(S_TRACE);
  1188. _et.remove(c);
  1189. }
  1190. _tree.control.setRedraw(false);
  1191. itm.dispose();
  1192. if (_tree.editor) { mixin(S_TRACE);
  1193. _tree.editor.updateEventTree();
  1194. }
  1195. _tree.control.setRedraw(true);
  1196. _comm.refUseCount.call();
  1197. _comm.refreshToolBar();
  1198. }
  1199. }
  1200. }
  1201. class EventDropTarget : DropTargetAdapter {
  1202. private:
  1203. void move(DropTargetEvent e) { mixin(S_TRACE);
  1204. if (_readOnly) { mixin(S_TRACE);
  1205. e.detail = DND.DROP_NONE;
  1206. return;
  1207. }
  1208. if (_tree.tree) { mixin(S_TRACE);
  1209. e.detail = e.item ? DND.DROP_MOVE : DND.DROP_NONE;
  1210. } else { mixin(S_TRACE);
  1211. auto p = _tree.editor.toControl(new Point(e.x, e.y));
  1212. auto c = _tree.editor.getContent(p.x, p.y);
  1213. _tree.editor.updateLightup();
  1214. e.detail = c ? DND.DROP_MOVE : DND.DROP_NONE;
  1215. }
  1216. }
  1217. public:
  1218. override void dragEnter(DropTargetEvent e){ mixin(S_TRACE);
  1219. move(e);
  1220. }
  1221. override void dragOver(DropTargetEvent e){ mixin(S_TRACE);
  1222. move(e);
  1223. }
  1224. override void drop(DropTargetEvent e){ mixin(S_TRACE);
  1225. if (_readOnly) return;
  1226. e.detail = DND.DROP_NONE;
  1227. if (!isXMLBytes(e.data)) return;
  1228. if (!_tree.tree) { mixin(S_TRACE);
  1229. auto p = _tree.editor.toControl(new Point(e.x, e.y));
  1230. auto c = _tree.editor.getContent(p.x, p.y);
  1231. if (!c) return;
  1232. e.item = EventEditorItem.valueOf(_tree.editor, c);
  1233. }
  1234. assert (cast(Item)e.item);
  1235. auto ti = cast(Item)e.item;
  1236. if (!(cast(Content)ti.getData()).detail.owner) { mixin(S_TRACE);
  1237. ti = _tree.getParentItem(ti);
  1238. if (!ti) return;
  1239. }
  1240. if ((cast(Content)ti.getData()).detail.owner) { mixin(S_TRACE);
  1241. try { mixin(S_TRACE);
  1242. auto node = XNode.parse(bytesToXML(e.data));
  1243. bool samePane = _id == node.attr("paneId", false, "");
  1244. string id = node.attr("contentId", false, "");
  1245. string lastNextType = node.attr("lastNextType", false, "");
  1246. auto ver = new XMLInfo(_prop.sys, LATEST_VERSION);
  1247. auto evt = Content.createFromNode(node, ver);
  1248. if (evt) { mixin(S_TRACE);
  1249. auto owner = cast(Content)ti.getData();
  1250. assert (owner.detail.owner);
  1251. auto sp = selParent(ti);
  1252. if (!sp || sp.eventId != id) { mixin(S_TRACE);
  1253. // ???????????????????????
  1254. bool empty = _et.owner.isEmpty;
  1255. scope (exit) {
  1256. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  1257. }
  1258. if (_dragItm) { mixin(S_TRACE);
  1259. auto top = _tree.topItem(ti);
  1260. if (top == _tree.topItem(_dragItm)) { mixin(S_TRACE);
  1261. store(cast(Content)top.getData());
  1262. } else { mixin(S_TRACE);
  1263. store(cast(Content)_tree.getParentItem(_dragItm).getData(), owner);
  1264. }
  1265. } else { mixin(S_TRACE);
  1266. store(owner);
  1267. }
  1268. if (cast(Content)_tree.getParentItem(_dragItm).getData() !is owner) { mixin(S_TRACE);
  1269. adjustText(owner, evt, lastNextType);
  1270. }
  1271. if (_box._insertFirst) { mixin(S_TRACE);
  1272. owner.insert(_prop.parent, 0, evt);
  1273. } else { mixin(S_TRACE);
  1274. owner.add(_prop.parent, evt);
  1275. }
  1276. _comm.refContent.call(evt);
  1277. _tree.control.setRedraw(false);
  1278. Item itm;
  1279. if (_tree.tree) { mixin(S_TRACE);
  1280. itm = createTreeItem(cast(TreeItem)ti, evt, eventText(owner, evt), _prop.images.content(evt.type));
  1281. } else { mixin(S_TRACE);
  1282. _tree.editor.updateEventTree();
  1283. itm = EventEditorItem.valueOf(_tree.editor, evt);
  1284. }
  1285. procTreeItem(itm);
  1286. _tree.setSelection([itm]);
  1287. refreshStatusLine();
  1288. _comm.refUseCount.call();
  1289. if (evt.detail.owner) { mixin(S_TRACE);
  1290. createChilds(itm, evt);
  1291. _tree.setExpanded(itm, true);
  1292. }
  1293. _tree.control.setRedraw(true);
  1294. refreshStatusLine();
  1295. e.detail = samePane ? DND.DROP_MOVE : DND.DROP_COPY;
  1296. _comm.refreshToolBar();
  1297. }
  1298. }
  1299. } catch (Exception e) {
  1300. debugln(e);
  1301. }
  1302. }
  1303. }
  1304. private Content selParent(Item targ) { mixin(S_TRACE);
  1305. auto itm = selection;
  1306. if (itm) { mixin(S_TRACE);
  1307. while (targ) { mixin(S_TRACE);
  1308. if (itm == targ) { mixin(S_TRACE);
  1309. return cast(Content)itm.getData();
  1310. }
  1311. targ = _tree.getParentItem(targ);
  1312. }
  1313. }
  1314. return null;
  1315. }
  1316. }
  1317. private void adjustText(in Content owner, Content evt, string lastNextType) { mixin(S_TRACE);
  1318. if (_readOnly) return;
  1319. if (!_prop.var.etc.adjustContentName) return;
  1320. if (lastNextType != "" && owner.detail.nextType !is toCNextType(lastNextType)) { mixin(S_TRACE);
  1321. // ???????????????????????
  1322. evt.setName(_prop.parent, "");
  1323. } else if (owner.detail.nextType !is CNextType.TEXT) { mixin(S_TRACE);
  1324. foreach (ct; owner.next) { mixin(S_TRACE);
  1325. if (ct.name == evt.name) { mixin(S_TRACE);
  1326. // ??????????????????????
  1327. // ????????????
  1328. evt.setName(_prop.parent, "");
  1329. break;
  1330. }
  1331. }
  1332. }
  1333. }
  1334. void redraw() { mixin(S_TRACE);
  1335. if (_tree.editor) { mixin(S_TRACE);
  1336. _tree.editor.updateEventTree();
  1337. } else { mixin(S_TRACE);
  1338. _tree.control.redraw();
  1339. }
  1340. }
  1341. class TRDListener : DisposeListener {
  1342. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  1343. if (!_readOnly) { mixin(S_TRACE);
  1344. _comm.refSkin.remove(&refSkin);
  1345. _comm.refCast.remove(&__refreshCast);
  1346. _comm.delCast.remove(&__refreshCast);
  1347. _comm.refSkill.remove(&__refreshSkill);
  1348. _comm.delSkill.remove(&__refreshSkill);
  1349. _comm.refItem.remove(&__refreshItem);
  1350. _comm.delItem.remove(&__refreshItem);
  1351. _comm.refBeast.remove(&__refreshBeast);
  1352. _comm.delBeast.remove(&__refreshBeast);
  1353. _comm.refInfo.remove(&__refreshInfo);
  1354. _comm.delInfo.remove(&__refreshInfo);
  1355. _comm.refArea.remove(&__refreshArea);
  1356. _comm.delArea.remove(&__refreshArea);
  1357. _comm.refBattle.remove(&__refreshBattle);
  1358. _comm.delBattle.remove(&__refreshBattle);
  1359. _comm.refPackage.remove(&__refreshPackage);
  1360. _comm.delPackage.remove(&__refreshPackage);
  1361. _comm.refFlagAndStep.remove(&__refreshFlagAndStep);
  1362. _comm.delFlagAndStep.remove(&__refreshFlagAndStep);
  1363. _comm.refPath.remove(&__refreshPath);
  1364. _comm.refPaths.remove(&__refreshPaths);
  1365. _comm.delPaths.remove(&__deletePaths);
  1366. _comm.replPath.remove(&__replacePaths);
  1367. _comm.replText.remove(&__refreshCard);
  1368. _comm.replText.remove(&__refreshEventText);
  1369. _comm.replID.remove(&__refreshCard);
  1370. _comm.refContentText.remove(&refreshStatusLine);
  1371. _comm.refPreviewValues.remove(&__refreshEventText);
  1372. _comm.selContentTool.remove(&selContentTool);
  1373. _comm.refEventTemplates.remove(&refreshTemplates);
  1374. }
  1375. _comm.refTargetVersion.remove(&redraw);
  1376. _comm.refEventTreeViewStyle.remove(&refEventTreeViewStyle);
  1377. if (_grayFont) _grayFont.dispose();
  1378. foreach (dlg; _editDlgs.values) { mixin(S_TRACE);
  1379. dlg.forceCancel();
  1380. }
  1381. foreach (dlg; _commentDlgs.values) { mixin(S_TRACE);
  1382. dlg.forceCancel();
  1383. }
  1384. _prop.var.etc.showEventTreeDetail = _showEventTreeDetail;
  1385. }
  1386. }
  1387. /// ?????????????????
  1388. void drawStartInfo(PaintEvent e, Color lineColor, Color fontColor) { mixin(S_TRACE);
  1389. if (!_et) return;
  1390. assert (_tree.tree !is null);
  1391. if (!_prop.var.etc.drawCountOfUseOfStart && !_prop.var.etc.drawContentTreeLine) return;
  1392. auto d = _tree.control.getDisplay();
  1393. auto ca = _tree.control.getClientArea();
  1394. auto suc = _et.startUseCounter;
  1395. auto fore = e.gc.getForeground();
  1396. auto back = e.gc.getBackground();
  1397. auto counts = new string[_tree.getItemCount()];
  1398. auto ucExtent = e.gc.textExtent(_prop.msgs.startUseCount);
  1399. int maxW = 0;
  1400. int h = e.gc.getFontMetrics().getHeight();
  1401. if (_prop.var.etc.drawCountOfUseOfStart) { mixin(S_TRACE);
  1402. foreach (i, itm; _tree.tree.getItems()) { mixin(S_TRACE);
  1403. auto c = cast(Content)itm.get

Large files files are truncated, but you can click here to view the full file