diff --git a/Build/Scintilla.dll b/Build/Scintilla.dll deleted file mode 100644 index c5c6879..0000000 Binary files a/Build/Scintilla.dll and /dev/null differ diff --git a/Build/ScintillaNET.3.5.dll b/Build/ScintillaNET.3.5.dll new file mode 100644 index 0000000..555afd4 Binary files /dev/null and b/Build/ScintillaNET.3.5.dll differ diff --git a/Build/Scripting/BCS.cfg b/Build/Scripting/BCS.cfg index f121a7f..dcc0c64 100644 --- a/Build/Scripting/BCS.cfg +++ b/Build/Scripting/BCS.cfg @@ -16,6 +16,10 @@ insertcase = 0; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; // CPP-style, case-insensitive functionopen = "("; functionclose = ")"; +codeblockopen = "{"; +codeblockclose = "}"; +arrayopen = "["; +arrayclose = "]"; argumentdelimiter = ","; terminator = ";"; keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K"; diff --git a/Build/Scripting/GZDoom_MODELDEF.cfg b/Build/Scripting/GZDoom_MODELDEF.cfg index e3d7fc2..c868778 100644 --- a/Build/Scripting/GZDoom_MODELDEF.cfg +++ b/Build/Scripting/GZDoom_MODELDEF.cfg @@ -7,6 +7,8 @@ description = "GZDoom MODELDEF"; codepage = 0; extensions = "mdd"; casesensitive = false; +codeblockopen = "{"; +codeblockclose = "}"; insertcase = 1; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; // CPP-style, case-insensitive keywordhelp = "http://zdoom.org/wiki/MODELDEF"; diff --git a/Build/Scripting/Hexen_ACS.cfg b/Build/Scripting/Hexen_ACS.cfg index 550ac28..12c84b5 100644 --- a/Build/Scripting/Hexen_ACS.cfg +++ b/Build/Scripting/Hexen_ACS.cfg @@ -16,6 +16,10 @@ insertcase = 0; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; // CPP-style, case-insensitive functionopen = "("; functionclose = ")"; +codeblockopen = "{"; +codeblockclose = "}"; +arrayopen = "["; +arrayclose = "]"; argumentdelimiter = ","; terminator = ";"; keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K"; diff --git a/Build/Scripting/ZDoom_ACS.cfg b/Build/Scripting/ZDoom_ACS.cfg index d82f449..9a7e828 100644 --- a/Build/Scripting/ZDoom_ACS.cfg +++ b/Build/Scripting/ZDoom_ACS.cfg @@ -16,6 +16,10 @@ insertcase = 0; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; // CPP-style, case-insensitive functionopen = "("; functionclose = ")"; +codeblockopen = "{"; +codeblockclose = "}"; +arrayopen = "["; +arrayclose = "]"; argumentdelimiter = ","; terminator = ";"; keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K"; @@ -24,12 +28,12 @@ scripttype = 1; //0 = unknown script, 1 = acc, 2 = modeldef, 3 = decorate keywords { - #Define = "#Define identifier expression"; - #EncryptStrings = "#EncryptStrings"; - #Import = "#Import"; - #Include = "#Include"; - #LibDefine = "#LibDefine identifier expression"; - #Library = "#Library"; + #define = "#Define identifier expression"; + #encryptstrings = "#EncryptStrings"; + #import = "#Import"; + #include = "#Include"; + #libdefine = "#LibDefine identifier expression"; + #library = "#Library"; #NoCompact = "#NoCompact"; #NoWadAuthor = "#NoWadAuthor"; #WadAuthor = "#WadAuthor"; @@ -59,11 +63,11 @@ keywords //BlueScore = "BlueScore()"; //BlueTeamCount = "BlueTeamCount()"; //BlueTeamScore = "BlueTeamScore()"; - Bool = "Bool expression"; - Break = "Break"; + bool = "Bool expression"; + break = "Break"; CancelFade = "void CancelFade(void)\nIf either FadeTo or FadeRange is currently in progress,\nCancelFade stops it and turns off the palette flash."; CanRaiseActor = "bool CanRaiseActor(int tid)\nChecks to see if the actor or actors with the specified tid are viable for resurrection.\nIf tid is 0, the check is done on the activator of the script."; - Case = "Case expression"; + case = "Case expression"; Ceiling_CrushAndRaise = "Ceiling_CrushAndRaise(tag, speed, crush, crushmode)"; Ceiling_CrushAndRaiseA = "Ceiling_CrushAndRaiseA(tag, dspeed, uspeed, crush, crushmode)"; Ceiling_CrushAndRaiseDist = "Ceiling_CrushAndRaiseDist(tag, dist, speed, damage, crushmode)"; @@ -113,16 +117,16 @@ keywords ClearInventory = "void ClearInventory(void)\nClears the player's inventory of weapons, ammo, armor and usable items."; ClearLineSpecial = "void ClearLineSpecial(void)\nClears the special of the line that activated the script."; //ConsoleCommand = "void ConsoleCommand(str command)"; - Const = "const"; - Continue = "continue"; - cos = "fixed Cos(int angle)"; + const = "const"; + continue = "continue"; + Cos = "fixed Cos(int angle)"; CreateTranslation = "void CreateTranslation(int transnumber, a:b=c:d, ...)"; DamageThing = "DamageThing(amount, mod)"; - Death = "Script expression Death"; - Default = "default:"; + DEATH = "Script expression Death"; + default = "default:"; Delay = "void Delay(int tics)"; - Disconnect = "Script expression Disconnect"; - Do = "do"; + DISCONNECT = "Script expression Disconnect"; + do = "do"; Door_Animated = "Door_Animated(tag, speed, delay, lock)"; Door_Close = "Door_Close(tag, speed, lighttag)"; Door_CloseWaitOpen = "Door_CloseWaitOpen(tag, speed, delay, lighttag)"; @@ -134,8 +138,8 @@ keywords Elevator_LowerToNearest = "Elevator_LowerToNearest(tag, speed)"; Elevator_MoveToFloor = "Elevator_MoveToFloor(tag, speed)"; Elevator_RaiseToNearest = "Elevator_RaiseToNearest(tag, speed)"; - Else = "Else"; - Enter = "Script expression Enter"; + else = "Else"; + ENTER = "Script expression Enter"; Exit_Normal = "Exit_Normal(pos)"; Exit_Secret = "Exit_Secret(pos)"; FadeRange = "void FadeRange(int red1, int green1, int blue1, fixed amount1, int red2, int green2, int blue2, fixed amount2, fixed seconds)\nSets the current flash to the first color set and then fades it to the second color set over the specified number of seconds."; @@ -170,10 +174,10 @@ keywords FloorAndCeiling_LowerByValue = "FloorAndCeiling_LowerByValue(tag, speed, height)"; FloorAndCeiling_LowerRaise = "FloorAndCeiling_LowerRaise(tag, fspeed, cspeed, boomemu)"; FloorAndCeiling_RaiseByValue = "FloorAndCeiling_RaiseByValue(tag, speed, height)"; - For = "for(initialization, condition, iteration)"; + for = "for(initialization, condition, iteration)"; ForceField = "ForceField"; FS_Execute = "FS_Execute(script, side, keynum, message)"; - Function = "function void expression(void)"; + function = "function void expression(void)"; GameSkill = "int GameSkill(void)"; GameType = "int GameType(void)"; Generic_Ceiling = "Generic_Ceiling(tag, speed, height, target, flag)"; @@ -242,8 +246,8 @@ keywords HealThing = "HealThing(amount)"; HudMessage = "void hudmessage(s:text; int type, int id, int color, fixed x, fixed y, fixed holdTime)"; HudMessageBold = "void HudMessageBold(s:text; int type, int id, int color, fixed x, fixed y, fixed holdTime)"; - If = "if(expression)"; - Int = "int expression"; + if = "if(expression)"; + int = "int expression"; //IsMultiplayer = "int IsMultiplayer(void)"; //IsOneFlagCTF = "int IsOneFlagCTF(void)"; IsPointerEqual = "bool IsPointerEqual(int ptr_select1, int ptr_select2[, int tid1[, int tid2]])"; @@ -260,7 +264,7 @@ keywords Light_Stop = "Light_Stop(tag)"; Light_Strobe = "Light_Strobe(tag, upper, lower, u-tics, l-tics)"; Light_StrobeDoom = "Light_StrobeDoom(tag, u-tics, l-tics)"; - Lightning = "Script expression Lightning"; + LIGHTNING = "Script expression Lightning"; LineAttack = "LineAttack(int tid, fixed angle, fixed pitch, int damage[, str pufftype = 'BulletPuff'[, str damagetype = 'None'[, fixed range = 2048[, int flags = 0[, int pufftid = 0]]]]])\nFires a hitscan attack. If tid is 0, the activator of the script is the source of the attack."; Line_AlignCeiling = "Line_AlignCeiling(lineid, side)"; Line_AlignFloor = "Line_AlignFloor(lineid, side)"; @@ -273,11 +277,11 @@ keywords Log = "void Log(type:expression)\nLog will print something in the log area of the screen (top left), as well as logging it to the console.\nIt uses the same parameter format as the Print function."; MorphActor = "int MorphActor(int tid, [str playerclass, [str monsterclass, [int duration, [int style, [str morphflash, [str unmorphflash]]]]]])"; NamedScriptWait = "void NamedScriptWait(str script)"; - Net = "Script expression Net"; + NET = "Script expression Net"; NoiseAlert = "NoiseAlert(target_tid, emiter_tid)"; - Open = "Script expression Open"; + OPEN = "Script expression Open"; PickActor = "bool PickActor(int source_tid, fixed angle, fixed pitch, fixed distance, int tid[, int actorMask = MF_SHOOTABLE[, int wallMask = ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN[, bool forcetid = false]]])"; - Pickup = "Script expression Pickup"; + //PICKUP = "Script expression Pickup"; Pillar_Build = "Pillar_Build(tag, speed, height)"; Pillar_BuildAndCrush = "Pillar_BuildAndCrush(tag, speed, height, crush, crushmode)"; Pillar_Open = "Pillar_Open(tag, speed, fdist, cdist)"; @@ -324,10 +328,10 @@ keywords Radius_Quake2 = "void Radius_Quake2(int tid, int intensity, int duration, int damrad, int tremrad, str sound)"; Random = "int Random(int min, int max)"; ReplaceTextures = "void ReplaceTextures(str oldtexturename, str newtexturename[, int flags])\nReplaces all occurences of oldtexturename with newtexturename.\nNOT_ flags can be used."; - Respawn = "Script expression Respawn"; + RESPAWN = "Script expression Respawn"; Restart = "Restart"; - Return = "Return"; - Script = "Script expression"; + return = "Return"; + script = "Script expression"; ScriptWait = "void ScriptWait(int script)"; Scroll_Ceiling = "Scroll_Ceiling(tag, x-move, y-move, unused)"; Scroll_Floor = "Scroll_Floor(tag, x-move, y-move, type)"; @@ -400,7 +404,7 @@ keywords SetUserCVarString = "bool SetUserCVarString(int playernumber, str cvar, str value)\nSets the console variable of a particular player.\nOnly mod-defined console variables through CVARINFO can be changed by using this function.\nReturns FALSE if cvar is invalid, it is not writable, or the player doesn't exist."; SetUserVariable = "void SetUserVariable(int tid, str name, int value)\nSets one of the affected actor's user variables."; SetWeapon = "bool SetWeapon(str weaponname)\nSets the player's current weapon to weaponname.\nReturns TRUE if the weapon was set successfully, and FALSE if not."; - sin = "fixed Sin(int angle)"; + Sin = "fixed Sin(int angle)"; SoundSequence = "void SoundSequence(str sndseq)\nPlays a sound sequence defined in SNDSEQ lump."; SoundSequenceOnActor = "void SoundSequenceOnActor(int tid, str sndseq)\nPlays a sound sequence defined in SNDSEQ lump."; SoundSequenceOnPolyObj = "void SoundSequenceOnPolyobj(int polynum, str sndseq)\nPlays a sound sequence defined in SNDSEQ lump."; @@ -435,7 +439,7 @@ keywords StrRight = "str StrRight(str string, int length)\nCreates a new string containing the length last characters of string.\nIf string does not exist, an empty string is returned.\nIf string is shorter than length characters, the entire string is returned."; Suspend = "Suspend"; SwapActorTeleFog = "int SwapActorTeleFog(int tid)"; - Switch = "Switch(expression)"; + switch = "Switch(expression)"; TagWait = "void TagWait(int tag)"; TakeActorInventory = "void TakeActorInventory(int tid, str inventory_item, int amount)\nThis function will take the amount of items from the specified actor.\nTakeActorInventory can remove items that are flagged as undroppable."; TakeInventory = "void TakeInventory(str inventory_item, int amount)\nThis function will take the number of items specified from the activator.\nTakeInventory can remove items that are flagged as undroppable."; @@ -482,19 +486,19 @@ keywords Timer = "int Timer(void)"; TranslucentLine = "TranslucentLine(lineid, amount, additive, moreflags)"; UniqueTID = "int UniqueTID([int tid[, int limit]])"; - Unloading = "Script expression Unloading"; + UNLOADING = "Script expression Unloading"; UnMorphActor = "int UnMorphActor(int tid[, bool force])"; - Until = "Until(expression)"; + until = "Until(expression)"; UseActorInventory = "int UseActorInventory(int tid, str classname)\nForces the actor(s) with the specified tid to use an item from their inventory, if they have one.\nReturns TRUE if the item was used successfully."; UseInventory = "int UseInventory(str classname)\nForces the activator to use the specified inventory item, if he has it.\nReturns TRUE if the item was used successfully."; UsePuzzleItem = "UsePuzzleItem(item, script, arg1, arg2, arg3)"; VectorAngle = "fixed VectorAngle(int x, int y)"; VectorLength = "int VectorLength(int x, int y)"; - Void = "void"; + void = "void"; Warp = "bool Warp(int destinationtid, fixed xofs, fixed yofs, fixed zofs, int angle, int flags[, str success_state[, bool exactstate[, fixed heightoffset]]])"; - While = "while(expression)"; - WhiteReturn = "Script expression WhiteReturn"; - World = "World Int expression:identifier"; + while = "while(expression)"; + //WHITERETURN = "Script expression WhiteReturn"; + world = "World Int expression:identifier"; } constants diff --git a/Build/Scripting/ZDoom_DECORATE.cfg b/Build/Scripting/ZDoom_DECORATE.cfg index 6ed7eb7..c6900a7 100644 --- a/Build/Scripting/ZDoom_DECORATE.cfg +++ b/Build/Scripting/ZDoom_DECORATE.cfg @@ -11,6 +11,10 @@ insertcase = 0; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; functionopen = "("; functionclose = ")"; +codeblockopen = "{"; +codeblockclose = "}"; +arrayopen = "["; +arrayclose = "]"; argumentdelimiter = ","; terminator = ";"; keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K"; @@ -127,7 +131,7 @@ keywords A_CheckFloor = "A_CheckFloor(int offset OR str state)"; A_CheckFlag = "A_CheckFlag(str flagname, state label[, int check_pointer = AAPTR_DEFAULT])"; A_CheckLOF = "A_CheckLOF(state jump[, int flags = 0[, float range = 0.0[, float minrange = 0.0[, float angle = 0.0[, float pitch = 0.0[, float offsetheight = 0.0[, float offsetwidth = 0.0[, int ptr_target = AAPTR_DEFAULT]]]]]]]])"; - A_CheckProximity = "A_CheckProximity(str \"jump\", str classname, float distance[, int count = 1[, int flags = 0[, int pointer]]])"; + A_CheckProximity = "A_CheckProximity(str jump, str classname, float distance[, int count = 1[, int flags = 0[, int pointer = AAPTR_DEFAULT]]])"; A_CheckRange = "A_CheckRange(float distance, int offset OR str state[, bool 2d_check])"; A_CheckSight = "A_CheckSight(int offset OR str state)"; A_CheckSightOrRange = "A_CheckSightOrRange(float distance, int offset OR str state[, bool 2d_check])"; @@ -1204,6 +1208,13 @@ constants CPXF_DEADONLY; CPXF_LESSOREQUAL; CPXF_EXACT; + CPXF_CHECKSIGHT; + CPXF_SETTARGET; + CPXF_SETMASTER; + CPXF_SETTRACER; + CPXF_FARTHEST; + CPXF_CLOSEST; + CPXF_SETONPTR; //A_FaceTraget/Master/Tracer flags FAF_BOTTOM; FAF_MIDDLE; diff --git a/Build/Scripting/ZDoom_USDF.cfg b/Build/Scripting/ZDoom_USDF.cfg index 13929e5..04b125a 100644 --- a/Build/Scripting/ZDoom_USDF.cfg +++ b/Build/Scripting/ZDoom_USDF.cfg @@ -9,6 +9,8 @@ extensions = "txt"; casesensitive = false; insertcase = 1; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; // CPP-style, case-insensitive +codeblockopen = "{"; +codeblockclose = "}"; terminator = ";"; keywords diff --git a/Build/Scripting/Zandronum_ACS.cfg b/Build/Scripting/Zandronum_ACS.cfg index 2436abc..a5d748a 100644 --- a/Build/Scripting/Zandronum_ACS.cfg +++ b/Build/Scripting/Zandronum_ACS.cfg @@ -16,6 +16,10 @@ insertcase = 0; // 0=Normal, 1=Lowercase, 2=Uppercase lexer = 35; // CPP-style, case-insensitive functionopen = "("; functionclose = ")"; +codeblockopen = "{"; +codeblockclose = "}"; +arrayopen = "["; +arrayclose = "]"; argumentdelimiter = ","; terminator = ";"; keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K"; diff --git a/Build/Snippets/acs/switch.txt b/Build/Snippets/acs/switch.txt new file mode 100644 index 0000000..2e98916 --- /dev/null +++ b/Build/Snippets/acs/switch.txt @@ -0,0 +1,3 @@ +switch ([EP])[LB]{ + +} \ No newline at end of file diff --git a/Build/ZoneBuilder.default.cfg b/Build/ZoneBuilder.default.cfg index 97a894a..50c3c23 100644 --- a/Build/ZoneBuilder.default.cfg +++ b/Build/ZoneBuilder.default.cfg @@ -305,6 +305,14 @@ colors color46 = -16776961; color47 = -15671297; color48 = -16720128; + color49 = -16711936; + color50 = -16711681; + color51 = -65536; + color52 = -8355712; + color53 = -1; + color54 = -13395457; + color55 = -6089451; + color56 = -9868951; } diff --git a/Setup/zonebuilder_setup.iss b/Setup/zonebuilder_setup.iss index 147d154..b4b4760 100644 --- a/Setup/zonebuilder_setup.iss +++ b/Setup/zonebuilder_setup.iss @@ -44,7 +44,7 @@ Source: Updater.ini; DestDir: {app}; Flags: ignoreversion Source: Refmanual.chm; DestDir: {app}; Flags: ignoreversion Source: DevIL.dll; DestDir: {app}; Flags: ignoreversion Source: SharpCompress.3.5.dll; DestDir: {app}; Flags: ignoreversion -Source: Scintilla.dll; DestDir: {app}; Flags: ignoreversion +Source: ScintillaNET.3.5.dll; DestDir: {app}; Flags: ignoreversion Source: SlimDX.dll; DestDir: {app}; Flags: ignoreversion Source: GPL.txt; DestDir: {app}; Flags: ignoreversion Source: Compilers\*; DestDir: {app}\Compilers; Flags: ignoreversion recursesubdirs diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 85d29ba..0e4071d 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -121,20 +121,10 @@ ArgumentBox.cs - - - UserControl - - - ScriptEditorControl.cs - + Component - - - Component - UserControl @@ -539,6 +529,9 @@ + + False + False @@ -710,7 +703,9 @@ - + + ScriptEditorControl.cs + @@ -777,6 +772,12 @@ PasteOptionsControl.cs + + + UserControl + + + ScriptEditorControl.cs UserControl @@ -1140,6 +1141,13 @@ + + + + + + + @@ -1213,9 +1221,6 @@ - - - @@ -1231,10 +1236,6 @@ - - Designer - ScriptEditorControl.cs - diff --git a/Source/Core/Config/ProgramConfiguration.cs b/Source/Core/Config/ProgramConfiguration.cs index 083719b..e74462b 100644 --- a/Source/Core/Config/ProgramConfiguration.cs +++ b/Source/Core/Config/ProgramConfiguration.cs @@ -67,7 +67,8 @@ namespace CodeImp.DoomBuilder.Config private bool scriptfontbold; private bool scriptontop; private bool scriptautoindent; - private bool snippetsallmanstyle; //mxd + private bool scriptusetabs; //mxd + private bool snippetsallmanstyle; //mxd private string screenshotspath; //mxd private int scripttabwidth; private int previewimagesize; @@ -167,7 +168,8 @@ namespace CodeImp.DoomBuilder.Config public int ZoomFactor { get { return zoomfactor; } internal set { zoomfactor = value; } } public bool ShowErrorsWindow { get { return showerrorswindow; } internal set { showerrorswindow = value; } } public bool AnimateVisualSelection { get { return animatevisualselection; } internal set { animatevisualselection = value; } } - public int ScriptTabWidth { get { return scripttabwidth; } internal set { scripttabwidth = value; } } + public bool ScriptUseTabs { get { return scriptusetabs; } internal set { scriptusetabs = value; } } //mxd + public int ScriptTabWidth { get { return scripttabwidth; } internal set { scripttabwidth = value; } } public bool ScriptAutoIndent { get { return scriptautoindent; } internal set { scriptautoindent = value; } } public bool SnippetsAllmanStyle { get { return snippetsallmanstyle; } internal set { snippetsallmanstyle = value; } } //mxd internal string ScreenshotsPath { get { return screenshotspath; } set { screenshotspath = value; } } //mxd @@ -277,14 +279,15 @@ namespace CodeImp.DoomBuilder.Config movespeed = cfg.ReadSetting("movespeed", 100); viewdistance = cfg.ReadSetting("viewdistance", 3000.0f); invertyaxis = cfg.ReadSetting("invertyaxis", false); - scriptfontname = cfg.ReadSetting("scriptfontname", "Lucida Console"); - scriptfontsize = cfg.ReadSetting("scriptfontsize", 10); + scriptfontname = cfg.ReadSetting("scriptfontname", "Courier New"); + scriptfontsize = cfg.ReadSetting("scriptfontsize", 10); scriptfontbold = cfg.ReadSetting("scriptfontbold", false); scriptautoindent = cfg.ReadSetting("scriptautoindent", true); snippetsallmanstyle = cfg.ReadSetting("snippetsallmanstyle", false); //mxd screenshotspath = cfg.ReadSetting("screenshotspath", General.DefaultScreenshotsPath); //mxd scriptontop = cfg.ReadSetting("scriptontop", true); - scripttabwidth = cfg.ReadSetting("scripttabwidth", 4); + scriptusetabs = cfg.ReadSetting("scriptusetabs", true); //mxd + scripttabwidth = cfg.ReadSetting("scripttabwidth", 4); previewimagesize = cfg.ReadSetting("previewimagesize", 1); autoscrollspeed = cfg.ReadSetting("autoscrollspeed", 0); zoomfactor = cfg.ReadSetting("zoomfactor", 3); @@ -381,7 +384,8 @@ namespace CodeImp.DoomBuilder.Config cfg.WriteSetting("scriptfontsize", scriptfontsize); cfg.WriteSetting("scriptfontbold", scriptfontbold); cfg.WriteSetting("scriptontop", scriptontop); - cfg.WriteSetting("scripttabwidth", scripttabwidth); + cfg.WriteSetting("scriptusetabs", scriptusetabs); //mxd + cfg.WriteSetting("scripttabwidth", scripttabwidth); cfg.WriteSetting("scriptautoindent", scriptautoindent); cfg.WriteSetting("snippetsallmanstyle", snippetsallmanstyle); //mxd cfg.WriteSetting("screenshotspath", screenshotspath); //mxd diff --git a/Source/Core/Config/ScriptConfiguration.cs b/Source/Core/Config/ScriptConfiguration.cs index 4cd10ef..6c6a6f1 100644 --- a/Source/Core/Config/ScriptConfiguration.cs +++ b/Source/Core/Config/ScriptConfiguration.cs @@ -21,6 +21,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; using CodeImp.DoomBuilder.IO; +using ScintillaNET; #endregion @@ -54,28 +55,34 @@ namespace CodeImp.DoomBuilder.Config private readonly string[] extensions; private readonly bool casesensitive; private readonly int insertcase; - private readonly int lexer; - private readonly string keywordhelp; + private readonly Lexer lexer; + private readonly string keywordhelp; private readonly string functionopen; private readonly string functionclose; - private readonly string argumentdelimiter; + private readonly string codeblockopen; //mxd + private readonly string codeblockclose; //mxd + private readonly string arrayopen; //mxd + private readonly string arrayclose; //mxd + private readonly string argumentdelimiter; private readonly string terminator; - private readonly string functionregex; private readonly ScriptType scripttype; //mxd // Collections private readonly Dictionary keywords; private readonly Dictionary lowerkeywords; - private readonly List constants; + private readonly List keywordkeyssorted; //mxd + private readonly List constants; private readonly Dictionary lowerconstants; private readonly Dictionary snippets; //mxd - - #endregion + private readonly HashSet snippetkeyssorted; //mxd + private readonly HashSet braces; //mxd - #region ================== Properties + #endregion - // Compiler settings - public CompilerInfo Compiler { get { return compiler; } } + #region ================== Properties + + // Compiler settings + public CompilerInfo Compiler { get { return compiler; } } public string Parameters { get { return parameters; } } public string ResultLump { get { return resultlump; } } @@ -85,37 +92,45 @@ namespace CodeImp.DoomBuilder.Config public string[] Extensions { get { return extensions; } } public bool CaseSensitive { get { return casesensitive; } } public int InsertCase { get { return insertcase; } } - public int Lexer { get { return lexer; } } - public string KeywordHelp { get { return keywordhelp; } } + public Lexer Lexer { get { return lexer; } } + public string KeywordHelp { get { return keywordhelp; } } public string FunctionOpen { get { return functionopen; } } public string FunctionClose { get { return functionclose; } } - public string ArgumentDelimiter { get { return argumentdelimiter; } } + public string CodeBlockOpen { get { return codeblockopen; } } //mxd + public string CodeBlockClose { get { return codeblockclose; } } //mxd + public string ArrayOpen { get { return arrayopen; } } //mxd + public string ArrayClose { get { return arrayclose; } } //mxd + public string ArgumentDelimiter { get { return argumentdelimiter; } } public string Terminator { get { return terminator; } } - public string FunctionRegEx { get { return functionregex; } } public ScriptType ScriptType { get { return scripttype; } } //mxd - public Dictionary Snippets { get { return snippets; } } //mxd - // Collections - public ICollection Keywords { get { return keywords.Keys; } } - public ICollection Constants { get { return constants; } } - - #endregion + // Collections + public ICollection Keywords { get { return keywordkeyssorted; } } + public ICollection Constants { get { return constants; } } + public ICollection Snippets { get { return snippetkeyssorted; } } + public HashSet BraceChars { get { return braces; } } //mxd - #region ================== Constructor / Disposer - - // This creates the default script configuration - // that is used for documents of unknown type - internal ScriptConfiguration() + #endregion + + #region ================== Constructor / Disposer + + // This creates the default script configuration + // that is used for documents of unknown type + internal ScriptConfiguration() { // Initialize this.keywords = new Dictionary(StringComparer.Ordinal); this.constants = new List(); this.lowerkeywords = new Dictionary(StringComparer.Ordinal); this.lowerconstants = new Dictionary(StringComparer.Ordinal); + this.keywordkeyssorted = new List(); //mxd + this.snippets = new Dictionary(StringComparer.OrdinalIgnoreCase); //mxd + this.snippetkeyssorted = new HashSet(); //mxd + this.braces = new HashSet(); //mxd - // Settings - lexer = 1; - casesensitive = false; + // Settings + lexer = Lexer.Null; + casesensitive = false; codepage = 65001; parameters = ""; resultlump = ""; @@ -123,13 +138,15 @@ namespace CodeImp.DoomBuilder.Config keywordhelp = ""; functionopen = ""; functionclose = ""; - argumentdelimiter = ""; + codeblockopen = ""; //mxd + codeblockclose = ""; //mxd + arrayopen = ""; //mxd + arrayclose = ""; //mxd + argumentdelimiter = ""; terminator = ""; - functionregex = ""; description = "Plain text"; scripttype = ScriptType.UNKNOWN; //mxd extensions = new[] { "txt" }; - snippets = new Dictionary(StringComparer.Ordinal); //mxd } // Constructor @@ -140,10 +157,12 @@ namespace CodeImp.DoomBuilder.Config this.constants = new List(); this.lowerkeywords = new Dictionary(StringComparer.Ordinal); this.lowerconstants = new Dictionary(StringComparer.Ordinal); - this.snippets = new Dictionary(StringComparer.Ordinal); //mxd - - // Read settings - description = cfg.ReadSetting("description", "Untitled script"); + this.keywordkeyssorted = new List(); //mxd + this.snippets = new Dictionary(StringComparer.OrdinalIgnoreCase); //mxd + this.snippetkeyssorted = new HashSet(); //mxd + this.braces = new HashSet(); //mxd + // Read settings + description = cfg.ReadSetting("description", "Untitled script"); codepage = cfg.ReadSetting("codepage", 0); string extensionsstring = cfg.ReadSetting("extensions", ""); string compilername = cfg.ReadSetting("compiler", ""); @@ -151,17 +170,28 @@ namespace CodeImp.DoomBuilder.Config resultlump = cfg.ReadSetting("resultlump", ""); casesensitive = cfg.ReadSetting("casesensitive", true); insertcase = cfg.ReadSetting("insertcase", 0); - lexer = cfg.ReadSetting("lexer", 0); - keywordhelp = cfg.ReadSetting("keywordhelp", ""); + lexer = (Lexer)cfg.ReadSetting("lexer", (int)Lexer.Container); + keywordhelp = cfg.ReadSetting("keywordhelp", ""); functionopen = cfg.ReadSetting("functionopen", ""); functionclose = cfg.ReadSetting("functionclose", ""); - argumentdelimiter = cfg.ReadSetting("argumentdelimiter", ""); + codeblockopen = cfg.ReadSetting("codeblockopen", ""); //mxd + codeblockclose = cfg.ReadSetting("codeblockclose", ""); //mxd + arrayopen = cfg.ReadSetting("arrayopen", ""); //mxd + arrayclose = cfg.ReadSetting("arrayclose", ""); //mxd + argumentdelimiter = cfg.ReadSetting("argumentdelimiter", ""); terminator = cfg.ReadSetting("terminator", ""); - functionregex = cfg.ReadSetting("functionregex", ""); scripttype = (ScriptType)cfg.ReadSetting("scripttype", (int)ScriptType.UNKNOWN); //mxd - - // Make extensions array - extensions = extensionsstring.Split(','); + + //mxd. Make braces array + if (!string.IsNullOrEmpty(functionopen)) braces.Add(functionopen[0]); + if (!string.IsNullOrEmpty(functionclose)) braces.Add(functionclose[0]); + if (!string.IsNullOrEmpty(codeblockopen)) braces.Add(codeblockopen[0]); + if (!string.IsNullOrEmpty(codeblockclose)) braces.Add(codeblockclose[0]); + if (!string.IsNullOrEmpty(arrayopen)) braces.Add(arrayopen[0]); + if (!string.IsNullOrEmpty(arrayclose)) braces.Add(arrayclose[0]); + + // Make extensions array + extensions = extensionsstring.Split(','); for(int i = 0; i < extensions.Length; i++) extensions[i] = extensions[i].Trim(); // Load keywords @@ -170,67 +200,82 @@ namespace CodeImp.DoomBuilder.Config { keywords.Add(de.Key.ToString(), de.Value.ToString()); lowerkeywords.Add(de.Key.ToString().ToLowerInvariant(), de.Key.ToString()); - } - - // Load constants - dic = cfg.ReadSetting("constants", new Hashtable()); + keywordkeyssorted.Add(de.Key.ToString()); //mxd + } + + //mxd. Sort keywords lookup + keywordkeyssorted.Sort(); + + // Load constants + dic = cfg.ReadSetting("constants", new Hashtable()); foreach(DictionaryEntry de in dic) { constants.Add(de.Key.ToString()); lowerconstants.Add(de.Key.ToString().ToLowerInvariant(), de.Key.ToString()); } - - // Compiler specified? - if(compilername.Length > 0) - { - // Find compiler - foreach(CompilerInfo c in General.Compilers) - { - // Compiler name matches? - if(c.Name == compilername) - { - // Apply compiler - this.compiler = c; - break; - } - } - - // No compiler found? - if(this.compiler == null) throw new Exception("No such compiler defined: '" + compilername + "'"); - } - //mxd. Load Snippets - string snippetsdir = cfg.ReadSetting("snippetsdir", ""); - if(!string.IsNullOrEmpty(snippetsdir)) + //mxd + constants.Sort(); + + //mxd. Load Snippets + string snippetsdir = cfg.ReadSetting("snippetsdir", ""); + if(!string.IsNullOrEmpty(snippetsdir)) { string snippetspath = Path.Combine(General.SnippetsPath, snippetsdir); - if(Directory.Exists(snippetspath)) + if(Directory.Exists(snippetspath)) { string[] files = Directory.GetFiles(snippetspath, "*.txt", SearchOption.TopDirectoryOnly); + List sortedkeys = new List(); - foreach(string file in files) + foreach (string file in files) { string name = Path.GetFileNameWithoutExtension(file); - if(name.Contains(" ")) + if (string.IsNullOrEmpty(name)) + { + General.ErrorLogger.Add(ErrorType.Warning, "Failed to load snippet '" + file + "' for '" + description + "' script configuration."); + } + else { - General.ErrorLogger.Add(ErrorType.Warning, "Failed to load snippet '" + file + "' for '" + description + "' script configuration: snippet file name must not contain spaces!"); - } - else - { - string[] lines = File.ReadAllLines(file); - if(lines.Length > 0) + if (name.Contains(" ")) name = name.Replace(' ', '_'); + string[] lines = File.ReadAllLines(file); + if(lines.Length > 0) { snippets.Add(name, lines); - } - else + sortedkeys.Add(name); + } + else { General.ErrorLogger.Add(ErrorType.Warning, "Failed to load snippet '" + file + "' for '" + description + "' script configuration: file is empty!"); } } } - } - } - } + + //mxd. Sort snippets lookup + sortedkeys.Sort(); + snippetkeyssorted = new HashSet(sortedkeys, StringComparer.OrdinalIgnoreCase); + + } + } + + // Compiler specified? + if (compilername.Length > 0) + { + // Find compiler + foreach (CompilerInfo c in General.Compilers) + { + // Compiler name matches? + if (c.Name == compilername) + { + // Apply compiler + this.compiler = c; + break; + } + } + + // No compiler found? + if (this.compiler == null) throw new Exception("No such compiler defined: '" + compilername + "'"); + } + } #endregion @@ -278,9 +323,15 @@ namespace CodeImp.DoomBuilder.Config else return null; } - - // This sorts by description - public int CompareTo(ScriptConfiguration other) + + //mxd + public string[] GetSnippet(string name) + { + return (snippetkeyssorted.Contains(name) ? snippets[name] : null); + } + + // This sorts by description + public int CompareTo(ScriptConfiguration other) { return string.Compare(this.description, other.description, true); } diff --git a/Source/Core/Controls/ScriptDocumentTab.cs b/Source/Core/Controls/ScriptDocumentTab.cs index bbe14ce..4542e81 100644 --- a/Source/Core/Controls/ScriptDocumentTab.cs +++ b/Source/Core/Controls/ScriptDocumentTab.cs @@ -20,13 +20,13 @@ using System; using System.IO; using System.Collections.Generic; using System.Drawing; -using System.Text; using System.Windows.Forms; using CodeImp.DoomBuilder.Windows; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Compilers; using CodeImp.DoomBuilder.GZBuilder.Data; using CodeImp.DoomBuilder.GZBuilder.GZDoom; +using ScintillaNET; #endregion @@ -34,11 +34,10 @@ namespace CodeImp.DoomBuilder.Controls { internal abstract class ScriptDocumentTab : TabPage { - #region ================== Constants + #region ================== Constants - private const int NAVIGATOR_BORDER_TOP = 8; //mxd - private const int EDITOR_BORDER_TOP = 33; - private const int EDITOR_BORDER_BOTTOM = 4; + private const int EDITOR_BORDER_TOP = 4; + private const int EDITOR_BORDER_BOTTOM = 4; private const int EDITOR_BORDER_LEFT = 4; private const int EDITOR_BORDER_RIGHT = 4; @@ -48,7 +47,6 @@ namespace CodeImp.DoomBuilder.Controls // The script edit control protected readonly ScriptEditorControl editor; - protected readonly ComboBox navigator; //mxd private bool preventchanges; //mxd private string title; //mxd @@ -68,11 +66,15 @@ namespace CodeImp.DoomBuilder.Controls public virtual bool IsReconfigurable { get { return true; } } public virtual string Filename { get { return null; } } public ScriptEditorPanel Panel { get { return panel; } } - public new string Text { get { return title; } } //mxd - public bool IsChanged { get { return editor.IsChanged; } internal set { editor.IsChanged = value; } } //mxd. Added setter - public int SelectionStart { get { return editor.SelectionStart; } set { editor.SelectionStart = value; } } + internal Scintilla Scintilla { get { return editor.Scintilla; } } //mxd + public string Title { get { return title; } } //mxd + public bool IsChanged { get { return editor.IsChanged; } } + public int SelectionStart { get { return editor.SelectionStart; } set { editor.SelectionStart = value; } } public int SelectionEnd { get { return editor.SelectionEnd; } set { editor.SelectionEnd = value; } } - public ScriptConfiguration Config { get { return config; } } + public bool ShowWhitespace { get { return editor.ShowWhitespace; } set { editor.ShowWhitespace = value; } } //mxd + public bool WrapLongLines { get { return editor.WrapLongLines; } set { editor.WrapLongLines = value; } } //mxd + public string SelectedText { get { return editor.SelectedText; } } //mxd + public ScriptConfiguration Config { get { return config; } } #endregion @@ -90,19 +92,6 @@ namespace CodeImp.DoomBuilder.Controls // Keep panel this.panel = panel; - //mxd - navigator = new ComboBox(); - navigator.Location = new Point(EDITOR_BORDER_LEFT, NAVIGATOR_BORDER_TOP); - navigator.Width = this.ClientSize.Width - EDITOR_BORDER_LEFT - EDITOR_BORDER_RIGHT; - navigator.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - navigator.DropDownStyle = ComboBoxStyle.DropDownList; - navigator.Name = "navigator"; - navigator.TabStop = true; - navigator.TabIndex = 0; - navigator.DropDown += navigator_DropDown; - navigator.SelectedIndexChanged += navigator_SelectedIndexChanged; - this.Controls.Add(navigator); - // Make the script control editor = new ScriptEditorControl(); editor.Location = new Point(EDITOR_BORDER_LEFT, EDITOR_BORDER_TOP); @@ -121,10 +110,14 @@ namespace CodeImp.DoomBuilder.Controls editor.OnFindNext += panel.FindNext; editor.OnFindPrevious += panel.FindPrevious; //mxd editor.OnTextChanged += editor_TextChanged; //mxd - } - - // Disposer - protected override void Dispose(bool disposing) + + //mxd. Bind functionbar events + editor.FunctionBar.DropDown += functionbar_DropDown; + editor.FunctionBar.SelectedIndexChanged += functionbar_SelectedIndexChanged; + } + + // Disposer + protected override void Dispose(bool disposing) { // Remove events editor.OnExplicitSaveTab -= panel.ExplicitSaveCurrentTab; @@ -263,134 +256,28 @@ namespace CodeImp.DoomBuilder.Controls // Find next result public bool FindNext(FindReplaceOptions options, bool useselectionstart) { - byte[] data = editor.GetText(); - string text = Encoding.GetEncoding(config.CodePage).GetString(data); - StringComparison mode = options.CaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; - int startpos = (useselectionstart ? Math.Min(editor.SelectionStart, editor.SelectionEnd) : Math.Max(editor.SelectionStart, editor.SelectionEnd)); //mxd - bool wrapped = false; - - while(true) - { - int result = text.IndexOf(options.FindText, startpos, mode); - if(result > -1) - { - // Check to see if it is the whole word - if(options.WholeWord) - { - // Veryfy that we have found a whole word - string foundword = editor.GetWordAt(result + 1); - if(foundword.Length != options.FindText.Length) - { - startpos = result + 1; - result = -1; - } - } - - // Still ok? - if(result > -1) - { - // Select the result - editor.SelectionStart = result; - editor.SelectionEnd = result + options.FindText.Length; - editor.EnsureLineVisible(editor.LineFromPosition(editor.SelectionEnd)); - return true; - } - } - else - { - // If we haven't tried from the start, try from the start now - if((startpos > 0) && !wrapped) - { - startpos = 0; - wrapped = true; - } - else - { - // Can't find it - return false; - } - } - } + return editor.FindNext(options, useselectionstart); } // Find previous result (mxd) public bool FindPrevious(FindReplaceOptions options) { - bool wrapped = false; - byte[] data = editor.GetText(); - string text = Encoding.GetEncoding(config.CodePage).GetString(data); - StringComparison mode = options.CaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; - int endpos = Math.Min(editor.SelectionStart, editor.SelectionEnd) - 1; - if(endpos < 0) - { - endpos = text.Length - 1; - wrapped = true; - } - - while(true) - { - int result = text.LastIndexOf(options.FindText, endpos, mode); - if(result > -1) - { - // Check to see if it is the whole word - if(options.WholeWord) - { - // Veryfy that we have found a whole word - string foundword = editor.GetWordAt(result + 1); - if(foundword.Length != options.FindText.Length) - { - endpos = result - 1; - result = -1; - } - } - - // Still ok? - if(result > -1) - { - // Select the result - editor.SelectionStart = result; - editor.SelectionEnd = result + options.FindText.Length; - editor.EnsureLineVisible(editor.LineFromPosition(editor.SelectionEnd)); - return true; - } - } - else - { - // If we haven't tried from the end, try from the end now - if(!wrapped) - { - endpos = Math.Max(0, text.Length - 2); - wrapped = true; - } - else - { - // Can't find it - return false; - } - } - } - } + return editor.FindPrevious(options); + } // This replaces the selection with the given text public void ReplaceSelection(string replacement) { editor.ReplaceSelection(replacement); } - - // This returns the selected text - public string GetSelectedText() - { - byte[] data = editor.GetText(); - string text = Encoding.GetEncoding(config.CodePage).GetString(data); - if(editor.SelectionStart < editor.SelectionEnd) - return text.Substring(editor.SelectionStart, editor.SelectionEnd - editor.SelectionStart); - return ""; - } //mxd - protected void UpdateNavigator() + protected void UpdateNavigator() { - switch(config.ScriptType) + // Store currently selected item name + string prevtext = editor.FunctionBar.Text; + + switch (config.ScriptType) { case ScriptType.ACS: UpdateNavigatorAcs(new MemoryStream(editor.GetText())); @@ -405,17 +292,33 @@ namespace CodeImp.DoomBuilder.Controls break; default: // Unsupported script type. Just clear the items - navigator.Items.Clear(); - break; + editor.FunctionBar.Items.Clear(); + break; } - // Put some text in the navigator (but don't actually trigger selection event) - navigator.Enabled = (navigator.Items.Count > 0); - if(navigator.Items.Count > 0) - { + // Put some text in the navigator (but don't actually trigger selection event) + editor.FunctionBar.Enabled = (editor.FunctionBar.Items.Count > 0); + if (editor.FunctionBar.Items.Count > 0) + { preventchanges = true; - navigator.Text = navigator.Items[0].ToString(); - preventchanges = false; + + // Put the text back if we still have the corresponding item + if (!string.IsNullOrEmpty(prevtext)) + { + foreach (var item in editor.FunctionBar.Items) + { + if (item.ToString() == prevtext) + { + editor.FunctionBar.Text = item.ToString(); + break; + } + } + } + + // No dice. Use the first item + if (string.IsNullOrEmpty(editor.FunctionBar.Text)) + editor.FunctionBar.Text = editor.FunctionBar.Items[0].ToString(); + preventchanges = false; } } @@ -423,13 +326,13 @@ namespace CodeImp.DoomBuilder.Controls private void UpdateNavigatorDecorate(MemoryStream stream) { if(stream == null) return; - navigator.Items.Clear(); + editor.FunctionBar.Items.Clear(); - DecorateParserSE parser = new DecorateParserSE(); + DecorateParserSE parser = new DecorateParserSE(); if(parser.Parse(stream, "DECORATE", false)) { - navigator.Items.AddRange(parser.Actors.ToArray()); - } + editor.FunctionBar.Items.AddRange(parser.Actors.ToArray()); + } if(parser.HasError) { @@ -441,13 +344,13 @@ namespace CodeImp.DoomBuilder.Controls private void UpdateNavigatorModeldef(MemoryStream stream) { if(stream == null) return; - navigator.Items.Clear(); + editor.FunctionBar.Items.Clear(); - ModeldefParserSE parser = new ModeldefParserSE(); + ModeldefParserSE parser = new ModeldefParserSE(); if(parser.Parse(stream, "MODELDEF", false)) { - navigator.Items.AddRange(parser.Models.ToArray()); - } + editor.FunctionBar.Items.AddRange(parser.Models.ToArray()); + } if(parser.HasError) { @@ -459,15 +362,15 @@ namespace CodeImp.DoomBuilder.Controls private void UpdateNavigatorAcs(MemoryStream stream) { if(stream == null) return; - navigator.Items.Clear(); + editor.FunctionBar.Items.Clear(); - AcsParserSE parser = new AcsParserSE { AddArgumentsToScriptNames = true, IsMapScriptsLump = this is ScriptLumpDocumentTab }; + AcsParserSE parser = new AcsParserSE { AddArgumentsToScriptNames = true, IsMapScriptsLump = this is ScriptLumpDocumentTab }; if(parser.Parse(stream, "SCRIPTS", false)) { - navigator.Items.AddRange(parser.NamedScripts.ToArray()); - navigator.Items.AddRange(parser.NumberedScripts.ToArray()); - navigator.Items.AddRange(parser.Functions.ToArray()); - } + editor.FunctionBar.Items.AddRange(parser.NamedScripts.ToArray()); + editor.FunctionBar.Items.AddRange(parser.NumberedScripts.ToArray()); + editor.FunctionBar.Items.AddRange(parser.Functions.ToArray()); + } if(parser.HasError) { @@ -493,18 +396,25 @@ namespace CodeImp.DoomBuilder.Controls return ScriptType.UNKNOWN; } - //mxd - internal void InsertSnippet(string[] lines) - { - editor.InsertSnippet(lines); - } + //mxd + internal void InsertSnippet(string name) + { + string[] lines = config.GetSnippet(name); + if (lines != null) editor.InsertSnippet(lines); + } - #endregion - - #region ================== Events - - // Mouse released - protected override void OnMouseUp(MouseEventArgs e) + //mxd + internal void IndentSelection(bool indent) + { + editor.IndentSelection(indent); + } + + #endregion + + #region ================== Events + + // Mouse released + protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); @@ -523,13 +433,13 @@ namespace CodeImp.DoomBuilder.Controls editor.GrabFocus(); } - //mxd - private void navigator_SelectedIndexChanged(object sender, EventArgs e) - { - if(!preventchanges && navigator.SelectedItem is ScriptItem) - { - ScriptItem si = navigator.SelectedItem as ScriptItem; - editor.EnsureLineVisible(editor.LineFromPosition(si.CursorPosition)); + //mxd + private void functionbar_SelectedIndexChanged(object sender, EventArgs e) + { + if (!preventchanges && editor.FunctionBar.SelectedItem is ScriptItem) + { + ScriptItem si = editor.FunctionBar.SelectedItem as ScriptItem; + editor.EnsureLineVisible(editor.LineFromPosition(si.CursorPosition)); editor.SelectionStart = si.CursorPosition; editor.SelectionEnd = si.CursorPosition; @@ -539,9 +449,9 @@ namespace CodeImp.DoomBuilder.Controls } } - //mxd - private void navigator_DropDown(object sender, EventArgs e) - { + //mxd + private void functionbar_DropDown(object sender, EventArgs e) + { if(!preventchanges && editor.IsChanged) UpdateNavigator(); } diff --git a/Source/Core/Controls/ScriptEditorControl.Designer.cs b/Source/Core/Controls/ScriptEditorControl.Designer.cs index 8f6bf47..c8205ed 100644 --- a/Source/Core/Controls/ScriptEditorControl.Designer.cs +++ b/Source/Core/Controls/ScriptEditorControl.Designer.cs @@ -1,167 +1,106 @@ namespace CodeImp.DoomBuilder.Controls { - partial class ScriptEditorControl - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; + partial class ScriptEditorControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if(disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } - #region Component Designer generated code + #region Component Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.functionbar = new System.Windows.Forms.ComboBox(); - this.scriptedit = new CodeImp.DoomBuilder.Controls.ScintillaControl(); - this.scriptpanel = new System.Windows.Forms.Panel(); - this.scriptpanel.SuspendLayout(); - this.SuspendLayout(); - // - // functionbar - // - this.functionbar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.functionbar.FormattingEnabled = true; - this.functionbar.Items.AddRange(new object[] { - "Function1", - "Function2", - "Function3"}); - this.functionbar.Location = new System.Drawing.Point(0, 0); - this.functionbar.Name = "functionbar"; - this.functionbar.Size = new System.Drawing.Size(474, 21); - this.functionbar.TabIndex = 1; - this.functionbar.TabStop = false; - // - // scriptedit - // - this.scriptedit.AnchorPosition = 0; - this.scriptedit.AutoCMaximumHeight = 0; - this.scriptedit.AutoCMaximumWidth = 0; - this.scriptedit.AutoCSeparator = 0; - this.scriptedit.AutoCTypeSeparator = 0; - this.scriptedit.BackColor = System.Drawing.SystemColors.Window; - this.scriptedit.CaretFore = 0; - this.scriptedit.CaretLineBack = 0; - this.scriptedit.CaretPeriod = 0; - this.scriptedit.CaretWidth = 0; - this.scriptedit.CodePage = 0; - this.scriptedit.ControlCharSymbol = 0; - this.scriptedit.CurrentPos = 0; - this.scriptedit.CursorType = 0; - this.scriptedit.Dock = System.Windows.Forms.DockStyle.Fill; - this.scriptedit.DocPointer = 0; - this.scriptedit.EdgeColour = 0; - this.scriptedit.EdgeColumn = 0; - this.scriptedit.EdgeMode = 0; - this.scriptedit.EndAtLastLine = 0; - this.scriptedit.EndOfLineMode = CodeImp.DoomBuilder.Controls.ScriptEndOfLine.CRLF; - this.scriptedit.EOLMode = 0; - this.scriptedit.ExtraAscent = 0; - this.scriptedit.ExtraDescent = 0; - this.scriptedit.HighlightGuide = 0; - this.scriptedit.Indent = 0; - this.scriptedit.IndentationGuides = 0; - this.scriptedit.IsAutoCGetAutoHide = false; - this.scriptedit.IsAutoCGetCancelAtStart = false; - this.scriptedit.IsAutoCGetChooseSingle = false; - this.scriptedit.IsAutoCGetDropRestOfWord = false; - this.scriptedit.IsAutoCGetIgnoreCase = false; - this.scriptedit.IsBackSpaceUnIndents = false; - this.scriptedit.IsBufferedDraw = false; - this.scriptedit.IsCaretLineVisible = false; - this.scriptedit.IsFocus = false; - this.scriptedit.IsHScrollBar = false; - this.scriptedit.IsMouseDownCaptures = false; - this.scriptedit.IsOvertype = false; - this.scriptedit.IsReadOnly = false; - this.scriptedit.IsTabIndents = false; - this.scriptedit.IsTwoPhaseDraw = false; - this.scriptedit.IsUndoCollection = false; - this.scriptedit.IsUsePalette = false; - this.scriptedit.IsUseTabs = false; - this.scriptedit.IsViewEOL = false; - this.scriptedit.IsVScrollBar = false; - this.scriptedit.LayoutCache = 0; - this.scriptedit.Lexer = 0; - this.scriptedit.Location = new System.Drawing.Point(0, 0); - this.scriptedit.MarginLeft = 0; - this.scriptedit.MarginRight = 0; - this.scriptedit.ModEventMask = 0; - this.scriptedit.MouseDwellTime = 0; - this.scriptedit.Name = "scriptedit"; - this.scriptedit.PrintColourMode = 0; - this.scriptedit.PrintMagnification = 0; - this.scriptedit.PrintWrapMode = 0; - this.scriptedit.ScrollWidth = 0; - this.scriptedit.SearchFlags = 0; - this.scriptedit.SelectionEnd = 0; - this.scriptedit.SelectionMode = 0; - this.scriptedit.SelectionStart = 0; - this.scriptedit.Size = new System.Drawing.Size(470, 377); - this.scriptedit.Status = 0; - this.scriptedit.StyleBits = 0; - this.scriptedit.TabIndex = 0; - this.scriptedit.TabStop = false; - this.scriptedit.TabWidth = 0; - this.scriptedit.TargetEnd = 0; - this.scriptedit.TargetStart = 0; - this.scriptedit.ViewWhitespace = CodeImp.DoomBuilder.Controls.ScriptWhiteSpace.Invisible; - this.scriptedit.ViewWS = 0; - this.scriptedit.WrapMode = 0; - this.scriptedit.WrapStartIndent = 0; - this.scriptedit.WrapVisualFlags = 0; - this.scriptedit.WrapVisualFlagsLocation = 0; - this.scriptedit.XOffset = 0; - this.scriptedit.ZoomLevel = 0; - this.scriptedit.KeyUp += new System.Windows.Forms.KeyEventHandler(this.scriptedit_KeyUp); - this.scriptedit.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scriptedit_KeyDown); - // - // scriptpanel - // - this.scriptpanel.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.scriptpanel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.scriptpanel.Controls.Add(this.scriptedit); - this.scriptpanel.Location = new System.Drawing.Point(0, 27); - this.scriptpanel.Name = "scriptpanel"; - this.scriptpanel.Size = new System.Drawing.Size(474, 381); - this.scriptpanel.TabIndex = 2; - // - // ScriptEditorControl - // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.Controls.Add(this.scriptpanel); - this.Controls.Add(this.functionbar); - this.Name = "ScriptEditorControl"; - this.Size = new System.Drawing.Size(474, 408); - this.scriptpanel.ResumeLayout(false); - this.ResumeLayout(false); + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.scriptedit = new ScintillaNET.Scintilla(); + this.scriptpanel = new System.Windows.Forms.Panel(); + this.functionbar = new System.Windows.Forms.ComboBox(); + this.scriptpanel.SuspendLayout(); + this.SuspendLayout(); + // + // scriptedit + // + this.scriptedit.AutoCIgnoreCase = true; + this.scriptedit.AutoCMaxHeight = 12; + this.scriptedit.AutoCOrder = ScintillaNET.Order.Custom; + this.scriptedit.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.scriptedit.CaretWidth = 2; + this.scriptedit.Dock = System.Windows.Forms.DockStyle.Fill; + this.scriptedit.ExtraAscent = 1; + this.scriptedit.ExtraDescent = 1; + this.scriptedit.FontQuality = ScintillaNET.FontQuality.LcdOptimized; + this.scriptedit.Location = new System.Drawing.Point(0, 0); + this.scriptedit.Name = "scriptedit"; + this.scriptedit.ScrollWidth = 200; + this.scriptedit.Size = new System.Drawing.Size(474, 381); + this.scriptedit.TabIndex = 0; + this.scriptedit.TabStop = false; + this.scriptedit.UseTabs = true; + this.scriptedit.WhitespaceSize = 2; + this.scriptedit.TextChanged += new System.EventHandler(this.scriptedit_TextChanged); + this.scriptedit.CharAdded += new System.EventHandler(this.scriptedit_CharAdded); + this.scriptedit.AutoCCompleted += new System.EventHandler(this.scriptedit_AutoCCompleted); + this.scriptedit.InsertCheck += new System.EventHandler(this.scriptedit_InsertCheck); + this.scriptedit.KeyUp += new System.Windows.Forms.KeyEventHandler(this.scriptedit_KeyUp); + this.scriptedit.UpdateUI += new System.EventHandler(this.scriptedit_UpdateUI); + this.scriptedit.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scriptedit_KeyDown); + // + // scriptpanel + // + this.scriptpanel.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.scriptpanel.Controls.Add(this.scriptedit); + this.scriptpanel.Location = new System.Drawing.Point(0, 27); + this.scriptpanel.Name = "scriptpanel"; + this.scriptpanel.Size = new System.Drawing.Size(474, 381); + this.scriptpanel.TabIndex = 2; + // + // functionbar + // + this.functionbar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.functionbar.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.functionbar.FormattingEnabled = true; + this.functionbar.Location = new System.Drawing.Point(0, 0); + this.functionbar.Name = "functionbar"; + this.functionbar.Size = new System.Drawing.Size(474, 21); + this.functionbar.TabIndex = 2; + this.functionbar.TabStop = false; + // + // ScriptEditorControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.Controls.Add(this.scriptpanel); + this.Controls.Add(this.functionbar); + this.Name = "ScriptEditorControl"; + this.Size = new System.Drawing.Size(474, 408); + this.scriptpanel.ResumeLayout(false); + this.ResumeLayout(false); - } + } - #endregion + #endregion - private ScintillaControl scriptedit; - private System.Windows.Forms.ComboBox functionbar; - private System.Windows.Forms.Panel scriptpanel; - } -} + private ScintillaNET.Scintilla scriptedit; + private System.Windows.Forms.Panel scriptpanel; + private System.Windows.Forms.ComboBox functionbar; + } +} \ No newline at end of file diff --git a/Source/Core/Controls/ScriptEditorControl.cs b/Source/Core/Controls/ScriptEditorControl.cs index 9b851e5..c442c20 100644 --- a/Source/Core/Controls/ScriptEditorControl.cs +++ b/Source/Core/Controls/ScriptEditorControl.cs @@ -17,941 +17,1357 @@ #region ================== Namespaces using System; +using System.Collections; using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.IO; using System.Text; using System.Windows.Forms; using CodeImp.DoomBuilder.Config; -using System.IO; using CodeImp.DoomBuilder.IO; -using System.Collections; -using System.Globalization; using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Properties; using CodeImp.DoomBuilder.Windows; +using ScintillaNET; #endregion namespace CodeImp.DoomBuilder.Controls { - internal partial class ScriptEditorControl : UserControl - { - #region ================== Constants - - private const string LEXERS_RESOURCE = "Lexers.cfg"; - private const int DEFAULT_STYLE = (int)ScriptStylesCommon.Default; - private const int MAX_BACKTRACK_LENGTH = 200; + internal partial class ScriptEditorControl : UserControl + { + #region ================== Enums - // Index for registered images - private enum ImageIndex - { - ScriptConstant = 0, - ScriptKeyword = 1, - ScriptError = 2, - ScriptSnippet = 3, //mxd - } - - #endregion + private enum ScriptStyleType + { + PlainText = 0, + Keyword = 1, + Constant = 2, + Comment = 3, + Literal = 4, + LineNumber = 5, + String = 6, //mxd + Include = 7, //mxd + } - #region ================== Delegates / Events + // Index for registered images + private enum ImageIndex + { + ScriptConstant = 0, + ScriptKeyword = 1, + ScriptError = 2, + ScriptSnippet = 3, //mxd + } - public delegate void ExplicitSaveTabDelegate(); - public delegate void OpenScriptBrowserDelegate(); - public delegate void OpenFindReplaceDelegate(); - public delegate void FindNextDelegate(); - public delegate void FindPreviousDelegate(); //mxd + #endregion - public event ExplicitSaveTabDelegate OnExplicitSaveTab; - public event OpenScriptBrowserDelegate OnOpenScriptBrowser; - public event OpenFindReplaceDelegate OnOpenFindAndReplace; - public event FindNextDelegate OnFindNext; - public event FindPreviousDelegate OnFindPrevious; //mxd - public new event EventHandler OnTextChanged; //mxd + #region ================== Constants - #endregion + private const string LEXERS_RESOURCE = "Lexers.cfg"; + private const int MAX_BACKTRACK_LENGTH = 200; + private const int HIGHLIGHT_INDICATOR = 8; //mxd. Indicators 0-7 could be in use by a lexer so we'll use indicator 8 to highlight words. - #region ================== Variables - - // Script configuration - private ScriptConfiguration scriptconfig; - - // List of keywords and constants, sorted as uppercase - private string autocompletestring; + #endregion - // Style translation from Scintilla style to ScriptStyleType - private Dictionary stylelookup; - - // Current position information - private string curfunctionname = ""; - private int curargumentindex; - private int curfunctionstartpos; - - // Status - private bool changed; - - #endregion + #region ================== Delegates / Events - #region ================== Properties + public delegate void ExplicitSaveTabDelegate(); + public delegate void OpenScriptBrowserDelegate(); + public delegate void OpenFindReplaceDelegate(); + public delegate void FindNextDelegate(); + public delegate void FindPreviousDelegate(); //mxd - public bool IsChanged { get { return changed; } set { changed = value; } } - public int Position { get { return scriptedit.CurrentPos; } set { scriptedit.CurrentPos = value; } } - public int SelectionStart { get { return scriptedit.SelectionStart; } set { scriptedit.SelectionStart = value; } } - public int SelectionEnd { get { return scriptedit.SelectionEnd; } set { scriptedit.SelectionEnd = value; } } - - #endregion + public event ExplicitSaveTabDelegate OnExplicitSaveTab; + public event OpenScriptBrowserDelegate OnOpenScriptBrowser; + public event OpenFindReplaceDelegate OnOpenFindAndReplace; + public event FindNextDelegate OnFindNext; + public event FindPreviousDelegate OnFindPrevious; //mxd + public new event EventHandler OnTextChanged; //mxd - #region ================== Contructor / Disposer + #endregion - // Constructor - public ScriptEditorControl() - { - // Initialize - InitializeComponent(); - - // Script editor properties - // Unfortunately, these cannot be set using the designer - // because the control is not really loaded in design mode - scriptedit.AutoCMaximumHeight = 8; - scriptedit.AutoCSeparator = ' '; - scriptedit.AutoCTypeSeparator = '?'; - scriptedit.AutoCSetFillUps("\r\n();[]"); // I should put this in the script configs - scriptedit.CaretWidth = 2; - scriptedit.EndAtLastLine = 1; - scriptedit.EndOfLineMode = ScriptEndOfLine.CRLF; - scriptedit.IsAutoCGetChooseSingle = true; - scriptedit.IsAutoCGetIgnoreCase = true; - scriptedit.IsBackSpaceUnIndents = true; - scriptedit.IsBufferedDraw = true; - scriptedit.IsCaretLineVisible = false; - scriptedit.IsHScrollBar = true; - scriptedit.IndentationGuides = (int)ScriptIdentGuides.None; - scriptedit.IsMouseDownCaptures = true; - scriptedit.IsTabIndents = true; - scriptedit.IsUndoCollection = true; - scriptedit.IsUseTabs = true; - scriptedit.IsViewEOL = false; - scriptedit.IsVScrollBar = true; - scriptedit.SetFoldFlags((int)ScriptFoldFlag.Box); - scriptedit.TabWidth = 4; - scriptedit.Indent = 4; - scriptedit.ExtraAscent = 1; - scriptedit.ExtraDescent = 1; - scriptedit.CursorType = -1; + #region ================== Variables - // Symbol margin - scriptedit.SetMarginTypeN(0, (int)ScriptMarginType.Symbol); - scriptedit.SetMarginWidthN(0, 20); - scriptedit.SetMarginMaskN(0, -1); // all - - // Line numbers margin - scriptedit.SetMarginTypeN(1, (int)ScriptMarginType.Number); - scriptedit.SetMarginWidthN(1, 40); - scriptedit.SetMarginMaskN(1, 0); // none + // Script configuration + private ScriptConfiguration scriptconfig; - // Spacing margin - scriptedit.SetMarginTypeN(2, (int)ScriptMarginType.Symbol); - scriptedit.SetMarginWidthN(2, 5); - scriptedit.SetMarginMaskN(2, 0); // none - - // Setup with default script config - // Disabled, the form designer doesn't like this - //SetupStyles(new ScriptConfiguration()); + // List of keywords and constants + private List autocompletelist; - // Images - RegisterAutoCompleteImage(ImageIndex.ScriptConstant, Resources.ScriptConstant); - RegisterAutoCompleteImage(ImageIndex.ScriptKeyword, Resources.ScriptKeyword); - RegisterAutoCompleteImage(ImageIndex.ScriptSnippet, Resources.ScriptSnippet); //mxd - RegisterMarkerImage(ImageIndex.ScriptError, Resources.ScriptError); + // Style translation from Scintilla style to ScriptStyleType + private Dictionary stylelookup; - // Events - scriptedit.ModEventMask = 0x7FFFF; // Which events to receive (see also ScriptModificationFlags) - scriptedit.TextDeleted += scriptedit_TextChanged; //mxd - scriptedit.TextInserted += scriptedit_TextChanged; //mxd - scriptedit.UndoPerformed += scriptedit_UndoRedoPerformed; //mxd - scriptedit.RedoPerformed += scriptedit_UndoRedoPerformed; //mxd - } - - #endregion - - #region ================== Methods - - // This launches keyword help website - public bool LaunchKeywordHelp() - { - string helpsite = scriptconfig.KeywordHelp; - string currentword = GetCurrentWord(); - if(!string.IsNullOrEmpty(currentword) && (currentword.Length > 1) && !string.IsNullOrEmpty(helpsite)) - { - currentword = scriptconfig.GetKeywordCase(currentword); - helpsite = helpsite.Replace("%K", currentword); - General.OpenWebsite(helpsite); - return true; - } - return !string.IsNullOrEmpty(helpsite); //mxd - } - - // This replaces the selection with the given text - public void ReplaceSelection(string replacement) - { - Encoding encoder = Encoding.GetEncoding(scriptedit.CodePage); - string text = encoder.GetString(GetText()); - int selectionstart = scriptedit.SelectionStart; - - // Make new text - StringBuilder newtext = new StringBuilder(text.Length + replacement.Length); - newtext.Append(text.Substring(0, scriptedit.SelectionStart)); - newtext.Append(replacement); - newtext.Append(text.Substring(scriptedit.SelectionEnd)); - - SetText(encoder.GetBytes(newtext.ToString())); - - // Adjust selection - scriptedit.SelectionStart = selectionstart; - scriptedit.SelectionEnd = selectionstart + replacement.Length; - } - - // This moves the caret to a given line and ensures the line is visible - public void MoveToLine(int linenumber) - { - scriptedit.GotoLine(linenumber); - EnsureLineVisible(linenumber); - } + // Current position information + private string curfunctionname = ""; + private int curargumentindex; + private int curfunctionstartpos; + private int linenumbercharlength; //mxd. Current max number of chars in the line number + private int lastcaretpos; //mxd. Used in brace matching + private int caretoffset; //mxd. Used to modify caret position after autogenerating stuff + private bool skiptextinsert; //mxd. Gross hacks + private bool expandcodeblock; //mxd. More gross hacks + private string highlightedword; //mxd - // This makes sure a line is visible - public void EnsureLineVisible(int linenumber) - { - scriptedit.EnsureVisibleEnforcePolicy(linenumber); - } + #endregion - // This returns the line for a position - public int LineFromPosition(int position) - { - return scriptedit.LineFromPosition(position); - } - - // This clears all marks - public void ClearMarks() - { - scriptedit.MarkerDeleteAll((int)ImageIndex.ScriptError); - } + #region ================== Properties - // This adds a mark on the given line - public void AddMark(int linenumber) - { - scriptedit.MarkerAdd(linenumber, (int)ImageIndex.ScriptError); - } + public bool IsChanged { get { return scriptedit.Modified; } } + public int SelectionStart { get { return scriptedit.SelectionStart; } set { scriptedit.SelectionStart = value; } } + public int SelectionEnd { get { return scriptedit.SelectionEnd; } set { scriptedit.SelectionEnd = value; } } + public new string Text { get { return scriptedit.Text; } set { scriptedit.Text = value; } } //mxd + public string SelectedText { get { return scriptedit.SelectedText; } } //mxd + public bool ShowWhitespace { get { return scriptedit.ViewWhitespace != WhitespaceMode.Invisible; } set { scriptedit.ViewWhitespace = value ? WhitespaceMode.VisibleAlways : WhitespaceMode.Invisible; } } + public bool WrapLongLines { get { return scriptedit.WrapMode != WrapMode.None; } set { scriptedit.WrapMode = (value ? WrapMode.Char : WrapMode.None); } } + public ComboBox FunctionBar { get { return functionbar; } } //mxd + public Scintilla Scintilla { get { return scriptedit; } } //mxd - // This refreshes the style setup - public void RefreshStyle() - { - // Re-setup with the same config - SetupStyles(scriptconfig); - } + #endregion - // This sets up the script editor with a script configuration - public void SetupStyles(ScriptConfiguration config) - { - Configuration lexercfg = new Configuration(); + #region ================== Contructor / Disposer - // Make collections - stylelookup = new Dictionary(); - SortedList autocompletelist = new SortedList(StringComparer.Ordinal); - - // Keep script configuration - scriptconfig = config; - - // Find a resource named Lexers.cfg - string[] resnames = General.ThisAssembly.GetManifestResourceNames(); - foreach(string rn in resnames) - { - // Found one? - if(rn.EndsWith(LEXERS_RESOURCE, StringComparison.InvariantCultureIgnoreCase)) - { - // Get a stream from the resource - Stream lexersdata = General.ThisAssembly.GetManifestResourceStream(rn); - StreamReader lexersreader = new StreamReader(lexersdata, Encoding.ASCII); + // Constructor + public ScriptEditorControl() + { + // Initialize + InitializeComponent(); - // Load configuration from stream - lexercfg.InputConfiguration(lexersreader.ReadToEnd()); + // Script editor properties + //TODO: use ScintillaNET properties instead when they become available + scriptedit.DirectMessage(NativeMethods.SCI_SETBACKSPACEUNINDENTS, new IntPtr(1)); + scriptedit.DirectMessage(NativeMethods.SCI_SETMOUSEDOWNCAPTURES, new IntPtr(1)); + scriptedit.DirectMessage(NativeMethods.SCI_SETTABINDENTS, new IntPtr(1)); - // Done with the resource - lexersreader.Dispose(); - lexersdata.Dispose(); - } - } - - // Check if specified lexer exists and set the lexer to use - string lexername = "lexer" + scriptconfig.Lexer.ToString(CultureInfo.InvariantCulture); - if(!lexercfg.SettingExists(lexername)) throw new InvalidOperationException("Unknown lexer " + scriptconfig.Lexer + " specified in script configuration!"); - scriptedit.Lexer = scriptconfig.Lexer; - - // Set the default style and settings - scriptedit.StyleSetFont(DEFAULT_STYLE, General.Settings.ScriptFontName); - scriptedit.StyleSetSize(DEFAULT_STYLE, General.Settings.ScriptFontSize); - scriptedit.StyleSetBold(DEFAULT_STYLE, General.Settings.ScriptFontBold); - scriptedit.StyleSetItalic(DEFAULT_STYLE, false); - scriptedit.StyleSetUnderline(DEFAULT_STYLE, false); - scriptedit.StyleSetCase(DEFAULT_STYLE, ScriptCaseVisible.Mixed); - scriptedit.StyleSetFore(DEFAULT_STYLE, General.Colors.PlainText.ToInversedColorRef()); - scriptedit.StyleSetBack(DEFAULT_STYLE, General.Colors.ScriptBackground.ToInversedColorRef()); - scriptedit.CaretPeriod = SystemInformation.CaretBlinkTime; - scriptedit.CaretFore = General.Colors.ScriptBackground.Inverse().ToInversedColorRef(); - scriptedit.StyleBits = 7; - - // These don't work? - scriptedit.TabWidth = General.Settings.ScriptTabWidth; - scriptedit.IsUseTabs = false; - scriptedit.IsTabIndents = true; - scriptedit.Indent = General.Settings.ScriptTabWidth; - scriptedit.IsBackSpaceUnIndents = true; - - // This applies the default style to all styles - scriptedit.StyleClearAll(); + // Symbol margin + scriptedit.Margins[0].Type = MarginType.Symbol; + scriptedit.Margins[0].Width = 20; + scriptedit.Margins[0].Mask = 1 << (int)ImageIndex.ScriptError; // Error marker only + scriptedit.Margins[0].Cursor = MarginCursor.Arrow; + scriptedit.Margins[0].Sensitive = true; - // Set the code page to use - scriptedit.CodePage = scriptconfig.CodePage; + // Line numbers margin + scriptedit.Margins[1].Type = MarginType.Number; + scriptedit.Margins[1].Width = 16; + scriptedit.Margins[1].Mask = 0; // No markers here - // Set the default to something normal (this is used by the autocomplete list) - scriptedit.StyleSetFont(DEFAULT_STYLE, this.Font.Name); - scriptedit.StyleSetBold(DEFAULT_STYLE, this.Font.Bold); - scriptedit.StyleSetItalic(DEFAULT_STYLE, this.Font.Italic); - scriptedit.StyleSetUnderline(DEFAULT_STYLE, this.Font.Underline); - scriptedit.StyleSetSize(DEFAULT_STYLE, (int)Math.Round(this.Font.SizeInPoints)); - - // Set style for linenumbers and margins - scriptedit.StyleSetBack((int)ScriptStylesCommon.LineNumber, General.Colors.ScriptBackground.ToInversedColorRef()); - - // Clear all keywords - for(int i = 0; i < 9; i++) scriptedit.KeyWords(i, null); - - // Now go for all elements in the lexer configuration - // We are looking for the numeric keys, because these are the - // style index to set and the value is our ScriptStyleType - IDictionary dic = lexercfg.ReadSetting(lexername, new Hashtable()); - foreach(DictionaryEntry de in dic) - { - // Check if this is a numeric key - int stylenum; - if(int.TryParse(de.Key.ToString(), out stylenum)) - { - // Add style to lookup table - stylelookup.Add(stylenum, (ScriptStyleType)(int)de.Value); - - // Apply color to style - int colorindex; - switch((ScriptStyleType)(int)de.Value) - { - case ScriptStyleType.PlainText: colorindex = ColorCollection.PLAINTEXT; break; - case ScriptStyleType.Comment: colorindex = ColorCollection.COMMENTS; break; - case ScriptStyleType.Constant: colorindex = ColorCollection.CONSTANTS; break; - case ScriptStyleType.Keyword: colorindex = ColorCollection.KEYWORDS; break; - case ScriptStyleType.LineNumber: colorindex = ColorCollection.LINENUMBERS; break; - case ScriptStyleType.Literal: colorindex = ColorCollection.LITERALS; break; - default: colorindex = ColorCollection.PLAINTEXT; break; - } - scriptedit.StyleSetFore(stylenum, General.Colors.Colors[colorindex].ToInversedColorRef()); - } - } - - // Create the keywords list and apply it - string imageindex = ((int)ImageIndex.ScriptKeyword).ToString(CultureInfo.InvariantCulture); - int keywordsindex = lexercfg.ReadSetting(lexername + ".keywordsindex", -1); - if(keywordsindex > -1) - { - StringBuilder keywordslist = new StringBuilder(""); - foreach(string k in scriptconfig.Keywords) - { - if(keywordslist.Length > 0) keywordslist.Append(" "); - keywordslist.Append(k); - autocompletelist.Add(k.ToUpperInvariant(), k + "?" + imageindex); - } - string words = keywordslist.ToString(); - if(scriptconfig.CaseSensitive) - scriptedit.KeyWords(keywordsindex, words); - else - scriptedit.KeyWords(keywordsindex, words.ToLowerInvariant()); - } + // Spacing margin + scriptedit.Margins[2].Type = MarginType.Symbol; + scriptedit.Margins[2].Width = 5; + scriptedit.Margins[2].Cursor = MarginCursor.Arrow; + scriptedit.Margins[2].Mask = 0; // No markers here - // Create the constants list and apply it - imageindex = ((int)ImageIndex.ScriptConstant).ToString(CultureInfo.InvariantCulture); - int constantsindex = lexercfg.ReadSetting(lexername + ".constantsindex", -1); - if(constantsindex > -1) - { - StringBuilder constantslist = new StringBuilder(""); - foreach(string c in scriptconfig.Constants) - { - if(autocompletelist.ContainsKey(c.ToUpperInvariant())) //mxd. This happens when there's a keyword and a constant with the same name... - { - General.ErrorLogger.Add(ErrorType.Error, "Constant '" + c + "' is double-defined in '" + scriptconfig.Description + "' script configuration!"); - continue; - } - - if(constantslist.Length > 0) constantslist.Append(" "); - constantslist.Append(c); - autocompletelist.Add(c.ToUpperInvariant(), c + "?" + imageindex); - } - string words = constantslist.ToString(); - if(scriptconfig.CaseSensitive) - scriptedit.KeyWords(constantsindex, words); - else - scriptedit.KeyWords(constantsindex, words.ToLowerInvariant()); - } + // Images + RegisterAutoCompleteImage(ImageIndex.ScriptConstant, Resources.ScriptConstant); + RegisterAutoCompleteImage(ImageIndex.ScriptKeyword, Resources.ScriptKeyword); + RegisterAutoCompleteImage(ImageIndex.ScriptSnippet, Resources.ScriptSnippet); //mxd + RegisterMarkerImage(ImageIndex.ScriptError, Resources.ScriptError); - //mxd. Create the snippets list and apply it - imageindex = ((int)ImageIndex.ScriptSnippet).ToString(CultureInfo.InvariantCulture); - int snippetindex = lexercfg.ReadSetting(lexername + ".snippetindex", -1); - if(snippetindex > -1 && scriptconfig.Snippets.Count > 0) - { - StringBuilder snippetslist = new StringBuilder(""); - foreach(string c in scriptconfig.Snippets.Keys) - { - if(autocompletelist.ContainsKey(c.ToUpperInvariant())) continue; - if(snippetslist.Length > 0) snippetslist.Append(" "); - snippetslist.Append(c); - autocompletelist.Add(c.ToUpperInvariant(), c + "?" + imageindex); - } - string words = snippetslist.ToString(); - if(scriptconfig.CaseSensitive) - scriptedit.KeyWords(snippetindex, words); - else - scriptedit.KeyWords(snippetindex, words.ToLowerInvariant()); - } - - // Sort the autocomplete list - List autocompleteplainlist = new List(autocompletelist.Values); - autocompletestring = string.Join(" ", autocompleteplainlist.ToArray()); - - // Show/hide the functions bar - functionbar.Visible = (scriptconfig.FunctionRegEx.Length > 0); + //mxd. These key combinations put odd characters in the script. Let's disable them + scriptedit.AssignCmdKey(Keys.Control | Keys.Q, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.W, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.E, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.R, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.Y, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.U, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.I, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.P, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.Shift | Keys.A, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.D, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.G, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.H, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.J, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.K, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.L, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.Shift | Keys.Z, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.Shift | Keys.X, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.Shift | Keys.C, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.Shift | Keys.V, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.B, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.N, Command.Null); + scriptedit.AssignCmdKey(Keys.Control | Keys.M, Command.Null); - // Rearrange the layout - bool ischanged = changed; //mxd. Don't want the "changed" status to change when changing text styles - scriptedit.ClearDocumentStyle(); - scriptedit.SetText(scriptedit.GetText(scriptedit.TextSize)); - changed = ischanged; //mxd - this.PerformLayout(); - } - - - // This returns the current word (where the caret is at) - public string GetCurrentWord() - { - return GetWordAt(scriptedit.CurrentPos); - } + //mxd. These key combinations are used to perform special actions. Let's disable them + scriptedit.AssignCmdKey(Keys.F3, Command.Null); // F3 for Find Next + scriptedit.AssignCmdKey(Keys.F2, Command.Null); // F2 for Find Previous + scriptedit.AssignCmdKey(Keys.Control | Keys.F, Command.Null); // CTRL+F for find & replace + scriptedit.AssignCmdKey(Keys.Control | Keys.S, Command.Null); // CTRL+S for save + scriptedit.AssignCmdKey(Keys.Control | Keys.O, Command.Null); // CTRL+O for open + scriptedit.AssignCmdKey(Keys.Control | Keys.Space, Command.Null); // CTRL+Space to autocomplete <- TODO: this doesn't seem to work... + } + #endregion - // This returns the word at the given position - public string GetWordAt(int position) - { - int wordstart = scriptedit.WordStartPosition(position, true); - int wordend = scriptedit.WordEndPosition(position, true); + #region ================== Public methods - // Decode the text - byte[] scripttextdata = scriptedit.GetText(scriptedit.TextSize); - Encoding encoder = Encoding.GetEncoding(scriptedit.CodePage); - string scripttext = encoder.GetString(scripttextdata); + // This launches keyword help website + public bool LaunchKeywordHelp() + { + string helpsite = scriptconfig.KeywordHelp; + string currentword = GetCurrentWord(); + if (!string.IsNullOrEmpty(currentword) && (currentword.Length > 1) && !string.IsNullOrEmpty(helpsite)) + { + currentword = scriptconfig.GetKeywordCase(currentword); + helpsite = helpsite.Replace("%K", currentword); + General.OpenWebsite(helpsite); + return true; + } - if(wordstart < wordend) - return scripttext.Substring(wordstart, wordend - wordstart); - else - return ""; - } - - - // This returns the ScriptStyleType for a given Scintilla style - private ScriptStyleType GetScriptStyle(int scintillastyle) - { - if(stylelookup.ContainsKey(scintillastyle)) - return stylelookup[scintillastyle]; - else - return ScriptStyleType.PlainText; - } - - - // This gathers information about the current caret position - private void UpdatePositionInfo() - { - int bracketlevel = 0; // bracket level counting - int argindex = 0; // function argument counting - int pos = scriptedit.CurrentPos; - - // Decode the text - byte[] scripttextdata = scriptedit.GetText(scriptedit.TextSize); - Encoding encoder = Encoding.GetEncoding(scriptedit.CodePage); - string scripttext = encoder.GetString(scripttextdata); - - // Reset position info - curfunctionname = ""; - curargumentindex = 0; - curfunctionstartpos = 0; - - // Determine lowest backtrack position - int limitpos = scriptedit.CurrentPos - MAX_BACKTRACK_LENGTH; - if(limitpos < 0) limitpos = 0; - - // We can only do this when we have function syntax information - if((scriptconfig.ArgumentDelimiter.Length == 0) || (scriptconfig.FunctionClose.Length == 0) || - (scriptconfig.FunctionOpen.Length == 0) || (scriptconfig.Terminator.Length == 0)) return; - - // Get int versions of the function syntax informantion - int argumentdelimiter = scriptconfig.ArgumentDelimiter[0]; - int functionclose = scriptconfig.FunctionClose[0]; - int functionopen = scriptconfig.FunctionOpen[0]; - int terminator = scriptconfig.Terminator[0]; - - // Continue backtracking until we reached the limitpos - while(pos >= limitpos) - { - // Backtrack 1 character - pos--; - - // Get the style and character at this position - ScriptStyleType curstyle = GetScriptStyle(scriptedit.StyleAt(pos)); - int curchar = scriptedit.CharAt(pos); - - // Then meeting ) then increase bracket level - // When meeting ( then decrease bracket level - // When bracket level goes -1, then the next word should be the function name - // Only when at bracket level 0, count the comma's for argument index - - // TODO: - // Original code checked for scope character here and breaks if found - - // Check if in plain text or keyword - if((curstyle == ScriptStyleType.PlainText) || (curstyle == ScriptStyleType.Keyword)) - { - // Closing bracket - if(curchar == functionclose) - { - bracketlevel++; - } - // Opening bracket - else if(curchar == functionopen) - { - bracketlevel--; - - // Out of the brackets? - if(bracketlevel < 0) - { - // Skip any whitespace before this bracket - do - { - // Backtrack 1 character - curchar = scriptedit.CharAt(--pos); - } - while((pos >= limitpos) && ((curchar == ' ') || (curchar == '\t') || - (curchar == '\r') || (curchar == '\n'))); - - // NOTE: We may need to set onlyWordCharacters argument in the - // following calls to false to get any argument delimiter included, - // but this may also cause a valid keyword to be combined with other - // surrounding characters that do not belong to the keyword. - - // Find the word before this bracket - int wordstart = scriptedit.WordStartPosition(pos, true); - int wordend = scriptedit.WordEndPosition(pos, true); - string word = scripttext.Substring(wordstart, wordend - wordstart); - if(word.Length > 0) - { - // Check if this is an argument delimiter - // I can't remember why I did this, but I'll probably stumble - // upon the problem if this doesn't work right (see note above) - if(word[0] == argumentdelimiter) - { - // We are now in the parent function - bracketlevel++; - argindex = 0; - } - // Now check if this is a keyword - else if(scriptconfig.IsKeyword(word)) - { - // Found it! - curfunctionname = scriptconfig.GetKeywordCase(word); - curargumentindex = argindex; - curfunctionstartpos = wordstart; - break; - } - else - { - // Don't know this word - break; - } - } - } - } - // Argument delimiter - else if(curchar == argumentdelimiter) - { - // Only count these at brackt level 0 - if(bracketlevel == 0) argindex++; - } - // Terminator - else if(curchar == terminator) - { - // Can't find anything, break now - break; - } - } - } - } - - // This clears all undo levels - public void ClearUndoRedo() - { - scriptedit.EmptyUndoBuffer(); - } - - // This registers an XPM image for the autocomplete list - private void RegisterAutoCompleteImage(ImageIndex index, byte[] imagedata) - { - // Convert to string - string bigstring = Encoding.UTF8.GetString(imagedata); - - // Register image - scriptedit.RegisterImage((int)index, bigstring); - } + return !string.IsNullOrEmpty(helpsite); //mxd + } - // This registers an XPM image for the markes list - private void RegisterMarkerImage(ImageIndex index, byte[] imagedata) - { - // Convert to string - string bigstring = Encoding.UTF8.GetString(imagedata); + // This replaces the selection with the given text + public void ReplaceSelection(string replacement) + { + scriptedit.ReplaceSelection(replacement); //mxd TODO: encoding check/conversion? + } - // Register image - scriptedit.MarkerDefinePixmap((int)index, bigstring); - } + // This moves the caret to a given line and ensures the line is visible + public void MoveToLine(int linenumber) + { + scriptedit.Lines[linenumber].Goto(); + EnsureLineVisible(linenumber); + } - // Perform undo - public void Undo() - { - scriptedit.Undo(); - } + // This makes sure a line is visible + public void EnsureLineVisible(int linenumber) + { + // Determine target lines range + int startline = Math.Max(0, linenumber - 4); + int endline = Math.Min(scriptedit.Lines.Count, Math.Max(linenumber, linenumber + scriptedit.LinesOnScreen - 6)); - // Perform redo - public void Redo() - { - scriptedit.Redo(); - } + // Go to target line + scriptedit.ShowLines(startline, endline); - // Perform cut - public void Cut() - { - scriptedit.Cut(); - } + // We may want to do some scrolling... + if (scriptedit.FirstVisibleLine >= startline) + scriptedit.Lines[startline].Goto(); + else if (scriptedit.FirstVisibleLine + scriptedit.LinesOnScreen <= endline) + scriptedit.Lines[endline].Goto(); + } - // Perform copy - public void Copy() - { - scriptedit.Copy(); - } + // This returns the line for a position + public int LineFromPosition(int position) + { + return scriptedit.LineFromPosition(position); + } - // Perform paste - public void Paste() - { - scriptedit.Paste(); - } - - // This steals the focus (use with care!) - public void GrabFocus() - { - scriptedit.GrabFocus(); - } + // This clears all marks + public void ClearMarks() + { + scriptedit.MarkerDeleteAll((int)ImageIndex.ScriptError); + } - public byte[] GetText() - { - return scriptedit.GetText(scriptedit.TextSize); - } + // This adds a mark on the given line + public void AddMark(int linenumber) + { + scriptedit.Lines[linenumber].MarkerAdd((int)ImageIndex.ScriptError); + } - public void SetText(byte[] text) - { - scriptedit.SetText(text); - } + // This refreshes the style setup + public void RefreshStyle() + { + // Re-setup with the same config + SetupStyles(scriptconfig); + } - //mxd - public void InsertSnippet(string[] lines) - { - //insert the snippet - int curline = scriptedit.LineFromPosition(scriptedit.SelectionStart); - int numtabs = scriptedit.GetLineIndentation(curline); - string tabs = Environment.NewLine + new String(' ', numtabs); - string spaces = new String(' ', General.Settings.ScriptTabWidth); - int entrypos = -1; - int entryline = -1; - string[] processedlines = ProcessLineBreaks(lines); + // This sets up the script editor with a script configuration + public void SetupStyles(ScriptConfiguration config) + { + Configuration lexercfg = new Configuration(); - for(int i = 0; i < lines.Length; i++) - { - processedlines[i] = processedlines[i].Replace("\t", spaces); + // Make collections + stylelookup = new Dictionary(); + Dictionary autocompletedict = new Dictionary(StringComparer.Ordinal); - //check if we have the [EP] marker - if(entrypos == -1) - { - int pos = processedlines[i].IndexOf("[EP]"); - if(pos != -1) - { - entryline = curline + i; - entrypos = pos + numtabs; - processedlines[i] = processedlines[i].Remove(pos, 4); - } - } - } + // Keep script configuration + scriptconfig = config; - //replace the text - string text = string.Join(tabs, processedlines); - scriptedit.SelectionStart = scriptedit.WordStartPosition(scriptedit.CurrentPos, true); - scriptedit.SelectionEnd = scriptedit.WordEndPosition(scriptedit.CurrentPos, true); - scriptedit.ReplaceSel(text); + // Find a resource named Lexers.cfg + string[] resnames = General.ThisAssembly.GetManifestResourceNames(); + foreach (string rn in resnames) + { + // Found one? + if (rn.EndsWith(LEXERS_RESOURCE, StringComparison.InvariantCultureIgnoreCase)) + { + // Get a stream from the resource + Stream lexersdata = General.ThisAssembly.GetManifestResourceStream(rn); + if (lexersdata != null) + { + StreamReader lexersreader = new StreamReader(lexersdata, Encoding.ASCII); - //move the cursor if we had the [EP] marker - if(entrypos != -1) - { - MoveToLine(entryline); - scriptedit.SelectionStart = scriptedit.PositionFromLine(entryline) + entrypos; - scriptedit.SelectionEnd = scriptedit.PositionFromLine(entryline) + entrypos; - } - } + // Load configuration from stream + lexercfg.InputConfiguration(lexersreader.ReadToEnd()); - //mxd. This converts [LB] markers to line breaks if necessary - private static string[] ProcessLineBreaks(string[] lines) - { - List result = new List(lines.Length); - string[] separator = new[] { "[LB]" }; + // Done with the resource + lexersreader.Dispose(); + lexersdata.Dispose(); + } - foreach(string line in lines) - { - if(line.IndexOf(separator[0]) != -1) - { - if(General.Settings.SnippetsAllmanStyle) - result.AddRange(line.Split(separator, StringSplitOptions.RemoveEmptyEntries)); - else - result.Add(line.Replace(separator[0], " ")); - } - else - { - result.Add(line); - } - } + //mxd. We are done here + break; + } + } - return result.ToArray(); - } + // Check if specified lexer exists and set the lexer to use + string lexername = "lexer" + (int)scriptconfig.Lexer; + if (!lexercfg.SettingExists(lexername)) throw new InvalidOperationException("Unknown lexer " + scriptconfig.Lexer + " specified in script configuration!"); + scriptedit.Lexer = scriptconfig.Lexer; - #endregion - - #region ================== Events - - // Layout needs to be re-organized - protected override void OnLayout(LayoutEventArgs e) - { - base.OnLayout(e); + // Set the default style and settings + scriptedit.Styles[Style.Default].Font = General.Settings.ScriptFontName; + scriptedit.Styles[Style.Default].Size = General.Settings.ScriptFontSize; + scriptedit.Styles[Style.Default].Bold = General.Settings.ScriptFontBold; + scriptedit.Styles[Style.Default].Italic = false; + scriptedit.Styles[Style.Default].Underline = false; + scriptedit.Styles[Style.Default].Case = StyleCase.Mixed; + scriptedit.Styles[Style.Default].ForeColor = General.Colors.PlainText.ToColor(); + scriptedit.Styles[Style.Default].BackColor = General.Colors.ScriptBackground.ToColor(); + scriptedit.CaretPeriod = SystemInformation.CaretBlinkTime; + scriptedit.CaretForeColor = General.Colors.ScriptBackground.Inverse().ToColor(); - // With or without functions bar? - if(functionbar.Visible) - { - scriptpanel.Top = functionbar.Bottom + 6; - scriptpanel.Height = this.ClientSize.Height - scriptpanel.Top; - } - else - { - scriptpanel.Top = 0; - scriptpanel.Height = this.ClientSize.Height; - } - } + // Set tabulation settings + scriptedit.UseTabs = General.Settings.ScriptUseTabs; + scriptedit.TabWidth = General.Settings.ScriptTabWidth; + //scriptedit.IndentWidth = General.Settings.ScriptTabWidth; // Equals to TabWidth by default + //TODO: use ScintillaNET properties instead when they become available + scriptedit.DirectMessage(NativeMethods.SCI_SETTABINDENTS, new IntPtr(1)); + scriptedit.DirectMessage(NativeMethods.SCI_SETBACKSPACEUNINDENTS, new IntPtr(1)); - //mxd. Script text changed - private void scriptedit_UndoRedoPerformed(ScintillaControl pSender) - { - changed = true; - if(OnTextChanged != null) OnTextChanged(this, EventArgs.Empty); - } + // This applies the default style to all styles + scriptedit.StyleClearAll(); - //mxd. Script text changed - private void scriptedit_TextChanged(ScintillaControl pSender, int position, int length, int linesAdded) - { - changed = true; - if(OnTextChanged != null) OnTextChanged(this, EventArgs.Empty); - } - - // Key pressed down - private void scriptedit_KeyDown(object sender, KeyEventArgs e) - { - // These key combinations put odd characters in the script, so I disabled them - if((e.KeyCode == Keys.Q) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.W) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.E) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.R) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.Y) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.U) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.I) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.P) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.A) && ((e.Modifiers & Keys.Control) == Keys.Control) && ((e.Modifiers & Keys.Shift) == Keys.Shift)) e.Handled = true; - else if((e.KeyCode == Keys.D) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.G) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.H) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.J) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.K) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.L) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.Z) && ((e.Modifiers & Keys.Control) == Keys.Control) && ((e.Modifiers & Keys.Shift) == Keys.Shift)) e.Handled = true; - else if((e.KeyCode == Keys.X) && ((e.Modifiers & Keys.Control) == Keys.Control) && ((e.Modifiers & Keys.Shift) == Keys.Shift)) e.Handled = true; - else if((e.KeyCode == Keys.C) && ((e.Modifiers & Keys.Control) == Keys.Control) && ((e.Modifiers & Keys.Shift) == Keys.Shift)) e.Handled = true; - else if((e.KeyCode == Keys.V) && ((e.Modifiers & Keys.Control) == Keys.Control) && ((e.Modifiers & Keys.Shift) == Keys.Shift)) e.Handled = true; - else if((e.KeyCode == Keys.B) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.N) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; - else if((e.KeyCode == Keys.M) && ((e.Modifiers & Keys.Control) == Keys.Control)) e.Handled = true; + // Set the code page to use. [mxd] No longer needed? + //scriptedit.CodePage = scriptconfig.CodePage; - // F3 for Find Next - else if((e.KeyCode == Keys.F3) && (e.Modifiers == Keys.None)) - { - if(OnFindNext != null) OnFindNext(); - e.Handled = true; - } + //mxd. We can't change Font or Size here because this will screw displayed tab width (because it's based on character width)... + // Set the default to something normal (this is used by the autocomplete list) + //scriptedit.Styles[Style.Default].Font = this.Font.Name; + scriptedit.Styles[Style.Default].Bold = this.Font.Bold; + scriptedit.Styles[Style.Default].Italic = this.Font.Italic; + scriptedit.Styles[Style.Default].Underline = this.Font.Underline; + //scriptedit.Styles[Style.Default].Size = (int)Math.Round(this.Font.SizeInPoints); - // F2 for Find Previous (mxd) - else if((e.KeyCode == Keys.F2) && (e.Modifiers == Keys.None)) - { - if(OnFindPrevious != null) OnFindPrevious(); - e.Handled = true; - } + // Set style for linenumbers and margins + scriptedit.Styles[Style.LineNumber].BackColor = General.Colors.ScriptBackground.ToColor(); - // CTRL+F for find & replace - else if((e.KeyCode == Keys.F) && ((e.Modifiers & Keys.Control) == Keys.Control)) - { - if(OnOpenFindAndReplace != null) OnOpenFindAndReplace(); - e.Handled = true; - } + //mxd. Set style for (mis)matching braces + scriptedit.Styles[Style.BraceLight].BackColor = General.Colors.ScriptBraceHighlight.ToColor(); //Color.Cyan; + scriptedit.Styles[Style.BraceBad].BackColor = General.Colors.ScriptBadBraceHighlight.ToColor(); //Color.Red; - // CTRL+S for save - else if((e.KeyCode == Keys.S) && ((e.Modifiers & Keys.Control) == Keys.Control)) - { - if(OnExplicitSaveTab != null) OnExplicitSaveTab(); - e.Handled = true; - } + //mxd. Set whitespace color + scriptedit.SetWhitespaceForeColor(true, General.Colors.ScriptWhitespace.ToColor()); - // CTRL+O for open - else if((e.KeyCode == Keys.O) && ((e.Modifiers & Keys.Control) == Keys.Control)) - { - if(OnOpenScriptBrowser != null) OnOpenScriptBrowser(); - e.Handled = true; - } + //mxd. Set selection colors + scriptedit.SetSelectionForeColor(true, General.Colors.ScriptSelectionForeColor.ToColor()); + scriptedit.SetSelectionBackColor(true, General.Colors.ScriptSelectionBackColor.ToColor()); - // CTRL+Space to autocomplete - else if((e.KeyCode == Keys.Space) && (e.Modifiers == Keys.Control)) - { - // Hide call tip if any - scriptedit.CallTipCancel(); - - // Show autocomplete - int currentpos = scriptedit.CurrentPos; - int wordstartpos = scriptedit.WordStartPosition(currentpos, true); - scriptedit.AutoCShow(currentpos - wordstartpos, autocompletestring); - - e.Handled = true; - } + // Clear all keywords + for (int i = 0; i < 9; i++) scriptedit.SetKeywords(i, null); - //mxd. Tab to expand code snippet - // Do it only when the text cursor is at the end of a keyword. - else if(e.KeyCode == Keys.Tab) - { - string curword = GetCurrentWord().ToLowerInvariant(); - if(scriptconfig.Snippets.ContainsKey(curword) && scriptedit.CurrentPos == scriptedit.WordEndPosition(scriptedit.CurrentPos, true)) - { - InsertSnippet(scriptconfig.Snippets[curword]); - e.Handled = true; - } - } + // Now go for all elements in the lexer configuration + // We are looking for the numeric keys, because these are the + // style index to set and the value is our ScriptStyleType + IDictionary dic = lexercfg.ReadSetting(lexername, new Hashtable()); + foreach (DictionaryEntry de in dic) + { + // Check if this is a numeric key + int stylenum; + if (int.TryParse(de.Key.ToString(), out stylenum)) + { + // Add style to lookup table + stylelookup.Add(stylenum, (ScriptStyleType)(int)de.Value); - //mxd. Handle screenshot saving - else if(DelayedForm.ProcessSaveScreenshotAction((int)e.KeyData)) - { - e.Handled = true; - } - } - - // Key released - private void scriptedit_KeyUp(object sender, KeyEventArgs e) - { - bool showcalltip = false; - int highlightstart = 0; - int highlightend = 0; - - // Enter pressed? - if((e.KeyCode == Keys.Enter) && (e.Modifiers == Keys.None)) - { - // Do we want auto-indent? - if(General.Settings.ScriptAutoIndent) - { - // Get the current line index and check if its not the first line - int curline = scriptedit.LineFromPosition(scriptedit.CurrentPos); - if(curline > 0 && scriptedit.GetLineIndentation(curline) == 0) - { - // Apply identation of the previous line to this line - int ident = scriptedit.GetLineIndentation(curline - 1); - scriptedit.SetLineIndentation(curline, ident); - scriptedit.SetSel(scriptedit.SelectionStart + ident, scriptedit.SelectionStart + ident); - } - } - } - - UpdatePositionInfo(); - - // Call tip shown - if(scriptedit.IsCallTipActive) - { - // Should we hide the call tip? - if(curfunctionname.Length == 0) - { - // Hide the call tip - scriptedit.CallTipCancel(); - } - else - { - // Update the call tip - showcalltip = true; - } - } - // No call tip - else - { - // Should we show a call tip? - showcalltip = (curfunctionname.Length > 0) && !scriptedit.IsAutoCActive; - } - - // Show or update call tip - if(showcalltip) - { - string functiondef = scriptconfig.GetFunctionDefinition(curfunctionname); - if(functiondef != null) - { - // Determine the range to highlight - int argsopenpos = functiondef.IndexOf(scriptconfig.FunctionOpen); - int argsclosepos = functiondef.LastIndexOf(scriptconfig.FunctionClose); - if((argsopenpos > -1) && (argsclosepos > -1)) - { - string argsstr = functiondef.Substring(argsopenpos + 1, argsclosepos - argsopenpos - 1); - string[] args = argsstr.Split(scriptconfig.ArgumentDelimiter[0]); - if((curargumentindex >= 0) && (curargumentindex < args.Length)) - { - int argoffset = 0; - for(int i = 0; i < curargumentindex; i++) argoffset += args[i].Length + 1; - highlightstart = argsopenpos + argoffset + 1; - highlightend = highlightstart + args[curargumentindex].Length; - } - } + // Apply color to style + int colorindex; + ScriptStyleType type = (ScriptStyleType)(int)de.Value; + switch (type) + { + case ScriptStyleType.PlainText: colorindex = ColorCollection.PLAINTEXT; break; + case ScriptStyleType.Comment: colorindex = ColorCollection.COMMENTS; break; + case ScriptStyleType.Constant: colorindex = ColorCollection.CONSTANTS; break; + case ScriptStyleType.Keyword: colorindex = ColorCollection.KEYWORDS; break; + case ScriptStyleType.LineNumber: colorindex = ColorCollection.LINENUMBERS; break; + case ScriptStyleType.Literal: colorindex = ColorCollection.LITERALS; break; + case ScriptStyleType.String: colorindex = ColorCollection.STRINGS; break; + case ScriptStyleType.Include: colorindex = ColorCollection.INCLUDES; break; + default: colorindex = ColorCollection.PLAINTEXT; break; + } - //mxd. If the tip obscures the view, move it down - int tippos; - int funcline = scriptedit.LineFromPosition(curfunctionstartpos); - int curline = scriptedit.LineFromPosition(scriptedit.CurrentPos); - if(curline > funcline) - tippos = scriptedit.PositionFromLine(curline) + scriptedit.GetLineIndentation(curline); //scriptedit.PositionFromLine(curline) /*+ (curfunctionstartpos - scriptedit.PositionFromLine(funcline))*/; - else - tippos = curfunctionstartpos; - - // Show tip - scriptedit.CallTipShow(tippos, functiondef); - scriptedit.CallTipSetHlt(highlightstart, highlightend); - } - } - } - - #endregion - } -} + scriptedit.Styles[stylenum].ForeColor = General.Colors.Colors[colorindex].ToColor(); + + //mxd. Display constants as uppercase + if (type == ScriptStyleType.Constant) scriptedit.Styles[stylenum].Case = StyleCase.Upper; + } + } + + // Create the keywords list and apply it + string imageindex = ((int)ImageIndex.ScriptKeyword).ToString(CultureInfo.InvariantCulture); + int keywordsindex = lexercfg.ReadSetting(lexername + ".keywordsindex", -1); + if (keywordsindex > -1) + { + StringBuilder keywordslist = new StringBuilder(""); + foreach (string k in scriptconfig.Keywords) + { + if (keywordslist.Length > 0) keywordslist.Append(" "); + keywordslist.Append(k); + + //mxd. Skip adding the keyword if we have a snippet with the same name + if (!scriptconfig.Snippets.Contains(k)) + autocompletedict.Add(k.ToUpperInvariant(), k + "?" + imageindex); + } + string words = keywordslist.ToString(); + scriptedit.SetKeywords(keywordsindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); + } + + // Create the constants list and apply it + imageindex = ((int)ImageIndex.ScriptConstant).ToString(CultureInfo.InvariantCulture); + int constantsindex = lexercfg.ReadSetting(lexername + ".constantsindex", -1); + if (constantsindex > -1) + { + StringBuilder constantslist = new StringBuilder(""); + foreach (string c in scriptconfig.Constants) + { + if (autocompletedict.ContainsKey(c.ToUpperInvariant())) //mxd. This happens when there's a keyword and a constant with the same name... + { + General.ErrorLogger.Add(ErrorType.Error, "Constant '" + c + "' is double-defined in '" + scriptconfig.Description + "' script configuration!"); + continue; + } + + if (constantslist.Length > 0) constantslist.Append(" "); + constantslist.Append(c); + + //mxd. Skip adding the constant if we have a snippet with the same name + if (!scriptconfig.Snippets.Contains(c)) + autocompletedict.Add(c.ToUpperInvariant(), c + "?" + imageindex); + } + string words = constantslist.ToString(); + scriptedit.SetKeywords(constantsindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); + } + + //mxd. Create the snippets list and apply it + imageindex = ((int)ImageIndex.ScriptSnippet).ToString(CultureInfo.InvariantCulture); + int snippetindex = lexercfg.ReadSetting(lexername + ".snippetindex", -1); + if (snippetindex > -1 && scriptconfig.Snippets.Count > 0) + { + StringBuilder snippetslist = new StringBuilder(""); + foreach (string c in scriptconfig.Snippets) + { + if (autocompletedict.ContainsKey(c.ToUpperInvariant())) continue; + if (snippetslist.Length > 0) snippetslist.Append(" "); + snippetslist.Append(c); + autocompletedict.Add(c.ToUpperInvariant(), c + "?" + imageindex); + } + string words = snippetslist.ToString(); + scriptedit.SetKeywords(snippetindex, (scriptconfig.CaseSensitive ? words : words.ToLowerInvariant())); + } + + // Make autocomplete list + autocompletelist = new List(autocompletedict.Values); + + // Setup folding (https://github.com/jacobslusser/ScintillaNET/wiki/Automatic-Code-Folding) + if (scriptconfig.Lexer == Lexer.Cpp || scriptconfig.Lexer == Lexer.CppNoCase) + { + // Instruct the lexer to calculate folding + scriptedit.SetProperty("fold", "1"); + scriptedit.SetProperty("fold.compact", "1"); + + // Configure a margin to display folding symbols + scriptedit.Margins[2].Type = MarginType.Symbol; + scriptedit.Margins[2].Mask = Marker.MaskFolders; + scriptedit.Margins[2].Sensitive = true; + scriptedit.Margins[2].Width = 12; + + // Set colors for all folding markers + for (int i = 25; i < 32; i++) + { + scriptedit.Markers[i].SetForeColor(SystemColors.ControlLightLight); + scriptedit.Markers[i].SetBackColor(SystemColors.ControlDark); + } + + // Configure folding markers with respective symbols + scriptedit.Markers[Marker.Folder].Symbol = MarkerSymbol.BoxPlus; + scriptedit.Markers[Marker.FolderOpen].Symbol = MarkerSymbol.BoxMinus; + scriptedit.Markers[Marker.FolderEnd].Symbol = MarkerSymbol.BoxPlusConnected; + scriptedit.Markers[Marker.FolderMidTail].Symbol = MarkerSymbol.TCorner; + scriptedit.Markers[Marker.FolderOpenMid].Symbol = MarkerSymbol.BoxMinusConnected; + scriptedit.Markers[Marker.FolderSub].Symbol = MarkerSymbol.VLine; + scriptedit.Markers[Marker.FolderTail].Symbol = MarkerSymbol.LCorner; + + // Enable automatic folding + scriptedit.AutomaticFold = (AutomaticFold.Show | AutomaticFold.Click | AutomaticFold.Change); + } + else + { + // Disable folding + scriptedit.SetProperty("fold", "0"); + scriptedit.SetProperty("fold.compact", "0"); + + scriptedit.Margins[2].Type = MarginType.Symbol; + scriptedit.Margins[2].Mask = 0; // No markers here + scriptedit.Margins[2].Sensitive = false; + scriptedit.Margins[2].Width = 5; + + scriptedit.AutomaticFold = AutomaticFold.None; + } + + // Rearrange the layout + scriptedit.ClearDocumentStyle(); + this.PerformLayout(); + } + + // This returns the current word (where the caret is at) + public string GetCurrentWord() + { + return GetWordAt(scriptedit.CurrentPosition); + } + + // This returns the word at the given position + public string GetWordAt(int position) + { + return scriptedit.GetWordFromPosition(position); + } + + // Perform undo + public void Undo() + { + scriptedit.Undo(); + } + + // Perform redo + public void Redo() + { + scriptedit.Redo(); + } + + // This clears all undo levels + public void ClearUndoRedo() + { + scriptedit.EmptyUndoBuffer(); + } + + //mxd. This marks the current document as unmodified + public void SetSavePoint() + { + scriptedit.SetSavePoint(); + } + + // Perform cut + public void Cut() + { + scriptedit.Cut(); + } + + // Perform copy + public void Copy() + { + scriptedit.Copy(); + } + + // Perform paste + public void Paste() + { + scriptedit.Paste(); + } + + // This steals the focus (use with care!) + public void GrabFocus() + { + scriptedit.Focus(); + } + + public byte[] GetText() + { + return Encoding.ASCII.GetBytes(scriptedit.Text); //mxd TODO: other encodings?.. + } + + public void SetText(byte[] text) + { + scriptedit.Text = Encoding.ASCII.GetString(text); //mxd TODO: other encodings?.. + } + + //mxd + public void InsertSnippet(string[] lines) + { + // Insert the snippet + int curline = scriptedit.LineFromPosition(scriptedit.SelectionStart); + int indent = scriptedit.Lines[scriptedit.CurrentLine].Indentation; + string tabs = Environment.NewLine + GetIndentationString(indent); + string spaces = new String(' ', General.Settings.ScriptTabWidth); + int entrypos = -1; + int entryline = -1; + string[] processedlines = ProcessLineBreaks(lines); + + // Process special chars, try to find entry position marker + for (int i = 0; i < lines.Length; i++) + { + if (!scriptedit.UseTabs) processedlines[i] = processedlines[i].Replace("\t", spaces); + + // Check if we have the [EP] marker + if (entrypos == -1) + { + int pos = processedlines[i].IndexOf("[EP]", StringComparison.Ordinal); + if (pos != -1) + { + processedlines[i] = processedlines[i].Remove(pos, 4); + entryline = curline + i; + entrypos = processedlines[i].Length - pos; + } + } + } + + // Replace the text + string text = string.Join(tabs, processedlines); + scriptedit.SelectionStart = scriptedit.WordStartPosition(scriptedit.CurrentPosition, true); + scriptedit.SelectionEnd = scriptedit.WordEndPosition(scriptedit.CurrentPosition, true); + scriptedit.ReplaceSelection(text); + + // Move the cursor if we had the [EP] marker + if (entrypos != -1) + { + scriptedit.SetEmptySelection(scriptedit.Lines[entryline].EndPosition - entrypos - 2); + } + } + + //mxd. Find next result + public bool FindNext(FindReplaceOptions options, bool useselectionstart) + { + int startpos = (useselectionstart ? Math.Min(scriptedit.SelectionStart, scriptedit.SelectionEnd) : Math.Max(scriptedit.SelectionStart, scriptedit.SelectionEnd)); + + // Search the document + scriptedit.TargetStart = startpos; + scriptedit.TargetEnd = scriptedit.TextLength; + scriptedit.SearchFlags = options.CaseSensitive ? SearchFlags.MatchCase : SearchFlags.None; + if (options.WholeWord) scriptedit.SearchFlags |= SearchFlags.WholeWord; + + int result = scriptedit.SearchInTarget(options.FindText); + + // Wrap around? + if (result == -1) + { + scriptedit.TargetStart = 0; + scriptedit.TargetEnd = startpos; + result = scriptedit.SearchInTarget(options.FindText); + } + + // Found something + if (result != -1) + { + // Select the result + SelectAndShow(result, result + options.FindText.Length); + + // Update extra highlights + HighlightWord(options.FindText); + + // All done + return true; + } + + // Nothing found... + return false; + } + + //mxd. Find previous result + public bool FindPrevious(FindReplaceOptions options) + { + int endpos = Math.Max(0, Math.Min(scriptedit.SelectionStart, scriptedit.SelectionEnd) - 1); + + // Search the document + scriptedit.TargetStart = endpos; + scriptedit.TargetEnd = 0; + scriptedit.SearchFlags = options.CaseSensitive ? SearchFlags.MatchCase : SearchFlags.None; + if (options.WholeWord) scriptedit.SearchFlags |= SearchFlags.WholeWord; + + int result = scriptedit.SearchInTarget(options.FindText); + + // Wrap around? + if (result == -1) + { + scriptedit.TargetStart = scriptedit.TextLength; + scriptedit.TargetEnd = endpos; + result = scriptedit.SearchInTarget(options.FindText); + } + + // Found something + if (result != -1) + { + // Select the result + SelectAndShow(result, result + options.FindText.Length); + + // Update extra highlights + HighlightWord(options.FindText); + + // All done + return true; + } + + // Nothing found... + return false; + } + + //mxd + private void SelectAndShow(int startpos, int endpos) + { + // Select the result + int startline = scriptedit.LineFromPosition(startpos); + int endline = scriptedit.LineFromPosition(endpos); + + // Go to target line + scriptedit.ShowLines(startline, endline); + scriptedit.GotoPosition(startpos); + + // We may want to do some extra scrolling... + if (startline > 1 && scriptedit.FirstVisibleLine >= startline - 1) + { + scriptedit.Lines[startline - 1].Goto(); + } + else if (endline < scriptedit.Lines.Count - 1 && scriptedit.FirstVisibleLine + scriptedit.LinesOnScreen <= endline + 1) + { + scriptedit.Lines[endline + 1].Goto(); + } + + // Update selection + scriptedit.SelectionStart = startpos; + scriptedit.SelectionEnd = endpos; + } + + //mxd. (Un)indents selection + public void IndentSelection(bool indent) + { + // Get selected range of lines + int startline = scriptedit.LineFromPosition(scriptedit.SelectionStart); + int endline = scriptedit.LineFromPosition(scriptedit.SelectionEnd); + + for (int i = startline; i < endline + 1; i++) + { + scriptedit.Lines[i].Indentation += (indent ? General.Settings.ScriptTabWidth : -General.Settings.ScriptTabWidth); + } + } + + #endregion + + #region ================== Utility methods + + // This returns the ScriptStyleType for a given Scintilla style + private ScriptStyleType GetScriptStyle(int scintillastyle) + { + return (stylelookup.ContainsKey(scintillastyle) ? stylelookup[scintillastyle] : ScriptStyleType.PlainText); + } + + // This gathers information about the current caret position + private void UpdatePositionInfo() + { + int bracketlevel = 0; // bracket level counting + int argindex = 0; // function argument counting + int pos = scriptedit.CurrentPosition; + + // Get the text + string scripttext = scriptedit.Text; + + // Reset position info + curfunctionname = ""; + curargumentindex = 0; + curfunctionstartpos = 0; + + // Determine lowest backtrack position + int limitpos = scriptedit.CurrentPosition - MAX_BACKTRACK_LENGTH; + if (limitpos < 0) limitpos = 0; + + // We can only do this when we have function syntax information + if ((scriptconfig.ArgumentDelimiter.Length == 0) || (scriptconfig.FunctionClose.Length == 0) || + (scriptconfig.FunctionOpen.Length == 0) || (scriptconfig.Terminator.Length == 0)) return; + + // Get int versions of the function syntax informantion + int argumentdelimiter = scriptconfig.ArgumentDelimiter[0]; + int functionclose = scriptconfig.FunctionClose[0]; + int functionopen = scriptconfig.FunctionOpen[0]; + int terminator = scriptconfig.Terminator[0]; + + // Continue backtracking until we reached the limitpos + while (pos >= limitpos) + { + // Backtrack 1 character + pos--; + + // Get the style and character at this position + ScriptStyleType curstyle = GetScriptStyle(scriptedit.GetStyleAt(pos)); + int curchar = scriptedit.GetCharAt(pos); + + // Then meeting ) then increase bracket level + // When meeting ( then decrease bracket level + // When bracket level goes -1, then the next word should be the function name + // Only when at bracket level 0, count the comma's for argument index + + // TODO: + // Original code checked for scope character here and breaks if found + + // Check if in plain text or keyword + if ((curstyle == ScriptStyleType.PlainText) || (curstyle == ScriptStyleType.Keyword)) + { + // Closing bracket + if (curchar == functionclose) + { + bracketlevel++; + } + // Opening bracket + else if (curchar == functionopen) + { + bracketlevel--; + + // Out of the brackets? + if (bracketlevel < 0) + { + // Skip any whitespace before this bracket + do + { + // Backtrack 1 character + curchar = scriptedit.GetCharAt(--pos); + } + while ((pos >= limitpos) && ((curchar == ' ') || (curchar == '\t') || + (curchar == '\r') || (curchar == '\n'))); + + // NOTE: We may need to set onlyWordCharacters argument in the + // following calls to false to get any argument delimiter included, + // but this may also cause a valid keyword to be combined with other + // surrounding characters that do not belong to the keyword. + + // Find the word before this bracket + int wordstart = scriptedit.WordStartPosition(pos, true); + int wordend = scriptedit.WordEndPosition(pos, true); + string word = scripttext.Substring(wordstart, wordend - wordstart); + if (word.Length > 0) + { + // Check if this is an argument delimiter + // I can't remember why I did this, but I'll probably stumble + // upon the problem if this doesn't work right (see note above) + if (word[0] == argumentdelimiter) + { + // We are now in the parent function + bracketlevel++; + argindex = 0; + } + // Now check if this is a keyword + else if (scriptconfig.IsKeyword(word)) + { + // Found it! + curfunctionname = scriptconfig.GetKeywordCase(word); + curargumentindex = argindex; + curfunctionstartpos = wordstart; + break; + } + else + { + // Don't know this word + break; + } + } + } + } + // Argument delimiter + else if (curchar == argumentdelimiter) + { + // Only count these at brackt level 0 + if (bracketlevel == 0) argindex++; + } + // Terminator + else if (curchar == terminator) + { + // Can't find anything, break now + break; + } + } + } + } + + // This registers an image for the autocomplete list + private void RegisterAutoCompleteImage(ImageIndex index, Bitmap image) + { + // Register image + scriptedit.RegisterRgbaImage((int)index, image); + } + + // This registers an image for the markes list + private void RegisterMarkerImage(ImageIndex index, Bitmap image) + { + // Register image + scriptedit.Markers[(int)index].DefineRgbaImage(image); + scriptedit.Markers[(int)index].Symbol = MarkerSymbol.RgbaImage; + } + + //mxd. This converts [LB] markers to line breaks if necessary + private static string[] ProcessLineBreaks(string[] lines) + { + List result = new List(lines.Length); + string[] separator = new[] { "[LB]" }; + + foreach (string line in lines) + { + if (line.IndexOf(separator[0], StringComparison.Ordinal) != -1) + { + if (General.Settings.SnippetsAllmanStyle) + result.AddRange(line.Split(separator, StringSplitOptions.RemoveEmptyEntries)); + else + result.Add(line.Replace(separator[0], " ")); + } + else + { + result.Add(line); + } + } + + return result.ToArray(); + } + + //mxd. Autocompletion handling (https://github.com/jacobslusser/ScintillaNET/wiki/Basic-Autocompletion) + private bool ShowAutoCompletionList() + { + int currentpos = scriptedit.CurrentPosition; + int wordstartpos = scriptedit.WordStartPosition(currentpos, true); + + if (wordstartpos >= currentpos) + { + // Hide the list + scriptedit.AutoCCancel(); + return false; + } + + // Get entered text + string start = scriptedit.GetTextRange(wordstartpos, currentpos - wordstartpos); + if (string.IsNullOrEmpty(start)) + { + // Hide the list + scriptedit.AutoCCancel(); + return false; + } + + // Filter the list + List filtered = new List(); + foreach (string s in autocompletelist) + if (s.IndexOf(start, StringComparison.OrdinalIgnoreCase) != -1) filtered.Add(s); + + // Any matches? + if (filtered.Count > 0) + { + // Show the list + scriptedit.AutoCShow(currentpos - wordstartpos, string.Join(" ", filtered.ToArray())); + return true; + } + + // Hide the list + scriptedit.AutoCCancel(); + return false; + } + + //mxd + private string GetIndentationString(int indent) + { + if (scriptedit.UseTabs) + { + string indentstr = string.Empty; + int numtabs = indent / scriptedit.TabWidth; + if (numtabs > 0) indentstr = new string('\t', numtabs); + + // Mixed padding? Add spaces + if (numtabs * scriptedit.TabWidth < indent) + { + int numspaces = indent - numtabs * scriptedit.TabWidth; + indentstr += new string(' ', numspaces); + } + + return indentstr; + } + else + { + return new string(' ', indent); + } + } + + //mxd. https://github.com/jacobslusser/ScintillaNET/wiki/Find-and-Highlight-Words + private void HighlightWord(string text) + { + // Remove all uses of our indicator + scriptedit.IndicatorCurrent = HIGHLIGHT_INDICATOR; + scriptedit.IndicatorClearRange(0, scriptedit.TextLength); + + // Update indicator appearance + scriptedit.Indicators[HIGHLIGHT_INDICATOR].Style = IndicatorStyle.RoundBox; + scriptedit.Indicators[HIGHLIGHT_INDICATOR].Under = true; + scriptedit.Indicators[HIGHLIGHT_INDICATOR].ForeColor = General.Colors.ScriptIndicator.ToColor(); + scriptedit.Indicators[HIGHLIGHT_INDICATOR].OutlineAlpha = 50; + scriptedit.Indicators[HIGHLIGHT_INDICATOR].Alpha = 30; + + // Search the document + scriptedit.TargetStart = 0; + scriptedit.TargetEnd = scriptedit.TextLength; + scriptedit.SearchFlags = SearchFlags.WholeWord; + + while (scriptedit.SearchInTarget(text) != -1) + { + //mxd. Don't mark currently selected word + if (scriptedit.SelectionStart != scriptedit.TargetStart && scriptedit.SelectionEnd != scriptedit.TargetEnd) + { + // Mark the search results with the current indicator + scriptedit.IndicatorFillRange(scriptedit.TargetStart, scriptedit.TargetEnd - scriptedit.TargetStart); + } + + // Search the remainder of the document + scriptedit.TargetStart = scriptedit.TargetEnd; + scriptedit.TargetEnd = scriptedit.TextLength; + } + } + + #endregion + + #region ================== Events + + // Layout needs to be re-organized + protected override void OnLayout(LayoutEventArgs e) + { + base.OnLayout(e); + + // With or without functions bar? + if (functionbar.Visible) + { + scriptpanel.Top = functionbar.Bottom + 6; + scriptpanel.Height = this.ClientSize.Height - scriptpanel.Top; + } + else + { + scriptpanel.Top = 0; + scriptpanel.Height = this.ClientSize.Height; + } + } + + //mxd. Script text changed + private void scriptedit_TextChanged(object sender, EventArgs e) + { + // Line number margin width needs changing? + int curlinenumbercharlength = scriptedit.Lines.Count.ToString().Length; + + // Calculate the width required to display the last line number + // and include some padding for good measure. + if (curlinenumbercharlength != linenumbercharlength) + { + const int padding = 2; + scriptedit.Margins[1].Width = scriptedit.TextWidth(Style.LineNumber, new string('9', curlinenumbercharlength + 1)) + padding; + linenumbercharlength = curlinenumbercharlength; + } + + if (OnTextChanged != null) OnTextChanged(this, EventArgs.Empty); + } + + //mxd + private void scriptedit_CharAdded(object sender, CharAddedEventArgs e) + { + // Hide call tip if any + scriptedit.CallTipCancel(); + + // Offset caret if needed + if (caretoffset != 0) + { + scriptedit.SetEmptySelection(scriptedit.SelectionStart + caretoffset); + caretoffset = 0; + if (!expandcodeblock) return; + } + + // Move CodeBlockOpen to the new line? + if (expandcodeblock) + { + if (scriptedit.CurrentLine > 0) + { + string linetext = scriptedit.Lines[scriptedit.CurrentLine - 1].Text; + int blockopenpos = (string.IsNullOrEmpty(scriptconfig.CodeBlockOpen) ? -1 : linetext.LastIndexOf(scriptconfig.CodeBlockOpen, StringComparison.Ordinal)); + if (blockopenpos != -1) + { + // Do it only if initial line doesn't start with CodeBlockOpen + string linestart = linetext.Substring(0, blockopenpos).Trim(); + if (linestart.Length > 0) + { + scriptedit.InsertText(scriptedit.Lines[scriptedit.CurrentLine - 1].Position + blockopenpos, + Environment.NewLine + GetIndentationString(scriptedit.Lines[scriptedit.CurrentLine - 1].Indentation)); + } + } + } + + expandcodeblock = false; + return; + } + + // Auto-match braces + //TODO: Auto-match quotes + bool endpos = (scriptedit.CurrentPosition == scriptedit.TextLength); + if (!string.IsNullOrEmpty(scriptconfig.CodeBlockOpen) && e.Char == scriptconfig.CodeBlockOpen[0] && !string.IsNullOrEmpty(scriptconfig.CodeBlockClose) && + (endpos || (char)scriptedit.GetCharAt(scriptedit.CurrentPosition + 1) != scriptconfig.CodeBlockClose[0])) + { + scriptedit.InsertText(scriptedit.CurrentPosition, scriptconfig.CodeBlockClose); + } + else if (!string.IsNullOrEmpty(scriptconfig.FunctionOpen) && e.Char == scriptconfig.FunctionOpen[0] && !string.IsNullOrEmpty(scriptconfig.FunctionClose) && + (endpos || (char)scriptedit.GetCharAt(scriptedit.CurrentPosition + 1) != scriptconfig.FunctionClose[0])) + { + scriptedit.InsertText(scriptedit.CurrentPosition, scriptconfig.FunctionClose); + } + else if (!string.IsNullOrEmpty(scriptconfig.ArrayOpen) && e.Char == scriptconfig.ArrayOpen[0] && !string.IsNullOrEmpty(scriptconfig.ArrayClose) && + (endpos || (char)scriptedit.GetCharAt(scriptedit.CurrentPosition + 1) != scriptconfig.ArrayClose[0])) + { + scriptedit.InsertText(scriptedit.CurrentPosition, scriptconfig.ArrayClose); + } + else + { + // Display the autocompletion list + // TODO: make this behaviour optional? + ShowAutoCompletionList(); + } + } + + //mxd + private void scriptedit_UpdateUI(object sender, UpdateUIEventArgs e) + { + // If a word is selected, highlight the same words + if (scriptedit.SelectedText != highlightedword) + { + // Highlight only when whole word is selected + if (!string.IsNullOrEmpty(scriptedit.SelectedText) && scriptedit.GetWordFromPosition(scriptedit.SelectionStart) == scriptedit.SelectedText) + { + HighlightWord(scriptedit.SelectedText); + } + else + { + // Clear highlight + scriptedit.IndicatorCurrent = HIGHLIGHT_INDICATOR; + scriptedit.IndicatorClearRange(0, scriptedit.TextLength); + } + + highlightedword = scriptedit.SelectedText; + } + + // Has the caret changed position? + int caretpos = scriptedit.CurrentPosition; + if (lastcaretpos != caretpos && scriptconfig.BraceChars.Count > 0) + { + // Perform brace matching (https://github.com/jacobslusser/ScintillaNET/wiki/Brace-Matching) + lastcaretpos = caretpos; + int bracepos1 = -1; + + // Is there a brace to the left or right? + if (caretpos > 0 && scriptconfig.BraceChars.Contains((char)scriptedit.GetCharAt(caretpos - 1))) + bracepos1 = (caretpos - 1); + else if (scriptconfig.BraceChars.Contains((char)(scriptedit.GetCharAt(caretpos)))) + bracepos1 = caretpos; + + if (bracepos1 > -1) + { + // Find the matching brace + int bracepos2 = scriptedit.BraceMatch(bracepos1); + if (bracepos2 == Scintilla.InvalidPosition) + scriptedit.BraceBadLight(bracepos1); + else + scriptedit.BraceHighlight(bracepos1, bracepos2); + } + else + { + // Turn off brace matching + scriptedit.BraceHighlight(Scintilla.InvalidPosition, Scintilla.InvalidPosition); + } + } + } + + //mxd + private void scriptedit_InsertCheck(object sender, InsertCheckEventArgs e) + { + // Gross hacks... + if (skiptextinsert) + { + e.Text = string.Empty; + skiptextinsert = false; + } + // Do we want auto-indentation? + else if (!expandcodeblock && General.Settings.ScriptAutoIndent && e.Text == "\r\n") + { + // Get current line indentation up to the cursor position + string linetext = scriptedit.Lines[scriptedit.CurrentLine].Text; + int selectionpos = scriptedit.SelectionStart - scriptedit.Lines[scriptedit.CurrentLine].Position; + int indent = 0; + for (int i = 0; i < selectionpos; i++) + { + switch (linetext[i]) + { + case ' ': indent++; break; + case '\t': indent += scriptedit.TabWidth; break; + default: i = selectionpos; break; // break the loop + } + } + + // Store initial indentation + int initialindent = indent; + + // Need to increase indentation? We do this when: + // 1. Line contains '{' and '}' and the cursor is between them + // 2. Line either doesn't contain '}', or it's before '{', it contains '{' and the cursor is after it + // 3. Line doesn't contain ';', line contains ')' and the cursor is after it + int blockopenpos = (string.IsNullOrEmpty(scriptconfig.CodeBlockOpen) ? -1 : linetext.LastIndexOf(scriptconfig.CodeBlockOpen, selectionpos, StringComparison.Ordinal)); + int blockclosepos = (string.IsNullOrEmpty(scriptconfig.CodeBlockOpen) ? -1 : linetext.IndexOf(scriptconfig.CodeBlockClose, selectionpos, StringComparison.Ordinal)); + int funcclosepos = (string.IsNullOrEmpty(scriptconfig.FunctionClose) ? -1 : linetext.LastIndexOf(scriptconfig.FunctionClose, StringComparison.Ordinal)); + + // Add indentation when the cursor is between { and } + bool addindent = (blockopenpos != -1 && blockopenpos < selectionpos) && (blockclosepos == -1 || (blockopenpos < blockclosepos && blockclosepos >= selectionpos)); + bool isblockindent = addindent; + addindent |= funcclosepos != -1 && blockopenpos == -1 && funcclosepos < selectionpos && !linetext.Contains(scriptconfig.Terminator); + if (addindent) indent += scriptedit.TabWidth; + + // Calculate indentation + string indentstr = GetIndentationString(indent); + + // Move CodeBlockOpen to the new line (will be applied in scriptedit_CharAdded)? + expandcodeblock = (isblockindent && General.Settings.SnippetsAllmanStyle); + + // Offset closing block char? + if (addindent && blockclosepos != -1) + { + string initialindentstr = GetIndentationString(initialindent); + indentstr += Environment.NewLine + initialindentstr; + + // Offset cursor position (will be performed in scriptedit_CharAdded) + caretoffset = -(initialindentstr.Length + Environment.NewLine.Length); + } + + // Apply new indentation + e.Text += indentstr; + } + } + + //mxd + private void scriptedit_AutoCCompleted(object sender, AutoCSelectionEventArgs e) + { + // Expand snippet? + string[] lines = scriptconfig.GetSnippet(e.Text); + if (lines != null) InsertSnippet(lines); + } + + // Key pressed down + private void scriptedit_KeyDown(object sender, KeyEventArgs e) + { + // F3 for Find Next + if ((e.KeyCode == Keys.F3) && (e.Modifiers == Keys.None)) + { + if (OnFindNext != null) OnFindNext(); + } + // F2 for Find Previous (mxd) + else if ((e.KeyCode == Keys.F2) && (e.Modifiers == Keys.None)) + { + if (OnFindPrevious != null) OnFindPrevious(); + } + // CTRL+F for find & replace + else if ((e.KeyCode == Keys.F) && ((e.Modifiers & Keys.Control) == Keys.Control)) + { + if (OnOpenFindAndReplace != null) OnOpenFindAndReplace(); + } + // CTRL+S for save + else if ((e.KeyCode == Keys.S) && ((e.Modifiers & Keys.Control) == Keys.Control)) + { + if (OnExplicitSaveTab != null) OnExplicitSaveTab(); + } + // CTRL+O for open + else if ((e.KeyCode == Keys.O) && ((e.Modifiers & Keys.Control) == Keys.Control)) + { + if (OnOpenScriptBrowser != null) OnOpenScriptBrowser(); + } + // CTRL+Space to autocomplete + else if ((e.KeyCode == Keys.Space) && (e.Modifiers == Keys.Control)) + { + // Hide call tip if any + scriptedit.CallTipCancel(); + + // Show autocomplete + if (ShowAutoCompletionList()) skiptextinsert = true; + } + //mxd. Tab to expand code snippet. Do it only when the text cursor is at the end of a keyword. + else if (e.KeyCode == Keys.Tab) + { + if (!scriptedit.AutoCActive) + { + string curword = GetCurrentWord().ToLowerInvariant(); + if (scriptconfig.Snippets.Contains(curword) && scriptedit.CurrentPosition == scriptedit.WordEndPosition(scriptedit.CurrentPosition, true)) + { + InsertSnippet(scriptconfig.GetSnippet(curword)); + skiptextinsert = true; + } + } + } + //mxd. Handle screenshot saving + else if (DelayedForm.ProcessSaveScreenshotAction((int)e.KeyData)) + { + skiptextinsert = true; + } + } + + // Key released + private void scriptedit_KeyUp(object sender, KeyEventArgs e) + { + bool showcalltip = false; + int highlightstart = 0; + int highlightend = 0; + + UpdatePositionInfo(); + + // Call tip shown + if (scriptedit.CallTipActive) + { + // Should we hide the call tip? + if (curfunctionname.Length == 0) + { + // Hide the call tip + scriptedit.CallTipCancel(); + } + else + { + // Update the call tip + showcalltip = true; + } + } + // No call tip + else + { + // Should we show a call tip? + showcalltip = (curfunctionname.Length > 0) && !scriptedit.AutoCActive; + } + + // Show or update call tip + if (showcalltip) + { + string functiondef = scriptconfig.GetFunctionDefinition(curfunctionname); + if (functiondef != null) + { + // Determine the range to highlight + int argsopenpos = functiondef.IndexOf(scriptconfig.FunctionOpen, StringComparison.Ordinal); + int argsclosepos = functiondef.LastIndexOf(scriptconfig.FunctionClose, StringComparison.Ordinal); + if ((argsopenpos > -1) && (argsclosepos > -1)) + { + string argsstr = functiondef.Substring(argsopenpos + 1, argsclosepos - argsopenpos - 1); + string[] args = argsstr.Split(scriptconfig.ArgumentDelimiter[0]); + if ((curargumentindex >= 0) && (curargumentindex < args.Length)) + { + int argoffset = 0; + for (int i = 0; i < curargumentindex; i++) argoffset += args[i].Length + 1; + highlightstart = argsopenpos + argoffset + 1; + highlightend = highlightstart + args[curargumentindex].Length; + } + } + + //mxd. If the tip obscures the view, move it down + int tippos; + int funcline = scriptedit.LineFromPosition(curfunctionstartpos); + if (scriptedit.CurrentLine > funcline) + tippos = scriptedit.Lines[scriptedit.CurrentLine].Position + scriptedit.Lines[scriptedit.CurrentLine].Indentation; //scriptedit.PositionFromLine(curline) /*+ (curfunctionstartpos - scriptedit.PositionFromLine(funcline))*/; + else + tippos = curfunctionstartpos; + + // Show tip + scriptedit.CallTipShow(tippos, functiondef); + scriptedit.CallTipSetHlt(highlightstart, highlightend); + } + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/Core/Controls/ScriptEditorPanel.Designer.cs b/Source/Core/Controls/ScriptEditorPanel.Designer.cs index 173230d..4381535 100644 --- a/Source/Core/Controls/ScriptEditorPanel.Designer.cs +++ b/Source/Core/Controls/ScriptEditorPanel.Designer.cs @@ -1,104 +1,110 @@ namespace CodeImp.DoomBuilder.Controls { - partial class ScriptEditorPanel - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; + partial class ScriptEditorPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if(disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } - #region Component Designer generated code + #region Component Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ScriptEditorPanel)); - this.tabs = new System.Windows.Forms.TabControl(); - this.toolbar = new System.Windows.Forms.ToolStrip(); - this.buttonnew = new System.Windows.Forms.ToolStripDropDownButton(); - this.buttonopen = new System.Windows.Forms.ToolStripButton(); - this.buttonsave = new System.Windows.Forms.ToolStripButton(); - this.buttonsaveall = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.buttonundo = new System.Windows.Forms.ToolStripButton(); - this.buttonredo = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.buttoncut = new System.Windows.Forms.ToolStripButton(); - this.buttoncopy = new System.Windows.Forms.ToolStripButton(); - this.buttonpaste = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.buttonsnippets = new System.Windows.Forms.ToolStripDropDownButton(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.buttonscriptconfig = new System.Windows.Forms.ToolStripDropDownButton(); - this.buttoncompile = new System.Windows.Forms.ToolStripButton(); - this.buttonclose = new System.Windows.Forms.ToolStripButton(); - this.buttonkeywordhelp = new System.Windows.Forms.ToolStripButton(); - this.buttonsearch = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this.searchbox = new System.Windows.Forms.ToolStripTextBox(); - this.searchprev = new System.Windows.Forms.ToolStripButton(); - this.searchnext = new System.Windows.Forms.ToolStripButton(); - this.searchmatchcase = new System.Windows.Forms.ToolStripButton(); - this.searchwholeword = new System.Windows.Forms.ToolStripButton(); - this.openfile = new System.Windows.Forms.OpenFileDialog(); - this.savefile = new System.Windows.Forms.SaveFileDialog(); - this.splitter = new System.Windows.Forms.SplitContainer(); - this.label1 = new System.Windows.Forms.Label(); - this.errorlist = new System.Windows.Forms.ListView(); - this.colIndex = new System.Windows.Forms.ColumnHeader(); - this.colDescription = new System.Windows.Forms.ColumnHeader(); - this.colFile = new System.Windows.Forms.ColumnHeader(); - this.errorimages = new System.Windows.Forms.ImageList(this.components); - this.statusbar = new System.Windows.Forms.StatusStrip(); - this.statuslabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.scripttype = new System.Windows.Forms.ToolStripStatusLabel(); - this.statusflasher = new System.Windows.Forms.Timer(this.components); - this.statusresetter = new System.Windows.Forms.Timer(this.components); - this.toolbar.SuspendLayout(); - this.splitter.Panel1.SuspendLayout(); - this.splitter.Panel2.SuspendLayout(); - this.splitter.SuspendLayout(); - this.statusbar.SuspendLayout(); - this.SuspendLayout(); - // - // tabs - // - this.tabs.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.tabs.Location = new System.Drawing.Point(3, 8); - this.tabs.Margin = new System.Windows.Forms.Padding(3, 8, 3, 3); - this.tabs.Name = "tabs"; - this.tabs.Padding = new System.Drawing.Point(12, 3); - this.tabs.SelectedIndex = 0; - this.tabs.Size = new System.Drawing.Size(720, 379); - this.tabs.TabIndex = 0; - this.tabs.TabStop = false; - this.tabs.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.tabs_Selecting); - this.tabs.MouseUp += new System.Windows.Forms.MouseEventHandler(this.tabs_MouseUp); - // - // toolbar - // - this.toolbar.AllowMerge = false; - this.toolbar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; - this.toolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ScriptEditorPanel)); + this.tabs = new System.Windows.Forms.TabControl(); + this.toolbar = new System.Windows.Forms.ToolStrip(); + this.buttonnew = new System.Windows.Forms.ToolStripDropDownButton(); + this.buttonopen = new System.Windows.Forms.ToolStripButton(); + this.buttonsave = new System.Windows.Forms.ToolStripButton(); + this.buttonsaveall = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.buttonundo = new System.Windows.Forms.ToolStripButton(); + this.buttonredo = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.buttoncut = new System.Windows.Forms.ToolStripButton(); + this.buttoncopy = new System.Windows.Forms.ToolStripButton(); + this.buttonpaste = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.buttonunindent = new System.Windows.Forms.ToolStripButton(); + this.buttonindent = new System.Windows.Forms.ToolStripButton(); + this.buttonwhitespace = new System.Windows.Forms.ToolStripButton(); + this.buttonwordwrap = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.buttonsnippets = new System.Windows.Forms.ToolStripDropDownButton(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.buttonscriptconfig = new System.Windows.Forms.ToolStripDropDownButton(); + this.buttoncompile = new System.Windows.Forms.ToolStripButton(); + this.buttonclose = new System.Windows.Forms.ToolStripButton(); + this.buttonkeywordhelp = new System.Windows.Forms.ToolStripButton(); + this.buttonsearch = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.searchbox = new System.Windows.Forms.ToolStripTextBox(); + this.searchprev = new System.Windows.Forms.ToolStripButton(); + this.searchnext = new System.Windows.Forms.ToolStripButton(); + this.searchmatchcase = new System.Windows.Forms.ToolStripButton(); + this.searchwholeword = new System.Windows.Forms.ToolStripButton(); + this.openfile = new System.Windows.Forms.OpenFileDialog(); + this.savefile = new System.Windows.Forms.SaveFileDialog(); + this.splitter = new System.Windows.Forms.SplitContainer(); + this.label1 = new System.Windows.Forms.Label(); + this.errorlist = new System.Windows.Forms.ListView(); + this.colIndex = new System.Windows.Forms.ColumnHeader(); + this.colDescription = new System.Windows.Forms.ColumnHeader(); + this.colFile = new System.Windows.Forms.ColumnHeader(); + this.errorimages = new System.Windows.Forms.ImageList(this.components); + this.statusbar = new System.Windows.Forms.StatusStrip(); + this.statuslabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.positionlabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.scripttype = new System.Windows.Forms.ToolStripStatusLabel(); + this.statusflasher = new System.Windows.Forms.Timer(this.components); + this.statusresetter = new System.Windows.Forms.Timer(this.components); + this.toolbar.SuspendLayout(); + this.splitter.Panel1.SuspendLayout(); + this.splitter.Panel2.SuspendLayout(); + this.splitter.SuspendLayout(); + this.statusbar.SuspendLayout(); + this.SuspendLayout(); + // + // tabs + // + this.tabs.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.tabs.Location = new System.Drawing.Point(3, 8); + this.tabs.Margin = new System.Windows.Forms.Padding(3, 8, 3, 3); + this.tabs.Name = "tabs"; + this.tabs.Padding = new System.Drawing.Point(12, 3); + this.tabs.SelectedIndex = 0; + this.tabs.Size = new System.Drawing.Size(794, 379); + this.tabs.TabIndex = 0; + this.tabs.TabStop = false; + this.tabs.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.tabs_Selecting); + this.tabs.MouseUp += new System.Windows.Forms.MouseEventHandler(this.tabs_MouseUp); + // + // toolbar + // + this.toolbar.AllowMerge = false; + this.toolbar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.toolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.buttonnew, this.buttonopen, this.buttonsave, @@ -111,6 +117,11 @@ namespace CodeImp.DoomBuilder.Controls this.buttoncopy, this.buttonpaste, this.toolStripSeparator3, + this.buttonunindent, + this.buttonindent, + this.buttonwhitespace, + this.buttonwordwrap, + this.toolStripSeparator6, this.buttonsnippets, this.toolStripSeparator4, this.buttonscriptconfig, @@ -124,438 +135,501 @@ namespace CodeImp.DoomBuilder.Controls this.searchnext, this.searchmatchcase, this.searchwholeword}); - this.toolbar.Location = new System.Drawing.Point(0, 0); - this.toolbar.Name = "toolbar"; - this.toolbar.Size = new System.Drawing.Size(726, 25); - this.toolbar.TabIndex = 1; - // - // buttonnew - // - this.buttonnew.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonnew.Image = global::CodeImp.DoomBuilder.Properties.Resources.NewScript; - this.buttonnew.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonnew.Margin = new System.Windows.Forms.Padding(6, 1, 0, 2); - this.buttonnew.Name = "buttonnew"; - this.buttonnew.Size = new System.Drawing.Size(29, 22); - this.buttonnew.Text = "New File"; - // - // buttonopen - // - this.buttonopen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonopen.Image = global::CodeImp.DoomBuilder.Properties.Resources.OpenScript; - this.buttonopen.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonopen.Margin = new System.Windows.Forms.Padding(3, 1, 0, 2); - this.buttonopen.Name = "buttonopen"; - this.buttonopen.Size = new System.Drawing.Size(23, 22); - this.buttonopen.Text = "Open File"; - this.buttonopen.Click += new System.EventHandler(this.buttonopen_Click); - // - // buttonsave - // - this.buttonsave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonsave.Enabled = false; - this.buttonsave.Image = global::CodeImp.DoomBuilder.Properties.Resources.SaveScript; - this.buttonsave.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonsave.Name = "buttonsave"; - this.buttonsave.Size = new System.Drawing.Size(23, 22); - this.buttonsave.Text = "Save File"; - this.buttonsave.Click += new System.EventHandler(this.buttonsave_Click); - // - // buttonsaveall - // - this.buttonsaveall.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonsaveall.Enabled = false; - this.buttonsaveall.Image = global::CodeImp.DoomBuilder.Properties.Resources.SaveAll; - this.buttonsaveall.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonsaveall.Name = "buttonsaveall"; - this.buttonsaveall.Size = new System.Drawing.Size(23, 22); - this.buttonsaveall.Text = "Save All Files"; - this.buttonsaveall.Click += new System.EventHandler(this.buttonsaveall_Click); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); - // - // buttonundo - // - this.buttonundo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonundo.Image = global::CodeImp.DoomBuilder.Properties.Resources.Undo; - this.buttonundo.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonundo.Name = "buttonundo"; - this.buttonundo.Size = new System.Drawing.Size(23, 22); - this.buttonundo.Text = "Undo"; - this.buttonundo.Click += new System.EventHandler(this.buttonundo_Click); - // - // buttonredo - // - this.buttonredo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonredo.Image = global::CodeImp.DoomBuilder.Properties.Resources.Redo; - this.buttonredo.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonredo.Name = "buttonredo"; - this.buttonredo.Size = new System.Drawing.Size(23, 22); - this.buttonredo.Text = "Redo"; - this.buttonredo.Click += new System.EventHandler(this.buttonredo_Click); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); - // - // buttoncut - // - this.buttoncut.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttoncut.Image = global::CodeImp.DoomBuilder.Properties.Resources.Cut; - this.buttoncut.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttoncut.Name = "buttoncut"; - this.buttoncut.Size = new System.Drawing.Size(23, 22); - this.buttoncut.Text = "Cut Selection"; - this.buttoncut.Click += new System.EventHandler(this.buttoncut_Click); - // - // buttoncopy - // - this.buttoncopy.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttoncopy.Image = global::CodeImp.DoomBuilder.Properties.Resources.Copy; - this.buttoncopy.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttoncopy.Name = "buttoncopy"; - this.buttoncopy.Size = new System.Drawing.Size(23, 22); - this.buttoncopy.Text = "Copy Selection"; - this.buttoncopy.Click += new System.EventHandler(this.buttoncopy_Click); - // - // buttonpaste - // - this.buttonpaste.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonpaste.Image = global::CodeImp.DoomBuilder.Properties.Resources.Paste; - this.buttonpaste.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonpaste.Name = "buttonpaste"; - this.buttonpaste.Size = new System.Drawing.Size(23, 22); - this.buttonpaste.Text = "Paste"; - this.buttonpaste.Click += new System.EventHandler(this.buttonpaste_Click); - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); - // - // buttonsnippets - // - this.buttonsnippets.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonsnippets.Enabled = false; - this.buttonsnippets.Image = global::CodeImp.DoomBuilder.Properties.Resources.PuzzlePiece; - this.buttonsnippets.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonsnippets.Name = "buttonsnippets"; - this.buttonsnippets.Size = new System.Drawing.Size(29, 22); - this.buttonsnippets.Text = "Insert a Code Snippet"; - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); - // - // buttonscriptconfig - // - this.buttonscriptconfig.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonscriptconfig.Enabled = false; - this.buttonscriptconfig.Image = global::CodeImp.DoomBuilder.Properties.Resources.ScriptPalette; - this.buttonscriptconfig.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonscriptconfig.Name = "buttonscriptconfig"; - this.buttonscriptconfig.Size = new System.Drawing.Size(29, 22); - this.buttonscriptconfig.Text = "Change Script Type"; - // - // buttoncompile - // - this.buttoncompile.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttoncompile.Image = global::CodeImp.DoomBuilder.Properties.Resources.ScriptCompile; - this.buttoncompile.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttoncompile.Margin = new System.Windows.Forms.Padding(3, 1, 0, 2); - this.buttoncompile.Name = "buttoncompile"; - this.buttoncompile.Size = new System.Drawing.Size(23, 22); - this.buttoncompile.Text = "Compile Script"; - this.buttoncompile.Click += new System.EventHandler(this.buttoncompile_Click); - // - // buttonclose - // - this.buttonclose.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; - this.buttonclose.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonclose.Image = global::CodeImp.DoomBuilder.Properties.Resources.Close; - this.buttonclose.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonclose.Name = "buttonclose"; - this.buttonclose.Size = new System.Drawing.Size(23, 22); - this.buttonclose.Text = "Close File"; - this.buttonclose.Click += new System.EventHandler(this.buttonclose_Click); - // - // buttonkeywordhelp - // - this.buttonkeywordhelp.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; - this.buttonkeywordhelp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonkeywordhelp.Image = global::CodeImp.DoomBuilder.Properties.Resources.ScriptHelp; - this.buttonkeywordhelp.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonkeywordhelp.Name = "buttonkeywordhelp"; - this.buttonkeywordhelp.Size = new System.Drawing.Size(23, 22); - this.buttonkeywordhelp.Text = "Keyword Help"; - this.buttonkeywordhelp.Click += new System.EventHandler(this.buttonkeywordhelp_Click); - // - // buttonsearch - // - this.buttonsearch.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; - this.buttonsearch.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.buttonsearch.Image = global::CodeImp.DoomBuilder.Properties.Resources.Search; - this.buttonsearch.ImageTransparentColor = System.Drawing.Color.Magenta; - this.buttonsearch.Name = "buttonsearch"; - this.buttonsearch.Size = new System.Drawing.Size(23, 22); - this.buttonsearch.Text = "Open Find and Replace Window"; - this.buttonsearch.Click += new System.EventHandler(this.buttonsearch_Click); - // - // toolStripSeparator5 - // - this.toolStripSeparator5.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); - // - // searchbox - // - this.searchbox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.searchbox.Name = "searchbox"; - this.searchbox.Size = new System.Drawing.Size(100, 25); - this.searchbox.TextChanged += new System.EventHandler(this.searchbox_TextChanged); - // - // searchprev - // - this.searchprev.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.searchprev.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchPrev; - this.searchprev.ImageTransparentColor = System.Drawing.Color.Magenta; - this.searchprev.Name = "searchprev"; - this.searchprev.Size = new System.Drawing.Size(23, 22); - this.searchprev.ToolTipText = "Previous Match"; - this.searchprev.Click += new System.EventHandler(this.searchprev_Click); - // - // searchnext - // - this.searchnext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.searchnext.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchNext; - this.searchnext.ImageTransparentColor = System.Drawing.Color.Magenta; - this.searchnext.Name = "searchnext"; - this.searchnext.Size = new System.Drawing.Size(23, 22); - this.searchnext.ToolTipText = "Next Match"; - this.searchnext.Click += new System.EventHandler(this.searchnext_Click); - // - // searchmatchcase - // - this.searchmatchcase.CheckOnClick = true; - this.searchmatchcase.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.searchmatchcase.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchMatchCase; - this.searchmatchcase.ImageTransparentColor = System.Drawing.Color.Magenta; - this.searchmatchcase.Name = "searchmatchcase"; - this.searchmatchcase.Size = new System.Drawing.Size(23, 22); - this.searchmatchcase.ToolTipText = "Match Case"; - this.searchmatchcase.Click += new System.EventHandler(this.searchbox_TextChanged); - // - // searchwholeword - // - this.searchwholeword.CheckOnClick = true; - this.searchwholeword.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.searchwholeword.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchMatch; - this.searchwholeword.ImageTransparentColor = System.Drawing.Color.Magenta; - this.searchwholeword.Name = "searchwholeword"; - this.searchwholeword.Size = new System.Drawing.Size(23, 22); - this.searchwholeword.ToolTipText = "Match Whole Word"; - this.searchwholeword.Click += new System.EventHandler(this.searchbox_TextChanged); - // - // openfile - // - this.openfile.Multiselect = true; - this.openfile.Title = "Open Script"; - // - // savefile - // - this.savefile.Title = "Save Script As"; - // - // splitter - // - this.splitter.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitter.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; - this.splitter.IsSplitterFixed = true; - this.splitter.Location = new System.Drawing.Point(0, 25); - this.splitter.Name = "splitter"; - this.splitter.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // splitter.Panel1 - // - this.splitter.Panel1.Controls.Add(this.tabs); - // - // splitter.Panel2 - // - this.splitter.Panel2.Controls.Add(this.label1); - this.splitter.Panel2.Controls.Add(this.errorlist); - this.splitter.Size = new System.Drawing.Size(726, 516); - this.splitter.SplitterDistance = 390; - this.splitter.TabIndex = 2; - this.splitter.TabStop = false; - // - // label1 - // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.label1.BackColor = System.Drawing.SystemColors.ActiveCaption; - this.label1.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; - this.label1.Location = new System.Drawing.Point(3, 0); - this.label1.Name = "label1"; - this.label1.Padding = new System.Windows.Forms.Padding(1); - this.label1.Size = new System.Drawing.Size(720, 16); - this.label1.TabIndex = 1; - this.label1.Text = "Errors"; - // - // errorlist - // - this.errorlist.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.errorlist.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.toolbar.Location = new System.Drawing.Point(0, 0); + this.toolbar.Name = "toolbar"; + this.toolbar.Size = new System.Drawing.Size(800, 25); + this.toolbar.TabIndex = 1; + // + // buttonnew + // + this.buttonnew.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonnew.Image = global::CodeImp.DoomBuilder.Properties.Resources.NewScript; + this.buttonnew.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonnew.Margin = new System.Windows.Forms.Padding(6, 1, 0, 2); + this.buttonnew.Name = "buttonnew"; + this.buttonnew.Size = new System.Drawing.Size(29, 22); + this.buttonnew.Text = "New File"; + // + // buttonopen + // + this.buttonopen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonopen.Image = global::CodeImp.DoomBuilder.Properties.Resources.OpenScript; + this.buttonopen.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonopen.Margin = new System.Windows.Forms.Padding(3, 1, 0, 2); + this.buttonopen.Name = "buttonopen"; + this.buttonopen.Size = new System.Drawing.Size(23, 22); + this.buttonopen.Text = "Open File"; + this.buttonopen.Click += new System.EventHandler(this.buttonopen_Click); + // + // buttonsave + // + this.buttonsave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonsave.Enabled = false; + this.buttonsave.Image = global::CodeImp.DoomBuilder.Properties.Resources.SaveScript; + this.buttonsave.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonsave.Name = "buttonsave"; + this.buttonsave.Size = new System.Drawing.Size(23, 22); + this.buttonsave.Text = "Save File"; + this.buttonsave.Click += new System.EventHandler(this.buttonsave_Click); + // + // buttonsaveall + // + this.buttonsaveall.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonsaveall.Enabled = false; + this.buttonsaveall.Image = global::CodeImp.DoomBuilder.Properties.Resources.SaveAll; + this.buttonsaveall.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonsaveall.Name = "buttonsaveall"; + this.buttonsaveall.Size = new System.Drawing.Size(23, 22); + this.buttonsaveall.Text = "Save All Files"; + this.buttonsaveall.Click += new System.EventHandler(this.buttonsaveall_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // buttonundo + // + this.buttonundo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonundo.Image = global::CodeImp.DoomBuilder.Properties.Resources.Undo; + this.buttonundo.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonundo.Name = "buttonundo"; + this.buttonundo.Size = new System.Drawing.Size(23, 22); + this.buttonundo.Text = "Undo"; + this.buttonundo.Click += new System.EventHandler(this.buttonundo_Click); + // + // buttonredo + // + this.buttonredo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonredo.Image = global::CodeImp.DoomBuilder.Properties.Resources.Redo; + this.buttonredo.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonredo.Name = "buttonredo"; + this.buttonredo.Size = new System.Drawing.Size(23, 22); + this.buttonredo.Text = "Redo"; + this.buttonredo.Click += new System.EventHandler(this.buttonredo_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // buttoncut + // + this.buttoncut.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttoncut.Image = global::CodeImp.DoomBuilder.Properties.Resources.Cut; + this.buttoncut.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttoncut.Name = "buttoncut"; + this.buttoncut.Size = new System.Drawing.Size(23, 22); + this.buttoncut.Text = "Cut Selection"; + this.buttoncut.Click += new System.EventHandler(this.buttoncut_Click); + // + // buttoncopy + // + this.buttoncopy.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttoncopy.Image = global::CodeImp.DoomBuilder.Properties.Resources.Copy; + this.buttoncopy.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttoncopy.Name = "buttoncopy"; + this.buttoncopy.Size = new System.Drawing.Size(23, 22); + this.buttoncopy.Text = "Copy Selection"; + this.buttoncopy.Click += new System.EventHandler(this.buttoncopy_Click); + // + // buttonpaste + // + this.buttonpaste.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonpaste.Image = global::CodeImp.DoomBuilder.Properties.Resources.Paste; + this.buttonpaste.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonpaste.Name = "buttonpaste"; + this.buttonpaste.Size = new System.Drawing.Size(23, 22); + this.buttonpaste.Text = "Paste"; + this.buttonpaste.Click += new System.EventHandler(this.buttonpaste_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // buttonunindent + // + this.buttonunindent.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonunindent.Image = global::CodeImp.DoomBuilder.Properties.Resources.TextUnindent; + this.buttonunindent.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonunindent.Name = "buttonunindent"; + this.buttonunindent.Size = new System.Drawing.Size(23, 22); + this.buttonunindent.Text = "Unindent selection"; + this.buttonunindent.Click += new System.EventHandler(this.buttonunindent_Click); + // + // buttonindent + // + this.buttonindent.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonindent.Image = global::CodeImp.DoomBuilder.Properties.Resources.TextIndent; + this.buttonindent.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonindent.Name = "buttonindent"; + this.buttonindent.Size = new System.Drawing.Size(23, 22); + this.buttonindent.Text = "Indent selection"; + this.buttonindent.Click += new System.EventHandler(this.buttonindent_Click); + // + // buttonwhitespace + // + this.buttonwhitespace.CheckOnClick = true; + this.buttonwhitespace.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonwhitespace.Image = global::CodeImp.DoomBuilder.Properties.Resources.TextWhitespace; + this.buttonwhitespace.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonwhitespace.Name = "buttonwhitespace"; + this.buttonwhitespace.Size = new System.Drawing.Size(23, 22); + this.buttonwhitespace.Text = "Show whitespace"; + this.buttonwhitespace.Click += new System.EventHandler(this.buttonwhitespace_Click); + // + // buttonwordwrap + // + this.buttonwordwrap.CheckOnClick = true; + this.buttonwordwrap.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonwordwrap.Image = global::CodeImp.DoomBuilder.Properties.Resources.WordWrap; + this.buttonwordwrap.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonwordwrap.Name = "buttonwordwrap"; + this.buttonwordwrap.Size = new System.Drawing.Size(23, 22); + this.buttonwordwrap.Text = "Wrap long lines"; + this.buttonwordwrap.Click += new System.EventHandler(this.buttonwordwrap_Click); + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(6, 25); + // + // buttonsnippets + // + this.buttonsnippets.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonsnippets.Enabled = false; + this.buttonsnippets.Image = global::CodeImp.DoomBuilder.Properties.Resources.PuzzlePiece; + this.buttonsnippets.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonsnippets.Name = "buttonsnippets"; + this.buttonsnippets.Size = new System.Drawing.Size(29, 22); + this.buttonsnippets.Text = "Insert a Code Snippet"; + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + // + // buttonscriptconfig + // + this.buttonscriptconfig.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonscriptconfig.Enabled = false; + this.buttonscriptconfig.Image = global::CodeImp.DoomBuilder.Properties.Resources.ScriptPalette; + this.buttonscriptconfig.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonscriptconfig.Name = "buttonscriptconfig"; + this.buttonscriptconfig.Size = new System.Drawing.Size(29, 22); + this.buttonscriptconfig.Text = "Change Script Type"; + // + // buttoncompile + // + this.buttoncompile.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttoncompile.Image = global::CodeImp.DoomBuilder.Properties.Resources.ScriptCompile; + this.buttoncompile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttoncompile.Margin = new System.Windows.Forms.Padding(3, 1, 0, 2); + this.buttoncompile.Name = "buttoncompile"; + this.buttoncompile.Size = new System.Drawing.Size(23, 22); + this.buttoncompile.Text = "Compile Script"; + this.buttoncompile.Click += new System.EventHandler(this.buttoncompile_Click); + // + // buttonclose + // + this.buttonclose.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.buttonclose.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonclose.Image = global::CodeImp.DoomBuilder.Properties.Resources.Close; + this.buttonclose.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonclose.Name = "buttonclose"; + this.buttonclose.Size = new System.Drawing.Size(23, 22); + this.buttonclose.Text = "Close File"; + this.buttonclose.Click += new System.EventHandler(this.buttonclose_Click); + // + // buttonkeywordhelp + // + this.buttonkeywordhelp.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.buttonkeywordhelp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonkeywordhelp.Image = global::CodeImp.DoomBuilder.Properties.Resources.ScriptHelp; + this.buttonkeywordhelp.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonkeywordhelp.Name = "buttonkeywordhelp"; + this.buttonkeywordhelp.Size = new System.Drawing.Size(23, 22); + this.buttonkeywordhelp.Text = "Keyword Help"; + this.buttonkeywordhelp.Click += new System.EventHandler(this.buttonkeywordhelp_Click); + // + // buttonsearch + // + this.buttonsearch.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; + this.buttonsearch.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.buttonsearch.Image = global::CodeImp.DoomBuilder.Properties.Resources.Search; + this.buttonsearch.ImageTransparentColor = System.Drawing.Color.Magenta; + this.buttonsearch.Name = "buttonsearch"; + this.buttonsearch.Size = new System.Drawing.Size(23, 22); + this.buttonsearch.Text = "Open Find and Replace Window"; + this.buttonsearch.Click += new System.EventHandler(this.buttonsearch_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); + // + // searchbox + // + this.searchbox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.searchbox.Name = "searchbox"; + this.searchbox.Size = new System.Drawing.Size(100, 25); + this.searchbox.TextChanged += new System.EventHandler(this.searchbox_TextChanged); + // + // searchprev + // + this.searchprev.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.searchprev.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchPrev; + this.searchprev.ImageTransparentColor = System.Drawing.Color.Magenta; + this.searchprev.Name = "searchprev"; + this.searchprev.Size = new System.Drawing.Size(23, 22); + this.searchprev.ToolTipText = "Previous Match"; + this.searchprev.Click += new System.EventHandler(this.searchprev_Click); + // + // searchnext + // + this.searchnext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.searchnext.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchNext; + this.searchnext.ImageTransparentColor = System.Drawing.Color.Magenta; + this.searchnext.Name = "searchnext"; + this.searchnext.Size = new System.Drawing.Size(23, 22); + this.searchnext.ToolTipText = "Next Match"; + this.searchnext.Click += new System.EventHandler(this.searchnext_Click); + // + // searchmatchcase + // + this.searchmatchcase.CheckOnClick = true; + this.searchmatchcase.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.searchmatchcase.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchMatchCase; + this.searchmatchcase.ImageTransparentColor = System.Drawing.Color.Magenta; + this.searchmatchcase.Name = "searchmatchcase"; + this.searchmatchcase.Size = new System.Drawing.Size(23, 22); + this.searchmatchcase.ToolTipText = "Match Case"; + this.searchmatchcase.Click += new System.EventHandler(this.searchbox_TextChanged); + // + // searchwholeword + // + this.searchwholeword.CheckOnClick = true; + this.searchwholeword.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.searchwholeword.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchMatch; + this.searchwholeword.ImageTransparentColor = System.Drawing.Color.Magenta; + this.searchwholeword.Name = "searchwholeword"; + this.searchwholeword.Size = new System.Drawing.Size(23, 22); + this.searchwholeword.ToolTipText = "Match Whole Word"; + this.searchwholeword.Click += new System.EventHandler(this.searchbox_TextChanged); + // + // openfile + // + this.openfile.Multiselect = true; + this.openfile.Title = "Open Script"; + // + // savefile + // + this.savefile.Title = "Save Script As"; + // + // splitter + // + this.splitter.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitter.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.splitter.IsSplitterFixed = true; + this.splitter.Location = new System.Drawing.Point(0, 25); + this.splitter.Name = "splitter"; + this.splitter.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitter.Panel1 + // + this.splitter.Panel1.Controls.Add(this.tabs); + // + // splitter.Panel2 + // + this.splitter.Panel2.Controls.Add(this.label1); + this.splitter.Panel2.Controls.Add(this.errorlist); + this.splitter.Size = new System.Drawing.Size(800, 516); + this.splitter.SplitterDistance = 390; + this.splitter.TabIndex = 2; + this.splitter.TabStop = false; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.BackColor = System.Drawing.SystemColors.ActiveCaption; + this.label1.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; + this.label1.Location = new System.Drawing.Point(3, 0); + this.label1.Name = "label1"; + this.label1.Padding = new System.Windows.Forms.Padding(1); + this.label1.Size = new System.Drawing.Size(794, 16); + this.label1.TabIndex = 1; + this.label1.Text = "Errors"; + // + // errorlist + // + this.errorlist.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.errorlist.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.colIndex, this.colDescription, this.colFile}); - this.errorlist.FullRowSelect = true; - this.errorlist.GridLines = true; - this.errorlist.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.errorlist.LabelWrap = false; - this.errorlist.Location = new System.Drawing.Point(3, 19); - this.errorlist.MultiSelect = false; - this.errorlist.Name = "errorlist"; - this.errorlist.ShowGroups = false; - this.errorlist.Size = new System.Drawing.Size(720, 100); - this.errorlist.SmallImageList = this.errorimages; - this.errorlist.TabIndex = 0; - this.errorlist.TabStop = false; - this.errorlist.UseCompatibleStateImageBehavior = false; - this.errorlist.View = System.Windows.Forms.View.Details; - this.errorlist.ItemActivate += new System.EventHandler(this.errorlist_ItemActivate); - // - // colIndex - // - this.colIndex.Text = ""; - this.colIndex.Width = 45; - // - // colDescription - // - this.colDescription.Text = "Description"; - this.colDescription.Width = 500; - // - // colFile - // - this.colFile.Text = "File"; - this.colFile.Width = 150; - // - // errorimages - // - this.errorimages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("errorimages.ImageStream"))); - this.errorimages.TransparentColor = System.Drawing.Color.Transparent; - this.errorimages.Images.SetKeyName(0, "ScriptError3.png"); - // - // statusbar - // - this.statusbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.errorlist.FullRowSelect = true; + this.errorlist.GridLines = true; + this.errorlist.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.errorlist.LabelWrap = false; + this.errorlist.Location = new System.Drawing.Point(3, 19); + this.errorlist.MultiSelect = false; + this.errorlist.Name = "errorlist"; + this.errorlist.ShowGroups = false; + this.errorlist.Size = new System.Drawing.Size(794, 100); + this.errorlist.SmallImageList = this.errorimages; + this.errorlist.TabIndex = 0; + this.errorlist.TabStop = false; + this.errorlist.UseCompatibleStateImageBehavior = false; + this.errorlist.View = System.Windows.Forms.View.Details; + this.errorlist.ItemActivate += new System.EventHandler(this.errorlist_ItemActivate); + // + // colIndex + // + this.colIndex.Text = ""; + this.colIndex.Width = 45; + // + // colDescription + // + this.colDescription.Text = "Description"; + this.colDescription.Width = 500; + // + // colFile + // + this.colFile.Text = "File"; + this.colFile.Width = 150; + // + // errorimages + // + this.errorimages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("errorimages.ImageStream"))); + this.errorimages.TransparentColor = System.Drawing.Color.Transparent; + this.errorimages.Images.SetKeyName(0, "ScriptError3.png"); + // + // statusbar + // + this.statusbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.statuslabel, + this.positionlabel, this.scripttype}); - this.statusbar.Location = new System.Drawing.Point(0, 541); - this.statusbar.Name = "statusbar"; - this.statusbar.Size = new System.Drawing.Size(726, 22); - this.statusbar.TabIndex = 3; - this.statusbar.Text = "statusStrip1"; - // - // statuslabel - // - this.statuslabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold); - this.statuslabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Status0; - this.statuslabel.Margin = new System.Windows.Forms.Padding(3, 3, 0, 2); - this.statuslabel.Name = "statuslabel"; - this.statuslabel.Size = new System.Drawing.Size(60, 17); - this.statuslabel.Text = "Ready."; - // - // scripttype - // - this.scripttype.Name = "scripttype"; - this.scripttype.Size = new System.Drawing.Size(648, 17); - this.scripttype.Spring = true; - this.scripttype.Text = "Plain Text"; - this.scripttype.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // statusflasher - // - this.statusflasher.Tick += new System.EventHandler(this.statusflasher_Tick); - // - // statusresetter - // - this.statusresetter.Tick += new System.EventHandler(this.statusresetter_Tick); - // - // ScriptEditorPanel - // - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackColor = System.Drawing.SystemColors.Control; - this.Controls.Add(this.splitter); - this.Controls.Add(this.statusbar); - this.Controls.Add(this.toolbar); - this.Name = "ScriptEditorPanel"; - this.Size = new System.Drawing.Size(726, 563); - this.toolbar.ResumeLayout(false); - this.toolbar.PerformLayout(); - this.splitter.Panel1.ResumeLayout(false); - this.splitter.Panel2.ResumeLayout(false); - this.splitter.ResumeLayout(false); - this.statusbar.ResumeLayout(false); - this.statusbar.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); + this.statusbar.Location = new System.Drawing.Point(0, 541); + this.statusbar.Name = "statusbar"; + this.statusbar.Size = new System.Drawing.Size(800, 22); + this.statusbar.TabIndex = 3; + this.statusbar.Text = "statusStrip1"; + // + // statuslabel + // + this.statuslabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold); + this.statuslabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Status0; + this.statuslabel.Margin = new System.Windows.Forms.Padding(3, 3, 0, 2); + this.statuslabel.Name = "statuslabel"; + this.statuslabel.Size = new System.Drawing.Size(60, 17); + this.statuslabel.Text = "Ready."; + // + // positionlabel + // + this.positionlabel.Name = "positionlabel"; + this.positionlabel.Size = new System.Drawing.Size(634, 17); + this.positionlabel.Spring = true; + this.positionlabel.Text = "100 : 12 (120)"; + this.positionlabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // scripttype + // + this.scripttype.Margin = new System.Windows.Forms.Padding(30, 3, 0, 2); + this.scripttype.Name = "scripttype"; + this.scripttype.Size = new System.Drawing.Size(58, 17); + this.scripttype.Text = "Plain Text"; + this.scripttype.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // statusflasher + // + this.statusflasher.Tick += new System.EventHandler(this.statusflasher_Tick); + // + // statusresetter + // + this.statusresetter.Tick += new System.EventHandler(this.statusresetter_Tick); + // + // ScriptEditorPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.BackColor = System.Drawing.SystemColors.Control; + this.Controls.Add(this.splitter); + this.Controls.Add(this.statusbar); + this.Controls.Add(this.toolbar); + this.Name = "ScriptEditorPanel"; + this.Size = new System.Drawing.Size(800, 563); + this.toolbar.ResumeLayout(false); + this.toolbar.PerformLayout(); + this.splitter.Panel1.ResumeLayout(false); + this.splitter.Panel2.ResumeLayout(false); + this.splitter.ResumeLayout(false); + this.statusbar.ResumeLayout(false); + this.statusbar.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); - } + } - #endregion + #endregion - private System.Windows.Forms.TabControl tabs; - private System.Windows.Forms.ToolStrip toolbar; - private System.Windows.Forms.ToolStripButton buttonopen; - private System.Windows.Forms.ToolStripDropDownButton buttonnew; - private System.Windows.Forms.OpenFileDialog openfile; - private System.Windows.Forms.SaveFileDialog savefile; - private System.Windows.Forms.ToolStripButton buttonsave; - private System.Windows.Forms.ToolStripButton buttonsaveall; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripButton buttoncompile; - private System.Windows.Forms.ToolStripButton buttonundo; - private System.Windows.Forms.ToolStripButton buttonredo; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; - private System.Windows.Forms.ToolStripButton buttoncut; - private System.Windows.Forms.ToolStripButton buttoncopy; - private System.Windows.Forms.ToolStripButton buttonpaste; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; - private System.Windows.Forms.ToolStripDropDownButton buttonscriptconfig; - private System.Windows.Forms.ToolStripButton buttonclose; - private System.Windows.Forms.SplitContainer splitter; - private System.Windows.Forms.ListView errorlist; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.ColumnHeader colIndex; - private System.Windows.Forms.ColumnHeader colDescription; - private System.Windows.Forms.ColumnHeader colFile; - private System.Windows.Forms.ImageList errorimages; - private System.Windows.Forms.ToolStripButton buttonkeywordhelp; - private System.Windows.Forms.ToolStripButton buttonsearch; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; - private System.Windows.Forms.ToolStripDropDownButton buttonsnippets; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; - private System.Windows.Forms.ToolStripTextBox searchbox; - private System.Windows.Forms.ToolStripButton searchnext; - private System.Windows.Forms.ToolStripButton searchprev; - private System.Windows.Forms.ToolStripButton searchmatchcase; - private System.Windows.Forms.ToolStripButton searchwholeword; - private System.Windows.Forms.StatusStrip statusbar; - private System.Windows.Forms.ToolStripStatusLabel statuslabel; - private System.Windows.Forms.ToolStripStatusLabel scripttype; - private System.Windows.Forms.Timer statusflasher; - private System.Windows.Forms.Timer statusresetter; - } -} + private System.Windows.Forms.TabControl tabs; + private System.Windows.Forms.ToolStrip toolbar; + private System.Windows.Forms.ToolStripButton buttonopen; + private System.Windows.Forms.ToolStripDropDownButton buttonnew; + private System.Windows.Forms.OpenFileDialog openfile; + private System.Windows.Forms.SaveFileDialog savefile; + private System.Windows.Forms.ToolStripButton buttonsave; + private System.Windows.Forms.ToolStripButton buttonsaveall; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton buttoncompile; + private System.Windows.Forms.ToolStripButton buttonundo; + private System.Windows.Forms.ToolStripButton buttonredo; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton buttoncut; + private System.Windows.Forms.ToolStripButton buttoncopy; + private System.Windows.Forms.ToolStripButton buttonpaste; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripDropDownButton buttonscriptconfig; + private System.Windows.Forms.ToolStripButton buttonclose; + private System.Windows.Forms.SplitContainer splitter; + private System.Windows.Forms.ListView errorlist; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ColumnHeader colIndex; + private System.Windows.Forms.ColumnHeader colDescription; + private System.Windows.Forms.ColumnHeader colFile; + private System.Windows.Forms.ImageList errorimages; + private System.Windows.Forms.ToolStripButton buttonkeywordhelp; + private System.Windows.Forms.ToolStripButton buttonsearch; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripDropDownButton buttonsnippets; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripTextBox searchbox; + private System.Windows.Forms.ToolStripButton searchnext; + private System.Windows.Forms.ToolStripButton searchprev; + private System.Windows.Forms.ToolStripButton searchmatchcase; + private System.Windows.Forms.ToolStripButton searchwholeword; + private System.Windows.Forms.StatusStrip statusbar; + private System.Windows.Forms.ToolStripStatusLabel statuslabel; + private System.Windows.Forms.ToolStripStatusLabel scripttype; + private System.Windows.Forms.Timer statusflasher; + private System.Windows.Forms.Timer statusresetter; + private System.Windows.Forms.ToolStripStatusLabel positionlabel; + private System.Windows.Forms.ToolStripButton buttonunindent; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + private System.Windows.Forms.ToolStripButton buttonindent; + private System.Windows.Forms.ToolStripButton buttonwhitespace; + private System.Windows.Forms.ToolStripButton buttonwordwrap; + } +} \ No newline at end of file diff --git a/Source/Core/Controls/ScriptEditorPanel.cs b/Source/Core/Controls/ScriptEditorPanel.cs index cb54d15..63d5045 100644 --- a/Source/Core/Controls/ScriptEditorPanel.cs +++ b/Source/Core/Controls/ScriptEditorPanel.cs @@ -25,1039 +25,1127 @@ using System.Windows.Forms; using CodeImp.DoomBuilder.Compilers; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Windows; +using ScintillaNET; #endregion namespace CodeImp.DoomBuilder.Controls { - internal partial class ScriptEditorPanel : UserControl - { - #region ================== Constants - - #endregion - - #region ================== Variables - - private List scriptconfigs; - private List compilererrors; - - // Find/Replace - private ScriptFindReplaceForm findreplaceform; - private FindReplaceOptions findoptions; - - // Quick search bar settings (mxd) - private static bool matchwholeword; - private static bool matchcase; - - //mxd. Status update - private ScriptStatusInfo status; - private int statusflashcount; - private bool statusflashicon; - - #endregion - - #region ================== Properties - - public ScriptDocumentTab ActiveTab { get { return (tabs.SelectedTab as ScriptDocumentTab); } } - - #endregion - - #region ================== Constructor - - // Constructor - public ScriptEditorPanel() - { - InitializeComponent(); - } - - // This initializes the control - public void Initialize() - { - // Make list of script configs - scriptconfigs = new List(General.ScriptConfigs.Values); - scriptconfigs.Add(new ScriptConfiguration()); - scriptconfigs.Sort(); - - // Fill the list of new document types - foreach(ScriptConfiguration cfg in scriptconfigs) - { - // Button for new script menu - ToolStripMenuItem item = new ToolStripMenuItem(cfg.Description); - //item.Image = buttonnew.Image; - item.Tag = cfg; - item.Click += buttonnew_Click; - buttonnew.DropDownItems.Add(item); - - // Button for script type menu - item = new ToolStripMenuItem(cfg.Description); - //item.Image = buttonnew.Image; - item.Tag = cfg; - item.Click += buttonscriptconfig_Click; - buttonscriptconfig.DropDownItems.Add(item); - } - - // Setup supported extensions - string filterall = ""; - string filterseperate = ""; - foreach(ScriptConfiguration cfg in scriptconfigs) - { - if(cfg.Extensions.Length > 0) - { - string exts = "*." + string.Join(";*.", cfg.Extensions); - if(filterseperate.Length > 0) filterseperate += "|"; - filterseperate += cfg.Description + "|" + exts; - if(filterall.Length > 0) filterall += ";"; - filterall += exts; - } - } - openfile.Filter = "Script files|" + filterall + "|" + filterseperate + "|All files|*.*"; - - // Load the script lumps - foreach(MapLumpInfo maplumpinfo in General.Map.Config.MapLumps.Values) - { - // Is this a script lump? - if(maplumpinfo.Script != null) - { - // Load this! - ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, maplumpinfo.Script); - tabs.TabPages.Add(t); - } - else if(maplumpinfo.ScriptBuild) //mxd - { - // Load this! - ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler]); - tabs.TabPages.Add(t); - } - } - - // Load the files that were previously opened for this map - foreach(String filename in General.Map.Options.ScriptFiles) - { - // Does this file exist? - if(File.Exists(filename)) - { - // Load this! - OpenFile(filename); - } - } - - //mxd. Select "Scripts" tab, because that's what user will want 99% of time - int scriptsindex = GetTabPageIndex("SCRIPTS"); - tabs.SelectedIndex = (scriptsindex == -1 ? 0 : scriptsindex); - - //mxd. Apply quick search settings - searchmatchcase.Checked = matchcase; - searchwholeword.Checked = matchwholeword; - searchbox_TextChanged(this, EventArgs.Empty); - - // If the map has remembered any compile errors, then show them - ShowErrors(General.Map.Errors); - - // Done - UpdateToolbar(true); - } - - // This applies user preferences - public void ApplySettings() - { - // Apply settings - //int panel2size = General.Settings.ReadSetting("scriptspanel.splitter", splitter.ClientRectangle.Height - splitter.SplitterDistance); - //splitter.SplitterDistance = splitter.ClientRectangle.Height - panel2size; - errorlist.Columns[0].Width = General.Settings.ReadSetting("scriptspanel.errorscolumn0width", errorlist.Columns[0].Width); - errorlist.Columns[1].Width = General.Settings.ReadSetting("scriptspanel.errorscolumn1width", errorlist.Columns[1].Width); - errorlist.Columns[2].Width = General.Settings.ReadSetting("scriptspanel.errorscolumn2width", errorlist.Columns[2].Width); - } - - // This saves user preferences - public void SaveSettings() - { - //General.Settings.WriteSetting("scriptspanel.splitter", splitter.ClientRectangle.Height - splitter.SplitterDistance); - General.Settings.WriteSetting("scriptspanel.errorscolumn0width", errorlist.Columns[0].Width); - General.Settings.WriteSetting("scriptspanel.errorscolumn1width", errorlist.Columns[1].Width); - General.Settings.WriteSetting("scriptspanel.errorscolumn2width", errorlist.Columns[2].Width); - } - - #endregion - - #region ================== Methods - - // Find Next - public void FindNext(FindReplaceOptions options) - { - // Save the options - findoptions = options; - FindNext(); - } - - // Find Next with saved options - public void FindNext() - { - if(!string.IsNullOrEmpty(findoptions.FindText) && (ActiveTab != null)) - { - if(!ActiveTab.FindNext(findoptions)) - DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\"."); - } - else - { - General.MessageBeep(MessageBeepType.Default); - } - } - - // Find Previous - public void FindPrevious(FindReplaceOptions options) - { - // Save the options - findoptions = options; - FindPrevious(); - } - - // Find Previous with saved options (mxd) - public void FindPrevious() - { - if(!string.IsNullOrEmpty(findoptions.FindText) && (ActiveTab != null)) - { - if(!ActiveTab.FindPrevious(findoptions)) - DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\"."); - } - else - { - General.MessageBeep(MessageBeepType.Default); - } - } - - // Replace if possible - public void Replace(FindReplaceOptions options) - { - if(!string.IsNullOrEmpty(findoptions.FindText) && (options.ReplaceWith != null) && (ActiveTab != null)) - { - if(string.Compare(ActiveTab.GetSelectedText(), options.FindText, !options.CaseSensitive) == 0) - { - // Replace selection - ActiveTab.ReplaceSelection(options.ReplaceWith); - } - } - else - { - General.MessageBeep(MessageBeepType.Default); - } - } - - // Replace all - public void ReplaceAll(FindReplaceOptions options) - { - int replacements = 0; - findoptions = options; - if(!string.IsNullOrEmpty(findoptions.FindText) && (options.ReplaceWith != null) && (ActiveTab != null)) - { - int firstfindpos = -1; - int lastpos = -1; - bool firstreplace = true; - bool wrappedaround = false; - int selectionstart = Math.Min(ActiveTab.SelectionStart, ActiveTab.SelectionEnd); - - // Continue finding and replacing until nothing more found - while(ActiveTab.FindNext(findoptions)) - { - int curpos = Math.Min(ActiveTab.SelectionStart, ActiveTab.SelectionEnd); - if(curpos <= lastpos) - wrappedaround = true; - - if(firstreplace) - { - // Remember where we started replacing - firstfindpos = curpos; - } - else if(wrappedaround) - { - // Make sure we don't go past our start point, or we could be in an endless loop - if(curpos >= firstfindpos) - break; - } - - Replace(findoptions); - replacements++; - firstreplace = false; - - lastpos = curpos; - } - - // Restore selection - ActiveTab.SelectionStart = selectionstart; - ActiveTab.SelectionEnd = selectionstart; - - // Show result - if(replacements == 0) - DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\"."); - else - DisplayStatus(ScriptStatusType.Info, "Replaced " + replacements + " occurences of \"" + findoptions.FindText + "\" with \"" + findoptions.ReplaceWith + "\"."); - } - else - { - General.MessageBeep(MessageBeepType.Default); - } - } - - // This closed the Find & Replace subwindow - public void CloseFindReplace(bool closing) - { - if(findreplaceform != null) - { - if(!closing) findreplaceform.Close(); - findreplaceform = null; - } - } - - // This opens the Find & Replace subwindow - public void OpenFindAndReplace() - { - if(findreplaceform == null) - findreplaceform = new ScriptFindReplaceForm(); - - try - { - if(findreplaceform.Visible) - findreplaceform.Focus(); - else - findreplaceform.Show(this.ParentForm); - - if(ActiveTab.SelectionEnd != ActiveTab.SelectionStart) - findreplaceform.SetFindText(ActiveTab.GetSelectedText()); - } - catch(Exception) - { - // If we can't pop up the find/replace form right now, thats just too bad. - } - } - - // This refreshes all settings - public void RefreshSettings() - { - foreach(ScriptDocumentTab t in tabs.TabPages) - { - t.RefreshSettings(); - } - } - - // This clears all error marks and hides the errors list - public void ClearErrors() - { - // Hide list - splitter.Panel2Collapsed = true; - errorlist.Items.Clear(); - - // Clear marks - foreach(ScriptDocumentTab t in tabs.TabPages) - { - t.ClearMarks(); - } - } - - // This shows the errors panel with the given errors - // Also updates the scripts with markers for the given errors - public void ShowErrors(IEnumerable errors) - { - // Copy list - if(errors != null) - compilererrors = new List(errors); - else - compilererrors = new List(); - - // Fill list - errorlist.BeginUpdate(); - errorlist.Items.Clear(); - int listindex = 1; - foreach(CompilerError e in compilererrors) - { - ListViewItem ei = new ListViewItem(listindex.ToString()); - ei.ImageIndex = 0; - ei.SubItems.Add(e.description); - string filename = (e.filename.StartsWith("?") ? e.filename.Replace("?", "") : Path.GetFileName(e.filename)); //mxd - string linenumber = (e.linenumber != CompilerError.NO_LINE_NUMBER ? " (line " + (e.linenumber + 1) + ")" : String.Empty); //mxd - ei.SubItems.Add(filename + linenumber); - ei.Tag = e; - errorlist.Items.Add(ei); - listindex++; - } - errorlist.EndUpdate(); - - // Show marks on scripts - foreach(ScriptDocumentTab t in tabs.TabPages) - { - t.MarkScriptErrors(compilererrors); - } - - // Show/hide panel - splitter.Panel2Collapsed = (errorlist.Items.Count == 0); - } - - // This writes all explicitly opened files to the configuration - public void WriteOpenFilesToConfiguration() - { - List files = new List(); - foreach(ScriptDocumentTab t in tabs.TabPages) - { - if(t.ExplicitSave) files.Add(t.Filename); - } - General.Map.Options.ScriptFiles = files; - } - - // This asks to save files and returns the result - public bool AskSaveAll() - { - foreach(ScriptDocumentTab t in tabs.TabPages) - { - if(t.ExplicitSave) - { - if(!CloseScript(t, true)) return false; - } - } - - return true; - } - - // This closes a script and returns true when closed - private bool CloseScript(ScriptDocumentTab t, bool saveonly) - { - if(t.IsChanged) - { - // Ask to save - DialogResult result = MessageBox.Show(this.ParentForm, "Do you want to save changes to " + t.Text + "?", "Close File", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); - switch(result) - { - case DialogResult.Yes: - if(!SaveScript(t)) return false; - break; - case DialogResult.Cancel: - return false; - } - } - - if(!saveonly) - { - //mxd. Select tab to the left of the one we are going to close - if(t == tabs.SelectedTab && tabs.SelectedIndex > 0) - tabs.SelectedIndex--; - - // Close file - tabs.TabPages.Remove(t); - t.Dispose(); - } - return true; - } - - // This returns true when any of the implicit-save scripts are changed - public bool CheckImplicitChanges() - { - foreach(ScriptDocumentTab t in tabs.TabPages) - { - if(!t.ExplicitSave && t.IsChanged) return true; - } - return false; - } - - // This forces the focus to the script editor - public void ForceFocus() - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - tabs.Focus(); - if(t != null) t.Focus(); - } - - // This does an implicit save on all documents that use implicit saving - // Call this to save the lumps before disposing the panel! - public void ImplicitSave() - { - // Save all scripts - foreach(ScriptDocumentTab t in tabs.TabPages) - { - if(!t.ExplicitSave) t.Save(); - } - - UpdateToolbar(false); - } - - // This updates the toolbar for the current status - private void UpdateToolbar(bool focuseditor) - { - int numscriptsopen = tabs.TabPages.Count; - int explicitsavescripts = 0; - ScriptDocumentTab t = null; - - // Any explicit save scripts? - foreach(ScriptDocumentTab dt in tabs.TabPages) - if(dt.ExplicitSave) explicitsavescripts++; - - // Get current script, if any are open - if(numscriptsopen > 0) - t = (tabs.SelectedTab as ScriptDocumentTab); - - // Enable/disable buttons - buttonsave.Enabled = (t != null) && t.ExplicitSave && t.IsChanged; - buttonsaveall.Enabled = (explicitsavescripts > 0); - buttoncompile.Enabled = (t != null) && (t.Config.Compiler != null); - buttonsearch.Enabled = (t != null); //mxd - buttonkeywordhelp.Enabled = (t != null) && !string.IsNullOrEmpty(t.Config.KeywordHelp); - buttonscriptconfig.Enabled = (t != null) && t.IsReconfigurable; - buttonundo.Enabled = (t != null); - buttonredo.Enabled = (t != null); - buttoncopy.Enabled = (t != null); - buttoncut.Enabled = (t != null); - buttonpaste.Enabled = (t != null); - buttonclose.Enabled = (t != null) && t.IsClosable; - buttonsnippets.DropDownItems.Clear(); //mxd - buttonsnippets.Enabled = (t != null) && t.Config.Snippets.Count > 0; //mxd - - if(t != null) - { - // Check the according script config in menu - foreach(ToolStripMenuItem item in buttonscriptconfig.DropDownItems) - { - ScriptConfiguration config = (item.Tag as ScriptConfiguration); - item.Checked = (config == t.Config); - } - - //mxd. Add snippets - if(t.Config != null && t.Config.Snippets.Count > 0) - { - if(t.Config.Snippets.Count > 0) foreach(KeyValuePair group in t.Config.Snippets) buttonsnippets.DropDownItems.Add(group.Key).Click += OnInsertSnippetClick; - } - - // Focus to script editor - if(focuseditor) ForceFocus(); - } - - //mxd. Update script type description - scripttype.Text = ((t != null && t.Config != null) ? t.Config.Description : "Plain Text"); - } - - //mxd - private int GetTabPageIndex(string title) - { - if(tabs.TabPages.Count == 0) return -1; - - for(int i = 0; i < tabs.TabPages.Count; i++) - { - if(tabs.TabPages[i].Text == title) return i; - } - - return -1; - } - - // This opens the given file, returns null when failed - public ScriptFileDocumentTab OpenFile(string filename) - { - ScriptConfiguration foundconfig = new ScriptConfiguration(); - - // Find the most suitable script configuration to use - foreach(ScriptConfiguration cfg in scriptconfigs) - { - foreach(string ext in cfg.Extensions) - { - // Use this configuration if the extension matches - if(filename.EndsWith("." + ext, true, CultureInfo.InvariantCulture)) - { - foundconfig = cfg; - break; - } - } - } - - // Create new document - ScriptFileDocumentTab t = new ScriptFileDocumentTab(this, foundconfig); - if(t.Open(filename)) - { - //mxd - ScriptType st = t.VerifyScriptType(); - if(st != ScriptType.UNKNOWN) - { - foreach(ScriptConfiguration cfg in scriptconfigs) - { - if(cfg.ScriptType == st) - { - t.ChangeScriptConfig(cfg); - break; - } - } - } - - // Mark any errors this script may have - if(compilererrors != null) t.MarkScriptErrors(compilererrors); - - // Add to tabs - tabs.TabPages.Add(t); - tabs.SelectedTab = t; - - // Done - t.OnTextChanged += tabpage_OnTextChanged; //mxd - t.IsChanged = false; //mxd. Not changed yet - UpdateToolbar(true); - return t; - } - else - { - // Failed - return null; - } - } - - // This saves the current open script - public void ExplicitSaveCurrentTab() - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - if((t != null) && t.ExplicitSave) - { - buttonsave_Click(this, EventArgs.Empty); - } - else - { - General.MessageBeep(MessageBeepType.Default); - } - } - - // This opens a script - public void OpenBrowseScript() - { - buttonopen_Click(this, EventArgs.Empty); - } - - //mxd. This launches keyword help website - public bool LaunchKeywordHelp() - { - // Get script - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - return t.LaunchKeywordHelp(); - } - - //mxd. This changes status text - private void DisplayStatus(ScriptStatusType type, string message) { DisplayStatus(new ScriptStatusInfo(type, message)); } - private void DisplayStatus(ScriptStatusInfo newstatus) - { - // Stop timers - if(!newstatus.displayed) - { - statusresetter.Stop(); - statusflasher.Stop(); - statusflashicon = false; - } - - // Determine what to do specifically for this status type - switch(newstatus.type) - { - // Shows information without flashing the icon. - case ScriptStatusType.Ready: - case ScriptStatusType.Info: - if(!newstatus.displayed) - { - statusresetter.Interval = MainForm.INFO_RESET_DELAY; - statusresetter.Start(); - } - break; - - // Shows a warning, makes a warning sound and flashes a warning icon. - case ScriptStatusType.Warning: - if(!newstatus.displayed) - { - General.MessageBeep(MessageBeepType.Warning); - statusflasher.Interval = MainForm.WARNING_FLASH_INTERVAL; - statusflashcount = MainForm.WARNING_FLASH_COUNT; - statusflasher.Start(); - statusresetter.Interval = MainForm.WARNING_RESET_DELAY; - statusresetter.Start(); - } - break; - } - - // Update status description - status = newstatus; - status.displayed = true; - statuslabel.Text = status.message; - - // Update icon as well - UpdateStatusIcon(); - - // Refresh - statusbar.Invalidate(); - this.Update(); - } - - // This updates the status icon - private void UpdateStatusIcon() - { - int statusflashindex = (statusflashicon ? 1 : 0); - - // Status type - switch(status.type) - { - case ScriptStatusType.Ready: - case ScriptStatusType.Info: - statuslabel.Image = General.MainWindow.STATUS_IMAGES[statusflashindex, 0]; - break; - - case ScriptStatusType.Busy: - statuslabel.Image = General.MainWindow.STATUS_IMAGES[statusflashindex, 2]; - break; - - case ScriptStatusType.Warning: - statuslabel.Image = General.MainWindow.STATUS_IMAGES[statusflashindex, 3]; - break; - - default: - throw new NotImplementedException("Unsupported Script Status Type!"); - } - } - - #endregion - - #region ================== Events - - // Called when the window that contains this panel closes - public void OnClose() - { - //mxd. Store quick search settings - matchcase = searchmatchcase.Checked; - matchwholeword = searchwholeword.Checked; - - //mxd. Stop status timers - statusresetter.Stop(); - statusflasher.Stop(); - - // Close the sub windows now - if(findreplaceform != null) findreplaceform.Dispose(); - } - - // Keyword help requested - private void buttonkeywordhelp_Click(object sender, EventArgs e) - { - LaunchKeywordHelp(); - } - - // When the user changes the script configuration - private void buttonscriptconfig_Click(object sender, EventArgs e) - { - // Get the tab and new script config - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - ScriptConfiguration scriptconfig = ((sender as ToolStripMenuItem).Tag as ScriptConfiguration); - - // Change script config - t.ChangeScriptConfig(scriptconfig); - - //mxd. Update script type description - scripttype.Text = scriptconfig.Description; - - // Done - UpdateToolbar(true); - } - - // When new script is clicked - private void buttonnew_Click(object sender, EventArgs e) - { - // Get the script config to use - ScriptConfiguration scriptconfig = ((sender as ToolStripMenuItem).Tag as ScriptConfiguration); - - // Create new document - ScriptFileDocumentTab t = new ScriptFileDocumentTab(this, scriptconfig); - tabs.TabPages.Add(t); - tabs.SelectedTab = t; - - // Done - UpdateToolbar(true); - } - - // Open script clicked - private void buttonopen_Click(object sender, EventArgs e) - { - // Show open file dialog - if(openfile.ShowDialog(this.ParentForm) == DialogResult.OK) - { - //mxd. Gather already opened file names - List openedfiles = new List(); - foreach(var page in tabs.TabPages) - { - var scriptpage = page as ScriptFileDocumentTab; - if(scriptpage != null) openedfiles.Add(scriptpage.Filename); - } - - //mxd. Add new tabs - foreach(string name in openfile.FileNames) - { - if(!openedfiles.Contains(name)) OpenFile(name); - } - - // Select the last new item - foreach(var page in tabs.TabPages) - { - var scriptpage = page as ScriptFileDocumentTab; - if(scriptpage != null && scriptpage.Filename == openfile.FileNames[openfile.FileNames.Length - 1]) - { - tabs.SelectedTab = scriptpage; - break; - } - } - } - } - - // Save script clicked - private void buttonsave_Click(object sender, EventArgs e) - { - // Save the current script - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - SaveScript(t); - UpdateToolbar(true); - } - - // Save All clicked - private void buttonsaveall_Click(object sender, EventArgs e) - { - // Save all scripts - foreach(ScriptDocumentTab t in tabs.TabPages) - { - // Use explicit save for this script? - if(t.ExplicitSave) - { - if(!SaveScript(t)) break; - } - } - - UpdateToolbar(true); - } - - // This is called by Save and Save All to save a script - // Returns false when cancelled by the user - private bool SaveScript(ScriptDocumentTab t) - { - // Do we have to do a save as? - if(t.IsSaveAsRequired) - { - // Setup save dialog - string scriptfilter = t.Config.Description + "|*." + string.Join(";*.", t.Config.Extensions); - savefile.Filter = scriptfilter + "|All files|*.*"; - if(savefile.ShowDialog(this.ParentForm) == DialogResult.OK) - { - // Save to new filename - t.SaveAs(savefile.FileName); - return true; - } - else - { - // Cancelled - return false; - } - } - else - { - // Save to same filename - t.Save(); - return true; - } - } - - // A tab is selected - private void tabs_Selecting(object sender, TabControlCancelEventArgs e) - { - UpdateToolbar(true); - } - - // This closes the current file - private void buttonclose_Click(object sender, EventArgs e) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - CloseScript(t, false); - UpdateToolbar(true); - } - - // Compile Script clicked - private void buttoncompile_Click(object sender, EventArgs e) - { - // First save all implicit scripts to the temporary wad file - ImplicitSave(); - - // Get script - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - - // Check if it must be saved as a new file - if(t.ExplicitSave && t.IsSaveAsRequired) - { - // Save the script first! - if(MessageBox.Show(this.ParentForm, "You must save your script before you can compile it. Do you want to save your script now?", "Compile Script", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) - { - if(!SaveScript(t)) return; - } - else - { - return; - } - } - else if(t.ExplicitSave && t.IsChanged) - { - // We can only compile when the script is saved - if(!SaveScript(t)) return; - } - - // Compile now - DisplayStatus(ScriptStatusType.Busy, "Compiling script \"" + t.Text + "\"..."); - Cursor.Current = Cursors.WaitCursor; - t.Compile(); - - // Show warning - if((compilererrors != null) && (compilererrors.Count > 0)) - DisplayStatus(ScriptStatusType.Warning, compilererrors.Count + " errors while compiling \"" + t.Text + "\"!"); - else - DisplayStatus(ScriptStatusType.Info, "Script \"" + t.Text + "\" compiled without errors."); - - Cursor.Current = Cursors.Default; - UpdateToolbar(true); - } - - // Undo clicked - private void buttonundo_Click(object sender, EventArgs e) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - t.Undo(); - UpdateToolbar(true); - } - - // Redo clicked - private void buttonredo_Click(object sender, EventArgs e) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - t.Redo(); - UpdateToolbar(true); - } - - // Cut clicked - private void buttoncut_Click(object sender, EventArgs e) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - t.Cut(); - UpdateToolbar(true); - } - - // Copy clicked - private void buttoncopy_Click(object sender, EventArgs e) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - t.Copy(); - UpdateToolbar(true); - } - - // Paste clicked - private void buttonpaste_Click(object sender, EventArgs e) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - t.Paste(); - UpdateToolbar(true); - } - - //mxd. Search clicked - private void buttonsearch_Click(object sender, EventArgs e) - { - OpenFindAndReplace(); - } - - //mxd - private void OnInsertSnippetClick(object sender, EventArgs eventArgs) - { - ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); - t.InsertSnippet( t.Config.Snippets[((ToolStripItem)sender).Text] ); - } - - // Mouse released on tabs - private void tabs_MouseUp(object sender, MouseEventArgs e) - { - ForceFocus(); - } - - //mxd - private void tabpage_OnTextChanged(object sender, EventArgs eventArgs) - { - if(tabs.SelectedTab != null) - { - ScriptDocumentTab curtab = tabs.SelectedTab as ScriptDocumentTab; - buttonsave.Enabled = (curtab != null && curtab.ExplicitSave && curtab.IsChanged); - } - } - - // User double-clicks and error in the list - private void errorlist_ItemActivate(object sender, EventArgs e) - { - // Anything selection? - if(errorlist.SelectedItems.Count > 0) - { - // Get the compiler error - CompilerError err = (CompilerError)errorlist.SelectedItems[0].Tag; - - // Show the tab with the script that matches - bool foundscript = false; - foreach(ScriptDocumentTab t in tabs.TabPages) - { - if(t.VerifyErrorForScript(err)) - { - tabs.SelectedTab = t; - t.MoveToLine(err.linenumber); - foundscript = true; - break; - } - } - - // If we don't have the script opened, see if we can find the file and open the script - if(!foundscript && File.Exists(err.filename)) - { - ScriptDocumentTab t = OpenFile(err.filename); - if(t != null) t.MoveToLine(err.linenumber); - } - - ForceFocus(); - } - } - - #endregion - - #region ================== Quick Search (mxd) - - private FindReplaceOptions GetQuickSearchOptions() - { - return new FindReplaceOptions - { - CaseSensitive = searchmatchcase.Checked, - WholeWord = searchwholeword.Checked, - FindText = searchbox.Text - }; - } - - private void searchbox_TextChanged(object sender, EventArgs e) - { - bool success = (searchbox.Text.Length > 0 && ActiveTab.FindNext(GetQuickSearchOptions(), true)); - searchbox.BackColor = ((success || searchbox.Text.Length == 0) ? SystemColors.Window : Color.MistyRose); - searchnext.Enabled = success; - searchprev.Enabled = success; - } - - private void searchnext_Click(object sender, EventArgs e) - { - ActiveTab.FindNext(GetQuickSearchOptions()); - } - - private void searchprev_Click(object sender, EventArgs e) - { - ActiveTab.FindPrevious(GetQuickSearchOptions()); - } - - //mxd. This flashes the status icon - private void statusflasher_Tick(object sender, EventArgs e) - { - statusflashicon = !statusflashicon; - UpdateStatusIcon(); - statusflashcount--; - if(statusflashcount == 0) statusflasher.Stop(); - } - - //mxd. This resets the status to ready - private void statusresetter_Tick(object sender, EventArgs e) - { - DisplayStatus(ScriptStatusType.Ready, null); - } - - #endregion - - } -} + internal partial class ScriptEditorPanel : UserControl + { + #region ================== Constants + + #endregion + + #region ================== Variables + + private List scriptconfigs; + private List compilererrors; + + // Find/Replace + private ScriptFindReplaceForm findreplaceform; + private FindReplaceOptions findoptions; + + // Quick search bar settings (mxd) + private static bool matchwholeword; + private static bool matchcase; + + //mxd. Status update + private ScriptStatusInfo status; + private int statusflashcount; + private bool statusflashicon; + + #endregion + + #region ================== Properties + + public ScriptDocumentTab ActiveTab { get { return (tabs.SelectedTab as ScriptDocumentTab); } } + + #endregion + + #region ================== Constructor + + // Constructor + public ScriptEditorPanel() + { + InitializeComponent(); + } + + // This initializes the control + public void Initialize() + { + // Make list of script configs + scriptconfigs = new List(General.ScriptConfigs.Values); + scriptconfigs.Add(new ScriptConfiguration()); + scriptconfigs.Sort(); + + // Fill the list of new document types + foreach (ScriptConfiguration cfg in scriptconfigs) + { + // Button for new script menu + ToolStripMenuItem item = new ToolStripMenuItem(cfg.Description); + //item.Image = buttonnew.Image; + item.Tag = cfg; + item.Click += buttonnew_Click; + buttonnew.DropDownItems.Add(item); + + // Button for script type menu + item = new ToolStripMenuItem(cfg.Description); + //item.Image = buttonnew.Image; + item.Tag = cfg; + item.Click += buttonscriptconfig_Click; + buttonscriptconfig.DropDownItems.Add(item); + } + + // Setup supported extensions + string filterall = ""; + string filterseperate = ""; + foreach (ScriptConfiguration cfg in scriptconfigs) + { + if (cfg.Extensions.Length > 0) + { + string exts = "*." + string.Join(";*.", cfg.Extensions); + if (filterseperate.Length > 0) filterseperate += "|"; + filterseperate += cfg.Description + "|" + exts; + if (filterall.Length > 0) filterall += ";"; + filterall += exts; + } + } + openfile.Filter = "Script files|" + filterall + "|" + filterseperate + "|All files|*.*"; + + // Load the script lumps + foreach (MapLumpInfo maplumpinfo in General.Map.Config.MapLumps.Values) + { + // Is this a script lump? + if (maplumpinfo.ScriptBuild) //mxd + { + // Load this! + ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler]); + t.OnTextChanged += tabpage_OnLumpTextChanged; //mxd + t.Scintilla.UpdateUI += scintilla_OnUpdateUI; //mxd + tabs.TabPages.Add(t); + } + else if (maplumpinfo.Script != null) + { + // Load this! + ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, maplumpinfo.Script); + t.OnTextChanged += tabpage_OnLumpTextChanged; //mxd + t.Scintilla.UpdateUI += scintilla_OnUpdateUI; //mxd + tabs.TabPages.Add(t); + } + } + + // Load the files that were previously opened for this map + foreach (String filename in General.Map.Options.ScriptFiles) + { + // Does this file exist? + if (File.Exists(filename)) + { + // Load this! + OpenFile(filename); + } + } + + //mxd. Select "Scripts" tab, because that's what user will want 99% of time + int scriptsindex = GetTabPageIndex("SCRIPTS"); + tabs.SelectedIndex = (scriptsindex == -1 ? 0 : scriptsindex); + + //mxd. Apply quick search settings + searchmatchcase.Checked = matchcase; + searchwholeword.Checked = matchwholeword; + searchbox_TextChanged(this, EventArgs.Empty); + + // If the map has remembered any compile errors, then show them + ShowErrors(General.Map.Errors); + + // Done + UpdateToolbar(true); + } + + // This applies user preferences + public void ApplySettings() + { + errorlist.Columns[0].Width = General.Settings.ReadSetting("scriptspanel.errorscolumn0width", errorlist.Columns[0].Width); + errorlist.Columns[1].Width = General.Settings.ReadSetting("scriptspanel.errorscolumn1width", errorlist.Columns[1].Width); + errorlist.Columns[2].Width = General.Settings.ReadSetting("scriptspanel.errorscolumn2width", errorlist.Columns[2].Width); + buttonwhitespace.Checked = General.Settings.ReadSetting("scriptspanel.showwhitespace", false); //mxd + buttonwordwrap.Checked = General.Settings.ReadSetting("scriptspanel.wraplonglines", false); //mxd + ApplyTabSettings(); //mxd + } + + // This saves user preferences + public void SaveSettings() + { + General.Settings.WriteSetting("scriptspanel.errorscolumn0width", errorlist.Columns[0].Width); + General.Settings.WriteSetting("scriptspanel.errorscolumn1width", errorlist.Columns[1].Width); + General.Settings.WriteSetting("scriptspanel.showwhitespace", buttonwhitespace.Checked); //mxd + General.Settings.WriteSetting("scriptspanel.wraplonglines", buttonwordwrap.Checked); //mxd + } + + //mxd + private void ApplyTabSettings() + { + foreach (var tp in tabs.TabPages) + { + ScriptDocumentTab scripttab = (tp as ScriptDocumentTab); + if (scripttab != null) + { + scripttab.WrapLongLines = buttonwordwrap.Checked; + scripttab.ShowWhitespace = buttonwhitespace.Checked; + } + } + } + + #endregion + + #region ================== Methods + + // Find Next + public void FindNext(FindReplaceOptions options) + { + // Save the options + findoptions = options; + FindNext(); + } + + // Find Next with saved options + public void FindNext() + { + if (!string.IsNullOrEmpty(findoptions.FindText) && (ActiveTab != null)) + { + if (!ActiveTab.FindNext(findoptions)) + DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\"."); + } + else + { + General.MessageBeep(MessageBeepType.Default); + } + } + + // Find Previous + public void FindPrevious(FindReplaceOptions options) + { + // Save the options + findoptions = options; + FindPrevious(); + } + + // Find Previous with saved options (mxd) + public void FindPrevious() + { + if (!string.IsNullOrEmpty(findoptions.FindText) && (ActiveTab != null)) + { + if (!ActiveTab.FindPrevious(findoptions)) + DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\"."); + } + else + { + General.MessageBeep(MessageBeepType.Default); + } + } + + // Replace if possible + public void Replace(FindReplaceOptions options) + { + if (!string.IsNullOrEmpty(findoptions.FindText) && (options.ReplaceWith != null) && (ActiveTab != null)) + { + if (string.Compare(ActiveTab.SelectedText, options.FindText, !options.CaseSensitive) == 0) + { + // Replace selection + ActiveTab.ReplaceSelection(options.ReplaceWith); + } + } + else + { + General.MessageBeep(MessageBeepType.Default); + } + } + + // Replace all + public void ReplaceAll(FindReplaceOptions options) + { + int replacements = 0; + findoptions = options; + if (!string.IsNullOrEmpty(findoptions.FindText) && (options.ReplaceWith != null) && (ActiveTab != null)) + { + int firstfindpos = -1; + int lastpos = -1; + bool firstreplace = true; + bool wrappedaround = false; + int selectionstart = Math.Min(ActiveTab.SelectionStart, ActiveTab.SelectionEnd); + + // Continue finding and replacing until nothing more found + while (ActiveTab.FindNext(findoptions)) + { + int curpos = Math.Min(ActiveTab.SelectionStart, ActiveTab.SelectionEnd); + if (curpos <= lastpos) + wrappedaround = true; + + if (firstreplace) + { + // Remember where we started replacing + firstfindpos = curpos; + } + else if (wrappedaround) + { + // Make sure we don't go past our start point, or we could be in an endless loop + if (curpos >= firstfindpos) + break; + } + + Replace(findoptions); + replacements++; + firstreplace = false; + + lastpos = curpos; + } + + // Restore selection + ActiveTab.SelectionStart = selectionstart; + ActiveTab.SelectionEnd = selectionstart; + + // Show result + if (replacements == 0) + DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\"."); + else + DisplayStatus(ScriptStatusType.Info, "Replaced " + replacements + " occurences of \"" + findoptions.FindText + "\" with \"" + findoptions.ReplaceWith + "\"."); + } + else + { + General.MessageBeep(MessageBeepType.Default); + } + } + + // This closed the Find & Replace subwindow + public void CloseFindReplace(bool closing) + { + if (findreplaceform != null) + { + if (!closing) findreplaceform.Close(); + findreplaceform = null; + } + } + + // This opens the Find & Replace subwindow + public void OpenFindAndReplace() + { + if (findreplaceform == null) + findreplaceform = new ScriptFindReplaceForm(); + + try + { + if (findreplaceform.Visible) + findreplaceform.Focus(); + else + findreplaceform.Show(this.ParentForm); + + if (ActiveTab.SelectionEnd != ActiveTab.SelectionStart) + findreplaceform.SetFindText(ActiveTab.SelectedText); + } + catch (Exception) + { + // If we can't pop up the find/replace form right now, thats just too bad. + } + } + + // This refreshes all settings + public void RefreshSettings() + { + foreach (ScriptDocumentTab t in tabs.TabPages) + { + t.RefreshSettings(); + } + } + + // This clears all error marks and hides the errors list + public void ClearErrors() + { + // Hide list + splitter.Panel2Collapsed = true; + errorlist.Items.Clear(); + + // Clear marks + foreach (ScriptDocumentTab t in tabs.TabPages) + { + t.ClearMarks(); + } + } + + // This shows the errors panel with the given errors + // Also updates the scripts with markers for the given errors + public void ShowErrors(IEnumerable errors) + { + // Copy list + if (errors != null) + compilererrors = new List(errors); + else + compilererrors = new List(); + + // Fill list + errorlist.BeginUpdate(); + errorlist.Items.Clear(); + int listindex = 1; + foreach (CompilerError e in compilererrors) + { + ListViewItem ei = new ListViewItem(listindex.ToString()); + ei.ImageIndex = 0; + ei.SubItems.Add(e.description); + string filename = (e.filename.StartsWith("?") ? e.filename.Replace("?", "") : Path.GetFileName(e.filename)); //mxd + string linenumber = (e.linenumber != CompilerError.NO_LINE_NUMBER ? " (line " + (e.linenumber + 1) + ")" : String.Empty); //mxd + ei.SubItems.Add(filename + linenumber); + ei.Tag = e; + errorlist.Items.Add(ei); + listindex++; + } + errorlist.EndUpdate(); + + // Show marks on scripts + foreach (ScriptDocumentTab t in tabs.TabPages) + { + t.MarkScriptErrors(compilererrors); + } + + // Show/hide panel + splitter.Panel2Collapsed = (errorlist.Items.Count == 0); + } + + // This writes all explicitly opened files to the configuration + public void WriteOpenFilesToConfiguration() + { + List files = new List(); + foreach (ScriptDocumentTab t in tabs.TabPages) + { + if (t.ExplicitSave) files.Add(t.Filename); + } + General.Map.Options.ScriptFiles = files; + } + + // This asks to save files and returns the result + public bool AskSaveAll() + { + foreach (ScriptDocumentTab t in tabs.TabPages) + { + if (t.ExplicitSave) + { + if (!CloseScript(t, true)) return false; + } + } + + return true; + } + + // This closes a script and returns true when closed + private bool CloseScript(ScriptDocumentTab t, bool saveonly) + { + if (t.IsChanged) + { + // Ask to save + DialogResult result = MessageBox.Show(this.ParentForm, "Do you want to save changes to " + t.Title + "?", "Close File", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); + switch (result) + { + case DialogResult.Yes: + if (!SaveScript(t)) return false; + break; + case DialogResult.Cancel: + return false; + } + } + + if (!saveonly) + { + //mxd. Select tab to the left of the one we are going to close + if (t == tabs.SelectedTab && tabs.SelectedIndex > 0) + tabs.SelectedIndex--; + + // Close file + tabs.TabPages.Remove(t); + t.Dispose(); + } + return true; + } + + // This returns true when any of the implicit-save scripts are changed + public bool CheckImplicitChanges() + { + foreach (ScriptDocumentTab t in tabs.TabPages) + { + if (!t.ExplicitSave && t.IsChanged) return true; + } + return false; + } + + // This forces the focus to the script editor + public void ForceFocus() + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + tabs.Focus(); + if (t != null) t.Focus(); + } + + // This does an implicit save on all documents that use implicit saving + // Call this to save the lumps before disposing the panel! + public void ImplicitSave() + { + // Save all scripts + foreach (ScriptDocumentTab t in tabs.TabPages) + { + if (!t.ExplicitSave) t.Save(); + } + + UpdateToolbar(false); + } + + // This updates the toolbar for the current status + private void UpdateToolbar(bool focuseditor) + { + int numscriptsopen = tabs.TabPages.Count; + int explicitsavescripts = 0; + ScriptDocumentTab t = null; + + // Any explicit save scripts? + foreach (ScriptDocumentTab dt in tabs.TabPages) + if (dt.ExplicitSave) explicitsavescripts++; + + // Get current script, if any are open + if (numscriptsopen > 0) + t = (tabs.SelectedTab as ScriptDocumentTab); + + // Enable/disable buttons + buttonsave.Enabled = (t != null && t.ExplicitSave && t.IsChanged); + buttonsaveall.Enabled = (explicitsavescripts > 0); + buttoncompile.Enabled = (t != null && t.Config.Compiler != null); + buttonsearch.Enabled = (t != null); //mxd + buttonkeywordhelp.Enabled = (t != null && !string.IsNullOrEmpty(t.Config.KeywordHelp)); + buttonscriptconfig.Enabled = (t != null && t.IsReconfigurable); + buttonundo.Enabled = (t != null && t.Scintilla.CanUndo); + buttonredo.Enabled = (t != null && t.Scintilla.CanRedo); + buttoncopy.Enabled = (t != null && t.Scintilla.SelectionStart < t.Scintilla.SelectionEnd); + buttoncut.Enabled = (t != null && t.Scintilla.SelectionStart < t.Scintilla.SelectionEnd); + buttonpaste.Enabled = (t != null && t.Scintilla.CanPaste); + buttonclose.Enabled = (t != null && t.IsClosable); + buttonsnippets.DropDownItems.Clear(); //mxd + buttonsnippets.Enabled = (t != null && t.Config.Snippets.Count > 0); //mxd + buttonindent.Enabled = (t != null); //mxd + buttonunindent.Enabled = (t != null && t.Scintilla.Lines[t.Scintilla.CurrentLine].Indentation > 0); //mxd + buttonwhitespace.Enabled = (t != null); //mxd + buttonwordwrap.Enabled = (t != null); //mxd + + if (t != null) + { + // Check the according script config in menu + foreach (ToolStripMenuItem item in buttonscriptconfig.DropDownItems) + { + ScriptConfiguration config = (item.Tag as ScriptConfiguration); + item.Checked = (config == t.Config); + } + + //mxd. Add snippets + if (t.Config != null && t.Config.Snippets.Count > 0) + { + if (t.Config.Snippets.Count > 0) + foreach (string snippetname in t.Config.Snippets) buttonsnippets.DropDownItems.Add(snippetname).Click += OnInsertSnippetClick; + } + + // Focus to script editor + if (focuseditor) ForceFocus(); + } + + //mxd. Update script type description + scripttype.Text = ((t != null && t.Config != null) ? t.Config.Description : "Plain Text"); + } + + //mxd + private int GetTabPageIndex(string title) + { + if (tabs.TabPages.Count == 0) return -1; + + for (int i = 0; i < tabs.TabPages.Count; i++) + { + if (tabs.TabPages[i].Text == title) return i; + } + + return -1; + } + + // This opens the given file, returns null when failed + public ScriptFileDocumentTab OpenFile(string filename) + { + ScriptConfiguration foundconfig = new ScriptConfiguration(); + + // Find the most suitable script configuration to use + foreach (ScriptConfiguration cfg in scriptconfigs) + { + foreach (string ext in cfg.Extensions) + { + // Use this configuration if the extension matches + if (filename.EndsWith("." + ext, true, CultureInfo.InvariantCulture)) + { + foundconfig = cfg; + break; + } + } + } + + // Create new document + ScriptFileDocumentTab t = new ScriptFileDocumentTab(this, foundconfig); + if (t.Open(filename)) + { + //mxd + ScriptType st = t.VerifyScriptType(); + if (st != ScriptType.UNKNOWN) + { + foreach (ScriptConfiguration cfg in scriptconfigs) + { + if (cfg.ScriptType == st) + { + t.ChangeScriptConfig(cfg); + break; + } + } + } + + // Mark any errors this script may have + if (compilererrors != null) t.MarkScriptErrors(compilererrors); + + // Add to tabs + tabs.TabPages.Add(t); + tabs.SelectedTab = t; + + // Done + t.OnTextChanged += tabpage_OnTextChanged; //mxd + t.Scintilla.UpdateUI += scintilla_OnUpdateUI; + UpdateToolbar(true); + return t; + } + + // Failed + return null; + } + + // This saves the current open script + public void ExplicitSaveCurrentTab() + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + if ((t != null)) + { + if (t.ExplicitSave) + buttonsave_Click(this, EventArgs.Empty); + else if (t.Config.Compiler != null) //mxd + buttoncompile_Click(this, EventArgs.Empty); + else + General.MessageBeep(MessageBeepType.Default); + } + else + { + General.MessageBeep(MessageBeepType.Default); + } + } + + // This opens a script + public void OpenBrowseScript() + { + buttonopen_Click(this, EventArgs.Empty); + } + + //mxd. This launches keyword help website + public bool LaunchKeywordHelp() + { + // Get script + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + return (t != null && t.LaunchKeywordHelp()); + } + + //mxd. This changes status text + private void DisplayStatus(ScriptStatusType type, string message) { DisplayStatus(new ScriptStatusInfo(type, message)); } + private void DisplayStatus(ScriptStatusInfo newstatus) + { + // Stop timers + if (!newstatus.displayed) + { + statusresetter.Stop(); + statusflasher.Stop(); + statusflashicon = false; + } + + // Determine what to do specifically for this status type + switch (newstatus.type) + { + // Shows information without flashing the icon. + case ScriptStatusType.Ready: + case ScriptStatusType.Info: + if (!newstatus.displayed) + { + statusresetter.Interval = MainForm.INFO_RESET_DELAY; + statusresetter.Start(); + } + break; + + // Shows a warning, makes a warning sound and flashes a warning icon. + case ScriptStatusType.Warning: + if (!newstatus.displayed) + { + General.MessageBeep(MessageBeepType.Warning); + statusflasher.Interval = MainForm.WARNING_FLASH_INTERVAL; + statusflashcount = MainForm.WARNING_FLASH_COUNT; + statusflasher.Start(); + statusresetter.Interval = MainForm.WARNING_RESET_DELAY; + statusresetter.Start(); + } + break; + } + + // Update status description + status = newstatus; + status.displayed = true; + statuslabel.Text = status.message; + + // Update icon as well + UpdateStatusIcon(); + + // Refresh + statusbar.Invalidate(); + this.Update(); + } + + // This updates the status icon + private void UpdateStatusIcon() + { + int statusflashindex = (statusflashicon ? 1 : 0); + + // Status type + switch (status.type) + { + case ScriptStatusType.Ready: + case ScriptStatusType.Info: + statuslabel.Image = General.MainWindow.STATUS_IMAGES[statusflashindex, 0]; + break; + + case ScriptStatusType.Busy: + statuslabel.Image = General.MainWindow.STATUS_IMAGES[statusflashindex, 2]; + break; + + case ScriptStatusType.Warning: + statuslabel.Image = General.MainWindow.STATUS_IMAGES[statusflashindex, 3]; + break; + + default: + throw new NotImplementedException("Unsupported Script Status Type!"); + } + } + + #endregion + + #region ================== Events + + // Called when the window that contains this panel closes + public void OnClose() + { + //mxd. Store quick search settings + matchcase = searchmatchcase.Checked; + matchwholeword = searchwholeword.Checked; + + //mxd. Stop status timers + statusresetter.Stop(); + statusflasher.Stop(); + + // Close the sub windows now + if (findreplaceform != null) findreplaceform.Dispose(); + } + + // Keyword help requested + private void buttonkeywordhelp_Click(object sender, EventArgs e) + { + LaunchKeywordHelp(); + } + + // When the user changes the script configuration + private void buttonscriptconfig_Click(object sender, EventArgs e) + { + // Get the tab and new script config + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + ScriptConfiguration scriptconfig = ((sender as ToolStripMenuItem).Tag as ScriptConfiguration); + + // Change script config + t.ChangeScriptConfig(scriptconfig); + + //mxd. Update script type description + scripttype.Text = scriptconfig.Description; + + // Done + UpdateToolbar(true); + } + + // When new script is clicked + private void buttonnew_Click(object sender, EventArgs e) + { + // Get the script config to use + ScriptConfiguration scriptconfig = ((sender as ToolStripMenuItem).Tag as ScriptConfiguration); + + // Create new document + ScriptFileDocumentTab t = new ScriptFileDocumentTab(this, scriptconfig); + tabs.TabPages.Add(t); + tabs.SelectedTab = t; + + // Done + UpdateToolbar(true); + } + + // Open script clicked + private void buttonopen_Click(object sender, EventArgs e) + { + // Show open file dialog + if (openfile.ShowDialog(this.ParentForm) == DialogResult.OK) + { + //mxd. Gather already opened file names + List openedfiles = new List(); + foreach (var page in tabs.TabPages) + { + var scriptpage = page as ScriptFileDocumentTab; + if (scriptpage != null) openedfiles.Add(scriptpage.Filename); + } + + //mxd. Add new tabs + foreach (string name in openfile.FileNames) + { + if (!openedfiles.Contains(name)) OpenFile(name); + } + + // Select the last new item + foreach (var page in tabs.TabPages) + { + var scriptpage = page as ScriptFileDocumentTab; + if (scriptpage != null && scriptpage.Filename == openfile.FileNames[openfile.FileNames.Length - 1]) + { + tabs.SelectedTab = scriptpage; + break; + } + } + } + } + + // Save script clicked + private void buttonsave_Click(object sender, EventArgs e) + { + // Save the current script + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + SaveScript(t); + UpdateToolbar(true); + } + + // Save All clicked + private void buttonsaveall_Click(object sender, EventArgs e) + { + // Save all scripts + foreach (ScriptDocumentTab t in tabs.TabPages) + { + // Use explicit save for this script? + if (t.ExplicitSave) + { + if (!SaveScript(t)) break; + } + } + + UpdateToolbar(true); + } + + // This is called by Save and Save All to save a script + // Returns false when cancelled by the user + private bool SaveScript(ScriptDocumentTab t) + { + // Do we have to do a save as? + if (t.IsSaveAsRequired) + { + // Setup save dialog + string scriptfilter = t.Config.Description + "|*." + string.Join(";*.", t.Config.Extensions); + savefile.Filter = scriptfilter + "|All files|*.*"; + if (savefile.ShowDialog(this.ParentForm) == DialogResult.OK) + { + // Save to new filename + t.SaveAs(savefile.FileName); + return true; + } + + // Cancelled + return false; + } + + // Save to same filename + t.Save(); + return true; + } + + // A tab is selected + private void tabs_Selecting(object sender, TabControlCancelEventArgs e) + { + UpdateToolbar(true); + } + + // This closes the current file + private void buttonclose_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + CloseScript(t, false); + UpdateToolbar(true); + } + + // Compile Script clicked + private void buttoncompile_Click(object sender, EventArgs e) + { + // First save all implicit scripts to the temporary wad file + ImplicitSave(); + + // Get script + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + + // Check if it must be saved as a new file + if (t.ExplicitSave && t.IsSaveAsRequired) + { + // Save the script first! + if (MessageBox.Show(this.ParentForm, "You must save your script before you can compile it. Do you want to save your script now?", "Compile Script", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + { + if (!SaveScript(t)) return; + } + else + { + return; + } + } + else if (t.ExplicitSave && t.IsChanged) + { + // We can only compile when the script is saved + if (!SaveScript(t)) return; + } + + // Compile now + DisplayStatus(ScriptStatusType.Busy, "Compiling script \"" + t.Title + "\"..."); + Cursor.Current = Cursors.WaitCursor; + t.Compile(); + + // Show warning + if ((compilererrors != null) && (compilererrors.Count > 0)) + DisplayStatus(ScriptStatusType.Warning, compilererrors.Count + " errors while compiling \"" + t.Title + "\"!"); + else + DisplayStatus(ScriptStatusType.Info, "Script \"" + t.Title + "\" compiled without errors."); + + Cursor.Current = Cursors.Default; + UpdateToolbar(true); + } + + // Undo clicked + private void buttonundo_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.Undo(); + UpdateToolbar(true); + } + + // Redo clicked + private void buttonredo_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.Redo(); + UpdateToolbar(true); + } + + // Cut clicked + private void buttoncut_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.Cut(); + UpdateToolbar(true); + } + + // Copy clicked + private void buttoncopy_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.Copy(); + UpdateToolbar(true); + } + + // Paste clicked + private void buttonpaste_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.Paste(); + UpdateToolbar(true); + } + + //mxd + private void buttonunindent_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.IndentSelection(false); + } + + //mxd + private void buttonindent_Click(object sender, EventArgs e) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.IndentSelection(true); + } + + //mxd + private void buttonwhitespace_Click(object sender, EventArgs e) + { + ApplyTabSettings(); + } + + //mxd + private void buttonwordwrap_Click(object sender, EventArgs e) + { + ApplyTabSettings(); + } + + //mxd. Search clicked + private void buttonsearch_Click(object sender, EventArgs e) + { + OpenFindAndReplace(); + } + + //mxd + private void OnInsertSnippetClick(object sender, EventArgs eventArgs) + { + ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab); + t.InsertSnippet(((ToolStripItem)sender).Text); + } + + // Mouse released on tabs + private void tabs_MouseUp(object sender, MouseEventArgs e) + { + ForceFocus(); + } + + //mxd. Text in ScriptFileDocumentTab was changed + private void tabpage_OnTextChanged(object sender, EventArgs eventArgs) + { + if (tabs.SelectedTab != null) + { + ScriptDocumentTab curtab = tabs.SelectedTab as ScriptDocumentTab; + if (curtab != null) + { + buttonsave.Enabled = (curtab.ExplicitSave && curtab.IsChanged); + buttonundo.Enabled = curtab.Scintilla.CanUndo; + buttonredo.Enabled = curtab.Scintilla.CanRedo; + } + } + } + + //mxd. Text in ScriptLumpDocumentTab was changed + private void tabpage_OnLumpTextChanged(object sender, EventArgs e) + { + if (tabs.SelectedTab != null) + { + ScriptDocumentTab curtab = tabs.SelectedTab as ScriptDocumentTab; + if (curtab != null) + { + buttonundo.Enabled = curtab.Scintilla.CanUndo; + buttonredo.Enabled = curtab.Scintilla.CanRedo; + } + } + } + + //mxd + private void scintilla_OnUpdateUI(object sender, UpdateUIEventArgs e) + { + Scintilla s = sender as Scintilla; + if (s != null) + { + // Update caret position info [line] : [caret pos start] OR [caret pos start x selection length] ([total lines]) + positionlabel.Text = (s.CurrentLine + 1) + " : " + + (s.SelectionStart + 1 - s.Lines[s.LineFromPosition(s.SelectionStart)].Position) + + (s.SelectionStart != s.SelectionEnd ? "x" + (s.SelectionEnd - s.SelectionStart) : "") + + " (" + s.Lines.Count + ")"; + + // Update copy-paste buttons + buttoncut.Enabled = (s.SelectionEnd > s.SelectionStart); + buttoncopy.Enabled = (s.SelectionEnd > s.SelectionStart); + buttonpaste.Enabled = s.CanPaste; + buttonunindent.Enabled = s.Lines[s.CurrentLine].Indentation > 0; + } + } + + // User double-clicks and error in the list + private void errorlist_ItemActivate(object sender, EventArgs e) + { + // Anything selection? + if (errorlist.SelectedItems.Count > 0) + { + // Get the compiler error + CompilerError err = (CompilerError)errorlist.SelectedItems[0].Tag; + + // Show the tab with the script that matches + bool foundscript = false; + foreach (ScriptDocumentTab t in tabs.TabPages) + { + if (t.VerifyErrorForScript(err)) + { + tabs.SelectedTab = t; + t.MoveToLine(err.linenumber); + foundscript = true; + break; + } + } + + // If we don't have the script opened, see if we can find the file and open the script + if (!foundscript && File.Exists(err.filename)) + { + ScriptDocumentTab t = OpenFile(err.filename); + if (t != null) t.MoveToLine(err.linenumber); + } + + ForceFocus(); + } + } + + #endregion + + #region ================== Quick Search (mxd) + + private FindReplaceOptions GetQuickSearchOptions() + { + return new FindReplaceOptions + { + CaseSensitive = searchmatchcase.Checked, + WholeWord = searchwholeword.Checked, + FindText = searchbox.Text + }; + } + + private void searchbox_TextChanged(object sender, EventArgs e) + { + bool success = (searchbox.Text.Length > 0 && ActiveTab.FindNext(GetQuickSearchOptions(), true)); + searchbox.BackColor = ((success || searchbox.Text.Length == 0) ? SystemColors.Window : Color.MistyRose); + searchnext.Enabled = success; + searchprev.Enabled = success; + } + + private void searchnext_Click(object sender, EventArgs e) + { + ActiveTab.FindNext(GetQuickSearchOptions()); + } + + private void searchprev_Click(object sender, EventArgs e) + { + ActiveTab.FindPrevious(GetQuickSearchOptions()); + } + + //mxd. This flashes the status icon + private void statusflasher_Tick(object sender, EventArgs e) + { + statusflashicon = !statusflashicon; + UpdateStatusIcon(); + statusflashcount--; + if (statusflashcount == 0) statusflasher.Stop(); + } + + //mxd. This resets the status to ready + private void statusresetter_Tick(object sender, EventArgs e) + { + DisplayStatus(ScriptStatusType.Ready, null); + } + + #endregion + + } +} \ No newline at end of file diff --git a/Source/Core/Controls/ScriptFileDocumentTab.cs b/Source/Core/Controls/ScriptFileDocumentTab.cs index 96f6f5e..ed46d29 100644 --- a/Source/Core/Controls/ScriptFileDocumentTab.cs +++ b/Source/Core/Controls/ScriptFileDocumentTab.cs @@ -61,15 +61,15 @@ namespace CodeImp.DoomBuilder.Controls if(config.Extensions.Length > 0) ext = "." + config.Extensions[0]; SetTitle("Untitled" + ext); editor.ClearUndoRedo(); - navigator.Enabled = (config.ScriptType != ScriptType.UNKNOWN); //mxd - } - - #endregion - - #region ================== Methods - - // This compiles the script file - public override void Compile() + editor.FunctionBar.Enabled = (config.ScriptType != ScriptType.UNKNOWN); //mxd + } + + #endregion + + #region ================== Methods + + // This compiles the script file + public override void Compile() { //mxd. ACS requires special handling... if(config.ScriptType == ScriptType.ACS) @@ -287,11 +287,11 @@ namespace CodeImp.DoomBuilder.Controls General.ShowErrorMessage("Unable to open file \"" + filepathname + "\" for writing. Make sure the path exists and that the file is not in use by another application.", MessageBoxButtons.OK); return false; } - - // Done - editor.IsChanged = false; - UpdateTitle(); //mxd - return true; + + // Done + editor.SetSavePoint(); //mxd + UpdateTitle(); //mxd + return true; } // This saves the document to a new file @@ -317,10 +317,11 @@ namespace CodeImp.DoomBuilder.Controls { try { - // Read the file - editor.SetText(File.ReadAllBytes(filepathname)); - } - catch(Exception e) + // Read the file + editor.Text = File.ReadAllText(filepathname); //mxd + } + + catch (Exception e) { // Failed General.ErrorLogger.Add(ErrorType.Error, "Cannot open file '" + filepathname + "' for reading. Make sure the path exists and that the file is not in use by another application."); @@ -332,7 +333,6 @@ namespace CodeImp.DoomBuilder.Controls // Setup this.filepathname = filepathname; editor.ClearUndoRedo(); - editor.IsChanged = false; //mxd. Not changed yet SetTitle(Path.GetFileName(filepathname)); UpdateNavigator(); //mxd diff --git a/Source/Core/Controls/ScriptLumpDocumentTab.cs b/Source/Core/Controls/ScriptLumpDocumentTab.cs index 404db73..45ed170 100644 --- a/Source/Core/Controls/ScriptLumpDocumentTab.cs +++ b/Source/Core/Controls/ScriptLumpDocumentTab.cs @@ -17,9 +17,9 @@ #region ================== Namespaces using System.Collections.Generic; -using CodeImp.DoomBuilder.Config; using System.IO; using CodeImp.DoomBuilder.Compilers; +using CodeImp.DoomBuilder.Config; #endregion @@ -72,13 +72,12 @@ namespace CodeImp.DoomBuilder.Controls MemoryStream stream = General.Map.GetLumpData(this.lumpname); if(stream != null) { - editor.SetText(stream.ToArray()); - editor.ClearUndoRedo(); - UpdateNavigator(); //mxd + editor.SetText(stream.ToArray()); //mxd + editor.ClearUndoRedo(); + UpdateNavigator(); //mxd } // Set title - IsChanged = false; //mxd. Not changed yet SetTitle(ismapheader ? General.Map.Options.CurrentName : this.lumpname.ToUpper()); } @@ -116,9 +115,9 @@ namespace CodeImp.DoomBuilder.Controls // Store the lump data MemoryStream stream = new MemoryStream(editor.GetText()); General.Map.SetLumpData(lumpname, stream); - editor.IsChanged = false; - UpdateTitle(); //mxd - return true; + editor.SetSavePoint(); //mxd + UpdateTitle(); //mxd + return true; } // This checks if a script error applies to this script diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index 8e95d87..5dd1bbd 100644 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -547,8 +547,8 @@ namespace CodeImp.DoomBuilder.Data // This returns a preview image public virtual Image GetPreview() { - lock(this) - { + //lock(this) + //{ // Preview ready? if(previewstate == ImageLoadState.Ready) { @@ -565,7 +565,7 @@ namespace CodeImp.DoomBuilder.Data // Return loading bitmap return Properties.Resources.Hourglass; - } + //} } //mxd. This greatly speeds up Dictionary lookups diff --git a/Source/Core/GZBuilder/GZDoom/AcsParserSE.cs b/Source/Core/GZBuilder/GZDoom/AcsParserSE.cs index 4f0ceb4..6fbe305 100644 --- a/Source/Core/GZBuilder/GZDoom/AcsParserSE.cs +++ b/Source/Core/GZBuilder/GZDoom/AcsParserSE.cs @@ -166,10 +166,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom case "function": { SkipWhitespace(true); - int startpos = (int)stream.Position; string funcname = ReadToken(); //read return type SkipWhitespace(true); - funcname += " " + ReadToken(); //read function name + int startpos = (int)stream.Position; + funcname += " " + ReadToken(); //read function name // Try to parse argument names List> args = ParseArgs(); diff --git a/Source/Core/GZBuilder/Windows/ExceptionDialog.cs b/Source/Core/GZBuilder/Windows/ExceptionDialog.cs index 121fef2..7a45aa8 100644 --- a/Source/Core/GZBuilder/Windows/ExceptionDialog.cs +++ b/Source/Core/GZBuilder/Windows/ExceptionDialog.cs @@ -156,10 +156,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows private static string GetExceptionDescription(Exception ex) { - //add to error logger - General.ErrorLogger.Add(ErrorType.Error, "**** " + ex.Source + ": " + ex.Message + " ****"); + // Add to error logger + General.WriteLogLine("***********************************************************"); + General.ErrorLogger.Add(ErrorType.Error, ex.Source + ": " + ex.Message); + General.WriteLogLine("***********************************************************"); - string message = "********EXCEPTION DETAILS********" + string message = "********EXCEPTION DETAILS********" + Environment.NewLine + ex.Source + ": " + ex.Message + Environment.NewLine + ex.StackTrace; if(File.Exists(General.LogFile)) diff --git a/Source/Core/General/ErrorLogger.cs b/Source/Core/General/ErrorLogger.cs index f2a9794..18d51ae 100644 --- a/Source/Core/General/ErrorLogger.cs +++ b/Source/Core/General/ErrorLogger.cs @@ -30,16 +30,17 @@ namespace CodeImp.DoomBuilder #region ================== Variables - private List errors; + private readonly List errors; private volatile bool changed; private volatile bool erroradded; private volatile bool warningadded; - - #endregion + private object threadlock = new object(); //mxd - #region ================== Properties - - public bool HasErrors { get { return (errors.Count > 0); } } + #endregion + + #region ================== Properties + + public bool HasErrors { get { return (errors.Count > 0); } } public int ErrorsCount { get { return errors.Count; } } //mxd public bool HasChanged { get { return changed; } set { changed = value; } } public bool IsErrorAdded { get { return erroradded; } set { erroradded = value; } } @@ -62,8 +63,8 @@ namespace CodeImp.DoomBuilder // This clears the errors public void Clear() { - lock(this) - { + lock (threadlock) + { changed = false; erroradded = false; warningadded = false; @@ -78,9 +79,9 @@ namespace CodeImp.DoomBuilder public void Add(ErrorType type, string message) { string prefix = ""; - - lock(this) - { + + lock (threadlock) + { //mxd. Don't add duplicate messages if(errors.Count == 0 || message != errors[errors.Count - 1].message || type != errors[errors.Count - 1].type) { @@ -115,17 +116,28 @@ namespace CodeImp.DoomBuilder } } } - - // This returns the list of errors - internal List GetErrors() + + // This returns the list of errors + /*internal List GetErrors() { lock(this) { List copylist = new List(errors); return copylist; } - } - - #endregion - } + }*/ + + //mxd. This returns the list of errors starting at given index + internal IEnumerable GetErrors(int startindex) + { + if (startindex >= errors.Count) return new List(); + + ErrorItem[] result = new ErrorItem[errors.Count - startindex]; + errors.CopyTo(startindex, result, 0, result.Length); + + return result; + } + + #endregion + } } diff --git a/Source/Core/Properties/Resources.Designer.cs b/Source/Core/Properties/Resources.Designer.cs index 8bda0f3..2f8a322 100644 --- a/Source/Core/Properties/Resources.Designer.cs +++ b/Source/Core/Properties/Resources.Designer.cs @@ -1059,24 +1059,26 @@ namespace CodeImp.DoomBuilder.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. /// - internal static byte[] ScriptConstant { + internal static System.Drawing.Bitmap ScriptConstant + { get { object obj = ResourceManager.GetObject("ScriptConstant", resourceCulture); - return ((byte[])(obj)); + return ((System.Drawing.Bitmap)(obj)); } } - + /// /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. /// - internal static byte[] ScriptError { + internal static System.Drawing.Bitmap ScriptError + { get { object obj = ResourceManager.GetObject("ScriptError", resourceCulture); - return ((byte[])(obj)); + return ((System.Drawing.Bitmap)(obj)); } } @@ -1089,14 +1091,15 @@ namespace CodeImp.DoomBuilder.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. /// - internal static byte[] ScriptKeyword { + internal static System.Drawing.Bitmap ScriptKeyword + { get { object obj = ResourceManager.GetObject("ScriptKeyword", resourceCulture); - return ((byte[])(obj)); + return ((System.Drawing.Bitmap)(obj)); } } @@ -1109,14 +1112,15 @@ namespace CodeImp.DoomBuilder.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + /// /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. /// - internal static byte[] ScriptSnippet { + internal static System.Drawing.Bitmap ScriptSnippet + { get { object obj = ResourceManager.GetObject("ScriptSnippet", resourceCulture); - return ((byte[])(obj)); + return ((System.Drawing.Bitmap)(obj)); } } @@ -1329,7 +1333,35 @@ namespace CodeImp.DoomBuilder.Properties { return ((System.Drawing.Bitmap)(obj)); } } - + + internal static System.Drawing.Bitmap TextIndent + { + get + { + object obj = ResourceManager.GetObject("TextIndent", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap TextUnindent + { + get + { + object obj = ResourceManager.GetObject("TextUnindent", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap TextWhitespace + { + get + { + object obj = ResourceManager.GetObject("TextWhitespace", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// diff --git a/Source/Core/Properties/Resources.resx b/Source/Core/Properties/Resources.resx index 3a2f26b..69d4a64 100644 --- a/Source/Core/Properties/Resources.resx +++ b/Source/Core/Properties/Resources.resx @@ -154,6 +154,9 @@ ..\Resources\SaveAll.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Update.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Monster2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -175,15 +178,27 @@ ..\Resources\MixedThings.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\TextUnindent.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Marine.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\InfoPanelCollapse.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\mergegeometry.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Splash3_small.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Group.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\TagStatistics.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\VisualVertices.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -196,6 +211,9 @@ ..\Resources\ScriptHelp.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Light_animate.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\CommentSmile.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -217,17 +235,14 @@ ..\Resources\Redo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Status0.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Brightness.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Model.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\mergegeometry.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\ScriptSnippet.xpm;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Configuration.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\CommentProblem.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -238,8 +253,8 @@ ..\Resources\MLogo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\UnknownImage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Reload.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Paste.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -248,8 +263,8 @@ ..\Resources\LightDisabled.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\ScriptConstant.xpm;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + ..\Resources\ScriptConstant.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\FolderExplore.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -265,12 +280,18 @@ ..\Resources\CLogo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\WarningOff.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\List.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\TextWhitespace.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\LinedefColorPresets.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -286,8 +307,8 @@ ..\Resources\Cursor.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Grid2_arrowup.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Preferences.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Reset.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -313,6 +334,12 @@ ..\Resources\NewMap2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\About.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\GridDecrease.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\SearchClear.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -331,6 +358,9 @@ ..\Resources\InfoLine.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Status10.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\MissingTexture.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -338,7 +368,7 @@ ..\Resources\ErrorLarge.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\ScriptError.xpm;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\ScriptError.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Lightbulb.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -370,6 +400,9 @@ ..\Resources\Model_selected.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\GridDynamic.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Collapse.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -382,11 +415,11 @@ ..\Resources\Unlink.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Status10.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\TextIndent.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Properties.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Status0.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Script2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -406,6 +439,9 @@ ..\Resources\Hourglass.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\GridIncrease.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Folder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -424,17 +460,20 @@ ..\Resources\Status2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Link.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Brightness.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\InfoPanelExpand.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\TagStatistics.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ScriptSnippet.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Properties.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Test.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -442,8 +481,8 @@ ..\Resources\Undo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\InfoPanelExpand.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\UnknownImage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Unpin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -454,8 +493,14 @@ ..\Resources\ViewTextureFloor.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Light_animate.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Grid2_arrowup.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\GroupRemove.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Pin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -464,7 +509,7 @@ ..\Resources\ViewNormal.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\ScriptKeyword.xpm;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\ScriptKeyword.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\MissingThing.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -472,11 +517,14 @@ ..\Resources\Monster3.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\SkySphere.md3;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\DockerCollapse.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\GroupAdd.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\ViewBrightness.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -511,45 +559,6 @@ ..\Resources\Check.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\GridDynamic.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\About.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Configuration.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Preferences.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Reload.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Update.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Group.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\GroupAdd.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\GroupRemove.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\GridDecrease.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\GridIncrease.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\Sky.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\SkySphere.md3;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Resources\zonebuilder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/Source/Core/Rendering/ColorCollection.cs b/Source/Core/Rendering/ColorCollection.cs index 90a209f..bfc8322 100644 --- a/Source/Core/Rendering/ColorCollection.cs +++ b/Source/Core/Rendering/ColorCollection.cs @@ -20,7 +20,6 @@ using System; using System.Globalization; using System.Drawing; using SlimDX; - using Configuration = CodeImp.DoomBuilder.IO.Configuration; #endregion @@ -38,7 +37,7 @@ namespace CodeImp.DoomBuilder.Rendering private const float DARK_ADDITION = -0.2f; // Palette size - private const int NUM_COLORS = 49; + private const int NUM_COLORS = 57; public const int NUM_THING_COLORS = 20; public const int THING_COLORS_OFFSET = 20; @@ -92,14 +91,22 @@ namespace CodeImp.DoomBuilder.Rendering public const int NIGHTSCOLORMARE6 = 46; public const int NIGHTSCOLORMARE7 = 47; public const int NIGHTSCOLORMARE8 = 48; + public const int SCRIPTINDICATOR = 49; //mxd. Additional Script Editor colors + public const int SCRIPTBRACEHIGHLIGHT = 50; + public const int SCRIPTBADBRACEHIGHLIGHT = 51; + public const int SCRIPTWHITESPACE = 52; + public const int SCRIPTSELECTIONFORE = 53; + public const int SCRIPTSELECTIONBACK = 54; + public const int STRINGS = 55; + public const int INCLUDES = 56; #endregion #region ================== Variables // Colors - private PixelColor[] colors; - private PixelColor[] brightcolors; - private PixelColor[] darkcolors; + private readonly PixelColor[] colors; + private readonly PixelColor[] brightcolors; + private readonly PixelColor[] darkcolors; // Color-correction table private byte[] correctiontable; @@ -131,7 +138,13 @@ namespace CodeImp.DoomBuilder.Rendering public PixelColor Selection3D { get { return colors[SELECTION3D]; } internal set { colors[SELECTION3D] = value; } } public PixelColor ScriptBackground { get { return colors[SCRIPTBACKGROUND]; } internal set { colors[SCRIPTBACKGROUND] = value; } } - public PixelColor LineNumbers { get { return colors[LINENUMBERS]; } internal set { colors[LINENUMBERS] = value; } } + public PixelColor ScriptIndicator { get { return colors[SCRIPTINDICATOR]; } internal set { colors[SCRIPTINDICATOR] = value; } } + public PixelColor ScriptBraceHighlight { get { return colors[SCRIPTBRACEHIGHLIGHT]; } internal set { colors[SCRIPTBRACEHIGHLIGHT] = value; } } + public PixelColor ScriptBadBraceHighlight { get { return colors[SCRIPTBADBRACEHIGHLIGHT]; } internal set { colors[SCRIPTBADBRACEHIGHLIGHT] = value; } } + public PixelColor ScriptWhitespace { get { return colors[SCRIPTWHITESPACE]; } internal set { colors[SCRIPTWHITESPACE] = value; } } + public PixelColor ScriptSelectionForeColor { get { return colors[SCRIPTSELECTIONFORE]; } internal set { colors[SCRIPTSELECTIONFORE] = value; } } + public PixelColor ScriptSelectionBackColor { get { return colors[SCRIPTSELECTIONBACK]; } internal set { colors[SCRIPTSELECTIONBACK] = value; } } + public PixelColor LineNumbers { get { return colors[LINENUMBERS]; } internal set { colors[LINENUMBERS] = value; } } public PixelColor PlainText { get { return colors[PLAINTEXT]; } internal set { colors[PLAINTEXT] = value; } } public PixelColor Comments { get { return colors[COMMENTS]; } internal set { colors[COMMENTS] = value; } } public PixelColor Keywords { get { return colors[KEYWORDS]; } internal set { colors[KEYWORDS] = value; } } @@ -153,9 +166,9 @@ namespace CodeImp.DoomBuilder.Rendering // Read all colors from config for(int i = 0; i < NUM_COLORS; i++) { - // Read color - colors[i] = PixelColor.FromInt(cfg.ReadSetting("colors.color" + i.ToString(CultureInfo.InvariantCulture), -16711872)); //mxd. changed default color from transparent to light-green - } + // Read color + colors[i] = PixelColor.FromInt(cfg.ReadSetting("colors.color" + i.ToString(CultureInfo.InvariantCulture), 0)); + } // Set new colors if(colors[THINGCOLOR00].ToInt() == 0) colors[THINGCOLOR00] = PixelColor.FromColor(Color.DimGray); diff --git a/Source/Core/Rendering/D3DShader.cs b/Source/Core/Rendering/D3DShader.cs index 6f66db6..3bfc465 100644 --- a/Source/Core/Rendering/D3DShader.cs +++ b/Source/Core/Rendering/D3DShader.cs @@ -109,24 +109,37 @@ namespace CodeImp.DoomBuilder.Rendering } catch(Exception) { - // Compiling failed, try with debug information - try - { + string debugerrors = string.Empty; //mxd + + // Compiling failed, try with debug information + try + { //mxd. Rewind before use! fxdata.Seek(0, SeekOrigin.Begin); // Compile effect - fx = Effect.FromStream(General.Map.Graphics.Device, fxdata, null, null, null, ShaderFlags.Debug, null, out errors); - if(!string.IsNullOrEmpty(errors)) - { - throw new Exception("Errors in effect file " + fxfile + ": " + errors); - } + fx = Effect.FromStream(General.Map.Graphics.Device, fxdata, null, null, null, ShaderFlags.Debug, null, out debugerrors); + if (!string.IsNullOrEmpty(debugerrors)) + { + throw new Exception("Errors in effect file " + fxfile + ": " + debugerrors); + } } catch(Exception e) - { - // No debug information, just crash - throw new Exception(e.GetType().Name + " while loading effect " + fxfile + ": " + e.Message + "\nInitial message: " + errors); - } + { + //mxd. Try to get something. Anything! + string message; + if (!string.IsNullOrEmpty(debugerrors)) + message = e.Message + "\nInitial message (debug mode): \"" + debugerrors + "\""; + else if (!string.IsNullOrEmpty(errors)) + message = e.Message + "\nInitial message: \"" + errors + "\""; + else + message = e.ToString(); + + if (string.IsNullOrEmpty(message)) message = "No initial message..."; + + // No debug information, just crash + throw new Exception(e.GetType().Name + " while loading effect " + fxfile + ": " + message); + } } fxdata.Dispose(); diff --git a/Source/Core/Resources/Lexers.cfg b/Source/Core/Resources/Lexers.cfg index 29c2911..a260da7 100644 --- a/Source/Core/Resources/Lexers.cfg +++ b/Source/Core/Resources/Lexers.cfg @@ -33,6 +33,8 @@ lexer3 // CPP-style, case-sensitive 7 = 4; // literal 16 = 2; // constants 37 = 5; // ident guides + 6 = 6; // strings + 9 = 7; // includes keywordsindex = 0; constantsindex = 1; @@ -87,10 +89,10 @@ lexer35 // CPP-style, case-insensitive 7 = 4; // literal 16 = 2; // constants 37 = 5; // ident guides + 6 = 6; // strings + 9 = 7; // includes keywordsindex = 0; constantsindex = 1; snippetindex = 2; -} - - +} \ No newline at end of file diff --git a/Source/Core/Resources/ScriptConstant.png b/Source/Core/Resources/ScriptConstant.png new file mode 100644 index 0000000..556e12a Binary files /dev/null and b/Source/Core/Resources/ScriptConstant.png differ diff --git a/Source/Core/Resources/ScriptError.png b/Source/Core/Resources/ScriptError.png new file mode 100644 index 0000000..bc396ed Binary files /dev/null and b/Source/Core/Resources/ScriptError.png differ diff --git a/Source/Core/Resources/ScriptKeyword.png b/Source/Core/Resources/ScriptKeyword.png new file mode 100644 index 0000000..a83b2f1 Binary files /dev/null and b/Source/Core/Resources/ScriptKeyword.png differ diff --git a/Source/Core/Resources/ScriptSnippet.png b/Source/Core/Resources/ScriptSnippet.png new file mode 100644 index 0000000..60d5346 Binary files /dev/null and b/Source/Core/Resources/ScriptSnippet.png differ diff --git a/Source/Core/Resources/TextIndent.png b/Source/Core/Resources/TextIndent.png new file mode 100644 index 0000000..9364532 Binary files /dev/null and b/Source/Core/Resources/TextIndent.png differ diff --git a/Source/Core/Resources/TextUnindent.png b/Source/Core/Resources/TextUnindent.png new file mode 100644 index 0000000..1651b07 Binary files /dev/null and b/Source/Core/Resources/TextUnindent.png differ diff --git a/Source/Core/Resources/TextWhitespace.png b/Source/Core/Resources/TextWhitespace.png new file mode 100644 index 0000000..88b6e52 Binary files /dev/null and b/Source/Core/Resources/TextWhitespace.png differ diff --git a/Source/Core/Resources/WordWrap.png b/Source/Core/Resources/WordWrap.png index 7f63034..7734f72 100644 Binary files a/Source/Core/Resources/WordWrap.png and b/Source/Core/Resources/WordWrap.png differ diff --git a/Source/Core/Windows/ErrorsForm.cs b/Source/Core/Windows/ErrorsForm.cs index aa2bc45..af506d3 100644 --- a/Source/Core/Windows/ErrorsForm.cs +++ b/Source/Core/Windows/ErrorsForm.cs @@ -42,24 +42,24 @@ namespace CodeImp.DoomBuilder.Windows FillList(); checkerrors.Start(); checkshow.Checked = General.Settings.ShowErrorsWindow; - //mxd - grid.Focus(); - } + grid.Focus(); //mxd + } - #endregion + #endregion - #region ================== Methods + #region ================== Methods - // This sets up the list - private void FillList() + // This sets up the list + private void FillList() { // Fill the list with the items we don't have yet General.ErrorLogger.HasChanged = false; - List errors = General.ErrorLogger.GetErrors(); - int startindex = grid.Rows.Count; - for(int i = startindex; i < errors.Count; i++) - { - ErrorItem e = errors[i]; + + //mxd. Rewritten to get only the new items from the ErrorLogger + int startindex = grid.Rows.Count; + IEnumerable errors = General.ErrorLogger.GetErrors(startindex); + foreach (ErrorItem e in errors) + { Image icon = (e.type == ErrorType.Error) ? Properties.Resources.ErrorLarge : Properties.Resources.WarningLarge; int index = grid.Rows.Add(); DataGridViewRow row = grid.Rows[index]; @@ -145,7 +145,6 @@ namespace CodeImp.DoomBuilder.Windows private void ErrorsForm_Shown(object sender, EventArgs e) { if(grid.Rows.Count > 0) grid.Rows[0].Selected = false; - } private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)