using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using NBTExplorer.Controllers; using Substrate.Nbt; using NBTExplorer.Model; using System.Threading; using NBTExplorer.Model.Search; namespace NBTExplorer.Windows { public partial class FindReplace : Form { private MainForm _main; private NodeTreeController _mainController; private DataNode _mainSearchRoot; private RuleTreeController _findController; private NodeTreeController _replaceController; public FindReplace (MainForm main, NodeTreeController controller, DataNode searchRoot) { InitializeComponent(); _main = main; _mainController = controller; _mainSearchRoot = searchRoot; _findController = new RuleTreeController(treeView1); //_findController.VirtualRootDisplay = "Find Rules"; _replaceController = new NodeTreeController(treeView2); _replaceController.VirtualRootDisplay = "Replacement Tags"; } #region Find Toolbar Buttons private void _tbFindDelete_Click (object sender, EventArgs e) { _findController.DeleteSelection(); } private void _tbFindGroupAnd_Click (object sender, EventArgs e) { _findController.CreateIntersectNode(); } private void _tbFindGroupOr_Click (object sender, EventArgs e) { _findController.CreateUnionNode(); } private void _tbFindAny_Click (object sender, EventArgs e) { _findController.CreateWildcardNode(); } private void _tbFindByte_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_BYTE); } private void _tbFindShort_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_SHORT); } private void _tbFindInt_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_INT); } private void _tbFindLong_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_LONG); } private void _tbFindFloat_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_FLOAT); } private void _tbFindDouble_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_DOUBLE); } private void _tbFindString_Click (object sender, EventArgs e) { _findController.CreateNode(TagType.TAG_STRING); } #endregion #region Replace Toolbar Icons private void _tbReplaceDelete_Click (object sender, EventArgs e) { _replaceController.DeleteSelection(); } private void _tbReplaceByte_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_BYTE); } private void _tbReplaceShort_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_SHORT); } private void _tbReplaceInt_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_INT); } private void _tbReplaceLong_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_LONG); } private void _tbReplaceFloat_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_FLOAT); } private void _tbReplaceDouble_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_DOUBLE); } private void _tbReplaceByteArray_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_BYTE_ARRAY); } private void _tbReplaceIntArray_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_INT_ARRAY); } private void _tbReplaceString_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_STRING); } private void _tbReplaceList_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_LIST); } private void _tbReplaceCompound_Click (object sender, EventArgs e) { _replaceController.CreateNode(TagType.TAG_COMPOUND); } #endregion private CancelSearchForm _searchForm; private ContainerRuleSearchStateWin _searchState; private void _buttonFind_Click (object sender, EventArgs e) { if (_searchState == null) { _searchState = new ContainerRuleSearchStateWin(_main) { RuleTags = _findController.Root, RootNode = _mainSearchRoot, DiscoverCallback = SearchDiscoveryCallback, CollapseCallback = SearchCollapseCallback, ProgressCallback = SearchProgressCallback, EndCallback = SearchEndCallback, }; } SearchNextNode(); } private void _buttonReplaceAll_Click (object sender, EventArgs e) { _searchState = new ContainerRuleSearchStateWin(_main) { RuleTags = _findController.Root, RootNode = _mainSearchRoot, DiscoverCallback = SearchDiscoveryReplaceAllCallback, CollapseCallback = SearchCollapseCallback, EndCallback = SearchEndCallback, TerminateOnDiscover = false, }; SearchNextNode(); } private void SearchNextNode () { if (_searchState == null) return; SearchWorker worker = new SearchWorker(_searchState); Thread t = new Thread(new ThreadStart(worker.Run)); t.IsBackground = true; t.Start(); _searchForm = new CancelSearchForm(); if (_searchForm.ShowDialog(this) == DialogResult.Cancel) { worker.Cancel(); _searchState = null; } t.Join(); } private void SearchDiscoveryCallback (DataNode node) { _mainController.SelectNode(node); _mainController.ExpandSelectedNode(); if (_searchForm != null) { _searchForm.DialogResult = DialogResult.OK; _searchForm = null; } _currentFindNode = node; } private void SearchDiscoveryReplaceAllCallback (DataNode node) { _mainController.SelectNode(node); _mainController.ExpandSelectedNode(); _currentFindNode = node; ReplaceCurrent(); } private void SearchProgressCallback (DataNode node) { if (node is TagCompoundDataNode && !string.IsNullOrEmpty(node.NodeName) && node.NodeName != _searchForm.SearchPathLabel) _searchForm.SearchPathLabel = node.NodeName; } private void SearchCollapseCallback (DataNode node) { _mainController.CollapseBelow(node); } private void SearchEndCallback (DataNode node) { if (_searchForm != null) { _searchForm.DialogResult = DialogResult.OK; _searchForm = null; } MessageBox.Show("End of Results"); } private DataNode _currentFindNode; private void _buttonReplace_Click (object sender, EventArgs e) { ReplaceCurrent(); } private void ReplaceCurrent () { TagCompoundDataNode node = _currentFindNode as TagCompoundDataNode; if (node == null) return; List matches = new List(); _findController.Root.Matches(node, matches); foreach (var replNode in matches) { replNode.DeleteNode(); } foreach (TagDataNode tag in _replaceController.Root.Nodes) { if (tag == null) continue; node.NamedTagContainer.AddTag(tag.Tag, tag.NodeName); node.SyncTag(); } _mainController.RefreshTreeNode(node); } private void _buttonCancel_Click (object sender, EventArgs e) { Close(); } private void _tbFindEdit_Click (object sender, EventArgs e) { //_findController.EditSelection(); } private void _tbReplaceEdit_Click (object sender, EventArgs e) { _replaceController.EditSelection(); } } public abstract class ContainerRuleSearchState : ISearchState { public GroupRule RuleTags { get; set; } public DataNode RootNode { get; set; } public IEnumerator State { get; set; } public bool TerminateOnDiscover { get; set; } public abstract void InvokeDiscoverCallback (DataNode node); public abstract void InvokeProgressCallback (DataNode node); public abstract void InvokeCollapseCallback (DataNode node); public abstract void InvokeEndCallback (DataNode node); protected ContainerRuleSearchState () { TerminateOnDiscover = true; } public bool TestNode (DataNode node) { if (RuleTags == null) return false; TagCompoundDataNode tagNode = node as TagCompoundDataNode; if (tagNode == null) return false; List matches = new List(); if (!RuleTags.Matches(tagNode, matches)) return false; return true; } } public class ContainerRuleSearchStateWin : ContainerRuleSearchState { private ContainerControl _sender; public ContainerRuleSearchStateWin (ContainerControl sender) { _sender = sender; } public Action DiscoverCallback { get; set; } public Action ProgressCallback { get; set; } public Action CollapseCallback { get; set; } public Action EndCallback { get; set; } public override void InvokeDiscoverCallback (DataNode node) { if (_sender != null && DiscoverCallback != null) _sender.BeginInvoke(DiscoverCallback, new object[] { node }); } public override void InvokeProgressCallback (DataNode node) { if (_sender != null && ProgressCallback != null) _sender.BeginInvoke(ProgressCallback, new object[] { node }); } public override void InvokeCollapseCallback (DataNode node) { if (_sender != null && CollapseCallback != null) _sender.BeginInvoke(CollapseCallback, new object[] { node }); } public override void InvokeEndCallback (DataNode node) { if (_sender != null && EndCallback != null) _sender.BeginInvoke(EndCallback, new object[] { node }); } } }