GZDoom Builder 1.10:

Finished Tag Explorer plugin.
Added "ZDBSP - UDMF Normal (no reject)", "ZDBSP - UDMF Normal (zero reject)" and "ZDBSP - Compress nodes (UDMF)" nodebuilder configurations.
This commit is contained in:
MaxED 2012-07-02 23:20:56 +00:00
parent ea312a6e22
commit ce60749092
12 changed files with 775 additions and 436 deletions

View file

@ -30,6 +30,14 @@ nodebuilders
// -c adds comment indices in UDMF format. This is not documented in the ZDBSP usage.
}
zdbsp_udmf_normal
{
title = "ZDBSP - UDMF Normal (no reject)";
compiler = "zdbsp";
parameters = "-c -X -o%FO %FI";
// -c adds comment indices in UDMF format. This is not documented in the ZDBSP usage.
}
zdbsp_fast
{
title = "ZDBSP - Normal (zero reject)";
@ -37,10 +45,24 @@ nodebuilders
parameters = "-R -o%FO %FI";
}
zdbsp_udmf_fast
{
title = "ZDBSP - UDMF Normal (zero reject)";
compiler = "zdbsp";
parameters = "-R -X -o%FO %FI";
}
zdbsp_compressed
{
title = "ZDBSP - Compress nodes";
compiler = "zdbsp";
parameters = "-z -o%FO %FI";
}
zdbsp_udmf_compressed
{
title = "ZDBSP - Compress nodes (UDMF)";
compiler = "zdbsp";
parameters = "-z -X -o%FO %FI";
}
}

View file

@ -283,6 +283,10 @@ mapformat_udmf
// The format interface handles the map data format
formatinterface = "UniversalMapSetIO";
// Default nodebuilder configurations
defaultsavecompiler = "zdbsp_udmf_normal";
defaulttestcompiler = "zdbsp_udmf_fast";
engine = "zdoom"; // override that so that DB2 uses the correct namespace
maplumpnames

View file

@ -16,10 +16,13 @@
<div id="gz_title"><h1>Tag Explorer plugin</h1></div>
<div id="contents">
<p><img style="float:left; margin-right:10px" src="gz_colorpicker.jpg"/>Tag Explorer plugin lets you view all things, sectors and linedefs, which have tags and/or actions/effects set. If current map is in UDMF map format, it also allows you to edit things, sectors and linedefs comments and search an item by a comment.<br /><br />
<p><img style="float:left; margin-right:10px" src="gz_plug_tagexplorer.jpg"/>Tag Explorer plugin lets you view all things, sectors and linedefs, which have tags and/or actions/effects set. It allows you to filter by tag or effect number. If current map is in UDMF map format, it also allows you to edit comments of things, sectors and linedefs and search an item by a comment.<br /><br />
<strong>Usage:</strong><br />
Right-click an item to open appropriate Edit menu.<br />
Double-click an item to edit comment (UDMF-only). Remove comment text to clear comment.
Double-click an item to edit comment (UDMF-only). Remove comment text to clear comment.<br /><br />
<strong>Special filter options:</strong><br />
Enter <b># + tag number</b> to show only elements with this tag. Example: enter "#12" to show elements with tag 12.<br />
Enter <b>$ + effect or action number</b> to show only elements with this effect or action. Example: enter "$9" to show elements with "Line Horizon" effect.
</p>
</div>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View file

@ -106,13 +106,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
if (gotComma) {
float scrollSpeed = 0;
/*if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out scrollSpeed)) {
// Not numeric!
GZBuilder.GZGeneral.LogAndTraceWarning("Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected " + skyType + " scroll speed value, but got '" + token + "'");
datastream.Seek(-token.Length - 1, SeekOrigin.Current); //step back and try parsing this token again
continue;
}*/
if (!ReadSignedFloat(token, ref scrollSpeed)) {
// Not numeric!
GZBuilder.GZGeneral.LogAndTraceWarning("Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected " + skyType + " scroll speed value, but got '" + token + "'");
@ -145,12 +138,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
token = StripTokenQuotes(ReadToken());
float scrollSpeed = 0;
/*if (!float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out scrollSpeed)) {
// Not numeric!
GZBuilder.GZGeneral.LogAndTraceWarning("Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected " + skyType + " scroll speed value, but got '" + token + "'");
datastream.Seek(-token.Length - 1, SeekOrigin.Current); //step back and try parsing this token again
continue;
}*/
if (!ReadSignedFloat(token, ref scrollSpeed)) {
// Not numeric!
GZBuilder.GZGeneral.LogAndTraceWarning("Unexpected token found in '" + sourcename + "' at line " + GetCurrentLineNumber() + ": expected " + skyType + " scroll speed value, but got '" + token + "'");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 229 KiB

View file

@ -9,7 +9,7 @@ using CodeImp.DoomBuilder.Plugins;
namespace CodeImp.DoomBuilder.TagExplorer
{
public class BuilderPlug : Plug
public sealed class BuilderPlug : Plug
{
private static BuilderPlug me;
@ -40,8 +40,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
// This is called after a map has been successfully opened
public override void OnMapOpenEnd() {
// If we just opened a UDMF format map, we want to create the Tag Explorer panel
if (General.Map.Config.FormatInterface == "UniversalMapSetIO") {
if (tagExplorer == null) {
tagExplorer = new TagExplorer();
docker = new Docker("tagexplorerdockerpanel", "Tag Explorer", tagExplorer);
General.Interface.AddDocker(docker);
@ -51,7 +50,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
// This is called after a map has been closed
public override void OnMapCloseEnd() {
// If we have a Comments panel, remove it
// If we have a Tag Explorer panel, remove it
if (tagExplorer != null) {
General.Interface.RemoveDocker(docker);
docker = null;
@ -62,32 +61,20 @@ namespace CodeImp.DoomBuilder.TagExplorer
// Geometry pasted
public override void OnPasteEnd(PasteOptions options) {
if (tagExplorer != null) {
if (tagExplorer != null)
tagExplorer.UpdateTree();
}
}
// Undo performed
public override void OnUndoEnd() {
if (tagExplorer != null) {
if (tagExplorer != null)
tagExplorer.UpdateTree();
}
}
// Redo performed
public override void OnRedoEnd() {
if (tagExplorer != null) {
if (tagExplorer != null)
tagExplorer.UpdateTree();
}
}
// Mode changes
/*public override bool OnModeChange(EditMode oldmode, EditMode newmode) {
if (tagExplorer != null) {
tagExplorer.UpdateTree();
}
return base.OnModeChange(oldmode, newmode);
}*/
}
}

View file

@ -24,10 +24,13 @@
this.label2 = new System.Windows.Forms.Label();
this.cbCenterOnSelected = new System.Windows.Forms.CheckBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label3 = new System.Windows.Forms.Label();
this.cbCommentsOnly = new System.Windows.Forms.CheckBox();
this.cbSelectOnClick = new System.Windows.Forms.CheckBox();
this.labelSearch = new System.Windows.Forms.Label();
this.btnClearSearch = new System.Windows.Forms.Button();
this.tbSearch = new System.Windows.Forms.TextBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
@ -36,18 +39,20 @@
this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.treeView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.treeView.HideSelection = false;
this.treeView.ImageIndex = 0;
this.treeView.ImageList = this.imageList1;
this.treeView.Location = new System.Drawing.Point(3, 125);
this.treeView.Location = new System.Drawing.Point(3, 172);
this.treeView.Name = "treeView";
this.treeView.SelectedImageIndex = 0;
this.treeView.Size = new System.Drawing.Size(266, 415);
this.treeView.Size = new System.Drawing.Size(266, 172);
this.treeView.TabIndex = 0;
this.toolTip1.SetToolTip(this.treeView, "Double-click item to edit item\'s comment\r\nRight-click item to open item\'s Propert" +
"ies");
this.treeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView_NodeMouseDoubleClick);
this.treeView.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.treeView_AfterLabelEdit);
this.treeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView_NodeMouseClick);
this.treeView.BeforeLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.treeView_BeforeLabelEdit);
this.treeView.MouseLeave += new System.EventHandler(this.treeView_MouseLeave);
//
// imageList1
//
@ -66,16 +71,16 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.cbDisplayMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbDisplayMode.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.cbDisplayMode.Location = new System.Drawing.Point(88, 13);
this.cbDisplayMode.Location = new System.Drawing.Point(57, 13);
this.cbDisplayMode.Name = "cbDisplayMode";
this.cbDisplayMode.Size = new System.Drawing.Size(172, 22);
this.cbDisplayMode.Size = new System.Drawing.Size(203, 22);
this.cbDisplayMode.TabIndex = 2;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label1.Location = new System.Drawing.Point(43, 16);
this.label1.Location = new System.Drawing.Point(12, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(39, 14);
this.label1.TabIndex = 3;
@ -88,16 +93,16 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.cbSortMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbSortMode.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.cbSortMode.Location = new System.Drawing.Point(88, 40);
this.cbSortMode.Location = new System.Drawing.Point(57, 40);
this.cbSortMode.Name = "cbSortMode";
this.cbSortMode.Size = new System.Drawing.Size(172, 22);
this.cbSortMode.Size = new System.Drawing.Size(203, 22);
this.cbSortMode.TabIndex = 4;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label2.Location = new System.Drawing.Point(52, 43);
this.label2.Location = new System.Drawing.Point(21, 43);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(30, 14);
this.label2.TabIndex = 5;
@ -109,7 +114,7 @@
this.cbCenterOnSelected.AutoSize = true;
this.cbCenterOnSelected.Location = new System.Drawing.Point(12, 94);
this.cbCenterOnSelected.Name = "cbCenterOnSelected";
this.cbCenterOnSelected.Size = new System.Drawing.Size(203, 17);
this.cbCenterOnSelected.Size = new System.Drawing.Size(207, 18);
this.cbCenterOnSelected.TabIndex = 6;
this.cbCenterOnSelected.Text = "Center view on selected map element";
this.cbCenterOnSelected.UseVisualStyleBackColor = true;
@ -118,7 +123,9 @@
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.cbCommentsOnly);
this.groupBox1.Controls.Add(this.cbSelectOnClick);
this.groupBox1.Controls.Add(this.labelSearch);
this.groupBox1.Controls.Add(this.btnClearSearch);
this.groupBox1.Controls.Add(this.tbSearch);
this.groupBox1.Controls.Add(this.label1);
@ -128,27 +135,48 @@
this.groupBox1.Controls.Add(this.cbSortMode);
this.groupBox1.Location = new System.Drawing.Point(3, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(266, 116);
this.groupBox1.Size = new System.Drawing.Size(266, 163);
this.groupBox1.TabIndex = 7;
this.groupBox1.TabStop = false;
//
// label3
// cbCommentsOnly
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label3.Location = new System.Drawing.Point(9, 71);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(76, 14);
this.label3.TabIndex = 9;
this.label3.Text = "Find comment:";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.cbCommentsOnly.AutoSize = true;
this.cbCommentsOnly.Location = new System.Drawing.Point(12, 140);
this.cbCommentsOnly.Name = "cbCommentsOnly";
this.cbCommentsOnly.Size = new System.Drawing.Size(184, 18);
this.cbCommentsOnly.TabIndex = 11;
this.cbCommentsOnly.Text = "Hide elements without comments";
this.cbCommentsOnly.UseVisualStyleBackColor = true;
this.cbCommentsOnly.CheckedChanged += new System.EventHandler(this.cbCommentsOnly_CheckedChanged);
//
// cbSelectOnClick
//
this.cbSelectOnClick.AutoSize = true;
this.cbSelectOnClick.Location = new System.Drawing.Point(12, 117);
this.cbSelectOnClick.Name = "cbSelectOnClick";
this.cbSelectOnClick.Size = new System.Drawing.Size(95, 18);
this.cbSelectOnClick.TabIndex = 10;
this.cbSelectOnClick.Text = "Select on click";
this.cbSelectOnClick.UseVisualStyleBackColor = true;
//
// labelSearch
//
this.labelSearch.AutoSize = true;
this.labelSearch.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.labelSearch.Location = new System.Drawing.Point(18, 71);
this.labelSearch.Name = "labelSearch";
this.labelSearch.Size = new System.Drawing.Size(33, 14);
this.labelSearch.TabIndex = 9;
this.labelSearch.Text = "Filter:";
this.labelSearch.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// btnClearSearch
//
this.btnClearSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnClearSearch.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.btnClearSearch.Image = global::CodeImp.DoomBuilder.TagExplorer.Properties.Resources.SearchClear;
this.btnClearSearch.Location = new System.Drawing.Point(236, 66);
this.btnClearSearch.Location = new System.Drawing.Point(236, 65);
this.btnClearSearch.Name = "btnClearSearch";
this.btnClearSearch.Size = new System.Drawing.Size(24, 24);
this.btnClearSearch.TabIndex = 8;
@ -160,20 +188,32 @@
//
this.tbSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tbSearch.Location = new System.Drawing.Point(88, 68);
this.tbSearch.Location = new System.Drawing.Point(57, 68);
this.tbSearch.Name = "tbSearch";
this.tbSearch.Size = new System.Drawing.Size(144, 20);
this.tbSearch.Size = new System.Drawing.Size(175, 20);
this.tbSearch.TabIndex = 7;
this.tbSearch.TextChanged += new System.EventHandler(this.tbSearch_TextChanged);
//
// groupBox2
//
this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox2.Location = new System.Drawing.Point(3, 344);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(266, 12);
this.groupBox2.TabIndex = 8;
this.groupBox2.TabStop = false;
//
// TagExplorer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.treeView);
this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.Name = "TagExplorer";
this.Size = new System.Drawing.Size(272, 543);
this.Size = new System.Drawing.Size(272, 359);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
@ -191,8 +231,11 @@
private System.Windows.Forms.CheckBox cbCenterOnSelected;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label labelSearch;
private System.Windows.Forms.Button btnClearSearch;
private System.Windows.Forms.TextBox tbSearch;
private System.Windows.Forms.CheckBox cbSelectOnClick;
private System.Windows.Forms.CheckBox cbCommentsOnly;
private System.Windows.Forms.GroupBox groupBox2;
}
}

View file

@ -1,52 +1,63 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Types;
namespace CodeImp.DoomBuilder.TagExplorer
{
public partial class TagExplorer : UserControl
public sealed partial class TagExplorer : UserControl
{
private const string DISPLAY_TAGS_AND_ACTIONS = "Tags and Actions";
private const string DISPLAY_TAGS_AND_ACTIONS = "Tags and Action specials";
private const string DISPLAY_TAGS = "Tags";
private const string DISPLAY_ACTIONS = "Actions";
private const string DISPLAY_ACTIONS = "Action specials";
private object[] DISPLAY_MODES = new object[] { DISPLAY_TAGS_AND_ACTIONS, DISPLAY_TAGS, DISPLAY_ACTIONS };
private const string SORT_BY_INDEX = "By Index";
private const string SORT_BY_TAG = "By Tag";
private const string SORT_BY_ACTION = "By Action";
private object[] SORT_MODES = new object[] { SORT_BY_INDEX, SORT_BY_TAG, SORT_BY_ACTION };
private string currentDisplayMode;
private string currentSortMode;
private const string CAT_THINGS = "Things:";
private const string CAT_SECTORS = "Sectors:";
private const string CAT_LINEDEFS = "Linedefs:";
private object[] CATEGORIES = new object[] { CAT_THINGS, CAT_SECTORS, CAT_LINEDEFS };
private const string defaultThingName = "Thing";
private const string defaultSectorName = "Sector";
private const string defaultLinedefName = "Linedef";
private Color commentColor = Color.DarkMagenta;
private SelectedNode selection;
public TagExplorer() {
InitializeComponent();
treeView.LabelEdit = true;
selection = new SelectedNode();
cbDisplayMode.Items.AddRange(DISPLAY_MODES);
cbDisplayMode.SelectedIndex = General.Settings.ReadPluginSetting("displaymode", 0);
cbDisplayMode.SelectedIndexChanged += new EventHandler(cbDisplayMode_SelectedIndexChanged);
currentDisplayMode = cbDisplayMode.SelectedItem.ToString();
cbSortMode.Items.AddRange(SORT_MODES);
cbSortMode.Items.AddRange(SortMode.SORT_MODES);
cbSortMode.SelectedIndex = General.Settings.ReadPluginSetting("sortmode", 0);
cbSortMode.SelectedIndexChanged += new EventHandler(cbSortMode_SelectedIndexChanged);
currentSortMode = cbSortMode.SelectedItem.ToString();
cbCenterOnSelected.Checked = General.Settings.ReadPluginSetting("centeronselected", false);
cbSelectOnClick.Checked = General.Settings.ReadPluginSetting("doselect", false);
if (GZBuilder.GZGeneral.UDMF) {
cbCommentsOnly.Checked = General.Settings.ReadPluginSetting("commentsonly", false);
treeView.LabelEdit = true;
toolTip1.SetToolTip(tbSearch, "Enter text to find comment\r\nEnter # + tag number to show only specified tag. Example: #667\r\nEnter $ + effect number to show only specified effect. Example: $80");
toolTip1.SetToolTip(treeView, "Double-click item to edit item's comment\r\nRight-click item to open item's Properties");
} else {
cbCommentsOnly.Enabled = false;
toolTip1.SetToolTip(tbSearch, "Enter # + tag number to show only specified tag. Example: #667\r\nEnter $ + effect number to show only specified effect. Example: $80");
toolTip1.SetToolTip(treeView, "Right-click item to open item's Properties");
}
}
// Disposer
@ -54,6 +65,10 @@ namespace CodeImp.DoomBuilder.TagExplorer
General.Settings.WritePluginSetting("sortmode", cbSortMode.SelectedIndex);
General.Settings.WritePluginSetting("displaymode", cbDisplayMode.SelectedIndex);
General.Settings.WritePluginSetting("centeronselected", cbCenterOnSelected.Checked);
General.Settings.WritePluginSetting("doselect", cbSelectOnClick.Checked);
if (GZBuilder.GZGeneral.UDMF)
General.Settings.WritePluginSetting("commentsonly", cbCommentsOnly.Checked);
if (disposing && (components != null))
components.Dispose();
@ -71,122 +86,310 @@ namespace CodeImp.DoomBuilder.TagExplorer
public void UpdateTree() {
treeView.Nodes.Clear();
bool showTags = (cbDisplayMode.SelectedItem.ToString() == DISPLAY_TAGS || cbDisplayMode.SelectedItem.ToString() == DISPLAY_TAGS_AND_ACTIONS);
bool showActions = (cbDisplayMode.SelectedItem.ToString() == DISPLAY_ACTIONS || cbDisplayMode.SelectedItem.ToString() == DISPLAY_TAGS_AND_ACTIONS);
bool showTags = (currentDisplayMode == DISPLAY_TAGS || currentDisplayMode == DISPLAY_TAGS_AND_ACTIONS);
bool showActions = (currentDisplayMode == DISPLAY_ACTIONS || currentDisplayMode == DISPLAY_TAGS_AND_ACTIONS);
bool hasComment = false;
string comment = "";
string serachStr = tbSearch.Text.ToLowerInvariant();
string serachStr = serachStr = tbSearch.Text.ToLowerInvariant();
int filteredTag = -1;
int filteredAction = -1;
getSpecialValues(serachStr, ref filteredTag, ref filteredAction);
if (filteredTag != -1 || filteredAction != -1) serachStr = "";
TreeNode selectedNode = null;
//add things
List<TreeNode> nodes = new List<TreeNode>();
ICollection<Thing> things = General.Map.Map.Things;
foreach (Thing t in things) {
if ((t.Tag > 0 && showTags) || (t.Action > 0 && showActions)) {
TreeNode node = new TreeNode(getThingName(t, ref hasComment, ref comment), 1, 1);
if ((showTags && t.Tag > 0) || (showActions && t.Action > 0)) {
if (filteredTag != -1 && t.Tag != filteredTag)
continue;
if (filteredAction != -1 && t.Action != filteredAction)
continue;
NodeInfo info = new NodeInfo(t);
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if (serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1)) {
node.Tag = new NodeInfo(t.Index, t.Action, t.Tag);
if (!hasComment && cbCommentsOnly.Checked)
continue;
if (!GZBuilder.GZGeneral.UDMF || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1)) {
TreeNode node = new TreeNode(name, 1, 1);
node.Tag = info;
if (hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if (info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
}
}
}
//sort nodes
sort(ref nodes, cbSortMode.SelectedItem.ToString());
sort(ref nodes, currentSortMode);
//add category
//add "things" category
if (nodes.Count > 0) {
treeView.Nodes.Add(new TreeNode(CAT_THINGS, 0, 0, nodes.ToArray()));
if (currentSortMode == SortMode.SORT_BY_ACTION) { //create action categories
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Action", 0, 0);
foreach (TreeNode node in nodes) {
NodeInfo nodeInfo = node.Tag as NodeInfo;
if (nodeInfo.Action == 0) {
noAction.Nodes.Add(node);
continue;
}
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(nodeInfo.Action);
if (!categories.ContainsKey(lai.Index))
categories.Add(lai.Index, new TreeNode(lai.Index + " - " + lai.Name, 0, 0, new TreeNode[] { node }));
else
categories[lai.Index].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
TreeNode category = new TreeNode(CAT_THINGS, 0, 0, catNodes);
if (noAction.Nodes.Count > 0)
category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
} else if (currentSortMode == SortMode.SORT_BY_INDEX) { //create thing categories
Dictionary<string, TreeNode> categories = new Dictionary<string, TreeNode>();
foreach (TreeNode node in nodes) {
NodeInfo nodeInfo = node.Tag as NodeInfo;
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(General.Map.Map.GetThingByIndex(nodeInfo.Index).Type);
if (!categories.ContainsKey(tti.Category.Title))
categories.Add(tti.Category.Title, new TreeNode(tti.Category.Title, 0, 0, new TreeNode[] { node }));
else
categories[tti.Category.Title].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
treeView.Nodes.Add(new TreeNode(CAT_THINGS, 0, 0, catNodes));
} else { //sort by tag. just add them as they are
treeView.Nodes.Add(new TreeNode(CAT_THINGS, 0, 0, nodes.ToArray()));
}
}
//add sectors
nodes = new List<TreeNode>();
ICollection<Sector> sectors = General.Map.Map.Sectors;
foreach (Sector s in sectors) {
if ((s.Tag > 0 && showTags) || (s.Effect > 0 && showActions)) {
TreeNode node = new TreeNode(getSectorName(s, ref hasComment, ref comment), 3, 3);
if ((showTags && s.Tag > 0) || (showActions && s.Effect > 0)) {
if (filteredTag != -1 && s.Tag != filteredTag)
continue;
if (filteredAction != -1 && s.Effect != filteredAction)
continue;
NodeInfo info = new NodeInfo(s);
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if (serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1)) {
node.Tag = new NodeInfo(s.FixedIndex, s.Effect, s.Tag);
if (!hasComment && cbCommentsOnly.Checked)
continue;
if (!GZBuilder.GZGeneral.UDMF || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1)) {
TreeNode node = new TreeNode(name, 3, 3);
node.Tag = info;
if (hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if (info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
}
}
}
//sort nodes
sort(ref nodes, cbSortMode.SelectedItem.ToString());
sort(ref nodes, currentSortMode);
//add category
if (nodes.Count > 0)
treeView.Nodes.Add(new TreeNode(CAT_SECTORS, 2, 2, nodes.ToArray()));
if (nodes.Count > 0) {
if (currentSortMode == SortMode.SORT_BY_ACTION) {
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Effect", 2, 2);
foreach (TreeNode node in nodes) {
NodeInfo nodeInfo = node.Tag as NodeInfo;
if (nodeInfo.Action == 0) {
noAction.Nodes.Add(node);
continue;
}
SectorEffectInfo sei = General.Map.Config.GetSectorEffectInfo(nodeInfo.Action);
if (!categories.ContainsKey(sei.Index))
categories.Add(sei.Index, new TreeNode(sei.Index + " - " + sei.Title, 2, 2, new TreeNode[] { node }));
else
categories[sei.Index].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
TreeNode category = new TreeNode(CAT_SECTORS, 2, 2, catNodes);
if (noAction.Nodes.Count > 0)
category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
} else { //just add them as they are
treeView.Nodes.Add(new TreeNode(CAT_SECTORS, 2, 2, nodes.ToArray()));
}
}
//add linedefs
nodes = new List<TreeNode>();
ICollection<Linedef> linedefs = General.Map.Map.Linedefs;
foreach (Linedef l in linedefs) {
if ((l.Tag > 0 && showTags) || (l.Action > 0 && showActions)) {
TreeNode node = new TreeNode(getLinedefName(l, ref hasComment, ref comment), 5, 5);
if ((showTags && l.Tag > 0) || (showActions && l.Action > 0)) {
if (filteredTag != -1 && l.Tag != filteredTag)
continue;
if (filteredAction != -1 && l.Action != filteredAction)
continue;
NodeInfo info = new NodeInfo(l);
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
if (serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1)) {
node.Tag = new NodeInfo(l.Index, l.Action, l.Tag);
if (!hasComment && cbCommentsOnly.Checked)
continue;
if (!GZBuilder.GZGeneral.UDMF || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1)) {
TreeNode node = new TreeNode(name, 5, 5);
node.Tag = info;
if (hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if (info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
}
}
}
//sort nodes
sort(ref nodes, cbSortMode.SelectedItem.ToString());
sort(ref nodes, currentSortMode);
//add category
if (nodes.Count > 0)
treeView.Nodes.Add(new TreeNode(CAT_LINEDEFS, 4, 4, nodes.ToArray()));
if (nodes.Count > 0) {
if (currentSortMode == SortMode.SORT_BY_ACTION) {
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Action", 4, 4);
treeView.ExpandAll();
foreach (TreeNode node in nodes) {
NodeInfo nodeInfo = node.Tag as NodeInfo;
if (nodeInfo.Action == 0) {
noAction.Nodes.Add(node);
continue;
}
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(nodeInfo.Action);
if (!categories.ContainsKey(lai.Index))
categories.Add(lai.Index, new TreeNode(lai.Index + " - " + lai.Name, 4, 4, new TreeNode[] { node }));
else
categories[lai.Index].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
TreeNode category = new TreeNode(CAT_LINEDEFS, 4, 4, catNodes);
if (noAction.Nodes.Count > 0)
category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
} else { //just add them as they are
treeView.Nodes.Add(new TreeNode(CAT_LINEDEFS, 4, 4, nodes.ToArray()));
}
}
//expand top level nodes
foreach (TreeNode t in treeView.Nodes)
t.Expand();
if (selectedNode != null)
treeView.SelectedNode = selectedNode;
//loose focus
General.Interface.FocusDisplay();
}
//tag/action search
private void getSpecialValues(string serachStr, ref int filteredTag, ref int filteredAction) {
if (serachStr.Length == 0) return;
int pos = serachStr.IndexOf("#");
if (pos != -1)
filteredTag = readNumber(serachStr, pos+1);
pos = serachStr.IndexOf("$");
if (pos != -1)
filteredAction = readNumber(serachStr, pos+1);
}
private int readNumber(string serachStr, int startPoition) {
string token = "";
int pos = startPoition;
while (pos < serachStr.Length && "1234567890".IndexOf(serachStr[pos]) != -1) {
token += serachStr[pos];
pos++;
}
if (token != "") {
int result = -1;
int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
return result;
}
return -1;
}
//sorting
private void sort(ref List<TreeNode> nodes, string sortMode) {
switch (sortMode) {
case SORT_BY_ACTION:
nodes.Sort(sortByAction);
break;
case SORT_BY_INDEX:
nodes.Sort(sortByIndex);
break;
case SORT_BY_TAG:
nodes.Sort(sortByTag);
break;
default://dbg
GZBuilder.GZGeneral.Trace("Got unknown sort mode: " + cbSortMode.SelectedItem.ToString());
break;
}
if(sortMode == SortMode.SORT_BY_ACTION)
nodes.Sort(sortByAction);
else if (sortMode == SortMode.SORT_BY_TAG)
nodes.Sort(sortByTag);
else
nodes.Sort(sortByIndex);
}
private int sortByAction(TreeNode t1, TreeNode t2) {
NodeInfo i1 = t1.Tag as NodeInfo;
NodeInfo i2 = t2.Tag as NodeInfo;
if (i1.Action == i2.Action) return 0;
if (i1.Action == 0) return 1; //push items with no action to the end of the list
if (i2.Action == 0) return -1; //push items with no action to the end of the list
if (i1.Action > i2.Action) return 1;
else if (i1.Action == i2.Action) return 0;
else if (i1.Action == 0) return 1; //push items with no action to the end of the list
else return -1;
return -1; //should be i1 < i2
}
private int sortByTag(TreeNode t1, TreeNode t2) {
NodeInfo i1 = t1.Tag as NodeInfo;
NodeInfo i2 = t2.Tag as NodeInfo;
if (i1.Tag == i2.Tag) return 0;
if (i1.Tag == 0) return 1; //push items with no tag to the end of the list
if (i2.Tag == 0) return -1; //push items with no tag to the end of the list
if (i1.Tag > i2.Tag) return 1;
else if (i1.Tag == i2.Tag) return 0;
else if (i1.Tag == 0) return 1; //push items with no tag to the end of the list
else return -1;
return -1; //should be i1 < i2
}
private int sortByIndex(TreeNode t1, TreeNode t2) {
@ -194,181 +397,107 @@ namespace CodeImp.DoomBuilder.TagExplorer
NodeInfo i2 = t2.Tag as NodeInfo;
if (i1.Index > i2.Index) return 1;
else if (i1.Index == i2.Index) return 0;
if (i1.Index == i2.Index) return 0;
return -1;
}
//naming
private string getThingName(Thing t, ref bool hasComment, ref string comment) {
if(GZBuilder.GZGeneral.UDMF && t.Fields.ContainsKey("comment")){
comment = t.Fields["comment"].Value.ToString();
hasComment = true;
}else{
comment = defaultThingName;
hasComment = false;
}
return combineName(comment, t.Tag, t.Action, t.Index, cbSortMode.SelectedItem.ToString(), false, !hasComment);
}
private string getSectorName(Sector s, ref bool hasComment, ref string comment) {
if(GZBuilder.GZGeneral.UDMF && s.Fields.ContainsKey("comment")){
comment = s.Fields["comment"].Value.ToString();
hasComment = true;
}else{
comment = defaultSectorName;
hasComment = false;
}
return combineName(comment, s.Tag, s.Effect, s.FixedIndex, cbSortMode.SelectedItem.ToString(), true, !hasComment);
}
private string getLinedefName(Linedef l, ref bool hasComment, ref string comment) {
if(GZBuilder.GZGeneral.UDMF && l.Fields.ContainsKey("comment")){
comment = l.Fields["comment"].Value.ToString();
hasComment = true;
}else{
comment = defaultLinedefName;
hasComment = false;
}
return combineName(comment, l.Tag, l.Action, l.Index, cbSortMode.SelectedItem.ToString(), false, !hasComment);
}
private string combineName(string name, int tag, int action, int index, string sortMode, bool isSector, bool isDefaultName) {
string combinedName = "";
switch(sortMode){
case SORT_BY_ACTION:
combinedName = (action > 0 ? (isSector ? "Effect:" : "Action:") + action + "; " : "") + (tag > 0 ? "Tag:" + tag + "; " : "") + name + (isDefaultName ? " " + index : "");
break;
case SORT_BY_INDEX:
combinedName = index + (tag > 0 ? ": Tag:" + tag + "; " : ": ") + (action > 0 ? (isSector ? "Effect:" : "Action:") + action + "; " : "") + name;
break;
case SORT_BY_TAG:
combinedName = (tag > 0 ? "Tag:" + tag + "; " : "") + (action > 0 ? (isSector ? "Effect:" : "Action:") + action + "; " : "") + name + (isDefaultName ? " " + index : "");
break;
default:
combinedName = name;
break;
}
return combinedName;
}
private void setComment(UniFields fields, string comment) {
if (!fields.ContainsKey("comment"))
fields.Add("comment", new UniValue((int)UniversalType.String, comment));
else
fields["comment"].Value = comment;
}
private string getComment(UniFields fields) {
if (!fields.ContainsKey("comment"))
return "";
else
return fields["comment"].Value.ToString();
}
//EVENTS
private void cbDisplayMode_SelectedIndexChanged(object sender, EventArgs e) {
currentDisplayMode = cbDisplayMode.SelectedItem.ToString();
UpdateTree();
}
private void cbSortMode_SelectedIndexChanged(object sender, EventArgs e) {
currentSortMode = cbSortMode.SelectedItem.ToString();
UpdateTree();
}
private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
if (e.Node.Parent == null) return;
NodeInfo info = e.Node.Tag as NodeInfo;
if (info == null) return;
//store selection
selection.Type = info.Type;
selection.Index = info.Index;
if (e.Button == MouseButtons.Right) { //open element properties
switch (e.Node.Parent.Text) {
case CAT_THINGS:
switch (info.Type) {
case NodeInfoType.THING:
Thing t = General.Map.Map.GetThingByIndex(info.Index);
if (t != null) General.Interface.ShowEditThings(new List<Thing>() { t });
break;
case CAT_SECTORS:
case NodeInfoType.SECTOR:
Sector s = General.Map.Map.GetSectorByIndex(info.Index);
if (s != null) General.Interface.ShowEditSectors(new List<Sector>() { s });
break;
case CAT_LINEDEFS:
case NodeInfoType.LINEDEF:
Linedef l = General.Map.Map.GetLinedefByIndex(info.Index);
if (l != null) General.Interface.ShowEditLinedefs(new List<Linedef>() { l });
break;
default:
GZBuilder.GZGeneral.Trace("Got unknown category: " + e.Node.Parent.Text);
GZBuilder.GZGeneral.Trace("Got unknown category: " + info.Type);
break;
}
General.Map.Map.Update();
UpdateTree();
} else { //focus on element
if (!cbCenterOnSelected.Checked) return;
} else {
//select element?
if (cbSelectOnClick.Checked) {
// Leave any volatile mode
General.Editing.CancelVolatileMode();
General.Map.Map.ClearAllSelected();
switch (e.Node.Parent.Text) {
case CAT_THINGS:
//make selection
if (info.Type == NodeInfoType.THING) {
General.Editing.ChangeMode("ThingsMode");
Thing t = General.Map.Map.GetThingByIndex(info.Index);
if (t != null) General.Map.Renderer2D.PositionView(t.Position.x, t.Position.y);
break;
case CAT_SECTORS:
Sector s = General.Map.Map.GetSectorByIndex(info.Index);
if (s != null) General.Map.Renderer2D.PositionView(s.BBox.Location.X + s.BBox.Width / 2, s.BBox.Location.Y + s.BBox.Height / 2);
break;
case CAT_LINEDEFS:
if (t != null) t.Selected = true;
} else if (info.Type == NodeInfoType.LINEDEF) {
General.Editing.ChangeMode("LinedefsMode");
Linedef l = General.Map.Map.GetLinedefByIndex(info.Index);
if (l != null) General.Map.Renderer2D.PositionView(l.Rect.Location.X + l.Rect.Width / 2, l.Rect.Location.Y + l.Rect.Height / 2);
break;
default:
GZBuilder.GZGeneral.Trace("Got unknown category: " + e.Node.Parent.Text);
break;
if (l != null) l.Selected = true;
} else {
General.Editing.ChangeMode("SectorsMode");
Sector s = General.Map.Map.GetSectorByIndex(info.Index);
if (s != null) {
foreach (Sidedef sd in s.Sidedefs)
sd.Line.Selected = true;
}
}
}
//focus on element?
if (cbCenterOnSelected.Checked) {
Vector2D pos = info.GetPosition();
General.Map.Renderer2D.PositionView(pos.x, pos.y);
}
//update view
General.Interface.RedrawDisplay();
}
}
private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
if (e.Node.Parent == null) return;
//edit comment
if (GZBuilder.GZGeneral.UDMF) {
//store current label...
NodeInfo info = e.Node.Tag as NodeInfo;
info.Label = e.Node.Text;
if (info == null) return;
//if we don't have comment - clear text
switch (e.Node.Parent.Text) {
case CAT_THINGS:
Thing t = General.Map.Map.GetThingByIndex(info.Index);
if (t != null) e.Node.Text = getComment(t.Fields);
break;
e.Node.Text = info.Comment; //set node text to comment
e.Node.BeginEdit(); //begin editing
}
}
case CAT_SECTORS:
Sector s = General.Map.Map.GetSectorByIndex(info.Index);
if (s != null) e.Node.Text = getComment(s.Fields);
break;
case CAT_LINEDEFS:
Linedef l = General.Map.Map.GetLinedefByIndex(info.Index);
if (l != null) e.Node.Text = getComment(l.Fields);
break;
default:
GZBuilder.GZGeneral.Trace("Got unknown category: " + e.Node.Parent.Text);
break;
}
//begin editing
e.Node.BeginEdit();
//we don't want to edit categories if we are in UDMF
private void treeView_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e) {
if (!GZBuilder.GZGeneral.UDMF || e.Node.Tag == null) {
e.CancelEdit = true;
return;
}
}
@ -377,110 +506,57 @@ namespace CodeImp.DoomBuilder.TagExplorer
NodeInfo info = e.Node.Tag as NodeInfo;
string comment = "";
//to set comment manually we actually have to cancel edit...
e.CancelEdit = true;
e.Node.EndEdit(true);
//to set comment manually we actually have to cancel edit...
if (e.Label != null && e.Label.Length > 1) {
bool hasComment = false;
//apply comment
switch (e.Node.Parent.Text) {
case CAT_THINGS:
Thing t = General.Map.Map.GetThingByIndex(info.Index);
if (t != null) {
setComment(t.Fields, e.Label);
e.Node.Text = getThingName(t, ref hasComment, ref comment);
e.Node.ForeColor = hasComment ? commentColor : Color.Black;
}
break;
case CAT_SECTORS:
Sector s = General.Map.Map.GetSectorByIndex(info.Index);
if (s != null) {
setComment(s.Fields, e.Label);
e.Node.Text = getSectorName(s, ref hasComment, ref comment);
e.Node.ForeColor = hasComment ? commentColor : Color.Black;
}
break;
case CAT_LINEDEFS:
Linedef l = General.Map.Map.GetLinedefByIndex(info.Index);
if (l != null) {
setComment(l.Fields, e.Label);
e.Node.Text = getLinedefName(l, ref hasComment, ref comment);
e.Node.ForeColor = hasComment ? commentColor : Color.Black;
}
break;
default://dbg
GZBuilder.GZGeneral.Trace("Got unknown category: " + e.Node.Parent.Text);
break;
}
} else { //Edit cancelled. Remove comment
switch (e.Node.Parent.Text) {
case CAT_THINGS:
Thing t = General.Map.Map.GetThingByIndex(info.Index);
if (t != null) {
e.Node.Text = defaultThingName;
e.Node.ForeColor = Color.Black;
if (t.Fields.ContainsKey("comment")) t.Fields.Remove("comment");
}
break;
case CAT_SECTORS:
Sector s = General.Map.Map.GetSectorByIndex(info.Index);
if (s != null) {
e.Node.Text = defaultSectorName;
e.Node.ForeColor = Color.Black;
if (s.Fields.ContainsKey("comment")) s.Fields.Remove("comment");
}
break;
case CAT_LINEDEFS:
Linedef l = General.Map.Map.GetLinedefByIndex(info.Index);
if (l != null) {
e.Node.Text = defaultLinedefName;
e.Node.ForeColor = Color.Black;
if (l.Fields.ContainsKey("comment")) l.Fields.Remove("comment");
}
break;
}
info.Comment = e.Label;
e.Node.Text = info.GetName(ref comment, currentSortMode);
//e.Node.ForeColor = (comment == "" ? Color.Black : commentColor);
e.Node.ForeColor = commentColor;
} else { //Edit cancelled.
info.Comment = ""; //Remove comment
e.Node.Text = info.GetName(ref comment, currentSortMode);
e.Node.ForeColor = Color.Black;
}
}
private void treeView_MouseLeave(object sender, EventArgs e) {
General.Interface.FocusDisplay();
}
//it is called every time a dialog window closes.
private void ParentForm_Activated(object sender, EventArgs e){
UpdateTree();
}
private void btnClearSearch_Click(object sender, EventArgs e) {
if (tbSearch.Text != "") {
tbSearch.Clear();
UpdateTree();
}
tbSearch.Clear();
General.Interface.FocusDisplay();
}
private void tbSearch_TextChanged(object sender, EventArgs e) {
if(tbSearch.Text.Length > 2) UpdateTree();
if (tbSearch.Text.Length > 1 || tbSearch.Text.Length == 0) UpdateTree();
}
private void cbCommentsOnly_CheckedChanged(object sender, EventArgs e) {
UpdateTree();
}
}
internal class NodeInfo
internal struct SortMode
{
private int index;
private int action;
private int tag;
public const string SORT_BY_INDEX = "By Index";
public const string SORT_BY_TAG = "By Tag";
public const string SORT_BY_ACTION = "By Action special";
public static object[] SORT_MODES = new object[] { SORT_BY_INDEX, SORT_BY_TAG, SORT_BY_ACTION };
}
public int Index { get { return index; } }
public int Tag { get { return tag; } }
public int Action { get { return action; } }
public string Label; //holds TreeNode text while it's edited
public NodeInfo(int index, int action, int tag) {
this.index = index;
this.action = action;
this.tag = tag;
}
internal struct SelectedNode
{
public NodeInfoType Type;
public int Index;
}
}

View file

@ -124,107 +124,107 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABo
FwAAAk1TRnQBSQFMAgEBBgEAARgBAAEYAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIBYAAxQBGQMUARkDFAEZNAADFAEZAxQBGQMUARmwAAMxAUwBBwFGAecB/wEH
ATIBoQH/AzEBTAMUARksAAMxAUwBswF0ASoB/wF+AU4BIAH/AzEBTAMUARmsAAEjAWMC/wEbAV0C/wEH
AT8BzgH/AQcBMgGhAf8DFAEZLAAB4AGHATIB/wHZAYYBMQH/AZ4BaAEnAf8BfgFOASAB/wMUARmsAAF3
AZsC/wHoAe8C/wEbAV0C/wEHAUYB5wH/AxQBGSwAAf4BtAFvAv8B/QHlAf8B2QGGATEB/wGzAXQBKgH/
AxQBGawAAzEBTAF3AZsC/wEjAWMC/wOJAf8DSwH/AyQBMygAAzEBTAH+AbQBbwH/AeABhwEyAf8BowGJ
AXQB/wNLAf8DJAEzsAADJAEzA7wB/wOBAf8DSwH/AyQBMwgAAyQBMwMkATMDJAEzGAADJAEzA7wB/wOB
Af8DSwH/AyQBMwgAAyQBMwMkATMDJAEznAADJAEzA80B/wOUAf8DSwH/AyQBMwMxAUwDSwH/A5QB/wMk
ATMcAAMkATMDzQH/A5QB/wNLAf8DJAEzAzEBTANLAf8DlAH/AyQBM6AAAyQBMwPNAf8DlAH/A0sB/wNL
Af8DlAH/AyQBMyQAAyQBMwPNAf8DlAH/A0sB/wNLAf8DlAH/AyQBM6gAAyQBMwO4Af8DlAH/A4EB/wMk
ATMsAAMkATMDuAH/A5QB/wOBAf8DJAEzsAADJAEzA88B/wOUAf8DSwH/AyQBMywAAyQBMwPPAf8DlAH/
A0sB/wMkATOwAAMkATMDwwH/A5QB/wNLAf8DJAEzLAADJAEzA8MB/wOUAf8DSwH/AyQBM7AAAyQBMwO8
Af8DlAH/A0sB/wMUARkDFAEZAxQBGSQAAyQBMwO8Af8DlAH/A0sB/wMUARkDFAEZAxQBGagAAyQBMwPZ
Af8DtwH/AQcBRgHnAf8BBwEyAaEB/wMxAUwDFAEZJAADJAEzA9kB/wHRAbcBnQH/AbMBdAEqAf8BfgFO
ASAB/wMxAUwDFAEZqAADJAEzASMBYwL/ARsBXQL/AQcBPwHOAf8BBwEyAaEB/wMUARkoAAMkATMB4AGH
ATIB/wHZAYYBMQH/AZ4BaAEnAf8BfgFOASAB/wMUARmsAAF3AZsC/wHoAe8C/wEbAV0C/wEHAUYB5wH/
AxQBGSwAAf4BtAFvAv8B/QHlAf8B2QGGATEB/wGzAXQBKgH/AxQBGawAAzEBTAF3AZsC/wEjAWMC/wMx
AUwwAAMxAUwB/gG0AW8B/wHgAYcBMgH/AzEBTJgAAwoBCwMhAS0DKAE7AygBOwMoATsDHwErAxMBGAMT
ARggAAMKAQsDIQEtAygBOwMoATsDKAE7Ax8BKwMTARgDEwEYEAADFAEZAxQBGQMUARkgAAMUARkDFAEZ
AxQBGQgAAxQBGQMUARkDFAEZIAADFAEZAxQBGQMUARkUAAM5AVwCYAFqAegBKQExAYEB/wEjASoBdwH/
ASIBKQF0Af8BIQEoAW0B/wFcAV0BYAHkAzkBXAMoATsDEwEYGAADOQFcAW4BZwFgAegBgQFcASkB/wF3
AVQBIwH/AXQBUgEiAf8BbQFNASEB/wFiAV4BXAHkAzkBXAMoATsDEwEYCAADMQFMASsBOgGyAf8BIQEu
AX0B/wMxAUwDFAEZAxQBGQMUARkDFAEZAxQBGQMUARkDFAEZAzEBTAErAToBsgH/ASEBLgF9Af8DMQFM
AxQBGQMxAUwBsgF0ASsB/wF9AU4BIQH/AzEBTAMUARkDFAEZAxQBGQMUARkDFAEZAxQBGQMUARkDMQFM
AbIBdAErAf8BfQFOASEB/wMxAUwDFAEZDAACXAFeAcUBOQFFAbsB/wE3AUMBvAH/ATYBQgG6Af8BNQFB
AbcB/wEzAT0BtAH/ATEBPAGsAf8BLAE0AZQB/wEiASoBdwH/A1sBvQMoATsDEwEYEAACXgFcAcUBuwGD
ATkB/wG8AYIBNwH/AboBgQE2Af8BtwGBATUB/wG0AYEBMwH/AawBegExAf8BlAFsASwB/wF3AVMBIgH/
A1sBvQMoATsDEwEYBAABNAFMAd8B/wEyAUYB2AH/AScBMwGdAf8BIQEuAX0B/wNEAf8DRAH/A0QB/wNE
Af8DRAH/A0QB/wNEAf8BNAFMAd8B/wEyAUYB2AH/AScBMwGdAf8BIQEuAX0B/wMUARkB3wGHATQB/wHY
AYYBMgH/AZ0BaAEnAf8BfQFOASEB/wNEAf8DRAH/A0QB/wNEAf8DRAH/A0QB/wNEAf8B3wGHATQB/wHY
AYYBMgH/AZ0BaAEnAf8BfQFOASEB/wMUARkIAANcAb4BPgFLAdMB/wFDAVIB6AH/AUcBVQHzAf8BRgFV
AfAB/wFFAVUB7wH/AUUBVQHvAf8BRAFSAe0B/wFBAVAB4gH/ATcBQwG7Af8BJwEuAYEB/wNbAb0DKAE7
AxMBGAgAAlwBWgG+AdMBkwE+Af8B6AGhAUMB/wHzAaoBRwH/AfABpwFGAf8B7wGlAUUB/wHvAaUBRQH/
Ae0BpQFEAf8B4gGcAUEB/wG7AYIBNwH/AYEBXgEnAf8DWwG9AygBOwMTARgBcAGBAf0B/wHsAeUC/wEy
AUYB2AH/ASsBOgGyAf8DuAH/A7gB/wO4Af8DuAH/A7gB/wOmAf8DmAH/AXABgQH9Af8B7AHlAv8BMgFG
AdgB/wErAToBsgH/AxQBGQH9AbQBcAL/Af0B5QH/AdgBhgEyAf8BsgF0ASsB/wO4Af8DuAH/A7gB/wO4
Af8DuAH/A6YB/wOYAf8B/QG0AXAC/wH9AeUB/wHYAYYBMgH/AbIBdAErAf8DFAEZBAADOQFcAUcBVQHj
Af8BRgFUAfEB/wE2AUEBswH/ATQBPwGrAf8BRAFSAeoB/wFJAVkB+gH/AUgBVwH2Af8BRgFUAfEB/wFG
AVUB8AH/AUMBUQHqAf8BNgFBAb4B/wEmASwBgQH/AzkBXAMTARgEAAM5AVwB4wGgAUcB/wHxAagBRgH/
AbMBgQE2Af8BqwF7ATQB/wHqAaMBRAH/AfoBrgFJAf8B9gGsAUgB/wHxAagBRgH/AfABpwFGAf8B6gGj
AUMB/wG+AYQBNgH/AYEBXQEmAf8DOQFcAxMBGAMxAUwBcAGBAf0B/wE0AUwB3wH/AzEBTAwAA7gB/wNP
AZkIAAMxAUwBcAGBAf0B/wE0AUwB3wH/AzEBTAQAAzEBTAH9AbQBcAH/Ad8BhwE0Af8DMQFMDAADuAH/
A08BmQgAAzEBTAH9AbQBcAH/Ad8BhwE0Af8DMQFMCAACYQFoAdsBVgFkAfYB/wFQAV8C/wE2AUEBsQH/
AwcB/wEPAREBKwH/ASQBKwF3Af8BOwFGAcIB/wFGAVYB8QH/AUkBWQH6Af8BRwFXAfQB/wFAAU4B5AH/
ATEBPAGsAf8CXQFlAecDHwErBAABagFmAWEB2wH2AbEBVgL/AbQBUAH/AbEBfwE2Af8DBwH/ASsBIAEP
Af8BdwFUASQB/wHCAYgBOwH/AfEBpwFGAf8B+gGuAUkB/wH0AakBRwH/AeQBngFAAf8BrAF6ATEB/wFl
AWIBXQHnAx8BKwQAA5gB/wNLAf8DFAEZDAADpQH/A08BmQwAA5gB/wNEAf8DFAEZCAADmAH/A0sB/wMU
ARkMAAOlAf8DTwGZDAADmAH/A0QB/wMUARkIAAFTAWEC/wFrAXkC/wFaAWcB+wH/AUwBWgHoAf8BDwEQ
ASEB/wMHAf8DBwH/AwcB/wETARYBOgH/ASkBMQGEAf8BPQFJAc4B/wFFAVQB7wH/ATsBRwHMAf8BKgEz
AYoB/wMoATsEAAH/AbYBUwL/Ab4BawH/AfsBtwFaAf8B6AGlAUwB/wEhARoBDwH/AwcB/wMHAf8DBwH/
AToBKgETAf8BhAFgASkB/wHOAZABPQH/Ae8BpgFFAf8BzAGOATsB/wGKAWQBKgH/AygBOwQAA6YB/wNL
Af8DFAEZIAADpgH/A0QB/wMUARkIAAOmAf8DSwH/AxQBGSAAA6YB/wNEAf8DFAEZBAADJAEzAWYBcwL/
AXwBhAL/AWQBcAH5Af8BVgFlAfwB/wEnAS8BfAH/AwcB/wMHAf8DBwH/AQ0BDgEUAf8BIAEnAWYB/wEw
ATkBnQH/AUMBUAHkAf8BQAFPAeEB/wEtATYBnAH/AygBOwMkATMB/wG9AWYC/wHGAXwB/wH5AboBZAH/
AfwBtAFWAf8BfAFYAScB/wMHAf8DBwH/AwcB/wEUAREBDQH/AWYBSAEgAf8BnQFyATAB/wHkAaABQwH/
AeEBmwFAAf8BnAFwAS0B/wMoATsEAAOwAf8DSwH/A08BmQNPAZkUAANPAZkDTwGZA7AB/wNEAf8DFAEZ
CAADsAH/A0sB/wNPAZkDTwGZFAADTwGZA08BmQOwAf8DRAH/AxQBGQQAAyQBMwFwAX0C/wGBAYwC/wFl
AXMB+AH/AVQBZAH7Af8BPAFIAcsB/wIIAQoB/wMHAf8DBwH/ARkBHQFMAf8BSQFYAfkB/wFJAVkB+gH/
AUYBVQHwAf8BQAFOAeMB/wEuATgBogH/AygBOwMkATMB/wHBAXAC/wHKAYEB/wH4AbgBZQH/AfsBsgFU
Af8BywGOATwB/wEKAQkBCAH/AwcB/wMHAf8BTAE3ARkB/wH5Aa4BSQH/AfoBrgFJAf8B8AGnAUYB/wHj
AZ0BQAH/AaIBdAEuAf8DKAE7BAADuAH/A7gB/wO4Af8DpQH/FAADpQH/A7gB/wO4Af8DRAH/AxQBGQgA
A7gB/wO4Af8DuAH/A6UB/xQAA6UB/wO4Af8DuAH/A0QB/wMUARkIAAFuAX0C/wGOAZcC/wFtAXgB/gH/
AVYBZQH1Af8BTAFaAfgB/wEYAR0BTAH/AQoBCQELAf8BJQEtAXsB/wMHAf8BHAEiAVsB/wFGAVUB8AH/
AUcBVQHzAf8BPgFMAdoB/wEwATkBnwH/AyMBMQQAAf8BvwFuAv8B0AGOAf8B/gHBAW0B/wH1AbABVgH/
AfgBrwFMAf8BTAE2ARgB/wILAQkB/wF7AVYBJQH/AwcB/wFbAUABHAH/AfABpwFGAf8B8wGqAUcB/wHa
AZcBPgH/AZ8BdAEwAf8DIwExBAADuAH/A0sB/wMUARkgAAO4Af8DRAH/AxQBGQgAA7gB/wNLAf8DFAEZ
IAADuAH/A0QB/wMUARkIAAJmAWkB2wGWAaAC/wGGAZAC/wFuAXsB+QH/AVkBZwH+Af8BMQE7AZ0B/wEX
ARwBSAH/AUsBWwL/AS8BOAGYAf8DBwH/ARwBIgFbAf8BRQFUAe0B/wE+AUsB1QH/Al0BbwHqAw0BEAQA
AWoBZgFhAdsB/wHSAZYC/wHMAYYB/wH5AbwBbgH/Af4BuAFZAf8BnQFyATEB/wFIATMBFwL/AbIBSwH/
AZgBbwEvAf8DBwH/AVsBQAEcAf8B7QGlAUUB/wHVAZQBPgH/AXABZwFbAeoDDQEQBAADuAH/A0sB/wMU
ARkgAAO4Af8DRAH/AxQBGQgAA7gB/wNLAf8DFAEZIAADuAH/A0QB/wMUARkIAAM5AVwBmAGiAv8BngGn
Av8BdwGBAv8BYwFwAfkB/wFOAVkB5AH/AT8BSgG+Af8BTwFfAfgB/wFRAV8B/QH/ATgBQAGcAf8DBwH/
ATUBPwGxAf8BQQFOAd4B/wM5AVwIAAM5AVwB/wHTAZgC/wHWAZ4C/wHFAXcB/wH5AbkBYwH/AeQBpQFO
Af8BvgGHAT8B/wH4Aa4BTwH/Af0BtAFRAf8BnAF1ATgB/wMHAf8BsQGAATUB/wHeAZsBQQH/AzkBXAgA
A7gB/wNLAf8DFAEZDAADpQH/A08BmQwAA7gB/wNEAf8DFAEZCAADuAH/A0sB/wMUARkMAAOlAf8DTwGZ
DAADuAH/A0QB/wMUARkMAANYAbIBqAGxAv8BiQGTAv8BfQGDAv8BdAGAAfwB/wFpAXUB9gH/AWMBbwH2
Af8BYgFuAfUB/wFeAWsB+wH/AUEBSwHCAf8BQgFQAeAB/wJcAV8BxhAAA1gBsgH/AdkBqAL/Ac4BiQL/
AcgBfQH/AfwBwQF0Af8B9gG5AWkB/wH2AbcBYwH/AfUBtgFiAf8B+wG4AV4B/wHCAYsBQQH/AeABnAFC
Af8CXwFcAcYIAAMxAUwBKwE6AbIB/wEhAS4BfQH/AzEBTAMUARkDFAEZAxQBGQO4Af8DTwGZAxQBGQMU
ARkDMQFMASsBOgGyAf8BIQEuAX0B/wMxAUwDFAEZAzEBTAGyAXQBKwH/AX0BTgEhAf8DMQFMAxQBGQMU
ARkDFAEZA7gB/wNPAZkDFAEZAxQBGQMxAUwBsgF0ASsB/wF9AU4BIQH/AzEBTAMUARkMAANZAbEBnwGp
Av8BlwGiAv8BiwGVAv8BeAGCAv8BZgF1Af0B/wFcAWkB+QH/AVABXwH3Af8BSQFZAfoB/wFdAVsBXQG9
GAADWQGxAf8B1QGfAv8B0QGXAv8BzwGLAv8BwwF4Af8B/QG6AWYB/wH5AbYBXAH/AfcBrwFQAf8B+gGt
AUkB/wJdAVsBvQwAATQBTAHfAf8BMgFGAdgB/wEnATMBnQH/ASEBLgF9Af8DSwH/A0sB/wNLAf8DuAH/
A0sB/wNLAf8DSwH/ATQBTAHfAf8BMgFGAdgB/wEnATMBnQH/ASEBLgF9Af8DFAEZAd8BhwE0Af8B2AGG
ATIB/wGdAWgBJwH/AX0BTgEhAf8DSwH/A0sB/wNLAf8DuAH/A0sB/wNLAf8DSwH/Ad8BhwE0Af8B2AGG
ATIB/wGdAWgBJwH/AX0BTgEhAf8DFAEZEAADOQFcA2UB2AF/AYcC/wGDAY0C/wF4AYMC/wFjAXEC/wJg
AWUB2AM5AVwgAAM5AVwBZwFlAWMB2AH/AccBfwL/AcwBgwL/AcIBeAL/AbwBYwH/AmUBYAHYAzkBXBAA
AXABgQH9Af8B7AHlAv8BMgFGAdgB/wErAToBsgH/A7gB/wO4Af8DuAH/A7gB/wO4Af8DpgH/A5gB/wFw
AYEB/QH/AewB5QL/ATIBRgHYAf8BKwE6AbIB/wMUARkB/QG0AXAC/wH9AeUB/wHYAYYBMgH/AbIBdAEr
Af8DuAH/A7gB/wO4Af8DuAH/A7gB/wOmAf8DmAH/Af0BtAFwAv8B/QHlAf8B2AGGATIB/wGyAXQBKwH/
AxQBGRwAAyQBMwMkATM4AAMkATMDJAEzHAADMQFMAXABgQH9Af8BNAFMAd8B/wMxAUwcAAMxAUwBcAGB
Af0B/wE0AUwB3wH/AzEBTAQAAzEBTAH9AbQBcAH/Ad8BhwE0Af8DMQFMHAADMQFMAf0BtAFwAf8B3wGH
ATQB/wMxAUwEAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/AQABjwH/AY8B/wQA
AQcB/wEHAf8EAAEHAf8BBwH/BAABBwH/AQcB/wQAAQMB/wEDAf8EAAHBAY8BwQGPBAAB4AEPAeABDwQA
AfABHwHwAR8EAAH4AT8B+AE/BAAB/AEfAfwBHwQAAf4BDwH+AQ8EAAH/AQEB/wEBBAAB/wGAAf8BgAQA
Af8BwAH/AcAEAAH/AeAB/wHgBAAB/wHhAf8B4QQAAfgBBwH4AQcBjwHxAY8B8QHwAQMB8AEDBAAB4AEB
AeABAQQAAcABAAHABQABgAEAAYABAAEOAWEBDgFhAYABAAGAAQABjgFxAY4BcQGAAQABgAEAAY8B8QGP
AfEEAAGHAcEBhwHBBAABhwHBAYcBwQGAAQABgAEAAY8B8QGPAfEBgAEAAYABAAGPAfEBjwHxAYABAQGA
AQEBjgFxAY4BcQHAAQMBwAEDBAAB4AEHAeABBwQAAfABDwHwAQ8EAAH+AX8B/gF/AQ8B4QEPAeEL
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABA
FwAAAk1TRnQBSQFMAgEBBgEAAUABAAFAAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIBYAAxIBGQMSARkDEgEZNAADEgEZAxIBGQMSARmwAAMwAUwBAgFBAecB/wEC
AS0BoQH/AzABTAMSARksAAMwAUwBswFvASUB/wF5AUkBGwH/AzABTAMSARmsAAEeAV4C/wEWAVgC/wEC
AToBzgH/AQIBLQGhAf8DEgEZLAAB4AGHAS0B/wHZAYYBLAH/AZ4BYwEiAf8BeQFJARsB/wMSARmsAAFy
AZsC/wHoAe8C/wEWAVgC/wECAUEB5wH/AxIBGSwAAf4BtAFqAv8B/QHlAf8B2QGGASwB/wGzAW8BJQH/
AxIBGawAAzABTAFyAZsC/wEeAV4C/wOJAf8DRgH/AyMBMygAAzABTAH+AbQBagH/AeABhwEtAf8BowGJ
AW8B/wNGAf8DIwEzsAADIwEzA7wB/wOBAf8DRgH/AyMBMwgAAyMBMwMjATMDIwEzGAADIwEzA7wB/wOB
Af8DRgH/AyMBMwgAAyMBMwMjATMDIwEznAADIwEzA80B/wOUAf8DRgH/AyMBMwMwAUwDRgH/A5QB/wMj
ATMcAAMjATMDzQH/A5QB/wNGAf8DIwEzAzABTANGAf8DlAH/AyMBM6AAAyMBMwPNAf8DlAH/A0YB/wNG
Af8DlAH/AyMBMyQAAyMBMwPNAf8DlAH/A0YB/wNGAf8DlAH/AyMBM6gAAyMBMwO4Af8DlAH/A4EB/wMj
ATMsAAMjATMDuAH/A5QB/wOBAf8DIwEzsAADIwEzA88B/wOUAf8DRgH/AyMBMywAAyMBMwPPAf8DlAH/
A0YB/wMjATOwAAMjATMDwwH/A5QB/wNGAf8DIwEzLAADIwEzA8MB/wOUAf8DRgH/AyMBM7AAAyMBMwO8
Af8DlAH/A0YB/wMSARkDEgEZAxIBGSQAAyMBMwO8Af8DlAH/A0YB/wMSARkDEgEZAxIBGagAAyMBMwPZ
Af8DtwH/AQIBQQHnAf8BAgEtAaEB/wMwAUwDEgEZJAADIwEzA9kB/wHRAbcBnQH/AbMBbwElAf8BeQFJ
ARsB/wMwAUwDEgEZqAADIwEzAR4BXgL/ARYBWAL/AQIBOgHOAf8BAgEtAaEB/wMSARkoAAMjATMB4AGH
AS0B/wHZAYYBLAH/AZ4BYwEiAf8BeQFJARsB/wMSARmsAAFyAZsC/wHoAe8C/wEWAVgC/wECAUEB5wH/
AxIBGSwAAf4BtAFqAv8B/QHlAf8B2QGGASwB/wGzAW8BJQH/AxIBGawAAzABTAFyAZsC/wEeAV4C/wMw
AUwwAAMwAUwB/gG0AWoB/wHgAYcBLQH/AzABTJgAAwgBCwMfAS0DJwE7AycBOwMnATsDHgErAxIBGAMS
ARggAAMIAQsDHwEtAycBOwMnATsDJwE7Ax4BKwMSARgDEgEYEAADEgEZAxIBGQMSARkgAAMSARkDEgEZ
AxIBGQgAAxIBGQMSARkDEgEZIAADEgEZAxIBGQMSARkUAAM4AVwCXwFkAegBJAEsAYEB/wEeASUBcgH/
AR0BJAFvAf8BHAEjAWgB/wJaAWAB5AM4AVwDJwE7AxIBGBgAAzgBXAFlAWEBXwHoAYEBVwEkAf8BcgFP
AR4B/wFvAU0BHQH/AWgBSAEcAf8BYQJaAeQDOAFcAycBOwMSARgIAAMwAUwBJgE1AbIB/wEcASkBeAH/
AzABTAMSARkDEgEZAxIBGQMSARkDEgEZAxIBGQMSARkDMAFMASYBNQGyAf8BHAEpAXgB/wMwAUwDEgEZ
AzABTAGyAW8BJgH/AXgBSQEcAf8DMAFMAxIBGQMSARkDEgEZAxIBGQMSARkDEgEZAxIBGQMwAUwBsgFv
ASYB/wF4AUkBHAH/AzABTAMSARkMAANaAcUBNAFAAbsB/wEyAT4BvAH/ATEBPQG6Af8BMAE8AbcB/wEu
ATgBtAH/ASwBNwGsAf8BJwEvAZQB/wEdASUBcgH/A1oBvQMnATsDEgEYEAADWgHFAbsBgwE0Af8BvAGC
ATIB/wG6AYEBMQH/AbcBgQEwAf8BtAGBAS4B/wGsAXUBLAH/AZQBZwEnAf8BcgFOAR0B/wNaAb0DJwE7
AxIBGAQAAS8BRwHfAf8BLQFBAdgB/wEiAS4BnQH/ARwBKQF4Af8DPwH/Az8B/wM/Af8DPwH/Az8B/wM/
Af8DPwH/AS8BRwHfAf8BLQFBAdgB/wEiAS4BnQH/ARwBKQF4Af8DEgEZAd8BhwEvAf8B2AGGAS0B/wGd
AWMBIgH/AXgBSQEcAf8DPwH/Az8B/wM/Af8DPwH/Az8B/wM/Af8DPwH/Ad8BhwEvAf8B2AGGAS0B/wGd
AWMBIgH/AXgBSQEcAf8DEgEZCAADWQG+ATkBRgHTAf8BPgFNAegB/wFCAVAB8wH/AUEBUAHwAf8BQAFQ
Ae8B/wFAAVAB7wH/AT8BTQHtAf8BPAFLAeIB/wEyAT4BuwH/ASIBKQGBAf8DWgG9AycBOwMSARgIAANZ
Ab4B0wGTATkB/wHoAaEBPgH/AfMBqgFCAf8B8AGnAUEB/wHvAaUBQAH/Ae8BpQFAAf8B7QGlAT8B/wHi
AZwBPAH/AbsBggEyAf8BgQFZASIB/wNaAb0DJwE7AxIBGAFrAYEB/QH/AewB5QL/AS0BQQHYAf8BJgE1
AbIB/wO4Af8DuAH/A7gB/wO4Af8DuAH/A6YB/wOYAf8BawGBAf0B/wHsAeUC/wEtAUEB2AH/ASYBNQGy
Af8DEgEZAf0BtAFrAv8B/QHlAf8B2AGGAS0B/wGyAW8BJgH/A7gB/wO4Af8DuAH/A7gB/wO4Af8DpgH/
A5gB/wH9AbQBawL/Af0B5QH/AdgBhgEtAf8BsgFvASYB/wMSARkEAAM4AVwBQgFQAeMB/wFBAU8B8QH/
ATEBPAGzAf8BLwE6AasB/wE/AU0B6gH/AUQBVAH6Af8BQwFSAfYB/wFBAU8B8QH/AUEBUAHwAf8BPgFM
AeoB/wExATwBvgH/ASEBJwGBAf8DOAFcAxIBGAQAAzgBXAHjAaABQgH/AfEBqAFBAf8BswGBATEB/wGr
AXYBLwH/AeoBowE/Af8B+gGuAUQB/wH2AawBQwH/AfEBqAFBAf8B8AGnAUEB/wHqAaMBPgH/Ab4BhAEx
Af8BgQFYASEB/wM4AVwDEgEYAzABTAFrAYEB/QH/AS8BRwHfAf8DMAFMDAADuAH/A04BmQgAAzABTAFr
AYEB/QH/AS8BRwHfAf8DMAFMBAADMAFMAf0BtAFrAf8B3wGHAS8B/wMwAUwMAAO4Af8DTgGZCAADMAFM
Af0BtAFrAf8B3wGHAS8B/wMwAUwIAANfAdsBUQFfAfYB/wFLAVoC/wExATwBsQH/AwIB/wEKAQwBJgH/
AR8BJgFyAf8BNgFBAcIB/wFBAVEB8QH/AUQBVAH6Af8BQgFSAfQB/wE7AUkB5AH/ASwBNwGsAf8CXAFk
AecDHgErBAADXwHbAfYBsQFRAv8BtAFLAf8BsQF6ATEB/wMCAf8BJgEbAQoB/wFyAU8BHwH/AcIBiAE2
Af8B8QGnAUEB/wH6Aa4BRAH/AfQBqQFCAf8B5AGeATsB/wGsAXUBLAH/AWQBYgFcAecDHgErBAADmAH/
A0YB/wMSARkMAAOlAf8DTgGZDAADmAH/Az8B/wMSARkIAAOYAf8DRgH/AxIBGQwAA6UB/wNOAZkMAAOY
Af8DPwH/AxIBGQgAAU4BXAL/AWYBdAL/AVUBYgH7Af8BRwFVAegB/wEKAQsBHAH/AwIB/wMCAf8DAgH/
AQ4BEQE1Af8BJAEsAYQB/wE4AUQBzgH/AUABTwHvAf8BNgFCAcwB/wElAS4BigH/AycBOwQAAf8BtgFO
Av8BvgFmAf8B+wG3AVUB/wHoAaUBRwH/ARwBFQEKAf8DAgH/AwIB/wMCAf8BNQElAQ4B/wGEAVsBJAH/
Ac4BkAE4Af8B7wGmAUAB/wHMAY4BNgH/AYoBXwElAf8DJwE7BAADpgH/A0YB/wMSARkgAAOmAf8DPwH/
AxIBGQgAA6YB/wNGAf8DEgEZIAADpgH/Az8B/wMSARkEAAMjATMBYQFuAv8BdwGEAv8BXwFrAfkB/wFR
AWAB/AH/ASIBKgF3Af8DAgH/AwIB/wMCAf8BCAEJAQ8B/wEbASIBYQH/ASsBNAGdAf8BPgFLAeQB/wE7
AUoB4QH/ASgBMQGcAf8DJwE7AyMBMwH/Ab0BYQL/AcYBdwH/AfkBugFfAf8B/AG0AVEB/wF3AVMBIgH/
AwIB/wMCAf8DAgH/AQ8BDAEIAf8BYQFDARsB/wGdAW0BKwH/AeQBoAE+Af8B4QGbATsB/wGcAWsBKAH/
AycBOwQAA7AB/wNGAf8DTgGZA04BmRQAA04BmQNOAZkDsAH/Az8B/wMSARkIAAOwAf8DRgH/A04BmQNO
AZkUAANOAZkDTgGZA7AB/wM/Af8DEgEZBAADIwEzAWsBeAL/AYEBjAL/AWABbgH4Af8BTwFfAfsB/wE3
AUMBywH/AgMBBQH/AwIB/wMCAf8BFAEYAUcB/wFEAVMB+QH/AUQBVAH6Af8BQQFQAfAB/wE7AUkB4wH/
ASkBMwGiAf8DJwE7AyMBMwH/AcEBawL/AcoBgQH/AfgBuAFgAf8B+wGyAU8B/wHLAY4BNwH/AQUBBAED
Af8DAgH/AwIB/wFHATIBFAH/AfkBrgFEAf8B+gGuAUQB/wHwAacBQQH/AeMBnQE7Af8BogFvASkB/wMn
ATsEAAO4Af8DuAH/A7gB/wOlAf8UAAOlAf8DuAH/A7gB/wM/Af8DEgEZCAADuAH/A7gB/wO4Af8DpQH/
FAADpQH/A7gB/wO4Af8DPwH/AxIBGQgAAWkBeAL/AY4BlwL/AWgBcwH+Af8BUQFgAfUB/wFHAVUB+AH/
ARMBGAFHAf8BBQEEAQYB/wEgASgBdgH/AwIB/wEXAR0BVgH/AUEBUAHwAf8BQgFQAfMB/wE5AUcB2gH/
ASsBNAGfAf8DIgExBAAB/wG/AWkC/wHQAY4B/wH+AcEBaAH/AfUBsAFRAf8B+AGvAUcB/wFHATEBEwH/
AgYBBAH/AXYBUQEgAf8DAgH/AVYBOwEXAf8B8AGnAUEB/wHzAaoBQgH/AdoBlwE5Af8BnwFvASsB/wMi
ATEEAAO4Af8DRgH/AxIBGSAAA7gB/wM/Af8DEgEZCAADuAH/A0YB/wMSARkgAAO4Af8DPwH/AxIBGQgA
A18B2wGWAaAC/wGGAZAC/wFpAXYB+QH/AVQBYgH+Af8BLAE2AZ0B/wESARcBQwH/AUYBVgL/ASoBMwGY
Af8DAgH/ARcBHQFWAf8BQAFPAe0B/wE5AUYB1QH/AlwBZAHqAwwBEAQAA18B2wH/AdIBlgL/AcwBhgH/
AfkBvAFpAf8B/gG4AVQB/wGdAW0BLAH/AUMBLgESAv8BsgFGAf8BmAFqASoB/wMCAf8BVgE7ARcB/wHt
AaUBQAH/AdUBlAE5Af8BZQFiAVwB6gMMARAEAAO4Af8DRgH/AxIBGSAAA7gB/wM/Af8DEgEZCAADuAH/
A0YB/wMSARkgAAO4Af8DPwH/AxIBGQgAAzgBXAGYAaIC/wGeAacC/wFyAYEC/wFeAWsB+QH/AUkBVAHk
Af8BOgFFAb4B/wFKAVoB+AH/AUwBWgH9Af8BMwE7AZwB/wMCAf8BMAE6AbEB/wE8AUkB3gH/AzgBXAgA
AzgBXAH/AdMBmAL/AdYBngL/AcUBcgH/AfkBuQFeAf8B5AGlAUkB/wG+AYcBOgH/AfgBrgFKAf8B/QG0
AUwB/wGcAXABMwH/AwIB/wGxAYABMAH/Ad4BmwE8Af8DOAFcCAADuAH/A0YB/wMSARkMAAOlAf8DTgGZ
DAADuAH/Az8B/wMSARkIAAO4Af8DRgH/AxIBGQwAA6UB/wNOAZkMAAO4Af8DPwH/AxIBGQwAA1UBsgGo
AbEC/wGJAZMC/wF4AYMC/wFvAYAB/AH/AWQBcAH2Af8BXgFqAfYB/wFdAWkB9QH/AVkBZgH7Af8BPAFG
AcIB/wE9AUsB4AH/A1sBxhAAA1UBsgH/AdkBqAL/Ac4BiQL/AcgBeAH/AfwBwQFvAf8B9gG5AWQB/wH2
AbcBXgH/AfUBtgFdAf8B+wG4AVkB/wHCAYsBPAH/AeABnAE9Af8DWwHGCAADMAFMASYBNQGyAf8BHAEp
AXgB/wMwAUwDEgEZAxIBGQMSARkDuAH/A04BmQMSARkDEgEZAzABTAEmATUBsgH/ARwBKQF4Af8DMAFM
AxIBGQMwAUwBsgFvASYB/wF4AUkBHAH/AzABTAMSARkDEgEZAxIBGQO4Af8DTgGZAxIBGQMSARkDMAFM
AbIBbwEmAf8BeAFJARwB/wMwAUwDEgEZDAADVgGxAZ8BqQL/AZcBogL/AYsBlQL/AXMBggL/AWEBcAH9
Af8BVwFkAfkB/wFLAVoB9wH/AUQBVAH6Af8DWgG9GAADVgGxAf8B1QGfAv8B0QGXAv8BzwGLAv8BwwFz
Af8B/QG6AWEB/wH5AbYBVwH/AfcBrwFLAf8B+gGtAUQB/wNaAb0MAAEvAUcB3wH/AS0BQQHYAf8BIgEu
AZ0B/wEcASkBeAH/A0YB/wNGAf8DRgH/A7gB/wNGAf8DRgH/A0YB/wEvAUcB3wH/AS0BQQHYAf8BIgEu
AZ0B/wEcASkBeAH/AxIBGQHfAYcBLwH/AdgBhgEtAf8BnQFjASIB/wF4AUkBHAH/A0YB/wNGAf8DRgH/
A7gB/wNGAf8DRgH/A0YB/wHfAYcBLwH/AdgBhgEtAf8BnQFjASIB/wF4AUkBHAH/AxIBGRAAAzgBXANe
AdgBegGHAv8BgwGNAv8BcwGDAv8BXgFsAv8DXgHYAzgBXCAAAzgBXANeAdgB/wHHAXoC/wHMAYMC/wHC
AXMC/wG8AV4B/wNeAdgDOAFcEAABawGBAf0B/wHsAeUC/wEtAUEB2AH/ASYBNQGyAf8DuAH/A7gB/wO4
Af8DuAH/A7gB/wOmAf8DmAH/AWsBgQH9Af8B7AHlAv8BLQFBAdgB/wEmATUBsgH/AxIBGQH9AbQBawL/
Af0B5QH/AdgBhgEtAf8BsgFvASYB/wO4Af8DuAH/A7gB/wO4Af8DuAH/A6YB/wOYAf8B/QG0AWsC/wH9
AeUB/wHYAYYBLQH/AbIBbwEmAf8DEgEZHAADIwEzAyMBMzgAAyMBMwMjATMcAAMwAUwBawGBAf0B/wEv
AUcB3wH/AzABTBwAAzABTAFrAYEB/QH/AS8BRwHfAf8DMAFMBAADMAFMAf0BtAFrAf8B3wGHAS8B/wMw
AUwcAAMwAUwB/QG0AWsB/wHfAYcBLwH/AzABTAQAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEB
BgABARYAA/8BAAGPAf8BjwH/BAABBwH/AQcB/wQAAQcB/wEHAf8EAAEHAf8BBwH/BAABAwH/AQMB/wQA
AcEBjwHBAY8EAAHgAQ8B4AEPBAAB8AEfAfABHwQAAfgBPwH4AT8EAAH8AR8B/AEfBAAB/gEPAf4BDwQA
Af8BAQH/AQEEAAH/AYAB/wGABAAB/wHAAf8BwAQAAf8B4AH/AeAEAAH/AeEB/wHhBAAB+AEHAfgBBwGP
AfEBjwHxAfABAwHwAQMEAAHgAQEB4AEBBAABwAEAAcAFAAGAAQABgAEAAQ4BYQEOAWEBgAEAAYABAAGO
AXEBjgFxAYABAAGAAQABjwHxAY8B8QQAAYcBwQGHAcEEAAGHAcEBhwHBAYABAAGAAQABjwHxAY8B8QGA
AQABgAEAAY8B8QGPAfEBgAEBAYABAQGOAXEBjgFxAcABAwHAAQMEAAHgAQcB4AEHBAAB8AEPAfABDwQA
Af4BfwH+AX8BDwHhAQ8B4Qs=
</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

View file

@ -0,0 +1,214 @@
using System;
using System.Collections.Generic;
using System.Text;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Types;
namespace CodeImp.DoomBuilder.TagExplorer
{
internal sealed class NodeInfo
{
private NodeInfoType type;
private int index;
private int action;
private int tag;
private int thingType;
private string defaultName;
public int Index { get { return index; } }
public int Tag { get { return tag; } }
public int Action { get { return action; } }
public int ThingType {
get {
if (type != NodeInfoType.THING)
throw new Exception("Error: ThingType property accessed in " + type.ToString() + " node!");
return thingType;
}
}
public NodeInfoType Type { get { return type; } }
public string Comment { get { return getComment(); } set { setComment(value); } }
public string DefaultName { get { return defaultName; } }
//constructor
public NodeInfo(Thing t) {
type = NodeInfoType.THING;
index = t.Index;
action = t.Action;
tag = t.Tag;
thingType = t.Type;
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(t.Type);
defaultName = (tti != null ? tti.Title : NodeInfoDefaultName.THING);
}
public NodeInfo(Sector s) {
type = NodeInfoType.SECTOR;
index = s.FixedIndex;
action = s.Effect;
tag = s.Tag;
}
public NodeInfo(Linedef l) {
type = NodeInfoType.LINEDEF;
index = l.Index;
action = l.Action;
tag = l.Tag;
}
//methods
private UniFields getFields() {
if (type == NodeInfoType.THING) {
Thing t = General.Map.Map.GetThingByIndex(index);
if (t == null) return null;
return t.Fields;
}
if (type == NodeInfoType.SECTOR) {
Sector s = General.Map.Map.GetSectorByIndex(index);
if (s == null) return null;
return s.Fields;
}
Linedef l = General.Map.Map.GetLinedefByIndex(index);
if (l == null) return null;
return l.Fields;
}
public Vector2D GetPosition() {
switch (type){
case NodeInfoType.THING:
Thing t = General.Map.Map.GetThingByIndex(index);
if (t != null) return new Vector2D(t.Position.x, t.Position.y);
return new Vector2D();
break;
case NodeInfoType.SECTOR:
Sector s = General.Map.Map.GetSectorByIndex(index);
if (s != null) return new Vector2D(s.BBox.Location.X + s.BBox.Width / 2, s.BBox.Location.Y + s.BBox.Height / 2);
return new Vector2D();
break;
case NodeInfoType.LINEDEF:
Linedef l = General.Map.Map.GetLinedefByIndex(index);
if (l != null) return new Vector2D(l.Rect.Location.X + l.Rect.Width / 2, l.Rect.Location.Y + l.Rect.Height / 2);
return new Vector2D();
break;
default:
return new Vector2D();
break;
}
}
//comment
private void setComment(string comment) {
UniFields fields = getFields();
if (comment == "") {
if (fields.ContainsKey("comment")) fields.Remove("comment");
return;
}
if (!fields.ContainsKey("comment"))
fields.Add("comment", new UniValue((int)UniversalType.String, comment));
else
fields["comment"].Value = comment;
}
private string getComment() {
UniFields fields = getFields();
if (fields == null) return "";
if (!fields.ContainsKey("comment")) return "";
return fields["comment"].Value.ToString();
}
//naming
public string GetName(ref string comment, string sortMode) {
if (type == NodeInfoType.THING) {
Thing t = General.Map.Map.GetThingByIndex(index);
if (t == null) return "<invalid thing>";
return getThingName(t, ref comment, sortMode);
}
if (type == NodeInfoType.SECTOR) {
Sector s = General.Map.Map.GetSectorByIndex(index);
if (s == null) return "<invalid sector>";
return getSectorName(s, ref comment, sortMode);
}
Linedef l = General.Map.Map.GetLinedefByIndex(index);
if (l == null) return "<invalid linedef>";
return getLinedefName(l, ref comment, sortMode);
}
private string getThingName(Thing t, ref string comment, string sortMode) {
bool isDefaultName = true;
comment = "";
if (GZBuilder.GZGeneral.UDMF && t.Fields.ContainsKey("comment")) {
comment = t.Fields["comment"].Value.ToString();
isDefaultName = false;
}
return combineName(comment == "" ? defaultName : comment, t.Tag, t.Action, t.Index, sortMode, isDefaultName);
}
private string getSectorName(Sector s, ref string comment, string sortMode) {
bool isDefaultName = true;
comment = "";
if (GZBuilder.GZGeneral.UDMF && s.Fields.ContainsKey("comment")) {
comment = s.Fields["comment"].Value.ToString();
isDefaultName = false;
}
return combineName(comment == "" ? NodeInfoDefaultName.SECTOR : comment, s.Tag, s.Effect, s.FixedIndex, sortMode, isDefaultName);
}
private string getLinedefName(Linedef l, ref string comment, string sortMode) {
bool isDefaultName = true;
comment = "";
if (GZBuilder.GZGeneral.UDMF && l.Fields.ContainsKey("comment")) {
comment = l.Fields["comment"].Value.ToString();
isDefaultName = false;
}
return combineName(comment == "" ? NodeInfoDefaultName.LINEDEF : comment, l.Tag, l.Action, l.Index, sortMode, isDefaultName);
}
private string combineName(string name, int tag, int action, int index, string sortMode, bool isDefaultName) {
string combinedName = "";
switch (sortMode) {
case SortMode.SORT_BY_ACTION:
combinedName = (action > 0 ? "Action:" + action + "; " : "") + (tag > 0 ? "Tag:" + tag + "; " : "") + name + (isDefaultName ? " " + index : "");
break;
case SortMode.SORT_BY_INDEX:
combinedName = index + (tag > 0 ? ": Tag:" + tag + "; " : ": ") + (action > 0 ? "Action:" + action + "; " : "") + name;
break;
case SortMode.SORT_BY_TAG:
combinedName = (tag > 0 ? "Tag:" + tag + "; " : "") + (action > 0 ? "Action:" + action + "; " : "") + name + (isDefaultName ? " " + index : "");
break;
default:
combinedName = name;
break;
}
return combinedName;
}
}
internal enum NodeInfoType
{
THING,
SECTOR,
LINEDEF
}
internal struct NodeInfoDefaultName
{
public const string THING = "Thing";
public const string SECTOR = "Sector";
public const string LINEDEF = "Linedef";
}
}

View file

@ -35,8 +35,10 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BuilderPlug.cs" />
@ -46,6 +48,7 @@
<Compile Include="Controls\TagExplorer.Designer.cs">
<DependentUpon>TagExplorer.cs</DependentUpon>
</Compile>
<Compile Include="NodeInfo.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>