#region ================== Namespaces using System.Collections.Generic; using System.IO; using System.Windows.Forms; using CodeImp.DoomBuilder.Compilers; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Data.Scripting; #endregion namespace CodeImp.DoomBuilder.Controls { //mxd. Document tab bound to a resource entry. Script type can't be changed. Can be readonly. //Must be replaced with ScriptFileDocumentTab when unable to locate target resource entry to save to. internal sealed class ScriptResourceDocumentTab : ScriptDocumentTab { #region ================== Variables private ScriptResource source; private string hash; private string filepathname; #endregion #region ================== Properties public override bool IsReconfigurable { get { return false; } } public override bool IsSaveAsRequired { get { return false; } } public override bool IsReadOnly { get { return source.IsReadOnly; } } public override string Filename { get { return filepathname; } } internal ScriptResource Resource { get { return source; } } #endregion #region ================== Constructor internal ScriptResourceDocumentTab(ScriptEditorPanel panel, ScriptResource resource, ScriptConfiguration config) : base(panel, config) { // Store resource source = resource; // Load the data MemoryStream stream = source.Resource.LoadFile(source.Filename, source.LumpIndex); if(stream != null) { hash = MD5Hash.Get(stream); editor.SetText(stream.ToArray()); editor.Scintilla.ReadOnly = source.IsReadOnly; editor.ClearUndoRedo(); } else { General.ErrorLogger.Add(ErrorType.Warning, "Failed to load " + source.ScriptType + " resource \"" + source.Filename + "\" from \"" + source.Resource.Location.GetDisplayName() + "\"."); } // Set title and tooltip tabtype = ScriptDocumentTabType.RESOURCE; filepathname = source.FilePathName; SetTitle(source.ToString()); this.ToolTipText = filepathname; // Update navigator panel.ShowErrors(UpdateNavigator(), true); } #endregion #region ================== Methods public override void Compile() { List errors = new List(); DataReader reader = source.Resource; if(reader != null && reader.CompileLump(source.Filename, source.LumpIndex, config, errors)) { // Update script navigator errors.AddRange(UpdateNavigator()); } // Feed errors to panel panel.ShowErrors(errors, false); } // This checks if a script error applies to this script public override bool VerifyErrorForScript(CompilerError e) { return (string.Compare(e.filename, source.Filename, true) == 0); } // This saves the document (used for both explicit and implicit) // Return true when successfully saved public override bool Save() { if(source.IsReadOnly) return false; // [ZZ] remove trailing whitespace RemoveTrailingWhitespace(); // Find lump, check it's hash bool dosave = true; DataReader reader = source.Resource; // reload the reader bool wasReadOnly = reader.IsReadOnly; reader.Reload(false); try { if (reader.FileExists(source.Filename, source.LumpIndex)) { using (MemoryStream ms = reader.LoadFile(source.Filename, source.LumpIndex)) { if (MD5Hash.Get(ms) != hash && MessageBox.Show("Target lump was modified by another application. Do you still want to replace it?", "Warning", MessageBoxButtons.OKCancel) == DialogResult.Cancel) { dosave = false; } } } if (dosave) { // Store the lump data using (MemoryStream stream = new MemoryStream(editor.GetText())) { if (reader.SaveFile(stream, source.Filename, source.LumpIndex)) { // Update what must be updated hash = MD5Hash.Get(stream); editor.SetSavePoint(); UpdateTitle(); } } } } finally { reader.Reload(wasReadOnly); } return dosave; } internal override ScriptDocumentSettings GetViewSettings() { // Store resource location var settings = base.GetViewSettings(); DataReader reader = source.Resource; if(reader != null) { settings.ResourceLocation = reader.Location.location; settings.Filename = Path.Combine(reader.Location.location, filepathname); // Make unique location } return settings; } //mxd. Check if resource still exists internal void OnReloadResources() { DataReader reader = source.Resource; if(reader == null) { // Ask script editor to replace us with ScriptFileDocumentTab panel.OnScriptResourceLost(this); } else { // Some paths may need updating... filepathname = source.FilePathName; this.ToolTipText = filepathname; } } #endregion } }