mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-17 01:22:18 +00:00
Script Editor:
Added: Tab text now looks differently when appropriate script was changed. Added: Script Editor now has it's own status bar. Added: several files can now be opened at once when using "Open File" command. Added: ACS scripts navigator now shows script and function arguments. Changed: when closing a tab, previous tab is selected instead of the first tab. Changed: SCRIPTS lump can't be compiled as a library. Changed: external acs files can only be compiled as libraries. Changed: when an external acs file is marked as #library, it will be saved as [library name].o alongside [filename].acs. Fixed: files opened using "Open File" command were immediately flagged as changed. Fixed: Script Editor was unable to navigate to error location after clicking on the error description when the error was in include file. Updated ZDoom ACC.
This commit is contained in:
parent
16da2531a6
commit
e8cda3c9c5
21 changed files with 646 additions and 143 deletions
|
@ -9,7 +9,5 @@ compilers
|
|||
{
|
||||
interface = "AccCompiler";
|
||||
program = "bcc.exe";
|
||||
zcommon = "zcommon.acs";
|
||||
std = "std.acs";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,5 @@ compilers
|
|||
{
|
||||
interface = "AccCompiler";
|
||||
program = "acc.exe";
|
||||
zcommon = "common.acs";
|
||||
zdefs = "defs.acs";
|
||||
zspecial = "specials.acs";
|
||||
zwvars = "wvars.acs";
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -9,9 +9,5 @@ compilers
|
|||
{
|
||||
interface = "AccCompiler";
|
||||
program = "acc.exe";
|
||||
zcommon = "zcommon.acs";
|
||||
zdefs = "zdefs.acs";
|
||||
zspecial = "zspecial.acs";
|
||||
zwvars = "zwvars.acs";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -989,6 +989,9 @@
|
|||
#define PICKAF_FORCETID 1
|
||||
#define PICKAF_RETURNTID 2
|
||||
|
||||
// magic value to set the ice translation through ACS
|
||||
#define TRANSLATION_ICE 0x100007
|
||||
|
||||
// Actor flags
|
||||
#define MF_SPECIAL 0x00000001
|
||||
#define MF_SOLID 0x00000002
|
||||
|
|
|
@ -9,9 +9,5 @@ compilers
|
|||
{
|
||||
interface = "AccCompiler";
|
||||
program = "acc.exe";
|
||||
zcommon = "zcommon.acs";
|
||||
zdefs = "zdefs.acs";
|
||||
zspecial = "zspecial.acs";
|
||||
zwvars = "zwvars.acs";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,13 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -73,27 +75,30 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
|
||||
//xabis
|
||||
// Copy includes from the resources into the compiler's folder, preserving relative pathing and naming
|
||||
foreach(string include in General.Map.ScriptIncludes)
|
||||
if(CopyIncludesToWorkingDirectory) //mxd
|
||||
{
|
||||
//grab the script text from the resources
|
||||
MemoryStream s = General.Map.Data.LoadFile(include);
|
||||
|
||||
if(s != null)
|
||||
foreach(string include in includes)
|
||||
{
|
||||
//pull the pk3 or directory sub folder out if applicable
|
||||
FileInfo fi = new FileInfo(Path.Combine(this.tempdir.FullName, include));
|
||||
// Grab the script text from the resources
|
||||
MemoryStream s = General.Map.Data.LoadFile(include);
|
||||
|
||||
//do not allow files to be overwritten, either accidentally or maliciously
|
||||
if(!fi.Exists)
|
||||
if(s != null)
|
||||
{
|
||||
General.WriteLogLine("Copying script include: " + include);
|
||||
// Pull the pk3 or directory sub folder out if applicable
|
||||
FileInfo fi = new FileInfo(Path.Combine(this.tempdir.FullName, include));
|
||||
|
||||
//create the directory path as needed
|
||||
if(!string.IsNullOrEmpty(fi.DirectoryName)) Directory.CreateDirectory(fi.DirectoryName);
|
||||
// Do not allow files to be overwritten, either accidentally or maliciously
|
||||
if(!fi.Exists)
|
||||
{
|
||||
General.WriteLogLine("Copying script include: " + include);
|
||||
|
||||
//dump the script into the target file
|
||||
BinaryReader reader = new BinaryReader(s);
|
||||
File.WriteAllBytes(fi.FullName, reader.ReadBytes((int)s.Length));
|
||||
// Create the directory path as needed
|
||||
if(!string.IsNullOrEmpty(fi.DirectoryName)) Directory.CreateDirectory(fi.DirectoryName);
|
||||
|
||||
// Dump the script into the target file
|
||||
BinaryReader reader = new BinaryReader(s);
|
||||
File.WriteAllBytes(fi.FullName, reader.ReadBytes((int)s.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,11 +175,26 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
err.linenumber--;
|
||||
|
||||
// Everything before the match is the filename
|
||||
err.filename = linestr.Substring(0, match.Index);
|
||||
err.filename = linestr.Substring(0, match.Index).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
if(!Path.IsPathRooted(err.filename))
|
||||
{
|
||||
// Add working directory to filename
|
||||
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
||||
//mxd. If the error is in an include file, try to find it in loaded resources
|
||||
if(includes.Contains(err.filename.ToLowerInvariant()))
|
||||
{
|
||||
foreach(DataReader dr in General.Map.Data.Containers)
|
||||
{
|
||||
if(dr is DirectoryReader && dr.FileExists(err.filename))
|
||||
{
|
||||
err.filename = Path.Combine(dr.Location.location, err.filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add working directory to filename, so it could be recognized as map namespace lump in MapManager.CompileLump()
|
||||
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
||||
}
|
||||
}
|
||||
|
||||
// Everything after the match is the description
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
protected string sourcefile;
|
||||
protected string outputfile;
|
||||
protected string inputfile;
|
||||
protected HashSet<string> includes; //mxd
|
||||
|
||||
// Files
|
||||
protected readonly DirectoryInfo tempdir;
|
||||
|
@ -60,6 +61,8 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
public string InputFile { get { return inputfile; } set { inputfile = value; } }
|
||||
public string OutputFile { get { return outputfile; } set { outputfile = value; } }
|
||||
public string Location { get { return tempdir.FullName; } }
|
||||
public HashSet<string> Includes { get { return includes; } set { includes = value; } } //mxd
|
||||
public bool CopyIncludesToWorkingDirectory; //mxd
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public CompilerError[] Errors { get { return errors.ToArray(); } }
|
||||
|
||||
|
@ -73,6 +76,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
// Initialize
|
||||
this.info = info;
|
||||
this.errors = new List<CompilerError>();
|
||||
this.includes = new HashSet<string>(); //mxd
|
||||
|
||||
General.WriteLogLine("Creating compiler '" + info.Name + "' on interface '" + this.GetType().Name + "'...");
|
||||
|
||||
|
@ -134,15 +138,15 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
// Copy files
|
||||
foreach(string f in info.Files)
|
||||
{
|
||||
string sourcefile = Path.Combine(info.Path, f);
|
||||
if (!File.Exists(sourcefile))
|
||||
string srcfile = Path.Combine(info.Path, f);
|
||||
if(!File.Exists(srcfile))
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "The file '" + f + "' required by the '" + info.Name + "' compiler is missing. According to the compiler configuration in '" + info.FileName + "', the was expected to be found in the following path: " + info.Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
string targetfile = Path.Combine(tempdir.FullName, f);
|
||||
File.Copy(sourcefile, targetfile, true);
|
||||
string tgtfile = Path.Combine(tempdir.FullName, f);
|
||||
File.Copy(srcfile, tgtfile, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ using System.Windows.Forms;
|
|||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
//mxd
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
using CodeImp.DoomBuilder.GZBuilder.GZDoom;
|
||||
|
||||
|
@ -50,6 +49,8 @@ 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
|
||||
|
||||
// Derived classes must set this!
|
||||
protected ScriptConfiguration config;
|
||||
|
@ -67,13 +68,20 @@ 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 bool IsChanged { get { return editor.IsChanged; } }
|
||||
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; } }
|
||||
public int SelectionEnd { get { return editor.SelectionEnd; } set { editor.SelectionEnd = value; } }
|
||||
public ScriptConfiguration Config { get { return config; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events (mxd)
|
||||
|
||||
public new event EventHandler OnTextChanged; //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
// Constructor
|
||||
|
@ -112,6 +120,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
editor.OnOpenFindAndReplace += panel.OpenFindAndReplace;
|
||||
editor.OnFindNext += panel.FindNext;
|
||||
editor.OnFindPrevious += panel.FindPrevious; //mxd
|
||||
editor.OnTextChanged += editor_TextChanged; //mxd
|
||||
}
|
||||
|
||||
// Disposer
|
||||
|
@ -123,6 +132,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
editor.OnOpenFindAndReplace -= panel.OpenFindAndReplace;
|
||||
editor.OnFindNext -= panel.FindNext;
|
||||
editor.OnFindPrevious -= panel.FindPrevious; //mxd
|
||||
editor.OnTextChanged -= editor_TextChanged; //mxd
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
@ -204,7 +214,14 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Call this to set the tab title
|
||||
protected void SetTitle(string title)
|
||||
{
|
||||
this.Text = title;
|
||||
this.title = title; //mxd
|
||||
base.Text = (editor.IsChanged ? "\u25CF " + title : title); //mxd
|
||||
}
|
||||
|
||||
//mxd
|
||||
protected void UpdateTitle()
|
||||
{
|
||||
SetTitle(title);
|
||||
}
|
||||
|
||||
// Perform undo
|
||||
|
@ -391,6 +408,14 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
navigator.Items.Clear();
|
||||
break;
|
||||
}
|
||||
|
||||
// Put some text in the navigator (but don't actually trigger selection event)
|
||||
if(navigator.Items.Count > 0)
|
||||
{
|
||||
preventchanges = true;
|
||||
navigator.Text = navigator.Items[0].ToString();
|
||||
preventchanges = false;
|
||||
}
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
@ -424,8 +449,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
navigator.Items.Clear();
|
||||
|
||||
AcsParserSE parser = new AcsParserSE();
|
||||
if(parser.Parse(stream, "ACS"))
|
||||
AcsParserSE parser = new AcsParserSE { AddArgumentsToScriptNames = true, IsMapScriptsLump = this is ScriptLumpDocumentTab };
|
||||
if(parser.Parse(stream, "SCRIPTS"))
|
||||
{
|
||||
navigator.Items.AddRange(parser.NamedScripts.ToArray());
|
||||
navigator.Items.AddRange(parser.NumberedScripts.ToArray());
|
||||
|
@ -478,7 +503,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
//mxd
|
||||
private void navigator_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (navigator.SelectedItem is ScriptItem)
|
||||
if(!preventchanges && navigator.SelectedItem is ScriptItem)
|
||||
{
|
||||
ScriptItem si = navigator.SelectedItem as ScriptItem;
|
||||
editor.EnsureLineVisible(editor.LineFromPosition(si.CursorPosition));
|
||||
|
@ -494,7 +519,14 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
//mxd
|
||||
private void navigator_DropDown(object sender, EventArgs e)
|
||||
{
|
||||
if(editor.IsChanged) UpdateNavigator();
|
||||
if(!preventchanges && editor.IsChanged) UpdateNavigator();
|
||||
}
|
||||
|
||||
//mxd
|
||||
private void editor_TextChanged(object sender, EventArgs eventArgs)
|
||||
{
|
||||
UpdateTitle();
|
||||
if(OnTextChanged != null) OnTextChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -65,6 +65,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
public event OpenFindReplaceDelegate OnOpenFindAndReplace;
|
||||
public event FindNextDelegate OnFindNext;
|
||||
public event FindPreviousDelegate OnFindPrevious; //mxd
|
||||
public new event EventHandler OnTextChanged; //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -163,7 +164,10 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// Events
|
||||
scriptedit.ModEventMask = 0x7FFFF; // Which events to receive (see also ScriptModificationFlags)
|
||||
scriptedit.Modified += scriptedit_Modified;
|
||||
scriptedit.TextDeleted += scriptedit_TextChanged; //mxd
|
||||
scriptedit.TextInserted += scriptedit_TextChanged; //mxd
|
||||
scriptedit.UndoPerformed += scriptedit_UndoRedoPerformed; //mxd
|
||||
scriptedit.RedoPerformed += scriptedit_UndoRedoPerformed; //mxd
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -752,10 +756,18 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
}
|
||||
}
|
||||
|
||||
// Script modified
|
||||
private void scriptedit_Modified(ScintillaControl pSender, int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
|
||||
//mxd. Script text changed
|
||||
private void scriptedit_UndoRedoPerformed(ScintillaControl pSender)
|
||||
{
|
||||
changed = true;
|
||||
if(OnTextChanged != null) OnTextChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
//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
|
||||
|
|
57
Source/Core/Controls/ScriptEditorPanel.Designer.cs
generated
57
Source/Core/Controls/ScriptEditorPanel.Designer.cs
generated
|
@ -66,10 +66,16 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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
|
||||
|
@ -82,7 +88,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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, 401);
|
||||
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);
|
||||
|
@ -361,6 +367,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
//
|
||||
// openfile
|
||||
//
|
||||
this.openfile.Multiselect = true;
|
||||
this.openfile.Title = "Open Script";
|
||||
//
|
||||
// savefile
|
||||
|
@ -384,8 +391,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
//
|
||||
this.splitter.Panel2.Controls.Add(this.label1);
|
||||
this.splitter.Panel2.Controls.Add(this.errorlist);
|
||||
this.splitter.Size = new System.Drawing.Size(726, 538);
|
||||
this.splitter.SplitterDistance = 412;
|
||||
this.splitter.Size = new System.Drawing.Size(726, 516);
|
||||
this.splitter.SplitterDistance = 390;
|
||||
this.splitter.TabIndex = 2;
|
||||
this.splitter.TabStop = false;
|
||||
//
|
||||
|
@ -449,12 +456,49 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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.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);
|
||||
|
@ -463,6 +507,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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();
|
||||
|
||||
|
@ -506,5 +552,10 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -49,6 +48,11 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// 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
|
||||
|
||||
|
@ -140,18 +144,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
}
|
||||
|
||||
//mxd. Select "Scripts" tab, because that's what user will want 99% of time
|
||||
if (tabs.TabPages.Count > 0)
|
||||
{
|
||||
foreach (TabPage p in tabs.TabPages)
|
||||
{
|
||||
if (p.Text == "SCRIPTS")
|
||||
{
|
||||
tabs.SelectedTab = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tabs.SelectedIndex == -1) tabs.SelectedIndex = 0;
|
||||
}
|
||||
int scriptsindex = GetTabPageIndex("SCRIPTS");
|
||||
tabs.SelectedIndex = (scriptsindex == -1 ? 0 : scriptsindex);
|
||||
|
||||
//mxd. Apply quick search settings
|
||||
searchmatchcase.Checked = matchcase;
|
||||
|
@ -203,9 +197,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
if(!string.IsNullOrEmpty(findoptions.FindText) && (ActiveTab != null))
|
||||
{
|
||||
if(!ActiveTab.FindNext(findoptions))
|
||||
{
|
||||
General.MainWindow.DisplayStatus(StatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\".");
|
||||
}
|
||||
DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\".");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -226,10 +218,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
{
|
||||
if(!string.IsNullOrEmpty(findoptions.FindText) && (ActiveTab != null))
|
||||
{
|
||||
if (!ActiveTab.FindPrevious(findoptions))
|
||||
{
|
||||
General.MainWindow.DisplayStatus(StatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\".");
|
||||
}
|
||||
if(!ActiveTab.FindPrevious(findoptions))
|
||||
DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\".");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -299,9 +289,9 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// Show result
|
||||
if(replacements == 0)
|
||||
General.MainWindow.DisplayStatus(StatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\".");
|
||||
DisplayStatus(ScriptStatusType.Warning, "Can't find any occurence of \"" + findoptions.FindText + "\".");
|
||||
else
|
||||
General.MainWindow.DisplayStatus(StatusType.Info, "Replaced " + replacements + " occurences of \"" + findoptions.FindText + "\" with \"" + findoptions.ReplaceWith + "\".");
|
||||
DisplayStatus(ScriptStatusType.Info, "Replaced " + replacements + " occurences of \"" + findoptions.FindText + "\" with \"" + findoptions.ReplaceWith + "\".");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -446,6 +436,10 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
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();
|
||||
|
@ -456,12 +450,11 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// This returns true when any of the implicit-save scripts are changed
|
||||
public bool CheckImplicitChanges()
|
||||
{
|
||||
bool changes = false;
|
||||
foreach(ScriptDocumentTab t in tabs.TabPages)
|
||||
{
|
||||
if(!t.ExplicitSave && t.IsChanged) changes = true;
|
||||
if(!t.ExplicitSave && t.IsChanged) return true;
|
||||
}
|
||||
return changes;
|
||||
return false;
|
||||
}
|
||||
|
||||
// This forces the focus to the script editor
|
||||
|
@ -501,7 +494,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
t = (tabs.SelectedTab as ScriptDocumentTab);
|
||||
|
||||
// Enable/disable buttons
|
||||
buttonsave.Enabled = (t != null) && t.ExplicitSave;
|
||||
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
|
||||
|
@ -526,15 +519,30 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
}
|
||||
|
||||
//mxd. Add snippets
|
||||
if(t.Config.Snippets.Count > 0)
|
||||
if(t.Config != null && t.Config.Snippets.Count > 0)
|
||||
{
|
||||
foreach(KeyValuePair<string, string[]> group in t.Config.Snippets)
|
||||
buttonsnippets.DropDownItems.Add(group.Key).Click += OnInsertSnippetClick;
|
||||
if(t.Config.Snippets.Count > 0) foreach(KeyValuePair<string, string[]> 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
|
||||
|
@ -562,11 +570,11 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
{
|
||||
//mxd
|
||||
ScriptType st = t.VerifyScriptType();
|
||||
if (st != ScriptType.UNKNOWN)
|
||||
if(st != ScriptType.UNKNOWN)
|
||||
{
|
||||
foreach (ScriptConfiguration cfg in scriptconfigs)
|
||||
foreach(ScriptConfiguration cfg in scriptconfigs)
|
||||
{
|
||||
if (cfg.ScriptType == st)
|
||||
if(cfg.ScriptType == st)
|
||||
{
|
||||
t.ChangeScriptConfig(cfg);
|
||||
break;
|
||||
|
@ -582,6 +590,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
tabs.SelectedTab = t;
|
||||
|
||||
// Done
|
||||
t.OnTextChanged += tabpage_OnTextChanged; //mxd
|
||||
t.IsChanged = false; //mxd. Not changed yet
|
||||
UpdateToolbar(true);
|
||||
return t;
|
||||
}
|
||||
|
@ -619,6 +629,84 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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
|
||||
|
||||
|
@ -630,6 +718,10 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
//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();
|
||||
|
@ -651,6 +743,9 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Change script config
|
||||
t.ChangeScriptConfig(scriptconfig);
|
||||
|
||||
//mxd. Update script type description
|
||||
scripttype.Text = scriptconfig.Description;
|
||||
|
||||
// Done
|
||||
UpdateToolbar(true);
|
||||
}
|
||||
|
@ -676,8 +771,30 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Show open file dialog
|
||||
if(openfile.ShowDialog(this.ParentForm) == DialogResult.OK)
|
||||
{
|
||||
// TODO: Make multi-select possible
|
||||
OpenFile(openfile.FileName);
|
||||
//mxd. Gather already opened file names
|
||||
List<string> openedfiles = new List<string>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -772,25 +889,22 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(t.ExplicitSave && t.IsChanged)
|
||||
{
|
||||
if(t.ExplicitSave && t.IsChanged)
|
||||
{
|
||||
// We can only compile when the script is saved
|
||||
if(!SaveScript(t)) return;
|
||||
}
|
||||
// We can only compile when the script is saved
|
||||
if(!SaveScript(t)) return;
|
||||
}
|
||||
|
||||
// Compile now
|
||||
General.MainWindow.DisplayStatus(StatusType.Busy, "Compiling script " + t.Text + "...");
|
||||
DisplayStatus(ScriptStatusType.Busy, "Compiling script \"" + t.Text + "\"...");
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
t.Compile();
|
||||
|
||||
// Show warning
|
||||
if((compilererrors != null) && (compilererrors.Count > 0))
|
||||
General.MainWindow.DisplayStatus(StatusType.Warning, compilererrors.Count + " errors while compiling " + t.Text + "!");
|
||||
DisplayStatus(ScriptStatusType.Warning, compilererrors.Count + " errors while compiling \"" + t.Text + "\"!");
|
||||
else
|
||||
General.MainWindow.DisplayStatus(StatusType.Info, "Script " + t.Text + " compiled without errors.");
|
||||
DisplayStatus(ScriptStatusType.Info, "Script \"" + t.Text + "\" compiled without errors.");
|
||||
|
||||
Cursor.Current = Cursors.Default;
|
||||
UpdateToolbar(true);
|
||||
|
@ -854,6 +968,16 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
{
|
||||
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)
|
||||
|
@ -920,6 +1044,21 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
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
|
||||
|
||||
}
|
||||
|
|
|
@ -176,6 +176,15 @@
|
|||
AQEGAAGAAQEGAAGAAQEGAAGAAQEGAAHAAQMGAAHgAQcGAAHwAQ8GAAL/BgAL
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="statusbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>400, 17</value>
|
||||
</metadata>
|
||||
<metadata name="statusflasher.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>501, 17</value>
|
||||
</metadata>
|
||||
<metadata name="statusresetter.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>588, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.GZBuilder.GZDoom;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -60,8 +61,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
if(config.Extensions.Length > 0) ext = "." + config.Extensions[0];
|
||||
SetTitle("Untitled" + ext);
|
||||
editor.ClearUndoRedo();
|
||||
//mxd
|
||||
navigator.Enabled = (config.ScriptType != ScriptType.UNKNOWN);
|
||||
navigator.Enabled = (config.ScriptType != ScriptType.UNKNOWN); //mxd
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -71,18 +71,15 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// This compiles the script file
|
||||
public override void Compile()
|
||||
{
|
||||
//mxd. List of errors. UpdateScriptNames can return errors and also updates acs includes list
|
||||
List<CompilerError> errors = (config.ScriptType == ScriptType.ACS ? General.Map.UpdateScriptNames() : new List<CompilerError>());
|
||||
|
||||
//mxd. Errors already?..
|
||||
if(errors.Count > 0)
|
||||
//mxd. ACS requires special handling...
|
||||
if(config.ScriptType == ScriptType.ACS)
|
||||
{
|
||||
// Feed errors to panel
|
||||
panel.ShowErrors(errors);
|
||||
CompileACS();
|
||||
return;
|
||||
}
|
||||
|
||||
Compiler compiler;
|
||||
List<CompilerError> errors = new List<CompilerError>();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -93,6 +90,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
panel.ShowErrors(errors); //mxd
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -135,6 +133,136 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
panel.ShowErrors(errors);
|
||||
}
|
||||
|
||||
//mxd. ACS requires special handling...
|
||||
private void CompileACS()
|
||||
{
|
||||
Compiler compiler;
|
||||
List<CompilerError> errors = new List<CompilerError>();
|
||||
string inputfile = Path.GetFileName(filepathname);
|
||||
|
||||
// Which compiler to use?
|
||||
ScriptConfiguration scriptconfig;
|
||||
if(!string.IsNullOrEmpty(General.Map.Options.ScriptCompiler))
|
||||
{
|
||||
// Boilderplate
|
||||
if(!General.CompiledScriptConfigs.ContainsKey(General.Map.Options.ScriptCompiler))
|
||||
{
|
||||
General.ShowErrorMessage("Unable to compile '" + inputfile + "'. Unable to find required script compiler configuration ('" + General.Map.Options.ScriptCompiler + "').", MessageBoxButtons.OK);
|
||||
return;
|
||||
}
|
||||
|
||||
scriptconfig = General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler];
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptconfig = config;
|
||||
}
|
||||
|
||||
// Initialize compiler
|
||||
try
|
||||
{
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
panel.ShowErrors(errors);
|
||||
return;
|
||||
}
|
||||
|
||||
// Preprocess the file
|
||||
AcsParserSE parser = new AcsParserSE { OnInclude = (se, path) => se.Parse(General.Map.Data.LoadFile(path), path, true, true) };
|
||||
using(FileStream stream = File.OpenRead(filepathname))
|
||||
{
|
||||
if(!parser.Parse(stream, inputfile, scriptconfig.Compiler.Files, true, false))
|
||||
{
|
||||
// Check for errors
|
||||
if(parser.HasError)
|
||||
{
|
||||
errors.Add(new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine));
|
||||
panel.ShowErrors(errors);
|
||||
compiler.Dispose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only works for libraries
|
||||
if(!parser.IsLibrary)
|
||||
{
|
||||
errors.Add(new CompilerError("External ACS files can only be compiled as libraries!", inputfile));
|
||||
panel.ShowErrors(errors);
|
||||
compiler.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = config.Parameters;
|
||||
compiler.InputFile = inputfile;
|
||||
compiler.OutputFile = outputfile;
|
||||
compiler.SourceFile = filepathname;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(filepathname);
|
||||
compiler.Includes = parser.Includes;
|
||||
compiler.CopyIncludesToWorkingDirectory = false;
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerr = e;
|
||||
|
||||
// If the error's filename equals our temporary file,
|
||||
// replace it with the original source filename
|
||||
if(string.Compare(e.filename, inputfile, true) == 0)
|
||||
newerr.filename = filepathname;
|
||||
|
||||
errors.Add(newerr);
|
||||
}
|
||||
|
||||
// No errors and output file exists?
|
||||
if(compiler.Errors.Length == 0)
|
||||
{
|
||||
// Output file exists?
|
||||
if(!File.Exists(outputfile))
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Output file '" + outputfile + "' doesn't exist."));
|
||||
panel.ShowErrors(errors);
|
||||
return;
|
||||
}
|
||||
|
||||
// Rename and copy to source file directory
|
||||
string targetfilename = Path.Combine(Path.GetDirectoryName(filepathname), parser.LibraryName + ".o");
|
||||
try
|
||||
{
|
||||
File.Copy(outputfile, targetfilename, true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to create library file '" + targetfilename + "'. " + e.GetType().Name + ": " + e.Message));
|
||||
panel.ShowErrors(errors);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose compiler
|
||||
compiler.Dispose();
|
||||
|
||||
// Update script navigator
|
||||
UpdateNavigator();
|
||||
|
||||
// Feed errors to panel
|
||||
panel.ShowErrors(errors);
|
||||
}
|
||||
|
||||
// This checks if a script error applies to this script
|
||||
public override bool VerifyErrorForScript(CompilerError e)
|
||||
{
|
||||
|
@ -161,6 +289,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// Done
|
||||
editor.IsChanged = false;
|
||||
UpdateTitle(); //mxd
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -201,8 +330,10 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// Setup
|
||||
this.filepathname = filepathname;
|
||||
SetTitle(Path.GetFileName(filepathname));
|
||||
editor.ClearUndoRedo();
|
||||
editor.IsChanged = false; //mxd. Not changed yet
|
||||
SetTitle(Path.GetFileName(filepathname));
|
||||
UpdateNavigator(); //mxd
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -210,14 +341,12 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// This changes the script configurations
|
||||
public override void ChangeScriptConfig(ScriptConfiguration newconfig)
|
||||
{
|
||||
string ext = "";
|
||||
|
||||
this.config = newconfig;
|
||||
editor.SetupStyles(config);
|
||||
|
||||
if(filepathname.Length == 0)
|
||||
{
|
||||
if(config.Extensions.Length > 0) ext = "." + config.Extensions[0];
|
||||
string ext = (config.Extensions.Length > 0 ? "." + config.Extensions[0] : "");
|
||||
SetTitle("Untitled" + ext);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
public override bool IsSaveAsRequired { get { return false; } }
|
||||
public override bool IsClosable { get { return false; } }
|
||||
public override bool IsReconfigurable { get { return false; } }
|
||||
public override string Filename { get { return lumpname; } } //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -75,8 +76,9 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
editor.ClearUndoRedo();
|
||||
UpdateNavigator(); //mxd
|
||||
}
|
||||
|
||||
// Done
|
||||
|
||||
// Set title
|
||||
IsChanged = false; //mxd. Not changed yet
|
||||
SetTitle(ismapheader ? General.Map.Options.CurrentName : this.lumpname.ToUpper());
|
||||
}
|
||||
|
||||
|
@ -115,6 +117,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
MemoryStream stream = new MemoryStream(editor.GetText());
|
||||
General.Map.SetLumpData(lumpname, stream);
|
||||
editor.IsChanged = false;
|
||||
UpdateTitle(); //mxd
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public Dictionary<string, KeyValuePair<int, int>> Reverbs { get { return reverbs; } }
|
||||
public Dictionary<long, GlowingFlatData> GlowingFlats { get { return glowingflats; } }
|
||||
public List<string> SoundSequences { get { return soundsequences; } }
|
||||
internal List<DataReader> Containers { get { return containers; } } //mxd
|
||||
|
||||
public Playpal Palette { get { return palette; } }
|
||||
public PreviewManager Previews { get { return previews; } }
|
||||
|
@ -2052,11 +2053,11 @@ namespace CodeImp.DoomBuilder.Data
|
|||
//mxd
|
||||
internal MemoryStream LoadFile(string name)
|
||||
{
|
||||
//relative path?
|
||||
// Relative path?
|
||||
if(name.StartsWith("..\\")) name = name.Replace("..\\", "");
|
||||
|
||||
foreach (DataReader dr in containers)
|
||||
if (dr.FileExists(name)) return dr.LoadFile(name);
|
||||
foreach(DataReader dr in containers)
|
||||
if(dr.FileExists(name)) return dr.LoadFile(name);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
|
||||
private readonly HashSet<string> parsedlumps;
|
||||
private readonly HashSet<string> includes;
|
||||
private List<string> includestoskip;
|
||||
private List<string> includestoskip;
|
||||
private string libraryname;
|
||||
|
||||
private readonly List<ScriptItem> namedscripts;
|
||||
private readonly List<ScriptItem> numberedscripts;
|
||||
|
@ -23,7 +24,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
internal List<ScriptItem> NamedScripts { get { return namedscripts; } }
|
||||
internal List<ScriptItem> NumberedScripts { get { return numberedscripts; } }
|
||||
internal List<ScriptItem> Functions { get { return functions; } }
|
||||
internal IEnumerable<string> Includes { get { return includes; } }
|
||||
internal HashSet<string> Includes { get { return includes; } }
|
||||
internal bool IsLibrary { get { return !string.IsNullOrEmpty(libraryname); } }
|
||||
internal string LibraryName { get { return libraryname; } }
|
||||
|
||||
internal bool AddArgumentsToScriptNames;
|
||||
internal bool IsMapScriptsLump;
|
||||
|
||||
internal AcsParserSE()
|
||||
{
|
||||
|
@ -99,6 +105,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
List<string> argnames = new List<string>();
|
||||
foreach(KeyValuePair<string, string> group in args) argnames.Add(group.Value);
|
||||
|
||||
// Make full name
|
||||
if(AddArgumentsToScriptNames) scriptname += " " + GetArgumentNames(args);
|
||||
|
||||
// Add to collection
|
||||
namedscripts.Add(new ScriptItem(scriptname, argnames, startpos, isinclude));
|
||||
}
|
||||
|
@ -123,7 +132,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
|
||||
if(!string.IsNullOrEmpty(token))
|
||||
{
|
||||
int commentstart = token.IndexOf("//");
|
||||
int commentstart = token.IndexOf("//", System.StringComparison.Ordinal);
|
||||
if(commentstart != -1) //found comment
|
||||
{
|
||||
commentstart += 2;
|
||||
|
@ -132,11 +141,14 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
}
|
||||
|
||||
bool customname = (name.Length > 0);
|
||||
name = (customname ? name + " [" + n + "]" : "Script " + n);
|
||||
name = (customname ? name + " [Script " + n + "]" : "Script " + n);
|
||||
|
||||
List<string> argnames = new List<string>();
|
||||
foreach(KeyValuePair<string, string> group in args) argnames.Add(group.Value);
|
||||
|
||||
// Make full name
|
||||
if(AddArgumentsToScriptNames) name += " " + GetArgumentNames(args);
|
||||
|
||||
// Add to collection
|
||||
numberedscripts.Add(new ScriptItem(n, name, argnames, startpos, isinclude, customname));
|
||||
}
|
||||
|
@ -157,11 +169,33 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
List<string> argnames = new List<string>();
|
||||
foreach(KeyValuePair<string, string> group in args) argnames.Add(group.Value);
|
||||
|
||||
// Make full name
|
||||
if(AddArgumentsToScriptNames) funcname += GetArgumentNames(args);
|
||||
|
||||
// Add to collection
|
||||
functions.Add(new ScriptItem(funcname, argnames, startpos, isinclude));
|
||||
}
|
||||
break;
|
||||
|
||||
case "#library":
|
||||
if(IsMapScriptsLump)
|
||||
{
|
||||
ReportError("Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": SCRIPTS lump can not be compiled as library!");
|
||||
return false;
|
||||
}
|
||||
|
||||
SkipWhitespace(true);
|
||||
libraryname = ReadToken();
|
||||
|
||||
if(string.IsNullOrEmpty(libraryname) || !libraryname.StartsWith("\"") || !libraryname.EndsWith("\""))
|
||||
{
|
||||
ReportError("Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber() + ": invalid #library directive!");
|
||||
return false;
|
||||
}
|
||||
|
||||
libraryname = StripTokenQuotes(libraryname);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(processincludes && (token == "#include" || token == "#import"))
|
||||
{
|
||||
|
@ -212,7 +246,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
if(IsSpecialToken(argtype)) break;
|
||||
if(argtype.ToUpperInvariant() == "VOID")
|
||||
{
|
||||
argnames.Add(new KeyValuePair<string, string>("(void)", string.Empty));
|
||||
argnames.Add(new KeyValuePair<string, string>("void", string.Empty));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -227,5 +261,20 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
|
|||
|
||||
return argnames;
|
||||
}
|
||||
|
||||
private static string GetArgumentNames(List<KeyValuePair<string, string>> args)
|
||||
{
|
||||
// Make full name
|
||||
if(args.Count > 0)
|
||||
{
|
||||
List<string> argdescs = new List<string>(args.Count);
|
||||
foreach(KeyValuePair<string, string> group in args)
|
||||
argdescs.Add((group.Key + " " + group.Value).TrimEnd());
|
||||
|
||||
return "(" + string.Join(", ", argdescs.ToArray()) + ")";
|
||||
}
|
||||
|
||||
return "(void)";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1054,7 +1054,6 @@ namespace CodeImp.DoomBuilder
|
|||
// This builds the nodes in the temproary file with the given configuration name
|
||||
private bool BuildNodes(string nodebuildername, bool failaswarning)
|
||||
{
|
||||
string tempfile2;
|
||||
bool lumpscomplete = false;
|
||||
WAD buildwad;
|
||||
|
||||
|
@ -1102,6 +1101,7 @@ namespace CodeImp.DoomBuilder
|
|||
buildwad.Dispose();
|
||||
|
||||
// Does the nodebuilder require an output file?
|
||||
string tempfile2;
|
||||
if(nodebuilder.HasSpecialOutputFile)
|
||||
{
|
||||
// Make a temporary output file for the nodebuilder
|
||||
|
@ -1146,7 +1146,7 @@ namespace CodeImp.DoomBuilder
|
|||
{
|
||||
//mxd. collect errors
|
||||
string compilererrors = "";
|
||||
foreach (CompilerError e in compiler.Errors)
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
compilererrors += Environment.NewLine + e.description;
|
||||
|
||||
// Nodebuilder did not build the lumps!
|
||||
|
@ -1232,7 +1232,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This writes a copy of the data to a lump in the temp file
|
||||
public void SetLumpData(string lumpname, MemoryStream data)
|
||||
public void SetLumpData(string lumpname, MemoryStream lumpdata)
|
||||
{
|
||||
int insertindex = tempwad.Lumps.Count;
|
||||
|
||||
|
@ -1245,9 +1245,12 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// Insert new lump
|
||||
Lump l = tempwad.Insert(lumpname, insertindex, (int)data.Length);
|
||||
Lump l = tempwad.Insert(lumpname, insertindex, (int)lumpdata.Length);
|
||||
l.Stream.Seek(0, SeekOrigin.Begin);
|
||||
data.WriteTo(l.Stream);
|
||||
lumpdata.WriteTo(l.Stream);
|
||||
|
||||
//mxd. Mark the map as changed (will also update the title)
|
||||
IsChanged = true;
|
||||
}
|
||||
|
||||
// This checks if the specified lump exists in the temp file
|
||||
|
@ -1682,7 +1685,7 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This checks if the scripts are changed
|
||||
internal bool CheckScriptChanged()
|
||||
private bool CheckScriptChanged()
|
||||
{
|
||||
if(scriptwindow != null)
|
||||
{
|
||||
|
@ -1797,6 +1800,14 @@ namespace CodeImp.DoomBuilder
|
|||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.SourceFile = sourcefile;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
|
||||
//mxd
|
||||
if(scriptconfig.ScriptType == ScriptType.ACS)
|
||||
{
|
||||
compiler.Includes = General.Map.ScriptIncludes;
|
||||
compiler.CopyIncludesToWorkingDirectory = true;
|
||||
}
|
||||
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Process errors
|
||||
|
@ -1871,7 +1882,8 @@ namespace CodeImp.DoomBuilder
|
|||
foreach(CompilerError error in compilererrors)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "ACS error in '" + error.filename
|
||||
+ "', line " + error.linenumber + ". " + error.description + ".");
|
||||
+ (error.linenumber != CompilerError.NO_LINE_NUMBER ? "', line " + error.linenumber : "'")
|
||||
+ ". " + error.description + ".");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1914,7 +1926,7 @@ namespace CodeImp.DoomBuilder
|
|||
if(stream != null && stream.Length > 0 && scriptconfig != null && scriptconfig.Compiler != null)
|
||||
{
|
||||
// Get script names
|
||||
AcsParserSE parser = new AcsParserSE { OnInclude = UpdateScriptsFromLocation };
|
||||
AcsParserSE parser = new AcsParserSE { OnInclude = (se, path) => se.Parse(General.Map.Data.LoadFile(path), path, true, true) };
|
||||
if(parser.Parse(stream, "SCRIPTS", scriptconfig.Compiler.Files, true, false))
|
||||
{
|
||||
// Add them to arrays
|
||||
|
@ -1960,12 +1972,6 @@ namespace CodeImp.DoomBuilder
|
|||
return compilererrors;
|
||||
}
|
||||
|
||||
//mxd
|
||||
private static void UpdateScriptsFromLocation(AcsParserSE parser, string path)
|
||||
{
|
||||
parser.Parse(General.Map.Data.LoadFile(path), path, true, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 240 KiB |
|
@ -55,15 +55,15 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
private const int MAX_RECENT_FILES_PIXELS = 250;
|
||||
|
||||
// Status bar
|
||||
private const int WARNING_FLASH_COUNT = 10;
|
||||
private const int WARNING_FLASH_INTERVAL = 100;
|
||||
private const int WARNING_RESET_DELAY = 5000;
|
||||
private const int INFO_RESET_DELAY = 5000;
|
||||
private const int ACTION_FLASH_COUNT = 3;
|
||||
private const int ACTION_FLASH_INTERVAL = 50;
|
||||
private const int ACTION_RESET_DELAY = 5000;
|
||||
internal const int WARNING_FLASH_COUNT = 10;
|
||||
internal const int WARNING_FLASH_INTERVAL = 100;
|
||||
internal const int WARNING_RESET_DELAY = 5000;
|
||||
internal const int INFO_RESET_DELAY = 5000;
|
||||
internal const int ACTION_FLASH_COUNT = 3;
|
||||
internal const int ACTION_FLASH_INTERVAL = 50;
|
||||
internal const int ACTION_RESET_DELAY = 5000;
|
||||
|
||||
private readonly Image[,] STATUS_IMAGES = new Image[,]
|
||||
internal readonly Image[,] STATUS_IMAGES = new Image[,]
|
||||
{
|
||||
// Normal versions
|
||||
{
|
||||
|
@ -424,7 +424,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
if(General.Map != null)
|
||||
{
|
||||
// Show map name and filename in caption
|
||||
this.Text = General.Map.FileTitle + (mapchanged ? "* (" : " (") + General.Map.Options.CurrentName + ") - " + Application.ProductName;
|
||||
this.Text = (mapchanged ? "\u25CF " : "") + General.Map.FileTitle + " (" + General.Map.Options.CurrentName + ") - " + Application.ProductName;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Windows
|
||||
|
@ -99,4 +101,61 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
/// </summary>
|
||||
Warning
|
||||
}
|
||||
|
||||
//mxd. StatusInfo used by Script Editor
|
||||
public struct ScriptStatusInfo
|
||||
{
|
||||
public const string READY_TEXT = "Ready.";
|
||||
|
||||
public readonly ScriptStatusType type;
|
||||
public readonly string message;
|
||||
internal bool displayed;
|
||||
|
||||
internal ScriptStatusInfo(ScriptStatusType type, string message)
|
||||
{
|
||||
this.type = type;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ScriptStatusType.Ready:
|
||||
this.message = READY_TEXT;
|
||||
break;
|
||||
|
||||
case ScriptStatusType.Info:
|
||||
case ScriptStatusType.Warning:
|
||||
case ScriptStatusType.Busy:
|
||||
this.message = message;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException("Unsupported Script Status Type!");
|
||||
}
|
||||
|
||||
this.displayed = false;
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. StatusType used by Script Editor
|
||||
public enum ScriptStatusType
|
||||
{
|
||||
/// <summary>
|
||||
/// When no particular information is to be displayed.
|
||||
/// </summary>
|
||||
Ready,
|
||||
|
||||
/// <summary>
|
||||
/// Shows information without flashing the icon.
|
||||
/// </summary>
|
||||
Info,
|
||||
|
||||
/// <summary>
|
||||
/// Shows information with the busy icon.
|
||||
/// </summary>
|
||||
Busy,
|
||||
|
||||
/// <summary>
|
||||
/// Shows a warning, makes a warning sound and flashes a warning icon.
|
||||
/// </summary>
|
||||
Warning
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue