#region Disclaimer / License // Copyright (C) 2006, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace OSGeo.MapGuide.Maestro { /// /// Summary description for XmlEditor. /// public class XmlEditor : System.Windows.Forms.Form { private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel2; private bool m_allowClose = false; private System.Windows.Forms.Button OKBtn; private System.Windows.Forms.Button CancelBtn; private System.Windows.Forms.TextBox textEditor; private System.ComponentModel.IContainer components; private OSGeo.MapGuide.MaestroAPI.ServerConnectionI m_connection; private System.Windows.Forms.ToolBar toolBar; private System.Windows.Forms.ImageList toolbarImages; private System.Windows.Forms.ToolBarButton CopyClipboardButton; private System.Windows.Forms.ToolBarButton CutClipboardButton; private System.Windows.Forms.ToolBarButton PasteClipboardButton; private System.Windows.Forms.ToolBarButton toolBarButton1; private System.Windows.Forms.ToolBarButton UndoClipboardButton; private System.Windows.Forms.ToolBarButton RedoClipboardButton; private System.Windows.Forms.ToolBarButton toolBarButton2; private System.Windows.Forms.ToolBarButton ValidateButton; private System.Type m_serializeType; private bool m_modified = false; private System.Windows.Forms.ToolBarButton toolBarButton3; private System.Windows.Forms.ToolBarButton LaunchExternalEditorButton; private object m_serializedObject = null; private System.Windows.Forms.Label label1; private System.Windows.Forms.Panel LockedMessagePanel; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.IO.FileSystemWatcher m_fsw = null; private string m_tempfile = null; private System.Diagnostics.Process m_externalProcess = null; private System.Threading.Thread m_externalProcessWatcher = null; private Globalizator.Globalizator m_globalizor = null; public XmlEditor(object item, OSGeo.MapGuide.MaestroAPI.ServerConnectionI connection) : this() { textEditor.Text = System.Text.Encoding.UTF8.GetString(connection.SerializeObject(item).ToArray()); m_connection = connection; m_serializeType = item.GetType(); m_modified = false; m_serializedObject = item; } private XmlEditor() { // // Required for Windows Form Designer support // InitializeComponent(); m_globalizor = new Globalizator.Globalizator(this); } //TODO: Add syntax higlighting for the editor /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form 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.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(XmlEditor)); this.panel1 = new System.Windows.Forms.Panel(); this.CancelBtn = new System.Windows.Forms.Button(); this.OKBtn = new System.Windows.Forms.Button(); this.panel2 = new System.Windows.Forms.Panel(); this.textEditor = new System.Windows.Forms.TextBox(); this.LockedMessagePanel = new System.Windows.Forms.Panel(); this.label3 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.toolBar = new System.Windows.Forms.ToolBar(); this.CopyClipboardButton = new System.Windows.Forms.ToolBarButton(); this.CutClipboardButton = new System.Windows.Forms.ToolBarButton(); this.PasteClipboardButton = new System.Windows.Forms.ToolBarButton(); this.toolBarButton1 = new System.Windows.Forms.ToolBarButton(); this.UndoClipboardButton = new System.Windows.Forms.ToolBarButton(); this.RedoClipboardButton = new System.Windows.Forms.ToolBarButton(); this.toolBarButton2 = new System.Windows.Forms.ToolBarButton(); this.ValidateButton = new System.Windows.Forms.ToolBarButton(); this.toolBarButton3 = new System.Windows.Forms.ToolBarButton(); this.LaunchExternalEditorButton = new System.Windows.Forms.ToolBarButton(); this.toolbarImages = new System.Windows.Forms.ImageList(this.components); this.panel1.SuspendLayout(); this.panel2.SuspendLayout(); this.LockedMessagePanel.SuspendLayout(); this.SuspendLayout(); // // panel1 // this.panel1.Controls.Add(this.CancelBtn); this.panel1.Controls.Add(this.OKBtn); this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; this.panel1.Location = new System.Drawing.Point(0, 477); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(656, 48); this.panel1.TabIndex = 0; // // CancelBtn // this.CancelBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.CancelBtn.FlatStyle = System.Windows.Forms.FlatStyle.System; this.CancelBtn.Location = new System.Drawing.Point(332, 16); this.CancelBtn.Name = "CancelBtn"; this.CancelBtn.Size = new System.Drawing.Size(96, 24); this.CancelBtn.TabIndex = 1; this.CancelBtn.Text = "Cancel"; this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click); // // OKBtn // this.OKBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.OKBtn.FlatStyle = System.Windows.Forms.FlatStyle.System; this.OKBtn.Location = new System.Drawing.Point(212, 16); this.OKBtn.Name = "OKBtn"; this.OKBtn.Size = new System.Drawing.Size(96, 24); this.OKBtn.TabIndex = 0; this.OKBtn.Text = "OK"; this.OKBtn.Click += new System.EventHandler(this.OKBtn_Click); // // panel2 // this.panel2.Controls.Add(this.textEditor); this.panel2.Controls.Add(this.LockedMessagePanel); this.panel2.Controls.Add(this.toolBar); this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; this.panel2.Location = new System.Drawing.Point(0, 0); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(656, 477); this.panel2.TabIndex = 1; // // textEditor // this.textEditor.AcceptsReturn = true; this.textEditor.AcceptsTab = true; this.textEditor.Dock = System.Windows.Forms.DockStyle.Fill; this.textEditor.Location = new System.Drawing.Point(0, 96); this.textEditor.Multiline = true; this.textEditor.Name = "textEditor"; this.textEditor.ScrollBars = System.Windows.Forms.ScrollBars.Both; this.textEditor.Size = new System.Drawing.Size(656, 381); this.textEditor.TabIndex = 0; this.textEditor.Text = ""; this.textEditor.TextChanged += new System.EventHandler(this.textEditor_TextChanged); // // LockedMessagePanel // this.LockedMessagePanel.Controls.Add(this.label3); this.LockedMessagePanel.Controls.Add(this.label2); this.LockedMessagePanel.Controls.Add(this.label1); this.LockedMessagePanel.Dock = System.Windows.Forms.DockStyle.Top; this.LockedMessagePanel.Location = new System.Drawing.Point(0, 28); this.LockedMessagePanel.Name = "LockedMessagePanel"; this.LockedMessagePanel.Size = new System.Drawing.Size(656, 68); this.LockedMessagePanel.TabIndex = 2; this.LockedMessagePanel.Visible = false; // // label3 // this.label3.Location = new System.Drawing.Point(8, 24); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(632, 16); this.label3.TabIndex = 2; this.label3.Text = "The text display will automatically update when the editor saves the file."; // // label2 // this.label2.Location = new System.Drawing.Point(8, 40); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(632, 16); this.label2.TabIndex = 1; this.label2.Text = "Close the external program to restore editing functionality in this xml editor."; // // label1 // this.label1.Location = new System.Drawing.Point(8, 8); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(632, 16); this.label1.TabIndex = 0; this.label1.Text = "The application associated with xml editing has been started."; // // toolBar // this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] { this.CopyClipboardButton, this.CutClipboardButton, this.PasteClipboardButton, this.toolBarButton1, this.UndoClipboardButton, this.RedoClipboardButton, this.toolBarButton2, this.ValidateButton, this.toolBarButton3, this.LaunchExternalEditorButton}); this.toolBar.DropDownArrows = true; this.toolBar.ImageList = this.toolbarImages; this.toolBar.Location = new System.Drawing.Point(0, 0); this.toolBar.Name = "toolBar"; this.toolBar.ShowToolTips = true; this.toolBar.Size = new System.Drawing.Size(656, 28); this.toolBar.TabIndex = 1; this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick); // // CopyClipboardButton // this.CopyClipboardButton.ImageIndex = 0; this.CopyClipboardButton.ToolTipText = "Copy selected text to the clipboard"; // // CutClipboardButton // this.CutClipboardButton.ImageIndex = 1; this.CutClipboardButton.ToolTipText = "Cut the selected text and place it in the clipboard"; // // PasteClipboardButton // this.PasteClipboardButton.ImageIndex = 2; this.PasteClipboardButton.ToolTipText = "Paste text from the clipboard"; // // toolBarButton1 // this.toolBarButton1.Style = System.Windows.Forms.ToolBarButtonStyle.Separator; // // UndoClipboardButton // this.UndoClipboardButton.ImageIndex = 3; this.UndoClipboardButton.ToolTipText = "Undo the last action"; // // RedoClipboardButton // this.RedoClipboardButton.ImageIndex = 4; this.RedoClipboardButton.ToolTipText = "Redo the last action"; // // toolBarButton2 // this.toolBarButton2.Style = System.Windows.Forms.ToolBarButtonStyle.Separator; // // ValidateButton // this.ValidateButton.ImageIndex = 5; this.ValidateButton.ToolTipText = "Validate the current xml"; // // toolBarButton3 // this.toolBarButton3.Style = System.Windows.Forms.ToolBarButtonStyle.Separator; // // LaunchExternalEditorButton // this.LaunchExternalEditorButton.ImageIndex = 6; this.LaunchExternalEditorButton.ToolTipText = "Launch the system editor associated with xml files"; // // toolbarImages // this.toolbarImages.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; this.toolbarImages.ImageSize = new System.Drawing.Size(16, 16); this.toolbarImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("toolbarImages.ImageStream"))); this.toolbarImages.TransparentColor = System.Drawing.Color.Transparent; // // XmlEditor // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(656, 525); this.Controls.Add(this.panel2); this.Controls.Add(this.panel1); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MinimizeBox = false; this.Name = "XmlEditor"; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "XmlEditor"; this.Closing += new System.ComponentModel.CancelEventHandler(this.XmlEditor_Closing); this.Load += new System.EventHandler(this.XmlEditor_Load); this.panel1.ResumeLayout(false); this.panel2.ResumeLayout(false); this.LockedMessagePanel.ResumeLayout(false); this.ResumeLayout(false); } #endregion private void OKBtn_Click(object sender, System.EventArgs e) { if (ValidateXml()) { EndExternalEditing(false); m_allowClose = true; this.DialogResult = DialogResult.OK; this.Close(); } } private void CancelBtn_Click(object sender, System.EventArgs e) { if (m_modified && MessageBox.Show(this, m_globalizor.Translate("Do you want to close this dialog and discard all changes?"), Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes) return; EndExternalEditing(false); m_allowClose = true; this.DialogResult = DialogResult.Cancel; this.Close(); } private void XmlEditor_Load(object sender, System.EventArgs e) { } private void XmlEditor_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (!m_allowClose) { CancelBtn.PerformClick(); if (!m_allowClose) e.Cancel = true; } } private void toolBar_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e) { if (e.Button == CopyClipboardButton) textEditor.Copy(); else if (e.Button == CutClipboardButton) textEditor.Cut(); else if (e.Button == PasteClipboardButton) textEditor.Paste(); else if (e.Button == UndoClipboardButton) textEditor.Undo(); else if (e.Button == RedoClipboardButton) {} else if (e.Button == ValidateButton) ValidateXml(); else if (e.Button == LaunchExternalEditorButton) { try { m_tempfile = System.IO.Path.GetTempFileName(); try { System.IO.File.Delete(m_tempfile); } catch { } m_tempfile += ".xml"; using (System.IO.StreamWriter sw = new System.IO.StreamWriter(m_tempfile, false, System.Text.Encoding.UTF8)) sw.Write(textEditor.Text); m_fsw = new System.IO.FileSystemWatcher(System.IO.Path.GetDirectoryName(m_tempfile), System.IO.Path.GetFileName(m_tempfile)); m_fsw.Changed += new System.IO.FileSystemEventHandler(m_fsw_Changed); m_fsw.EnableRaisingEvents = true; m_externalProcess = new System.Diagnostics.Process(); m_externalProcess.StartInfo.UseShellExecute = true; m_externalProcess.StartInfo.Verb = "edit"; m_externalProcess.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(m_tempfile); m_externalProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized; m_externalProcess.StartInfo.FileName = m_tempfile; m_externalProcess.Start(); m_externalProcessWatcher = new System.Threading.Thread(new System.Threading.ThreadStart(WaitForExternalProcess)); m_externalProcessWatcher.IsBackground = true; m_externalProcessWatcher.Start(); LockedMessagePanel.Visible = true; toolBar.Enabled = false; textEditor.ReadOnly = true; } catch (Exception ex) { EndExternalEditing(false); MessageBox.Show(this, string.Format(m_globalizor.Translate("Failed to start external editor, most likely this means that theres is no external editor associated with xml files.\nError message was: {0}"), ex.ToString()), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } private void WaitForExternalProcess() { try { m_externalProcess.WaitForExit(); } catch(System.Threading.ThreadAbortException) { return; } catch { } this.Invoke(new EndExternalEditingDelegate(EndExternalEditing), new object[] { true }); } private delegate void EndExternalEditingDelegate(bool fromThread); private void EndExternalEditing(bool fromThread) { if (m_externalProcessWatcher != null) { if (!fromThread && m_externalProcessWatcher.IsAlive) { m_externalProcessWatcher.Abort(); m_externalProcessWatcher.Join(500); } m_externalProcessWatcher = null; } if (m_fsw != null) { m_fsw.EnableRaisingEvents = false; m_fsw.Dispose(); m_fsw = null; } if (m_externalProcess != null) { m_externalProcess.Dispose(); m_externalProcess = null; } if (m_tempfile != null) { try { System.IO.File.Delete(m_tempfile); } catch { } m_tempfile = null; } LockedMessagePanel.Visible = false; toolBar.Enabled = true; textEditor.ReadOnly = false; } private bool ValidateXml() { try { System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(textEditor.Text)); object o = m_connection.DeserializeObject(m_serializeType, ms); if (o.GetType() != m_serializeType) throw new Exception(string.Format(m_globalizor.Translate("Item did not correspond to the desired type.\nXml gave type: {0}\nExpected type was: {1}"), o.GetType().FullName, m_serializeType.FullName)); m_serializedObject = o; return true; } catch (Exception ex) { MessageBox.Show(this, string.Format(m_globalizor.Translate("The entered xml failed to serialize into an object.\nError message is: {0}"), ex.ToString()), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } public object SerializedObject { get { return m_serializedObject; } } private void textEditor_TextChanged(object sender, System.EventArgs e) { m_modified = true; } private void m_fsw_Changed(object sender, System.IO.FileSystemEventArgs e) { try { using(System.IO.StreamReader sr = new System.IO.StreamReader(m_tempfile)) textEditor.Text = sr.ReadToEnd(); } catch { } } } }