1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-05-28 08:34:06 +02:00

Update TweetDuck codebase to C# 7.0

This commit is contained in:
chylex 2017-04-28 13:29:45 +02:00
parent 37fec7e952
commit abddf61c88
39 changed files with 120 additions and 358 deletions

View File

@ -46,72 +46,44 @@ sealed class UserConfig{
public string CustomBrowserCSS { get; set; } public string CustomBrowserCSS { get; set; }
public string CustomNotificationCSS { get; set; } public string CustomNotificationCSS { get; set; }
public bool IsCustomNotificationPositionSet{ public bool IsCustomNotificationPositionSet => CustomNotificationPosition != ControlExtensions.InvisibleLocation;
get{
return CustomNotificationPosition != ControlExtensions.InvisibleLocation; public string NotificationSoundPath{
} get => string.IsNullOrEmpty(notificationSoundPath) ? string.Empty : notificationSoundPath;
set => notificationSoundPath = value;
} }
public bool MuteNotifications{ public bool MuteNotifications{
get{ get => muteNotifications;
return muteNotifications;
}
set{ set{
if (muteNotifications == value)return; if (muteNotifications != value){
muteNotifications = value;
muteNotifications = value; MuteToggled?.Invoke(this, new EventArgs());
if (MuteToggled != null){
MuteToggled(this, new EventArgs());
} }
} }
} }
public int ZoomLevel{ public int ZoomLevel{
get{ get => zoomLevel;
return zoomLevel;
}
set{ set{
if (zoomLevel == value)return; if (zoomLevel != value){
zoomLevel = value;
zoomLevel = value; ZoomLevelChanged?.Invoke(this, new EventArgs());
if (ZoomLevelChanged != null){
ZoomLevelChanged(this, new EventArgs());
} }
} }
} }
public double ZoomMultiplier{ public double ZoomMultiplier => zoomLevel/100.0;
get{
return zoomLevel/100.0;
}
}
public string NotificationSoundPath{
get{
return string.IsNullOrEmpty(notificationSoundPath) ? string.Empty : notificationSoundPath;
}
set{
notificationSoundPath = value;
}
}
public TrayIcon.Behavior TrayBehavior{ public TrayIcon.Behavior TrayBehavior{
get{ get => trayBehavior;
return trayBehavior;
}
set{ set{
if (trayBehavior == value)return; if (trayBehavior != value){
trayBehavior = value;
trayBehavior = value; TrayBehaviorChanged?.Invoke(this, new EventArgs());
if (TrayBehaviorChanged != null){
TrayBehaviorChanged(this, new EventArgs());
} }
} }
} }
@ -247,11 +219,8 @@ public static UserConfig Load(string file){
config.file = file; config.file = file;
} }
} }
if (config != null){
config.UpgradeFile();
}
config?.UpgradeFile();
break; break;
}catch(FileNotFoundException){ }catch(FileNotFoundException){
}catch(DirectoryNotFoundException){ }catch(DirectoryNotFoundException){

View File

@ -3,11 +3,7 @@
namespace TweetDck.Core.Controls{ namespace TweetDck.Core.Controls{
class FlatButton : Button{ class FlatButton : Button{
protected override bool ShowFocusCues{ protected override bool ShowFocusCues => false;
get{
return false;
}
}
public FlatButton(){ public FlatButton(){
GotFocus += FlatButton_GotFocus; GotFocus += FlatButton_GotFocus;

View File

@ -6,21 +6,11 @@
namespace TweetDck.Core.Controls{ namespace TweetDck.Core.Controls{
sealed partial class TabPanel : UserControl{ sealed partial class TabPanel : UserControl{
public IEnumerable<TabButton> Buttons{ public Panel Content => panelContent;
get{ public IEnumerable<TabButton> Buttons => panelButtons.Controls.Cast<TabButton>();
return panelButtons.Controls.Cast<TabButton>();
}
}
public TabButton ActiveButton { get; private set; } public TabButton ActiveButton { get; private set; }
// ReSharper disable once ConvertToAutoPropertyWithPrivateSetter
public Panel Content{
get{
return panelContent;
}
}
private int btnWidth; private int btnWidth;
public TabPanel(){ public TabPanel(){

View File

@ -23,11 +23,7 @@
namespace TweetDck.Core{ namespace TweetDck.Core{
sealed partial class FormBrowser : Form{ sealed partial class FormBrowser : Form{
private static UserConfig Config{ private static UserConfig Config => Program.UserConfig;
get{
return Program.UserConfig;
}
}
public string UpdateInstallerPath { get; private set; } public string UpdateInstallerPath { get; private set; }
@ -93,13 +89,8 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings)
browser.Dispose(); browser.Dispose();
contextMenu.Dispose(); contextMenu.Dispose();
if (notificationScreenshotManager != null){ notificationScreenshotManager?.Dispose();
notificationScreenshotManager.Dispose(); soundNotification?.Dispose();
}
if (soundNotification != null){
soundNotification.Dispose();
}
}; };
this.trayIcon.ClickRestore += trayIcon_ClickRestore; this.trayIcon.ClickRestore += trayIcon_ClickRestore;
@ -365,7 +356,7 @@ public void ResumeNotification(){
// javascript calls // javascript calls
public void ReinjectCustomCSS(string css){ public void ReinjectCustomCSS(string css){
browser.ExecuteScriptAsync("TDGF_reinjectCustomCSS", css == null ? string.Empty : css.Replace(Environment.NewLine, " ")); browser.ExecuteScriptAsync("TDGF_reinjectCustomCSS", css?.Replace(Environment.NewLine, " ") ?? string.Empty);
} }
public void UpdateProperties(PropertyBridge.Properties properties){ public void UpdateProperties(PropertyBridge.Properties properties){

View File

@ -5,8 +5,7 @@ namespace TweetDck.Core.Handling{
class BrowserProcessHandler : IBrowserProcessHandler{ class BrowserProcessHandler : IBrowserProcessHandler{
void IBrowserProcessHandler.OnContextInitialized(){ void IBrowserProcessHandler.OnContextInitialized(){
using(IRequestContext ctx = Cef.GetGlobalRequestContext()){ using(IRequestContext ctx = Cef.GetGlobalRequestContext()){
string err; ctx.SetPreference("browser.enable_spellchecking", Program.UserConfig.EnableSpellCheck, out string _);
ctx.SetPreference("browser.enable_spellchecking", Program.UserConfig.EnableSpellCheck, out err);
} }
} }

View File

@ -9,10 +9,7 @@ class ResourceHandlerNotification : IResourceHandler{
private MemoryStream dataIn; private MemoryStream dataIn;
public void SetHTML(string html){ public void SetHTML(string html){
if (dataIn != null){ dataIn?.Dispose();
dataIn.Dispose();
}
dataIn = ResourceHandler.GetMemoryStream(html, Encoding.UTF8); dataIn = ResourceHandler.GetMemoryStream(html, Encoding.UTF8);
} }
@ -35,7 +32,7 @@ void IResourceHandler.GetResponseHeaders(IResponse response, out long responseLe
response.StatusCode = 200; response.StatusCode = 200;
response.StatusText = "OK"; response.StatusText = "OK";
response.ResponseHeaders = headers; response.ResponseHeaders = headers;
responseLength = dataIn != null ? dataIn.Length : -1; responseLength = dataIn?.Length ?? -1;
} }
bool IResourceHandler.ReadResponse(Stream dataOut, out int bytesRead, ICallback callback){ bool IResourceHandler.ReadResponse(Stream dataOut, out int bytesRead, ICallback callback){

View File

@ -50,23 +50,15 @@ protected Point PrimaryLocation{
} }
} }
public bool IsNotificationVisible{ public bool IsNotificationVisible => Location != ControlExtensions.InvisibleLocation;
get{
return Location != ControlExtensions.InvisibleLocation;
}
}
public new Point Location{ public new Point Location{
get{ get => base.Location;
return base.Location; set => Visible = (base.Location = value) != ControlExtensions.InvisibleLocation;
}
set{
Visible = (base.Location = value) != ControlExtensions.InvisibleLocation;
}
} }
public Func<bool> CanMoveWindow = () => true; public Func<bool> CanMoveWindow = () => true;
protected override bool ShowWithoutActivation => true;
protected readonly Form owner; protected readonly Form owner;
protected readonly ChromiumWebBrowser browser; protected readonly ChromiumWebBrowser browser;
@ -76,17 +68,7 @@ public bool IsNotificationVisible{
private string currentColumn; private string currentColumn;
private int pauseCounter; private int pauseCounter;
public bool IsPaused{ public bool IsPaused => pauseCounter > 0;
get{
return pauseCounter > 0;
}
}
protected override bool ShowWithoutActivation{
get{
return true;
}
}
public bool FreezeTimer { get; set; } public bool FreezeTimer { get; set; }
public bool ContextMenuOpen { get; set; } public bool ContextMenuOpen { get; set; }
@ -143,8 +125,8 @@ private void owner_FormClosed(object sender, FormClosedEventArgs e){
} }
private void Browser_IsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs e){ private void Browser_IsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs e){
if (e.IsBrowserInitialized && Initialized != null){ if (e.IsBrowserInitialized){
Initialized(this, new EventArgs()); Initialized?.Invoke(this, new EventArgs());
} }
} }

View File

@ -10,11 +10,7 @@ sealed partial class FormNotificationTweet : FormNotificationMain{
private const int NonIntrusiveIdleLimit = 30; private const int NonIntrusiveIdleLimit = 30;
private const int TrimMinimum = 32; private const int TrimMinimum = 32;
private bool IsCursorOverNotificationArea{ private bool IsCursorOverNotificationArea => new Rectangle(PrimaryLocation, Size).Contains(Cursor.Position);
get{
return new Rectangle(PrimaryLocation, Size).Contains(Cursor.Position);
}
}
private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4); private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4);
private bool needsTrim; private bool needsTrim;

View File

@ -69,10 +69,7 @@ private void Callback(){
public void Dispose(){ public void Dispose(){
timeout.Dispose(); timeout.Dispose();
disposer.Dispose(); disposer.Dispose();
screenshot?.Dispose();
if (screenshot != null){
screenshot.Dispose();
}
} }
} }
} }

View File

@ -2,7 +2,7 @@
namespace TweetDck.Core.Notification.Sound{ namespace TweetDck.Core.Notification.Sound{
sealed class PlaybackErrorEventArgs : EventArgs{ sealed class PlaybackErrorEventArgs : EventArgs{
public string Message { get; private set; } public string Message { get; }
public bool Ignore { get; set; } public bool Ignore { get; set; }
public PlaybackErrorEventArgs(string message){ public PlaybackErrorEventArgs(string message){

View File

@ -4,11 +4,7 @@
namespace TweetDck.Core.Notification.Sound{ namespace TweetDck.Core.Notification.Sound{
sealed class SoundPlayerImplFallback : ISoundNotificationPlayer{ sealed class SoundPlayerImplFallback : ISoundNotificationPlayer{
string ISoundNotificationPlayer.SupportedFormats{ string ISoundNotificationPlayer.SupportedFormats => "*.wav";
get{
return "*.wav";
}
}
public event EventHandler<PlaybackErrorEventArgs> PlaybackError; public event EventHandler<PlaybackErrorEventArgs> PlaybackError;

View File

@ -5,11 +5,7 @@
namespace TweetDck.Core.Notification.Sound{ namespace TweetDck.Core.Notification.Sound{
sealed class SoundPlayerImplWMP : ISoundNotificationPlayer{ sealed class SoundPlayerImplWMP : ISoundNotificationPlayer{
string ISoundNotificationPlayer.SupportedFormats{ string ISoundNotificationPlayer.SupportedFormats => "*.wav;*.mp3;*.mp2;*.m4a;*.mid;*.midi;*.rmi;*.wma;*.aif;*.aifc;*.aiff;*.snd;*.au";
get{
return "*.wav;*.mp3;*.mp2;*.m4a;*.mid;*.midi;*.rmi;*.wma;*.aif;*.aifc;*.aiff;*.snd;*.au";
}
}
public event EventHandler<PlaybackErrorEventArgs> PlaybackError; public event EventHandler<PlaybackErrorEventArgs> PlaybackError;

View File

@ -51,23 +51,9 @@ public enum Position{
TopLeft, TopRight, BottomLeft, BottomRight, Custom TopLeft, TopRight, BottomLeft, BottomRight, Custom
} }
public string Column{ public string Column => column;
get{ public string TweetUrl => tweetUrl;
return column; public string QuoteUrl => quoteUrl;
}
}
public string TweetUrl{
get{
return tweetUrl;
}
}
public string QuoteUrl{
get{
return quoteUrl;
}
}
private readonly string column; private readonly string column;
private readonly string html; private readonly string html;

View File

@ -6,20 +6,11 @@ namespace TweetDck.Core.Other{
sealed partial class FormMessage : Form{ sealed partial class FormMessage : Form{
public Button ClickedButton { get; private set; } public Button ClickedButton { get; private set; }
public int ActionPanelY{ public int ActionPanelY => panelActions.Location.Y;
get{
return panelActions.Location.Y;
}
}
private int ClientWidth{ private int ClientWidth{
get{ get => ClientSize.Width;
return ClientSize.Width; set => ClientSize = new Size(value, ClientSize.Height);
}
set{
ClientSize = new Size(value, ClientSize.Height);
}
} }
private readonly Icon icon; private readonly Icon icon;

View File

@ -31,9 +31,7 @@ public FormSettings(FormBrowser browser, PluginManager plugins, UpdateHandler up
} }
private void SelectTab<T>(Func<T> constructor) where T : BaseTabSettings{ private void SelectTab<T>(Func<T> constructor) where T : BaseTabSettings{
BaseTabSettings control; if (tabs.TryGetValue(typeof(T), out BaseTabSettings control)){
if (tabs.TryGetValue(typeof(T), out control)){
tabPanel.ReplaceContent(control); tabPanel.ReplaceContent(control);
} }
else{ else{

View File

@ -3,11 +3,7 @@
namespace TweetDck.Core.Other.Settings{ namespace TweetDck.Core.Other.Settings{
class BaseTabSettings : UserControl{ class BaseTabSettings : UserControl{
protected static UserConfig Config{ protected static UserConfig Config => Program.UserConfig;
get{
return Program.UserConfig;
}
}
public BaseTabSettings(){ public BaseTabSettings(){
Padding = new Padding(6); Padding = new Padding(6);

View File

@ -5,17 +5,8 @@
namespace TweetDck.Core.Other.Settings.Dialogs{ namespace TweetDck.Core.Other.Settings.Dialogs{
sealed partial class DialogSettingsCSS : Form{ sealed partial class DialogSettingsCSS : Form{
public string BrowserCSS{ public string BrowserCSS => textBoxBrowserCSS.Text;
get{ public string NotificationCSS => textBoxNotificationCSS.Text;
return textBoxBrowserCSS.Text;
}
}
public string NotificationCSS{
get{
return textBoxNotificationCSS.Text;
}
}
private readonly Action<string> reinjectBrowserCSS; private readonly Action<string> reinjectBrowserCSS;

View File

@ -5,11 +5,7 @@
namespace TweetDck.Core.Other.Settings.Dialogs{ namespace TweetDck.Core.Other.Settings.Dialogs{
sealed partial class DialogSettingsCefArgs : Form{ sealed partial class DialogSettingsCefArgs : Form{
public string CefArgs{ public string CefArgs => textBoxArgs.Text;
get{
return textBoxArgs.Text;
}
}
public DialogSettingsCefArgs(){ public DialogSettingsCefArgs(){
InitializeComponent(); InitializeComponent();

View File

@ -13,9 +13,7 @@ public static DialogSettingsExport Export(){
} }
public ExportFileFlags Flags{ public ExportFileFlags Flags{
get{ get => selectedFlags;
return selectedFlags;
}
set{ set{
// this will call events and SetFlag, which also updates the UI // this will call events and SetFlag, which also updates the UI

View File

@ -92,7 +92,7 @@ void IDisposable.Dispose(){
} }
public class Entry{ public class Entry{
public string Identifier { get; private set; } public string Identifier { get; }
public string KeyName{ public string KeyName{
get{ get{

View File

@ -12,9 +12,7 @@ public enum Behavior{ // keep order
public event EventHandler ClickClose; public event EventHandler ClickClose;
public bool Visible{ public bool Visible{
get{ get => notifyIcon.Visible;
return notifyIcon.Visible;
}
set{ set{
if (value){ if (value){
@ -72,9 +70,7 @@ private void contextMenu_Popup(object sender, EventArgs e){
} }
private void menuItemRestore_Click(object sender, EventArgs e){ private void menuItemRestore_Click(object sender, EventArgs e){
if (ClickRestore != null){ ClickRestore?.Invoke(this, e);
ClickRestore(this, e);
}
} }
private void menuItemMuteNotifications_Click(object sender, EventArgs e){ private void menuItemMuteNotifications_Click(object sender, EventArgs e){
@ -83,9 +79,7 @@ private void menuItemMuteNotifications_Click(object sender, EventArgs e){
} }
private void menuItemClose_Click(object sender, EventArgs e){ private void menuItemClose_Click(object sender, EventArgs e){
if (ClickClose != null){ ClickClose?.Invoke(this, e);
ClickClose(this, e);
}
} }
} }

View File

@ -23,11 +23,7 @@ public static string HeaderAcceptLanguage{
} }
} }
public static string HeaderUserAgent{ public static string HeaderUserAgent => Program.BrandName+" "+Application.ProductVersion;
get{
return Program.BrandName+" "+Application.ProductVersion;
}
}
public static readonly Color BackgroundColor = Color.FromArgb(28, 99, 153); public static readonly Color BackgroundColor = Color.FromArgb(28, 99, 153);
public const string BackgroundColorFix = "let e=document.createElement('style');document.head.appendChild(e);e.innerHTML='body::before{background:#1c6399!important}'"; public const string BackgroundColorFix = "let e=document.createElement('style');document.head.appendChild(e);e.innerHTML='body::before{background:#1c6399!important}'";
@ -37,9 +33,7 @@ public static string HeaderUserAgent{
}; };
public static bool IsValidUrl(string url){ public static bool IsValidUrl(string url){
Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri)){
if (Uri.TryCreate(url, UriKind.Absolute, out uri)){
string scheme = uri.Scheme; string scheme = uri.Scheme;
return scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp || scheme == Uri.UriSchemeMailto; return scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp || scheme == Uri.UriSchemeMailto;
} }

View File

@ -35,11 +35,7 @@ public static void ReadStringArray(char entryChar, string[] array, CommandLineAr
private readonly HashSet<string> flags = new HashSet<string>(); private readonly HashSet<string> flags = new HashSet<string>();
private readonly Dictionary<string, string> values = new Dictionary<string, string>(); private readonly Dictionary<string, string> values = new Dictionary<string, string>();
public int Count{ public int Count => flags.Count+values.Count;
get{
return flags.Count+values.Count;
}
}
public void AddFlag(string flag){ public void AddFlag(string flag){
flags.Add(flag.ToLowerInvariant()); flags.Add(flag.ToLowerInvariant());
@ -62,8 +58,7 @@ public bool HasValue(string key){
} }
public string GetValue(string key, string defaultValue){ public string GetValue(string key, string defaultValue){
string val; return values.TryGetValue(key.ToLowerInvariant(), out string val) ? val : defaultValue;
return values.TryGetValue(key.ToLowerInvariant(), out val) ? val : defaultValue;
} }
public void RemoveValue(string key){ public void RemoveValue(string key){

View File

@ -4,11 +4,7 @@ namespace TweetDck.Core.Utils{
static class CommandLineArgsParser{ static class CommandLineArgsParser{
private static Regex splitRegex; private static Regex splitRegex;
private static Regex SplitRegex{ private static Regex SplitRegex => splitRegex ?? (splitRegex = new Regex(@"([^=\s]+(?:=(?:[^ ]*""[^""]*?""[^ ]*|[^ ]*))?)", RegexOptions.Compiled));
get{
return splitRegex ?? (splitRegex = new Regex(@"([^=\s]+(?:=(?:[^ ]*""[^""]*?""[^ ]*|[^ ]*))?)", RegexOptions.Compiled));
}
}
public static CommandLineArgs ReadCefArguments(string argumentString){ public static CommandLineArgs ReadCefArguments(string argumentString){
CommandLineArgs args = new CommandLineArgs(); CommandLineArgs args = new CommandLineArgs();

View File

@ -9,18 +9,9 @@ static class HardwareAcceleration{
private static readonly string DisabledLibEGL = LibEGL+".bak"; private static readonly string DisabledLibEGL = LibEGL+".bak";
private static readonly string DisabledLibGLES = LibGLES+".bak"; private static readonly string DisabledLibGLES = LibGLES+".bak";
public static bool IsEnabled{ public static bool IsEnabled => File.Exists(LibEGL) && File.Exists(LibGLES);
get{ public static bool CanEnable => File.Exists(DisabledLibEGL) && File.Exists(DisabledLibGLES);
return File.Exists(LibEGL) && File.Exists(LibGLES);
}
}
public static bool CanEnable{
get{
return File.Exists(DisabledLibEGL) && File.Exists(DisabledLibGLES);
}
}
public static bool Enable(){ public static bool Enable(){
if (IsEnabled)return false; if (IsEnabled)return false;

View File

@ -21,9 +21,7 @@ public TwoKeyDictionary(int outerCapacity, int innerCapacity){
} }
set{ set{
Dictionary<K2, V> innerDict; if (!dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
if (!dict.TryGetValue(outerKey, out innerDict)){
dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity)); dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity));
} }
@ -44,9 +42,7 @@ public IEnumerable<V> InnerValues{
// Members // Members
public void Add(K1 outerKey, K2 innerKey, V value){ // throws on duplicate public void Add(K1 outerKey, K2 innerKey, V value){ // throws on duplicate
Dictionary<K2, V> innerDict; if (!dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
if (!dict.TryGetValue(outerKey, out innerDict)){
dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity)); dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity));
} }
@ -54,7 +50,7 @@ public void Add(K1 outerKey, K2 innerKey, V value){ // throws on duplicate
} }
public void Clear(){ public void Clear(){
this.dict.Clear(); dict.Clear();
} }
public void Clear(K1 outerKey){ // throws on missing key, but keeps the key unlike Remove(K1) public void Clear(K1 outerKey){ // throws on missing key, but keeps the key unlike Remove(K1)
@ -83,10 +79,8 @@ public bool Remove(K1 outerKey){
} }
public bool Remove(K1 outerKey, K2 innerKey){ public bool Remove(K1 outerKey, K2 innerKey){
Dictionary<K2, V> innerDict; if (dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict) && innerDict.Remove(innerKey)){
if (innerDict.Count == 0) {
if (dict.TryGetValue(outerKey, out innerDict) && innerDict.Remove(innerKey)){
if (innerDict.Count == 0){
dict.Remove(outerKey); dict.Remove(outerKey);
} }
@ -96,9 +90,7 @@ public bool Remove(K1 outerKey, K2 innerKey){
} }
public bool TryGetValue(K1 outerKey, K2 innerKey, out V value){ public bool TryGetValue(K1 outerKey, K2 innerKey, out V value){
Dictionary<K2, V> innerDict; if (dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
if (dict.TryGetValue(outerKey, out innerDict)){
return innerDict.TryGetValue(innerKey, out value); return innerDict.TryGetValue(innerKey, out value);
} }
else{ else{

View File

@ -2,8 +2,8 @@
namespace TweetDck.Plugins.Events{ namespace TweetDck.Plugins.Events{
class PluginChangedStateEventArgs : EventArgs{ class PluginChangedStateEventArgs : EventArgs{
public Plugin Plugin { get; private set; } public Plugin Plugin { get; }
public bool IsEnabled { get; private set; } public bool IsEnabled { get; }
public PluginChangedStateEventArgs(Plugin plugin, bool isEnabled){ public PluginChangedStateEventArgs(Plugin plugin, bool isEnabled){
this.Plugin = plugin; this.Plugin = plugin;

View File

@ -3,11 +3,7 @@
namespace TweetDck.Plugins.Events{ namespace TweetDck.Plugins.Events{
class PluginErrorEventArgs : EventArgs{ class PluginErrorEventArgs : EventArgs{
public bool HasErrors{ public bool HasErrors => Errors.Count > 0;
get{
return Errors.Count > 0;
}
}
public IList<string> Errors; public IList<string> Errors;

View File

@ -7,51 +7,41 @@
namespace TweetDck.Plugins{ namespace TweetDck.Plugins{
class Plugin{ class Plugin{
public string Identifier { get { return identifier; } } public string Identifier { get; }
public string Name { get { return metadata["NAME"]; } } public PluginGroup Group { get; }
public string Description { get { return metadata["DESCRIPTION"]; } }
public string Author { get { return metadata["AUTHOR"]; } }
public string Version { get { return metadata["VERSION"]; } }
public string Website { get { return metadata["WEBSITE"]; } }
public string ConfigFile { get { return metadata["CONFIGFILE"]; } }
public string ConfigDefault { get { return metadata["CONFIGDEFAULT"]; } }
public string RequiredVersion { get { return metadata["REQUIRES"]; } }
public PluginGroup Group { get; private set; }
public PluginEnvironment Environments { get; private set; } public PluginEnvironment Environments { get; private set; }
public string Name => metadata["NAME"];
public string Description => metadata["DESCRIPTION"];
public string Author => metadata["AUTHOR"];
public string Version => metadata["VERSION"];
public string Website => metadata["WEBSITE"];
public string ConfigFile => metadata["CONFIGFILE"];
public string ConfigDefault => metadata["CONFIGDEFAULT"];
public string RequiredVersion => metadata["REQUIRES"];
public bool CanRun{ public bool CanRun{
get{ get => canRun ?? (canRun = CheckRequiredVersion(RequiredVersion)).Value;
return canRun ?? (canRun = CheckRequiredVersion(RequiredVersion)).Value;
}
} }
public bool HasConfig{ public bool HasConfig{
get{ get => ConfigFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, ConfigFile).Length > 0;
return ConfigFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, ConfigFile).Length > 0;
}
} }
public string ConfigPath{ public string ConfigPath{
get{ get => HasConfig ? Path.Combine(GetPluginFolder(PluginFolder.Data), ConfigFile) : string.Empty;
return HasConfig ? Path.Combine(GetPluginFolder(PluginFolder.Data), ConfigFile) : string.Empty;
}
} }
public bool HasDefaultConfig{ public bool HasDefaultConfig{
get{ get => ConfigDefault.Length > 0 && GetFullPathIfSafe(PluginFolder.Root, ConfigDefault).Length > 0;
return ConfigDefault.Length > 0 && GetFullPathIfSafe(PluginFolder.Root, ConfigDefault).Length > 0;
}
} }
public string DefaultConfigPath{ public string DefaultConfigPath{
get{ get => HasDefaultConfig ? Path.Combine(GetPluginFolder(PluginFolder.Root), ConfigDefault) : string.Empty;
return HasDefaultConfig ? Path.Combine(GetPluginFolder(PluginFolder.Root), ConfigDefault) : string.Empty;
}
} }
private readonly string pathRoot; private readonly string pathRoot;
private readonly string pathData; private readonly string pathData;
private readonly string identifier;
private readonly Dictionary<string, string> metadata = new Dictionary<string, string>(4){ private readonly Dictionary<string, string> metadata = new Dictionary<string, string>(4){
{ "NAME", "" }, { "NAME", "" },
{ "DESCRIPTION", "" }, { "DESCRIPTION", "" },
@ -72,7 +62,7 @@ private Plugin(string path, PluginGroup group){
this.pathRoot = path; this.pathRoot = path;
this.pathData = Path.Combine(Program.PluginDataPath, group.GetIdentifierPrefix(), name); this.pathData = Path.Combine(Program.PluginDataPath, group.GetIdentifierPrefix(), name);
this.identifier = group.GetIdentifierPrefix()+name; this.Identifier = group.GetIdentifierPrefix()+name;
this.Group = group; this.Group = group;
this.Environments = PluginEnvironment.None; this.Environments = PluginEnvironment.None;
} }
@ -103,7 +93,7 @@ private void OnMetadataLoaded(){
Directory.CreateDirectory(dataFolder); Directory.CreateDirectory(dataFolder);
File.Copy(defaultConfigPath, configPath, false); File.Copy(defaultConfigPath, configPath, false);
}catch(Exception e){ }catch(Exception e){
Program.Reporter.HandleException("Plugin Loading Error", "Could not generate a configuration file for '"+identifier+"' plugin.", true, e); Program.Reporter.HandleException("Plugin Loading Error", "Could not generate a configuration file for '"+Identifier+"' plugin.", true, e);
} }
} }
} }
@ -154,12 +144,12 @@ public override string ToString(){
} }
public override int GetHashCode(){ public override int GetHashCode(){
return identifier.GetHashCode(); return Identifier.GetHashCode();
} }
public override bool Equals(object obj){ public override bool Equals(object obj){
Plugin plugin = obj as Plugin; Plugin plugin = obj as Plugin;
return plugin != null && plugin.identifier.Equals(identifier); return plugin != null && plugin.Identifier.Equals(Identifier);
} }
public static Plugin CreateFromFolder(string path, PluginGroup group, out string error){ public static Plugin CreateFromFolder(string path, PluginGroup group, out string error){
@ -236,9 +226,7 @@ private static bool LoadMetadata(string path, Plugin plugin, out string error){
return false; return false;
} }
Version ver; if (plugin.RequiredVersion.Length == 0 || !(plugin.RequiredVersion.Equals("*") || System.Version.TryParse(plugin.RequiredVersion, out Version _))){
if (plugin.RequiredVersion.Length == 0 || !(plugin.RequiredVersion.Equals("*") || System.Version.TryParse(plugin.RequiredVersion, out ver))){
error = "Plugin contains invalid version: "+plugin.RequiredVersion; error = "Plugin contains invalid version: "+plugin.RequiredVersion;
return false; return false;
} }

View File

@ -16,11 +16,7 @@ private static string SanitizeCacheKey(string key){
private readonly TwoKeyDictionary<int, string, string> fileCache = new TwoKeyDictionary<int, string, string>(4, 2); private readonly TwoKeyDictionary<int, string, string> fileCache = new TwoKeyDictionary<int, string, string>(4, 2);
private readonly TwoKeyDictionary<int, string, InjectedHTML> notificationInjections = new TwoKeyDictionary<int,string,InjectedHTML>(4, 1); private readonly TwoKeyDictionary<int, string, InjectedHTML> notificationInjections = new TwoKeyDictionary<int,string,InjectedHTML>(4, 1);
public IEnumerable<InjectedHTML> NotificationInjections{ public IEnumerable<InjectedHTML> NotificationInjections => notificationInjections.InnerValues;
get{
return notificationInjections.InnerValues;
}
}
public PluginBridge(PluginManager manager){ public PluginBridge(PluginManager manager){
this.manager = manager; this.manager = manager;
@ -63,10 +59,8 @@ private string GetFullPathOrThrow(int token, PluginFolder folder, string path){
private string ReadFileUnsafe(int token, string cacheKey, string fullPath, bool readCached){ private string ReadFileUnsafe(int token, string cacheKey, string fullPath, bool readCached){
cacheKey = SanitizeCacheKey(cacheKey); cacheKey = SanitizeCacheKey(cacheKey);
string cachedContents;
if (readCached && fileCache.TryGetValue(token, cacheKey, out cachedContents)){ if (readCached && fileCache.TryGetValue(token, cacheKey, out string cachedContents)){
return cachedContents; return cachedContents;
} }

View File

@ -8,25 +8,14 @@ sealed class PluginConfig{
[field:NonSerialized] [field:NonSerialized]
public event EventHandler<PluginChangedStateEventArgs> InternalPluginChangedState; // should only be accessed from PluginManager public event EventHandler<PluginChangedStateEventArgs> InternalPluginChangedState; // should only be accessed from PluginManager
public IEnumerable<string> DisabledPlugins{ public IEnumerable<string> DisabledPlugins => Disabled;
get{ public bool AnyDisabled => Disabled.Count > 0;
return Disabled;
}
}
public bool AnyDisabled{
get{
return Disabled.Count > 0;
}
}
private readonly HashSet<string> Disabled = new HashSet<string>(); private readonly HashSet<string> Disabled = new HashSet<string>();
public void SetEnabled(Plugin plugin, bool enabled){ public void SetEnabled(Plugin plugin, bool enabled){
if ((enabled && Disabled.Remove(plugin.Identifier)) || (!enabled && Disabled.Add(plugin.Identifier))){ if ((enabled && Disabled.Remove(plugin.Identifier)) || (!enabled && Disabled.Add(plugin.Identifier))){
if (InternalPluginChangedState != null){ InternalPluginChangedState?.Invoke(this, new PluginChangedStateEventArgs(plugin, enabled));
InternalPluginChangedState(this, new PluginChangedStateEventArgs(plugin, enabled));
}
} }
} }

View File

@ -15,12 +15,12 @@ sealed class PluginManager{
private const int InvalidToken = 0; private const int InvalidToken = 0;
public string PathOfficialPlugins { get { return Path.Combine(rootPath, "official"); } } public string PathOfficialPlugins => Path.Combine(rootPath, "official");
public string PathCustomPlugins { get { return Path.Combine(rootPath, "user"); } } public string PathCustomPlugins => Path.Combine(rootPath, "user");
public IEnumerable<Plugin> Plugins { get { return plugins; } } public IEnumerable<Plugin> Plugins => plugins;
public PluginConfig Config { get; private set; } public PluginConfig Config { get; private set; }
public PluginBridge Bridge { get; private set; } public PluginBridge Bridge { get; }
public event EventHandler<PluginErrorEventArgs> Reloaded; public event EventHandler<PluginErrorEventArgs> Reloaded;
public event EventHandler<PluginErrorEventArgs> Executed; public event EventHandler<PluginErrorEventArgs> Executed;
@ -47,9 +47,7 @@ private void Program_UserConfigReplaced(object sender, EventArgs e){
} }
private void Config_InternalPluginChangedState(object sender, PluginChangedStateEventArgs e){ private void Config_InternalPluginChangedState(object sender, PluginChangedStateEventArgs e){
if (PluginChangedState != null){ PluginChangedState?.Invoke(this, e);
PluginChangedState(this, e);
}
} }
private void SetConfig(PluginConfig config){ private void SetConfig(PluginConfig config){
@ -88,8 +86,7 @@ public int GetTokenFromPlugin(Plugin plugin){
} }
public Plugin GetPluginFromToken(int token){ public Plugin GetPluginFromToken(int token){
Plugin plugin; return tokens.TryGetValue(token, out Plugin plugin) ? plugin : null;
return tokens.TryGetValue(token, out plugin) ? plugin : null;
} }
public void Reload(){ public void Reload(){
@ -106,9 +103,7 @@ public void Reload(){
plugins.Add(plugin); plugins.Add(plugin);
} }
if (Reloaded != null){ Reloaded?.Invoke(this, new PluginErrorEventArgs(loadErrors));
Reloaded(this, new PluginErrorEventArgs(loadErrors));
}
} }
public void ExecutePlugins(IFrame frame, PluginEnvironment environment, bool includeDisabled){ public void ExecutePlugins(IFrame frame, PluginEnvironment environment, bool includeDisabled){
@ -144,9 +139,7 @@ public void ExecutePlugins(IFrame frame, PluginEnvironment environment, bool inc
ScriptLoader.ExecuteScript(frame, PluginScriptGenerator.GeneratePlugin(plugin.Identifier, script, token, environment), "plugin:"+plugin); ScriptLoader.ExecuteScript(frame, PluginScriptGenerator.GeneratePlugin(plugin.Identifier, script, token, environment), "plugin:"+plugin);
} }
if (Executed != null){ Executed?.Invoke(this, new PluginErrorEventArgs(failedPlugins));
Executed(this, new PluginErrorEventArgs(failedPlugins));
}
} }
private IEnumerable<Plugin> LoadPluginsFrom(string path, PluginGroup group){ private IEnumerable<Plugin> LoadPluginsFrom(string path, PluginGroup group){
@ -155,8 +148,7 @@ private IEnumerable<Plugin> LoadPluginsFrom(string path, PluginGroup group){
} }
foreach(string fullDir in Directory.EnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly)){ foreach(string fullDir in Directory.EnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly)){
string error; Plugin plugin = Plugin.CreateFromFolder(fullDir, group, out string error);
Plugin plugin = Plugin.CreateFromFolder(fullDir, group, out error);
if (plugin == null){ if (plugin == null){
loadErrors.Add(group.GetIdentifierPrefix()+Path.GetFileName(fullDir)+": "+error); loadErrors.Add(group.GetIdentifierPrefix()+Path.GetFileName(fullDir)+": "+error);

View File

@ -213,10 +213,7 @@ private static string GetDataStoragePath(){
public static void ReloadConfig(){ public static void ReloadConfig(){
UserConfig = UserConfig.Load(ConfigFilePath); UserConfig = UserConfig.Load(ConfigFilePath);
UserConfigReplaced?.Invoke(UserConfig, new EventArgs());
if (UserConfigReplaced != null){
UserConfigReplaced(UserConfig, new EventArgs());
}
} }
public static void ResetConfig(){ public static void ResetConfig(){

View File

@ -42,6 +42,7 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>false</UseVSHostingProcess> <UseVSHostingProcess>false</UseVSHostingProcess>
<LangVersion>7</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<ApplicationIcon>Resources\icon.ico</ApplicationIcon> <ApplicationIcon>Resources\icon.ico</ApplicationIcon>

View File

@ -2,9 +2,9 @@
namespace TweetDck.Updates.Events{ namespace TweetDck.Updates.Events{
class UpdateCheckEventArgs : EventArgs{ class UpdateCheckEventArgs : EventArgs{
public int EventId { get; private set; } public int EventId { get; }
public bool UpdateAvailable { get; private set; } public bool UpdateAvailable { get; }
public string LatestVersion { get; private set; } public string LatestVersion { get; }
public UpdateCheckEventArgs(int eventId, bool updateAvailable, string latestVersion){ public UpdateCheckEventArgs(int eventId, bool updateAvailable, string latestVersion){
EventId = eventId; EventId = eventId;

View File

@ -10,11 +10,7 @@ namespace TweetDck.Updates{
sealed partial class FormUpdateDownload : Form{ sealed partial class FormUpdateDownload : Form{
private const double BytesToKB = 1024.0; private const double BytesToKB = 1024.0;
public string InstallerPath{ public string InstallerPath => Path.Combine(Path.GetTempPath(), updateInfo.FileName);
get{
return Path.Combine(Path.GetTempPath(), updateInfo.FileName);
}
}
public enum Status{ public enum Status{
Waiting, Failed, Cancelled, Manual, Succeeded Waiting, Failed, Cancelled, Manual, Succeeded

View File

@ -9,11 +9,7 @@
namespace TweetDck.Updates{ namespace TweetDck.Updates{
sealed class UpdateHandler{ sealed class UpdateHandler{
private static bool IsSystemSupported{ private static bool IsSystemSupported => true; // Environment.OSVersion.Version >= new Version("6.1"); // 6.1 NT version = Windows 7
get{
return true; // Environment.OSVersion.Version >= new Version("6.1"); // 6.1 NT version = Windows 7
}
}
private readonly ChromiumWebBrowser browser; private readonly ChromiumWebBrowser browser;
private readonly FormBrowser form; private readonly FormBrowser form;
@ -61,10 +57,7 @@ public int Check(bool force){
public void DismissUpdate(string tag){ public void DismissUpdate(string tag){
settings.DismissedUpdate = tag; settings.DismissedUpdate = tag;
UpdateDismissed?.Invoke(this, new UpdateDismissedEventArgs(tag));
if (UpdateDismissed != null){
UpdateDismissed(this, new UpdateDismissedEventArgs(tag));
}
} }
private void TriggerUpdateAcceptedEvent(UpdateAcceptedEventArgs args){ private void TriggerUpdateAcceptedEvent(UpdateAcceptedEventArgs args){
@ -76,10 +69,7 @@ private void TriggerUpdateAcceptedEvent(UpdateAcceptedEventArgs args){
private void TriggerUpdateDismissedEvent(UpdateDismissedEventArgs args){ private void TriggerUpdateDismissedEvent(UpdateDismissedEventArgs args){
form.InvokeAsyncSafe(() => { form.InvokeAsyncSafe(() => {
settings.DismissedUpdate = args.VersionTag; settings.DismissedUpdate = args.VersionTag;
UpdateDismissed?.Invoke(this, args);
if (UpdateDismissed != null){
UpdateDismissed(this, args);
}
}); });
} }

View File

@ -5,11 +5,7 @@ class UpdateInfo{
public readonly string VersionTag; public readonly string VersionTag;
public readonly string DownloadUrl; public readonly string DownloadUrl;
public string FileName{ public string FileName => BrowserUtils.GetFileNameFromUrl(DownloadUrl) ?? Program.BrandName+".Update.exe";
get{
return BrowserUtils.GetFileNameFromUrl(DownloadUrl) ?? Program.BrandName+".Update.exe";
}
}
public UpdateInfo(string versionTag, string downloadUrl){ public UpdateInfo(string versionTag, string downloadUrl){
this.VersionTag = versionTag; this.VersionTag = versionTag;

View File

@ -7,11 +7,7 @@
namespace UnitTests.Core.Utils{ namespace UnitTests.Core.Utils{
[TestClass] [TestClass]
public class TestInjectedHTML{ public class TestInjectedHTML{
private static IEnumerable<InjectedHTML.Position> Positions{ private static IEnumerable<InjectedHTML.Position> Positions => Enum.GetValues(typeof(InjectedHTML.Position)).Cast<InjectedHTML.Position>();
get{
return Enum.GetValues(typeof(InjectedHTML.Position)).Cast<InjectedHTML.Position>();
}
}
[TestMethod] [TestMethod]
public void TestFailedMatches(){ public void TestFailedMatches(){