/* * GNU AFFERO GENERAL PUBLIC LICENSE * Version 3, 19 November 2007 * Copyright (C) 2007 Free Software Foundation, Inc. * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. */ using System; using System.ComponentModel; using System.Xml.Serialization; using UVtools.Core.FileFormats; using UVtools.Core.Objects; using UVtools.Core.Operations; namespace UVtools.Core.Suggestions; public abstract class Suggestion : BindableBase { #region Enums public enum SuggestionApplyWhen : byte { [Description("Outside limits: Applies when the recommended value does not meet the current limit criteria")] OutsideLimits, [Description("Different: Applies when the recommended value is different from the current")] Different, } #endregion #region Members protected FileFormat _slicerFile = null!; protected bool _enabled = true; protected bool _autoApply; protected SuggestionApplyWhen _applyWhen = SuggestionApplyWhen.OutsideLimits; #endregion #region Properties /// /// Gets or sets the /// [XmlIgnore] public FileFormat SlicerFile { get => _slicerFile; set { if (ReferenceEquals(_slicerFile, value)) return; _slicerFile = value; RaisePropertyChanged(); RaisePropertyChanged(nameof(IsAvailable)); RaisePropertyChanged(nameof(IsApplied)); } } /// /// Gets or sets if this suggestion is enabled /// public bool Enabled { get => _enabled; set => RaiseAndSetIfChanged(ref _enabled, value); } /// /// Gets or sets if this suggestion can be auto applied once file load /// public bool AutoApply { get => _autoApply; set => RaiseAndSetIfChanged(ref _autoApply, value); } /// /// Gets or sets when to apply the suggestion /// public SuggestionApplyWhen ApplyWhen { get => _applyWhen; set => RaiseAndSetIfChanged(ref _applyWhen, value); } /// /// Gets if this suggestion is informative only and contain no actions to execute /// public virtual bool IsInformativeOnly => false; /// /// Gets if this suggestion is available given the /// public virtual bool IsAvailable => true; /// /// Gets if this suggestion is already applied given the /// public abstract bool IsApplied { get; } /// /// Gets the title for this suggestion /// public abstract string Title { get; } public abstract string Description { get; } /// /// Gets the message for this suggestion /// public abstract string Message { get; } /// /// Gets the tooltip message /// public virtual string ToolTip => Description; public virtual string? InformationUrl => null; /// /// Gets the confirmation message before apply the suggestion /// public virtual string? ConfirmationMessage => null; public string GlobalAppliedMessage => $"✓ {Title}"; public string GlobalNotAppliedMessage => $"⚠ {Title}"; #endregion #region Methods public void RefreshNotifyAll() { RaisePropertyChanged(nameof(IsAvailable)); RaisePropertyChanged(nameof(IsApplied)); RefreshNotifyMessage(); } public void RefreshNotifyMessage() { RaisePropertyChanged(nameof(Message)); RaisePropertyChanged(nameof(ToolTip)); } /// /// Validates the settings and return a string message if got any error /// /// public virtual string? Validate() => null; /// /// Executes and applies the suggestion /// /// /// /// protected virtual bool ExecuteInternally(OperationProgress progress) { throw new NotImplementedException(); } /// /// Executes and applies the suggestion /// /// /// public bool Execute(OperationProgress? progress = null) { if (_slicerFile is null) throw new InvalidOperationException($"The suggestion '{Title}' can't execute due the lacking of a file parent."); if (!Enabled || !IsAvailable || IsApplied || IsInformativeOnly || SlicerFile.LayerCount == 0) return false; progress ??= new OperationProgress(); progress.Title = $"Applying suggestion: {Title}"; var result = ExecuteInternally(progress); RaisePropertyChanged(nameof(IsApplied)); RefreshNotifyMessage(); return result; } /// /// Executes only if this suggestion is marked with as true /// /// public bool ExecuteIfAutoApply() { return _autoApply && Execute(); } public Suggestion Clone() { return (MemberwiseClone() as Suggestion)!; } #endregion }