mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-12-25 02:00:12 +08:00
distribute long class
This commit is contained in:
@@ -150,6 +150,8 @@
|
||||
<Compile Include="Plugin\ContextObject.cs" />
|
||||
<Compile Include="Helpers\WindowHelper.cs" />
|
||||
<Compile Include="Helpers\Updater.cs" />
|
||||
<Compile Include="ViewerWindow.Actions.cs" />
|
||||
<Compile Include="ViewerWindow.Properties.cs" />
|
||||
<Compile Include="ViewWindowManager.cs" />
|
||||
<Compile Include="Controls\WebClientEx.cs">
|
||||
<SubType>Component</SubType>
|
||||
|
||||
273
QuickLook/ViewerWindow.Actions.cs
Normal file
273
QuickLook/ViewerWindow.Actions.cs
Normal file
@@ -0,0 +1,273 @@
|
||||
// Copyright © 2017 Paddy Xu
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using QuickLook.Helpers;
|
||||
using QuickLook.Plugin;
|
||||
|
||||
namespace QuickLook
|
||||
{
|
||||
public partial class ViewerWindow
|
||||
{
|
||||
internal void RunWith(string with, string arg)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(with)
|
||||
{
|
||||
Arguments = arg,
|
||||
WorkingDirectory = Path.GetDirectoryName(_path)
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Run()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(_path)
|
||||
{
|
||||
WorkingDirectory = Path.GetDirectoryName(_path)
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RunAndHide()
|
||||
{
|
||||
Run();
|
||||
BeginHide();
|
||||
}
|
||||
|
||||
internal void RunAndClose()
|
||||
{
|
||||
Run();
|
||||
BeginClose();
|
||||
}
|
||||
|
||||
private static void ResizeAndCenter(Window window, Size size, bool canOldPluginResize, bool canNextPluginResize)
|
||||
{
|
||||
// resize to MinSize first
|
||||
size.Width = Math.Max(size.Width, window.MinWidth);
|
||||
size.Height = Math.Max(size.Height, window.MinHeight);
|
||||
|
||||
if (!window.IsLoaded)
|
||||
{
|
||||
// if the window is not loaded yet, just leave the problem to WPF
|
||||
window.Width = size.Width;
|
||||
window.Height = size.Height;
|
||||
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
window.Dispatcher.BeginInvoke(new Action(window.BringToFront), DispatcherPriority.Render);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// is the window is now now maximized, do not move it
|
||||
if (window.WindowState == WindowState.Maximized)
|
||||
return;
|
||||
|
||||
// if this is a new window, place it to top
|
||||
if (window.Visibility != Visibility.Visible)
|
||||
window.BringToFront();
|
||||
|
||||
var screen = WindowHelper.GetCurrentWindowRect();
|
||||
|
||||
// do not resize or reposition the window is it is visible - unless the next window is size-fixed
|
||||
if (window.Visibility == Visibility.Visible && canOldPluginResize && canNextPluginResize)
|
||||
return;
|
||||
|
||||
// otherwise, resize it and place it to the old window center.
|
||||
var oldCenterX = window.Left + window.Width / 2;
|
||||
var oldCenterY = window.Top + window.Height / 2;
|
||||
|
||||
var newLeft = oldCenterX - size.Width / 2;
|
||||
var newTop = oldCenterY - size.Height / 2;
|
||||
|
||||
// ensure the new window is fully visible
|
||||
newLeft = Math.Max(newLeft, screen.Left); // left
|
||||
newTop = Math.Max(newTop, screen.Top); // top
|
||||
newLeft = newLeft + size.Width > screen.Right ? screen.Right - size.Width : newLeft; // right
|
||||
newTop = newTop + size.Height > screen.Bottom ? screen.Bottom - size.Height : newTop; // bottom
|
||||
|
||||
window.MoveWindow(newLeft, newTop, size.Width, size.Height);
|
||||
}
|
||||
|
||||
internal void UnloadPlugin()
|
||||
{
|
||||
// the focused element will not processed by GC: https://stackoverflow.com/questions/30848939/memory-leak-due-to-window-efectivevalues-retention
|
||||
FocusManager.SetFocusedElement(this, null);
|
||||
Keyboard.DefaultRestoreFocusMode =
|
||||
RestoreFocusMode.None; // WPF will put the focused item into a "_restoreFocus" list ... omg
|
||||
Keyboard.ClearFocus();
|
||||
|
||||
_canOldPluginResize = ContextObject.CanResize;
|
||||
|
||||
ContextObject.Reset();
|
||||
|
||||
try
|
||||
{
|
||||
Plugin?.Cleanup();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e);
|
||||
}
|
||||
Plugin = null;
|
||||
|
||||
_path = string.Empty;
|
||||
}
|
||||
|
||||
internal void BeginShow(IViewer matchedPlugin, string path,
|
||||
Action<string, ExceptionDispatchInfo> exceptionHandler)
|
||||
{
|
||||
_path = path;
|
||||
Plugin = matchedPlugin;
|
||||
|
||||
ContextObject.ViewerWindow = this;
|
||||
|
||||
// get window size before showing it
|
||||
Plugin.Prepare(path, ContextObject);
|
||||
|
||||
SetOpenWithButtonAndPath();
|
||||
|
||||
// revert UI changes
|
||||
ContextObject.IsBusy = true;
|
||||
|
||||
var margin = windowFrameContainer.Margin.Top * 2;
|
||||
|
||||
var newHeight = ContextObject.PreferredSize.Height + margin +
|
||||
(ContextObject.TitlebarOverlap ? 0 : windowCaptionContainer.Height);
|
||||
var newWidth = ContextObject.PreferredSize.Width + margin;
|
||||
|
||||
ResizeAndCenter(this, new Size(newWidth, newHeight), _canOldPluginResize, ContextObject.CanResize);
|
||||
|
||||
if (Visibility != Visibility.Visible)
|
||||
Show();
|
||||
|
||||
ShowWindowCaptionContainer(null, null);
|
||||
//WindowHelper.SetActivate(new WindowInteropHelper(this), ContextObject.CanFocus);
|
||||
|
||||
// load plugin, do not block UI
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Plugin.View(path, ContextObject);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionHandler(path, ExceptionDispatchInfo.Capture(e));
|
||||
}
|
||||
}),
|
||||
DispatcherPriority.Input);
|
||||
}
|
||||
|
||||
private void SetOpenWithButtonAndPath()
|
||||
{
|
||||
buttonOpenWithText.Inlines.Clear();
|
||||
|
||||
if (Directory.Exists(_path))
|
||||
{
|
||||
AddToInlines("MW_BrowseFolder", Path.GetFileName(_path));
|
||||
return;
|
||||
}
|
||||
var isExe = FileHelper.IsExecutable(_path, out var appFriendlyName);
|
||||
if (isExe)
|
||||
{
|
||||
AddToInlines("MW_Run", appFriendlyName);
|
||||
return;
|
||||
}
|
||||
// not an exe
|
||||
var found = FileHelper.GetAssocApplication(_path, out appFriendlyName);
|
||||
if (found)
|
||||
{
|
||||
AddToInlines("MW_OpenWith", appFriendlyName);
|
||||
return;
|
||||
}
|
||||
// assoc not found
|
||||
AddToInlines("MW_Open", Path.GetFileName(_path));
|
||||
|
||||
void AddToInlines(string str, string replaceWith)
|
||||
{
|
||||
// limit str length
|
||||
if (replaceWith.Length > 16)
|
||||
replaceWith = replaceWith.Substring(0, 14) + "…" + replaceWith.Substring(replaceWith.Length - 2);
|
||||
|
||||
str = TranslationHelper.GetString(str);
|
||||
var elements = str.Split(new[] {"{0}"}, StringSplitOptions.None).ToList();
|
||||
while (elements.Count < 2)
|
||||
elements.Add(string.Empty);
|
||||
|
||||
buttonOpenWithText.Inlines.Add(
|
||||
new Run(elements[0]) {FontWeight = FontWeights.Normal}); // text beforehand
|
||||
buttonOpenWithText.Inlines.Add(
|
||||
new Run(replaceWith) {FontWeight = FontWeights.SemiBold}); // appFriendlyName
|
||||
buttonOpenWithText.Inlines.Add(
|
||||
new Run(elements[1]) {FontWeight = FontWeights.Normal}); // text afterward
|
||||
}
|
||||
}
|
||||
|
||||
internal void BeginHide()
|
||||
{
|
||||
UnloadPlugin();
|
||||
|
||||
// if the this window is hidden in Max state, new show() will results in failure:
|
||||
// "Cannot show Window when ShowActivated is false and WindowState is set to Maximized"
|
||||
WindowState = WindowState.Normal;
|
||||
|
||||
Hide();
|
||||
//Dispatcher.BeginInvoke(new Action(Hide), DispatcherPriority.ApplicationIdle);
|
||||
|
||||
ProcessHelper.PerformAggressiveGC();
|
||||
}
|
||||
|
||||
internal void BeginClose()
|
||||
{
|
||||
UnloadPlugin();
|
||||
|
||||
Close();
|
||||
|
||||
ProcessHelper.PerformAggressiveGC();
|
||||
}
|
||||
|
||||
internal void Share(object sender, RoutedEventArgs e)
|
||||
{
|
||||
RunWith("rundll32.exe", $"shell32.dll,OpenAs_RunDLL {_path}");
|
||||
}
|
||||
}
|
||||
}
|
||||
68
QuickLook/ViewerWindow.Properties.cs
Normal file
68
QuickLook/ViewerWindow.Properties.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright © 2017 Paddy Xu
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using QuickLook.Annotations;
|
||||
using QuickLook.Plugin;
|
||||
|
||||
namespace QuickLook
|
||||
{
|
||||
public partial class ViewerWindow : INotifyPropertyChanged
|
||||
{
|
||||
private readonly ResourceDictionary _darkDict = new ResourceDictionary
|
||||
{
|
||||
Source = new Uri("pack://application:,,,/QuickLook;component/Styles/MainWindowStyles.Dark.xaml")
|
||||
};
|
||||
private bool _canOldPluginResize;
|
||||
private bool _pinned;
|
||||
private bool Pinned
|
||||
{
|
||||
get => _pinned;
|
||||
set
|
||||
{
|
||||
_pinned = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
public IViewer Plugin { get; private set; }
|
||||
public ContextObject ContextObject { get; private set; }
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public void SwitchTheme(bool dark)
|
||||
{
|
||||
if (dark)
|
||||
{
|
||||
if (!Resources.MergedDictionaries.Contains(_darkDict))
|
||||
Resources.MergedDictionaries.Add(_darkDict);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Resources.MergedDictionaries.Contains(_darkDict))
|
||||
Resources.MergedDictionaries.Remove(_darkDict);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,10 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Threading;
|
||||
using QuickLook.Annotations;
|
||||
using QuickLook.Controls;
|
||||
using QuickLook.Helpers;
|
||||
using QuickLook.Plugin;
|
||||
@@ -38,16 +29,10 @@ namespace QuickLook
|
||||
/// <summary>
|
||||
/// Interaction logic for ViewerWindow.xaml
|
||||
/// </summary>
|
||||
public partial class ViewerWindow : MainWindowBase, INotifyPropertyChanged
|
||||
public partial class ViewerWindow : MainWindowBase
|
||||
{
|
||||
private readonly ResourceDictionary _darkDict = new ResourceDictionary
|
||||
{
|
||||
Source = new Uri("pack://application:,,,/QuickLook;component/Styles/MainWindowStyles.Dark.xaml")
|
||||
};
|
||||
private string _path;
|
||||
private bool _pinned;
|
||||
private bool _restoreForDragMove;
|
||||
private bool _canOldPluginResize;
|
||||
|
||||
internal ViewerWindow()
|
||||
{
|
||||
@@ -99,26 +84,9 @@ namespace QuickLook
|
||||
buttonWindowStatus.Click += (sender, e) =>
|
||||
WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
|
||||
|
||||
buttonShare.Click +=
|
||||
(sender, e) => RunWith("rundll32.exe", $"shell32.dll,OpenAs_RunDLL {_path}");
|
||||
buttonShare.Click += Share;
|
||||
}
|
||||
|
||||
public bool Pinned
|
||||
{
|
||||
get => _pinned;
|
||||
private set
|
||||
{
|
||||
_pinned = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public IViewer Plugin { get; private set; }
|
||||
|
||||
public ContextObject ContextObject { get; private set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void ShowWindowCaptionContainer(object sender, MouseEventArgs e)
|
||||
{
|
||||
var show = (Storyboard) windowCaptionContainer.FindResource("ShowCaptionContainerStoryboard");
|
||||
@@ -191,259 +159,5 @@ namespace QuickLook
|
||||
DragMove();
|
||||
}
|
||||
}
|
||||
|
||||
internal void RunWith(string with, string arg)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(with)
|
||||
{
|
||||
Arguments = arg,
|
||||
WorkingDirectory = Path.GetDirectoryName(_path)
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Run()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_path))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(_path)
|
||||
{
|
||||
WorkingDirectory = Path.GetDirectoryName(_path)
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RunAndHide()
|
||||
{
|
||||
Run();
|
||||
BeginHide();
|
||||
}
|
||||
|
||||
internal void RunAndClose()
|
||||
{
|
||||
Run();
|
||||
BeginClose();
|
||||
}
|
||||
|
||||
private static void ResizeAndCenter(Window window, Size size, bool canOldPluginResize, bool canNextPluginResize)
|
||||
{
|
||||
// resize to MinSize first
|
||||
size.Width = Math.Max(size.Width, window.MinWidth);
|
||||
size.Height = Math.Max(size.Height, window.MinHeight);
|
||||
|
||||
if (!window.IsLoaded)
|
||||
{
|
||||
// if the window is not loaded yet, just leave the problem to WPF
|
||||
window.Width = size.Width;
|
||||
window.Height = size.Height;
|
||||
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
window.Dispatcher.BeginInvoke(new Action(window.BringToFront), DispatcherPriority.Render);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// is the window is now now maximized, do not move it
|
||||
if (window.WindowState == WindowState.Maximized)
|
||||
return;
|
||||
|
||||
// if this is a new window, place it to top
|
||||
if (window.Visibility != Visibility.Visible)
|
||||
window.BringToFront();
|
||||
|
||||
var screen = WindowHelper.GetCurrentWindowRect();
|
||||
|
||||
// do not resize or reposition the window is it is visible - unless the next window is size-fixed
|
||||
if (window.Visibility == Visibility.Visible && canOldPluginResize && canNextPluginResize)
|
||||
return;
|
||||
|
||||
// otherwise, resize it and place it to the old window center.
|
||||
var oldCenterX = window.Left + window.Width / 2;
|
||||
var oldCenterY = window.Top + window.Height / 2;
|
||||
|
||||
var newLeft = oldCenterX - size.Width / 2;
|
||||
var newTop = oldCenterY - size.Height / 2;
|
||||
|
||||
// ensure the new window is fully visible
|
||||
newLeft = Math.Max(newLeft, screen.Left); // left
|
||||
newTop = Math.Max(newTop, screen.Top); // top
|
||||
newLeft = newLeft + size.Width > screen.Right ? screen.Right - size.Width : newLeft; // right
|
||||
newTop = newTop + size.Height > screen.Bottom ? screen.Bottom - size.Height : newTop; // bottom
|
||||
|
||||
window.MoveWindow(newLeft, newTop, size.Width, size.Height);
|
||||
}
|
||||
|
||||
internal void UnloadPlugin()
|
||||
{
|
||||
// the focused element will not processed by GC: https://stackoverflow.com/questions/30848939/memory-leak-due-to-window-efectivevalues-retention
|
||||
FocusManager.SetFocusedElement(this, null);
|
||||
Keyboard.DefaultRestoreFocusMode =
|
||||
RestoreFocusMode.None; // WPF will put the focused item into a "_restoreFocus" list ... omg
|
||||
Keyboard.ClearFocus();
|
||||
|
||||
_canOldPluginResize = ContextObject.CanResize;
|
||||
|
||||
ContextObject.Reset();
|
||||
|
||||
try
|
||||
{
|
||||
Plugin?.Cleanup();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e);
|
||||
}
|
||||
Plugin = null;
|
||||
|
||||
_path = string.Empty;
|
||||
}
|
||||
|
||||
internal void BeginShow(IViewer matchedPlugin, string path,
|
||||
Action<string, ExceptionDispatchInfo> exceptionHandler)
|
||||
{
|
||||
_path = path;
|
||||
Plugin = matchedPlugin;
|
||||
|
||||
ContextObject.ViewerWindow = this;
|
||||
|
||||
// get window size before showing it
|
||||
Plugin.Prepare(path, ContextObject);
|
||||
|
||||
SetOpenWithButtonAndPath();
|
||||
|
||||
// revert UI changes
|
||||
ContextObject.IsBusy = true;
|
||||
|
||||
var margin = windowFrameContainer.Margin.Top * 2;
|
||||
|
||||
var newHeight = ContextObject.PreferredSize.Height + margin +
|
||||
(ContextObject.TitlebarOverlap ? 0 : windowCaptionContainer.Height);
|
||||
var newWidth = ContextObject.PreferredSize.Width + margin;
|
||||
|
||||
ResizeAndCenter(this, new Size(newWidth, newHeight), _canOldPluginResize, ContextObject.CanResize);
|
||||
|
||||
if (Visibility != Visibility.Visible)
|
||||
Show();
|
||||
|
||||
ShowWindowCaptionContainer(null, null);
|
||||
//WindowHelper.SetActivate(new WindowInteropHelper(this), ContextObject.CanFocus);
|
||||
|
||||
// load plugin, do not block UI
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Plugin.View(path, ContextObject);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionHandler(path, ExceptionDispatchInfo.Capture(e));
|
||||
}
|
||||
}),
|
||||
DispatcherPriority.Input);
|
||||
}
|
||||
|
||||
private void SetOpenWithButtonAndPath()
|
||||
{
|
||||
buttonOpenWithText.Inlines.Clear();
|
||||
|
||||
if (Directory.Exists(_path))
|
||||
{
|
||||
AddToInlines("MW_BrowseFolder", Path.GetFileName(_path));
|
||||
return;
|
||||
}
|
||||
var isExe = FileHelper.IsExecutable(_path, out var appFriendlyName);
|
||||
if (isExe)
|
||||
{
|
||||
AddToInlines("MW_Run", appFriendlyName);
|
||||
return;
|
||||
}
|
||||
// not an exe
|
||||
var found = FileHelper.GetAssocApplication(_path, out appFriendlyName);
|
||||
if (found)
|
||||
{
|
||||
AddToInlines("MW_OpenWith", appFriendlyName);
|
||||
return;
|
||||
}
|
||||
// assoc not found
|
||||
AddToInlines("MW_Open", Path.GetFileName(_path));
|
||||
|
||||
void AddToInlines(string str, string replaceWith)
|
||||
{
|
||||
// limit str length
|
||||
if (replaceWith.Length > 16)
|
||||
replaceWith = replaceWith.Substring(0, 14) + "…" + replaceWith.Substring(replaceWith.Length - 2);
|
||||
|
||||
str = TranslationHelper.GetString(str);
|
||||
var elements = str.Split(new[] {"{0}"}, StringSplitOptions.None).ToList();
|
||||
while (elements.Count < 2)
|
||||
elements.Add(string.Empty);
|
||||
|
||||
buttonOpenWithText.Inlines.Add(
|
||||
new Run(elements[0]) {FontWeight = FontWeights.Normal}); // text beforehand
|
||||
buttonOpenWithText.Inlines.Add(
|
||||
new Run(replaceWith) {FontWeight = FontWeights.SemiBold}); // appFriendlyName
|
||||
buttonOpenWithText.Inlines.Add(
|
||||
new Run(elements[1]) {FontWeight = FontWeights.Normal}); // text afterward
|
||||
}
|
||||
}
|
||||
|
||||
internal void BeginHide()
|
||||
{
|
||||
UnloadPlugin();
|
||||
|
||||
// if the this window is hidden in Max state, new show() will results in failure:
|
||||
// "Cannot show Window when ShowActivated is false and WindowState is set to Maximized"
|
||||
WindowState = WindowState.Normal;
|
||||
|
||||
Hide();
|
||||
//Dispatcher.BeginInvoke(new Action(Hide), DispatcherPriority.ApplicationIdle);
|
||||
|
||||
ProcessHelper.PerformAggressiveGC();
|
||||
}
|
||||
|
||||
internal void BeginClose()
|
||||
{
|
||||
UnloadPlugin();
|
||||
|
||||
Close();
|
||||
|
||||
ProcessHelper.PerformAggressiveGC();
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public void SwitchTheme(bool dark)
|
||||
{
|
||||
if (dark)
|
||||
{
|
||||
if (!Resources.MergedDictionaries.Contains(_darkDict))
|
||||
Resources.MergedDictionaries.Add(_darkDict);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Resources.MergedDictionaries.Contains(_darkDict))
|
||||
Resources.MergedDictionaries.Remove(_darkDict);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user