From 1772394d28ece70d4752020c8279289bdb731c5d Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Thu, 3 Oct 2019 02:41:25 -0400 Subject: [PATCH] Implemented loads of expected functionality for FileSystemEditor - needs a lot of improvement though --- .../Commands.uexml | 62 +++ ...lEditor.Content.PlatformIndependent.csproj | 2 + .../ObjectModels/FileSystem/Folder.cs | 14 + .../Dialogs/FilePropertiesDialog.cs | 104 +++++ .../FileSystem/FileSystemEditor.Designer.cs | 33 +- .../Editors/FileSystem/FileSystemEditor.cs | 359 ++++++++++++++++-- .../Editors/FileSystem/FileSystemSelection.cs | 13 +- .../MainWindow.cs | 32 +- .../TemporaryFileManager.cs | 7 + .../UniversalEditor.UserInterface.csproj | 2 + 10 files changed, 582 insertions(+), 46 deletions(-) create mode 100644 CSharp/Content/UniversalEditor.Content.PlatformIndependent/Editors/UniversalEditor.Editors.FileSystem.FileSystemEditor/Commands.uexml create mode 100644 CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/Dialogs/FilePropertiesDialog.cs diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Editors/UniversalEditor.Editors.FileSystem.FileSystemEditor/Commands.uexml b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Editors/UniversalEditor.Editors.FileSystem.FileSystemEditor/Commands.uexml new file mode 100644 index 00000000..f55992bf --- /dev/null +++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Editors/UniversalEditor.Editors.FileSystem.FileSystemEditor/Commands.uexml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj index efd918f6..f0d152ac 100644 --- a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj +++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj @@ -641,6 +641,7 @@ + @@ -656,6 +657,7 @@ + diff --git a/CSharp/Libraries/UniversalEditor.Essential/ObjectModels/FileSystem/Folder.cs b/CSharp/Libraries/UniversalEditor.Essential/ObjectModels/FileSystem/Folder.cs index 6d9eff77..e335c6b4 100644 --- a/CSharp/Libraries/UniversalEditor.Essential/ObjectModels/FileSystem/Folder.cs +++ b/CSharp/Libraries/UniversalEditor.Essential/ObjectModels/FileSystem/Folder.cs @@ -186,5 +186,19 @@ namespace UniversalEditor.ObjectModels.FileSystem } return file; } + + public IFileSystemObject[] GetContents() + { + List fsos = new List(); + foreach (Folder folder in Folders) + { + fsos.Add(folder); + } + foreach (File file in Files) + { + fsos.Add(file); + } + return fsos.ToArray(); + } } } diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/Dialogs/FilePropertiesDialog.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/Dialogs/FilePropertiesDialog.cs new file mode 100644 index 00000000..ab7bbcca --- /dev/null +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/Dialogs/FilePropertiesDialog.cs @@ -0,0 +1,104 @@ +// +// FilePropertiesDialog.cs +// +// Author: +// Mike Becker +// +// Copyright (c) 2019 Mike Becker +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.ComponentModel; +using MBS.Framework.UserInterface; +using MBS.Framework.UserInterface.Controls; +using MBS.Framework.UserInterface.Layouts; +using UniversalEditor.ObjectModels.FileSystem; + +namespace UniversalEditor.Editors.FileSystem.Dialogs +{ + public class FilePropertiesDialog : Dialog + { + private TextBox txtFileName = null; + private TextBox txtFileType = null; + private TextBox txtFileSize = null; + private TextBox txtFileDate = null; + + public static DialogResult ShowDialog(IFileSystemObject fso) + { + FilePropertiesDialog dlg = new FilePropertiesDialog(); + dlg.Text = String.Format("{0} Properties", fso.Name); + dlg.txtFileName.Text = fso.Name; + + if (fso is Folder) + { + Folder f = fso as Folder; + dlg.txtFileType.Text = "Folder"; + dlg.txtFileSize.Text = String.Format("{0} files, {1} folders", f.Files.Count, f.Folders.Count); + } + else if (fso is File) + { + File f = fso as File; + dlg.txtFileType.Text = System.IO.Path.GetExtension(f.Name) + " File"; + dlg.txtFileSize.Text = UniversalEditor.UserInterface.Common.FileInfo.FormatSize(f.Size); + } + + if (dlg.ShowDialog() == DialogResult.OK) + { + fso.Name = dlg.txtFileName.Text; + return DialogResult.OK; + } + return DialogResult.Cancel; + } + + public FilePropertiesDialog() + { + Layout = new BoxLayout(Orientation.Vertical); + Size = new MBS.Framework.Drawing.Dimension2D(400, 600); + + TabContainer tbs = new TabContainer(); + + TabPage tabGeneral = new TabPage(); + tabGeneral.Text = "General"; + tabGeneral.Layout = new GridLayout(); + + tabGeneral.Controls.Add(new Label("_Name"), new GridLayout.Constraints(0, 0)); + txtFileName = new TextBox(); + tabGeneral.Controls.Add(txtFileName, new GridLayout.Constraints(0, 1, 1, 2, ExpandMode.Horizontal)); + + tabGeneral.Controls.Add(new Label("_Size"), new GridLayout.Constraints(1, 0)); + txtFileSize = new TextBox(); + txtFileSize.Editable = false; + tabGeneral.Controls.Add(txtFileSize, new GridLayout.Constraints(1, 1, 1, 2, ExpandMode.Horizontal)); + + tabGeneral.Controls.Add(new Label("_Type"), new GridLayout.Constraints(2, 0)); + txtFileType = new TextBox(); + txtFileType.Editable = false; + tabGeneral.Controls.Add(txtFileType, new GridLayout.Constraints(2, 1, 1, 2, ExpandMode.Horizontal)); + + Button cmdChangeType = new Button("C_hange..."); + tabGeneral.Controls.Add(cmdChangeType, new GridLayout.Constraints(2, 2, 1, 1)); + + tabGeneral.Controls.Add(new Label("_Date modified"), new GridLayout.Constraints(3, 0)); + txtFileDate = new TextBox(); + tabGeneral.Controls.Add(txtFileDate, new GridLayout.Constraints(3, 1, 1, 2, ExpandMode.Horizontal)); + + tbs.TabPages.Add(tabGeneral); + + Controls.Add(tbs, new BoxLayout.Constraints(true, true)); + + Buttons.Add(new Button(ButtonStockType.OK, DialogResult.OK)); + Buttons.Add(new Button(ButtonStockType.Cancel, DialogResult.Cancel)); + } + } +} diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.Designer.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.Designer.cs index da6e16b6..e3ea93d6 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.Designer.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.Designer.cs @@ -21,6 +21,7 @@ using System; using MBS.Framework.UserInterface; using MBS.Framework.UserInterface.Controls; +using MBS.Framework.UserInterface.Dialogs; using MBS.Framework.UserInterface.Input.Mouse; using MBS.Framework.UserInterface.Layouts; @@ -34,8 +35,13 @@ namespace UniversalEditor.Editors.FileSystem private Menu contextMenuUnselected = new Menu(); private Menu contextMenuSelected = new Menu(); + private CommandMenuItem contextMenuUnselectedPaste = null; + private CommandMenuItem contextMenuUnselectedPasteShortcut = new CommandMenuItem("Paste _shortcut"); + private void InitializeComponent() { + contextMenuUnselectedPaste = new CommandMenuItem("_Paste", null, contextMenuUnselectedPaste_Click); + this.Layout = new BoxLayout(Orientation.Vertical); this.tmTreeView = new DefaultTreeModel(new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) }); @@ -45,6 +51,7 @@ namespace UniversalEditor.Editors.FileSystem this.tv.SelectionMode = SelectionMode.Multiple; this.tv.Model = this.tmTreeView; + // these need to somehow be loaded from xml contextMenuUnselected.Items.AddRange(new MenuItem[] { new CommandMenuItem("_View", new MenuItem[] @@ -67,14 +74,24 @@ namespace UniversalEditor.Editors.FileSystem new CommandMenuItem("_Auto arrange"), new CommandMenuItem("A_lign to grid") }), - new CommandMenuItem("_Refresh"), + new CommandMenuItem("R_efresh"), new SeparatorMenuItem(), - new CommandMenuItem("_Paste"), - new CommandMenuItem("Paste _shortcut"), + contextMenuUnselectedPaste, + contextMenuUnselectedPasteShortcut, new SeparatorMenuItem(), + new CommandMenuItem("A_dd", new MenuItem[] + { + new CommandMenuItem("Ne_w Item", null, delegate(object sender, EventArgs e) { MessageDialog.ShowDialog("TODO: Implement a way to open a new document editor for an embedded file", "Not Implemented", MessageDialogButtons.OK, MessageDialogIcon.Warning); }), + new CommandMenuItem("E_xisting Item...", null, FileAddExistingItem_Click), + new SeparatorMenuItem(), + new CommandMenuItem("New Fol_der", null, FileNewFolder_Click), + new CommandMenuItem("Existin_g Folder...", null, FileAddItemsFromFolder_Click), + new SeparatorMenuItem(), + new CommandMenuItem("_Files from Folder...", null, FileAddExistingFolder_Click) + }), new CommandMenuItem("Ne_w", new MenuItem[] { - new CommandMenuItem("_Folder"), + new CommandMenuItem("_Folder", null, FileNewFolder_Click), new CommandMenuItem("_Shortcut"), new SeparatorMenuItem(), new CommandMenuItem("Briefcase"), @@ -85,7 +102,7 @@ namespace UniversalEditor.Editors.FileSystem new CommandMenuItem("Compressed (zipped) folder") }), new SeparatorMenuItem(), - new CommandMenuItem("P_roperties") + new CommandMenuItem("P_roperties", null, ContextMenuProperties_Click) }); contextMenuSelected.Items.AddRange(new MenuItem[] @@ -104,10 +121,10 @@ namespace UniversalEditor.Editors.FileSystem new CommandMenuItem("Copy to...", null, ContextMenuCopyTo_Click), new SeparatorMenuItem(), new CommandMenuItem("Create _shortcut"), - new CommandMenuItem("_Delete"), - new CommandMenuItem("Rena_me"), + new CommandMenuItem("_Delete", null, ContextMenuDelete_Click), + new CommandMenuItem("Rena_me", null, ContextMenuRename_Click), new SeparatorMenuItem(), - new CommandMenuItem("P_roperties") + new CommandMenuItem("P_roperties", null, ContextMenuProperties_Click) }); this.tv.BeforeContextMenu += tv_BeforeContextMenu; diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs index ee1d0e2e..c743ecfb 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs @@ -28,6 +28,7 @@ using MBS.Framework.UserInterface.Dialogs; using MBS.Framework.UserInterface.DragDrop; using MBS.Framework.UserInterface.Input.Keyboard; using MBS.Framework.UserInterface.Input.Mouse; +using UniversalEditor.Editors.FileSystem.Dialogs; namespace UniversalEditor.Editors.FileSystem { @@ -42,7 +43,7 @@ namespace UniversalEditor.Editors.FileSystem { while (tv.SelectedRows.Count > 0) { - if (tv.SelectedRows[0].GetExtraData("item") == sel.Item) + if (tv.SelectedRows[0].GetExtraData("item") == sel.Items[0]) { tmTreeView.Rows.Remove(tv.SelectedRows[0]); break; @@ -62,6 +63,20 @@ namespace UniversalEditor.Editors.FileSystem this.tv.DragDropDataRequest += tv_DragDropDataRequest; } + private void ContextMenuDelete_Click(object sender, EventArgs e) + { + // forward to EditDelete - this will be unnecessary once we implement these menu item definitions as XML + if (Application.Commands["EditDelete"] != null) + Application.Commands["EditDelete"].Execute(); + } + + private void contextMenuUnselectedPaste_Click(object sender, EventArgs e) + { + // forward to EditPaste - this will be unnecessary once we implement these menu item definitions as XML + if (Application.Commands["EditPaste"] != null) + Application.Commands["EditPaste"].Execute(); + } + private void tv_DragDropDataRequest(object sender, DragDropDataRequestEventArgs e) { if (tv.SelectedRows.Count == 0) return; @@ -80,10 +95,249 @@ namespace UniversalEditor.Editors.FileSystem e.Data = list.ToArray(); } + /// + /// Prompts the user to select an existing file to add to the currently-loaded . + /// + /// Sender. + /// E. + private void FileAddExistingItem_Click(object sender, EventArgs e) + { + FileSystemObjectModel fsom = ObjectModel as FileSystemObjectModel; + if (fsom == null) + return; + + FileDialog fd = new FileDialog(); + fd.Mode = FileDialogMode.Open; + fd.MultiSelect = true; + if (fd.ShowDialog() == DialogResult.OK) + { + foreach (string fileName in fd.SelectedFileNames) + { + string fileTitle = System.IO.Path.GetFileName(fileName); + byte[] data = System.IO.File.ReadAllBytes(fileName); + + UIAddExistingFile(fsom, fileTitle, data); + } + } + } + + private Folder UIAddEmptyFolder(IFileSystemContainer fsom, string fileTitle) + { + Folder f = fsom.Folders.Add(fileTitle); + TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[] + { + new TreeModelRowColumn(tmTreeView.Columns[0], f.Name), + new TreeModelRowColumn(tmTreeView.Columns[1], String.Format("{0} files, {1} folders", f.Files.Count, f.Folders.Count)), + new TreeModelRowColumn(tmTreeView.Columns[2], "Folder"), + new TreeModelRowColumn(tmTreeView.Columns[3], DateTime.Now.ToString()) + }); + row.SetExtraData("item", f); + + tmTreeView.Rows.Add(row); + return f; + } + private File UIAddExistingFile(IFileSystemContainer fsom, string fileTitle, byte[] data) + { + File f = fsom.AddFile(fileTitle, data); + TreeModelRow row = UIGetTreeModelRowForFileSystemObject(f); + row.SetExtraData("item", f); + tmTreeView.Rows.Add(row); + return f; + } + + /// + /// Creates a new folder in the current directory of the currently-loaded . + /// + /// Sender. + /// E. + private void FileNewFolder_Click(object sender, EventArgs e) + { + FileSystemObjectModel fsom = ObjectModel as FileSystemObjectModel; + if (fsom == null) + return; + + int iNewFolderCt = 0; + foreach (Folder ef in fsom.Folders) + { + if (ef.Name.Equals("New folder") || ef.Name.StartsWith("New folder ")) + { + iNewFolderCt++; + } + } + + UIAddEmptyFolder(fsom, String.Format("New folder{0}", ((iNewFolderCt > 0) ? " (" + (iNewFolderCt + 1).ToString() + ")" : String.Empty))); + } + + private void FileAddItemsFromFolder_Click(object sender, EventArgs e) + { + FileSystemObjectModel fsom = ObjectModel as FileSystemObjectModel; + if (fsom == null) + return; + + FileDialog fd = new FileDialog(); + fd.Mode = FileDialogMode.SelectFolder; + if (fd.ShowDialog() == DialogResult.OK) + { + Folder f = FolderFromPath(fd.SelectedFileNames[fd.SelectedFileNames.Count - 1]); + RecursiveAddFolder(f); + } + } + private void FileAddExistingFolder_Click(object sender, EventArgs e) + { + FileSystemObjectModel fsom = ObjectModel as FileSystemObjectModel; + if (fsom == null) + return; + + FileDialog fd = new FileDialog(); + fd.Mode = FileDialogMode.SelectFolder; + if (fd.ShowDialog() == DialogResult.OK) + { + Folder f = FolderFromPath(fd.SelectedFileNames[fd.SelectedFileNames.Count - 1]); + IFileSystemObject[] files = f.GetContents(); + foreach (IFileSystemObject fso in files) + { + if (fso is File) + { + RecursiveAddFile(fso as File); + } + else if (fso is Folder) + { + RecursiveAddFolder(fso as Folder); + } + } + } + } + protected override EditorSelection CreateSelectionInternal(object content) { - throw new NotImplementedException(); + FileSystemObjectModel fsom = (ObjectModel as FileSystemObjectModel); + if (fsom == null) return null; + + if (content is string) + { + string str = (string)content; + + // FIXME: assuming nautilus, for now, PLEASE FIX THIS + string[] parts = str.Split(new char[] { '\n' }); + if (parts[0] == "x-special/nautilus-clipboard") + { + if (parts[1] == "cut" || parts[1] == "copy") + { + List fileList = new List(); + for (int ip = 2; ip < parts.Length - 1; ip++) + { + string url = parts[ip]; + Uri uri = new Uri(url); + + string filepath = uri.LocalPath; + + IFileSystemObject fso = FileSystemObjectFromPath(filepath); + if (fso == null) + continue; + + TreeModelRow row = UIGetTreeModelRowForFileSystemObject(fso); + tmTreeView.Rows.Add(row); + + fileList.Add(fso); + } + return new FileSystemSelection(this, fileList.ToArray()); + } + } + } + return null; } + + /// + /// Creates and returns a new containing details about the specified . + /// + /// The et tree model row for file system object. + /// Fso. + private TreeModelRow UIGetTreeModelRowForFileSystemObject(IFileSystemObject fso, bool recurse = true) + { + TreeModelRow r = null; + if (fso is Folder) + { + Folder f = (fso as Folder); + r = new TreeModelRow(new TreeModelRowColumn[] + { + new TreeModelRowColumn(tmTreeView.Columns[0], f.Name), + new TreeModelRowColumn(tmTreeView.Columns[1], (f.Folders.Count + f.Files.Count).ToString() + " items"), + new TreeModelRowColumn(tmTreeView.Columns[2], "Folder"), + new TreeModelRowColumn(tmTreeView.Columns[3], "") + }); + + if (recurse) + { + foreach (Folder folder in f.Folders) + { + TreeModelRow r2 = UIGetTreeModelRowForFileSystemObject(folder); + r.Rows.Add(r2); + } + foreach (File file in f.Files) + { + TreeModelRow r2 = UIGetTreeModelRowForFileSystemObject(file); + r.Rows.Add(r2); + } + } + } + else if (fso is File) + { + File f = (fso as File); + r = new TreeModelRow(new TreeModelRowColumn[] + { + new TreeModelRowColumn(tmTreeView.Columns[0], f.Name), + new TreeModelRowColumn(tmTreeView.Columns[1], UserInterface.Common.FileInfo.FormatSize(f.Size)), + new TreeModelRowColumn(tmTreeView.Columns[2], "File"), + new TreeModelRowColumn(tmTreeView.Columns[3], DateTime.Now.ToString()) + }); + } + r.SetExtraData("item", fso); + return r; + } + + /// + /// Creates a or a from the specified path to a folder or a file. + /// + /// The created . + /// The path in the actual file system that contains the object to load. + private IFileSystemObject FileSystemObjectFromPath(string filepath) + { + if (System.IO.Directory.Exists(filepath)) + { + return FolderFromPath(filepath); + } + else if (System.IO.File.Exists(filepath)) + { + return FileFromPath(filepath); + } + return null; + } + + private File FileFromPath(string filepath) + { + File file = new File(); + file.Name = System.IO.Path.GetFileName(filepath); + file.SetData(System.IO.File.ReadAllBytes(filepath)); + return file; + } + private Folder FolderFromPath(string filepath) + { + Folder f = new Folder(); + f.Name = System.IO.Path.GetFileName(filepath); + + string[] folders = System.IO.Directory.GetDirectories(filepath); + foreach (string folder in folders) + { + f.Folders.Add(FolderFromPath(folder)); + } + string[] files = System.IO.Directory.GetFiles(filepath); + foreach (string file in files) + { + f.Files.Add(FileFromPath(file)); + } + return f; + } + public override void UpdateSelections() { Selections.Clear(); @@ -109,15 +363,7 @@ namespace UniversalEditor.Editors.FileSystem private void RecursiveAddFolder(Folder f, TreeModelRow parent = null) { - TreeModelRow r = new TreeModelRow(new TreeModelRowColumn[] - { - new TreeModelRowColumn(tmTreeView.Columns[0], f.Name), - new TreeModelRowColumn(tmTreeView.Columns[1], (f.Folders.Count + f.Files.Count).ToString() + " items"), - new TreeModelRowColumn(tmTreeView.Columns[2], "Folder"), - new TreeModelRowColumn(tmTreeView.Columns[3], "") - }); - r.SetExtraData("item", f); - + TreeModelRow r = UIGetTreeModelRowForFileSystemObject(f, false); foreach (Folder f2 in f.Folders) { RecursiveAddFolder(f2, r); @@ -138,13 +384,7 @@ namespace UniversalEditor.Editors.FileSystem } private void RecursiveAddFile(File f, TreeModelRow parent = null) { - TreeModelRow r = new TreeModelRow(new TreeModelRowColumn[] - { - new TreeModelRowColumn(tmTreeView.Columns[0], f.Name), - new TreeModelRowColumn(tmTreeView.Columns[1], UniversalEditor.UserInterface.Common.FileInfo.FormatSize(f.Size)), - new TreeModelRowColumn(tmTreeView.Columns[2], ""), - new TreeModelRowColumn(tmTreeView.Columns[3], "") - }); + TreeModelRow r = UIGetTreeModelRowForFileSystemObject(f); r.SetExtraData("item", f); if (parent == null) @@ -174,7 +414,29 @@ namespace UniversalEditor.Editors.FileSystem } } - void ContextMenuCopyTo_Click(object sender, EventArgs e) + private void ContextMenuProperties_Click(object sender, EventArgs e) + { + if (tv.SelectedRows.Count == 1 && tv.LastHitTest.Row != null) + { + TreeModelRow row = tv.SelectedRows[0]; + IFileSystemObject fso = row.GetExtraData("item"); + + if (FilePropertiesDialog.ShowDialog(fso) == DialogResult.OK) + { + row.RowColumns[0].Value = fso.Name; + } + } + else + { + } + } + + /// + /// Prompts the user to choose a filename, and then extracts the selected file in the current to a file on disk with the chosen filename. + /// + /// Sender. + /// E. + private void ContextMenuCopyTo_Click(object sender, EventArgs e) { // extract files if (tv.SelectedRows.Count == 1) @@ -186,8 +448,59 @@ namespace UniversalEditor.Editors.FileSystem FileDialog fd = new FileDialog(); fd.Mode = FileDialogMode.SelectFolder; fd.MultiSelect = false; - foreach (TreeModelRow row in tv.SelectedRows) + + if (fd.ShowDialog() == DialogResult.OK) { + string fileName = fd.SelectedFileNames[0]; + + if (!System.IO.Directory.Exists(fileName)) + System.IO.Directory.CreateDirectory(fileName); + + foreach (TreeModelRow row in tv.SelectedRows) + { + IFileSystemObject fso = row.GetExtraData("item"); + ExtractFileSystemObject(fso, fileName); + } + } + } + } + + private void ContextMenuRename_Click(object sender, EventArgs e) + { + // gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column, GtkCellRenderer* cell); + // tv.SelectedRows[0].RowColumns[0].BeginEdit(); + } + + private void ExtractFileSystemObject(IFileSystemObject fso, string fileName) + { + if (String.IsNullOrEmpty(fso.Name)) + { + Console.Error.WriteLine("ERROR! FileSystemEditor::ExtractFileSystemObject - we have to work around some weirdo bug in ZIP"); + return; + } + + if (fso is File) + { + File f = (fso as File); + + string filePath = System.IO.Path.Combine(new string[] { fileName, System.IO.Path.GetFileName(f.Name) }); + System.IO.File.WriteAllBytes(filePath, f.GetData()); + } + else if (fso is Folder) + { + Folder f = (fso as Folder); + + string filePath = System.IO.Path.Combine(new string[] { fileName, f.Name }); + if (!System.IO.Directory.Exists(filePath)) + System.IO.Directory.CreateDirectory(filePath); + + foreach (File file in f.Files) + { + ExtractFileSystemObject(file, filePath); + } + foreach (Folder file in f.Folders) + { + ExtractFileSystemObject(file, filePath); } } } @@ -223,8 +536,7 @@ namespace UniversalEditor.Editors.FileSystem fd.MultiSelect = false; if (fd.ShowDialog() == DialogResult.OK) { - System.IO.Directory.CreateDirectory(fd.SelectedFileNames[fd.SelectedFileNames.Count - 1]); - // TODO: implement this + ExtractFileSystemObject(f, fd.SelectedFileNames[fd.SelectedFileNames.Count - 1]); } } } @@ -240,6 +552,9 @@ namespace UniversalEditor.Editors.FileSystem row = info.Row; } + contextMenuUnselectedPaste.Enabled = Clipboard.Default.ContainsFileList; + contextMenuUnselectedPasteShortcut.Enabled = Clipboard.Default.ContainsFileList; + if (row != null) { tv.ContextMenu = contextMenuSelected; diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs index 4aed0b28..a43ebc04 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs @@ -25,16 +25,16 @@ namespace UniversalEditor.Editors.FileSystem { internal class FileSystemSelection : EditorSelection { - public IFileSystemObject Item { get; set; } = null; + public IFileSystemObject[] Items { get; set; } = null; public override object Content { - get => Item; + get => Items; set { if (value == null) _parent.ClearSelectionContent(this); - Item = (value is IFileSystemObject ? (value as IFileSystemObject) : null); + Items = (value is IFileSystemObject[] ? (value as IFileSystemObject[]) : null); } } @@ -42,7 +42,12 @@ namespace UniversalEditor.Editors.FileSystem internal FileSystemSelection(FileSystemEditor parent, IFileSystemObject item) { _parent = parent; - Item = item; + Items = new IFileSystemObject[] { item }; + } + internal FileSystemSelection(FileSystemEditor parent, IFileSystemObject[] items) + { + _parent = parent; + Items = items; } } } \ No newline at end of file diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/MainWindow.cs b/CSharp/Libraries/UniversalEditor.UserInterface/MainWindow.cs index 692e2321..8d092a94 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/MainWindow.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/MainWindow.cs @@ -370,23 +370,31 @@ namespace UniversalEditor.UserInterface } } } - - EditorReference[] editors = Common.Reflection.GetAvailableEditors(doc.ObjectModel.MakeReference()); - Console.WriteLine("found {0} editors for object model {1}", editors.Length.ToString(), doc.ObjectModel.ToString()); - if (editors.Length > 0) + + if (doc.ObjectModel != null) { - // no need to open and load file, it's already been done - Editor editor = editors[0].Create(); - EditorPage page = new EditorPage(); - page.Controls.Add(editor, new BoxLayout.Constraints(true, true)); + EditorReference[] editors = Common.Reflection.GetAvailableEditors(doc.ObjectModel.MakeReference()); + Console.WriteLine("found {0} editors for object model {1}", editors.Length.ToString(), doc.ObjectModel.ToString()); + if (editors.Length > 0) + { + // no need to open and load file, it's already been done + Editor editor = editors[0].Create(); + EditorPage page = new EditorPage(); + page.Controls.Add(editor, new BoxLayout.Constraints(true, true)); - InitDocTab(doc.Title, page); + InitDocTab(doc.Title, page); - editor.ObjectModel = doc.ObjectModel; + editor.ObjectModel = doc.ObjectModel; + } + else + { + Console.Error.WriteLine("Editor not found for object model " + doc.ObjectModel.MakeReference().Title + " ; using default editor"); + OpenDefaultEditor(doc.Accessor.GetFileName()); + } } else { - Console.Error.WriteLine("Editor not found for object model " + doc.ObjectModel.MakeReference().Title + " ; using default editor"); + Console.Error.WriteLine("ObjectModel not specified for accessor " + doc.Accessor.ToString() + " ; using default editor"); OpenDefaultEditor(doc.Accessor.GetFileName()); } } @@ -416,7 +424,7 @@ namespace UniversalEditor.UserInterface if (System.IO.File.Exists(filename)) { System.IO.FileInfo fi = new System.IO.FileInfo(filename); - if (fi.Length < Math.Pow(1024, 2)) + if (fi.Length < Math.Pow(1024, 4)) { byte[] content = System.IO.File.ReadAllBytes(filename); om1.Data = content; diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs b/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs index 0c111e4b..60b8577c 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs @@ -51,6 +51,7 @@ namespace UniversalEditor.UserInterface string path = System.IO.Path.Combine(new string[] { System.IO.Path.GetTempPath(), + "universal-editor", pathName }); @@ -106,6 +107,12 @@ namespace UniversalEditor.UserInterface { System.IO.Directory.Delete(mvarTemporaryFilePath, true); } + + string uetmppath = System.IO.Path.Combine(new string[] { System.IO.Path.GetTempPath(), "universal-editor" }); + if (System.IO.Directory.Exists(uetmppath) && System.IO.Directory.GetFileSystemEntries(uetmppath).Length == 0) + { + System.IO.Directory.Delete(uetmppath); + } return true; } } diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj b/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj index 207a7cdd..8ce63f0b 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj +++ b/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj @@ -121,6 +121,7 @@ + @@ -172,6 +173,7 @@ +