PageRenderTime 91ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 1ms

/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
  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.getData();
  1404. assert (c);
  1405. int count = suc.get(toStartId(c.name));
  1406. if (0 == i) count++;
  1407. counts[i] = .text(count);
  1408. auto extent = e.gc.textExtent(counts[i]);
  1409. maxW = max(maxW, extent.x);
  1410. }
  1411. }
  1412. foreach (i, itm; _tree.tree.getItems()) { mixin(S_TRACE);
  1413. auto b = itm.getBounds();
  1414. if (b.y + b.height <= ca.y) continue;
  1415. if (ca.y + ca.height < b.y) break;
  1416. if (_prop.var.etc.drawContentTreeLine && 0 < i) { mixin(S_TRACE);
  1417. e.gc.setForeground(lineColor);
  1418. scope (exit) e.gc.setForeground(fore);
  1419. e.gc.drawLine(0, b.y, ca.width, b.y);
  1420. }
  1421. if (_prop.var.etc.drawCountOfUseOfStart) { mixin(S_TRACE);
  1422. string t = counts[i];
  1423. int tx = ca.width - maxW - 5;
  1424. int ty = b.y + (b.height - h) / 2;
  1425. e.gc.drawString(t, tx, ty);
  1426. e.gc.setForeground(fontColor);
  1427. scope (exit) e.gc.setForeground(fore);
  1428. e.gc.drawString(_prop.msgs.startUseCount, tx - ucExtent.x - 5, ty);
  1429. }
  1430. }
  1431. }
  1432. /// ???????????
  1433. void drawComment(PaintEvent e, Color lineColor) { mixin(S_TRACE);
  1434. assert (_tree.tree !is null);
  1435. auto fore = e.gc.getForeground();
  1436. auto back = e.gc.getBackground();
  1437. auto font = e.gc.getFont();
  1438. auto fSize = font ? cast(uint)font.getFontData()[0].height : 0;
  1439. e.gc.setFont(new Font(_tree.control.getDisplay(), dwtData(_prop.looks.textDlgFont(fSize))));
  1440. scope (exit) e.gc.getFont().dispose();
  1441. Rectangle[] boxes;
  1442. TreeItem[] itms;
  1443. void recurse(TreeItem itm) { mixin(S_TRACE);
  1444. boxes ~= itm.getBounds();
  1445. itms ~= itm;
  1446. if (_tree.getExpanded(itm)) { mixin(S_TRACE);
  1447. foreach (chld; itm.getItems()) { mixin(S_TRACE);
  1448. recurse(chld);
  1449. }
  1450. }
  1451. }
  1452. foreach (itm; _tree.tree.getItems()) { mixin(S_TRACE);
  1453. recurse(itm);
  1454. }
  1455. if (!itms.length) return;
  1456. auto ca = _tree.control.getClientArea();
  1457. auto itmBounds = itms[0].getBounds();
  1458. int itmH = itmBounds.height;
  1459. int mny = itmBounds.y;
  1460. auto bb = itms[$ - 1].getBounds();
  1461. int mxy = bb.y + bb.height;
  1462. int alpha = e.gc.getAlpha();
  1463. auto lineHeight = e.gc.getFontMetrics().getHeight();
  1464. Rectangle[] bs;
  1465. string[][] texts;
  1466. static const MARGIN_L = 5;
  1467. static const MARGIN_T = 4;
  1468. Image wImg = null;
  1469. scope (exit) {
  1470. if (wImg) wImg.dispose();
  1471. }
  1472. _warningRects = [];
  1473. Image warningImage() { mixin(S_TRACE);
  1474. if (!wImg) { mixin(S_TRACE);
  1475. wImg = .warningImage(_prop, _tree.control.getDisplay());
  1476. }
  1477. return wImg;
  1478. }
  1479. auto dotExtent = e.gc.textExtent("...");
  1480. foreach (i, itm; itms) { mixin(S_TRACE);
  1481. if (itm.getItemCount() && !itm.getExpanded()) { mixin(S_TRACE);
  1482. // ?????????????????
  1483. e.gc.setAlpha(128);
  1484. scope (exit) e.gc.setAlpha(255);
  1485. auto bounds = itm.getBounds();
  1486. int dotX = bounds.x + bounds.width + 2;
  1487. bounds.x = dotX + 10;
  1488. bounds.width = dotExtent.x + 10;
  1489. e.gc.drawString("...", bounds.x + 5, bounds.y + (bounds.height - dotExtent.y) / 2, true);
  1490. auto lineY = bounds.y + bounds.height / 2;
  1491. e.gc.drawLine(dotX, lineY, bounds.x, lineY);
  1492. e.gc.setAntialias(SWT.ON);
  1493. scope (exit) e.gc.setAntialias(SWT.OFF);
  1494. e.gc.drawRoundRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 10, 10);
  1495. }
  1496. auto c = cast(Content) itm.getData();
  1497. string cm = c.comment;
  1498. if (cm.length) { mixin(S_TRACE);
  1499. int dis = _prop.var.etc.commentBoxDistance;
  1500. auto ib = itm.getBounds();
  1501. cm = std.string.chomp(cm);
  1502. auto te = e.gc.textExtent(cm);
  1503. // ???????????????????
  1504. // ????
  1505. te.x = 0;
  1506. auto lines = splitLines!string(cm);
  1507. foreach (line; lines) { mixin(S_TRACE);
  1508. te.x = max(e.gc.textExtent(line).x, te.x);
  1509. }
  1510. int tx = ib.x + ib.width + dis;
  1511. int ty = ib.y + (ib.height - te.y) / 2;
  1512. int bx = tx - MARGIN_L;
  1513. int by = ty - MARGIN_T;
  1514. int bw = te.x + MARGIN_L * 2;
  1515. int bh = te.y + MARGIN_T * 2;
  1516. if (by < mny) { mixin(S_TRACE);
  1517. ty += mny - by;
  1518. by = ty - MARGIN_T;
  1519. }
  1520. if (mxy < by + bh) { mixin(S_TRACE);
  1521. ty -= by + bh - mxy;
  1522. by = ty - MARGIN_T;
  1523. }
  1524. auto box = new Rectangle(bx, by, bw, bh);
  1525. foreach (b; boxes) { mixin(S_TRACE);
  1526. if (b.intersects(box)) { mixin(S_TRACE);
  1527. bx = b.x + b.width + MARGIN_L;
  1528. box.x = bx;
  1529. tx = bx + MARGIN_L;
  1530. dis = tx - ib.x - ib.width;
  1531. }
  1532. }
  1533. /// ??????????
  1534. e.gc.setBackground(lineColor);
  1535. scope (exit) e.gc.setBackground(back);
  1536. int px = ib.x + ib.width + 2;
  1537. int py = ib.y + ib.height / 2 - 1;
  1538. e.gc.fillRectangle(px, py, dis - MARGIN_L - 2, 1);
  1539. boxes ~= box;
  1540. bs ~= box;
  1541. texts ~= lines;
  1542. }
  1543. if (_prop.var.etc.drawContentWarnings) { mixin(S_TRACE);
  1544. auto warnings = .warnings(_prop.parent, summSkin, _summ, c, _prop.var.etc.targetVersion);
  1545. if (warnings.length) { mixin(S_TRACE);
  1546. auto b = itm.getBounds();
  1547. if (b.y + b.height <= ca.y) continue;
  1548. if (ca.y + ca.height < b.y) continue;
  1549. auto ib = itm.getImageBounds(0);
  1550. if (ca.width <= ib.x) continue;
  1551. auto img = warningImage();
  1552. int ix = .max(ib.x, ca.width - _prop.var.etc.warningImageWidth);
  1553. e.gc.drawImage(img, 0, 0, _prop.var.etc.warningImageWidth, 1, ix, b.y, ca.width - ix, itmH);
  1554. auto bounds = _prop.images.warning.getBounds();
  1555. int wx = .max(b.x + b.width, ca.width - bounds.width - 1);
  1556. if (wx < ca.width) { mixin(S_TRACE);
  1557. e.gc.drawImage(_prop.images.warning, wx, b.y + (itmH - bounds.height) / 2);
  1558. }
  1559. auto rect = new Rectangle(ix, b.y, _prop.var.etc.warningImageWidth, b.height);
  1560. _warningRects ~= Warning(rect, warnings);
  1561. }
  1562. }
  1563. }
  1564. updateToolTip();
  1565. foreach (i, lines; texts) { mixin(S_TRACE);
  1566. auto b = bs[i];
  1567. int bx = b.x;
  1568. int by = b.y;
  1569. int bw = b.width;
  1570. int bh = b.height;
  1571. int tx = b.x + MARGIN_L;
  1572. int ty = b.y + MARGIN_T;
  1573. e.gc.setAlpha(128);
  1574. e.gc.fillRectangle(bx, by, bw, bh);
  1575. e.gc.setAlpha(alpha);
  1576. // FIXME: ???????????????
  1577. // e.gc.drawString(cm, tx, ty, true);
  1578. foreach (line; lines) { mixin(S_TRACE);
  1579. e.gc.drawString(line, tx, ty, true);
  1580. ty += lineHeight;
  1581. }
  1582. // FIXME: ????setAlpha()??????????????
  1583. e.gc.setBackground(lineColor);
  1584. scope (exit) e.gc.setBackground(back);
  1585. // e.gc.drawRectangle(bx, by, bw, bh);
  1586. // e.gc.drawLine(px, py, px + dis - MARGIN_L - 2, py);
  1587. e.gc.fillRectangle(bx, by, bw, 1);
  1588. e.gc.fillRectangle(bx, by + bh - 1, bw, 1);
  1589. e.gc.fillRectangle(bx, by + 1, 1, bh - 2);
  1590. e.gc.fillRectangle(bx + bw - 1, by + 1, 1, bh - 2);
  1591. }
  1592. }
  1593. class PaintTree : PaintListener {
  1594. override void paintControl(PaintEvent e) { mixin(S_TRACE);
  1595. auto d = _tree.control.getDisplay();
  1596. auto fore = e.gc.getForeground();
  1597. auto back = e.gc.getBackground();
  1598. auto lineColor = new Color(d, alphaColor(fore.getRGB(), back.getRGB(), 64));
  1599. scope (exit) lineColor.dispose();
  1600. drawStartInfo(e, lineColor, _grayFont);
  1601. drawComment(e, lineColor);
  1602. }
  1603. }
  1604. private void selContentTool(bool arrowMode, CType cType, MenuID putMode, bool autoOpen, bool insertFirst) {
  1605. Cursor cursor = null;
  1606. if (!arrowMode) {
  1607. cursor = _conts[cType].cursor;
  1608. }
  1609. _comp.setCursor(cursor);
  1610. _arrowMode = arrowMode;
  1611. _cType = cType;
  1612. }
  1613. private void refreshTemplates() { mixin(S_TRACE);
  1614. if (!_evTemplM) return;
  1615. ContentsToolBox.refreshTemplates(_comm, _prop, _summ, _evTemplM, widget.getShell(), () => _et !is null, &pasteScript);
  1616. }
  1617. public:
  1618. this (Commons comm, Props prop, Summary summ, Composite parent, UndoManager undo,
  1619. void delegate(size_t[]) forceSel,
  1620. void delegate() refreshTopStart,
  1621. Composite contentsBoxArea, bool readOnly) { mixin(S_TRACE);
  1622. _id = format("%08X", &this) ~ "-" ~ to!(string)(Clock.currTime());
  1623. _comm = comm;
  1624. _prop = prop;
  1625. _summ = summ;
  1626. _undo = undo;
  1627. _readOnly = readOnly ? SWT.READ_ONLY : SWT.NONE;
  1628. if (_readOnly) _summSkin = findSkin(_comm, _prop, _summ);
  1629. _forceSel = forceSel;
  1630. _refreshTopStart = refreshTopStart;
  1631. _contentsBoxArea = contentsBoxArea;
  1632. _comp = new Composite(parent, SWT.NONE);
  1633. _comp.setLayout(zeroGridLayout(1, false));
  1634. _comp.addDisposeListener(new TRDListener);
  1635. _showEventTreeDetail = _prop.var.etc.showEventTreeDetail;
  1636. if (!_readOnly) { mixin(S_TRACE);
  1637. _cbarPar = new Composite(_comp, SWT.NONE);
  1638. _comm.refSkin.add(&refSkin);
  1639. _comm.refCast.add(&__refreshCast);
  1640. _comm.delCast.add(&__refreshCast);
  1641. _comm.refSkill.add(&__refreshSkill);
  1642. _comm.delSkill.add(&__refreshSkill);
  1643. _comm.refItem.add(&__refreshItem);
  1644. _comm.delItem.add(&__refreshItem);
  1645. _comm.refBeast.add(&__refreshBeast);
  1646. _comm.delBeast.add(&__refreshBeast);
  1647. _comm.refInfo.add(&__refreshInfo);
  1648. _comm.delInfo.add(&__refreshInfo);
  1649. _comm.refArea.add(&__refreshArea);
  1650. _comm.delArea.add(&__refreshArea);
  1651. _comm.refBattle.add(&__refreshBattle);
  1652. _comm.delBattle.add(&__refreshBattle);
  1653. _comm.refPackage.add(&__refreshPackage);
  1654. _comm.delPackage.add(&__refreshPackage);
  1655. _comm.refFlagAndStep.add(&__refreshFlagAndStep);
  1656. _comm.delFlagAndStep.add(&__refreshFlagAndStep);
  1657. _comm.refPath.add(&__refreshPath);
  1658. _comm.refPaths.add(&__refreshPaths);
  1659. _comm.delPaths.add(&__deletePaths);
  1660. _comm.replPath.add(&__replacePaths);
  1661. _comm.replText.add(&__refreshCard);
  1662. _comm.replText.add(&__refreshEventText);
  1663. _comm.replID.add(&__refreshCard);
  1664. _comm.refContentText.add(&refreshStatusLine);
  1665. _comm.refPreviewValues.add(&__refreshEventText);
  1666. _comm.selContentTool.add(&selContentTool);
  1667. _comm.refEventTemplates.add(&refreshTemplates);
  1668. }
  1669. _comm.refTargetVersion.add(&redraw);
  1670. _comm.refEventTreeViewStyle.add(&refEventTreeViewStyle);
  1671. foreach (cGrp, cs; CTYPE_GROUP) { mixin(S_TRACE);
  1672. foreach (cType; cs) { mixin(S_TRACE);
  1673. _conts[cType] = new Converter(cType);
  1674. }
  1675. }
  1676. refEventTreeViewStyle();
  1677. }
  1678. private void refEventTreeViewStyle() { mixin(S_TRACE);
  1679. _comp.setRedraw(false);
  1680. scope (exit) _comp.setRedraw(true);
  1681. auto sel = selection;
  1682. size_t[] ctPath = sel ? (cast(Content)sel.getData()).ctPath : [];
  1683. auto et = _et;
  1684. refresh(null);
  1685. if (_tree.tree) { mixin(S_TRACE);
  1686. _tree.tree.dispose();
  1687. _tree.tree = null;
  1688. }
  1689. if (_tree.editor) { mixin(S_TRACE);
  1690. _tree.editor.dispose();
  1691. _tree.editor = null;
  1692. }
  1693. if (_prop.var.etc.straightEventTreeView) { mixin(S_TRACE);
  1694. _tree.editor = new EventEditor(_comm, _comp, SWT.BORDER | _readOnly, _summ, null);
  1695. _tree.editor.showEventTreeDetail = _showEventTreeDetail;
  1696. new EventEdit(_comm, _tree.editor, &editEnd, &createEditor);
  1697. } else { mixin(S_TRACE);
  1698. _tree.tree = new Tree(_comp, SWT.SINGLE | SWT.BORDER | SWT.VIRTUAL);
  1699. initTree(_comm, _tree.tree, true);
  1700. if (!_readOnly) { mixin(S_TRACE);
  1701. new TreeEdit(_comm, _tree.tree, &editEnd, &createEditor);
  1702. }
  1703. _tree.tree.addPaintListener(new PaintTree);
  1704. if (!_grayFont) { mixin(S_TRACE);
  1705. _grayFont = new Color(_tree.control.getDisplay(), alphaColor(_tree.tree.getForeground().getRGB(), _tree.tree.getBackground().getRGB(), 128));
  1706. }
  1707. }
  1708. _tree.control.setLayoutData(new GridData(GridData.FILL_BOTH));
  1709. _tree.control.addMouseListener(new CreateL);
  1710. auto mml = new MouseMove;
  1711. _tree.control.addMouseMoveListener(mml);
  1712. _tree.control.addMouseTrackListener(mml);
  1713. auto editl = new EditL;
  1714. _tree.control.addKeyListener(editl);
  1715. _tree.control.addMouseListener(editl);
  1716. _tree.addTreeListener(new TListener);
  1717. _tree.addSelectionListener(new SListener);
  1718. .listener(_tree.control, SWT.KeyUp, { mixin(S_TRACE);
  1719. _comm.refreshToolBar();
  1720. });
  1721. void initMenu() { mixin(S_TRACE);
  1722. auto shell = _tree.control.getShell();
  1723. auto popup = new Menu(shell, SWT.POP_UP);
  1724. if (!_readOnly) { mixin (S_TRACE);
  1725. createMenuItem(_comm, popup, MenuID.EditProp, &editM, &canEdit);
  1726. new MenuItem(popup, SWT.SEPARATOR);
  1727. createMenuItem(_comm, popup, MenuID.Comment, &writeComment, &canWriteComment);
  1728. new MenuItem(popup, SWT.SEPARATOR);
  1729. createMenuItem(_comm, popup, MenuID.Undo, &this.undo, () => !_readOnly && _undo.canUndo);
  1730. createMenuItem(_comm, popup, MenuID.Redo, &this.redo, () => !_readOnly && _undo.canRedo);
  1731. new MenuItem(popup, SWT.SEPARATOR);
  1732. appendMenuTCPD(_comm, popup, this, true, true, true, true, true);
  1733. new MenuItem(popup, SWT.SEPARATOR);
  1734. createMenuItem(_comm, popup, MenuID.Cut1Content, &cut1Content, &canCut1Content);
  1735. } else {
  1736. appendMenuTCPD(_comm, popup, this, false, true, false, false, false);
  1737. new MenuItem(popup, SWT.SEPARATOR);
  1738. }
  1739. createMenuItem(_comm, popup, MenuID.Copy1Content, &copy1Content, &canCopy1Content);
  1740. if (!_readOnly) { mixin (S_TRACE);
  1741. createMenuItem(_comm, popup, MenuID.Delete1Content, &del1Content, &canDel1Content);
  1742. new MenuItem(popup, SWT.SEPARATOR);
  1743. createMenuItem(_comm, popup, MenuID.PasteInsert, &pasteInsert, &canPasteInsert);
  1744. new MenuItem(popup, SWT.SEPARATOR);
  1745. createMenuItem(_comm, popup, MenuID.SwapToParent, &swapToParent, &canSwapToParent);
  1746. createMenuItem(_comm, popup, MenuID.SwapToChild, &swapToChild, &canSwapToChild);
  1747. }
  1748. new MenuItem(popup, SWT.SEPARATOR);
  1749. createMenuItem(_comm, popup, MenuID.Expand, &expand, &canExpand);
  1750. createMenuItem(_comm, popup, MenuID.Collapse, &collapse, &canCollapse);
  1751. new MenuItem(popup, SWT.SEPARATOR);
  1752. createMenuItem(_comm, popup, MenuID.ToScript, &toScript, &canToScript);
  1753. createMenuItem(_comm, popup, MenuID.ToScript1Content, &toScript1Content, &canToScript);
  1754. createMenuItem(_comm, popup, MenuID.ToScriptAll, &toScriptAll, &canToScriptAll);
  1755. if (!_readOnly) { mixin (S_TRACE);
  1756. new MenuItem(popup, SWT.SEPARATOR);
  1757. createMenuItem(_comm, popup, MenuID.StartToPackage, &startToPackage, &canStartToPackage);
  1758. createMenuItem(_comm, popup, MenuID.WrapTree, &wrapTree, &canWrapTree);
  1759. new MenuItem(popup, SWT.SEPARATOR);
  1760. void delegate() dlg = null;
  1761. auto createMI = createMenuItem(_comm, popup, MenuID.CreateContent, dlg, () => _et !is null, SWT.CASCADE);
  1762. _createM = new Menu(_tree.control.getShell(), SWT.DROP_DOWN);
  1763. createMI.setMenu(_createM);
  1764. auto convMI = createMenuItem(_comm, popup, MenuID.ConvertContent, dlg, { mixin(S_TRACE);
  1765. if (_readOnly) return false;
  1766. auto itm = selection;
  1767. if (!itm) return false;
  1768. auto evt = cast(Content) itm.getData();
  1769. return evt.type !is CType.START;
  1770. }, SWT.CASCADE);
  1771. _convM = new Menu(_tree.control.getShell(), SWT.DROP_DOWN);
  1772. convMI.setMenu(_convM);
  1773. new MenuItem(popup, SWT.SEPARATOR);
  1774. auto evTemplMI = createMenuItem(_comm, popup, MenuID.EvTemplates, dlg, () => _summ && _et && (_prop.var.etc.eventTemplates.length || _summ.eventTemplates.length), SWT.CASCADE);
  1775. _evTemplM = new Menu(_tree.control.getShell(), SWT.DROP_DOWN);
  1776. evTemplMI.setMenu(_evTemplM);
  1777. // initConvMenu()????????????????
  1778. auto shown = new class MenuAdapter {
  1779. override void menuShown(MenuEvent e) { mixin(S_TRACE);
  1780. initConvMenu();
  1781. _createM.removeMenuListener(this);
  1782. _convM.removeMenuListener(this);
  1783. }
  1784. };
  1785. _createM.addMenuListener(shown);
  1786. _convM.addMenuListener(shown);
  1787. .listener(_convM, SWT.Show, &refreshConvMenu);
  1788. refreshTemplates();
  1789. }
  1790. /+ debug {
  1791. new MenuItem(popup, SWT.SEPARATOR);
  1792. createMenuItem2(_comm, popup, "debug: Create CWX &Path", null, &createCWXPath, () => selection !is null);
  1793. }
  1794. +/
  1795. _tree.control.setMenu(popup);
  1796. }
  1797. auto im = new class PaintListener {
  1798. override void paintControl(PaintEvent e) { mixin(S_TRACE);
  1799. _tree.control.removePaintListener(this);
  1800. initMenu();
  1801. }
  1802. };
  1803. _tree.control.addPaintListener(im);
  1804. if (!_readOnly) { mixin(S_TRACE);
  1805. auto dt = new DropTarget(_tree.control, DND.DROP_DEFAULT | DND.DROP_MOVE);
  1806. dt.setTransfer([XMLBytesTransfer.getInstance()]);
  1807. dt.addDropListener(new EventDropTarget);
  1808. }
  1809. auto ds = new DragSource(_tree.control, DND.DROP_MOVE);
  1810. ds.setTransfer([XMLBytesTransfer.getInstance()]);
  1811. ds.addDragListener(new EventDragSource);
  1812. if (!_readOnly) { mixin(S_TRACE);
  1813. .listener(widget, SWT.Paint, { mixin(S_TRACE);
  1814. if (!(_prop.var.etc.contentsFloat || _prop.var.etc.contentsAutoHide)) getContentsBox();
  1815. });
  1816. }
  1817. _comp.layout();
  1818. refresh(et);
  1819. if (ctPath.length) { mixin(S_TRACE);
  1820. sel = fromPath(ctPath);
  1821. _tree.setSelection([sel]);
  1822. _tree.showSelection();
  1823. }
  1824. }
  1825. private Composite _cbarPar = null;
  1826. @property
  1827. Control widget() {return _comp;}
  1828. @property
  1829. ContentsToolBox contentsToolBox() { return _box; }
  1830. @property
  1831. private Composite boxOwner() { return _cbarPar; }
  1832. @property
  1833. string statusLine() {return _statusLine;}
  1834. void undo() { mixin(S_TRACE);
  1835. if (_readOnly) return;
  1836. _undo.undo();
  1837. _comm.refreshToolBar();
  1838. }
  1839. void redo() { mixin(S_TRACE);
  1840. if (_readOnly) return;
  1841. _undo.redo();
  1842. _comm.refreshToolBar();
  1843. }
  1844. debug {
  1845. void createCWXPath() { mixin(S_TRACE);
  1846. auto itm = selection;
  1847. if (itm) { mixin(S_TRACE);
  1848. auto c = cast(Content) itm.getData();
  1849. _comm.clipboard.setContents([new ArrayWrapperString(c.cwxPath(true))], [TextTransfer.getInstance()]);
  1850. _comm.refreshToolBar();
  1851. }
  1852. }
  1853. }
  1854. @property
  1855. bool canToScript() { mixin(S_TRACE);
  1856. return selection !is null;
  1857. }
  1858. @property
  1859. bool canToScriptAll() { mixin(S_TRACE);
  1860. return _et !is null;
  1861. }
  1862. void toScript() { mixin(S_TRACE);
  1863. auto itm = selection;
  1864. if (!itm) return;
  1865. auto c = cast(Content) itm.getData();
  1866. auto script = new CWXScript(_prop.parent, _summ);
  1867. auto text = script.toScript([c], summSkin.evtChildOK, _summ.legacy, "\t");
  1868. text = std.array.replace(text ~ "\n", "\n", .newline);
  1869. _comm.clipboard.setContents([new ArrayWrapperString(text)], [TextTransfer.getInstance()]);
  1870. _comm.refreshToolBar();
  1871. }
  1872. void toScriptAll() { mixin(S_TRACE);
  1873. if (!_et) return;
  1874. auto script = new CWXScript(_prop.parent, _summ);
  1875. auto text = script.toScript(_et.starts, summSkin.evtChildOK, _summ.legacy, "\t");
  1876. text = std.array.replace(text ~ "\n", "\n", .newline);
  1877. _comm.clipboard.setContents([new ArrayWrapperString(text)], [TextTransfer.getInstance()]);
  1878. _comm.refreshToolBar();
  1879. }
  1880. void toScript1Content() { mixin(S_TRACE);
  1881. auto itm = selection;
  1882. if (!itm) return;
  1883. auto c = cast(Content) itm.getData();
  1884. auto script = new CWXScript(_prop.parent, _summ);
  1885. auto c2 = new Content(c.type, c.name);
  1886. c2.shallowCopy(c);
  1887. auto text = script.toScript([c2], summSkin.evtChildOK, _summ.legacy, "\t");
  1888. text = std.array.replace(text ~ "\n", "\n", .newline);
  1889. _comm.clipboard.setContents([new ArrayWrapperString(text)], [TextTransfer.getInstance()]);
  1890. _comm.refreshToolBar();
  1891. }
  1892. private ContentCommentDialog[Content] _commentDlgs;
  1893. @property
  1894. bool canWriteComment() { mixin(S_TRACE);
  1895. if (_readOnly) return false;
  1896. return selection !is null;
  1897. }
  1898. void writeComment() { mixin(S_TRACE);
  1899. if (_readOnly) return;
  1900. auto itm = selection;
  1901. if (!itm) return;
  1902. .forceFocus(_tree.control, false);
  1903. auto c = cast(Content) itm.getData();
  1904. auto p = c in _commentDlgs;
  1905. if (p) { mixin(S_TRACE);
  1906. p.active();
  1907. return;
  1908. }
  1909. auto dlg = new ContentCommentDialog(_comm, _prop, _tree.control.getShell(), c.parent, c);
  1910. auto undo = new UndoContent(this, _comm, _prop, _summ, _et, [c]);
  1911. dlg.appliedEvent ~= { mixin(S_TRACE);
  1912. _undo ~= undo;
  1913. undo = new UndoContent(this, _comm, _prop, _summ, _et, [c]);
  1914. redraw();
  1915. };
  1916. _commentDlgs[c] = dlg;
  1917. dlg.closeEvent ~= { mixin(S_TRACE);
  1918. _commentDlgs.remove(c);
  1919. };
  1920. dlg.open();
  1921. }
  1922. @property
  1923. bool canStartToPackage() { mixin(S_TRACE);
  1924. return !_readOnly && 1 < _tree.getItemCount() && selection !is null;
  1925. }
  1926. void startToPackage() { mixin(S_TRACE);
  1927. if (!canStartToPackage) return;
  1928. if (!_et || !selection) return;
  1929. if (_tree.getItemCount() <= 1) return;
  1930. auto sel = selection;
  1931. if (!sel) return;
  1932. auto base = cast(Content) selection.getData();
  1933. auto startItm = _tree.topItem(sel);
  1934. auto start = base.parentStart;
  1935. assert (start);
  1936. assert (start is startItm.getData(), start.name ~ " : " ~ startItm.getText());
  1937. int index = _tree.indexOf(startItm);
  1938. Item[] users;
  1939. Content[] conts = [start];
  1940. void find(Item itm) { mixin(S_TRACE);
  1941. if (itm == startItm) return;
  1942. auto c = cast(Content)itm.getData();
  1943. if (c.start == start.name) { mixin(S_TRACE);
  1944. users ~= itm;
  1945. conts ~= c;
  1946. }
  1947. foreach (cld; _tree.getItems(itm)) find(cld);
  1948. }
  1949. foreach (itm; _tree.getItems()) find(itm);
  1950. auto ucp = new UndoCP(this, _comm, _prop, _summ, _et, conts, index, start);
  1951. auto id = _comm.createPackage(start, false);
  1952. if (id == 0) { mixin(S_TRACE);
  1953. ucp.dispose();
  1954. return;
  1955. }
  1956. _undo ~= ucp;
  1957. delImpl(startItm, false);
  1958. foreach (itm; users) { mixin(S_TRACE);
  1959. auto c = cast(Content) itm.getData();
  1960. switch (c.type) {
  1961. case CType.LINK_START: { mixin(S_TRACE);
  1962. c.convertType(CType.LINK_PACKAGE, _prop.parent);
  1963. c.packages = id;
  1964. } break;
  1965. case CType.CALL_START: { mixin(S_TRACE);
  1966. c.convertType(CType.CALL_PACKAGE, _prop.parent);
  1967. c.packages = id;
  1968. } break;
  1969. default: assert (0);
  1970. }
  1971. itm.setImage(_prop.images.content(c.type));
  1972. }
  1973. refreshStatusLine();
  1974. _comm.refUseCount.call();
  1975. _comm.refreshToolBar();
  1976. }
  1977. @property
  1978. bool canWrapTree() { mixin(S_TRACE);
  1979. return !_readOnly && selection && (cast(Content)selection.getData()).parent;
  1980. }
  1981. void wrapTree() { mixin(S_TRACE);
  1982. if (!canWrapTree) return;
  1983. auto sel = selection;
  1984. assert (sel !is null);
  1985. auto c = cast(Content)sel.getData();
  1986. auto parentStart = c.parentStart;
  1987. auto si = c.tree.starts.cCountUntil(parentStart) + 1;
  1988. storeContentAndInsert(c.parent, si, 1);
  1989. auto start = new Content(CType.START, createNewName(parentStart.name, (string name) { mixin(S_TRACE);
  1990. foreach (s; _et.starts) { mixin(S_TRACE);
  1991. if (icmp(s.name, name) == 0) { mixin(S_TRACE);
  1992. return false;
  1993. }
  1994. }
  1995. return true;
  1996. }, true));
  1997. _et.insert(si, start);
  1998. auto link = new Content(CType.LINK_START, c.name);
  1999. link.start = start.name;
  2000. c.parent.insert(_prop.parent, c.parent.next.cCountUntil(c), link);
  2001. c.parent.remove(c);
  2002. start.add(_prop.parent, c);
  2003. _comm.delContent.call(c);
  2004. Item sItm;
  2005. if (_tree.tree) { mixin(S_TRACE);
  2006. sItm = createTreeItem(_tree.tree, start, start.name, _prop.images.content(CType.START), si);
  2007. createChilds(sItm, start);
  2008. } else { mixin(S_TRACE);
  2009. _tree.editor.updateEventTree();
  2010. sItm = EventEditorItem.valueOf(_tree.editor, start);
  2011. }
  2012. _tree.select(sItm);
  2013. _tree.showSelection();
  2014. _comm.refContent.call(c);
  2015. _comm.refContent.call(link);
  2016. refreshStatusLine();
  2017. _comm.refUseCount.call();
  2018. _comm.refreshToolBar();
  2019. }
  2020. void refresh(EventTree et) { mixin(S_TRACE);
  2021. _comm.setStatusLine(_tree.control, "");
  2022. _statusLine = "";
  2023. if (_et !is et) { mixin(S_TRACE);
  2024. foreach (dlg; _editDlgs.values) { mixin(S_TRACE);
  2025. dlg.forceCancel();
  2026. }
  2027. foreach (dlg; _commentDlgs.values) { mixin(S_TRACE);
  2028. dlg.forceCancel();
  2029. }
  2030. _et = et;
  2031. _tree.control.setRedraw(false);
  2032. scope (exit) _tree.control.setRedraw(true);
  2033. if (_tree.tree) { mixin(S_TRACE);
  2034. _tree.tree.removeAll();
  2035. if (et) { mixin(S_TRACE);
  2036. foreach (start; et.starts) { mixin(S_TRACE);
  2037. auto itm = createTreeItem(_tree.tree, start, start.name, _prop.images.content(CType.START));
  2038. createChilds(itm, start);
  2039. _tree.setExpanded(itm, true);
  2040. }
  2041. }
  2042. } else { mixin(S_TRACE);
  2043. _tree.editor.eventTree = _et;
  2044. }
  2045. if (0 < _tree.getItemCount()) { mixin(S_TRACE);
  2046. _tree.setSelection([_tree.getItem(0)]);
  2047. _tree.showSelection();
  2048. }
  2049. if (et) { mixin(S_TRACE);
  2050. openToolWindow(true);
  2051. } else { mixin(S_TRACE);
  2052. closeToolWindow();
  2053. }
  2054. refreshStatusLine();
  2055. _comm.refreshToolBar();
  2056. }
  2057. }
  2058. void treeOpen() { mixin(S_TRACE);
  2059. _tree.treeExpandedAll();
  2060. _comm.refreshToolBar();
  2061. }
  2062. void treeClose() { mixin(S_TRACE);
  2063. foreach (itm; _tree.getItems()) { mixin(S_TRACE);
  2064. _tree.setExpanded(itm, false);
  2065. }
  2066. _comm.refreshToolBar();
  2067. }
  2068. @property
  2069. bool canExpandTree() { mixin(S_TRACE);
  2070. foreach (itm; _tree.getItems()) { mixin(S_TRACE);
  2071. if (_tree.getItems(itm).length && !_tree.getExpanded(itm)) { mixin(S_TRACE);
  2072. return true;
  2073. }
  2074. }
  2075. return false;
  2076. }
  2077. @property
  2078. bool canFoldTree() { mixin(S_TRACE);
  2079. foreach (itm; _tree.getItems()) { mixin(S_TRACE);
  2080. if (_tree.getItems(itm).length && _tree.getExpanded(itm)) { mixin(S_TRACE);
  2081. return true;
  2082. }
  2083. }
  2084. return false;
  2085. }
  2086. @property
  2087. bool canExpand() { mixin(S_TRACE);
  2088. auto itm = selection;
  2089. if (!itm) return false;
  2090. auto c = cast(Content)itm.getData();
  2091. return c.next.length && !_tree.getExpanded(itm);
  2092. }
  2093. @property
  2094. bool canCollapse() { mixin(S_TRACE);
  2095. auto itm = selection;
  2096. if (!itm) return false;
  2097. auto c = cast(Content)itm.getData();
  2098. return c.next.length && _tree.getExpanded(itm);
  2099. }
  2100. void expand() { mixin(S_TRACE);
  2101. if (!canExpand) return;
  2102. auto itm = selection;
  2103. if (!itm) return;
  2104. _tree.setExpanded(itm, true);
  2105. }
  2106. void collapse() { mixin(S_TRACE);
  2107. if (!canCollapse) return;
  2108. auto itm = selection;
  2109. if (!itm) return;
  2110. _tree.setExpanded(itm, false);
  2111. }
  2112. private void editEnd(TreeItem itm, Control c) { mixin(S_TRACE);
  2113. editEnd(cast(Item)itm, c);
  2114. }
  2115. private void editEnd(EventEditorItem itm, Control c) { mixin(S_TRACE);
  2116. editEnd(cast(Item)itm, c);
  2117. }
  2118. private void editEnd(Item itm, Control c) { mixin(S_TRACE);
  2119. if (_readOnly) return;
  2120. auto t = cast(Text) c;
  2121. auto evt = (cast(Content) itm.getData());
  2122. if (t) { mixin(S_TRACE);
  2123. auto text = t.getText();
  2124. if (!text) text = "";
  2125. if (text == evt.name) return;
  2126. store(evt);
  2127. if (evt.type == CType.START) { mixin(S_TRACE);
  2128. evt.setName(_prop.parent, createNewName(text, (string name) { mixin(S_TRACE);
  2129. foreach (s; _et.starts) { mixin(S_TRACE);
  2130. if (s !is evt && icmp(s.name, name) == 0) { mixin(S_TRACE);
  2131. return false;
  2132. }
  2133. }
  2134. return true;
  2135. }, true));
  2136. itm.setText(evt.name);
  2137. } else { mixin(S_TRACE);
  2138. evt.setName(_prop.parent, text);
  2139. itm.setText(eventText(evt.parent, evt));
  2140. }
  2141. if (evt.type == CType.START && _tree.indexOf(itm) == 0) { mixin(S_TRACE);
  2142. _refreshTopStart();
  2143. }
  2144. } else { mixin(S_TRACE);
  2145. auto combo = cast(Combo) c;
  2146. int index = combo.getSelectionIndex();
  2147. auto data = cast(Content)_tree.getParentItem(itm).getData();
  2148. string name;
  2149. switch (data.type) {
  2150. case CType.BRANCH_MULTI_STEP: { mixin(S_TRACE);
  2151. if (index + 1 < combo.getItemCount()) { mixin(S_TRACE);
  2152. name = to!(string)(index);
  2153. } else { mixin(S_TRACE);
  2154. assert (index + 1 == combo.getItemCount());
  2155. name = _prop.sys.evtChildDefault;
  2156. }
  2157. break;
  2158. } case CType.BRANCH_AREA: { mixin(S_TRACE);
  2159. if (index < _summ.areas.length) { mixin(S_TRACE);
  2160. name = to!(string)(_summ.areas[index].id);
  2161. } else { mixin(S_TRACE);
  2162. assert (index == _summ.areas.length);
  2163. name = _prop.sys.evtChildDefault;
  2164. }
  2165. break;
  2166. } case CType.BRANCH_BATTLE: { mixin(S_TRACE);
  2167. if (index < _summ.battles.length) { mixin(S_TRACE);
  2168. name = to!(string)(_summ.battles[index].id);
  2169. } else { mixin(S_TRACE);
  2170. assert (index == _summ.battles.length);
  2171. name = _prop.sys.evtChildDefault;
  2172. }
  2173. break;
  2174. } case CType.BRANCH_STEP_CMP: { mixin(S_TRACE);
  2175. switch (combo.getSelectionIndex()) {
  2176. case 0:
  2177. name = _prop.sys.evtChildGreater;
  2178. break;
  2179. case 1:
  2180. name = _prop.sys.evtChildLesser;
  2181. break;
  2182. case 2:
  2183. name = _prop.sys.evtChildEq;
  2184. break;
  2185. default:
  2186. assert (0);
  2187. }
  2188. break;
  2189. } default:
  2190. assert (combo.getItemCount() == 2);
  2191. name = index == 0 ? _prop.sys.evtChildTrue : _prop.sys.evtChildFalse;
  2192. }
  2193. if (name == evt.name) return;
  2194. store(evt);
  2195. evt.setName(_prop.parent, name);
  2196. itm.setText(combo.getText());
  2197. }
  2198. procTreeItem(itm);
  2199. redraw();
  2200. _comm.refContent.call(evt);
  2201. refreshStatusLine();
  2202. _comm.refreshToolBar();
  2203. _comm.refUseCount.call();
  2204. }
  2205. private Combo createBoolEditor(string Create)(Content evt, Content child) { mixin(S_TRACE);
  2206. if (_readOnly) return null;
  2207. string[] vals;
  2208. vals.length = 2;
  2209. string name = _prop.sys.evtChildTrue;
  2210. vals[0] = mixin (Create);
  2211. name = _prop.sys.evtChildFalse;
  2212. vals[1] = mixin (Create);
  2213. return createComboEditor(_comm, _prop, _tree.control, vals, vals[child.name == _prop.sys.evtChildTrue ? 0 : 1]);
  2214. }
  2215. private Combo createBoolEditor2(string Create)(Content evt, Content child) { mixin(S_TRACE);
  2216. if (_readOnly) return null;
  2217. string[] vals;
  2218. vals.length = 2;
  2219. string name = _prop.sys.evtChildTrue;
  2220. vals[0] = mixin (Create);
  2221. name = _prop.sys.evtChildFalse;
  2222. vals[1] = mixin (Create);
  2223. return createComboEditor(_comm, _prop, _tree.control, vals, vals[child.name == _prop.sys.evtChildTrue ? 0 : 1]);
  2224. }
  2225. private Combo createNumEditor(string Create)(Content evt, Content child, ulong[] nums) { mixin(S_TRACE);
  2226. if (_readOnly) return null;
  2227. string[] vals;
  2228. vals.length = nums.length + 1;
  2229. int index = nums.length;
  2230. foreach (i, n; nums) { mixin(S_TRACE);
  2231. string name = to!(string)(n);
  2232. vals[i] = mixin (Create);
  2233. if (name == child.name) { mixin(S_TRACE);
  2234. index = i;
  2235. }
  2236. }
  2237. string name = _prop.sys.evtChildDefault;
  2238. vals[$ - 1] = mixin (Create);
  2239. return createComboEditor(_comm, _prop, _tree.control, vals, vals[index]);
  2240. }
  2241. private Combo createAreaSelectEditor(string Create, A)(Content evt, Content child, A[] areas) { mixin(S_TRACE);
  2242. if (_readOnly) return null;
  2243. ulong[] nums;
  2244. nums.length = areas.length;
  2245. foreach (i, area; areas) { mixin(S_TRACE);
  2246. nums[i] = area.id;
  2247. }
  2248. return createNumEditor!(Create)(evt, child, nums);
  2249. }
  2250. private Combo createTrioEditor(string Create)(Content evt, Content child) { mixin(S_TRACE);
  2251. if (_readOnly) return null;
  2252. string[] vals;
  2253. vals.length = 3;
  2254. string name = _prop.sys.evtChildGreater;
  2255. vals[0] = mixin (Create);
  2256. name = _prop.sys.evtChildLesser;
  2257. vals[1] = mixin (Create);
  2258. name = _prop.sys.evtChildEq;
  2259. vals[2] = mixin (Create);
  2260. size_t index;
  2261. if (child.name == _prop.sys.evtChildEq) { mixin(S_TRACE);
  2262. index = 2;
  2263. } else if (child.name == _prop.sys.evtChildLesser) { mixin(S_TRACE);
  2264. index = 1;
  2265. } else { mixin(S_TRACE);
  2266. index = 0;
  2267. }
  2268. return createComboEditor(_comm, _prop, _tree.control, vals, vals[index]);
  2269. }
  2270. private Control createEditor(TreeItem itm) { mixin(S_TRACE);
  2271. return createEditor(cast(Item)itm);
  2272. }
  2273. private Control createEditor(EventEditorItem itm) { mixin(S_TRACE);
  2274. return createEditor(cast(Item)itm);
  2275. }
  2276. private Control createEditor(Item itm) { mixin(S_TRACE);
  2277. if (_readOnly) return null;
  2278. auto parent = _tree.getParentItem(itm);
  2279. if (parent) { mixin(S_TRACE);
  2280. if ((cast(Content)parent.getData()).detail.nextType == CNextType.TEXT) { mixin(S_TRACE);
  2281. return createTextEditor(_comm, _prop, _tree.control, (cast(Content)itm.getData()).name);
  2282. }
  2283. } else { mixin(S_TRACE);
  2284. return createTextEditor(_comm, _prop, _tree.control, (cast(Content)itm.getData()).name);
  2285. }
  2286. auto data = cast(Content)parent.getData();
  2287. auto c = cast(Content)itm.getData();
  2288. switch (data.type) {
  2289. case CType.BRANCH_FLAG: { mixin(S_TRACE);
  2290. return createBoolEditor!("evtChildBrFlag(_prop, _summ, evt.flag, name)")(data, c);
  2291. } case CType.BRANCH_MULTI_STEP: { mixin(S_TRACE);
  2292. Step step = _summ.flagDirRoot.findStep(data.step);
  2293. ulong[] nums;
  2294. ulong count = step is null ? _prop.looks.stepMaxCount : step.count;
  2295. for (ulong i = 0; i < count; i++) { mixin(S_TRACE);
  2296. nums ~= i;
  2297. }
  2298. return createNumEditor!("evtChildBrStepN(_prop, _summ, evt.step, name)")(data, c, nums);
  2299. } case CType.BRANCH_STEP: { mixin(S_TRACE);
  2300. return createBoolEditor!("evtChildBrStepUL(_prop, _summ, evt.step, evt.stepValue, name)")(data, c);
  2301. } case CType.BRANCH_SELECT: { mixin(S_TRACE);
  2302. return createBoolEditor!("evtChildBrMember(_prop, evt.targetAll, evt.random, name)")(data, c);
  2303. } case CType.BRANCH_ABILITY: { mixin(S_TRACE);
  2304. return createBoolEditor!("evtChildBrPower(_prop, evt.targetS, evt.physical, evt.mental, evt.signedLevel, name)")(data, c);
  2305. } case CType.BRANCH_RANDOM: { mixin(S_TRACE);
  2306. return createBoolEditor!("evtChildBrRandom(_prop, evt.percent, name)")(data, c);
  2307. } case CType.BRANCH_LEVEL: { mixin(S_TRACE);
  2308. return createBoolEditor!("evtChildBrLevel(_prop, evt.unsignedLevel, evt.average, name)")(data, c);
  2309. } case CType.BRANCH_STATUS: { mixin(S_TRACE);
  2310. return createBoolEditor!("evtChildBrState(_prop, evt.targetNS, evt.status, name)")(data, c);
  2311. } case CType.BRANCH_PARTY_NUMBER: { mixin(S_TRACE);
  2312. return createBoolEditor!("evtChildBrNum(_prop, evt.partyNumber, name)")(data, c);
  2313. } case CType.BRANCH_AREA: { mixin(S_TRACE);
  2314. return createAreaSelectEditor!("evtChildBrArea(_prop, _summ.areas, name)")(data, c, _summ.areas);
  2315. } case CType.BRANCH_BATTLE: { mixin(S_TRACE);
  2316. return createAreaSelectEditor!("evtChildBrBattle(_prop, _summ.battles, name)")(data, c, _summ.battles);
  2317. } case CType.BRANCH_IS_BATTLE: { mixin(S_TRACE);
  2318. return createBoolEditor!("evtChildBrOnBattle(_prop, name)")(data, c);
  2319. } case CType.BRANCH_CAST: { mixin(S_TRACE);
  2320. return createBoolEditor!("evtChildBrCast(_prop, _summ, evt.casts, name)")(data, c);
  2321. } case CType.BRANCH_ITEM: { mixin(S_TRACE);
  2322. return createBoolEditor!("evtChildBrItem(_prop, _summ, evt.item, evt.range, evt.cardNumber, name)")(data, c);
  2323. } case CType.BRANCH_SKILL: { mixin(S_TRACE);
  2324. return createBoolEditor!("evtChildBrSkill(_prop, _summ, evt.skill, evt.range, evt.cardNumber, name)")(data, c);
  2325. } case CType.BRANCH_BEAST: { mixin(S_TRACE);
  2326. return createBoolEditor!("evtChildBrBeast(_prop, _summ, evt.beast, evt.range, evt.cardNumber, name)")(data, c);
  2327. } case CType.BRANCH_INFO: { mixin(S_TRACE);
  2328. return createBoolEditor!("evtChildBrInfo(_prop, _summ, evt.info, name)")(data, c);
  2329. } case CType.BRANCH_MONEY: { mixin(S_TRACE);
  2330. return createBoolEditor!("evtChildBrMoney(_prop, evt.money, name)")(data, c);
  2331. } case CType.BRANCH_COUPON: { mixin(S_TRACE);
  2332. return createBoolEditor!("evtChildBrCoupon(_prop, evt.range, evt.coupon, name)")(data, c);
  2333. } case CType.BRANCH_COMPLETE_STAMP: { mixin(S_TRACE);
  2334. return createBoolEditor!("evtChildBrEnd(_prop, evt.completeStamp, name)")(data, c);
  2335. } case CType.BRANCH_GOSSIP: { mixin(S_TRACE);
  2336. return createBoolEditor!("evtChildBrGossip(_prop, evt.gossip, name)")(data, c);
  2337. } case CType.BRANCH_STEP_CMP: { mixin(S_TRACE);
  2338. return createTrioEditor!("evtChildBrStepCmp(_prop, _summ, evt.step, evt.step2, name)")(data, c);
  2339. } case CType.BRANCH_FLAG_CMP: { mixin(S_TRACE);
  2340. return createBoolEditor!("evtChildBrFlagCmp(_prop, _summ, evt.flag, evt.flag2, name)")(data, c);
  2341. } case CType.BRANCH_RANDOM_SELECT: { mixin(S_TRACE);
  2342. return createBoolEditor!("evtChildBrRandomSelect(_prop, evt, name)")(data, c);
  2343. } case CType.BRANCH_KEY_CODE: { mixin(S_TRACE);
  2344. return createBoolEditor!("evtChildBrKeyCode(_prop, evt, name)")(data, c);
  2345. } case CType.BRANCH_ROUND: { mixin(S_TRACE);
  2346. return createBoolEditor!("evtChildBrRound(_prop, evt, name)")(data, c);
  2347. } default:
  2348. }
  2349. return null;
  2350. }
  2351. /// Params:
  2352. /// parent = ??????
  2353. /// e = ????????????????
  2354. /// Returns: ?????
  2355. private string eventText(Content parent, Content e) { mixin(S_TRACE);
  2356. return .eventText(_comm, _summ, parent, e, _readOnly != SWT.NONE);
  2357. }
  2358. /// ????????????????????
  2359. private void procTreeItem(Item targ) { mixin(S_TRACE);
  2360. auto itm = cast(TreeItem)targ;
  2361. if (!itm) return;
  2362. auto c = cast(Content) itm.getData();
  2363. assert (c !is null);
  2364. if (c.parent && c.parent.detail.nextType == CNextType.TEXT) { mixin(S_TRACE);
  2365. if (c.name.length) { mixin(S_TRACE);
  2366. itm.setForeground(_tree.control.getForeground());
  2367. } else { mixin(S_TRACE);
  2368. itm.setForeground(_grayFont);
  2369. if (_prop.var.etc.showInputGuide) { mixin(S_TRACE);
  2370. itm.setText(summSkin.evtChildOK);
  2371. } else { mixin(S_TRACE);
  2372. itm.setText(" ");
  2373. }
  2374. }
  2375. }
  2376. }
  2377. /// ???????????
  2378. private Item createChilds(Item parentItm, Content evt) { mixin(S_TRACE);
  2379. if (!evt.detail.owner) return parentItm;
  2380. if (auto parent = cast(TreeItem)parentItm) { mixin(S_TRACE);
  2381. parent.removeAll();
  2382. Item itm = parent;
  2383. foreach (c; evt.next) { mixin(S_TRACE);
  2384. auto itm2 = createTreeItem(parent, c, eventText(evt, c), _prop.images.content(c.type));
  2385. itm = itm2;
  2386. if (c.detail.owner) { mixin(S_TRACE);
  2387. itm = createChilds(itm2, c);
  2388. }
  2389. procTreeItem(itm2);
  2390. _tree.setExpanded(itm2, true);
  2391. }
  2392. return itm;
  2393. } else { mixin(S_TRACE);
  2394. _tree.editor.updateEventTree();
  2395. while (evt.next.length) { mixin(S_TRACE);
  2396. evt = evt.next[$ - 1];
  2397. }
  2398. return EventEditorItem.valueOf(_tree.editor, evt);
  2399. }
  2400. }
  2401. @property
  2402. EventTree eventTree() { mixin(S_TRACE);
  2403. return _et;
  2404. }
  2405. @property
  2406. bool isFocusControl() { mixin(S_TRACE);
  2407. return _tree.control.isFocusControl();
  2408. }
  2409. private static void udImpl(int To)(EventTreeView v, Commons comm, EventTree et, Content c, bool store) { mixin(S_TRACE);
  2410. if (!et) return;
  2411. if (v) v._tree.control.setRedraw(false);
  2412. scope (exit) if (v) v._tree.control.setRedraw(true);
  2413. auto pc = c.parent;
  2414. int i, j;
  2415. auto path = c.ctPath;
  2416. if (pc) { mixin(S_TRACE);
  2417. i = cCountUntil!("a is b")(pc.next, c);
  2418. j = i + To;
  2419. if (j < 0 || pc.next.length <= j) return;
  2420. if (v && store) { mixin(S_TRACE);
  2421. v.store(pc);
  2422. }
  2423. comm.delContent.call(pc.next[i]);
  2424. comm.delContent.call(pc.next[j]);
  2425. pc.swapContent(i, j);
  2426. } else { mixin(S_TRACE);
  2427. i = cCountUntil!("a is b")(et.starts, c);
  2428. j = i + To;
  2429. if (j < 0 || et.starts.length <= j) return;
  2430. if (v && store) { mixin(S_TRACE);
  2431. v.storeSwap(i, j);
  2432. }
  2433. comm.delContent.call(et.starts[i]);
  2434. comm.delContent.call(et.starts[j]);
  2435. et.swapStart(i, j);
  2436. }
  2437. if (v) { mixin(S_TRACE);
  2438. if (v._tree.tree) { mixin(S_TRACE);
  2439. static if (To == -1) {
  2440. treeItemUp(cast(TreeItem)v.fromPath(path));
  2441. } else static if (To == 1) {
  2442. treeItemDown(cast(TreeItem)v.fromPath(path));
  2443. } else static assert (0);
  2444. } else { mixin(S_TRACE);
  2445. v._tree.editor.updateEventTree();
  2446. }
  2447. v._tree.showSelection();
  2448. if (!pc && (i == 0 || j == 0)) { mixin(S_TRACE);
  2449. v._refreshTopStart();
  2450. }
  2451. }
  2452. }
  2453. @property
  2454. bool canUp() { mixin(S_TRACE);
  2455. return canUpImpl(true);
  2456. }
  2457. @property
  2458. bool canDown() { mixin(S_TRACE);
  2459. return canDownImpl(true);
  2460. }
  2461. private bool canUpImpl(bool swapPC) { mixin(S_TRACE);
  2462. if (_readOnly) return false;
  2463. auto itm = selection;
  2464. if (!itm) return false;
  2465. auto par = _tree.getParentItem(itm);
  2466. if (par) { mixin(S_TRACE);
  2467. if (0 < _tree.indexOf(par, itm)) return true;
  2468. } else { mixin(S_TRACE);
  2469. if (0 < _tree.indexOf(itm)) return true;
  2470. }
  2471. if (!swapPC) return false;
  2472. if (!_tree.editor) return false;
  2473. // ?????????????????????????
  2474. return canSwapToParent;
  2475. }
  2476. private bool canDownImpl(bool swapPC) { mixin(S_TRACE);
  2477. if (_readOnly) return false;
  2478. auto itm = selection;
  2479. if (!itm) return false;
  2480. auto par = _tree.getParentItem(itm);
  2481. if (par) { mixin(S_TRACE);
  2482. if (_tree.indexOf(par, itm) + 1 < _tree.getItemCount(par)) return true;
  2483. } else { mixin(S_TRACE);
  2484. if (_tree.indexOf(itm) + 1 < _tree.getItemCount()) return true;
  2485. }
  2486. if (!swapPC) return false;
  2487. if (!_tree.editor) return false;
  2488. // ?????????????????????????
  2489. return canSwapToChild;
  2490. }
  2491. private void up(Item itm, bool store) { mixin(S_TRACE);
  2492. if (_readOnly) return;
  2493. if (!itm) return;
  2494. udImpl!(-1)(this, _comm, _et, cast(Content) itm.getData(), store);
  2495. _comm.refreshToolBar();
  2496. }
  2497. void up() { mixin(S_TRACE);
  2498. if (!canUpImpl(false)) { mixin(S_TRACE);
  2499. if (canSwapToParent) { mixin(S_TRACE);
  2500. swapToParent();
  2501. }
  2502. return;
  2503. }
  2504. auto itm = selection;
  2505. if (itm) up(itm, true);
  2506. }
  2507. private void down(Item itm, bool store) { mixin(S_TRACE);
  2508. if (_readOnly) return;
  2509. if (!itm) return;
  2510. udImpl!(1)(this, _comm, _et, cast(Content) itm.getData(), store);
  2511. _comm.refreshToolBar();
  2512. }
  2513. void down() { mixin(S_TRACE);
  2514. if (!canDownImpl(false)) { mixin(S_TRACE);
  2515. if (canSwapToChild) { mixin(S_TRACE);
  2516. swapToChild();
  2517. }
  2518. return;
  2519. }
  2520. auto itm = selection;
  2521. if (itm) down(itm, true);
  2522. }
  2523. void reverseShowEventTreeDetail() { mixin(S_TRACE);
  2524. _showEventTreeDetail = !_showEventTreeDetail;
  2525. if (_tree.editor) { mixin(S_TRACE);
  2526. _tree.editor.showEventTreeDetail = _showEventTreeDetail;
  2527. }
  2528. }
  2529. @property
  2530. bool canSwapToParent() { mixin(S_TRACE);
  2531. if (_readOnly) return false;
  2532. auto itm = selection;
  2533. if (!itm) return false;
  2534. auto c = cast(Content)itm.getData();
  2535. if (!c.parent) return false;
  2536. if (c.parent.type == CType.START) return false;
  2537. if (c.parent.next.length != 1) return false;
  2538. if (!c.detail.owner) return false;
  2539. return true;
  2540. }
  2541. @property
  2542. bool canSwapToChild() { mixin(S_TRACE);
  2543. if (_readOnly) return false;
  2544. auto itm = selection;
  2545. if (!itm) return false;
  2546. auto c = cast(Content)itm.getData();
  2547. if (c.type == CType.START) return false;
  2548. if (c.next.length != 1) return false;
  2549. if (!c.next[0].detail.owner) return false;
  2550. return true;
  2551. }
  2552. /// ???????????????????
  2553. private void swapToPCImpl(Item parent, Item child, Item selTarg) { mixin(S_TRACE);
  2554. if (_readOnly) return;
  2555. auto par = cast(Content)parent.getData();
  2556. auto next = cast(Content)child.getData();
  2557. auto parPar = par.parent;
  2558. auto parName = par.name;
  2559. auto nextName = next.name;
  2560. auto parNType = fromCNextType(par.detail.nextType);
  2561. auto nextNType = fromCNextType(next.detail.nextType);
  2562. auto parParNType = fromCNextType(parPar.detail.nextType);
  2563. auto parIndex = parPar.next.cCountUntil!"a is b"(par);
  2564. store(parPar);
  2565. // ????
  2566. parPar.remove(par);
  2567. par.remove(next);
  2568. foreach (c; next.next.dup) { mixin(S_TRACE);
  2569. next.remove(c);
  2570. adjustText(par, c, nextNType);
  2571. par.add(_prop.parent, c);
  2572. }
  2573. par.setName(_prop.parent, nextName);
  2574. next.setName(_prop.parent, parName);
  2575. adjustText(parPar, next, parParNType); // ???????????????lastNextType??????
  2576. parPar.insert(_prop.parent, parIndex, next);
  2577. adjustText(next, par, parNType);
  2578. next.add(_prop.parent, par);
  2579. // ?????
  2580. if (_tree.tree) { mixin(S_TRACE);
  2581. parent.setText(eventText(parPar, next));
  2582. child.setText(eventText(next, par));
  2583. parent.setData(next);
  2584. child.setData(par);
  2585. parent.setImage(_prop.images.content(next.type));
  2586. child.setImage(_prop.images.content(par.type));
  2587. procTreeItem(parent);
  2588. procTreeItem(child);
  2589. foreach (cc; _tree.getItems(child)) { mixin(S_TRACE);
  2590. cc.setText(eventText(par, cast(Content)cc.getData()));
  2591. procTreeItem(cc);
  2592. }
  2593. _tree.setSelection([selTarg]);
  2594. } else { mixin(S_TRACE);
  2595. _tree.editor.updateEventTree();
  2596. }
  2597. _tree.showSelection();
  2598. }
  2599. void swapToParent() { mixin(S_TRACE);
  2600. if (_readOnly) return;
  2601. if (!canSwapToParent) return;
  2602. auto itm = selection;
  2603. auto par = _tree.getParentItem(itm);
  2604. swapToPCImpl(par, itm, par);
  2605. }
  2606. void swapToChild() { mixin(S_TRACE);
  2607. if (_readOnly) return;
  2608. if (!canSwapToChild) return;
  2609. auto par = selection;
  2610. auto itm = _tree.getItem(par, 0);
  2611. swapToPCImpl(par, itm, itm);
  2612. }
  2613. private void getContentsBox() { mixin(S_TRACE);
  2614. if (_box) return;
  2615. _comp.setRedraw(false);
  2616. scope (exit) _comp.setRedraw(true);
  2617. _comm.getContentsToolBox(this);
  2618. }
  2619. void refreshTreeName() { mixin(S_TRACE);
  2620. _tree.getItems()[0].setText(_et.name);
  2621. redraw();
  2622. refreshStatusLine();
  2623. }
  2624. void openToolWindow(bool focusInEventView) { mixin(S_TRACE);
  2625. if (_readOnly) return;
  2626. if (!(_prop.var.etc.contentsFloat || _prop.var.etc.contentsAutoHide)) return;
  2627. _comp.setRedraw(false);
  2628. scope (exit) _comp.setRedraw(true);
  2629. if (focusInEventView || (widget.isVisible() && !(_prop.var.etc.contentsFloat || _prop.var.etc.contentsAutoHide))) { mixin(S_TRACE);
  2630. getContentsBox();
  2631. }
  2632. if (_box) { mixin(S_TRACE);
  2633. _box.openToolWindow();
  2634. }
  2635. }
  2636. void closeToolWindow() { mixin(S_TRACE);
  2637. if (_readOnly) return;
  2638. if (!_box) return;
  2639. _box.closeToolWindow();
  2640. }
  2641. @property
  2642. private Content insertOwner(bool tryInsert, ref Item itm) { mixin(S_TRACE);
  2643. if (!itm) return null;
  2644. auto owner = cast(Content)itm.getData();
  2645. assert (owner);
  2646. if (tryInsert || owner.detail.owner) return owner;
  2647. itm = _tree.getParentItem(itm);
  2648. return owner.parent;
  2649. }
  2650. private void addContents(bool stored, Content[] cs, Content[] refCS, bool tryInsert, string lastNextType = "") { mixin(S_TRACE);
  2651. if (!_box) return;
  2652. if (_readOnly) return;
  2653. auto itm = selection;
  2654. if (!itm) return;
  2655. auto owner = insertOwner(tryInsert, itm);
  2656. if (!owner) return;
  2657. bool empty = _et.owner.isEmpty;
  2658. scope (exit) {
  2659. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  2660. }
  2661. Content[] cs2;
  2662. foreach (ct; cs) { mixin(S_TRACE);
  2663. if (ct.type is CType.START) continue;
  2664. cs2 ~= ct;
  2665. }
  2666. if (!cs2.length) return;
  2667. Content last = null, allLast = null;
  2668. int index = -1;
  2669. if (tryInsert && owner.parent) { mixin(S_TRACE);
  2670. // cs2??????????????????
  2671. // ?????????????
  2672. void recurse(Content c) { mixin(S_TRACE);
  2673. if (c.detail.owner) { mixin(S_TRACE);
  2674. last = c;
  2675. }
  2676. allLast = c;
  2677. foreach (cc; c.next) { mixin(S_TRACE);
  2678. recurse(cc);
  2679. }
  2680. }
  2681. foreach (c; cs2) { mixin(S_TRACE);
  2682. recurse(c);
  2683. }
  2684. }
  2685. if (!last && !owner.detail.owner) return;
  2686. _tree.control.setRedraw(false);
  2687. scope (exit) _tree.control.setRedraw(true);
  2688. if (stored) store(owner);
  2689. if (last) { mixin(S_TRACE);
  2690. cs2[0].setName(_prop.parent, owner.name);
  2691. auto parent = owner.parent;
  2692. index = parent.next.countUntil(owner);
  2693. parent.remove(owner);
  2694. if (_prop.var.etc.adjustContentName) { mixin(S_TRACE);
  2695. owner.setName(_prop.parent, "");
  2696. }
  2697. last.add(_prop.parent, owner);
  2698. owner = parent;
  2699. itm = _tree.getParentItem(itm);
  2700. }
  2701. bool insertFirst = (index == -1 && _box._insertFirst);
  2702. Content lastCt = null;
  2703. int i = 0;
  2704. foreach (ct; cs2) { mixin(S_TRACE);
  2705. if (index == -1) { mixin(S_TRACE);
  2706. adjustText(owner, ct, lastNextType);
  2707. if (insertFirst) { mixin(S_TRACE);
  2708. owner.insert(_prop.parent, i, ct);
  2709. lastCt = ct;
  2710. i++;
  2711. } else { mixin(S_TRACE);
  2712. owner.add(_prop.parent, ct);
  2713. }
  2714. } else { mixin(S_TRACE);
  2715. owner.insert(_prop.parent, index, ct);
  2716. index = -1;
  2717. }
  2718. _comm.refContent.call(ct);
  2719. }
  2720. auto lastItm = createChilds(itm, owner);
  2721. if (lastCt) { mixin(S_TRACE);
  2722. while (lastCt.next.length) { mixin(S_TRACE);
  2723. lastCt = lastCt.next[$ - 1];
  2724. }
  2725. Item find(Item itm) { mixin(S_TRACE);
  2726. if (lastCt is itm.getData()) { mixin(S_TRACE);
  2727. return itm;
  2728. } else { mixin(S_TRACE);
  2729. foreach (child; _tree.getItems(itm)) { mixin(S_TRACE);
  2730. auto f = find(child);
  2731. if (f) return f;
  2732. }
  2733. return null;
  2734. }
  2735. }
  2736. lastItm = find(itm);
  2737. } else if (last) { mixin(S_TRACE);
  2738. Item findLast(Item itm) { mixin(S_TRACE);
  2739. if (allLast is itm.getData()) { mixin(S_TRACE);
  2740. return itm;
  2741. } else { mixin(S_TRACE);
  2742. foreach (child; _tree.getItems(itm)) { mixin(S_TRACE);
  2743. auto f = findLast(child);
  2744. if (f) return f;
  2745. }
  2746. return null;
  2747. }
  2748. }
  2749. lastItm = findLast(itm);
  2750. assert (lastItm !is null);
  2751. }
  2752. _tree.setSelection([lastItm]);
  2753. _tree.showSelection();
  2754. _comm.refUseCount.call();
  2755. refreshStatusLine();
  2756. _comm.refreshToolBar();
  2757. }
  2758. @property
  2759. private int insertStartIndex() { mixin(S_TRACE);
  2760. auto sel = selection;
  2761. if (sel) { mixin(S_TRACE);
  2762. return _tree.indexOf(_tree.topItem(sel)) + 1;
  2763. } else { mixin(S_TRACE);
  2764. return 1;
  2765. }
  2766. }
  2767. private void addStarts(bool stored, Content[] cs, Content[] refCS = []) { mixin(S_TRACE);
  2768. if (_readOnly) return;
  2769. _tree.control.setRedraw(false);
  2770. scope (exit) _tree.control.setRedraw(true);
  2771. bool empty = _et.owner.isEmpty;
  2772. scope (exit) {
  2773. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  2774. }
  2775. auto sel = selection;
  2776. int index = insertStartIndex;
  2777. Content[] cs2;
  2778. foreach (ct; cs) { mixin(S_TRACE);
  2779. if (ct.type !is CType.START) continue;
  2780. cs2 ~= ct;
  2781. }
  2782. if (!cs2.length) return;
  2783. auto top = _tree.getTopItem();
  2784. if (stored) storeInsert(index, cs2.length);
  2785. Item sItm = null, lastItm = null;
  2786. foreach (i, c; cs2) { mixin(S_TRACE);
  2787. if (!c.type is CType.START) continue;
  2788. auto oldName = c.name;
  2789. c.setName(_prop.parent, createNewName(c.name, (string name) { mixin(S_TRACE);
  2790. foreach (s; _et.starts) { mixin(S_TRACE);
  2791. if (icmp(s.name, name) == 0) { mixin(S_TRACE);
  2792. return false;
  2793. }
  2794. }
  2795. foreach (s; cs2) { mixin(S_TRACE);
  2796. if (s is c) continue;
  2797. if (icmp(s.name, name) == 0) { mixin(S_TRACE);
  2798. return false;
  2799. }
  2800. }
  2801. return true;
  2802. }, true));
  2803. if (c.name != oldName) { mixin(S_TRACE);
  2804. void recurse(Content[] cs) { mixin(S_TRACE);
  2805. foreach (ct; cs) { mixin(S_TRACE);
  2806. if (ct.start == oldName) { mixin(S_TRACE);
  2807. ct.start = c.name;
  2808. }
  2809. recurse(ct.next);
  2810. }
  2811. }
  2812. recurse(refCS);
  2813. }
  2814. _et.insert(index + i, c);
  2815. if (_tree.tree) { mixin(S_TRACE);
  2816. sItm = createTreeItem(_tree.tree, c, c.name, _prop.images.content(c.type), index + i);
  2817. } else { mixin(S_TRACE);
  2818. sItm = EventEditorItem.valueOf(_tree.editor, c);
  2819. }
  2820. lastItm = createChilds(sItm, c);
  2821. _tree.setExpanded(sItm, true);
  2822. _comm.refContent.call(c);
  2823. }
  2824. if (!sItm) return;
  2825. if (lastItm) _tree.setSelection([lastItm]);
  2826. _tree.showSelection();
  2827. _comm.refUseCount.call();
  2828. refreshStatusLine();
  2829. _comm.refreshToolBar();
  2830. }
  2831. override {
  2832. void cut(SelectionEvent se) { mixin(S_TRACE);
  2833. if (_readOnly) return;
  2834. auto itm = selection;
  2835. if (itm && itm !is _tree.getItems()[0]) { mixin(S_TRACE);
  2836. copy(se);
  2837. del(se);
  2838. }
  2839. }
  2840. void copy(SelectionEvent se) { mixin(S_TRACE);
  2841. auto itm = selection;
  2842. if (itm) { mixin(S_TRACE);
  2843. auto c = cast(Content)itm.getData();
  2844. XMLtoCB(_prop, _comm.clipboard, toXML(c));
  2845. _comm.refreshToolBar();
  2846. }
  2847. }
  2848. void paste(SelectionEvent se) { mixin(S_TRACE);
  2849. if (_readOnly) return;
  2850. pasteImpl(false);
  2851. }
  2852. void del(SelectionEvent se) { mixin(S_TRACE);
  2853. if (_readOnly) return;
  2854. auto itm = selection;
  2855. if (itm && itm !is _tree.getItems()[0]) { mixin(S_TRACE);
  2856. _tree.control.setRedraw(false);
  2857. scope(exit) _tree.control.setRedraw(true);
  2858. delImpl(itm, true);
  2859. _comm.refUseCount.call();
  2860. _comm.refreshToolBar();
  2861. }
  2862. }
  2863. void clone(SelectionEvent se) { mixin(S_TRACE);
  2864. if (_readOnly) return;
  2865. _comm.clipboard.memoryMode = true;
  2866. scope (exit) _comm.clipboard.memoryMode = false;
  2867. copy(se);
  2868. auto itm = selection;
  2869. auto parItm = _tree.getParentItem(itm);
  2870. if (parItm) { mixin(S_TRACE);
  2871. _tree.setSelection([parItm]);
  2872. }
  2873. paste(se);
  2874. }
  2875. @property
  2876. bool canDoTCPD() { mixin(S_TRACE);
  2877. return !_readOnly && _et !is null && _tree.control.isFocusControl();
  2878. }
  2879. @property
  2880. bool canDoT() { mixin(S_TRACE);
  2881. auto itm = selection;
  2882. return !_readOnly && itm && itm !is _tree.getItems()[0];
  2883. }
  2884. @property
  2885. bool canDoC() { mixin(S_TRACE);
  2886. return selection !is null;
  2887. }
  2888. @property
  2889. bool canDoP() { mixin(S_TRACE);
  2890. return !_readOnly && _et !is null && (CBisXML(_comm.clipboard) || CBisText(_comm.clipboard));
  2891. }
  2892. @property
  2893. bool canDoD() { mixin(S_TRACE);
  2894. return !_readOnly && canDoT;
  2895. }
  2896. @property
  2897. bool canDoClone() { mixin(S_TRACE);
  2898. return !_readOnly && canDoC;
  2899. }
  2900. }
  2901. private string toXML(in Content c, bool shallow = false) { mixin(S_TRACE);
  2902. auto opt = new XMLOption(_prop.sys);
  2903. opt.shallow = shallow;
  2904. auto node = c.toNode(opt);
  2905. CNextType next;
  2906. if (c.parent) { mixin(S_TRACE);
  2907. next = c.parent.detail.nextType;
  2908. } else { mixin(S_TRACE);
  2909. assert (c.type is CType.START);
  2910. next = CNextType.TEXT;
  2911. }
  2912. node.newAttr("lastNextType", fromCNextType(next));
  2913. node.newAttr("paneId", _id);
  2914. return node.text;
  2915. }
  2916. @property
  2917. bool canCut1Content() { return canDoT && _tree.getParentItem(selection); }
  2918. @property
  2919. bool canDel1Content() { return canDoD && _tree.getParentItem(selection); }
  2920. alias canDoC canCopy1Content;
  2921. alias canDoP canPasteInsert;
  2922. void cut1Content() { mixin(S_TRACE);
  2923. if (_readOnly) return;
  2924. auto itm = selection;
  2925. if (itm && _tree.getParentItem(itm)) { mixin(S_TRACE);
  2926. copy1Content();
  2927. del1Content();
  2928. }
  2929. }
  2930. void copy1Content() { mixin(S_TRACE);
  2931. if (_readOnly) return;
  2932. auto itm = selection;
  2933. if (itm) { mixin(S_TRACE);
  2934. auto c = cast(Content)itm.getData();
  2935. XMLtoCB(_prop, _comm.clipboard, toXML(c, true));
  2936. _comm.refreshToolBar();
  2937. }
  2938. }
  2939. void pasteInsert() { mixin(S_TRACE);
  2940. if (_readOnly) return;
  2941. pasteImpl(true);
  2942. }
  2943. void del1Content() { mixin(S_TRACE);
  2944. if (_readOnly) return;
  2945. auto itm = selection;
  2946. if (itm && _tree.getParentItem(itm)) { mixin(S_TRACE);
  2947. _tree.control.setRedraw(false);
  2948. scope(exit) _tree.control.setRedraw(true);
  2949. auto ownerItm = _tree.getParentItem(itm);
  2950. auto c = cast(Content)itm.getData();
  2951. _comm.delContent.call(c);
  2952. auto owner = cast(Content)ownerItm.getData();
  2953. this.store(owner);
  2954. int insertIndex = owner.next.countUntil(c);
  2955. owner.remove(c);
  2956. auto lastNextType = fromCNextType(c.detail.nextType);
  2957. foreach (i, next; c.next.dup) { mixin(S_TRACE);
  2958. c.remove(next);
  2959. if (_prop.var.etc.adjustContentName) { mixin(S_TRACE);
  2960. if (i == 0 && lastNextType != fromCNextType(owner.detail.nextType)) { mixin(S_TRACE);
  2961. next.setName(_prop.parent, c.name);
  2962. } else { mixin(S_TRACE);
  2963. adjustText(owner, next, lastNextType);
  2964. }
  2965. } else { mixin(S_TRACE);
  2966. adjustText(owner, next, lastNextType);
  2967. }
  2968. owner.insert(_prop.parent, insertIndex + i, next);
  2969. }
  2970. createChilds(ownerItm, owner);
  2971. _comm.refUseCount.call();
  2972. _comm.refreshToolBar();
  2973. }
  2974. }
  2975. private void pasteImpl(bool tryInsert) { mixin(S_TRACE);
  2976. if (_readOnly) return;
  2977. if (!_et) return;
  2978. string c;
  2979. try { mixin(S_TRACE);
  2980. c = CBtoXML(_comm.clipboard);
  2981. } catch (Exception e) {
  2982. // ?????????????
  2983. debugln(e);
  2984. return;
  2985. }
  2986. if (c) { mixin(S_TRACE);
  2987. try { mixin(S_TRACE);
  2988. auto ver = new XMLInfo(_prop.sys, LATEST_VERSION);
  2989. auto node = XNode.parse(c);
  2990. string id = node.attr("contentId", false);
  2991. string lastNextType = node.attr("lastNextType", false, "");
  2992. auto evt = Content.createFromNode(node, ver);
  2993. if (!evt) return;
  2994. if (evt.type == CType.START) { mixin(S_TRACE);
  2995. addStarts(true, [evt]);
  2996. } else { mixin(S_TRACE);
  2997. addContents(true, [evt], [], tryInsert, lastNextType);
  2998. }
  2999. redraw();
  3000. _comm.refreshToolBar();
  3001. return;
  3002. } catch (Exception e) {
  3003. printStackTrace();
  3004. debugln(e);
  3005. }
  3006. }
  3007. auto script = cast(ArrayWrapperString) _comm.clipboard.getContents(TextTransfer.getInstance());
  3008. if (script) { mixin(S_TRACE);
  3009. pasteScript(script.array.idup, tryInsert);
  3010. }
  3011. }
  3012. void pasteScript(string script, bool tryInsert) { mixin(S_TRACE);
  3013. if (_readOnly) return;
  3014. if (!_et) return;
  3015. string base = script;
  3016. CompileOption opt;
  3017. try { mixin(S_TRACE);
  3018. try { mixin(S_TRACE);
  3019. opt.linkId = _prop.var.etc.linkCard;
  3020. auto compiler = new CWXScript(_prop.parent, _summ);
  3021. auto vars = compiler.eatEmptyVars(script, opt);
  3022. if (vars.length) { mixin(S_TRACE);
  3023. auto dlg = new ScriptVarSetDialog(_comm, _summ, _tree.control.getShell(), vars, script, base, opt);
  3024. dlg.appliedEvent ~= { mixin(S_TRACE);
  3025. putContents(dlg.contents, tryInsert);
  3026. };
  3027. dlg.open();
  3028. } else { mixin(S_TRACE);
  3029. auto cs = cwx.script.compile(_prop.parent, _summ, script, opt);
  3030. putContents(cs, tryInsert);
  3031. }
  3032. } catch (CWXScriptException e) {
  3033. throw e;
  3034. } catch (Exception e) {
  3035. debugln(e);
  3036. throw e;
  3037. } catch (Throwable e) {
  3038. debugln(e);
  3039. throw new CWXScriptException(__FILE__, __LINE__, "", [CWXSError(_prop.msgs.scriptErrorSystem, 0, 0, __FILE__, __LINE__)], false);
  3040. }
  3041. } catch (CWXScriptException e) {
  3042. auto dlg = new ScriptErrorDialog(_comm, _prop, _tree.control, e, base, opt);
  3043. dlg.open();
  3044. }
  3045. }
  3046. void putContents(Content[] cs, bool tryInsert) { mixin(S_TRACE);
  3047. if (_readOnly) return;
  3048. if (!_et) return;
  3049. if (!cs.length) return;
  3050. Content[] starts;
  3051. Content[] contents;
  3052. foreach (c; cs) { mixin(S_TRACE);
  3053. if (c.type is CType.START) { mixin(S_TRACE);
  3054. starts ~= c;
  3055. } else { mixin(S_TRACE);
  3056. contents ~= c;
  3057. }
  3058. }
  3059. int si = insertStartIndex;
  3060. bool s = starts.length > 0;
  3061. if (s) tryInsert = false;
  3062. auto sel = selection;
  3063. auto owner = insertOwner(tryInsert, sel);
  3064. bool c = contents.length && owner;
  3065. if (s && c) { mixin(S_TRACE);
  3066. storeContentAndInsert(owner, si, starts.length);
  3067. addContents(false, contents, cs, tryInsert);
  3068. addStarts(false, starts, cs);
  3069. } else if (s) { mixin(S_TRACE);
  3070. addStarts(true, starts);
  3071. } else if (c) { mixin(S_TRACE);
  3072. addContents(true, contents, [], tryInsert);
  3073. } else { mixin(S_TRACE);
  3074. return;
  3075. }
  3076. redraw();
  3077. _comm.refreshToolBar();
  3078. }
  3079. private void delImpl(Item itm, bool store) { mixin(S_TRACE);
  3080. if (_readOnly) return;
  3081. bool empty = _et.owner.isEmpty;
  3082. scope (exit) {
  3083. if (empty != _et.owner.isEmpty) _comm.refEventTree.call(_et);
  3084. }
  3085. auto ownerItm = _tree.getParentItem(itm);
  3086. auto c = cast(Content) itm.getData();
  3087. _comm.delContent.call(c);
  3088. if (ownerItm) { mixin(S_TRACE);
  3089. auto owner = cast(Content) ownerItm.getData();
  3090. if (store) this.store(owner);
  3091. owner.remove(c);
  3092. } else { mixin(S_TRACE);
  3093. if (store) this.storeDelete(.cCountUntil!("a is b")(_et.starts, c), c);
  3094. _et.remove(c);
  3095. }
  3096. itm.dispose();
  3097. if (_tree.editor) { mixin(S_TRACE);
  3098. _tree.editor.updateEventTree();
  3099. }
  3100. }
  3101. private static void delImpl(EventTreeView v, Commons comm, EventTree et, Content c) { mixin(S_TRACE);
  3102. if (v) { mixin(S_TRACE);
  3103. v.delImpl(v.fromPath(c.ctPath), false);
  3104. } else { mixin(S_TRACE);
  3105. bool empty = et.owner.isEmpty;
  3106. scope (exit) {
  3107. if (empty != et.owner.isEmpty) comm.refEventTree.call(et);
  3108. }
  3109. comm.delContent.call(c);
  3110. if (c.parent) { mixin(S_TRACE);
  3111. c.parent.remove(c);
  3112. } else { mixin(S_TRACE);
  3113. et.remove(c);
  3114. }
  3115. }
  3116. }
  3117. private void __refreshCardImpl(Item evt) { mixin(S_TRACE);
  3118. foreach (childItm; _tree.getItems(evt)) { mixin(S_TRACE);
  3119. auto child = cast(Content) childItm.getData();
  3120. childItm.setText(eventText(cast(Content) evt.getData(), child));
  3121. if (child.detail.owner) { mixin(S_TRACE);
  3122. __refreshCardImpl(childItm);
  3123. }
  3124. procTreeItem(childItm);
  3125. }
  3126. }
  3127. private void __refreshCard() { mixin(S_TRACE);
  3128. if (_tree.control.isDisposed()) return;
  3129. if (_et) { mixin(S_TRACE);
  3130. if (_tree.editor) { mixin(S_TRACE);
  3131. _tree.editor.updateEventTree();
  3132. return;
  3133. }
  3134. foreach (itm; _tree.getItems()) { mixin(S_TRACE);
  3135. __refreshCardImpl(itm);
  3136. }
  3137. refreshStatusLine();
  3138. }
  3139. }
  3140. private void __refreshEventTextImpl(Content par, Item itm) in { mixin(S_TRACE);
  3141. assert (par.detail.owner);
  3142. } body { mixin(S_TRACE);
  3143. auto e = cast(Content) itm.getData();
  3144. itm.setText(eventText(par, e));
  3145. if (e.detail.owner) { mixin(S_TRACE);
  3146. foreach (child; _tree.getItems(itm)) { mixin(S_TRACE);
  3147. __refreshEventTextImpl(e, child);
  3148. }
  3149. } else { mixin(S_TRACE);
  3150. assert (!_tree.getItems(itm).length);
  3151. }
  3152. procTreeItem(itm);
  3153. }
  3154. private void __refreshEventText() { mixin(S_TRACE);
  3155. if (_et) { mixin(S_TRACE);
  3156. if (_tree.editor) { mixin(S_TRACE);
  3157. _tree.editor.updateEventTree();
  3158. return;
  3159. }
  3160. foreach (itm; _tree.getItems()) { mixin(S_TRACE);
  3161. auto start = cast(Content) itm.getData();
  3162. assert (start.type == CType.START);
  3163. itm.setText(start.name);
  3164. foreach (child; _tree.getItems(itm)) { mixin(S_TRACE);
  3165. __refreshEventTextImpl(start, child);
  3166. }
  3167. }
  3168. refreshStatusLine();
  3169. }
  3170. }
  3171. private void refSkin() {__refreshCard();}
  3172. private void __refreshCast(CastCard c) {__refreshCard();}
  3173. private void __refreshSkill(SkillCard c) {__refreshCard();}
  3174. private void __refreshItem(ItemCard c) {__refreshCard();}
  3175. private void __refreshBeast(BeastCard c) {__refreshCard();}
  3176. private void __refreshInfo(InfoCard c) {__refreshCard();}
  3177. private void __refreshArea(Area c) {__refreshCard();}
  3178. private void __refreshPackage(Package c) {__refreshCard();}
  3179. private void __refreshBattle(Battle c) {__refreshCard();}
  3180. private void __refreshFlagAndStep(Flag[] flags, Step[] steps) { mixin(S_TRACE);
  3181. if (flags.length || steps.length) { mixin(S_TRACE);
  3182. __refreshCard();
  3183. if (_prop.var.etc.showVariableValuesInEventText) { mixin(S_TRACE);
  3184. __refreshEventText();
  3185. }
  3186. }
  3187. }
  3188. private void __refreshPath(string from, string to, bool isDir) {refreshStatusLine();}
  3189. private void __refreshPaths(string path) {refreshStatusLine();}
  3190. private void __deletePaths() {refreshStatusLine();}
  3191. private void __replacePaths(string from, string to) {refreshStatusLine();}
  3192. private bool openCWXPathImpl(T)(T itm, string path, bool shellActivate) { mixin(S_TRACE);
  3193. auto cate = cpcategory(path);
  3194. if (cate == "") { mixin(S_TRACE);
  3195. auto index = cpindex(path);
  3196. if (index >= _tree.getItemCount(itm)) return false;
  3197. auto child = _tree.getItem(itm, index);
  3198. path = cpbottom(path);
  3199. if (cpempty(path) || cpcategory(path) != "") { mixin(S_TRACE);
  3200. if (!cphasattr(path, "nofocus")) .forceFocus(_tree.control, shellActivate);
  3201. _tree.select(child);
  3202. _tree.showSelection();
  3203. refreshStatusLine();
  3204. if (cphasattr(path, "opendialog")) { mixin(S_TRACE);
  3205. auto d = edit();
  3206. if (d) { mixin(S_TRACE);
  3207. // ????????????????????????
  3208. _comm.refreshToolBar();
  3209. return true;
  3210. }
  3211. if (!cpempty(path)) { mixin(S_TRACE);
  3212. return d.openCWXPath(path, shellActivate);
  3213. }
  3214. }
  3215. _comm.refreshToolBar();
  3216. return true;
  3217. } else { mixin(S_TRACE);
  3218. return openCWXPathImpl(child, path, shellActivate);
  3219. }
  3220. }
  3221. return false;
  3222. }
  3223. bool openCWXPath(string path, bool shellActivate) { mixin(S_TRACE);
  3224. return openCWXPathImpl(_tree, path, shellActivate);
  3225. }
  3226. @property
  3227. string[] openedCWXPath() { mixin(S_TRACE);
  3228. string[] r;
  3229. if (_et) { mixin(S_TRACE);
  3230. auto e = selection;
  3231. if (e) { mixin(S_TRACE);
  3232. auto c = cast(Content) e.getData();
  3233. assert (c);
  3234. r ~= c.cwxPath(true);
  3235. } else { mixin(S_TRACE);
  3236. r ~= _et.cwxPath(true);
  3237. }
  3238. }
  3239. return r;
  3240. }
  3241. }
  3242. string eventText(Commons comm, Summary summ, Content parent, Content e, bool readOnly) in { mixin(S_TRACE);
  3243. assert (!parent || parent.detail.owner);
  3244. } body { mixin(S_TRACE);
  3245. if (!parent) return e.name;
  3246. auto prop = comm.prop;
  3247. if (parent.detail.nextType == CNextType.TEXT) { mixin(S_TRACE);
  3248. if (prop.var.etc.showVariableValuesInEventText) { mixin(S_TRACE);
  3249. string[string] flags;
  3250. string[string] steps;
  3251. string[char] names;
  3252. getPreviewValues(prop, summ, SPCHAR_TEXT, names, flags, steps);
  3253. return simpleFormatMsg(e.name, flags, steps, names);
  3254. } else { mixin(S_TRACE);
  3255. return e.name;
  3256. }
  3257. }
  3258. string name = e.name;
  3259. string r;
  3260. switch (parent.type) {
  3261. case CType.BRANCH_FLAG: { mixin(S_TRACE);
  3262. r = evtChildBrFlag(prop, summ, parent.flag, name);
  3263. break;
  3264. } case CType.BRANCH_MULTI_STEP: { mixin(S_TRACE);
  3265. r = evtChildBrStepN(prop, summ, parent.step, name);
  3266. break;
  3267. } case CType.BRANCH_STEP: { mixin(S_TRACE);
  3268. r = evtChildBrStepUL(prop, summ, parent.step, parent.stepValue, name);
  3269. break;
  3270. } case CType.BRANCH_SELECT: { mixin(S_TRACE);
  3271. r = evtChildBrMember(prop, parent.targetAll, parent.random, name);
  3272. break;
  3273. } case CType.BRANCH_ABILITY: { mixin(S_TRACE);
  3274. r = evtChildBrPower(prop, parent.targetS, parent.physical, parent.mental, parent.signedLevel, name);
  3275. break;
  3276. } case CType.BRANCH_RANDOM: { mixin(S_TRACE);
  3277. r = evtChildBrRandom(prop, parent.percent, name);
  3278. break;
  3279. } case CType.BRANCH_LEVEL: { mixin(S_TRACE);
  3280. r = evtChildBrLevel(prop, parent.unsignedLevel, parent.average, name);
  3281. break;
  3282. } case CType.BRANCH_STATUS: { mixin(S_TRACE);
  3283. r = evtChildBrState(prop, parent.targetNS, parent.status, name);
  3284. break;
  3285. } case CType.BRANCH_PARTY_NUMBER: { mixin(S_TRACE);
  3286. r = evtChildBrNum(prop, parent.partyNumber, name);
  3287. break;
  3288. } case CType.BRANCH_AREA: { mixin(S_TRACE);
  3289. r = evtChildBrArea(prop, summ.areas, name);
  3290. break;
  3291. } case CType.BRANCH_BATTLE: { mixin(S_TRACE);
  3292. r = evtChildBrBattle(prop, summ.battles, name);
  3293. break;
  3294. } case CType.BRANCH_IS_BATTLE: { mixin(S_TRACE);
  3295. r = evtChildBrOnBattle(prop, name);
  3296. break;
  3297. } case CType.BRANCH_CAST: { mixin(S_TRACE);
  3298. r = evtChildBrCast(prop, summ, parent.casts, name);
  3299. break;
  3300. } case CType.BRANCH_ITEM: { mixin(S_TRACE);
  3301. r = evtChildBrItem(prop, summ, parent.item, parent.range, parent.cardNumber, name);
  3302. break;
  3303. } case CType.BRANCH_SKILL: { mixin(S_TRACE);
  3304. r = evtChildBrSkill(prop, summ, parent.skill, parent.range, parent.cardNumber, name);
  3305. break;
  3306. } case CType.BRANCH_BEAST: { mixin(S_TRACE);
  3307. r = evtChildBrBeast(prop, summ, parent.beast, parent.range, parent.cardNumber, name);
  3308. break;
  3309. } case CType.BRANCH_INFO: { mixin(S_TRACE);
  3310. r = evtChildBrInfo(prop, summ, parent.info, name);
  3311. break;
  3312. } case CType.BRANCH_MONEY: { mixin(S_TRACE);
  3313. r = evtChildBrMoney(prop, parent.money, name);
  3314. break;
  3315. } case CType.BRANCH_COUPON: { mixin(S_TRACE);
  3316. r = evtChildBrCoupon(prop, parent.range, parent.coupon, name);
  3317. break;
  3318. } case CType.BRANCH_COMPLETE_STAMP: { mixin(S_TRACE);
  3319. r = evtChildBrEnd(prop, parent.completeStamp, name);
  3320. break;
  3321. } case CType.BRANCH_GOSSIP: { mixin(S_TRACE);
  3322. r = evtChildBrGossip(prop, parent.gossip, name);
  3323. break;
  3324. } case CType.BRANCH_STEP_CMP: { mixin(S_TRACE);
  3325. r = evtChildBrStepCmp(prop, summ, parent.step, parent.step2, name);
  3326. break;
  3327. } case CType.BRANCH_FLAG_CMP: { mixin(S_TRACE);
  3328. r = evtChildBrFlagCmp(prop, summ, parent.flag, parent.flag2, name);
  3329. break;
  3330. } case CType.BRANCH_RANDOM_SELECT: { mixin(S_TRACE);
  3331. r = evtChildBrRandomSelect(prop, parent, name);
  3332. break;
  3333. } case CType.BRANCH_KEY_CODE: { mixin(S_TRACE);
  3334. r = evtChildBrKeyCode(prop, parent, name);
  3335. break;
  3336. } case CType.BRANCH_ROUND: { mixin(S_TRACE);
  3337. r = evtChildBrRound(prop, parent, name);
  3338. break;
  3339. } default:
  3340. name = "";
  3341. r = "";
  3342. }
  3343. if (e.name != name && !readOnly) { mixin(S_TRACE);
  3344. e.setName(prop.parent, name);
  3345. comm.refContent.call(e);
  3346. }
  3347. return r;
  3348. }
  3349. private string evtChildBrFlag(in Props prop, in Summary summ, string path, ref string text) { mixin(S_TRACE);
  3350. bool val = (text != prop.sys.evtChildFalse);
  3351. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3352. string name = prop.msgs.noSelectFlag;
  3353. string on = prop.msgs.flagOn;
  3354. string off = prop.msgs.flagOff;
  3355. if (path.length) { mixin(S_TRACE);
  3356. auto o = summ.flagDirRoot.findFlag(path);
  3357. if (o) { mixin(S_TRACE);
  3358. name = path;
  3359. on = o.on;
  3360. off = o.off;
  3361. } else { mixin(S_TRACE);
  3362. name = .tryFormat(prop.msgs.noFlag, path);
  3363. }
  3364. }
  3365. return .tryFormat(prop.msgs.evtChildBrVar, name, (val ? on : off));
  3366. }
  3367. private string evtChildBrStepN(in Props prop, in Summary summ, string path, ref string text) { mixin(S_TRACE);
  3368. int val = -1;
  3369. try { mixin(S_TRACE);
  3370. val = text == prop.sys.evtChildDefault ? -1 : (isNumeric(text) ? to!(int)(text) : -1);
  3371. } catch { mixin(S_TRACE);
  3372. // Nothing
  3373. }
  3374. string name = prop.msgs.noSelectStep;
  3375. string value = val >= 0 ? .tryFormat(prop.msgs.dlgLblStep, val) : prop.msgs.etc;
  3376. if (path.length) { mixin(S_TRACE);
  3377. auto o = summ.flagDirRoot.findStep(path);
  3378. if (o) { mixin(S_TRACE);
  3379. if (o.count <= val) { mixin(S_TRACE);
  3380. val = -1;
  3381. text = prop.sys.evtChildDefault;
  3382. }
  3383. name = path;
  3384. if (0 <= val) value = o.getValue(val);
  3385. } else { mixin(S_TRACE);
  3386. name = .tryFormat(prop.msgs.noStep, path);
  3387. }
  3388. }
  3389. return .tryFormat(prop.msgs.evtChildBrVar, name, value);
  3390. }
  3391. private string evtChildBrStepUL(in Props prop, in Summary summ, string path, int num, ref string text) { mixin(S_TRACE);
  3392. bool val = (text != prop.sys.evtChildFalse);
  3393. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3394. string name = prop.msgs.noSelectStep;
  3395. string value = .tryFormat(prop.msgs.dlgLblStep, num);
  3396. if (path.length) { mixin(S_TRACE);
  3397. auto o = summ.flagDirRoot.findStep(path);
  3398. if (o) { mixin(S_TRACE);
  3399. name = path;
  3400. if (0 <= num && num < o.count) value = o.getValue(num);
  3401. } else { mixin(S_TRACE);
  3402. name = .tryFormat(prop.msgs.noStep, path);
  3403. }
  3404. }
  3405. if (val) { mixin(S_TRACE);
  3406. return .tryFormat(prop.msgs.stepMoreThan, name, value);
  3407. } else { mixin(S_TRACE);
  3408. return .tryFormat(prop.msgs.stepLessThan, name, value);
  3409. }
  3410. }
  3411. private string evtChildBrMember(in Props prop, bool all, bool random, ref string text) { mixin(S_TRACE);
  3412. bool val = (text != prop.sys.evtChildFalse);
  3413. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3414. string mem = all ? prop.msgs.partyAll : prop.msgs.partyActive;
  3415. string am = random ? prop.msgs.autoSelect : prop.msgs.manualSelect;
  3416. if (val) { mixin(S_TRACE);
  3417. return .tryFormat(prop.msgs.selectMemberSuccess, mem, am);
  3418. } else { mixin(S_TRACE);
  3419. return .tryFormat(prop.msgs.selectMemberFailure, mem, am);
  3420. }
  3421. }
  3422. private string evtChildBrPower(in Props prop, Target targ, Physical p, Mental m, int lev, ref string text) { mixin(S_TRACE);
  3423. bool val = (text != prop.sys.evtChildFalse);
  3424. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3425. string tt = prop.msgs.targetName(targ.m);
  3426. string tp = prop.msgs.physicalName(p);
  3427. string tm = prop.msgs.mentalName(m);
  3428. if (val) { mixin(S_TRACE);
  3429. return .tryFormat(prop.msgs.branchAbilitySuccess, tt, lev, tp, tm);
  3430. } else { mixin(S_TRACE);
  3431. return .tryFormat(prop.msgs.branchAbilityFailure, tt, lev, tp, tm);
  3432. }
  3433. }
  3434. private string evtChildBrRandom(in Props prop, int percent, ref string text) { mixin(S_TRACE);
  3435. bool val = (text != prop.sys.evtChildFalse);
  3436. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3437. if (val) { mixin(S_TRACE);
  3438. return .tryFormat(prop.msgs.branchRandomSuccess, percent);
  3439. } else { mixin(S_TRACE);
  3440. return .tryFormat(prop.msgs.branchRandomFailure, percent);
  3441. }
  3442. }
  3443. private string evtChildBrLevel(in Props prop, int lev, bool avg, ref string text) { mixin(S_TRACE);
  3444. bool val = (text != prop.sys.evtChildFalse);
  3445. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3446. string ta = avg ? prop.msgs.levelAverage : prop.msgs.levelSelected;
  3447. if (val) { mixin(S_TRACE);
  3448. return .tryFormat(prop.msgs.branchLevelSuccess, ta, lev);
  3449. } else { mixin(S_TRACE);
  3450. return .tryFormat(prop.msgs.branchLevelFailure, ta, lev);
  3451. }
  3452. }
  3453. private string evtChildBrState(in Props prop, Target targ, Status stat, ref string text) { mixin(S_TRACE);
  3454. bool val = (text != prop.sys.evtChildFalse);
  3455. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3456. string tt = prop.msgs.targetName(targ.m);
  3457. string ts = prop.msgs.statusName(stat);
  3458. if (val) { mixin(S_TRACE);
  3459. return .tryFormat(prop.msgs.branchStatusSuccess, tt, ts);
  3460. } else { mixin(S_TRACE);
  3461. return .tryFormat(prop.msgs.branchStatusFailure, tt, ts);
  3462. }
  3463. }
  3464. private string evtChildBrNum(in Props prop, int num, ref string text) { mixin(S_TRACE);
  3465. bool val = (text != prop.sys.evtChildFalse);
  3466. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3467. if (val) { mixin(S_TRACE);
  3468. return .tryFormat(prop.msgs.branchNumberSuccess, num);
  3469. } else { mixin(S_TRACE);
  3470. return .tryFormat(prop.msgs.branchNumberFailure, num);
  3471. }
  3472. }
  3473. private string evtChildBrArea(in Props prop, in Area[] areas, ref string text) { mixin(S_TRACE);
  3474. if (text.length > 0) { mixin(S_TRACE);
  3475. try { mixin(S_TRACE);
  3476. long val = text == prop.sys.evtChildDefault ? -1 : (isNumeric(text) ? to!(long)(text) : -1);
  3477. if (val >= 0) { mixin(S_TRACE);
  3478. foreach (a; areas) { mixin(S_TRACE);
  3479. if (a.id == val) { mixin(S_TRACE);
  3480. return .tryFormat(prop.msgs.branchArea, a.name);
  3481. }
  3482. }
  3483. }
  3484. } catch {}
  3485. }
  3486. text = prop.sys.evtChildDefault;
  3487. return .tryFormat(prop.msgs.branchArea, prop.msgs.etc);
  3488. }
  3489. private string evtChildBrBattle(in Props prop, in Battle[] btls, ref string text) { mixin(S_TRACE);
  3490. if (text.length > 0) { mixin(S_TRACE);
  3491. try { mixin(S_TRACE);
  3492. long val = text == prop.sys.evtChildDefault ? -1 : (isNumeric(text) ? to!(long)(text) : -1);
  3493. if (val >= 0) { mixin(S_TRACE);
  3494. foreach (b; btls) { mixin(S_TRACE);
  3495. if (b.id == val) { mixin(S_TRACE);
  3496. return .tryFormat(prop.msgs.branchBattle, b.name);
  3497. }
  3498. }
  3499. }
  3500. } catch {}
  3501. }
  3502. text = prop.sys.evtChildDefault;
  3503. return .tryFormat(prop.msgs.branchBattle, prop.msgs.etc);
  3504. }
  3505. private string evtChildBrOnBattle(in Props prop, ref string text) { mixin(S_TRACE);
  3506. bool val = (text != prop.sys.evtChildFalse);
  3507. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3508. if (val) { mixin(S_TRACE);
  3509. return prop.msgs.branchOnBattleSuccess;
  3510. } else { mixin(S_TRACE);
  3511. return prop.msgs.branchOnBattleFailure;
  3512. }
  3513. }
  3514. private string evtChildBrCast(in Props prop, in Summary summ, ulong id, ref string text) { mixin(S_TRACE);
  3515. bool val = (text != prop.sys.evtChildFalse);
  3516. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3517. string name = prop.msgs.noSelectCast;
  3518. if (0 != id) { mixin(S_TRACE);
  3519. auto c = summ.cwCast(id);
  3520. name = c ? c.name : .tryFormat(prop.msgs.noCast, id);
  3521. }
  3522. if (val) { mixin(S_TRACE);
  3523. return .tryFormat(prop.msgs.branchCastSuccess, name);
  3524. } else { mixin(S_TRACE);
  3525. return .tryFormat(prop.msgs.branchCastFailure, name);
  3526. }
  3527. }
  3528. private string evtChildBrItem(in Props prop, in Summary summ, ulong id, Range r, uint num, ref string text) { mixin(S_TRACE);
  3529. bool val = (text != prop.sys.evtChildFalse);
  3530. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3531. string tr = prop.msgs.rangeName(r);
  3532. string name = prop.msgs.noSelectItem;
  3533. if (0 != id) { mixin(S_TRACE);
  3534. auto c = summ.item(id);
  3535. name = c ? c.name : .tryFormat(prop.msgs.noItem, id);
  3536. }
  3537. if (val) { mixin(S_TRACE);
  3538. return .tryFormat(prop.msgs.branchEffectCardSuccess, tr, name);
  3539. } else { mixin(S_TRACE);
  3540. return .tryFormat(prop.msgs.branchEffectCardFailure, tr, name);
  3541. }
  3542. }
  3543. private string evtChildBrSkill(in Props prop, in Summary summ, ulong id, Range r, uint num, ref string text) { mixin(S_TRACE);
  3544. bool val = (text != prop.sys.evtChildFalse);
  3545. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3546. string tr = prop.msgs.rangeName(r);
  3547. string name = prop.msgs.noSelectSkill;
  3548. if (0 != id) { mixin(S_TRACE);
  3549. auto c = summ.skill(id);
  3550. name = c ? c.name : .tryFormat(prop.msgs.noSkill, id);
  3551. }
  3552. if (val) { mixin(S_TRACE);
  3553. return .tryFormat(prop.msgs.branchEffectCardSuccess, tr, name);
  3554. } else { mixin(S_TRACE);
  3555. return .tryFormat(prop.msgs.branchEffectCardFailure, tr, name);
  3556. }
  3557. }
  3558. private string evtChildBrBeast(in Props prop, in Summary summ, ulong id, Range r, uint num, ref string text) { mixin(S_TRACE);
  3559. bool val = (text != prop.sys.evtChildFalse);
  3560. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3561. string tr = prop.msgs.rangeName(r);
  3562. string name = prop.msgs.noSelectBeast;
  3563. if (0 != id) { mixin(S_TRACE);
  3564. auto c = summ.beast(id);
  3565. name = c ? c.name : .tryFormat(prop.msgs.noBeast, id);
  3566. }
  3567. if (val) { mixin(S_TRACE);
  3568. return .tryFormat(prop.msgs.branchEffectCardSuccess, tr, name);
  3569. } else { mixin(S_TRACE);
  3570. return .tryFormat(prop.msgs.branchEffectCardFailure, tr, name);
  3571. }
  3572. }
  3573. private string evtChildBrInfo(in Props prop, in Summary summ, ulong id, ref string text) { mixin(S_TRACE);
  3574. bool val = (text != prop.sys.evtChildFalse);
  3575. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3576. string name = prop.msgs.noSelectInfo;
  3577. if (0 != id) { mixin(S_TRACE);
  3578. auto c = summ.info(id);
  3579. name = c ? c.name : .tryFormat(prop.msgs.noInfo, id);
  3580. }
  3581. if (val) { mixin(S_TRACE);
  3582. return .tryFormat(prop.msgs.branchInfoSuccess, name);
  3583. } else { mixin(S_TRACE);
  3584. return .tryFormat(prop.msgs.branchInfoFailure, name);
  3585. }
  3586. }
  3587. private string evtChildBrMoney(in Props prop, uint sp, ref string text) { mixin(S_TRACE);
  3588. bool val = (text != prop.sys.evtChildFalse);
  3589. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3590. if (val) { mixin(S_TRACE);
  3591. return .tryFormat(prop.msgs.branchMoneySuccess, sp);
  3592. } else { mixin(S_TRACE);
  3593. return .tryFormat(prop.msgs.branchMoneyFailure, sp);
  3594. }
  3595. }
  3596. private string evtChildBrCoupon(in Props prop, Range r, string coupon, ref string text) { mixin(S_TRACE);
  3597. bool val = (text != prop.sys.evtChildFalse);
  3598. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3599. if (!coupon || !coupon.length) coupon = prop.msgs.noSelectCoupon;
  3600. string tr = prop.msgs.rangeName(r);
  3601. if (val) { mixin(S_TRACE);
  3602. return .tryFormat(prop.msgs.branchCouponSuccess, tr, coupon);
  3603. } else { mixin(S_TRACE);
  3604. return .tryFormat(prop.msgs.branchCouponFailure, tr, coupon);
  3605. }
  3606. }
  3607. private string evtChildBrEnd(in Props prop, string scenario, ref string text) { mixin(S_TRACE);
  3608. bool val = (text != prop.sys.evtChildFalse);
  3609. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3610. if (!scenario || !scenario.length) scenario = prop.msgs.noSelectCompleteStamp;
  3611. if (val) { mixin(S_TRACE);
  3612. return .tryFormat(prop.msgs.branchCompleteSuccess, scenario);
  3613. } else { mixin(S_TRACE);
  3614. return .tryFormat(prop.msgs.branchCompleteFailure, scenario);
  3615. }
  3616. }
  3617. private string evtChildBrGossip(in Props prop, string gossip, ref string text) { mixin(S_TRACE);
  3618. bool val = (text != prop.sys.evtChildFalse);
  3619. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3620. if (!gossip || !gossip.length) gossip = prop.msgs.noSelectGossip;
  3621. if (val) { mixin(S_TRACE);
  3622. return .tryFormat(prop.msgs.branchGossipSuccess, gossip);
  3623. } else { mixin(S_TRACE);
  3624. return .tryFormat(prop.msgs.branchGossipFailure, gossip);
  3625. }
  3626. }
  3627. private string evtChildBrStepCmp(in Props prop, in Summary summ, string step1, string step2, ref string text) { mixin(S_TRACE);
  3628. int index;
  3629. if (text == prop.sys.evtChildEq) { mixin(S_TRACE);
  3630. index = 2;
  3631. text = prop.sys.evtChildEq;
  3632. } else if (text == prop.sys.evtChildLesser) { mixin(S_TRACE);
  3633. index = 1;
  3634. text = prop.sys.evtChildLesser;
  3635. } else { mixin(S_TRACE);
  3636. index = 0;
  3637. text = prop.sys.evtChildGreater;
  3638. }
  3639. string nameFrom(string path) { mixin(S_TRACE);
  3640. string name = prop.msgs.noSelectStep;
  3641. if (path.length) { mixin(S_TRACE);
  3642. auto o = summ.flagDirRoot.findStep(path);
  3643. if (o) { mixin(S_TRACE);
  3644. name = path;
  3645. } else { mixin(S_TRACE);
  3646. name = .tryFormat(prop.msgs.noStep, path);
  3647. }
  3648. }
  3649. return name;
  3650. }
  3651. step1 = nameFrom(step1);
  3652. step2 = nameFrom(step2);
  3653. switch (index) {
  3654. case 0:
  3655. return .tryFormat(prop.msgs.branchStepCmpGreater, step1, step2);
  3656. case 1:
  3657. return .tryFormat(prop.msgs.branchStepCmpLesser, step1, step2);
  3658. case 2:
  3659. return .tryFormat(prop.msgs.branchStepCmpEq, step1, step2);
  3660. default:
  3661. assert (0);
  3662. }
  3663. }
  3664. private string evtChildBrFlagCmp(in Props prop, in Summary summ, string flag1, string flag2, ref string text) { mixin(S_TRACE);
  3665. bool val = (text != prop.sys.evtChildFalse);
  3666. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3667. string nameFrom(string path) { mixin(S_TRACE);
  3668. string name = prop.msgs.noSelectFlag;
  3669. if (path.length) { mixin(S_TRACE);
  3670. auto o = summ.flagDirRoot.findFlag(path);
  3671. if (o) { mixin(S_TRACE);
  3672. name = path;
  3673. } else { mixin(S_TRACE);
  3674. name = .tryFormat(prop.msgs.noFlag, path);
  3675. }
  3676. }
  3677. return name;
  3678. }
  3679. flag1 = nameFrom(flag1);
  3680. flag2 = nameFrom(flag2);
  3681. if (val) { mixin(S_TRACE);
  3682. return .tryFormat(prop.msgs.branchFlagCmpEq, flag1, flag2);
  3683. } else { mixin(S_TRACE);
  3684. return .tryFormat(prop.msgs.branchFlagCmpNotEq, flag1, flag2);
  3685. }
  3686. }
  3687. private string evtChildBrRandomSelect(in Props prop, in Content evt, ref string text) { mixin(S_TRACE);
  3688. bool val = (text != prop.sys.evtChildFalse);
  3689. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3690. string r = castRangesName(prop, evt.castRange);
  3691. bool hasLevel = 0 < evt.levelMax;
  3692. bool hasStatus = evt.status !is Status.NONE;
  3693. if (hasLevel || hasStatus) { mixin(S_TRACE);
  3694. string s = prop.msgs.statusName(evt.status);
  3695. auto l1 = evt.levelMin, l2 = evt.levelMax;
  3696. string cond;
  3697. if (hasLevel && hasStatus) { mixin(S_TRACE);
  3698. cond = .tryFormat(prop.msgs.randomSelectCondition3, l1, l2, s);
  3699. } else if (hasLevel) { mixin(S_TRACE);
  3700. cond = .tryFormat(prop.msgs.randomSelectCondition1, l1, l2);
  3701. } else if (hasStatus) { mixin(S_TRACE);
  3702. cond = .tryFormat(prop.msgs.randomSelectCondition2, s);
  3703. } else assert (0);
  3704. if (val) { mixin(S_TRACE);
  3705. return .tryFormat(prop.msgs.branchRandomSelectSuccess, r, cond);
  3706. } else { mixin(S_TRACE);
  3707. return .tryFormat(prop.msgs.branchRandomSelectFailure, r, cond);
  3708. }
  3709. } else { mixin(S_TRACE);
  3710. if (val) { mixin(S_TRACE);
  3711. return .tryFormat(prop.msgs.branchRandomSelectSuccessN, r);
  3712. } else { mixin(S_TRACE);
  3713. return .tryFormat(prop.msgs.branchRandomSelectFailureN, r);
  3714. }
  3715. }
  3716. }
  3717. private string evtChildBrKeyCode(in Props prop, in Content evt, ref string text) { mixin(S_TRACE);
  3718. bool val = (text != prop.sys.evtChildFalse);
  3719. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3720. string range = prop.msgs.rangeName(evt.keyCodeRange);
  3721. if (evt.effectCardType is EffectCardType.ALL) { mixin(S_TRACE);
  3722. if (val) { mixin(S_TRACE);
  3723. return .tryFormat(prop.msgs.branchKeyCodeAllTypeSuccess, evt.keyCode, range);
  3724. } else { mixin(S_TRACE);
  3725. return .tryFormat(prop.msgs.branchKeyCodeAllTypeFailure, evt.keyCode, range);
  3726. }
  3727. } else { mixin(S_TRACE);
  3728. string type = prop.msgs.effectCardTypeName(evt.effectCardType);
  3729. if (val) { mixin(S_TRACE);
  3730. return .tryFormat(prop.msgs.branchKeyCodeSuccess, evt.keyCode, type, range);
  3731. } else { mixin(S_TRACE);
  3732. return .tryFormat(prop.msgs.branchKeyCodeFailure, evt.keyCode, type, range);
  3733. }
  3734. }
  3735. }
  3736. private string evtChildBrRound(in Props prop, in Content evt, ref string text) { mixin(S_TRACE);
  3737. bool val = (text != prop.sys.evtChildFalse);
  3738. text = val ? prop.sys.evtChildTrue : prop.sys.evtChildFalse;
  3739. string cmp;
  3740. if (val) { mixin(S_TRACE);
  3741. cmp = prop.msgs.comparison3Name(evt.comparison3);
  3742. } else { mixin(S_TRACE);
  3743. cmp = prop.msgs.comparison3FalseName(evt.comparison3);
  3744. }
  3745. return .tryFormat(prop.msgs.branchRound, evt.round, cmp);
  3746. }
  3747. Image warningImage(Props prop, Display d) { mixin(S_TRACE);
  3748. auto height = 1;
  3749. auto buf = new Image(d, prop.var.etc.warningImageWidth, height);
  3750. scope (exit) buf.dispose();
  3751. auto gc = new GC(buf);
  3752. scope (exit) gc.dispose();
  3753. int alpha;
  3754. auto rgb = dwtData(prop.var.etc.warningImageColor, alpha);
  3755. auto color = new Color(d, rgb);
  3756. scope (exit) color.dispose();
  3757. gc.setForeground(color);
  3758. gc.setBackground(color);
  3759. gc.fillRectangle(0, 0, prop.var.etc.warningImageWidth, height);
  3760. auto alphas = new byte[prop.var.etc.warningImageWidth];
  3761. foreach (i, ref b; alphas) { mixin(S_TRACE);
  3762. b = cast(byte)(cast(real)i / prop.var.etc.warningImageWidth * alpha);
  3763. }
  3764. alphas = std.array.replicate(alphas, height);
  3765. assert (alphas.length == prop.var.etc.warningImageWidth * height);
  3766. auto imgData = buf.getImageData();
  3767. imgData.setAlphas(0, 0, prop.var.etc.warningImageWidth * height, alphas, 0);
  3768. return new Image(d, imgData);
  3769. }
  3770. class ContentsToolBox {
  3771. private Commons _comm;
  3772. private Props _prop;
  3773. private Summary _summ;
  3774. private EventTreeView _parent = null;
  3775. private CoolBar _cbar;
  3776. private Menu _templMenu;
  3777. private ToolItem _templTI;
  3778. private auto _putMode = MenuID.PutSelect;
  3779. private bool _autoOpen;
  3780. private bool _insertFirst;
  3781. private MenuItem _putQuickMI;
  3782. private MenuItem _putSelectMI;
  3783. private MenuItem _putContinueMI;
  3784. private ToolItem _putModeTI;
  3785. private ToolItem _autoOpenTI;
  3786. private ToolItem _insertFirstTI;
  3787. private bool _arrowMode = true;
  3788. private CType _cType;
  3789. private ToolItem _arrowTI;
  3790. private ToolItem _evtTI = null;
  3791. private ToolItemGroup _radioGroup;
  3792. private Cursor[] _cursors;
  3793. private CreateEvent[CType] _conts;
  3794. private bool _shiftDown = false;
  3795. private MouseTrack _mTrack = null;
  3796. private Shell _toolWin = null;
  3797. private Shell _autoHideTools = null;
  3798. private TCListener _tcListener = null;
  3799. private bool _opened = false;
  3800. private int _parX, _parY;
  3801. private DisposeListener _disposeParent = null;
  3802. private AHTCListener _autoResize = null;
  3803. private void autoOpen() { mixin(S_TRACE);
  3804. _autoOpen = _autoOpenTI.getSelection();
  3805. _comm.selContentTool.call(this, _arrowMode, _cType, _putMode, _autoOpen, _insertFirst);
  3806. }
  3807. private void updatePutMode() { mixin(S_TRACE);
  3808. if (_putQuickMI.getSelection()) { mixin(S_TRACE);
  3809. _putMode = MenuID.PutQuick;
  3810. arrow();
  3811. foreach (ti; _radioGroup.set) { mixin(S_TRACE);
  3812. ti.setSelection(false);
  3813. }
  3814. _arrowTI.setSelection(false);
  3815. } else if (_putSelectMI.getSelection()) { mixin(S_TRACE);
  3816. _putMode = MenuID.PutSelect;
  3817. if (!_arrowTI.getEnabled()) arrow();
  3818. } else if (_putContinueMI.getSelection()) { mixin(S_TRACE);
  3819. _putMode = MenuID.PutContinue;
  3820. if (!_arrowTI.getEnabled()) arrow();
  3821. }
  3822. _arrowTI.setEnabled(_putMode !is MenuID.PutQuick);
  3823. _putModeTI.setToolTipText(_prop.buildTool(_putMode));
  3824. _putModeTI.setImage(_prop.images.menu(_putMode));
  3825. _comm.selContentTool.call(this, _arrowMode, _cType, _putMode, _autoOpen, _insertFirst);
  3826. }
  3827. private void insertFirst() { mixin(S_TRACE);
  3828. _insertFirst = _insertFirstTI.getSelection();
  3829. _comm.selContentTool.call(this, _arrowMode, _cType, _putMode, _autoOpen, _insertFirst);
  3830. }
  3831. private void arrow() { mixin(S_TRACE);
  3832. _arrowMode = true;
  3833. if (_radioGroup && _putMode !is MenuID.PutQuick) _radioGroup.select(_arrowTI);
  3834. _comm.selContentTool.call(this, _arrowMode, _cType, _putMode, _autoOpen, _insertFirst);
  3835. }
  3836. private void updateCursor() {
  3837. auto cursor = _arrowMode ? null : _conts[_cType]._cursor;
  3838. if (_toolWin && !_toolWin.isDisposed()) { mixin(S_TRACE);
  3839. _toolWin.setCursor(cursor);
  3840. }
  3841. if (_autoHideTools) { mixin(S_TRACE);
  3842. _autoHideTools.setCursor(cursor);
  3843. }
  3844. }
  3845. private void selContentTool(Object sender, bool arrowMode, CType cType, MenuID putMode, bool autoOpen, bool insertFirst) { mixin(S_TRACE);
  3846. scope (exit) {
  3847. updateCursor();
  3848. _prop.var.etc.contentsAutoOpen = _autoOpen;
  3849. switch (_putMode) {
  3850. case MenuID.PutQuick:
  3851. _prop.var.etc.contentsPutMode = 0;
  3852. break;
  3853. case MenuID.PutSelect:
  3854. _prop.var.etc.contentsPutMode = 1;
  3855. break;
  3856. case MenuID.PutContinue:
  3857. _prop.var.etc.contentsPutMode = 1;
  3858. break;
  3859. default:
  3860. assert (0);
  3861. }
  3862. _prop.var.etc.contentsInsertFirst = _insertFirst;
  3863. }
  3864. if (sender is this) return;
  3865. if (!_arrowMode && arrowMode) { mixin(S_TRACE);
  3866. arrow();
  3867. }
  3868. if (((_arrowMode && !arrowMode) || (_cType != cType)) && MenuID.PutQuick !is putMode) { mixin(S_TRACE);
  3869. assert (cType in _conts, .format("%s, putMode", cType));
  3870. auto ce = _conts[cType];
  3871. _radioGroup.select(ce.ti);
  3872. ce.create(null);
  3873. }
  3874. if (_autoOpen != autoOpen) { mixin(S_TRACE);
  3875. _autoOpenTI.setSelection(autoOpen);
  3876. this.autoOpen();
  3877. }
  3878. if (_putMode != putMode) { mixin(S_TRACE);
  3879. _putMode = putMode;
  3880. _putQuickMI.setSelection(_putMode is MenuID.PutQuick);
  3881. _putSelectMI.setSelection(_putMode is MenuID.PutSelect);
  3882. _putContinueMI.setSelection(_putMode is MenuID.PutContinue);
  3883. this.updatePutMode();
  3884. }
  3885. if (_insertFirst != insertFirst) { mixin(S_TRACE);
  3886. _insertFirstTI.setSelection(insertFirst);
  3887. this.insertFirst();
  3888. }
  3889. }
  3890. private class CreateEvent {
  3891. CType type;
  3892. private ToolItem _itm;
  3893. private Cursor _cursor;
  3894. this (CType type, Cursor cursor) { mixin(S_TRACE);
  3895. this.type = type;
  3896. _cursor = cursor;
  3897. }
  3898. void create(SelectionEvent e) { mixin(S_TRACE);
  3899. if (_itm.getSelection()) { mixin(S_TRACE);
  3900. auto itm = _parent.selection;
  3901. if (_putMode is MenuID.PutQuick) { mixin(S_TRACE);
  3902. putQuick(_shiftDown);
  3903. if (e) e.doit = false;
  3904. return;
  3905. }
  3906. _parent.clearClickStart();
  3907. _arrowMode = false;
  3908. _cType = type;
  3909. _evtTI = _itm;
  3910. _comm.refreshToolBar();
  3911. _comm.selContentTool.call(_arrowMode, _cType, _putMode, _autoOpen, _insertFirst);
  3912. }
  3913. }
  3914. void middleClick() { putQuick(true); }
  3915. private void putQuick(bool insert) { mixin(S_TRACE);
  3916. auto itm = _parent.selection;
  3917. if (_putMode !is MenuID.PutQuick || !itm) { mixin(S_TRACE);
  3918. arrow();
  3919. _itm.setSelection(false);
  3920. return;
  3921. }
  3922. _cType = type;
  3923. _evtTI = _itm;
  3924. _parent.create(insert ? itm : null);
  3925. _parent.clearClickStart();
  3926. arrow();
  3927. _itm.setSelection(false);
  3928. }
  3929. @property
  3930. void ti(ToolItem ti) { mixin(S_TRACE);
  3931. _itm = ti;
  3932. auto listener = new class MouseAdapter {
  3933. override void mouseUp(MouseEvent e) { mixin(S_TRACE);
  3934. if (e.button != 2) return;
  3935. auto itm = _itm.getParent().getItem(new Point(e.x, e.y));
  3936. if (itm is _itm) { mixin(S_TRACE);
  3937. middleClick();
  3938. }
  3939. }
  3940. };
  3941. _itm.getParent().addMouseListener(listener);
  3942. .listener(_itm, SWT.Dispose, { mixin(S_TRACE);
  3943. _itm.getParent().removeMouseListener(listener);
  3944. });
  3945. }
  3946. @property
  3947. ToolItem ti() {return _itm;}
  3948. }
  3949. private ToolItem createEI(CType type, ToolBar bar, ToolItemGroup g) { mixin(S_TRACE);
  3950. auto text = _prop.msgs.contentName(type);
  3951. auto img = _prop.images.content(type);
  3952. auto cursor = _prop.images.cursor(type);
  3953. _cursors ~= cursor;
  3954. auto ce = new CreateEvent(type, cursor);
  3955. auto itm = createToolItem2(_comm, bar, text, img, &ce.create, () => _parent.selection !is null, SWT.RADIO);
  3956. ce.ti = itm;
  3957. g.append(itm);
  3958. _conts[type] = ce;
  3959. return itm;
  3960. }
  3961. private class TRDListener : DisposeListener {
  3962. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  3963. if (_comm.poolContentsToolBox(this.outer)) { mixin(S_TRACE);
  3964. return;
  3965. }
  3966. disposeParent();
  3967. }
  3968. }
  3969. private void disposeParent() {
  3970. _comm.refEventTemplates.remove(&refreshTemplatesM);
  3971. _comm.selContentTool.remove(&selContentTool);
  3972. if (_toolWin) { mixin(S_TRACE);
  3973. saveToolWinPos();
  3974. _toolWin.dispose();
  3975. }
  3976. if (_tcListener) { mixin(S_TRACE);
  3977. _autoHideTools.getParent().removeControlListener(_tcListener);
  3978. }
  3979. if (_autoHideTools) { mixin(S_TRACE);
  3980. _autoHideTools.dispose();
  3981. }
  3982. }
  3983. private class TMListener : MouseAdapter {
  3984. override void mouseUp(MouseEvent e) { mixin(S_TRACE);
  3985. if (e.button == 3) { mixin(S_TRACE);
  3986. arrow();
  3987. _comm.refreshToolBar();
  3988. }
  3989. }
  3990. }
  3991. private static class PutScript {
  3992. private string _script;
  3993. private void delegate(string, bool) _pasteScript;
  3994. private Image _img = null;
  3995. this (Props prop, in Summary summ, string script, void delegate(string, bool) pasteScript) { mixin(S_TRACE);
  3996. _script = script;
  3997. _pasteScript = pasteScript;
  3998. auto type = cwx.script.firstContentType(prop.parent, summ, _script);
  3999. if (type != -1) { mixin(S_TRACE);
  4000. _img = prop.images.content(type);
  4001. }
  4002. }
  4003. void put(SelectionEvent se) { mixin(S_TRACE);
  4004. _pasteScript(_script, (se.stateMask & SWT.SHIFT) != 0);
  4005. }
  4006. @property
  4007. Image image() { mixin(S_TRACE);
  4008. return _img;
  4009. }
  4010. }
  4011. static void refreshTemplates(Commons comm, Props prop, Summary summ, Menu menu, Shell shell, bool delegate() enabled, void delegate(string, bool) pasteScript) { mixin(S_TRACE);
  4012. foreach (itm; menu.getItems()) { mixin(S_TRACE);
  4013. itm.dispose();
  4014. }
  4015. // ??????????????????????????????????????
  4016. foreach (t; summ.eventTemplates) { mixin(S_TRACE);
  4017. auto c = new PutScript(prop, summ, t.script, pasteScript);
  4018. auto text = MenuProps.buildMenu(t.name, t.mnemonic, t.hotkey, false);
  4019. createMenuItem2(comm, menu, text, c.image, &c.put, enabled);
  4020. }
  4021. if (prop.var.etc.eventTemplates.length && summ.eventTemplates.length) { mixin(S_TRACE);
  4022. new MenuItem(menu, SWT.SEPARATOR);
  4023. }
  4024. foreach (t; prop.var.etc.eventTemplates) { mixin(S_TRACE);
  4025. auto c = new PutScript(prop, summ, t.script, pasteScript);
  4026. auto text = MenuProps.buildMenu(t.name, t.mnemonic, t.hotkey, false);
  4027. createMenuItem2(comm, menu, text, c.image, &c.put, enabled);
  4028. }
  4029. if (prop.var.etc.eventTemplates.length || summ.eventTemplates.length) { mixin(S_TRACE);
  4030. new MenuItem(menu, SWT.SEPARATOR);
  4031. }
  4032. void editScEvTemplate() { mixin(S_TRACE);
  4033. auto dlg = new EventTemplateDialog(comm, prop, summ, shell, summ.eventTemplates);
  4034. dlg.appliedEvent ~= { mixin(S_TRACE);
  4035. summ.eventTemplates = dlg.eventTemplates;
  4036. comm.refEventTemplates.call();
  4037. };
  4038. dlg.open();
  4039. }
  4040. createMenuItem(comm, menu, MenuID.EvTemplatesOfScenario, &editScEvTemplate, enabled);
  4041. }
  4042. private void refreshTemplatesM() { mixin(S_TRACE);
  4043. refreshTemplates(_comm, _prop, _summ, _templMenu, _parent.widget.getShell(), () => _parent._et !is null, (string script, bool tryInsert) {
  4044. _parent.pasteScript(script, tryInsert);
  4045. });
  4046. _templTI.setEnabled(0 < _templMenu.getItemCount());
  4047. }
  4048. private class TDListener : DisposeListener {
  4049. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  4050. assert (_toolWin);
  4051. if (_toolWin.isDisposed()) return;
  4052. if (_toolWin.getVisible()) { mixin(S_TRACE);
  4053. saveToolWinPos();
  4054. }
  4055. }
  4056. }
  4057. private class TCListener : ControlAdapter {
  4058. override void controlMoved(ControlEvent e) { mixin(S_TRACE);
  4059. if (_autoHideTools) { mixin(S_TRACE);
  4060. calcAutoHideSize();
  4061. return;
  4062. }
  4063. assert (_toolWin);
  4064. if (!_toolWin || _toolWin.isDisposed()) return;
  4065. auto pb = _toolWin.getParent().getBounds();
  4066. auto tb = _toolWin.getBounds();
  4067. _toolWin.setBounds(tb.x + pb.x - _parX, tb.y + pb.y - _parY, tb.width, tb.height);
  4068. _parX = pb.x;
  4069. _parY = pb.y;
  4070. }
  4071. }
  4072. private class AHTCListener : ControlAdapter {
  4073. override void controlResized(ControlEvent e) { mixin(S_TRACE);
  4074. if (!_autoHideTools.isVisible()) return;
  4075. calcAutoHideSize();
  4076. }
  4077. }
  4078. private class MouseTrack : Listener {
  4079. override void handleEvent(Event e) { mixin(S_TRACE);
  4080. auto c = cast(Control) e.widget;
  4081. if (!c || !_autoHideTools) return;
  4082. if (!_parent._et) { mixin(S_TRACE);
  4083. _autoHideTools.setVisible(false);
  4084. return;
  4085. }
  4086. if (e.type is SWT.MouseMove && _parent._contentsBoxArea.isVisible()) return;
  4087. if (c !is _parent._tree.control && !isDescendant(_autoHideTools, c) && !isDescendant(_parent._contentsBoxArea, c)) { mixin(S_TRACE);
  4088. _autoHideTools.setVisible(false);
  4089. return;
  4090. }
  4091. auto p = c.toDisplay(e.x, e.y);
  4092. auto ca2 = _autoHideTools.getBounds();
  4093. ca2.x = 0;
  4094. ca2.y = 0;
  4095. if (!_autoHideTools.isVisible()) { mixin(S_TRACE);
  4096. ca2.width = 0;
  4097. ca2.height = 0;
  4098. }
  4099. auto p2 = _autoHideTools.toControl(p);
  4100. auto ca1 = _parent._contentsBoxArea.getBounds();
  4101. ca1.x = 0;
  4102. ca1.y = 0;
  4103. if (0 == ca1.height) { mixin(S_TRACE);
  4104. ca1.height = _prop.var.etc.showContentsBoxHeightWhenNoToolBar;
  4105. }
  4106. auto p1 = _parent._contentsBoxArea.toControl(p);
  4107. if (ca1.contains(p1) || ca2.contains(p2)) { mixin(S_TRACE);
  4108. if (e.type is SWT.MouseUp && _autoHideTools.isVisible()) { mixin(S_TRACE);
  4109. _autoHideTools.setVisible(false);
  4110. } else if ((e.type is SWT.MouseUp || _parent._tree.control.isFocusControl()) && !_autoHideTools.isVisible()) { mixin(S_TRACE);
  4111. calcAutoHideSize();
  4112. _autoHideTools.setVisible(true);
  4113. }
  4114. } else { mixin(S_TRACE);
  4115. _autoHideTools.setVisible(false);
  4116. }
  4117. }
  4118. }
  4119. private class TSListener : ShellAdapter {
  4120. public override void shellClosed(ShellEvent e) { mixin(S_TRACE);
  4121. assert (_toolWin);
  4122. if (_toolWin.isDisposed()) return;
  4123. _toolWin.setVisible(false);
  4124. e.doit = false;
  4125. }
  4126. }
  4127. this (EventTreeView parent) {
  4128. _comm = parent._comm;
  4129. _prop = parent._prop;
  4130. _summ = parent._summ;
  4131. _parent = parent;
  4132. Composite cbarPar;
  4133. if (_prop.var.etc.contentsFloat) { mixin(S_TRACE);
  4134. _toolWin = new Shell(parent.widget.getShell(), SWT.TITLE | SWT.RESIZE | SWT.TOOL);
  4135. _toolWin.setLayout(zeroGridLayout(1));
  4136. _toolWin.setText(_prop.msgs.tools);
  4137. _toolWin.addShellListener(new TSListener);
  4138. cbarPar = new Composite(_toolWin, SWT.NONE);
  4139. cbarPar.setLayoutData(new GridData(GridData.FILL_BOTH));
  4140. } else if (_prop.var.etc.contentsAutoHide) { mixin(S_TRACE);
  4141. _autoHideTools = new Shell(parent.widget.getShell(), SWT.NO_TRIM);
  4142. _autoHideTools.setLayout(zeroGridLayout(1));
  4143. cbarPar = new Composite(_autoHideTools, SWT.NONE);
  4144. cbarPar.setLayoutData(new GridData(GridData.FILL_BOTH));
  4145. _mTrack = new MouseTrack;
  4146. _autoHideTools.getDisplay().addFilter(SWT.MouseUp, _mTrack);
  4147. _autoHideTools.getDisplay().addFilter(SWT.MouseEnter, _mTrack);
  4148. _autoHideTools.getDisplay().addFilter(SWT.MouseExit, _mTrack);
  4149. .listener(_autoHideTools, SWT.Dispose, {
  4150. _autoHideTools.getDisplay().removeFilter(SWT.MouseUp, _mTrack);
  4151. _autoHideTools.getDisplay().removeFilter(SWT.MouseEnter, _mTrack);
  4152. _autoHideTools.getDisplay().removeFilter(SWT.MouseExit, _mTrack);
  4153. });
  4154. } else {
  4155. cbarPar = _parent.boxOwner;
  4156. }
  4157. cbarPar.setLayout(new FillLayout);
  4158. _disposeParent = new TRDListener;
  4159. _arrowMode = _parent._arrowMode;
  4160. _cType = _parent._cType;
  4161. _autoOpen = _prop.var.etc.contentsAutoOpen;
  4162. switch (_prop.var.etc.contentsPutMode.value) {
  4163. case 0:
  4164. _putMode = MenuID.PutQuick;
  4165. break;
  4166. case 1:
  4167. _putMode = MenuID.PutSelect;
  4168. break;
  4169. case 2:
  4170. _putMode = MenuID.PutContinue;
  4171. break;
  4172. default:
  4173. _putMode = MenuID.PutSelect;
  4174. }
  4175. _insertFirst = _prop.var.etc.contentsInsertFirst;
  4176. auto shiftCaptcha = new class Listener {
  4177. override void handleEvent(Event e) { mixin(S_TRACE);
  4178. if (e.type == SWT.KeyUp && e.keyCode == SWT.SHIFT) { mixin(S_TRACE);
  4179. _shiftDown = false;
  4180. } else if (e.type == SWT.KeyDown && e.keyCode == SWT.SHIFT) { mixin(S_TRACE);
  4181. _shiftDown = true;
  4182. }
  4183. }
  4184. };
  4185. _comm.refEventTemplates.add(&refreshTemplatesM);
  4186. _comm.selContentTool.add(&selContentTool);
  4187. _cbar = createCoolBar!("contents")(_comm, cbarPar, (CoolBar cbar) { mixin(S_TRACE);
  4188. void createCoolItem(CoolBar cbar, ToolBar tbar, int index = -1) { mixin(S_TRACE);
  4189. .createCoolItem(cbar, tbar, index);
  4190. }
  4191. if (!_prop.var.etc.contentsFloat || _autoHideTools) { mixin(S_TRACE);
  4192. cbar.addMouseListener(new TMListener);
  4193. }
  4194. auto g = new ToolItemGroup;
  4195. _radioGroup = g;
  4196. auto atm = new ToolBar(cbar, SWT.FLAT);
  4197. atm.addMouseListener(new TMListener);
  4198. _arrowTI = createToolItem2(_comm, atm, _prop.msgs.evtArrow, _prop.images.evtArrow, &arrow, null, SWT.RADIO);
  4199. if (_putMode !is MenuID.PutQuick) _arrowTI.setSelection(true);
  4200. g.append(_arrowTI);
  4201. createCoolItem(cbar, atm);
  4202. auto mode = new ToolBar(cbar, SWT.FLAT);
  4203. mode.addMouseListener(new TMListener);
  4204. Menu putModeMenu;
  4205. void delegate() dlg = null;
  4206. _putModeTI = createDropDownItem2(_comm, mode, _prop.buildTool(_putMode), _prop.images.menu(_putMode), dlg, putModeMenu, MenuID.None, null);
  4207. _putQuickMI = createMenuItem(_comm, putModeMenu, MenuID.PutQuick, &updatePutMode, null, SWT.RADIO);
  4208. _putSelectMI = createMenuItem(_comm, putModeMenu, MenuID.PutSelect, &updatePutMode, null, SWT.RADIO);
  4209. _putContinueMI = createMenuItem(_comm, putModeMenu, MenuID.PutContinue, &updatePutMode, null, SWT.RADIO);
  4210. _autoOpenTI = createToolItem2(_comm, mode, _prop.msgs.evtAutoOpen, _prop.images.evtAutoOpen, &autoOpen, null, SWT.CHECK);
  4211. _autoOpenTI.setSelection(_autoOpen);
  4212. _insertFirstTI = createToolItem2(_comm, mode, _prop.msgs.evtInsertFirst, _prop.images.evtInsertFirst, &insertFirst, null, SWT.CHECK);
  4213. _insertFirstTI.setSelection(_insertFirst);
  4214. new ToolItem(mode, SWT.SEPARATOR);
  4215. _templTI = createDropDownItem(_comm, mode, MenuID.EvTemplates, null, _templMenu, () => _summ && _parent._et && (_prop.var.etc.eventTemplates.length || _summ.eventTemplates.length));
  4216. _putQuickMI.setSelection(_putMode is MenuID.PutQuick);
  4217. _putSelectMI.setSelection(_putMode is MenuID.PutSelect);
  4218. _putContinueMI.setSelection(_putMode is MenuID.PutContinue);
  4219. refreshTemplatesM();
  4220. createCoolItem(cbar, mode);
  4221. auto tml = new TMListener;
  4222. foreach (cGrp, cs; CTYPE_GROUP) { mixin(S_TRACE);
  4223. auto eBar = new ToolBar(cbar, SWT.FLAT);
  4224. eBar.addMouseListener(tml);
  4225. foreach (cType; cs) { mixin(S_TRACE);
  4226. createEI(cType, eBar, g);
  4227. }
  4228. if (cGrp is CTypeGroup.Visual) { mixin(S_TRACE);
  4229. createCoolItem(cbar, eBar, 2);
  4230. } else { mixin(S_TRACE);
  4231. createCoolItem(cbar, eBar);
  4232. }
  4233. _comm.put(eBar);
  4234. }
  4235. updatePutMode();
  4236. });
  4237. _cbar.addMouseListener(new TMListener);
  4238. _cbar.getDisplay().addFilter(SWT.KeyDown, shiftCaptcha);
  4239. _cbar.getDisplay().addFilter(SWT.KeyUp, shiftCaptcha);
  4240. .listener(_cbar, SWT.Dispose, { mixin(S_TRACE);
  4241. _cbar.getDisplay().removeFilter(SWT.KeyDown, shiftCaptcha);
  4242. _cbar.getDisplay().removeFilter(SWT.KeyUp, shiftCaptcha);
  4243. });
  4244. if (_toolWin) { mixin(S_TRACE);
  4245. auto dummy = new Composite(_toolWin, SWT.NONE);
  4246. auto gd = new GridData(GridData.FILL_BOTH);
  4247. gd.heightHint = 0;
  4248. dummy.setLayoutData(gd);
  4249. _toolWin.setVisible(false);
  4250. auto pb = _toolWin.getParent().getBounds();
  4251. auto size = _toolWin.computeSize(SWT.DEFAULT, SWT.DEFAULT);
  4252. auto ts = _toolWin.getBounds();
  4253. int tx = _prop.var.contentsWin.x == SWT.DEFAULT ? ts.x : pb.x + _prop.var.contentsWin.x;
  4254. int ty = _prop.var.contentsWin.y == SWT.DEFAULT ? ts.y : pb.y + _prop.var.contentsWin.y;
  4255. intoDisplay(tx, ty, size.x, size.y);
  4256. _parX = pb.x;
  4257. _parY = pb.y;
  4258. _toolWin.setBounds(tx, ty, size.x, size.y);
  4259. _toolWin.addDisposeListener(new TDListener);
  4260. _toolWin.getParent().addControlListener(new TCListener);
  4261. } else if (cbarPar) { mixin(S_TRACE);
  4262. if (_autoHideTools) { mixin(S_TRACE);
  4263. _autoResize = new AHTCListener;
  4264. _tcListener = new TCListener;
  4265. _autoHideTools.getParent().addControlListener(_tcListener);
  4266. }
  4267. }
  4268. updateCursor();
  4269. if (!_arrowMode) {
  4270. _evtTI = _conts[_cType].ti;
  4271. _radioGroup.select(_evtTI);
  4272. }
  4273. _parent._box = this;
  4274. addListenersToOwner();
  4275. relayout();
  4276. }
  4277. void dispose() { mixin(S_TRACE);
  4278. removeListenersToOwner();
  4279. _cbar.dispose();
  4280. disposeParent();
  4281. _parent._box = null;
  4282. }
  4283. private void addListenersToOwner() { mixin(S_TRACE);
  4284. if (_autoHideTools) {
  4285. owner.boxOwner.addControlListener(_autoResize);
  4286. }
  4287. owner.boxOwner.addDisposeListener(_disposeParent);
  4288. }
  4289. private void removeListenersToOwner() { mixin(S_TRACE);
  4290. if (_autoHideTools) {
  4291. owner.boxOwner.removeControlListener(_autoResize);
  4292. }
  4293. owner.boxOwner.removeDisposeListener(_disposeParent);
  4294. }
  4295. private void relayout() { mixin(S_TRACE);
  4296. if (isSingleton) { mixin(S_TRACE);
  4297. auto parGd = new GridData(GridData.FILL_HORIZONTAL);
  4298. parGd.heightHint = 0;
  4299. _parent.boxOwner.setLayoutData(parGd);
  4300. _parent.boxOwner.getParent().layout();
  4301. } else {
  4302. _cbar.setParent(_parent.boxOwner);
  4303. _parent.boxOwner.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  4304. _parent.boxOwner.getParent().layout();
  4305. _parent.boxOwner.layout();
  4306. }
  4307. }
  4308. @property
  4309. void owner(EventTreeView owner) { mixin(S_TRACE);
  4310. removeListenersToOwner();
  4311. _parent._box = null;
  4312. _parent = owner;
  4313. owner._box = this;
  4314. relayout();
  4315. addListenersToOwner();
  4316. }
  4317. @property
  4318. EventTreeView owner() { return _parent; }
  4319. @property
  4320. const
  4321. bool isSingleton() {
  4322. return _prop.var.etc.contentsAutoHide || _prop.var.etc.contentsFloat;
  4323. }
  4324. private void calcAutoHideSize() { mixin(S_TRACE);
  4325. if (!_autoHideTools) return;
  4326. auto tb = _parent._tree.control.getBounds();
  4327. auto ca1 =_parent. _contentsBoxArea.getBounds();
  4328. int x = _parent._tree.control.toDisplay(tb.x, tb.y).x;
  4329. int y = _parent._contentsBoxArea.toDisplay(0, ca1.y).y + ca1.height;
  4330. auto size = _autoHideTools.computeSize(tb.width, SWT.DEFAULT);
  4331. _autoHideTools.setBounds(new Rectangle(x, y, size.x, size.y));
  4332. }
  4333. private void saveToolWinPos() { mixin(S_TRACE);
  4334. assert (_toolWin);
  4335. if (_toolWin.isDisposed()) return;
  4336. _prop.var.contentsWin.x = _toolWin.getBounds().x - _toolWin.getParent().getBounds().x;
  4337. _prop.var.contentsWin.y = _toolWin.getBounds().y - _toolWin.getParent().getBounds().y;
  4338. }
  4339. private void openToolWindow() { mixin(S_TRACE);
  4340. if (_toolWin) { mixin(S_TRACE);
  4341. if (_toolWin.isDisposed()) return;
  4342. if (_parent._et) { mixin(S_TRACE);
  4343. if (_opened) { mixin(S_TRACE);
  4344. _toolWin.setVisible(true);
  4345. } else { mixin(S_TRACE);
  4346. _opened = true;
  4347. _toolWin.setVisible(true);
  4348. }
  4349. } else {
  4350. closeToolWindow();
  4351. }
  4352. }
  4353. _comm.refreshToolBar();
  4354. }
  4355. private void closeToolWindow() { mixin(S_TRACE);
  4356. // ????????????????????
  4357. if (_autoHideTools) { mixin(S_TRACE);
  4358. _autoHideTools.setVisible(false);
  4359. }
  4360. }
  4361. }