notofficer fix + audio player volume saved + click notif to open path

This commit is contained in:
iAmAsval 2020-05-25 00:38:10 +02:00
parent 23b126a00a
commit a4f1cc2b2c
27 changed files with 179 additions and 99 deletions

View File

@ -26,10 +26,11 @@ namespace FModel
{
StartTimer = Stopwatch.StartNew();
if (FModel.Properties.Settings.Default.UseEnglish)
DebugHelper.Init(LogsFilePath); // get old settings too
if (FModel.Properties.Settings.Default.UseEnglish) // use old settings here
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
DebugHelper.Init(LogsFilePath);
DebugHelper.WriteLine("{0} {1}", "[FModel]", "");
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Version]", Assembly.GetExecutingAssembly().GetName().Version.ToString());
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Build]", Globals.Build);
@ -64,7 +65,7 @@ namespace FModel
{
string errorMessage = string.Format(FModel.Properties.Resources.UnhandledExceptionOccured, e.Exception.Message);
DebugHelper.WriteException(e.Exception, "thrown in App.xaml.cs by OnDispatcherUnhandledException");
DarkMessageBoxHelper.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
DarkMessageBoxHelper.Show(errorMessage, FModel.Properties.Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
}

View File

@ -58,6 +58,10 @@ namespace FModel.Creator
public static SKBitmap GetSoftObjectTexture(SoftObjectProperty s) => GetTexture(s.Value.AssetPathName.String);
public static SKBitmap GetTexture(string s)
{
// FortniteGame/Content/Catalog/DisplayAssets/DA_BattlePassBundle_2020.uasset
if (s.Equals("/Game/UI/Foundation/Textures/BattleRoyale/FeaturedItems/Outfit/T_UI_InspectScreen_annualPass"))
s += "_1024";
PakPackage p = GetPropertyPakPackage(s);
if (p.HasExport() && !p.Equals(default))
{

View File

@ -50,8 +50,8 @@ namespace FModel.Discord
{
Assets = _assets,
Timestamps = _baseTimestamp,
Details = string.IsNullOrEmpty(detail) ? _presence.Details : detail,
State = string.IsNullOrEmpty(state) ? _presence.State : state
Details = string.IsNullOrEmpty(detail) ? _presence?.Details : detail,
State = string.IsNullOrEmpty(state) ? _presence?.State : state
});
_client.Invoke();
}

View File

@ -8,6 +8,7 @@ using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
@ -19,44 +20,48 @@ namespace FModel.Grabber.Paks
{
PopulateBase();
if (string.IsNullOrEmpty(Properties.Settings.Default.PakPath))
await Task.Run(() =>
{
var launcher = new FLauncher();
if ((bool)launcher.ShowDialog())
if (string.IsNullOrEmpty(Properties.Settings.Default.PakPath))
{
Properties.Settings.Default.PakPath = launcher.Path;
Properties.Settings.Default.Save();
}
}
// define the current game thank to the pak path
Folders.SetGameName(Properties.Settings.Default.PakPath);
// Add Pak Files
if (Directory.Exists(Properties.Settings.Default.PakPath))
{
foreach (string pak in Directory.GetFiles(Properties.Settings.Default.PakPath, "*.pak"))
{
if (!Utils.Paks.IsFileReadLocked(new FileInfo(pak)))
var launcher = new FLauncher();
if ((bool)launcher.ShowDialog())
{
PakFileReader pakFile = new PakFileReader(pak);
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Registering]", $"{pakFile.FileName} with GUID {pakFile.Info.EncryptionKeyGuid.Hex}");
Properties.Settings.Default.PakPath = launcher.Path;
Properties.Settings.Default.Save();
}
}
MenuItems.pakFiles.Add(new PakMenuItemViewModel
// define the current game thank to the pak path
Folders.SetGameName(Properties.Settings.Default.PakPath);
// Add Pak Files
if (Directory.Exists(Properties.Settings.Default.PakPath))
{
foreach (string pak in Directory.GetFiles(Properties.Settings.Default.PakPath, "*.pak"))
{
if (!Utils.Paks.IsFileReadLocked(new FileInfo(pak)))
{
PakFile = pakFile,
IsEnabled = false
});
}
else
{
Globals.gNotifier.ShowCustomMessage(Properties.Resources.PakFiles, string.Format(Properties.Resources.PakFileLocked, Path.GetFileNameWithoutExtension(pak)));
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Locked]", pak);
PakFileReader pakFile = new PakFileReader(pak);
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Registering]", $"{pakFile.FileName} with GUID {pakFile.Info.EncryptionKeyGuid.Hex}");
Application.Current.Dispatcher.Invoke(delegate
{
MenuItems.pakFiles.Add(new PakMenuItemViewModel
{
PakFile = pakFile,
IsEnabled = false
});
});
}
else
{
FConsole.AppendText(string.Format(Properties.Resources.PakFileLocked, Path.GetFileNameWithoutExtension(pak)), FColors.Red, true);
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[PAK]", "[Locked]", pak);
}
}
}
}
await Task.CompletedTask.ConfigureAwait(false);
});
}
private static void PopulateBase()

View File

@ -1,10 +1,17 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace PakReader
{
static class BinaryHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long Align(long val, long alignment)
{
return val + alignment - 1 & ~(alignment - 1);
}
public static uint Flip(uint value) => (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |
(value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;

View File

@ -105,7 +105,7 @@ namespace PakReader
reader.ReadUInt32(); // SourceStringHash
string EntryLocalizedString = string.Empty;
string EntryLocalizedString;
if (VersionNumber >= Version.COMPACT)
{
int LocalizedStringIndex = reader.ReadInt32();
@ -130,18 +130,16 @@ namespace PakReader
}
else
{
//throw new IOException($"LocRes has an invalid localized string index for namespace '{Namespace}' and key '{Key}'. This entry will have no translation.");
throw new IOException($"LocRes has an invalid localized string index for namespace '{Namespace}' and key '{Key}'. This entry will have no translation.");
}
}
else
{
EntryLocalizedString = reader.ReadFString();
}
if (Key != null) Entries.Add(Key, EntryLocalizedString);
Entries.Add(Key, EntryLocalizedString);
}
if (Namespace != null) this.Entries.Add(Namespace, Entries);
this.Entries.Add(Namespace, Entries);
}
}

View File

@ -417,18 +417,17 @@ namespace PakReader.Pak
// Get the right pointer to start copying the CompressionBlocks information from.
// Alignment of the compressed blocks
var CompressedBlockAlignment = Encrypted ? AESDecryptor.BLOCK_SIZE : 1;
var CompressedBlockAlignment = Encrypted ? 16 : 1;
// CompressedBlockOffset is the starting offset. Everything else can be derived from there.
long CompressedBlockOffset = BaseOffset + FPakEntry.GetSize(EPakVersion.LATEST, CompressionMethodIndex, CompressionBlocksCount);
for (int CompressionBlockIndex = 0; CompressionBlockIndex < CompressionBlocks.Length; ++CompressionBlockIndex)
{
CompressionBlocks[CompressionBlockIndex] = new FPakCompressedBlock(CompressedBlockOffset, CompressedBlockOffset + BitConverter.ToUInt32(encodedPakEntries, pakLocation));
pakLocation += sizeof(uint);
{
var toAlign = CompressionBlocks[CompressionBlockIndex].CompressedEnd - CompressionBlocks[CompressionBlockIndex].CompressedStart;
CompressedBlockOffset += toAlign + CompressedBlockAlignment - (toAlign % CompressedBlockAlignment);
}
FPakCompressedBlock CompressionBlock = new FPakCompressedBlock(CompressedBlockOffset, CompressedBlockOffset + BitConverter.ToUInt32(encodedPakEntries, pakLocation));
CompressionBlocks[CompressionBlockIndex] = CompressionBlock;
CompressedBlockOffset += BinaryHelper.Align(CompressionBlock.CompressedEnd - CompressionBlock.CompressedStart, CompressedBlockAlignment);
pakLocation += 4;
}
}
return new FPakEntry(this.FileName, name, Offset, Size, UncompressedSize, new byte[20], CompressionBlocks, CompressionBlockSize, CompressionMethodIndex, (byte)((Encrypted ? 0x01 : 0x00) | (Deleted ? 0x02 : 0x00)));

View File

@ -6,17 +6,20 @@ namespace PakReader.Parsers.Objects
{
public readonly long CompressedStart;
public readonly long CompressedEnd;
public readonly long Size;
internal FPakCompressedBlock(BinaryReader reader)
{
CompressedStart = reader.ReadInt64();
CompressedEnd = reader.ReadInt64();
Size = CompressedEnd - CompressedStart;
}
internal FPakCompressedBlock(long start, long end)
{
CompressedStart = start;
CompressedEnd = end;
Size = end - start;
}
}
}

View File

@ -136,52 +136,67 @@ namespace PakReader.Parsers.Objects
{
lock (stream)
{
stream.Position = Offset + StructSize;
if (Encrypted)
if (CompressionMethodIndex == 0U)
{
var data = new byte[(Size & 15) == 0 ? Size : ((Size / 16) + 1) * 16];
stream.Read(data, 0, data.Length);
byte[] decrypted = AESDecryptor.DecryptAES(data, key);
if (CompressionMethodIndex != 0U)
stream.Position = Offset + StructSize;
if (Encrypted)
{
using var m = new MemoryStream(decrypted, 0, decrypted.Length)
{
Position = 0
};
Decompress(m, compressionMethods, decrypted);
var data = new byte[(Size & 15) == 0 ? Size : (Size / 16 + 1) * 16];
stream.Read(data, 0, data.Length);
return new ArraySegment<byte>(AESDecryptor.DecryptAES(data, key), 0, (int)UncompressedSize);
}
else
{
var data = new byte[UncompressedSize];
stream.Read(data, 0, data.Length);
return new ArraySegment<byte>(data);
}
return new ArraySegment<byte>(decrypted, 0, decrypted.Length <= (int)UncompressedSize ? decrypted.Length : (int)UncompressedSize);
}
else
{
var data = new byte[UncompressedSize];
if (CompressionMethodIndex == 0U)
stream.Read(data, 0, data.Length);
else
Decompress(stream, compressionMethods, data);
Decompress(stream, key, compressionMethods, data);
return new ArraySegment<byte>(data);
}
}
throw new NotImplementedException("Decompression not yet implemented");
}
private void Decompress(Stream stream, string[] compressionMethods, byte[] outData)
private void Decompress(Stream stream, byte[] key, string[] compressionMethods, byte[] outData)
{
if (compressionMethods == null || compressionMethods.Length == 0)
throw new IndexOutOfRangeException("CompressionMethods are null or empty");
throw new ArgumentOutOfRangeException(nameof(compressionMethods), "CompressionMethods are null or empty");
var compressionMethod = compressionMethods[CompressionMethodIndex - 1]; // -1 because we dont have 'NAME_None' in the array
Stream compressionStream = compressionMethod.ToLower() switch
string compressionMethod = compressionMethods[CompressionMethodIndex - 1]; // -1 because we dont have 'NAME_None' in the array
int bytesRead = 0;
for (int i = 0; i < CompressionBlocks.Length; i++)
{
"zlib" => new ZlibStream(stream, CompressionMode.Decompress, true),
"gzip" => new GZipStream(stream, CompressionMode.Decompress, true),
_ => throw new NotImplementedException($"Decompression not yet implemented ({compressionMethod})")
};
compressionStream.Read(outData, 0, outData.Length);
compressionStream.Dispose();
stream.Position = Offset + CompressionBlocks[i].CompressedStart;
int uncompressedSize = (int)Math.Min(CompressionBlockSize, outData.Length - bytesRead);
byte[] blockBbuffer;
if (Encrypted)
{
blockBbuffer = new byte[BinaryHelper.Align(CompressionBlocks[i].Size, AESDecryptor.BLOCK_SIZE)];
stream.Read(blockBbuffer, 0, blockBbuffer.Length);
blockBbuffer = AESDecryptor.DecryptAES(blockBbuffer, key);
}
else
{
blockBbuffer = new byte[CompressionBlocks[i].Size];
stream.Read(blockBbuffer, 0, blockBbuffer.Length);
}
using var blockMs = new MemoryStream(blockBbuffer, false);
using Stream compressionStream = compressionMethod switch
{
"Zlib" => new ZlibStream(blockMs, CompressionMode.Decompress),
"Gzip" => new GZipStream(blockMs, CompressionMode.Decompress),
_ => throw new NotImplementedException($"Decompression not yet implemented ({compressionMethod})")
};
bytesRead += compressionStream.Read(outData, bytesRead, uncompressedSize);
}
}
public static long GetSize(EPakVersion version, uint CompressionMethodIndex = 0, uint CompressionBlocksCount = 0)

View File

@ -346,7 +346,7 @@
<value>Немецкий</value>
</data>
<data name="Hello" xml:space="preserve">
<value>Здравсвтуйте</value>
<value>Здравствуйте</value>
</data>
<data name="Help" xml:space="preserve">
<value>Помощь</value>

View File

@ -227,6 +227,18 @@ namespace FModel.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0.5")]
public string AudioPlayerVolume {
get {
return ((string)(this["AudioPlayerVolume"]));
}
set {
this["AudioPlayerVolume"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]

View File

@ -53,6 +53,9 @@
<Setting Name="AudioPlayerDevice" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="AudioPlayerVolume" Type="System.String" Scope="User">
<Value Profile="(Default)">0.5</Value>
</Setting>
<Setting Name="AutoExport" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>

View File

@ -1172,12 +1172,12 @@
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<!-- FModel ViewModel Support -->
<Setter Property="Content" Value="{Binding Content}"/>
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<!-- End FModel ViewModel Support -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
@ -1211,7 +1211,6 @@
</Setter>
</Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonBackground}"/>

View File

@ -344,7 +344,7 @@ namespace FModel.Utils
if (autoSave)
FConsole.AppendText(string.Format(Properties.Resources.DataExported, name), FColors.Green, true);
else
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.DataExported, name));
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.DataExported, name), string.Empty, fullPath);
}
}
}
@ -370,7 +370,7 @@ namespace FModel.Utils
if (autoSave)
FConsole.AppendText(string.Format(Properties.Resources.DataExported, name), FColors.Green, true);
else
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.DataExported, name));
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.DataExported, name, string.Empty, fullPath));
}
}
break;

View File

@ -58,7 +58,7 @@ namespace FModel.Utils
{
mainError = true;
StatusBarVm.statusBarViewModel.Set(e.Message, Properties.Resources.Error);
FConsole.AppendText(string.Format(Properties.Resources.StaticKeyNotWorking, $"0x{sKey}"), FColors.Red);
FConsole.AppendText(string.Format(Properties.Resources.StaticKeyNotWorking, $"0x{sKey}"), FColors.Red, true);
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[AES]", $"0x{sKey} is NOT!!!! working with user's pak files");
}
}
@ -82,7 +82,7 @@ namespace FModel.Utils
}
}
menuItem.IsEnabled = menuItem.PakFile.AesKey != null;
menuItem.IsEnabled = menuItem.PakFile.AesKey != null || !menuItem.PakFile.Info.bEncryptedIndex;
}
}
}

View File

@ -58,11 +58,10 @@ namespace FModel.Utils
foreach (var namespac in new LocResReader(asset).Entries)
{
if (!_fortniteLocalizationDict.ContainsKey(namespac.Key))
_fortniteLocalizationDict[namespac.Key] = new Dictionary<string, string>();
_fortniteLocalizationDict.Add(namespac.Key, new Dictionary<string, string>());
foreach (var key in namespac.Value)
if (!string.IsNullOrEmpty(key.Value))
_fortniteLocalizationDict[namespac.Key][key.Key] = key.Value;
_fortniteLocalizationDict[namespac.Key][key.Key] = key.Value;
}
}
}

View File

@ -71,7 +71,7 @@ namespace FModel.ViewModels.AvalonEdit
if (File.Exists(saveFileDialog.FileName))
{
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[AvalonEditViewModel]", $"{vm.OwerName} successfully saved");
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, Properties.Resources.DataSaved);
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, Properties.Resources.DataSaved, string.Empty, saveFileDialog.FileName);
}
}
}

View File

@ -145,7 +145,7 @@ namespace FModel.ViewModels.ImageBox
if (File.Exists(saveFileDialog.FileName))
{
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[AvalonEditViewModel]", $"{vm.Name} successfully saved");
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, Properties.Resources.ImageSaved);
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, Properties.Resources.ImageSaved, string.Empty, saveFileDialog.FileName);
}
}
}

View File

@ -122,7 +122,7 @@ namespace FModel.ViewModels.MenuItem
{
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[CDN]", $"Downloaded {Header} in {downloadTimer.ElapsedMilliseconds} ms");
StatusBarVm.statusBarViewModel.Set(string.Format(Properties.Resources.DownloadSuccess, Header), Properties.Resources.Success);
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.DownloadSuccess, Header), "/FModel;component/Resources/check-circle.ico");
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.DownloadSuccess, Header), "/FModel;component/Resources/check-circle.ico", path);
}
else
{
@ -202,7 +202,7 @@ namespace FModel.ViewModels.MenuItem
{
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[BackupMenuItemViewModel]", "[Create]", $"{_backupFileName} successfully created");
StatusBarVm.statusBarViewModel.Set(string.Format(Properties.Resources.CreateSuccess, _backupFileName), Properties.Resources.Success);
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.CreateSuccess, _backupFileName), "/FModel;component/Resources/check-circle.ico");
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, string.Format(Properties.Resources.CreateSuccess, _backupFileName), "/FModel;component/Resources/check-circle.ico", _backupFilePath);
}
else
{

View File

@ -11,11 +11,12 @@ namespace FModel.ViewModels.Notifier
public override NotificationDisplayPart DisplayPart => _displayPart ?? (_displayPart = new CustomNotifier(this));
public NotifierViewModel(string title, string message, string icon, MessageOptions messageOptions) : base(message, messageOptions)
public NotifierViewModel(string title, string message, string icon, string path, MessageOptions messageOptions) : base(message, messageOptions)
{
Title = title;
Message = message;
Icon = icon;
Path = path;
}
private string _title;
@ -51,6 +52,17 @@ namespace FModel.ViewModels.Notifier
}
}
private string _path;
public string Path
{
get { return _path; }
set
{
_path = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)

View File

@ -1,5 +1,6 @@
using FModel.Windows.SoundPlayer.Visualization;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows;
namespace FModel.ViewModels.SoundPlayer
@ -38,7 +39,7 @@ namespace FModel.ViewModels.SoundPlayer
private string _content;
private string _bytes;
private string _duration;
private float _volume = 0.5f;
private float _volume = float.Parse(Properties.Settings.Default.AudioPlayerVolume, CultureInfo.InvariantCulture.NumberFormat);
public ObservableCollection<Device> Devices
{

View File

@ -8,7 +8,8 @@
xmlns:core="clr-namespace:ToastNotifications.Core;assembly=ToastNotifications"
mc:Ignorable="d" Background="#FF232930"
d:DesignHeight="60" d:DesignWidth="250"
d:DataContext="{d:DesignInstance vm:NotifierViewModel, IsDesignTimeCreatable=False}">
d:DataContext="{d:DesignInstance vm:NotifierViewModel, IsDesignTimeCreatable=False}"
MouseLeftButtonUp="NotificationDisplayPart_MouseLeftButtonUp">
<Grid>
<Border BorderThickness="2" BorderBrush="#7F748198">
<Grid Margin="4">
@ -20,11 +21,14 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.RowSpan="2" Source="{Binding Icon}"/>
<TextBlock Text="{Binding Title}" FontWeight="Bold" Foreground="White" Grid.Column="2" FontFamily="Calibri" />
<TextBlock Text="{Binding Message}" FontWeight="Light" Foreground="White" Grid.Row="1" Grid.Column="2" TextWrapping="Wrap"/>
<Image x:Name="OpenPath_Img" Grid.Row="2" Grid.Column="2" Source="/Resources/open-in-new.png" Visibility="Hidden"
Width="12" Height="12" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
</Grid>
</Border>
</Grid>

View File

@ -1,4 +1,6 @@
using FModel.ViewModels.Notifier;
using System.Diagnostics;
using System.Windows.Input;
using ToastNotifications.Core;
namespace FModel.Windows.CustomNotifier
@ -11,7 +13,20 @@ namespace FModel.Windows.CustomNotifier
public CustomNotifier(NotifierViewModel notifier)
{
InitializeComponent();
if (!string.IsNullOrEmpty(notifier.Path))
OpenPath_Img.Visibility = System.Windows.Visibility.Visible;
Bind(notifier);
}
private void NotificationDisplayPart_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (sender is CustomNotifier c && c.DataContext is NotifierViewModel n)
{
if (!string.IsNullOrEmpty(n.Path))
Process.Start(new ProcessStartInfo { FileName = "explorer.exe", Arguments = $"/select, \"{n.Path.Replace('/', '\\')}\"", UseShellExecute = true });
}
}
}
}

View File

@ -6,9 +6,9 @@ namespace FModel.Windows.CustomNotifier
{
public static class CustomNotifierHelper
{
public static void ShowCustomMessage(this Notifier notifier, string title, string message, string icon = null, MessageOptions messageOptions = null)
public static void ShowCustomMessage(this Notifier notifier, string title, string message, string icon = null, string path = null, MessageOptions messageOptions = null)
{
notifier.Notify(() => new NotifierViewModel(title, message, string.IsNullOrEmpty(icon) ? "/FModel;component/FModel.ico" : icon, messageOptions));
notifier.Notify(() => new NotifierViewModel(title, message, string.IsNullOrEmpty(icon) ? "/FModel;component/FModel.ico" : icon, path, messageOptions));
}
}
}

View File

@ -276,7 +276,7 @@ namespace FModel.Windows.ImagesMerger
if (File.Exists(saveFileDialog.FileName))
{
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[ImagesMerger]", "Preview successfully saved");
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, Properties.Resources.ImageSaved);
Globals.gNotifier.ShowCustomMessage(Properties.Resources.Success, Properties.Resources.ImageSaved, string.Empty, saveFileDialog.FileName);
}
}
}

View File

@ -60,6 +60,8 @@ namespace FModel.Windows.SoundPlayer.Visualization
set
{
volume = value;
Properties.Settings.Default.AudioPlayerVolume = volume.ToString();
Properties.Settings.Default.Save();
if (_soundOut != null)
{

View File

@ -131,6 +131,7 @@ This software uses the following open source packages:
- [Autoupdater.NET.Official](https://github.com/ravibpatel/AutoUpdater.NET)
- [AvalonEdit](https://github.com/icsharpcode/AvalonEdit)
- [CSCore](https://github.com/filoe/cscore)
- [DotNetZip](https://github.com/haf/DotNetZip.Semverd)
- [DiscordRichPresence](https://github.com/Lachee/discord-rpc-csharp)
- [Extended.Wpf.Toolkit](https://github.com/xceedsoftware/wpftoolkit)
- [K4os.Compression.LZ4.Streams](https://github.com/MiloszKrajewski/K4os.Compression.LZ4)