#region Disclaimer / License // Copyright (C) 2009, 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.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using OSGeo.MapGuide.MaestroAPI; using OSGeo.MapGuide.MaestroAPI.Exceptions; using OSGeo.MapGuide.MaestroAPI.Resource; using System.IO; using Maestro.Packaging; namespace Maestro.Editors.Packaging { /// /// A dialog for editing the contents of a MapGuide Package /// public partial class PackageEditorDialog : Form { private string m_filename; private Dictionary m_resources; private IServerConnection _conn; /// /// Initializes a new instance of the class. /// /// The filename. /// The conn. public PackageEditorDialog(string filename, IServerConnection conn) : this() { _conn = conn; m_filename = filename; m_resources = new Dictionary(); ResourceTree.ImageList = RepositoryIcons.CreateImageList(); //owner.ResourceEditorMap.SmallImageList; ResourceDataFileList.SmallImageList = RepositoryIcons.CreateImageList(); //ResourceEditors.ShellIcons.ImageList; } private PackageEditorDialog() { InitializeComponent(); } private void PackageEditor_Load(object sender, EventArgs e) { this.Show(); try { m_resources = PackageProgress.ListPackageContents(this, _conn, m_filename); if (m_resources == null) { this.DialogResult = DialogResult.Cancel; this.Close(); return; } RebuildTree(); } catch (Exception ex) { if (ex is System.Reflection.TargetInvocationException && ex.InnerException != null) ex = ex.InnerException; string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); MessageBox.Show(this, string.Format(Properties.Resources.PackageReadError, msg), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); this.DialogResult = DialogResult.Cancel; this.Close(); return; } OKBtn.Enabled = true; } private void RebuildTree() { ResourceTree.Nodes.Clear(); TreeNode root = ResourceTree.Nodes.Add("Library://"); root.ImageIndex = root.SelectedImageIndex = RepositoryIcons.RES_ROOT; foreach (ResourceItem ri in m_resources.Values) { string partial = ri.ResourcePath.Substring(root.Text.Length); string[] parts = partial.Split('/'); TreeNode cur = root; root.Expand(); for (int i = 0; i < parts.Length - 1; i++) { TreeNode next = null; foreach (TreeNode n in cur.Nodes) if (n.Text == parts[i]) { next = n; break; } if (next == null) { cur = cur.Nodes.Add(parts[i]); cur.ImageIndex = cur.SelectedImageIndex = RepositoryIcons.RES_FOLDER; } else cur = next; cur.Expand(); } if (parts[parts.Length - 1].Trim().Length > 0) { TreeNode n = cur.Nodes.Add(parts[parts.Length - 1]); n.Tag = ri; n.ImageIndex = n.SelectedImageIndex = RepositoryIcons.GetImageIndexForResourceType(ResourceIdentifier.GetResourceType(ri.ResourcePath)); } else cur.Tag = ri; } } private void MainGroup_Panel2_Paint(object sender, PaintEventArgs e) { } private void ResourcDataFileList_SelectedIndexChanged(object sender, EventArgs e) { DeleteResourceButton.Enabled = EditResourceData.Enabled = SaveResourceData.Enabled = ResourceDataFileList.SelectedItems.Count == 1; } private void AddResourceData_Click(object sender, EventArgs e) { if (BrowseResourceDataFile.ShowDialog(this) == DialogResult.OK) { ResourceDataItem rdi = new ResourceDataItem( System.IO.Path.GetFileName(BrowseResourceDataFile.FileName), "application/octet-stream", BrowseResourceDataFile.FileName, "File"); rdi.EntryType = EntryTypeEnum.Added; ((ResourceItem)ResourceTree.SelectedNode.Tag).Items.Add(rdi); RefreshFileList(); } } private void RefreshFileList() { ResourceDataFileList.Items.Clear(); foreach (ResourceDataItem rdi in ((ResourceItem)ResourceTree.SelectedNode.Tag).Items) if (rdi.EntryType != EntryTypeEnum.Deleted) { var lvi = new ListViewItem(new string[] { rdi.ResourceName, rdi.ContentType, rdi.DataType.ToString(), rdi.Filename }); ResourceDataFileList.Items.Add(lvi).Tag = rdi; } } private void ResourceTree_AfterSelect(object sender, TreeViewEventArgs e) { DeleteResourceButton.Enabled = MainGroup.Panel2.Enabled = (ResourceTree.SelectedNode != null && ResourceTree.SelectedNode.Tag as ResourceItem != null); if (MainGroup.Panel2.Enabled) { HeaderFilepath.Text = ((ResourceItem)ResourceTree.SelectedNode.Tag).Headerpath; ContentFilePath.Text = ((ResourceItem)ResourceTree.SelectedNode.Tag).Contentpath; RefreshFileList(); } } private void DeleteResourceData_Click(object sender, EventArgs e) { if (ResourceDataFileList.SelectedItems.Count != 1 || ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem == null) return; (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).EntryType = EntryTypeEnum.Deleted; RefreshFileList(); } private void SaveResourceData_Click(object sender, EventArgs e) { try { if (ResourceDataFileList.SelectedItems.Count != 1 || ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem == null) return; SaveResourceDataFile.FileName = System.IO.Path.GetFileName((ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).Filename); if (SaveResourceDataFile.ShowDialog(this) != DialogResult.OK) return; if ((ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).Filename == SaveResourceDataFile.FileName) return; if ((ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).EntryType == EntryTypeEnum.Regular) { using(ICSharpCode.SharpZipLib.Zip.ZipFile zipfile = new ICSharpCode.SharpZipLib.Zip.ZipFile(m_filename)) { int index = FindZipEntry(zipfile, (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).Filename); if (index >= 0) using (System.IO.FileStream fs = new System.IO.FileStream(SaveResourceDataFile.FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None)) Utility.CopyStream(zipfile.GetInputStream(index), fs); } } else if ((ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).EntryType == EntryTypeEnum.Added) { System.IO.File.Copy((ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).Filename, SaveResourceDataFile.FileName, true); } } catch (Exception ex) { string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); MessageBox.Show(this, string.Format(Properties.Resources.FileCopyError, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void EditResourceData_Click(object sender, EventArgs e) { if (ResourceDataFileList.SelectedItems.Count != 1 || ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem == null) return; var dlg = new EditResourceDataEntryDialog(); dlg.ResourceName = (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).ResourceName; dlg.ContentType = (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).ContentType; dlg.DataType = (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).DataType; dlg.Filename = (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).Filename; if (dlg.ShowDialog(this) == DialogResult.OK) { (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).ResourceName = dlg.ResourceName; (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).ContentType = dlg.ContentType; (ResourceDataFileList.SelectedItems[0].Tag as ResourceDataItem).DataType = dlg.DataType; RefreshFileList(); } } private void ResourceDataFileList_DoubleClick(object sender, EventArgs e) { EditResourceData_Click(sender, e); } private void ResourceTree_DragDrop(object sender, DragEventArgs e) { TreeNode x = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (x == null || x.Tag == null) return; TreeNode n = ResourceTree.GetNodeAt(ResourceTree.PointToClient(new Point(e.X, e.Y))); if (n != null && n.Tag as ResourceItem != null && (n.Tag as ResourceItem).IsFolder) { //Can't drag onto its' own child TreeNode t = n; while (t.Parent != null) if (t == x) return; else t = t.Parent; x.Remove(); n.Nodes.Add(x); } else return; } private void ResourceTree_DragOver(object sender, DragEventArgs e) { TreeNode x = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (x == null || x.Tag == null) { e.Effect = DragDropEffects.None; return; } TreeNode n = ResourceTree.GetNodeAt(ResourceTree.PointToClient(new Point(e.X, e.Y))); if (n != null && n.Tag as ResourceItem != null && (n.Tag as ResourceItem).IsFolder) { //Can't drag onto its' own child TreeNode t = n; while (t.Parent != null) if (t == x) { e.Effect = DragDropEffects.None; return; } else t = t.Parent; e.Effect = DragDropEffects.Move; } else e.Effect = DragDropEffects.None; } private void ResourceTree_ItemDrag(object sender, ItemDragEventArgs e) { ResourceTree.DoDragDrop(e.Item, DragDropEffects.Move); } private void AddFolderButton_Click(object sender, EventArgs e) { TreeNode n = new TreeNode(Properties.Resources.NewFolder, RepositoryIcons.RES_FOLDER, RepositoryIcons.RES_FOLDER); n.Tag = new ResourceItem("", "", ""); (n.Tag as ResourceItem).EntryType = EntryTypeEnum.Added; (n.Tag as ResourceItem).IsFolder = true; if (ResourceTree.SelectedNode == null || ResourceTree.SelectedNode.Parent == null) ResourceTree.Nodes[0].Nodes.Add(n); else if (ResourceTree.SelectedNode.Tag as ResourceItem != null) { if ((ResourceTree.SelectedNode.Tag as ResourceItem).IsFolder) ResourceTree.SelectedNode.Nodes.Add(n); else if (ResourceTree.SelectedNode.Parent == null) ResourceTree.Nodes[0].Nodes.Add(n); else ResourceTree.SelectedNode.Parent.Nodes.Add(n); } n.EnsureVisible(); ResourceTree.SelectedNode = n; ResourceTree.Focus(); } private void DeleteResourceButton_Click(object sender, EventArgs e) { if (ResourceTree.SelectedNode == null || ResourceTree.SelectedNode.Tag as ResourceItem == null) return; if (MessageBox.Show(this, Properties.Resources.DeleteConfirmation, Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes) return; TreeNode root = ResourceTree.SelectedNode; Queue lst = new Queue(); lst.Enqueue(root); while (lst.Count > 0) { TreeNode n = lst.Dequeue(); foreach (TreeNode tn in n.Nodes) lst.Enqueue(tn); if (n.Tag as ResourceItem != null) { if ((n.Tag as ResourceItem).EntryType == EntryTypeEnum.Regular) { for (int i = 0; i < (n.Tag as ResourceItem).Items.Count; i++) if ((n.Tag as ResourceItem).Items[i].EntryType == EntryTypeEnum.Added) { (n.Tag as ResourceItem).Items.RemoveAt(i); i--; } } (n.Tag as ResourceItem).EntryType = EntryTypeEnum.Deleted; } } root.Remove(); } private void AddResourceButton_Click(object sender, EventArgs e) { var dlg = new AddResourceEntryDialog(); if (dlg.ShowDialog(this) == DialogResult.OK) { int imageindex = RepositoryIcons.GetImageIndexForResourceType((ResourceTypes)Enum.Parse(typeof(ResourceTypes), Path.GetExtension(dlg.ResourceName).Replace(".", ""))); TreeNode n = new TreeNode(dlg.ResourceName, imageindex, imageindex); ResourceItem i = new ResourceItem("", dlg.HeaderFilepath, dlg.ContentFilepath); i.EntryType = EntryTypeEnum.Added; n.Tag = i; if (ResourceTree.SelectedNode == null || ResourceTree.SelectedNode.Parent == null) ResourceTree.Nodes[0].Nodes.Add(n); else if (ResourceTree.SelectedNode.Tag as ResourceItem != null) { if ((ResourceTree.SelectedNode.Tag as ResourceItem).IsFolder) ResourceTree.SelectedNode.Nodes.Add(n); else if (ResourceTree.SelectedNode.Parent == null) ResourceTree.Nodes[0].Nodes.Add(n); else ResourceTree.SelectedNode.Parent.Nodes.Add(n); } n.EnsureVisible(); ResourceTree.SelectedNode = n; ResourceTree.Focus(); } } private void OKBtn_Click(object sender, EventArgs e) { SavePackageDialog.FileName = m_filename; if (SavePackageDialog.ShowDialog(this) != DialogResult.OK) return; //Preparation: Update all resources with the correct path, and build a list with them List items = new List(); try { ResourceTree.PathSeparator = "/"; ResourceTree.Nodes[0].Text = "Library:/"; Queue nl = new Queue(); foreach (TreeNode n in ResourceTree.Nodes[0].Nodes) nl.Enqueue(n); while (nl.Count > 0) { TreeNode n = nl.Dequeue(); foreach (TreeNode tn in n.Nodes) nl.Enqueue(tn); if (n.Tag as ResourceItem != null && (n.Tag as ResourceItem).EntryType != EntryTypeEnum.Deleted) { ResourceItem ri = new ResourceItem(n.Tag as ResourceItem); ri.ResourcePath = n.FullPath + (ri.IsFolder ? "/" : ""); if (string.IsNullOrEmpty(ri.OriginalResourcePath)) ri.OriginalResourcePath = ri.ResourcePath; items.Add(ri); } } } finally { ResourceTree.Nodes[0].Text = "Library://"; } try { if (PackageProgress.RebuildPackage(this, _conn, m_filename, items, SavePackageDialog.FileName, InsertDeleteCommands.Checked) != DialogResult.OK) return; } catch (Exception ex) { if (ex is System.Reflection.TargetInvocationException && ex.InnerException != null) ex = ex.InnerException; string msg = NestedExceptionMessageProcessor.GetFullMessage(ex); MessageBox.Show(this, string.Format(Properties.Resources.PackageBuildError, msg), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } finally { } this.DialogResult = DialogResult.OK; this.Close(); } private int FindZipEntry(ICSharpCode.SharpZipLib.Zip.ZipFile file, string path) { string p = path.Replace('\\', '/'); foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in file) if (ze.Name.Replace('\\', '/').Equals(p)) return (int)ze.ZipFileIndex; return -1; } } }