PageRenderTime 69ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/k4nagatsuki/cwxeditor
D | 2683 lines | 2500 code | 135 blank | 48 comment | 359 complexity | c7da1b3e317cf6cd1cc458f9f702851d MD5 | raw file
Possible License(s): LGPL-2.1

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

  1. module cwx.editor.gui.dwt.messageutils;
  2. import cwx.utils;
  3. import cwx.types;
  4. import cwx.event;
  5. import cwx.summary;
  6. import cwx.skin;
  7. import cwx.xml;
  8. import cwx.flag;
  9. import cwx.path;
  10. import cwx.structs;
  11. import cwx.msgutils;
  12. import cwx.menu;
  13. import cwx.types;
  14. import cwx.imagesize;
  15. import cwx.system;
  16. import cwx.editor.gui.dwt.dprops;
  17. import cwx.editor.gui.dwt.dskin;
  18. import cwx.editor.gui.dwt.dutils;
  19. import cwx.editor.gui.dwt.commons;
  20. import cwx.editor.gui.dwt.centerlayout;
  21. import cwx.editor.gui.dwt.customtext;
  22. import cwx.editor.gui.dwt.customtable;
  23. import cwx.editor.gui.dwt.imageselect;
  24. import cwx.editor.gui.dwt.materialselect;
  25. import cwx.editor.gui.dwt.absdialog;
  26. import cwx.editor.gui.dwt.eventdialog;
  27. import cwx.editor.gui.dwt.xmlbytestransfer;
  28. import cwx.editor.gui.dwt.undo;
  29. import cwx.editor.gui.dwt.splitpane;
  30. import cwx.editor.gui.dwt.properties;
  31. import cwx.editor.gui.dwt.absdialog;
  32. import cwx.editor.gui.dwt.dmenu;
  33. import cwx.editor.gui.dwt.couponview;
  34. import cwx.editor.gui.dwt.chooser;
  35. import std.array;
  36. import std.utf;
  37. import std.string;
  38. import std.datetime;
  39. import std.conv;
  40. import std.exception;
  41. import org.eclipse.swt.all;
  42. import java.lang.all;
  43. /// ??????????????????????????????
  44. class AbstractMessageDialog : EventDialog {
  45. private KeyDownFilter _kdFilter;
  46. private MsgPreviewWindow _previewWin = null;
  47. private MsgPreview _preview = null;
  48. private UndoManager _undo;
  49. private class SelPrev : SelectionAdapter {
  50. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  51. auto btn = cast(Button) e.widget;
  52. if (btn.getSelection()) { mixin(S_TRACE);
  53. auto s = wrapReturnCode(text);
  54. if (_previewWin) { mixin(S_TRACE);
  55. if (_previewWin.isVisible()) return;
  56. _previewWin.text(selectedTalker, "", s);
  57. _previewWin.open();
  58. } else { mixin(S_TRACE);
  59. if (rightGroup.isVisible()) return;
  60. _preview.text(selectedTalker, imgPath, s);
  61. setPreviewLData(true);
  62. }
  63. } else { mixin(S_TRACE);
  64. if (_previewWin) { mixin(S_TRACE);
  65. if (!_previewWin.isVisible()) return;
  66. _previewWin.close();
  67. } else { mixin(S_TRACE);
  68. if (!rightGroup.isVisible()) return;
  69. setPreviewLData(false);
  70. }
  71. }
  72. }
  73. }
  74. private void setPreviewLData(bool visible, bool regWin = true) { mixin(S_TRACE);
  75. bool oVisible = rightGroup.isVisible();
  76. assert (_preview);
  77. rightGroup.setVisible(visible);
  78. int pvw;
  79. if (!visible) { mixin(S_TRACE);
  80. pvw = rightGroup.getSize().x;
  81. }
  82. int w = visible ? prop.looks.messageBounds.width : 0;
  83. int h = 0;
  84. rightGroupSize(w, h);
  85. if (getShell().isVisible()) getShell().setRedraw(false);
  86. scope (exit) {
  87. if (getShell().isVisible()) getShell().setRedraw(true);
  88. }
  89. if (regWin && oVisible != visible) { mixin(S_TRACE);
  90. auto ws = getShell().getSize();
  91. if (visible) { mixin(S_TRACE);
  92. pvw = rightGroup.getSize().x;
  93. }
  94. if (visible) { mixin(S_TRACE);
  95. ws.x += pvw;
  96. } else { mixin(S_TRACE);
  97. ws.x -= pvw;
  98. }
  99. getShell().setSize(ws);
  100. }
  101. }
  102. private class Dispose : DisposeListener {
  103. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  104. comm.refMenu.remove(&refMenu);
  105. comm.refUndoMax.remove(&refUndoMax);
  106. getShell().getDisplay().removeFilter(SWT.KeyDown, _kdFilter);
  107. if (_preview) { mixin(S_TRACE);
  108. if (type is CType.TALK_MESSAGE) { mixin(S_TRACE);
  109. prop.var.etc.showMessagePreview = _preview.isVisible();
  110. } else if (type is CType.TALK_DIALOG) { mixin(S_TRACE);
  111. prop.var.etc.showDialogPreview = _preview.isVisible();
  112. } else assert (0);
  113. }
  114. }
  115. }
  116. private class KeyDownFilter : Listener {
  117. this () { mixin(S_TRACE);
  118. refMenu(MenuID.Undo);
  119. refMenu(MenuID.Redo);
  120. }
  121. override void handleEvent(Event e) { mixin(S_TRACE);
  122. auto c = cast(Control) e.widget;
  123. if (!c || c.getShell() !is getShell()) return;
  124. if (!canHookKeyDown(c)) return;
  125. if (cast(Text) c) return;
  126. if (eqAcc(_undoAcc, e.keyCode, e.character, e.stateMask)) { mixin(S_TRACE);
  127. _undo.undo();
  128. e.doit = false;
  129. } else if (eqAcc(_redoAcc, e.keyCode, e.character, e.stateMask)) { mixin(S_TRACE);
  130. _undo.redo();
  131. e.doit = false;
  132. }
  133. }
  134. }
  135. protected bool canHookKeyDown(Control fc) { mixin(S_TRACE);
  136. return !_preview || !_preview.focusInValues;
  137. }
  138. private int _undoAcc;
  139. private int _redoAcc;
  140. private void refMenu(MenuID id) { mixin(S_TRACE);
  141. if (id == MenuID.Undo) _undoAcc = convertAccelerator(prop.buildMenu(MenuID.Undo));
  142. if (id == MenuID.Redo) _redoAcc = convertAccelerator(prop.buildMenu(MenuID.Redo));
  143. }
  144. private void refUndoMax() { mixin(S_TRACE);
  145. _undo.max = prop.var.etc.undoMaxEtc;
  146. }
  147. protected void initPreview(Composite area, WSize size) { mixin(S_TRACE);
  148. auto aComp = addition();
  149. aComp.setLayout(new GridLayout(1, true));
  150. auto prev = new Button(aComp, SWT.TOGGLE);
  151. prev.setText(prop.msgs.messagePreview);
  152. bool show;
  153. if (type is CType.TALK_MESSAGE) { mixin(S_TRACE);
  154. show = prop.var.etc.showMessagePreview;
  155. } else if (type is CType.TALK_DIALOG) { mixin(S_TRACE);
  156. show = prop.var.etc.showDialogPreview;
  157. } else assert (0);
  158. prev.setSelection(show);
  159. prev.addSelectionListener(new SelPrev);
  160. if (prop.var.etc.floatMessagePreview) { mixin(S_TRACE);
  161. _previewWin = new MsgPreviewWindow(getShell(), comm, prop, summ, prev, size);
  162. } else { mixin(S_TRACE);
  163. _preview = new MsgPreview(rightGroup, comm, prop, summ);
  164. rightGroup.setLayout(zeroGridLayout(1, false));
  165. _preview.setLayoutData(new GridData(GridData.FILL_BOTH));
  166. setPreviewLData(show, false);
  167. }
  168. refreshPreview();
  169. }
  170. this (Commons comm, Props prop, Shell shell, Summary summ, CType type, Content parent, Content evt, DSize size) { mixin(S_TRACE);
  171. super (comm, prop, shell, summ, type, parent, evt, true, size, false, !prop.var.etc.floatMessagePreview);
  172. _undo = new UndoManager(prop.var.etc.undoMaxEtc);
  173. }
  174. override
  175. protected void opened() { mixin(S_TRACE);
  176. if (!_previewWin) return;
  177. if (type is CType.TALK_MESSAGE) { mixin(S_TRACE);
  178. if (prop.var.etc.showMessagePreview) _previewWin.open();
  179. closeEvent ~= { mixin(S_TRACE);
  180. prop.var.etc.showMessagePreview = _previewWin.isVisible();
  181. };
  182. } else if (type is CType.TALK_DIALOG) { mixin(S_TRACE);
  183. if (prop.var.etc.showDialogPreview) _previewWin.open();
  184. closeEvent ~= { mixin(S_TRACE);
  185. prop.var.etc.showDialogPreview = _previewWin.isVisible();
  186. };
  187. } else assert (0);
  188. }
  189. protected override void setup(Composite area) { mixin(S_TRACE);
  190. area.addDisposeListener(new Dispose);
  191. _kdFilter = new KeyDownFilter;
  192. area.getDisplay().addFilter(SWT.KeyDown, _kdFilter);
  193. comm.refMenu.add(&refMenu);
  194. comm.refUndoMax.add(&refUndoMax);
  195. }
  196. void refreshPreview() { mixin(S_TRACE);
  197. if (!_previewWin && !_preview) return;
  198. auto s = wrapReturnCode(text);
  199. if (_previewWin) { mixin(S_TRACE);
  200. _previewWin.text(selectedTalker, imgPath, s);
  201. _previewWin.refresh();
  202. } else { mixin(S_TRACE);
  203. _preview.text(selectedTalker, imgPath, s);
  204. _preview.refresh();
  205. }
  206. }
  207. @property
  208. abstract string text();
  209. @property
  210. abstract Talker selectedTalker();
  211. @property
  212. abstract string imgPath();
  213. }
  214. /// ????????????????
  215. class SpeakDialog : AbstractMessageDialog {
  216. private:
  217. class APData {
  218. int selDlg;
  219. SDialog[] dlgs;
  220. }
  221. Object readAPD(Object old) { mixin(S_TRACE);
  222. auto o = new APData;
  223. o.selDlg = _dlgsL.getSelectionIndex();
  224. foreach (d; _dlgs) { mixin(S_TRACE);
  225. o.dlgs ~= new SDialog(d);
  226. }
  227. return o;
  228. }
  229. void writeAPD(Object o) { mixin(S_TRACE);
  230. bool oldIgnoreMod = ignoreMod;
  231. ignoreMod = true;
  232. scope (exit) ignoreMod = oldIgnoreMod;
  233. auto apd = cast(APData)o;
  234. assert (apd);
  235. foreach (i, d; apd.dlgs) { mixin(S_TRACE);
  236. _dlgs[i] = new SDialog(d);
  237. }
  238. refreshDlgList();
  239. _dlgsL.select(apd.selDlg);
  240. selectChanged();
  241. }
  242. class SUndo : Undo {
  243. private SDialog[] _dlgs;
  244. private int _selDlg;
  245. this () { mixin(S_TRACE);
  246. save();
  247. }
  248. private void save() { mixin(S_TRACE);
  249. _dlgs = [];
  250. foreach (d; this.outer._dlgs) { mixin(S_TRACE);
  251. _dlgs ~= new SDialog(d);
  252. }
  253. _selDlg = _dlgsL.getSelectionIndex();
  254. }
  255. private void impl() { mixin(S_TRACE);
  256. auto dlgs = _dlgs;
  257. int selDlg = _selDlg;
  258. save();
  259. this.outer._dlgs = [];
  260. foreach (dlg; dlgs) { mixin(S_TRACE);
  261. this.outer._dlgs ~= new SDialog(dlg);
  262. }
  263. refreshDlgList();
  264. _dlgsL.select(selDlg);
  265. selectChanged();
  266. }
  267. override void undo() {impl();}
  268. override void redo() {impl();}
  269. override void dispose() { mixin(S_TRACE);
  270. // Nothing
  271. }
  272. }
  273. void storeEdit() { mixin(S_TRACE);
  274. _undo ~= new SUndo;
  275. }
  276. void updateValue() { mixin(S_TRACE);
  277. int max = _initValue.getSelection();
  278. int min = max;
  279. foreach (cp; _couponView.coupons) { mixin(S_TRACE);
  280. if (cp.value < 0) { mixin(S_TRACE);
  281. min -= cp.value;
  282. } else { mixin(S_TRACE);
  283. max += cp.value;
  284. }
  285. }
  286. if (0 >= min) { mixin(S_TRACE);
  287. _couponView.toolTip = .tryFormat(prop.msgs.valuedTalkerMaxMinLess0, max, min);
  288. } else { mixin(S_TRACE);
  289. _couponView.toolTip = .tryFormat(prop.msgs.valuedTalkerMaxMin, max, min);
  290. }
  291. }
  292. override
  293. protected void refreshWarning() { mixin(S_TRACE);
  294. string[] ws;
  295. if (prop.targetVersion("1.50")) { mixin(S_TRACE);
  296. if (Talker.VALUED is selectedTalker) { mixin(S_TRACE);
  297. ws ~= prop.msgs.warningValuedTalker;
  298. }
  299. }
  300. warning = ws;
  301. }
  302. string _id;
  303. Combo _talkers;
  304. SDialog[] _dlgs;
  305. Table _dlgsL;
  306. Text _rCoupons;
  307. Combo _rCouponsList;
  308. FixedWidthText _text;
  309. TextMenuModify _textTM, _rCouponsTM;
  310. CouponView!(CVType.Valued) _couponView;
  311. Spinner _initValue;
  312. protected override bool canHookKeyDown(Control fc) { mixin(S_TRACE);
  313. return super.canHookKeyDown(fc) && !isDescendant(_couponView, fc);
  314. }
  315. void selectChanged() { mixin(S_TRACE);
  316. bool oldIgnoreMod = ignoreMod;
  317. ignoreMod = true;
  318. scope (exit) ignoreMod = oldIgnoreMod;
  319. auto dlg = _dlgs[_dlgsL.getSelectionIndex()];
  320. string rcs;
  321. foreach (rc; dlg.rCoupons) { mixin(S_TRACE);
  322. rcs ~= rc;
  323. rcs ~= '\n';
  324. }
  325. _rCoupons.setText(rcs);
  326. _text.setText(dlg.text);
  327. auto len = dlg.text.length;
  328. _text.widget.setSelection(len, len);
  329. refreshPreview();
  330. comm.refreshToolBar();
  331. }
  332. void createDialog(SDialog dlg) { mixin(S_TRACE);
  333. insertDialog(dlg, _dlgsL.getSelectionIndex());
  334. }
  335. void createDialog() { mixin(S_TRACE);
  336. createDialog(new SDialog);
  337. }
  338. void insertDialog(SDialog dlg, int index, bool store = true) { mixin(S_TRACE);
  339. if (store) storeEdit();
  340. if (index < 0) index = _dlgs.length;
  341. _dlgs = _dlgs[0 .. index] ~ dlg ~ _dlgs[index .. $];
  342. auto itm = new TableItem(_dlgsL, SWT.NONE, index);
  343. itm.setImage(prop.images.content(CType.TALK_DIALOG));
  344. _dlgsL.setSelection([itm]);
  345. _dlgsL.showSelection();
  346. selectChanged();
  347. applyEnabled();
  348. }
  349. void deleteDialog(int index, bool store = true) { mixin(S_TRACE);
  350. if (index < 0 || _dlgs.length <= 1) return;
  351. if (store) storeEdit();
  352. bool sel = _dlgsL.getSelectionIndex() == index;
  353. _dlgs = _dlgs[0 .. index] ~ _dlgs[index + 1 .. $];
  354. _dlgsL.remove(index);
  355. if (sel) { mixin(S_TRACE);
  356. _dlgsL.select(index < _dlgs.length ? index : _dlgs.length - 1);
  357. selectChanged();
  358. } else { mixin(S_TRACE);
  359. comm.refreshToolBar();
  360. }
  361. applyEnabled();
  362. }
  363. void deleteDialogSel() { mixin(S_TRACE);
  364. deleteDialog(_dlgsL.getSelectionIndex());
  365. }
  366. void overDialog() { mixin(S_TRACE);
  367. int index = _dlgsL.getSelectionIndex();
  368. if (index > 0) { mixin(S_TRACE);
  369. _dlgsL.select(index - 1);
  370. selectChanged();
  371. }
  372. }
  373. void underDialog() { mixin(S_TRACE);
  374. int index = _dlgsL.getSelectionIndex();
  375. if (index + 1 < _dlgs.length) { mixin(S_TRACE);
  376. _dlgsL.select(index + 1);
  377. selectChanged();
  378. }
  379. }
  380. void up() { mixin(S_TRACE);
  381. int index = _dlgsL.getSelectionIndex();
  382. if (index > 0) { mixin(S_TRACE);
  383. storeEdit();
  384. auto temp = _dlgs[index - 1];
  385. _dlgs[index - 1] = _dlgs[index];
  386. _dlgs[index] = temp;
  387. auto tempL = _dlgsL.getItem(index - 1).getText();
  388. _dlgsL.getItem(index - 1).setText(_dlgsL.getItem(index).getText());
  389. _dlgsL.getItem(index).setText(tempL);
  390. _dlgsL.select(index - 1);
  391. applyEnabled();
  392. comm.refreshToolBar();
  393. }
  394. }
  395. void down() { mixin(S_TRACE);
  396. int index = _dlgsL.getSelectionIndex();
  397. if (index + 1 < _dlgs.length) { mixin(S_TRACE);
  398. storeEdit();
  399. auto temp = _dlgs[index + 1];
  400. _dlgs[index + 1] = _dlgs[index];
  401. _dlgs[index] = temp;
  402. auto tempL = _dlgsL.getItem(index + 1).getText();
  403. _dlgsL.getItem(index + 1).setText(_dlgsL.getItem(index).getText());
  404. _dlgsL.getItem(index).setText(tempL);
  405. _dlgsL.select(index + 1);
  406. applyEnabled();
  407. comm.refreshToolBar();
  408. }
  409. }
  410. void copyToUpper() { mixin(S_TRACE);
  411. storeEdit();
  412. int index = _dlgsL.getSelectionIndex();
  413. string textL = _dlgsL.getItem(index).getText();
  414. string text = lastRet(wrapReturnCode(_text.getText()));
  415. for (int i = 0; i < index; i++) { mixin(S_TRACE);
  416. _dlgsL.getItem(i).setText(textL);
  417. _dlgs[i].text = text;
  418. }
  419. applyEnabled();
  420. comm.refreshToolBar();
  421. }
  422. void copyToLower() { mixin(S_TRACE);
  423. storeEdit();
  424. int index = _dlgsL.getSelectionIndex();
  425. string textL = _dlgsL.getItem(index).getText();
  426. string text = lastRet(wrapReturnCode(_text.getText()));
  427. for (int i = index + 1; i < _dlgs.length; i++) { mixin(S_TRACE);
  428. _dlgsL.getItem(i).setText(textL);
  429. _dlgs[i].text = text;
  430. }
  431. applyEnabled();
  432. comm.refreshToolBar();
  433. }
  434. void copyToDialogs() { mixin(S_TRACE);
  435. storeEdit();
  436. int index = _dlgsL.getSelectionIndex();
  437. string textL = _dlgsL.getItem(index).getText();
  438. string text = lastRet(wrapReturnCode(_text.getText()));
  439. foreach (i, dlg; _dlgs) { mixin(S_TRACE);
  440. if (i != index) { mixin(S_TRACE);
  441. _dlgsL.getItem(i).setText(textL);
  442. dlg.text = text;
  443. }
  444. }
  445. applyEnabled();
  446. comm.refreshToolBar();
  447. }
  448. void put(dchar put) { mixin(S_TRACE);
  449. putColor(_text, put);
  450. }
  451. void insert(string put) { mixin(S_TRACE);
  452. _text.insert(put);
  453. }
  454. void putText(SDialog dlg) { mixin(S_TRACE);
  455. dlg.text = lastRet(wrapReturnCode(_text.getText()));
  456. }
  457. void putRCoupons(SDialog dlg) { mixin(S_TRACE);
  458. string[] rcs;
  459. foreach (rc; splitLines!string(_rCoupons.getText())) { mixin(S_TRACE);
  460. if (rc.length > 0) { mixin(S_TRACE);
  461. rcs ~= rc;
  462. }
  463. }
  464. dlg.rCoupons = rcs;
  465. }
  466. void updateTalker() { mixin(S_TRACE);
  467. _couponView.enabled = (Talker.VALUED is selectedTalker);
  468. _initValue.setEnabled(_couponView.enabled);
  469. comm.refreshToolBar();
  470. }
  471. class SelL : SelectionAdapter {
  472. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  473. selectChanged();
  474. }
  475. }
  476. class SelectTalker : SelectionAdapter {
  477. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  478. refreshPreview();
  479. refreshWarning();
  480. updateTalker();
  481. }
  482. }
  483. private void refreshDlgList(int index) { mixin(S_TRACE);
  484. string text = wrapReturnCode(_dlgs[index].text).singleLine;
  485. // FIXME: ""?setText???Argument cannot be null
  486. if (text == "") text = " ";
  487. _dlgsL.getItem(index).setText(0, text);
  488. }
  489. class ModL : ModifyListener {
  490. override void modifyText(ModifyEvent e) { mixin(S_TRACE);
  491. if (_textTM && _rCouponsTM && !_textTM.inProc() && !_rCouponsTM.inProc()) { mixin(S_TRACE);
  492. putText(_dlgs[_dlgsL.getSelectionIndex()]);
  493. }
  494. refreshDlgList(_dlgsL.getSelectionIndex());
  495. refreshPreview();
  496. }
  497. }
  498. class ModRC : ModifyListener {
  499. override void modifyText(ModifyEvent e) { mixin(S_TRACE);
  500. if (_textTM && _rCouponsTM && !_textTM.inProc() && !_rCouponsTM.inProc()) { mixin(S_TRACE);
  501. putRCoupons(_dlgs[_dlgsL.getSelectionIndex()]);
  502. }
  503. }
  504. }
  505. @property
  506. SDialog selection() { mixin(S_TRACE);
  507. int index = _dlgsL.getSelectionIndex();
  508. return index >= 0 ? _dlgs[index] : null;
  509. }
  510. class DialogsTCPD : TCPD {
  511. void cut(SelectionEvent se) { mixin(S_TRACE);
  512. if (_dlgsL.getItemCount() > 1 && selection) { mixin(S_TRACE);
  513. copy(se);
  514. del(se);
  515. }
  516. }
  517. void copy(SelectionEvent se) { mixin(S_TRACE);
  518. auto d = selection;
  519. if (d) { mixin(S_TRACE);
  520. XMLtoCB(prop, comm.clipboard, d.toNode().text);
  521. comm.refreshToolBar();
  522. }
  523. }
  524. void paste(SelectionEvent se) { mixin(S_TRACE);
  525. auto xml = CBtoXML(comm.clipboard);
  526. if (xml) { mixin(S_TRACE);
  527. try { mixin(S_TRACE);
  528. auto node = XNode.parse(xml);
  529. if (node.name == SDialog.XML_NAME) { mixin(S_TRACE);
  530. auto ver = new XMLInfo(prop.sys, LATEST_VERSION);
  531. createDialog(SDialog.createFromNode(node, ver));
  532. }
  533. } catch (Exception e) {
  534. debugln(e);
  535. }
  536. }
  537. }
  538. void del(SelectionEvent se) {deleteDialogSel();}
  539. void clone(SelectionEvent se) { mixin(S_TRACE);
  540. comm.clipboard.memoryMode = true;
  541. scope (exit) comm.clipboard.memoryMode = false;
  542. copy(se);
  543. paste(se);
  544. }
  545. @property bool canDoTCPD() {return _dlgsL.isFocusControl();}
  546. @property bool canDoT() {return _dlgsL.getSelectionIndex() > 0;}
  547. @property bool canDoC() {return canDoT;}
  548. @property bool canDoP() {return CBisXML(comm.clipboard);}
  549. @property bool canDoD() {return canDoT;}
  550. @property bool canDoClone() {return canDoC;}
  551. }
  552. class DDropListener : DropTargetAdapter {
  553. override void dragEnter(DropTargetEvent e){ mixin(S_TRACE);
  554. e.detail = DND.DROP_MOVE;
  555. }
  556. override void dragOver(DropTargetEvent e){ mixin(S_TRACE);
  557. e.detail = DND.DROP_MOVE;
  558. }
  559. override void drop(DropTargetEvent e){ mixin(S_TRACE);
  560. if (!isXMLBytes(e.data)) return;
  561. e.detail = DND.DROP_NONE;
  562. string xml = bytesToXML(e.data);
  563. try { mixin(S_TRACE);
  564. auto node = XNode.parse(xml);
  565. if (node.name != SDialog.XML_NAME) return;
  566. storeEdit();
  567. scope p = (cast(DropTarget) e.getSource()).getControl().toControl(e.x, e.y);
  568. auto t = _dlgsL.getItem(p);
  569. int index = t ? _dlgsL.indexOf(t) : _dlgsL.getItemCount();
  570. auto ver = new XMLInfo(prop.sys, LATEST_VERSION);
  571. insertDialog(SDialog.createFromNode(node, ver), index, false);
  572. if (_id == node.attr("paneId", false)) { mixin(S_TRACE);
  573. e.detail = DND.DROP_MOVE;
  574. }
  575. } catch {}
  576. }
  577. }
  578. class DDragListener : DragSourceAdapter {
  579. private TableItem _itm;
  580. override void dragStart(DragSourceEvent e) { mixin(S_TRACE);
  581. e.doit = (cast(DragSource) e.getSource()).getControl().isFocusControl();
  582. }
  583. override void dragSetData(DragSourceEvent e){ mixin(S_TRACE);
  584. if (XMLBytesTransfer.getInstance().isSupportedType(e.dataType)) { mixin(S_TRACE);
  585. auto c = cast(Table) (cast(DragSource) e.getSource()).getControl();
  586. int index = c.getSelectionIndex();
  587. if (index >= 0) { mixin(S_TRACE);
  588. auto d = _dlgs[index];
  589. auto node = d.toNode();
  590. node.newAttr("paneId", _id);
  591. e.data = bytesFromXML(node.text);
  592. _itm = c.getItem(index);
  593. }
  594. }
  595. }
  596. override void dragFinished(DragSourceEvent e) { mixin(S_TRACE);
  597. if (e.detail == DND.DROP_MOVE) { mixin(S_TRACE);
  598. deleteDialog(_dlgsL.indexOf(_itm), false);
  599. }
  600. }
  601. }
  602. protected override void refSkin() { mixin(S_TRACE);
  603. _text.font = dwtData(prop.looks.messageFont(summ.legacy));
  604. }
  605. void refreshDlgList() { mixin(S_TRACE);
  606. bool oldIgnoreMod = ignoreMod;
  607. ignoreMod = true;
  608. scope (exit) ignoreMod = oldIgnoreMod;
  609. int selIndex = _dlgsL.getSelectionIndex();
  610. int topIndex = _dlgsL.getTopIndex();
  611. _dlgsL.removeAll();
  612. foreach (dlg; _dlgs) { mixin(S_TRACE);
  613. auto itm = new TableItem(_dlgsL, SWT.NONE);
  614. itm.setImage(prop.images.content(CType.TALK_DIALOG));
  615. string text = dlg.text.singleLine;
  616. // FIXME: ""?setText???Argument cannot be null
  617. itm.setText(text.length > 0 ? text : " ");
  618. }
  619. if (selIndex < 0 || _dlgs.length <= selIndex) { mixin(S_TRACE);
  620. _dlgsL.select(0);
  621. } else { mixin(S_TRACE);
  622. _dlgsL.select(selIndex);
  623. _dlgsL.setTopIndex(topIndex);
  624. }
  625. if (selIndex != _dlgsL.getSelectionIndex()) { mixin(S_TRACE);
  626. selectChanged();
  627. } else { mixin(S_TRACE);
  628. comm.refreshToolBar();
  629. }
  630. }
  631. class DisposeLeftSash : DisposeListener {
  632. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  633. auto sash = cast(SplitPane) e.widget;
  634. auto ws = sash.getWeights();
  635. prop.var.etc.talkLeftSashL = ws[0];
  636. prop.var.etc.talkLeftSashR = ws[1];
  637. }
  638. }
  639. class DisposeMainSash : DisposeListener {
  640. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  641. auto sash = cast(SplitPane) e.widget;
  642. auto ws = sash.getWeights();
  643. prop.var.etc.talkMainSashL = ws[0];
  644. prop.var.etc.talkMainSashR = ws[1];
  645. }
  646. }
  647. private class KeyDownFilter : Listener {
  648. this () { mixin(S_TRACE);
  649. refMenu(MenuID.OverDialog);
  650. refMenu(MenuID.UnderDialog);
  651. }
  652. override void handleEvent(Event e) { mixin(S_TRACE);
  653. auto c = cast(Control) e.widget;
  654. if (!c || c.getShell() !is getShell()) return;
  655. if (_dlgsL is c) return;
  656. if (eqAcc(_overAcc, e.keyCode, e.character, e.stateMask)) { mixin(S_TRACE);
  657. overDialog();
  658. e.doit = false;
  659. } else if (eqAcc(_underAcc, e.keyCode, e.character, e.stateMask)) { mixin(S_TRACE);
  660. underDialog();
  661. e.doit = false;
  662. }
  663. }
  664. }
  665. private int _overAcc;
  666. private int _underAcc;
  667. private void refMenu(MenuID id) { mixin(S_TRACE);
  668. if (id == MenuID.OverDialog) _overAcc = convertAccelerator(prop.buildMenu(MenuID.OverDialog));
  669. if (id == MenuID.UnderDialog) _underAcc = convertAccelerator(prop.buildMenu(MenuID.UnderDialog));
  670. }
  671. public:
  672. this (Commons comm, Props prop, Shell shell, Summary summ, Content parent, Content evt) { mixin(S_TRACE);
  673. _id = format("%08X", &this) ~ "-" ~ to!(string)(Clock.currTime());
  674. super(comm, prop, shell, summ, CType.TALK_DIALOG, parent, evt, prop.var.speakDlg);
  675. }
  676. override
  677. bool openCWXPath(string path, bool shellActivate) { mixin(S_TRACE);
  678. auto cate = cpcategory(path);
  679. if ("dialog" == cate) { mixin(S_TRACE);
  680. auto index = cpindex(path);
  681. if (index >= _dlgsL.getItemCount()) return false;
  682. _dlgsL.select(index);
  683. selectChanged();
  684. .forceFocus(_dlgsL, shellActivate);
  685. path = cpbottom(path);
  686. return cpempty(path);
  687. }
  688. return super.openCWXPath(path, shellActivate);
  689. }
  690. @property
  691. override
  692. string text() { mixin(S_TRACE);
  693. return wrapReturnCode(_text.getText());
  694. }
  695. @property
  696. override
  697. Talker selectedTalker() { mixin(S_TRACE);
  698. switch (_talkers.getSelectionIndex()) {
  699. case 0: return Talker.SELECTED;
  700. case 1: return Talker.UNSELECTED;
  701. case 2: return Talker.RANDOM;
  702. case 3: return Talker.VALUED;
  703. default: assert (0);
  704. }
  705. }
  706. @property
  707. override
  708. string imgPath() { mixin(S_TRACE);
  709. return "";
  710. }
  711. protected:
  712. override void setup(Composite area) { mixin(S_TRACE);
  713. super.setup(area);
  714. area.setLayout(windowGridLayout(1, true));
  715. auto sash = new SplitPane(area, SWT.HORIZONTAL);
  716. sash.setLayoutData(new GridData(GridData.FILL_BOTH));
  717. auto left = new Composite(sash, SWT.NONE);
  718. left.setLayout(zeroMarginGridLayout(1, true));
  719. { mixin(S_TRACE);
  720. auto grp = new Group(left, SWT.NONE);
  721. grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  722. grp.setText(prop.msgs.talker);
  723. grp.setLayout(new GridLayout(1, true));
  724. _talkers = new Combo(grp, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.BORDER);
  725. mod(_talkers);
  726. _talkers.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  727. _talkers.add(prop.msgs.talkerName(Talker.SELECTED));
  728. _talkers.add(prop.msgs.talkerName(Talker.UNSELECTED));
  729. _talkers.add(prop.msgs.talkerName(Talker.RANDOM));
  730. _talkers.add(prop.msgs.talkerName(Talker.VALUED));
  731. _talkers.addSelectionListener(new SelectTalker);
  732. }
  733. auto leftSash = new SplitPane(left, SWT.VERTICAL);
  734. leftSash.setLayoutData(new GridData(GridData.FILL_BOTH));
  735. auto skin = comm.skin;
  736. { mixin(S_TRACE);
  737. auto grp = new Group(leftSash, SWT.NONE);
  738. grp.setText(prop.msgs.toneCoupons);
  739. grp.setLayout(new GridLayout(1, true));
  740. Control tp;
  741. if (evt) { mixin(S_TRACE);
  742. tp = createTalkerPane2(grp, comm, prop, summ, evt.dialogs[0].rCoupons, _rCoupons, _rCouponsList);
  743. } else { mixin(S_TRACE);
  744. tp = createTalkerPane2(grp, comm, prop, summ, [], _rCoupons, _rCouponsList);
  745. }
  746. mod(_rCoupons);
  747. _rCoupons.addModifyListener(new ModRC);
  748. tp.setLayoutData(new GridData(GridData.FILL_BOTH));
  749. }
  750. { mixin(S_TRACE);
  751. auto grp = new Group(leftSash, SWT.NONE);
  752. grp.setText(prop.msgs.valued);
  753. grp.setLayout(new GridLayout(2, false));
  754. auto lbl = new Label(grp, SWT.NONE);
  755. lbl.setText(prop.msgs.initValue);
  756. _initValue = new Spinner(grp, SWT.BORDER);
  757. initSpinner(_initValue);
  758. mod(_initValue);
  759. _initValue.setMinimum(cast(int) prop.var.etc.couponValueMax * -1);
  760. _initValue.setMaximum(prop.var.etc.couponValueMax);
  761. _initValue.setSelection(1);
  762. _initValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  763. .listener(_initValue, SWT.Selection, &updateValue);
  764. _couponView = new CouponView!(CVType.Valued)(comm, summ, grp, SWT.NONE, &catchMod);
  765. mod(_couponView);
  766. auto gd = new GridData(GridData.FILL_BOTH);
  767. gd.horizontalSpan = 2;
  768. _couponView.setLayoutData(gd);
  769. _couponView.modEvent ~= &updateValue;
  770. }
  771. auto right = new Composite(sash, SWT.NONE);
  772. right.setLayout(zeroMarginGridLayout(2, false));
  773. { mixin(S_TRACE);
  774. _dlgsL = new Table(right, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL);
  775. new FullTableColumn(_dlgsL, SWT.NONE);
  776. auto gd = new GridData(GridData.FILL_BOTH);
  777. gd.widthHint = 0;
  778. gd.heightHint = 0;
  779. _dlgsL.setLayoutData(gd);
  780. _dlgsL.addSelectionListener(new SelL);
  781. auto drag = new DragSource(_dlgsL, DND.DROP_MOVE | DND.DROP_COPY);
  782. drag.setTransfer([XMLBytesTransfer.getInstance()]);
  783. drag.addDragListener(new DDragListener);
  784. auto drop = new DropTarget(_dlgsL, DND.DROP_DEFAULT | DND.DROP_MOVE | DND.DROP_COPY);
  785. drop.setTransfer([XMLBytesTransfer.getInstance()]);
  786. drop.addDropListener(new DDropListener);
  787. auto menu = new Menu(_dlgsL);
  788. createMenuItem(comm, menu, MenuID.Undo, {_undo.undo();}, &_undo.canUndo);
  789. createMenuItem(comm, menu, MenuID.Redo, {_undo.redo();}, &_undo.canRedo);
  790. new MenuItem(menu, SWT.SEPARATOR);
  791. createMenuItem(comm, menu, MenuID.Up, &up, () => _dlgsL.getSelectionIndex() != -1 && 0 < _dlgsL.getSelectionIndex());
  792. createMenuItem(comm, menu, MenuID.Down, &down, () => _dlgsL.getSelectionIndex() != -1 && _dlgsL.getSelectionIndex() + 1 < _dlgsL.getItemCount());
  793. new MenuItem(menu, SWT.SEPARATOR);
  794. createMenuItem(comm, menu, MenuID.OverDialog, &overDialog, () => _dlgsL.getSelectionIndex() != -1 && 0 < _dlgsL.getSelectionIndex());
  795. createMenuItem(comm, menu, MenuID.UnderDialog, &underDialog, () => _dlgsL.getSelectionIndex() != -1 && _dlgsL.getSelectionIndex() + 1 < _dlgsL.getItemCount());
  796. new MenuItem(menu, SWT.SEPARATOR);
  797. appendMenuTCPD(comm, menu, new DialogsTCPD, true, true, true, true, true);
  798. _dlgsL.setMenu(menu);
  799. auto bar = new ToolBar(right, SWT.FLAT | SWT.VERTICAL);
  800. comm.put(bar);
  801. bar.setLayoutData(new GridData(GridData.FILL_VERTICAL));
  802. bar.addListener(SWT.Traverse, new class Listener {
  803. override void handleEvent(Event e) {e.doit = true;}
  804. });
  805. bar.addListener(SWT.KeyDown, new class Listener {
  806. override void handleEvent(Event e) {e.doit = true;}
  807. });
  808. createToolItem2(comm, bar, prop.msgs.createDialog, prop.images.createDialog, &createDialog, null);
  809. createToolItem2(comm, bar, prop.msgs.deleteDialog, prop.images.deleteDialog, &deleteDialogSel, () => _dlgsL.getItemCount() > 1 && _dlgsL.getSelectionIndex() != -1);
  810. new ToolItem(bar, SWT.SEPARATOR);
  811. createToolItem(comm, bar, MenuID.Up, &up, () => _dlgsL.getSelectionIndex() != -1 && 0 < _dlgsL.getSelectionIndex());
  812. createToolItem(comm, bar, MenuID.Down, &down, () => _dlgsL.getSelectionIndex() != -1 && _dlgsL.getSelectionIndex() + 1 < _dlgsL.getItemCount());
  813. new ToolItem(bar, SWT.SEPARATOR);
  814. createToolItem2(comm, bar, prop.msgs.copyToDialogs, prop.images.copyToDialogs, &copyToDialogs, () => _dlgsL.getSelectionIndex() != -1 && _dlgsL.getItemCount() > 1);
  815. createToolItem2(comm, bar, prop.msgs.copyToUpper, prop.images.copyToUpper, &copyToUpper, () => _dlgsL.getSelectionIndex() != -1 && 0 < _dlgsL.getSelectionIndex());
  816. createToolItem2(comm, bar, prop.msgs.copyToLower, prop.images.copyToLower, &copyToLower, () => _dlgsL.getSelectionIndex() != -1 && _dlgsL.getSelectionIndex() + 1 < _dlgsL.getItemCount());
  817. }
  818. { mixin(S_TRACE);
  819. auto msgComp = new Composite(right, SWT.NONE);
  820. auto gd = new GridData(GridData.FILL_HORIZONTAL);
  821. gd.horizontalSpan = 2;
  822. msgComp.setLayoutData(gd);
  823. msgComp.setLayout(new CenterLayout(SWT.HORIZONTAL | SWT.VERTICAL, 0));
  824. _text = createMessagePane(comm, prop, true, msgComp, summ);
  825. mod(_text.widget);
  826. _text.widget.setLayoutData(_text.computeTextBaseSize(prop.looks.messageLine));
  827. _text.widget.addModifyListener(new ModL);
  828. }
  829. { mixin(S_TRACE);
  830. auto bar = createSCharBar(comm, area, &insert, &put, prop, skin);
  831. bar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  832. }
  833. { mixin(S_TRACE);
  834. auto bar = createSkinSCharBar(comm, area, &insert, prop, skin);
  835. bar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  836. }
  837. { mixin(S_TRACE);
  838. auto bar = createFlagStepBar(area, &insert, comm, prop);
  839. bar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  840. }
  841. leftSash.setWeights([prop.var.etc.talkLeftSashL, prop.var.etc.talkLeftSashR]);
  842. leftSash.addDisposeListener(new DisposeLeftSash);
  843. sash.setWeights([prop.var.etc.talkMainSashL, prop.var.etc.talkMainSashR]);
  844. sash.addDisposeListener(new DisposeMainSash);
  845. auto kdFilter = new KeyDownFilter;
  846. area.getDisplay().addFilter(SWT.KeyDown, kdFilter);
  847. comm.refMenu.add(&refMenu);
  848. .listener(area, SWT.Dispose, { mixin(S_TRACE);
  849. area.getDisplay().removeFilter(SWT.KeyDown, kdFilter);
  850. comm.refMenu.remove(&refMenu);
  851. });
  852. ignoreMod = true;
  853. scope (exit) ignoreMod = false;
  854. if (evt) { mixin(S_TRACE);
  855. switch (evt.talkerNC) {
  856. case Talker.SELECTED:
  857. _talkers.select(0);
  858. break;
  859. case Talker.UNSELECTED:
  860. _talkers.select(1);
  861. break;
  862. case Talker.RANDOM:
  863. _talkers.select(2);
  864. break;
  865. case Talker.VALUED:
  866. _talkers.select(3);
  867. break;
  868. default:
  869. _talkers.select(0);
  870. }
  871. foreach (dlg; evt.dialogs) { mixin(S_TRACE);
  872. _dlgs ~= new SDialog(dlg.text, dlg.rCoupons);
  873. }
  874. _couponView.coupons = evt.coupons;
  875. _initValue.setSelection(evt.initValue);
  876. } else { mixin(S_TRACE);
  877. _talkers.select(0);
  878. _dlgs = [new SDialog];
  879. }
  880. refreshDlgList();
  881. _textTM = createTextMenu!Text(comm, prop, _rCoupons, &catchMod, _undo, TMAppendData(&readAPD, &writeAPD));
  882. _rCouponsTM = createTextMenu!Text(comm, prop, _text.widget, &catchMod, _undo, TMAppendData(&readAPD, &writeAPD));
  883. initPreview(area, prop.var.dlgPrev);
  884. updateValue();
  885. updateTalker();
  886. refreshWarning();
  887. }
  888. override bool apply() { mixin(S_TRACE);
  889. if (!evt) evt = new Content(CType.TALK_DIALOG, "");
  890. evt.dialogs = _dlgs;
  891. evt.talkerNC = selectedTalker;
  892. if (Talker.VALUED is evt.talkerNC) { mixin(S_TRACE);
  893. evt.coupons = _couponView.coupons;
  894. evt.initValue = _initValue.getSelection();
  895. } else { mixin(S_TRACE);
  896. evt.coupons = [];
  897. evt.initValue = 0;
  898. }
  899. comm.refCoupons.call();
  900. return true;
  901. }
  902. }
  903. /// ???????????????????
  904. class MessageDialog : AbstractMessageDialog {
  905. private:
  906. CTabFolder _tabf;
  907. Composite _msgCompA, _msgCompB;
  908. FixedWidthText _text;
  909. ImageSelect!(MtType.CARD, Combo) _msel;
  910. override
  911. protected void refreshWarning() { mixin(S_TRACE);
  912. string[] ws;
  913. ws ~= _msel.warnings;
  914. warning = ws;
  915. }
  916. void tabChanged() { mixin(S_TRACE);
  917. switch (_tabf.getSelectionIndex()) {
  918. case 0:
  919. _text.num = prop.looks.messageImageLen;
  920. _text.widget.setParent(_msgCompA);
  921. break;
  922. case 1:
  923. _text.num = prop.looks.messageLen;
  924. _text.widget.setParent(_msgCompB);
  925. break;
  926. default: return;
  927. }
  928. _text.widget.setLayoutData(_text.computeTextBaseSize(prop.looks.messageLine));
  929. _text.widget.getParent().layout();
  930. if (0 == _tabf.getSelectionIndex()) { mixin(S_TRACE);
  931. _text.widget.getParent().getParent().layout();
  932. }
  933. refreshPreview();
  934. }
  935. class SL : SelectionAdapter {
  936. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  937. tabChanged();
  938. }
  939. }
  940. class ModText : ModifyListener {
  941. override void modifyText(ModifyEvent e) { mixin(S_TRACE);
  942. refreshPreview();
  943. }
  944. }
  945. void put(dchar put) { mixin(S_TRACE);
  946. putColor(_text, put);
  947. }
  948. void insert(string put) { mixin(S_TRACE);
  949. _text.insert(put);
  950. }
  951. protected override void refSkin() { mixin(S_TRACE);
  952. _text.font = dwtData(prop.looks.messageFont(summ.legacy));
  953. }
  954. public:
  955. this (Commons comm, Props prop, Shell shell, Summary summ, Content parent, Content evt) { mixin(S_TRACE);
  956. super(comm, prop, shell, summ, CType.TALK_MESSAGE, parent, evt, prop.var.msgDlg);
  957. }
  958. void selectedTalkerParam(out Talker talker, out string imgPath) { mixin(S_TRACE);
  959. imgPath = "";
  960. switch (_tabf.getSelectionIndex()) {
  961. case 0:
  962. switch (_msel.dirsCombo.getSelectionIndex()) {
  963. case 0:
  964. talker = Talker.SELECTED;
  965. break;
  966. case 1:
  967. talker = Talker.UNSELECTED;
  968. break;
  969. case 2:
  970. talker = Talker.RANDOM;
  971. break;
  972. case 3:
  973. talker = Talker.CARD;
  974. break;
  975. default:
  976. talker = Talker.IMAGE;
  977. imgPath = _msel.image;
  978. }
  979. break;
  980. case 1:
  981. talker = Talker.NARRATION;
  982. break;
  983. default: assert (0);
  984. }
  985. }
  986. @property
  987. override Talker selectedTalker() { mixin(S_TRACE);
  988. Talker talker;
  989. string imgPath;
  990. selectedTalkerParam(talker, imgPath);
  991. return talker;
  992. }
  993. @property
  994. override string imgPath() { mixin(S_TRACE);
  995. Talker talker;
  996. string imgPath;
  997. selectedTalkerParam(talker, imgPath);
  998. return imgPath;
  999. }
  1000. @property
  1001. override string text() { mixin(S_TRACE);
  1002. return wrapReturnCode(_text.getText());
  1003. }
  1004. protected:
  1005. override void setup(Composite area) { mixin(S_TRACE);
  1006. super.setup(area);
  1007. area.setLayout(new GridLayout(1, true));
  1008. _tabf = new CTabFolder(area, SWT.BORDER);
  1009. mod(_tabf);
  1010. _tabf.setLayoutData(new GridData(GridData.FILL_BOTH));
  1011. auto skin = comm.skin;
  1012. { mixin(S_TRACE);
  1013. auto comp = new Composite(_tabf, SWT.NONE);
  1014. comp.setLayout(new GridLayout(2, false));
  1015. Control tp;
  1016. if (evt) { mixin(S_TRACE);
  1017. tp = createTalkerPane(comp, comm, prop, summ, evt.talkerC, evt.cardPath, _msel);
  1018. } else { mixin(S_TRACE);
  1019. tp = createTalkerPane(comp, comm, prop, summ, Talker.SELECTED, "", _msel);
  1020. }
  1021. mod(_msel);
  1022. _msel.modEvent ~= &refreshWarning;
  1023. _msel.cardMode = CardMode.Message;
  1024. tp.setLayoutData(new GridData(GridData.FILL_BOTH));
  1025. _msgCompA = new Composite(comp, SWT.NONE);
  1026. _msgCompA.setLayoutData(new GridData(GridData.FILL_VERTICAL));
  1027. _msgCompA.setLayout(new CenterLayout(SWT.HORIZONTAL | SWT.VERTICAL, 0));
  1028. _text = createMessagePane(comm, prop, true, _msgCompA, summ);
  1029. mod(_text.widget);
  1030. _text.widget.addModifyListener(new ModText);
  1031. createTextMenu!Text(comm, prop, _text.widget, &catchMod, _undo);
  1032. auto tab = new CTabItem(_tabf, SWT.NONE);
  1033. tab.setText(prop.msgs.imageMessage);
  1034. tab.setControl(comp);
  1035. }
  1036. { mixin(S_TRACE);
  1037. _msgCompB = new Composite(_tabf, SWT.NONE);
  1038. _msgCompB.setLayout(new CenterLayout);
  1039. auto tab = new CTabItem(_tabf, SWT.NONE);
  1040. tab.setText(prop.msgs.noImageMessage);
  1041. tab.setControl(_msgCompB);
  1042. }
  1043. { mixin(S_TRACE);
  1044. auto bar = createSCharBar(comm, area, &insert, &put, prop, skin);
  1045. bar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  1046. }
  1047. { mixin(S_TRACE);
  1048. auto bar = createSkinSCharBar(comm, area, &insert, prop, skin);
  1049. bar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  1050. }
  1051. { mixin(S_TRACE);
  1052. auto bar = createFlagStepBar(area, &insert, comm, prop);
  1053. bar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  1054. }
  1055. _tabf.addSelectionListener(new SL);
  1056. ignoreMod = true;
  1057. scope (exit) ignoreMod = false;
  1058. _tabf.setSelection(0);
  1059. if (evt) { mixin(S_TRACE);
  1060. _text.setText(evt.text);
  1061. if (evt.talkerC == Talker.NARRATION) { mixin(S_TRACE);
  1062. _tabf.setSelection(1);
  1063. }
  1064. } else { mixin(S_TRACE);
  1065. _tabf.setSelection(1);
  1066. }
  1067. tabChanged();
  1068. initPreview(area, prop.var.msgPrev);
  1069. _msel.modEvent ~= &refreshPreview;
  1070. _msel.updateImageEvent ~= &refreshPreview;
  1071. }
  1072. override bool apply() { mixin(S_TRACE);
  1073. string text;
  1074. string path = "";
  1075. Talker talker;
  1076. selectedTalkerParam(talker, path);
  1077. text = lastRet(wrapReturnCode(_text.getText()));
  1078. if (!evt) evt = new Content(CType.TALK_MESSAGE, "");
  1079. evt.text = text;
  1080. evt.talkerC = talker;
  1081. evt.cardPath = path;
  1082. return true;
  1083. }
  1084. }
  1085. private Composite createTalkerPane2(Composite parent, Commons comm, Props prop, Summary summ,
  1086. string[] coupons, out Text couponList, out Combo couponCombo) { mixin(S_TRACE);
  1087. auto comp = new Composite(parent, SWT.NONE);
  1088. comp.setLayout(zeroMarginGridLayout(2, false));
  1089. couponCombo = createCouponCombo(comm, summ, comp, null, CouponComboType.Talker, "");
  1090. auto push = new Button(comp, SWT.PUSH);
  1091. auto skin = comm.skin;
  1092. { mixin(S_TRACE);
  1093. auto gd = new GridData(GridData.FILL_HORIZONTAL);
  1094. gd.widthHint = prop.var.etc.talkersWidth;
  1095. couponCombo.setLayoutData(gd);
  1096. push.setToolTipText(prop.msgs.setTalkerCoupon);
  1097. push.setImage(prop.images.setTalkerCoupon);
  1098. }
  1099. { mixin(S_TRACE);
  1100. couponList = new Text(comp, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
  1101. auto gd = new GridData(GridData.FILL_BOTH);
  1102. gd.horizontalSpan = 2;
  1103. couponList.setLayoutData(gd);
  1104. string buf;
  1105. foreach (coupon; coupons) { mixin(S_TRACE);
  1106. buf ~= coupon ~ "\n";
  1107. }
  1108. couponList.setText(buf);
  1109. push.addSelectionListener(new class SelectionAdapter {
  1110. private Combo _combo;
  1111. private Text _list;
  1112. this() { mixin(S_TRACE);
  1113. _combo = couponCombo;
  1114. _list = couponList;
  1115. }
  1116. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  1117. if (_combo.getText().length > 0) { mixin(S_TRACE);
  1118. _list.setSelection(_list.getText().length, _list.getText().length);
  1119. string[] lines = splitLines!string(_list.getText());
  1120. if (lines.length > 0 && lines[$ - 1].length > 0) { mixin(S_TRACE);
  1121. _list.insert("\n");
  1122. }
  1123. _list.insert(_combo.getText() ~ "\n");
  1124. }
  1125. }
  1126. });
  1127. }
  1128. return comp;
  1129. }
  1130. private Composite createTalkerPane
  1131. (Composite parent, Commons comm, Props prop, Summary summ, Talker talker, string path,
  1132. out ImageSelect!(MtType.CARD, Combo) msel) { mixin(S_TRACE);
  1133. auto comp = new Composite(parent, SWT.NONE);
  1134. { mixin(S_TRACE);
  1135. comp.setLayout(zeroMarginGridLayout(1, true));
  1136. }
  1137. auto selected = prop.images.talker(Talker.SELECTED).getImageData();
  1138. auto unselected = prop.images.talker(Talker.UNSELECTED).getImageData();
  1139. auto random = prop.images.talker(Talker.RANDOM).getImageData();
  1140. ImageData createDefImage(size_t index) { mixin(S_TRACE);
  1141. switch (index) {
  1142. case 0:
  1143. // ???
  1144. return selected;
  1145. case 1:
  1146. // ?????
  1147. return unselected;
  1148. case 2:
  1149. // ????
  1150. return random;
  1151. case 3:
  1152. // ???
  1153. return menuCard(comm.skin);
  1154. default: assert (0);
  1155. }
  1156. }
  1157. string[] defs = [
  1158. prop.msgs.talkerName(Talker.SELECTED),
  1159. prop.msgs.talkerName(Talker.UNSELECTED),
  1160. prop.msgs.talkerName(Talker.RANDOM),
  1161. prop.msgs.talkerName(Talker.CARD)
  1162. ];
  1163. auto s = prop.looks.cardSize;
  1164. msel = new ImageSelect!(MtType.CARD, Combo)(comp, SWT.NONE, comm, prop, summ, s.width, s.height,
  1165. false, false, () => "", null, defs, &createDefImage);
  1166. auto gd = new GridData(GridData.FILL_BOTH);
  1167. msel.widget.setLayoutData(gd);
  1168. msel.image = path;
  1169. if (msel.image.length == 0) { mixin(S_TRACE);
  1170. switch (talker) {
  1171. case Talker.SELECTED:
  1172. msel.dirsCombo.select(0);
  1173. break;
  1174. case Talker.UNSELECTED:
  1175. msel.dirsCombo.select(1);
  1176. break;
  1177. case Talker.RANDOM:
  1178. msel.dirsCombo.select(2);
  1179. break;
  1180. case Talker.CARD:
  1181. msel.dirsCombo.select(3);
  1182. break;
  1183. default:
  1184. msel.dirsCombo.select(0);
  1185. }
  1186. }
  1187. return comp;
  1188. }
  1189. private class DisposeText : DisposeListener {
  1190. private Color _back, _fore;
  1191. this (Color back, Color fore) { mixin(S_TRACE);
  1192. _back = back;
  1193. _fore = fore;
  1194. }
  1195. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  1196. _back.dispose();
  1197. _fore.dispose();
  1198. }
  1199. }
  1200. private FixedWidthText createMessagePane(Commons comm, Props prop, bool image, Composite parent, Summary summ) { mixin(S_TRACE);
  1201. int len = image ? prop.looks.messageImageLen : prop.looks.messageLen;
  1202. auto r = new FixedWidthText(dwtData(prop.looks.messageFont(summ.legacy)), len, parent, SWT.BORDER, true);
  1203. auto d = r.widget.getDisplay();
  1204. auto back = new Color(d, new RGB(prop.var.etc.msgBackR, prop.var.etc.msgBackG, prop.var.etc.msgBackB));
  1205. auto fore = new Color(d, new RGB(prop.var.etc.msgForeR, prop.var.etc.msgForeG, prop.var.etc.msgForeB));
  1206. r.widget.setBackground(back);
  1207. r.widget.setForeground(fore);
  1208. r.widget.addDisposeListener(new DisposeText(back, fore));
  1209. return r;
  1210. }
  1211. private class PutC {
  1212. private void delegate(string) _insert;
  1213. private string _put;
  1214. this(void delegate(string) insert, string put) { mixin(S_TRACE);
  1215. _insert = insert;
  1216. _put = put;
  1217. }
  1218. void put() { mixin(S_TRACE);
  1219. _insert(_put);
  1220. }
  1221. }
  1222. private class PutColor {
  1223. private void delegate(dchar) _put;
  1224. private dchar _color;
  1225. this(void delegate(dchar) put, dchar color) { mixin(S_TRACE);
  1226. _put = put;
  1227. _color = color;
  1228. }
  1229. void put() { mixin(S_TRACE);
  1230. _put(_color);
  1231. }
  1232. }
  1233. private ToolBar createSCharBar(Commons comm, Composite parent,
  1234. void delegate(string) insert, void delegate(dchar) putColor, Props prop, Skin skin) { mixin(S_TRACE);
  1235. auto bar = new ToolBar(parent, SWT.FLAT);
  1236. comm.put(bar);
  1237. bar.addListener(SWT.Traverse, new class Listener {
  1238. override void handleEvent(Event e) {e.doit = true;}
  1239. });
  1240. bar.addListener(SWT.KeyDown, new class Listener {
  1241. override void handleEvent(Event e) {e.doit = true;}
  1242. });
  1243. foreach (c; [
  1244. 'W', 'R', 'B', 'G', 'Y'
  1245. ] ~ [
  1246. 'O', 'P', 'L', 'D' // CardWirth 1.50
  1247. ]) { mixin(S_TRACE);
  1248. string t;
  1249. final switch (c) {
  1250. case 'W': t = prop.msgs.colorW; break;
  1251. case 'R': t = prop.msgs.colorR; break;
  1252. case 'B': t = prop.msgs.colorB; break;
  1253. case 'G': t = prop.msgs.colorG; break;
  1254. case 'Y': t = prop.msgs.colorY; break;
  1255. case 'O': t = prop.msgs.colorO; break; // CardWirth 1.50
  1256. case 'P': t = prop.msgs.colorP; break; // CardWirth 1.50
  1257. case 'L': t = prop.msgs.colorL; break; // CardWirth 1.50
  1258. case 'D': t = prop.msgs.colorD; break; // CardWirth 1.50
  1259. }
  1260. createToolItem2(comm, bar, t, prop.images.color(c), &(new PutColor(putColor, c)).put, null);
  1261. }
  1262. new ToolItem(bar, SWT.SEPARATOR);
  1263. createToolItem2(comm, bar, prop.msgs.scRef, prop.images.scRef, &(new PutC(insert, "#I")).put, null);
  1264. createToolItem2(comm, bar, prop.msgs.scTalkerName(Talker.SELECTED), prop.images.scTalker(Talker.SELECTED),
  1265. &(new PutC(insert, "#M")).put, null);
  1266. createToolItem2(comm, bar, prop.msgs.scTalkerName(Talker.UNSELECTED), prop.images.scTalker(Talker.UNSELECTED),
  1267. &(new PutC(insert, "#U")).put, null);
  1268. createToolItem2(comm, bar, prop.msgs.scTalkerName(Talker.RANDOM), prop.images.scTalker(Talker.RANDOM),
  1269. &(new PutC(insert, "#R")).put, null);
  1270. createToolItem2(comm, bar, prop.msgs.scTalkerName(Talker.CARD), prop.images.scTalker(Talker.CARD),
  1271. &(new PutC(insert, "#C")).put, null);
  1272. createToolItem2(comm, bar, prop.msgs.scTeam, prop.images.scTeam, &(new PutC(insert, "#T")).put, null);
  1273. createToolItem2(comm, bar, prop.msgs.scYado, prop.images.scYado, &(new PutC(insert, "#Y")).put, null);
  1274. return bar;
  1275. }
  1276. private ToolBar createSkinSCharBar(Commons comm, Composite parent, void delegate(string) insert, Props prop, Skin skin) { mixin(S_TRACE);
  1277. auto bar = new ToolBar(parent, SWT.FLAT);
  1278. comm.put(bar);
  1279. bar.addListener(SWT.Traverse, new class Listener {
  1280. override void handleEvent(Event e) {e.doit = true;}
  1281. });
  1282. bar.addListener(SWT.KeyDown, new class Listener {
  1283. override void handleEvent(Event e) {e.doit = true;}
  1284. });
  1285. Image[] imgs;
  1286. foreach (spc; skin.spChars.keys) { mixin(S_TRACE);
  1287. auto img = new Image(Display.getCurrent(), spChar(skin, spc));
  1288. string name = toUTF8("#"d ~ spc);
  1289. auto scp = new PutC(insert, name);
  1290. createToolItem2(comm, bar, name, img, &scp.put, null);
  1291. imgs ~= img;
  1292. }
  1293. bar.addDisposeListener(new class DisposeListener {
  1294. private Image[] _imgs;
  1295. this() {_imgs = imgs;}
  1296. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  1297. foreach (img; _imgs) { mixin(S_TRACE);
  1298. img.dispose();
  1299. }
  1300. }
  1301. });
  1302. return bar;
  1303. }
  1304. private Composite createFlagStepBar(Composite parent, void delegate(string) insert, Commons comm, Props prop) { mixin(S_TRACE);
  1305. auto bar = new Composite(parent, SWT.NONE);
  1306. bar.setLayout(zeroMarginGridLayout(2, true));
  1307. void create(out Combo list, out Button put, string puts, Image image, string lc) { mixin(S_TRACE);
  1308. auto comp = new Composite(bar, SWT.NONE);
  1309. comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  1310. comp.setLayout(zeroMarginGridLayout(2, false));
  1311. list = new Combo(comp, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.BORDER);
  1312. list.setVisibleItemCount(prop.var.etc.comboVisibleItemCount);
  1313. list.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  1314. put = new Button(comp, SWT.PUSH);
  1315. put.setToolTipText(puts);
  1316. put.setImage(image);
  1317. put.addSelectionListener(new class SelectionAdapter {
  1318. override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
  1319. insert(lc ~ list.getText() ~ lc);
  1320. }
  1321. });
  1322. }
  1323. Combo flags, steps;
  1324. Button putFlag, putStep;
  1325. create(flags, putFlag, prop.msgs.addMsgRefFlag, prop.images.flag, "%");
  1326. create(steps, putStep, prop.msgs.addMsgRefStep, prop.images.step, "$");
  1327. void refList() { mixin(S_TRACE);
  1328. auto root = comm.summary.flagDirRoot;
  1329. auto fSel = flags.getText();
  1330. auto sSel = steps.getText();
  1331. flags.removeAll();
  1332. foreach (i, flag; root.allFlags) { mixin(S_TRACE);
  1333. auto p = flag.path;
  1334. flags.add(p);
  1335. if (0 == i || 0 == icmp(p, fSel)) flags.select(i);
  1336. }
  1337. steps.removeAll();
  1338. foreach (i, step; root.allSteps) { mixin(S_TRACE);
  1339. auto p = step.path;
  1340. steps.add(p);
  1341. if (0 == i || 0 == icmp(p, sSel)) steps.select(i);
  1342. }
  1343. flags.setEnabled(flags.getItemCount() > 0);
  1344. putFlag.setEnabled(flags.getEnabled());
  1345. steps.setEnabled(steps.getItemCount() > 0);
  1346. putStep.setEnabled(steps.getEnabled());
  1347. }
  1348. refList();
  1349. void refFlagAndStep(Flag[] flags, Step[] steps) { mixin(S_TRACE);
  1350. refList();
  1351. }
  1352. comm.refFlagAndStep.add(&refFlagAndStep);
  1353. comm.delFlagAndStep.add(&refFlagAndStep);
  1354. bar.addDisposeListener(new class DisposeListener {
  1355. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  1356. comm.refFlagAndStep.remove(&refFlagAndStep);
  1357. comm.delFlagAndStep.remove(&refFlagAndStep);
  1358. }
  1359. });
  1360. return bar;
  1361. }
  1362. private void putColor(FixedWidthText text, dchar put) { mixin(S_TRACE);
  1363. auto sel = text.widget.getSelection();
  1364. auto old = toUTF32(text.getText());
  1365. auto newt = cwx.msgutils.putColor(old, put, sel.x, sel.y);
  1366. text.setText(toUTF8(newt));
  1367. int nSel = sel.y + (newt.length - old.length);
  1368. text.widget.setSelection(nSel);
  1369. }
  1370. class MsgPreviewWindow {
  1371. private MsgPreview _preview;
  1372. private Button _toggle;
  1373. private WSize _size;
  1374. private Shell _win;
  1375. private ControlListener _winL;
  1376. private int _parX, _parY;
  1377. private class Dispose : DisposeListener {
  1378. override void widgetDisposed(DisposeEvent e) { mixin(S_TRACE);
  1379. _win.getParent().removeControlListener(_winL);
  1380. saveWin();
  1381. }
  1382. }
  1383. private class PShellL : ControlAdapter {
  1384. override void controlMoved(ControlEvent e) { mixin(S_TRACE);
  1385. auto pb = _win.getParent().getBounds();
  1386. auto tb = _win.getBounds();
  1387. _win.setBounds(tb.x + pb.x - _parX, tb.y + pb.y - _parY, tb.width, tb.height);
  1388. _parX = pb.x;
  1389. _parY = pb.y;
  1390. }
  1391. }
  1392. private class ShellL : ShellAdapter {
  1393. override void shellClosed(ShellEvent e) { mixin(S_TRACE);
  1394. close();
  1395. e.doit = false;
  1396. }
  1397. }
  1398. this (Shell parent, Commons comm, Props prop, Summary summ, Button toggle, WSize size) { mixin(S_TRACE);
  1399. _size = size;
  1400. _toggle = toggle;
  1401. _winL = new PShellL;
  1402. parent.addControlListener(_winL);
  1403. _win = new Shell(parent, SWT.TITLE | SWT.RESIZE | SWT.TOOL | SWT.CLOSE);
  1404. _win.setText(prop.msgs.dlgTitMessagePreview);
  1405. auto cl = new CenterLayout(SWT.HORIZONTAL | SWT.VERTICAL, 0);
  1406. cl.fillHorizontal = true;
  1407. cl.fillVertical = true;
  1408. _win.setLayout(cl);
  1409. _win.addShellListener(new ShellL);
  1410. _win.addDisposeListener(new Dispose);
  1411. _preview = new MsgPreview(_win, comm, prop, summ);
  1412. }
  1413. private void saveWin() { mixin(S_TRACE);
  1414. auto winProps = _size;
  1415. winProps.width = _win.getSize().x;
  1416. winProps.height = _win.getSize().y;
  1417. winProps.x = _win.getBounds().x - _win.getParent().getBounds().x;
  1418. winProps.y = _win.getBounds().y - _win.getParent().getBounds().y;
  1419. }
  1420. bool isVisible() {return _win.isVisible();}
  1421. void open() { mixin(S_TRACE);
  1422. if (_win.isVisible()) return;
  1423. auto pb = _win.getParent().getBounds();
  1424. _parX = pb.x;
  1425. _parY = pb.y;
  1426. auto winProps = _size;
  1427. scope wp = _win.computeSize(SWT.DEFAULT, SWT.DEFAULT);
  1428. int width = winProps.width == SWT.DEFAULT ? wp.x : winProps.width;
  1429. int height = winProps.height == SWT.DEFAULT ? wp.y : winProps.height;
  1430. int x = winProps.x == SWT.DEFAULT ? pb.x + pb.width : winProps.x + pb.x;
  1431. int y = winProps.y == SWT.DEFAULT ? pb.y : winProps.y + pb.y;
  1432. intoDisplay(x, y, width, height);
  1433. _win.setBounds(x, y, width, height);
  1434. refresh();
  1435. _win.setVisible(true);
  1436. _toggle.setSelection(true);
  1437. }
  1438. void close() { mixin(S_TRACE);
  1439. if (!_win.isVisible()) return;
  1440. saveWin();
  1441. _win.setVisible(false);
  1442. _toggle.setSelection(false);
  1443. }
  1444. void text(Talker talker, string imgPath, string message) { mixin(S_TRACE);
  1445. _preview.text(talker, imgPath, message);
  1446. }
  1447. private void refresh() { mixin(S_TRACE);
  1448. _preview.refresh();
  1449. }
  1450. }
  1451. enum SPChar {
  1452. M = 0, /// ???
  1453. U = 1, /// ???
  1454. R = 2, /// ????
  1455. C = 3, /// ???
  1456. I = 4, /// ??
  1457. T = 5, /// ???
  1458. Y = 6 /// ?
  1459. }
  1460. immutable SPCHAR_ALL = [
  1461. SPChar.M,
  1462. SPChar.U,
  1463. SPChar.R,
  1464. SPChar.C,
  1465. SPChar.I,
  1466. SPChar.T,
  1467. SPChar.Y,
  1468. ];
  1469. immutable SPCHAR_TEXT = [
  1470. SPChar.M,
  1471. SPChar.U,
  1472. SPChar.R,
  1473. SPChar.T,
  1474. SPChar.Y,
  1475. ];
  1476. private immutable C_TBL = [
  1477. 'M',
  1478. 'U',
  1479. 'R',
  1480. 'C',
  1481. 'I',
  1482. 'T',
  1483. 'Y',
  1484. ];
  1485. class PreviewValues : Composite {
  1486. void delegate()[] modEvent;
  1487. private static class FlagData {
  1488. Flag flag;
  1489. bool onOff;
  1490. }
  1491. private static class StepData {
  1492. Step step;
  1493. int select;
  1494. }
  1495. private Commons _comm;
  1496. private Props _prop;
  1497. private Summary _summ;
  1498. private bool _isMessage;
  1499. private const(SPChar)[] _targetChars;
  1500. private Table _values;
  1501. private int[SPChar] _indexTable;
  1502. private UndoManager _undo;
  1503. private bool _changedText = false;
  1504. private class UndoPV : Undo {
  1505. private string[char] _names;
  1506. private bool[string] _flags;
  1507. private int[string] _steps;
  1508. this () { mixin(S_TRACE);
  1509. getValues2(_names, _flags, _steps);

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