mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-16 12:08:36 +00:00
502 lines
12 KiB
C#
502 lines
12 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using System.Runtime.Serialization;
|
|
using System.Runtime.Serialization.Formatters;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
namespace m
|
|
{
|
|
public enum Command { Cut, Copy, Paste, Delete };
|
|
|
|
public interface ICommandTarget {
|
|
void DispatchCommand(Command cmd);
|
|
}
|
|
|
|
public class DocManager {
|
|
static ArrayList s_alsTemplates = new ArrayList();
|
|
static Form s_frmParent = null;
|
|
static ICommandTarget m_cmdt;
|
|
|
|
public static void SetCommandTarget(ICommandTarget cmdt) {
|
|
m_cmdt = cmdt;
|
|
}
|
|
|
|
public static ICommandTarget GetCommandTarget() {
|
|
return m_cmdt;
|
|
}
|
|
|
|
public static void SetFrameParent(Form frmParent) {
|
|
s_frmParent = frmParent;
|
|
}
|
|
|
|
public static Form GetFrameParent() {
|
|
return s_frmParent;
|
|
}
|
|
|
|
public static void AddTemplate(DocTemplate doct) {
|
|
s_alsTemplates.Add(doct);
|
|
}
|
|
|
|
public static void RemoveTemplate(DocTemplate doct) {
|
|
s_alsTemplates.Remove(doct);
|
|
}
|
|
|
|
public static DocTemplate FindDocTemplate(Type type) {
|
|
foreach (DocTemplate doct in s_alsTemplates) {
|
|
if (doct.GetDocumentType() == type)
|
|
return doct;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static Document NewDocument(Type typeDoc, Object[] aobj) {
|
|
DocTemplate doct = FindDocTemplate(typeDoc);
|
|
return doct.NewDocument(aobj);
|
|
}
|
|
|
|
public static Document OpenDocument(Type typeDoc) {
|
|
DocTemplate doct = FindDocTemplate(typeDoc);
|
|
return doct.OpenDocument();
|
|
}
|
|
|
|
public static Document OpenDocument(string strFileName) {
|
|
string extFile = Path.GetExtension(strFileName);
|
|
foreach (DocTemplate doct in s_alsTemplates) {
|
|
string extDoc = doct.GetString(DocTemplate.Strings.FilterExt);
|
|
if (extFile == "." + extDoc)
|
|
return doct.OpenDocument(strFileName);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static bool SaveAllModified(Type type) {
|
|
foreach (DocTemplate doct in s_alsTemplates) {
|
|
if (type == null || doct.GetDocumentType() == type) {
|
|
if (!doct.SaveAllModified())
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static bool CloseAllDocuments() {
|
|
foreach (DocTemplate doct in s_alsTemplates) {
|
|
if (!doct.CloseAllDocuments())
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static Document GetActiveDocument(Type typeDoc) {
|
|
DocTemplate doct = FindDocTemplate(typeDoc);
|
|
return doct.GetActiveDocument();
|
|
}
|
|
|
|
public static void SetActiveDocument(Type typeDoc, Document doc) {
|
|
DocTemplate doct = FindDocTemplate(typeDoc);
|
|
doct.SetActiveDocument(doc);
|
|
}
|
|
}
|
|
|
|
public class DocTemplate {
|
|
string[] m_astr;
|
|
protected Type m_typeDoc;
|
|
protected Type m_typeFrame;
|
|
protected Type m_typeView;
|
|
protected ArrayList m_alsDocuments;
|
|
protected SerializationBinder m_serBinder;
|
|
protected Document m_docActive = null;
|
|
|
|
public delegate void DocActiveHandler(Document doc);
|
|
public event DocActiveHandler DocActive;
|
|
public delegate void DocAddedHandler(Document doc);
|
|
public event DocAddedHandler DocAdded;
|
|
public delegate void DocRemovedHandler(Document doc);
|
|
public event DocRemovedHandler DocRemoved;
|
|
|
|
public DocTemplate(string[] astr, Type typeDoc, Type typeFrame, Type typeView, SerializationBinder serBinder) {
|
|
m_astr = (string[])astr.Clone();
|
|
m_typeDoc = typeDoc;
|
|
m_typeFrame = typeFrame;
|
|
m_typeView = typeView;
|
|
m_alsDocuments = new ArrayList();
|
|
m_serBinder = serBinder;
|
|
}
|
|
|
|
public Type GetDocumentType() {
|
|
return m_typeDoc;
|
|
}
|
|
|
|
public virtual Document NewDocument(Object[] aobj) {
|
|
// Create a new (empty) document
|
|
|
|
Object[] aobjT = { this, null, aobj };
|
|
Document doc = (Document)System.Activator.CreateInstance(m_typeDoc, aobjT);
|
|
|
|
// Success?
|
|
|
|
if (doc == null)
|
|
return null;
|
|
|
|
// Add to doc list
|
|
|
|
AddDocument(doc);
|
|
return OpenFinish(doc);
|
|
}
|
|
|
|
public virtual Document OpenDocument() {
|
|
string strExt = GetString(DocTemplate.Strings.FilterExt);
|
|
string strFilterName = GetString(DocTemplate.Strings.FilterName);
|
|
string strTitle = GetString(DocTemplate.Strings.WindowTitle);
|
|
OpenFileDialog frmOpen = new OpenFileDialog();
|
|
frmOpen.DefaultExt = strExt;
|
|
frmOpen.Filter = strFilterName + " (*." + strExt + ")|*." + strExt;
|
|
frmOpen.Title = "Open " + strTitle;
|
|
if (frmOpen.ShowDialog() == DialogResult.Cancel)
|
|
return null;
|
|
return OpenDocument(frmOpen.FileName);
|
|
}
|
|
|
|
public virtual Document OpenDocument(string strFile) {
|
|
// Already open? If so, return the already open document after incrementing its open count
|
|
|
|
Document doc = null;
|
|
string strPath = Path.GetFullPath(strFile);
|
|
foreach (Document docT in m_alsDocuments) {
|
|
string strPathT = docT.GetPath();
|
|
if (strPathT == null)
|
|
continue;
|
|
if (strPathT.ToLower() == strPath.ToLower()) {
|
|
return OpenFinish(docT);
|
|
}
|
|
}
|
|
|
|
// Not already open - open it
|
|
|
|
Stream stm = null;
|
|
try {
|
|
Hashtable ht = new Hashtable();
|
|
ht.Add("DocTemplate", this);
|
|
ht.Add("Filename", strFile);
|
|
IFormatter fmtr = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File, ht));
|
|
if (m_serBinder != null)
|
|
fmtr.Binder = m_serBinder;
|
|
stm = new FileStream(strFile, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
doc = (Document)fmtr.Deserialize(stm);
|
|
stm.Close();
|
|
|
|
} catch (SerializationException ex) {
|
|
string strErr = String.Format("Failed to load {0}\n{1}", strFile, ex.ToString());
|
|
MessageBox.Show(strErr, "Deserialization Error");
|
|
|
|
if (stm != null)
|
|
stm.Close();
|
|
doc = null;
|
|
|
|
} catch (System.Reflection.TargetInvocationException ex) {
|
|
string strErr = String.Format("Failed to load {0}\n{1}", strFile, ex.ToString());
|
|
MessageBox.Show(strErr, "Deserialization TargetInvocation Error");
|
|
|
|
if (stm != null)
|
|
stm.Close();
|
|
doc = null;
|
|
}
|
|
|
|
// Success?
|
|
|
|
if (doc == null)
|
|
return null;
|
|
|
|
// Add to doc list
|
|
|
|
AddDocument(doc);
|
|
return OpenFinish(doc);
|
|
}
|
|
|
|
|
|
Document OpenFinish(Document doc) {
|
|
// This doc is being opened
|
|
|
|
doc.IncrementOpenCount();
|
|
|
|
// Doc is not modified
|
|
|
|
doc.SetModified(false);
|
|
|
|
// Make it active
|
|
|
|
SetActiveDocument(doc);
|
|
|
|
// Create a frame window of the desired type. It might already know what
|
|
// view type to create, but parameterize it just in case
|
|
|
|
if (m_typeFrame != null) {
|
|
Object[] aobjT = { DocManager.GetFrameParent(), doc, m_typeView };
|
|
System.Activator.CreateInstance(m_typeFrame, aobjT);
|
|
}
|
|
|
|
// The doc is ready to go
|
|
|
|
doc.InitDone();
|
|
return doc;
|
|
}
|
|
|
|
public virtual void AddDocument(Document doc) {
|
|
m_alsDocuments.Add(doc);
|
|
if (DocAdded != null)
|
|
DocAdded(doc);
|
|
}
|
|
|
|
public virtual void RemoveDocument(Document doc) {
|
|
m_alsDocuments.Remove(doc);
|
|
if (doc == m_docActive) {
|
|
if (m_alsDocuments.Count != 0) {
|
|
SetActiveDocument((Document)m_alsDocuments[0]);
|
|
} else {
|
|
SetActiveDocument(null);
|
|
}
|
|
}
|
|
if (DocRemoved != null)
|
|
DocRemoved(doc);
|
|
}
|
|
|
|
public virtual Document[] GetDocuments() {
|
|
return (Document[])m_alsDocuments.ToArray(typeof(Document));
|
|
}
|
|
|
|
public enum Strings { WindowTitle, NewFileName, FilterName, FilterExt };
|
|
|
|
public virtual string GetString(Strings enmStr) {
|
|
return m_astr[(int)enmStr];
|
|
}
|
|
|
|
public virtual bool SaveAllModified() {
|
|
foreach (Document doc in m_alsDocuments) {
|
|
if (doc.IsModified()) {
|
|
if (!doc.Save())
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public virtual bool CloseAllDocuments() {
|
|
while (m_alsDocuments.Count != 0) {
|
|
Document doc = (Document)m_alsDocuments[0];
|
|
if (!doc.Close())
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public virtual Document GetActiveDocument() {
|
|
return m_docActive;
|
|
}
|
|
|
|
public virtual void SetActiveDocument(Document docActive) {
|
|
if (Globals.PropertyGrid != null) {
|
|
if (Globals.PropertyGrid.SelectedObject != null) {
|
|
if (Globals.PropertyGrid.SelectedObject.GetType() == m_typeDoc) {
|
|
Globals.PropertyGrid.SelectedObject = (object)docActive;
|
|
} else {
|
|
Globals.PropertyGrid.SelectedObject = null;
|
|
}
|
|
}
|
|
}
|
|
if (m_docActive == docActive)
|
|
return;
|
|
m_docActive = docActive;
|
|
if (DocActive != null)
|
|
DocActive(docActive);
|
|
}
|
|
}
|
|
|
|
public class Document {
|
|
protected DocTemplate m_doct;
|
|
protected string m_strDir;
|
|
protected string m_strFileName;
|
|
protected bool m_fModified;
|
|
protected bool m_fIniting;
|
|
protected int m_cOpen;
|
|
|
|
public delegate void ModifiedChangedHandler(Document doc, bool fModified);
|
|
public event ModifiedChangedHandler ModifiedChanged;
|
|
public delegate void PathChangedHandler(Document doc);
|
|
public event PathChangedHandler PathChanged;
|
|
public delegate void OpenCountChangedHandler(Document doc);
|
|
public event OpenCountChangedHandler OpenCountChanged;
|
|
|
|
public Document(DocTemplate doct, string strFile) {
|
|
m_doct = doct;
|
|
SetPath(strFile);
|
|
m_fModified = false;
|
|
m_fIniting = true;
|
|
m_cOpen = 0;
|
|
}
|
|
|
|
public DocTemplate GetDocTemplate() {
|
|
return m_doct;
|
|
}
|
|
|
|
public virtual void InitDone() {
|
|
m_fIniting = false;
|
|
}
|
|
|
|
public bool IsModified() {
|
|
return m_fModified;
|
|
}
|
|
|
|
public void SetModified(bool fModified) {
|
|
if (m_fIniting)
|
|
return;
|
|
if (fModified == m_fModified)
|
|
return;
|
|
m_fModified = fModified;
|
|
if (ModifiedChanged != null)
|
|
ModifiedChanged(this, fModified);
|
|
}
|
|
|
|
public virtual string GetName() {
|
|
return m_doct.GetString(DocTemplate.Strings.NewFileName);
|
|
}
|
|
|
|
public virtual string GetPath() {
|
|
if (m_strFileName == null)
|
|
return null;
|
|
return m_strDir + Path.DirectorySeparatorChar + m_strFileName;
|
|
}
|
|
|
|
public virtual void SetPath(string strFile) {
|
|
string strDir;
|
|
string strFileName;
|
|
if (strFile == null) {
|
|
strDir = null;
|
|
strFileName = null;
|
|
} else {
|
|
strDir = Path.GetDirectoryName(Path.GetFullPath(strFile));
|
|
if (strDir == "")
|
|
strDir = ".";
|
|
strFileName = Path.GetFileName(strFile);
|
|
}
|
|
if (strDir != m_strDir || strFileName != m_strFileName) {
|
|
m_strDir = strDir;
|
|
m_strFileName = strFileName;
|
|
if (PathChanged != null)
|
|
PathChanged(this);
|
|
}
|
|
}
|
|
|
|
public virtual int GetOpenCount() {
|
|
return m_cOpen;
|
|
}
|
|
|
|
public virtual void DecrementOpenCount() {
|
|
m_cOpen--;
|
|
if (OpenCountChanged != null)
|
|
OpenCountChanged(this);
|
|
}
|
|
|
|
public virtual void IncrementOpenCount() {
|
|
m_cOpen++;
|
|
if (OpenCountChanged != null)
|
|
OpenCountChanged(this);
|
|
}
|
|
|
|
public virtual bool Save() {
|
|
if (m_strFileName == null)
|
|
return SaveAs(null);
|
|
return SaveHelper(m_strDir + Path.DirectorySeparatorChar + m_strFileName);
|
|
}
|
|
|
|
bool SaveHelper(string strFile) {
|
|
Stream stm = null;
|
|
try {
|
|
IFormatter fmtr = new BinaryFormatter();
|
|
stm = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.None);
|
|
fmtr.Serialize(stm, this);
|
|
stm.Close();
|
|
} catch (Exception ex) {
|
|
if (stm != null)
|
|
stm.Close();
|
|
MessageBox.Show("Error saving..." + ex.ToString());
|
|
return false;
|
|
}
|
|
|
|
SetPath(strFile);
|
|
SetModified(false);
|
|
return true;
|
|
}
|
|
|
|
public virtual bool SaveAs(string strFile) {
|
|
// Have a filename? use it.
|
|
|
|
if (strFile != null) {
|
|
if (SaveHelper(strFile)) {
|
|
SetPath(strFile);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Open dialog
|
|
|
|
if (m_strFileName != null)
|
|
strFile = m_strDir + Path.DirectorySeparatorChar + m_strFileName;
|
|
|
|
SaveFileDialog frmSave = new SaveFileDialog();
|
|
|
|
string strExt = m_doct.GetString(DocTemplate.Strings.FilterExt);
|
|
string strFilterName = m_doct.GetString(DocTemplate.Strings.FilterName);
|
|
string strTitle = m_doct.GetString(DocTemplate.Strings.WindowTitle);
|
|
string strFileNew = m_doct.GetString(DocTemplate.Strings.NewFileName);
|
|
|
|
frmSave.DefaultExt = strExt;
|
|
frmSave.Filter = strFilterName + " (*." + strExt + ")|*." + strExt;
|
|
frmSave.Title = "Save " + GetName() + " As...";
|
|
frmSave.FileName = strFile != null ? strFile : strFileNew;
|
|
if (frmSave.ShowDialog() == DialogResult.Cancel)
|
|
return false;
|
|
|
|
return SaveHelper(frmSave.FileName);
|
|
}
|
|
|
|
public bool Close() {
|
|
// Don't close if the open count is not zero yet
|
|
|
|
if (GetOpenCount() > 1) {
|
|
DecrementOpenCount();
|
|
return true;
|
|
}
|
|
|
|
// Ask if modified
|
|
|
|
if (m_fModified) {
|
|
string strName;
|
|
string strPath = GetPath();
|
|
if (strPath == null) {
|
|
strName = GetName();
|
|
} else {
|
|
strName = Path.GetFileName(strPath);
|
|
}
|
|
switch (MessageBox.Show("Save changes to " + strName + "?", Application.ProductName, MessageBoxButtons.YesNoCancel)) {
|
|
case DialogResult.Cancel:
|
|
return false;
|
|
|
|
case DialogResult.No:
|
|
break;
|
|
|
|
case DialogResult.Yes:
|
|
if (!Save())
|
|
return false;
|
|
break;
|
|
}
|
|
}
|
|
m_doct.RemoveDocument(this);
|
|
return true;
|
|
}
|
|
}
|
|
}
|