Skip to content

Commit

Permalink
Merge pull request #17 from ItsTheSky/features/addons-enhancement
Browse files Browse the repository at this point in the history
🚀 Addons enhancement & file association
  • Loading branch information
ItsTheSky authored Jan 30, 2024
2 parents 5b69b73 + 30c708e commit 5265cbe
Show file tree
Hide file tree
Showing 25 changed files with 3,284 additions and 20 deletions.
7 changes: 5 additions & 2 deletions SkEditor/API/AddonLoader.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using Serilog;
using SkEditor.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using Serilog;
using SkEditor.Utilities;
using SkEditor.Views;

namespace SkEditor.API;
public class AddonLoader
Expand Down Expand Up @@ -91,6 +92,8 @@ private static void EnableAddons()
{
Log.Error(ex, "Failed to load addons");
}

MainWindow.Instance.MainMenu.LoadAddonsMenus();
}

public static List<Assembly> LoadAddonsFromFolder(string folder)
Expand Down
9 changes: 8 additions & 1 deletion SkEditor/API/ApiVault.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace SkEditor.API;
using SkEditor.Utilities.Files;

namespace SkEditor.API;

public static class ApiVault
{
Expand All @@ -13,4 +15,9 @@ public static ISkEditorAPI Get()
{
return instance;
}

public static void RegisterFileAssociation(FileTypes.FileAssociation association)
{
FileTypes.RegisterExternalAssociation(association);
}
}
17 changes: 16 additions & 1 deletion SkEditor/API/IAddon.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
namespace SkEditor.API;
using System.Collections.Generic;
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using SkEditor.Utilities.Files;

namespace SkEditor.API;
public interface IAddon
{
public string Name { get; }
public string Version { get; }

public virtual List<MenuItem> GetMenuItems()
{
return [];
}

public virtual Symbol GetMenuIcon()
{
return Symbol.Document;
}

public void OnEnable();
}
2 changes: 1 addition & 1 deletion SkEditor/API/ISkEditorAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public interface ISkEditorAPI

public bool IsFile(TabViewItem tabItem);

public TextEditor GetTextEditor();
public TextEditor? GetTextEditor();

public TabView GetTabView();

Expand Down
1 change: 1 addition & 0 deletions SkEditor/App.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<Application.Styles>
<sty:FluentAvaloniaTheme />
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
<StyleInclude Source="/Views/FileTypes/Images/AdvancedImageBox.axaml"/>
<StyleInclude Source="/Styles/ButtonStyles.axaml"></StyleInclude>
</Application.Styles>

Expand Down
2 changes: 2 additions & 0 deletions SkEditor/Controls/BottomBarControl.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using AvaloniaEdit.Document;
using SkEditor.API;
using SkEditor.Utilities;
using SkEditor.Utilities.Files;

namespace SkEditor.Controls;
public partial class BottomBarControl : UserControl
Expand All @@ -17,6 +18,7 @@ public BottomBarControl()
{
Application.Current.ResourcesChanged += (sender, e) => UpdatePosition();
ApiVault.Get().GetTabView().SelectionChanged += (sender, e) => UpdatePosition();
ApiVault.Get().GetTabView().SelectionChanged += (sender, e) => FileHandler.TabSwitchAction();
};
}

Expand Down
3 changes: 3 additions & 0 deletions SkEditor/Controls/MainMenuControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@
<ui:IconSourceElement IconSource="{StaticResource RefactorIcon}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Name="AddonsMenuItem" Header="{DynamicResource MenuHeaderAddons}">

</MenuItem>
<MenuItem Header="{DynamicResource MenuHeaderOther}">
<MenuItem Header="{DynamicResource MenuHeaderMarketplace}" Name="MenuItemMarketplace">
Expand Down
26 changes: 26 additions & 0 deletions SkEditor/Controls/MainMenuControl.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using SkEditor.Views.Generators;
using SkEditor.Views.Generators.Gui;
using System;
using FluentAvalonia.UI.Controls;

namespace SkEditor.Controls;
public partial class MainMenuControl : UserControl
Expand Down Expand Up @@ -57,4 +58,29 @@ private void AssignCommands()
MenuItemRefactor.Command = new RelayCommand(() => new RefactorWindow().ShowDialog(ApiVault.Get().GetMainWindow()));
MenuItemMarketplace.Command = new RelayCommand(() => new MarketplaceWindow().ShowDialog(ApiVault.Get().GetMainWindow()));
}

public void LoadAddonsMenus()
{
bool hasAnyMenu = false;
foreach (IAddon addon in AddonLoader.Addons)
{
var items = addon.GetMenuItems();
if (items.Count <= 0)
continue;

hasAnyMenu = true;
var menuItem = new MenuItem()
{
Header = addon.Name,
Icon = new SymbolIcon() { Symbol = addon.GetMenuIcon() }
};

foreach (MenuItem sub in items)
menuItem.Items.Add(sub);

AddonsMenuItem.Items.Add(menuItem);
}

AddonsMenuItem.IsVisible = hasAnyMenu;
}
}
14 changes: 14 additions & 0 deletions SkEditor/Languages/English.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<system:String x:Key="MenuHeaderEdit">Edit</system:String>
<system:String x:Key="MenuHeaderTools">Tools</system:String>
<system:String x:Key="MenuHeaderOther">Other</system:String>
<system:String x:Key="MenuHeaderAddons">Addons</system:String>

<!-- File Menu -->
<system:String x:Key="MenuHeaderNew">New</system:String>
Expand Down Expand Up @@ -80,6 +81,8 @@
<system:String x:Key="UpdateAvailable">Update available</system:String>
<system:String x:Key="UpdateAvailableMessage">An update is available.\nWould you like to download it now?</system:String>
<system:String x:Key="UpdateFailed">Failed to download the update. Please try again later.</system:String>
<system:String x:Key="BinaryFileFound">It seems you're trying to open a binary file (or a non text-based file).\n\nDo you want to open it anyway? SkEditor may not handle it correctly.</system:String>
<system:String x:Key="BinaryFileTitle">Binary File Found</system:String>


<!-- Publish Window -->
Expand All @@ -93,6 +96,14 @@
<system:String x:Key="RefactorWindowRemoveComments">Remove comments</system:String>
<system:String x:Key="RefactorWindowTabsToSpaces">Convert tabs to spaces</system:String>
<system:String x:Key="RefactorWindowSpacesToTabs">Convert spaces to tabs</system:String>

<!-- File Association Selection Window -->
<system:String x:Key="FileAssociationSelectionWindowTitle">Select file association</system:String>
<system:String x:Key="FileAssociationSelectionWindowInfo">There's multiple provider for this file type. Please select one.</system:String>
<system:String x:Key="FileAssociationSelectionWindowOfficialItem">This is an official file type from SkEditor.</system:String>
<system:String x:Key="FileAssociationSelectionWindowUnofficialItem">This is an unofficial file type from an addon, {0}.</system:String>
<system:String x:Key="FileAssociationSelectionWindowRememberMyChoice">Remember my choice</system:String>
<system:String x:Key="FileAssociationSelectionWindowConfirm">Confirm</system:String>

<!-- Settings -->
<system:String x:Key="SettingsEnabled">Enabled</system:String>
Expand Down Expand Up @@ -156,6 +167,9 @@

<!-- Addon Settings -->
<system:String x:Key="SettingsAddonsTitle">Addons</system:String>

<!-- File Views -->
<system:String x:Key="FileViewImageAA">Antialiasing</system:String>

<!-- Discord RPC -->
<system:String x:Key="DiscordRpcEditing">Editing: {0}</system:String>
Expand Down
3 changes: 3 additions & 0 deletions SkEditor/SkEditor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<AssemblyVersion>2.1.2</AssemblyVersion>
<FileVersion>2.1.2</FileVersion>
<Version>2.1.2</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>CS8600;CS8604;CS8622;CS8603;CS8602;CA2211;CS8619;CS8629;CS8601;CS8618;CS8620</NoWarn>
Expand Down Expand Up @@ -137,6 +138,8 @@
<Compile Update="Views\Settings\Personalization\ThemePage.axaml.cs">
<DependentUpon>ThemePage.axaml</DependentUpon>
</Compile>
<Compile Update="Views\FileTypes\Images\ImageViewer.axaml.cs">
<DependentUpon>ImageViewer.axaml</DependentUpon>
<Compile Update="Controls\Sidebar\CodeParser\ParserSidebarPanel.axaml.cs">
<DependentUpon>ParserSidebarPanel.axaml</DependentUpon>
<SubType>Code</SubType>
Expand Down
1 change: 1 addition & 0 deletions SkEditor/Utilities/AppConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class AppConfig
public HashSet<string> AddonsToUpdate { get; set; } = [];

public Dictionary<string, object> CustomOptions { get; set; } = [];
public Dictionary<string, string> PreferredFileAssociations { get; set; } = [];

public bool EnableAutoCompletionExperiment { get; set; } = false;

Expand Down
2 changes: 2 additions & 0 deletions SkEditor/Utilities/CrashChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public async static Task<bool> CheckForCrash()
Directory.GetFiles(tempPath).ToList().ForEach(async file =>
{
TabViewItem tabItem = await FileBuilder.Build(Path.GetFileName(file), file);
if (tabItem == null)
return;
tabItem.Tag = null;
(ApiVault.Get().GetTabView().TabItems as IList)?.Add(tabItem);
});
Expand Down
112 changes: 104 additions & 8 deletions SkEditor/Utilities/Files/FileBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,35 @@
using SkEditor.Utilities.Completion;
using SkEditor.Utilities.Editor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using SkEditor.Views;
using SkEditor.Views.FileTypes;

namespace SkEditor.Utilities.Files;

public class FileBuilder
{
public async static Task<TabViewItem> Build(string header, string path = "")
public static readonly Dictionary<string, FileTypes.FileType> OpenedFiles = new();

public static async Task<TabViewItem?> Build(string header, string path = "")
{
TextEditor editor = await GetDefaultEditor(path);
var fileType = await GetFileDisplay(path);
if (fileType == null)
return null;

TabViewItem tabViewItem = new()
{
Header = header,
IsSelected = true,
Content = editor,
Content = fileType.Display,
Tag = string.Empty
};

MainWindow.Instance.BottomBar.IsVisible = fileType.NeedsBottomBar;

if (!string.IsNullOrWhiteSpace(path))
{
tabViewItem.Tag = Uri.UnescapeDataString(path);
Expand All @@ -46,16 +56,102 @@ public async static Task<TabViewItem> Build(string header, string path = "")
Icon.SetIcon(tabViewItem);
}

ApiVault.Get().OnFileCreated(editor);
Dispatcher.UIThread.Post(() => TextEditorEventHandler.CheckForHex(editor));
if (fileType.IsEditor)
{
var editor = fileType.Display as TextEditor;

ApiVault.Get().OnFileCreated(editor);
Dispatcher.UIThread.Post(() => TextEditorEventHandler.CheckForHex(editor));
}

if (OpenedFiles.ContainsKey(header))
OpenedFiles.Remove(header);

OpenedFiles.Add(header, fileType);
return tabViewItem;
}

private async static Task<TextEditor> GetDefaultEditor(string path)
private static async Task<FileTypes.FileType?> GetFileDisplay(string path)
{
FileTypes.FileType? fileType = null;
if (FileTypes.RegisteredFileTypes.ContainsKey(Path.GetExtension(path)))
{
var handlers = FileTypes.RegisteredFileTypes[Path.GetExtension(path)];
if (handlers.Count == 1)
{
fileType = handlers[0].Handle(path);
}
else
{
var ext = Path.GetExtension(path);
if (ApiVault.Get().GetAppConfig().PreferredFileAssociations.ContainsKey(ext))
{
var pref = ApiVault.Get().GetAppConfig().PreferredFileAssociations[ext];
if (pref == "SkEditor")
{
fileType = handlers.Find(association => !association.IsFromAddon).Handle(path);
}
else
{
var preferred = handlers.Find(association => association.IsFromAddon &&
association.Addon.Name == ApiVault.Get().GetAppConfig().PreferredFileAssociations[ext]);
if (preferred != null)
{
fileType = preferred.Handle(path);
}
else
{
ApiVault.Get().GetAppConfig().PreferredFileAssociations.Remove(ext);
}
}
}

if (fileType == null)
{
var window = new AssociationSelectionWindow(path, handlers);
await window.ShowDialog(MainWindow.Instance);
var selected = window.SelectedAssociation;
if (selected != null)
{
fileType = selected.Handle(path);
if (window.RememberCheck.IsChecked == true)
{
ApiVault.Get().GetAppConfig().PreferredFileAssociations[ext] = selected.IsFromAddon ? selected.Addon.Name : "SkEditor";
}
else
{
ApiVault.Get().GetAppConfig().PreferredFileAssociations.Remove(ext);
}
ApiVault.Get().GetAppConfig().Save();
}
}
}
}

return fileType ?? await GetDefaultEditor(path);
}

private static async Task<FileTypes.FileType?> GetDefaultEditor(string path)
{
AppConfig config = ApiVault.Get().GetAppConfig();

string fileContent = null;
if (!string.IsNullOrWhiteSpace(path))
{
path = Uri.UnescapeDataString(path);
if (File.Exists(path))
fileContent = await File.ReadAllTextAsync(path);
}

if (fileContent != null && fileContent.Any(c => char.IsControl(c) && c != '\n' && c != '\r' && c != '\t'))
{
var response = await ApiVault.Get().ShowMessageWithIcon(
Translation.Get("BinaryFileTitle"), Translation.Get("BinaryFileFound"),
new SymbolIconSource() { Symbol = Symbol.Alert });
if (response != ContentDialogResult.Primary)
return null;
}

TextEditor editor = new()
{
ShowLineNumbers = true,
Expand Down Expand Up @@ -83,14 +179,14 @@ private async static Task<TextEditor> GetDefaultEditor(string path)
path = Uri.UnescapeDataString(path);
if (File.Exists(path))
{
editor.Text = await File.ReadAllTextAsync(path);
editor.Text = fileContent;
}
}

editor = AddEventHandlers(editor);
editor = SetOptions(editor);

return editor;
return new FileTypes.FileType(editor, path, true);
}

private static TextEditor AddEventHandlers(TextEditor editor)
Expand Down
Loading

0 comments on commit 5265cbe

Please sign in to comment.