From 59476f27186991347a4a134e19782b2a866da9e4 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Mon, 2 Sep 2019 16:51:36 -0400 Subject: [PATCH] Preliminary support for selections and editor-dependent cut/copy/paste --- .../UniversalEditor.UserInterface/Editor.cs | 71 +++++++++++++++++-- .../EditorSelection.cs | 33 +++++++++ .../Editors/FileSystem/FileSystemEditor.cs | 20 +++--- .../Editors/FileSystem/FileSystemSelection.cs | 36 ++++++++++ .../PropertyList/PropertyListEditor.cs | 11 ++- .../Editors/Text/Plain/PlainTextEditor.cs | 28 ++++---- .../Editors/Text/TextEditor.cs | 30 ++++++++ .../Editors/Text/TextEditorSelection.cs | 60 ++++++++++++++++ .../UniversalEditor.UserInterface/Engine.cs | 8 +-- .../UniversalEditor.UserInterface.csproj | 4 ++ 10 files changed, 263 insertions(+), 38 deletions(-) create mode 100644 CSharp/Libraries/UniversalEditor.UserInterface/EditorSelection.cs create mode 100644 CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs create mode 100644 CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditor.cs create mode 100644 CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditorSelection.cs diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editor.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editor.cs index 6b685df3..0647136a 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editor.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editor.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Text; +using System.Threading.Tasks; using UniversalEditor.Accessors; using UniversalEditor.DataFormats.PropertyList.XML; using UniversalEditor.ObjectModels.PropertyList; @@ -15,19 +17,76 @@ namespace UniversalEditor.UserInterface /// public abstract class Editor : UniversalWidgetToolkit.Container { + public EditorSelection.EditorSelectionCollection Selections { get; } = new EditorSelection.EditorSelectionCollection(); + public abstract void UpdateSelections(); + public EditorSelection[] GetSelections() + { + UpdateSelections(); + + EditorSelection[] sels = new EditorSelection[Selections.Count]; + for (int i = 0; i < Selections.Count; i++) + { + sels[i] = Selections[i]; + } + return sels; + } + + protected abstract EditorSelection CreateSelectionInternal(object content); + public EditorSelection CreateSelection(object content) + { + return CreateSelectionInternal(content); + } /// - /// Copies the selected content to the Universal Editor clipboard. + /// Copies the content of all selections to the system clipboard, and then clears the content. /// - public abstract void Copy(); + public void Cut() + { + StringBuilder sb = new StringBuilder(); + EditorSelection[] sels = GetSelections(); + foreach (EditorSelection sel in sels) + { + if (sel.Content != null) + { + sb.Append(sel.Content.ToString()); + } + sel.Content = null; + } + Clipboard.Default.SetText(sb.ToString()); + } /// - /// Pastes the content from the Universal Editor clipboard, overwriting any selected content. + /// Copies the content of all selections to the system clipboard. /// - public abstract void Paste(); + public void Copy() + { + StringBuilder sb = new StringBuilder(); + EditorSelection[] sels = GetSelections(); + foreach (EditorSelection sel in sels) + { + if (sel.Content != null) + { + sb.Append(sel.Content.ToString()); + } + } + Clipboard.Default.SetText(sb.ToString()); + } /// - /// Causes the editor to delete the currently-selected item. + /// Pastes the content from the system clipboard into a new selection, overwriting any selected content. /// - public abstract void Delete(); + public void Paste() + { + Selections.Clear(); + + string clipboardText = Clipboard.Default.GetText(); + Selections.Add(CreateSelection(clipboardText)); + } + public void Delete() + { + foreach (EditorSelection sel in Selections) + { + sel.Content = null; + } + } #region IEditorImplementation Members public virtual string Title { get { return String.Empty; } } diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/EditorSelection.cs b/CSharp/Libraries/UniversalEditor.UserInterface/EditorSelection.cs new file mode 100644 index 00000000..524e8c48 --- /dev/null +++ b/CSharp/Libraries/UniversalEditor.UserInterface/EditorSelection.cs @@ -0,0 +1,33 @@ +// +// EditorSelection.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; +namespace UniversalEditor.UserInterface +{ + public abstract class EditorSelection + { + public class EditorSelectionCollection + : System.Collections.ObjectModel.Collection + { + } + + public abstract object Content { get; set; } + } +} diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs index 7176d1f4..fb8123ea 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemEditor.cs @@ -57,17 +57,20 @@ namespace UniversalEditor.Editors.FileSystem e.Data = sb.ToString(); } - public override void Copy() + protected override EditorSelection CreateSelectionInternal(object content) { throw new NotImplementedException(); } - public override void Paste() + public override void UpdateSelections() { - throw new NotImplementedException(); - } - public override void Delete() - { - throw new NotImplementedException(); + Selections.Clear(); + for (int i = 0; i < tv.SelectedRows.Count; i++) + { + TreeModelRow row = tv.SelectedRows[i]; + + FileSystemSelection sel = new FileSystemSelection(row.GetExtraData("item")); + Selections.Add(sel); + } } private static EditorReference _er = null; @@ -90,6 +93,7 @@ namespace UniversalEditor.Editors.FileSystem new TreeModelRowColumn(tmTreeView.Columns[2], "Folder"), new TreeModelRowColumn(tmTreeView.Columns[3], "") }); + r.SetExtraData("item", f); foreach (Folder f2 in f.Folders) { @@ -118,7 +122,7 @@ namespace UniversalEditor.Editors.FileSystem new TreeModelRowColumn(tmTreeView.Columns[2], ""), new TreeModelRowColumn(tmTreeView.Columns[3], "") }); - + r.SetExtraData("item", f); if (parent == null) { diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs new file mode 100644 index 00000000..df77542c --- /dev/null +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/FileSystem/FileSystemSelection.cs @@ -0,0 +1,36 @@ +// +// FileSystemEditor.cs - cross-platform (UWT) file system editor for Universal Editor +// +// Author: +// Michael Becker +// +// Copyright (c) 2019 +// +// 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 UniversalEditor.ObjectModels.FileSystem; +using UniversalEditor.UserInterface; + +namespace UniversalEditor.Editors.FileSystem +{ + internal class FileSystemSelection : EditorSelection + { + public IFileSystemObject Item { get; set; } = null; + public override object Content { get => Item; set => Item = (value is IFileSystemObject ? (value as IFileSystemObject) : null); } + + public FileSystemSelection(IFileSystemObject item) + { + Item = item; + } + } +} \ No newline at end of file diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/PropertyList/PropertyListEditor.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/PropertyList/PropertyListEditor.cs index 135a0f2d..77046813 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/PropertyList/PropertyListEditor.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/PropertyList/PropertyListEditor.cs @@ -41,16 +41,13 @@ namespace UniversalEditor.Editors.PropertyList return _er; } - public override void Copy() + protected override EditorSelection CreateSelectionInternal(object content) { + throw new NotImplementedException(); } - - public override void Delete() - { - } - - public override void Paste() + public override void UpdateSelections() { + throw new NotImplementedException(); } protected override void OnObjectModelChanged(EventArgs e) diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/Plain/PlainTextEditor.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/Plain/PlainTextEditor.cs index 6fface16..010cba6e 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/Plain/PlainTextEditor.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/Plain/PlainTextEditor.cs @@ -29,25 +29,29 @@ using UniversalWidgetToolkit.Layouts; namespace UniversalEditor.Editors.Text.Plain { - public class PlainTextEditor : Editor + public class PlainTextEditor : TextEditor { - public override void Copy() + protected override EditorSelection CreateSelectionInternal(object content) { - throw new NotImplementedException(); + if (content is string) + { + txt.SelectedText = (string)content; + return new TextEditorSelection(this, (string)content); + } + return null; } - - public override void Delete() + public override void UpdateSelections() { - throw new NotImplementedException(); + Selections.Clear(); + Selections.Add(new TextEditorSelection(this, txt.SelectedText, txt.SelectionStart, txt.SelectionLength)); } - - public override void Paste() - { - throw new NotImplementedException(); - } - private TextBox txt = null; + internal override void ClearSelectedText() + { + txt.SelectedText = null; + } + private static EditorReference _er = null; public override EditorReference MakeReference () { diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditor.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditor.cs new file mode 100644 index 00000000..e1debc1b --- /dev/null +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditor.cs @@ -0,0 +1,30 @@ +// +// TextEditor.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 UniversalEditor.UserInterface; + +namespace UniversalEditor.Editors.Text +{ + public abstract class TextEditor : Editor + { + internal abstract void ClearSelectedText(); + } +} diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditorSelection.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditorSelection.cs new file mode 100644 index 00000000..2b6d7d98 --- /dev/null +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Editors/Text/TextEditorSelection.cs @@ -0,0 +1,60 @@ +// +// TextEditorSelection.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 UniversalEditor.UserInterface; + +namespace UniversalEditor.Editors.Text +{ + public class TextEditorSelection : EditorSelection + { + public int Start { get; set; } = -1; + public int Length { get; set; } = -1; + + private string mvarContent = null; + public override object Content + { + get => mvarContent; + set + { + mvarContent = (value is string ? (string)value : null); + if (mvarContent == null) + { + Length = 0; + _parent.ClearSelectedText(); + } + } + } + + private TextEditor _parent = null; + internal TextEditorSelection(TextEditor parent, string text) + { + _parent = parent; + mvarContent = text; + } + internal TextEditorSelection(TextEditor parent, string text, int start, int length) + { + _parent = parent; + mvarContent = text; + Start = start; + Length = length; + } + } +} diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs index 980df1e8..b1601af8 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs +++ b/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs @@ -281,11 +281,9 @@ namespace UniversalEditor.UserInterface #region Edit Application.AttachCommandEventHandler("EditCut", delegate(object sender, EventArgs e) { - Command cmdCopy = Application.Commands["EditCopy"]; - Command cmdDelete = Application.Commands["EditDelete"]; - - cmdCopy.Execute (); - cmdDelete.Execute (); + Editor editor = LastWindow.GetCurrentEditor(); + if (editor == null) return; + editor.Cut(); }); Application.AttachCommandEventHandler("EditCopy", delegate(object sender, EventArgs e) { diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj b/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj index 3cc37441..aeb4cfbd 100644 --- a/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj +++ b/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj @@ -114,6 +114,10 @@ + + + +