From 4d53a6b0cda7433446a940857d22fef3dbdf3e4a Mon Sep 17 00:00:00 2001 From: Lehonti Ramos <17771375+Lehonti@users.noreply.github.com> Date: Sat, 5 Aug 2023 02:36:01 +0200 Subject: [PATCH] Changed `Extensions` and `Mimes` in `FormatDescriptor` from `string[]` to `ReadOnlyCollection` (#277) * Changed `Extensions` and `Mimes` in `FormatDescriptor` from `string[]` to `ReadOnlyCollection` * Fix inconsistent line endings to resolve formatting issues * Removed unnecessary null check --------- Co-authored-by: John Doe --- Pinta.Core/Extensions/OtherExtensions.cs | 66 +++ Pinta.Core/ImageFormats/FormatDescriptor.cs | 31 +- Pinta.Docking/Dock.cs | 80 ++- Pinta.Gui.Addins/InstallDialog.cs | 561 ++++++++++---------- Pinta.Tools/Tools/LassoSelectTool.cs | 237 ++++----- Pinta/Actions/File/CloseDocumentAction.cs | 91 ++-- Pinta/Actions/File/DBus/RequestsPortal.cs | 37 +- Pinta/Actions/File/DBus/ScreenshotPortal.cs | 75 ++- 8 files changed, 616 insertions(+), 562 deletions(-) diff --git a/Pinta.Core/Extensions/OtherExtensions.cs b/Pinta.Core/Extensions/OtherExtensions.cs index 05732d75a..460f0a256 100644 --- a/Pinta.Core/Extensions/OtherExtensions.cs +++ b/Pinta.Core/Extensions/OtherExtensions.cs @@ -9,11 +9,77 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; +using System.Collections.ObjectModel; namespace Pinta.Core { public static class OtherExtensions { + /// + /// In most cases, it creates a wrapped read-only copy of the values generated by the + /// argument, except if the argument is of type + /// or , in which case only + /// the wrapping (not the copying) is necessary; or if the argument is an object that has + /// been previously returned from this method, in which case the reference is returned as is. + /// + /// Sequence of values to be materialized + /// + /// Read-only collection wrapper, suitable for class interfaces, + /// backed by an immutable collection type such as + /// + public static ReadOnlyCollection ToReadOnlyCollection (this IEnumerable values) + { + switch (values) { + case ImmutableBackedReadOnlyCollection transparent: + return transparent; + case ImmutableArray array: + return array.ToReadOnlyCollection (); + case ImmutableList list: + return list.ToReadOnlyCollection (); + default: + return values.ToImmutableArray ().ToReadOnlyCollection (); + } + } + + /// + /// Wraps the in a custom + /// and returns it. + /// + /// Immutable array to be wrapped + /// + /// Read-only collection wrapper, suitable for class interfaces, + /// backed by the argument that has been passed + /// + public static ReadOnlyCollection ToReadOnlyCollection (this ImmutableArray array) + { + return new ImmutableBackedReadOnlyCollection (array); + } + + /// + /// Wraps the in a custom + /// and returns it. + /// + /// Immutable list to be wrapped + /// + /// Read-only collection wrapper, suitable for class interfaces, + /// backed by the argument that has been passed + /// + public static ReadOnlyCollection ToReadOnlyCollection (this ImmutableList list) + { + return new ImmutableBackedReadOnlyCollection (list); + } + + private sealed class ImmutableBackedReadOnlyCollection : ReadOnlyCollection + { + internal ImmutableBackedReadOnlyCollection (ImmutableList list) : base (list) + { + } + internal ImmutableBackedReadOnlyCollection (ImmutableArray array) : base (array) + { + } + } + public static bool In (this T enumeration, params T[] values) { if (enumeration is null) diff --git a/Pinta.Core/ImageFormats/FormatDescriptor.cs b/Pinta.Core/ImageFormats/FormatDescriptor.cs index 7d8d69661..e568d18f1 100644 --- a/Pinta.Core/ImageFormats/FormatDescriptor.cs +++ b/Pinta.Core/ImageFormats/FormatDescriptor.cs @@ -25,6 +25,8 @@ // THE SOFTWARE. using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Text; @@ -41,12 +43,12 @@ public sealed class FormatDescriptor /// /// A list of the supported extensions (for example, "jpeg" and "JPEG"). /// - public string[] Extensions { get; } + public ReadOnlyCollection Extensions { get; } /// /// A list of supported MIME types (for example, "image/jpg" and "image/png"). /// - public string[] Mimes { get; } + public ReadOnlyCollection Mimes { get; } /// /// The importer for this file format. This may be null if only exporting @@ -73,22 +75,21 @@ public sealed class FormatDescriptor /// A list of supported file MIME types (for example, "image/jpeg" and "image/png"). /// The importer for this file format, or null if importing is not supported. /// The exporter for this file format, or null if exporting is not supported. - public FormatDescriptor (string displayPrefix, string[] extensions, string[] mimes, + public FormatDescriptor (string displayPrefix, IEnumerable extensions, IEnumerable mimes, IImageImporter? importer, IImageExporter? exporter) { - if (extensions == null || (importer == null && exporter == null)) { - throw new ArgumentNullException ("Format descriptor is initialized incorrectly"); - } + if (importer == null && exporter == null) + throw new ArgumentException ("Format descriptor is initialized incorrectly", $"{nameof (importer)}, {nameof (exporter)}"); - this.Extensions = extensions; - this.Mimes = mimes; + this.Extensions = extensions.ToReadOnlyCollection (); // Create a read-only copy + this.Mimes = mimes.ToReadOnlyCollection (); // Create a read-only copy this.Importer = importer; this.Exporter = exporter; FileFilter ff = FileFilter.New (); StringBuilder formatNames = new StringBuilder (); - foreach (string ext in extensions) { + foreach (string ext in Extensions) { if (formatNames.Length > 0) formatNames.Append (", "); @@ -102,7 +103,7 @@ public FormatDescriptor (string displayPrefix, string[] extensions, string[] mim // Windows does not understand MIME types natively. // Adding a MIME filter on Windows would break the native file picker and force a GTK file picker instead. if (SystemManager.GetOperatingSystem () != OS.Windows) { - foreach (string mime in mimes) { + foreach (string mime in Mimes) { ff.AddMimeType (mime); } } @@ -112,15 +113,9 @@ public FormatDescriptor (string displayPrefix, string[] extensions, string[] mim } [MemberNotNullWhen (returnValue: false, member: nameof (Exporter))] - public bool IsReadOnly () - { - return Exporter == null; - } + public bool IsReadOnly () => Exporter == null; [MemberNotNullWhen (returnValue: false, member: nameof (Importer))] - public bool IsWriteOnly () - { - return Importer == null; - } + public bool IsWriteOnly () => Importer == null; } } diff --git a/Pinta.Docking/Dock.cs b/Pinta.Docking/Dock.cs index f510a8442..7e3a2bbf6 100644 --- a/Pinta.Docking/Dock.cs +++ b/Pinta.Docking/Dock.cs @@ -22,61 +22,59 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using System; using Gtk; using Pinta.Core; -namespace Pinta.Docking +namespace Pinta.Docking; + +/// +/// The root widget, containing all dock items underneath it. +/// +public class Dock : Box { - /// - /// The root widget, containing all dock items underneath it. - /// - public class Dock : Box - { - private readonly DockPanel right_panel = new DockPanel (); - private readonly Paned pane = Paned.New (Orientation.Horizontal); + private readonly DockPanel right_panel = new DockPanel (); + private readonly Paned pane = Paned.New (Orientation.Horizontal); - public Dock () - { - SetOrientation (Orientation.Horizontal); + public Dock () + { + SetOrientation (Orientation.Horizontal); - pane.EndChild = right_panel; - pane.ResizeEndChild = false; - pane.ShrinkEndChild = false; - Append (pane); - } + pane.EndChild = right_panel; + pane.ResizeEndChild = false; + pane.ShrinkEndChild = false; + Append (pane); + } - public void AddItem (DockItem item, DockPlacement placement) - { - switch (placement) { - case DockPlacement.Center: - pane.StartChild = item; - pane.ResizeStartChild = true; - pane.ShrinkStartChild = false; - break; - case DockPlacement.Right: - right_panel.AddItem (item); - break; - } + public void AddItem (DockItem item, DockPlacement placement) + { + switch (placement) { + case DockPlacement.Center: + pane.StartChild = item; + pane.ResizeStartChild = true; + pane.ShrinkStartChild = false; + break; + case DockPlacement.Right: + right_panel.AddItem (item); + break; } + } - private const string RightSplitPosKey = "dock-right-splitpos"; + private const string RightSplitPosKey = "dock-right-splitpos"; - public void SaveSettings (ISettingsService settings) - { + public void SaveSettings (ISettingsService settings) + { #if false - settings.PutSetting (RightSplitPosKey, pane.Position); + settings.PutSetting (RightSplitPosKey, pane.Position); #endif - right_panel.SaveSettings (settings); - } + right_panel.SaveSettings (settings); + } - public void LoadSettings (ISettingsService settings) - { - // TODO-GTK3(docking) Disabled for now, as the size isn't quite restored properly (gradually increases over time) + public void LoadSettings (ISettingsService settings) + { + // TODO-GTK3(docking) Disabled for now, as the size isn't quite restored properly (gradually increases over time) #if false - pane.Position = settings.GetSetting (RightSplitPosKey, pane.Position); + pane.Position = settings.GetSetting (RightSplitPosKey, pane.Position); #endif - right_panel.LoadSettings (settings); - } + right_panel.LoadSettings (settings); } } diff --git a/Pinta.Gui.Addins/InstallDialog.cs b/Pinta.Gui.Addins/InstallDialog.cs index 1b1b30a6f..34abda053 100644 --- a/Pinta.Gui.Addins/InstallDialog.cs +++ b/Pinta.Gui.Addins/InstallDialog.cs @@ -1,338 +1,337 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; -using System.Text; +using System.Text; using System.Threading.Tasks; using Mono.Addins; -using Mono.Addins.Description; -using Mono.Addins.Setup; +using Mono.Addins.Description; +using Mono.Addins.Setup; using Pinta.Core; -namespace Pinta.Gui.Addins +namespace Pinta.Gui.Addins; + +internal class InstallDialog : Adw.Window { - internal class InstallDialog : Adw.Window + private readonly SetupService service; + private readonly PackageCollection packages_to_install = new (); + private List addins_to_remove = new (); + private readonly InstallErrorReporter error_reporter = new (); + + private readonly Adw.WindowTitle window_title = new (); + private readonly StatusProgressBar progress_bar; + + private readonly Gtk.Label error_heading_label; + private readonly Gtk.Label error_label; + private readonly Gtk.Label warning_heading_label; + private readonly Gtk.Label warning_label; + private readonly Gtk.Label install_heading_label; + private readonly Gtk.Label install_label; + private readonly Gtk.Label uninstall_heading_label; + private readonly Gtk.Label uninstall_label; + private readonly Gtk.Label dependencies_heading_label; + private readonly Gtk.Label dependencies_label; + + private readonly Gtk.Button install_button; + private readonly Gtk.Button cancel_button; + + public event EventHandler? OnSuccess; + + public InstallDialog (Gtk.Window parent, SetupService service) { - private readonly SetupService service; - private readonly PackageCollection packages_to_install = new (); - private List addins_to_remove = new (); - private readonly InstallErrorReporter error_reporter = new (); - - private readonly Adw.WindowTitle window_title = new (); - private readonly StatusProgressBar progress_bar; - - private readonly Gtk.Label error_heading_label; - private readonly Gtk.Label error_label; - private readonly Gtk.Label warning_heading_label; - private readonly Gtk.Label warning_label; - private readonly Gtk.Label install_heading_label; - private readonly Gtk.Label install_label; - private readonly Gtk.Label uninstall_heading_label; - private readonly Gtk.Label uninstall_label; - private readonly Gtk.Label dependencies_heading_label; - private readonly Gtk.Label dependencies_label; - - private readonly Gtk.Button install_button; - private readonly Gtk.Button cancel_button; - - public event EventHandler? OnSuccess; - - public InstallDialog (Gtk.Window parent, SetupService service) - { - this.service = service; - - TransientFor = parent; - WidthRequest = 500; - HeightRequest = 250; - - var content = Gtk.Box.New (Gtk.Orientation.Vertical, 12); - content.Append (new Adw.HeaderBar () { - TitleWidget = window_title - }); - - var labels = Gtk.Box.New (Gtk.Orientation.Vertical, 12); - labels.SetAllMargins (6); - - error_heading_label = Gtk.Label.New ( - Translations.GetString ("The selected extension packages can't be installed because there are dependency conflicts.")); - error_heading_label.AddCssClass (AdwaitaStyles.Title4); - labels.Append (error_heading_label); - - error_label = new Gtk.Label (); - error_label.AddCssClass (AdwaitaStyles.Body); - error_label.AddCssClass (AdwaitaStyles.Error); - labels.Append (error_label); - - warning_heading_label = new Gtk.Label (); - warning_heading_label.AddCssClass (AdwaitaStyles.Title4); - labels.Append (warning_heading_label); - - warning_label = new Gtk.Label (); - warning_label.AddCssClass (AdwaitaStyles.Body); - warning_label.AddCssClass (AdwaitaStyles.Warning); - labels.Append (warning_label); - - install_heading_label = Gtk.Label.New (Translations.GetString ("The following packages will be installed:")); - install_heading_label.AddCssClass (AdwaitaStyles.Title4); - labels.Append (install_heading_label); - - install_label = new Gtk.Label (); - install_label.AddCssClass (AdwaitaStyles.Body); - labels.Append (install_label); - - uninstall_heading_label = Gtk.Label.New (Translations.GetString ("The following packages need to be uninstalled:")); - uninstall_heading_label.AddCssClass (AdwaitaStyles.Title4); - labels.Append (uninstall_heading_label); - - uninstall_label = new Gtk.Label (); - uninstall_label.AddCssClass (AdwaitaStyles.Body); - uninstall_label.AddCssClass (AdwaitaStyles.Warning); - labels.Append (uninstall_label); - - dependencies_heading_label = Gtk.Label.New (Translations.GetString ("The following dependencies could not be resolved:")); - dependencies_heading_label.AddCssClass (AdwaitaStyles.Title4); - labels.Append (dependencies_heading_label); - - dependencies_label = new Gtk.Label (); - dependencies_label.AddCssClass (AdwaitaStyles.Body); - dependencies_label.AddCssClass (AdwaitaStyles.Error); - labels.Append (dependencies_label); - - // Left align all labels. - Gtk.Widget? label = labels.GetFirstChild (); - while (label != null) { - label.Halign = Gtk.Align.Start; - label = label.GetNextSibling (); - } - - var scroll = Gtk.ScrolledWindow.New (); - scroll.Child = labels; - scroll.HscrollbarPolicy = Gtk.PolicyType.Never; - scroll.Vexpand = true; - - progress_bar = new StatusProgressBar (scroll, error_reporter); - content.Append (progress_bar); - - var buttons = Gtk.Box.New (Gtk.Orientation.Horizontal, 12); - buttons.Halign = Gtk.Align.End; - buttons.SetAllMargins (12); - - cancel_button = Gtk.Button.NewWithLabel (Translations.GetString ("Cancel")); - buttons.Append (cancel_button); - - install_button = Gtk.Button.NewWithLabel (Translations.GetString ("Install")); - buttons.Append (install_button); - - content.Append (buttons); - Content = content; - - install_button.OnClicked += (_, _) => HandleInstallClicked (); - cancel_button.OnClicked += (_, _) => Close (); + this.service = service; + + TransientFor = parent; + WidthRequest = 500; + HeightRequest = 250; + + var content = Gtk.Box.New (Gtk.Orientation.Vertical, 12); + content.Append (new Adw.HeaderBar () { + TitleWidget = window_title + }); + + var labels = Gtk.Box.New (Gtk.Orientation.Vertical, 12); + labels.SetAllMargins (6); + + error_heading_label = Gtk.Label.New ( + Translations.GetString ("The selected extension packages can't be installed because there are dependency conflicts.")); + error_heading_label.AddCssClass (AdwaitaStyles.Title4); + labels.Append (error_heading_label); + + error_label = new Gtk.Label (); + error_label.AddCssClass (AdwaitaStyles.Body); + error_label.AddCssClass (AdwaitaStyles.Error); + labels.Append (error_label); + + warning_heading_label = new Gtk.Label (); + warning_heading_label.AddCssClass (AdwaitaStyles.Title4); + labels.Append (warning_heading_label); + + warning_label = new Gtk.Label (); + warning_label.AddCssClass (AdwaitaStyles.Body); + warning_label.AddCssClass (AdwaitaStyles.Warning); + labels.Append (warning_label); + + install_heading_label = Gtk.Label.New (Translations.GetString ("The following packages will be installed:")); + install_heading_label.AddCssClass (AdwaitaStyles.Title4); + labels.Append (install_heading_label); + + install_label = new Gtk.Label (); + install_label.AddCssClass (AdwaitaStyles.Body); + labels.Append (install_label); + + uninstall_heading_label = Gtk.Label.New (Translations.GetString ("The following packages need to be uninstalled:")); + uninstall_heading_label.AddCssClass (AdwaitaStyles.Title4); + labels.Append (uninstall_heading_label); + + uninstall_label = new Gtk.Label (); + uninstall_label.AddCssClass (AdwaitaStyles.Body); + uninstall_label.AddCssClass (AdwaitaStyles.Warning); + labels.Append (uninstall_label); + + dependencies_heading_label = Gtk.Label.New (Translations.GetString ("The following dependencies could not be resolved:")); + dependencies_heading_label.AddCssClass (AdwaitaStyles.Title4); + labels.Append (dependencies_heading_label); + + dependencies_label = new Gtk.Label (); + dependencies_label.AddCssClass (AdwaitaStyles.Body); + dependencies_label.AddCssClass (AdwaitaStyles.Error); + labels.Append (dependencies_label); + + // Left align all labels. + Gtk.Widget? label = labels.GetFirstChild (); + while (label != null) { + label.Halign = Gtk.Align.Start; + label = label.GetNextSibling (); } - public void InitForInstall (AddinRepositoryEntry[] addins_to_install) - { - foreach (var addin in addins_to_install) - packages_to_install.Add (Package.FromRepository (addin)); + var scroll = Gtk.ScrolledWindow.New (); + scroll.Child = labels; + scroll.HscrollbarPolicy = Gtk.PolicyType.Never; + scroll.Vexpand = true; - DisplayInstallInfo (); - } + progress_bar = new StatusProgressBar (scroll, error_reporter); + content.Append (progress_bar); - public bool InitForInstall (string[] files_to_install) - { - try { - foreach (string file in files_to_install) - packages_to_install.Add (Package.FromFile (file)); + var buttons = Gtk.Box.New (Gtk.Orientation.Horizontal, 12); + buttons.Halign = Gtk.Align.End; + buttons.SetAllMargins (12); - DisplayInstallInfo (); + cancel_button = Gtk.Button.NewWithLabel (Translations.GetString ("Cancel")); + buttons.Append (cancel_button); - } catch (Exception) { - var dialog = Adw.MessageDialog.New ( - TransientFor, - Translations.GetString ("Failed to load extension package"), - Translations.GetString ("The file may be an invalid or corrupt extension package")); + install_button = Gtk.Button.NewWithLabel (Translations.GetString ("Install")); + buttons.Append (install_button); - const string ok_response = "ok"; - dialog.AddResponse (ok_response, Translations.GetString ("_OK")); - dialog.DefaultResponse = ok_response; - dialog.CloseResponse = ok_response; + content.Append (buttons); + Content = content; - dialog.Present (); - return false; - } + install_button.OnClicked += (_, _) => HandleInstallClicked (); + cancel_button.OnClicked += (_, _) => Close (); + } - return true; - } + public void InitForInstall (AddinRepositoryEntry[] addins_to_install) + { + foreach (var addin in addins_to_install) + packages_to_install.Add (Package.FromRepository (addin)); - public void InitForUninstall (Addin[] addins_to_uninstall) - { - window_title.Title = Translations.GetString ("Uninstall"); - install_button.Label = Translations.GetString ("Uninstall"); - install_button.AddCssClass (AdwaitaStyles.DestructiveAction); + DisplayInstallInfo (); + } - addins_to_remove = addins_to_uninstall.Select (a => a.Id).ToList (); + public bool InitForInstall (string[] files_to_install) + { + try { + foreach (string file in files_to_install) + packages_to_install.Add (Package.FromFile (file)); - error_heading_label.Visible = error_label.Visible = false; - warning_heading_label.Visible = warning_label.Visible = false; - install_heading_label.Visible = install_label.Visible = false; + DisplayInstallInfo (); - uninstall_heading_label.SetLabel (Translations.GetString ("The following packages will be uninstalled:")); - uninstall_label.SetLabel (string.Join (Environment.NewLine, addins_to_uninstall.Select (a => a.Name))); + } catch (Exception) { + var dialog = Adw.MessageDialog.New ( + TransientFor, + Translations.GetString ("Failed to load extension package"), + Translations.GetString ("The file may be an invalid or corrupt extension package")); - var dependents = new HashSet (); - foreach (string id in addins_to_remove) { - dependents.UnionWith (service.GetDependentAddins (id, true)); - } + const string ok_response = "ok"; + dialog.AddResponse (ok_response, Translations.GetString ("_OK")); + dialog.DefaultResponse = ok_response; + dialog.CloseResponse = ok_response; - dependencies_heading_label.Visible = dependencies_label.Visible = dependents.Any (); - if (dependents.Any ()) { - dependencies_heading_label.SetLabel (Translations.GetString ( - "There are other extension packages that depend on the previous ones which will also be uninstalled:")); - dependencies_label.SetLabel (string.Join (Environment.NewLine, dependents.Select (a => a.Name))); - } + dialog.Present (); + return false; } - private void DisplayInstallInfo () - { - window_title.Title = Translations.GetString ("Install"); - install_button.AddCssClass (AdwaitaStyles.SuggestedAction); - - PackageCollection to_uninstall; - DependencyCollection unresolved; - error_reporter.Clear (); - bool success = service.ResolveDependencies (progress_bar, packages_to_install, out to_uninstall, out unresolved); + return true; + } - error_heading_label.Visible = error_label.Visible = !success; - if (error_label.Visible) - error_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Errors)); + public void InitForUninstall (Addin[] addins_to_uninstall) + { + window_title.Title = Translations.GetString ("Uninstall"); + install_button.Label = Translations.GetString ("Uninstall"); + install_button.AddCssClass (AdwaitaStyles.DestructiveAction); - warning_heading_label.Visible = false; - warning_label.Visible = error_reporter.Warnings.Any (); - if (warning_label.Visible) - warning_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Warnings)); + addins_to_remove = addins_to_uninstall.Select (a => a.Id).ToList (); - var sb = new StringBuilder (); - foreach (Package p in packages_to_install) { - sb.Append (p.Name); - if (!p.SharedInstall) - sb.Append (Translations.GetString (" (in user directory)")); - sb.AppendLine (); - } - install_label.SetLabel (sb.ToString ()); + error_heading_label.Visible = error_label.Visible = false; + warning_heading_label.Visible = warning_label.Visible = false; + install_heading_label.Visible = install_label.Visible = false; - uninstall_label.Visible = to_uninstall.Count > 0; - if (uninstall_label.Visible) { - sb.Clear (); + uninstall_heading_label.SetLabel (Translations.GetString ("The following packages will be uninstalled:")); + uninstall_label.SetLabel (string.Join (Environment.NewLine, addins_to_uninstall.Select (a => a.Name))); - foreach (Package p in to_uninstall) - sb.AppendLine (p.Name); + var dependents = new HashSet (); + foreach (string id in addins_to_remove) { + dependents.UnionWith (service.GetDependentAddins (id, true)); + } - uninstall_label.SetLabel (sb.ToString ()); - } + dependencies_heading_label.Visible = dependencies_label.Visible = dependents.Any (); + if (dependents.Any ()) { + dependencies_heading_label.SetLabel (Translations.GetString ( + "There are other extension packages that depend on the previous ones which will also be uninstalled:")); + dependencies_label.SetLabel (string.Join (Environment.NewLine, dependents.Select (a => a.Name))); + } + } - uninstall_heading_label.Visible = uninstall_label.Visible = to_uninstall.Count > 0; - if (uninstall_label.Visible) { - sb.Clear (); + private void DisplayInstallInfo () + { + window_title.Title = Translations.GetString ("Install"); + install_button.AddCssClass (AdwaitaStyles.SuggestedAction); + + PackageCollection to_uninstall; + DependencyCollection unresolved; + error_reporter.Clear (); + bool success = service.ResolveDependencies (progress_bar, packages_to_install, out to_uninstall, out unresolved); + + error_heading_label.Visible = error_label.Visible = !success; + if (error_label.Visible) + error_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Errors)); + + warning_heading_label.Visible = false; + warning_label.Visible = error_reporter.Warnings.Any (); + if (warning_label.Visible) + warning_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Warnings)); + + var sb = new StringBuilder (); + foreach (Package p in packages_to_install) { + sb.Append (p.Name); + if (!p.SharedInstall) + sb.Append (Translations.GetString (" (in user directory)")); + sb.AppendLine (); + } + install_label.SetLabel (sb.ToString ()); - foreach (Package p in to_uninstall) - sb.AppendLine (p.Name); + uninstall_label.Visible = to_uninstall.Count > 0; + if (uninstall_label.Visible) { + sb.Clear (); - uninstall_label.SetLabel (sb.ToString ()); - } + foreach (Package p in to_uninstall) + sb.AppendLine (p.Name); - dependencies_heading_label.Visible = dependencies_label.Visible = unresolved.Count > 0; - if (dependencies_label.Visible) { - sb.Clear (); + uninstall_label.SetLabel (sb.ToString ()); + } - foreach (Dependency p in unresolved) - sb.AppendLine (p.Name); + uninstall_heading_label.Visible = uninstall_label.Visible = to_uninstall.Count > 0; + if (uninstall_label.Visible) { + sb.Clear (); - dependencies_label.SetLabel (sb.ToString ()); - } + foreach (Package p in to_uninstall) + sb.AppendLine (p.Name); - install_button.Sensitive = success; + uninstall_label.SetLabel (sb.ToString ()); } - private async void HandleInstallClicked () - { - install_button.Sensitive = false; - cancel_button.Sensitive = false; + dependencies_heading_label.Visible = dependencies_label.Visible = unresolved.Count > 0; + if (dependencies_label.Visible) { + sb.Clear (); - error_reporter.Clear (); - progress_bar.ShowProgress (); + foreach (Dependency p in unresolved) + sb.AppendLine (p.Name); - if (addins_to_remove.Any ()) - await Uninstall (); - else - await Install (); - - progress_bar.HideProgress (); - - install_button.Visible = false; - cancel_button.Sensitive = true; - cancel_button.SetLabel (Translations.GetString ("Close")); - - install_heading_label.Visible = install_label.Visible = false; - uninstall_heading_label.Visible = uninstall_label.Visible = false; - dependencies_heading_label.Visible = dependencies_label.Visible = false; - - error_heading_label.Visible = error_label.Visible = error_reporter.Errors.Any (); - if (error_label.Visible) - error_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Errors)); - else { - warning_heading_label.Visible = warning_label.Visible = error_reporter.Warnings.Any (); - if (warning_label.Visible) - warning_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Warnings)); - else - Close (); // Success with no warnings! - - OnSuccess?.Invoke (this, EventArgs.Empty); - } + dependencies_label.SetLabel (sb.ToString ()); } - private Task Install () - { - error_heading_label.SetLabel (Translations.GetString ("The installation failed!")); - warning_heading_label.SetLabel (Translations.GetString ("The installation has completed with warnings.")); + install_button.Sensitive = success; + } - return Task.Run (() => { - service.Install (progress_bar, packages_to_install); - }); - } + private async void HandleInstallClicked () + { + install_button.Sensitive = false; + cancel_button.Sensitive = false; + + error_reporter.Clear (); + progress_bar.ShowProgress (); + + if (addins_to_remove.Any ()) + await Uninstall (); + else + await Install (); - private Task Uninstall () - { - error_heading_label.SetLabel (Translations.GetString ("The uninstallation failed!")); - warning_heading_label.SetLabel (Translations.GetString ("The uninstallation has completed with warnings.")); + progress_bar.HideProgress (); - return Task.Run (() => { - service.Uninstall (progress_bar, addins_to_remove); - }); + install_button.Visible = false; + cancel_button.Sensitive = true; + cancel_button.SetLabel (Translations.GetString ("Close")); + + install_heading_label.Visible = install_label.Visible = false; + uninstall_heading_label.Visible = uninstall_label.Visible = false; + dependencies_heading_label.Visible = dependencies_label.Visible = false; + + error_heading_label.Visible = error_label.Visible = error_reporter.Errors.Any (); + if (error_label.Visible) + error_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Errors)); + else { + warning_heading_label.Visible = warning_label.Visible = error_reporter.Warnings.Any (); + if (warning_label.Visible) + warning_label.SetLabel (string.Join (Environment.NewLine, error_reporter.Warnings)); + else + Close (); // Success with no warnings! + + OnSuccess?.Invoke (this, EventArgs.Empty); } } - internal class InstallErrorReporter : IErrorReporter + private Task Install () { - public List Errors { get; private init; } = new (); - public List Warnings { get; private init; } = new (); + error_heading_label.SetLabel (Translations.GetString ("The installation failed!")); + warning_heading_label.SetLabel (Translations.GetString ("The installation has completed with warnings.")); - public InstallErrorReporter () - { - } + return Task.Run (() => { + service.Install (progress_bar, packages_to_install); + }); + } - public void ReportError (string message, Exception exception) - { - Errors.Add (message); - } + private Task Uninstall () + { + error_heading_label.SetLabel (Translations.GetString ("The uninstallation failed!")); + warning_heading_label.SetLabel (Translations.GetString ("The uninstallation has completed with warnings.")); - public void ReportWarning (string message) - { - Warnings.Add (message); - } + return Task.Run (() => { + service.Uninstall (progress_bar, addins_to_remove); + }); + } +} - public void Clear () - { - Errors.Clear (); - Warnings.Clear (); - } +internal class InstallErrorReporter : IErrorReporter +{ + public List Errors { get; private init; } = new (); + public List Warnings { get; private init; } = new (); + + public InstallErrorReporter () + { + } + + public void ReportError (string message, Exception exception) + { + Errors.Add (message); + } + + public void ReportWarning (string message) + { + Warnings.Add (message); + } + + public void Clear () + { + Errors.Clear (); + Warnings.Clear (); } } diff --git a/Pinta.Tools/Tools/LassoSelectTool.cs b/Pinta.Tools/Tools/LassoSelectTool.cs index b2b7cf47b..92e8192f7 100644 --- a/Pinta.Tools/Tools/LassoSelectTool.cs +++ b/Pinta.Tools/Tools/LassoSelectTool.cs @@ -24,122 +24,121 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using System.Collections.Generic; -using System.Linq; -using Cairo; -using ClipperLib; -using Gtk; -using Pinta.Core; - -namespace Pinta.Tools -{ - public class LassoSelectTool : BaseTool - { - private readonly IWorkspaceService workspace; - - private bool is_drawing = false; - private CombineMode combine_mode; - private SelectionHistoryItem? hist; - - private Path? path; - private readonly List lasso_polygon = new List (); - - public LassoSelectTool (IServiceManager services) : base (services) - { - workspace = services.GetService (); - } - - public override string Name => Translations.GetString ("Lasso Select"); - public override string Icon => Pinta.Resources.Icons.ToolSelectLasso; - public override string StatusBarText => Translations.GetString ("Click and drag to draw the outline for a selection area."); - public override Gdk.Key ShortcutKey => Gdk.Key.S; - public override Gdk.Cursor DefaultCursor => Gdk.Cursor.NewFromTexture (Resources.GetIcon ("Cursor.LassoSelect.png"), 9, 18, null); - public override int Priority => 17; - - protected override void OnBuildToolBar (Box tb) - { - base.OnBuildToolBar (tb); - - workspace.SelectionHandler.BuildToolbar (tb, Settings); - } - - protected override void OnMouseDown (Document document, ToolMouseEventArgs e) - { - if (is_drawing) - return; - - hist = new SelectionHistoryItem (Icon, Name); - hist.TakeSnapshot (); - - combine_mode = workspace.SelectionHandler.DetermineCombineMode (e); - path = null; - is_drawing = true; - - document.PreviousSelection = document.Selection.Clone (); - } - - protected override void OnMouseMove (Document document, ToolMouseEventArgs e) - { - if (!is_drawing) - return; - - var x = Utility.Clamp (e.PointDouble.X, 0, document.ImageSize.Width - 1); - var y = Utility.Clamp (e.PointDouble.Y, 0, document.ImageSize.Height - 1); - - document.Selection.Visible = true; - - var surf = document.Layers.SelectionLayer.Surface; - - var g = new Context (surf); - g.Antialias = Antialias.Subpixel; - - if (path != null) { - g.AppendPath (path); - } else { - g.MoveTo (x, y); - } - - g.LineTo (x, y); - lasso_polygon.Add (new IntPoint ((long) x, (long) y)); - - path = g.CopyPath (); - - g.FillRule = FillRule.EvenOdd; - g.ClosePath (); - - document.Selection.SelectionPolygons.Clear (); - document.Selection.SelectionPolygons.Add (lasso_polygon.ToList ()); - - SelectionModeHandler.PerformSelectionMode (document, combine_mode, document.Selection.SelectionPolygons); - - document.Workspace.Invalidate (); - } - - protected override void OnMouseUp (Document document, ToolMouseEventArgs e) - { - var surf = document.Layers.SelectionLayer.Surface; - - var g = new Context (surf); - if (path != null) { - g.AppendPath (path); - path = null; - } - - g.FillRule = FillRule.EvenOdd; - g.ClosePath (); - - document.Selection.SelectionPolygons.Clear (); - document.Selection.SelectionPolygons.Add (lasso_polygon.ToList ()); - SelectionModeHandler.PerformSelectionMode (document, combine_mode, document.Selection.SelectionPolygons); - document.Workspace.Invalidate (); - - if (hist != null) { - document.History.PushNewItem (hist); - hist = null; - } - - lasso_polygon.Clear (); - is_drawing = false; - } - } -} +using System.Collections.Generic; +using System.Linq; +using Cairo; +using ClipperLib; +using Gtk; +using Pinta.Core; + +namespace Pinta.Tools; + +public class LassoSelectTool : BaseTool +{ + private readonly IWorkspaceService workspace; + + private bool is_drawing = false; + private CombineMode combine_mode; + private SelectionHistoryItem? hist; + + private Path? path; + private readonly List lasso_polygon = new List (); + + public LassoSelectTool (IServiceManager services) : base (services) + { + workspace = services.GetService (); + } + + public override string Name => Translations.GetString ("Lasso Select"); + public override string Icon => Pinta.Resources.Icons.ToolSelectLasso; + public override string StatusBarText => Translations.GetString ("Click and drag to draw the outline for a selection area."); + public override Gdk.Key ShortcutKey => Gdk.Key.S; + public override Gdk.Cursor DefaultCursor => Gdk.Cursor.NewFromTexture (Resources.GetIcon ("Cursor.LassoSelect.png"), 9, 18, null); + public override int Priority => 17; + + protected override void OnBuildToolBar (Box tb) + { + base.OnBuildToolBar (tb); + + workspace.SelectionHandler.BuildToolbar (tb, Settings); + } + + protected override void OnMouseDown (Document document, ToolMouseEventArgs e) + { + if (is_drawing) + return; + + hist = new SelectionHistoryItem (Icon, Name); + hist.TakeSnapshot (); + + combine_mode = workspace.SelectionHandler.DetermineCombineMode (e); + path = null; + is_drawing = true; + + document.PreviousSelection = document.Selection.Clone (); + } + + protected override void OnMouseMove (Document document, ToolMouseEventArgs e) + { + if (!is_drawing) + return; + + var x = Utility.Clamp (e.PointDouble.X, 0, document.ImageSize.Width - 1); + var y = Utility.Clamp (e.PointDouble.Y, 0, document.ImageSize.Height - 1); + + document.Selection.Visible = true; + + var surf = document.Layers.SelectionLayer.Surface; + + var g = new Context (surf); + g.Antialias = Antialias.Subpixel; + + if (path != null) { + g.AppendPath (path); + } else { + g.MoveTo (x, y); + } + + g.LineTo (x, y); + lasso_polygon.Add (new IntPoint ((long) x, (long) y)); + + path = g.CopyPath (); + + g.FillRule = FillRule.EvenOdd; + g.ClosePath (); + + document.Selection.SelectionPolygons.Clear (); + document.Selection.SelectionPolygons.Add (lasso_polygon.ToList ()); + + SelectionModeHandler.PerformSelectionMode (document, combine_mode, document.Selection.SelectionPolygons); + + document.Workspace.Invalidate (); + } + + protected override void OnMouseUp (Document document, ToolMouseEventArgs e) + { + var surf = document.Layers.SelectionLayer.Surface; + + var g = new Context (surf); + if (path != null) { + g.AppendPath (path); + path = null; + } + + g.FillRule = FillRule.EvenOdd; + g.ClosePath (); + + document.Selection.SelectionPolygons.Clear (); + document.Selection.SelectionPolygons.Add (lasso_polygon.ToList ()); + SelectionModeHandler.PerformSelectionMode (document, combine_mode, document.Selection.SelectionPolygons); + document.Workspace.Invalidate (); + + if (hist != null) { + document.History.PushNewItem (hist); + hist = null; + } + + lasso_polygon.Clear (); + is_drawing = false; + } +} diff --git a/Pinta/Actions/File/CloseDocumentAction.cs b/Pinta/Actions/File/CloseDocumentAction.cs index 7f0b98688..085bda64e 100644 --- a/Pinta/Actions/File/CloseDocumentAction.cs +++ b/Pinta/Actions/File/CloseDocumentAction.cs @@ -27,65 +27,64 @@ using System; using Pinta.Core; -namespace Pinta.Actions +namespace Pinta.Actions; + +class CloseDocumentAction : IActionHandler { - class CloseDocumentAction : IActionHandler + #region IActionHandler Members + public void Initialize () { - #region IActionHandler Members - public void Initialize () - { - PintaCore.Actions.File.Close.Activated += Activated; - } + PintaCore.Actions.File.Close.Activated += Activated; + } - public void Uninitialize () - { - PintaCore.Actions.File.Close.Activated -= Activated; - } - #endregion + public void Uninitialize () + { + PintaCore.Actions.File.Close.Activated -= Activated; + } + #endregion - private void Activated (object sender, EventArgs e) - { - // Commit any pending changes - PintaCore.Tools.Commit (); + private void Activated (object sender, EventArgs e) + { + // Commit any pending changes + PintaCore.Tools.Commit (); - // If it's not dirty, just close it - if (!PintaCore.Workspace.ActiveDocument.IsDirty) { - PintaCore.Workspace.CloseActiveDocument (); - return; - } + // If it's not dirty, just close it + if (!PintaCore.Workspace.ActiveDocument.IsDirty) { + PintaCore.Workspace.CloseActiveDocument (); + return; + } - var heading = Translations.GetString ("Save changes to image \"{0}\" before closing?", - PintaCore.Workspace.ActiveDocument.DisplayName); - var body = Translations.GetString ("If you don't save, all changes will be permanently lost."); + var heading = Translations.GetString ("Save changes to image \"{0}\" before closing?", + PintaCore.Workspace.ActiveDocument.DisplayName); + var body = Translations.GetString ("If you don't save, all changes will be permanently lost."); - var dialog = Adw.MessageDialog.New (PintaCore.Chrome.MainWindow, heading, body); + var dialog = Adw.MessageDialog.New (PintaCore.Chrome.MainWindow, heading, body); - const string cancel_response = "cancel"; - const string discard_response = "discard"; - const string save_response = "save"; - dialog.AddResponse (cancel_response, Translations.GetString ("_Cancel")); - dialog.AddResponse (discard_response, Translations.GetString ("_Discard")); - dialog.AddResponse (save_response, Translations.GetString ("_Save")); + const string cancel_response = "cancel"; + const string discard_response = "discard"; + const string save_response = "save"; + dialog.AddResponse (cancel_response, Translations.GetString ("_Cancel")); + dialog.AddResponse (discard_response, Translations.GetString ("_Discard")); + dialog.AddResponse (save_response, Translations.GetString ("_Save")); - // Configure the styling for the save / discard buttons. - dialog.SetResponseAppearance (discard_response, Adw.ResponseAppearance.Destructive); - dialog.SetResponseAppearance (save_response, Adw.ResponseAppearance.Suggested); + // Configure the styling for the save / discard buttons. + dialog.SetResponseAppearance (discard_response, Adw.ResponseAppearance.Destructive); + dialog.SetResponseAppearance (save_response, Adw.ResponseAppearance.Suggested); - dialog.CloseResponse = cancel_response; - dialog.DefaultResponse = save_response; + dialog.CloseResponse = cancel_response; + dialog.DefaultResponse = save_response; - string response = dialog.RunBlocking (); - if (response == save_response) { - PintaCore.Workspace.ActiveDocument.Save (false); + string response = dialog.RunBlocking (); + if (response == save_response) { + PintaCore.Workspace.ActiveDocument.Save (false); - // If the image is still dirty, the user - // must have cancelled the Save dialog - if (!PintaCore.Workspace.ActiveDocument.IsDirty) - PintaCore.Workspace.CloseActiveDocument (); - } else if (response == discard_response) { + // If the image is still dirty, the user + // must have cancelled the Save dialog + if (!PintaCore.Workspace.ActiveDocument.IsDirty) PintaCore.Workspace.CloseActiveDocument (); - } - + } else if (response == discard_response) { + PintaCore.Workspace.CloseActiveDocument (); } + } } diff --git a/Pinta/Actions/File/DBus/RequestsPortal.cs b/Pinta/Actions/File/DBus/RequestsPortal.cs index 6d0e04357..f2d23ec76 100644 --- a/Pinta/Actions/File/DBus/RequestsPortal.cs +++ b/Pinta/Actions/File/DBus/RequestsPortal.cs @@ -1,21 +1,20 @@ -/// This file is generated automatically and manually adjusted. -/// dotnet tool install -g Tmds.DBus.Tool -/// dotnet dbus codegen Requests.xml -/// https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.Request.xml +/// This file is generated automatically and manually adjusted. +/// dotnet tool install -g Tmds.DBus.Tool +/// dotnet dbus codegen Requests.xml +/// https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.Request.xml -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; -using Tmds.DBus; - -[assembly: InternalsVisibleTo (Tmds.DBus.Connection.DynamicAssemblyName)] -namespace Requests.DBus +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Tmds.DBus; + +[assembly: InternalsVisibleTo (Tmds.DBus.Connection.DynamicAssemblyName)] +namespace Requests.DBus; + +[DBusInterface ("org.freedesktop.portal.Request")] +interface IRequest : IDBusObject { - [DBusInterface ("org.freedesktop.portal.Request")] - interface IRequest : IDBusObject - { - Task CloseAsync (); - Task WatchResponseAsync (Action<(uint response, IDictionary results)> handler, Action? onError = null); - } -} + Task CloseAsync (); + Task WatchResponseAsync (Action<(uint response, IDictionary results)> handler, Action? onError = null); +} diff --git a/Pinta/Actions/File/DBus/ScreenshotPortal.cs b/Pinta/Actions/File/DBus/ScreenshotPortal.cs index 3f6c2e52a..9bade5282 100644 --- a/Pinta/Actions/File/DBus/ScreenshotPortal.cs +++ b/Pinta/Actions/File/DBus/ScreenshotPortal.cs @@ -1,45 +1,44 @@ -/// This file is generated automatically and manually adjusted. -/// dotnet tool install -g Tmds.DBus.Tool -/// dotnet dbus codegen --bus session --service org.freedesktop.portal.Desktop --interface org.freedesktop.portal.Screenshot +/// This file is generated automatically and manually adjusted. +/// dotnet tool install -g Tmds.DBus.Tool +/// dotnet dbus codegen --bus session --service org.freedesktop.portal.Desktop --interface org.freedesktop.portal.Screenshot -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; -using Requests.DBus; -using Tmds.DBus; - -[assembly: InternalsVisibleTo (Tmds.DBus.Connection.DynamicAssemblyName)] -namespace ScreenshotPortal.DBus +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Requests.DBus; +using Tmds.DBus; + +[assembly: InternalsVisibleTo (Tmds.DBus.Connection.DynamicAssemblyName)] +namespace ScreenshotPortal.DBus; + +[DBusInterface ("org.freedesktop.portal.Screenshot")] +interface IScreenshot : IDBusObject { - [DBusInterface ("org.freedesktop.portal.Screenshot")] - interface IScreenshot : IDBusObject - { - Task ScreenshotAsync (string ParentWindow, IDictionary Options); - Task PickColorAsync (string ParentWindow, IDictionary Options); - Task GetAsync (string prop); - Task GetAllAsync (); - Task SetAsync (string prop, object val); - Task WatchPropertiesAsync (Action handler); - } + Task ScreenshotAsync (string ParentWindow, IDictionary Options); + Task PickColorAsync (string ParentWindow, IDictionary Options); + Task GetAsync (string prop); + Task GetAllAsync (); + Task SetAsync (string prop, object val); + Task WatchPropertiesAsync (Action handler); +} - [Dictionary] - class ScreenshotProperties - { - private uint _version = default (uint); - public uint Version { - get { - return _version; - } +[Dictionary] +class ScreenshotProperties +{ + private uint _version = default (uint); + public uint Version { + get { + return _version; + } - set { - _version = (value); - } + set { + _version = (value); } } +} - static class ScreenshotExtensions - { - public static Task GetVersionAsync (this IScreenshot o) => o.GetAsync ("version"); - } -} +static class ScreenshotExtensions +{ + public static Task GetVersionAsync (this IScreenshot o) => o.GetAsync ("version"); +}