diff --git a/src/AppCommon/FileTime.App.Core/Command/Commands.cs b/src/AppCommon/FileTime.App.Core/Command/Commands.cs index 5ccb72f..8f83c72 100644 --- a/src/AppCommon/FileTime.App.Core/Command/Commands.cs +++ b/src/AppCommon/FileTime.App.Core/Command/Commands.cs @@ -23,5 +23,7 @@ namespace FileTime.App.Core.Command GoToRoot, GoToProvider, GoToHome, + EnterRapidTravel, + OpenOrRun, } } \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/Application.CommandHandlers.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/Application.CommandHandlers.cs index 9d6147d..4c9ed99 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/Application.CommandHandlers.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/Application.CommandHandlers.cs @@ -1,5 +1,6 @@ using FileTime.ConsoleUI.App.UI.Color; using FileTime.Core.Command; +using FileTime.Core.Extensions; using FileTime.Core.Models; namespace FileTime.ConsoleUI.App @@ -38,7 +39,7 @@ namespace FileTime.ConsoleUI.App var currentLocation = await _selectedTab!.GetCurrentLocation(); - IContainer containerToOpen = currentLocation; + /*IContainer containerToOpen = currentLocation; if (currentLocation is VirtualContainer oldVirtualContainer) { @@ -49,13 +50,15 @@ namespace FileTime.ConsoleUI.App else { containerToOpen = GenerateHiddenFilterVirtualContainer(currentLocation); - } + } */ + + var containerToOpen = await currentLocation.ToggleVirtualContainerInChain(hiddenFilterName, GenerateHiddenFilterVirtualContainer); await _selectedTab.OpenContainer(containerToOpen); - static VirtualContainer GenerateHiddenFilterVirtualContainer(IContainer container) + static async Task GenerateHiddenFilterVirtualContainer(IContainer container) { - return new VirtualContainer( + var newContainer = new VirtualContainer( container, new List, IEnumerable>>() { @@ -69,6 +72,10 @@ namespace FileTime.ConsoleUI.App true, hiddenFilterName ); + + await newContainer.Init(); + + return newContainer; } } diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs index 2b59d04..9170c3a 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/UI/Render.cs @@ -43,7 +43,7 @@ namespace FileTime.ConsoleUI.App.UI if (paneState == null) throw new Exception($"{nameof(paneState)} can not be null"); Tab = pane; - Tab.CurrentLocationChanged += (o, e) => _currentDisplayStartY = 0; + Tab.CurrentLocationChanged.Add((_, _) => { _currentDisplayStartY = 0; return Task.CompletedTask; }); TabState = paneState; } diff --git a/src/Core/FileTime.Core/Components/Tab.cs b/src/Core/FileTime.Core/Components/Tab.cs index 7f4ed29..dc74cbe 100644 --- a/src/Core/FileTime.Core/Components/Tab.cs +++ b/src/Core/FileTime.Core/Components/Tab.cs @@ -7,39 +7,7 @@ namespace FileTime.Core.Components { private IItem? _currentSelectedItem; private IContainer _currentLocation; - - /* public IContainer CurrentLocation - { - get => _currentLocation; - private set - { - if (_currentLocation != value) - { - if (_currentLocation != null) - { - _currentLocation.Refreshed -= HandleCurrentLocationRefresh; - } - - _currentLocation = value; - CurrentLocationChanged?.Invoke(this, EventArgs.Empty); - CurrentSelectedItem = CurrentLocation.Items.Count > 0 ? CurrentLocation.Items[0] : null; - _currentLocation.Refreshed += HandleCurrentLocationRefresh; - } - } - } - public IItem? CurrentSelectedItem - { - get => _currentSelectedItem; - set - { - if (_currentSelectedItem != value && (_currentLocation.Items.Contains(value) || value == null)) - { - _currentSelectedItem = value; - CurrentSelectedIndex = GetItemIndex(value); - CurrentSelectedItemChanged?.Invoke(this, EventArgs.Empty); - } - } - } */ + public int CurrentSelectedIndex { get; private set; } public AsyncEventHandler CurrentLocationChanged = new(); diff --git a/src/Core/FileTime.Core/Extensions/ContainerExtensions.cs b/src/Core/FileTime.Core/Extensions/ContainerExtensions.cs new file mode 100644 index 0000000..03a206a --- /dev/null +++ b/src/Core/FileTime.Core/Extensions/ContainerExtensions.cs @@ -0,0 +1,25 @@ +using FileTime.Core.Models; + +namespace FileTime.Core.Extensions +{ + public static class ContainerExtensions + { + public static async Task ToggleVirtualContainerInChain(this IContainer container, string filterName, Func> generator) + { + if (container is VirtualContainer oldVirtualContainer) + { + return oldVirtualContainer.HasWithName(filterName) + ? await oldVirtualContainer.ExceptWithName(filterName) + : await generator(container); + } + else + { + return await generator(container); + } + } + public static async Task WithoutVirtualContainer(this IContainer container, string filterName) => + container is VirtualContainer oldVirtualContainer + ? await oldVirtualContainer.ExceptWithName(filterName) + : container; + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core/Models/IContainer.cs b/src/Core/FileTime.Core/Models/IContainer.cs index 32fab49..f6a70f8 100644 --- a/src/Core/FileTime.Core/Models/IContainer.cs +++ b/src/Core/FileTime.Core/Models/IContainer.cs @@ -16,6 +16,8 @@ namespace FileTime.Core.Models Task IsExists(string name); + Task Clone(); + AsyncEventHandler Refreshed { get; } } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Models/VirtualContainer.cs b/src/Core/FileTime.Core/Models/VirtualContainer.cs index 1a727d1..931e5eb 100644 --- a/src/Core/FileTime.Core/Models/VirtualContainer.cs +++ b/src/Core/FileTime.Core/Models/VirtualContainer.cs @@ -90,17 +90,20 @@ namespace FileTime.Core.Models || (BaseContainer is VirtualContainer virtualContainer && virtualContainer.HasWithName(name)); - public IContainer ExceptWithName(string name) + public async Task ExceptWithName(string name) { if (BaseContainer is VirtualContainer virtualBaseContainer && virtualBaseContainer.VirtualContainerName == name) { - return new VirtualContainer( - virtualBaseContainer.ExceptWithName(name), + var newContainer = new VirtualContainer( + await virtualBaseContainer.ExceptWithName(name), _containerTransformators, _elementTransformators, IsPermanent, IsTransitive, VirtualContainerName); + + await newContainer.Init(); + return newContainer; } else if (VirtualContainerName == name) { @@ -145,5 +148,16 @@ namespace FileTime.Core.Models } public async Task Delete() => await BaseContainer.Delete(); + public async Task Clone() + { + return new VirtualContainer( + await BaseContainer.Clone(), + _containerTransformators, + _elementTransformators, + IsPermanent, + IsTransitive, + VirtualContainerName + ); + } } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Providers/TopContainer.cs b/src/Core/FileTime.Core/Providers/TopContainer.cs index 28c8af5..9615d04 100644 --- a/src/Core/FileTime.Core/Providers/TopContainer.cs +++ b/src/Core/FileTime.Core/Providers/TopContainer.cs @@ -50,5 +50,7 @@ namespace FileTime.Core.Providers public Task?> GetItems(CancellationToken token = default) => Task.FromResult(_items); public Task?> GetContainers(CancellationToken token = default) => Task.FromResult(_containers); public Task?> GetElements(CancellationToken token = default) => Task.FromResult(_elements); + + public Task Clone() => Task.FromResult((IContainer)this); } } \ No newline at end of file diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/App.xaml.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/App.xaml.cs index e68b624..df0eadc 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/App.xaml.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/App.xaml.cs @@ -32,6 +32,7 @@ namespace FileTime.Uno ServiceProvider ??= DependencyInjection .RegisterDefaultServices() .AddViewModels() + .AddServices() .BuildServiceProvider(); #if HAS_UNO || NETFX_CORE diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/AppState.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/AppState.cs index 1266fe7..3c60988 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/AppState.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/AppState.cs @@ -15,6 +15,13 @@ namespace FileTime.Uno.Application [Property] private TabContainer _selectedTab; + + [Property] + private ViewMode _viewMode; + + [Property] + private string _rapidTravelText = ""; + private void TabsChanged() { SelectedTab ??= Tabs[0]; diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/TabContainer.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/TabContainer.cs index 4bb6437..417b58c 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/TabContainer.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/TabContainer.cs @@ -2,6 +2,7 @@ using FileTime.Core.Components; using FileTime.Core.Models; using FileTime.Providers.Local; +using FileTime.Uno.Services; using FileTime.Uno.ViewModels; using MvvmGen; using System; @@ -14,6 +15,7 @@ using System.Threading.Tasks; namespace FileTime.Uno.Application { [ViewModel] + [Inject(typeof(ItemNameConverterService))] [Inject(typeof(LocalContentProvider))] [Inject(typeof(Tab))] public partial class TabContainer @@ -27,22 +29,36 @@ namespace FileTime.Uno.Application [Property] private ContainerViewModel _childContainer; - [Property] - [PropertyCallMethod(nameof(SelectedItemChanged))] + //[Property] + //[PropertyCallMethod(nameof(SelectedItemChanged))] private IItemViewModel _selectedItem; + public IItemViewModel SelectedItem + { + get => _selectedItem; + set + { + if (_selectedItem != value && value != null) + { + _selectedItem = value; + OnPropertyChanged("SelectedItem"); + SelectedItemChanged(); + } + } + } + public async Task Init() { Tab.CurrentLocationChanged.Add(Tab_CurrentLocationChanged); Tab.CurrentSelectedItemChanged.Add(Tab_CurrentSelectedItemChanged); - CurrentLocation = new ContainerViewModel(await Tab.GetCurrentLocation()); + CurrentLocation = new ContainerViewModel(await Tab.GetCurrentLocation(), ItemNameConverterService); await CurrentLocation.Init(); var parent = (await Tab.GetCurrentLocation()).GetParent(); if (parent != null) { - Parent = new ContainerViewModel(parent); + Parent = new ContainerViewModel(parent, ItemNameConverterService); await Parent.Init(); } else @@ -56,13 +72,13 @@ namespace FileTime.Uno.Application private async Task Tab_CurrentLocationChanged(object sender, AsyncEventArgs e) { var currentLocation = await Tab.GetCurrentLocation(); - CurrentLocation = new ContainerViewModel(currentLocation); + CurrentLocation = new ContainerViewModel(currentLocation, ItemNameConverterService); await CurrentLocation.Init(); var parent = currentLocation.GetParent(); if (parent != null) { - Parent = new ContainerViewModel(parent); + Parent = new ContainerViewModel(parent, ItemNameConverterService); await Parent.Init(); } else @@ -174,7 +190,7 @@ namespace FileTime.Uno.Application public async Task GotToHome() { var path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile).Replace(Path.DirectorySeparatorChar, Constants.SeparatorChar); - var resolvedPath = LocalContentProvider.GetByPath(path); + var resolvedPath = await LocalContentProvider.GetByPath(path); if (resolvedPath is IContainer homeFolder) { await Tab.OpenContainer(homeFolder); @@ -185,5 +201,10 @@ namespace FileTime.Uno.Application { (await Tab.GetCurrentLocation())?.CreateContainer(name); } + + public async Task OpenContainer(IContainer container) + { + await Tab.OpenContainer(container); + } } } diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/ViewMode.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/ViewMode.cs new file mode 100644 index 0000000..b7dedcd --- /dev/null +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Application/ViewMode.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FileTime.Uno.Application +{ + public enum ViewMode + { + Default, + RapidTravel + } +} diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/EqualityToVisibilityConverter.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/EqualityToVisibilityConverter.cs index 6f383b4..04523a1 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/EqualityToVisibilityConverter.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/EqualityToVisibilityConverter.cs @@ -45,6 +45,7 @@ namespace FileTime.Uno.Converters { if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt == parameterInt; else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble == parameterDouble; + else if (value.GetType().IsEnum && Enum.TryParse(value.GetType(), parameter.ToString(), out var _)) return value.ToString() == parameter.ToString(); } return value == parameter; diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/ItemViewModeToBrushConverter.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/ItemViewModeToBrushConverter.cs new file mode 100644 index 0000000..c826f75 --- /dev/null +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Converters/ItemViewModeToBrushConverter.cs @@ -0,0 +1,38 @@ +using FileTime.Uno.Application; +using FileTime.Uno.ViewModels; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Media; +using System; +using System.Collections.Generic; +using System.Text; + +namespace FileTime.Uno.Converters +{ + public class ItemViewModeToBrushConverter : IValueConverter + { + public string DefaultBrush { get; set; } + public string SelectedBrush { get; set; } + public string AlternativeBrush { get; set; } + + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is ItemViewMode viewMode) + { + return viewMode switch + { + ItemViewMode.Default => Microsoft.UI.Xaml.Application.Current.Resources[DefaultBrush], + ItemViewMode.Selected => Microsoft.UI.Xaml.Application.Current.Resources[SelectedBrush], + ItemViewMode.Alternative => Microsoft.UI.Xaml.Application.Current.Resources[AlternativeBrush], + _ => throw new NotSupportedException(), + }; + } + + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.projitems b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.projitems index 82075e6..220b9b8 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.projitems +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.projitems @@ -20,6 +20,7 @@ + @@ -29,6 +30,7 @@ + @@ -38,13 +40,16 @@ + + + diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.shproj b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.shproj index e0cbb72..cbb1127 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.shproj +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/FileTime.Uno.Shared.shproj @@ -13,6 +13,7 @@ <_Globbed_Compile Remove="Application\AppState.cs" /> <_Globbed_Compile Remove="Application\TabContainer.cs" /> + <_Globbed_Compile Remove="Application\ViewMode.cs" /> <_Globbed_Compile Remove="Command\CommandBinding.cs" /> <_Globbed_Compile Remove="Converters\BoolToVisibilityConverter.cs" /> <_Globbed_Compile Remove="Converters\DebugConverter.cs" /> @@ -27,7 +28,9 @@ <_Globbed_Compile Remove="IconProviders\SystemIconProvider.cs" /> <_Globbed_Compile Remove="Misc\InputElementWrapper.cs" /> <_Globbed_Compile Remove="Misc\KeyWithModifiers.cs" /> + <_Globbed_Compile Remove="Models\ItemNamePart.cs" /> <_Globbed_Compile Remove="Models\RootDriveInfo.cs" /> + <_Globbed_Compile Remove="Services\ItemNameConverterService.cs" /> <_Globbed_Compile Remove="Startup.cs" /> <_Globbed_Compile Remove="StyleSelectors\ContentItemStyleSelector.cs" /> <_Globbed_Compile Remove="ViewModels\ContainerViewModel.cs" /> @@ -35,6 +38,7 @@ <_Globbed_Compile Remove="ViewModels\IItemViewModel.cs" /> <_Globbed_Compile Remove="ViewModels\ItemViewMode.cs" /> <_Globbed_Compile Remove="ViewModels\MainPageViewModel.cs" /> + <_Globbed_Compile Remove="ViewModels\TabControlViewModel.cs" /> <_Globbed_Content Remove="Assets\Fonts\Font Awesome 5 Brands-Regular-400.otf" /> diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml index 1901fa1..94307b0 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml @@ -105,11 +105,78 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -235,7 +302,37 @@ - + + + + + + + + + + + + + + + + + + + + diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml.cs index 275bf6a..9d6142f 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/MainPage.xaml.cs @@ -32,9 +32,9 @@ namespace FileTime.Uno ViewModel.FocusDefaultElement = () => (FindName(nameof(CurrentItems)) as FrameworkElement)?.Focus(FocusState.Programmatic); - foreach (var asd in Microsoft.UI.Xaml.Application.Current.Resources.MergedDictionaries) + foreach (var resourceDictionary in Microsoft.UI.Xaml.Application.Current.Resources.MergedDictionaries) { - if (asd is ResourceDictionary resourceDictionary && resourceDictionary.Source != null) + if (resourceDictionary.Source != null) { if (resourceDictionary.Source.LocalPath == "/Files/Themes/DefaultLight.xaml") { @@ -57,9 +57,9 @@ namespace FileTime.Uno CurrentItems.Focus(FocusState.Programmatic); } - private void CurrentItems_KeyDown(object sender, KeyRoutedEventArgs e) + private async void CurrentItems_KeyDown(object sender, KeyRoutedEventArgs e) { - e.Handled = ViewModel.ProcessKeyDown(e.Key) || e.Handled; + e.Handled = await ViewModel.ProcessKeyDown(e.Key) || e.Handled; } private async void CurrentItems_KeyUp(object sender, KeyRoutedEventArgs e) diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Models/ItemNamePart.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Models/ItemNamePart.cs new file mode 100644 index 0000000..9894407 --- /dev/null +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Models/ItemNamePart.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Windows.UI.Text; + +namespace FileTime.Uno.Models +{ + public class ItemNamePart + { + public string Text { get; set; } + public TextDecorations TextDecorations { get; set; } + + public ItemNamePart(string text) + { + Text = text; + } + } +} diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Services/ItemNameConverterService.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Services/ItemNameConverterService.cs new file mode 100644 index 0000000..cc719d1 --- /dev/null +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Services/ItemNameConverterService.cs @@ -0,0 +1,52 @@ +using FileTime.Uno.Application; +using FileTime.Uno.Models; +using FileTime.Uno.ViewModels; +using MvvmGen; +using System; +using System.Collections.Generic; +using System.Text; +using Windows.UI.Text; + +namespace FileTime.Uno.Services +{ + [ViewModel] + [Inject(typeof(AppState))] + public partial class ItemNameConverterService + { + public List GetDisplayName(IItemViewModel itemViewModel) + { + var nameParts = new List(); + var rapidTravelText = AppState.RapidTravelText.ToLower(); + + if (AppState.ViewMode == ViewMode.RapidTravel && rapidTravelText.Length > 0) + { + var nameLeft = itemViewModel.Item.Name; + + while (nameLeft.ToLower().Contains(rapidTravelText)) + { + var rapidTextStart = nameLeft.ToLower().IndexOf(rapidTravelText); + var before = rapidTextStart > 0 ? nameLeft.Substring(0, rapidTextStart) : null; + var rapidTravel = nameLeft.Substring(rapidTextStart, rapidTravelText.Length); + + nameLeft = nameLeft.Substring(rapidTextStart + rapidTravelText.Length); + + if (before != null) + { + nameParts.Add(new ItemNamePart(before)); + } + nameParts.Add(new ItemNamePart(rapidTravel) { TextDecorations = TextDecorations.Underline }); + } + + if (nameLeft.Length > 0) + { + nameParts.Add(new ItemNamePart(nameLeft)); + } + } + else + { + nameParts.Add(new ItemNamePart(itemViewModel.Item.Name)); + } + return nameParts; + } + } +} diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Startup.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Startup.cs index a340413..6ce1740 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Startup.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Startup.cs @@ -1,4 +1,5 @@ using FileTime.Uno.Application; +using FileTime.Uno.Services; using FileTime.Uno.ViewModels; using Microsoft.Extensions.DependencyInjection; using System; @@ -12,9 +13,14 @@ namespace FileTime.Uno internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection) { return serviceCollection - .AddLogging() - .AddTransient() + .AddSingleton() .AddTransient(); } + internal static IServiceCollection AddServices(this IServiceCollection serviceCollection) + { + return serviceCollection + .AddLogging() + .AddSingleton(); + } } } diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Styles/ListStyles.xaml b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Styles/ListStyles.xaml index ad3fbda..b33e908 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Styles/ListStyles.xaml +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/Styles/ListStyles.xaml @@ -1,14 +1,23 @@  + + + - - - @@ -54,11 +51,28 @@ Height="32" Margin="10,0" Source="{Binding Converter={StaticResource ItemToImageConverter}}" /> - + ItemsSource="{Binding DisplayName}"> + + + + + + + + + + + + + diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ContainerViewModel.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ContainerViewModel.cs index f09c0e3..afcf544 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ContainerViewModel.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ContainerViewModel.cs @@ -1,5 +1,7 @@ using AsyncEvent; using FileTime.Core.Models; +using FileTime.Uno.Models; +using FileTime.Uno.Services; using MvvmGen; using System; using System.Collections.Generic; @@ -11,6 +13,7 @@ using System.Threading.Tasks; namespace FileTime.Uno.ViewModels { [ViewModel] + [Inject(typeof(ItemNameConverterService))] public partial class ContainerViewModel : IItemViewModel { private bool isRefreshing; @@ -45,6 +48,8 @@ namespace FileTime.Uno.ViewModels ? ItemViewMode.Alternative : ItemViewMode.Default; + public List DisplayName => ItemNameConverterService.GetDisplayName(this); + public ObservableCollection Containers { get @@ -70,12 +75,14 @@ namespace FileTime.Uno.ViewModels } } - public ContainerViewModel(IContainer container) : this() + public ContainerViewModel(IContainer container, ItemNameConverterService itemNameConverterService) : this(itemNameConverterService) { Container = container; Container.Refreshed.Add(Container_Refreshed); } + public void InvalidateDisplayName() => OnPropertyChanged(nameof(DisplayName)); + public async Task Init(bool initializeChildren = true) { await Refresh(initializeChildren); @@ -98,8 +105,8 @@ namespace FileTime.Uno.ViewModels { isRefreshing = true; - var containers = (await _container.GetContainers()).Select(c => new ContainerViewModel(c)).ToList(); - var elements = (await _container.GetElements()).Select(e => new ElementViewModel(e)).ToList(); + var containers = (await _container.GetContainers()).Select(c => new ContainerViewModel(c, ItemNameConverterService)).ToList(); + var elements = (await _container.GetElements()).Select(e => new ElementViewModel(e, ItemNameConverterService)).ToList(); _containers.Clear(); _elements.Clear(); diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ElementViewModel.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ElementViewModel.cs index 6782541..6621004 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ElementViewModel.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/ElementViewModel.cs @@ -1,12 +1,13 @@ using FileTime.Core.Models; +using FileTime.Uno.Models; +using FileTime.Uno.Services; using MvvmGen; -using System; using System.Collections.Generic; -using System.Text; namespace FileTime.Uno.ViewModels { [ViewModel] + [Inject(typeof(ItemNameConverterService))] public partial class ElementViewModel : IItemViewModel { public IItem Item => _element; @@ -29,9 +30,13 @@ namespace FileTime.Uno.ViewModels ? ItemViewMode.Alternative : ItemViewMode.Default; - public ElementViewModel(IElement element) + public List DisplayName => ItemNameConverterService.GetDisplayName(this); + + public ElementViewModel(IElement element, ItemNameConverterService itemNameConverterService) : this(itemNameConverterService) { Element = element; } + + public void InvalidateDisplayName() => OnPropertyChanged(nameof(DisplayName)); } } diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/IItemViewModel.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/IItemViewModel.cs index 9c943c2..69aa54a 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/IItemViewModel.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/IItemViewModel.cs @@ -1,4 +1,5 @@ using FileTime.Core.Models; +using FileTime.Uno.Models; using System; using System.Collections.Generic; using System.Text; @@ -13,5 +14,9 @@ namespace FileTime.Uno.ViewModels bool IsAlternative { get; set; } ItemViewMode ViewMode { get; } + + List DisplayName { get; } + + void InvalidateDisplayName(); } } diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/MainPageViewModel.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/MainPageViewModel.cs index 0b83209..4d2018d 100644 --- a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/MainPageViewModel.cs +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/MainPageViewModel.cs @@ -1,13 +1,18 @@ using FileTime.Core.Components; +using FileTime.Core.Extensions; using FileTime.Core.Interactions; +using FileTime.Core.Models; using FileTime.Providers.Local; using FileTime.Uno.Application; using FileTime.Uno.Command; using FileTime.Uno.Misc; using FileTime.Uno.Models; +using FileTime.Uno.Services; using MvvmGen; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -18,22 +23,24 @@ namespace FileTime.Uno.ViewModels [ViewModel] [Inject(typeof(LocalContentProvider))] [Inject(typeof(AppState), PropertyAccessModifier = AccessModifier.Public)] + [Inject(typeof(ItemNameConverterService))] public partial class MainPageViewModel { + const string RAPIDTRAVEL = "rapidTravel"; + private readonly List _previousKeys = new List(); private readonly List _keysToSkip = new List(); private bool _isAltPressed = false; private bool _isShiftPressed = false; private bool _isCtrlPressed = false; + private List _commandBindings = new(); + private List _universalCommandBindings = new(); private Action _inputHandler; [Property] private string _text; - [Property] - private List _commandBindings = new(); - [Property] private bool _noCommandFound; @@ -46,6 +53,9 @@ namespace FileTime.Uno.ViewModels [Property] private List _rootDriveInfos; + [Property] + private ObservableCollection _tabs = new ObservableCollection(); + public Action FocusDefaultElement { get; set; } async partial void OnInitialize() @@ -55,17 +65,21 @@ namespace FileTime.Uno.ViewModels _keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(VirtualKey.Up) }); _keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(VirtualKey.Down) }); _keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(VirtualKey.Tab) }); + _keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(VirtualKey.PageDown) }); + _keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(VirtualKey.PageUp) }); var tab = new Tab(); await tab.Init(LocalContentProvider); - var tabContainer = new TabContainer(tab, LocalContentProvider); + var tabContainer = new TabContainer(tab, LocalContentProvider, ItemNameConverterService); await tabContainer.Init(); AppState.Tabs = new List() { tabContainer }; + _tabs.Add(new TabControlViewModel(1, tabContainer)); + var driveInfos = new List(); foreach (var drive in DriveInfo.GetDrives()) { @@ -82,9 +96,27 @@ namespace FileTime.Uno.ViewModels public async Task OpenContainer() { + AppState.RapidTravelText = ""; await AppState.SelectedTab.Open(); } + public async Task OpenOrRun() + { + if (AppState.SelectedTab.SelectedItem is ContainerViewModel) + { + await OpenContainer(); + } + else if (AppState.SelectedTab.SelectedItem is ElementViewModel elementViewModel && elementViewModel.Element is LocalFile localFile) + { + Process.Start(new ProcessStartInfo(localFile.File.FullName) { UseShellExecute = true }); + + if (AppState.ViewMode == ViewMode.RapidTravel) + { + await ExitRapidTravelMode(); + } + } + } + public async Task GoUp() { await AppState.SelectedTab.GoUp(); @@ -135,6 +167,90 @@ namespace FileTime.Uno.ViewModels await AppState.SelectedTab.GotToHome(); } + public Task EnterRapidTravelMode() + { + AppState.ViewMode = ViewMode.RapidTravel; + + _previousKeys.Clear(); + PossibleCommands = new(); + FocusDefaultElement?.Invoke(); + + return Task.CompletedTask; + } + + public async Task ExitRapidTravelMode() + { + AppState.ViewMode = ViewMode.Default; + + _previousKeys.Clear(); + PossibleCommands = new(); + AppState.RapidTravelText = ""; + + await AppState.SelectedTab.OpenContainer(await AppState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(RAPIDTRAVEL)); + FocusDefaultElement?.Invoke(); + } + + public async Task SwitchToTab(int number) + { + var tab = _tabs.FirstOrDefault(t => t.TabNumber == number); + + if (number == -1) + { + var greatestNumber = _tabs.Select(t => t.TabNumber).Max(); + tab = _tabs.FirstOrDefault(t => t.TabNumber == greatestNumber); + } + else if (tab == null) + { + var newContainer = await AppState.SelectedTab.CurrentLocation.Container.Clone(); + + var newTab = new Tab(); + await newTab.Init(newContainer); + + var tabContainer = new TabContainer(newTab, LocalContentProvider, ItemNameConverterService); + await tabContainer.Init(); + + tab = new TabControlViewModel(number, tabContainer); + var i = 0; + for (i = 0; i < Tabs.Count; i++) + { + if (Tabs[i].TabNumber > number) break; + } + Tabs.Insert(i, tab); + } + + if (AppState.ViewMode == ViewMode.RapidTravel) + { + await ExitRapidTravelMode(); + } + + AppState.SelectedTab = tab.Tab; + + foreach (var tab2 in Tabs) + { + tab2.IsSelected = tab2.TabNumber == tab.TabNumber; + } + } + + public async Task CloseTab() + { + if (_tabs.Count > 1) + { + var currentTab = _tabs.FirstOrDefault(t => t.Tab == AppState.SelectedTab); + + if (currentTab != null) + { + _tabs.Remove(currentTab); + var tabNumber = _tabs[0].TabNumber; + for (var i = 0; i < Tabs.Count; i++) + { + if (Tabs[i].TabNumber > currentTab.TabNumber) break; + tabNumber = _tabs[i].TabNumber; + } + await SwitchToTab(tabNumber); + } + } + } + public Task CreateContainer() { var handler = () => @@ -167,7 +283,7 @@ namespace FileTime.Uno.ViewModels _inputHandler = null; } - public bool ProcessKeyDown(VirtualKey key) + public async Task ProcessKeyDown(VirtualKey key) { NoCommandFound = false; if (key == VirtualKey.Menu) @@ -182,10 +298,126 @@ namespace FileTime.Uno.ViewModels { _isCtrlPressed = true; } + else + { + if (AppState.ViewMode == ViewMode.Default) + { + var keyWithModifiers = new KeyWithModifiers(key, _isAltPressed, _isShiftPressed, _isCtrlPressed); + _previousKeys.Add(keyWithModifiers); + + var selectedCommandBinding = _universalCommandBindings.Find(c => AreKeysEqual(c.Keys, _previousKeys)); + selectedCommandBinding ??= _commandBindings.Find(c => AreKeysEqual(c.Keys, _previousKeys)); + + if (key == VirtualKey.Escape) + { + _previousKeys.Clear(); + PossibleCommands = new(); + } + else if (selectedCommandBinding != null) + { + await selectedCommandBinding.InvokeAsync(); + _previousKeys.Clear(); + PossibleCommands = new(); + + FocusDefaultElement?.Invoke(); + } + else if (_keysToSkip.Any(k => AreKeysEqual(k, _previousKeys))) + { + _previousKeys.Clear(); + PossibleCommands = new(); + } + else if (_previousKeys.Count == 2) + { + NoCommandFound = true; + _previousKeys.Clear(); + PossibleCommands = new(); + } + else + { + var possibleCommands = _universalCommandBindings.Concat(_commandBindings).Where(c => AreKeysEqual(c.Keys[0], keyWithModifiers)).ToList(); + + if (possibleCommands.Count == 0) + { + NoCommandFound = true; + _previousKeys.Clear(); + } + else + { + PossibleCommands = possibleCommands; + } + } + return true; + } + else + { + var keyString = key.ToString(); + var updateRapidTravelFilter = false; + + if (key == VirtualKey.Escape) + { + await ExitRapidTravelMode(); + } + else if (key == VirtualKey.Back) + { + if (AppState.RapidTravelText.Length > 0) + { + AppState.RapidTravelText = AppState.RapidTravelText.Substring(0, AppState.RapidTravelText.Length - 1); + updateRapidTravelFilter = true; + } + } + else if (keyString.Length == 1) + { + AppState.RapidTravelText += keyString.ToString().ToLower(); + updateRapidTravelFilter = true; + } + else + { + var currentKeyAsList = new List() { new KeyWithModifiers(key) }; + var selectedCommandBinding = _universalCommandBindings.Find(c => AreKeysEqual(c.Keys, currentKeyAsList)); + if (selectedCommandBinding != null) + { + await selectedCommandBinding.InvokeAsync(); + FocusDefaultElement?.Invoke(); + } + } + + if (updateRapidTravelFilter) + { + var currentLocation = await AppState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(RAPIDTRAVEL); + var newLocation = new VirtualContainer( + currentLocation, + new List, IEnumerable>>() + { + container => container.Where(c => c.Name.ToLower().Contains(AppState.RapidTravelText)) + }, + new List, IEnumerable>>() + { + element => element.Where(e => e.Name.ToLower().Contains(AppState.RapidTravelText)) + }, + virtualContainerName: RAPIDTRAVEL + ); + + await newLocation.Init(); + + await AppState.SelectedTab.OpenContainer(newLocation); + + var selectedItemName = AppState.SelectedTab.SelectedItem.Item.Name; + if (!AppState.SelectedTab.CurrentLocation.Items.Select(i => i.Item.Name).Any(n => n == selectedItemName)) + { + await AppState.SelectedTab.MoveCursorToFirst(); + } + + FocusDefaultElement?.Invoke(); + } + + return true; + } + } + return false; } - public async Task ProcessKeyUp(VirtualKey key) + public Task ProcessKeyUp(VirtualKey key) { if (key == VirtualKey.Menu) { @@ -199,57 +431,8 @@ namespace FileTime.Uno.ViewModels { _isCtrlPressed = false; } - else - { - var keyWithModifiers = new KeyWithModifiers(key, _isAltPressed, _isShiftPressed, _isCtrlPressed); - _previousKeys.Add(keyWithModifiers); - var selectedCommandBinding = _commandBindings.Find(c => AreKeysEqual(c.Keys, _previousKeys)); - - if (key == VirtualKey.Escape) - { - _previousKeys.Clear(); - PossibleCommands = new(); - } - else if (selectedCommandBinding != null) - { - await selectedCommandBinding.InvokeAsync(); - _previousKeys.Clear(); - PossibleCommands = new(); - - if (selectedCommandBinding.Name != "") - { - FocusDefaultElement?.Invoke(); - } - } - else if (_keysToSkip.Any(k => AreKeysEqual(k, _previousKeys))) - { - _previousKeys.Clear(); - PossibleCommands = new(); - } - else if (_previousKeys.Count == 2) - { - NoCommandFound = true; - _previousKeys.Clear(); - PossibleCommands = new(); - } - else - { - var possibleCommands = _commandBindings.Where(c => AreKeysEqual(c.Keys[0], keyWithModifiers)).ToList(); - - if (possibleCommands.Count == 0) - { - NoCommandFound = true; - _previousKeys.Clear(); - } - else - { - PossibleCommands = possibleCommands; - } - } - return true; - } - return false; + return Task.FromResult(false); } public void ResetSpecialKeys() @@ -287,17 +470,11 @@ namespace FileTime.Uno.ViewModels { var commandBindings = new List() { - new CommandBinding("go up", FileTime.App.Core.Command.Commands.GoUp, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Left)}, GoUp), - new CommandBinding("open", FileTime.App.Core.Command.Commands.Open, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Right)}, OpenContainer), - /*new CommandBinding("cursor up", FileTime.App.Core.Command.Commands.MoveCursorUp, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Up)}, MoveCursorUp), - new CommandBinding("cursor down", FileTime.App.Core.Command.Commands.MoveCursorDown, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Down)}, MoveCursorDown), - new CommandBinding("cursor page up", FileTime.App.Core.Command.Commands.MoveCursorUpPage, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageUp)}, MoveCursorUpPage), - new CommandBinding("cursor page down", FileTime.App.Core.Command.Commands.MoveCursorDownPage, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageDown)}, MoveCursorDownPage),*/ - /*new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Up)}, () =>{ }), - new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Down)}, () =>{ }), - new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageUp)}, () =>{ }), - new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageDown)}, () =>{ }), - new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Tab)}, () =>{ }),*/ + new CommandBinding( + "enter rapid travel mode", + FileTime.App.Core.Command.Commands.EnterRapidTravel, + new KeyWithModifiers[]{new KeyWithModifiers((VirtualKey)188, shift: true)}, + EnterRapidTravelMode), new CommandBinding( "create container", FileTime.App.Core.Command.Commands.CreateContainer, @@ -328,9 +505,75 @@ namespace FileTime.Uno.ViewModels FileTime.App.Core.Command.Commands.GoToHome, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.G),new KeyWithModifiers(VirtualKey.H)}, GotToHome), + new CommandBinding( + "switch to tab 1", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number1)}, + async() => await SwitchToTab(1)), + new CommandBinding( + "switch to tab 2", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number2)}, + async() => await SwitchToTab(2)), + new CommandBinding( + "switch to tab 3", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number3)}, + async() => await SwitchToTab(3)), + new CommandBinding( + "switch to tab 4", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number4)}, + async() => await SwitchToTab(4)), + new CommandBinding( + "switch to tab 5", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number5)}, + async() => await SwitchToTab(5)), + new CommandBinding( + "switch to tab 6", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number6)}, + async() => await SwitchToTab(6)), + new CommandBinding( + "switch to tab 7", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number7)}, + async() => await SwitchToTab(7)), + new CommandBinding( + "switch to tab 8", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number8)}, + async() => await SwitchToTab(8)), + new CommandBinding( + "switch to last tab", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Number9)}, + async() => await SwitchToTab(-1)), + new CommandBinding( + "close tab", + FileTime.App.Core.Command.Commands.GoToHome, + new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Q)}, + CloseTab), + }; + var universalCommandBindings = new List() + { + new CommandBinding("go up", FileTime.App.Core.Command.Commands.GoUp, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Left)}, GoUp), + new CommandBinding("open", FileTime.App.Core.Command.Commands.Open, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Right)}, OpenContainer), + new CommandBinding("open or run", FileTime.App.Core.Command.Commands.OpenOrRun, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Enter)}, OpenOrRun), + /*new CommandBinding("cursor up", FileTime.App.Core.Command.Commands.MoveCursorUp, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Up)}, MoveCursorUp), + new CommandBinding("cursor down", FileTime.App.Core.Command.Commands.MoveCursorDown, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Down)}, MoveCursorDown), + new CommandBinding("cursor page up", FileTime.App.Core.Command.Commands.MoveCursorUpPage, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageUp)}, MoveCursorUpPage), + new CommandBinding("cursor page down", FileTime.App.Core.Command.Commands.MoveCursorDownPage, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageDown)}, MoveCursorDownPage),*/ + /*new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Up)}, () =>{ }), + new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Down)}, () =>{ }), + new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageUp)}, () =>{ }), + new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.PageDown)}, () =>{ }), + new CommandBinding("", null, new KeyWithModifiers[]{new KeyWithModifiers(VirtualKey.Tab)}, () =>{ }),*/ }; _commandBindings.AddRange(commandBindings); + _universalCommandBindings.AddRange(universalCommandBindings); } } } diff --git a/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/TabControlViewModel.cs b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/TabControlViewModel.cs new file mode 100644 index 0000000..de43387 --- /dev/null +++ b/src/GuiApp/FileTime.Uno/FileTime.Uno.Shared/ViewModels/TabControlViewModel.cs @@ -0,0 +1,17 @@ +using FileTime.Uno.Application; +using MvvmGen; +using System; +using System.Collections.Generic; +using System.Text; + +namespace FileTime.Uno.ViewModels +{ + [ViewModel] + [Inject(typeof(TabContainer), "Tab", PropertyAccessModifier = AccessModifier.Public)] + [Inject(typeof(int), "TabNumber", PropertyAccessModifier = AccessModifier.Public)] + public partial class TabControlViewModel + { + [Property] + private bool _isSelected; + } +} diff --git a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs index 118dc4a..f18d0d8 100644 --- a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs +++ b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs @@ -15,14 +15,6 @@ namespace FileTime.Providers.Local private readonly IReadOnlyList? _items; private readonly IReadOnlyList? _elements = new List().AsReadOnly(); - /* public IReadOnlyList RootContainers { get; } - - public IReadOnlyList Items => RootContainers; - - public IReadOnlyList Containers => RootContainers; - - public IReadOnlyList Elements { get; } = new List(); */ - public string Name { get; } = "local"; public string? FullName { get; } @@ -66,6 +58,8 @@ namespace FileTime.Providers.Local public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); + public Task Clone() => Task.FromResult((IContainer)this); + public IContainer? GetParent() => _parent; public Task CreateContainer(string name) => throw new NotSupportedException(); public Task CreateElement(string name) => throw new NotSupportedException(); diff --git a/src/Providers/FileTime.Providers.Local/LocalFolder.cs b/src/Providers/FileTime.Providers.Local/LocalFolder.cs index 3a7492c..a94e937 100644 --- a/src/Providers/FileTime.Providers.Local/LocalFolder.cs +++ b/src/Providers/FileTime.Providers.Local/LocalFolder.cs @@ -34,6 +34,8 @@ namespace FileTime.Providers.Local public IContainer? GetParent() => _parent; + public Task Clone() => Task.FromResult((IContainer)new LocalFolder(Directory, Provider, _parent)); + public Task Refresh() { _containers = new List(); diff --git a/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs b/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs index d5a2153..2082a50 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs @@ -64,6 +64,8 @@ namespace FileTime.Providers.Smb public IContainer? GetParent() => _parent; + public Task Clone() => Task.FromResult((IContainer)this); + public async Task IsExists(string name) => (await GetItems())?.Any(i => i.Name == name) ?? false; public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); diff --git a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs index 3662f84..4cfd02c 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs @@ -45,6 +45,8 @@ namespace FileTime.Providers.Smb throw new NotImplementedException(); } + public Task Clone() => Task.FromResult((IContainer)this); + public async Task GetByPath(string path) { var paths = path.Split(Constants.SeparatorChar); diff --git a/src/Providers/FileTime.Providers.Smb/SmbServer.cs b/src/Providers/FileTime.Providers.Smb/SmbServer.cs index ea884c2..7b7b8d8 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbServer.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbServer.cs @@ -92,6 +92,8 @@ namespace FileTime.Providers.Smb await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty); } + public Task Clone() => Task.FromResult((IContainer)this); + private async Task GetSmbClient() { if (_client == null) diff --git a/src/Providers/FileTime.Providers.Smb/SmbShare.cs b/src/Providers/FileTime.Providers.Smb/SmbShare.cs index 7a33c73..6687d92 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbShare.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbShare.cs @@ -88,6 +88,8 @@ namespace FileTime.Providers.Smb public IContainer? GetParent() => _parent; + public Task Clone() => Task.FromResult((IContainer)this); + public Task IsExists(string name) { throw new NotImplementedException();