Skip to content

Commit

Permalink
Support compressed file
Browse files Browse the repository at this point in the history
  • Loading branch information
HeHang0 committed Jul 17, 2023
1 parent a4b3854 commit e20fc64
Show file tree
Hide file tree
Showing 11 changed files with 645 additions and 286 deletions.
44 changes: 44 additions & 0 deletions FileControl/Compressed/CompressedControl.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<fc:FileControl x:Class="FileViewer.FileControl.Compressed.CompressedControl"
xmlns:fc="clr-namespace:FileViewer.FileControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:FileViewer.FileControl.Compressed"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TreeView Background="Transparent" BorderThickness="0" ItemsSource="{Binding FileList}">
<TreeView.Resources>
<Style x:Key="TextBlockColor" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="{DynamicResource TreeTextColor}" />
</Style>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="False" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<Grid HorizontalAlignment="Stretch" Margin="0 2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="22"></ColumnDefinition>
<ColumnDefinition Width="300"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="150"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding Icon}" Width="20" Height="18" Margin="0 0 5 0" Stretch="Uniform"/>
<TextBlock TextTrimming="CharacterEllipsis" Style="{StaticResource TextBlockColor}" Grid.Column="1" Text="{Binding FileName}" ToolTip="{Binding FileName}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<TextBlock Grid.Column="2" Style="{StaticResource TextBlockColor}" Text="{Binding FileSize}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="3" Style="{StaticResource TextBlockColor}" Text="{Binding LastModified}" VerticalAlignment="Center" HorizontalAlignment="Center">

</TextBlock>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</fc:FileControl>
31 changes: 31 additions & 0 deletions FileControl/Compressed/CompressedControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using FileViewer.FileControl.Office;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static FileViewer.FileControl.Compressed.CompressedModel;

namespace FileViewer.FileControl.Compressed
{
/// <summary>
/// CompressedControl.xaml 的交互逻辑
/// </summary>
public partial class CompressedControl : FileControl
{
public CompressedControl() : base(new CompressedModel())
{
InitializeComponent();
}
}
}
199 changes: 199 additions & 0 deletions FileControl/Compressed/CompressedModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
using FileViewer.FileHelper;
using FileViewer.Globle;
using Prism.Commands;
using SharpCompress.Archives;
using SharpCompress.Common;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace FileViewer.FileControl.Compressed
{
public class CompressedModel : BaseBackgroundWork, IFileModel
{
public event PropertyChangedEventHandler PropertyChanged;

private string currentFilePath;
public void ChangeFile((string FilePath, FileExtension Ext) file)
{
InitBackGroundWork();
currentFilePath = file.FilePath;
bgWorker.RunWorkerAsync(file.FilePath);
}

public void ChangeTheme(bool dark)
{
if (dark)
{
GlobalNotify.OnColorChange(Color.FromRgb(0x33, 0x33, 0x33));
Application.Current.Resources["TreeTextColor"] = new SolidColorBrush(Colors.White);
}
else
{
GlobalNotify.OnColorChange(Color.FromRgb(0xEE, 0xF5, 0xFD));
Application.Current.Resources["TreeTextColor"] = new SolidColorBrush(Colors.Black);
}
}

protected override void BgWorker_DoWork(object sender, DoWorkEventArgs e)
{
var filePath = e.Argument as string;
List<FileItem> result = new List<FileItem>();
Dictionary<string, FileItem> fileItemMap = new Dictionary<string, FileItem>();
try
{
IEnumerable<IArchiveEntry> entries = null;
using (var stream = File.OpenRead(filePath))
{

switch (Path.GetExtension(filePath).ToLower())
{
case ".rar":
entries = SharpCompress.Archives.Rar.RarArchive.Open(stream).Entries;
break;
case ".tar":
entries = SharpCompress.Archives.Tar.TarArchive.Open(stream).Entries;
break;
case ".gz":
entries = SharpCompress.Archives.GZip.GZipArchive.Open(stream).Entries;
break;
case ".zip":
entries = SharpCompress.Archives.Zip.ZipArchive.Open(stream).Entries;
break;
case ".7z":
entries = SharpCompress.Archives.SevenZip.SevenZipArchive.Open(stream).Entries;
break;
}
if(entries != null)
{
entries = entries.OrderBy(m => m.Key).OrderByDescending(m => m.IsDirectory);
foreach (var entry in entries)
{
ParseEntry(result, fileItemMap, entry.IsDirectory, entry.Key.TrimEnd('/'), entry.Size, entry.LastModifiedTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
}
}
}
}
catch (Exception ex)
{
}
e.Result = result.Count > 0 ? result : null;
}

void ParseEntry(List<FileItem> result, Dictionary<string, FileItem> fileItemMap, bool isFolder, string fullName, long length, string lastWriteTime)
{
var folderPath = Path.GetDirectoryName(fullName).Replace("\\", "/");
FileItem fileItem = new FileItem(fullName, isFolder, length, lastWriteTime); ;
if (isFolder)
{
if (fileItemMap.ContainsKey(folderPath))
{
fileItemMap[folderPath].Children.Add(fileItem);
}
else
{
fileItem.IsExpanded = true;
result.Add(fileItem);
}
fileItemMap[fullName] = fileItem;
}
else
{
if (fileItemMap.ContainsKey(folderPath))
{
fileItemMap[folderPath].Children.Add(fileItem);
}
else
{
result.Add(fileItem);
}
}
}

protected override void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Result == null)
{
GlobalNotify.OnFileLoadFailed(currentFilePath);
return;
}
FileList.Clear();
FileList.AddRange(e.Result as List<FileItem>);
GlobalNotify.OnLoadingChange(false);
}

protected override void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{

}

public ObservableCollection<FileItem> FileList { get; set; } = new ObservableCollection<FileItem>();

public class FileItem
{
private readonly string fullName;

private readonly bool isFolder;

private static Dictionary<string, BitmapSource> iconCache = new Dictionary<string, BitmapSource>();

public FileItem(string fullName, bool isFolder, long length, string lastWriteTime)
{
FileSize = isFolder ? string.Empty : length.ToSizeString();
LastModified = lastWriteTime;
this.isFolder = isFolder;
this.fullName = fullName;
}

public string FileName
{
get
{
return Path.GetFileName(fullName);
}
}
public string FileSize { get; set; }
public string LastModified { get; set; }
public bool IsExpanded { get; set; }

private static object lockObject = new object();
public BitmapSource Icon
{
get
{
BitmapSource fileIcon;
lock (lockObject)
{
string extension = isFolder ? "folder" : Path.GetExtension(fullName);
if (iconCache.ContainsKey(extension))
{
fileIcon = iconCache[extension];
}
else
{
try
{
fileIcon = isFolder ? Utils.GetBitmapSource(IconHelper.GetFolderIcon()) : Utils.GetBitmapSource(IconHelper.GetDefaultFileIcon(extension));
}
catch (Exception ex)
{
fileIcon = Utils.GetBitmapSource(Properties.Resources.logo);
}
iconCache[isFolder ? "folder" : extension] = fileIcon;
}
}
return fileIcon;
}
}
public ObservableCollection<FileItem> Children { get; set; } = new ObservableCollection<FileItem> { };
}
}
}
4 changes: 2 additions & 2 deletions FileControl/FileControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public FileControl()

public void ChangeFile((string FilePath, FileExtension Ext) file)
{
model.ChangeFile(file);
model?.ChangeFile(file);
}

public void ChangeTheme(bool dark)
{
model.ChangeTheme(dark);
model?.ChangeTheme(dark);
}
}
}
4 changes: 3 additions & 1 deletion FileControl/FileViewControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using FileViewer.FileControl.App;
using FileViewer.FileControl.Common;
using FileViewer.FileControl.Compressed;
using FileViewer.FileControl.Hello;
using FileViewer.FileControl.Image;
using FileViewer.FileControl.MobileProvision;
Expand Down Expand Up @@ -77,7 +78,8 @@ private void OnFileLoadFailed(string filePath)
[FileViewType.Word] = (typeof(OfficeControl), true),
[FileViewType.PowerPoint] = (typeof(OfficeControl), true),
[FileViewType.MobileProvision] = (typeof(MobileProvisionControl), true),
[FileViewType.App] = (typeof(AppControl), true)
[FileViewType.App] = (typeof(AppControl), true),
[FileViewType.Compressed] = (typeof(CompressedControl), true)
};

private void SetResource(string filePath, bool loadWithTypeNone = false)
Expand Down
18 changes: 16 additions & 2 deletions FileHelper/FileType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ static FileExtension GetFileType(string filePath)
{
return ext;
}
if(Path.GetExtension(filePath).ToUpper() == ".7Z")
{
return FileExtension.SEVENZIP;
}
}
else if (Directory.Exists(filePath))
{
Expand Down Expand Up @@ -103,6 +107,13 @@ public static (FileViewType Type, FileExtension Ext) GetFileViewType(string file
case FileExtension.Folder:
type = FileViewType.Folder;
break;
case FileExtension.ZIP:
case FileExtension.RAR:
case FileExtension.TAR:
case FileExtension.GZ:
case FileExtension.SEVENZIP:
type = FileViewType.Compressed;
break;
case FileExtension.APK:
case FileExtension.IPA:
case FileExtension.APP:
Expand Down Expand Up @@ -211,7 +222,7 @@ private static byte[] ReadFirstBytes(string filePath)

public enum FileViewType
{
Image, Text, Music, Video, Word, Excel, PowerPoint, Pdf, Folder, MobileProvision, App, None
Image, Text, Music, Video, Word, Excel, PowerPoint, Pdf, Compressed, Folder, MobileProvision, App, None
}

public enum FileExtension
Expand Down Expand Up @@ -281,6 +292,9 @@ public enum FileExtension
APK,
IPA,
APP,
ICNS
ICNS,
TAR,
GZ,
SEVENZIP
}
}
Loading

0 comments on commit e20fc64

Please sign in to comment.