diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index b132a85..31477f2 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -87,6 +87,7 @@
+
diff --git a/Source/Core/Config/ScriptDocumentSettings.cs b/Source/Core/Config/ScriptDocumentSettings.cs
new file mode 100644
index 0000000..6d21e6e
--- /dev/null
+++ b/Source/Core/Config/ScriptDocumentSettings.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace CodeImp.DoomBuilder.Config
+{
+ internal struct ScriptDocumentSettings
+ {
+ public Dictionary> FoldLevels; //
+ public int CaretPosition;
+ public int FirstVisibleLine;
+ public string Filename;
+ public bool IsActiveTab;
+ public long Hash;
+ }
+}
\ No newline at end of file
diff --git a/Source/Core/Controls/ScriptDocumentTab.cs b/Source/Core/Controls/ScriptDocumentTab.cs
index 35e6669..ba1f0a4 100644
--- a/Source/Core/Controls/ScriptDocumentTab.cs
+++ b/Source/Core/Controls/ScriptDocumentTab.cs
@@ -409,6 +409,63 @@ namespace CodeImp.DoomBuilder.Controls
editor.IndentSelection(indent);
}
+ //mxd
+ internal void SetViewSettings(ScriptDocumentSettings settings)
+ {
+ // Text must be exactly the same
+ long hash = MurmurHash2.Hash(Text);
+ if (hash != settings.Hash) return;
+
+ // Restore fold levels
+ if (settings.FoldLevels != null && General.Settings.ScriptShowFolding && (Scintilla.Lexer == Lexer.Cpp || Scintilla.Lexer == Lexer.CppNoCase))
+ {
+ // We'll want to fold deeper levels first...
+ int[] fl = new int[settings.FoldLevels.Keys.Count];
+ settings.FoldLevels.Keys.CopyTo(fl, 0);
+
+ List foldlevels = new List(fl);
+ foldlevels.Sort((a, b) => -1 * a.CompareTo(b)); // Sort in descending order
+
+ foreach (int level in foldlevels)
+ {
+ foreach (int line in settings.FoldLevels[level])
+ Scintilla.Lines[line].FoldLine(FoldAction.Contract);
+ }
+ }
+
+ // Restore scroll
+ Scintilla.FirstVisibleLine = settings.FirstVisibleLine;
+
+ // Restore caret position
+ Scintilla.SetEmptySelection(settings.CaretPosition);
+ }
+
+ //mxd
+ internal ScriptDocumentSettings GetViewSettings()
+ {
+ Dictionary> foldlevels = new Dictionary>();
+
+ for (int i = 0; i < Scintilla.Lines.Count; i++)
+ {
+ if (!Scintilla.Lines[i].Expanded)
+ {
+ if (!foldlevels.ContainsKey(Scintilla.Lines[i].FoldLevel))
+ foldlevels.Add(Scintilla.Lines[i].FoldLevel, new HashSet());
+ foldlevels[Scintilla.Lines[i].FoldLevel].Add(i);
+ }
+ }
+
+ return new ScriptDocumentSettings
+ {
+ Filename = this.Filename,
+ FoldLevels = foldlevels,
+ CaretPosition = Scintilla.SelectionStart,
+ IsActiveTab = (this.Panel.ActiveTab == this),
+ FirstVisibleLine = Scintilla.FirstVisibleLine,
+ Hash = MurmurHash2.Hash(Text),
+ };
+ }
+
#endregion
#region ================== Events
diff --git a/Source/Core/Controls/ScriptEditorPanel.cs b/Source/Core/Controls/ScriptEditorPanel.cs
index aff6ab4..dba9a72 100644
--- a/Source/Core/Controls/ScriptEditorPanel.cs
+++ b/Source/Core/Controls/ScriptEditorPanel.cs
@@ -19,7 +19,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
-using System.Globalization;
using System.IO;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Compilers;
@@ -119,6 +118,7 @@ namespace CodeImp.DoomBuilder.Controls
openfile.Filter = "Script files|" + filterall + "|" + filterseperate + "|All files|*.*";
// Load the script lumps
+ ScriptDocumentTab activetab = null; //mxd
foreach (MapLumpInfo maplumpinfo in General.Map.Config.MapLumps.Values)
{
// Is this a script lump?
@@ -126,6 +126,15 @@ namespace CodeImp.DoomBuilder.Controls
{
// Load this!
ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler]);
+
+ //mxd. Apply stored settings?
+ if (General.Map.Options.ScriptLumpSettings.ContainsKey(maplumpinfo.Name))
+ {
+ t.SetViewSettings(General.Map.Options.ScriptLumpSettings[maplumpinfo.Name]);
+ if (General.Map.Options.ScriptLumpSettings[maplumpinfo.Name].IsActiveTab)
+ activetab = t;
+ }
+
t.OnTextChanged += tabpage_OnLumpTextChanged; //mxd
t.Scintilla.UpdateUI += scintilla_OnUpdateUI; //mxd
tabs.TabPages.Add(t);
@@ -134,6 +143,15 @@ namespace CodeImp.DoomBuilder.Controls
{
// Load this!
ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, maplumpinfo.Script);
+
+ //mxd. Apply stored settings?
+ if (General.Map.Options.ScriptLumpSettings.ContainsKey(maplumpinfo.Name))
+ {
+ t.SetViewSettings(General.Map.Options.ScriptLumpSettings[maplumpinfo.Name]);
+ if (General.Map.Options.ScriptLumpSettings[maplumpinfo.Name].IsActiveTab)
+ activetab = t;
+ }
+
t.OnTextChanged += tabpage_OnLumpTextChanged; //mxd
t.Scintilla.UpdateUI += scintilla_OnUpdateUI; //mxd
tabs.TabPages.Add(t);
@@ -157,6 +175,15 @@ namespace CodeImp.DoomBuilder.Controls
if (l.Name.ToUpperInvariant().StartsWith(scriptlumpinfo.Name.ToUpperInvariant()))
{
GlobalScriptLumpDocumentTab t = new GlobalScriptLumpDocumentTab(this, l.Name, scriptlumpinfo.Script, General.Map.FilePathName);
+
+ //mxd. Apply stored settings?
+ if (General.Map.Options.ScriptFileSettings.ContainsKey(l.Name))
+ {
+ t.SetViewSettings(General.Map.Options.ScriptFileSettings[l.Name]);
+ if (General.Map.Options.ScriptFileSettings[l.Name].IsActiveTab)
+ activetab = t;
+ }
+
t.OnTextChanged += tabpage_OnTextChanged;
t.Scintilla.UpdateUI += scintilla_OnUpdateUI;
tabs.TabPages.Add(t);
@@ -166,6 +193,15 @@ namespace CodeImp.DoomBuilder.Controls
else
{
GlobalScriptLumpDocumentTab t = new GlobalScriptLumpDocumentTab(this, scriptlumpinfo.Name, scriptlumpinfo.Script, General.Map.FilePathName);
+
+ //mxd. Apply stored settings?
+ if (General.Map.Options.ScriptFileSettings.ContainsKey(scriptlumpinfo.Name))
+ {
+ t.SetViewSettings(General.Map.Options.ScriptFileSettings[scriptlumpinfo.Name]);
+ if (General.Map.Options.ScriptFileSettings[scriptlumpinfo.Name].IsActiveTab)
+ activetab = t;
+ }
+
t.OnTextChanged += tabpage_OnTextChanged;
t.Scintilla.UpdateUI += scintilla_OnUpdateUI;
tabs.TabPages.Add(t);
@@ -175,20 +211,30 @@ namespace CodeImp.DoomBuilder.Controls
}
// Load the files that were previously opened for this map
- foreach (String filename in General.Map.Options.ScriptFiles)
+ foreach (ScriptDocumentSettings settings in General.Map.Options.ScriptFileSettings.Values)
{
// Does this file exist?
- if (File.Exists(filename))
+ if (File.Exists(settings.Filename))
{
// Load this!
- OpenFile(filename);
+ ScriptFileDocumentTab t = OpenFile(settings.Filename);
+ t.SetViewSettings(settings); //mxd
+ if (settings.IsActiveTab) activetab = t;
}
}
+ //mxd. Reselect previously selected tab
+ if (activetab != null)
+ {
+ tabs.SelectedTab = activetab;
+ }
//mxd. Select "Scripts" tab, because that's what user will want 99% of time
//MascaraSnake: For SRB2, select "MAINCFG" tab
- int scriptsindex = General.Map.SRB2 ? GetTabPageIndex("MAINCFG") : GetTabPageIndex("SCRIPTS");
- tabs.SelectedIndex = (scriptsindex == -1 ? 0 : scriptsindex);
+ else
+ {
+ int scriptsindex = General.Map.SRB2 ? GetTabPageIndex("MAINCFG") : GetTabPageIndex("SCRIPTS");
+ tabs.SelectedIndex = (scriptsindex == -1 ? 0 : scriptsindex);
+ }
//mxd. Apply quick search settings
searchmatchcase.Checked = matchcase;
@@ -452,12 +498,16 @@ namespace CodeImp.DoomBuilder.Controls
// This writes all explicitly opened files to the configuration
public void WriteOpenFilesToConfiguration()
{
- List files = new List();
- foreach (ScriptDocumentTab t in tabs.TabPages)
+ General.Map.Options.ScriptFileSettings.Clear(); //mxd
+ General.Map.Options.ScriptLumpSettings.Clear(); //mxd
+
+ foreach (ScriptDocumentTab t in tabs.TabPages) //mxd
{
- if (t.ExplicitSave) files.Add(t.Filename);
+ if (t.ExplicitSave)
+ General.Map.Options.ScriptFileSettings.Add(t.Filename, t.GetViewSettings());
+ else
+ General.Map.Options.ScriptLumpSettings.Add(t.Filename, t.GetViewSettings());
}
- General.Map.Options.ScriptFiles = files;
}
// This asks to save files and returns the result
diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs
index 74a95ff..7609905 100644
--- a/Source/Core/General/MapManager.cs
+++ b/Source/Core/General/MapManager.cs
@@ -251,7 +251,7 @@ namespace CodeImp.DoomBuilder
// Apply settings
this.filetitle = options.CurrentName + ".wad";
- this.filepathname = "";
+ this.filepathname = String.Empty;
this.maploading = true; //mxd
this.changed = false;
this.options = options;
@@ -956,9 +956,9 @@ namespace CodeImp.DoomBuilder
General.ShowErrorMessage("Error renaming map lump name: the original map lump could not be found!", MessageBoxButtons.OK);
options.CurrentName = options.PreviousName;
}
-
}
- options.PreviousName = "";
+
+ options.PreviousName = String.Empty;
}
// Done with the target file
@@ -1194,15 +1194,15 @@ namespace CodeImp.DoomBuilder
else
{
//mxd. collect errors
- string compilererrors = "";
+ string compilererrors = String.Empty;
foreach(CompilerError e in compiler.Errors)
compilererrors += Environment.NewLine + e.description;
// Nodebuilder did not build the lumps!
if(failaswarning)
- General.ShowWarningMessage("Unable to build the nodes: The nodebuilder failed to build the expected data structures.\nThe map will be saved without the nodes." + (compiler.Errors.Length > 0 ? Environment.NewLine + compilererrors : ""), MessageBoxButtons.OK);
+ General.ShowWarningMessage("Unable to build the nodes: The nodebuilder failed to build the expected data structures.\nThe map will be saved without the nodes." + (compiler.Errors.Length > 0 ? Environment.NewLine + compilererrors : String.Empty), MessageBoxButtons.OK);
else
- General.ShowErrorMessage("Unable to build the nodes: The nodebuilder failed to build the expected data structures." + (compiler.Errors.Length > 0 ? Environment.NewLine + compilererrors : ""), MessageBoxButtons.OK);
+ General.ShowErrorMessage("Unable to build the nodes: The nodebuilder failed to build the expected data structures." + (compiler.Errors.Length > 0 ? Environment.NewLine + compilererrors : String.Empty), MessageBoxButtons.OK);
}
// Done with the build wad
@@ -1211,7 +1211,7 @@ namespace CodeImp.DoomBuilder
else //mxd
{
//collect errors
- string compilererrors = "";
+ string compilererrors = String.Empty;
foreach(CompilerError e in compiler.Errors)
compilererrors += Environment.NewLine + e.description;
@@ -2081,7 +2081,7 @@ namespace CodeImp.DoomBuilder
//INFO: also, error.linenumber is zero-based
foreach(CompilerError error in compilererrors)
{
- General.ErrorLogger.Add(ErrorType.Error, "ACS error in '" + (error.filename.StartsWith("?") ? error.filename.Replace("?", "") : error.filename)
+ General.ErrorLogger.Add(ErrorType.Error, "ACS error in '" + (error.filename.StartsWith("?") ? error.filename.Replace("?", String.Empty) : error.filename)
+ (error.linenumber != CompilerError.NO_LINE_NUMBER ? "', line " + (error.linenumber + 1) : "'")
+ ". " + error.description + ".");
}
diff --git a/Source/Core/Map/MapOptions.cs b/Source/Core/Map/MapOptions.cs
index 95a96cf..8553219 100644
--- a/Source/Core/Map/MapOptions.cs
+++ b/Source/Core/Map/MapOptions.cs
@@ -16,16 +16,18 @@
#region ================== Namespaces
+using System;
using System.Collections;
using System.Collections.Generic;
+using System.Collections.Specialized;
using System.Globalization;
+using System.IO;
using System.Reflection;
+using CodeImp.DoomBuilder.Config;
+using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.IO;
-using System.IO;
-using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Plugins;
-using System.Collections.Specialized;
#endregion
@@ -40,7 +42,7 @@ namespace CodeImp.DoomBuilder.Map
#region ================== Variables
// Map configuration
- private Configuration mapconfig;
+ private readonly Configuration mapconfig;
// Game configuration
private string configfile;
@@ -55,11 +57,12 @@ namespace CodeImp.DoomBuilder.Map
// Additional resources
private DataLocationList resources;
- // Script files opened
- private List scriptfiles;
+ //mxd. View settings for opened script files and lumps
+ private Dictionary scriptfilesettings;
+ private Dictionary scriptlumpsettings;
- // mxd. Script compiler
- private string scriptcompiler;
+ // mxd. Script compiler
+ private string scriptcompiler;
//mxd. Sector drawing options
private string defaultfloortexture;
@@ -85,8 +88,8 @@ namespace CodeImp.DoomBuilder.Map
private bool uselongtexturenames;
//mxd. Position and scale
- private Vector2D viewposition;
- private float viewscale;
+ private readonly Vector2D viewposition;
+ private readonly float viewscale;
#endregion
@@ -95,9 +98,10 @@ namespace CodeImp.DoomBuilder.Map
internal string ConfigFile { get { return configfile; } set { configfile = value; } }
internal DataLocationList Resources { get { return resources; } }
internal bool StrictPatches { get { return strictpatches; } set { strictpatches = value; } }
- internal List ScriptFiles { get { return scriptfiles; } set { scriptfiles = value; } }
- internal string ScriptCompiler { get { return scriptcompiler; } set { scriptcompiler = value; } } //mxd
- internal string PreviousName { get { return previousname; } set { previousname = value; } }
+ internal Dictionary ScriptFileSettings { get { return scriptfilesettings; } } //mxd
+ internal Dictionary ScriptLumpSettings { get { return scriptlumpsettings; } } //mxd
+ internal string ScriptCompiler { get { return scriptcompiler; } set { scriptcompiler = value; } } //mxd
+ internal string PreviousName { get { return previousname; } set { previousname = value; } }
internal string CurrentName
{
get { return currentname; }
@@ -159,9 +163,10 @@ namespace CodeImp.DoomBuilder.Map
this.strictpatches = false;
this.resources = new DataLocationList();
this.mapconfig = new Configuration(true);
- this.scriptfiles = new List();
- this.scriptcompiler = ""; //mxd
- this.tagLabels = new Dictionary(); //mxd
+ this.scriptfilesettings = new Dictionary(); //mxd
+ this.scriptlumpsettings = new Dictionary(); //mxd
+ this.scriptcompiler = ""; //mxd
+ this.tagLabels = new Dictionary(); //mxd
this.viewposition = new Vector2D(float.NaN, float.NaN); //mxd
this.viewscale = float.NaN; //mxd
@@ -180,8 +185,9 @@ namespace CodeImp.DoomBuilder.Map
this.configfile = cfg.ReadSetting("gameconfig", "");
this.resources = new DataLocationList();
this.mapconfig = new Configuration(true);
- this.scriptfiles = new List();
-
+ this.scriptfilesettings = new Dictionary(); //mxd
+ this.scriptlumpsettings = new Dictionary(); //mxd
+
// Read map configuration
this.mapconfig.Root = cfg.ReadSetting("maps." + mapname, new Hashtable());
@@ -243,11 +249,11 @@ namespace CodeImp.DoomBuilder.Map
IDictionary reslist = this.mapconfig.ReadSetting("resources", new Hashtable());
foreach(DictionaryEntry mp in reslist)
{
- // Item is a structure?
- if(mp.Value is IDictionary)
- {
+ // Item is a structure?
+ IDictionary resinfo = mp.Value as IDictionary;
+ if (resinfo != null)
+ {
// Create resource
- IDictionary resinfo = (IDictionary)mp.Value;
DataLocation res = new DataLocation();
// Copy information from Configuration to ResourceLocation
@@ -261,25 +267,48 @@ namespace CodeImp.DoomBuilder.Map
}
}
- // Scripts
- IDictionary scplist = this.mapconfig.ReadSetting("scripts", new Hashtable());
- foreach(DictionaryEntry mp in scplist)
- scriptfiles.Add(mp.Value.ToString());
- }
+ //mxd. Script files settings
+ IDictionary sflist = this.mapconfig.ReadSetting("scriptfiles", new Hashtable());
+ foreach (DictionaryEntry mp in sflist)
+ {
+ // Item is a structure?
+ IDictionary scfinfo = mp.Value as IDictionary;
+ if (scfinfo != null)
+ {
+ ScriptDocumentSettings settings = ReadScriptDocumentSettings(scfinfo);
+ if (!string.IsNullOrEmpty(settings.Filename)) scriptfilesettings.Add(settings.Filename, settings);
+ }
+ }
- ~MapOptions()
- {
- // Clean up
- this.resources = null;
- this.scriptfiles = null;
- }
-
- #endregion
+ //mxd. Script lumps settings
+ IDictionary sllist = this.mapconfig.ReadSetting("scriptlumps", new Hashtable());
+ foreach (DictionaryEntry mp in sllist)
+ {
+ // Item is a structure?
+ IDictionary sclinfo = mp.Value as IDictionary;
+ if (sclinfo != null)
+ {
+ ScriptDocumentSettings settings = ReadScriptDocumentSettings(sclinfo);
+ if (!string.IsNullOrEmpty(settings.Filename)) scriptlumpsettings.Add(settings.Filename, settings);
+ }
+ }
+ }
- #region ================== Methods
+ //mxd. Is that really needed?..
+ ~MapOptions()
+ {
+ // Clean up
+ this.resources = null;
+ this.scriptfilesettings = null; //mxd
+ this.scriptlumpsettings = null; //mxd
+ }
- // This makes the path prefix for the given assembly
- private static string GetPluginPathPrefix(Assembly asm)
+ #endregion
+
+ #region ================== Methods
+
+ // This makes the path prefix for the given assembly
+ private static string GetPluginPathPrefix(Assembly asm)
{
Plugin p = General.Plugins.FindPluginByAssembly(asm);
return "plugins." + p.Name.ToLowerInvariant() + ".";
@@ -375,13 +404,19 @@ namespace CodeImp.DoomBuilder.Map
// Write grid settings
General.Map.Grid.WriteToConfig(mapconfig, "grid");
- // Write scripts to config
- mapconfig.DeleteSetting("scripts");
- for(int i = 0; i < scriptfiles.Count; i++)
- mapconfig.WriteSetting("scripts." + "file" + i.ToString(CultureInfo.InvariantCulture), scriptfiles[i]);
+ //mxd. Write script files settings to config
+ mapconfig.DeleteSetting("scriptfiles");
+ foreach (ScriptDocumentSettings settings in scriptfilesettings.Values)
+ WriteScriptDocumentSettings(mapconfig, "scriptfiles.file", settings);
- // Load the file or make a new file
- if(File.Exists(settingsfile))
+
+ //mxd. Write script lumps settings to config
+ mapconfig.DeleteSetting("scriptlumps");
+ foreach (ScriptDocumentSettings settings in scriptlumpsettings.Values)
+ WriteScriptDocumentSettings(mapconfig, "scriptlumps.lump", settings);
+
+ // Load the file or make a new file
+ if (File.Exists(settingsfile))
wadcfg = new Configuration(settingsfile, true);
else
wadcfg = new Configuration(true);
@@ -397,9 +432,89 @@ namespace CodeImp.DoomBuilder.Map
// Save file
wadcfg.SaveConfiguration(settingsfile);
}
-
- // This adds a resource location and returns the index where the item was added
- internal int AddResource(DataLocation res)
+
+ //mxd
+ private static ScriptDocumentSettings ReadScriptDocumentSettings(IDictionary scfinfo)
+ {
+ ScriptDocumentSettings settings = new ScriptDocumentSettings { FoldLevels = new Dictionary>() };
+
+ // Copy information from Configuration to ScriptDocumentSaveSettings
+ if (scfinfo.Contains("filename") && (scfinfo["filename"] is string)) settings.Filename = (string)scfinfo["filename"];
+ if (scfinfo.Contains("hash") && (scfinfo["hash"] is long)) settings.Hash = (long)scfinfo["hash"];
+ if (scfinfo.Contains("caretposition") && (scfinfo["caretposition"] is int)) settings.CaretPosition = (int)scfinfo["caretposition"];
+ if (scfinfo.Contains("firstvisibleline") && (scfinfo["firstvisibleline"] is int)) settings.FirstVisibleLine = (int)scfinfo["firstvisibleline"];
+ if (scfinfo.Contains("activetab") && (scfinfo["activetab"] is bool)) settings.IsActiveTab = (bool)scfinfo["activetab"];
+ if (scfinfo.Contains("foldlevels") && (scfinfo["foldlevels"] is string))
+ {
+ // 1:12,13,14;2:21,43,36
+ string foldstr = (string)scfinfo["foldlevels"];
+
+ // Convert string to dictionary
+ if (!string.IsNullOrEmpty(foldstr))
+ {
+ //TODO: add all kinds of warnings?
+ string[] foldlevels = foldstr.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (string foldlevel in foldlevels)
+ {
+ // 1:12,13,14
+ string[] parts = foldlevel.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (parts.Length != 2) continue;
+
+ int fold;
+ if (!int.TryParse(parts[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out fold)) continue;
+ if (settings.FoldLevels.ContainsKey(fold)) continue;
+
+ string[] linenumbersstr = parts[1].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ if (linenumbersstr.Length == 0) continue;
+
+ HashSet linenumbers = new HashSet();
+ foreach (string linenumber in linenumbersstr)
+ {
+ int linenum;
+ if (int.TryParse(linenumber, NumberStyles.Integer, CultureInfo.InvariantCulture, out linenum))
+ linenumbers.Add(linenum);
+ }
+
+ if (linenumbers.Count != linenumbersstr.Length) continue;
+
+ // Add to collection
+ settings.FoldLevels.Add(fold, new HashSet(linenumbers));
+ }
+ }
+ }
+
+ return settings;
+ }
+
+ //mxd
+ private static void WriteScriptDocumentSettings(Configuration mapconfig, string prefix, ScriptDocumentSettings settings)
+ {
+ // Store data
+ ListDictionary data = new ListDictionary();
+ data.Add("filename", settings.Filename);
+ data.Add("hash", settings.Hash);
+ if (settings.CaretPosition > 0) data.Add("caretposition", settings.CaretPosition);
+ if (settings.FirstVisibleLine > 0) data.Add("firstvisibleline", settings.FirstVisibleLine);
+ if (settings.IsActiveTab) data.Add("activetab", true);
+
+ // Convert dictionary to string
+ List foldlevels = new List();
+ foreach (KeyValuePair> group in settings.FoldLevels)
+ {
+ List linenums = new List(group.Value.Count);
+ foreach (int i in group.Value) linenums.Add(i.ToString());
+ foldlevels.Add(group.Key + ":" + string.Join(",", linenums.ToArray()));
+ }
+
+ // Add to collection
+ if (foldlevels.Count > 0) data.Add("foldlevels", string.Join(";", foldlevels.ToArray()));
+
+ // Write to config
+ mapconfig.WriteSetting(prefix, data);
+ }
+
+ // This adds a resource location and returns the index where the item was added
+ internal int AddResource(DataLocation res)
{
// Get a fully qualified path
res.location = Path.GetFullPath(res.location);