PageRenderTime 161ms CodeModel.GetById 5ms app.highlight 138ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://bitbucket.org/k4nagatsuki/cwxeditor
D | 4172 lines | 3962 code | 140 blank | 70 comment | 734 complexity | db2c64d38f688f2071e9751bd1eb210b MD5 | raw file

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

   1
   2module cwx.editor.gui.dwt.replacedialog;
   3
   4import cwx.area;
   5import cwx.summary;
   6import cwx.event;
   7import cwx.coupon;
   8import cwx.utils;
   9import cwx.card;
  10import cwx.motion;
  11import cwx.flag;
  12import cwx.usecounter;
  13import cwx.types;
  14import cwx.path;
  15import cwx.background;
  16import cwx.skin;
  17import cwx.msgutils;
  18import cwx.menu;
  19import cwx.jpy;
  20import cwx.cab;
  21import cwx.features;
  22import cwx.textholder;
  23import cwx.system;
  24import cwx.warning;
  25
  26import cwx.editor.gui.dwt.dprops;
  27import cwx.editor.gui.dwt.dutils;
  28import cwx.editor.gui.dwt.centerlayout;
  29import cwx.editor.gui.dwt.customtable;
  30import cwx.editor.gui.dwt.commons;
  31import cwx.editor.gui.dwt.dskin;
  32import cwx.editor.gui.dwt.splitpane;
  33import cwx.editor.gui.dwt.undo;
  34import cwx.editor.gui.dwt.dmenu;
  35import cwx.editor.gui.dwt.chooser;
  36import cwx.editor.gui.dwt.incsearch;
  37
  38import std.ascii;
  39import std.conv;
  40import std.array;
  41import std.string;
  42import std.file;
  43import std.path;
  44import std.regex : Regex, regex, RegexMatch, match;
  45import std.utf;
  46import std.algorithm : uniq, swap;
  47import std.traits;
  48import std.typecons : Tuple;
  49
  50import org.eclipse.swt.all;
  51
  52import java.lang.all;
  53
  54private class CWXPathString {
  55	string scPath;
  56	CWXPath path;
  57	string array;
  58	this (string scPath, CWXPath path, string array) { mixin(S_TRACE);
  59		this.scPath = scPath;
  60		this.path = path;
  61		this.array = array;
  62	}
  63}
  64private class FilePathString {
  65	string scPath;
  66	string array;
  67	this (string scPath, string array) { mixin(S_TRACE);
  68		this.scPath = scPath;
  69		this.array = array;
  70	}
  71}
  72
  73private class FKeyCodesUndo : TUndo!(FKeyCode[]) {
  74	this (FKeyCode[] old, FKeyCode[] n, void delegate(FKeyCode[]) set) { mixin(S_TRACE);
  75		super (old.dup, n.dup, set, (FKeyCode[] v) {return v.dup;});
  76	}
  77}
  78
  79/// ??????????????
  80class ReplaceDialog {
  81private:
  82	class UndoRepl : UndoArr {
  83		this (Undo[] array, bool rev = true) { mixin(S_TRACE);
  84			super (array, rev);
  85		}
  86		override void undo() { mixin(S_TRACE);
  87			reset(false);
  88			super.undo();
  89			refContentText();
  90			_status.setText(.tryFormat(_prop.msgs.replaceUndo, .formatNum(_result.getItemCount())));
  91			_comm.replText.call();
  92		}
  93		override void redo() { mixin(S_TRACE);
  94			reset(false);
  95			super.redo();
  96			refContentText();
  97			_status.setText(.tryFormat(_prop.msgs.replaceRedo, .formatNum(_result.getItemCount())));
  98			_comm.replText.call();
  99		}
 100	}
 101
 102	class RUndo : Undo {
 103		private CWXPath _path = null;
 104		private string _filePath = null;
 105		private Undo[] _uArr;
 106		this (CWXPath path, Undo[] uArr) { mixin(S_TRACE);
 107			_path = path;
 108			_uArr = uArr;
 109		}
 110		this (string filePath, Undo[] uArr) { mixin(S_TRACE);
 111			_filePath = filePath;
 112			_uArr = uArr;
 113		}
 114		void undo() { mixin(S_TRACE);
 115			size_t dmy = 0;
 116			foreach_reverse (u; _uArr) u.undo();
 117			if (_path) addResult(_path, dmy);
 118			if (_filePath) addResult(_filePath, dmy);
 119		}
 120		void redo() { mixin(S_TRACE);
 121			size_t dmy = 0;
 122			foreach_reverse (u; _uArr) u.redo();
 123			if (_path) addResult(_path, dmy);
 124			if (_filePath) addResult(_filePath, dmy);
 125		}
 126		void dispose() { mixin(S_TRACE);
 127			foreach (u; _uArr) u.dispose();
 128		}
 129	}
 130
 131	void store(string filePath, Undo[] uArr) { mixin(S_TRACE);
 132		_rUndo ~= new RUndo(filePath, uArr);
 133	}
 134	void store(CWXPath path, Undo[] uArr) { mixin(S_TRACE);
 135		_rUndo ~= new RUndo(path, uArr);
 136	}
 137	void store(CWXPath path, string o, string n, void delegate(string) set) { mixin(S_TRACE);
 138		_rUndo ~= new RUndo(path, [new StrUndo(o, n, set)]);
 139	}
 140	void store(CWXPath path, string[] o, string[] n, void delegate(string[]) set) { mixin(S_TRACE);
 141		_rUndo ~= new RUndo(path, [new StrArrUndo(o, n, set)]);
 142	}
 143	void store(CWXPath path, FKeyCode[] o, FKeyCode[] n, void delegate(FKeyCode[]) set) { mixin(S_TRACE);
 144		_rUndo ~= new RUndo(path, [new FKeyCodesUndo(o, n, set)]);
 145	}
 146	void storeID(User, Id)(CWXPath path, User u, Id from, Id to, void delegate(Id) set) { mixin(S_TRACE);
 147		_rUndo ~= new RUndo(path, [new TUndo!Id(from, to, set)]);
 148	}
 149
 150	bool _inProc = false;
 151	bool _inUndo = false;
 152	Undo[] _rUndo;
 153	void delegate()[] _after;
 154	core.thread.Thread _uiThread;
 155
 156	Commons _comm;
 157	Props _prop;
 158	Summary _summ;
 159	UndoManager _undo;
 160
 161	Summary _grepSumm = null;
 162	int _grepCount = -1;
 163	Skin _grepSkin = null;
 164	string _grepFile = "";
 165	bool _inGrep = false;
 166
 167	bool _cancel = false;
 168
 169	Shell _win;
 170	Composite _parent;
 171	CTabFolder _tabf;
 172	CTabItem _tabText;
 173	CTabItem _tabID;
 174	CTabItem _tabPath;
 175	CTabItem _tabContents;
 176	CTabItem _tabCoupon;
 177	CTabItem _tabUnuse;
 178	CTabItem _tabError;
 179	CTabItem _tabGrep;
 180	CTabItem _lastFind = null;
 181	Button _find;
 182	Button _replace;
 183	Button _close;
 184	Button _rangeAllCheck;
 185
 186	bool ignoreMod = false;
 187
 188	Composite _textGrp1, _textGrp2, _textFromComp, _grepFromComp;
 189	Combo _from;
 190	Combo _to;
 191	IncSearch _fromIncSearch = null;
 192	IncSearch _toIncSearch = null;
 193
 194	Combo _idKind;
 195	Combo _fromID;
 196	Composite _fromIDComp;
 197	Spinner _fromIDVal;
 198	ulong[int] _fromIDTbl;
 199	Combo _toID;
 200	Composite _toIDComp;
 201	Spinner _toIDVal;
 202	ulong[int] _toIDTbl;
 203	IncSearch _fromIDIncSearch = null;
 204	IncSearch _toIDIncSearch = null;
 205
 206	Combo _fromPath;
 207	Combo _toPath;
 208	IncSearch _fromPathIncSearch = null;
 209	IncSearch _toPathIncSearch = null;
 210
 211	Combo _grepDir;
 212	Button _grepSubDir;
 213
 214	Button _notIgnoreCase;
 215	Button _useRegex;
 216	Button _useWildcard;
 217	Button _exact;
 218	Button _ignoreReturnCode;
 219	class SelRegex : SelectionAdapter {
 220		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 221			if (_useRegex.getSelection()) { mixin(S_TRACE);
 222				_useWildcard.setSelection(false);
 223			}
 224		}
 225	}
 226	class SelWildcard : SelectionAdapter {
 227		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 228			if (_useWildcard.getSelection()) { mixin(S_TRACE);
 229				_useRegex.setSelection(false);
 230			}
 231		}
 232	}
 233	class SelIgnoreReturnCode : SelectionAdapter {
 234		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 235			_comm.refreshToolBar();
 236		}
 237	}
 238	@property
 239	const
 240	bool catchMod() {return !ignoreMod;}
 241
 242	/// ???
 243	Button _summary;
 244	/// ????????
 245	Button _rCoupon;
 246	/// ?????
 247	Button _msg;
 248	/// ????
 249	Button _cardName;
 250	/// ?????
 251	Button _cardDesc;
 252	/// ????????
 253	Button _event;
 254	/// ?????
 255	Button _start;
 256	/// ???/????
 257	Button _flag;
 258	/// ????
 259	Button _coupon;
 260	/// ????
 261	Button _gossip;
 262	/// ???
 263	Button _end;
 264	/// ???/???/??????
 265	Button _area;
 266	/// ?????
 267	Button _keyCode;
 268	/// ????
 269	Button _file;
 270	/// ????
 271	Button _comment;
 272	/// JPTX????
 273	Button _jptx;
 274
 275	Button[] _noSummText;
 276
 277	Button _unuseFlag;
 278	Button _unuseStep;
 279	Button _unuseArea;
 280	Button _unuseBattle;
 281	Button _unusePackage;
 282	Button _unuseCast;
 283	Button _unuseSkill;
 284	Button _unuseItem;
 285	Button _unuseBeast;
 286	Button _unuseInfo;
 287	Button _unuseStart;
 288	Button _unusePath;
 289
 290	Button _cCoupon;
 291	Button _cGossip;
 292	Button _cEnd;
 293	Button _cKeyCode;
 294	// FIXME: CardWirth 1.60 ????
 295/+	Button _cCellName;
 296+/
 297	Table _result;
 298	TableTextEdit _edit;
 299	Tree _range;
 300
 301	Composite[CTabItem] _comps;
 302
 303	ToolItem[CType] _contents;
 304
 305	Label _status;
 306
 307	bool _notIgnoreCaseSel;
 308	bool _exactSel;
 309	bool _ignoreReturnCodeSel;
 310	bool _summarySel;
 311	bool _msgSel;
 312	bool _cardNameSel;
 313	bool _cardDescSel;
 314	bool _eventSel;
 315	bool _startSel;
 316	bool _flagSel;
 317	bool _couponSel;
 318	bool _gossipSel;
 319	bool _endSel;
 320	bool _areaSel;
 321	bool _keyCodeSel;
 322	bool _fileSel;
 323	bool _commentSel;
 324	bool _jptxSel;
 325	string _fromText;
 326	string _toText;
 327
 328	bool _flagDirOnRange = false;
 329
 330	bool _resultRedraw = true;
 331	void resultRedraw(bool val) { mixin(S_TRACE);
 332		if (!_win || _win.isDisposed()) return;
 333		if (_resultRedraw !is val) { mixin(S_TRACE);
 334			_resultRedraw = val;
 335			_result.setRedraw(val);
 336		}
 337	}
 338
 339	class AddResultPath : Runnable {
 340		size_t count = 0;
 341		string path;
 342		string desc;
 343		void run() { mixin(S_TRACE);
 344			if (cancel) return;
 345			if (!_win || _win.isDisposed()) return;
 346			if (_inProc && !_prop.var.etc.searchResultRealtime) resultRedraw(false);
 347			auto itm = new TableItem(_result, SWT.NONE);
 348			auto summ = _grepSumm ? _grepSumm : _summ;
 349			auto fullPath = std.path.buildPath(summ.scenarioPath, path);
 350			if (_grepSumm) { mixin(S_TRACE);
 351				if (!_grepSkin) _grepSkin = findSkin(_comm, _prop, summ);
 352				itm.setImage(fimage(fullPath, _grepSkin));
 353			} else { mixin(S_TRACE);
 354				itm.setImage(fimage(fullPath, _comm.skin));
 355			}
 356			string scPath = null;
 357			string text = encodePath(path);
 358			itm.setText(0, text);
 359			if (desc.length) { mixin(S_TRACE);
 360				itm.setText(2, desc);
 361				itm.setImage(2, _prop.images.warning);
 362			}
 363			if (_grepSumm) { mixin(S_TRACE);
 364				scPath = _grepSumm.useTemp ? _grepSumm.zipName : _grepSumm.scenarioPath;
 365				text = .tryFormat(_prop.msgs.grepScenario, _grepSumm.scenarioName, scPath);
 366				itm.setText(2, text);
 367				itm.setImage(2, _prop.images.summary);
 368			}
 369			itm.setData(new FilePathString(scPath, path));
 370			refResultStatus(count, false);
 371		}
 372	}
 373	class AddResultCWXPath : Runnable {
 374		CWXPath path;
 375		int index;
 376		string desc;
 377		size_t count = 0;
 378		void run() { mixin(S_TRACE);
 379			if (cancel) return;
 380			if (!_win || _win.isDisposed()) return;
 381			if (_inProc && !_prop.var.etc.searchResultRealtime) resultRedraw(false);
 382			auto itm = new TableItem(_result, SWT.NONE, -1 == index ? _result.getItemCount() : index);
 383			string text1, text2;
 384			Image img1, img2;
 385			getPathParams(path, text1, text2, img1, img2);
 386			itm.setImage(0, img1);
 387			itm.setText(0, text1);
 388			itm.setImage(1, img2);
 389			itm.setText(1, text2);
 390			if (desc.length) { mixin(S_TRACE);
 391				itm.setText(2, desc);
 392				itm.setImage(2, _prop.images.warning);
 393			}
 394			string scPath = null;
 395			if (_grepSumm) { mixin(S_TRACE);
 396				scPath = _grepSumm.useTemp ? _grepSumm.zipName : _grepSumm.scenarioPath;
 397				itm.setText(2, .tryFormat(_prop.msgs.grepScenario, _grepSumm.scenarioName, scPath));
 398				itm.setImage(2, _prop.images.summary);
 399			}
 400			itm.setData(new CWXPathString(scPath, _grepSumm ? null : path, path.cwxPath(true)));
 401			refResultStatus(count, false);
 402		}
 403	}
 404	class AddResultMsg : Runnable {
 405		string name;
 406		Image delegate() image;
 407		int index;
 408		size_t count = 0;
 409		void run() { mixin(S_TRACE);
 410			if (cancel) return;
 411			if (!_win || _win.isDisposed()) return;
 412			if (_inProc && !_prop.var.etc.searchResultRealtime) resultRedraw(false);
 413			auto itm = new TableItem(_result, SWT.NONE, -1 == index ? _result.getItemCount() : index);
 414			itm.setText(name);
 415			itm.setImage(image());
 416			refResultStatus(count, false);
 417		}
 418	}
 419	class AddResultUse : Runnable {
 420		string name;
 421		uint use;
 422		Image delegate() image;
 423		int index;
 424		size_t count = 0;
 425		void run() { mixin(S_TRACE);
 426			if (cancel) return;
 427			if (!_win || _win.isDisposed()) return;
 428			if (_inProc && !_prop.var.etc.searchResultRealtime) resultRedraw(false);
 429			auto itm = new TableItem(_result, SWT.NONE, -1 == index ? _result.getItemCount() : index);
 430			itm.setText(0, name);
 431			itm.setImage(0, image());
 432			itm.setText(1, .text(use));
 433			refResultStatus(count, false);
 434		}
 435	}
 436	Display _display;
 437
 438	class ML : MouseAdapter {
 439		public override void mouseDoubleClick(MouseEvent e) { mixin(S_TRACE);
 440			if (_result.isFocusControl() && e.button == 1) { mixin(S_TRACE);
 441				openPath();
 442			}
 443		}
 444	}
 445	class KL : KeyAdapter {
 446		public override void keyPressed(KeyEvent e) { mixin(S_TRACE);
 447			if (_result.isFocusControl() && e.character == SWT.CR) { mixin(S_TRACE);
 448				openPath();
 449			}
 450		}
 451	}
 452	static const ID_AREA = 0;
 453	static const ID_BATTLE = 1;
 454	static const ID_PACKAGE = 2;
 455	static const ID_CAST = 3;
 456	static const ID_SKILL = 4;
 457	static const ID_ITEM = 5;
 458	static const ID_BEAST = 6;
 459	static const ID_INFO = 7;
 460	static const ID_FLAG = 8;
 461	static const ID_STEP = 9;
 462	static const ID_COUPON = 10;
 463	static const ID_GOSSIP = 11;
 464	static const ID_COMPLETE_STAMP = 12;
 465	static const ID_KEY_CODE = 13;
 466	// FIXME: CardWirth 1.60 ????
 467/+	static const ID_CELL_NAME = 14;
 468+/	private void setupIDsImpl2(T)(T[] arr, Combo combo, Spinner spn, ref ulong[int] tbl, bool clear, IncSearch incSearch) { mixin(S_TRACE);
 469		ulong[int] tbl2;
 470		string oldSel = clear ? "" : combo.getText();
 471		combo.removeAll();
 472		static if (is(T:Flag) || is(T:Step)) {
 473			auto set = new HashSet!string;
 474			if (_summ) { mixin(S_TRACE);
 475				static if (is(T:Flag)) {
 476					foreach (key; _summ.useCounter.flag.keys) { mixin(S_TRACE);
 477						if (_prop.sys.randomValue == cast(string)key) continue;
 478						if (!incSearch.match(cast(string)key)) continue;
 479						set.add(cast(string)key);
 480					}
 481				} else static if (is(T:Step)) {
 482					foreach (key; _summ.useCounter.step.keys) { mixin(S_TRACE);
 483						if (_prop.sys.randomValue == cast(string)key) continue;
 484						if (!incSearch.match(cast(string)key)) continue;
 485						set.add(cast(string)key);
 486					}
 487				} else static assert (0);
 488			}
 489			foreach (i, a; arr) { mixin(S_TRACE);
 490				auto p = a.path;
 491				if (p == "") continue;
 492				if (!incSearch.match(p)) continue;
 493				combo.add(p);
 494				set.remove(p);
 495			}
 496			bool delegate(string a, string b) cmps;
 497			if (_prop.var.etc.logicalSort) { mixin(S_TRACE);
 498				cmps = (a, b) => incmp(a, b) < 0;
 499			} else { mixin(S_TRACE);
 500				cmps = (a, b) => icmp(a, b) < 0;
 501			}
 502			foreach (p; .sortDlg(set.array(), cmps)) { mixin(S_TRACE);
 503				if (p == "") continue;
 504				if (!incSearch.match(p)) continue;
 505				combo.add(p);
 506			}
 507			combo.setText(oldSel);
 508			if (combo.getText() == "" && combo.getItemCount()) { mixin(S_TRACE);
 509				combo.select(0);
 510			}
 511			spn.setEnabled(false);
 512		} else static if (is(T:CouponId) || is(T:GossipId) || is(T:CompleteStampId) || is(T:KeyCodeId) || is(T:CellNameId)) {
 513			string[] arr2;
 514			static if (is(T:CouponId)) {
 515				arr2 = .allCoupons(_comm, _summ, CouponComboType.AllCoupons);
 516			} else static if (is(T:GossipId)) {
 517				arr2 = .allGossips(_comm, _summ);
 518			} else static if (is(T:CompleteStampId)) {
 519				arr2 = .allCompleteStamps(_comm, _summ);
 520			} else static if (is(T:KeyCodeId)) {
 521				arr2 = .allKeyCodes(_comm, _summ);
 522			} else static if (is(T:CellNameId)) {
 523				arr2 = .allCellNames(_comm, _summ);
 524			} else static assert (0);
 525			foreach (a; arr2) {
 526				if (!incSearch.match(a)) continue;
 527				combo.add(a);
 528			}
 529			combo.setText(oldSel);
 530			if (combo.getText() == "" && combo.getItemCount()) { mixin(S_TRACE);
 531				combo.select(0);
 532			}
 533			spn.setEnabled(false);
 534		} else {
 535			combo.add(_prop.msgs.replSetID);
 536			foreach (i, a; arr) { mixin(S_TRACE);
 537				if (!incSearch.match(a.name)) continue;
 538				combo.add(to!(string)(a.id) ~ "." ~ a.name);
 539				tbl2[i + 1] = a.id;
 540			}
 541			combo.select(1 < combo.getItemCount() ? 1 : 0);
 542			if (oldSel) { mixin(S_TRACE);
 543				auto i = combo.indexOf(oldSel);
 544				if (i >= 0) combo.select(i);
 545			}
 546			spn.setEnabled(combo.getSelectionIndex() == 0);
 547		}
 548		tbl = tbl2;
 549	}
 550	private void setupIDsImpl1(T)(T[] arr, bool clear, bool from, bool to) { mixin(S_TRACE);
 551		if (from) setupIDsImpl2(arr, _fromID, _fromIDVal, _fromIDTbl, clear, _fromIDIncSearch);
 552		if (to) setupIDsImpl2(arr, _toID, _toIDVal, _toIDTbl, clear, _toIDIncSearch);
 553	}
 554	private void setupIDs(bool clear, bool from, bool to) { mixin(S_TRACE);
 555		if (!_summ) { mixin(S_TRACE);
 556			_fromID.removeAll();
 557			_fromID.setEnabled(false);
 558			_fromIDVal.setEnabled(false);
 559			_toID.removeAll();
 560			_toID.setEnabled(false);
 561			_toIDVal.setEnabled(false);
 562			return;
 563		}
 564		if (from) _fromID.setEnabled(true);
 565		if (to) _toID.setEnabled(true);
 566		switch (_idKind.getSelectionIndex()) {
 567		case ID_AREA: setupIDsImpl1(_summ.areas, clear, from, to); break;
 568		case ID_BATTLE: setupIDsImpl1(_summ.battles, clear, from, to); break;
 569		case ID_PACKAGE: setupIDsImpl1(_summ.packages, clear, from, to); break;
 570		case ID_CAST: setupIDsImpl1(_summ.casts, clear, from, to); break;
 571		case ID_SKILL: setupIDsImpl1(_summ.skills, clear, from, to); break;
 572		case ID_ITEM: setupIDsImpl1(_summ.items, clear, from, to); break;
 573		case ID_BEAST: setupIDsImpl1(_summ.beasts, clear, from, to); break;
 574		case ID_INFO: setupIDsImpl1(_summ.infos, clear, from, to); break;
 575		case ID_FLAG: setupIDsImpl1(_summ.flagDirRoot.allFlags, clear, from, to); break;
 576		case ID_STEP: setupIDsImpl1(_summ.flagDirRoot.allSteps, clear, from, to); break;
 577		case ID_COUPON: setupIDsImpl1(_summ.useCounter.coupon.keys, clear, from, to); break;
 578		case ID_GOSSIP: setupIDsImpl1(_summ.useCounter.gossip.keys, clear, from, to); break;
 579		case ID_COMPLETE_STAMP: setupIDsImpl1(_summ.useCounter.completeStamp.keys, clear, from, to); break;
 580		case ID_KEY_CODE: setupIDsImpl1(_summ.useCounter.keyCode.keys, clear, from, to); break;
 581		// FIXME: CardWirth 1.60 ????
 582/+		case ID_CELL_NAME: setupIDsImpl1(_summ.useCounter.cellName.keys, clear, from, to); break;
 583+/		default: assert (0);
 584		}
 585	}
 586	private void fromIDIncSearch() { mixin(S_TRACE);
 587		.forceFocus(_fromID, true);
 588		_fromIDIncSearch.startIncSearch();
 589	}
 590	private void toIDIncSearch() { mixin(S_TRACE);
 591		.forceFocus(_toID, true);
 592		_toIDIncSearch.startIncSearch();
 593	}
 594
 595	private string[] _lastMaterialPaths;
 596	private string[] allMaterials(bool scenarioOnly) { mixin(S_TRACE);
 597		if (!_summ) return [];
 598		return _summ.allMaterials(_comm.skin, _prop.var.etc.ignorePaths, _prop.var.etc.logicalSort, scenarioOnly);
 599	}
 600	private void setupPaths() { mixin(S_TRACE);
 601		bool oldIgnoreMod = ignoreMod;
 602		ignoreMod = true;
 603		scope (exit) ignoreMod = oldIgnoreMod;
 604
 605		_lastMaterialPaths = [""] ~ allMaterials(false);
 606		setupPathsImpl(true, true);
 607	}
 608	private void setupPathsImpl(bool from, bool to) {
 609		void setPaths(Combo combo, IncSearch incSearch) { mixin(S_TRACE);
 610			auto old = combo.getText();
 611			combo.removeAll();
 612			foreach (path; _lastMaterialPaths) {
 613				if (!incSearch.match(path)) continue;
 614				combo.add(path);
 615			}
 616			combo.setText(old);
 617		}
 618		if (from) setPaths(_fromPath, _fromPathIncSearch);
 619		if (to) setPaths(_toPath, _toPathIncSearch);
 620	}
 621	class SListener : ShellAdapter {
 622		override void shellActivated(ShellEvent e) { mixin(S_TRACE);
 623			setupIDs(false, true, true);
 624			setupPaths();
 625			_comm.refreshToolBar();
 626		}
 627	}
 628	class SelID : SelectionAdapter {
 629		private Spinner _spn;
 630		this (Spinner spn) {_spn = spn;}
 631		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 632			auto combo = cast(Combo) e.widget;
 633			_spn.setEnabled(combo.getSelectionIndex() == 0);
 634			_comm.refreshToolBar();
 635		}
 636	}
 637	class SelIDKind : SelectionAdapter {
 638		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 639			selIDKind();
 640		}
 641	}
 642	void selIDKind() {
 643		updateIDCombo();
 644		setupIDs(true, true, true);
 645		_prop.var.etc.searchIDKind = _idKind.getSelectionIndex();
 646		_comm.refreshToolBar();
 647	}
 648	@property
 649	private bool idKindIsString() {
 650		auto index = _idKind.getSelectionIndex();
 651		// FIXME: CardWirth 1.60 ???? ????
 652/+		return index == ID_FLAG || index == ID_STEP || index == ID_COUPON || index == ID_GOSSIP || index == ID_COMPLETE_STAMP || index == ID_KEY_CODE || index == ID_CELL_NAME;
 653+/		return index == ID_FLAG || index == ID_STEP || index == ID_COUPON || index == ID_GOSSIP || index == ID_COMPLETE_STAMP || index == ID_KEY_CODE;
 654		// FIXME: CardWirth 1.60 ???? ????
 655	}
 656	private void updateIDCombo() { mixin(S_TRACE);
 657		if (idKindIsString) { mixin(S_TRACE);
 658			if (_fromID && !(_fromID.getStyle() & SWT.READ_ONLY)) return;
 659			if (_fromID) { mixin(S_TRACE);
 660				_fromID.dispose();
 661				_toID.dispose();
 662			}
 663			
 664			_fromID = new Combo(_fromIDComp, SWT.BORDER | SWT.DROP_DOWN);
 665			_fromID.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 666			_toID = new Combo(_toIDComp, SWT.BORDER | SWT.DROP_DOWN);
 667			_toID.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 668		} else { mixin(S_TRACE);
 669			if (_fromID && (_fromID.getStyle() & SWT.READ_ONLY)) return;
 670			if (_fromID) { mixin(S_TRACE);
 671				_fromID.dispose();
 672				_toID.dispose();
 673			}
 674			_fromID = new Combo(_fromIDComp, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
 675			_fromID.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 676			_fromID.addSelectionListener(new SelID(_fromIDVal));
 677			_toID = new Combo(_toIDComp, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
 678			_toID.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 679			_toID.addSelectionListener(new SelID(_toIDVal));
 680		}
 681		auto fMenu = new Menu(_win, SWT.POP_UP);
 682		_fromID.setMenu(fMenu);
 683		createMenuItem(_comm, fMenu, MenuID.IncSearch, &fromIDIncSearch, null);
 684		new MenuItem(fMenu, SWT.SEPARATOR);
 685		createTextMenu!Combo(_comm, _prop, _fromID, &catchMod);
 686
 687		auto tMenu = new Menu(_win, SWT.POP_UP);
 688		_toID.setMenu(tMenu);
 689		createMenuItem(_comm, tMenu, MenuID.IncSearch, &toIDIncSearch, null);
 690		new MenuItem(tMenu, SWT.SEPARATOR);
 691		createTextMenu!Combo(_comm, _prop, _toID, &catchMod);
 692
 693		_fromIDIncSearch = new IncSearch(_comm, _fromID);
 694		_fromIDIncSearch.modEvent ~= () => setupIDs(false, true, false);
 695		_toIDIncSearch = new IncSearch(_comm, _toID);
 696		_toIDIncSearch.modEvent ~= () => setupIDs(false, false, true);
 697
 698		_fromIDComp.layout();
 699		_toIDComp.layout();
 700	}
 701	private void tabChanged() { mixin(S_TRACE);
 702		auto sel = _tabf.getSelection();
 703		if (!sel) return;
 704
 705		_parent.setRedraw(false);
 706		scope (exit) _parent.setRedraw(true);
 707
 708		_prop.var.etc.searchPlan = _tabf.getSelectionIndex();
 709		if (sel is _tabText || sel is _tabGrep) { mixin(S_TRACE);
 710			auto comp = _comps[sel is _tabGrep ? _tabGrep : _tabText];
 711			if (_textGrp1.getParent() !is comp) _textGrp1.setParent(comp);
 712			if (_textGrp2.getParent() !is comp) _textGrp2.setParent(comp);
 713			auto fromComp = sel is _tabGrep ? _grepFromComp : _textFromComp;
 714			if (_from.getParent() !is fromComp) { mixin(S_TRACE);
 715				_from.setParent(fromComp);
 716			}
 717		}
 718		foreach (tab, comp; _comps) { mixin(S_TRACE);
 719			auto gd = cast(GridData) comp.getLayoutData();
 720			if (tab is sel) { mixin(S_TRACE);
 721				gd.heightHint= SWT.DEFAULT;
 722			} else { mixin(S_TRACE);
 723				gd.heightHint= 0;
 724			}
 725		}
 726		_parent.layout(true);
 727		_replace.setEnabled(!(sel is _tabText && _ignoreReturnCode.getSelection()) && sel !is _tabContents && sel !is _tabCoupon && sel !is _tabUnuse && sel !is _tabError);
 728		_range.setEnabled(sel !is _tabUnuse && sel !is _tabGrep);
 729		_rangeAllCheck.setEnabled(_range.getEnabled());
 730		_comm.refreshToolBar();
 731	}
 732	class TSListener : SelectionAdapter {
 733		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 734			tabChanged();
 735		}
 736	}
 737	LCheck[] _checked;
 738	class LCheck : SelectionAdapter {
 739		Widget[] buttons;
 740		private Button _all = null;
 741		private void setSelection(Widget b, bool s) { mixin(S_TRACE);
 742			auto button = cast(Button) b;
 743			if (button) button.setSelection(s);
 744			auto ti = cast(ToolItem) b;
 745			if (ti) ti.setSelection(s);
 746		}
 747		private bool getSelection(Widget b) { mixin(S_TRACE);
 748			auto button = cast(Button) b;
 749			if (button) return button.getSelection();
 750			auto ti = cast(ToolItem) b;
 751			if (ti) return ti.getSelection();
 752			assert (0);
 753		}
 754		class AllCheck : SelectionAdapter {
 755			override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 756				foreach (b; buttons) { mixin(S_TRACE);
 757					setSelection(b, _all.getSelection());
 758				}
 759			}
 760		}
 761		void check() { mixin(S_TRACE);
 762			bool checked = true;
 763			foreach (b; buttons) { mixin(S_TRACE);
 764				checked &= getSelection(b);
 765			}
 766			_all.setSelection(checked);
 767		}
 768		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
 769			assert (_all);
 770			check();
 771		}
 772		void createAlls(Composite parent, string text) { mixin(S_TRACE);
 773			_all = new Button(parent, SWT.CHECK);
 774			_all.setText(text);
 775			_all.addSelectionListener(new AllCheck);
 776			check();
 777		}
 778	}
 779	Composite addButtonLine(Composite grp) { mixin(S_TRACE);
 780		auto comp = new Composite(grp, SWT.NONE);
 781		comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 782		auto rl = new RowLayout(SWT.HORIZONTAL);
 783		rl.wrap = true;
 784		rl.pack = false;
 785		comp.setLayout(rl);
 786		return comp;
 787	}
 788	void constructText(CTabFolder tabf) { mixin(S_TRACE);
 789		auto comp = new Composite(tabf, SWT.NONE);
 790		comp.setLayout(new GridLayout(1, true));
 791		auto comp2 = new Composite(comp, SWT.NONE);
 792		auto comp2gl = windowGridLayout(1, true);
 793		comp2gl.marginWidth = 0;
 794		comp2gl.marginHeight = 0;
 795		comp2.setLayout(comp2gl);
 796		{ mixin(S_TRACE);
 797			auto grp = new Group(comp2, SWT.NONE);
 798			grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 799			grp.setText(_prop.msgs.replText);
 800			grp.setLayout(new GridLayout(2, false));
 801			auto fl = new Label(grp, SWT.NONE);
 802			fl.setText(_prop.msgs.replFrom);
 803			_textFromComp = new Composite(grp, SWT.NONE);
 804			_textFromComp.setLayout(new FillLayout);
 805			_from = new Combo(grp, SWT.BORDER | SWT.DROP_DOWN);
 806			_from.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 807			auto gd = new GridData(GridData.FILL_HORIZONTAL);
 808			gd.widthHint = _prop.var.etc.nameWidth;
 809			_textFromComp.setLayoutData(gd);
 810			auto lt = new Label(grp, SWT.NONE);
 811			lt.setText(_prop.msgs.replTo);
 812			_to = new Combo(grp, SWT.BORDER | SWT.DROP_DOWN);
 813			_to.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 814			_to.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 815
 816			auto fMenu = new Menu(_win, SWT.POP_UP);
 817			_from.setMenu(fMenu);
 818			createMenuItem(_comm, fMenu, MenuID.IncSearch, {
 819				.forceFocus(_from, true);
 820				_fromIncSearch.startIncSearch();
 821			}, null);
 822			new MenuItem(fMenu, SWT.SEPARATOR);
 823			createTextMenu!Combo(_comm, _prop, _from, &catchMod);
 824
 825			auto tMenu = new Menu(_win, SWT.POP_UP);
 826			_to.setMenu(tMenu);
 827			createMenuItem(_comm, tMenu, MenuID.IncSearch, {
 828				.forceFocus(_to, true);
 829				_toIncSearch.startIncSearch();
 830			}, null);
 831			new MenuItem(tMenu, SWT.SEPARATOR);
 832			createTextMenu!Combo(_comm, _prop, _to, &catchMod);
 833
 834			_fromIncSearch = new IncSearch(_comm, _from);
 835			_fromIncSearch.modEvent ~= &updateFromHistory;
 836			_toIncSearch = new IncSearch(_comm, _to);
 837			_toIncSearch.modEvent ~= &updateToHistory;
 838		}
 839		{ mixin(S_TRACE);
 840			auto grp = new Group(comp2, SWT.NONE);
 841			_textGrp1 = grp;
 842			auto gd = new GridData(GridData.FILL_HORIZONTAL);
 843			gd.widthHint = _prop.var.etc.searchResultTableWidth;
 844			grp.setLayoutData(gd);
 845			grp.setText(_prop.msgs.replCond);
 846			grp.setLayout(new GridLayout(3, false));
 847			_notIgnoreCase = new Button(grp, SWT.CHECK);
 848			_notIgnoreCase.setText(_prop.msgs.replNotIgnoreCase);
 849			_exact = new Button(grp, SWT.CHECK);
 850			_exact.setText(_prop.msgs.replExactMatch);
 851			_ignoreReturnCode = new Button(grp, SWT.CHECK);
 852			_ignoreReturnCode.setText(_prop.msgs.replIgnoreReturnCode);
 853			_ignoreReturnCode.addSelectionListener(new SelIgnoreReturnCode);
 854			_useWildcard = new Button(grp, SWT.CHECK);
 855			_useWildcard.setText(_prop.msgs.replWildcard);
 856			_useWildcard.addSelectionListener(new SelWildcard);
 857			auto gdw = new GridData;
 858			gdw.horizontalSpan = 3;
 859			_useWildcard.setLayoutData(gdw);
 860			_useRegex = new Button(grp, SWT.CHECK);
 861			_useRegex.setText(_prop.msgs.replRegExp);
 862			_useRegex.addSelectionListener(new SelRegex);
 863			auto gdr = new GridData;
 864			gdr.horizontalSpan = 3;
 865			_useRegex.setLayoutData(gdr);
 866		}
 867		{ mixin(S_TRACE);
 868			auto grp = new Group(comp2, SWT.NONE);
 869			_textGrp2 = grp;
 870			auto gd = new GridData(GridData.FILL_HORIZONTAL);
 871			gd.widthHint = _prop.var.etc.searchResultTableWidth;
 872			grp.setLayoutData(gd);
 873			grp.setText(_prop.msgs.replTextTarget);
 874			grp.setLayout(zeroGridLayout(1, true));
 875			auto checked = new LCheck;
 876			_checked ~= checked;
 877			{ mixin(S_TRACE);
 878				auto btns = addButtonLine(grp);
 879				Button createB(string text, char accr, bool summ = false) { mixin(S_TRACE);
 880					auto b = new Button(btns, SWT.CHECK);
 881					b.setText(text ~ "(&" ~ accr ~ ")");
 882					checked.buttons ~= b;
 883					b.addSelectionListener(checked);
 884					if (!summ) _noSummText ~= b;
 885					return b;
 886				}
 887				_summary = createB(_prop.msgs.replTextSummary, '1', true);
 888				_msg = createB(_prop.msgs.replTextMessage, '2');
 889				_cardName = createB(_prop.msgs.replTextCardName, '3');
 890				_cardDesc = createB(_prop.msgs.replTextCardDesc, '4');
 891				_event = createB(_prop.msgs.replTextEventText, '5');
 892				_start = createB(_prop.msgs.replTextStart, '6');
 893				_flag = createB(_prop.msgs.replTextFlagAndStep, '7');
 894				_coupon = createB(_prop.msgs.replTextCoupon, '8');
 895				_gossip = createB(_prop.msgs.replTextGossip, '9');
 896				_end = createB(_prop.msgs.replTextEndScenario, 'A');
 897				_area = createB(_prop.msgs.replTextAreaName, 'B');
 898				_keyCode = createB(_prop.msgs.replTextKeyCode, 'D');
 899				_file = createB(_prop.msgs.replTextFile, 'E');
 900				_comment = createB(_prop.msgs.replTextComment, 'G');
 901				_jptx = createB(_prop.msgs.replTextJptx, 'H');
 902			}
 903			auto sep = new Label(grp, SWT.SEPARATOR | SWT.HORIZONTAL);
 904			sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 905			{ mixin(S_TRACE);
 906				auto btns = addButtonLine(grp);
 907				checked.createAlls(btns, _prop.msgs.allCheck);
 908			}
 909		}
 910
 911		auto tab = new CTabItem(tabf, SWT.NONE);
 912		tab.setText(_prop.msgs.replForText);
 913		tab.setControl(comp);
 914		_tabText = tab;
 915
 916		auto gd = new GridData(GridData.FILL_BOTH);
 917		comp2.setLayoutData(gd);
 918		_comps[tab] = comp2;
 919	}
 920	void constructID(CTabFolder tabf) { mixin(S_TRACE);
 921		auto comp = new Composite(tabf, SWT.NONE);
 922		comp.setLayout(new GridLayout(1, true));
 923		auto comp2 = new Composite(comp, SWT.NONE);
 924		comp2.setLayout(zeroGridLayout(1, true));
 925		{ mixin(S_TRACE);
 926			auto grp = new Group(comp2, SWT.NONE);
 927			grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 928			grp.setText(_prop.msgs.replID);
 929			grp.setLayout(new GridLayout(3, false));
 930			{ mixin(S_TRACE);
 931				auto l = new Label(grp, SWT.NONE);
 932				l.setText(_prop.msgs.replIDKind);
 933				_idKind = new Combo(grp, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
 934				_idKind.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
 935				_idKind.add(_prop.msgs.replIDArea);
 936				_idKind.add(_prop.msgs.replIDBattle);
 937				_idKind.add(_prop.msgs.replIDPackage);
 938				_idKind.add(_prop.msgs.replIDCast);
 939				_idKind.add(_prop.msgs.replIDSkill);
 940				_idKind.add(_prop.msgs.replIDItem);
 941				_idKind.add(_prop.msgs.replIDBeast);
 942				_idKind.add(_prop.msgs.replIDInfo);
 943				_idKind.add(_prop.msgs.replIDFlag);
 944				_idKind.add(_prop.msgs.replIDStep);
 945				_idKind.add(_prop.msgs.replIDCoupon);
 946				_idKind.add(_prop.msgs.replIDGossip);
 947				_idKind.add(_prop.msgs.replIDCompleteStamp);
 948				_idKind.add(_prop.msgs.replIDKeyCode);
 949				// FIXME: CardWirth 1.60 ????
 950/+				_idKind.add(_prop.msgs.replIDCellName);
 951+/				_idKind.select(0);
 952				if (0 <= _prop.var.etc.searchIDKind && _prop.var.etc.searchIDKind < _idKind.getItemCount()) { mixin(S_TRACE);
 953					_idKind.select(_prop.var.etc.searchIDKind);
 954				}
 955				auto gd = new GridData;
 956				gd.horizontalSpan = 2;
 957				_idKind.setLayoutData(gd);
 958				_idKind.addSelectionListener(new SelIDKind);
 959			}
 960			{ mixin(S_TRACE);
 961				auto sep = new Label(grp, SWT.SEPARATOR | SWT.HORIZONTAL);
 962				auto gd = new GridData(GridData.FILL_HORIZONTAL);
 963				gd.horizontalSpan = 3;
 964				sep.setLayoutData(gd);
 965			}
 966			void setupID(string text, ref Composite comboComp, ref Spinner spn) { mixin(S_TRACE);
 967				auto l = new Label(grp, SWT.NONE);
 968				l.setText(text);
 969				comboComp = new Composite(grp, SWT.NONE);
 970				auto cl = new CenterLayout(SWT.HORIZONTAL | SWT.VERTICAL, 0);
 971				cl.fillHorizontal = true;
 972				cl.fillVertical = true;
 973				comboComp.setLayout(cl);
 974				auto gd = new GridData(GridData.FILL_HORIZONTAL);
 975				gd.widthHint = _prop.var.etc.nameWidth;
 976				comboComp.setLayoutData(gd);
 977				spn = new Spinner(grp, SWT.BORDER);
 978				initSpinner(spn);
 979				spn.setMinimum(1);
 980				spn.setMaximum(_prop.looks.idMax);
 981			}
 982			setupID(_prop.msgs.replFrom, _fromIDComp, _fromIDVal);
 983			setupID(_prop.msgs.replTo, _toIDComp, _toIDVal);
 984			updateIDCombo();
 985		}
 986
 987		auto tab = new CTabItem(tabf, SWT.NONE);
 988		tab.setText(_prop.msgs.replForID);
 989		tab.setControl(comp);
 990		_tabID = tab;
 991
 992		auto gd = new GridData(GridData.FILL_BOTH);
 993		gd.heightHint = 0;
 994		comp2.setLayoutData(gd);
 995		_comps[tab] = comp2;
 996	}
 997	void constructPath(CTabFolder tabf) { mixin(S_TRACE);
 998		auto comp = new Composite(tabf, SWT.NONE);
 999		comp.setLayout(new GridLayout(1, true));
1000		auto comp2 = new Composite(comp, SWT.NONE);
1001		comp2.setLayout(zeroGridLayout(1, true));
1002		{ mixin(S_TRACE);
1003			auto grp = new Group(comp2, SWT.NONE);
1004			grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1005			grp.setText(_prop.msgs.replPath);
1006			grp.setLayout(new GridLayout(2, false));
1007			Combo setupPath(string text, ref IncSearch incSearch) { mixin(S_TRACE);
1008				auto l = new Label(grp, SWT.NONE);
1009				l.setText(text);
1010				auto combo = new Combo(grp, SWT.BORDER | SWT.DROP_DOWN);
1011				combo.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
1012				auto gd = new GridData(GridData.FILL_HORIZONTAL);
1013				gd.widthHint = _prop.var.etc.nameWidth;
1014				combo.setLayoutData(gd);
1015
1016				auto menu = new Menu(_win, SWT.POP_UP);
1017				combo.setMenu(menu);
1018				createMenuItem(_comm, menu, MenuID.IncSearch, {
1019					.forceFocus(combo, true);
1020					incSearch.startIncSearch();
1021				}, null);
1022				new MenuItem(menu, SWT.SEPARATOR);
1023				createTextMenu!Combo(_comm, _prop, combo, &catchMod);
1024
1025				incSearch = new IncSearch(_comm, combo);
1026
1027				return combo;
1028			}
1029			_fromPath = setupPath(_prop.msgs.replFrom, _fromPathIncSearch);
1030			_fromPathIncSearch.modEvent ~= () => setupPathsImpl(true, false);
1031			_toPath = setupPath(_prop.msgs.replTo, _toPathIncSearch);
1032			_fromPathIncSearch.modEvent ~= () => setupPathsImpl(false, true);
1033		}
1034
1035		auto tab = new CTabItem(tabf, SWT.NONE);
1036		tab.setText(_prop.msgs.replForPath);
1037		tab.setControl(comp);
1038		_tabPath = tab;
1039
1040		auto gd = new GridData(GridData.FILL_BOTH);
1041		gd.heightHint = 0;
1042		comp2.setLayoutData(gd);
1043		_comps[tab] = comp2;
1044	}
1045	void constructContents(CTabFolder tabf) { mixin(S_TRACE);
1046		auto comp = new Composite(tabf, SWT.NONE);
1047		comp.setLayout(new GridLayout(1, true));
1048		auto comp2 = new Composite(comp, SWT.NONE);
1049		comp2.setLayout(zeroGridLayout(1, true));
1050		{ mixin(S_TRACE);
1051			auto grp = new Group(comp2, SWT.NONE);
1052			auto gd = new GridData(GridData.FILL_HORIZONTAL);
1053			gd.widthHint = _prop.var.etc.searchResultTableWidth;
1054			grp.setLayoutData(gd);
1055			grp.setText(_prop.msgs.searchRange);
1056			grp.setLayout(zeroGridLayout(1, true));
1057			auto checked = new LCheck;
1058			_checked ~= checked;
1059
1060			auto comp3 = new Composite(grp, SWT.NONE);
1061			comp3.setLayoutData(new GridData(GridData.FILL_BOTH));
1062			comp3.setLayout(windowGridLayout(1, true));
1063			auto bar = new ToolBar(comp3, SWT.HORIZONTAL | SWT.FLAT | SWT.WRAP);
1064			_comm.put(bar);
1065			bar.setLayoutData(new GridData(GridData.FILL_BOTH));
1066			foreach (cGrp, cs; CTYPE_GROUP) { mixin(S_TRACE);
1067				foreach (cType; cs) { mixin(S_TRACE);
1068					auto text = _prop.msgs.contentName(cType);
1069					auto img = _prop.images.content(cType);
1070					void delegate() func = null;
1071					auto ti = createToolItem2(_comm, bar, text, img, func, null, SWT.CHECK);
1072					_contents[cType] = ti;
1073					checked.buttons ~= ti;
1074					ti.addSelectionListener(checked);
1075				}
1076				if (cGrp < CTypeGroup.max) { mixin(S_TRACE);
1077					new ToolItem(bar, SWT.SEPARATOR);
1078				}
1079			}
1080			auto sep = new Label(grp, SWT.SEPARATOR | SWT.HORIZONTAL);
1081			sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1082
1083			auto btns = addButtonLine(grp);
1084			checked.createAlls(btns, _prop.msgs.allSelect);
1085		}
1086
1087		auto tab = new CTabItem(tabf, SWT.NONE);
1088		tab.setText(_prop.msgs.replContents);
1089		tab.setControl(comp);
1090		_tabContents = tab;
1091
1092		auto gd = new GridData(GridData.FILL_BOTH);
1093		gd.heightHint = 0;
1094		comp2.setLayoutData(gd);
1095		_comps[tab] = comp2;
1096	}
1097	void constructCoupon(CTabFolder tabf) { mixin(S_TRACE);
1098		auto comp = new Composite(tabf, SWT.NONE);
1099		comp.setLayout(new GridLayout(1, true));
1100		auto comp2 = new Composite(comp, SWT.NONE);
1101		auto comp2gl = windowGridLayout(1, true);
1102		comp2gl.marginWidth = 0;
1103		comp2gl.marginHeight = 0;
1104		comp2.setLayout(comp2gl);
1105		{ mixin(S_TRACE);
1106			auto grp = new Group(comp2, SWT.NONE);
1107			auto gd = new GridData(GridData.FILL_HORIZONTAL);
1108			gd.widthHint = _prop.var.etc.searchResultTableWidth;
1109			grp.setLayoutData(gd);
1110			grp.setText(_prop.msgs.searchRange);
1111			grp.setLayout(zeroGridLayout(1, true));
1112			auto checked = new LCheck;
1113			_checked ~= checked;
1114			{ mixin(S_TRACE);
1115				auto btns = addButtonLine(grp);
1116				Button createB(string text, char accr) { mixin(S_TRACE);
1117					auto b = new Button(btns, SWT.CHECK);
1118					b.setText(text ~ "(&" ~ accr ~ ")");
1119					checked.buttons ~= b;
1120					b.addSelectionListener(checked);
1121					return b;
1122				}
1123				_cCoupon = createB(_prop.msgs.replTextCoupon, '1');
1124				_cGossip = createB(_prop.msgs.replTextGossip, '2');
1125				_cEnd = createB(_prop.msgs.replTextEndScenario, '3');
1126				_cKeyCode = createB(_prop.msgs.replTextKeyCode, '4');
1127				// FIXME: CardWirth 1.60 ????
1128/+				_cCellName = createB(_prop.msgs.replTextCellName, '5');
1129+/			}
1130			auto sep = new Label(grp, SWT.SEPARATOR | SWT.HORIZONTAL);
1131			sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1132			{ mixin(S_TRACE);
1133				auto btns = addButtonLine(grp);
1134				checked.createAlls(btns, _prop.msgs.allCheck);
1135			}
1136		}
1137
1138		auto tab = new CTabItem(tabf, SWT.NONE);
1139		tab.setText(_prop.msgs.replForCoupon);
1140		tab.setControl(comp);
1141		_tabCoupon = tab;
1142
1143		auto gd = new GridData(GridData.FILL_BOTH);
1144		comp2.setLayoutData(gd);
1145		_comps[tab] = comp2;
1146	}
1147	void constructUnuse(CTabFolder tabf) { mixin(S_TRACE);
1148		auto comp = new Composite(tabf, SWT.NONE);
1149		comp.setLayout(new GridLayout(1, true));
1150		auto comp2 = new Composite(comp, SWT.NONE);
1151		comp2.setLayout(zeroGridLayout(1, true));
1152		{ mixin(S_TRACE);
1153			auto grp = new Group(comp2, SWT.NONE);
1154			grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1155			grp.setText(_prop.msgs.replUnuseTarget);
1156			grp.setLayout(zeroGridLayout(1, true));
1157			auto checked = new LCheck;
1158			_checked ~= checked;
1159			{ mixin(S_TRACE);
1160				auto btns = addButtonLine(grp);
1161				Button createB(string text, char accr) { mixin(S_TRACE);
1162					auto b = new Button(btns, SWT.CHECK);
1163					b.setText(text ~ "(&" ~ accr ~ ")");
1164					checked.buttons ~= b;
1165					b.addSelectionListener(checked);
1166					return b;
1167				}
1168				_unuseFlag = createB(_prop.msgs.replUnuseFlag, '1');
1169				_unuseStep = createB(_prop.msgs.replUnuseStep, '2');
1170				_unuseArea = createB(_prop.msgs.replUnuseArea, '3');
1171				_unuseBattle = createB(_prop.msgs.replUnuseBattle, '4');
1172				_unusePackage = createB(_prop.msgs.replUnusePackage, '5');
1173				_unuseCast = createB(_prop.msgs.replUnuseCast, '6');
1174				_unuseSkill = createB(_prop.msgs.replUnuseSkill, '7');
1175				_unuseItem = createB(_prop.msgs.replUnuseItem, '8');
1176				_unuseBeast = createB(_prop.msgs.replUnuseBeast, '9');
1177				_unuseInfo = createB(_prop.msgs.replUnuseInfo, 'A');
1178				_unuseStart = createB(_prop.msgs.replUnuseStart, 'B');
1179				_unusePath = createB(_prop.msgs.replUnusePath, 'C');
1180			}
1181			auto sep = new Label(grp, SWT.SEPARATOR | SWT.HORIZONTAL);
1182			sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1183			{ mixin(S_TRACE);
1184				auto btns = addButtonLine(grp);
1185				checked.createAlls(btns, _prop.msgs.allCheck);
1186			}
1187		}
1188
1189		auto tab = new CTabItem(tabf, SWT.NONE);
1190		tab.setText(_prop.msgs.replForUnuse);
1191		tab.setControl(comp);
1192		_tabUnuse = tab;
1193
1194		auto gd = new GridData(GridData.FILL_BOTH);
1195		gd.heightHint = 0;
1196		comp2.setLayoutData(gd);
1197		_comps[tab] = comp2;
1198	}
1199	void constructError(CTabFolder tabf) { mixin(S_TRACE);
1200		auto comp = new Composite(tabf, SWT.NONE);
1201		comp.setLayout(new GridLayout(1, true));
1202		auto comp2 = new Composite(comp, SWT.NONE);
1203		comp2.setLayout(zeroGridLayout(1, true));
1204		{ mixin(S_TRACE);
1205			auto l = new Label(comp2, SWT.WRAP);
1206			l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1207			l.setText(_prop.msgs.replError);
1208		}
1209
1210		auto tab = new CTabItem(tabf, SWT.NONE);
1211		tab.setText(_prop.msgs.replForError);
1212		tab.setControl(comp);
1213		_tabError = tab;
1214
1215		auto gd = new GridData(GridData.FILL_BOTH);
1216		gd.heightHint = 0;
1217		comp2.setLayoutData(gd);
1218		_comps[tab] = comp2;
1219	}
1220	void constructGrep(CTabFolder tabf) { mixin(S_TRACE);
1221		auto comp = new Composite(tabf, SWT.NONE);
1222		comp.setLayout(new GridLayout(1, true));
1223		auto comp2 = new Composite(comp, SWT.NONE);
1224		auto comp2gl = windowGridLayout(1, true);
1225		comp2gl.marginWidth = 0;
1226		comp2gl.marginHeight = 0;
1227		comp2.setLayout(comp2gl);
1228
1229		{ mixin(S_TRACE);
1230			auto grp = new Group(comp2, SWT.NONE);
1231			grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1232			grp.setText(_prop.msgs.grepText);
1233			grp.setLayout(new GridLayout(2, false));
1234			auto fl = new Label(grp, SWT.NONE);
1235			fl.setText(_prop.msgs.grepFrom);
1236			_grepFromComp = new Composite(grp, SWT.NONE);
1237			_grepFromComp.setLayout(new FillLayout);
1238			auto gd = new GridData(GridData.FILL_HORIZONTAL);
1239			gd.widthHint = _prop.var.etc.nameWidth;
1240			_grepFromComp.setLayoutData(gd);
1241		}
1242		{ mixin(S_TRACE);
1243			auto grp = new Group(comp2, SWT.NONE);
1244			grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1245			grp.setText(_prop.msgs.grepTarget);
1246			grp.setLayout(new GridLayout(4, false));
1247
1248			_grepDir = new Combo(grp, SWT.BORDER | SWT.DROP_DOWN);
1249			_grepDir.setVisibleItemCount(_prop.var.etc.comboVisibleItemCount);
1250			createTextMenu!Combo(_comm, _prop, _grepDir, &catchMod);
1251			_grepDir.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1252			auto grepDirRef = new Button(grp, SWT.PUSH);
1253			grepDirRef.setText(_prop.msgs.reference);
1254			.listener(grepDirRef, SWT.Selection, { mixin(S_TRACE);
1255				selectDir(_prop, _grepDir, _prop.msgs.grepDir, _prop.msgs.grepDirDesc, _grepDir.getText());
1256			});
1257			createOpenButton(_comm, grp, {return _prop.toAppAbs(_grepDir.getText());}, true);
1258
1259			auto grepCurrent = new Button(grp, SWT.PUSH);
1260			grepCurrent.setText(_prop.msgs.grepCurrent);
1261			.listener(grepCurrent, SWT.Selection, &setGrepCurrentDir);
1262			_grepSubDir = new Button(grp, SWT.CHECK);
1263			auto gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
1264			gd.horizontalSpan = 4;
1265			_grepSubDir.setLayoutData(gd);
1266			_grepSubDir.setText(_prop.msgs.grepSubDir);
1267			.listener(_grepDir, SWT.Modify, { mixin(S_TRACE);
1268				if (ignoreMod) return;
1269				_prop.var.etc.grepDir = _grepDir.getText();
1270			});
1271			.listener(_grepSubDir, SWT.Selection, { mixin(S_TRACE);
1272				if (ignoreMod) return;
1273				_prop.var.etc.grepSubDir = _grepSubDir.getSelection();
1274			});
1275		}
1276
1277		auto tab = new CTabItem(tabf, SWT.NONE);
1278		tab.setText(_prop.msgs.replGrep);
1279		tab.setControl(comp);
1280		_tabGrep = tab;
1281
1282		auto gd = new GridData(GridData.FILL_BOTH);
1283		comp2.setLayoutData(gd);
1284		_comps[tab] = comp2;
1285	}
1286	void setGrepCurrentDir() { mixin(S_TRACE);
1287		if (_summ) { mixin(S_TRACE);
1288			auto sc = _summ.scenarioPath.dirName();
1289			if (_summ.useTemp) sc = _summ.zipName.dirName();
1290			_grepDir.setText(sc);
1291		}
1292	}
1293
1294	void refFunc(bool Del, A : CWXPath)(A a) { mixin(S_TRACE);
1295		bool recurse(TreeItem itm) { mixin(S_TRACE);
1296			if (a is itm.getData()) { mixin(S_TRACE);
1297				static if (Del) {
1298					itm.dispose();
1299				} else { mixin(S_TRACE);
1300					itm.setText(a.name);
1301				}
1302				return true;
1303			} else { mixin(S_TRACE);
1304				foreach (child; itm.getItems()) { mixin(S_TRACE);
1305					if (recurse(child)) { mixin(S_TRACE);
1306						return true;
1307					}
1308				}
1309				return false;
1310			}
1311		}
1312		foreach (child; _range.getItems()) { mixin(S_TRACE);
1313			if (recurse(child)) { mixin(S_TRACE);
1314				return;
1315			}
1316		}
1317		static if (!Del) {
1318			// ??
1319			refreshRangeTree();
1320		}
1321	}
1322	void delArea(Area a) { mixin(S_TRACE);
1323		refFunc!true(a);
1324	}
1325	void delBattle(Battle a) { mixin(S_TRACE);
1326		refFunc!true(a);
1327	}
1328	void delPackage(Package a) { mixin(S_TRACE);
1329		refFunc!true(a);
1330	}
1331	void delCast(CastCard a) { mixin(S_TRACE);
1332		refFunc!true(a);
1333	}
1334	void delSkill(SkillCard a) { mixin(S_TRACE);
1335		refFunc!true(a);
1336	}
1337	void delItem(ItemCard a) { mixin(S_TRACE);
1338		refFunc!true(a);
1339	}
1340	void delBeast(BeastCard a) { mixin(S_TRACE);
1341		refFunc!true(a);
1342	}
1343	void delInfo(InfoCard a) { mixin(S_TRACE);
1344		refFunc!true(a);
1345	}
1346	void refArea(Area a) { mixin(S_TRACE);
1347		if (_prop.var.etc.showAreaDirTree) {
1348			refreshRangeTree();
1349		} else {
1350			refFunc!false(a);
1351		}
1352	}
1353	void refBattle(Battle a) { mixin(S_TRACE);
1354		if (_prop.var.etc.showAreaDirTree) {
1355			refreshRangeTree();
1356		} else {
1357			refFunc!false(a);
1358		}
1359	}
1360	void refPackage(Package a) { mixin(S_TRACE);
1361		if (_prop.var.etc.showAreaDirTree) {
1362			refreshRangeTree();
1363		} else {
1364			refFunc!false(a);
1365		}
1366	}
1367	void refCast(CastCard a) { mixin(S_TRACE);
1368		refFunc!false(a);
1369	}
1370	void refSkill(SkillCard a) { mixin(S_TRACE);
1371		refFunc!false(a);
1372	}
1373	void refItem(ItemCard a) { mixin(S_TRACE);
1374		refFunc!false(a);
1375	}
1376	void refBeast(BeastCard a) { mixin(S_TRACE);
1377		refFunc!false(a);
1378	}
1379	void refInfo(InfoCard a) { mixin(S_TRACE);
1380		refFunc!false(a);
1381	}
1382	static CWXPath[] rangeTree(Summary summ) { mixin(S_TRACE);
1383		CWXPath[] r;
1384		r ~= summ;
1385		r ~= summ.flagDirRoot;
1386		foreach (a; summ.areas) r ~= a;
1387		foreach (a; summ.battles) r ~= a;
1388		foreach (a; summ.packages) r ~= a;
1389		foreach (a; summ.casts) { mixin(S_TRACE);
1390			r ~= a;
1391			foreach (c; a.skills) { mixin(S_TRACE);
1392				if (0 != c.linkId) continue;
1393				r ~= c;
1394			}
1395			foreach (c; a.items) { mixin(S_TRACE);
1396				if (0 != c.linkId) continue;
1397				r ~= c;
1398			}
1399			foreach (c; a.beasts) { mixin(S_TRACE);
1400				if (0 != c.linkId) continue;
1401				r ~= c;
1402			}
1403		}
1404		foreach (a; summ.skills) r ~= a;
1405		foreach (a; summ.items) r ~= a;
1406		foreach (a; summ.beasts) r ~= a;
1407		foreach (a; summ.infos) r ~= a;
1408		return r;
1409	}
1410	void refreshRangeTree() { mixin(S_TRACE);
1411		_range.setRedraw(false);
1412		scope (exit) _range.setRedraw(true);
1413		if (!_summ) { mixin(S_TRACE);
1414			_range.removeAll();
1415			return;
1416		}
1417		CWXPath sel = null;
1418		auto selItm = _range.getSelection();
1419		if (selItm.length) { mixin(S_TRACE);
1420			sel = cast(CWXPath)selItm[0].getData();
1421		}
1422		_range.removeAll();
1423		TreeItem add(TreeItem par, string name, CWXPath path) { mixin(S_TRACE);
1424			TreeItem itm;
1425			if (par) { mixin(S_TRACE);
1426				itm = new TreeItem(par, SWT.NONE);
1427			} else { mixin(S_TRACE);
1428				itm = new TreeItem(_range, SWT.NONE);
1429			}
1430			string text1, text2;
1431			Image img1, img2;
1432			getPathParams(path, text1, text2, img1, img2, false);
1433			itm.setText(name);
1434			itm.setImage(img1);
1435			itm.setData(cast(Object) path);
1436			itm.setChecked(true);
1437			if (sel is path) { mixin(S_TRACE);
1438				_range.setSelection([itm]);
1439			}
1440			return itm;
1441		}
1442		add(null, _prop.msgs.summary, _summ);
1443		add(null, _prop.msgs.flagsAndSteps, _summ.flagDirRoot);
1444		if (_prop.var.etc.showAreaDirTree) { mixin(S_TRACE);
1445			TreeItem[string] itmTable;
1446			auto dirSet = new HashSet!string;
1447			auto dirSet2 = new HashSet!string;
1448			void put1(string dirName) { mixin(S_TRACE);
1449				auto l = dirName.toLower();
1450				if (dirSet2.contains(l)) return;
1451				dirSet.add(dirName);
1452				dirSet2.add(l);
1453			}
1454			foreach (a; _summ.areas) put1(a.dirName);
1455			foreach (a; _summ.battles) put1(a.dirName);
1456			foreach (a; _summ.packages) put1(a.dirName);
1457			bool delegate(string, string) cmps;
1458			if (_prop.var.etc.logicalSort) {
1459				cmps = (a, b) => incmp(a, b) < 0;
1460			} else {
1461				cmps = (a, b) => icmp(a, b) < 0;
1462			}
1463			foreach (dirName; .sortDlg(dirSet.toArray(), cmps)) { mixin (S_TRACE);
1464				auto dirs = .split(dirName, "\\");
1465				TreeItem itm = null;
1466				foreach (i, dir; dirs) { mixin (S_TRACE);
1467					auto fPath = dirs[0 .. i + 1].join("\\");
1468					auto path = fPath.toLower();
1469					auto p = path in itmTable;
1470					if (p) { mixin (S_TRACE);
1471						itm = *p;
1472					} else { mixin (S_TRACE);
1473						TreeItem sub;
1474						if (itm) { mixin (S_TRACE);
1475							sub = new TreeItem(itm, SWT.NONE);
1476						} else { mixin (S_TRACE);
1477							sub = new TreeItem(_range, SWT.NONE);
1478						}
1479						sub.setText(dir);
1480						sub.setImage(_prop.images.areaDir);
1481						sub.setChecked(true);
1482						itm = sub;
1483						itmTable[path] = sub;
1484					}
1485				}
1486				itmTable[dirName.toLower()] = itm;
1487			}
1488			void put(A)(A[] arr) { mixin (S_TRACE);
1489				foreach (a; arr) { mixin (S_TRACE);
1490					add(itmTable[a.dirName.toLower()], .tryFormat("%s.%s", a.id, a.baseName), a);
1491				}
1492			}
1493			put(_summ.areas);
1494			put(_summ.battles);
1495			put(_summ.packages);
1496		} else { mixin(S_TRACE);
1497			foreach (a; _summ.areas) add(null, a.name, a);
1498			foreach (a; _summ.battles) add(null, a.name, a);
1499			foreach (a; _summ.packages) add(null, a.name, a);
1500		}
1501		foreach (a; _summ.casts) { mixin(S_TRACE);
1502			auto par = add(null, .tryFormat("%s.%s", a.id, a.name), a);
1503			foreach (c; a.skills) { mixin(S_TRACE);
1504				if (0 != c.linkId) continue;
1505				add(par, .tryFormat("%s.%s", c.id, c.name), c);
1506			}
1507			foreach (c; a.items) { mixin(S_TRACE);
1508				if (0 != c.linkId) continue;
1509				add(par, .tryFormat("%s.%s", c.id, c.name), c);
1510			}
1511			foreach (c; a.beasts) { mixin(S_TRACE);
1512				if (0 != c.linkId) continue;
1513				add(par, .tryFormat("%s.%s", c.id, c.name), c);
1514			}
1515		}
1516		foreach (a; _summ.skills) { mixin(S_TRACE);
1517			add(null, .tryFormat("%s.%s", a.id, a.name), a);
1518		}
1519		foreach (a; _summ.items) { mixin(S_TRACE);
1520			add(null, .tryFormat("%s.%s", a.id, a.name), a);
1521		}
1522		foreach (a; _summ.beasts) { mixin(S_TRACE);
1523			add(null, .tryFormat("%s.%s", a.id, a.name), a);
1524		}
1525		foreach (a; _summ.infos) { mixin(S_TRACE);
1526			add(null, .tryFormat("%s.%s", a.id, a.name), a);
1527		}
1528		_range.treeExpandedAll();
1529		_range.showSelection();
1530		_comm.refreshToolBar();
1531	}
1532	void refreshRangeAllCheck() { mixin(S_TRACE);
1533		bool recurse(TreeItem itm) { mixin(S_TRACE);
1534			if (!itm.getChecked()) { mixin(S_TRACE);
1535				return true;
1536			} else { mixin(S_TRACE);
1537				foreach (child; itm.getItems()) { mixin(S_TRACE);
1538					if (recurse(child)) { mixin(S_TRACE);
1539						return true;
1540					}
1541				}
1542				return false;
1543			}
1544		}
1545		foreach (child; _range.getItems()) { mixin(S_TRACE);
1546			if (recurse(child)) { mixin(S_TRACE);
1547				_rangeAllCheck.setSelection(false);
1548				return;
1549			}
1550		}
1551		_rangeAllCheck.setSelection(true);
1552	}
1553	class RefRangeAllCheck : SelectionAdapter {
1554		override void widgetSelected(SelectionEvent e) { mixin(S_TRACE);
1555			if (SWT.CHECK != e.detail) return;
1556			auto par = (cast(TreeItem)e.item);
1557			// ????????????????
1558			// ??????????????????
1559			if (par && !par.getData()) { mixin(S_TRACE);
1560				void recurse(TreeItem itm) { mixin(S_TRACE);
1561					itm.setChecked(par.getChecked());
1562					foreach (child; itm.getItems()) recurse(child);
1563				}
1564				foreach (itm; par.getItems()) { mixin(S_TRACE);
1565					recurse(itm);
1566				}
1567			}
1568			// ??????????????????
1569			// ?????????????????????????
1570			while (par && par.getParentItem() && !par.getParentItem().getData()) { mixin(S_TRACE);
1571				bool same = true;
1572				void recurse2(TreeItem itm) { mixin(S_TRACE);
1573					if (itm.getChecked() != par.getChecked()) { mixin(S_TRACE);
1574						same = false;
1575						return;
1576					}
1577					foreach (child; itm.getItems()) recurse2(child);
1578				}
1579				foreach (itm; par.getParentItem().getItems()) { mixin(S_TRACE);
1580					recurse2(itm);
1581				}
1582				if (!same) break;
1583				par.getParentItem().setChecked(par.getChecked());
1584				pa

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