Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Files.App.Launcher/Files.App.Launcher.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
Expand All @@ -103,7 +103,7 @@
<ClCompile>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Items/EncodingItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public EncodingItem(Encoding encoding, string name)
//reference: https://en.wikipedia.org/wiki/Windows_code_page
//East Asian
"shift_jis", //Japanese
"gb2312", //Simplified Chinese
"gb18030", //Simplified Chinese
"big5", //Traditional Chinese
"ks_c_5601-1987", //Korean

Expand Down
14 changes: 14 additions & 0 deletions src/Files.App/Data/Models/CurrentInstanceViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@ public bool IsPageTypeLibrary
}
}

private string? zipEncodingName;
public string? ZipEncodingName
{
get => zipEncodingName;
set => SetProperty(ref zipEncodingName, value);
}

private bool isZipEncodingUndetermined;
public bool IsZipEncodingUndetermined
{
get => isZipEncodingUndetermined;
set => SetProperty(ref isZipEncodingUndetermined, value);
}

public bool CanCopyPathInPage
{
get => !isPageTypeMtpDevice && !isPageTypeRecycleBin && isPageTypeNotHome && !isPageTypeSearchResults && !IsPageTypeReleaseNotes && !IsPageTypeSettings;
Expand Down
137 changes: 137 additions & 0 deletions src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using Files.App.Data.Items;
using Files.App.Utils.Storage;
using Microsoft.Extensions.Logging;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;

namespace Files.App.ViewModels.UserControls
Expand All @@ -9,6 +14,8 @@
{
private IContentPageContext ContentPageContext { get; } = Ioc.Default.GetRequiredService<IContentPageContext>();
private IDevToolsSettingsService DevToolsSettingsService = Ioc.Default.GetRequiredService<IDevToolsSettingsService>();
private readonly IStorageArchiveService StorageArchiveService = Ioc.Default.GetRequiredService<IStorageArchiveService>();
private CurrentInstanceViewModel? InstanceViewModel => ContentPageContext.ShellPage?.InstanceViewModel;

// The first branch will always be the active one.
public const int ACTIVE_BRANCH_INDEX = 0;
Expand Down Expand Up @@ -81,6 +88,26 @@
set => SetProperty(ref _ExtendedStatusInfo, value);
}

private bool _IsZipEncodingSelectorVisible;
public bool IsZipEncodingSelectorVisible
{
get => _IsZipEncodingSelectorVisible;
set => SetProperty(ref _IsZipEncodingSelectorVisible, value);
}

public List<EncodingItem> ZipEncodingOptions { get; } = EncodingItem.Defaults.ToList();

private EncodingItem? _SelectedZipEncoding;
public EncodingItem? SelectedZipEncoding
{
get => _SelectedZipEncoding;
set
{
if (SetProperty(ref _SelectedZipEncoding, value) && value is not null)
_ = OnZipEncodingChangedAsync(value);
}
}

public bool ShowOpenInIDEButton
{
get
Expand Down Expand Up @@ -112,6 +139,24 @@
break;
}
};

SubscribeToShellPage();
ContentPageContext.PropertyChanged += OnContentPageContextPropertyChanged;
}

private void OnContentPageContextPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ContentPageContext.ShellPage))
{
UnsubscribeFromInstanceViewModel();
SubscribeToShellPage();
}
}

private void SubscribeToShellPage()
{
SubscribeToInstanceViewModel();
_ = UpdateZipEncodingStateAsync();
}

public void UpdateGitInfo(bool isGitRepository, string? repositoryPath, BranchItem? head)
Expand Down Expand Up @@ -164,5 +209,97 @@
{
return GitHelpers.DeleteBranchAsync(_gitRepositoryPath, GitBranchDisplayName, branchName);
}

public async Task UpdateZipEncodingStateAsync()
{
var instanceVM = InstanceViewModel;
if (instanceVM is null)
return;

if (!instanceVM.IsPageTypeZipFolder)
{
IsZipEncodingSelectorVisible = false;
ZipStorageFolder.CurrentEncoding = null;

Check failure on line 222 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Debug, x64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

Check failure on line 222 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Release, x64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

Check failure on line 222 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Debug, arm64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

Check failure on line 222 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Release, arm64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'
return;
}

var workingDir = ContentPageContext.ShellPage?.ShellViewModel.WorkingDirectory;
if (string.IsNullOrEmpty(workingDir) || !ZipStorageFolder.IsZipPath(workingDir))
return;

try
{
var isUndetermined = await StorageArchiveService.IsEncodingUndeterminedAsync(workingDir);
instanceVM.IsZipEncodingUndetermined = isUndetermined;

if (!isUndetermined)
{
IsZipEncodingSelectorVisible = false;
return;
}

var detected = await StorageArchiveService.DetectEncodingAsync(workingDir);
if (detected is not null)
{
instanceVM.ZipEncodingName = detected.WebName;
EncodingItem? ZipEncodingItem = ZipEncodingOptions.FirstOrDefault(e =>
e.Encoding?.WebName.Equals(detected.WebName, StringComparison.OrdinalIgnoreCase) == true);
if(ZipEncodingItem == null)
{
ZipEncodingItem = new EncodingItem(detected, detected.EncodingName);
}
ZipEncodingOptions.Add(ZipEncodingItem);
SelectedZipEncoding = ZipEncodingItem;
}
else
{
instanceVM.ZipEncodingName = null;
SelectedZipEncoding = ZipEncodingOptions.FirstOrDefault(e => e.Encoding is null);
}

IsZipEncodingSelectorVisible = true;
}
catch (Exception ex)
{
App.Logger.LogError(ex, "Error checking zip encoding.");
IsZipEncodingSelectorVisible = false;
}
}

private async Task OnZipEncodingChangedAsync(EncodingItem encodingItem)
{
if (ContentPageContext.ShellPage is null)
return;

var workingDir = ContentPageContext.ShellPage.ShellViewModel.WorkingDirectory;
if (string.IsNullOrEmpty(workingDir))
return;

ZipStorageFolder.CurrentEncoding = encodingItem.Encoding;

Check failure on line 278 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Debug, x64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

Check failure on line 278 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Release, x64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

Check failure on line 278 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Debug, arm64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

Check failure on line 278 in src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs

View workflow job for this annotation

GitHub Actions / build (Release, arm64)

An object reference is required for the non-static field, method, or property 'ZipStorageFolder.CurrentEncoding'

ContentPageContext.ShellPage.ShellViewModel.RefreshItems(null);
}

internal void SubscribeToInstanceViewModel()
{
var instanceVM = InstanceViewModel;
if (instanceVM is not null)
instanceVM.PropertyChanged += OnInstanceViewModelPropertyChanged;
}

internal void UnsubscribeFromInstanceViewModel()
{
var instanceVM = InstanceViewModel;
if (instanceVM is not null)
instanceVM.PropertyChanged -= OnInstanceViewModelPropertyChanged;
}

private void OnInstanceViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(CurrentInstanceViewModel.IsPageTypeZipFolder))
{
_ = UpdateZipEncodingStateAsync();
}
}
}
}
4 changes: 3 additions & 1 deletion src/Files.App/Services/Storage/StorageArchiveService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,9 @@ public async Task<bool> IsEncodingUndeterminedAsync(string archiveFilePath)
{
using (ZipFile zipFile = new ZipFile(archiveFilePath))
{
return !zipFile.Cast<ZipEntry>().All(entry => entry.IsUnicodeText);
return !zipFile.Cast<ZipEntry>().All(
entry => entry.IsUnicodeText || entry.Name.All(c => char.IsAscii(c))
);
}
}
catch (Exception ex)
Expand Down
50 changes: 49 additions & 1 deletion src/Files.App/UserControls/StatusBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<!-- Folder and selection info -->
Expand Down Expand Up @@ -193,10 +194,57 @@
Background="{ThemeResource DividerStrokeColorDefaultBrush}" />
</StackPanel>

<!-- ZIP Encoding Selector -->
<Button
x:Name="ZipEncodingSelector"
Grid.Column="2"
Height="24"
Padding="8,0,8,0"
Background="Transparent"
BorderBrush="Transparent"
ToolTipService.ToolTip="{helpers:ResourceString Name=Encoding}"
Visibility="{x:Bind StatusBarViewModel.IsZipEncodingSelectorVisible, Mode=OneWay}">

<!-- Encoding Name -->
<TextBlock Text="{x:Bind StatusBarViewModel.SelectedZipEncoding.Name, Mode=OneWay, FallbackValue='', TargetNullValue=''}" />

<Button.Flyout>
<Flyout x:Name="ZipEncodingFlyout">
<Grid
Width="240"
Height="300"
Margin="-16">

<!-- Encodings List -->
<ListView
x:Name="ZipEncodingList"
Padding="4"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
IsItemClickEnabled="True"
ItemClick="ZipEncodingList_ItemClick"
ItemsSource="{x:Bind StatusBarViewModel.ZipEncodingOptions, Mode=OneWay}"
SelectedItem="{x:Bind StatusBarViewModel.SelectedZipEncoding, Mode=TwoWay}"
SelectionMode="Single">

<ListView.ItemTemplate>
<DataTemplate x:DataType="data:EncodingItem">
<TextBlock
VerticalAlignment="Center"
Text="{x:Bind Name}"
TextTrimming="CharacterEllipsis" />
</DataTemplate>
</ListView.ItemTemplate>

</ListView>
</Grid>
</Flyout>
</Button.Flyout>
</Button>

<!-- Use visibility because it causes a crash to use a TwoWay x:Bind on an element that is inside an element with x:Load (#12589, #12599) -->
<Button
x:Name="GitBranch"
Grid.Column="2"
Grid.Column="3"
Height="24"
Margin="4,0,0,0"
Padding="8,0,8,0"
Expand Down
5 changes: 5 additions & 0 deletions src/Files.App/UserControls/StatusBar.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ private void BranchesList_ItemClick(object sender, ItemClickEventArgs e)
BranchesFlyout.Hide();
}

private void ZipEncodingList_ItemClick(object sender, ItemClickEventArgs e)
{
ZipEncodingFlyout.Hide();
}

private void BranchesFlyout_Closing(object _, object e)
{
if (StatusBarViewModel is null)
Expand Down
Loading
Loading