mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-09-14 01:32:10 +02:00
Compare commits
277 Commits
Author | SHA1 | Date | |
---|---|---|---|
746eba185b | |||
82dec92510 | |||
2edc93df47 | |||
c5a6738199 | |||
dfd578165b | |||
285d400f69 | |||
47a3444ace | |||
0ec227da52 | |||
f9cf582306 | |||
b0883229bf | |||
31b5d9a4c0 | |||
6841a78556 | |||
9d2089a8ce | |||
6d6bb79199 | |||
937c8e22c4 | |||
34c8d44dfe | |||
2dbf778e56 | |||
873fe2b393 | |||
0c53bc6f32 | |||
fa407e150b | |||
4e52102c5c | |||
0355a5c646 | |||
377d9c3554 | |||
20b1b3c895 | |||
41bbe7c51b | |||
27fa6aefd3 | |||
a63c3232da | |||
146908a115 | |||
48b0f35fee | |||
6c435ebe26 | |||
b8d0b721a2 | |||
a6d5957f46 | |||
9e5f676e23 | |||
414f3a1f9d | |||
fedf9c60ee | |||
b6385d9622 | |||
76d25a712d | |||
2c6d935273 | |||
830d98a101 | |||
d7378bd75a | |||
0f41cb9dbc | |||
77bc922d93 | |||
c91b635132 | |||
e5521de34a | |||
7c0f8d0f24 | |||
f60d5f650f | |||
ca67f2fe0a | |||
16cce8be1d | |||
770619d948 | |||
cfedb7d6b1 | |||
738557b3a2 | |||
38b01deec1 | |||
1a31e69ec9 | |||
e065983c95 | |||
30a169171a | |||
8d1900362e | |||
e154189de1 | |||
b0f147de24 | |||
979b3548db | |||
05d6c578b3 | |||
a117559063 | |||
f87c649b09 | |||
6504dc9184 | |||
25a8ddffd4 | |||
fa0f9b89cf | |||
4d00a67891 | |||
bd2c43e1f4 | |||
c7279eaa34 | |||
fd523e552c | |||
cb877b8b23 | |||
ed1bee8b89 | |||
a8e1492056 | |||
5587216c01 | |||
86569261ad | |||
4a9049c7aa | |||
75d60a8182 | |||
14d4dc2ed9 | |||
fd0e1740a5 | |||
70ca890bef | |||
b9318dfd8e | |||
995642a719 | |||
d14de4ac9e | |||
b7f325a241 | |||
27c55718c2 | |||
421ff0654b | |||
ed947458f9 | |||
9cdb20ba84 | |||
d8774b735f | |||
adcb42695f | |||
dd77b5bcbb | |||
d2445be155 | |||
10254c8af7 | |||
d7e830badf | |||
b445a3a9b8 | |||
97f42ead66 | |||
03730fafb9 | |||
0be9465dca | |||
d7f1df4995 | |||
3cb0f90706 | |||
a3e9b15a8a | |||
00bfa68a57 | |||
c311e24f08 | |||
1cdd4e4455 | |||
8078c0081a | |||
a867e1fc40 | |||
61da36ac1c | |||
720ca2a018 | |||
b39c593552 | |||
c808952a45 | |||
b468d7a766 | |||
28578f60be | |||
92a39e2527 | |||
1bce5e4342 | |||
68f586e104 | |||
d27a66202e | |||
07de2f450c | |||
3c03726634 | |||
6fb2643063 | |||
5eef6c8196 | |||
829c332e13 | |||
47eec14bca | |||
e7ee1d6be7 | |||
e41b5e5ff7 | |||
ba1bacd08c | |||
1029ea5840 | |||
339eaf0195 | |||
aa1e1549d8 | |||
1f8ae9ef80 | |||
65165de060 | |||
485836d2ce | |||
64c07c14d9 | |||
b6313c2b72 | |||
58124b5821 | |||
b6a599f8a6 | |||
19a6bc0dbd | |||
8cb81d44ee | |||
22d0a372d8 | |||
988fae75c3 | |||
a82b0e3622 | |||
bc6cacacf9 | |||
03ad1b3cbc | |||
eac300627f | |||
12525ac386 | |||
7558551859 | |||
a9cce13eef | |||
5bb2c43dd0 | |||
5b1dcc88cc | |||
5c8fc1d136 | |||
82c2ab3448 | |||
b05c8d180f | |||
87109e5d01 | |||
be1a809098 | |||
ba0e3f1bd4 | |||
27d41e6164 | |||
1ce5ddfd98 | |||
0096a1a4ef | |||
d2a6560a90 | |||
4d7c048139 | |||
1d78bd2655 | |||
9250f1907c | |||
a63e210b88 | |||
06bd65b7f8 | |||
b6c17eb05e | |||
a3d40fdc2b | |||
c064ef7a30 | |||
762717da1e | |||
b7d3758bea | |||
d20541fd24 | |||
2c2f860f26 | |||
d1db3aa673 | |||
cedc52cdf5 | |||
33f8eafbcf | |||
ad45cf8c72 | |||
f99d035621 | |||
f3072caea8 | |||
1410974292 | |||
44413fa96c | |||
342a4b4067 | |||
4356dde92d | |||
21e64a18d8 | |||
5a305a6740 | |||
44595bad40 | |||
7fc9edc9cb | |||
93e191f522 | |||
8d8355e792 | |||
a5379d290c | |||
caea8d4315 | |||
24224ab4c6 | |||
4dbc02360c | |||
aa7a29af0c | |||
296d0c6199 | |||
812a034e8d | |||
e9de789b79 | |||
cfbc1b9575 | |||
e39e85e4dd | |||
3f0b161cd0 | |||
ebe3868720 | |||
ffd0f5e986 | |||
217535a3ba | |||
7abfbea2da | |||
86ffeaac9a | |||
ab915b7115 | |||
705b5d38cf | |||
fc2acb00b3 | |||
5add8a1d0e | |||
063d3a2637 | |||
f1f90a2ee3 | |||
ed317a4e46 | |||
cca16f3bb1 | |||
aba156cb3b | |||
cd4e4d7095 | |||
8fbb639430 | |||
d5bf8ec558 | |||
b6cff40f1e | |||
833e42f455 | |||
8134843dad | |||
1f92d5e633 | |||
dc51c0ae85 | |||
45c79643d6 | |||
9041bfc627 | |||
0b3b3dd0be | |||
89e92dab59 | |||
8c168c9ad7 | |||
9f63357a92 | |||
d91b4bd1f3 | |||
c0c64f6d62 | |||
1a5d2af779 | |||
f40a33192b | |||
ca4900aff0 | |||
56fc9e2d40 | |||
d2174c0b69 | |||
9f76754ad3 | |||
118ceaec35 | |||
5a57d28a7d | |||
07af99f862 | |||
59fba7fba0 | |||
dd4edc4249 | |||
856226473a | |||
8d1c07d6b2 | |||
c32462cc9e | |||
ec94ea3273 | |||
41acd8c15b | |||
155a79f2ec | |||
9197cb9be6 | |||
03d50c847b | |||
bf45c40365 | |||
679e126194 | |||
50e39164bd | |||
cb9f75e968 | |||
aa7f6cc3b1 | |||
fe601aed41 | |||
2282a9df28 | |||
2b54627750 | |||
16051a0d25 | |||
66d5f0d790 | |||
07d29207f0 | |||
a60be2afcc | |||
027f3ee253 | |||
04774815e4 | |||
61a73c055b | |||
7731534ffc | |||
ed7bf99610 | |||
cbe4272556 | |||
8f5e3dfdcc | |||
35500c51f1 | |||
629f873bb2 | |||
a44cb884c4 | |||
d5ad1d0daa | |||
61ae7e3b6a | |||
01583e424f | |||
5c0aa1b3da | |||
07391efa70 | |||
b80f1bfc7c | |||
ad310db86c | |||
4ce0122a29 | |||
a8894f7054 | |||
1d1515351b |
@@ -6,7 +6,8 @@ namespace TweetDuck.Configuration{
|
||||
// public args
|
||||
public const string ArgDataFolder = "-datafolder";
|
||||
public const string ArgLogging = "-log";
|
||||
public const string ArgDebugUpdates = "-debugupdates";
|
||||
public const string ArgIgnoreGDPR = "-nogdpr";
|
||||
public const string ArgNotificationScrollWA = "-nscrollwa";
|
||||
|
||||
// internal args
|
||||
public const string ArgRestart = "-restart";
|
||||
|
@@ -1,28 +1,17 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using TweetDuck.Data.Serialization;
|
||||
|
||||
namespace TweetDuck.Configuration{
|
||||
sealed class SystemConfig{
|
||||
private static readonly FileSerializer<SystemConfig> Serializer = new FileSerializer<SystemConfig>();
|
||||
|
||||
public static readonly bool IsHardwareAccelerationSupported = File.Exists(Path.Combine(Program.ProgramPath, "libEGL.dll")) &&
|
||||
File.Exists(Path.Combine(Program.ProgramPath, "libGLESv2.dll"));
|
||||
|
||||
// CONFIGURATION DATA
|
||||
|
||||
private bool _hardwareAcceleration = true;
|
||||
|
||||
|
||||
public bool HardwareAcceleration { get; set; } = true;
|
||||
|
||||
public bool ClearCacheAutomatically { get; set; } = true;
|
||||
public int ClearCacheThreshold { get; set; } = 250;
|
||||
|
||||
// SPECIAL PROPERTIES
|
||||
|
||||
public bool HardwareAcceleration{
|
||||
get => _hardwareAcceleration && IsHardwareAccelerationSupported;
|
||||
set => _hardwareAcceleration = value;
|
||||
}
|
||||
|
||||
// END OF CONFIG
|
||||
|
||||
private readonly string file;
|
||||
|
@@ -35,15 +35,13 @@ namespace TweetDuck.Configuration{
|
||||
|
||||
// CONFIGURATION DATA
|
||||
|
||||
public bool FirstRun { get; set; } = true;
|
||||
public bool AllowDataCollection { get; set; } = false;
|
||||
public bool ShowFollowNotification { get; set; } = true;
|
||||
public bool FirstRun { get; set; } = true;
|
||||
public bool AllowDataCollection { get; set; } = false;
|
||||
|
||||
public WindowState BrowserWindow { get; set; } = new WindowState();
|
||||
public WindowState PluginsWindow { get; set; } = new WindowState();
|
||||
public Size PluginsWindowSize { get; set; } = Size.Empty;
|
||||
|
||||
public bool ExpandLinksOnHover { get; set; } = true;
|
||||
public bool SwitchAccountSelectors { get; set; } = true;
|
||||
public bool OpenSearchInFirstColumn { get; set; } = true;
|
||||
public bool KeepLikeFollowDialogsOpen { get; set; } = true;
|
||||
public bool BestImageQuality { get; set; } = true;
|
||||
@@ -52,6 +50,7 @@ namespace TweetDuck.Configuration{
|
||||
public bool IgnoreTrackingUrlWarning { get; set; } = false;
|
||||
public bool EnableSmoothScrolling { get; set; } = true;
|
||||
public string BrowserPath { get; set; } = null;
|
||||
public string SearchEngineUrl { get; set; } = null;
|
||||
private int _zoomLevel = 100;
|
||||
private bool _muteNotifications;
|
||||
|
||||
|
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
|
||||
namespace TweetDuck.Core.Bridge{
|
||||
sealed class CallbackBridge{
|
||||
private readonly Control owner;
|
||||
private readonly Action safeCallback;
|
||||
|
||||
public CallbackBridge(Control owner, Action safeCallback){
|
||||
this.owner = owner;
|
||||
this.safeCallback = safeCallback;
|
||||
}
|
||||
|
||||
public void Trigger(){
|
||||
owner.InvokeSafe(safeCallback);
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,7 +15,6 @@ namespace TweetDuck.Core.Bridge{
|
||||
build.Append("x.expandLinksOnHover=").Append(Bool(Program.UserConfig.ExpandLinksOnHover));
|
||||
|
||||
if (environment == Environment.Browser){
|
||||
build.Append("x.switchAccountSelectors=").Append(Bool(Program.UserConfig.SwitchAccountSelectors));
|
||||
build.Append("x.openSearchInFirstColumn=").Append(Bool(Program.UserConfig.OpenSearchInFirstColumn));
|
||||
build.Append("x.keepLikeFollowDialogsOpen=").Append(Bool(Program.UserConfig.KeepLikeFollowDialogsOpen));
|
||||
build.Append("x.muteNotifications=").Append(Bool(Program.UserConfig.MuteNotifications));
|
||||
|
@@ -3,7 +3,7 @@ using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Utils;
|
||||
@@ -13,20 +13,12 @@ namespace TweetDuck.Core.Bridge{
|
||||
class TweetDeckBridge{
|
||||
public static string FontSize { get; private set; }
|
||||
public static string NotificationHeadLayout { get; private set; }
|
||||
|
||||
public static string LastHighlightedTweetUrl = string.Empty;
|
||||
public static string LastHighlightedQuoteUrl = string.Empty;
|
||||
private static string LastHighlightedTweetAuthors = string.Empty;
|
||||
private static string LastHighlightedTweetImages = string.Empty;
|
||||
|
||||
public static string[] LastHighlightedTweetAuthorsArray => LastHighlightedTweetAuthors.Split(';');
|
||||
public static string[] LastHighlightedTweetImagesArray => LastHighlightedTweetImages.Split(';');
|
||||
public static readonly ContextInfo ContextInfo = new ContextInfo();
|
||||
|
||||
private static readonly Dictionary<string, string> SessionData = new Dictionary<string, string>(2);
|
||||
|
||||
public static void ResetStaticProperties(){
|
||||
FontSize = NotificationHeadLayout = null;
|
||||
LastHighlightedTweetUrl = LastHighlightedQuoteUrl = LastHighlightedTweetAuthors = LastHighlightedTweetImages = string.Empty;
|
||||
}
|
||||
|
||||
public static void RestoreSessionData(IFrame frame){
|
||||
@@ -58,6 +50,10 @@ namespace TweetDuck.Core.Bridge{
|
||||
public void OpenContextMenu(){
|
||||
form.InvokeAsyncSafe(form.OpenContextMenu);
|
||||
}
|
||||
|
||||
public void OpenProfileImport(){
|
||||
form.InvokeAsyncSafe(form.OpenProfileImport);
|
||||
}
|
||||
|
||||
public void OnIntroductionClosed(bool showGuide, bool allowDataCollection){
|
||||
form.InvokeAsyncSafe(() => {
|
||||
@@ -72,13 +68,12 @@ namespace TweetDuck.Core.Bridge{
|
||||
});
|
||||
}
|
||||
|
||||
public void SetLastHighlightedTweet(string tweetUrl, string quoteUrl, string authors, string imageList){
|
||||
form.InvokeAsyncSafe(() => {
|
||||
LastHighlightedTweetUrl = tweetUrl;
|
||||
LastHighlightedQuoteUrl = quoteUrl;
|
||||
LastHighlightedTweetAuthors = authors;
|
||||
LastHighlightedTweetImages = imageList;
|
||||
});
|
||||
public void SetRightClickedLink(string type, string url){
|
||||
ContextInfo.SetLink(type, url);
|
||||
}
|
||||
|
||||
public void SetRightClickedChirp(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
|
||||
ContextInfo.SetChirp(tweetUrl, quoteUrl, chirpAuthors, chirpImages);
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text){
|
||||
@@ -112,10 +107,6 @@ namespace TweetDuck.Core.Bridge{
|
||||
|
||||
// Global
|
||||
|
||||
public void SetLastRightClickInfo(string type, string link){
|
||||
form.InvokeAsyncSafe(() => ContextMenuBase.SetContextInfo(type, link));
|
||||
}
|
||||
|
||||
public void OnTweetPopup(string columnId, string chirpId, string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){
|
||||
notification.InvokeAsyncSafe(() => {
|
||||
form.OnTweetNotification();
|
||||
@@ -130,8 +121,8 @@ namespace TweetDuck.Core.Bridge{
|
||||
});
|
||||
}
|
||||
|
||||
public void ScreenshotTweet(string html, int width, int height){
|
||||
form.InvokeAsyncSafe(() => form.OnTweetScreenshotReady(html, width, height));
|
||||
public void ScreenshotTweet(string html, int width){
|
||||
form.InvokeAsyncSafe(() => form.OnTweetScreenshotReady(html, width));
|
||||
}
|
||||
|
||||
public void PlayVideo(string url, string username){
|
||||
|
@@ -7,7 +7,7 @@ namespace TweetDuck.Core.Controls{
|
||||
public int LineHeight { get; set; }
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e){
|
||||
int y = (int)Math.Floor((ClientRectangle.Height-Text.Length*LineHeight)/2F)-2; // 2 = random
|
||||
int y = (int)Math.Floor((ClientRectangle.Height-Text.Length*LineHeight)/2F)-1;
|
||||
|
||||
using(Brush brush = new SolidBrush(ForeColor)){
|
||||
foreach(char chr in Text){
|
||||
|
6
Core/FormBrowser.Designer.cs
generated
6
Core/FormBrowser.Designer.cs
generated
@@ -39,17 +39,17 @@
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = TweetDuck.Core.Utils.TwitterUtils.BackgroundColor;
|
||||
this.ClientSize = new System.Drawing.Size(400, 386);
|
||||
this.ClientSize = new System.Drawing.Size(1008, 730);
|
||||
this.Icon = Properties.Resources.icon;
|
||||
this.Location = TweetDuck.Core.Controls.ControlExtensions.InvisibleLocation;
|
||||
this.MinimumSize = new System.Drawing.Size(416, 424);
|
||||
this.MinimumSize = new System.Drawing.Size(348, 424);
|
||||
this.Name = "FormBrowser";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Activated += new System.EventHandler(this.FormBrowser_Activated);
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormBrowser_FormClosing);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormBrowser_FormClosed);
|
||||
this.LocationChanged += new System.EventHandler(this.FormBrowser_LocationChanged);
|
||||
this.ResizeEnd += new System.EventHandler(this.FormBrowser_ResizeEnd);
|
||||
this.LocationChanged += new System.EventHandler(this.FormBrowser_LocationChanged);
|
||||
this.Resize += new System.EventHandler(this.FormBrowser_Resize);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
|
@@ -5,18 +5,22 @@ using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Handling.General;
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Notification.Screenshot;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Core.Other.Settings.Dialogs;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
using TweetDuck.Plugins.Events;
|
||||
using TweetDuck.Updates;
|
||||
using TweetDuck.Updates.Events;
|
||||
|
||||
namespace TweetDuck.Core{
|
||||
sealed partial class FormBrowser : Form{
|
||||
sealed partial class FormBrowser : Form, AnalyticsFile.IProvider{
|
||||
private static UserConfig Config => Program.UserConfig;
|
||||
|
||||
public bool IsWaiting{
|
||||
@@ -37,6 +41,9 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
public string UpdateInstallerPath { get; private set; }
|
||||
private bool ignoreUpdateCheckError;
|
||||
|
||||
public AnalyticsFile AnalyticsFile => analytics?.File ?? AnalyticsFile.Dummy;
|
||||
|
||||
private readonly TweetDeckBrowser browser;
|
||||
private readonly PluginManager plugins;
|
||||
@@ -51,7 +58,7 @@ namespace TweetDuck.Core{
|
||||
private VideoPlayer videoPlayer;
|
||||
private AnalyticsManager analytics;
|
||||
|
||||
public FormBrowser(UpdaterSettings updaterSettings){
|
||||
public FormBrowser(){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName;
|
||||
@@ -64,16 +71,19 @@ namespace TweetDuck.Core{
|
||||
this.notification = new FormNotificationTweet(this, plugins);
|
||||
this.notification.Show();
|
||||
|
||||
this.browser = new TweetDeckBrowser(this, plugins, new TweetDeckBridge.Browser(this, notification));
|
||||
this.browser = new TweetDeckBrowser(this, new TweetDeckBridge.Browser(this, notification));
|
||||
this.contextMenu = ContextMenuBrowser.CreateMenu(this);
|
||||
|
||||
this.plugins.Register(browser, PluginEnvironment.Browser, this, true);
|
||||
|
||||
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
|
||||
|
||||
Disposed += (sender, args) => {
|
||||
Config.MuteToggled -= Config_MuteToggled;
|
||||
Config.TrayBehaviorChanged -= Config_TrayBehaviorChanged;
|
||||
|
||||
|
||||
browser.Dispose();
|
||||
updates.Dispose();
|
||||
contextMenu.Dispose();
|
||||
|
||||
notificationScreenshotManager?.Dispose();
|
||||
@@ -87,9 +97,14 @@ namespace TweetDuck.Core{
|
||||
this.trayIcon.ClickClose += trayIcon_ClickClose;
|
||||
Config.TrayBehaviorChanged += Config_TrayBehaviorChanged;
|
||||
|
||||
UpdateTrayIcon();
|
||||
UpdateTray();
|
||||
|
||||
this.updates = browser.CreateUpdateHandler(updaterSettings);
|
||||
if (Config.MuteNotifications){
|
||||
UpdateFormIcon();
|
||||
}
|
||||
|
||||
this.updates = new UpdateHandler(browser, Program.InstallerPath);
|
||||
this.updates.CheckFinished += updates_CheckFinished;
|
||||
this.updates.UpdateAccepted += updates_UpdateAccepted;
|
||||
this.updates.UpdateDismissed += updates_UpdateDismissed;
|
||||
|
||||
@@ -118,7 +133,11 @@ namespace TweetDuck.Core{
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
private void UpdateTrayIcon(){
|
||||
private void UpdateFormIcon(){ // TODO fix to show icon in taskbar too
|
||||
Icon = Config.MuteNotifications ? Properties.Resources.icon_muted : Properties.Resources.icon;
|
||||
}
|
||||
|
||||
private void UpdateTray(){
|
||||
trayIcon.Visible = Config.TrayBehavior.ShouldDisplayIcon();
|
||||
}
|
||||
|
||||
@@ -193,18 +212,19 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
private void Config_MuteToggled(object sender, EventArgs e){
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.MuteNotification);
|
||||
UpdateFormIcon();
|
||||
AnalyticsFile.NotificationMutes.Trigger();
|
||||
}
|
||||
|
||||
private void Config_TrayBehaviorChanged(object sender, EventArgs e){
|
||||
UpdateTrayIcon();
|
||||
UpdateTray();
|
||||
}
|
||||
|
||||
private void trayIcon_ClickRestore(object sender, EventArgs e){
|
||||
Show();
|
||||
RestoreWindow();
|
||||
Activate();
|
||||
UpdateTrayIcon();
|
||||
UpdateTray();
|
||||
}
|
||||
|
||||
private void trayIcon_ClickClose(object sender, EventArgs e){
|
||||
@@ -217,7 +237,7 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
if (isLoaded){
|
||||
ReloadToTweetDeck();
|
||||
browser.ReloadToTweetDeck();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,6 +247,27 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
}
|
||||
|
||||
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
|
||||
e.Result.Handle(update => {
|
||||
string tag = update.VersionTag;
|
||||
|
||||
if (tag != Program.VersionTag && tag != Config.DismissedUpdate){
|
||||
updates.PrepareUpdate(update);
|
||||
browser.ShowUpdateNotification(tag, update.ReleaseNotes);
|
||||
}
|
||||
else{
|
||||
updates.StartTimer();
|
||||
}
|
||||
}, ex => {
|
||||
if (!ignoreUpdateCheckError){
|
||||
Program.Reporter.HandleException("Update Check Error", "An error occurred while checking for updates.", true, ex);
|
||||
updates.StartTimer();
|
||||
}
|
||||
});
|
||||
|
||||
ignoreUpdateCheckError = true;
|
||||
}
|
||||
|
||||
private void updates_UpdateAccepted(object sender, UpdateEventArgs e){
|
||||
this.InvokeAsyncSafe(() => {
|
||||
FormManager.CloseAllDialogs();
|
||||
@@ -235,13 +276,21 @@ namespace TweetDuck.Core{
|
||||
Config.DismissedUpdate = null;
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
updates.BeginUpdateDownload(this, e.UpdateInfo, update => {
|
||||
if (update.DownloadStatus == UpdateDownloadStatus.Done){
|
||||
UpdateInstallerPath = update.InstallerPath;
|
||||
}
|
||||
|
||||
ForceClose();
|
||||
updates.BeginUpdateDownload(this, e.UpdateInfo, update => {
|
||||
UpdateDownloadStatus status = update.DownloadStatus;
|
||||
|
||||
if (status == UpdateDownloadStatus.Done){
|
||||
UpdateInstallerPath = update.InstallerPath;
|
||||
ForceClose();
|
||||
}
|
||||
else if (status != UpdateDownloadStatus.Canceled && FormMessage.Error("Update Has Failed", "Could not automatically download the update: "+(update.DownloadError?.Message ?? "unknown error")+"\n\nWould you like to open the website and try downloading the update manually?", FormMessage.Yes, FormMessage.No)){
|
||||
BrowserUtils.OpenExternalBrowser(Program.Website);
|
||||
ForceClose();
|
||||
}
|
||||
else{
|
||||
Show();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -268,7 +317,7 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
else{
|
||||
browser.OnMouseClickExtra(m.WParam);
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.BrowserExtraMouseButton);
|
||||
AnalyticsFile.BrowserExtraMouseButtons.Trigger();
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -292,7 +341,17 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
public void ReloadToTweetDeck(){
|
||||
#if DEBUG
|
||||
Resources.ScriptLoader.HotSwap();
|
||||
#endif
|
||||
|
||||
ignoreUpdateCheckError = false;
|
||||
browser.ReloadToTweetDeck();
|
||||
AnalyticsFile.BrowserReloads.Trigger();
|
||||
}
|
||||
|
||||
public void AddSearchColumn(string query){
|
||||
browser.AddSearchColumn(query);
|
||||
}
|
||||
|
||||
public void TriggerTweetScreenshot(){
|
||||
@@ -309,10 +368,11 @@ namespace TweetDuck.Core{
|
||||
|
||||
public void ApplyROT13(){
|
||||
browser.ApplyROT13();
|
||||
AnalyticsFile.UsedROT13.Trigger();
|
||||
}
|
||||
|
||||
public void TriggerAnalyticsEvent(AnalyticsFile.Event e){
|
||||
analytics?.TriggerEvent(e);
|
||||
public void OpenDevTools(){
|
||||
browser.OpenDevTools();
|
||||
}
|
||||
|
||||
// callback handlers
|
||||
@@ -320,7 +380,6 @@ namespace TweetDuck.Core{
|
||||
public void OnIntroductionClosed(bool showGuide, bool allowDataCollection){
|
||||
if (Config.FirstRun){
|
||||
Config.FirstRun = false;
|
||||
Config.ShowFollowNotification = false;
|
||||
Config.AllowDataCollection = allowDataCollection;
|
||||
Config.Save();
|
||||
|
||||
@@ -328,10 +387,6 @@ namespace TweetDuck.Core{
|
||||
analytics = new AnalyticsManager(this, plugins, Program.AnalyticsFilePath);
|
||||
}
|
||||
}
|
||||
else if (Config.ShowFollowNotification){
|
||||
Config.ShowFollowNotification = false;
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
if (showGuide){
|
||||
FormGuide.Show();
|
||||
@@ -345,13 +400,13 @@ namespace TweetDuck.Core{
|
||||
public void OpenSettings(){
|
||||
OpenSettings(null);
|
||||
}
|
||||
|
||||
|
||||
public void OpenSettings(Type startTab){
|
||||
if (!FormManager.TryBringToFront<FormSettings>()){
|
||||
bool prevEnableUpdateCheck = Config.EnableUpdateCheck;
|
||||
|
||||
FormSettings form = new FormSettings(this, plugins, updates, analytics, startTab);
|
||||
|
||||
|
||||
form.FormClosed += (sender, args) => {
|
||||
if (!prevEnableUpdateCheck && Config.EnableUpdateCheck){
|
||||
Config.DismissedUpdate = null;
|
||||
@@ -388,25 +443,37 @@ namespace TweetDuck.Core{
|
||||
form.Dispose();
|
||||
};
|
||||
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.OpenOptions);
|
||||
AnalyticsFile.OpenOptions.Trigger();
|
||||
ShowChildForm(form);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenAbout(){
|
||||
if (!FormManager.TryBringToFront<FormAbout>()){
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.OpenAbout);
|
||||
AnalyticsFile.OpenAbout.Trigger();
|
||||
ShowChildForm(new FormAbout());
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenPlugins(){
|
||||
if (!FormManager.TryBringToFront<FormPlugins>()){
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.OpenPlugins);
|
||||
AnalyticsFile.OpenPlugins.Trigger();
|
||||
ShowChildForm(new FormPlugins(plugins));
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenProfileImport(){
|
||||
FormManager.TryFind<FormSettings>()?.Close();
|
||||
|
||||
using(DialogSettingsManage dialog = new DialogSettingsManage(plugins, true)){
|
||||
if (dialog.ShowDialog() == DialogResult.OK && !dialog.IsRestarting){
|
||||
BrowserProcessHandler.UpdatePrefs();
|
||||
FormManager.TryFind<FormPlugins>()?.Close();
|
||||
plugins.Reload(); // also reloads the browser
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTweetNotification(){ // may be called multiple times, once for each type of notification
|
||||
if (Config.EnableTrayHighlight && !ContainsFocus){
|
||||
trayIcon.HasNotifications = true;
|
||||
@@ -414,7 +481,7 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
public void OnTweetSound(){
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.SoundNotification);
|
||||
AnalyticsFile.SoundNotifications.Trigger();
|
||||
}
|
||||
|
||||
public void PlayVideo(string url, string username){
|
||||
@@ -432,7 +499,7 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
videoPlayer.Launch(url, username);
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.VideoPlay);
|
||||
AnalyticsFile.VideoPlays.Trigger();
|
||||
}
|
||||
|
||||
public bool ProcessBrowserKey(Keys key){
|
||||
@@ -454,16 +521,16 @@ namespace TweetDuck.Core{
|
||||
|
||||
notification.FinishCurrentNotification();
|
||||
browser.ShowTweetDetail(columnId, chirpId, fallbackUrl);
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.TweetDetail);
|
||||
AnalyticsFile.TweetDetails.Trigger();
|
||||
}
|
||||
|
||||
public void OnTweetScreenshotReady(string html, int width, int height){
|
||||
public void OnTweetScreenshotReady(string html, int width){
|
||||
if (notificationScreenshotManager == null){
|
||||
notificationScreenshotManager = new TweetScreenshotManager(this, plugins);
|
||||
}
|
||||
|
||||
notificationScreenshotManager.Trigger(html, width, height);
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.TweetScreenshot);
|
||||
notificationScreenshotManager.Trigger(html, width);
|
||||
AnalyticsFile.TweetScreenshots.Trigger();
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text){
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Other;
|
||||
|
||||
namespace TweetDuck.Core{
|
||||
static class FormManager{
|
||||
@@ -18,12 +17,14 @@ namespace TweetDuck.Core{
|
||||
else return false;
|
||||
}
|
||||
|
||||
public static bool HasAnyDialogs => Application.OpenForms.OfType<IAppDialog>().Any();
|
||||
|
||||
public static void CloseAllDialogs(){
|
||||
foreach(Form form in Application.OpenForms.Cast<Form>().Reverse()){
|
||||
if (form is FormSettings || form is FormPlugins || form is FormAbout || form is FormGuide){
|
||||
form.Close();
|
||||
}
|
||||
foreach(IAppDialog dialog in Application.OpenForms.OfType<IAppDialog>().Reverse()){
|
||||
((Form)dialog).Close();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IAppDialog{}
|
||||
}
|
||||
}
|
||||
|
@@ -3,34 +3,20 @@ using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
abstract class ContextMenuBase : IContextMenuHandler{
|
||||
public static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak"));
|
||||
|
||||
private static TwitterUtils.ImageQuality ImageQuality => Program.UserConfig.TwitterImageQuality;
|
||||
|
||||
private static KeyValuePair<string, string> ContextInfo;
|
||||
private static bool IsLink => ContextInfo.Key == "link";
|
||||
private static bool IsImage => ContextInfo.Key == "image";
|
||||
private static bool IsVideo => ContextInfo.Key == "video";
|
||||
|
||||
public static void SetContextInfo(string type, string link){
|
||||
ContextInfo = new KeyValuePair<string, string>(string.IsNullOrEmpty(link) ? null : type, link);
|
||||
}
|
||||
|
||||
private static string GetMediaLink(IContextMenuParams parameters){
|
||||
return IsImage || IsVideo ? ContextInfo.Value : parameters.SourceUrl;
|
||||
}
|
||||
|
||||
private const CefMenuCommand MenuOpenLinkUrl = (CefMenuCommand)26500;
|
||||
private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501;
|
||||
private const CefMenuCommand MenuCopyUsername = (CefMenuCommand)26502;
|
||||
@@ -39,24 +25,43 @@ namespace TweetDuck.Core.Handling{
|
||||
private const CefMenuCommand MenuCopyMediaUrl = (CefMenuCommand)26505;
|
||||
private const CefMenuCommand MenuSaveMedia = (CefMenuCommand)26506;
|
||||
private const CefMenuCommand MenuSaveTweetImages = (CefMenuCommand)26507;
|
||||
private const CefMenuCommand MenuSearchInBrowser = (CefMenuCommand)26508;
|
||||
private const CefMenuCommand MenuReadApplyROT13 = (CefMenuCommand)26509;
|
||||
private const CefMenuCommand MenuOpenDevTools = (CefMenuCommand)26599;
|
||||
|
||||
private string[] lastHighlightedTweetAuthors;
|
||||
private string[] lastHighlightedTweetImageList;
|
||||
protected ContextInfo.LinkInfo LastLink { get; private set; }
|
||||
protected ContextInfo.ChirpInfo LastChirp { get; private set; }
|
||||
|
||||
private readonly AnalyticsFile.IProvider analytics;
|
||||
|
||||
protected ContextMenuBase(AnalyticsFile.IProvider analytics){
|
||||
this.analytics = analytics;
|
||||
}
|
||||
|
||||
private void ResetContextInfo(){
|
||||
LastLink = default(ContextInfo.LinkInfo);
|
||||
LastChirp = default(ContextInfo.ChirpInfo);
|
||||
TweetDeckBridge.ContextInfo.Reset();
|
||||
}
|
||||
|
||||
public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
|
||||
lastHighlightedTweetAuthors = StringUtils.EmptyArray;
|
||||
lastHighlightedTweetImageList = StringUtils.EmptyArray;
|
||||
ContextInfo = default(KeyValuePair<string, string>);
|
||||
ResetContextInfo();
|
||||
}
|
||||
else{
|
||||
lastHighlightedTweetAuthors = TweetDeckBridge.LastHighlightedTweetAuthorsArray;
|
||||
lastHighlightedTweetImageList = TweetDeckBridge.LastHighlightedTweetImagesArray;
|
||||
LastLink = TweetDeckBridge.ContextInfo.Link;
|
||||
LastChirp = TweetDeckBridge.ContextInfo.Chirp;
|
||||
}
|
||||
|
||||
bool hasTweetImage = IsImage;
|
||||
bool hasTweetVideo = IsVideo;
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Selection) && !parameters.TypeFlags.HasFlag(ContextMenuType.Editable)){
|
||||
model.AddItem(MenuSearchInBrowser, "Search in browser");
|
||||
model.AddSeparator();
|
||||
model.AddItem(MenuReadApplyROT13, "Apply ROT13");
|
||||
model.AddSeparator();
|
||||
}
|
||||
|
||||
bool hasTweetImage = LastLink.IsImage;
|
||||
bool hasTweetVideo = LastLink.IsVideo;
|
||||
|
||||
string TextOpen(string name) => "Open "+name+" in browser";
|
||||
string TextCopy(string name) => "Copy "+name+" address";
|
||||
@@ -82,13 +87,13 @@ namespace TweetDuck.Core.Handling{
|
||||
model.AddItem(MenuSaveMedia, TextSave("video"));
|
||||
model.AddSeparator();
|
||||
}
|
||||
else if (((parameters.TypeFlags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents) || hasTweetImage) && parameters.SourceUrl != TweetNotification.AppLogoLink){
|
||||
else if (((parameters.TypeFlags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents) || hasTweetImage) && parameters.SourceUrl != TweetNotification.AppLogo.Url){
|
||||
model.AddItem(MenuViewImage, "View image in photo viewer");
|
||||
model.AddItem(MenuOpenMediaUrl, TextOpen("image"));
|
||||
model.AddItem(MenuCopyMediaUrl, TextCopy("image"));
|
||||
model.AddItem(MenuSaveMedia, TextSave("image"));
|
||||
|
||||
if (lastHighlightedTweetImageList.Length > 1){
|
||||
if (LastChirp.Images.Length > 1){
|
||||
model.AddItem(MenuSaveTweetImages, TextSave("all images"));
|
||||
}
|
||||
|
||||
@@ -97,66 +102,105 @@ namespace TweetDuck.Core.Handling{
|
||||
}
|
||||
|
||||
public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
||||
Control control = browserControl.AsControl();
|
||||
|
||||
switch(commandId){
|
||||
case MenuOpenLinkUrl:
|
||||
OpenBrowser(browserControl.AsControl(), IsLink ? ContextInfo.Value : parameters.LinkUrl);
|
||||
OpenBrowser(control, LastLink.GetUrl(parameters, true));
|
||||
break;
|
||||
|
||||
case MenuCopyLinkUrl:
|
||||
SetClipboardText(browserControl.AsControl(), IsLink ? ContextInfo.Value : parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(control, LastLink.GetUrl(parameters, false));
|
||||
break;
|
||||
|
||||
case MenuCopyUsername:
|
||||
Match match = TwitterUtils.RegexAccount.Match(parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(browserControl.AsControl(), match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(control, match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.CopiedUsernames.Trigger);
|
||||
break;
|
||||
|
||||
case MenuOpenMediaUrl:
|
||||
OpenBrowser(browserControl.AsControl(), TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality));
|
||||
OpenBrowser(control, TwitterUtils.GetMediaLink(LastLink.GetMediaSource(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuCopyMediaUrl:
|
||||
SetClipboardText(browserControl.AsControl(), TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality));
|
||||
SetClipboardText(control, TwitterUtils.GetMediaLink(LastLink.GetMediaSource(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuViewImage:
|
||||
string url = GetMediaLink(parameters);
|
||||
string file = Path.Combine(BrowserCache.CacheFolder, TwitterUtils.GetImageFileName(url));
|
||||
|
||||
void ViewFile(){
|
||||
string ext = Path.GetExtension(file);
|
||||
case MenuViewImage: {
|
||||
void ViewImage(string path){
|
||||
string ext = Path.GetExtension(path);
|
||||
|
||||
if (TwitterUtils.ValidImageExtensions.Contains(ext)){
|
||||
WindowsUtils.OpenAssociatedProgram(file);
|
||||
WindowsUtils.OpenAssociatedProgram(path);
|
||||
}
|
||||
else{
|
||||
FormMessage.Error("Image Download", "Invalid file extension "+ext, FormMessage.OK);
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(file)){
|
||||
ViewFile();
|
||||
}
|
||||
else{
|
||||
BrowserUtils.DownloadFileAsync(TwitterUtils.GetMediaLink(url, ImageQuality), file, ViewFile, ex => {
|
||||
FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK);
|
||||
});
|
||||
}
|
||||
string url = LastLink.GetMediaSource(parameters);
|
||||
string file = Path.Combine(BrowserCache.CacheFolder, TwitterUtils.GetImageFileName(url) ?? Path.GetRandomFileName());
|
||||
|
||||
control.InvokeAsyncSafe(() => {
|
||||
if (File.Exists(file)){
|
||||
ViewImage(file);
|
||||
}
|
||||
else{
|
||||
analytics.AnalyticsFile.ViewedImages.Trigger();
|
||||
|
||||
BrowserUtils.DownloadFileAsync(TwitterUtils.GetMediaLink(url, ImageQuality), file, () => {
|
||||
ViewImage(file);
|
||||
}, ex => {
|
||||
FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MenuSaveMedia: {
|
||||
bool isVideo = LastLink.IsVideo;
|
||||
string url = LastLink.GetMediaSource(parameters);
|
||||
string username = LastChirp.Authors.LastOrDefault();
|
||||
|
||||
control.InvokeAsyncSafe(() => {
|
||||
if (isVideo){
|
||||
TwitterUtils.DownloadVideo(url, username);
|
||||
analytics.AnalyticsFile.DownloadedVideos.Trigger();
|
||||
}
|
||||
else{
|
||||
TwitterUtils.DownloadImage(url, username, ImageQuality);
|
||||
analytics.AnalyticsFile.DownloadedImages.Trigger();
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MenuSaveMedia:
|
||||
if (IsVideo){
|
||||
TwitterUtils.DownloadVideo(GetMediaLink(parameters), lastHighlightedTweetAuthors.LastOrDefault());
|
||||
}
|
||||
else{
|
||||
TwitterUtils.DownloadImage(GetMediaLink(parameters), lastHighlightedTweetAuthors.LastOrDefault(), ImageQuality);
|
||||
}
|
||||
case MenuSaveTweetImages: {
|
||||
string[] urls = LastChirp.Images;
|
||||
string username = LastChirp.Authors.LastOrDefault();
|
||||
|
||||
control.InvokeAsyncSafe(() => {
|
||||
TwitterUtils.DownloadImages(urls, username, ImageQuality);
|
||||
analytics.AnalyticsFile.DownloadedImages.Trigger();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MenuSaveTweetImages:
|
||||
TwitterUtils.DownloadImages(lastHighlightedTweetImageList, lastHighlightedTweetAuthors.LastOrDefault(), ImageQuality);
|
||||
case MenuReadApplyROT13:
|
||||
string selection = parameters.SelectionText;
|
||||
control.InvokeAsyncSafe(() => FormMessage.Information("ROT13", StringUtils.ConvertRot13(selection), FormMessage.OK));
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.UsedROT13.Trigger);
|
||||
return true;
|
||||
|
||||
case MenuSearchInBrowser:
|
||||
string query = parameters.SelectionText;
|
||||
control.InvokeAsyncSafe(() => BrowserUtils.OpenExternalSearch(query));
|
||||
DeselectAll(frame);
|
||||
break;
|
||||
|
||||
case MenuOpenDevTools:
|
||||
@@ -168,23 +212,34 @@ namespace TweetDuck.Core.Handling{
|
||||
}
|
||||
|
||||
public virtual void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){
|
||||
ContextInfo = default(KeyValuePair<string, string>);
|
||||
ResetContextInfo();
|
||||
}
|
||||
|
||||
public virtual bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback){
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void OpenBrowser(Control control, string url){
|
||||
protected static void DeselectAll(IFrame frame){
|
||||
ScriptLoader.ExecuteScript(frame, "window.getSelection().removeAllRanges()", "gen:deselect");
|
||||
}
|
||||
|
||||
protected static void OpenBrowser(Control control, string url){
|
||||
control.InvokeAsyncSafe(() => BrowserUtils.OpenExternalBrowser(url));
|
||||
}
|
||||
|
||||
protected void SetClipboardText(Control control, string text){
|
||||
protected static void SetClipboardText(Control control, string text){
|
||||
control.InvokeAsyncSafe(() => WindowsUtils.SetClipboard(text, TextDataFormat.UnicodeText));
|
||||
}
|
||||
|
||||
protected static void InsertSelectionSearchItem(IMenuModel model, CefMenuCommand insertCommand, string insertLabel){
|
||||
model.InsertItemAt(model.GetIndexOf(MenuSearchInBrowser)+1, insertCommand, insertLabel);
|
||||
}
|
||||
|
||||
protected static void AddDebugMenuItems(IMenuModel model){
|
||||
model.AddItem(MenuOpenDevTools, "Open dev tools");
|
||||
if (BrowserUtils.HasDevTools){
|
||||
AddSeparator(model);
|
||||
model.AddItem(MenuOpenDevTools, "Open dev tools");
|
||||
}
|
||||
}
|
||||
|
||||
protected static void RemoveSeparatorIfLast(IMenuModel model){
|
||||
|
@@ -1,8 +1,6 @@
|
||||
using CefSharp;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
@@ -18,7 +16,8 @@ namespace TweetDuck.Core.Handling{
|
||||
private const CefMenuCommand MenuOpenQuotedTweetUrl = (CefMenuCommand)26612;
|
||||
private const CefMenuCommand MenuCopyQuotedTweetUrl = (CefMenuCommand)26613;
|
||||
private const CefMenuCommand MenuScreenshotTweet = (CefMenuCommand)26614;
|
||||
private const CefMenuCommand MenuInputApplyROT13 = (CefMenuCommand)26615;
|
||||
private const CefMenuCommand MenuWriteApplyROT13 = (CefMenuCommand)26615;
|
||||
private const CefMenuCommand MenuSearchInColumn = (CefMenuCommand)26616;
|
||||
|
||||
private const string TitleReloadBrowser = "Reload browser";
|
||||
private const string TitleMuteNotifications = "Mute notifications";
|
||||
@@ -27,25 +26,25 @@ namespace TweetDuck.Core.Handling{
|
||||
private const string TitleAboutProgram = "About "+Program.BrandName;
|
||||
|
||||
private readonly FormBrowser form;
|
||||
|
||||
private string lastHighlightedTweetUrl;
|
||||
private string lastHighlightedQuoteUrl;
|
||||
|
||||
public ContextMenuBrowser(FormBrowser form){
|
||||
|
||||
public ContextMenuBrowser(FormBrowser form) : base(form){
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
bool isSelecting = parameters.TypeFlags.HasFlag(ContextMenuType.Selection);
|
||||
bool isEditing = parameters.TypeFlags.HasFlag(ContextMenuType.Editable);
|
||||
|
||||
model.Remove(CefMenuCommand.Back);
|
||||
model.Remove(CefMenuCommand.Forward);
|
||||
model.Remove(CefMenuCommand.Print);
|
||||
model.Remove(CefMenuCommand.ViewSource);
|
||||
RemoveSeparatorIfLast(model);
|
||||
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Selection)){
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Editable)){
|
||||
if (isSelecting){
|
||||
if (isEditing){
|
||||
model.AddSeparator();
|
||||
model.AddItem(MenuInputApplyROT13, "Apply ROT13");
|
||||
model.AddItem(MenuWriteApplyROT13, "Apply ROT13");
|
||||
}
|
||||
|
||||
model.AddSeparator();
|
||||
@@ -53,20 +52,16 @@ namespace TweetDuck.Core.Handling{
|
||||
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
|
||||
lastHighlightedTweetUrl = TweetDeckBridge.LastHighlightedTweetUrl;
|
||||
lastHighlightedQuoteUrl = TweetDeckBridge.LastHighlightedQuoteUrl;
|
||||
|
||||
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
|
||||
lastHighlightedTweetUrl = string.Empty;
|
||||
lastHighlightedQuoteUrl = string.Empty;
|
||||
if (isSelecting && !isEditing && TwitterUtils.IsTweetDeckWebsite(frame)){
|
||||
InsertSelectionSearchItem(model, MenuSearchInColumn, "Search in a column");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(lastHighlightedTweetUrl) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||
if (!string.IsNullOrEmpty(LastChirp.TweetUrl) && !isSelecting && !isEditing){
|
||||
model.AddItem(MenuOpenTweetUrl, "Open tweet in browser");
|
||||
model.AddItem(MenuCopyTweetUrl, "Copy tweet address");
|
||||
model.AddItem(MenuScreenshotTweet, "Screenshot tweet to clipboard");
|
||||
|
||||
if (!string.IsNullOrEmpty(lastHighlightedQuoteUrl)){
|
||||
if (!string.IsNullOrEmpty(LastChirp.QuoteUrl)){
|
||||
model.AddSeparator();
|
||||
model.AddItem(MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
|
||||
model.AddItem(MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
@@ -75,7 +70,7 @@ namespace TweetDuck.Core.Handling{
|
||||
model.AddSeparator();
|
||||
}
|
||||
|
||||
if ((parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||
if (!isSelecting && !isEditing){
|
||||
AddSeparator(model);
|
||||
|
||||
IMenuModel globalMenu = model.Count == 0 ? model : model.AddSubMenu(MenuGlobal, Program.BrandName);
|
||||
@@ -88,16 +83,13 @@ namespace TweetDuck.Core.Handling{
|
||||
globalMenu.AddItem(MenuSettings, TitleSettings);
|
||||
globalMenu.AddItem(MenuPlugins, TitlePlugins);
|
||||
globalMenu.AddItem(MenuAbout, TitleAboutProgram);
|
||||
|
||||
if (HasDevTools){
|
||||
globalMenu.AddSeparator();
|
||||
AddDebugMenuItems(globalMenu);
|
||||
}
|
||||
|
||||
AddDebugMenuItems(globalMenu);
|
||||
}
|
||||
|
||||
RemoveSeparatorIfLast(model);
|
||||
|
||||
form.InvokeAsyncSafe(() => form.TriggerAnalyticsEvent(AnalyticsFile.Event.BrowserContextMenu));
|
||||
form.InvokeAsyncSafe(form.AnalyticsFile.BrowserContextMenus.Trigger);
|
||||
}
|
||||
|
||||
public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
||||
@@ -127,11 +119,11 @@ namespace TweetDuck.Core.Handling{
|
||||
return true;
|
||||
|
||||
case MenuOpenTweetUrl:
|
||||
OpenBrowser(form, lastHighlightedTweetUrl);
|
||||
OpenBrowser(form, LastChirp.TweetUrl);
|
||||
return true;
|
||||
|
||||
case MenuCopyTweetUrl:
|
||||
SetClipboardText(form, lastHighlightedTweetUrl);
|
||||
SetClipboardText(form, LastChirp.TweetUrl);
|
||||
return true;
|
||||
|
||||
case MenuScreenshotTweet:
|
||||
@@ -139,16 +131,22 @@ namespace TweetDuck.Core.Handling{
|
||||
return true;
|
||||
|
||||
case MenuOpenQuotedTweetUrl:
|
||||
OpenBrowser(form, lastHighlightedQuoteUrl);
|
||||
OpenBrowser(form, LastChirp.QuoteUrl);
|
||||
return true;
|
||||
|
||||
case MenuCopyQuotedTweetUrl:
|
||||
SetClipboardText(form, lastHighlightedQuoteUrl);
|
||||
SetClipboardText(form, LastChirp.QuoteUrl);
|
||||
return true;
|
||||
|
||||
case MenuInputApplyROT13:
|
||||
case MenuWriteApplyROT13:
|
||||
form.InvokeAsyncSafe(form.ApplyROT13);
|
||||
return true;
|
||||
|
||||
case MenuSearchInColumn:
|
||||
string query = parameters.SelectionText;
|
||||
form.InvokeAsyncSafe(() => form.AddSearchColumn(query));
|
||||
DeselectAll(frame);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -166,7 +164,7 @@ namespace TweetDuck.Core.Handling{
|
||||
|
||||
menu.Popup += (sender, args) => {
|
||||
menu.MenuItems[1].Checked = Program.UserConfig.MuteNotifications;
|
||||
form.TriggerAnalyticsEvent(AnalyticsFile.Event.BrowserContextMenu);
|
||||
form.AnalyticsFile.BrowserContextMenus.Trigger();
|
||||
};
|
||||
|
||||
return menu;
|
||||
|
@@ -1,15 +1,14 @@
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
sealed class ContextMenuGuide : ContextMenuBase{
|
||||
public ContextMenuGuide(AnalyticsFile.IProvider analytics) : base(analytics){}
|
||||
|
||||
public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
model.Clear();
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
|
||||
if (HasDevTools){
|
||||
AddSeparator(model);
|
||||
AddDebugMenuItems(model);
|
||||
}
|
||||
AddDebugMenuItems(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
sealed class ContextMenuNotification : ContextMenuBase{
|
||||
@@ -14,7 +13,7 @@ namespace TweetDuck.Core.Handling{
|
||||
private readonly FormNotificationBase form;
|
||||
private readonly bool enableCustomMenu;
|
||||
|
||||
public ContextMenuNotification(FormNotificationBase form, bool enableCustomMenu){
|
||||
public ContextMenuNotification(FormNotificationBase form, bool enableCustomMenu) : base(form){
|
||||
this.form = form;
|
||||
this.enableCustomMenu = enableCustomMenu;
|
||||
}
|
||||
@@ -48,16 +47,12 @@ namespace TweetDuck.Core.Handling{
|
||||
}
|
||||
}
|
||||
|
||||
if (HasDevTools){
|
||||
AddSeparator(model);
|
||||
AddDebugMenuItems(model);
|
||||
}
|
||||
|
||||
AddDebugMenuItems(model);
|
||||
RemoveSeparatorIfLast(model);
|
||||
|
||||
form.InvokeAsyncSafe(() => {
|
||||
form.ContextMenuOpen = true;
|
||||
form.TriggerAnalyticsEvent(AnalyticsFile.Event.NotificationContextMenu);
|
||||
form.AnalyticsFile.NotificationContextMenus.Trigger();
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using CefSharp;
|
||||
using CefSharp.Enums;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
sealed class DragHandlerBrowser : IDragHandler{
|
||||
private readonly RequestHandlerBrowser requestHandler;
|
||||
|
||||
public DragHandlerBrowser(RequestHandlerBrowser requestHandler){
|
||||
this.requestHandler = requestHandler;
|
||||
}
|
||||
|
||||
public bool OnDragEnter(IWebBrowser browserControl, IBrowser browser, IDragData dragData, DragOperationsMask mask){
|
||||
void TriggerDragStart(string type, string data = null){
|
||||
browserControl.ExecuteScriptAsync("window.TDGF_onGlobalDragStart", type, data);
|
||||
}
|
||||
|
||||
requestHandler.BlockNextUserNavUrl = dragData.LinkUrl; // empty if not a link
|
||||
|
||||
if (dragData.IsLink){
|
||||
TriggerDragStart("link", dragData.LinkUrl);
|
||||
|
72
Core/Handling/Filters/ResponseFilterBase.cs
Normal file
72
Core/Handling/Filters/ResponseFilterBase.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using CefSharp;
|
||||
|
||||
namespace TweetDuck.Core.Handling.Filters{
|
||||
abstract class ResponseFilterBase : IResponseFilter{
|
||||
private enum State{
|
||||
Reading, Writing, Done
|
||||
}
|
||||
|
||||
private readonly Encoding encoding;
|
||||
private byte[] responseData;
|
||||
|
||||
private State state;
|
||||
private int offset;
|
||||
|
||||
protected ResponseFilterBase(int totalBytes, Encoding encoding){
|
||||
this.responseData = new byte[totalBytes];
|
||||
this.encoding = encoding;
|
||||
this.state = State.Reading;
|
||||
}
|
||||
|
||||
FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten){
|
||||
int responseLength = responseData.Length;
|
||||
|
||||
if (state == State.Reading){
|
||||
int bytesToRead = Math.Min(responseLength-offset, (int)Math.Min(dataIn.Length, int.MaxValue));
|
||||
|
||||
dataIn.Read(responseData, offset, bytesToRead);
|
||||
offset += bytesToRead;
|
||||
|
||||
dataInRead = bytesToRead;
|
||||
dataOutWritten = 0;
|
||||
|
||||
if (offset >= responseLength){
|
||||
responseData = encoding.GetBytes(ProcessResponse(encoding.GetString(responseData)));
|
||||
state = State.Writing;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
return FilterStatus.NeedMoreData;
|
||||
}
|
||||
else if (state == State.Writing){
|
||||
int bytesToWrite = Math.Min(responseLength-offset, (int)Math.Min(dataOut.Length, int.MaxValue));
|
||||
|
||||
if (bytesToWrite > 0){
|
||||
dataOut.Write(responseData, offset, bytesToWrite);
|
||||
offset += bytesToWrite;
|
||||
}
|
||||
|
||||
dataOutWritten = bytesToWrite;
|
||||
dataInRead = 0;
|
||||
|
||||
if (offset < responseLength){
|
||||
return FilterStatus.NeedMoreData;
|
||||
}
|
||||
else{
|
||||
state = State.Done;
|
||||
return FilterStatus.Done;
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw new InvalidOperationException("This resource filter cannot be reused.");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool InitFilter();
|
||||
protected abstract string ProcessResponse(string text);
|
||||
public abstract void Dispose();
|
||||
}
|
||||
}
|
20
Core/Handling/Filters/ResponseFilterVendor.cs
Normal file
20
Core/Handling/Filters/ResponseFilterVendor.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TweetDuck.Core.Handling.Filters{
|
||||
sealed class ResponseFilterVendor : ResponseFilterBase{
|
||||
private static readonly Regex RegexRestoreJQuery = new Regex(@"(\w+)\.fn=\1\.prototype", RegexOptions.Compiled);
|
||||
|
||||
public ResponseFilterVendor(int totalBytes) : base(totalBytes, Encoding.UTF8){}
|
||||
|
||||
public override bool InitFilter(){
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override string ProcessResponse(string text){
|
||||
return RegexRestoreJQuery.Replace(text, "window.$$=$1;$&", 1);
|
||||
}
|
||||
|
||||
public override void Dispose(){}
|
||||
}
|
||||
}
|
@@ -7,16 +7,14 @@ using CefSharp;
|
||||
|
||||
namespace TweetDuck.Core.Handling.General{
|
||||
sealed class FileDialogHandler : IDialogHandler{
|
||||
public bool OnFileDialog(IWebBrowser browserControl, IBrowser browser, CefFileDialogMode mode, string title, string defaultFilePath, List<string> acceptFilters, int selectedAcceptFilter, IFileDialogCallback callback){
|
||||
CefFileDialogMode dialogType = mode & CefFileDialogMode.TypeMask;
|
||||
|
||||
if (dialogType == CefFileDialogMode.Open || dialogType == CefFileDialogMode.OpenMultiple){
|
||||
public bool OnFileDialog(IWebBrowser browserControl, IBrowser browser, CefFileDialogMode mode, CefFileDialogFlags flags, string title, string defaultFilePath, List<string> acceptFilters, int selectedAcceptFilter, IFileDialogCallback callback){
|
||||
if (mode == CefFileDialogMode.Open || mode == CefFileDialogMode.OpenMultiple){
|
||||
string allFilters = string.Join(";", acceptFilters.Select(filter => "*"+filter));
|
||||
|
||||
using(OpenFileDialog dialog = new OpenFileDialog{
|
||||
AutoUpgradeEnabled = true,
|
||||
DereferenceLinks = true,
|
||||
Multiselect = dialogType == CefFileDialogMode.OpenMultiple,
|
||||
Multiselect = mode == CefFileDialogMode.OpenMultiple,
|
||||
Title = "Open Files",
|
||||
Filter = $"All Supported Formats ({allFilters})|{allFilters}|All Files (*.*)|*.*"
|
||||
}){
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Utils;
|
||||
@@ -28,7 +27,7 @@ namespace TweetDuck.Core.Handling.General{
|
||||
}
|
||||
|
||||
bool IJsDialogHandler.OnJSDialog(IWebBrowser browserControl, IBrowser browser, string originUrl, CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback, ref bool suppressMessage){
|
||||
((ChromiumWebBrowser)browserControl).InvokeSafe(() => {
|
||||
browserControl.AsControl().InvokeSafe(() => {
|
||||
FormMessage form;
|
||||
TextBox input = null;
|
||||
|
||||
@@ -51,8 +50,9 @@ namespace TweetDuck.Core.Handling.General{
|
||||
|
||||
input = new TextBox{
|
||||
Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom,
|
||||
Font = SystemFonts.MessageBoxFont,
|
||||
Location = new Point(BrowserUtils.Scale(22+inputPad, dpiScale), form.ActionPanelY-BrowserUtils.Scale(46, dpiScale)),
|
||||
Size = new Size(form.ClientSize.Width-BrowserUtils.Scale(44+inputPad, dpiScale), 20)
|
||||
Size = new Size(form.ClientSize.Width-BrowserUtils.Scale(44+inputPad, dpiScale), BrowserUtils.Scale(23, dpiScale))
|
||||
};
|
||||
|
||||
form.Controls.Add(input);
|
||||
|
@@ -2,7 +2,6 @@
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
|
||||
namespace TweetDuck.Core.Handling {
|
||||
sealed class KeyboardHandlerNotification : IKeyboardHandler{
|
||||
@@ -13,7 +12,7 @@ namespace TweetDuck.Core.Handling {
|
||||
}
|
||||
|
||||
private void TriggerKeyboardShortcutAnalytics(){
|
||||
notification.InvokeAsyncSafe(() => notification.TriggerAnalyticsEvent(AnalyticsFile.Event.NotificationKeyboardShortcut));
|
||||
notification.InvokeAsyncSafe(notification.AnalyticsFile.NotificationKeyboardShortcuts.Trigger);
|
||||
}
|
||||
|
||||
bool IKeyboardHandler.OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut){
|
||||
|
@@ -1,11 +1,35 @@
|
||||
using CefSharp;
|
||||
using System.Collections.Specialized;
|
||||
using CefSharp;
|
||||
using CefSharp.Handler;
|
||||
using TweetDuck.Core.Handling.General;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class RequestHandlerBase : DefaultRequestHandler{
|
||||
private readonly bool autoReload;
|
||||
|
||||
public RequestHandlerBase(bool autoReload){
|
||||
this.autoReload = autoReload;
|
||||
}
|
||||
|
||||
public override bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture){
|
||||
return LifeSpanHandler.HandleLinkClick(browserControl, targetDisposition, targetUrl);
|
||||
}
|
||||
|
||||
public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback){
|
||||
if (BrowserUtils.HasDevTools){
|
||||
NameValueCollection headers = request.Headers;
|
||||
headers.Remove("x-devtools-emulate-network-conditions-client-id");
|
||||
request.Headers = headers;
|
||||
}
|
||||
|
||||
return base.OnBeforeResourceLoad(browserControl, browser, frame, request, callback);
|
||||
}
|
||||
|
||||
public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){
|
||||
if (autoReload){
|
||||
browser.Reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,17 +1,96 @@
|
||||
using CefSharp;
|
||||
// Uncomment to force TweetDeck to load a predefined version of the vendor/bundle scripts
|
||||
// #define FREEZE_TWEETDECK_SCRIPTS
|
||||
|
||||
using System.Collections.Specialized;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Handling.Filters;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
#if FREEZE_TWEETDECK_SCRIPTS
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
#endif
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
sealed class RequestHandlerBrowser : RequestHandlerBase{
|
||||
public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){
|
||||
browser.Reload();
|
||||
}
|
||||
public string BlockNextUserNavUrl { get; set; }
|
||||
|
||||
public RequestHandlerBrowser() : base(true){}
|
||||
|
||||
public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback){
|
||||
if (request.ResourceType == ResourceType.Script && request.Url.Contains("analytics.")){
|
||||
callback.Dispose();
|
||||
return CefReturnValue.Cancel;
|
||||
}
|
||||
|
||||
return CefReturnValue.Continue;
|
||||
return base.OnBeforeResourceLoad(browserControl, browser, frame, request, callback);
|
||||
}
|
||||
|
||||
public override bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect){
|
||||
if (userGesture && request.TransitionType == TransitionType.LinkClicked){
|
||||
bool block = request.Url == BlockNextUserNavUrl;
|
||||
BlockNextUserNavUrl = string.Empty;
|
||||
return block;
|
||||
}
|
||||
|
||||
return base.OnBeforeBrowse(browserControl, browser, frame, request, userGesture, isRedirect);
|
||||
}
|
||||
|
||||
#if FREEZE_TWEETDECK_SCRIPTS
|
||||
private static readonly Regex TweetDeckScriptUrl = new Regex(@"/dist/(.*?)\.(.*?)\.js$", RegexOptions.Compiled);
|
||||
|
||||
private static readonly SortedList<string, string> TweetDeckHashes = new SortedList<string, string>(2){
|
||||
{ "vendor", "942c0a20e8" },
|
||||
{ "bundle", "1bd75b5854" }
|
||||
};
|
||||
#endif
|
||||
|
||||
public override bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response){
|
||||
if (request.ResourceType == ResourceType.Image && request.Url.Contains("/backgrounds/spinner_blue")){
|
||||
request.Url = TwitterUtils.LoadingSpinner.Url;
|
||||
return true;
|
||||
}
|
||||
#if FREEZE_TWEETDECK_SCRIPTS
|
||||
else if (request.ResourceType == ResourceType.Script){
|
||||
Match match = TweetDeckScriptUrl.Match(request.Url);
|
||||
|
||||
if (match.Success && TweetDeckHashes.TryGetValue(match.Groups[1].Value, out string hash)){
|
||||
if (match.Groups[2].Value == hash){
|
||||
System.Diagnostics.Debug.WriteLine($"accepting {request.Url}");
|
||||
}
|
||||
else{
|
||||
System.Diagnostics.Debug.WriteLine($"rewriting {request.Url} to {hash}");
|
||||
request.Url = TweetDeckScriptUrl.Replace(request.Url, "/dist/$1."+hash+".js");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return base.OnResourceResponse(browserControl, browser, frame, request, response);
|
||||
}
|
||||
|
||||
public override IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response){
|
||||
if (request.ResourceType == ResourceType.Script && request.Url.Contains("/dist/vendor")){
|
||||
NameValueCollection headers = response.ResponseHeaders;
|
||||
|
||||
if (int.TryParse(headers["x-ton-expected-size"], out int totalBytes)){
|
||||
return new ResponseFilterVendor(totalBytes);
|
||||
}
|
||||
#if DEBUG
|
||||
else{
|
||||
System.Diagnostics.Debug.WriteLine($"Missing uncompressed size header in {request.Url}");
|
||||
|
||||
foreach(string key in headers){
|
||||
System.Diagnostics.Debug.WriteLine($" {key}: {headers[key]}");
|
||||
}
|
||||
|
||||
System.Diagnostics.Debugger.Break();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return base.GetResourceResponseFilter(browserControl, browser, frame, request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
68
Core/Management/ContextInfo.cs
Normal file
68
Core/Management/ContextInfo.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Management{
|
||||
sealed class ContextInfo{
|
||||
public LinkInfo Link { get; private set; }
|
||||
public ChirpInfo Chirp { get; private set; }
|
||||
|
||||
public ContextInfo(){
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void SetLink(string type, string url){
|
||||
Link = string.IsNullOrEmpty(url) ? new LinkInfo() : new LinkInfo(type, url);
|
||||
}
|
||||
|
||||
public void SetChirp(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
|
||||
Chirp = new ChirpInfo(tweetUrl, quoteUrl, chirpAuthors, chirpImages);
|
||||
}
|
||||
|
||||
public void Reset(){
|
||||
Link = new LinkInfo();
|
||||
Chirp = new ChirpInfo();
|
||||
}
|
||||
|
||||
// Data structures
|
||||
|
||||
public struct LinkInfo{
|
||||
public bool IsLink => type == "link";
|
||||
public bool IsImage => type == "image";
|
||||
public bool IsVideo => type == "video";
|
||||
|
||||
public string GetUrl(IContextMenuParams parameters, bool safe){
|
||||
return IsLink ? url : (safe ? parameters.LinkUrl : parameters.UnfilteredLinkUrl);
|
||||
}
|
||||
|
||||
public string GetMediaSource(IContextMenuParams parameters){
|
||||
return IsImage || IsVideo ? url : parameters.SourceUrl;
|
||||
}
|
||||
|
||||
private readonly string type;
|
||||
private readonly string url;
|
||||
|
||||
public LinkInfo(string type, string url){
|
||||
this.type = type;
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChirpInfo{
|
||||
public string TweetUrl { get; }
|
||||
public string QuoteUrl { get; }
|
||||
|
||||
public string[] Authors => chirpAuthors?.Split(';') ?? StringUtils.EmptyArray;
|
||||
public string[] Images => chirpImages?.Split(';') ?? StringUtils.EmptyArray;
|
||||
|
||||
private readonly string chirpAuthors;
|
||||
private readonly string chirpImages;
|
||||
|
||||
public ChirpInfo(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
|
||||
this.TweetUrl = tweetUrl;
|
||||
this.QuoteUrl = quoteUrl;
|
||||
this.chirpAuthors = chirpAuthors;
|
||||
this.chirpImages = chirpImages;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,14 +16,13 @@ namespace TweetDuck.Core.Management{
|
||||
public enum Items{
|
||||
None = 0,
|
||||
UserConfig = 1,
|
||||
SystemConfig = 2, // TODO implement later
|
||||
SystemConfig = 2,
|
||||
Session = 4,
|
||||
PluginData = 8,
|
||||
All = UserConfig|SystemConfig|Session|PluginData
|
||||
}
|
||||
|
||||
public bool IsRestarting { get; private set; }
|
||||
public Exception LastException { get; private set; }
|
||||
|
||||
private readonly string file;
|
||||
private readonly PluginManager plugins;
|
||||
@@ -67,7 +66,7 @@ namespace TweetDuck.Core.Management{
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
LastException = e;
|
||||
Program.Reporter.HandleException("Profile Export Error", "An exception happened while exporting TweetDuck profile.", true, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -100,8 +99,7 @@ namespace TweetDuck.Core.Management{
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
LastException = e;
|
||||
}catch(Exception){
|
||||
items = Items.None;
|
||||
}
|
||||
|
||||
@@ -164,12 +162,12 @@ namespace TweetDuck.Core.Management{
|
||||
}
|
||||
|
||||
if (missingPlugins.Count > 0){
|
||||
FormMessage.Information("Importing TweetDuck Profile", "Detected missing plugins when importing plugin data:\n"+string.Join("\n", missingPlugins), FormMessage.OK);
|
||||
FormMessage.Information("Profile Import", "Detected missing plugins when importing plugin data:\n"+string.Join("\n", missingPlugins), FormMessage.OK);
|
||||
}
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
LastException = e;
|
||||
Program.Reporter.HandleException("Profile Import Error", "An exception happened while importing TweetDuck profile.", true, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -199,15 +197,29 @@ namespace TweetDuck.Core.Management{
|
||||
}
|
||||
|
||||
private static IEnumerable<PathInfo> EnumerateFilesRelative(string root){
|
||||
return Directory.Exists(root) ? Directory.EnumerateFiles(root, "*.*", SearchOption.AllDirectories).Select(fullPath => new PathInfo{
|
||||
Full = fullPath,
|
||||
Relative = fullPath.Substring(root.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) // strip leading separator character
|
||||
}) : Enumerable.Empty<PathInfo>();
|
||||
if (Directory.Exists(root)){
|
||||
int rootLength = root.Length;
|
||||
return Directory.EnumerateFiles(root, "*.*", SearchOption.AllDirectories).Select(fullPath => new PathInfo(fullPath, rootLength));
|
||||
}
|
||||
else{
|
||||
return Enumerable.Empty<PathInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class PathInfo{
|
||||
public string Full { get; set; }
|
||||
public string Relative { get; set; }
|
||||
public string Full { get; }
|
||||
public string Relative { get; }
|
||||
|
||||
public PathInfo(string fullPath, int rootLength){
|
||||
this.Full = fullPath;
|
||||
this.Relative = fullPath.Substring(rootLength).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); // strip leading separator character
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ProfileManagerExtensions{
|
||||
public static bool NeedsRestart(this ProfileManager.Items items){
|
||||
return items.HasFlag(ProfileManager.Items.SystemConfig) || items.HasFlag(ProfileManager.Items.Session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,28 +9,16 @@ using TweetLib.Communication;
|
||||
|
||||
namespace TweetDuck.Core.Management{
|
||||
sealed class VideoPlayer : IDisposable{
|
||||
public bool Running{
|
||||
get{
|
||||
if (currentProcess == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
currentProcess.Refresh();
|
||||
return !currentProcess.HasExited;
|
||||
}
|
||||
}
|
||||
public bool Running => currentInstance != null && currentInstance.Running;
|
||||
|
||||
public event EventHandler ProcessExited;
|
||||
|
||||
private readonly Form owner;
|
||||
private string lastUrl;
|
||||
private string lastUsername;
|
||||
private readonly FormBrowser owner;
|
||||
|
||||
private Process currentProcess;
|
||||
private DuplexPipe.Server currentPipe;
|
||||
private Instance currentInstance;
|
||||
private bool isClosing;
|
||||
|
||||
public VideoPlayer(Form owner){
|
||||
public VideoPlayer(FormBrowser owner){
|
||||
this.owner = owner;
|
||||
this.owner.FormClosing += owner_FormClosing;
|
||||
}
|
||||
@@ -40,38 +28,43 @@ namespace TweetDuck.Core.Management{
|
||||
Destroy();
|
||||
isClosing = false;
|
||||
}
|
||||
|
||||
lastUrl = url;
|
||||
lastUsername = username;
|
||||
|
||||
try{
|
||||
currentPipe = DuplexPipe.CreateServer();
|
||||
currentPipe.DataIn += currentPipe_DataIn;
|
||||
DuplexPipe.Server pipe = DuplexPipe.CreateServer();
|
||||
pipe.DataIn += pipe_DataIn;
|
||||
|
||||
if ((currentProcess = Process.Start(new ProcessStartInfo{
|
||||
Process process;
|
||||
|
||||
if ((process = Process.Start(new ProcessStartInfo{
|
||||
FileName = Path.Combine(Program.ProgramPath, "TweetDuck.Video.exe"),
|
||||
Arguments = $"{owner.Handle} {Program.UserConfig.VideoPlayerVolume} \"{url}\" \"{currentPipe.GenerateToken()}\"",
|
||||
Arguments = $"{owner.Handle} {Program.UserConfig.VideoPlayerVolume} \"{url}\" \"{pipe.GenerateToken()}\"",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true
|
||||
})) != null){
|
||||
currentProcess.EnableRaisingEvents = true;
|
||||
currentProcess.Exited += process_Exited;
|
||||
|
||||
currentProcess.BeginOutputReadLine();
|
||||
currentProcess.OutputDataReceived += process_OutputDataReceived;
|
||||
}
|
||||
currentInstance = new Instance(process, pipe, url, username);
|
||||
|
||||
currentPipe.DisposeToken();
|
||||
process.EnableRaisingEvents = true;
|
||||
process.Exited += process_Exited;
|
||||
|
||||
process.BeginOutputReadLine();
|
||||
process.OutputDataReceived += process_OutputDataReceived;
|
||||
|
||||
pipe.DisposeToken();
|
||||
}
|
||||
else{
|
||||
pipe.DataIn -= pipe_DataIn;
|
||||
pipe.Dispose();
|
||||
}
|
||||
}catch(Exception e){
|
||||
Program.Reporter.HandleException("Video Playback Error", "Error launching video player.", true, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendKeyEvent(Keys key){
|
||||
currentPipe?.Write("key", ((int)key).ToString());
|
||||
currentInstance?.Pipe.Write("key", ((int)key).ToString());
|
||||
}
|
||||
|
||||
private void currentPipe_DataIn(object sender, DuplexPipe.PipeReadEventArgs e){
|
||||
private void pipe_DataIn(object sender, DuplexPipe.PipeReadEventArgs e){
|
||||
owner.InvokeSafe(() => {
|
||||
switch(e.Key){
|
||||
case "vol":
|
||||
@@ -83,15 +76,16 @@ namespace TweetDuck.Core.Management{
|
||||
break;
|
||||
|
||||
case "download":
|
||||
TwitterUtils.DownloadVideo(lastUrl, lastUsername);
|
||||
if (currentInstance != null){
|
||||
owner.AnalyticsFile.DownloadedVideos.Trigger();
|
||||
TwitterUtils.DownloadVideo(currentInstance.Url, currentInstance.Username);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "rip":
|
||||
currentPipe.Dispose();
|
||||
currentPipe = null;
|
||||
|
||||
currentProcess.Dispose();
|
||||
currentProcess = null;
|
||||
currentInstance?.Dispose();
|
||||
currentInstance = null;
|
||||
|
||||
isClosing = false;
|
||||
TriggerProcessExitEventUnsafe();
|
||||
@@ -101,15 +95,15 @@ namespace TweetDuck.Core.Management{
|
||||
}
|
||||
|
||||
public void Close(){
|
||||
if (currentProcess != null){
|
||||
if (currentInstance != null){
|
||||
if (isClosing){
|
||||
Destroy();
|
||||
isClosing = false;
|
||||
}
|
||||
else{
|
||||
isClosing = true;
|
||||
currentProcess.Exited -= process_Exited;
|
||||
currentPipe.Write("die");
|
||||
currentInstance.Process.Exited -= process_Exited;
|
||||
currentInstance.Pipe.Write("die");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,26 +116,17 @@ namespace TweetDuck.Core.Management{
|
||||
}
|
||||
|
||||
private void Destroy(){
|
||||
if (currentProcess != null){
|
||||
try{
|
||||
currentProcess.Kill();
|
||||
}catch{
|
||||
// kill me instead then
|
||||
}
|
||||
|
||||
currentProcess.Dispose();
|
||||
currentProcess = null;
|
||||
|
||||
currentPipe.Dispose();
|
||||
currentPipe = null;
|
||||
if (currentInstance != null){
|
||||
currentInstance.KillAndDispose();
|
||||
currentInstance = null;
|
||||
|
||||
TriggerProcessExitEventUnsafe();
|
||||
}
|
||||
}
|
||||
|
||||
private void owner_FormClosing(object sender, FormClosingEventArgs e){
|
||||
if (currentProcess != null){
|
||||
currentProcess.Exited -= process_Exited;
|
||||
if (currentInstance != null){
|
||||
currentInstance.Process.Exited -= process_Exited;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,25 +137,27 @@ namespace TweetDuck.Core.Management{
|
||||
}
|
||||
|
||||
private void process_Exited(object sender, EventArgs e){
|
||||
int exitCode = currentProcess.ExitCode;
|
||||
if (currentInstance == null){
|
||||
return;
|
||||
}
|
||||
|
||||
currentProcess.Dispose();
|
||||
currentProcess = null;
|
||||
int exitCode = currentInstance.Process.ExitCode;
|
||||
string url = currentInstance.Url;
|
||||
|
||||
currentPipe.Dispose();
|
||||
currentPipe = null;
|
||||
currentInstance.Dispose();
|
||||
currentInstance = null;
|
||||
|
||||
switch(exitCode){
|
||||
case 3: // CODE_LAUNCH_FAIL
|
||||
if (FormMessage.Error("Video Playback Error", "Error launching video player, this may be caused by missing Windows Media Player. Do you want to open the video in your browser?", FormMessage.Yes, FormMessage.No)){
|
||||
BrowserUtils.OpenExternalBrowser(lastUrl);
|
||||
BrowserUtils.OpenExternalBrowser(url);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4: // CODE_MEDIA_ERROR
|
||||
if (FormMessage.Error("Video Playback Error", "The video could not be loaded, most likely due to unknown format. Do you want to open the video in your browser?", FormMessage.Yes, FormMessage.No)){
|
||||
BrowserUtils.OpenExternalBrowser(lastUrl);
|
||||
BrowserUtils.OpenExternalBrowser(url);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -182,5 +169,42 @@ namespace TweetDuck.Core.Management{
|
||||
private void TriggerProcessExitEventUnsafe(){
|
||||
ProcessExited?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private sealed class Instance : IDisposable{
|
||||
public bool Running{
|
||||
get{
|
||||
Process.Refresh();
|
||||
return !Process.HasExited;
|
||||
}
|
||||
}
|
||||
|
||||
public Process Process { get; }
|
||||
public DuplexPipe.Server Pipe { get; }
|
||||
|
||||
public string Url { get; }
|
||||
public string Username { get; }
|
||||
|
||||
public Instance(Process process, DuplexPipe.Server pipe, string url, string username){
|
||||
this.Process = process;
|
||||
this.Pipe = pipe;
|
||||
this.Url = url;
|
||||
this.Username = username;
|
||||
}
|
||||
|
||||
public void KillAndDispose(){
|
||||
try{
|
||||
Process.Kill();
|
||||
}catch{
|
||||
// kill me instead then
|
||||
}
|
||||
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
Process.Dispose();
|
||||
Pipe.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using System.Windows.Forms;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Resources;
|
||||
@@ -21,10 +23,14 @@ namespace TweetDuck.Core.Notification.Example{
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler Ready;
|
||||
|
||||
private readonly TweetNotification exampleNotification;
|
||||
|
||||
public FormNotificationExample(FormBrowser owner, PluginManager pluginManager) : base(owner, pluginManager, false){
|
||||
string exampleTweetHTML = ScriptLoader.LoadResource("pages/example.html", true).Replace("{avatar}", TweetNotification.AppLogoLink);
|
||||
browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||
|
||||
string exampleTweetHTML = ScriptLoader.LoadResourceSilent("pages/example.html")?.Replace("{avatar}", TweetNotification.AppLogo.Url) ?? string.Empty;
|
||||
|
||||
#if DEBUG
|
||||
exampleTweetHTML = exampleTweetHTML.Replace("</p>", @"</p><div style='margin-top:256px'>Scrollbar test padding...</div>");
|
||||
@@ -33,6 +39,13 @@ namespace TweetDuck.Core.Notification.Example{
|
||||
exampleNotification = TweetNotification.Example(exampleTweetHTML, 176);
|
||||
}
|
||||
|
||||
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
||||
if (!e.IsLoading){
|
||||
Ready?.Invoke(this, EventArgs.Empty);
|
||||
browser.LoadingStateChanged -= browser_LoadingStateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HideNotification(){
|
||||
Location = ControlExtensions.InvisibleLocation;
|
||||
}
|
||||
|
@@ -1,6 +1,4 @@
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using System;
|
||||
using CefSharp.WinForms;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
@@ -12,7 +10,7 @@ using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
partial class FormNotificationBase : Form{
|
||||
partial class FormNotificationBase : Form, AnalyticsFile.IProvider{
|
||||
protected static int FontSizeLevel{
|
||||
get{
|
||||
switch(TweetDeckBridge.FontSize){
|
||||
@@ -65,7 +63,7 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNotificationVisible => Location != ControlExtensions.InvisibleLocation;
|
||||
protected bool IsNotificationVisible => Location != ControlExtensions.InvisibleLocation;
|
||||
protected virtual bool CanDragWindow => true;
|
||||
|
||||
public new Point Location{
|
||||
@@ -89,6 +87,8 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AnalyticsFile AnalyticsFile => owner.AnalyticsFile;
|
||||
|
||||
protected override bool ShowWithoutActivation => true;
|
||||
|
||||
@@ -107,15 +107,13 @@ namespace TweetDuck.Core.Notification{
|
||||
public string CurrentQuoteUrl => currentNotification?.QuoteUrl;
|
||||
|
||||
public bool CanViewDetail => currentNotification != null && !string.IsNullOrEmpty(currentNotification.ColumnId) && !string.IsNullOrEmpty(currentNotification.ChirpId);
|
||||
public bool IsPaused => pauseCounter > 0;
|
||||
|
||||
protected bool IsPaused => pauseCounter > 0;
|
||||
protected bool IsCursorOverBrowser => browser.Bounds.Contains(PointToClient(Cursor.Position));
|
||||
|
||||
public bool FreezeTimer { get; set; }
|
||||
public bool ContextMenuOpen { get; set; }
|
||||
|
||||
public event EventHandler Initialized;
|
||||
|
||||
protected FormNotificationBase(FormBrowser owner, bool enableContextMenu){
|
||||
InitializeComponent();
|
||||
|
||||
@@ -126,21 +124,14 @@ namespace TweetDuck.Core.Notification{
|
||||
MenuHandler = new ContextMenuNotification(this, enableContextMenu),
|
||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||
LifeSpanHandler = new LifeSpanHandler(),
|
||||
RequestHandler = new RequestHandlerBase()
|
||||
RequestHandler = new RequestHandlerBase(false)
|
||||
};
|
||||
|
||||
this.browser.Dock = DockStyle.None;
|
||||
this.browser.ClientSize = ClientSize;
|
||||
this.browser.IsBrowserInitializedChanged += browser_IsBrowserInitializedChanged;
|
||||
|
||||
#if DEBUG
|
||||
this.browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
||||
#endif
|
||||
|
||||
DpiScale = this.GetDPIScale();
|
||||
|
||||
|
||||
browser.SetupResourceHandler(TwitterUtils.TweetDeckURL, this.resourceHandler);
|
||||
browser.SetupResourceHandler(TweetNotification.AppLogoLink, TweetNotification.AppLogoHandler);
|
||||
browser.SetupResourceHandler(TweetNotification.AppLogo);
|
||||
|
||||
Controls.Add(browser);
|
||||
|
||||
@@ -149,6 +140,8 @@ namespace TweetDuck.Core.Notification{
|
||||
this.owner.FormClosed -= owner_FormClosed;
|
||||
};
|
||||
|
||||
DpiScale = this.GetDPIScale();
|
||||
|
||||
// ReSharper disable once VirtualMemberCallInContructor
|
||||
UpdateTitle();
|
||||
}
|
||||
@@ -161,22 +154,12 @@ namespace TweetDuck.Core.Notification{
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
public void TriggerAnalyticsEvent(AnalyticsFile.Event e){
|
||||
owner.TriggerAnalyticsEvent(e);
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void owner_FormClosed(object sender, FormClosedEventArgs e){
|
||||
Close();
|
||||
}
|
||||
|
||||
private void browser_IsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs e){
|
||||
if (e.IsBrowserInitialized){
|
||||
Initialized?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
// notification methods
|
||||
|
||||
public virtual void HideNotification(){
|
||||
@@ -202,7 +185,7 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
|
||||
protected virtual string GetTweetHTML(TweetNotification tweet){
|
||||
return tweet.GenerateHtml(IsCursorOverBrowser ? "td-hover" : string.Empty);
|
||||
return tweet.GenerateHtml(IsCursorOverBrowser ? "td-notification td-hover" : "td-notification", this);
|
||||
}
|
||||
|
||||
protected virtual void LoadTweet(TweetNotification tweet){
|
||||
@@ -223,7 +206,9 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
|
||||
public void ShowTweetDetail(){
|
||||
owner.ShowTweetDetail(currentNotification.ColumnId, currentNotification.ChirpId, currentNotification.TweetUrl);
|
||||
if (currentNotification != null){
|
||||
owner.ShowTweetDetail(currentNotification.ColumnId, currentNotification.ChirpId, currentNotification.TweetUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveToVisibleLocation(){
|
||||
|
@@ -2,10 +2,11 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Core.Other.Interfaces;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Data;
|
||||
using TweetDuck.Plugins;
|
||||
@@ -13,12 +14,7 @@ using TweetDuck.Plugins.Enums;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
abstract partial class FormNotificationMain : FormNotificationBase{
|
||||
private const string NotificationScriptFile = "notification.js";
|
||||
|
||||
private static readonly string NotificationScriptIdentifier = ScriptLoader.GetRootIdentifier(NotificationScriptFile);
|
||||
private static readonly string NotificationJS = ScriptLoader.LoadResource(NotificationScriptFile);
|
||||
|
||||
abstract partial class FormNotificationMain : FormNotificationBase, ITweetDeckBrowser{
|
||||
private readonly PluginManager plugins;
|
||||
private readonly int timerBarHeight;
|
||||
|
||||
@@ -65,7 +61,7 @@ namespace TweetDuck.Core.Notification{
|
||||
get{
|
||||
switch(Program.UserConfig.NotificationSize){
|
||||
default:
|
||||
return BrowserUtils.Scale(122, SizeScale*(1.0+0.075*FontSizeLevel));
|
||||
return BrowserUtils.Scale(122, SizeScale*(1.0+0.08*FontSizeLevel));
|
||||
|
||||
case TweetNotification.Size.Custom:
|
||||
return Program.UserConfig.CustomNotificationSize.Height;
|
||||
@@ -82,17 +78,39 @@ namespace TweetDuck.Core.Notification{
|
||||
this.timerBarHeight = BrowserUtils.Scale(4, DpiScale);
|
||||
|
||||
browser.KeyboardHandler = new KeyboardHandlerNotification(this);
|
||||
|
||||
browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge.Notification(owner, this));
|
||||
browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
||||
|
||||
browser.LoadingStateChanged += Browser_LoadingStateChanged;
|
||||
browser.FrameLoadEnd += Browser_FrameLoadEnd;
|
||||
|
||||
plugins.Register(this, PluginEnvironment.Notification, this);
|
||||
|
||||
mouseHookDelegate = MouseHookProc;
|
||||
Disposed += (sender, args) => StopMouseHook(true);
|
||||
}
|
||||
|
||||
// implementation of ITweetDeckBrowser
|
||||
|
||||
bool ITweetDeckBrowser.IsTweetDeckWebsite => IsNotificationVisible;
|
||||
|
||||
void ITweetDeckBrowser.RegisterBridge(string name, object obj){
|
||||
browser.RegisterAsyncJsObject(name, obj);
|
||||
}
|
||||
|
||||
void ITweetDeckBrowser.OnFrameLoaded(Action<IFrame> callback){
|
||||
browser.FrameLoadEnd += (sender, args) => {
|
||||
IFrame frame = args.Frame;
|
||||
|
||||
if (frame.IsMain && browser.Address != "about:blank"){
|
||||
callback(frame);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void ITweetDeckBrowser.ExecuteFunction(string name, params object[] args){
|
||||
browser.ExecuteScriptAsync(name, args);
|
||||
}
|
||||
|
||||
// mouse wheel hook
|
||||
|
||||
private void StartMouseHook(){
|
||||
@@ -114,7 +132,14 @@ namespace TweetDuck.Core.Notification{
|
||||
int eventType = wParam.ToInt32();
|
||||
|
||||
if (eventType == NativeMethods.WM_MOUSEWHEEL && IsCursorOverBrowser){
|
||||
browser.SendMouseWheelEvent(0, 0, 0, BrowserUtils.Scale(NativeMethods.GetMouseHookData(lParam), Program.UserConfig.NotificationScrollSpeed*0.01), CefEventFlags.None);
|
||||
if (Arguments.HasFlag(Arguments.ArgNotificationScrollWA)){
|
||||
int delta = BrowserUtils.Scale(NativeMethods.GetMouseHookData(lParam), Program.UserConfig.NotificationScrollSpeed*0.01);
|
||||
browser.ExecuteScriptAsync("window.scrollBy", 0, -Math.Round(delta/0.72));
|
||||
}
|
||||
else{
|
||||
browser.SendMouseWheelEvent(0, 0, 0, BrowserUtils.Scale(NativeMethods.GetMouseHookData(lParam), Program.UserConfig.NotificationScrollSpeed*0.01), CefEventFlags.None);
|
||||
}
|
||||
|
||||
return NativeMethods.HOOK_HANDLED;
|
||||
}
|
||||
else if (eventType == NativeMethods.WM_XBUTTONDOWN && DesktopBounds.Contains(Cursor.Position)){
|
||||
@@ -128,7 +153,7 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
|
||||
blockXButtonUp = true;
|
||||
this.InvokeAsyncSafe(() => TriggerAnalyticsEvent(AnalyticsFile.Event.NotificationExtraMouseButton));
|
||||
this.InvokeAsyncSafe(AnalyticsFile.NotificationExtraMouseButtons.Trigger);
|
||||
return NativeMethods.HOOK_HANDLED;
|
||||
}
|
||||
else if (eventType == NativeMethods.WM_XBUTTONUP && blockXButtonUp){
|
||||
@@ -164,10 +189,9 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
|
||||
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
if (e.Frame.IsMain && NotificationJS != null && browser.Address != "about:blank"){
|
||||
if (e.Frame.IsMain && browser.Address != "about:blank"){
|
||||
e.Frame.ExecuteJavaScriptAsync(PropertyBridge.GenerateScript(PropertyBridge.Environment.Notification));
|
||||
ScriptLoader.ExecuteScript(e.Frame, NotificationJS, NotificationScriptIdentifier);
|
||||
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Notification);
|
||||
ScriptLoader.ExecuteScript(e.Frame, ScriptLoader.LoadResource("notification.js", this), "root:notification");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,8 +257,8 @@ namespace TweetDuck.Core.Notification{
|
||||
protected override string GetTweetHTML(TweetNotification tweet){
|
||||
string html = base.GetTweetHTML(tweet);
|
||||
|
||||
foreach(InjectedHTML injection in plugins.Bridge.NotificationInjections){
|
||||
html = injection.Inject(html);
|
||||
foreach(InjectedHTML injection in plugins.NotificationInjections){
|
||||
html = injection.InjectInto(html);
|
||||
}
|
||||
|
||||
return html;
|
||||
|
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using TweetDuck.Plugins;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
@@ -94,7 +93,7 @@ namespace TweetDuck.Core.Notification{
|
||||
}
|
||||
|
||||
needsTrim |= tweetQueue.Count >= TrimMinimum;
|
||||
TriggerAnalyticsEvent(AnalyticsFile.Event.DesktopNotification);
|
||||
AnalyticsFile.DesktopNotifications.Trigger();
|
||||
}
|
||||
|
||||
public override void HideNotification(){
|
||||
|
@@ -3,7 +3,7 @@ using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Data;
|
||||
@@ -15,44 +15,74 @@ namespace TweetDuck.Core.Notification.Screenshot{
|
||||
protected override bool CanDragWindow => false;
|
||||
|
||||
private readonly PluginManager plugins;
|
||||
private int height;
|
||||
|
||||
public FormNotificationScreenshotable(Action callback, FormBrowser owner, PluginManager pluginManager) : base(owner, false){
|
||||
public FormNotificationScreenshotable(Action callback, FormBrowser owner, PluginManager pluginManager, string html, int width) : base(owner, false){
|
||||
this.plugins = pluginManager;
|
||||
|
||||
browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new CallbackBridge(this, callback));
|
||||
int realWidth = BrowserUtils.Scale(width, DpiScale);
|
||||
|
||||
browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new ScreenshotBridge(this, SetScreenshotHeight, callback));
|
||||
|
||||
browser.LoadingStateChanged += (sender, args) => {
|
||||
if (!args.IsLoading){
|
||||
using(IFrame frame = args.Browser.MainFrame){
|
||||
ScriptLoader.ExecuteScript(frame, "window.setTimeout($TD_NotificationScreenshot.trigger, document.getElementsByTagName('iframe').length ? 267 : 67)", "gen:screenshot");
|
||||
}
|
||||
if (args.IsLoading){
|
||||
return;
|
||||
}
|
||||
|
||||
string script = ScriptLoader.LoadResourceSilent("screenshot.js");
|
||||
|
||||
if (script == null){
|
||||
this.InvokeAsyncSafe(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
using(IFrame frame = args.Browser.MainFrame){
|
||||
ScriptLoader.ExecuteScript(frame, script.Replace("{width}", realWidth.ToString()).Replace("{frames}", TweetScreenshotManager.WaitFrames.ToString()), "gen:screenshot");
|
||||
}
|
||||
};
|
||||
|
||||
SetNotificationSize(realWidth, 1024);
|
||||
LoadTweet(new TweetNotification(string.Empty, string.Empty, string.Empty, html, 0, string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
protected override string GetTweetHTML(TweetNotification tweet){
|
||||
string html = tweet.GenerateHtml("td-screenshot", false);
|
||||
|
||||
foreach(InjectedHTML injection in plugins.Bridge.NotificationInjections){
|
||||
html = injection.Inject(html);
|
||||
protected override string GetTweetHTML(TweetNotification tweet){
|
||||
string html = tweet.GenerateHtml("td-screenshot", this);
|
||||
|
||||
foreach(InjectedHTML injection in plugins.NotificationInjections){
|
||||
html = injection.InjectInto(html);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
public void LoadNotificationForScreenshot(TweetNotification tweet, int width, int height){
|
||||
LoadTweet(tweet);
|
||||
SetNotificationSize(width, height);
|
||||
private void SetScreenshotHeight(int browserHeight){
|
||||
this.height = BrowserUtils.Scale(browserHeight, SizeScale);
|
||||
}
|
||||
|
||||
public void TakeScreenshot(){
|
||||
public bool TakeScreenshot(bool ignoreHeightError = false){
|
||||
if (!ignoreHeightError){
|
||||
if (height == 0){
|
||||
FormMessage.Error("Screenshot Failed", "Could not detect screenshot size.", FormMessage.OK);
|
||||
return false;
|
||||
}
|
||||
else if (height > ClientSize.Height){
|
||||
FormMessage.Error("Screenshot Failed", $"Screenshot is too large: {height}px > {ClientSize.Height}px", FormMessage.OK);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WindowsUtils.IsAeroEnabled){
|
||||
MoveToVisibleLocation(); // TODO make this look nicer I guess
|
||||
}
|
||||
|
||||
IntPtr context = NativeMethods.GetDC(this.Handle);
|
||||
|
||||
if (context == IntPtr.Zero){
|
||||
FormMessage.Error("Screenshot Failed", "Could not retrieve a graphics context handle for the notification window to take the screenshot.", FormMessage.OK);
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
using(Bitmap bmp = new Bitmap(ClientSize.Width, ClientSize.Height, PixelFormat.Format32bppRgb)){
|
||||
using(Bitmap bmp = new Bitmap(ClientSize.Width, Math.Max(1, height), PixelFormat.Format32bppRgb)){
|
||||
try{
|
||||
NativeMethods.RenderSourceIntoBitmap(context, bmp);
|
||||
}finally{
|
||||
@@ -60,6 +90,7 @@ namespace TweetDuck.Core.Notification.Screenshot{
|
||||
}
|
||||
|
||||
Clipboard.SetImage(bmp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
Core/Notification/Screenshot/ScreenshotBridge.cs
Normal file
26
Core/Notification/Screenshot/ScreenshotBridge.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
|
||||
namespace TweetDuck.Core.Notification.Screenshot{
|
||||
sealed class ScreenshotBridge{
|
||||
private readonly Control owner;
|
||||
|
||||
private readonly Action<int> safeSetHeight;
|
||||
private readonly Action safeTriggerScreenshot;
|
||||
|
||||
public ScreenshotBridge(Control owner, Action<int> safeSetHeight, Action safeTriggerScreenshot){
|
||||
this.owner = owner;
|
||||
this.safeSetHeight = safeSetHeight;
|
||||
this.safeTriggerScreenshot = safeTriggerScreenshot;
|
||||
}
|
||||
|
||||
public void SetHeight(int tweetHeight){
|
||||
owner.InvokeSafe(() => safeSetHeight(tweetHeight));
|
||||
}
|
||||
|
||||
public void TriggerScreenshot(){
|
||||
owner.InvokeSafe(safeTriggerScreenshot);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,17 +1,37 @@
|
||||
// Uncomment to keep screenshot windows visible for debugging
|
||||
#if DEBUG
|
||||
// Uncomment to keep screenshot windows visible for debugging
|
||||
// #define NO_HIDE_SCREENSHOTS
|
||||
|
||||
// Uncomment to generate screenshots of individual frames for at most 1 second
|
||||
// #define GEN_SCREENSHOT_FRAMES
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Plugins;
|
||||
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using TweetDuck.Core.Utils;
|
||||
#endif
|
||||
|
||||
namespace TweetDuck.Core.Notification.Screenshot{
|
||||
sealed class TweetScreenshotManager : IDisposable{
|
||||
private readonly FormBrowser owner;
|
||||
private readonly PluginManager plugins;
|
||||
private readonly Timer timeout;
|
||||
private readonly Timer disposer;
|
||||
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
private readonly Timer debugger;
|
||||
private int frameCounter;
|
||||
|
||||
public const int WaitFrames = 60;
|
||||
#else
|
||||
public const int WaitFrames = 5;
|
||||
#endif
|
||||
|
||||
private FormNotificationScreenshotable screenshot;
|
||||
|
||||
@@ -24,6 +44,11 @@ namespace TweetDuck.Core.Notification.Screenshot{
|
||||
|
||||
this.disposer = new Timer{ Interval = 1 };
|
||||
this.disposer.Tick += disposer_Tick;
|
||||
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
this.debugger = new Timer{ Interval = 16 };
|
||||
this.debugger.Tick += debugger_Tick;
|
||||
#endif
|
||||
}
|
||||
|
||||
private void timeout_Tick(object sender, EventArgs e){
|
||||
@@ -37,17 +62,20 @@ namespace TweetDuck.Core.Notification.Screenshot{
|
||||
screenshot = null;
|
||||
}
|
||||
|
||||
public void Trigger(string html, int width, int height){
|
||||
public void Trigger(string html, int width){
|
||||
if (screenshot != null){
|
||||
return;
|
||||
}
|
||||
|
||||
screenshot = new FormNotificationScreenshotable(Callback, owner, plugins);
|
||||
screenshot.LoadNotificationForScreenshot(new TweetNotification(string.Empty, string.Empty, string.Empty, html, 0, string.Empty, string.Empty), width, height);
|
||||
screenshot = new FormNotificationScreenshotable(Callback, owner, plugins, html, width);
|
||||
screenshot.Show();
|
||||
timeout.Start();
|
||||
|
||||
#if !(DEBUG && NO_HIDE_SCREENSHOTS)
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
StartDebugger();
|
||||
#endif
|
||||
|
||||
#if !NO_HIDE_SCREENSHOTS
|
||||
owner.IsWaiting = true;
|
||||
#endif
|
||||
}
|
||||
@@ -59,8 +87,8 @@ namespace TweetDuck.Core.Notification.Screenshot{
|
||||
|
||||
timeout.Stop();
|
||||
screenshot.TakeScreenshot();
|
||||
|
||||
#if !(DEBUG && NO_HIDE_SCREENSHOTS)
|
||||
|
||||
#if !NO_HIDE_SCREENSHOTS
|
||||
OnFinished();
|
||||
#else
|
||||
screenshot.MoveToVisibleLocation();
|
||||
@@ -69,15 +97,52 @@ namespace TweetDuck.Core.Notification.Screenshot{
|
||||
}
|
||||
|
||||
private void OnFinished(){
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
debugger.Stop();
|
||||
#endif
|
||||
|
||||
screenshot.Location = ControlExtensions.InvisibleLocation;
|
||||
owner.IsWaiting = false;
|
||||
disposer.Start();
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
debugger.Dispose();
|
||||
#endif
|
||||
|
||||
timeout.Dispose();
|
||||
disposer.Dispose();
|
||||
screenshot?.Dispose();
|
||||
}
|
||||
|
||||
#if GEN_SCREENSHOT_FRAMES
|
||||
private static readonly string DebugScreenshotPath = Path.Combine(Program.StoragePath, "TD_Screenshots");
|
||||
|
||||
private void StartDebugger(){
|
||||
frameCounter = 0;
|
||||
|
||||
try{
|
||||
Directory.Delete(DebugScreenshotPath, true);
|
||||
WindowsUtils.TrySleepUntil(() => !Directory.Exists(DebugScreenshotPath), 1000, 10);
|
||||
}catch(DirectoryNotFoundException){}
|
||||
|
||||
Directory.CreateDirectory(DebugScreenshotPath);
|
||||
debugger.Start();
|
||||
}
|
||||
|
||||
private void debugger_Tick(object sender, EventArgs e){
|
||||
if (frameCounter < 63 && screenshot.TakeScreenshot(true)){
|
||||
try{
|
||||
Clipboard.GetImage()?.Save(Path.Combine(DebugScreenshotPath, "frame_"+(++frameCounter)+".png"), ImageFormat.Png);
|
||||
}catch{
|
||||
System.Diagnostics.Debug.WriteLine("Failed generating frame "+frameCounter);
|
||||
}
|
||||
}
|
||||
else{
|
||||
debugger.Stop();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ using TweetDuck.Core.Other.Settings;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
static class SoundNotification{
|
||||
public const string SupportedFormats = "*.wav;*.ogg;*.flac;*.opus;*.weba;*.webm"; // TODO add mp3 when supported
|
||||
public const string SupportedFormats = "*.wav;*.ogg;*.mp3;*.flac;*.opus;*.weba;*.webm";
|
||||
|
||||
public static IResourceHandler CreateFileHandler(string path){
|
||||
string mimeType;
|
||||
@@ -18,36 +18,33 @@ namespace TweetDuck.Core.Notification{
|
||||
case ".webm": mimeType = "audio/webm"; break;
|
||||
case ".wav": mimeType = "audio/wav"; break;
|
||||
case ".ogg": mimeType = "audio/ogg"; break;
|
||||
case ".mp3": mimeType = "audio/mp3"; break;
|
||||
case ".flac": mimeType = "audio/flac"; break;
|
||||
case ".opus": mimeType = "audio/ogg; codecs=opus"; break;
|
||||
case ".mp3": TryShowError("MP3 sound notifications are temporarily unsupported, please convert the file to another format, such as .ogg, .wav, or .flac."); return null;
|
||||
default: mimeType = null; break;
|
||||
}
|
||||
|
||||
try{
|
||||
return ResourceHandler.FromFilePath(path, mimeType);
|
||||
}catch{
|
||||
TryShowError("Could not find custom notification sound file:\n"+path);
|
||||
FormBrowser browser = FormManager.TryFind<FormBrowser>();
|
||||
|
||||
browser?.InvokeAsyncSafe(() => {
|
||||
using(FormMessage form = new FormMessage("Sound Notification Error", "Could not find custom notification sound file:\n"+path, MessageBoxIcon.Error)){
|
||||
form.AddButton(FormMessage.Ignore, ControlType.Cancel | ControlType.Focused);
|
||||
|
||||
Button btnViewOptions = form.AddButton("View Options");
|
||||
btnViewOptions.Width += 16;
|
||||
btnViewOptions.Location = new Point(btnViewOptions.Location.X-16, btnViewOptions.Location.Y);
|
||||
|
||||
if (form.ShowDialog() == DialogResult.OK && form.ClickedButton == btnViewOptions){
|
||||
browser.OpenSettings(typeof(TabSettingsSounds));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void TryShowError(string message){
|
||||
FormBrowser browser = FormManager.TryFind<FormBrowser>();
|
||||
|
||||
browser?.InvokeAsyncSafe(() => {
|
||||
using(FormMessage form = new FormMessage("Sound Notification Error", message, MessageBoxIcon.Error)){
|
||||
form.AddButton(FormMessage.Ignore, ControlType.Cancel | ControlType.Focused);
|
||||
|
||||
Button btnViewOptions = form.AddButton("View Options");
|
||||
btnViewOptions.Width += 16;
|
||||
btnViewOptions.Location = new Point(btnViewOptions.Location.X-16, btnViewOptions.Location.Y);
|
||||
|
||||
if (form.ShowDialog() == DialogResult.OK && form.ClickedButton == btnViewOptions){
|
||||
browser.OpenSettings(typeof(TabSettingsSounds));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,15 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Data;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
sealed class TweetNotification{
|
||||
private const string DefaultHeadLayout = @"<html id='tduck' class='os-windows txt-size--14' data-td-font='medium' data-td-theme='dark'><head><meta charset='utf-8'><meta http-equiv='X-UA-Compatible' content='chrome=1'><link rel='stylesheet' href='https://ton.twimg.com/tweetdeck-web/web/css/font.5ef884f9f9.css'><link rel='stylesheet' href='https://ton.twimg.com/tweetdeck-web/web/css/app-dark.5631e0dd42.css'><style type='text/css'>body{background:#222426}</style>";
|
||||
private static readonly string CustomCSS = ScriptLoader.LoadResource("styles/notification.css");
|
||||
|
||||
public const string AppLogoLink = "https://ton.twimg.com/tduck/avatar";
|
||||
public static readonly IResourceHandler AppLogoHandler = ResourceHandler.FromByteArray(Properties.Resources.avatar, "image/png");
|
||||
private const string DefaultHeadLayout = @"<html class=""scroll-v os-windows dark txt-size--14"" lang=""en-US"" id=""tduck"" data-td-font=""medium"" data-td-theme=""dark""><head><meta charset=""utf-8""><link href=""https://ton.twimg.com/tweetdeck-web/web/dist/bundle.4b1f87e09d.css"" rel=""stylesheet""><style type='text/css'>body { background: rgb(34, 36, 38) !important }</style>";
|
||||
public static readonly ResourceLink AppLogo = new ResourceLink("https://ton.twimg.com/tduck/avatar", ResourceHandler.FromByteArray(Properties.Resources.avatar, "image/png"));
|
||||
|
||||
public static TweetNotification Example(string html, int characters){
|
||||
return new TweetNotification(string.Empty, string.Empty, "Home", html, characters, string.Empty, string.Empty, true);
|
||||
@@ -54,17 +53,14 @@ namespace TweetDuck.Core.Notification{
|
||||
return 2000+Math.Max(1000, value*characters);
|
||||
}
|
||||
|
||||
public string GenerateHtml(string bodyClasses = null, bool enableCustomCSS = true){
|
||||
public string GenerateHtml(string bodyClasses, Control sync){
|
||||
StringBuilder build = new StringBuilder();
|
||||
build.Append("<!DOCTYPE html>");
|
||||
build.Append(TweetDeckBridge.NotificationHeadLayout ?? DefaultHeadLayout);
|
||||
|
||||
if (enableCustomCSS){
|
||||
build.Append("<style type='text/css'>").Append(CustomCSS).Append("</style>");
|
||||
build.Append("<style type='text/css'>").Append(ScriptLoader.LoadResource("styles/notification.css", sync) ?? string.Empty).Append("</style>");
|
||||
|
||||
if (!string.IsNullOrEmpty(Program.UserConfig.CustomNotificationCSS)){
|
||||
build.Append("<style type='text/css'>").Append(Program.UserConfig.CustomNotificationCSS).Append("</style>");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Program.UserConfig.CustomNotificationCSS)){
|
||||
build.Append("<style type='text/css'>").Append(Program.UserConfig.CustomNotificationCSS).Append("</style>");
|
||||
}
|
||||
|
||||
build.Append("</head>");
|
||||
@@ -74,7 +70,7 @@ namespace TweetDuck.Core.Notification{
|
||||
build.Append(' ').Append(bodyClasses);
|
||||
}
|
||||
|
||||
build.Append('\'').Append(isExample ? " td-example-notification" : "").Append("><div class='column' style='width:100%!important;height:auto!important;overflow:initial!important;'>");
|
||||
build.Append('\'').Append(isExample ? " td-example-notification" : "").Append("><div class='column' style='width:100%!important;min-height:100vh!important;height:auto!important;overflow:initial!important;'>");
|
||||
build.Append(html);
|
||||
build.Append("</div></body>");
|
||||
build.Append("</html>");
|
||||
|
@@ -1,7 +1,11 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using TweetDuck.Data.Serialization;
|
||||
|
||||
namespace TweetDuck.Core.Other.Analytics{
|
||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Local")]
|
||||
sealed class AnalyticsFile{
|
||||
private static readonly FileSerializer<AnalyticsFile> Serializer = new FileSerializer<AnalyticsFile>();
|
||||
|
||||
@@ -10,15 +14,14 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
ConvertToString = value => value.ToBinary().ToString(),
|
||||
ConvertToObject = value => DateTime.FromBinary(long.Parse(value))
|
||||
});
|
||||
|
||||
Serializer.RegisterTypeConverter(typeof(Counter), new SingleTypeConverter<Counter>{
|
||||
ConvertToString = value => value.Value.ToString(),
|
||||
ConvertToObject = value => int.Parse(value)
|
||||
});
|
||||
}
|
||||
|
||||
public enum Event{
|
||||
OpenOptions, OpenPlugins, OpenAbout, OpenGuide,
|
||||
DesktopNotification, SoundNotification, MuteNotification,
|
||||
BrowserContextMenu, BrowserExtraMouseButton,
|
||||
NotificationContextMenu, NotificationExtraMouseButton, NotificationKeyboardShortcut,
|
||||
TweetScreenshot, TweetDetail, VideoPlay
|
||||
}
|
||||
public static readonly AnalyticsFile Dummy = new AnalyticsFile();
|
||||
|
||||
// STATE PROPERTIES
|
||||
|
||||
@@ -28,26 +31,35 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
|
||||
// USAGE DATA
|
||||
|
||||
public int CountOpenOptions { get; private set; } = 0;
|
||||
public int CountOpenPlugins { get; private set; } = 0;
|
||||
public int CountOpenAbout { get; private set; } = 0;
|
||||
public int CountOpenGuide { get; private set; } = 0;
|
||||
public Counter OpenOptions { get; private set; } = 0;
|
||||
public Counter OpenPlugins { get; private set; } = 0;
|
||||
public Counter OpenAbout { get; private set; } = 0;
|
||||
public Counter OpenGuide { get; private set; } = 0;
|
||||
|
||||
public int CountDesktopNotifications { get; private set; } = 0;
|
||||
public int CountSoundNotifications { get; private set; } = 0;
|
||||
public int CountMuteNotifications { get; private set; } = 0;
|
||||
public Counter DesktopNotifications { get; private set; } = 0;
|
||||
public Counter SoundNotifications { get; private set; } = 0;
|
||||
public Counter NotificationMutes { get; private set; } = 0;
|
||||
|
||||
public int CountBrowserContextMenus { get; private set; } = 0;
|
||||
public int CountBrowserExtraMouseButtons { get; private set; } = 0;
|
||||
public int CountNotificationContextMenus { get; private set; } = 0;
|
||||
public int CountNotificationExtraMouseButtons { get; private set; } = 0;
|
||||
public int CountNotificationKeyboardShortcuts { get; private set; } = 0;
|
||||
public Counter BrowserContextMenus { get; private set; } = 0;
|
||||
public Counter BrowserExtraMouseButtons { get; private set; } = 0;
|
||||
public Counter NotificationContextMenus { get; private set; } = 0;
|
||||
public Counter NotificationExtraMouseButtons { get; private set; } = 0;
|
||||
public Counter NotificationKeyboardShortcuts { get; private set; } = 0;
|
||||
|
||||
public int CountTweetScreenshots { get; private set; } = 0;
|
||||
public int CountTweetDetails { get; private set; } = 0;
|
||||
public int CountVideoPlays { get; private set; } = 0;
|
||||
public Counter BrowserReloads { get; private set; } = 0;
|
||||
public Counter CopiedUsernames { get; private set; } = 0;
|
||||
public Counter ViewedImages { get; private set; } = 0;
|
||||
public Counter DownloadedImages { get; private set; } = 0;
|
||||
public Counter DownloadedVideos { get; private set; } = 0;
|
||||
public Counter UsedROT13 { get; private set; } = 0;
|
||||
|
||||
public Counter TweetScreenshots { get; private set; } = 0;
|
||||
public Counter TweetDetails { get; private set; } = 0;
|
||||
public Counter VideoPlays { get; private set; } = 0;
|
||||
|
||||
// END OF DATA
|
||||
|
||||
public event EventHandler PropertyChanged;
|
||||
|
||||
private readonly string file;
|
||||
|
||||
@@ -55,30 +67,25 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public void TriggerEvent(Event e){
|
||||
switch(e){
|
||||
case Event.OpenOptions: ++CountOpenOptions; break;
|
||||
case Event.OpenPlugins: ++CountOpenPlugins; break;
|
||||
case Event.OpenAbout: ++CountOpenAbout; break;
|
||||
case Event.OpenGuide: ++CountOpenGuide; break;
|
||||
private AnalyticsFile(){
|
||||
this.file = null;
|
||||
}
|
||||
|
||||
case Event.DesktopNotification: ++CountDesktopNotifications; break;
|
||||
case Event.SoundNotification: ++CountSoundNotifications; break;
|
||||
case Event.MuteNotification: ++CountMuteNotifications; break;
|
||||
|
||||
case Event.BrowserContextMenu: ++CountBrowserContextMenus; break;
|
||||
case Event.BrowserExtraMouseButton: ++CountBrowserExtraMouseButtons; break;
|
||||
case Event.NotificationContextMenu: ++CountNotificationContextMenus; break;
|
||||
case Event.NotificationExtraMouseButton: ++CountNotificationExtraMouseButtons; break;
|
||||
case Event.NotificationKeyboardShortcut: ++CountNotificationKeyboardShortcuts; break;
|
||||
|
||||
case Event.TweetScreenshot: ++CountTweetScreenshots; break;
|
||||
case Event.TweetDetail: ++CountTweetDetails; break;
|
||||
case Event.VideoPlay: ++CountVideoPlays; break;
|
||||
private void SetupProperties(){
|
||||
foreach(Counter counter in GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(prop => prop.PropertyType == typeof(Counter)).Select(prop => (Counter)prop.GetValue(this))){
|
||||
counter.SetOwner(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPropertyChanged(){
|
||||
PropertyChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void Save(){
|
||||
if (file == null){
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
Serializer.Write(file, this);
|
||||
}catch(Exception e){
|
||||
@@ -94,8 +101,35 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
}catch(Exception e){
|
||||
Program.Reporter.HandleException("Analytics File Error", "Could not open the analytics file.", true, e);
|
||||
}
|
||||
|
||||
|
||||
config.SetupProperties();
|
||||
return config;
|
||||
}
|
||||
|
||||
public interface IProvider{
|
||||
AnalyticsFile AnalyticsFile { get; }
|
||||
}
|
||||
|
||||
public sealed class Counter{
|
||||
public int Value { get; private set; }
|
||||
|
||||
private AnalyticsFile owner;
|
||||
|
||||
public Counter(int value){
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public void SetOwner(AnalyticsFile owner){
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void Trigger(){
|
||||
++Value;
|
||||
owner?.OnPropertyChanged();
|
||||
}
|
||||
|
||||
public static implicit operator int(Counter counter) => counter.Value;
|
||||
public static implicit operator Counter(int value) => new Counter(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,8 @@
|
||||
using System;
|
||||
// Uncomment to debug reports locally
|
||||
// #define ANALYTICS_LOCALHOST
|
||||
// #define ANALYTICS_INSTANT
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
@@ -8,8 +12,15 @@ using TweetDuck.Plugins;
|
||||
|
||||
namespace TweetDuck.Core.Other.Analytics{
|
||||
sealed class AnalyticsManager : IDisposable{
|
||||
private static readonly TimeSpan CollectionInterval = TimeSpan.FromDays(7);
|
||||
private static readonly Uri CollectionUrl = new Uri("https://tweetduck.chylex.com/breadcrumb/report");
|
||||
private static readonly TimeSpan CollectionInterval = TimeSpan.FromDays(14);
|
||||
|
||||
private static readonly Uri CollectionUrl = new Uri(
|
||||
#if (DEBUG && ANALYTICS_LOCALHOST)
|
||||
"http://localhost/newhome/tweetduck/~breadcrumb/request.php?type=report"
|
||||
#else
|
||||
"https://tweetduck.chylex.com/breadcrumb/report"
|
||||
#endif
|
||||
);
|
||||
|
||||
public AnalyticsFile File { get; }
|
||||
|
||||
@@ -20,7 +31,9 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
public AnalyticsManager(FormBrowser browser, PluginManager plugins, string file){
|
||||
this.browser = browser;
|
||||
this.plugins = plugins;
|
||||
|
||||
this.File = AnalyticsFile.Load(file);
|
||||
this.File.PropertyChanged += File_PropertyChanged;
|
||||
|
||||
this.currentTimer = new Timer{ SynchronizingObject = browser };
|
||||
this.currentTimer.Elapsed += currentTimer_Elapsed;
|
||||
@@ -29,14 +42,20 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
this.saveTimer.Elapsed += saveTimer_Elapsed;
|
||||
|
||||
if (this.File.LastCollectionVersion != Program.VersionTag){
|
||||
ScheduleReportIn(TimeSpan.FromHours(12), string.Empty);
|
||||
ScheduleReportIn(TimeSpan.FromHours(8), string.Empty);
|
||||
}
|
||||
else{
|
||||
RestartTimer();
|
||||
}
|
||||
|
||||
#if (DEBUG && ANALYTICS_INSTANT)
|
||||
SendReport();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
File.PropertyChanged -= File_PropertyChanged;
|
||||
|
||||
if (saveTimer.Enabled){
|
||||
File.Save();
|
||||
}
|
||||
@@ -45,8 +64,7 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
saveTimer.Dispose();
|
||||
}
|
||||
|
||||
public void TriggerEvent(AnalyticsFile.Event e){
|
||||
File.TriggerEvent(e);
|
||||
private void File_PropertyChanged(object sender, EventArgs e){
|
||||
saveTimer.Enabled = true;
|
||||
}
|
||||
|
||||
@@ -72,7 +90,7 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
TimeSpan diff = DateTime.Now.Subtract(File.LastDataCollection);
|
||||
int minutesTillNext = (int)(CollectionInterval.TotalMinutes-Math.Floor(diff.TotalMinutes));
|
||||
|
||||
currentTimer.Interval = Math.Max(minutesTillNext, 1)*60000;
|
||||
currentTimer.Interval = Math.Max(minutesTillNext, 2)*60000;
|
||||
currentTimer.Start();
|
||||
}
|
||||
|
||||
@@ -95,7 +113,7 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
Task.Factory.StartNew(() => {
|
||||
AnalyticsReport report = AnalyticsReportGenerator.Create(File, info, plugins);
|
||||
|
||||
#if DEBUG
|
||||
#if (DEBUG && !ANALYTICS_INSTANT)
|
||||
System.Diagnostics.Debugger.Break();
|
||||
#endif
|
||||
|
||||
@@ -122,6 +140,14 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
message = "HTTP Error "+(response != null ? $"{(int)response.StatusCode} ({response.StatusDescription})" : "(unknown code)");
|
||||
break;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
System.IO.Stream responseStream = e.Response.GetResponseStream();
|
||||
|
||||
if (responseStream != null){
|
||||
System.Diagnostics.Debug.WriteLine(new System.IO.StreamReader(responseStream).ReadToEnd());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ScheduleReportIn(TimeSpan.FromHours(4), message ?? "Error: "+(task.Exception.InnerException?.Message ?? task.Exception.Message));
|
||||
|
@@ -8,10 +8,10 @@ using TweetDuck.Configuration;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Text.RegularExpressions;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
|
||||
namespace TweetDuck.Core.Other.Analytics{
|
||||
static class AnalyticsReportGenerator{
|
||||
@@ -21,7 +21,7 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
return new AnalyticsReport{
|
||||
{ "App Version" , Program.VersionTag },
|
||||
{ "App Type" , Program.IsPortable ? "portable" : "installed" },
|
||||
{ "App Dev Tools" , Bool(ContextMenuBase.HasDevTools) },
|
||||
{ "App Dev Tools" , Bool(BrowserUtils.HasDevTools) },
|
||||
0,
|
||||
{ "System Name" , SystemName },
|
||||
{ "System Edition" , SystemEdition },
|
||||
@@ -36,15 +36,23 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
{ "Screen Resolution" , info.Resolution ?? "(unknown)" },
|
||||
{ "Screen DPI" , info.DPI != null ? Exact(info.DPI.Value) : "(unknown)" },
|
||||
0,
|
||||
{ "Hardware Acceleration" , Bool(SysConfig.HardwareAcceleration) },
|
||||
{ "Hardware Acceleration" , Bool(SysConfig.HardwareAcceleration) },
|
||||
{ "Clear Cache Automatically" , Bool(SysConfig.ClearCacheAutomatically) },
|
||||
{ "Clear Cache Threshold" , Exact(SysConfig.ClearCacheThreshold) },
|
||||
0,
|
||||
{ "Expand Links" , Bool(UserConfig.ExpandLinksOnHover) },
|
||||
{ "Switch Account Selectors" , Bool(UserConfig.SwitchAccountSelectors) },
|
||||
{ "Search In First Column" , Bool(UserConfig.OpenSearchInFirstColumn) },
|
||||
{ "Keep Like Follow Dialogs Open" , Bool(UserConfig.KeepLikeFollowDialogsOpen) },
|
||||
{ "Best Image Quality" , Bool(UserConfig.BestImageQuality) },
|
||||
{ "Spell Check" , Bool(UserConfig.EnableSpellCheck) },
|
||||
{ "Zoom" , Exact(UserConfig.ZoomLevel) },
|
||||
{ "Animated Images" , Bool(UserConfig.EnableAnimatedImages) },
|
||||
0,
|
||||
{ "Smooth Scrolling" , Bool(UserConfig.EnableSmoothScrolling) },
|
||||
{ "Custom Browser" , CustomBrowser },
|
||||
{ "Zoom" , Exact(UserConfig.ZoomLevel) },
|
||||
0,
|
||||
{ "Spell Check" , Bool(UserConfig.EnableSpellCheck) },
|
||||
{ "Spell Check Language" , UserConfig.SpellCheckLanguage.ToLower() },
|
||||
{ "Translation Target Language" , UserConfig.TranslationTarget },
|
||||
0,
|
||||
{ "Updates" , Bool(UserConfig.EnableUpdateCheck) },
|
||||
{ "Update Dismissed" , Bool(!string.IsNullOrEmpty(UserConfig.DismissedUpdate)) },
|
||||
@@ -70,8 +78,8 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
{ "Custom Browser CSS" , RoundUp((UserConfig.CustomBrowserCSS ?? string.Empty).Length, 50) },
|
||||
{ "Custom Notification CSS" , RoundUp((UserConfig.CustomNotificationCSS ?? string.Empty).Length, 50) },
|
||||
0,
|
||||
{ "Plugins All" , List(plugins.Plugins.Select(plugin => plugin.Identifier)) },
|
||||
{ "Plugins Enabled" , List(plugins.Plugins.Where(plugin => plugins.Config.IsEnabled(plugin)).Select(plugin => plugin.Identifier)) },
|
||||
{ "Plugins All" , List(plugins.Plugins.Select(Plugin)) },
|
||||
{ "Plugins Enabled" , List(plugins.Plugins.Where(plugin => plugins.Config.IsEnabled(plugin)).Select(Plugin)) },
|
||||
0,
|
||||
{ "Theme" , Dict(editLayoutDesign, "_theme", "light/def") },
|
||||
{ "Column Width" , Dict(editLayoutDesign, "columnWidth", "310px/def") },
|
||||
@@ -87,21 +95,27 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
{ "Reply Account Mode" , ReplyAccountConfigFromPlugin },
|
||||
{ "Template Count" , Exact(TemplateCountFromPlugin) },
|
||||
0,
|
||||
{ "Opened Options" , LogRound(file.CountOpenOptions, 4) },
|
||||
{ "Opened Plugins" , LogRound(file.CountOpenPlugins, 4) },
|
||||
{ "Opened About" , LogRound(file.CountOpenAbout, 4) },
|
||||
{ "Opened Guide" , LogRound(file.CountOpenGuide, 4) },
|
||||
{ "Desktop Notifications" , LogRound(file.CountDesktopNotifications, 5) },
|
||||
{ "Sound Notifications" , LogRound(file.CountSoundNotifications, 5) },
|
||||
{ "Mute Notifications" , LogRound(file.CountMuteNotifications, 2) },
|
||||
{ "Browser Context Menus" , LogRound(file.CountBrowserContextMenus, 2) },
|
||||
{ "Browser Extra Mouse Buttons" , LogRound(file.CountBrowserExtraMouseButtons, 2) },
|
||||
{ "Notification Context Menus" , LogRound(file.CountNotificationContextMenus, 2) },
|
||||
{ "Notification Extra Mouse Buttons" , LogRound(file.CountNotificationExtraMouseButtons, 2) },
|
||||
{ "Notification Keyboard Shortcuts" , LogRound(file.CountNotificationKeyboardShortcuts, 2) },
|
||||
{ "Tweet Screenshots" , LogRound(file.CountTweetScreenshots, 2) },
|
||||
{ "Tweet Details" , LogRound(file.CountTweetDetails, 2) },
|
||||
{ "Video Plays" , LogRound(file.CountVideoPlays, 4) }
|
||||
{ "Opened Options" , LogRound(file.OpenOptions, 4) },
|
||||
{ "Opened Plugins" , LogRound(file.OpenPlugins, 4) },
|
||||
{ "Opened About" , LogRound(file.OpenAbout, 4) },
|
||||
{ "Opened Guide" , LogRound(file.OpenGuide, 4) },
|
||||
{ "Desktop Notifications" , LogRound(file.DesktopNotifications, 5) },
|
||||
{ "Sound Notifications" , LogRound(file.SoundNotifications, 5) },
|
||||
{ "Notification Mutes" , LogRound(file.NotificationMutes, 2) },
|
||||
{ "Browser Context Menus" , LogRound(file.BrowserContextMenus, 2) },
|
||||
{ "Browser Extra Mouse Buttons" , LogRound(file.BrowserExtraMouseButtons, 2) },
|
||||
{ "Notification Context Menus" , LogRound(file.NotificationContextMenus, 2) },
|
||||
{ "Notification Extra Mouse Buttons" , LogRound(file.NotificationExtraMouseButtons, 2) },
|
||||
{ "Notification Keyboard Shortcuts" , LogRound(file.NotificationKeyboardShortcuts, 2) },
|
||||
{ "Browser Reloads" , LogRound(file.BrowserReloads, 2) },
|
||||
{ "Copied Usernames" , LogRound(file.CopiedUsernames, 2) },
|
||||
{ "Viewed Images" , LogRound(file.ViewedImages, 2) },
|
||||
{ "Downloaded Images" , LogRound(file.DownloadedImages, 2) },
|
||||
{ "Downloaded Videos" , LogRound(file.DownloadedVideos, 2) },
|
||||
{ "Used ROT13" , LogRound(file.UsedROT13, 2) },
|
||||
{ "Tweet Screenshots" , LogRound(file.TweetScreenshots, 2) },
|
||||
{ "Tweet Details" , LogRound(file.TweetDetails, 2) },
|
||||
{ "Video Plays" , LogRound(file.VideoPlays, 4) }
|
||||
}.FinalizeReport();
|
||||
}
|
||||
|
||||
@@ -112,6 +126,7 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
private static string Exact(int value) => value.ToString();
|
||||
private static string RoundUp(int value, int multiple) => (multiple*(int)Math.Ceiling((double)value/multiple)).ToString();
|
||||
private static string LogRound(int value, int logBase) => (value <= 0 ? 0 : (int)Math.Pow(logBase, Math.Floor(Math.Log(value, logBase)))).ToString();
|
||||
private static string Plugin(Plugin plugin) => plugin.Group.GetIdentifierPrefixShort()+plugin.Identifier.Substring(plugin.Group.GetIdentifierPrefix().Length);
|
||||
private static string Dict(Dictionary<string, string> dict, string key, string def = "(unknown)") => dict.TryGetValue(key, out string value) ? value : def;
|
||||
private static string List(IEnumerable<string> list) => string.Join("|", list.DefaultIfEmpty("(none)"));
|
||||
|
||||
@@ -182,6 +197,12 @@ namespace TweetDuck.Core.Other.Analytics{
|
||||
ProgramArguments = args.Keys.Select(key => key.TrimStart('-')).ToArray();
|
||||
}
|
||||
|
||||
private static string CustomBrowser{
|
||||
get{
|
||||
return Path.GetFileName(UserConfig.BrowserPath) ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private static string TrayMode{
|
||||
get{
|
||||
switch(UserConfig.TrayBehavior){
|
||||
|
27
Core/Other/FormAbout.Designer.cs
generated
27
Core/Other/FormAbout.Designer.cs
generated
@@ -23,7 +23,6 @@ namespace TweetDuck.Core.Other {
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormAbout));
|
||||
this.pictureLogo = new System.Windows.Forms.PictureBox();
|
||||
this.labelDescription = new System.Windows.Forms.Label();
|
||||
this.labelTips = new System.Windows.Forms.LinkLabel();
|
||||
@@ -42,6 +41,7 @@ namespace TweetDuck.Core.Other {
|
||||
this.pictureLogo.Location = new System.Drawing.Point(12, 12);
|
||||
this.pictureLogo.Name = "pictureLogo";
|
||||
this.pictureLogo.Size = new System.Drawing.Size(96, 96);
|
||||
this.pictureLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.pictureLogo.TabIndex = 0;
|
||||
this.pictureLogo.TabStop = false;
|
||||
//
|
||||
@@ -50,23 +50,22 @@ namespace TweetDuck.Core.Other {
|
||||
this.labelDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelDescription.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDescription.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDescription.Location = new System.Drawing.Point(114, 12);
|
||||
this.labelDescription.Name = "labelDescription";
|
||||
this.labelDescription.Size = new System.Drawing.Size(232, 109);
|
||||
this.labelDescription.Size = new System.Drawing.Size(232, 113);
|
||||
this.labelDescription.TabIndex = 0;
|
||||
//
|
||||
// labelTips
|
||||
//
|
||||
this.labelTips.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.labelTips.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTips.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTips.LinkArea = new System.Windows.Forms.LinkArea(0, 0);
|
||||
this.labelTips.Location = new System.Drawing.Point(117, 0);
|
||||
this.labelTips.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelTips.Name = "labelTips";
|
||||
this.labelTips.Size = new System.Drawing.Size(99, 16);
|
||||
this.labelTips.Size = new System.Drawing.Size(99, 18);
|
||||
this.labelTips.TabIndex = 1;
|
||||
this.labelTips.TabStop = true;
|
||||
this.labelTips.Text = "Tips && Tricks";
|
||||
this.labelTips.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
this.labelTips.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClicked);
|
||||
@@ -75,14 +74,13 @@ namespace TweetDuck.Core.Other {
|
||||
//
|
||||
this.labelWebsite.AutoSize = true;
|
||||
this.labelWebsite.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.labelWebsite.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelWebsite.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelWebsite.LinkArea = new System.Windows.Forms.LinkArea(0, 0);
|
||||
this.labelWebsite.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelWebsite.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelWebsite.Name = "labelWebsite";
|
||||
this.labelWebsite.Size = new System.Drawing.Size(117, 16);
|
||||
this.labelWebsite.Size = new System.Drawing.Size(117, 18);
|
||||
this.labelWebsite.TabIndex = 0;
|
||||
this.labelWebsite.TabStop = true;
|
||||
this.labelWebsite.Text = "Official Website";
|
||||
this.labelWebsite.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.labelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClicked);
|
||||
@@ -98,24 +96,23 @@ namespace TweetDuck.Core.Other {
|
||||
this.tablePanelLinks.Controls.Add(this.labelIssues, 2, 0);
|
||||
this.tablePanelLinks.Controls.Add(this.labelWebsite, 0, 0);
|
||||
this.tablePanelLinks.Controls.Add(this.labelTips, 1, 0);
|
||||
this.tablePanelLinks.Location = new System.Drawing.Point(12, 124);
|
||||
this.tablePanelLinks.Location = new System.Drawing.Point(12, 128);
|
||||
this.tablePanelLinks.Name = "tablePanelLinks";
|
||||
this.tablePanelLinks.RowCount = 1;
|
||||
this.tablePanelLinks.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tablePanelLinks.Size = new System.Drawing.Size(334, 16);
|
||||
this.tablePanelLinks.Size = new System.Drawing.Size(334, 18);
|
||||
this.tablePanelLinks.TabIndex = 1;
|
||||
//
|
||||
// labelIssues
|
||||
//
|
||||
this.labelIssues.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.labelIssues.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelIssues.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelIssues.LinkArea = new System.Windows.Forms.LinkArea(0, 0);
|
||||
this.labelIssues.Location = new System.Drawing.Point(216, 0);
|
||||
this.labelIssues.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelIssues.Name = "labelIssues";
|
||||
this.labelIssues.Size = new System.Drawing.Size(118, 16);
|
||||
this.labelIssues.Size = new System.Drawing.Size(118, 18);
|
||||
this.labelIssues.TabIndex = 2;
|
||||
this.labelIssues.TabStop = true;
|
||||
this.labelIssues.Text = "Report an Issue";
|
||||
this.labelIssues.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.labelIssues.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClicked);
|
||||
@@ -125,7 +122,7 @@ namespace TweetDuck.Core.Other {
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.White;
|
||||
this.ClientSize = new System.Drawing.Size(358, 152);
|
||||
this.ClientSize = new System.Drawing.Size(358, 156);
|
||||
this.Controls.Add(this.tablePanelLinks);
|
||||
this.Controls.Add(this.labelDescription);
|
||||
this.Controls.Add(this.pictureLogo);
|
||||
|
@@ -5,7 +5,7 @@ using System.Windows.Forms;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormAbout : Form{
|
||||
sealed partial class FormAbout : Form, FormManager.IAppDialog{
|
||||
private const string TipsLink = "https://github.com/chylex/TweetDuck/wiki";
|
||||
private const string IssuesLink = "https://github.com/chylex/TweetDuck/issues";
|
||||
|
||||
|
@@ -6,16 +6,18 @@ using CefSharp.WinForms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Handling.General;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
using TweetDuck.Core.Utils;
|
||||
using System.Text.RegularExpressions;
|
||||
using TweetDuck.Data;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormGuide : Form{
|
||||
sealed partial class FormGuide : Form, FormManager.IAppDialog{
|
||||
private const string GuideUrl = "https://tweetduck.chylex.com/guide/v2/";
|
||||
private const string GuidePathRegex = @"^guide(?:/v\d+)?(?:/(#.*))?";
|
||||
|
||||
private static readonly ResourceLink DummyPage = new ResourceLink("http://td/dummy", ResourceHandler.FromString(""));
|
||||
|
||||
public static bool CheckGuideUrl(string url, out string hash){
|
||||
if (!url.Contains("//tweetduck.chylex.com/guide")){
|
||||
hash = null;
|
||||
@@ -43,7 +45,7 @@ namespace TweetDuck.Core.Other{
|
||||
FormBrowser owner = FormManager.TryFind<FormBrowser>();
|
||||
|
||||
if (owner != null){
|
||||
owner.TriggerAnalyticsEvent(AnalyticsFile.Event.OpenGuide);
|
||||
owner.AnalyticsFile.OpenGuide.Trigger();
|
||||
new FormGuide(url, owner).Show(owner);
|
||||
}
|
||||
}
|
||||
@@ -54,22 +56,20 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
private readonly ChromiumWebBrowser browser;
|
||||
private string nextUrl;
|
||||
|
||||
private FormGuide(string url, Form owner){
|
||||
private FormGuide(string url, FormBrowser owner){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Guide";
|
||||
|
||||
if (owner != null){
|
||||
Size = new Size(owner.Size.Width*3/4, owner.Size.Height*3/4);
|
||||
VisibleChanged += (sender, args) => this.MoveToCenter(owner);
|
||||
}
|
||||
Size = new Size(owner.Size.Width*3/4, owner.Size.Height*3/4);
|
||||
VisibleChanged += (sender, args) => this.MoveToCenter(owner);
|
||||
|
||||
this.browser = new ChromiumWebBrowser(url){
|
||||
MenuHandler = new ContextMenuGuide(),
|
||||
MenuHandler = new ContextMenuGuide(owner),
|
||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||
LifeSpanHandler = new LifeSpanHandler(),
|
||||
RequestHandler = new RequestHandlerBrowser()
|
||||
RequestHandler = new RequestHandlerBase(true)
|
||||
};
|
||||
|
||||
browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||
@@ -79,6 +79,9 @@ namespace TweetDuck.Core.Other{
|
||||
browser.BrowserSettings.BackgroundColor = (uint)BackColor.ToArgb();
|
||||
browser.Dock = DockStyle.None;
|
||||
browser.Location = ControlExtensions.InvisibleLocation;
|
||||
|
||||
browser.SetupResourceHandler(DummyPage);
|
||||
|
||||
Controls.Add(browser);
|
||||
|
||||
Disposed += (sender, args) => {
|
||||
@@ -90,21 +93,26 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
private void Reload(string url){
|
||||
nextUrl = url;
|
||||
browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||
browser.Dock = DockStyle.None;
|
||||
browser.Location = ControlExtensions.InvisibleLocation;
|
||||
browser.Load("about:blank");
|
||||
browser.Load(url);
|
||||
browser.Load(DummyPage.Url);
|
||||
}
|
||||
|
||||
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
||||
if (!e.IsLoading && browser.Address != "about:blank"){
|
||||
this.InvokeAsyncSafe(() => {
|
||||
browser.Location = Point.Empty;
|
||||
browser.Dock = DockStyle.Fill;
|
||||
});
|
||||
if (!e.IsLoading){
|
||||
if (browser.Address == DummyPage.Url){
|
||||
browser.Load(nextUrl);
|
||||
}
|
||||
else{
|
||||
this.InvokeAsyncSafe(() => {
|
||||
browser.Location = Point.Empty;
|
||||
browser.Dock = DockStyle.Fill;
|
||||
});
|
||||
|
||||
browser.LoadingStateChanged -= browser_LoadingStateChanged;
|
||||
browser.LoadingStateChanged -= browser_LoadingStateChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +121,6 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
// idiot chromium
|
||||
ScriptLoader.ExecuteScript(e.Frame, "Array.prototype.forEach.call(document.getElementsByTagName('A'), ele => ele.addEventListener('click', e => { e.preventDefault(); window.open(ele.getAttribute('href')); }))", "gen:links");
|
||||
}
|
||||
|
||||
|
37
Core/Other/FormPlugins.Designer.cs
generated
37
Core/Other/FormPlugins.Designer.cs
generated
@@ -23,20 +23,23 @@
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.btnReload = new System.Windows.Forms.Button();
|
||||
this.btnOpenFolder = new System.Windows.Forms.Button();
|
||||
this.flowLayoutPlugins = new TweetDuck.Plugins.Controls.PluginListFlowLayout();
|
||||
this.timerLayout = new System.Windows.Forms.Timer(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.AutoSize = true;
|
||||
this.btnClose.Location = new System.Drawing.Point(643, 439);
|
||||
this.btnClose.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnClose.Location = new System.Drawing.Point(642, 433);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnClose.Size = new System.Drawing.Size(49, 23);
|
||||
this.btnClose.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnClose.Size = new System.Drawing.Size(50, 25);
|
||||
this.btnClose.TabIndex = 1;
|
||||
this.btnClose.Text = "Close";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
@@ -46,10 +49,11 @@
|
||||
//
|
||||
this.btnReload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnReload.AutoSize = true;
|
||||
this.btnReload.Location = new System.Drawing.Point(131, 439);
|
||||
this.btnReload.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnReload.Location = new System.Drawing.Point(141, 433);
|
||||
this.btnReload.Name = "btnReload";
|
||||
this.btnReload.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnReload.Size = new System.Drawing.Size(71, 23);
|
||||
this.btnReload.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnReload.Size = new System.Drawing.Size(74, 25);
|
||||
this.btnReload.TabIndex = 2;
|
||||
this.btnReload.Text = "Reload All";
|
||||
this.btnReload.UseVisualStyleBackColor = true;
|
||||
@@ -59,10 +63,11 @@
|
||||
//
|
||||
this.btnOpenFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnOpenFolder.AutoSize = true;
|
||||
this.btnOpenFolder.Location = new System.Drawing.Point(12, 439);
|
||||
this.btnOpenFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnOpenFolder.Location = new System.Drawing.Point(12, 433);
|
||||
this.btnOpenFolder.Name = "btnOpenFolder";
|
||||
this.btnOpenFolder.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnOpenFolder.Size = new System.Drawing.Size(113, 23);
|
||||
this.btnOpenFolder.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnOpenFolder.Size = new System.Drawing.Size(123, 25);
|
||||
this.btnOpenFolder.TabIndex = 3;
|
||||
this.btnOpenFolder.Text = "Open Plugin Folder";
|
||||
this.btnOpenFolder.UseVisualStyleBackColor = true;
|
||||
@@ -77,22 +82,29 @@
|
||||
this.flowLayoutPlugins.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowLayoutPlugins.Location = new System.Drawing.Point(12, 12);
|
||||
this.flowLayoutPlugins.Name = "flowLayoutPlugins";
|
||||
this.flowLayoutPlugins.Size = new System.Drawing.Size(680, 421);
|
||||
this.flowLayoutPlugins.Size = new System.Drawing.Size(680, 415);
|
||||
this.flowLayoutPlugins.TabIndex = 0;
|
||||
this.flowLayoutPlugins.WrapContents = false;
|
||||
this.flowLayoutPlugins.Resize += new System.EventHandler(this.flowLayoutPlugins_Resize);
|
||||
//
|
||||
// timerLayout
|
||||
//
|
||||
this.timerLayout.Interval = 99;
|
||||
this.timerLayout.Tick += new System.EventHandler(this.timerLayout_Tick);
|
||||
//
|
||||
// FormPlugins
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(704, 474);
|
||||
this.ClientSize = new System.Drawing.Size(704, 470);
|
||||
this.Controls.Add(this.flowLayoutPlugins);
|
||||
this.Controls.Add(this.btnOpenFolder);
|
||||
this.Controls.Add(this.btnReload);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Icon = global::TweetDuck.Properties.Resources.icon;
|
||||
this.MinimumSize = new System.Drawing.Size(480, 320);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(640, 360);
|
||||
this.Name = "FormPlugins";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.ResumeLayout(false);
|
||||
@@ -106,5 +118,6 @@
|
||||
private System.Windows.Forms.Button btnReload;
|
||||
private System.Windows.Forms.Button btnOpenFolder;
|
||||
private Plugins.Controls.PluginListFlowLayout flowLayoutPlugins;
|
||||
private System.Windows.Forms.Timer timerLayout;
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Controls;
|
||||
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormPlugins : Form{
|
||||
sealed partial class FormPlugins : Form, FormManager.IAppDialog{
|
||||
private readonly PluginManager pluginManager;
|
||||
|
||||
public FormPlugins(){
|
||||
@@ -19,15 +19,23 @@ namespace TweetDuck.Core.Other{
|
||||
public FormPlugins(PluginManager pluginManager) : this(){
|
||||
this.pluginManager = pluginManager;
|
||||
|
||||
if (!Program.UserConfig.PluginsWindowSize.IsEmpty){
|
||||
Size targetSize = Program.UserConfig.PluginsWindowSize;
|
||||
Size = new Size(Math.Max(MinimumSize.Width, targetSize.Width), Math.Max(MinimumSize.Height, targetSize.Height));
|
||||
}
|
||||
|
||||
Shown += (sender, args) => {
|
||||
Program.UserConfig.PluginsWindow.Restore(this, false);
|
||||
ReloadPluginList();
|
||||
};
|
||||
|
||||
FormClosed += (sender, args) => {
|
||||
Program.UserConfig.PluginsWindow.Save(this);
|
||||
Program.UserConfig.PluginsWindowSize = Size;
|
||||
Program.UserConfig.Save();
|
||||
};
|
||||
|
||||
ResizeEnd += (sender, args) => {
|
||||
timerLayout.Start();
|
||||
};
|
||||
}
|
||||
|
||||
private int GetPluginOrderIndex(Plugin plugin){
|
||||
@@ -50,18 +58,26 @@ namespace TweetDuck.Core.Other{
|
||||
|
||||
flowLayoutPlugins.ResumeLayout(true);
|
||||
|
||||
// sorry, I guess...
|
||||
Padding = new Padding(Padding.Left, Padding.Top, Padding.Right+1, Padding.Bottom);
|
||||
Padding = new Padding(Padding.Left, Padding.Top, Padding.Right-1, Padding.Bottom);
|
||||
timerLayout_Tick(null, EventArgs.Empty);
|
||||
timerLayout.Start();
|
||||
}
|
||||
|
||||
private void flowLayoutPlugins_Resize(object sender, EventArgs e){
|
||||
if (flowLayoutPlugins.Controls.Count == 0){
|
||||
private void timerLayout_Tick(object sender, EventArgs e){
|
||||
timerLayout.Stop();
|
||||
|
||||
// stupid WinForms scrollbars and panels
|
||||
Padding = new Padding(Padding.Left, Padding.Top, Padding.Right+1, Padding.Bottom+1);
|
||||
Padding = new Padding(Padding.Left, Padding.Top, Padding.Right-1, Padding.Bottom-1);
|
||||
}
|
||||
|
||||
public void flowLayoutPlugins_Resize(object sender, EventArgs e){
|
||||
Control lastPlugin = flowLayoutPlugins.Controls.OfType<PluginControl>().LastOrDefault();
|
||||
|
||||
if (lastPlugin == null){
|
||||
return;
|
||||
}
|
||||
|
||||
Control lastControl = flowLayoutPlugins.Controls[flowLayoutPlugins.Controls.Count-1];
|
||||
bool showScrollBar = lastControl.Location.Y+lastControl.Height >= flowLayoutPlugins.Height;
|
||||
bool showScrollBar = lastPlugin.Location.Y+lastPlugin.Height+1 >= flowLayoutPlugins.Height;
|
||||
int horizontalOffset = showScrollBar ? SystemInformation.VerticalScrollBarWidth : 0;
|
||||
|
||||
flowLayoutPlugins.AutoScroll = showScrollBar;
|
||||
@@ -71,12 +87,12 @@ namespace TweetDuck.Core.Other{
|
||||
control.Width = flowLayoutPlugins.Width-control.Margin.Horizontal-horizontalOffset;
|
||||
}
|
||||
|
||||
lastControl.Visible = !showScrollBar;
|
||||
flowLayoutPlugins.Controls[flowLayoutPlugins.Controls.Count-1].Visible = !showScrollBar;
|
||||
flowLayoutPlugins.Focus();
|
||||
}
|
||||
|
||||
private void btnOpenFolder_Click(object sender, EventArgs e){
|
||||
using(Process.Start("explorer.exe", "\""+pluginManager.PathCustomPlugins+"\"")){}
|
||||
using(Process.Start("explorer.exe", '"'+pluginManager.PathCustomPlugins+'"')){}
|
||||
}
|
||||
|
||||
private void btnReload_Click(object sender, EventArgs e){
|
||||
|
20
Core/Other/FormSettings.Designer.cs
generated
20
Core/Other/FormSettings.Designer.cs
generated
@@ -33,10 +33,11 @@
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.AutoSize = true;
|
||||
this.btnClose.Location = new System.Drawing.Point(449, 483);
|
||||
this.btnClose.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnClose.Location = new System.Drawing.Point(448, 525);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnClose.Size = new System.Drawing.Size(49, 23);
|
||||
this.btnClose.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnClose.Size = new System.Drawing.Size(50, 25);
|
||||
this.btnClose.TabIndex = 3;
|
||||
this.btnClose.Text = "Close";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
@@ -52,7 +53,7 @@
|
||||
this.panelContents.Location = new System.Drawing.Point(135, 12);
|
||||
this.panelContents.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
|
||||
this.panelContents.Name = "panelContents";
|
||||
this.panelContents.Size = new System.Drawing.Size(363, 465);
|
||||
this.panelContents.Size = new System.Drawing.Size(363, 507);
|
||||
this.panelContents.TabIndex = 1;
|
||||
//
|
||||
// panelButtons
|
||||
@@ -63,17 +64,18 @@
|
||||
this.panelButtons.Location = new System.Drawing.Point(12, 12);
|
||||
this.panelButtons.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
|
||||
this.panelButtons.Name = "panelButtons";
|
||||
this.panelButtons.Size = new System.Drawing.Size(124, 465);
|
||||
this.panelButtons.Size = new System.Drawing.Size(124, 507);
|
||||
this.panelButtons.TabIndex = 0;
|
||||
//
|
||||
// btnManageOptions
|
||||
//
|
||||
this.btnManageOptions.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnManageOptions.AutoSize = true;
|
||||
this.btnManageOptions.Location = new System.Drawing.Point(12, 483);
|
||||
this.btnManageOptions.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnManageOptions.Location = new System.Drawing.Point(12, 525);
|
||||
this.btnManageOptions.Name = "btnManageOptions";
|
||||
this.btnManageOptions.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnManageOptions.Size = new System.Drawing.Size(101, 23);
|
||||
this.btnManageOptions.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnManageOptions.Size = new System.Drawing.Size(109, 25);
|
||||
this.btnManageOptions.TabIndex = 4;
|
||||
this.btnManageOptions.Text = "Manage Options";
|
||||
this.btnManageOptions.UseVisualStyleBackColor = true;
|
||||
@@ -83,7 +85,7 @@
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(510, 518);
|
||||
this.ClientSize = new System.Drawing.Size(510, 562);
|
||||
this.Controls.Add(this.btnManageOptions);
|
||||
this.Controls.Add(this.panelContents);
|
||||
this.Controls.Add(this.panelButtons);
|
||||
|
@@ -13,7 +13,7 @@ using TweetDuck.Plugins;
|
||||
using TweetDuck.Updates;
|
||||
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormSettings : Form{
|
||||
sealed partial class FormSettings : Form, FormManager.IAppDialog{
|
||||
private readonly FormBrowser browser;
|
||||
private readonly PluginManager plugins;
|
||||
|
||||
@@ -36,13 +36,13 @@ namespace TweetDuck.Core.Other{
|
||||
|
||||
this.buttonHeight = BrowserUtils.Scale(39, this.GetDPIScale()) | 1;
|
||||
|
||||
AddButton("General", () => new TabSettingsGeneral(this.browser, updates));
|
||||
AddButton("General", () => new TabSettingsGeneral(this.browser.ReloadColumns, updates));
|
||||
AddButton("Locales", () => new TabSettingsLocales());
|
||||
AddButton("System Tray", () => new TabSettingsTray());
|
||||
AddButton("Notifications", () => new TabSettingsNotifications(new FormNotificationExample(this.browser, this.plugins)));
|
||||
AddButton("Sounds", () => new TabSettingsSounds(this.browser.PlaySoundNotification));
|
||||
AddButton("Feedback", () => new TabSettingsFeedback(analytics, AnalyticsReportGenerator.ExternalInfo.From(this.browser), this.plugins));
|
||||
AddButton("Advanced", () => new TabSettingsAdvanced(this.browser.ReinjectCustomCSS));
|
||||
AddButton("Advanced", () => new TabSettingsAdvanced(this.browser.ReinjectCustomCSS, this.browser.OpenDevTools));
|
||||
|
||||
SelectTab(tabs[startTab ?? typeof(TabSettingsGeneral)]);
|
||||
}
|
||||
@@ -67,10 +67,13 @@ namespace TweetDuck.Core.Other{
|
||||
FormClosing -= FormSettings_FormClosing;
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK){
|
||||
browser.ResumeNotification();
|
||||
if (!dialog.IsRestarting){
|
||||
browser.ResumeNotification();
|
||||
|
||||
BrowserProcessHandler.UpdatePrefs();
|
||||
ShouldReloadBrowser = dialog.ShouldReloadBrowser;
|
||||
BrowserProcessHandler.UpdatePrefs();
|
||||
ShouldReloadBrowser = dialog.ShouldReloadBrowser;
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
else{
|
||||
@@ -87,6 +90,7 @@ namespace TweetDuck.Core.Other{
|
||||
FlatButton btn = new FlatButton{
|
||||
BackColor = SystemColors.Control,
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
Font = SystemFonts.MessageBoxFont,
|
||||
Location = new Point(0, (buttonHeight+1)*(panelButtons.Controls.Count/2)),
|
||||
Margin = new Padding(0),
|
||||
Size = new Size(panelButtons.Width, buttonHeight),
|
||||
@@ -153,6 +157,10 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
private void control_MouseLeave(object sender, EventArgs e){
|
||||
if (sender is ComboBox cb && cb.DroppedDown){
|
||||
return; // prevents comboboxes from closing when MouseLeave event triggers during opening animation
|
||||
}
|
||||
|
||||
panelContents.Focus();
|
||||
}
|
||||
|
||||
|
12
Core/Other/Interfaces/ITweetDeckBrowser.cs
Normal file
12
Core/Other/Interfaces/ITweetDeckBrowser.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using CefSharp;
|
||||
|
||||
namespace TweetDuck.Core.Other.Interfaces{
|
||||
interface ITweetDeckBrowser{
|
||||
bool IsTweetDeckWebsite { get; }
|
||||
|
||||
void RegisterBridge(string name, object obj);
|
||||
void OnFrameLoaded(Action<IFrame> callback);
|
||||
void ExecuteFunction(string name, params object[] args);
|
||||
}
|
||||
}
|
@@ -34,21 +34,23 @@
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textBoxReport.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.textBoxReport.Location = new System.Drawing.Point(12, 41);
|
||||
this.textBoxReport.Location = new System.Drawing.Point(12, 45);
|
||||
this.textBoxReport.Multiline = true;
|
||||
this.textBoxReport.Name = "textBoxReport";
|
||||
this.textBoxReport.ReadOnly = true;
|
||||
this.textBoxReport.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.textBoxReport.Size = new System.Drawing.Size(460, 480);
|
||||
this.textBoxReport.Size = new System.Drawing.Size(435, 474);
|
||||
this.textBoxReport.TabIndex = 1;
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnClose.Location = new System.Drawing.Point(416, 527);
|
||||
this.btnClose.AutoSize = true;
|
||||
this.btnClose.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnClose.Location = new System.Drawing.Point(397, 525);
|
||||
this.btnClose.Name = "btnClose";
|
||||
this.btnClose.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnClose.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnClose.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnClose.Size = new System.Drawing.Size(50, 25);
|
||||
this.btnClose.TabIndex = 2;
|
||||
this.btnClose.Text = "Close";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
@@ -56,23 +58,25 @@
|
||||
//
|
||||
// labelInfo
|
||||
//
|
||||
this.labelInfo.AutoSize = true;
|
||||
this.labelInfo.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelInfo.Location = new System.Drawing.Point(12, 9);
|
||||
this.labelInfo.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
|
||||
this.labelInfo.Name = "labelInfo";
|
||||
this.labelInfo.Size = new System.Drawing.Size(460, 26);
|
||||
this.labelInfo.Size = new System.Drawing.Size(434, 30);
|
||||
this.labelInfo.TabIndex = 0;
|
||||
this.labelInfo.Text = "When enabled, this data will be sent over a secure network roughly once every wee" +
|
||||
"k.\r\nSome numbers in the report were made imprecise on purpose.";
|
||||
this.labelInfo.Text = "When enabled, this data will be sent over a secure network roughly every 14 days." +
|
||||
"\r\nSome numbers in the report were made imprecise on purpose.";
|
||||
//
|
||||
// DialogSettingsAnalytics
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(484, 562);
|
||||
this.ClientSize = new System.Drawing.Size(459, 562);
|
||||
this.Controls.Add(this.labelInfo);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Controls.Add(this.textBoxReport);
|
||||
this.MinimumSize = new System.Drawing.Size(450, 340);
|
||||
this.MinimumSize = new System.Drawing.Size(475, 340);
|
||||
this.Name = "DialogSettingsAnalytics";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
|
@@ -27,40 +27,41 @@
|
||||
this.textBoxBrowserCSS = new System.Windows.Forms.TextBox();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.btnApply = new System.Windows.Forms.Button();
|
||||
this.splitContainer = new System.Windows.Forms.SplitContainer();
|
||||
this.labelBrowser = new System.Windows.Forms.Label();
|
||||
this.labelNotification = new System.Windows.Forms.Label();
|
||||
this.textBoxNotificationCSS = new System.Windows.Forms.TextBox();
|
||||
this.labelWarning = new System.Windows.Forms.Label();
|
||||
this.btnOpenWiki = new System.Windows.Forms.Button();
|
||||
this.btnOpenDevTools = new System.Windows.Forms.Button();
|
||||
this.timerTestBrowser = new System.Windows.Forms.Timer(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
this.splitContainer.SuspendLayout();
|
||||
this.tabPanel = new System.Windows.Forms.TabControl();
|
||||
this.tabPageBrowser = new System.Windows.Forms.TabPage();
|
||||
this.tabPageNotification = new System.Windows.Forms.TabPage();
|
||||
this.tabPanel.SuspendLayout();
|
||||
this.tabPageBrowser.SuspendLayout();
|
||||
this.tabPageNotification.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// textBoxBrowserCSS
|
||||
//
|
||||
this.textBoxBrowserCSS.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.textBoxBrowserCSS.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.textBoxBrowserCSS.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.textBoxBrowserCSS.Location = new System.Drawing.Point(0, 16);
|
||||
this.textBoxBrowserCSS.Location = new System.Drawing.Point(3, 3);
|
||||
this.textBoxBrowserCSS.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
|
||||
this.textBoxBrowserCSS.Multiline = true;
|
||||
this.textBoxBrowserCSS.Name = "textBoxBrowserCSS";
|
||||
this.textBoxBrowserCSS.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.textBoxBrowserCSS.Size = new System.Drawing.Size(378, 253);
|
||||
this.textBoxBrowserCSS.TabIndex = 1;
|
||||
this.textBoxBrowserCSS.Size = new System.Drawing.Size(426, 332);
|
||||
this.textBoxBrowserCSS.TabIndex = 0;
|
||||
this.textBoxBrowserCSS.WordWrap = false;
|
||||
this.textBoxBrowserCSS.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBoxCSS_KeyDown);
|
||||
this.textBoxBrowserCSS.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBoxBrowserCSS_KeyUp);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(654, 287);
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(337, 384);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
@@ -69,119 +70,105 @@
|
||||
// btnApply
|
||||
//
|
||||
this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnApply.Location = new System.Drawing.Point(716, 287);
|
||||
this.btnApply.AutoSize = true;
|
||||
this.btnApply.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnApply.Location = new System.Drawing.Point(400, 384);
|
||||
this.btnApply.Name = "btnApply";
|
||||
this.btnApply.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnApply.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnApply.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnApply.Size = new System.Drawing.Size(52, 25);
|
||||
this.btnApply.TabIndex = 1;
|
||||
this.btnApply.Text = "Apply";
|
||||
this.btnApply.UseVisualStyleBackColor = true;
|
||||
this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
|
||||
//
|
||||
// splitContainer
|
||||
//
|
||||
this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.splitContainer.Location = new System.Drawing.Point(12, 12);
|
||||
this.splitContainer.Name = "splitContainer";
|
||||
//
|
||||
// splitContainer.Panel1
|
||||
//
|
||||
this.splitContainer.Panel1.Controls.Add(this.labelBrowser);
|
||||
this.splitContainer.Panel1.Controls.Add(this.textBoxBrowserCSS);
|
||||
this.splitContainer.Panel1MinSize = 64;
|
||||
//
|
||||
// splitContainer.Panel2
|
||||
//
|
||||
this.splitContainer.Panel2.Controls.Add(this.labelNotification);
|
||||
this.splitContainer.Panel2.Controls.Add(this.textBoxNotificationCSS);
|
||||
this.splitContainer.Panel2MinSize = 64;
|
||||
this.splitContainer.Size = new System.Drawing.Size(760, 269);
|
||||
this.splitContainer.SplitterDistance = 378;
|
||||
this.splitContainer.SplitterWidth = 5;
|
||||
this.splitContainer.TabIndex = 0;
|
||||
//
|
||||
// labelBrowser
|
||||
//
|
||||
this.labelBrowser.AutoSize = true;
|
||||
this.labelBrowser.Location = new System.Drawing.Point(-3, 0);
|
||||
this.labelBrowser.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelBrowser.Name = "labelBrowser";
|
||||
this.labelBrowser.Size = new System.Drawing.Size(45, 13);
|
||||
this.labelBrowser.TabIndex = 0;
|
||||
this.labelBrowser.Text = "Browser";
|
||||
//
|
||||
// labelNotification
|
||||
//
|
||||
this.labelNotification.AutoSize = true;
|
||||
this.labelNotification.Location = new System.Drawing.Point(-3, 0);
|
||||
this.labelNotification.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelNotification.Name = "labelNotification";
|
||||
this.labelNotification.Size = new System.Drawing.Size(60, 13);
|
||||
this.labelNotification.TabIndex = 0;
|
||||
this.labelNotification.Text = "Notification";
|
||||
//
|
||||
// textBoxNotificationCSS
|
||||
//
|
||||
this.textBoxNotificationCSS.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.textBoxNotificationCSS.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.textBoxNotificationCSS.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.textBoxNotificationCSS.Location = new System.Drawing.Point(0, 16);
|
||||
this.textBoxNotificationCSS.Location = new System.Drawing.Point(3, 3);
|
||||
this.textBoxNotificationCSS.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
|
||||
this.textBoxNotificationCSS.Multiline = true;
|
||||
this.textBoxNotificationCSS.Name = "textBoxNotificationCSS";
|
||||
this.textBoxNotificationCSS.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.textBoxNotificationCSS.Size = new System.Drawing.Size(377, 253);
|
||||
this.textBoxNotificationCSS.TabIndex = 1;
|
||||
this.textBoxNotificationCSS.Size = new System.Drawing.Size(426, 332);
|
||||
this.textBoxNotificationCSS.TabIndex = 0;
|
||||
this.textBoxNotificationCSS.WordWrap = false;
|
||||
this.textBoxNotificationCSS.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBoxCSS_KeyDown);
|
||||
//
|
||||
// labelWarning
|
||||
// btnOpenDevTools
|
||||
//
|
||||
this.labelWarning.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelWarning.AutoSize = true;
|
||||
this.labelWarning.Location = new System.Drawing.Point(91, 292);
|
||||
this.labelWarning.Name = "labelWarning";
|
||||
this.labelWarning.Size = new System.Drawing.Size(341, 13);
|
||||
this.labelWarning.TabIndex = 3;
|
||||
this.labelWarning.Text = "The code is not validated, please make sure there are no syntax errors.";
|
||||
//
|
||||
// btnOpenWiki
|
||||
//
|
||||
this.btnOpenWiki.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnOpenWiki.Location = new System.Drawing.Point(12, 287);
|
||||
this.btnOpenWiki.Name = "btnOpenWiki";
|
||||
this.btnOpenWiki.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnOpenWiki.Size = new System.Drawing.Size(73, 23);
|
||||
this.btnOpenWiki.TabIndex = 4;
|
||||
this.btnOpenWiki.Text = "Open Wiki";
|
||||
this.btnOpenWiki.UseVisualStyleBackColor = true;
|
||||
this.btnOpenWiki.Click += new System.EventHandler(this.btnOpenWiki_Click);
|
||||
this.btnOpenDevTools.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnOpenDevTools.AutoSize = true;
|
||||
this.btnOpenDevTools.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.btnOpenDevTools.Location = new System.Drawing.Point(12, 384);
|
||||
this.btnOpenDevTools.Name = "btnOpenDevTools";
|
||||
this.btnOpenDevTools.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnOpenDevTools.Size = new System.Drawing.Size(104, 25);
|
||||
this.btnOpenDevTools.TabIndex = 3;
|
||||
this.btnOpenDevTools.Text = "Open Dev Tools";
|
||||
this.btnOpenDevTools.UseVisualStyleBackColor = true;
|
||||
this.btnOpenDevTools.Click += new System.EventHandler(this.btnOpenDevTools_Click);
|
||||
//
|
||||
// timerTestBrowser
|
||||
//
|
||||
this.timerTestBrowser.Interval = 500;
|
||||
this.timerTestBrowser.Interval = 400;
|
||||
this.timerTestBrowser.Tick += new System.EventHandler(this.timerTestBrowser_Tick);
|
||||
//
|
||||
// tabPanel
|
||||
//
|
||||
this.tabPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tabPanel.Controls.Add(this.tabPageBrowser);
|
||||
this.tabPanel.Controls.Add(this.tabPageNotification);
|
||||
this.tabPanel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.tabPanel.Location = new System.Drawing.Point(12, 12);
|
||||
this.tabPanel.Name = "tabPanel";
|
||||
this.tabPanel.SelectedIndex = 0;
|
||||
this.tabPanel.Size = new System.Drawing.Size(440, 366);
|
||||
this.tabPanel.TabIndex = 0;
|
||||
this.tabPanel.SelectedIndexChanged += new System.EventHandler(this.tabPanel_SelectedIndexChanged);
|
||||
//
|
||||
// tabPageBrowser
|
||||
//
|
||||
this.tabPageBrowser.Controls.Add(this.textBoxBrowserCSS);
|
||||
this.tabPageBrowser.Location = new System.Drawing.Point(4, 24);
|
||||
this.tabPageBrowser.Name = "tabPageBrowser";
|
||||
this.tabPageBrowser.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPageBrowser.Size = new System.Drawing.Size(432, 338);
|
||||
this.tabPageBrowser.TabIndex = 0;
|
||||
this.tabPageBrowser.Text = "Browser";
|
||||
this.tabPageBrowser.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tabPageNotification
|
||||
//
|
||||
this.tabPageNotification.Controls.Add(this.textBoxNotificationCSS);
|
||||
this.tabPageNotification.Location = new System.Drawing.Point(4, 24);
|
||||
this.tabPageNotification.Name = "tabPageNotification";
|
||||
this.tabPageNotification.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPageNotification.Size = new System.Drawing.Size(432, 338);
|
||||
this.tabPageNotification.TabIndex = 1;
|
||||
this.tabPageNotification.Text = "Notification";
|
||||
this.tabPageNotification.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DialogSettingsCSS
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(784, 322);
|
||||
this.Controls.Add(this.btnOpenWiki);
|
||||
this.Controls.Add(this.labelWarning);
|
||||
this.Controls.Add(this.splitContainer);
|
||||
this.ClientSize = new System.Drawing.Size(464, 421);
|
||||
this.Controls.Add(this.tabPanel);
|
||||
this.Controls.Add(this.btnOpenDevTools);
|
||||
this.Controls.Add(this.btnApply);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.MinimumSize = new System.Drawing.Size(600, 160);
|
||||
this.MinimumSize = new System.Drawing.Size(320, 240);
|
||||
this.Name = "DialogSettingsCSS";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.splitContainer.Panel1.ResumeLayout(false);
|
||||
this.splitContainer.Panel1.PerformLayout();
|
||||
this.splitContainer.Panel2.ResumeLayout(false);
|
||||
this.splitContainer.Panel2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
|
||||
this.splitContainer.ResumeLayout(false);
|
||||
this.tabPanel.ResumeLayout(false);
|
||||
this.tabPageBrowser.ResumeLayout(false);
|
||||
this.tabPageBrowser.PerformLayout();
|
||||
this.tabPageNotification.ResumeLayout(false);
|
||||
this.tabPageNotification.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@@ -192,12 +179,11 @@
|
||||
private System.Windows.Forms.TextBox textBoxBrowserCSS;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Button btnApply;
|
||||
private System.Windows.Forms.SplitContainer splitContainer;
|
||||
private System.Windows.Forms.TextBox textBoxNotificationCSS;
|
||||
private System.Windows.Forms.Label labelBrowser;
|
||||
private System.Windows.Forms.Label labelNotification;
|
||||
private System.Windows.Forms.Label labelWarning;
|
||||
private System.Windows.Forms.Button btnOpenWiki;
|
||||
private System.Windows.Forms.Button btnOpenDevTools;
|
||||
private System.Windows.Forms.Timer timerTestBrowser;
|
||||
private System.Windows.Forms.TabControl tabPanel;
|
||||
private System.Windows.Forms.TabPage tabPageBrowser;
|
||||
private System.Windows.Forms.TabPage tabPageNotification;
|
||||
}
|
||||
}
|
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
@@ -9,19 +11,108 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
public string NotificationCSS => textBoxNotificationCSS.Text;
|
||||
|
||||
private readonly Action<string> reinjectBrowserCSS;
|
||||
private readonly Action openDevTools;
|
||||
|
||||
public DialogSettingsCSS(Action<string> reinjectBrowserCSS){
|
||||
public DialogSettingsCSS(Action<string> reinjectBrowserCSS, Action openDevTools){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Options - CSS";
|
||||
|
||||
this.reinjectBrowserCSS = reinjectBrowserCSS;
|
||||
this.openDevTools = openDevTools;
|
||||
|
||||
textBoxBrowserCSS.EnableMultilineShortcuts();
|
||||
textBoxBrowserCSS.Text = Program.UserConfig.CustomBrowserCSS ?? "";
|
||||
|
||||
textBoxNotificationCSS.EnableMultilineShortcuts();
|
||||
textBoxNotificationCSS.Text = Program.UserConfig.CustomNotificationCSS ?? "";
|
||||
|
||||
if (!BrowserUtils.HasDevTools){
|
||||
btnOpenDevTools.Enabled = false;
|
||||
}
|
||||
|
||||
ActiveControl = textBoxBrowserCSS;
|
||||
textBoxBrowserCSS.Select(textBoxBrowserCSS.TextLength, 0);
|
||||
}
|
||||
|
||||
private void tabPanel_SelectedIndexChanged(object sender, EventArgs e){
|
||||
TextBox tb = tabPanel.SelectedTab.Controls.OfType<TextBox>().FirstOrDefault();
|
||||
|
||||
if (tb != null){
|
||||
tb.Focus();
|
||||
tb.Select(tb.TextLength, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void textBoxCSS_KeyDown(object sender, KeyEventArgs e){
|
||||
TextBox tb = (TextBox)sender;
|
||||
string text = tb.Text;
|
||||
|
||||
if (e.KeyCode == Keys.Back && e.Modifiers == Keys.Control){
|
||||
e.SuppressKeyPress = true;
|
||||
|
||||
int deleteTo = tb.SelectionStart;
|
||||
|
||||
if (deleteTo > 0){
|
||||
char initialChar = text[--deleteTo];
|
||||
bool shouldDeleteAlphanumeric = char.IsLetterOrDigit(initialChar);
|
||||
|
||||
while(--deleteTo >= 0){
|
||||
if ((shouldDeleteAlphanumeric && !char.IsLetterOrDigit(text[deleteTo])) ||
|
||||
(!shouldDeleteAlphanumeric && text[deleteTo] != initialChar)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(deleteTo < text.Length-1 && text[deleteTo] == '\r' && text[deleteTo+1] == '\n')){
|
||||
++deleteTo;
|
||||
}
|
||||
|
||||
tb.Select(deleteTo, tb.SelectionLength+tb.SelectionStart-deleteTo);
|
||||
tb.SelectedText = string.Empty;
|
||||
}
|
||||
}
|
||||
else if (e.KeyCode == Keys.Back && e.Modifiers == Keys.None){
|
||||
int deleteTo = tb.SelectionStart;
|
||||
|
||||
if (deleteTo > 1 && text[deleteTo-1] == ' ' && text[deleteTo-2] == ' '){
|
||||
e.SuppressKeyPress = true;
|
||||
|
||||
tb.Select(deleteTo-2, 2);
|
||||
tb.SelectedText = string.Empty;
|
||||
}
|
||||
}
|
||||
else if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.None && tb.SelectionLength == 0){
|
||||
int insertAt = tb.SelectionStart, cursorOffset = 0;
|
||||
string insertText;
|
||||
|
||||
if (insertAt == 0){
|
||||
return;
|
||||
}
|
||||
else if (text[insertAt-1] == '{'){
|
||||
insertText = Environment.NewLine+" ";
|
||||
|
||||
int nextBracket = insertAt < text.Length ? text.IndexOfAny(new char[]{ '{', '}' }, insertAt+1) : -1;
|
||||
|
||||
if (nextBracket == -1 || text[nextBracket] == '{'){
|
||||
string insertExtra = Environment.NewLine+"}";
|
||||
insertText += insertExtra;
|
||||
cursorOffset -= insertExtra.Length;
|
||||
}
|
||||
}
|
||||
else{
|
||||
int lineStart = text.LastIndexOf('\n', tb.SelectionStart-1);
|
||||
|
||||
Match match = Regex.Match(text.Substring(lineStart == -1 ? 0 : lineStart+1), "^([ \t]+)");
|
||||
insertText = match.Success ? Environment.NewLine+match.Groups[1].Value : null;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(insertText)){
|
||||
e.SuppressKeyPress = true;
|
||||
tb.Text = text.Insert(insertAt, insertText);
|
||||
tb.SelectionStart = insertAt+cursorOffset+insertText.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void textBoxBrowserCSS_KeyUp(object sender, KeyEventArgs e){
|
||||
@@ -34,8 +125,8 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
timerTestBrowser.Stop();
|
||||
}
|
||||
|
||||
private void btnOpenWiki_Click(object sender, EventArgs e){
|
||||
BrowserUtils.OpenExternalBrowser("https://github.com/chylex/TweetDuck/wiki");
|
||||
private void btnOpenDevTools_Click(object sender, EventArgs e){
|
||||
openDevTools();
|
||||
}
|
||||
|
||||
private void btnApply_Click(object sender, EventArgs e){
|
||||
|
@@ -36,19 +36,21 @@
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textBoxArgs.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.textBoxArgs.Location = new System.Drawing.Point(12, 28);
|
||||
this.textBoxArgs.Location = new System.Drawing.Point(12, 30);
|
||||
this.textBoxArgs.Multiline = true;
|
||||
this.textBoxArgs.Name = "textBoxArgs";
|
||||
this.textBoxArgs.Size = new System.Drawing.Size(460, 193);
|
||||
this.textBoxArgs.Size = new System.Drawing.Size(480, 189);
|
||||
this.textBoxArgs.TabIndex = 1;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(354, 227);
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(377, 225);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnCancel.TabIndex = 3;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
@@ -57,10 +59,12 @@
|
||||
// btnApply
|
||||
//
|
||||
this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnApply.Location = new System.Drawing.Point(416, 227);
|
||||
this.btnApply.AutoSize = true;
|
||||
this.btnApply.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnApply.Location = new System.Drawing.Point(440, 225);
|
||||
this.btnApply.Name = "btnApply";
|
||||
this.btnApply.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnApply.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnApply.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnApply.Size = new System.Drawing.Size(52, 25);
|
||||
this.btnApply.TabIndex = 2;
|
||||
this.btnApply.Text = "Apply";
|
||||
this.btnApply.UseVisualStyleBackColor = true;
|
||||
@@ -69,10 +73,12 @@
|
||||
// btnHelp
|
||||
//
|
||||
this.btnHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnHelp.Location = new System.Drawing.Point(12, 227);
|
||||
this.btnHelp.AutoSize = true;
|
||||
this.btnHelp.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnHelp.Location = new System.Drawing.Point(12, 225);
|
||||
this.btnHelp.Name = "btnHelp";
|
||||
this.btnHelp.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnHelp.Size = new System.Drawing.Size(124, 23);
|
||||
this.btnHelp.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnHelp.Size = new System.Drawing.Size(141, 25);
|
||||
this.btnHelp.TabIndex = 4;
|
||||
this.btnHelp.Text = "List of Chromium Args";
|
||||
this.btnHelp.UseVisualStyleBackColor = true;
|
||||
@@ -81,10 +87,11 @@
|
||||
// labelWarning
|
||||
//
|
||||
this.labelWarning.AutoSize = true;
|
||||
this.labelWarning.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelWarning.Location = new System.Drawing.Point(12, 9);
|
||||
this.labelWarning.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
|
||||
this.labelWarning.Name = "labelWarning";
|
||||
this.labelWarning.Size = new System.Drawing.Size(423, 13);
|
||||
this.labelWarning.Size = new System.Drawing.Size(478, 15);
|
||||
this.labelWarning.TabIndex = 0;
|
||||
this.labelWarning.Text = "Warning: Some arguments may cause the program to stop working, edit at your own r" +
|
||||
"isk.";
|
||||
@@ -93,13 +100,13 @@
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(484, 262);
|
||||
this.ClientSize = new System.Drawing.Size(504, 262);
|
||||
this.Controls.Add(this.labelWarning);
|
||||
this.Controls.Add(this.btnHelp);
|
||||
this.Controls.Add(this.btnApply);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.textBoxArgs);
|
||||
this.MinimumSize = new System.Drawing.Size(500, 160);
|
||||
this.MinimumSize = new System.Drawing.Size(520, 160);
|
||||
this.Name = "DialogSettingsCefArgs";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
|
@@ -26,26 +26,29 @@
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.btnContinue = new System.Windows.Forms.Button();
|
||||
this.cbConfig = new System.Windows.Forms.CheckBox();
|
||||
this.cbProgramConfig = new System.Windows.Forms.CheckBox();
|
||||
this.cbSession = new System.Windows.Forms.CheckBox();
|
||||
this.cbPluginData = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.panelExport = new System.Windows.Forms.Panel();
|
||||
this.panelDecision = new System.Windows.Forms.Panel();
|
||||
this.radioReset = new System.Windows.Forms.RadioButton();
|
||||
this.radioExport = new System.Windows.Forms.RadioButton();
|
||||
this.cbSystemConfig = new System.Windows.Forms.CheckBox();
|
||||
this.panelSelection = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.panelDecision = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.radioImport = new System.Windows.Forms.RadioButton();
|
||||
this.panelExport.SuspendLayout();
|
||||
this.radioExport = new System.Windows.Forms.RadioButton();
|
||||
this.radioReset = new System.Windows.Forms.RadioButton();
|
||||
this.panelSelection.SuspendLayout();
|
||||
this.panelDecision.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(176, 97);
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(165, 92);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnCancel.TabIndex = 4;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
@@ -56,127 +59,163 @@
|
||||
this.btnContinue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnContinue.AutoSize = true;
|
||||
this.btnContinue.Enabled = false;
|
||||
this.btnContinue.Location = new System.Drawing.Point(125, 97);
|
||||
this.btnContinue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnContinue.Location = new System.Drawing.Point(114, 92);
|
||||
this.btnContinue.Name = "btnContinue";
|
||||
this.btnContinue.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnContinue.Size = new System.Drawing.Size(45, 23);
|
||||
this.btnContinue.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnContinue.Size = new System.Drawing.Size(45, 25);
|
||||
this.btnContinue.TabIndex = 3;
|
||||
this.btnContinue.Text = "Next";
|
||||
this.btnContinue.UseVisualStyleBackColor = true;
|
||||
this.btnContinue.Click += new System.EventHandler(this.btnContinue_Click);
|
||||
//
|
||||
// cbConfig
|
||||
// cbProgramConfig
|
||||
//
|
||||
this.cbConfig.AutoSize = true;
|
||||
this.cbConfig.Location = new System.Drawing.Point(0, 3);
|
||||
this.cbConfig.Name = "cbConfig";
|
||||
this.cbConfig.Size = new System.Drawing.Size(104, 17);
|
||||
this.cbConfig.TabIndex = 0;
|
||||
this.cbConfig.Text = "Program Options";
|
||||
this.toolTip.SetToolTip(this.cbConfig, "Interface, notification, and update options.");
|
||||
this.cbConfig.UseVisualStyleBackColor = true;
|
||||
this.cbConfig.CheckedChanged += new System.EventHandler(this.cbConfig_CheckedChanged);
|
||||
this.cbProgramConfig.AutoSize = true;
|
||||
this.cbProgramConfig.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.cbProgramConfig.Location = new System.Drawing.Point(3, 3);
|
||||
this.cbProgramConfig.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.cbProgramConfig.Name = "cbProgramConfig";
|
||||
this.cbProgramConfig.Size = new System.Drawing.Size(117, 19);
|
||||
this.cbProgramConfig.TabIndex = 0;
|
||||
this.cbProgramConfig.Text = "Program Options";
|
||||
this.toolTip.SetToolTip(this.cbProgramConfig, "Interface, notification, and update options.");
|
||||
this.cbProgramConfig.UseVisualStyleBackColor = true;
|
||||
this.cbProgramConfig.CheckedChanged += new System.EventHandler(this.checkBoxSelection_CheckedChanged);
|
||||
//
|
||||
// cbSession
|
||||
//
|
||||
this.cbSession.AutoSize = true;
|
||||
this.cbSession.Location = new System.Drawing.Point(0, 27);
|
||||
this.cbSession.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.cbSession.Location = new System.Drawing.Point(3, 51);
|
||||
this.cbSession.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.cbSession.Name = "cbSession";
|
||||
this.cbSession.Size = new System.Drawing.Size(92, 17);
|
||||
this.cbSession.TabIndex = 1;
|
||||
this.cbSession.Size = new System.Drawing.Size(98, 19);
|
||||
this.cbSession.TabIndex = 2;
|
||||
this.cbSession.Text = "Login Session";
|
||||
this.toolTip.SetToolTip(this.cbSession, "A token that allows logging into the\r\ncurrent TweetDeck account.");
|
||||
this.cbSession.UseVisualStyleBackColor = true;
|
||||
this.cbSession.CheckedChanged += new System.EventHandler(this.cbSession_CheckedChanged);
|
||||
this.cbSession.CheckedChanged += new System.EventHandler(this.checkBoxSelection_CheckedChanged);
|
||||
//
|
||||
// cbPluginData
|
||||
//
|
||||
this.cbPluginData.AutoSize = true;
|
||||
this.cbPluginData.Location = new System.Drawing.Point(0, 51);
|
||||
this.cbPluginData.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.cbPluginData.Location = new System.Drawing.Point(3, 75);
|
||||
this.cbPluginData.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.cbPluginData.Name = "cbPluginData";
|
||||
this.cbPluginData.Size = new System.Drawing.Size(81, 17);
|
||||
this.cbPluginData.TabIndex = 2;
|
||||
this.cbPluginData.Size = new System.Drawing.Size(87, 19);
|
||||
this.cbPluginData.TabIndex = 3;
|
||||
this.cbPluginData.Text = "Plugin Data";
|
||||
this.toolTip.SetToolTip(this.cbPluginData, "Data files generated by plugins.\r\nDoes not include the plugins themselves.");
|
||||
this.cbPluginData.UseVisualStyleBackColor = true;
|
||||
this.cbPluginData.CheckedChanged += new System.EventHandler(this.cbPluginData_CheckedChanged);
|
||||
this.cbPluginData.CheckedChanged += new System.EventHandler(this.checkBoxSelection_CheckedChanged);
|
||||
//
|
||||
// panelExport
|
||||
// cbSystemConfig
|
||||
//
|
||||
this.panelExport.Controls.Add(this.cbConfig);
|
||||
this.panelExport.Controls.Add(this.cbPluginData);
|
||||
this.panelExport.Controls.Add(this.cbSession);
|
||||
this.panelExport.Location = new System.Drawing.Point(12, 12);
|
||||
this.panelExport.Name = "panelExport";
|
||||
this.panelExport.Size = new System.Drawing.Size(220, 79);
|
||||
this.panelExport.TabIndex = 5;
|
||||
this.panelExport.Visible = false;
|
||||
this.cbSystemConfig.AutoSize = true;
|
||||
this.cbSystemConfig.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.cbSystemConfig.Location = new System.Drawing.Point(3, 27);
|
||||
this.cbSystemConfig.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.cbSystemConfig.Name = "cbSystemConfig";
|
||||
this.cbSystemConfig.Size = new System.Drawing.Size(109, 19);
|
||||
this.cbSystemConfig.TabIndex = 1;
|
||||
this.cbSystemConfig.Text = "System Options";
|
||||
this.toolTip.SetToolTip(this.cbSystemConfig, "Hardware acceleration and cache options.");
|
||||
this.cbSystemConfig.UseVisualStyleBackColor = true;
|
||||
this.cbSystemConfig.CheckedChanged += new System.EventHandler(this.checkBoxSelection_CheckedChanged);
|
||||
//
|
||||
// panelSelection
|
||||
//
|
||||
this.panelSelection.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelSelection.Controls.Add(this.cbProgramConfig);
|
||||
this.panelSelection.Controls.Add(this.cbSystemConfig);
|
||||
this.panelSelection.Controls.Add(this.cbSession);
|
||||
this.panelSelection.Controls.Add(this.cbPluginData);
|
||||
this.panelSelection.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.panelSelection.Location = new System.Drawing.Point(12, 12);
|
||||
this.panelSelection.Name = "panelSelection";
|
||||
this.panelSelection.Size = new System.Drawing.Size(210, 97);
|
||||
this.panelSelection.TabIndex = 2;
|
||||
this.panelSelection.Visible = false;
|
||||
this.panelSelection.WrapContents = false;
|
||||
//
|
||||
// panelDecision
|
||||
//
|
||||
this.panelDecision.Controls.Add(this.radioReset);
|
||||
this.panelDecision.Controls.Add(this.radioExport);
|
||||
this.panelDecision.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelDecision.Controls.Add(this.radioImport);
|
||||
this.panelDecision.Controls.Add(this.radioExport);
|
||||
this.panelDecision.Controls.Add(this.radioReset);
|
||||
this.panelDecision.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.panelDecision.Location = new System.Drawing.Point(12, 12);
|
||||
this.panelDecision.Name = "panelDecision";
|
||||
this.panelDecision.Size = new System.Drawing.Size(220, 79);
|
||||
this.panelDecision.TabIndex = 6;
|
||||
//
|
||||
// radioReset
|
||||
//
|
||||
this.radioReset.AutoSize = true;
|
||||
this.radioReset.Location = new System.Drawing.Point(3, 49);
|
||||
this.radioReset.Name = "radioReset";
|
||||
this.radioReset.Size = new System.Drawing.Size(104, 17);
|
||||
this.radioReset.TabIndex = 2;
|
||||
this.radioReset.TabStop = true;
|
||||
this.radioReset.Text = "Restore Defaults";
|
||||
this.radioReset.UseVisualStyleBackColor = true;
|
||||
this.radioReset.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// radioExport
|
||||
//
|
||||
this.radioExport.AutoSize = true;
|
||||
this.radioExport.Location = new System.Drawing.Point(3, 26);
|
||||
this.radioExport.Name = "radioExport";
|
||||
this.radioExport.Size = new System.Drawing.Size(87, 17);
|
||||
this.radioExport.TabIndex = 1;
|
||||
this.radioExport.TabStop = true;
|
||||
this.radioExport.Text = "Export Profile";
|
||||
this.radioExport.UseVisualStyleBackColor = true;
|
||||
this.radioExport.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
this.panelDecision.Size = new System.Drawing.Size(210, 75);
|
||||
this.panelDecision.TabIndex = 0;
|
||||
this.panelDecision.WrapContents = false;
|
||||
//
|
||||
// radioImport
|
||||
//
|
||||
this.radioImport.AutoSize = true;
|
||||
this.radioImport.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioImport.Location = new System.Drawing.Point(3, 3);
|
||||
this.radioImport.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.radioImport.Name = "radioImport";
|
||||
this.radioImport.Size = new System.Drawing.Size(86, 17);
|
||||
this.radioImport.Size = new System.Drawing.Size(98, 19);
|
||||
this.radioImport.TabIndex = 0;
|
||||
this.radioImport.TabStop = true;
|
||||
this.radioImport.Text = "Import Profile";
|
||||
this.radioImport.UseVisualStyleBackColor = true;
|
||||
this.radioImport.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// radioExport
|
||||
//
|
||||
this.radioExport.AutoSize = true;
|
||||
this.radioExport.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioExport.Location = new System.Drawing.Point(3, 27);
|
||||
this.radioExport.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.radioExport.Name = "radioExport";
|
||||
this.radioExport.Size = new System.Drawing.Size(95, 19);
|
||||
this.radioExport.TabIndex = 1;
|
||||
this.radioExport.TabStop = true;
|
||||
this.radioExport.Text = "Export Profile";
|
||||
this.radioExport.UseVisualStyleBackColor = true;
|
||||
this.radioExport.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// radioReset
|
||||
//
|
||||
this.radioReset.AutoSize = true;
|
||||
this.radioReset.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioReset.Location = new System.Drawing.Point(3, 51);
|
||||
this.radioReset.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.radioReset.Name = "radioReset";
|
||||
this.radioReset.Size = new System.Drawing.Size(110, 19);
|
||||
this.radioReset.TabIndex = 2;
|
||||
this.radioReset.TabStop = true;
|
||||
this.radioReset.Text = "Restore Defaults";
|
||||
this.radioReset.UseVisualStyleBackColor = true;
|
||||
this.radioReset.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// DialogSettingsManage
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(244, 132);
|
||||
this.Controls.Add(this.panelDecision);
|
||||
this.Controls.Add(this.panelExport);
|
||||
this.ClientSize = new System.Drawing.Size(234, 129);
|
||||
this.Controls.Add(this.btnContinue);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.panelDecision);
|
||||
this.Controls.Add(this.panelSelection);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(200, 170);
|
||||
this.MinimumSize = new System.Drawing.Size(250, 167);
|
||||
this.Name = "DialogSettingsManage";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Manage Options";
|
||||
this.panelExport.ResumeLayout(false);
|
||||
this.panelExport.PerformLayout();
|
||||
this.panelSelection.ResumeLayout(false);
|
||||
this.panelSelection.PerformLayout();
|
||||
this.panelDecision.ResumeLayout(false);
|
||||
this.panelDecision.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
@@ -188,12 +227,13 @@
|
||||
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Button btnContinue;
|
||||
private System.Windows.Forms.CheckBox cbConfig;
|
||||
private System.Windows.Forms.CheckBox cbProgramConfig;
|
||||
private System.Windows.Forms.CheckBox cbSystemConfig;
|
||||
private System.Windows.Forms.CheckBox cbSession;
|
||||
private System.Windows.Forms.CheckBox cbPluginData;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.Panel panelExport;
|
||||
private System.Windows.Forms.Panel panelDecision;
|
||||
private System.Windows.Forms.FlowLayoutPanel panelSelection;
|
||||
private System.Windows.Forms.FlowLayoutPanel panelDecision;
|
||||
private System.Windows.Forms.RadioButton radioReset;
|
||||
private System.Windows.Forms.RadioButton radioExport;
|
||||
private System.Windows.Forms.RadioButton radioImport;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
@@ -16,42 +17,47 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
|
||||
set{
|
||||
// this will call events and SetFlag, which also updates the UI
|
||||
cbConfig.Checked = value.HasFlag(ProfileManager.Items.UserConfig);
|
||||
cbSession.Checked = value.HasFlag(ProfileManager.Items.Session);
|
||||
cbPluginData.Checked = value.HasFlag(ProfileManager.Items.PluginData);
|
||||
foreach(KeyValuePair<CheckBox, ProfileManager.Items> kvp in checkBoxMap){
|
||||
kvp.Key.Checked = value.HasFlag(kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool IsRestarting { get; private set; }
|
||||
public bool ShouldReloadBrowser { get; private set; }
|
||||
|
||||
private readonly PluginManager plugins;
|
||||
private readonly Dictionary<CheckBox, ProfileManager.Items> checkBoxMap = new Dictionary<CheckBox, ProfileManager.Items>(4);
|
||||
|
||||
private State currentState;
|
||||
private ProfileManager importManager;
|
||||
|
||||
private ProfileManager.Items _selectedItems = ProfileManager.Items.None;
|
||||
|
||||
public DialogSettingsManage(PluginManager plugins){
|
||||
public DialogSettingsManage(PluginManager plugins, bool openImportImmediately = false){
|
||||
InitializeComponent();
|
||||
|
||||
this.plugins = plugins;
|
||||
this.currentState = State.Deciding;
|
||||
|
||||
this.checkBoxMap[cbProgramConfig] = ProfileManager.Items.UserConfig;
|
||||
this.checkBoxMap[cbSystemConfig] = ProfileManager.Items.SystemConfig;
|
||||
this.checkBoxMap[cbSession] = ProfileManager.Items.Session;
|
||||
this.checkBoxMap[cbPluginData] = ProfileManager.Items.PluginData;
|
||||
|
||||
if (openImportImmediately){
|
||||
radioImport.Checked = true;
|
||||
btnContinue_Click(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void radioDecision_CheckedChanged(object sender, EventArgs e){
|
||||
btnContinue.Enabled = true;
|
||||
}
|
||||
|
||||
private void cbConfig_CheckedChanged(object sender, EventArgs e){
|
||||
SetFlag(ProfileManager.Items.UserConfig, cbConfig.Checked);
|
||||
}
|
||||
|
||||
private void cbSession_CheckedChanged(object sender, EventArgs e){
|
||||
SetFlag(ProfileManager.Items.Session, cbSession.Checked);
|
||||
}
|
||||
|
||||
private void cbPluginData_CheckedChanged(object sender, EventArgs e){
|
||||
SetFlag(ProfileManager.Items.PluginData, cbPluginData.Checked);
|
||||
private void checkBoxSelection_CheckedChanged(object sender, EventArgs e){
|
||||
CheckBox cb = (CheckBox)sender;
|
||||
SetFlag(checkBoxMap[cb], cb.Checked);
|
||||
}
|
||||
|
||||
private void btnContinue_Click(object sender, EventArgs e){
|
||||
@@ -88,9 +94,9 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
Text = "Import Profile";
|
||||
SelectedItems = importManager.FindImportItems();
|
||||
|
||||
cbConfig.Enabled = cbConfig.Checked;
|
||||
cbSession.Enabled = cbSession.Checked;
|
||||
cbPluginData.Enabled = cbPluginData.Checked;
|
||||
foreach(CheckBox cb in checkBoxMap.Keys){
|
||||
cb.Enabled = cb.Checked;
|
||||
}
|
||||
}
|
||||
|
||||
// Export
|
||||
@@ -99,12 +105,13 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
|
||||
Text = "Export Profile";
|
||||
btnContinue.Text = "Export Profile";
|
||||
SelectedItems = ProfileManager.Items.All & ~ProfileManager.Items.Session;
|
||||
SelectedItems = ProfileManager.Items.UserConfig | ProfileManager.Items.PluginData;
|
||||
}
|
||||
|
||||
// Continue...
|
||||
panelDecision.Visible = false;
|
||||
panelExport.Visible = true;
|
||||
panelSelection.Visible = true;
|
||||
Height += panelSelection.Height-panelDecision.Height;
|
||||
break;
|
||||
|
||||
case State.Reset:
|
||||
@@ -131,10 +138,10 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
}
|
||||
|
||||
if (SelectedItems.HasFlag(ProfileManager.Items.Session)){
|
||||
Program.Restart(Arguments.ArgDeleteCookies);
|
||||
RestartProgram(Arguments.ArgDeleteCookies);
|
||||
}
|
||||
else if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
|
||||
Program.Restart();
|
||||
RestartProgram();
|
||||
}
|
||||
else{
|
||||
ShouldReloadBrowser = true;
|
||||
@@ -152,19 +159,16 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
|
||||
if (importManager.IsRestarting){
|
||||
if (SelectedItems.HasFlag(ProfileManager.Items.Session)){
|
||||
Program.Restart(Arguments.ArgImportCookies);
|
||||
RestartProgram(Arguments.ArgImportCookies);
|
||||
}
|
||||
else if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
|
||||
Program.Restart();
|
||||
RestartProgram();
|
||||
}
|
||||
}
|
||||
else{
|
||||
ShouldReloadBrowser = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Program.Reporter.HandleException("Profile Import Error", "An exception happened while importing TweetDuck profile.", true, importManager.LastException);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
@@ -189,12 +193,8 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
|
||||
Program.UserConfig.Save();
|
||||
Program.SystemConfig.Save();
|
||||
|
||||
ProfileManager manager = new ProfileManager(file, plugins);
|
||||
|
||||
if (!manager.Export(SelectedItems)){
|
||||
Program.Reporter.HandleException("Profile Export Error", "An exception happened while exporting TweetDuck profile.", true, manager.LastException);
|
||||
}
|
||||
|
||||
new ProfileManager(file, plugins).Export(SelectedItems);
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
@@ -210,13 +210,18 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
private void SetFlag(ProfileManager.Items flag, bool enable){
|
||||
_selectedItems = enable ? _selectedItems | flag : _selectedItems & ~flag;
|
||||
btnContinue.Enabled = _selectedItems != ProfileManager.Items.None;
|
||||
|
||||
|
||||
if (currentState == State.Import){
|
||||
btnContinue.Text = _selectedItems.HasFlag(ProfileManager.Items.Session) ? "Import && Restart" : "Import Profile";
|
||||
btnContinue.Text = _selectedItems.NeedsRestart() ? "Import && Restart" : "Import Profile";
|
||||
}
|
||||
else if (currentState == State.Reset){
|
||||
btnContinue.Text = _selectedItems.HasFlag(ProfileManager.Items.Session) ? "Restore && Restart" : "Restore Defaults";
|
||||
btnContinue.Text = _selectedItems.NeedsRestart() ? "Restore && Restart" : "Restore Defaults";
|
||||
}
|
||||
}
|
||||
|
||||
private void RestartProgram(params string[] extraArgs){
|
||||
IsRestarting = true;
|
||||
Program.Restart(extraArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -28,21 +28,24 @@
|
||||
this.btnRestart = new System.Windows.Forms.Button();
|
||||
this.cbLogging = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.cbDebugUpdates = new System.Windows.Forms.CheckBox();
|
||||
this.tbDataFolder = new System.Windows.Forms.TextBox();
|
||||
this.tbShortcutTarget = new System.Windows.Forms.TextBox();
|
||||
this.labelDataFolder = new System.Windows.Forms.Label();
|
||||
this.labelShortcutTarget = new System.Windows.Forms.Label();
|
||||
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.flowPanel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(215, 163);
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(215, 146);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.TabIndex = 9;
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
@@ -50,11 +53,13 @@
|
||||
// btnRestart
|
||||
//
|
||||
this.btnRestart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnRestart.Location = new System.Drawing.Point(152, 163);
|
||||
this.btnRestart.AutoSize = true;
|
||||
this.btnRestart.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnRestart.Location = new System.Drawing.Point(152, 146);
|
||||
this.btnRestart.Name = "btnRestart";
|
||||
this.btnRestart.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnRestart.Size = new System.Drawing.Size(57, 23);
|
||||
this.btnRestart.TabIndex = 8;
|
||||
this.btnRestart.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnRestart.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnRestart.TabIndex = 1;
|
||||
this.btnRestart.Text = "Restart";
|
||||
this.btnRestart.UseVisualStyleBackColor = true;
|
||||
this.btnRestart.Click += new System.EventHandler(this.btnRestart_Click);
|
||||
@@ -62,33 +67,23 @@
|
||||
// cbLogging
|
||||
//
|
||||
this.cbLogging.AutoSize = true;
|
||||
this.cbLogging.Location = new System.Drawing.Point(12, 12);
|
||||
this.cbLogging.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.cbLogging.Location = new System.Drawing.Point(3, 3);
|
||||
this.cbLogging.Margin = new System.Windows.Forms.Padding(3, 3, 3, 2);
|
||||
this.cbLogging.Name = "cbLogging";
|
||||
this.cbLogging.Size = new System.Drawing.Size(64, 17);
|
||||
this.cbLogging.Size = new System.Drawing.Size(70, 19);
|
||||
this.cbLogging.TabIndex = 0;
|
||||
this.cbLogging.Text = "Logging";
|
||||
this.toolTip.SetToolTip(this.cbLogging, "Logging JavaScript output into TD_Console.txt file in the data folder.");
|
||||
this.toolTip.SetToolTip(this.cbLogging, "Logs JavaScript output into TD_Console.txt file in the data folder.");
|
||||
this.cbLogging.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// cbDebugUpdates
|
||||
//
|
||||
this.cbDebugUpdates.AutoSize = true;
|
||||
this.cbDebugUpdates.Location = new System.Drawing.Point(12, 35);
|
||||
this.cbDebugUpdates.Name = "cbDebugUpdates";
|
||||
this.cbDebugUpdates.Size = new System.Drawing.Size(127, 17);
|
||||
this.cbDebugUpdates.TabIndex = 1;
|
||||
this.cbDebugUpdates.Text = "Pre-Release Updates";
|
||||
this.toolTip.SetToolTip(this.cbDebugUpdates, "Allows updating to pre-releases.");
|
||||
this.cbDebugUpdates.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tbDataFolder
|
||||
//
|
||||
this.tbDataFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tbDataFolder.Location = new System.Drawing.Point(15, 83);
|
||||
this.tbDataFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.tbDataFolder.Location = new System.Drawing.Point(3, 54);
|
||||
this.tbDataFolder.Name = "tbDataFolder";
|
||||
this.tbDataFolder.Size = new System.Drawing.Size(257, 20);
|
||||
this.tbDataFolder.TabIndex = 5;
|
||||
this.tbDataFolder.Size = new System.Drawing.Size(260, 23);
|
||||
this.tbDataFolder.TabIndex = 2;
|
||||
this.toolTip.SetToolTip(this.tbDataFolder, "Path to the data folder. Must be either an absolute path,\r\nor a simple folder nam" +
|
||||
"e that will be created in LocalAppData.");
|
||||
//
|
||||
@@ -97,44 +92,60 @@
|
||||
this.tbShortcutTarget.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tbShortcutTarget.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.tbShortcutTarget.Location = new System.Drawing.Point(15, 134);
|
||||
this.tbShortcutTarget.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.tbShortcutTarget.Location = new System.Drawing.Point(3, 110);
|
||||
this.tbShortcutTarget.Name = "tbShortcutTarget";
|
||||
this.tbShortcutTarget.ReadOnly = true;
|
||||
this.tbShortcutTarget.Size = new System.Drawing.Size(257, 20);
|
||||
this.tbShortcutTarget.TabIndex = 7;
|
||||
this.tbShortcutTarget.Size = new System.Drawing.Size(260, 23);
|
||||
this.tbShortcutTarget.TabIndex = 4;
|
||||
this.tbShortcutTarget.Click += new System.EventHandler(this.tbShortcutTarget_Click);
|
||||
//
|
||||
// labelDataFolder
|
||||
//
|
||||
this.labelDataFolder.AutoSize = true;
|
||||
this.labelDataFolder.Location = new System.Drawing.Point(12, 67);
|
||||
this.labelDataFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDataFolder.Location = new System.Drawing.Point(3, 36);
|
||||
this.labelDataFolder.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelDataFolder.Name = "labelDataFolder";
|
||||
this.labelDataFolder.Size = new System.Drawing.Size(62, 13);
|
||||
this.labelDataFolder.TabIndex = 4;
|
||||
this.labelDataFolder.Size = new System.Drawing.Size(67, 15);
|
||||
this.labelDataFolder.TabIndex = 1;
|
||||
this.labelDataFolder.Text = "Data Folder";
|
||||
//
|
||||
// labelShortcutTarget
|
||||
//
|
||||
this.labelShortcutTarget.AutoSize = true;
|
||||
this.labelShortcutTarget.Location = new System.Drawing.Point(12, 118);
|
||||
this.labelShortcutTarget.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelShortcutTarget.Location = new System.Drawing.Point(3, 92);
|
||||
this.labelShortcutTarget.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelShortcutTarget.Name = "labelShortcutTarget";
|
||||
this.labelShortcutTarget.Size = new System.Drawing.Size(155, 13);
|
||||
this.labelShortcutTarget.TabIndex = 6;
|
||||
this.labelShortcutTarget.Size = new System.Drawing.Size(171, 15);
|
||||
this.labelShortcutTarget.TabIndex = 3;
|
||||
this.labelShortcutTarget.Text = "Shortcut Target (click to select)";
|
||||
//
|
||||
// flowPanel
|
||||
//
|
||||
this.flowPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowPanel.Controls.Add(this.cbLogging);
|
||||
this.flowPanel.Controls.Add(this.labelDataFolder);
|
||||
this.flowPanel.Controls.Add(this.tbDataFolder);
|
||||
this.flowPanel.Controls.Add(this.labelShortcutTarget);
|
||||
this.flowPanel.Controls.Add(this.tbShortcutTarget);
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(266, 136);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
// DialogSettingsRestart
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(284, 198);
|
||||
this.Controls.Add(this.tbShortcutTarget);
|
||||
this.Controls.Add(this.labelShortcutTarget);
|
||||
this.Controls.Add(this.tbDataFolder);
|
||||
this.Controls.Add(this.labelDataFolder);
|
||||
this.Controls.Add(this.cbDebugUpdates);
|
||||
this.Controls.Add(this.cbLogging);
|
||||
this.ClientSize = new System.Drawing.Size(284, 183);
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Controls.Add(this.btnRestart);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
@@ -143,6 +154,8 @@
|
||||
this.Name = "DialogSettingsRestart";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.flowPanel.ResumeLayout(false);
|
||||
this.flowPanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@@ -154,10 +167,10 @@
|
||||
private System.Windows.Forms.Button btnRestart;
|
||||
private System.Windows.Forms.CheckBox cbLogging;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.CheckBox cbDebugUpdates;
|
||||
private System.Windows.Forms.Label labelDataFolder;
|
||||
private System.Windows.Forms.TextBox tbDataFolder;
|
||||
private System.Windows.Forms.TextBox tbShortcutTarget;
|
||||
private System.Windows.Forms.Label labelShortcutTarget;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowPanel;
|
||||
}
|
||||
}
|
@@ -11,11 +11,8 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
InitializeComponent();
|
||||
|
||||
cbLogging.Checked = currentArgs.HasFlag(Arguments.ArgLogging);
|
||||
cbDebugUpdates.Checked = currentArgs.HasFlag(Arguments.ArgDebugUpdates);
|
||||
|
||||
cbLogging.CheckedChanged += control_Change;
|
||||
cbDebugUpdates.CheckedChanged += control_Change;
|
||||
|
||||
|
||||
if (Program.IsPortable){
|
||||
tbDataFolder.Text = "Not available in portable version";
|
||||
tbDataFolder.Enabled = false;
|
||||
@@ -37,10 +34,6 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
Args.AddFlag(Arguments.ArgLogging);
|
||||
}
|
||||
|
||||
if (cbDebugUpdates.Checked){
|
||||
Args.AddFlag(Arguments.ArgDebugUpdates);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tbDataFolder.Text) && tbDataFolder.Enabled){
|
||||
Args.SetValue(Arguments.ArgDataFolder, tbDataFolder.Text);
|
||||
}
|
||||
|
109
Core/Other/Settings/Dialogs/DialogSettingsSearchEngine.Designer.cs
generated
Normal file
109
Core/Other/Settings/Dialogs/DialogSettingsSearchEngine.Designer.cs
generated
Normal file
@@ -0,0 +1,109 @@
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs {
|
||||
partial class DialogSettingsSearchEngine {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.textBoxUrl = new System.Windows.Forms.TextBox();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.btnApply = new System.Windows.Forms.Button();
|
||||
this.labelInfo = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// textBoxUrl
|
||||
//
|
||||
this.textBoxUrl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textBoxUrl.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.textBoxUrl.Location = new System.Drawing.Point(12, 30);
|
||||
this.textBoxUrl.Name = "textBoxUrl";
|
||||
this.textBoxUrl.Size = new System.Drawing.Size(310, 23);
|
||||
this.textBoxUrl.TabIndex = 1;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnCancel.Location = new System.Drawing.Point(207, 59);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnCancel.TabIndex = 3;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// btnApply
|
||||
//
|
||||
this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnApply.AutoSize = true;
|
||||
this.btnApply.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnApply.Location = new System.Drawing.Point(270, 59);
|
||||
this.btnApply.Name = "btnApply";
|
||||
this.btnApply.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnApply.Size = new System.Drawing.Size(52, 25);
|
||||
this.btnApply.TabIndex = 2;
|
||||
this.btnApply.Text = "Apply";
|
||||
this.btnApply.UseVisualStyleBackColor = true;
|
||||
this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
|
||||
//
|
||||
// labelInfo
|
||||
//
|
||||
this.labelInfo.AutoSize = true;
|
||||
this.labelInfo.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelInfo.Location = new System.Drawing.Point(12, 9);
|
||||
this.labelInfo.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
|
||||
this.labelInfo.Name = "labelInfo";
|
||||
this.labelInfo.Size = new System.Drawing.Size(287, 15);
|
||||
this.labelInfo.TabIndex = 0;
|
||||
this.labelInfo.Text = "The search query will be added at the end of the URL.";
|
||||
//
|
||||
// DialogSettingsSearchEngine
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(334, 96);
|
||||
this.Controls.Add(this.labelInfo);
|
||||
this.Controls.Add(this.btnApply);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.textBoxUrl);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "DialogSettingsSearchEngine";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox textBoxUrl;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Button btnApply;
|
||||
private System.Windows.Forms.Label labelInfo;
|
||||
}
|
||||
}
|
27
Core/Other/Settings/Dialogs/DialogSettingsSearchEngine.cs
Normal file
27
Core/Other/Settings/Dialogs/DialogSettingsSearchEngine.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
sealed partial class DialogSettingsSearchEngine : Form{
|
||||
public string Url => textBoxUrl.Text;
|
||||
|
||||
public DialogSettingsSearchEngine(){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Options - Custom Search Engine";
|
||||
|
||||
textBoxUrl.Text = Program.UserConfig.SearchEngineUrl ?? "";
|
||||
textBoxUrl.Select(textBoxUrl.Text.Length, 0);
|
||||
}
|
||||
|
||||
private void btnApply_Click(object sender, EventArgs e){
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e){
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
102
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
102
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
@@ -52,101 +52,128 @@
|
||||
//
|
||||
// btnClearCache
|
||||
//
|
||||
this.btnClearCache.Location = new System.Drawing.Point(5, 172);
|
||||
this.btnClearCache.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnClearCache.Location = new System.Drawing.Point(5, 179);
|
||||
this.btnClearCache.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnClearCache.Name = "btnClearCache";
|
||||
this.btnClearCache.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnClearCache.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnClearCache.TabIndex = 5;
|
||||
this.btnClearCache.Text = "Clear Cache (calculating)";
|
||||
this.btnClearCache.Text = "Clear Cache (...)";
|
||||
this.btnClearCache.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkHardwareAcceleration
|
||||
//
|
||||
this.checkHardwareAcceleration.AutoSize = true;
|
||||
this.checkHardwareAcceleration.Location = new System.Drawing.Point(6, 124);
|
||||
this.checkHardwareAcceleration.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkHardwareAcceleration.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkHardwareAcceleration.Location = new System.Drawing.Point(6, 128);
|
||||
this.checkHardwareAcceleration.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkHardwareAcceleration.Name = "checkHardwareAcceleration";
|
||||
this.checkHardwareAcceleration.Size = new System.Drawing.Size(134, 17);
|
||||
this.checkHardwareAcceleration.Size = new System.Drawing.Size(146, 19);
|
||||
this.checkHardwareAcceleration.TabIndex = 3;
|
||||
this.checkHardwareAcceleration.Text = "Hardware Acceleration";
|
||||
this.checkHardwareAcceleration.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnEditCefArgs
|
||||
//
|
||||
this.btnEditCefArgs.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnEditCefArgs.Location = new System.Drawing.Point(5, 3);
|
||||
this.btnEditCefArgs.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnEditCefArgs.Name = "btnEditCefArgs";
|
||||
this.btnEditCefArgs.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnEditCefArgs.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnEditCefArgs.TabIndex = 0;
|
||||
this.btnEditCefArgs.Text = "Edit CEF Arguments";
|
||||
this.btnEditCefArgs.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnEditCSS
|
||||
//
|
||||
this.btnEditCSS.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnEditCSS.Location = new System.Drawing.Point(155, 3);
|
||||
this.btnEditCSS.Name = "btnEditCSS";
|
||||
this.btnEditCSS.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnEditCSS.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnEditCSS.TabIndex = 1;
|
||||
this.btnEditCSS.Text = "Edit CSS";
|
||||
this.btnEditCSS.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnRestartArgs
|
||||
//
|
||||
this.btnRestartArgs.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnRestartArgs.Location = new System.Drawing.Point(155, 32);
|
||||
this.btnRestartArgs.Name = "btnRestartArgs";
|
||||
this.btnRestartArgs.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnRestartArgs.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnRestartArgs.TabIndex = 3;
|
||||
this.btnRestartArgs.Text = "Restart with Arguments";
|
||||
this.btnRestartArgs.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnRestart
|
||||
//
|
||||
this.btnRestart.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnRestart.Location = new System.Drawing.Point(155, 3);
|
||||
this.btnRestart.Name = "btnRestart";
|
||||
this.btnRestart.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnRestart.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnRestart.TabIndex = 2;
|
||||
this.btnRestart.Text = "Restart the Program";
|
||||
this.btnRestart.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnOpenAppFolder
|
||||
//
|
||||
this.btnOpenAppFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnOpenAppFolder.Location = new System.Drawing.Point(5, 3);
|
||||
this.btnOpenAppFolder.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnOpenAppFolder.Name = "btnOpenAppFolder";
|
||||
this.btnOpenAppFolder.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnOpenAppFolder.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnOpenAppFolder.TabIndex = 0;
|
||||
this.btnOpenAppFolder.Text = "Open Program Folder";
|
||||
this.btnOpenAppFolder.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnOpenDataFolder
|
||||
//
|
||||
this.btnOpenDataFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnOpenDataFolder.Location = new System.Drawing.Point(5, 32);
|
||||
this.btnOpenDataFolder.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnOpenDataFolder.Name = "btnOpenDataFolder";
|
||||
this.btnOpenDataFolder.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnOpenDataFolder.Size = new System.Drawing.Size(144, 25);
|
||||
this.btnOpenDataFolder.TabIndex = 1;
|
||||
this.btnOpenDataFolder.Text = "Open Data Folder";
|
||||
this.btnOpenDataFolder.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// numClearCacheThreshold
|
||||
//
|
||||
this.numClearCacheThreshold.Increment = 50;
|
||||
this.numClearCacheThreshold.Location = new System.Drawing.Point(227, 4);
|
||||
this.numClearCacheThreshold.Maximum = 1000;
|
||||
this.numClearCacheThreshold.Minimum = 100;
|
||||
this.numClearCacheThreshold.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.numClearCacheThreshold.Increment = new decimal(new int[] {
|
||||
50,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numClearCacheThreshold.Location = new System.Drawing.Point(246, 5);
|
||||
this.numClearCacheThreshold.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numClearCacheThreshold.Minimum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numClearCacheThreshold.Name = "numClearCacheThreshold";
|
||||
this.numClearCacheThreshold.Size = new System.Drawing.Size(72, 20);
|
||||
this.numClearCacheThreshold.Size = new System.Drawing.Size(68, 23);
|
||||
this.numClearCacheThreshold.TabIndex = 1;
|
||||
this.numClearCacheThreshold.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
|
||||
this.numClearCacheThreshold.TextSuffix = " MB";
|
||||
this.numClearCacheThreshold.Value = 250;
|
||||
this.numClearCacheThreshold.Value = new decimal(new int[] {
|
||||
250,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// checkClearCacheAuto
|
||||
//
|
||||
this.checkClearCacheAuto.AutoSize = true;
|
||||
this.checkClearCacheAuto.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkClearCacheAuto.Location = new System.Drawing.Point(6, 6);
|
||||
this.checkClearCacheAuto.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkClearCacheAuto.Margin = new System.Windows.Forms.Padding(6, 6, 0, 2);
|
||||
this.checkClearCacheAuto.Name = "checkClearCacheAuto";
|
||||
this.checkClearCacheAuto.Size = new System.Drawing.Size(215, 17);
|
||||
this.checkClearCacheAuto.Size = new System.Drawing.Size(237, 19);
|
||||
this.checkClearCacheAuto.TabIndex = 0;
|
||||
this.checkClearCacheAuto.Text = "Clear Cache Automatically When Above";
|
||||
this.checkClearCacheAuto.UseVisualStyleBackColor = true;
|
||||
@@ -154,11 +181,11 @@
|
||||
// labelApp
|
||||
//
|
||||
this.labelApp.AutoSize = true;
|
||||
this.labelApp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelApp.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelApp.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelApp.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelApp.Name = "labelApp";
|
||||
this.labelApp.Size = new System.Drawing.Size(38, 20);
|
||||
this.labelApp.Size = new System.Drawing.Size(37, 20);
|
||||
this.labelApp.TabIndex = 0;
|
||||
this.labelApp.Text = "App";
|
||||
//
|
||||
@@ -172,17 +199,17 @@
|
||||
this.panelAppButtons.Location = new System.Drawing.Point(0, 20);
|
||||
this.panelAppButtons.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelAppButtons.Name = "panelAppButtons";
|
||||
this.panelAppButtons.Size = new System.Drawing.Size(322, 58);
|
||||
this.panelAppButtons.Size = new System.Drawing.Size(322, 62);
|
||||
this.panelAppButtons.TabIndex = 1;
|
||||
//
|
||||
// labelPerformance
|
||||
//
|
||||
this.labelPerformance.AutoSize = true;
|
||||
this.labelPerformance.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelPerformance.Location = new System.Drawing.Point(0, 98);
|
||||
this.labelPerformance.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelPerformance.Location = new System.Drawing.Point(0, 102);
|
||||
this.labelPerformance.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelPerformance.Name = "labelPerformance";
|
||||
this.labelPerformance.Size = new System.Drawing.Size(100, 20);
|
||||
this.labelPerformance.Size = new System.Drawing.Size(93, 20);
|
||||
this.labelPerformance.TabIndex = 2;
|
||||
this.labelPerformance.Text = "Performance";
|
||||
//
|
||||
@@ -191,19 +218,20 @@
|
||||
this.panelClearCacheAuto.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelClearCacheAuto.Controls.Add(this.checkClearCacheAuto);
|
||||
this.panelClearCacheAuto.Controls.Add(this.numClearCacheThreshold);
|
||||
this.panelClearCacheAuto.Location = new System.Drawing.Point(0, 198);
|
||||
this.panelClearCacheAuto.Location = new System.Drawing.Point(0, 207);
|
||||
this.panelClearCacheAuto.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelClearCacheAuto.Name = "panelClearCacheAuto";
|
||||
this.panelClearCacheAuto.Size = new System.Drawing.Size(322, 26);
|
||||
this.panelClearCacheAuto.Size = new System.Drawing.Size(322, 28);
|
||||
this.panelClearCacheAuto.TabIndex = 6;
|
||||
//
|
||||
// labelCache
|
||||
//
|
||||
this.labelCache.AutoSize = true;
|
||||
this.labelCache.Location = new System.Drawing.Point(3, 156);
|
||||
this.labelCache.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelCache.Location = new System.Drawing.Point(3, 161);
|
||||
this.labelCache.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelCache.Name = "labelCache";
|
||||
this.labelCache.Size = new System.Drawing.Size(38, 13);
|
||||
this.labelCache.Size = new System.Drawing.Size(40, 15);
|
||||
this.labelCache.TabIndex = 4;
|
||||
this.labelCache.Text = "Cache";
|
||||
//
|
||||
@@ -212,20 +240,20 @@
|
||||
this.panelConfiguration.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelConfiguration.Controls.Add(this.btnEditCSS);
|
||||
this.panelConfiguration.Controls.Add(this.btnEditCefArgs);
|
||||
this.panelConfiguration.Location = new System.Drawing.Point(0, 264);
|
||||
this.panelConfiguration.Location = new System.Drawing.Point(0, 275);
|
||||
this.panelConfiguration.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelConfiguration.Name = "panelConfiguration";
|
||||
this.panelConfiguration.Size = new System.Drawing.Size(322, 29);
|
||||
this.panelConfiguration.Size = new System.Drawing.Size(322, 31);
|
||||
this.panelConfiguration.TabIndex = 8;
|
||||
//
|
||||
// labelConfiguration
|
||||
//
|
||||
this.labelConfiguration.AutoSize = true;
|
||||
this.labelConfiguration.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelConfiguration.Location = new System.Drawing.Point(0, 244);
|
||||
this.labelConfiguration.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelConfiguration.Location = new System.Drawing.Point(0, 255);
|
||||
this.labelConfiguration.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelConfiguration.Name = "labelConfiguration";
|
||||
this.labelConfiguration.Size = new System.Drawing.Size(104, 20);
|
||||
this.labelConfiguration.Size = new System.Drawing.Size(100, 20);
|
||||
this.labelConfiguration.TabIndex = 7;
|
||||
this.labelConfiguration.Text = "Configuration";
|
||||
//
|
||||
@@ -246,7 +274,7 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 295);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 307);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
@@ -256,7 +284,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsAdvanced";
|
||||
this.Size = new System.Drawing.Size(340, 313);
|
||||
this.Size = new System.Drawing.Size(340, 325);
|
||||
((System.ComponentModel.ISupportInitialize)(this.numClearCacheThreshold)).EndInit();
|
||||
this.panelAppButtons.ResumeLayout(false);
|
||||
this.panelClearCacheAuto.ResumeLayout(false);
|
||||
|
@@ -13,18 +13,20 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
private static SystemConfig SysConfig => Program.SystemConfig;
|
||||
|
||||
private readonly Action<string> reinjectBrowserCSS;
|
||||
private readonly Action openDevTools;
|
||||
|
||||
public TabSettingsAdvanced(Action<string> reinjectBrowserCSS){
|
||||
public TabSettingsAdvanced(Action<string> reinjectBrowserCSS, Action openDevTools){
|
||||
InitializeComponent();
|
||||
|
||||
this.reinjectBrowserCSS = reinjectBrowserCSS;
|
||||
this.openDevTools = openDevTools;
|
||||
|
||||
toolTip.SetToolTip(btnOpenAppFolder, "Opens the folder where the app is located.");
|
||||
toolTip.SetToolTip(btnOpenDataFolder, "Opens the folder where your profile data is located.");
|
||||
toolTip.SetToolTip(btnRestart, "Restarts the program using the same command\r\nline arguments that were used at launch.");
|
||||
toolTip.SetToolTip(btnRestartArgs, "Restarts the program with customizable\r\ncommand line arguments.");
|
||||
|
||||
toolTip.SetToolTip(checkHardwareAcceleration, "Uses graphics card to improve performance. Disable if you experience\r\nvisual glitches. This option will not be exported in a profile.");
|
||||
toolTip.SetToolTip(checkHardwareAcceleration, "Uses graphics card to improve performance. Disable if you experience visual glitches, or to save a small amount of RAM.");
|
||||
|
||||
toolTip.SetToolTip(btnClearCache, "Clearing cache will free up space taken by downloaded images and other resources.");
|
||||
toolTip.SetToolTip(checkClearCacheAuto, "Automatically clears cache when its size exceeds the set threshold. Note that cache can only be cleared when closing TweetDuck.");
|
||||
@@ -32,13 +34,7 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
toolTip.SetToolTip(btnEditCefArgs, "Set custom command line arguments for Chromium Embedded Framework.");
|
||||
toolTip.SetToolTip(btnEditCSS, "Set custom CSS for browser and notification windows.");
|
||||
|
||||
if (SystemConfig.IsHardwareAccelerationSupported){
|
||||
checkHardwareAcceleration.Checked = SysConfig.HardwareAcceleration;
|
||||
}
|
||||
else{
|
||||
checkHardwareAcceleration.Enabled = false;
|
||||
checkHardwareAcceleration.Checked = false;
|
||||
}
|
||||
checkHardwareAcceleration.Checked = SysConfig.HardwareAcceleration;
|
||||
|
||||
checkClearCacheAuto.Checked = SysConfig.ClearCacheAutomatically;
|
||||
numClearCacheThreshold.Enabled = checkClearCacheAuto.Checked;
|
||||
@@ -109,7 +105,7 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
}
|
||||
|
||||
private void btnEditCSS_Click(object sender, EventArgs e){
|
||||
DialogSettingsCSS form = new DialogSettingsCSS(reinjectBrowserCSS);
|
||||
DialogSettingsCSS form = new DialogSettingsCSS(reinjectBrowserCSS, openDevTools);
|
||||
|
||||
form.VisibleChanged += (sender2, args2) => {
|
||||
form.MoveToCenter(ParentForm);
|
||||
|
43
Core/Other/Settings/TabSettingsFeedback.Designer.cs
generated
43
Core/Other/Settings/TabSettingsFeedback.Designer.cs
generated
@@ -43,21 +43,22 @@
|
||||
this.panelDataCollection.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelDataCollection.Controls.Add(this.labelDataCollectionLink);
|
||||
this.panelDataCollection.Controls.Add(this.checkDataCollection);
|
||||
this.panelDataCollection.Location = new System.Drawing.Point(0, 74);
|
||||
this.panelDataCollection.Location = new System.Drawing.Point(0, 78);
|
||||
this.panelDataCollection.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelDataCollection.Name = "panelDataCollection";
|
||||
this.panelDataCollection.Size = new System.Drawing.Size(322, 26);
|
||||
this.panelDataCollection.Size = new System.Drawing.Size(322, 28);
|
||||
this.panelDataCollection.TabIndex = 3;
|
||||
//
|
||||
// labelDataCollectionLink
|
||||
//
|
||||
this.labelDataCollectionLink.AutoSize = true;
|
||||
this.labelDataCollectionLink.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDataCollectionLink.LinkArea = new System.Windows.Forms.LinkArea(1, 10);
|
||||
this.labelDataCollectionLink.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
|
||||
this.labelDataCollectionLink.Location = new System.Drawing.Point(141, 6);
|
||||
this.labelDataCollectionLink.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelDataCollectionLink.Location = new System.Drawing.Point(153, 4);
|
||||
this.labelDataCollectionLink.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelDataCollectionLink.Name = "labelDataCollectionLink";
|
||||
this.labelDataCollectionLink.Size = new System.Drawing.Size(66, 17);
|
||||
this.labelDataCollectionLink.Size = new System.Drawing.Size(71, 21);
|
||||
this.labelDataCollectionLink.TabIndex = 1;
|
||||
this.labelDataCollectionLink.TabStop = true;
|
||||
this.labelDataCollectionLink.Text = "(learn more)";
|
||||
@@ -67,17 +68,19 @@
|
||||
// checkDataCollection
|
||||
//
|
||||
this.checkDataCollection.AutoSize = true;
|
||||
this.checkDataCollection.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkDataCollection.Location = new System.Drawing.Point(6, 6);
|
||||
this.checkDataCollection.Margin = new System.Windows.Forms.Padding(6, 6, 0, 3);
|
||||
this.checkDataCollection.Margin = new System.Windows.Forms.Padding(6, 6, 0, 2);
|
||||
this.checkDataCollection.Name = "checkDataCollection";
|
||||
this.checkDataCollection.Size = new System.Drawing.Size(135, 17);
|
||||
this.checkDataCollection.Size = new System.Drawing.Size(147, 19);
|
||||
this.checkDataCollection.TabIndex = 0;
|
||||
this.checkDataCollection.Text = "Send Anonymous Data";
|
||||
this.checkDataCollection.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelDataCollectionMessage
|
||||
//
|
||||
this.labelDataCollectionMessage.Location = new System.Drawing.Point(6, 135);
|
||||
this.labelDataCollectionMessage.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDataCollectionMessage.Location = new System.Drawing.Point(6, 143);
|
||||
this.labelDataCollectionMessage.Margin = new System.Windows.Forms.Padding(6);
|
||||
this.labelDataCollectionMessage.Name = "labelDataCollectionMessage";
|
||||
this.labelDataCollectionMessage.Size = new System.Drawing.Size(310, 67);
|
||||
@@ -86,10 +89,12 @@
|
||||
// btnViewReport
|
||||
//
|
||||
this.btnViewReport.AutoSize = true;
|
||||
this.btnViewReport.Location = new System.Drawing.Point(5, 103);
|
||||
this.btnViewReport.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnViewReport.Location = new System.Drawing.Point(5, 109);
|
||||
this.btnViewReport.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnViewReport.Name = "btnViewReport";
|
||||
this.btnViewReport.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnViewReport.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnViewReport.Size = new System.Drawing.Size(155, 25);
|
||||
this.btnViewReport.TabIndex = 4;
|
||||
this.btnViewReport.Text = "View My Analytics Report";
|
||||
this.btnViewReport.UseVisualStyleBackColor = true;
|
||||
@@ -97,11 +102,12 @@
|
||||
// btnSendFeedback
|
||||
//
|
||||
this.btnSendFeedback.AutoSize = true;
|
||||
this.btnSendFeedback.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnSendFeedback.Location = new System.Drawing.Point(5, 23);
|
||||
this.btnSendFeedback.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnSendFeedback.Name = "btnSendFeedback";
|
||||
this.btnSendFeedback.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnSendFeedback.Size = new System.Drawing.Size(164, 23);
|
||||
this.btnSendFeedback.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnSendFeedback.Size = new System.Drawing.Size(170, 25);
|
||||
this.btnSendFeedback.TabIndex = 1;
|
||||
this.btnSendFeedback.Text = "Send Feedback / Bug Report";
|
||||
this.btnSendFeedback.UseVisualStyleBackColor = true;
|
||||
@@ -109,21 +115,22 @@
|
||||
// labelDataCollection
|
||||
//
|
||||
this.labelDataCollection.AutoSize = true;
|
||||
this.labelDataCollection.Location = new System.Drawing.Point(3, 61);
|
||||
this.labelDataCollection.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDataCollection.Location = new System.Drawing.Point(3, 63);
|
||||
this.labelDataCollection.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelDataCollection.Name = "labelDataCollection";
|
||||
this.labelDataCollection.Size = new System.Drawing.Size(79, 13);
|
||||
this.labelDataCollection.Size = new System.Drawing.Size(88, 15);
|
||||
this.labelDataCollection.TabIndex = 2;
|
||||
this.labelDataCollection.Text = "Data Collection";
|
||||
//
|
||||
// labelFeedback
|
||||
//
|
||||
this.labelFeedback.AutoSize = true;
|
||||
this.labelFeedback.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelFeedback.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelFeedback.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelFeedback.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelFeedback.Name = "labelFeedback";
|
||||
this.labelFeedback.Size = new System.Drawing.Size(80, 20);
|
||||
this.labelFeedback.Size = new System.Drawing.Size(72, 20);
|
||||
this.labelFeedback.TabIndex = 0;
|
||||
this.labelFeedback.Text = "Feedback";
|
||||
//
|
||||
@@ -141,7 +148,7 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 209);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 212);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
@@ -151,7 +158,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsFeedback";
|
||||
this.Size = new System.Drawing.Size(340, 227);
|
||||
this.Size = new System.Drawing.Size(340, 230);
|
||||
this.panelDataCollection.ResumeLayout(false);
|
||||
this.panelDataCollection.PerformLayout();
|
||||
this.flowPanel.ResumeLayout(false);
|
||||
|
160
Core/Other/Settings/TabSettingsGeneral.Designer.cs
generated
160
Core/Other/Settings/TabSettingsGeneral.Designer.cs
generated
@@ -29,7 +29,6 @@
|
||||
this.checkUpdateNotifications = new System.Windows.Forms.CheckBox();
|
||||
this.btnCheckUpdates = new System.Windows.Forms.Button();
|
||||
this.labelZoomValue = new System.Windows.Forms.Label();
|
||||
this.checkSwitchAccountSelectors = new System.Windows.Forms.CheckBox();
|
||||
this.checkBestImageQuality = new System.Windows.Forms.CheckBox();
|
||||
this.checkOpenSearchInFirstColumn = new System.Windows.Forms.CheckBox();
|
||||
this.trackBarZoom = new System.Windows.Forms.TrackBar();
|
||||
@@ -45,6 +44,8 @@
|
||||
this.checkSmoothScrolling = new System.Windows.Forms.CheckBox();
|
||||
this.labelBrowserPath = new System.Windows.Forms.Label();
|
||||
this.comboBoxBrowserPath = new System.Windows.Forms.ComboBox();
|
||||
this.labelSearchEngine = new System.Windows.Forms.Label();
|
||||
this.comboBoxSearchEngine = new System.Windows.Forms.ComboBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarZoom)).BeginInit();
|
||||
this.panelZoom.SuspendLayout();
|
||||
this.flowPanel.SuspendLayout();
|
||||
@@ -53,10 +54,11 @@
|
||||
// checkExpandLinks
|
||||
//
|
||||
this.checkExpandLinks.AutoSize = true;
|
||||
this.checkExpandLinks.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkExpandLinks.Location = new System.Drawing.Point(6, 26);
|
||||
this.checkExpandLinks.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkExpandLinks.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkExpandLinks.Name = "checkExpandLinks";
|
||||
this.checkExpandLinks.Size = new System.Drawing.Size(166, 17);
|
||||
this.checkExpandLinks.Size = new System.Drawing.Size(176, 19);
|
||||
this.checkExpandLinks.TabIndex = 1;
|
||||
this.checkExpandLinks.Text = "Expand Links When Hovered";
|
||||
this.checkExpandLinks.UseVisualStyleBackColor = true;
|
||||
@@ -64,27 +66,32 @@
|
||||
// checkUpdateNotifications
|
||||
//
|
||||
this.checkUpdateNotifications.AutoSize = true;
|
||||
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 386);
|
||||
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkUpdateNotifications.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 427);
|
||||
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkUpdateNotifications.Name = "checkUpdateNotifications";
|
||||
this.checkUpdateNotifications.Size = new System.Drawing.Size(165, 17);
|
||||
this.checkUpdateNotifications.TabIndex = 14;
|
||||
this.checkUpdateNotifications.Size = new System.Drawing.Size(182, 19);
|
||||
this.checkUpdateNotifications.TabIndex = 15;
|
||||
this.checkUpdateNotifications.Text = "Check Updates Automatically";
|
||||
this.checkUpdateNotifications.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnCheckUpdates
|
||||
//
|
||||
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 409);
|
||||
this.btnCheckUpdates.AutoSize = true;
|
||||
this.btnCheckUpdates.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 451);
|
||||
this.btnCheckUpdates.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnCheckUpdates.Name = "btnCheckUpdates";
|
||||
this.btnCheckUpdates.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnCheckUpdates.TabIndex = 15;
|
||||
this.btnCheckUpdates.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnCheckUpdates.Size = new System.Drawing.Size(128, 25);
|
||||
this.btnCheckUpdates.TabIndex = 16;
|
||||
this.btnCheckUpdates.Text = "Check Updates Now";
|
||||
this.btnCheckUpdates.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelZoomValue
|
||||
//
|
||||
this.labelZoomValue.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelZoomValue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelZoomValue.Location = new System.Drawing.Point(147, 4);
|
||||
this.labelZoomValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelZoomValue.Name = "labelZoomValue";
|
||||
@@ -93,36 +100,27 @@
|
||||
this.labelZoomValue.Text = "100%";
|
||||
this.labelZoomValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// checkSwitchAccountSelectors
|
||||
//
|
||||
this.checkSwitchAccountSelectors.AutoSize = true;
|
||||
this.checkSwitchAccountSelectors.Location = new System.Drawing.Point(6, 49);
|
||||
this.checkSwitchAccountSelectors.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkSwitchAccountSelectors.Name = "checkSwitchAccountSelectors";
|
||||
this.checkSwitchAccountSelectors.Size = new System.Drawing.Size(172, 17);
|
||||
this.checkSwitchAccountSelectors.TabIndex = 2;
|
||||
this.checkSwitchAccountSelectors.Text = "Shift Selects Multiple Accounts";
|
||||
this.checkSwitchAccountSelectors.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkBestImageQuality
|
||||
//
|
||||
this.checkBestImageQuality.AutoSize = true;
|
||||
this.checkBestImageQuality.Location = new System.Drawing.Point(6, 118);
|
||||
this.checkBestImageQuality.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkBestImageQuality.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkBestImageQuality.Location = new System.Drawing.Point(6, 98);
|
||||
this.checkBestImageQuality.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkBestImageQuality.Name = "checkBestImageQuality";
|
||||
this.checkBestImageQuality.Size = new System.Drawing.Size(114, 17);
|
||||
this.checkBestImageQuality.TabIndex = 5;
|
||||
this.checkBestImageQuality.Size = new System.Drawing.Size(125, 19);
|
||||
this.checkBestImageQuality.TabIndex = 4;
|
||||
this.checkBestImageQuality.Text = "Best Image Quality";
|
||||
this.checkBestImageQuality.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkOpenSearchInFirstColumn
|
||||
//
|
||||
this.checkOpenSearchInFirstColumn.AutoSize = true;
|
||||
this.checkOpenSearchInFirstColumn.Location = new System.Drawing.Point(6, 72);
|
||||
this.checkOpenSearchInFirstColumn.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkOpenSearchInFirstColumn.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkOpenSearchInFirstColumn.Location = new System.Drawing.Point(6, 50);
|
||||
this.checkOpenSearchInFirstColumn.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkOpenSearchInFirstColumn.Name = "checkOpenSearchInFirstColumn";
|
||||
this.checkOpenSearchInFirstColumn.Size = new System.Drawing.Size(219, 17);
|
||||
this.checkOpenSearchInFirstColumn.TabIndex = 3;
|
||||
this.checkOpenSearchInFirstColumn.Size = new System.Drawing.Size(245, 19);
|
||||
this.checkOpenSearchInFirstColumn.TabIndex = 2;
|
||||
this.checkOpenSearchInFirstColumn.Text = "Add Search Columns Before First Column";
|
||||
this.checkOpenSearchInFirstColumn.UseVisualStyleBackColor = true;
|
||||
//
|
||||
@@ -144,11 +142,12 @@
|
||||
// labelZoom
|
||||
//
|
||||
this.labelZoom.AutoSize = true;
|
||||
this.labelZoom.Location = new System.Drawing.Point(3, 291);
|
||||
this.labelZoom.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelZoom.Location = new System.Drawing.Point(3, 330);
|
||||
this.labelZoom.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelZoom.Name = "labelZoom";
|
||||
this.labelZoom.Size = new System.Drawing.Size(34, 13);
|
||||
this.labelZoom.TabIndex = 11;
|
||||
this.labelZoom.Size = new System.Drawing.Size(39, 15);
|
||||
this.labelZoom.TabIndex = 12;
|
||||
this.labelZoom.Text = "Zoom";
|
||||
//
|
||||
// zoomUpdateTimer
|
||||
@@ -159,11 +158,11 @@
|
||||
// labelUI
|
||||
//
|
||||
this.labelUI.AutoSize = true;
|
||||
this.labelUI.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelUI.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelUI.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelUI.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelUI.Name = "labelUI";
|
||||
this.labelUI.Size = new System.Drawing.Size(111, 20);
|
||||
this.labelUI.Size = new System.Drawing.Size(100, 20);
|
||||
this.labelUI.TabIndex = 0;
|
||||
this.labelUI.Text = "User Interface";
|
||||
//
|
||||
@@ -172,32 +171,33 @@
|
||||
this.panelZoom.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelZoom.Controls.Add(this.trackBarZoom);
|
||||
this.panelZoom.Controls.Add(this.labelZoomValue);
|
||||
this.panelZoom.Location = new System.Drawing.Point(0, 304);
|
||||
this.panelZoom.Location = new System.Drawing.Point(0, 345);
|
||||
this.panelZoom.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelZoom.Name = "panelZoom";
|
||||
this.panelZoom.Size = new System.Drawing.Size(322, 36);
|
||||
this.panelZoom.TabIndex = 12;
|
||||
this.panelZoom.TabIndex = 13;
|
||||
//
|
||||
// checkAnimatedAvatars
|
||||
//
|
||||
this.checkAnimatedAvatars.AutoSize = true;
|
||||
this.checkAnimatedAvatars.Location = new System.Drawing.Point(6, 141);
|
||||
this.checkAnimatedAvatars.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkAnimatedAvatars.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkAnimatedAvatars.Location = new System.Drawing.Point(6, 122);
|
||||
this.checkAnimatedAvatars.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkAnimatedAvatars.Name = "checkAnimatedAvatars";
|
||||
this.checkAnimatedAvatars.Size = new System.Drawing.Size(145, 17);
|
||||
this.checkAnimatedAvatars.TabIndex = 6;
|
||||
this.checkAnimatedAvatars.Size = new System.Drawing.Size(158, 19);
|
||||
this.checkAnimatedAvatars.TabIndex = 5;
|
||||
this.checkAnimatedAvatars.Text = "Enable Animated Avatars";
|
||||
this.checkAnimatedAvatars.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelUpdates
|
||||
//
|
||||
this.labelUpdates.AutoSize = true;
|
||||
this.labelUpdates.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelUpdates.Location = new System.Drawing.Point(0, 360);
|
||||
this.labelUpdates.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelUpdates.Location = new System.Drawing.Point(0, 401);
|
||||
this.labelUpdates.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelUpdates.Name = "labelUpdates";
|
||||
this.labelUpdates.Size = new System.Drawing.Size(70, 20);
|
||||
this.labelUpdates.TabIndex = 13;
|
||||
this.labelUpdates.Size = new System.Drawing.Size(64, 20);
|
||||
this.labelUpdates.TabIndex = 14;
|
||||
this.labelUpdates.Text = "Updates";
|
||||
//
|
||||
// flowPanel
|
||||
@@ -207,7 +207,6 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowPanel.Controls.Add(this.labelUI);
|
||||
this.flowPanel.Controls.Add(this.checkExpandLinks);
|
||||
this.flowPanel.Controls.Add(this.checkSwitchAccountSelectors);
|
||||
this.flowPanel.Controls.Add(this.checkOpenSearchInFirstColumn);
|
||||
this.flowPanel.Controls.Add(this.checkKeepLikeFollowDialogsOpen);
|
||||
this.flowPanel.Controls.Add(this.checkBestImageQuality);
|
||||
@@ -216,6 +215,8 @@
|
||||
this.flowPanel.Controls.Add(this.checkSmoothScrolling);
|
||||
this.flowPanel.Controls.Add(this.labelBrowserPath);
|
||||
this.flowPanel.Controls.Add(this.comboBoxBrowserPath);
|
||||
this.flowPanel.Controls.Add(this.labelSearchEngine);
|
||||
this.flowPanel.Controls.Add(this.comboBoxSearchEngine);
|
||||
this.flowPanel.Controls.Add(this.labelZoom);
|
||||
this.flowPanel.Controls.Add(this.panelZoom);
|
||||
this.flowPanel.Controls.Add(this.labelUpdates);
|
||||
@@ -224,62 +225,88 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 438);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 486);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
// checkKeepLikeFollowDialogsOpen
|
||||
//
|
||||
this.checkKeepLikeFollowDialogsOpen.AutoSize = true;
|
||||
this.checkKeepLikeFollowDialogsOpen.Location = new System.Drawing.Point(6, 95);
|
||||
this.checkKeepLikeFollowDialogsOpen.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkKeepLikeFollowDialogsOpen.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkKeepLikeFollowDialogsOpen.Location = new System.Drawing.Point(6, 74);
|
||||
this.checkKeepLikeFollowDialogsOpen.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkKeepLikeFollowDialogsOpen.Name = "checkKeepLikeFollowDialogsOpen";
|
||||
this.checkKeepLikeFollowDialogsOpen.Size = new System.Drawing.Size(176, 17);
|
||||
this.checkKeepLikeFollowDialogsOpen.TabIndex = 4;
|
||||
this.checkKeepLikeFollowDialogsOpen.Size = new System.Drawing.Size(190, 19);
|
||||
this.checkKeepLikeFollowDialogsOpen.TabIndex = 3;
|
||||
this.checkKeepLikeFollowDialogsOpen.Text = "Keep Like/Follow Dialogs Open";
|
||||
this.checkKeepLikeFollowDialogsOpen.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelBrowserSettings
|
||||
//
|
||||
this.labelBrowserSettings.AutoSize = true;
|
||||
this.labelBrowserSettings.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelBrowserSettings.Location = new System.Drawing.Point(0, 181);
|
||||
this.labelBrowserSettings.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelBrowserSettings.Location = new System.Drawing.Point(0, 163);
|
||||
this.labelBrowserSettings.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelBrowserSettings.Name = "labelBrowserSettings";
|
||||
this.labelBrowserSettings.Size = new System.Drawing.Size(130, 20);
|
||||
this.labelBrowserSettings.TabIndex = 7;
|
||||
this.labelBrowserSettings.Size = new System.Drawing.Size(119, 20);
|
||||
this.labelBrowserSettings.TabIndex = 6;
|
||||
this.labelBrowserSettings.Text = "Browser Settings";
|
||||
//
|
||||
// checkSmoothScrolling
|
||||
//
|
||||
this.checkSmoothScrolling.AutoSize = true;
|
||||
this.checkSmoothScrolling.Location = new System.Drawing.Point(6, 207);
|
||||
this.checkSmoothScrolling.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkSmoothScrolling.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkSmoothScrolling.Location = new System.Drawing.Point(6, 189);
|
||||
this.checkSmoothScrolling.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkSmoothScrolling.Name = "checkSmoothScrolling";
|
||||
this.checkSmoothScrolling.Size = new System.Drawing.Size(105, 17);
|
||||
this.checkSmoothScrolling.TabIndex = 8;
|
||||
this.checkSmoothScrolling.Size = new System.Drawing.Size(117, 19);
|
||||
this.checkSmoothScrolling.TabIndex = 7;
|
||||
this.checkSmoothScrolling.Text = "Smooth Scrolling";
|
||||
this.checkSmoothScrolling.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelBrowserPath
|
||||
//
|
||||
this.labelBrowserPath.AutoSize = true;
|
||||
this.labelBrowserPath.Location = new System.Drawing.Point(3, 239);
|
||||
this.labelBrowserPath.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelBrowserPath.Location = new System.Drawing.Point(3, 222);
|
||||
this.labelBrowserPath.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelBrowserPath.Name = "labelBrowserPath";
|
||||
this.labelBrowserPath.Size = new System.Drawing.Size(95, 13);
|
||||
this.labelBrowserPath.TabIndex = 9;
|
||||
this.labelBrowserPath.Size = new System.Drawing.Size(103, 15);
|
||||
this.labelBrowserPath.TabIndex = 8;
|
||||
this.labelBrowserPath.Text = "Open Links With...";
|
||||
//
|
||||
// comboBoxBrowserPath
|
||||
//
|
||||
this.comboBoxBrowserPath.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxBrowserPath.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxBrowserPath.FormattingEnabled = true;
|
||||
this.comboBoxBrowserPath.Location = new System.Drawing.Point(5, 255);
|
||||
this.comboBoxBrowserPath.Location = new System.Drawing.Point(5, 240);
|
||||
this.comboBoxBrowserPath.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxBrowserPath.Name = "comboBoxBrowserPath";
|
||||
this.comboBoxBrowserPath.Size = new System.Drawing.Size(173, 21);
|
||||
this.comboBoxBrowserPath.TabIndex = 10;
|
||||
this.comboBoxBrowserPath.Size = new System.Drawing.Size(173, 23);
|
||||
this.comboBoxBrowserPath.TabIndex = 9;
|
||||
//
|
||||
// labelSearchEngine
|
||||
//
|
||||
this.labelSearchEngine.AutoSize = true;
|
||||
this.labelSearchEngine.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelSearchEngine.Location = new System.Drawing.Point(3, 276);
|
||||
this.labelSearchEngine.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelSearchEngine.Name = "labelSearchEngine";
|
||||
this.labelSearchEngine.Size = new System.Drawing.Size(81, 15);
|
||||
this.labelSearchEngine.TabIndex = 10;
|
||||
this.labelSearchEngine.Text = "Search Engine";
|
||||
//
|
||||
// comboBoxSearchEngine
|
||||
//
|
||||
this.comboBoxSearchEngine.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxSearchEngine.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxSearchEngine.FormattingEnabled = true;
|
||||
this.comboBoxSearchEngine.Location = new System.Drawing.Point(5, 294);
|
||||
this.comboBoxSearchEngine.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxSearchEngine.Name = "comboBoxSearchEngine";
|
||||
this.comboBoxSearchEngine.Size = new System.Drawing.Size(173, 23);
|
||||
this.comboBoxSearchEngine.TabIndex = 11;
|
||||
//
|
||||
// TabSettingsGeneral
|
||||
//
|
||||
@@ -287,7 +314,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsGeneral";
|
||||
this.Size = new System.Drawing.Size(340, 456);
|
||||
this.Size = new System.Drawing.Size(340, 504);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarZoom)).EndInit();
|
||||
this.panelZoom.ResumeLayout(false);
|
||||
this.flowPanel.ResumeLayout(false);
|
||||
@@ -306,7 +333,6 @@
|
||||
private System.Windows.Forms.Label labelZoomValue;
|
||||
private System.Windows.Forms.TrackBar trackBarZoom;
|
||||
private System.Windows.Forms.Timer zoomUpdateTimer;
|
||||
private System.Windows.Forms.CheckBox checkSwitchAccountSelectors;
|
||||
private System.Windows.Forms.Label labelUI;
|
||||
private System.Windows.Forms.Panel panelZoom;
|
||||
private System.Windows.Forms.Label labelUpdates;
|
||||
@@ -319,5 +345,7 @@
|
||||
private System.Windows.Forms.ComboBox comboBoxBrowserPath;
|
||||
private System.Windows.Forms.Label labelBrowserSettings;
|
||||
private System.Windows.Forms.CheckBox checkSmoothScrolling;
|
||||
private System.Windows.Forms.Label labelSearchEngine;
|
||||
private System.Windows.Forms.ComboBox comboBoxSearchEngine;
|
||||
}
|
||||
}
|
||||
|
@@ -4,29 +4,34 @@ using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling.General;
|
||||
using TweetDuck.Core.Other.Settings.Dialogs;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Updates;
|
||||
using TweetDuck.Updates.Events;
|
||||
|
||||
namespace TweetDuck.Core.Other.Settings{
|
||||
sealed partial class TabSettingsGeneral : BaseTabSettings{
|
||||
private readonly FormBrowser browser;
|
||||
private readonly Action reloadColumns;
|
||||
|
||||
private readonly UpdateHandler updates;
|
||||
private int updateCheckEventId = -1;
|
||||
|
||||
private readonly int browserListIndexDefault;
|
||||
private readonly int browserListIndexCustom;
|
||||
|
||||
public TabSettingsGeneral(FormBrowser browser, UpdateHandler updates){
|
||||
private readonly int searchEngineIndexDefault;
|
||||
private readonly int searchEngineIndexCustom;
|
||||
|
||||
public TabSettingsGeneral(Action reloadColumns, UpdateHandler updates){
|
||||
InitializeComponent();
|
||||
|
||||
this.browser = browser;
|
||||
|
||||
this.reloadColumns = reloadColumns;
|
||||
|
||||
this.updates = updates;
|
||||
this.updates.CheckFinished += updates_CheckFinished;
|
||||
Disposed += (sender, args) => this.updates.CheckFinished -= updates_CheckFinished;
|
||||
|
||||
toolTip.SetToolTip(checkExpandLinks, "Expands links inside the tweets. If disabled,\r\nthe full links show up in a tooltip instead.");
|
||||
toolTip.SetToolTip(checkSwitchAccountSelectors, "When (re)tweeting, click to select a single account or hold Shift to\r\nselect multiple accounts, instead of TweetDeck\'s default behavior.");
|
||||
toolTip.SetToolTip(checkOpenSearchInFirstColumn, "By default, TweetDeck adds Search columns at the end.\r\nThis option makes them appear before the first column instead.");
|
||||
toolTip.SetToolTip(checkKeepLikeFollowDialogsOpen, "Allows liking and following from multiple accounts at once,\r\ninstead of automatically closing the dialog after taking an action.");
|
||||
toolTip.SetToolTip(checkBestImageQuality, "When right-clicking a tweet image, the context menu options\r\nwill use links to the original image size (:orig in the URL).");
|
||||
@@ -41,7 +46,6 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
toolTip.SetToolTip(btnCheckUpdates, "Forces an update check, even for updates that had been dismissed.");
|
||||
|
||||
checkExpandLinks.Checked = Config.ExpandLinksOnHover;
|
||||
checkSwitchAccountSelectors.Checked = Config.SwitchAccountSelectors;
|
||||
checkOpenSearchInFirstColumn.Checked = Config.OpenSearchInFirstColumn;
|
||||
checkKeepLikeFollowDialogsOpen.Checked = Config.KeepLikeFollowDialogsOpen;
|
||||
checkBestImageQuality.Checked = Config.BestImageQuality;
|
||||
@@ -57,6 +61,14 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
browserListIndexCustom = comboBoxBrowserPath.Items.Add("(custom program...)");
|
||||
UpdateBrowserPathSelection();
|
||||
|
||||
comboBoxSearchEngine.Items.Add(new SearchEngine("DuckDuckGo", "https://duckduckgo.com/?q="));
|
||||
comboBoxSearchEngine.Items.Add(new SearchEngine("Google", "https://www.google.com/search?q="));
|
||||
comboBoxSearchEngine.Items.Add(new SearchEngine("Bing", "https://www.bing.com/search?q="));
|
||||
comboBoxSearchEngine.Items.Add(new SearchEngine("Yahoo", "https://search.yahoo.com/search?p="));
|
||||
searchEngineIndexDefault = comboBoxSearchEngine.Items.Add("(no engine set)");
|
||||
searchEngineIndexCustom = comboBoxSearchEngine.Items.Add("(custom url...)");
|
||||
UpdateSearchEngineSelection();
|
||||
|
||||
trackBarZoom.SetValueSafe(Config.ZoomLevel);
|
||||
labelZoomValue.Text = trackBarZoom.Value+"%";
|
||||
|
||||
@@ -65,7 +77,6 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
|
||||
public override void OnReady(){
|
||||
checkExpandLinks.CheckedChanged += checkExpandLinks_CheckedChanged;
|
||||
checkSwitchAccountSelectors.CheckedChanged += checkSwitchAccountSelectors_CheckedChanged;
|
||||
checkOpenSearchInFirstColumn.CheckedChanged += checkOpenSearchInFirstColumn_CheckedChanged;
|
||||
checkKeepLikeFollowDialogsOpen.CheckedChanged += checkKeepLikeFollowDialogsOpen_CheckedChanged;
|
||||
checkBestImageQuality.CheckedChanged += checkBestImageQuality_CheckedChanged;
|
||||
@@ -73,6 +84,7 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
|
||||
checkSmoothScrolling.CheckedChanged += checkSmoothScrolling_CheckedChanged;
|
||||
comboBoxBrowserPath.SelectedIndexChanged += comboBoxBrowserPath_SelectedIndexChanged;
|
||||
comboBoxSearchEngine.SelectedIndexChanged += comboBoxSearchEngine_SelectedIndexChanged;
|
||||
trackBarZoom.ValueChanged += trackBarZoom_ValueChanged;
|
||||
|
||||
checkUpdateNotifications.CheckedChanged += checkUpdateNotifications_CheckedChanged;
|
||||
@@ -87,10 +99,6 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
Config.ExpandLinksOnHover = checkExpandLinks.Checked;
|
||||
}
|
||||
|
||||
private void checkSwitchAccountSelectors_CheckedChanged(object sender, EventArgs e){
|
||||
Config.SwitchAccountSelectors = checkSwitchAccountSelectors.Checked;
|
||||
}
|
||||
|
||||
private void checkOpenSearchInFirstColumn_CheckedChanged(object sender, EventArgs e){
|
||||
Config.OpenSearchInFirstColumn = checkOpenSearchInFirstColumn.Checked;
|
||||
}
|
||||
@@ -105,7 +113,7 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
|
||||
private void checkAnimatedAvatars_CheckedChanged(object sender, EventArgs e){
|
||||
Config.EnableAnimatedImages = checkAnimatedAvatars.Checked;
|
||||
BrowserProcessHandler.UpdatePrefs().ContinueWith(task => browser.ReloadColumns());
|
||||
BrowserProcessHandler.UpdatePrefs().ContinueWith(task => reloadColumns());
|
||||
}
|
||||
|
||||
private void checkSmoothScrolling_CheckedChanged(object sender, EventArgs e){
|
||||
@@ -141,18 +149,50 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
if (dialog.ShowDialog() == DialogResult.OK){
|
||||
Config.BrowserPath = dialog.FileName;
|
||||
}
|
||||
else{
|
||||
comboBoxBrowserPath.SelectedIndexChanged -= comboBoxBrowserPath_SelectedIndexChanged;
|
||||
UpdateBrowserPathSelection();
|
||||
comboBoxBrowserPath.SelectedIndexChanged += comboBoxBrowserPath_SelectedIndexChanged;
|
||||
}
|
||||
}
|
||||
|
||||
comboBoxBrowserPath.SelectedIndexChanged -= comboBoxBrowserPath_SelectedIndexChanged;
|
||||
UpdateBrowserPathSelection();
|
||||
comboBoxBrowserPath.SelectedIndexChanged += comboBoxBrowserPath_SelectedIndexChanged;
|
||||
}
|
||||
else{
|
||||
Config.BrowserPath = (comboBoxBrowserPath.SelectedItem as WindowsUtils.Browser)?.Path; // default browser item is a string and casts to null
|
||||
}
|
||||
}
|
||||
|
||||
private void comboBoxSearchEngine_SelectedIndexChanged(object sender, EventArgs e){
|
||||
if (comboBoxSearchEngine.SelectedIndex == searchEngineIndexCustom){
|
||||
using(DialogSettingsSearchEngine dialog = new DialogSettingsSearchEngine()){
|
||||
if (dialog.ShowDialog() == DialogResult.OK){
|
||||
Config.SearchEngineUrl = dialog.Url.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
comboBoxSearchEngine.SelectedIndexChanged -= comboBoxSearchEngine_SelectedIndexChanged;
|
||||
UpdateSearchEngineSelection();
|
||||
comboBoxSearchEngine.SelectedIndexChanged += comboBoxSearchEngine_SelectedIndexChanged;
|
||||
}
|
||||
else{
|
||||
Config.SearchEngineUrl = (comboBoxSearchEngine.SelectedItem as SearchEngine)?.Url; // default search engine item is a string and casts to null
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSearchEngineSelection(){
|
||||
if (string.IsNullOrEmpty(Config.SearchEngineUrl)){
|
||||
comboBoxSearchEngine.SelectedIndex = searchEngineIndexDefault;
|
||||
}
|
||||
else{
|
||||
SearchEngine engineInfo = comboBoxSearchEngine.Items.OfType<SearchEngine>().FirstOrDefault(engine => engine.Url == Config.SearchEngineUrl);
|
||||
|
||||
if (engineInfo == null){
|
||||
comboBoxSearchEngine.SelectedIndex = searchEngineIndexCustom;
|
||||
}
|
||||
else{
|
||||
comboBoxSearchEngine.SelectedItem = engineInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void trackBarZoom_ValueChanged(object sender, EventArgs e){
|
||||
if (trackBarZoom.AlignValueToTick()){
|
||||
zoomUpdateTimer.Stop();
|
||||
@@ -170,23 +210,44 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
|
||||
btnCheckUpdates.Enabled = false;
|
||||
updateCheckEventId = updates.Check(true);
|
||||
|
||||
if (updateCheckEventId == UpdateHandler.CheckCodeNotOnTweetDeck){
|
||||
FormMessage.Error("Update Check", "Updates can only be checked once TweetDeck is fully loaded.", FormMessage.OK);
|
||||
btnCheckUpdates.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updates_CheckFinished(object sender, UpdateEventArgs e){
|
||||
this.InvokeAsyncSafe(() => {
|
||||
if (e.EventId == updateCheckEventId){
|
||||
btnCheckUpdates.Enabled = true;
|
||||
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
|
||||
if (e.EventId == updateCheckEventId){
|
||||
btnCheckUpdates.Enabled = true;
|
||||
|
||||
if (!e.IsUpdateAvailable){
|
||||
e.Result.Handle(update => {
|
||||
if (update.VersionTag == Program.VersionTag){
|
||||
FormMessage.Information("No Updates Available", "Your version of TweetDuck is up to date.", FormMessage.OK);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, ex => {
|
||||
Program.Reporter.HandleException("Update Check Error", "An error occurred while checking for updates.", true, ex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void zoomUpdateTimer_Tick(object sender, EventArgs e){
|
||||
Config.ZoomLevel = trackBarZoom.Value;
|
||||
zoomUpdateTimer.Stop();
|
||||
}
|
||||
|
||||
private sealed class SearchEngine{
|
||||
private string Name { get; }
|
||||
public string Url { get; }
|
||||
|
||||
public SearchEngine(string name, string url){
|
||||
Name = name;
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public override int GetHashCode() => Name.GetHashCode();
|
||||
public override bool Equals(object obj) => obj is SearchEngine other && Name == other.Name;
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
Core/Other/Settings/TabSettingsLocales.Designer.cs
generated
39
Core/Other/Settings/TabSettingsLocales.Designer.cs
generated
@@ -39,10 +39,11 @@
|
||||
// checkSpellCheck
|
||||
//
|
||||
this.checkSpellCheck.AutoSize = true;
|
||||
this.checkSpellCheck.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkSpellCheck.Location = new System.Drawing.Point(6, 26);
|
||||
this.checkSpellCheck.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkSpellCheck.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkSpellCheck.Name = "checkSpellCheck";
|
||||
this.checkSpellCheck.Size = new System.Drawing.Size(119, 17);
|
||||
this.checkSpellCheck.Size = new System.Drawing.Size(125, 19);
|
||||
this.checkSpellCheck.TabIndex = 1;
|
||||
this.checkSpellCheck.Text = "Enable Spell Check";
|
||||
this.checkSpellCheck.UseVisualStyleBackColor = true;
|
||||
@@ -50,11 +51,11 @@
|
||||
// labelLocales
|
||||
//
|
||||
this.labelLocales.AutoSize = true;
|
||||
this.labelLocales.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelLocales.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelLocales.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelLocales.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelLocales.Name = "labelLocales";
|
||||
this.labelLocales.Size = new System.Drawing.Size(64, 20);
|
||||
this.labelLocales.Size = new System.Drawing.Size(58, 20);
|
||||
this.labelLocales.TabIndex = 0;
|
||||
this.labelLocales.Text = "Locales";
|
||||
//
|
||||
@@ -73,59 +74,63 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 193);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 201);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
// labelSpellCheckLanguage
|
||||
//
|
||||
this.labelSpellCheckLanguage.AutoSize = true;
|
||||
this.labelSpellCheckLanguage.Location = new System.Drawing.Point(3, 58);
|
||||
this.labelSpellCheckLanguage.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelSpellCheckLanguage.Location = new System.Drawing.Point(3, 59);
|
||||
this.labelSpellCheckLanguage.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelSpellCheckLanguage.Name = "labelSpellCheckLanguage";
|
||||
this.labelSpellCheckLanguage.Size = new System.Drawing.Size(115, 13);
|
||||
this.labelSpellCheckLanguage.Size = new System.Drawing.Size(123, 15);
|
||||
this.labelSpellCheckLanguage.TabIndex = 2;
|
||||
this.labelSpellCheckLanguage.Text = "Spell Check Language";
|
||||
//
|
||||
// comboBoxSpellCheckLanguage
|
||||
//
|
||||
this.comboBoxSpellCheckLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxSpellCheckLanguage.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxSpellCheckLanguage.FormattingEnabled = true;
|
||||
this.comboBoxSpellCheckLanguage.Location = new System.Drawing.Point(5, 74);
|
||||
this.comboBoxSpellCheckLanguage.Location = new System.Drawing.Point(5, 77);
|
||||
this.comboBoxSpellCheckLanguage.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxSpellCheckLanguage.Name = "comboBoxSpellCheckLanguage";
|
||||
this.comboBoxSpellCheckLanguage.Size = new System.Drawing.Size(311, 21);
|
||||
this.comboBoxSpellCheckLanguage.Size = new System.Drawing.Size(311, 23);
|
||||
this.comboBoxSpellCheckLanguage.TabIndex = 3;
|
||||
//
|
||||
// labelTranslations
|
||||
//
|
||||
this.labelTranslations.AutoSize = true;
|
||||
this.labelTranslations.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTranslations.Location = new System.Drawing.Point(0, 118);
|
||||
this.labelTranslations.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTranslations.Location = new System.Drawing.Point(0, 123);
|
||||
this.labelTranslations.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelTranslations.Name = "labelTranslations";
|
||||
this.labelTranslations.Size = new System.Drawing.Size(116, 20);
|
||||
this.labelTranslations.Size = new System.Drawing.Size(109, 20);
|
||||
this.labelTranslations.TabIndex = 4;
|
||||
this.labelTranslations.Text = "Bing Translator";
|
||||
//
|
||||
// labelTranslationTarget
|
||||
//
|
||||
this.labelTranslationTarget.AutoSize = true;
|
||||
this.labelTranslationTarget.Location = new System.Drawing.Point(3, 150);
|
||||
this.labelTranslationTarget.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTranslationTarget.Location = new System.Drawing.Point(3, 155);
|
||||
this.labelTranslationTarget.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelTranslationTarget.Name = "labelTranslationTarget";
|
||||
this.labelTranslationTarget.Size = new System.Drawing.Size(89, 13);
|
||||
this.labelTranslationTarget.Size = new System.Drawing.Size(96, 15);
|
||||
this.labelTranslationTarget.TabIndex = 5;
|
||||
this.labelTranslationTarget.Text = "Target Language";
|
||||
//
|
||||
// comboBoxTranslationTarget
|
||||
//
|
||||
this.comboBoxTranslationTarget.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxTranslationTarget.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxTranslationTarget.FormattingEnabled = true;
|
||||
this.comboBoxTranslationTarget.Location = new System.Drawing.Point(5, 166);
|
||||
this.comboBoxTranslationTarget.Location = new System.Drawing.Point(5, 173);
|
||||
this.comboBoxTranslationTarget.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxTranslationTarget.Name = "comboBoxTranslationTarget";
|
||||
this.comboBoxTranslationTarget.Size = new System.Drawing.Size(311, 21);
|
||||
this.comboBoxTranslationTarget.Size = new System.Drawing.Size(311, 23);
|
||||
this.comboBoxTranslationTarget.TabIndex = 6;
|
||||
//
|
||||
// TabSettingsLocales
|
||||
@@ -134,7 +139,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsLocales";
|
||||
this.Size = new System.Drawing.Size(340, 211);
|
||||
this.Size = new System.Drawing.Size(340, 219);
|
||||
this.flowPanel.ResumeLayout(false);
|
||||
this.flowPanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
@@ -42,12 +42,12 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
}
|
||||
|
||||
private void comboBoxSpellCheckLanguage_SelectedValueChanged(object sender, EventArgs e){
|
||||
Config.SpellCheckLanguage = (comboBoxSpellCheckLanguage.SelectedItem as LocaleUtils.Item)?.Code;
|
||||
Config.SpellCheckLanguage = (comboBoxSpellCheckLanguage.SelectedItem as LocaleUtils.Item)?.Code ?? "en-US";
|
||||
PromptRestart();
|
||||
}
|
||||
|
||||
private void comboBoxTranslationTarget_SelectedValueChanged(object sender, EventArgs e){
|
||||
Config.TranslationTarget = (comboBoxTranslationTarget.SelectedItem as LocaleUtils.Item)?.Code;
|
||||
Config.TranslationTarget = (comboBoxTranslationTarget.SelectedItem as LocaleUtils.Item)?.Code ?? "en";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
162
Core/Other/Settings/TabSettingsNotifications.Designer.cs
generated
162
Core/Other/Settings/TabSettingsNotifications.Designer.cs
generated
@@ -80,10 +80,11 @@
|
||||
//
|
||||
// labelEdgeDistanceValue
|
||||
//
|
||||
this.labelEdgeDistanceValue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelEdgeDistanceValue.Location = new System.Drawing.Point(145, 4);
|
||||
this.labelEdgeDistanceValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelEdgeDistanceValue.Name = "labelEdgeDistanceValue";
|
||||
this.labelEdgeDistanceValue.Size = new System.Drawing.Size(40, 13);
|
||||
this.labelEdgeDistanceValue.Size = new System.Drawing.Size(40, 15);
|
||||
this.labelEdgeDistanceValue.TabIndex = 1;
|
||||
this.labelEdgeDistanceValue.Text = "0 px";
|
||||
this.labelEdgeDistanceValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
@@ -91,39 +92,43 @@
|
||||
// labelDisplay
|
||||
//
|
||||
this.labelDisplay.AutoSize = true;
|
||||
this.labelDisplay.Location = new System.Drawing.Point(3, 451);
|
||||
this.labelDisplay.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDisplay.Location = new System.Drawing.Point(3, 465);
|
||||
this.labelDisplay.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelDisplay.Name = "labelDisplay";
|
||||
this.labelDisplay.Size = new System.Drawing.Size(41, 13);
|
||||
this.labelDisplay.Size = new System.Drawing.Size(45, 15);
|
||||
this.labelDisplay.TabIndex = 15;
|
||||
this.labelDisplay.Text = "Display";
|
||||
//
|
||||
// comboBoxDisplay
|
||||
//
|
||||
this.comboBoxDisplay.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxDisplay.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxDisplay.FormattingEnabled = true;
|
||||
this.comboBoxDisplay.Location = new System.Drawing.Point(5, 467);
|
||||
this.comboBoxDisplay.Location = new System.Drawing.Point(5, 483);
|
||||
this.comboBoxDisplay.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxDisplay.Name = "comboBoxDisplay";
|
||||
this.comboBoxDisplay.Size = new System.Drawing.Size(144, 21);
|
||||
this.comboBoxDisplay.Size = new System.Drawing.Size(144, 23);
|
||||
this.comboBoxDisplay.TabIndex = 16;
|
||||
//
|
||||
// labelEdgeDistance
|
||||
//
|
||||
this.labelEdgeDistance.AutoSize = true;
|
||||
this.labelEdgeDistance.Location = new System.Drawing.Point(3, 503);
|
||||
this.labelEdgeDistance.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelEdgeDistance.Location = new System.Drawing.Point(3, 521);
|
||||
this.labelEdgeDistance.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelEdgeDistance.Name = "labelEdgeDistance";
|
||||
this.labelEdgeDistance.Size = new System.Drawing.Size(103, 13);
|
||||
this.labelEdgeDistance.Size = new System.Drawing.Size(112, 15);
|
||||
this.labelEdgeDistance.TabIndex = 17;
|
||||
this.labelEdgeDistance.Text = "Distance From Edge";
|
||||
//
|
||||
// radioLocCustom
|
||||
//
|
||||
this.radioLocCustom.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioLocCustom.Location = new System.Drawing.Point(205, 4);
|
||||
this.radioLocCustom.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocCustom.Name = "radioLocCustom";
|
||||
this.radioLocCustom.Size = new System.Drawing.Size(65, 41);
|
||||
this.radioLocCustom.Size = new System.Drawing.Size(70, 43);
|
||||
this.radioLocCustom.TabIndex = 4;
|
||||
this.radioLocCustom.TabStop = true;
|
||||
this.radioLocCustom.Text = "Custom";
|
||||
@@ -131,10 +136,11 @@
|
||||
//
|
||||
// radioLocBR
|
||||
//
|
||||
this.radioLocBR.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioLocBR.Location = new System.Drawing.Point(105, 28);
|
||||
this.radioLocBR.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocBR.Name = "radioLocBR";
|
||||
this.radioLocBR.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocBR.Size = new System.Drawing.Size(92, 19);
|
||||
this.radioLocBR.TabIndex = 3;
|
||||
this.radioLocBR.TabStop = true;
|
||||
this.radioLocBR.Text = "Bottom Right";
|
||||
@@ -142,10 +148,11 @@
|
||||
//
|
||||
// radioLocBL
|
||||
//
|
||||
this.radioLocBL.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioLocBL.Location = new System.Drawing.Point(5, 28);
|
||||
this.radioLocBL.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocBL.Name = "radioLocBL";
|
||||
this.radioLocBL.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocBL.Size = new System.Drawing.Size(92, 19);
|
||||
this.radioLocBL.TabIndex = 2;
|
||||
this.radioLocBL.TabStop = true;
|
||||
this.radioLocBL.Text = "Bottom Left";
|
||||
@@ -153,10 +160,11 @@
|
||||
//
|
||||
// radioLocTR
|
||||
//
|
||||
this.radioLocTR.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioLocTR.Location = new System.Drawing.Point(105, 4);
|
||||
this.radioLocTR.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocTR.Name = "radioLocTR";
|
||||
this.radioLocTR.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocTR.Size = new System.Drawing.Size(92, 19);
|
||||
this.radioLocTR.TabIndex = 1;
|
||||
this.radioLocTR.TabStop = true;
|
||||
this.radioLocTR.Text = "Top Right";
|
||||
@@ -164,10 +172,11 @@
|
||||
//
|
||||
// radioLocTL
|
||||
//
|
||||
this.radioLocTL.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioLocTL.Location = new System.Drawing.Point(5, 4);
|
||||
this.radioLocTL.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocTL.Name = "radioLocTL";
|
||||
this.radioLocTL.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocTL.Size = new System.Drawing.Size(92, 19);
|
||||
this.radioLocTL.TabIndex = 0;
|
||||
this.radioLocTL.TabStop = true;
|
||||
this.radioLocTL.Text = "Top Left";
|
||||
@@ -196,11 +205,11 @@
|
||||
this.tableLayoutDurationButtons.Controls.Add(this.btnDurationMedium, 0, 0);
|
||||
this.tableLayoutDurationButtons.Controls.Add(this.btnDurationLong, 1, 0);
|
||||
this.tableLayoutDurationButtons.Controls.Add(this.btnDurationShort, 0, 0);
|
||||
this.tableLayoutDurationButtons.Location = new System.Drawing.Point(3, 320);
|
||||
this.tableLayoutDurationButtons.Location = new System.Drawing.Point(3, 332);
|
||||
this.tableLayoutDurationButtons.Name = "tableLayoutDurationButtons";
|
||||
this.tableLayoutDurationButtons.RowCount = 1;
|
||||
this.tableLayoutDurationButtons.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutDurationButtons.Size = new System.Drawing.Size(171, 27);
|
||||
this.tableLayoutDurationButtons.Size = new System.Drawing.Size(180, 27);
|
||||
this.tableLayoutDurationButtons.TabIndex = 12;
|
||||
//
|
||||
// btnDurationMedium
|
||||
@@ -210,10 +219,11 @@
|
||||
this.btnDurationMedium.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.ControlLight;
|
||||
this.btnDurationMedium.FlatAppearance.MouseOverBackColor = System.Drawing.Color.White;
|
||||
this.btnDurationMedium.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnDurationMedium.Location = new System.Drawing.Point(55, 1);
|
||||
this.btnDurationMedium.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnDurationMedium.Location = new System.Drawing.Point(58, 1);
|
||||
this.btnDurationMedium.Margin = new System.Windows.Forms.Padding(1);
|
||||
this.btnDurationMedium.Name = "btnDurationMedium";
|
||||
this.btnDurationMedium.Size = new System.Drawing.Size(59, 25);
|
||||
this.btnDurationMedium.Size = new System.Drawing.Size(62, 25);
|
||||
this.btnDurationMedium.TabIndex = 1;
|
||||
this.btnDurationMedium.Text = "Medium";
|
||||
this.btnDurationMedium.UseVisualStyleBackColor = true;
|
||||
@@ -225,10 +235,11 @@
|
||||
this.btnDurationLong.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.ControlLight;
|
||||
this.btnDurationLong.FlatAppearance.MouseOverBackColor = System.Drawing.Color.White;
|
||||
this.btnDurationLong.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnDurationLong.Location = new System.Drawing.Point(116, 1);
|
||||
this.btnDurationLong.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnDurationLong.Location = new System.Drawing.Point(122, 1);
|
||||
this.btnDurationLong.Margin = new System.Windows.Forms.Padding(1);
|
||||
this.btnDurationLong.Name = "btnDurationLong";
|
||||
this.btnDurationLong.Size = new System.Drawing.Size(54, 25);
|
||||
this.btnDurationLong.Size = new System.Drawing.Size(57, 25);
|
||||
this.btnDurationLong.TabIndex = 2;
|
||||
this.btnDurationLong.Text = "Long";
|
||||
this.btnDurationLong.UseVisualStyleBackColor = true;
|
||||
@@ -240,10 +251,11 @@
|
||||
this.btnDurationShort.FlatAppearance.MouseDownBackColor = System.Drawing.SystemColors.ControlLight;
|
||||
this.btnDurationShort.FlatAppearance.MouseOverBackColor = System.Drawing.Color.White;
|
||||
this.btnDurationShort.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnDurationShort.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnDurationShort.Location = new System.Drawing.Point(1, 1);
|
||||
this.btnDurationShort.Margin = new System.Windows.Forms.Padding(1);
|
||||
this.btnDurationShort.Name = "btnDurationShort";
|
||||
this.btnDurationShort.Size = new System.Drawing.Size(52, 25);
|
||||
this.btnDurationShort.Size = new System.Drawing.Size(55, 25);
|
||||
this.btnDurationShort.TabIndex = 0;
|
||||
this.btnDurationShort.Text = "Short";
|
||||
this.btnDurationShort.UseVisualStyleBackColor = true;
|
||||
@@ -251,10 +263,11 @@
|
||||
// labelDurationValue
|
||||
//
|
||||
this.labelDurationValue.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelDurationValue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDurationValue.Location = new System.Drawing.Point(147, 4);
|
||||
this.labelDurationValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelDurationValue.Name = "labelDurationValue";
|
||||
this.labelDurationValue.Size = new System.Drawing.Size(52, 13);
|
||||
this.labelDurationValue.Size = new System.Drawing.Size(52, 15);
|
||||
this.labelDurationValue.TabIndex = 1;
|
||||
this.labelDurationValue.Text = "0 ms/c";
|
||||
this.labelDurationValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
@@ -274,10 +287,11 @@
|
||||
// checkSkipOnLinkClick
|
||||
//
|
||||
this.checkSkipOnLinkClick.AutoSize = true;
|
||||
this.checkSkipOnLinkClick.Location = new System.Drawing.Point(6, 72);
|
||||
this.checkSkipOnLinkClick.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkSkipOnLinkClick.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkSkipOnLinkClick.Location = new System.Drawing.Point(6, 74);
|
||||
this.checkSkipOnLinkClick.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkSkipOnLinkClick.Name = "checkSkipOnLinkClick";
|
||||
this.checkSkipOnLinkClick.Size = new System.Drawing.Size(113, 17);
|
||||
this.checkSkipOnLinkClick.Size = new System.Drawing.Size(121, 19);
|
||||
this.checkSkipOnLinkClick.TabIndex = 3;
|
||||
this.checkSkipOnLinkClick.Text = "Skip On Link Click";
|
||||
this.checkSkipOnLinkClick.UseVisualStyleBackColor = true;
|
||||
@@ -285,10 +299,11 @@
|
||||
// checkColumnName
|
||||
//
|
||||
this.checkColumnName.AutoSize = true;
|
||||
this.checkColumnName.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkColumnName.Location = new System.Drawing.Point(6, 26);
|
||||
this.checkColumnName.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkColumnName.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkColumnName.Name = "checkColumnName";
|
||||
this.checkColumnName.Size = new System.Drawing.Size(129, 17);
|
||||
this.checkColumnName.Size = new System.Drawing.Size(145, 19);
|
||||
this.checkColumnName.TabIndex = 1;
|
||||
this.checkColumnName.Text = "Display Column Name";
|
||||
this.checkColumnName.UseVisualStyleBackColor = true;
|
||||
@@ -296,30 +311,33 @@
|
||||
// labelIdlePause
|
||||
//
|
||||
this.labelIdlePause.AutoSize = true;
|
||||
this.labelIdlePause.Location = new System.Drawing.Point(3, 127);
|
||||
this.labelIdlePause.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelIdlePause.Location = new System.Drawing.Point(3, 131);
|
||||
this.labelIdlePause.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelIdlePause.Name = "labelIdlePause";
|
||||
this.labelIdlePause.Size = new System.Drawing.Size(89, 13);
|
||||
this.labelIdlePause.Size = new System.Drawing.Size(94, 15);
|
||||
this.labelIdlePause.TabIndex = 5;
|
||||
this.labelIdlePause.Text = "Pause When Idle";
|
||||
//
|
||||
// comboBoxIdlePause
|
||||
//
|
||||
this.comboBoxIdlePause.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxIdlePause.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxIdlePause.FormattingEnabled = true;
|
||||
this.comboBoxIdlePause.Location = new System.Drawing.Point(5, 143);
|
||||
this.comboBoxIdlePause.Location = new System.Drawing.Point(5, 149);
|
||||
this.comboBoxIdlePause.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxIdlePause.Name = "comboBoxIdlePause";
|
||||
this.comboBoxIdlePause.Size = new System.Drawing.Size(144, 21);
|
||||
this.comboBoxIdlePause.Size = new System.Drawing.Size(144, 23);
|
||||
this.comboBoxIdlePause.TabIndex = 6;
|
||||
//
|
||||
// checkNonIntrusive
|
||||
//
|
||||
this.checkNonIntrusive.AutoSize = true;
|
||||
this.checkNonIntrusive.Location = new System.Drawing.Point(6, 95);
|
||||
this.checkNonIntrusive.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkNonIntrusive.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkNonIntrusive.Location = new System.Drawing.Point(6, 98);
|
||||
this.checkNonIntrusive.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkNonIntrusive.Name = "checkNonIntrusive";
|
||||
this.checkNonIntrusive.Size = new System.Drawing.Size(128, 17);
|
||||
this.checkNonIntrusive.Size = new System.Drawing.Size(142, 19);
|
||||
this.checkNonIntrusive.TabIndex = 4;
|
||||
this.checkNonIntrusive.Text = "Non-Intrusive Popups";
|
||||
this.checkNonIntrusive.UseVisualStyleBackColor = true;
|
||||
@@ -327,10 +345,11 @@
|
||||
// checkTimerCountDown
|
||||
//
|
||||
this.checkTimerCountDown.AutoSize = true;
|
||||
this.checkTimerCountDown.Location = new System.Drawing.Point(6, 236);
|
||||
this.checkTimerCountDown.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkTimerCountDown.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkTimerCountDown.Location = new System.Drawing.Point(6, 245);
|
||||
this.checkTimerCountDown.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkTimerCountDown.Name = "checkTimerCountDown";
|
||||
this.checkTimerCountDown.Size = new System.Drawing.Size(119, 17);
|
||||
this.checkTimerCountDown.Size = new System.Drawing.Size(132, 19);
|
||||
this.checkTimerCountDown.TabIndex = 9;
|
||||
this.checkTimerCountDown.Text = "Timer Counts Down";
|
||||
this.checkTimerCountDown.UseVisualStyleBackColor = true;
|
||||
@@ -338,20 +357,22 @@
|
||||
// checkNotificationTimer
|
||||
//
|
||||
this.checkNotificationTimer.AutoSize = true;
|
||||
this.checkNotificationTimer.Location = new System.Drawing.Point(6, 213);
|
||||
this.checkNotificationTimer.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkNotificationTimer.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkNotificationTimer.Location = new System.Drawing.Point(6, 221);
|
||||
this.checkNotificationTimer.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkNotificationTimer.Name = "checkNotificationTimer";
|
||||
this.checkNotificationTimer.Size = new System.Drawing.Size(145, 17);
|
||||
this.checkNotificationTimer.Size = new System.Drawing.Size(164, 19);
|
||||
this.checkNotificationTimer.TabIndex = 8;
|
||||
this.checkNotificationTimer.Text = "Display Notification Timer";
|
||||
this.checkNotificationTimer.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radioSizeAuto
|
||||
//
|
||||
this.radioSizeAuto.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioSizeAuto.Location = new System.Drawing.Point(5, 4);
|
||||
this.radioSizeAuto.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioSizeAuto.Name = "radioSizeAuto";
|
||||
this.radioSizeAuto.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioSizeAuto.Size = new System.Drawing.Size(92, 19);
|
||||
this.radioSizeAuto.TabIndex = 0;
|
||||
this.radioSizeAuto.TabStop = true;
|
||||
this.radioSizeAuto.Text = "Auto";
|
||||
@@ -359,10 +380,11 @@
|
||||
//
|
||||
// radioSizeCustom
|
||||
//
|
||||
this.radioSizeCustom.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.radioSizeCustom.Location = new System.Drawing.Point(105, 4);
|
||||
this.radioSizeCustom.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioSizeCustom.Name = "radioSizeCustom";
|
||||
this.radioSizeCustom.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioSizeCustom.Size = new System.Drawing.Size(92, 19);
|
||||
this.radioSizeCustom.TabIndex = 1;
|
||||
this.radioSizeCustom.TabStop = true;
|
||||
this.radioSizeCustom.Text = "Custom";
|
||||
@@ -371,11 +393,11 @@
|
||||
// labelGeneral
|
||||
//
|
||||
this.labelGeneral.AutoSize = true;
|
||||
this.labelGeneral.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelGeneral.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelGeneral.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelGeneral.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelGeneral.Name = "labelGeneral";
|
||||
this.labelGeneral.Size = new System.Drawing.Size(66, 20);
|
||||
this.labelGeneral.Size = new System.Drawing.Size(60, 20);
|
||||
this.labelGeneral.TabIndex = 0;
|
||||
this.labelGeneral.Text = "General";
|
||||
//
|
||||
@@ -384,7 +406,7 @@
|
||||
this.panelEdgeDistance.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelEdgeDistance.Controls.Add(this.trackBarEdgeDistance);
|
||||
this.panelEdgeDistance.Controls.Add(this.labelEdgeDistanceValue);
|
||||
this.panelEdgeDistance.Location = new System.Drawing.Point(0, 516);
|
||||
this.panelEdgeDistance.Location = new System.Drawing.Point(0, 536);
|
||||
this.panelEdgeDistance.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelEdgeDistance.Name = "panelEdgeDistance";
|
||||
this.panelEdgeDistance.Size = new System.Drawing.Size(322, 36);
|
||||
@@ -393,20 +415,22 @@
|
||||
// checkMediaPreviews
|
||||
//
|
||||
this.checkMediaPreviews.AutoSize = true;
|
||||
this.checkMediaPreviews.Location = new System.Drawing.Point(6, 49);
|
||||
this.checkMediaPreviews.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkMediaPreviews.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkMediaPreviews.Location = new System.Drawing.Point(6, 50);
|
||||
this.checkMediaPreviews.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||
this.checkMediaPreviews.Name = "checkMediaPreviews";
|
||||
this.checkMediaPreviews.Size = new System.Drawing.Size(131, 17);
|
||||
this.checkMediaPreviews.Size = new System.Drawing.Size(140, 19);
|
||||
this.checkMediaPreviews.TabIndex = 2;
|
||||
this.checkMediaPreviews.Text = "Show Media Previews";
|
||||
this.checkMediaPreviews.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelScrollSpeedValue
|
||||
//
|
||||
this.labelScrollSpeedValue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelScrollSpeedValue.Location = new System.Drawing.Point(145, 4);
|
||||
this.labelScrollSpeedValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelScrollSpeedValue.Name = "labelScrollSpeedValue";
|
||||
this.labelScrollSpeedValue.Size = new System.Drawing.Size(38, 13);
|
||||
this.labelScrollSpeedValue.Size = new System.Drawing.Size(38, 15);
|
||||
this.labelScrollSpeedValue.TabIndex = 1;
|
||||
this.labelScrollSpeedValue.Text = "100%";
|
||||
this.labelScrollSpeedValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
@@ -428,21 +452,22 @@
|
||||
// labelScrollSpeed
|
||||
//
|
||||
this.labelScrollSpeed.AutoSize = true;
|
||||
this.labelScrollSpeed.Location = new System.Drawing.Point(3, 629);
|
||||
this.labelScrollSpeed.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelScrollSpeed.Location = new System.Drawing.Point(3, 651);
|
||||
this.labelScrollSpeed.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelScrollSpeed.Name = "labelScrollSpeed";
|
||||
this.labelScrollSpeed.Size = new System.Drawing.Size(67, 13);
|
||||
this.labelScrollSpeed.Size = new System.Drawing.Size(71, 15);
|
||||
this.labelScrollSpeed.TabIndex = 21;
|
||||
this.labelScrollSpeed.Text = "Scroll Speed";
|
||||
//
|
||||
// labelLocation
|
||||
//
|
||||
this.labelLocation.AutoSize = true;
|
||||
this.labelLocation.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelLocation.Location = new System.Drawing.Point(0, 370);
|
||||
this.labelLocation.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelLocation.Location = new System.Drawing.Point(0, 382);
|
||||
this.labelLocation.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelLocation.Name = "labelLocation";
|
||||
this.labelLocation.Size = new System.Drawing.Size(70, 20);
|
||||
this.labelLocation.Size = new System.Drawing.Size(66, 20);
|
||||
this.labelLocation.TabIndex = 13;
|
||||
this.labelLocation.Text = "Location";
|
||||
//
|
||||
@@ -454,10 +479,10 @@
|
||||
this.panelLocation.Controls.Add(this.radioLocBL);
|
||||
this.panelLocation.Controls.Add(this.radioLocCustom);
|
||||
this.panelLocation.Controls.Add(this.radioLocBR);
|
||||
this.panelLocation.Location = new System.Drawing.Point(0, 390);
|
||||
this.panelLocation.Location = new System.Drawing.Point(0, 402);
|
||||
this.panelLocation.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelLocation.Name = "panelLocation";
|
||||
this.panelLocation.Size = new System.Drawing.Size(322, 49);
|
||||
this.panelLocation.Size = new System.Drawing.Size(322, 51);
|
||||
this.panelLocation.TabIndex = 14;
|
||||
//
|
||||
// panelTimer
|
||||
@@ -465,7 +490,7 @@
|
||||
this.panelTimer.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelTimer.Controls.Add(this.labelDurationValue);
|
||||
this.panelTimer.Controls.Add(this.trackBarDuration);
|
||||
this.panelTimer.Location = new System.Drawing.Point(0, 281);
|
||||
this.panelTimer.Location = new System.Drawing.Point(0, 293);
|
||||
this.panelTimer.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelTimer.Name = "panelTimer";
|
||||
this.panelTimer.Size = new System.Drawing.Size(322, 36);
|
||||
@@ -474,32 +499,33 @@
|
||||
// labelDuration
|
||||
//
|
||||
this.labelDuration.AutoSize = true;
|
||||
this.labelDuration.Location = new System.Drawing.Point(3, 268);
|
||||
this.labelDuration.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelDuration.Location = new System.Drawing.Point(3, 278);
|
||||
this.labelDuration.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelDuration.Name = "labelDuration";
|
||||
this.labelDuration.Size = new System.Drawing.Size(47, 13);
|
||||
this.labelDuration.Size = new System.Drawing.Size(53, 15);
|
||||
this.labelDuration.TabIndex = 10;
|
||||
this.labelDuration.Text = "Duration";
|
||||
//
|
||||
// labelTimer
|
||||
//
|
||||
this.labelTimer.AutoSize = true;
|
||||
this.labelTimer.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTimer.Location = new System.Drawing.Point(0, 187);
|
||||
this.labelTimer.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTimer.Location = new System.Drawing.Point(0, 195);
|
||||
this.labelTimer.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelTimer.Name = "labelTimer";
|
||||
this.labelTimer.Size = new System.Drawing.Size(48, 20);
|
||||
this.labelTimer.Size = new System.Drawing.Size(47, 20);
|
||||
this.labelTimer.TabIndex = 7;
|
||||
this.labelTimer.Text = "Timer";
|
||||
//
|
||||
// labelSize
|
||||
//
|
||||
this.labelSize.AutoSize = true;
|
||||
this.labelSize.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelSize.Location = new System.Drawing.Point(0, 572);
|
||||
this.labelSize.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelSize.Location = new System.Drawing.Point(0, 592);
|
||||
this.labelSize.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelSize.Name = "labelSize";
|
||||
this.labelSize.Size = new System.Drawing.Size(40, 20);
|
||||
this.labelSize.Size = new System.Drawing.Size(36, 20);
|
||||
this.labelSize.TabIndex = 19;
|
||||
this.labelSize.Text = "Size";
|
||||
//
|
||||
@@ -509,10 +535,10 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelSize.Controls.Add(this.radioSizeCustom);
|
||||
this.panelSize.Controls.Add(this.radioSizeAuto);
|
||||
this.panelSize.Location = new System.Drawing.Point(0, 592);
|
||||
this.panelSize.Location = new System.Drawing.Point(0, 612);
|
||||
this.panelSize.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelSize.Name = "panelSize";
|
||||
this.panelSize.Size = new System.Drawing.Size(322, 25);
|
||||
this.panelSize.Size = new System.Drawing.Size(322, 27);
|
||||
this.panelSize.TabIndex = 20;
|
||||
//
|
||||
// durationUpdateTimer
|
||||
@@ -551,7 +577,7 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 678);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 698);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
@@ -560,7 +586,7 @@
|
||||
this.panelScrollSpeed.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelScrollSpeed.Controls.Add(this.trackBarScrollSpeed);
|
||||
this.panelScrollSpeed.Controls.Add(this.labelScrollSpeedValue);
|
||||
this.panelScrollSpeed.Location = new System.Drawing.Point(0, 642);
|
||||
this.panelScrollSpeed.Location = new System.Drawing.Point(0, 666);
|
||||
this.panelScrollSpeed.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelScrollSpeed.Name = "panelScrollSpeed";
|
||||
this.panelScrollSpeed.Size = new System.Drawing.Size(322, 36);
|
||||
@@ -572,7 +598,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsNotifications";
|
||||
this.Size = new System.Drawing.Size(340, 697);
|
||||
this.Size = new System.Drawing.Size(340, 717);
|
||||
this.ParentChanged += new System.EventHandler(this.TabSettingsNotifications_ParentChanged);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarEdgeDistance)).EndInit();
|
||||
this.tableLayoutDurationButtons.ResumeLayout(false);
|
||||
|
@@ -15,7 +15,7 @@ namespace TweetDuck.Core.Other.Settings{
|
||||
|
||||
this.notification = notification;
|
||||
|
||||
this.notification.Initialized += (sender, args) => {
|
||||
this.notification.Ready += (sender, args) => {
|
||||
this.InvokeAsyncSafe(() => {
|
||||
this.notification.ShowExampleNotification(true);
|
||||
this.notification.Move += notification_Move;
|
||||
|
44
Core/Other/Settings/TabSettingsSounds.Designer.cs
generated
44
Core/Other/Settings/TabSettingsSounds.Designer.cs
generated
@@ -47,18 +47,20 @@
|
||||
//
|
||||
this.tbCustomSound.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tbCustomSound.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.tbCustomSound.Location = new System.Drawing.Point(3, 3);
|
||||
this.tbCustomSound.Name = "tbCustomSound";
|
||||
this.tbCustomSound.Size = new System.Drawing.Size(316, 20);
|
||||
this.tbCustomSound.Size = new System.Drawing.Size(316, 23);
|
||||
this.tbCustomSound.TabIndex = 0;
|
||||
//
|
||||
// labelVolumeValue
|
||||
//
|
||||
this.labelVolumeValue.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelVolumeValue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelVolumeValue.Location = new System.Drawing.Point(147, 4);
|
||||
this.labelVolumeValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelVolumeValue.Name = "labelVolumeValue";
|
||||
this.labelVolumeValue.Size = new System.Drawing.Size(38, 13);
|
||||
this.labelVolumeValue.Size = new System.Drawing.Size(38, 15);
|
||||
this.labelVolumeValue.TabIndex = 1;
|
||||
this.labelVolumeValue.Text = "100%";
|
||||
this.labelVolumeValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
@@ -67,10 +69,11 @@
|
||||
//
|
||||
this.btnPlaySound.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnPlaySound.AutoSize = true;
|
||||
this.btnPlaySound.Location = new System.Drawing.Point(203, 29);
|
||||
this.btnPlaySound.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnPlaySound.Location = new System.Drawing.Point(202, 32);
|
||||
this.btnPlaySound.Name = "btnPlaySound";
|
||||
this.btnPlaySound.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnPlaySound.Size = new System.Drawing.Size(43, 23);
|
||||
this.btnPlaySound.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnPlaySound.Size = new System.Drawing.Size(43, 25);
|
||||
this.btnPlaySound.TabIndex = 2;
|
||||
this.btnPlaySound.Text = "Play";
|
||||
this.btnPlaySound.UseVisualStyleBackColor = true;
|
||||
@@ -78,10 +81,11 @@
|
||||
// btnResetSound
|
||||
//
|
||||
this.btnResetSound.AutoSize = true;
|
||||
this.btnResetSound.Location = new System.Drawing.Point(3, 29);
|
||||
this.btnResetSound.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnResetSound.Location = new System.Drawing.Point(3, 32);
|
||||
this.btnResetSound.Name = "btnResetSound";
|
||||
this.btnResetSound.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnResetSound.Size = new System.Drawing.Size(51, 23);
|
||||
this.btnResetSound.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnResetSound.Size = new System.Drawing.Size(49, 25);
|
||||
this.btnResetSound.TabIndex = 3;
|
||||
this.btnResetSound.Text = "Reset";
|
||||
this.btnResetSound.UseVisualStyleBackColor = true;
|
||||
@@ -90,10 +94,11 @@
|
||||
//
|
||||
this.btnBrowseSound.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnBrowseSound.AutoSize = true;
|
||||
this.btnBrowseSound.Location = new System.Drawing.Point(252, 29);
|
||||
this.btnBrowseSound.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnBrowseSound.Location = new System.Drawing.Point(251, 32);
|
||||
this.btnBrowseSound.Name = "btnBrowseSound";
|
||||
this.btnBrowseSound.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnBrowseSound.Size = new System.Drawing.Size(67, 23);
|
||||
this.btnBrowseSound.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.btnBrowseSound.Size = new System.Drawing.Size(68, 25);
|
||||
this.btnBrowseSound.TabIndex = 1;
|
||||
this.btnBrowseSound.Text = "Browse...";
|
||||
this.btnBrowseSound.UseVisualStyleBackColor = true;
|
||||
@@ -101,11 +106,11 @@
|
||||
// labelSoundNotification
|
||||
//
|
||||
this.labelSoundNotification.AutoSize = true;
|
||||
this.labelSoundNotification.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelSoundNotification.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelSoundNotification.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelSoundNotification.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelSoundNotification.Name = "labelSoundNotification";
|
||||
this.labelSoundNotification.Size = new System.Drawing.Size(198, 20);
|
||||
this.labelSoundNotification.Size = new System.Drawing.Size(188, 20);
|
||||
this.labelSoundNotification.TabIndex = 0;
|
||||
this.labelSoundNotification.Text = "Custom Sound Notification";
|
||||
//
|
||||
@@ -119,16 +124,17 @@
|
||||
this.panelSoundNotification.Location = new System.Drawing.Point(0, 20);
|
||||
this.panelSoundNotification.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelSoundNotification.Name = "panelSoundNotification";
|
||||
this.panelSoundNotification.Size = new System.Drawing.Size(322, 55);
|
||||
this.panelSoundNotification.Size = new System.Drawing.Size(322, 59);
|
||||
this.panelSoundNotification.TabIndex = 1;
|
||||
//
|
||||
// labelVolume
|
||||
//
|
||||
this.labelVolume.AutoSize = true;
|
||||
this.labelVolume.Location = new System.Drawing.Point(3, 87);
|
||||
this.labelVolume.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelVolume.Location = new System.Drawing.Point(3, 91);
|
||||
this.labelVolume.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelVolume.Name = "labelVolume";
|
||||
this.labelVolume.Size = new System.Drawing.Size(42, 13);
|
||||
this.labelVolume.Size = new System.Drawing.Size(48, 15);
|
||||
this.labelVolume.TabIndex = 2;
|
||||
this.labelVolume.Text = "Volume";
|
||||
//
|
||||
@@ -157,7 +163,7 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 136);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 142);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
@@ -165,7 +171,7 @@
|
||||
//
|
||||
this.panelVolume.Controls.Add(this.trackBarVolume);
|
||||
this.panelVolume.Controls.Add(this.labelVolumeValue);
|
||||
this.panelVolume.Location = new System.Drawing.Point(0, 100);
|
||||
this.panelVolume.Location = new System.Drawing.Point(0, 106);
|
||||
this.panelVolume.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelVolume.Name = "panelVolume";
|
||||
this.panelVolume.Size = new System.Drawing.Size(322, 36);
|
||||
@@ -182,7 +188,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsSounds";
|
||||
this.Size = new System.Drawing.Size(340, 154);
|
||||
this.Size = new System.Drawing.Size(340, 160);
|
||||
this.panelSoundNotification.ResumeLayout(false);
|
||||
this.panelSoundNotification.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();
|
||||
|
23
Core/Other/Settings/TabSettingsTray.Designer.cs
generated
23
Core/Other/Settings/TabSettingsTray.Designer.cs
generated
@@ -36,10 +36,11 @@
|
||||
// checkTrayHighlight
|
||||
//
|
||||
this.checkTrayHighlight.AutoSize = true;
|
||||
this.checkTrayHighlight.Location = new System.Drawing.Point(6, 77);
|
||||
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
|
||||
this.checkTrayHighlight.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.checkTrayHighlight.Location = new System.Drawing.Point(6, 81);
|
||||
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||
this.checkTrayHighlight.Name = "checkTrayHighlight";
|
||||
this.checkTrayHighlight.Size = new System.Drawing.Size(103, 17);
|
||||
this.checkTrayHighlight.Size = new System.Drawing.Size(114, 19);
|
||||
this.checkTrayHighlight.TabIndex = 3;
|
||||
this.checkTrayHighlight.Text = "Enable Highlight";
|
||||
this.checkTrayHighlight.UseVisualStyleBackColor = true;
|
||||
@@ -47,31 +48,33 @@
|
||||
// comboBoxTrayType
|
||||
//
|
||||
this.comboBoxTrayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxTrayType.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxTrayType.FormattingEnabled = true;
|
||||
this.comboBoxTrayType.Location = new System.Drawing.Point(5, 25);
|
||||
this.comboBoxTrayType.Margin = new System.Windows.Forms.Padding(5, 5, 3, 3);
|
||||
this.comboBoxTrayType.Name = "comboBoxTrayType";
|
||||
this.comboBoxTrayType.Size = new System.Drawing.Size(144, 21);
|
||||
this.comboBoxTrayType.Size = new System.Drawing.Size(144, 23);
|
||||
this.comboBoxTrayType.TabIndex = 1;
|
||||
//
|
||||
// labelTrayIcon
|
||||
//
|
||||
this.labelTrayIcon.AutoSize = true;
|
||||
this.labelTrayIcon.Location = new System.Drawing.Point(3, 58);
|
||||
this.labelTrayIcon.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTrayIcon.Location = new System.Drawing.Point(3, 60);
|
||||
this.labelTrayIcon.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
|
||||
this.labelTrayIcon.Name = "labelTrayIcon";
|
||||
this.labelTrayIcon.Size = new System.Drawing.Size(52, 13);
|
||||
this.labelTrayIcon.Size = new System.Drawing.Size(56, 15);
|
||||
this.labelTrayIcon.TabIndex = 2;
|
||||
this.labelTrayIcon.Text = "Tray Icon";
|
||||
//
|
||||
// labelTray
|
||||
//
|
||||
this.labelTray.AutoSize = true;
|
||||
this.labelTray.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTray.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelTray.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelTray.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelTray.Name = "labelTray";
|
||||
this.labelTray.Size = new System.Drawing.Size(96, 20);
|
||||
this.labelTray.Size = new System.Drawing.Size(88, 20);
|
||||
this.labelTray.TabIndex = 0;
|
||||
this.labelTray.Text = "System Tray";
|
||||
//
|
||||
@@ -87,7 +90,7 @@
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 97);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 102);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
@@ -97,7 +100,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsTray";
|
||||
this.Size = new System.Drawing.Size(340, 115);
|
||||
this.Size = new System.Drawing.Size(340, 120);
|
||||
this.flowPanel.ResumeLayout(false);
|
||||
this.flowPanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
using Res = TweetDuck.Properties.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class TrayIcon : Component{
|
||||
@@ -8,6 +10,8 @@ namespace TweetDuck.Core.Other{
|
||||
Disabled, DisplayOnly, MinimizeToTray, CloseToTray, Combined
|
||||
}
|
||||
|
||||
private static UserConfig Config => Program.UserConfig;
|
||||
|
||||
public event EventHandler ClickRestore;
|
||||
public event EventHandler ClickClose;
|
||||
|
||||
@@ -17,12 +21,9 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
set{
|
||||
if (value){
|
||||
notifyIcon.Icon = Properties.Resources.icon_tray;
|
||||
}
|
||||
|
||||
notifyIcon.Visible = value;
|
||||
hasNotifications = false;
|
||||
UpdateIcon();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +33,9 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
set{
|
||||
if (hasNotifications != value && Visible){
|
||||
notifyIcon.Icon = value ? Properties.Resources.icon_tray_new : Properties.Resources.icon_tray;
|
||||
if (hasNotifications != value){
|
||||
hasNotifications = value;
|
||||
UpdateIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,14 +54,26 @@ namespace TweetDuck.Core.Other{
|
||||
|
||||
this.notifyIcon.ContextMenu = contextMenu;
|
||||
this.notifyIcon.Text = Program.BrandName;
|
||||
|
||||
Config.MuteToggled += Config_MuteToggled;
|
||||
}
|
||||
|
||||
public TrayIcon(IContainer container) : this(){
|
||||
container.Add(this);
|
||||
}
|
||||
|
||||
private void UpdateIcon(){
|
||||
if (Visible){
|
||||
notifyIcon.Icon = hasNotifications ? Res.icon_tray_new : Config.MuteNotifications ? Res.icon_tray_muted : Res.icon_tray;
|
||||
}
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void Config_MuteToggled(object sender, EventArgs e){
|
||||
UpdateIcon();
|
||||
}
|
||||
|
||||
private void trayIcon_MouseClick(object sender, MouseEventArgs e){
|
||||
if (e.Button == MouseButtons.Left){
|
||||
menuItemRestore_Click(sender, e);
|
||||
@@ -68,7 +81,7 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
private void contextMenu_Popup(object sender, EventArgs e){
|
||||
contextMenu.MenuItems[1].Checked = Program.UserConfig.MuteNotifications;
|
||||
contextMenu.MenuItems[1].Checked = Config.MuteNotifications;
|
||||
}
|
||||
|
||||
private void menuItemRestore_Click(object sender, EventArgs e){
|
||||
@@ -76,8 +89,8 @@ namespace TweetDuck.Core.Other{
|
||||
}
|
||||
|
||||
private void menuItemMuteNotifications_Click(object sender, EventArgs e){
|
||||
Program.UserConfig.MuteNotifications = !contextMenu.MenuItems[1].Checked;
|
||||
Program.UserConfig.Save();
|
||||
Config.MuteNotifications = !contextMenu.MenuItems[1].Checked;
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
private void menuItemClose_Click(object sender, EventArgs e){
|
||||
|
@@ -1,22 +1,22 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Handling.General;
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other.Interfaces;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
using TweetDuck.Plugins.Events;
|
||||
using TweetDuck.Resources;
|
||||
using TweetDuck.Updates;
|
||||
|
||||
namespace TweetDuck.Core{
|
||||
sealed class TweetDeckBrowser : IDisposable{
|
||||
sealed class TweetDeckBrowser : ITweetDeckBrowser, IDisposable{
|
||||
public bool Ready { get; private set; }
|
||||
|
||||
public bool Enabled{
|
||||
@@ -26,6 +26,10 @@ namespace TweetDuck.Core{
|
||||
|
||||
public bool IsTweetDeckWebsite{
|
||||
get{
|
||||
if (!Ready){
|
||||
return false;
|
||||
}
|
||||
|
||||
using(IFrame frame = browser.GetBrowser().MainFrame){
|
||||
return TwitterUtils.IsTweetDeckWebsite(frame);
|
||||
}
|
||||
@@ -33,43 +37,37 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
private readonly ChromiumWebBrowser browser;
|
||||
private readonly PluginManager plugins;
|
||||
|
||||
private string prevSoundNotificationPath = null;
|
||||
|
||||
public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridge bridge){
|
||||
public TweetDeckBrowser(FormBrowser owner, TweetDeckBridge bridge){
|
||||
RequestHandlerBrowser requestHandler = new RequestHandlerBrowser();
|
||||
|
||||
this.browser = new ChromiumWebBrowser(TwitterUtils.TweetDeckURL){
|
||||
DialogHandler = new FileDialogHandler(),
|
||||
DragHandler = new DragHandlerBrowser(),
|
||||
DragHandler = new DragHandlerBrowser(requestHandler),
|
||||
MenuHandler = new ContextMenuBrowser(owner),
|
||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||
KeyboardHandler = new KeyboardHandlerBrowser(owner),
|
||||
LifeSpanHandler = new LifeSpanHandler(),
|
||||
RequestHandler = new RequestHandlerBrowser()
|
||||
RequestHandler = requestHandler
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
this.browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
||||
#endif
|
||||
|
||||
this.browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||
this.browser.FrameLoadStart += browser_FrameLoadStart;
|
||||
this.browser.FrameLoadEnd += browser_FrameLoadEnd;
|
||||
this.browser.LoadError += browser_LoadError;
|
||||
|
||||
this.browser.RegisterAsyncJsObject("$TD", bridge);
|
||||
this.browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
||||
|
||||
this.browser.BrowserSettings.BackgroundColor = (uint)TwitterUtils.BackgroundColor.ToArgb();
|
||||
this.browser.Dock = DockStyle.None;
|
||||
this.browser.Location = ControlExtensions.InvisibleLocation;
|
||||
|
||||
this.browser.SetupResourceHandler(TweetNotification.AppLogoLink, TweetNotification.AppLogoHandler);
|
||||
this.browser.SetupResourceHandler(TweetNotification.AppLogo);
|
||||
this.browser.SetupResourceHandler(TwitterUtils.LoadingSpinner);
|
||||
|
||||
owner.Controls.Add(browser);
|
||||
|
||||
this.plugins = plugins;
|
||||
this.plugins.PluginChangedState += plugins_PluginChangedState;
|
||||
|
||||
Program.UserConfig.MuteToggled += UserConfig_MuteToggled;
|
||||
Program.UserConfig.ZoomLevelChanged += UserConfig_ZoomLevelChanged;
|
||||
@@ -91,14 +89,30 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
plugins.PluginChangedState -= plugins_PluginChangedState;
|
||||
|
||||
Program.UserConfig.MuteToggled -= UserConfig_MuteToggled;
|
||||
Program.UserConfig.ZoomLevelChanged -= UserConfig_ZoomLevelChanged;
|
||||
Program.UserConfig.SoundNotificationChanged -= UserConfig_SoundNotificationInfoChanged;
|
||||
|
||||
browser.Dispose();
|
||||
}
|
||||
|
||||
void ITweetDeckBrowser.RegisterBridge(string name, object obj){
|
||||
browser.RegisterAsyncJsObject(name, obj);
|
||||
}
|
||||
|
||||
void ITweetDeckBrowser.OnFrameLoaded(Action<IFrame> callback){
|
||||
browser.FrameLoadEnd += (sender, args) => {
|
||||
IFrame frame = args.Frame;
|
||||
|
||||
if (frame.IsMain && TwitterUtils.IsTweetDeckWebsite(frame)){
|
||||
callback(frame);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void ITweetDeckBrowser.ExecuteFunction(string name, params object[] args){
|
||||
browser.ExecuteScriptAsync(name, args);
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
@@ -114,36 +128,42 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
private void browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e){
|
||||
if (e.Frame.IsMain){
|
||||
IFrame frame = e.Frame;
|
||||
|
||||
if (frame.IsMain){
|
||||
if (Program.UserConfig.ZoomLevel != 100){
|
||||
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Program.UserConfig.ZoomLevel);
|
||||
}
|
||||
|
||||
if (TwitterUtils.IsTwitterWebsite(e.Frame)){
|
||||
ScriptLoader.ExecuteFile(e.Frame, "twitter.js");
|
||||
if (TwitterUtils.IsTwitterWebsite(frame)){
|
||||
ScriptLoader.ExecuteFile(frame, "twitter.js", browser);
|
||||
}
|
||||
|
||||
frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorOverride);
|
||||
}
|
||||
}
|
||||
|
||||
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
if (e.Frame.IsMain && TwitterUtils.IsTweetDeckWebsite(e.Frame)){
|
||||
e.Frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorFix);
|
||||
IFrame frame = e.Frame;
|
||||
|
||||
if (frame.IsMain && TwitterUtils.IsTweetDeckWebsite(frame)){
|
||||
UpdateProperties();
|
||||
TweetDeckBridge.RestoreSessionData(e.Frame);
|
||||
ScriptLoader.ExecuteFile(e.Frame, "code.js");
|
||||
TweetDeckBridge.RestoreSessionData(frame);
|
||||
ScriptLoader.ExecuteFile(frame, "code.js", browser);
|
||||
ScriptLoader.ExecuteFile(frame, "update.js", browser);
|
||||
|
||||
InjectBrowserCSS();
|
||||
ReinjectCustomCSS(Program.UserConfig.CustomBrowserCSS);
|
||||
UserConfig_SoundNotificationInfoChanged(null, EventArgs.Empty);
|
||||
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Browser);
|
||||
|
||||
TweetDeckBridge.ResetStaticProperties();
|
||||
|
||||
if (Program.UserConfig.FirstRun){
|
||||
ScriptLoader.ExecuteFile(e.Frame, "introduction.js");
|
||||
if (Arguments.HasFlag(Arguments.ArgIgnoreGDPR)){
|
||||
ScriptLoader.ExecuteScript(frame, "TD.storage.Account.prototype.requiresConsent = function(){ return false; }", "gen:gdpr");
|
||||
}
|
||||
else if (Program.UserConfig.ShowFollowNotification){
|
||||
ScriptLoader.ExecuteFile(e.Frame, "introduction.follow.js");
|
||||
|
||||
if (Program.UserConfig.FirstRun){
|
||||
ScriptLoader.ExecuteFile(frame, "introduction.js", browser);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,7 +174,7 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
if (!e.FailedUrl.StartsWith("http://td/", StringComparison.Ordinal)){
|
||||
string errorPage = ScriptLoader.LoadResource("pages/error.html", true);
|
||||
string errorPage = ScriptLoader.LoadResourceSilent("pages/error.html");
|
||||
|
||||
if (errorPage != null){
|
||||
browser.LoadHtml(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode)), "http://td/error");
|
||||
@@ -162,10 +182,6 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
}
|
||||
|
||||
private void plugins_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
browser.ExecuteScriptAsync("TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
||||
}
|
||||
|
||||
private void UserConfig_MuteToggled(object sender, EventArgs e){
|
||||
UpdateProperties();
|
||||
}
|
||||
@@ -188,10 +204,6 @@ namespace TweetDuck.Core{
|
||||
|
||||
// external handling
|
||||
|
||||
public UpdateHandler CreateUpdateHandler(UpdaterSettings settings){
|
||||
return new UpdateHandler(browser, settings);
|
||||
}
|
||||
|
||||
public void HideVideoOverlay(bool focus){
|
||||
if (focus){
|
||||
browser.GetBrowser().GetHost().SendFocusEvent(true);
|
||||
@@ -211,7 +223,7 @@ namespace TweetDuck.Core{
|
||||
}
|
||||
|
||||
public void InjectBrowserCSS(){
|
||||
browser.ExecuteScriptAsync("TDGF_injectBrowserCSS", ScriptLoader.LoadResource("styles/browser.css").TrimEnd());
|
||||
browser.ExecuteScriptAsync("TDGF_injectBrowserCSS", ScriptLoader.LoadResource("styles/browser.css", browser)?.TrimEnd() ?? string.Empty);
|
||||
}
|
||||
|
||||
public void ReinjectCustomCSS(string css){
|
||||
@@ -226,6 +238,10 @@ namespace TweetDuck.Core{
|
||||
browser.ExecuteScriptAsync("TDGF_showTweetDetail", columnId, chirpId, fallbackUrl);
|
||||
}
|
||||
|
||||
public void AddSearchColumn(string query){
|
||||
browser.ExecuteScriptAsync("TDGF_performSearch", query);
|
||||
}
|
||||
|
||||
public void TriggerTweetScreenshot(){
|
||||
browser.ExecuteScriptAsync("TDGF_triggerScreenshot()");
|
||||
}
|
||||
@@ -241,5 +257,13 @@ namespace TweetDuck.Core{
|
||||
public void ApplyROT13(){
|
||||
browser.ExecuteScriptAsync("TDGF_applyROT13()");
|
||||
}
|
||||
|
||||
public void ShowUpdateNotification(string versionTag, string releaseNotes){
|
||||
browser.ExecuteScriptAsync("TDUF_displayNotification", versionTag, Convert.ToBase64String(Encoding.GetEncoding("iso-8859-1").GetBytes(releaseNotes)));
|
||||
}
|
||||
|
||||
public void OpenDevTools(){
|
||||
browser.ShowDevTools();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,11 +7,15 @@ using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp.WinForms;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Data;
|
||||
|
||||
namespace TweetDuck.Core.Utils{
|
||||
static class BrowserUtils{
|
||||
public static string HeaderUserAgent => Program.BrandName+" "+Application.ProductVersion;
|
||||
public static string UserAgentVanilla => Program.BrandName+" "+Application.ProductVersion;
|
||||
public static string UserAgentChrome => "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"+Cef.ChromiumVersion+" Safari/537.36";
|
||||
|
||||
public static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak"));
|
||||
|
||||
public static void SetupCefArgs(IDictionary<string, string> args){
|
||||
if (!Program.SystemConfig.HardwareAcceleration){
|
||||
args["disable-gpu"] = "1";
|
||||
@@ -49,6 +53,10 @@ namespace TweetDuck.Core.Utils{
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetupResourceHandler(this ChromiumWebBrowser browser, ResourceLink resource){
|
||||
browser.SetupResourceHandler(resource.Url, resource.Handler);
|
||||
}
|
||||
|
||||
private const string TwitterTrackingUrl = "t.co";
|
||||
|
||||
public enum UrlCheckResult{
|
||||
@@ -122,6 +130,33 @@ namespace TweetDuck.Core.Utils{
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenExternalSearch(string query){
|
||||
if (string.IsNullOrWhiteSpace(query))return;
|
||||
|
||||
string searchUrl = Program.UserConfig.SearchEngineUrl;
|
||||
|
||||
if (string.IsNullOrEmpty(searchUrl)){
|
||||
if (FormMessage.Question("Search Options", "You have not configured a default search engine yet, would you like to do it now?", FormMessage.Yes, FormMessage.No)){
|
||||
bool wereSettingsOpen = FormManager.TryFind<FormSettings>() != null;
|
||||
|
||||
FormManager.TryFind<FormBrowser>()?.OpenSettings();
|
||||
if (wereSettingsOpen)return;
|
||||
|
||||
FormSettings settings = FormManager.TryFind<FormSettings>();
|
||||
if (settings == null)return;
|
||||
|
||||
settings.FormClosed += (sender, args) => {
|
||||
if (args.CloseReason == CloseReason.UserClosing && Program.UserConfig.SearchEngineUrl != searchUrl){
|
||||
OpenExternalSearch(query);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
else{
|
||||
OpenExternalBrowser(searchUrl+Uri.EscapeUriString(query));
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetFileNameFromUrl(string url){
|
||||
string file = Path.GetFileName(new Uri(url).AbsolutePath);
|
||||
return string.IsNullOrEmpty(file) ? null : file;
|
||||
@@ -132,8 +167,10 @@ namespace TweetDuck.Core.Utils{
|
||||
}
|
||||
|
||||
public static WebClient CreateWebClient(){
|
||||
WindowsUtils.EnsureTLS12();
|
||||
|
||||
WebClient client = new WebClient{ Proxy = null };
|
||||
client.Headers[HttpRequestHeader.UserAgent] = HeaderUserAgent;
|
||||
client.Headers[HttpRequestHeader.UserAgent] = UserAgentVanilla;
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -167,11 +204,5 @@ namespace TweetDuck.Core.Utils{
|
||||
public static void SetZoomLevel(IBrowser browser, int percentage){
|
||||
browser.GetHost().SetZoomLevel(Math.Log(percentage/100.0, 1.2));
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public static void HandleConsoleMessage(object sender, ConsoleMessageEventArgs e){
|
||||
Debug.WriteLine("[Console] {0} ({1}:{2})", e.Message, e.Source, e.Line);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -71,6 +71,9 @@ namespace TweetDuck.Core.Utils{
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmIsCompositionEnabled(out bool enabled);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);
|
||||
|
@@ -19,11 +19,23 @@ namespace TweetDuck.Core.Utils{
|
||||
return Regex.Replace(str, @"(\p{Ll})(\P{Ll})|(\P{Ll})(\P{Ll}\p{Ll})", "$1$3_$2$4").ToUpper();
|
||||
}
|
||||
|
||||
public static string ConvertRot13(string str){
|
||||
return Regex.Replace(str, @"[a-zA-Z]", match => {
|
||||
int code = match.Value[0];
|
||||
int start = code <= 90 ? 65 : 97;
|
||||
return ((char)(start+(code-start+13)%26)).ToString();
|
||||
});
|
||||
}
|
||||
|
||||
public static int CountOccurrences(string source, string substring){
|
||||
int count = 0, index = 0;
|
||||
if (substring.Length == 0){
|
||||
throw new ArgumentOutOfRangeException(nameof(substring), "Searched substring must not be empty.");
|
||||
}
|
||||
|
||||
int count = 0, index = 0, length = substring.Length;
|
||||
|
||||
while((index = source.IndexOf(substring, index)) != -1){
|
||||
index += substring.Length;
|
||||
index += length;
|
||||
++count;
|
||||
}
|
||||
|
||||
|
@@ -6,15 +6,18 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Data;
|
||||
|
||||
namespace TweetDuck.Core.Utils{
|
||||
static class TwitterUtils{
|
||||
public const string TweetDeckURL = "https://tweetdeck.twitter.com";
|
||||
|
||||
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 BackgroundColorOverride = "setTimeout(function f(){let h=document.head;if(!h){setTimeout(f,5);return;}let e=document.createElement('style');e.innerHTML='body,body::before{background:#1c6399!important}';h.appendChild(e);},1)";
|
||||
|
||||
public static readonly ResourceLink LoadingSpinner = new ResourceLink("https://ton.twimg.com/tduck/spinner", ResourceHandler.FromByteArray(Properties.Resources.spinner, "image/apng"));
|
||||
|
||||
private static readonly Lazy<Regex> RegexAccountLazy = new Lazy<Regex>(() => new Regex(@"^https?://twitter\.com/(?!signup$|tos$|privacy$)([^/]+)/?$", RegexOptions.Compiled), false);
|
||||
private static readonly Lazy<Regex> RegexAccountLazy = new Lazy<Regex>(() => new Regex(@"^https?://twitter\.com/(?!signup$|tos$|privacy$|search$|search-)([^/?]+)/?$", RegexOptions.Compiled), false);
|
||||
public static Regex RegexAccount => RegexAccountLazy.Value;
|
||||
|
||||
public static readonly string[] DictionaryWords = {
|
||||
@@ -38,8 +41,8 @@ namespace TweetDuck.Core.Utils{
|
||||
}
|
||||
|
||||
private static string ExtractMediaBaseLink(string url){
|
||||
int dot = url.LastIndexOf('/');
|
||||
return dot == -1 ? url : StringUtils.ExtractBefore(url, ':', dot);
|
||||
int slash = url.LastIndexOf('/');
|
||||
return slash == -1 ? url : StringUtils.ExtractBefore(url, ':', slash);
|
||||
}
|
||||
|
||||
public static string GetMediaLink(string url, ImageQuality quality){
|
||||
@@ -88,7 +91,7 @@ namespace TweetDuck.Core.Utils{
|
||||
AutoUpgradeEnabled = true,
|
||||
OverwritePrompt = urls.Length == 1,
|
||||
Title = "Save Image",
|
||||
FileName = $"{string.Join(" ", fileNameParts.Where(part => part.Length > 0))}{ext}",
|
||||
FileName = $"{string.Join(" ", fileNameParts.Where(part => !string.IsNullOrEmpty(part)))}{ext}",
|
||||
Filter = (urls.Length == 1 ? "Image" : "Images")+(string.IsNullOrEmpty(ext) ? " (unknown)|*.*" : $" (*{ext})|*{ext}")
|
||||
}){
|
||||
if (dialog.ShowDialog() == DialogResult.OK){
|
||||
|
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
@@ -14,8 +15,12 @@ namespace TweetDuck.Core.Utils{
|
||||
private static readonly Lazy<Regex> RegexStripHtmlStyles = new Lazy<Regex>(() => new Regex(@"\s?(?:style|class)="".*?"""), false);
|
||||
private static readonly Lazy<Regex> RegexOffsetClipboardHtml = new Lazy<Regex>(() => new Regex(@"(?<=EndHTML:|EndFragment:)(\d+)"), false);
|
||||
|
||||
private static readonly bool IsWindows8OrNewer;
|
||||
private static bool HasMicrosoftBeenBroughtTo2008Yet;
|
||||
|
||||
public static int CurrentProcessID { get; }
|
||||
public static bool ShouldAvoidToolWindow { get; }
|
||||
public static bool IsAeroEnabled => IsWindows8OrNewer || (NativeMethods.DwmIsCompositionEnabled(out bool isCompositionEnabled) == 0 && isCompositionEnabled);
|
||||
|
||||
static WindowsUtils(){
|
||||
using(Process me = Process.GetCurrentProcess()){
|
||||
@@ -23,7 +28,17 @@ namespace TweetDuck.Core.Utils{
|
||||
}
|
||||
|
||||
Version ver = Environment.OSVersion.Version;
|
||||
ShouldAvoidToolWindow = ver.Major == 6 && ver.Minor == 2; // windows 8/10
|
||||
IsWindows8OrNewer = ver.Major == 6 && ver.Minor == 2; // windows 8/10
|
||||
|
||||
ShouldAvoidToolWindow = IsWindows8OrNewer;
|
||||
}
|
||||
|
||||
public static void EnsureTLS12(){
|
||||
if (!HasMicrosoftBeenBroughtTo2008Yet){
|
||||
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
|
||||
ServicePointManager.SecurityProtocol &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11);
|
||||
HasMicrosoftBeenBroughtTo2008Yet = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateDirectoryForFile(string file){
|
||||
|
@@ -16,7 +16,7 @@ namespace TweetDuck.Data{
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
public string Inject(string targetHTML){
|
||||
public string InjectInto(string targetHTML){
|
||||
int index = targetHTML.IndexOf(search, StringComparison.Ordinal);
|
||||
|
||||
if (index == -1){
|
||||
|
13
Data/ResourceLink.cs
Normal file
13
Data/ResourceLink.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using CefSharp;
|
||||
|
||||
namespace TweetDuck.Data{
|
||||
sealed class ResourceLink{
|
||||
public string Url { get; }
|
||||
public IResourceHandler Handler { get; }
|
||||
|
||||
public ResourceLink(string url, IResourceHandler handler){
|
||||
this.Url = url;
|
||||
this.Handler = handler;
|
||||
}
|
||||
}
|
||||
}
|
36
Data/Result.cs
Normal file
36
Data/Result.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace TweetDuck.Data{
|
||||
sealed class Result<T>{
|
||||
public bool HasValue => exception == null;
|
||||
|
||||
public T Value => HasValue ? value : throw new InvalidOperationException("Requested value from a failed result.");
|
||||
public Exception Exception => exception ?? throw new InvalidOperationException("Requested exception from a successful result.");
|
||||
|
||||
private readonly T value;
|
||||
private readonly Exception exception;
|
||||
|
||||
public Result(T value){
|
||||
this.value = value;
|
||||
this.exception = null;
|
||||
}
|
||||
|
||||
public Result(Exception exception){
|
||||
this.value = default(T);
|
||||
this.exception = exception ?? throw new ArgumentNullException(nameof(exception));
|
||||
}
|
||||
|
||||
public void Handle(Action<T> onSuccess, Action<Exception> onException){
|
||||
if (HasValue){
|
||||
onSuccess(value);
|
||||
}
|
||||
else{
|
||||
onException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<R> Select<R>(Func<T, R> map){
|
||||
return HasValue ? new Result<R>(map(value)) : new Result<R>(exception);
|
||||
}
|
||||
}
|
||||
}
|
@@ -62,8 +62,7 @@ namespace TweetDuck.Data{
|
||||
}
|
||||
|
||||
public bool Contains(K1 outerKey, K2 innerKey){
|
||||
Dictionary<K2, V> innerDict;
|
||||
return dict.TryGetValue(outerKey, out innerDict) && innerDict.ContainsKey(innerKey);
|
||||
return dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict) && innerDict.ContainsKey(innerKey);
|
||||
}
|
||||
|
||||
public int Count(){
|
||||
|
126
Plugins/Controls/PluginControl.Designer.cs
generated
126
Plugins/Controls/PluginControl.Designer.cs
generated
@@ -23,6 +23,7 @@
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.btnToggleState = new System.Windows.Forms.Button();
|
||||
this.labelName = new System.Windows.Forms.Label();
|
||||
this.panelDescription = new System.Windows.Forms.Panel();
|
||||
@@ -31,8 +32,10 @@
|
||||
this.flowLayoutInfo = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.labelWebsite = new System.Windows.Forms.Label();
|
||||
this.labelVersion = new System.Windows.Forms.Label();
|
||||
this.btnOpenConfig = new System.Windows.Forms.Button();
|
||||
this.btnConfigure = new System.Windows.Forms.Button();
|
||||
this.labelType = new TweetDuck.Core.Controls.LabelVertical();
|
||||
this.timerLayout = new System.Windows.Forms.Timer(this.components);
|
||||
this.panelBorder = new System.Windows.Forms.Panel();
|
||||
this.panelDescription.SuspendLayout();
|
||||
this.flowLayoutInfo.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@@ -40,21 +43,24 @@
|
||||
// btnToggleState
|
||||
//
|
||||
this.btnToggleState.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnToggleState.Location = new System.Drawing.Point(456, 80);
|
||||
this.btnToggleState.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnToggleState.Location = new System.Drawing.Point(451, 59);
|
||||
this.btnToggleState.Name = "btnToggleState";
|
||||
this.btnToggleState.Size = new System.Drawing.Size(65, 23);
|
||||
this.btnToggleState.TabIndex = 5;
|
||||
this.btnToggleState.Size = new System.Drawing.Size(70, 23);
|
||||
this.btnToggleState.TabIndex = 6;
|
||||
this.btnToggleState.Text = "Disable";
|
||||
this.btnToggleState.UseVisualStyleBackColor = true;
|
||||
this.btnToggleState.Click += new System.EventHandler(this.btnToggleState_Click);
|
||||
//
|
||||
// labelName
|
||||
//
|
||||
this.labelName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelName.AutoSize = true;
|
||||
this.labelName.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelName.Location = new System.Drawing.Point(24, 7);
|
||||
this.labelName.Font = new System.Drawing.Font("Segoe UI Semibold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelName.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelName.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelName.Name = "labelName";
|
||||
this.labelName.Size = new System.Drawing.Size(61, 24);
|
||||
this.labelName.Size = new System.Drawing.Size(53, 21);
|
||||
this.labelName.TabIndex = 0;
|
||||
this.labelName.Text = "Name";
|
||||
this.labelName.UseMnemonic = false;
|
||||
@@ -66,10 +72,11 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelDescription.AutoScroll = true;
|
||||
this.panelDescription.Controls.Add(this.labelDescription);
|
||||
this.panelDescription.Location = new System.Drawing.Point(28, 35);
|
||||
this.panelDescription.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.panelDescription.Location = new System.Drawing.Point(28, 33);
|
||||
this.panelDescription.Name = "panelDescription";
|
||||
this.panelDescription.Size = new System.Drawing.Size(493, 39);
|
||||
this.panelDescription.TabIndex = 2;
|
||||
this.panelDescription.Size = new System.Drawing.Size(410, 47);
|
||||
this.panelDescription.TabIndex = 4;
|
||||
this.panelDescription.Resize += new System.EventHandler(this.panelDescription_Resize);
|
||||
//
|
||||
// labelDescription
|
||||
@@ -80,44 +87,51 @@
|
||||
this.labelDescription.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelDescription.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelDescription.Name = "labelDescription";
|
||||
this.labelDescription.Size = new System.Drawing.Size(13, 39);
|
||||
this.labelDescription.Size = new System.Drawing.Size(14, 45);
|
||||
this.labelDescription.TabIndex = 0;
|
||||
this.labelDescription.Text = "a\r\nb\r\nc";
|
||||
this.labelDescription.UseMnemonic = false;
|
||||
//
|
||||
// labelAuthor
|
||||
//
|
||||
this.labelAuthor.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelAuthor.AutoSize = true;
|
||||
this.labelAuthor.Location = new System.Drawing.Point(3, 0);
|
||||
this.labelAuthor.Margin = new System.Windows.Forms.Padding(3, 0, 32, 0);
|
||||
this.labelAuthor.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelAuthor.Location = new System.Drawing.Point(53, 5);
|
||||
this.labelAuthor.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.labelAuthor.Name = "labelAuthor";
|
||||
this.labelAuthor.Size = new System.Drawing.Size(38, 13);
|
||||
this.labelAuthor.TabIndex = 0;
|
||||
this.labelAuthor.Size = new System.Drawing.Size(44, 15);
|
||||
this.labelAuthor.TabIndex = 1;
|
||||
this.labelAuthor.Text = "Author";
|
||||
this.labelAuthor.UseMnemonic = false;
|
||||
//
|
||||
// flowLayoutInfo
|
||||
//
|
||||
this.flowLayoutInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
this.flowLayoutInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowLayoutInfo.Controls.Add(this.labelName);
|
||||
this.flowLayoutInfo.Controls.Add(this.labelAuthor);
|
||||
this.flowLayoutInfo.Controls.Add(this.labelWebsite);
|
||||
this.flowLayoutInfo.Location = new System.Drawing.Point(28, 85);
|
||||
this.flowLayoutInfo.Location = new System.Drawing.Point(24, 6);
|
||||
this.flowLayoutInfo.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.flowLayoutInfo.Name = "flowLayoutInfo";
|
||||
this.flowLayoutInfo.Size = new System.Drawing.Size(348, 18);
|
||||
this.flowLayoutInfo.TabIndex = 3;
|
||||
this.flowLayoutInfo.Size = new System.Drawing.Size(414, 21);
|
||||
this.flowLayoutInfo.TabIndex = 2;
|
||||
this.flowLayoutInfo.WrapContents = false;
|
||||
//
|
||||
// labelWebsite
|
||||
//
|
||||
this.labelWebsite.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelWebsite.AutoEllipsis = true;
|
||||
this.labelWebsite.AutoSize = true;
|
||||
this.labelWebsite.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.labelWebsite.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelWebsite.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelWebsite.ForeColor = System.Drawing.Color.Blue;
|
||||
this.labelWebsite.Location = new System.Drawing.Point(76, 0);
|
||||
this.labelWebsite.Location = new System.Drawing.Point(100, 5);
|
||||
this.labelWebsite.Margin = new System.Windows.Forms.Padding(3, 0, 0, 1);
|
||||
this.labelWebsite.Name = "labelWebsite";
|
||||
this.labelWebsite.Size = new System.Drawing.Size(46, 13);
|
||||
this.labelWebsite.TabIndex = 1;
|
||||
this.labelWebsite.Size = new System.Drawing.Size(49, 15);
|
||||
this.labelWebsite.TabIndex = 2;
|
||||
this.labelWebsite.Text = "Website";
|
||||
this.labelWebsite.UseMnemonic = false;
|
||||
this.labelWebsite.Click += new System.EventHandler(this.labelWebsite_Click);
|
||||
@@ -126,25 +140,28 @@
|
||||
//
|
||||
this.labelVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelVersion.Location = new System.Drawing.Point(14, 12);
|
||||
this.labelVersion.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
|
||||
this.labelVersion.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelVersion.Location = new System.Drawing.Point(88, 6);
|
||||
this.labelVersion.Margin = new System.Windows.Forms.Padding(0, 0, 1, 0);
|
||||
this.labelVersion.Name = "labelVersion";
|
||||
this.labelVersion.Size = new System.Drawing.Size(510, 13);
|
||||
this.labelVersion.TabIndex = 1;
|
||||
this.labelVersion.Padding = new System.Windows.Forms.Padding(0, 0, 0, 3);
|
||||
this.labelVersion.Size = new System.Drawing.Size(436, 21);
|
||||
this.labelVersion.TabIndex = 3;
|
||||
this.labelVersion.Text = "Version";
|
||||
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.BottomRight;
|
||||
this.labelVersion.UseMnemonic = false;
|
||||
//
|
||||
// btnOpenConfig
|
||||
// btnConfigure
|
||||
//
|
||||
this.btnOpenConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOpenConfig.Location = new System.Drawing.Point(382, 80);
|
||||
this.btnOpenConfig.Name = "btnOpenConfig";
|
||||
this.btnOpenConfig.Size = new System.Drawing.Size(68, 23);
|
||||
this.btnOpenConfig.TabIndex = 4;
|
||||
this.btnOpenConfig.Text = "Configure";
|
||||
this.btnOpenConfig.UseVisualStyleBackColor = true;
|
||||
this.btnOpenConfig.Click += new System.EventHandler(this.btnOpenConfig_Click);
|
||||
this.btnConfigure.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnConfigure.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.btnConfigure.Location = new System.Drawing.Point(451, 30);
|
||||
this.btnConfigure.Name = "btnConfigure";
|
||||
this.btnConfigure.Size = new System.Drawing.Size(70, 23);
|
||||
this.btnConfigure.TabIndex = 5;
|
||||
this.btnConfigure.Text = "Configure";
|
||||
this.btnConfigure.UseVisualStyleBackColor = true;
|
||||
this.btnConfigure.Click += new System.EventHandler(this.btnConfigure_Click);
|
||||
//
|
||||
// labelType
|
||||
//
|
||||
@@ -152,35 +169,50 @@
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.labelType.BackColor = System.Drawing.Color.DarkGray;
|
||||
this.labelType.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelType.LineHeight = 0;
|
||||
this.labelType.Location = new System.Drawing.Point(0, 0);
|
||||
this.labelType.Name = "labelType";
|
||||
this.labelType.Size = new System.Drawing.Size(18, 109);
|
||||
this.labelType.TabIndex = 6;
|
||||
this.labelType.Size = new System.Drawing.Size(18, 88);
|
||||
this.labelType.TabIndex = 0;
|
||||
this.labelType.Text = "TYPE";
|
||||
//
|
||||
// timerLayout
|
||||
//
|
||||
this.timerLayout.Interval = 1;
|
||||
this.timerLayout.Tick += new System.EventHandler(this.timerLayout_Tick);
|
||||
//
|
||||
// panelBorder
|
||||
//
|
||||
this.panelBorder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.panelBorder.BackColor = System.Drawing.Color.DimGray;
|
||||
this.panelBorder.Location = new System.Drawing.Point(18, 0);
|
||||
this.panelBorder.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelBorder.Name = "panelBorder";
|
||||
this.panelBorder.Size = new System.Drawing.Size(1, 88);
|
||||
this.panelBorder.TabIndex = 1;
|
||||
//
|
||||
// PluginControl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.labelType);
|
||||
this.Controls.Add(this.btnOpenConfig);
|
||||
this.Controls.Add(this.btnConfigure);
|
||||
this.Controls.Add(this.flowLayoutInfo);
|
||||
this.Controls.Add(this.panelBorder);
|
||||
this.Controls.Add(this.panelDescription);
|
||||
this.Controls.Add(this.labelName);
|
||||
this.Controls.Add(this.btnToggleState);
|
||||
this.Controls.Add(this.labelVersion);
|
||||
this.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.MaximumSize = new System.Drawing.Size(65535, 109);
|
||||
this.MinimumSize = new System.Drawing.Size(0, 61);
|
||||
this.MaximumSize = new System.Drawing.Size(65535, 88);
|
||||
this.Name = "PluginControl";
|
||||
this.Padding = new System.Windows.Forms.Padding(3, 3, 6, 3);
|
||||
this.Size = new System.Drawing.Size(530, 109);
|
||||
this.Size = new System.Drawing.Size(530, 88);
|
||||
this.panelDescription.ResumeLayout(false);
|
||||
this.panelDescription.PerformLayout();
|
||||
this.flowLayoutInfo.ResumeLayout(false);
|
||||
this.flowLayoutInfo.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@@ -194,7 +226,9 @@
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutInfo;
|
||||
private System.Windows.Forms.Label labelWebsite;
|
||||
private System.Windows.Forms.Label labelVersion;
|
||||
private System.Windows.Forms.Button btnOpenConfig;
|
||||
private System.Windows.Forms.Button btnConfigure;
|
||||
private Core.Controls.LabelVertical labelType;
|
||||
private System.Windows.Forms.Timer timerLayout;
|
||||
private System.Windows.Forms.Panel panelBorder;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
@@ -11,8 +9,9 @@ namespace TweetDuck.Plugins.Controls{
|
||||
sealed partial class PluginControl : UserControl{
|
||||
private readonly PluginManager pluginManager;
|
||||
private readonly Plugin plugin;
|
||||
|
||||
private readonly float dpiScale;
|
||||
private readonly bool isConfigurable;
|
||||
|
||||
private int nextHeight;
|
||||
|
||||
public PluginControl(){
|
||||
InitializeComponent();
|
||||
@@ -22,32 +21,59 @@ namespace TweetDuck.Plugins.Controls{
|
||||
this.pluginManager = pluginManager;
|
||||
this.plugin = plugin;
|
||||
|
||||
this.dpiScale = this.GetDPIScale();
|
||||
this.isConfigurable = pluginManager.IsPluginConfigurable(plugin);
|
||||
|
||||
this.labelName.Text = plugin.Name;
|
||||
this.labelDescription.Text = plugin.CanRun ? plugin.Description : "This plugin requires TweetDuck "+plugin.RequiredVersion+" or newer.";
|
||||
this.labelVersion.Text = plugin.Version;
|
||||
this.labelAuthor.Text = plugin.Author;
|
||||
this.labelWebsite.Text = plugin.Website;
|
||||
float dpiScale = this.GetDPIScale();
|
||||
|
||||
if (dpiScale > 1F){
|
||||
Size = MaximumSize = new Size(MaximumSize.Width, MaximumSize.Height+3);
|
||||
}
|
||||
|
||||
this.labelType.LineHeight = BrowserUtils.Scale(9, dpiScale);
|
||||
this.labelName.Text = plugin.Name;
|
||||
this.labelDescription.Text = plugin.CanRun ? plugin.Description : $"This plugin requires TweetDuck {plugin.RequiredVersion} or newer.";
|
||||
this.labelAuthor.Text = string.IsNullOrWhiteSpace(plugin.Author) ? string.Empty : $"by {plugin.Author}";
|
||||
this.labelWebsite.Text = plugin.Website;
|
||||
this.labelVersion.Text = plugin.Version;
|
||||
|
||||
this.labelType.LineHeight = BrowserUtils.Scale(11, dpiScale);
|
||||
|
||||
UpdatePluginState();
|
||||
|
||||
if (labelDescription.Text.Length == 0){
|
||||
labelDescription.Visible = false;
|
||||
}
|
||||
|
||||
panelDescription_Resize(panelDescription, EventArgs.Empty);
|
||||
}
|
||||
|
||||
panelDescription_Resize(panelDescription, null);
|
||||
private void timerLayout_Tick(object sender, EventArgs e){
|
||||
timerLayout.Stop();
|
||||
Height = nextHeight;
|
||||
ResumeLayout();
|
||||
}
|
||||
|
||||
private void panelDescription_Resize(object sender, EventArgs e){
|
||||
if (labelDescription.Text.Length == 0){
|
||||
Height = MinimumSize.Height;
|
||||
SuspendLayout();
|
||||
|
||||
int maxWidth = panelDescription.Width-(panelDescription.VerticalScroll.Visible ? SystemInformation.VerticalScrollBarWidth : 0);
|
||||
labelDescription.MaximumSize = new Size(maxWidth, int.MaxValue);
|
||||
|
||||
Font font = labelDescription.Font;
|
||||
int descriptionLines = TextRenderer.MeasureText(labelDescription.Text, font, new Size(maxWidth, int.MaxValue), TextFormatFlags.WordBreak).Height/(font.Height-1);
|
||||
|
||||
int requiredLines = Math.Max(descriptionLines, 1+(string.IsNullOrEmpty(labelVersion.Text) ? 0 : 1)+(isConfigurable ? 1 : 0));
|
||||
|
||||
switch(requiredLines){
|
||||
case 1: nextHeight = MaximumSize.Height-2*(font.Height-1); break;
|
||||
case 2: nextHeight = MaximumSize.Height-(font.Height-1); break;
|
||||
default: nextHeight = MaximumSize.Height; break;
|
||||
}
|
||||
|
||||
if (nextHeight != Height){
|
||||
timerLayout.Start();
|
||||
}
|
||||
else{
|
||||
labelDescription.MaximumSize = new Size(panelDescription.Width-SystemInformation.VerticalScrollBarWidth, 0);
|
||||
Height = Math.Min(MinimumSize.Height+BrowserUtils.Scale(9, dpiScale)+labelDescription.Height, MaximumSize.Height);
|
||||
ResumeLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +83,9 @@ namespace TweetDuck.Plugins.Controls{
|
||||
}
|
||||
}
|
||||
|
||||
private void btnOpenConfig_Click(object sender, EventArgs e){
|
||||
using(Process.Start("explorer.exe", "/select,\""+plugin.ConfigPath.Replace('/', '\\')+"\"")){}
|
||||
private void btnConfigure_Click(object sender, EventArgs e){
|
||||
pluginManager.ConfigurePlugin(plugin);
|
||||
ParentForm?.Close();
|
||||
}
|
||||
|
||||
private void btnToggleState_Click(object sender, EventArgs e){
|
||||
@@ -75,11 +102,11 @@ namespace TweetDuck.Plugins.Controls{
|
||||
labelWebsite.ForeColor = isEnabled ? Color.Blue : Color.FromArgb(90, 90, 249);
|
||||
|
||||
if (plugin.Group == PluginGroup.Official){
|
||||
labelType.Text = "OFFICIAL";
|
||||
labelType.Text = "CORE";
|
||||
labelType.BackColor = isEnabled ? Color.FromArgb(154, 195, 217) : Color.FromArgb(185, 185, 185);
|
||||
}
|
||||
else{
|
||||
labelType.Text = "CUSTOM";
|
||||
labelType.Text = "USER";
|
||||
labelType.BackColor = isEnabled ? Color.FromArgb(208, 154, 217) : Color.FromArgb(185, 185, 185);
|
||||
}
|
||||
|
||||
@@ -87,14 +114,14 @@ namespace TweetDuck.Plugins.Controls{
|
||||
labelName.ForeColor = textColor;
|
||||
labelDescription.ForeColor = textColor;
|
||||
btnToggleState.Text = isEnabled ? "Disable" : "Enable";
|
||||
btnOpenConfig.Visible = plugin.HasConfig;
|
||||
btnOpenConfig.Enabled = btnOpenConfig.Visible && File.Exists(plugin.ConfigPath);
|
||||
btnConfigure.Visible = isConfigurable;
|
||||
btnConfigure.Enabled = isEnabled;
|
||||
}
|
||||
else{
|
||||
labelName.ForeColor = Color.DarkRed;
|
||||
labelDescription.ForeColor = Color.DarkRed;
|
||||
btnToggleState.Visible = false;
|
||||
btnOpenConfig.Visible = false;
|
||||
btnConfigure.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,10 @@ namespace TweetDuck.Plugins.Controls{
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m){
|
||||
NativeMethods.ShowScrollBar(Handle, NativeMethods.SB_HORZ, false); // basically fuck the horizontal scrollbar very much
|
||||
if (m.Msg == 0x85){ // WM_NCPAINT
|
||||
NativeMethods.ShowScrollBar(Handle, NativeMethods.SB_HORZ, false); // basically fuck the horizontal scrollbar very much
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace TweetDuck.Plugins.Enums{
|
||||
[Flags]
|
||||
@@ -21,15 +24,6 @@ namespace TweetDuck.Plugins.Enums{
|
||||
return environment == PluginEnvironment.Browser;
|
||||
}
|
||||
|
||||
public static string GetScriptIdentifier(this PluginEnvironment environment){
|
||||
switch(environment){
|
||||
case PluginEnvironment.None: return "root:plugins";
|
||||
case PluginEnvironment.Browser: return "root:plugins.browser";
|
||||
case PluginEnvironment.Notification: return "root:plugins.notification";
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPluginScriptFile(this PluginEnvironment environment){
|
||||
switch(environment){
|
||||
case PluginEnvironment.Browser: return "browser.js";
|
||||
@@ -45,5 +39,50 @@ namespace TweetDuck.Plugins.Enums{
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static IReadOnlyDictionary<PluginEnvironment, T> Map<T>(T forNone, T forBrowser, T forNotification){
|
||||
return new PluginEnvironmentDictionary<T>(forNone, forBrowser, forNotification);
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "MemberHidesStaticFromOuterClass")]
|
||||
private sealed class PluginEnvironmentDictionary<T> : IReadOnlyDictionary<PluginEnvironment, T>{
|
||||
private const int TotalKeys = 3;
|
||||
|
||||
public IEnumerable<PluginEnvironment> Keys => Enum.GetValues(typeof(PluginEnvironment)).Cast<PluginEnvironment>();
|
||||
public IEnumerable<T> Values => data;
|
||||
public int Count => TotalKeys;
|
||||
|
||||
public T this[PluginEnvironment key] => data[(int)key];
|
||||
|
||||
private readonly T[] data;
|
||||
|
||||
public PluginEnvironmentDictionary(T forNone, T forBrowser, T forNotification){
|
||||
this.data = new T[TotalKeys];
|
||||
this.data[(int)PluginEnvironment.None] = forNone;
|
||||
this.data[(int)PluginEnvironment.Browser] = forBrowser;
|
||||
this.data[(int)PluginEnvironment.Notification] = forNotification;
|
||||
}
|
||||
|
||||
public bool ContainsKey(PluginEnvironment key){
|
||||
return key >= 0 && (int)key < TotalKeys;
|
||||
}
|
||||
|
||||
public bool TryGetValue(PluginEnvironment key, out T value){
|
||||
if (ContainsKey(key)){
|
||||
value = this[key];
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<PluginEnvironment, T>> GetEnumerator(){
|
||||
return Keys.Select(key => new KeyValuePair<PluginEnvironment, T>(key, this[key])).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,5 +11,13 @@
|
||||
default: return "unknown/";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetIdentifierPrefixShort(this PluginGroup group){
|
||||
switch(group){
|
||||
case PluginGroup.Official: return "o/";
|
||||
case PluginGroup.Custom: return "c/";
|
||||
default: return "?/";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,28 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
|
||||
namespace TweetDuck.Plugins{
|
||||
sealed class Plugin{
|
||||
private const string VersionWildcard = "*";
|
||||
private static readonly Version AppVersion = new Version(Program.VersionTag);
|
||||
|
||||
public string Identifier { get; }
|
||||
public PluginGroup Group { get; }
|
||||
public PluginEnvironment Environments { get; }
|
||||
|
||||
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 string Name { get; }
|
||||
public string Description { get; }
|
||||
public string Author { get; }
|
||||
public string Version { get; }
|
||||
public string Website { get; }
|
||||
public string ConfigFile { get; }
|
||||
public string ConfigDefault { get; }
|
||||
public Version RequiredVersion { get; }
|
||||
|
||||
public bool CanRun { get; private set; }
|
||||
public bool CanRun { get; }
|
||||
|
||||
public bool HasConfig{
|
||||
get => ConfigFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, ConfigFile).Length > 0;
|
||||
@@ -42,41 +39,25 @@ namespace TweetDuck.Plugins{
|
||||
|
||||
private readonly string pathRoot;
|
||||
private readonly string pathData;
|
||||
private readonly Dictionary<string, string> metadata = new Dictionary<string, string>(8){
|
||||
{ "NAME", "" },
|
||||
{ "DESCRIPTION", "" },
|
||||
{ "AUTHOR", "(anonymous)" },
|
||||
{ "VERSION", "(unknown)" },
|
||||
{ "WEBSITE", "" },
|
||||
{ "CONFIGFILE", "" },
|
||||
{ "CONFIGDEFAULT", "" },
|
||||
{ "REQUIRES", VersionWildcard }
|
||||
};
|
||||
|
||||
private Plugin(string path, string name, PluginGroup group, PluginEnvironment environments){
|
||||
this.pathRoot = path;
|
||||
this.pathData = Path.Combine(Program.PluginDataPath, group.GetIdentifierPrefix(), name);
|
||||
private Plugin(PluginGroup group, string identifier, string pathRoot, string pathData, Builder builder){
|
||||
this.pathRoot = pathRoot;
|
||||
this.pathData = pathData;
|
||||
|
||||
this.Identifier = group.GetIdentifierPrefix()+name;
|
||||
this.Group = group;
|
||||
this.Environments = environments;
|
||||
}
|
||||
this.Identifier = identifier;
|
||||
this.Environments = builder.Environments;
|
||||
|
||||
private void OnMetadataLoaded(){
|
||||
CanRun = CheckRequiredVersion(RequiredVersion);
|
||||
this.Name = builder.Name;
|
||||
this.Description = builder.Description;
|
||||
this.Author = builder.Author;
|
||||
this.Version = builder.Version;
|
||||
this.Website = builder.Website;
|
||||
this.ConfigFile = builder.ConfigFile;
|
||||
this.ConfigDefault = builder.ConfigDefault;
|
||||
this.RequiredVersion = builder.RequiredVersion;
|
||||
|
||||
string configPath = ConfigPath, defaultConfigPath = DefaultConfigPath;
|
||||
|
||||
if (configPath.Length > 0 && defaultConfigPath.Length > 0 && !File.Exists(configPath) && File.Exists(defaultConfigPath)){
|
||||
string dataFolder = GetPluginFolder(PluginFolder.Data);
|
||||
|
||||
try{
|
||||
Directory.CreateDirectory(dataFolder);
|
||||
File.Copy(defaultConfigPath, configPath, false);
|
||||
}catch(Exception e){
|
||||
throw new IOException("Could not generate a configuration file for '"+Identifier+"' plugin: "+e.Message, e);
|
||||
}
|
||||
}
|
||||
this.CanRun = AppVersion >= RequiredVersion;
|
||||
}
|
||||
|
||||
public string GetScriptPath(PluginEnvironment environment){
|
||||
@@ -103,14 +84,20 @@ namespace TweetDuck.Plugins{
|
||||
|
||||
try{
|
||||
string folderPathName = new DirectoryInfo(rootFolder).FullName;
|
||||
DirectoryInfo currentInfo = new DirectoryInfo(fullPath);
|
||||
DirectoryInfo currentInfo = new DirectoryInfo(fullPath); // initially points to the file, which is convenient for the Attributes check below
|
||||
DirectoryInfo parentInfo = currentInfo.Parent;
|
||||
|
||||
while(currentInfo.Parent != null){
|
||||
if (currentInfo.Parent.FullName == folderPathName){
|
||||
while(parentInfo != null){
|
||||
if (currentInfo.Exists && currentInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)){
|
||||
return string.Empty; // no reason why a plugin should have files/folders with symlinks, junctions, or any other crap
|
||||
}
|
||||
|
||||
if (parentInfo.FullName == folderPathName){
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
currentInfo = currentInfo.Parent;
|
||||
|
||||
currentInfo = parentInfo;
|
||||
parentInfo = currentInfo.Parent;
|
||||
}
|
||||
}
|
||||
catch{
|
||||
@@ -132,78 +119,77 @@ namespace TweetDuck.Plugins{
|
||||
return obj is Plugin plugin && plugin.Identifier.Equals(Identifier);
|
||||
}
|
||||
|
||||
// Static
|
||||
|
||||
private static readonly Version AppVersion = new Version(Program.VersionTag);
|
||||
private static readonly string[] EndTag = { "[END]" };
|
||||
// Builder
|
||||
|
||||
public static Plugin CreateFromFolder(string path, PluginGroup group){
|
||||
Plugin plugin = new Plugin(path, Path.GetFileName(path), group, LoadEnvironments(path));
|
||||
LoadMetadata(path, plugin);
|
||||
return plugin;
|
||||
}
|
||||
public sealed class Builder{
|
||||
private static readonly Version DefaultRequiredVersion = new Version(0, 0, 0, 0);
|
||||
|
||||
private static PluginEnvironment LoadEnvironments(string path){
|
||||
PluginEnvironment environments = PluginEnvironment.None;
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public string Author { get; set; } = "(anonymous)";
|
||||
public string Version { get; set; } = string.Empty;
|
||||
public string Website { get; set; } = string.Empty;
|
||||
public string ConfigFile { get; set; } = string.Empty;
|
||||
public string ConfigDefault { get; set; } = string.Empty;
|
||||
public Version RequiredVersion { get; set; } = DefaultRequiredVersion;
|
||||
|
||||
foreach(string file in Directory.EnumerateFiles(path, "*.js", SearchOption.TopDirectoryOnly).Select(Path.GetFileName)){
|
||||
environments |= PluginEnvironmentExtensions.Values.FirstOrDefault(env => file.Equals(env.GetPluginScriptFile(), StringComparison.Ordinal));
|
||||
public PluginEnvironment Environments { get; private set; } = PluginEnvironment.None;
|
||||
|
||||
private readonly PluginGroup group;
|
||||
private readonly string pathRoot;
|
||||
private readonly string pathData;
|
||||
private readonly string identifier;
|
||||
|
||||
public Builder(PluginGroup group, string name, string pathRoot, string pathData){
|
||||
this.group = group;
|
||||
this.pathRoot = pathRoot;
|
||||
this.pathData = pathData;
|
||||
this.identifier = group.GetIdentifierPrefix()+name;
|
||||
}
|
||||
|
||||
if (environments == PluginEnvironment.None){
|
||||
throw new ArgumentException("Plugin has no script files");
|
||||
public void AddEnvironment(PluginEnvironment environment){
|
||||
this.Environments |= environment;
|
||||
}
|
||||
|
||||
return environments;
|
||||
}
|
||||
public Plugin BuildAndSetup(){
|
||||
Plugin plugin = new Plugin(group, identifier, pathRoot, pathData, this);
|
||||
|
||||
private static void LoadMetadata(string path, Plugin plugin){
|
||||
string metaFile = Path.Combine(path, ".meta");
|
||||
if (plugin.Name.Length == 0){
|
||||
throw new InvalidOperationException("Plugin is missing a name in the .meta file");
|
||||
}
|
||||
|
||||
if (!File.Exists(metaFile)){
|
||||
throw new ArgumentException("Missing .meta file");
|
||||
}
|
||||
|
||||
string currentTag = null, currentContents = string.Empty;
|
||||
if (plugin.Environments == PluginEnvironment.None){
|
||||
throw new InvalidOperationException("Plugin has no script files");
|
||||
}
|
||||
|
||||
foreach(string line in File.ReadAllLines(metaFile, Encoding.UTF8).Concat(EndTag).Select(line => line.TrimEnd()).Where(line => line.Length > 0)){
|
||||
if (line[0] == '[' && line[line.Length-1] == ']'){
|
||||
if (currentTag != null){
|
||||
plugin.metadata[currentTag] = currentContents;
|
||||
if (plugin.Group == PluginGroup.Official){
|
||||
if (plugin.RequiredVersion != AppVersion){
|
||||
throw new InvalidOperationException("Plugin is not supported in this version of TweetDuck, this may indicate a failed update or an unsupported plugin that was not removed automatically");
|
||||
}
|
||||
|
||||
currentTag = line.Substring(1, line.Length-2).ToUpper();
|
||||
currentContents = string.Empty;
|
||||
|
||||
if (line.Equals(EndTag[0])){
|
||||
break;
|
||||
}
|
||||
|
||||
if (!plugin.metadata.ContainsKey(currentTag)){
|
||||
throw new FormatException("Invalid metadata tag: "+currentTag);
|
||||
else if (!string.IsNullOrEmpty(plugin.Version)){
|
||||
throw new InvalidOperationException("Official plugins cannot have a version identifier");
|
||||
}
|
||||
}
|
||||
else if (currentTag != null){
|
||||
currentContents = currentContents.Length == 0 ? line : currentContents+Environment.NewLine+line;
|
||||
}
|
||||
else{
|
||||
throw new FormatException("Missing metadata tag before value: "+line);
|
||||
|
||||
// setup
|
||||
|
||||
string configPath = plugin.ConfigPath, defaultConfigPath = plugin.DefaultConfigPath;
|
||||
|
||||
if (configPath.Length > 0 && defaultConfigPath.Length > 0 && !File.Exists(configPath) && File.Exists(defaultConfigPath)){
|
||||
string dataFolder = plugin.GetPluginFolder(PluginFolder.Data);
|
||||
|
||||
try{
|
||||
Directory.CreateDirectory(dataFolder);
|
||||
File.Copy(defaultConfigPath, configPath, false);
|
||||
}catch(Exception e){
|
||||
throw new IOException($"Could not generate a configuration file for '{plugin.Identifier}' plugin: {e.Message}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
if (plugin.Name.Length == 0){
|
||||
throw new FormatException("Plugin is missing a name in the .meta file");
|
||||
}
|
||||
|
||||
if (plugin.RequiredVersion.Length == 0 || !(plugin.RequiredVersion == VersionWildcard || System.Version.TryParse(plugin.RequiredVersion, out Version _))){
|
||||
throw new FormatException("Plugin contains invalid version: "+plugin.RequiredVersion);
|
||||
}
|
||||
|
||||
plugin.OnMetadataLoaded();
|
||||
}
|
||||
|
||||
private static bool CheckRequiredVersion(string requires){
|
||||
return requires == VersionWildcard || AppVersion >= new Version(requires);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,14 +15,15 @@ namespace TweetDuck.Plugins{
|
||||
|
||||
private readonly PluginManager manager;
|
||||
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 => notificationInjections.InnerValues;
|
||||
public HashSet<Plugin> WithConfigureFunction { get; } = new HashSet<Plugin>();
|
||||
|
||||
public PluginBridge(PluginManager manager){
|
||||
this.manager = manager;
|
||||
this.manager.Reloaded += manager_Reloaded;
|
||||
this.manager.PluginChangedState += manager_PluginChangedState;
|
||||
this.manager.Config.PluginChangedState += Config_PluginChangedState;
|
||||
}
|
||||
|
||||
// Event handlers
|
||||
@@ -31,7 +32,7 @@ namespace TweetDuck.Plugins{
|
||||
fileCache.Clear();
|
||||
}
|
||||
|
||||
private void manager_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
private void Config_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
if (!e.IsEnabled){
|
||||
int token = manager.GetTokenFromPlugin(e.Plugin);
|
||||
|
||||
@@ -114,5 +115,13 @@ namespace TweetDuck.Plugins{
|
||||
public void InjectIntoNotificationsAfter(int token, string key, string search, string html){
|
||||
notificationInjections[token, key] = new InjectedHTML(InjectedHTML.Position.After, search, html);
|
||||
}
|
||||
|
||||
public void SetConfigurable(int token){
|
||||
Plugin plugin = manager.GetPluginFromToken(token);
|
||||
|
||||
if (plugin != null){
|
||||
WithConfigureFunction.Add(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ using TweetDuck.Plugins.Events;
|
||||
|
||||
namespace TweetDuck.Plugins{
|
||||
sealed class PluginConfig{
|
||||
public event EventHandler<PluginChangedStateEventArgs> InternalPluginChangedState; // should only be accessed from PluginManager
|
||||
public event EventHandler<PluginChangedStateEventArgs> PluginChangedState;
|
||||
|
||||
public IEnumerable<string> DisabledPlugins => disabled;
|
||||
public bool AnyDisabled => disabled.Count > 0;
|
||||
@@ -20,7 +20,7 @@ namespace TweetDuck.Plugins{
|
||||
|
||||
public void SetEnabled(Plugin plugin, bool enabled){
|
||||
if ((enabled && disabled.Remove(plugin.Identifier)) || (!enabled && disabled.Add(plugin.Identifier))){
|
||||
InternalPluginChangedState?.Invoke(this, new PluginChangedStateEventArgs(plugin, enabled));
|
||||
PluginChangedState?.Invoke(this, new PluginChangedStateEventArgs(plugin, enabled));
|
||||
}
|
||||
}
|
||||
|
||||
|
70
Plugins/PluginLoader.cs
Normal file
70
Plugins/PluginLoader.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
|
||||
namespace TweetDuck.Plugins{
|
||||
static class PluginLoader{
|
||||
private static readonly string[] EndTag = { "[END]" };
|
||||
|
||||
public static Plugin FromFolder(string path, PluginGroup group){
|
||||
string name = Path.GetFileName(path);
|
||||
|
||||
if (string.IsNullOrEmpty(name)){
|
||||
throw new ArgumentException("Could not extract directory name from path: "+path);
|
||||
}
|
||||
|
||||
Plugin.Builder builder = new Plugin.Builder(group, name, path, Path.Combine(Program.PluginDataPath, group.GetIdentifierPrefix(), name));
|
||||
|
||||
foreach(string file in Directory.EnumerateFiles(path, "*.js", SearchOption.TopDirectoryOnly).Select(Path.GetFileName)){
|
||||
builder.AddEnvironment(PluginEnvironmentExtensions.Values.FirstOrDefault(env => file.Equals(env.GetPluginScriptFile(), StringComparison.Ordinal)));
|
||||
}
|
||||
|
||||
string metaFile = Path.Combine(path, ".meta");
|
||||
|
||||
if (!File.Exists(metaFile)){
|
||||
throw new ArgumentException("Plugin is missing a .meta file");
|
||||
}
|
||||
|
||||
string currentTag = null, currentContents = string.Empty;
|
||||
|
||||
foreach(string line in File.ReadAllLines(metaFile, Encoding.UTF8).Concat(EndTag).Select(line => line.TrimEnd()).Where(line => line.Length > 0)){
|
||||
if (line[0] == '[' && line[line.Length-1] == ']'){
|
||||
if (currentTag != null){
|
||||
SetProperty(builder, currentTag, currentContents);
|
||||
}
|
||||
|
||||
currentTag = line.Substring(1, line.Length-2).ToUpper();
|
||||
currentContents = string.Empty;
|
||||
|
||||
if (line.Equals(EndTag[0])){
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (currentTag != null){
|
||||
currentContents = currentContents.Length == 0 ? line : currentContents+Environment.NewLine+line;
|
||||
}
|
||||
else{
|
||||
throw new FormatException("Missing metadata tag before value: "+line);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.BuildAndSetup();
|
||||
}
|
||||
|
||||
private static void SetProperty(Plugin.Builder builder, string tag, string value){
|
||||
switch(tag){
|
||||
case "NAME": builder.Name = value; break;
|
||||
case "DESCRIPTION": builder.Description = value; break;
|
||||
case "AUTHOR": builder.Author = value; break;
|
||||
case "VERSION": builder.Version = value; break;
|
||||
case "WEBSITE": builder.Website = value; break;
|
||||
case "CONFIGFILE": builder.ConfigFile = value; break;
|
||||
case "CONFIGDEFAULT": builder.ConfigDefault = value; break;
|
||||
case "REQUIRES": builder.RequiredVersion = Version.TryParse(value, out Version version) ? version : throw new FormatException("Invalid required minimum version: "+value); break;
|
||||
default: throw new FormatException("Invalid metadata tag: "+tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,51 +1,63 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Other.Interfaces;
|
||||
using TweetDuck.Data;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
using TweetDuck.Plugins.Events;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Plugins{
|
||||
sealed class PluginManager{
|
||||
private static readonly Dictionary<PluginEnvironment, string> PluginSetupScripts = new Dictionary<PluginEnvironment, string>(4){
|
||||
{ PluginEnvironment.None, ScriptLoader.LoadResource("plugins.js") },
|
||||
{ PluginEnvironment.Browser, ScriptLoader.LoadResource("plugins.browser.js") },
|
||||
{ PluginEnvironment.Notification, ScriptLoader.LoadResource("plugins.notification.js") }
|
||||
};
|
||||
private static readonly IReadOnlyDictionary<PluginEnvironment, string> PluginSetupScriptNames = PluginEnvironmentExtensions.Map(null, "plugins.browser.js", "plugins.notification.js");
|
||||
|
||||
public string PathOfficialPlugins => Path.Combine(rootPath, "official");
|
||||
public string PathCustomPlugins => Path.Combine(rootPath, "user");
|
||||
|
||||
public IEnumerable<Plugin> Plugins => plugins;
|
||||
public IEnumerable<InjectedHTML> NotificationInjections => bridge.NotificationInjections;
|
||||
|
||||
public PluginConfig Config { get; }
|
||||
public PluginBridge Bridge { get; }
|
||||
|
||||
public event EventHandler<PluginErrorEventArgs> Reloaded;
|
||||
public event EventHandler<PluginErrorEventArgs> Executed;
|
||||
public event EventHandler<PluginChangedStateEventArgs> PluginChangedState;
|
||||
|
||||
private readonly string rootPath;
|
||||
private readonly string configPath;
|
||||
private readonly PluginBridge bridge;
|
||||
|
||||
private readonly HashSet<Plugin> plugins = new HashSet<Plugin>();
|
||||
private readonly Dictionary<int, Plugin> tokens = new Dictionary<int, Plugin>();
|
||||
private readonly Random rand = new Random();
|
||||
|
||||
private ITweetDeckBrowser mainBrowser;
|
||||
|
||||
public PluginManager(string rootPath, string configPath){
|
||||
this.rootPath = rootPath;
|
||||
this.configPath = configPath;
|
||||
|
||||
this.Config = new PluginConfig();
|
||||
this.Bridge = new PluginBridge(this);
|
||||
this.bridge = new PluginBridge(this);
|
||||
|
||||
Config.Load(configPath);
|
||||
Config.InternalPluginChangedState += Config_InternalPluginChangedState;
|
||||
Config.PluginChangedState += Config_PluginChangedState;
|
||||
}
|
||||
|
||||
private void Config_InternalPluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
PluginChangedState?.Invoke(this, e);
|
||||
public void Register(ITweetDeckBrowser browser, PluginEnvironment environment, Control sync, bool asMainBrowser = false){
|
||||
browser.OnFrameLoaded(frame => ExecutePlugins(frame, environment, sync));
|
||||
browser.RegisterBridge("$TDP", bridge);
|
||||
|
||||
if (asMainBrowser){
|
||||
mainBrowser = browser;
|
||||
}
|
||||
}
|
||||
|
||||
private void Config_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
mainBrowser?.ExecuteFunction("TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
||||
Config.Save(configPath);
|
||||
}
|
||||
|
||||
@@ -57,6 +69,24 @@ namespace TweetDuck.Plugins{
|
||||
return plugins.Any(plugin => plugin.Environments.HasFlag(environment));
|
||||
}
|
||||
|
||||
public bool IsPluginConfigurable(Plugin plugin){
|
||||
return plugin.HasConfig || bridge.WithConfigureFunction.Contains(plugin);
|
||||
}
|
||||
|
||||
public void ConfigurePlugin(Plugin plugin){
|
||||
if (bridge.WithConfigureFunction.Contains(plugin)){
|
||||
mainBrowser?.ExecuteFunction("TDPF_configurePlugin", plugin);
|
||||
}
|
||||
else if (plugin.HasConfig){
|
||||
if (File.Exists(plugin.ConfigPath)){
|
||||
using(Process.Start("explorer.exe", "/select,\""+plugin.ConfigPath.Replace('/', '\\')+"\"")){}
|
||||
}
|
||||
else{
|
||||
using(Process.Start("explorer.exe", '"'+plugin.GetPluginFolder(PluginFolder.Data).Replace('/', '\\')+'"')){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetTokenFromPlugin(Plugin plugin){
|
||||
foreach(KeyValuePair<int, Plugin> kvp in tokens){
|
||||
if (kvp.Value.Equals(plugin)){
|
||||
@@ -99,7 +129,7 @@ namespace TweetDuck.Plugins{
|
||||
Plugin plugin;
|
||||
|
||||
try{
|
||||
plugin = Plugin.CreateFromFolder(fullDir, group);
|
||||
plugin = PluginLoader.FromFolder(fullDir, group);
|
||||
}catch(Exception e){
|
||||
loadErrors.Add(group.GetIdentifierPrefix()+Path.GetFileName(fullDir)+": "+e.Message);
|
||||
continue;
|
||||
@@ -115,14 +145,11 @@ namespace TweetDuck.Plugins{
|
||||
Reloaded?.Invoke(this, new PluginErrorEventArgs(loadErrors));
|
||||
}
|
||||
|
||||
public void ExecutePlugins(IFrame frame, PluginEnvironment environment){
|
||||
if (!HasAnyPlugin(environment)){
|
||||
private void ExecutePlugins(IFrame frame, PluginEnvironment environment, Control sync){
|
||||
if (!HasAnyPlugin(environment) || !ScriptLoader.ExecuteFile(frame, PluginSetupScriptNames[environment], sync)){
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptLoader.ExecuteScript(frame, PluginSetupScripts[environment], environment.GetScriptIdentifier());
|
||||
ScriptLoader.ExecuteScript(frame, PluginSetupScripts[PluginEnvironment.None], PluginEnvironment.None.GetScriptIdentifier());
|
||||
|
||||
bool includeDisabled = environment.IncludesDisabledPlugins();
|
||||
|
||||
if (includeDisabled){
|
||||
|
29
Program.cs
29
Program.cs
@@ -13,25 +13,24 @@ using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Data;
|
||||
using TweetDuck.Updates;
|
||||
|
||||
namespace TweetDuck{
|
||||
static class Program{
|
||||
public const string BrandName = "TweetDuck";
|
||||
public const string Website = "https://tweetduck.chylex.com";
|
||||
|
||||
public const string VersionTag = "1.12.5";
|
||||
|
||||
public static readonly bool IsPortable = File.Exists("makeportable");
|
||||
public const string VersionTag = "1.15";
|
||||
|
||||
public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
public static readonly string StoragePath = IsPortable ? Path.Combine(ProgramPath, "portable", "storage") : GetDataStoragePath();
|
||||
public static readonly bool IsPortable = File.Exists(Path.Combine(ProgramPath, "makeportable"));
|
||||
|
||||
public static readonly string ScriptPath = Path.Combine(ProgramPath, "scripts");
|
||||
public static readonly string PluginPath = Path.Combine(ProgramPath, "plugins");
|
||||
|
||||
public static readonly string StoragePath = IsPortable ? Path.Combine(ProgramPath, "portable", "storage") : GetDataStoragePath();
|
||||
|
||||
public static readonly string PluginDataPath = Path.Combine(StoragePath, "TD_Plugins");
|
||||
private static readonly string InstallerPath = Path.Combine(StoragePath, "TD_Updates");
|
||||
public static readonly string InstallerPath = Path.Combine(StoragePath, "TD_Updates");
|
||||
private static readonly string CefDataPath = Path.Combine(StoragePath, "TD_Chromium");
|
||||
|
||||
public static string UserConfigFilePath => Path.Combine(StoragePath, "TD_UserConfig.cfg");
|
||||
@@ -129,10 +128,12 @@ namespace TweetDuck{
|
||||
}
|
||||
|
||||
BrowserCache.RefreshTimer();
|
||||
|
||||
CefSharpSettings.WcfEnabled = false;
|
||||
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
|
||||
|
||||
CefSettings settings = new CefSettings{
|
||||
UserAgent = BrowserUtils.HeaderUserAgent,
|
||||
UserAgent = BrowserUtils.UserAgentChrome,
|
||||
BrowserSubprocessPath = BrandName+".Browser.exe",
|
||||
CachePath = StoragePath,
|
||||
UserDataPath = CefDataPath,
|
||||
@@ -141,28 +142,22 @@ namespace TweetDuck{
|
||||
LogSeverity = Arguments.HasFlag(Arguments.ArgLogging) ? LogSeverity.Info : LogSeverity.Disable
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
CommandLineArgs.ReadCefArguments(UserConfig.CustomCefArgs).ToDictionary(settings.CefCommandLineArgs);
|
||||
BrowserUtils.SetupCefArgs(settings.CefCommandLineArgs);
|
||||
|
||||
Cef.Initialize(settings, false, new BrowserProcessHandler());
|
||||
|
||||
Application.ApplicationExit += (sender, args) => ExitCleanup();
|
||||
|
||||
UpdaterSettings updaterSettings = new UpdaterSettings{
|
||||
AllowPreReleases = Arguments.HasFlag(Arguments.ArgDebugUpdates),
|
||||
DismissedUpdate = UserConfig.DismissedUpdate,
|
||||
InstallerDownloadFolder = InstallerPath
|
||||
};
|
||||
|
||||
FormBrowser mainForm = new FormBrowser(updaterSettings);
|
||||
|
||||
FormBrowser mainForm = new FormBrowser();
|
||||
Application.Run(mainForm);
|
||||
|
||||
if (mainForm.UpdateInstallerPath != null){
|
||||
ExitCleanup();
|
||||
|
||||
// ProgramPath has a trailing backslash
|
||||
string updaterArgs = "/SP- /SILENT /CLOSEAPPLICATIONS /UPDATEPATH=\""+ProgramPath+"\" /RUNARGS=\""+Arguments.GetCurrentForInstallerCmd()+"\""+(IsPortable ? " /PORTABLE=1" : "");
|
||||
string updaterArgs = "/SP- /SILENT /FORCECLOSEAPPLICATIONS /UPDATEPATH=\""+ProgramPath+"\" /RUNARGS=\""+Arguments.GetCurrentForInstallerCmd()+"\""+(IsPortable ? " /PORTABLE=1" : "");
|
||||
bool runElevated = !IsPortable || !WindowsUtils.CheckFolderWritePermission(ProgramPath);
|
||||
|
||||
if (WindowsUtils.OpenAssociatedProgram(mainForm.UpdateInstallerPath, updaterArgs, runElevated)){
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -42,5 +42,6 @@ using TweetDuck;
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
#if DEBUG
|
||||
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("UnitTests")]
|
||||
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TweetTest.System")]
|
||||
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TweetTest.Unit")]
|
||||
#endif
|
||||
|
30
Properties/Resources.Designer.cs
generated
30
Properties/Resources.Designer.cs
generated
@@ -80,6 +80,16 @@ namespace TweetDuck.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon icon_muted {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("icon_muted", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
@@ -90,6 +100,16 @@ namespace TweetDuck.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon icon_tray_muted {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("icon_tray_muted", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
@@ -99,5 +119,15 @@ namespace TweetDuck.Properties {
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] spinner {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("spinner", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -119,15 +119,24 @@
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="avatar" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\avatar.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>..\Resources\Images\avatar.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="icon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<value>..\Resources\Images\icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="icon_muted" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\icon-muted.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="icon_tray" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\icon-tray.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<value>..\Resources\Images\icon-tray.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="icon_tray_muted" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\icon-tray-muted.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="icon_tray_new" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\icon-tray-new.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<value>..\Resources\Images\icon-tray-new.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="spinner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\spinner.apng;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
50
README.md
50
README.md
@@ -9,54 +9,48 @@
|
||||
The program was built using Visual Studio 2017. Before opening the solution, please make sure you have the following workloads and components installed (optional components that are not listed can be deselected to save space):
|
||||
* **.NET desktop development**
|
||||
* .NET Framework 4 – 4.6 development tools
|
||||
* F# desktop language support
|
||||
* **Desktop development with C++**
|
||||
* VC++ 2017 v141 toolset
|
||||
* VC++ 2017 latest v141 tools
|
||||
|
||||
After opening the solution, download the following NuGet packages by right-clicking on the solution and selecting **Restore NuGet Packages**, or manually running these commands in the **Package Manager Console**:
|
||||
After opening the solution, right-click the solution and select **Restore NuGet Packages**, or manually run this command in the **Package Manager Console**:
|
||||
```
|
||||
PM> Install-Package CefSharp.WinForms -Version 63.0.0-pre01 -Source https://www.myget.org/F/cefsharp/api/v3/index.json
|
||||
PM> Install-Package Microsoft.VC120.CRT.JetBrains
|
||||
PM> Install-Package CefSharp.WinForms -Version 67.0.0-CI2662 -Source https://www.myget.org/F/cefsharp/api/v3/index.json
|
||||
```
|
||||
|
||||
Note that some pre-release builds of CefSharp are not available on NuGet. To correctly restore packages in that case, open **Package Manager Settings**, and add `https://www.myget.org/F/cefsharp/api/v3/index.json` to the list of package sources.
|
||||
|
||||
### Debug
|
||||
|
||||
It is recommended to create a separate data folder for debugging, otherwise you will not be able to run TweetDuck while debugging the solution.
|
||||
The `Debug` configuration uses a separate data folder by default (`%LOCALAPPDATA%\TweetDuckDebug`) to avoid affecting an existing installation of TweetDuck. You can modify this by opening **TweetDuck Properties** in Visual Studio, clicking the **Debug** tab, and changing the **Command line arguments** field.
|
||||
|
||||
To do that, open **TweetDuck Properties**, click the **Debug** tab, make sure your **Configuration** is set to `Active (Debug)` (or just `Debug`), and insert this into the **Command line arguments** field:
|
||||
```
|
||||
-datafolder TweetDuckDebug
|
||||
```
|
||||
While debugging, opening the main menu and clicking **Reload browser** automatically rebuilds all resources in the `Resources/Scripts` and `Resources/Plugins` folders. This allows editing HTML/CSS/JS files and applying the changes without restarting the program, but it will cause a short delay between browser reloads.
|
||||
|
||||
### Build
|
||||
### Release
|
||||
|
||||
To make a release build of TweetDuck, open **Batch Build**, tick all `Release` configurations except for the `UnitTest` project (otherwise the build will fail), and click **Rebuild**. Check the status bar to make sure it says **Rebuild All succeeded**; if not, see the [Troubleshooting](#troubleshooting) section.
|
||||
Open **Batch Build**, tick all `Release` configurations with `x86` platform, and click **Rebuild**. Check the status bar to make sure it says **Rebuild All succeeded**; if not, see the [Troubleshooting](#troubleshooting) section.
|
||||
|
||||
After the build succeeds, the `bin/x86/Release` folder will contain files intended for distribution (no debug symbols or other unnecessary files). You may package these files yourself, or see the [Installers](#installers) section for automated installer generation.
|
||||
|
||||
If you decide to release a custom version publicly, please make it clear that it is not an official release of TweetDuck.
|
||||
The `Release` configuration omits debug symbols and other unnecessary files. You can modify this behavior by opening `TweetDuck.csproj`, and editing the `<Target Name="AfterBuild" Condition="$(ConfigurationName) == Release">` section.
|
||||
|
||||
If you decide to publicly release a custom version, please make it clear that it is not an official release of TweetDuck. There are many references to the official website and this repository, especially in the update system, so search for `chylex.com` and `github.com` in all files and replace them appropriately.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
There are a few quirks in the build process that may catch you off guard:
|
||||
|
||||
- **Plugin files are not updated automatically**
|
||||
- Since official plugins (`Resources/Plugins`) are not included in the project, Visual Studio will not automatically detect changes in the files
|
||||
- To ensure plugins are updated when testing the app, click **Rebuild Solution** before clicking **Start**
|
||||
- **Error: The command (...) exited with code 1**
|
||||
- If the post-build event fails, open the **Output** tab and look for the cause
|
||||
- Determine if there was an IO error while copying files or modifying folders, or whether the final .ps1 script failed (`Encountered an error while running PostBuild.ps1 on line xyz`)
|
||||
- Some files are checked for invalid characters:
|
||||
- `Resources/Plugins/emoji-keyboard/emoji-ordering.txt` line endings must be LF (line feed); any CR (carriage return) in the file will cause a failed build, and you will need to ensure correct line endings in your text editor
|
||||
#### Error: The command (...) exited with code 1
|
||||
- This indicates a failed post-build event, open the **Output** tab for logs
|
||||
- Determine if there was an IO error from the `rmdir` commands, or whether the error was in the **PostBuild.ps1** script (`Encountered an error while running PostBuild.ps1 on line <xyz>`)
|
||||
- Some files are checked for invalid characters:
|
||||
- `Resources/Plugins/emoji-keyboard/emoji-ordering.txt` line endings must be LF (line feed); any CR (carriage return) in the file will cause a failed build, and you will need to ensure correct line endings in your text editor
|
||||
|
||||
### Installers
|
||||
|
||||
TweetDuck uses **Inno Setup** to automate the creation of installers. First, download and install [InnoSetup QuickStart Pack](http://www.jrsoftware.org/isdl.php) (non-unicode; editor and encryption support not required) and the [Inno Download Plugin](https://code.google.com/archive/p/inno-download-plugin).
|
||||
TweetDuck uses **Inno Setup** for installers and updates. First, download and install [InnoSetup QuickStart Pack](http://www.jrsoftware.org/isdl.php) (non-unicode; editor and encryption support not required) and the [Inno Download Plugin](https://code.google.com/archive/p/inno-download-plugin).
|
||||
|
||||
Next, add the Inno Setup installation folder (usually `C:\Program Files (x86)\Inno Setup 5`) into your **PATH** environment variable. You may need to restart File Explorer for the change to take place.
|
||||
|
||||
Now you can generate installers after a build by running `bld/RUN BUILD.bat`. Note that despite the name, this will only package the files, you still need to run the [build](#build) in Visual Studio!
|
||||
Now you can generate installers after a build by running `bld/RUN BUILD.bat`. Note that this will only package the files, you still need to run the [release build](#release) in Visual Studio!
|
||||
|
||||
After the window closes, three installers will be generated inside the `bld/Output` folder:
|
||||
* **TweetDuck.exe**
|
||||
@@ -68,8 +62,10 @@ After the window closes, three installers will be generated inside the `bld/Outp
|
||||
* This is a portable installer that does not need administrator privileges
|
||||
* It automatically creates a `makeportable` file in the program folder, which forces TweetDuck to run in portable mode
|
||||
|
||||
Note: There is a small chance you will see a resource error when running `RUN BUILD.bat`. If that happens, close the console window (which will terminate all Inno Setup processes and leave corrupted installer files in the output folder), and run it again.
|
||||
#### Notes
|
||||
|
||||
### Code Notes
|
||||
> When opening **Batch Build**, you will also see `x64` and `AnyCPU` configurations. These are visible due to what I consider a Visual Studio bug, and will not work without significant changes to the project. Manually running the `Resources/PostCefUpdate.ps1` PowerShell script modifies the downloaded CefSharp packages, and removes the invalid configurations.
|
||||
|
||||
There are many references to the official TweetDuck website and this repository in the code and installers, so if you plan to release your own version, make sure to search for `tweetduck.chylex.com` and `github.com` in the whole repository and replace them appropriately.
|
||||
> There is a small chance running `RUN BUILD.bat` immediately shows a resource error. If that happens, close the console window (which terminates all Inno Setup processes and leaves corrupted installers in the output folder), and run it again.
|
||||
|
||||
> Running `RUN BUILD.bat` uses about 400 MB of RAM due to high compression. You can lower this to about 140 MB by opening `gen_full.iss` and `gen_port.iss`, and changing `LZMADictionarySize=15360` to `LZMADictionarySize=4096`.
|
||||
|
15
Reporter.cs
15
Reporter.cs
@@ -46,8 +46,9 @@ namespace TweetDuck{
|
||||
|
||||
public void HandleException(string caption, string message, bool canIgnore, Exception e){
|
||||
bool loggedSuccessfully = Log(e.ToString());
|
||||
|
||||
FormMessage form = new FormMessage(caption, message+"\nError: "+e.Message, canIgnore ? MessageBoxIcon.Warning : MessageBoxIcon.Error);
|
||||
|
||||
string exceptionText = e is ExpandedLogException ? e.Message+"\n\nDetails with potentially sensitive information are in the Error Log." : e.Message;
|
||||
FormMessage form = new FormMessage(caption, message+"\nError: "+exceptionText, canIgnore ? MessageBoxIcon.Warning : MessageBoxIcon.Error);
|
||||
|
||||
Button btnExit = form.AddButton(FormMessage.Exit);
|
||||
Button btnIgnore = form.AddButton(FormMessage.Ignore, DialogResult.Ignore, ControlType.Cancel);
|
||||
@@ -95,5 +96,15 @@ namespace TweetDuck{
|
||||
Environment.FailFast(message, new Exception(message));
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ExpandedLogException : Exception{
|
||||
private readonly string details;
|
||||
|
||||
public ExpandedLogException(Exception source, string details) : base(source.Message, source){
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public override string ToString() => base.ToString()+"\r\n"+details;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
Resources/..code-workspace
Normal file
20
Resources/..code-workspace
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "Installers",
|
||||
"path": "..\\bld"
|
||||
},
|
||||
{
|
||||
"name": "Resources",
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"editor.tabSize": 2,
|
||||
"javascript.validate.enable": false,
|
||||
"files.autoGuessEncoding": false,
|
||||
"files.insertFinalNewline": true,
|
||||
"files.trimFinalNewlines": true,
|
||||
"files.encoding": "utf8",
|
||||
}
|
||||
}
|
BIN
Resources/Design/app_logos_large.afdesign
Normal file
BIN
Resources/Design/app_logos_large.afdesign
Normal file
Binary file not shown.
BIN
Resources/Design/app_logos_small.afdesign
Normal file
BIN
Resources/Design/app_logos_small.afdesign
Normal file
Binary file not shown.
BIN
Resources/Design/icon_pushpin.afdesign
Normal file
BIN
Resources/Design/icon_pushpin.afdesign
Normal file
Binary file not shown.
BIN
Resources/Design/video_buttons.afdesign
Normal file
BIN
Resources/Design/video_buttons.afdesign
Normal file
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
Resources/Images/icon-muted.ico
Normal file
BIN
Resources/Images/icon-muted.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user