1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-09-14 10:32:10 +02:00

Compare commits

..

184 Commits

Author SHA1 Message Date
a951c3a7c9 Tweak Options visuals (labels, spacing, colors) & fix off-by-pixel bug on high DPI 2018-07-27 19:29:21 +02:00
b25fae54fe Update PostCefUpdate script to remove x64/AnyCPU from .targets file 2018-07-27 05:59:27 +02:00
a87bc4609e Add a cue text to Sounds tab in Options 2018-07-27 05:32:17 +02:00
3e68026949 Redesign Options to reduce amount of tabs and organize code 2018-07-27 05:12:17 +02:00
78d6d285cd Remove GDI charset from fonts in designer files 2018-07-26 20:17:53 +02:00
72e3596a3c Tweak heading font in Options and fix minor issues (tab order, overflowing text) 2018-07-26 19:37:07 +02:00
643ebcaab4 Prompt restart after profile import/reset only if an updated option requires it 2018-07-25 22:01:37 +02:00
52ef6cd95a Unify configs (backups, behavior, error handling) & make future development easier 2018-07-25 17:25:20 +02:00
4aec2f3260 Refactor FileSerializer to attempt error recovery & tweak StreamWriter usage 2018-07-25 03:38:44 +02:00
73549515eb Remove old user configuration fix 2018-07-24 06:16:52 +02:00
d83d2660cf Initial Options dialog refactoring to use an event for restart requests 2018-07-24 04:04:44 +02:00
8de913172c Minor visual fixes (old column icon alignment, TweetDeck reply triangle bug) 2018-07-23 20:14:54 +02:00
4acfd64cff Update xUnit 2018-07-23 20:13:04 +02:00
b56f90ed52 Add README instructions to fix broken MSBuild task 2018-07-23 14:20:07 +02:00
1375630727 Safeguard ResponseFilterBase in case input stream is null
Closes #234 (hopefully)
2018-07-23 12:37:57 +02:00
668825bc01 Add option to toggle touch adjustment & disable it by default
Closes #230
2018-07-23 01:36:49 +02:00
90414ae579 Release 1.15.1 2018-07-13 08:28:44 +02:00
41c8caa2a4 Make avatars in DM recipient list square 2018-07-12 15:23:01 +02:00
15305ecabe Revert TweetDeck style changes to the 'Add column' dialog
Closes #233
2018-07-12 08:37:44 +02:00
50090effd4 Refactor image/video download code and fix video download error message 2018-07-10 18:31:39 +02:00
6dffdcd1ed Add update notifications outside TweetDeck, tweak changelog styling 2018-07-10 08:50:09 +02:00
db9daf2714 Refactor update notification into a bridge object & tweak installer pre-downloading 2018-07-10 08:17:42 +02:00
502ac4ebc1 Enable high DPI awareness for video player process
Closes #232
2018-07-09 18:14:58 +02:00
3f44f3bab4 Fix notification scrolling issue by disabling threaded scrolling & latching
Closes #221
2018-07-09 17:47:20 +02:00
746eba185b Release 1.15 2018-07-09 14:06:13 +02:00
82dec92510 Fix wrong screenshot width on high DPI 2018-07-09 14:06:07 +02:00
2edc93df47 Update CefSharp to the newest build 2018-07-09 13:23:13 +02:00
c5a6738199 Fix a missing 'Clear columns' button after re-enabling the clear-columns plugin 2018-07-09 13:20:58 +02:00
dfd578165b Revert custom throttling, it is not ready due to issues w/ notifications 2018-07-09 13:04:55 +02:00
285d400f69 Refactor ScriptLoader to cache files on its own & change method signatures 2018-07-09 12:22:29 +02:00
47a3444ace Remove unnecessary styles and tweak formatting in black theme CSS 2018-07-09 10:21:44 +02:00
0ec227da52 Redesign Edit CSS dialog, add 'Open Dev Tools' button and better editor 2018-07-08 12:57:22 +02:00
f9cf582306 ... 2018-07-08 10:09:44 +02:00
b0883229bf Move HasDevTools to BrowserUtils 2018-07-08 10:06:40 +02:00
31b5d9a4c0 Protect code.js from uncaught errors & add custom 'throw if' statement 2018-07-08 09:53:42 +02:00
6841a78556 Rewrite clear-columns plugin to work w/o reload & fix broken Clear icon 2018-07-08 08:09:29 +02:00
9d2089a8ce Extract markup from introduction.js into an imported file & fix import regex 2018-07-08 06:14:33 +02:00
6d6bb79199 Massive JS formatting refactoring 2018-07-08 06:09:51 +02:00
937c8e22c4 Force UTF-8 in VS Code workspace settings 2018-07-08 05:16:31 +02:00
34c8d44dfe Project tweaks (make update installer on build, stopwatch resource swap, formatting) 2018-07-08 05:03:30 +02:00
2dbf778e56 Change the new DM limit behavior b/c older DMs don't load when scrolled to bottom 2018-07-06 22:09:09 +02:00
873fe2b393 Remove legacy HW acceleration support check & update tooltip 2018-07-06 09:37:25 +02:00
0c53bc6f32 Move icons and images to a separate folder 2018-07-06 07:26:22 +02:00
fa407e150b Add a quick way to import profile from the login page
Closes #228
2018-07-06 07:03:39 +02:00
4e52102c5c Add option for browser throttling w/ default when covered by larger window 2018-07-06 06:26:50 +02:00
0355a5c646 Add VS Code workspace file & fix some warnings 2018-07-06 06:04:10 +02:00
377d9c3554 Make an interface for dialogs to avoid hard-coding them in FormManager 2018-07-06 05:30:12 +02:00
20b1b3c895 Add more safety checks to code.js 2018-07-05 09:05:20 +02:00
41bbe7c51b Decrease amount of loaded DMs to lower performance hit from re-opening DMs 2018-07-05 07:39:26 +02:00
27fa6aefd3 Improve CSS minification 2018-07-05 06:32:45 +02:00
a63c3232da Update CefSharp to 67 (early) 2018-07-05 06:30:41 +02:00
146908a115 Include files for importing in the project to let VS detect changes 2018-07-04 17:27:49 +02:00
48b0f35fee Move template plugin HTML and CSS into a separate file 2018-07-04 17:24:32 +02:00
6c435ebe26 Extract styles from update.js into an imported CSS file 2018-07-04 07:03:48 +02:00
b8d0b721a2 Extract styles from introduction.js into an imported CSS file 2018-07-04 07:00:47 +02:00
a6d5957f46 Extract styles from twitter.js into imported CSS files 2018-07-04 06:55:10 +02:00
9e5f676e23 Move imported files into structured folder for easier handling & tweak syntax 2018-07-04 06:53:31 +02:00
414f3a1f9d Import shared plugin setup code into individual environment files 2018-07-04 06:26:41 +02:00
fedf9c60ee Hack up a simple import system in the build process 2018-07-04 06:25:22 +02:00
b6385d9622 Change unit test namespaces 2018-07-04 03:07:45 +02:00
76d25a712d Move old IO test project in preparation for future refactoring 2018-07-04 03:07:15 +02:00
2c6d935273 Rewrite unit tests for CommandLineArgs into xUnit 2018-07-04 02:45:11 +02:00
830d98a101 Rewrite unit tests for TwoKeyDictionary into xUnit 2018-07-03 21:23:34 +02:00
d7378bd75a Add leading slashes to URL strings in RequestHandlerBrowser 2018-07-02 20:32:23 +02:00
0f41cb9dbc Add response filter to restore global jQuery & unfreeze TweetDeck resources 2018-07-02 20:27:54 +02:00
77bc922d93 Add base class for response filters to safely modify intercepted files 2018-07-02 19:57:24 +02:00
c91b635132 Fix TDPF_createCustomStyle's remove function depending on jQuery 2018-07-01 16:51:57 +02:00
e5521de34a Split icon design files & update 256x256 icon 2018-07-01 15:45:33 +02:00
7c0f8d0f24 Remove temporarily forced update checking 2018-07-01 03:10:47 +02:00
f60d5f650f Add new program and tray icons to show when notifications are muted 2018-06-30 21:28:41 +02:00
ca67f2fe0a Redo app icon background as vector & update all icons 2018-06-30 19:39:16 +02:00
16cce8be1d Remove unnecessary code for disabling TweetDeck update notification 2018-06-30 15:02:46 +02:00
770619d948 Make update notification work without jQuery & optimize slide animation 2018-06-30 14:30:45 +02:00
cfedb7d6b1 Improve logged error message when update checking fails 2018-06-30 13:22:37 +02:00
738557b3a2 Add exception type that adds (potentially sensitive) details to error log 2018-06-30 13:20:25 +02:00
38b01deec1 Make it easier to freeze TweetDeck resources in the future 2018-06-30 11:49:46 +02:00
1a31e69ec9 Release 1.14.4.1 2018-06-29 19:56:00 +02:00
e065983c95 Delay the apocalypse (freeze TweetDeck JS resources, force update checking) 2018-06-29 19:41:02 +02:00
30a169171a Apparently deserializing @TryMyAwesomeApp sometimes causes a hidden crash 2018-06-29 17:10:11 +02:00
8d1900362e Update PostCefUpdate script to remove invalid build configurations (x64, AnyCPU) 2018-06-29 17:05:53 +02:00
e154189de1 Cleanup TweetDuck.csproj and fix names in TestResult unit test 2018-06-28 14:06:03 +02:00
b0f147de24 Fix misaligned 'Add column' icons when using old icon design 2018-06-28 08:10:48 +02:00
979b3548db Release 1.14.4 2018-06-28 07:54:38 +02:00
05d6c578b3 Move InjectedHTML unit tests to xUnit and rename Inject method 2018-06-26 11:19:44 +02:00
a117559063 Minor formatting tweaks 2018-06-26 10:05:53 +02:00
f87c649b09 Fix Twitter experiment causing crash in notifications and subsequent render corruption 2018-06-26 09:49:37 +02:00
6504dc9184 Add unit tests for Result and a few utility methods & fix edge case in StringUtils 2018-06-24 21:41:02 +02:00
25a8ddffd4 Rewrite and tweak existing Core namespace unit tests into xUnit 2018-06-24 19:29:24 +02:00
fa0f9b89cf Remove 'Release' configuration from UnitTests project 2018-06-24 16:16:11 +02:00
4d00a67891 Add a new F# xUnit test project 2018-06-24 16:09:21 +02:00
bd2c43e1f4 Fix analytics not counting applying ROT13 on non-editable text 2018-06-19 21:35:35 +02:00
c7279eaa34 Fix bug with falsely detecting symlinks in plugins if a file/folder doesn't exist 2018-06-19 21:32:21 +02:00
fd523e552c Symlinks/junctions in plugin folders can go to hell 2018-06-13 22:20:10 +02:00
cb877b8b23 Fix broken desktop notifications for retweets with sensitive media 2018-06-10 23:53:01 +02:00
ed1bee8b89 Release 1.14.3 2018-06-10 20:13:05 +02:00
a8e1492056 Push pin icon to the repository 2018-06-08 10:16:58 +02:00
5587216c01 Fix one more case of breaking overlays (account dialog) 2018-06-07 17:48:52 +02:00
86569261ad Add a visual response when hovering filter icons under column header 2018-06-07 14:52:39 +02:00
4a9049c7aa Fix CSS change in dialog overlays breaking some cases 2018-06-07 14:09:35 +02:00
75d60a8182 Work around browser redirection when dragging links into a scrolling column 2018-06-07 13:23:19 +02:00
14d4dc2ed9 Fix more instances of cut off badges 2018-06-06 16:04:15 +02:00
fd0e1740a5 Rename SetLastRightClickInfo bridge method and make it browser-only 2018-06-06 15:11:07 +02:00
70ca890bef Fix not stripping t.co in notifications when dragging & sometimes when copying 2018-06-06 15:10:52 +02:00
b9318dfd8e Minor visual fixes (Edit List modal, set minimum column width) 2018-06-05 04:25:05 +02:00
995642a719 Add support for 1 or 2 columns on screen in edit-design plugin 2018-06-05 03:48:40 +02:00
d14de4ac9e Lower minimum width of browser window & fix modals breaking in small windows 2018-06-05 02:51:21 +02:00
b7f325a241 Minor RequestHandlerBase refactoring 2018-06-05 02:05:04 +02:00
27c55718c2 Release 1.14.2.1 2018-06-04 13:01:44 +02:00
421ff0654b Temporarily work around buggy notification scrolling 2018-06-04 12:35:34 +02:00
ed947458f9 Update fallback HTML in desktop notifications 2018-06-04 12:09:02 +02:00
9cdb20ba84 Fix several broken column types in 'Add column' modal 2018-06-04 11:02:52 +02:00
d8774b735f Release 1.14.2 2018-06-04 08:59:32 +02:00
adcb42695f Update CEF so I don't have to workaround wrong dev tools version
Closes #220
2018-06-01 22:32:44 +02:00
dd77b5bcbb Revert smooth scrolling fix and rewrite horizontal scrolling fix to avoid column jumping 2018-06-01 21:48:26 +02:00
d2445be155 Fix missing GIF previews in tweet screenshots 2018-05-31 03:07:51 +02:00
10254c8af7 Fix tweet screenshots with Aero disabled by making the window visible
Closes #223
2018-05-31 02:58:25 +02:00
d7e830badf Slightly increase default notification height for larger font sizes 2018-05-31 01:11:17 +02:00
b445a3a9b8 Fix broken reply-account advanced selector arguments after a TweetDeck update 2018-05-31 00:52:08 +02:00
97f42ead66 Make it easier to debug screenshots 2018-05-30 19:50:11 +02:00
03730fafb9 ...because I can't be bothered 2018-05-29 15:34:02 +02:00
0be9465dca Fix column icons being hidden by title with clear-columns or edit-design features on 2018-05-29 15:23:41 +02:00
d7f1df4995 Release 1.14.1 2018-05-16 13:07:47 +02:00
3cb0f90706 Prevent an unlikely crash when showing an error message in context menu 2018-05-16 13:05:59 +02:00
a3e9b15a8a Add 'Apply ROT13' to non-editable selections to allow decoding tweets 2018-05-16 12:40:49 +02:00
00bfa68a57 Fix UI issues after recent TweetDeck updates 2018-05-16 07:48:47 +02:00
c311e24f08 Make it easier to update devtools file after updating CEF 2018-05-15 12:42:57 +02:00
1cdd4e4455 Update CefSharp to 66 (early) to fix memory leak 2018-05-15 10:10:03 +02:00
8078c0081a Add a script to fix browser project references after updating CEF 2018-05-15 10:04:08 +02:00
a867e1fc40 Optimize speed and memory usage of build process for app & installers 2018-05-08 20:20:02 +02:00
61da36ac1c Update README.md 2018-05-08 19:37:06 +02:00
720ca2a018 Update README.md 2018-05-08 19:36:08 +02:00
b39c593552 Update README.md 2018-05-08 06:28:07 +02:00
c808952a45 Update README.md 2018-05-08 00:03:08 +02:00
b468d7a766 Update README.md 2018-05-07 20:03:50 +02:00
28578f60be Include plugin files in the project & update README 2018-05-07 19:35:08 +02:00
92a39e2527 Push debug configuration start arguments (-datafolder TweetDuckDebug) 2018-05-07 18:11:56 +02:00
1bce5e4342 Release 1.14 2018-05-07 17:28:34 +02:00
68f586e104 Fix wrong info in the analytics dialog 2018-05-07 15:42:41 +02:00
d27a66202e Remove "Show this thread" in quoted tweets from notifications and screenshots 2018-05-07 03:01:24 +02:00
07de2f450c Fix broken notification scrolling in CEF 65 properly 2018-05-07 02:43:40 +02:00
3c03726634 Remove old and no longer necessary code from update installer 2018-05-06 22:47:58 +02:00
6fb2643063 Slightly increase installer compression level 2018-05-06 22:24:55 +02:00
5eef6c8196 Kill stubborn app processes when installing updates 2018-05-06 21:18:23 +02:00
829c332e13 Add a global function for mustache injection & fix broken clear-columns mustache 2018-05-05 11:47:19 +02:00
47eec14bca Fix freshly broken GIF previews in notifications 2018-05-04 21:07:33 +02:00
e7ee1d6be7 Revert "Fix broken notification scrolling in CEF 65"
This reverts commit 1029ea5840.
2018-05-04 14:00:41 +02:00
e41b5e5ff7 Replace generated license files with just one and include CEF license 2018-05-04 13:30:54 +02:00
ba1bacd08c Fix minor formatting and method modifier issues 2018-05-04 13:04:23 +02:00
1029ea5840 Fix broken notification scrolling in CEF 65 2018-05-04 11:41:20 +02:00
339eaf0195 Fix button appearance in introduction dialog and some plugins 2018-05-03 16:02:44 +02:00
aa1e1549d8 Fix Twitter's broken Cancel button when logging out 2018-05-03 15:04:09 +02:00
1f8ae9ef80 Update CefSharp to 65 (pre01) and fix blank example notification
* Update CefSharp to 65 (pre01)

* Fix blank example notification on first load
2018-05-03 14:05:56 +02:00
65165de060 Release 1.13.6 2018-05-02 16:27:23 +02:00
485836d2ce Replace about:blank in FormGuide with a dummy page 2018-05-02 15:21:23 +02:00
64c07c14d9 Revert "Update to CefSharp 65 (early) (#215)"
This reverts commit b6a599f8a6.
2018-05-02 15:19:01 +02:00
b6313c2b72 Update CefSharp to 65 (pre01) 2018-05-02 00:05:08 +02:00
58124b5821 Force Chrome UA on TweetDeck and remove -chromeagent argument 2018-05-01 19:31:39 +02:00
b6a599f8a6 Update to CefSharp 65 (early) (#215) 2018-05-01 19:20:13 +02:00
19a6bc0dbd Improve performance of PostBuild.ps1 2018-05-01 16:37:06 +02:00
8cb81d44ee Fix update installer changing uninstaller name and remove /MERGETASKS parameter 2018-05-01 14:36:51 +02:00
22d0a372d8 Add dev tools to the installer as an optional component 2018-05-01 14:30:56 +02:00
988fae75c3 Add a command line argument to use Chrome user agent 2018-04-30 21:02:15 +02:00
a82b0e3622 Release 1.13.5 2018-04-29 20:55:33 +02:00
bc6cacacf9 Fix portable install not recognizing itself after importing login session 2018-04-29 19:00:17 +02:00
03ad1b3cbc Update instructions for reply-account plugin and TDPF_getColumnName 2018-04-29 14:29:33 +02:00
eac300627f Fix broken column names again and make getColumnName accessible to plugins 2018-04-29 13:17:00 +02:00
12525ac386 Fix screenshots with zoom & try to fix rendering issues 2018-04-28 20:36:49 +02:00
7558551859 Add a debug flag to generate individual screenshot frames 2018-04-28 18:15:25 +02:00
a9cce13eef Fix visual inconsistencies with new icons 2018-04-28 15:34:15 +02:00
5bb2c43dd0 Fix edit-design plugin not loading when enabled after a restart 2018-04-28 15:22:55 +02:00
5b1dcc88cc Make Plugins form always show Configure button when configurable 2018-04-28 15:19:58 +02:00
5c8fc1d136 Fix clear-columns plugin button disappearing when adding/removing columns 2018-04-27 21:13:38 +02:00
82c2ab3448 Fix broken smooth and horizontal scrolling after a TweetDeck update 2018-04-27 19:33:32 +02:00
b05c8d180f Remove UpdaterSettings and fix not restarting the timer after a dismissed update 2018-04-27 19:21:42 +02:00
87109e5d01 Fix a few visual issues with high DPI 2018-04-27 18:29:02 +02:00
be1a809098 Update all forms and dialogs to use the 'Segoe UI' font 2018-04-27 18:06:45 +02:00
ba0e3f1bd4 Continue redesign of Plugins form (tweak visuals, position, and size limits) 2018-04-27 14:59:36 +02:00
27d41e6164 Begin redesign of the Plugins form (layout reorganization, fixes, optimization) 2018-04-27 13:47:29 +02:00
1ce5ddfd98 Rewrite names and descriptions of plugins & update debug plugin 2018-04-26 21:54:40 +02:00
0096a1a4ef Move debug configuration build events to PostBuild script 2018-04-26 15:37:02 +02:00
d2a6560a90 Measure PostBuild script duration and fix formatting 2018-04-25 19:35:57 +02:00
4d7c048139 Remove versions from official plugins and make them only work on one app version 2018-04-25 19:35:04 +02:00
1d78bd2655 Release 1.13.4.1 2018-04-24 18:16:13 +02:00
9250f1907c Quick semi-temporary fix for removed column.isOfType 2018-04-24 18:10:22 +02:00
184 changed files with 6162 additions and 4094 deletions

View File

@@ -6,6 +6,7 @@ namespace TweetDuck.Configuration{
// public args
public const string ArgDataFolder = "-datafolder";
public const string ArgLogging = "-log";
public const string ArgIgnoreGDPR = "-nogdpr";
// internal args
public const string ArgRestart = "-restart";

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using TweetDuck.Configuration.Instance;
using TweetDuck.Core.Utils;
using TweetDuck.Data;
using TweetDuck.Data.Serialization;
namespace TweetDuck.Configuration{
sealed class ConfigManager{
public UserConfig User { get; }
public SystemConfig System { get; }
public event EventHandler ProgramRestartRequested;
private readonly FileConfigInstance<UserConfig> infoUser;
private readonly FileConfigInstance<SystemConfig> infoSystem;
private readonly IConfigInstance<BaseConfig>[] infoList;
public ConfigManager(){
User = new UserConfig(this);
System = new SystemConfig(this);
infoList = new IConfigInstance<BaseConfig>[]{
infoUser = new FileConfigInstance<UserConfig>(Program.UserConfigFilePath, User, "program options"),
infoSystem = new FileConfigInstance<SystemConfig>(Program.SystemConfigFilePath, System, "system options")
};
// TODO refactor further
infoUser.Serializer.RegisterTypeConverter(typeof(WindowState), WindowState.Converter);
infoUser.Serializer.RegisterTypeConverter(typeof(Point), new SingleTypeConverter<Point>{
ConvertToString = value => $"{value.X} {value.Y}",
ConvertToObject = value => {
int[] elements = StringUtils.ParseInts(value, ' ');
return new Point(elements[0], elements[1]);
}
});
infoUser.Serializer.RegisterTypeConverter(typeof(Size), new SingleTypeConverter<Size>{
ConvertToString = value => $"{value.Width} {value.Height}",
ConvertToObject = value => {
int[] elements = StringUtils.ParseInts(value, ' ');
return new Size(elements[0], elements[1]);
}
});
}
public void LoadAll(){
infoUser.Load();
infoSystem.Load();
}
public void SaveAll(){
infoUser.Save();
infoSystem.Save();
}
public void ReloadAll(){
infoUser.Reload();
infoSystem.Reload();
}
private void TriggerProgramRestartRequested(){
ProgramRestartRequested?.Invoke(this, EventArgs.Empty);
}
private IConfigInstance<BaseConfig> GetInstanceInfo(BaseConfig instance){
Type instanceType = instance.GetType();
return Array.Find(infoList, info => info.Instance.GetType() == instanceType); // TODO handle null
}
public abstract class BaseConfig{
private readonly ConfigManager configManager;
protected BaseConfig(ConfigManager configManager){
this.configManager = configManager;
}
// Management
public void Save(){
configManager.GetInstanceInfo(this).Save();
}
public void Reload(){
configManager.GetInstanceInfo(this).Reload();
}
public void Reset(){
configManager.GetInstanceInfo(this).Reset();
}
// Construction methods
public T ConstructWithDefaults<T>() where T : BaseConfig{
return ConstructWithDefaults(configManager) as T;
}
protected abstract BaseConfig ConstructWithDefaults(ConfigManager configManager);
// Utility methods
protected void UpdatePropertyWithEvent<T>(ref T field, T value, EventHandler eventHandler){
if (!EqualityComparer<T>.Default.Equals(field, value)){
field = value;
eventHandler?.Invoke(this, EventArgs.Empty);
}
}
protected void UpdatePropertyWithRestartRequest<T>(ref T field, T value){
if (!EqualityComparer<T>.Default.Equals(field, value)){
field = value;
configManager.TriggerProgramRestartRequested();
}
}
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using System.IO;
using TweetDuck.Data.Serialization;
namespace TweetDuck.Configuration.Instance{
sealed class FileConfigInstance<T> : IConfigInstance<T> where T : ConfigManager.BaseConfig{
private const string ErrorTitle = "Configuration Error";
public T Instance { get; }
public FileSerializer<T> Serializer { get; }
private readonly string filenameMain;
private readonly string filenameBackup;
private readonly string errorIdentifier;
public FileConfigInstance(string filename, T instance, string errorIdentifier){
this.filenameMain = filename;
this.filenameBackup = filename+".bak";
this.errorIdentifier = errorIdentifier;
this.Instance = instance;
this.Serializer = new FileSerializer<T>();
}
private void LoadInternal(bool backup){
Serializer.Read(backup ? filenameBackup : filenameMain, Instance);
}
public void Load(){
Exception firstException = null;
for(int attempt = 0; attempt < 2; attempt++){
try{
LoadInternal(attempt > 0);
if (firstException != null){ // silently log exception that caused a backup restore
Program.Reporter.Log(firstException.ToString());
}
return;
}catch(FileNotFoundException){
}catch(DirectoryNotFoundException){
break;
}catch(Exception e){
if (firstException == null){
firstException = e;
}
}
}
if (firstException is FormatException){
Program.Reporter.HandleException(ErrorTitle, "The configuration file for "+errorIdentifier+" is outdated or corrupted. If you continue, your "+errorIdentifier+" will be reset.", true, firstException);
}
else if (firstException is SerializationSoftException sse){
Program.Reporter.HandleException(ErrorTitle, $"{sse.Errors.Count} error{(sse.Errors.Count == 1 ? " was" : "s were")} encountered while loading the configuration file for "+errorIdentifier+". If you continue, some of your "+errorIdentifier+" will be reset.", true, firstException);
}
else if (firstException != null){
Program.Reporter.HandleException(ErrorTitle, "Could not open the configuration file for "+errorIdentifier+". If you continue, your "+errorIdentifier+" will be reset.", true, firstException);
}
}
public void Save(){
try{
if (File.Exists(filenameMain)){
File.Delete(filenameBackup);
File.Move(filenameMain, filenameBackup);
}
Serializer.Write(filenameMain, Instance);
}catch(SerializationSoftException e){
Program.Reporter.HandleException(ErrorTitle, $"{e.Errors.Count} error{(e.Errors.Count == 1 ? " was" : "s were")} encountered while saving the configuration file for "+errorIdentifier+".", true, e);
}catch(Exception e){
Program.Reporter.HandleException(ErrorTitle, "Could not save the configuration file for "+errorIdentifier+".", true, e);
}
}
public void Reload(){
try{
LoadInternal(false);
}catch(FileNotFoundException){
try{
Serializer.Write(filenameMain, Instance.ConstructWithDefaults<T>());
LoadInternal(false);
}catch(Exception e){
Program.Reporter.HandleException(ErrorTitle, "Could not regenerate the configuration file for "+errorIdentifier+".", true, e);
}
}catch(Exception e){
Program.Reporter.HandleException(ErrorTitle, "Could not reload the configuration file for "+errorIdentifier+".", true, e);
}
}
public void Reset(){
try{
File.Delete(filenameMain);
File.Delete(filenameBackup);
}catch(Exception e){
Program.Reporter.HandleException(ErrorTitle, "Could not delete configuration files to reset "+errorIdentifier+".", true, e);
return;
}
Reload();
}
}
}

View File

@@ -0,0 +1,9 @@
namespace TweetDuck.Configuration.Instance{
interface IConfigInstance<out T>{
T Instance { get; }
void Save();
void Reload();
void Reset();
}
}

View File

@@ -1,54 +1,26 @@
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"));
namespace TweetDuck.Configuration{
sealed class SystemConfig : ConfigManager.BaseConfig{
// CONFIGURATION DATA
private bool _hardwareAcceleration = true;
public bool _hardwareAcceleration = true;
public bool ClearCacheAutomatically { get; set; } = true;
public int ClearCacheThreshold { get; set; } = 250;
// SPECIAL PROPERTIES
public bool HardwareAcceleration{
get => _hardwareAcceleration && IsHardwareAccelerationSupported;
set => _hardwareAcceleration = value;
get => _hardwareAcceleration;
set => UpdatePropertyWithRestartRequest(ref _hardwareAcceleration, value);
}
// END OF CONFIG
private readonly string file;
private SystemConfig(string file){
this.file = file;
}
public SystemConfig(ConfigManager configManager) : base(configManager){}
public void Save(){
try{
Serializer.Write(file, this);
}catch(Exception e){
Program.Reporter.HandleException("Configuration Error", "Could not save the system configuration file.", true, e);
}
}
public static SystemConfig Load(string file){
SystemConfig config = new SystemConfig(file);
try{
Serializer.ReadIfExists(file, config);
}catch(Exception e){
Program.Reporter.HandleException("Configuration Error", "Could not open the system configuration file. If you continue, you will lose system specific configuration such as Hardware Acceleration.", true, e);
}
return config;
protected override ConfigManager.BaseConfig ConstructWithDefaults(ConfigManager configManager){
return new SystemConfig(configManager);
}
}
}

View File

@@ -1,37 +1,13 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using TweetDuck.Core.Controls;
using TweetDuck.Core.Notification;
using TweetDuck.Core.Other;
using TweetDuck.Core.Utils;
using TweetDuck.Data;
using TweetDuck.Data.Serialization;
namespace TweetDuck.Configuration{
sealed class UserConfig{
private static readonly FileSerializer<UserConfig> Serializer = new FileSerializer<UserConfig>();
static UserConfig(){
Serializer.RegisterTypeConverter(typeof(WindowState), WindowState.Converter);
Serializer.RegisterTypeConverter(typeof(Point), new SingleTypeConverter<Point>{
ConvertToString = value => $"{value.X} {value.Y}",
ConvertToObject = value => {
int[] elements = StringUtils.ParseInts(value, ' ');
return new Point(elements[0], elements[1]);
}
});
Serializer.RegisterTypeConverter(typeof(Size), new SingleTypeConverter<Size>{
ConvertToString = value => $"{value.Width} {value.Height}",
ConvertToObject = value => {
int[] elements = StringUtils.ParseInts(value, ' ');
return new Size(elements[0], elements[1]);
}
});
}
sealed class UserConfig : ConfigManager.BaseConfig{
// CONFIGURATION DATA
@@ -39,7 +15,7 @@ namespace TweetDuck.Configuration{
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 OpenSearchInFirstColumn { get; set; } = true;
@@ -47,18 +23,21 @@ namespace TweetDuck.Configuration{
public bool BestImageQuality { get; set; } = true;
public bool EnableAnimatedImages { get; set; } = true;
public bool IgnoreTrackingUrlWarning { get; set; } = false;
public bool EnableSmoothScrolling { get; set; } = true;
public bool _enableSmoothScrolling = true;
public bool _enableTouchAdjustment = false;
public string _customCefArgs = null;
public string BrowserPath { get; set; } = null;
public bool IgnoreTrackingUrlWarning { get; set; } = false;
public string SearchEngineUrl { get; set; } = null;
private int _zoomLevel = 100;
private bool _muteNotifications;
public int VideoPlayerVolume { get; set; } = 50;
public bool EnableSpellCheck { get; set; } = false;
public string SpellCheckLanguage { get; set; } = "en-US";
public string TranslationTarget { get; set; } = "en";
public bool EnableSpellCheck { get; set; } = false;
private string _spellCheckLanguage = "en-US";
public string TranslationTarget { get; set; } = "en";
private TrayIcon.Behavior _trayBehavior = TrayIcon.Behavior.Disabled;
public bool EnableTrayHighlight { get; set; } = true;
@@ -72,9 +51,9 @@ namespace TweetDuck.Configuration{
public bool NotificationNonIntrusiveMode { get; set; } = true;
public int NotificationIdlePauseSeconds { get; set; } = 0;
public bool DisplayNotificationTimer { get; set; } = true;
public bool NotificationTimerCountDown { get; set; } = false;
public int NotificationDurationValue { get; set; } = 25;
public bool DisplayNotificationTimer { get; set; } = true;
public bool NotificationTimerCountDown { get; set; } = false;
public int NotificationDurationValue { get; set; } = 25;
public TweetNotification.Position NotificationPosition { get; set; } = TweetNotification.Position.TopRight;
public Point CustomNotificationPosition { get; set; } = ControlExtensions.InvisibleLocation;
@@ -84,11 +63,12 @@ namespace TweetDuck.Configuration{
public TweetNotification.Size NotificationSize { get; set; } = TweetNotification.Size.Auto;
public Size CustomNotificationSize { get; set; } = Size.Empty;
public int NotificationScrollSpeed { get; set; } = 100;
private string _notificationSoundPath;
private int _notificationSoundVolume = 100;
public string CustomCefArgs { get; set; } = null;
private bool _muteNotifications;
public string CustomBrowserCSS { get; set; } = null;
public string CustomNotificationCSS { get; set; } = null;
@@ -124,6 +104,26 @@ namespace TweetDuck.Configuration{
get => _trayBehavior;
set => UpdatePropertyWithEvent(ref _trayBehavior, value, TrayBehaviorChanged);
}
public bool EnableSmoothScrolling{
get => _enableSmoothScrolling;
set => UpdatePropertyWithRestartRequest(ref _enableSmoothScrolling, value);
}
public bool EnableTouchAdjustment{
get => _enableTouchAdjustment;
set => UpdatePropertyWithRestartRequest(ref _enableTouchAdjustment, value);
}
public string CustomCefArgs{
get => _customCefArgs;
set => UpdatePropertyWithRestartRequest(ref _customCefArgs, value);
}
public string SpellCheckLanguage{
get => _spellCheckLanguage;
set => UpdatePropertyWithRestartRequest(ref _spellCheckLanguage, value);
}
// EVENTS
@@ -134,105 +134,10 @@ namespace TweetDuck.Configuration{
// END OF CONFIG
private readonly string file;
public UserConfig(ConfigManager configManager) : base(configManager){}
private UserConfig(string file){
this.file = file;
}
private void UpdatePropertyWithEvent<T>(ref T field, T value, EventHandler eventHandler){
if (!EqualityComparer<T>.Default.Equals(field, value)){
field = value;
eventHandler?.Invoke(this, EventArgs.Empty);
}
}
public void Save(){
try{
if (File.Exists(file)){
string backupFile = GetBackupFile(file);
File.Delete(backupFile);
File.Move(file, backupFile);
}
Serializer.Write(file, this);
}catch(Exception e){
Program.Reporter.HandleException("Configuration Error", "Could not save the configuration file.", true, e);
}
}
public void Reload(){
try{
LoadInternal(false);
}catch(FileNotFoundException){
try{
Serializer.Write(file, new UserConfig(file));
LoadInternal(false);
}catch(Exception e){
Program.Reporter.HandleException("Configuration Error", "Could not regenerate configuration file.", true, e);
}
}catch(Exception e){
Program.Reporter.HandleException("Configuration Error", "Could not reload configuration file.", true, e);
}
}
public void Reset(){
try{
File.Delete(file);
File.Delete(GetBackupFile(file));
}catch(Exception e){
Program.Reporter.HandleException("Configuration Error", "Could not delete configuration files to reset the options.", true, e);
return;
}
Reload();
}
private void LoadInternal(bool backup){
Serializer.Read(backup ? GetBackupFile(file) : file, this);
if (NotificationScrollSpeed == 10){ // incorrect initial value
NotificationScrollSpeed = 100;
Save();
}
}
public static UserConfig Load(string file){
Exception firstException = null;
for(int attempt = 0; attempt < 2; attempt++){
try{
UserConfig config = new UserConfig(file);
config.LoadInternal(attempt > 0);
return config;
}catch(FileNotFoundException){
}catch(DirectoryNotFoundException){
break;
}catch(Exception e){
if (attempt == 0){
firstException = e;
Program.Reporter.Log(e.ToString());
}
else if (firstException is FormatException){
Program.Reporter.HandleException("Configuration Error", "The configuration file is outdated or corrupted. If you continue, your program options will be reset.", true, e);
return new UserConfig(file);
}
else if (firstException != null){
Program.Reporter.HandleException("Configuration Error", "Could not open the backup configuration file. If you continue, your program options will be reset.", true, e);
return new UserConfig(file);
}
}
}
if (firstException != null){
Program.Reporter.HandleException("Configuration Error", "Could not open the configuration file.", true, firstException);
}
return new UserConfig(file);
}
public static string GetBackupFile(string file){
return file+".bak";
protected override ConfigManager.BaseConfig ConstructWithDefaults(ConfigManager configManager){
return new UserConfig(configManager);
}
}
}

View File

@@ -50,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(() => {
@@ -64,6 +68,10 @@ namespace TweetDuck.Core.Bridge{
});
}
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);
}
@@ -99,10 +107,6 @@ namespace TweetDuck.Core.Bridge{
// Global
public void SetLastRightClickInfo(string type, string url){
ContextInfo.SetLink(type, url);
}
public void OnTweetPopup(string columnId, string chirpId, string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){
notification.InvokeAsyncSafe(() => {
form.OnTweetNotification();

View File

@@ -0,0 +1,68 @@
using System;
using System.Windows.Forms;
using TweetDuck.Core.Controls;
using TweetDuck.Updates;
namespace TweetDuck.Core.Bridge{
class UpdateBridge{
private readonly UpdateHandler updates;
private readonly Control sync;
private UpdateInfo nextUpdate = null;
public event EventHandler<UpdateInfo> UpdateAccepted;
public event EventHandler<UpdateInfo> UpdateDelayed;
public event EventHandler<UpdateInfo> UpdateDismissed;
public UpdateBridge(UpdateHandler updates, Control sync){
this.sync = sync;
this.updates = updates;
this.updates.CheckFinished += updates_CheckFinished;
}
internal void Cleanup(){
updates.CheckFinished -= updates_CheckFinished;
nextUpdate?.DeleteInstaller();
}
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
UpdateInfo foundUpdate = e.Result.HasValue ? e.Result.Value : null;
if (nextUpdate != null && !nextUpdate.Equals(foundUpdate)){
nextUpdate.DeleteInstaller();
}
nextUpdate = foundUpdate;
}
private void HandleInteractionEvent(EventHandler<UpdateInfo> eventHandler){
UpdateInfo tmpInfo = nextUpdate;
if (tmpInfo != null){
sync.InvokeAsyncSafe(() => eventHandler?.Invoke(this, tmpInfo));
}
}
// Bridge methods
public void TriggerUpdateCheck(){
updates.Check(false);
}
public void OnUpdateAccepted(){
HandleInteractionEvent(UpdateAccepted);
}
public void OnUpdateDelayed(){
HandleInteractionEvent(UpdateDelayed);
}
public void OnUpdateDismissed(){
HandleInteractionEvent(UpdateDismissed);
nextUpdate?.DeleteInstaller();
nextUpdate = null;
}
}
}

View File

@@ -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){

View File

@@ -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);

View File

@@ -5,17 +5,18 @@ 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, AnalyticsFile.IProvider{
@@ -48,6 +49,7 @@ namespace TweetDuck.Core{
private readonly UpdateHandler updates;
private readonly FormNotificationTweet notification;
private readonly ContextMenu contextMenu;
private readonly UpdateBridge updateBridge;
private bool isLoaded;
private FormWindowState prevState;
@@ -56,11 +58,11 @@ namespace TweetDuck.Core{
private VideoPlayer videoPlayer;
private AnalyticsManager analytics;
public FormBrowser(UpdaterSettings updaterSettings){
public FormBrowser(){
InitializeComponent();
Text = Program.BrandName;
this.plugins = new PluginManager(Program.PluginPath, Program.PluginConfigFilePath);
this.plugins.Reloaded += plugins_Reloaded;
this.plugins.Executed += plugins_Executed;
@@ -69,10 +71,18 @@ namespace TweetDuck.Core{
this.notification = new FormNotificationTweet(this, plugins);
this.notification.Show();
this.browser = new TweetDeckBrowser(this, new TweetDeckBridge.Browser(this, notification));
this.updates = new UpdateHandler(Program.InstallerPath);
this.updates.CheckFinished += updates_CheckFinished;
this.updateBridge = new UpdateBridge(updates, this);
this.updateBridge.UpdateAccepted += updateBridge_UpdateAccepted;
this.updateBridge.UpdateDelayed += updateBridge_UpdateDelayed;
this.updateBridge.UpdateDismissed += updateBridge_UpdateDismissed;
this.browser = new TweetDeckBrowser(this, new TweetDeckBridge.Browser(this, notification), updateBridge);
this.contextMenu = ContextMenuBrowser.CreateMenu(this);
this.plugins.Register(browser, PluginEnvironment.Browser, true);
this.plugins.Register(browser, PluginEnvironment.Browser, this, true);
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
@@ -95,12 +105,11 @@ namespace TweetDuck.Core{
this.trayIcon.ClickClose += trayIcon_ClickClose;
Config.TrayBehaviorChanged += Config_TrayBehaviorChanged;
UpdateTrayIcon();
UpdateTray();
this.updates = new UpdateHandler(browser, updaterSettings);
this.updates.CheckFinished += updates_CheckFinished;
this.updates.UpdateAccepted += updates_UpdateAccepted;
this.updates.UpdateDismissed += updates_UpdateDismissed;
if (Config.MuteNotifications){
UpdateFormIcon();
}
if (Config.AllowDataCollection){
analytics = new AnalyticsManager(this, plugins, Program.AnalyticsFilePath);
@@ -127,7 +136,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();
}
@@ -197,23 +210,24 @@ namespace TweetDuck.Core{
private void FormBrowser_FormClosed(object sender, FormClosedEventArgs e){
if (isLoaded && UpdateInstallerPath == null){
updates.CleanupDownload();
updateBridge.Cleanup();
}
}
private void Config_MuteToggled(object sender, EventArgs e){
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){
@@ -237,59 +251,81 @@ namespace TweetDuck.Core{
}
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
this.InvokeAsyncSafe(() => {
e.Result.Handle(update => {
if (!update.IsUpdateDismissed){
if (update.IsUpdateNew){
browser.ShowUpdateNotification(update.VersionTag, 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;
});
}
e.Result.Handle(update => {
string tag = update.VersionTag;
private void updates_UpdateAccepted(object sender, UpdateEventArgs e){
this.InvokeAsyncSafe(() => {
FormManager.CloseAllDialogs();
if (!string.IsNullOrEmpty(Config.DismissedUpdate)){
Config.DismissedUpdate = null;
Config.Save();
if (tag != Program.VersionTag && tag != Config.DismissedUpdate){
update.BeginSilentDownload();
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();
}
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();
}
});
});
ignoreUpdateCheckError = true;
}
private void updates_UpdateDismissed(object sender, UpdateEventArgs e){
this.InvokeAsyncSafe(() => {
Config.DismissedUpdate = e.UpdateInfo.VersionTag;
private void updateBridge_UpdateAccepted(object sender, UpdateInfo update){
FormManager.CloseAllDialogs();
if (!string.IsNullOrEmpty(Config.DismissedUpdate)){
Config.DismissedUpdate = null;
Config.Save();
});
}
void OnFinished(){
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();
}
}
if (update.DownloadStatus.IsFinished(true)){
OnFinished();
}
else{
FormUpdateDownload downloadForm = new FormUpdateDownload(update);
downloadForm.VisibleChanged += (sender2, args2) => {
downloadForm.MoveToCenter(this);
Hide();
};
downloadForm.FormClosed += (sender2, args2) => {
if (downloadForm.DialogResult != DialogResult.OK){
update.CancelDownload();
}
downloadForm.Dispose();
OnFinished();
};
downloadForm.Show();
}
}
private void updateBridge_UpdateDelayed(object sender, UpdateInfo update){
// stops the timer
}
private void updateBridge_UpdateDismissed(object sender, UpdateInfo update){
Config.DismissedUpdate = update.VersionTag;
Config.Save();
}
protected override void WndProc(ref Message m){
@@ -361,6 +397,10 @@ namespace TweetDuck.Core{
AnalyticsFile.UsedROT13.Trigger();
}
public void OpenDevTools(){
browser.OpenDevTools();
}
// callback handlers
public void OnIntroductionClosed(bool showGuide, bool allowDataCollection){
@@ -386,13 +426,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;
@@ -448,6 +488,18 @@ namespace TweetDuck.Core{
}
}
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;

View File

@@ -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{}
}
}

View File

@@ -15,8 +15,6 @@ 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 const CefMenuCommand MenuOpenLinkUrl = (CefMenuCommand)26500;
@@ -28,6 +26,7 @@ namespace TweetDuck.Core.Handling{
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;
protected ContextInfo.LinkInfo LastLink { get; private set; }
@@ -57,6 +56,8 @@ namespace TweetDuck.Core.Handling{
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;
@@ -126,7 +127,7 @@ namespace TweetDuck.Core.Handling{
SetClipboardText(control, TwitterUtils.GetMediaLink(LastLink.GetMediaSource(parameters), ImageQuality));
break;
case MenuViewImage:
case MenuViewImage: {
void ViewImage(string path){
string ext = Path.GetExtension(path);
@@ -141,37 +142,60 @@ namespace TweetDuck.Core.Handling{
string url = LastLink.GetMediaSource(parameters);
string file = Path.Combine(BrowserCache.CacheFolder, TwitterUtils.GetImageFileName(url) ?? Path.GetRandomFileName());
if (File.Exists(file)){
ViewImage(file);
}
else{
control.InvokeAsyncSafe(analytics.AnalyticsFile.ViewedImages.Trigger);
BrowserUtils.DownloadFileAsync(TwitterUtils.GetMediaLink(url, ImageQuality), file, () => {
control.InvokeAsyncSafe(() => {
if (File.Exists(file)){
ViewImage(file);
}, ex => {
FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK);
});
}
}
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 (LastLink.IsVideo){
control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedVideos.Trigger);
TwitterUtils.DownloadVideo(LastLink.GetMediaSource(parameters), LastChirp.Authors.LastOrDefault());
}
else{
control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedImages.Trigger);
TwitterUtils.DownloadImage(LastLink.GetMediaSource(parameters), LastChirp.Authors.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:
control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedImages.Trigger);
TwitterUtils.DownloadImages(LastChirp.Images, LastChirp.Authors.LastOrDefault(), ImageQuality);
break;
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;
@@ -195,15 +219,15 @@ namespace TweetDuck.Core.Handling{
return false;
}
protected void DeselectAll(IFrame frame){
protected static void DeselectAll(IFrame frame){
ScriptLoader.ExecuteScript(frame, "window.getSelection().removeAllRanges()", "gen:deselect");
}
protected void OpenBrowser(Control control, string url){
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));
}
@@ -212,7 +236,10 @@ namespace TweetDuck.Core.Handling{
}
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){

View File

@@ -16,7 +16,7 @@ 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";
@@ -44,7 +44,7 @@ namespace TweetDuck.Core.Handling{
if (isSelecting){
if (isEditing){
model.AddSeparator();
model.AddItem(MenuInputApplyROT13, "Apply ROT13");
model.AddItem(MenuWriteApplyROT13, "Apply ROT13");
}
model.AddSeparator();
@@ -83,11 +83,8 @@ 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);
@@ -141,7 +138,7 @@ namespace TweetDuck.Core.Handling{
SetClipboardText(form, LastChirp.QuoteUrl);
return true;
case MenuInputApplyROT13:
case MenuWriteApplyROT13:
form.InvokeAsyncSafe(form.ApplyROT13);
return true;

View File

@@ -8,11 +8,7 @@ namespace TweetDuck.Core.Handling{
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);
}
}
}

View File

@@ -47,11 +47,7 @@ namespace TweetDuck.Core.Handling{
}
}
if (HasDevTools){
AddSeparator(model);
AddDebugMenuItems(model);
}
AddDebugMenuItems(model);
RemoveSeparatorIfLast(model);
form.InvokeAsyncSafe(() => {

View File

@@ -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);

View 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 ?? 0, 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();
}
}

View 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(){}
}
}

View File

@@ -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 (*.*)|*.*"
}){

View File

@@ -50,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);

View File

@@ -2,15 +2,22 @@
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 (ContextMenuBase.HasDevTools){
if (BrowserUtils.HasDevTools){
NameValueCollection headers = request.Headers;
headers.Remove("x-devtools-emulate-network-conditions-client-id");
request.Headers = headers;
@@ -18,5 +25,11 @@ namespace TweetDuck.Core.Handling{
return base.OnBeforeResourceLoad(browserControl, browser, frame, request, callback);
}
public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){
if (autoReload){
browser.Reload();
}
}
}
}

View File

@@ -1,11 +1,21 @@
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.")){
@@ -16,13 +26,71 @@ namespace TweetDuck.Core.Handling{
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")){
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);
}
}
}

View File

@@ -21,9 +21,7 @@ namespace TweetDuck.Core.Management{
PluginData = 8,
All = UserConfig|SystemConfig|Session|PluginData
}
public bool IsRestarting { get; private set; }
private readonly string file;
private readonly PluginManager plugins;
@@ -125,7 +123,6 @@ namespace TweetDuck.Core.Management{
case "system":
if (items.HasFlag(Items.SystemConfig)){
entry.WriteToFile(Program.SystemConfigFilePath);
IsRestarting = true;
}
break;
@@ -153,7 +150,6 @@ namespace TweetDuck.Core.Management{
case "cookies":
if (items.HasFlag(Items.Session)){
entry.WriteToFile(Path.Combine(Program.StoragePath, TempCookiesPath));
IsRestarting = true;
}
break;
@@ -167,7 +163,7 @@ namespace TweetDuck.Core.Management{
return true;
}catch(Exception e){
Program.Reporter.HandleException("Profile Import Error", "An exception happened while importing TweetDuck profile.", true, e);
Program.Reporter.HandleException("Profile Import", "An exception happened while importing TweetDuck profile.", true, e);
return false;
}
}
@@ -216,10 +212,4 @@ namespace TweetDuck.Core.Management{
}
}
}
static class ProfileManagerExtensions{
public static bool NeedsRestart(this ProfileManager.Items items){
return items.HasFlag(ProfileManager.Items.SystemConfig) || items.HasFlag(ProfileManager.Items.Session);
}
}
}

View File

@@ -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.AppLogo.Url) ?? string.Empty;
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;
}

View File

@@ -1,6 +1,4 @@
using CefSharp;
using CefSharp.WinForms;
using System;
using CefSharp.WinForms;
using System.Drawing;
using System.Windows.Forms;
using TweetDuck.Configuration;
@@ -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{
@@ -109,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();
@@ -128,12 +124,11 @@ 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;
browser.SetupResourceHandler(TwitterUtils.TweetDeckURL, this.resourceHandler);
browser.SetupResourceHandler(TweetNotification.AppLogo);
@@ -165,12 +160,6 @@ namespace TweetDuck.Core.Notification{
Close();
}
private void browser_IsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs e){
if (e.IsBrowserInitialized){
Initialized?.Invoke(this, EventArgs.Empty);
}
}
// notification methods
public virtual void HideNotification(){
@@ -196,7 +185,7 @@ namespace TweetDuck.Core.Notification{
}
protected virtual string GetTweetHTML(TweetNotification tweet){
return tweet.GenerateHtml(IsCursorOverBrowser ? "td-notification td-hover" : "td-notification");
return tweet.GenerateHtml(IsCursorOverBrowser ? "td-notification td-hover" : "td-notification", this);
}
protected virtual void LoadTweet(TweetNotification tweet){

View File

@@ -14,11 +14,6 @@ using TweetDuck.Resources;
namespace TweetDuck.Core.Notification{
abstract partial class FormNotificationMain : FormNotificationBase, ITweetDeckBrowser{
private const string NotificationScriptFile = "notification.js";
private static readonly string NotificationScriptIdentifier = ScriptLoader.GetRootIdentifier(NotificationScriptFile);
private static readonly string NotificationJS = ScriptLoader.LoadResource(NotificationScriptFile);
private readonly PluginManager plugins;
private readonly int timerBarHeight;
@@ -65,7 +60,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;
@@ -87,7 +82,7 @@ namespace TweetDuck.Core.Notification{
browser.LoadingStateChanged += Browser_LoadingStateChanged;
browser.FrameLoadEnd += Browser_FrameLoadEnd;
plugins.Register(this, PluginEnvironment.Notification);
plugins.Register(this, PluginEnvironment.Notification, this);
mouseHookDelegate = MouseHookProc;
Disposed += (sender, args) => StopMouseHook(true);
@@ -105,7 +100,7 @@ namespace TweetDuck.Core.Notification{
browser.FrameLoadEnd += (sender, args) => {
IFrame frame = args.Frame;
if (frame.IsMain && NotificationJS != null && browser.Address != "about:blank"){
if (frame.IsMain && browser.Address != "about:blank"){
callback(frame);
}
};
@@ -186,9 +181,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);
ScriptLoader.ExecuteScript(e.Frame, ScriptLoader.LoadResource("notification.js", this), "root:notification");
}
}
@@ -255,7 +250,7 @@ namespace TweetDuck.Core.Notification{
string html = base.GetTweetHTML(tweet);
foreach(InjectedHTML injection in plugins.NotificationInjections){
html = injection.Inject(html);
html = injection.InjectInto(html);
}
return html;

View File

@@ -15,11 +15,12 @@ namespace TweetDuck.Core.Notification.Screenshot{
protected override bool CanDragWindow => false;
private readonly PluginManager plugins;
private readonly int width;
private int height;
public FormNotificationScreenshotable(Action callback, FormBrowser owner, PluginManager pluginManager, string html, int width) : base(owner, false){
this.plugins = pluginManager;
this.width = width;
int realWidth = BrowserUtils.Scale(width, DpiScale);
browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new ScreenshotBridge(this, SetScreenshotHeight, callback));
@@ -28,7 +29,7 @@ namespace TweetDuck.Core.Notification.Screenshot{
return;
}
string script = ScriptLoader.LoadResource("screenshot.js", true);
string script = ScriptLoader.LoadResourceSilent("screenshot.js");
if (script == null){
this.InvokeAsyncSafe(callback);
@@ -36,41 +37,52 @@ namespace TweetDuck.Core.Notification.Screenshot{
}
using(IFrame frame = args.Browser.MainFrame){
ScriptLoader.ExecuteScript(frame, script.Replace("{width}", ClientSize.Width.ToString()), "screenshot");
ScriptLoader.ExecuteScript(frame, script.Replace("{width}", realWidth.ToString()).Replace("{frames}", TweetScreenshotManager.WaitFrames.ToString()), "gen:screenshot");
}
};
SetScreenshotHeight(1);
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");
string html = tweet.GenerateHtml("td-screenshot", this);
foreach(InjectedHTML injection in plugins.NotificationInjections){
html = injection.Inject(html);
html = injection.InjectInto(html);
}
return html;
}
private void SetScreenshotHeight(int height){
SetNotificationSize(width, height);
private void SetScreenshotHeight(int browserHeight){
this.height = BrowserUtils.Scale(browserHeight, SizeScale);
}
public void TakeScreenshot(){
if (ClientSize.Height == 0){
FormMessage.Error("Screenshot Failed", "Could not detect screenshot size.", FormMessage.OK);
return;
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{
@@ -78,6 +90,7 @@ namespace TweetDuck.Core.Notification.Screenshot{
}
Clipboard.SetImage(bmp);
return true;
}
}
}

View File

@@ -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){
@@ -46,7 +71,11 @@ namespace TweetDuck.Core.Notification.Screenshot{
screenshot.Show();
timeout.Start();
#if !(DEBUG && NO_HIDE_SCREENSHOTS)
#if GEN_SCREENSHOT_FRAMES
StartDebugger();
#endif
#if !NO_HIDE_SCREENSHOTS
owner.IsWaiting = true;
#endif
}
@@ -58,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();
@@ -68,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
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Text;
using System.Windows.Forms;
using CefSharp;
using TweetDuck.Core.Bridge;
using TweetDuck.Data;
@@ -7,8 +8,7 @@ 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") ?? string.Empty;
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){
@@ -53,11 +53,11 @@ namespace TweetDuck.Core.Notification{
return 2000+Math.Max(1000, value*characters);
}
public string GenerateHtml(string bodyClasses){
public string GenerateHtml(string bodyClasses, Control sync){
StringBuilder build = new StringBuilder();
build.Append("<!DOCTYPE html>");
build.Append(TweetDeckBridge.NotificationHeadLayout ?? DefaultHeadLayout);
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>");
@@ -70,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>");

View File

@@ -8,7 +8,6 @@ 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;
@@ -22,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 },
@@ -42,7 +41,6 @@ namespace TweetDuck.Core.Other.Analytics{
{ "Clear Cache Threshold" , Exact(SysConfig.ClearCacheThreshold) },
0,
{ "Expand Links" , Bool(UserConfig.ExpandLinksOnHover) },
{ "Switch Account Selectors" , Bool(false) }, // TODO remove in next major update
{ "Search In First Column" , Bool(UserConfig.OpenSearchInFirstColumn) },
{ "Keep Like Follow Dialogs Open" , Bool(UserConfig.KeepLikeFollowDialogsOpen) },
{ "Best Image Quality" , Bool(UserConfig.BestImageQuality) },

View File

@@ -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);
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);
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);
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);
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);

View File

@@ -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";

View File

@@ -8,13 +8,16 @@ using TweetDuck.Core.Handling;
using TweetDuck.Core.Handling.General;
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;
@@ -53,6 +56,7 @@ namespace TweetDuck.Core.Other{
}
private readonly ChromiumWebBrowser browser;
private string nextUrl;
private FormGuide(string url, FormBrowser owner){
InitializeComponent();
@@ -65,7 +69,7 @@ namespace TweetDuck.Core.Other{
MenuHandler = new ContextMenuGuide(owner),
JsDialogHandler = new JavaScriptDialogHandler(),
LifeSpanHandler = new LifeSpanHandler(),
RequestHandler = new RequestHandlerBrowser()
RequestHandler = new RequestHandlerBase(true)
};
browser.LoadingStateChanged += browser_LoadingStateChanged;
@@ -75,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) => {
@@ -86,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;
}
}
}
@@ -109,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");
}

View File

@@ -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);
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);
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);
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;
}
}

View File

@@ -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,7 +87,7 @@ 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();
}

View File

@@ -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, 504);
this.btnClose.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnClose.Location = new System.Drawing.Point(747, 500);
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, 486);
this.panelContents.Size = new System.Drawing.Size(662, 482);
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, 486);
this.panelButtons.Size = new System.Drawing.Size(124, 482);
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, 504);
this.btnManageOptions.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnManageOptions.Location = new System.Drawing.Point(12, 500);
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, 539);
this.ClientSize = new System.Drawing.Size(809, 537);
this.Controls.Add(this.btnManageOptions);
this.Controls.Add(this.panelContents);
this.Controls.Add(this.panelButtons);

View File

@@ -13,17 +13,17 @@ using TweetDuck.Plugins;
using TweetDuck.Updates;
namespace TweetDuck.Core.Other{
sealed partial class FormSettings : Form{
sealed partial class FormSettings : Form, FormManager.IAppDialog{
public bool ShouldReloadBrowser { get; private set; }
private readonly FormBrowser browser;
private readonly PluginManager plugins;
private readonly int buttonHeight;
private readonly Dictionary<Type, SettingsTab> tabs = new Dictionary<Type, SettingsTab>(4);
private readonly Dictionary<Type, SettingsTab> tabs = new Dictionary<Type, SettingsTab>(8);
private SettingsTab currentTab;
public bool ShouldReloadBrowser { get; private set; }
public FormSettings(FormBrowser browser, PluginManager plugins, UpdateHandler updates, AnalyticsManager analytics, Type startTab){
InitializeComponent();
@@ -36,19 +36,36 @@ namespace TweetDuck.Core.Other{
this.buttonHeight = BrowserUtils.Scale(39, this.GetDPIScale()) | 1;
PrepareLoad();
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)]);
}
private void FormSettings_FormClosing(object sender, FormClosingEventArgs e){
private void PrepareLoad(){
Program.Config.ProgramRestartRequested += Config_ProgramRestartRequested;
}
private void PrepareUnload(){ // TODO refactor this further later
currentTab.Control.OnClosing();
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
Program.Config.SaveAll();
}
private void Config_ProgramRestartRequested(object sender, EventArgs e){
if (FormMessage.Information("TweetDuck Options", "The application must restart for the option to take place. Do you want to restart now?", FormMessage.Yes, FormMessage.No)){
Program.Restart();
}
}
private void FormSettings_FormClosing(object sender, FormClosingEventArgs e){
PrepareUnload();
foreach(SettingsTab tab in tabs.Values){
if (tab.IsInitialized){
@@ -56,28 +73,30 @@ namespace TweetDuck.Core.Other{
}
}
Program.UserConfig.Save();
browser.ResumeNotification();
}
private void btnManageOptions_Click(object sender, EventArgs e){
currentTab.Control.OnClosing();
PrepareUnload();
using(DialogSettingsManage dialog = new DialogSettingsManage(plugins)){
FormClosing -= FormSettings_FormClosing;
if (dialog.ShowDialog() == DialogResult.OK){
if (!dialog.IsRestarting){
browser.ResumeNotification();
BrowserProcessHandler.UpdatePrefs();
ShouldReloadBrowser = dialog.ShouldReloadBrowser;
if (dialog.ShouldReloadBrowser){
BrowserProcessHandler.UpdatePrefs();
ShouldReloadBrowser = true;
}
}
Close();
}
else{
FormClosing += FormSettings_FormClosing;
PrepareLoad();
}
}
}
@@ -90,6 +109,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),
@@ -137,6 +157,10 @@ namespace TweetDuck.Core.Other{
}
}
if (tab.Control.Height < panelContents.Height-2){
tab.Control.Height = panelContents.Height-2; // fixes off-by-pixel error on high DPI
}
tab.Control.OnReady();
}

View File

@@ -5,6 +5,7 @@ using TweetDuck.Configuration;
namespace TweetDuck.Core.Other.Settings{
class BaseTabSettings : UserControl{
protected static UserConfig Config => Program.UserConfig;
protected static SystemConfig SysConfig => Program.SystemConfig;
public IEnumerable<Control> InteractiveControls{
get{
@@ -31,11 +32,5 @@ namespace TweetDuck.Core.Other.Settings{
public virtual void OnReady(){}
public virtual void OnClosing(){}
protected static void PromptRestart(){
if (FormMessage.Information("TweetDuck Options", "The application must restart for the option to take place. Do you want to restart now?", FormMessage.Yes, FormMessage.No)){
Program.Restart();
}
}
}
}

View File

@@ -33,22 +33,24 @@
this.textBoxReport.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.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.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular);
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);
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);
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;

View File

@@ -27,42 +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.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.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.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxBrowserCSS.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular);
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;
@@ -71,121 +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.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.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.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxNotificationCSS.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular);
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);
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();
@@ -196,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;
}
}

View File

@@ -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){

View File

@@ -35,20 +35,22 @@
this.textBoxArgs.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.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.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular);
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);
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);
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);
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);
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;

View File

@@ -43,10 +43,12 @@
// 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);
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;
@@ -57,10 +59,11 @@
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(119, 97);
this.btnContinue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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(51, 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;
@@ -69,9 +72,11 @@
// cbProgramConfig
//
this.cbProgramConfig.AutoSize = true;
this.cbProgramConfig.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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(104, 17);
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.");
@@ -81,9 +86,11 @@
// cbSession
//
this.cbSession.AutoSize = true;
this.cbSession.Location = new System.Drawing.Point(3, 49);
this.cbSession.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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.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.");
@@ -93,9 +100,11 @@
// cbPluginData
//
this.cbPluginData.AutoSize = true;
this.cbPluginData.Location = new System.Drawing.Point(3, 72);
this.cbPluginData.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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.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.");
@@ -105,9 +114,11 @@
// cbSystemConfig
//
this.cbSystemConfig.AutoSize = true;
this.cbSystemConfig.Location = new System.Drawing.Point(3, 26);
this.cbSystemConfig.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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(99, 17);
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.");
@@ -125,7 +136,7 @@
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(220, 89);
this.panelSelection.Size = new System.Drawing.Size(210, 97);
this.panelSelection.TabIndex = 2;
this.panelSelection.Visible = false;
this.panelSelection.WrapContents = false;
@@ -140,16 +151,18 @@
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, 71);
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);
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";
@@ -159,9 +172,11 @@
// radioExport
//
this.radioExport.AutoSize = true;
this.radioExport.Location = new System.Drawing.Point(3, 26);
this.radioExport.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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(87, 17);
this.radioExport.Size = new System.Drawing.Size(95, 19);
this.radioExport.TabIndex = 1;
this.radioExport.TabStop = true;
this.radioExport.Text = "Export Profile";
@@ -171,9 +186,11 @@
// radioReset
//
this.radioReset.AutoSize = true;
this.radioReset.Location = new System.Drawing.Point(3, 49);
this.radioReset.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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(104, 17);
this.radioReset.Size = new System.Drawing.Size(110, 19);
this.radioReset.TabIndex = 2;
this.radioReset.TabStop = true;
this.radioReset.Text = "Restore Defaults";
@@ -184,7 +201,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(244, 132);
this.ClientSize = new System.Drawing.Size(234, 129);
this.Controls.Add(this.btnContinue);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.panelDecision);
@@ -192,7 +209,7 @@
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(260, 170);
this.MinimumSize = new System.Drawing.Size(250, 167);
this.Name = "DialogSettingsManage";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Windows.Forms;
using TweetDuck.Configuration;
using TweetDuck.Core.Management;
using TweetDuck.Core.Utils;
using TweetDuck.Plugins;
namespace TweetDuck.Core.Other.Settings.Dialogs{
@@ -22,6 +23,10 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
}
}
}
private bool SelectedItemsForceRestart{
get => _selectedItems.HasFlag(ProfileManager.Items.Session);
}
public bool IsRestarting { get; private set; }
public bool ShouldReloadBrowser { get; private set; }
@@ -31,10 +36,11 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
private State currentState;
private ProfileManager importManager;
private bool requestedRestartFromConfig;
private ProfileManager.Items _selectedItems = ProfileManager.Items.None;
public DialogSettingsManage(PluginManager plugins){
public DialogSettingsManage(PluginManager plugins, bool openImportImmediately = false){
InitializeComponent();
this.plugins = plugins;
@@ -44,6 +50,11 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
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){
@@ -111,37 +122,38 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
case State.Reset:
if (FormMessage.Warning("Reset TweetDuck Options", "This will reset the selected items. Are you sure you want to proceed?", FormMessage.Yes, FormMessage.No)){
Program.Config.ProgramRestartRequested += Config_ProgramRestartRequested;
if (SelectedItems.HasFlag(ProfileManager.Items.UserConfig)){
Program.UserConfig.Reset();
}
if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
try{
File.Delete(Program.SystemConfigFilePath);
}catch(Exception ex){
Program.Reporter.HandleException("System Config Reset Error", "Could not delete system config.", true, ex);
}
Program.SystemConfig.Reset();
}
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
if (SelectedItems.HasFlag(ProfileManager.Items.PluginData)){
try{
File.Delete(Program.PluginConfigFilePath);
Directory.Delete(Program.PluginDataPath, true);
}catch(Exception ex){
Program.Reporter.HandleException("Plugin Data Reset Error", "Could not delete plugin data.", true, ex);
Program.Reporter.HandleException("Profile Reset", "Could not delete plugin data.", true, ex);
}
}
if (SelectedItems.HasFlag(ProfileManager.Items.Session)){
RestartProgram(Arguments.ArgDeleteCookies);
if (SelectedItemsForceRestart){
RestartProgram(SelectedItems.HasFlag(ProfileManager.Items.Session) ? new string[]{ Arguments.ArgDeleteCookies } : StringUtils.EmptyArray);
}
else if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
RestartProgram();
}
else{
ShouldReloadBrowser = true;
else if (requestedRestartFromConfig){
if (FormMessage.Information("Profile Reset", "The application must restart for some of the restored options to take place. Do you want to restart now?", FormMessage.Yes, FormMessage.No)){
RestartProgram();
}
}
ShouldReloadBrowser = true;
DialogResult = DialogResult.OK;
Close();
}
@@ -150,21 +162,22 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
case State.Import:
if (importManager.Import(SelectedItems)){
Program.UserConfig.Reload();
if (importManager.IsRestarting){
if (SelectedItems.HasFlag(ProfileManager.Items.Session)){
RestartProgram(Arguments.ArgImportCookies);
}
else if (SelectedItems.HasFlag(ProfileManager.Items.SystemConfig)){
Program.Config.ProgramRestartRequested += Config_ProgramRestartRequested;
Program.Config.ReloadAll();
Program.Config.ProgramRestartRequested -= Config_ProgramRestartRequested;
if (SelectedItemsForceRestart){
RestartProgram(SelectedItems.HasFlag(ProfileManager.Items.Session) ? new string[]{ Arguments.ArgImportCookies } : StringUtils.EmptyArray);
}
else if (requestedRestartFromConfig){
if (FormMessage.Information("Profile Import", "The application must restart for some of the imported options to take place. Do you want to restart now?", FormMessage.Yes, FormMessage.No)){
RestartProgram();
}
}
else{
ShouldReloadBrowser = true;
}
}
ShouldReloadBrowser = true;
DialogResult = DialogResult.OK;
Close();
break;
@@ -185,9 +198,6 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
file = dialog.FileName;
}
Program.UserConfig.Save();
Program.SystemConfig.Save();
new ProfileManager(file, plugins).Export(SelectedItems);
@@ -202,15 +212,19 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
Close();
}
private void Config_ProgramRestartRequested(object sender, EventArgs e){
requestedRestartFromConfig = true;
}
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.NeedsRestart() ? "Import && Restart" : "Import Profile";
btnContinue.Text = SelectedItemsForceRestart ? "Import && Restart" : "Import Profile";
}
else if (currentState == State.Reset){
btnContinue.Text = _selectedItems.NeedsRestart() ? "Restore && Restart" : "Restore Defaults";
btnContinue.Text = SelectedItemsForceRestart ? "Restore && Restart" : "Restore Defaults";
}
}

View File

@@ -39,10 +39,12 @@
// 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, 139);
this.btnCancel.AutoSize = true;
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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.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;
@@ -51,10 +53,12 @@
// 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, 139);
this.btnRestart.AutoSize = true;
this.btnRestart.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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.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;
@@ -63,19 +67,22 @@
// cbLogging
//
this.cbLogging.AutoSize = true;
this.cbLogging.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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;
//
// tbDataFolder
//
this.tbDataFolder.Location = new System.Drawing.Point(3, 51);
this.tbDataFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
this.tbDataFolder.Location = new System.Drawing.Point(3, 54);
this.tbDataFolder.Name = "tbDataFolder";
this.tbDataFolder.Size = new System.Drawing.Size(260, 20);
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.");
@@ -85,30 +92,33 @@
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(3, 102);
this.tbShortcutTarget.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
this.tbShortcutTarget.Location = new System.Drawing.Point(3, 110);
this.tbShortcutTarget.Name = "tbShortcutTarget";
this.tbShortcutTarget.ReadOnly = true;
this.tbShortcutTarget.Size = new System.Drawing.Size(260, 20);
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(3, 35);
this.labelDataFolder.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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.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(3, 86);
this.labelShortcutTarget.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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.Size = new System.Drawing.Size(171, 15);
this.labelShortcutTarget.TabIndex = 3;
this.labelShortcutTarget.Text = "Shortcut Target (click to select)";
//
@@ -126,7 +136,7 @@
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, 127);
this.flowPanel.Size = new System.Drawing.Size(266, 136);
this.flowPanel.TabIndex = 0;
this.flowPanel.WrapContents = false;
//
@@ -134,7 +144,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 174);
this.ClientSize = new System.Drawing.Size(284, 183);
this.Controls.Add(this.flowPanel);
this.Controls.Add(this.btnRestart);
this.Controls.Add(this.btnCancel);
@@ -147,6 +157,7 @@
this.flowPanel.ResumeLayout(false);
this.flowPanel.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}

View File

@@ -12,7 +12,7 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
cbLogging.Checked = currentArgs.HasFlag(Arguments.ArgLogging);
cbLogging.CheckedChanged += control_Change;
if (Program.IsPortable){
tbDataFolder.Text = "Not available in portable version";
tbDataFolder.Enabled = false;
@@ -33,7 +33,7 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
if (cbLogging.Checked){
Args.AddFlag(Arguments.ArgLogging);
}
if (!string.IsNullOrWhiteSpace(tbDataFolder.Text) && tbDataFolder.Enabled){
Args.SetValue(Arguments.ArgDataFolder, tbDataFolder.Text);
}

View File

@@ -34,18 +34,21 @@
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.Location = new System.Drawing.Point(12, 28);
this.textBoxUrl.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
this.textBoxUrl.Location = new System.Drawing.Point(12, 30);
this.textBoxUrl.Name = "textBoxUrl";
this.textBoxUrl.Size = new System.Drawing.Size(310, 20);
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.Location = new System.Drawing.Point(204, 56);
this.btnCancel.AutoSize = true;
this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
this.btnCancel.Location = new System.Drawing.Point(207, 59);
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;
@@ -54,10 +57,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(266, 56);
this.btnApply.AutoSize = true;
this.btnApply.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
this.btnApply.Location = new System.Drawing.Point(270, 59);
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;
@@ -66,10 +71,11 @@
// labelInfo
//
this.labelInfo.AutoSize = true;
this.labelInfo.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
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(264, 13);
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.";
//
@@ -77,7 +83,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(334, 91);
this.ClientSize = new System.Drawing.Size(334, 96);
this.Controls.Add(this.labelInfo);
this.Controls.Add(this.btnApply);
this.Controls.Add(this.btnCancel);

View File

@@ -25,7 +25,6 @@
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
this.btnClearCache = new System.Windows.Forms.Button();
this.checkHardwareAcceleration = new System.Windows.Forms.CheckBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.btnEditCefArgs = new System.Windows.Forms.Button();
this.btnEditCSS = new System.Windows.Forms.Button();
@@ -37,9 +36,8 @@
this.checkClearCacheAuto = new System.Windows.Forms.CheckBox();
this.labelApp = new System.Windows.Forms.Label();
this.panelAppButtons = new System.Windows.Forms.Panel();
this.labelPerformance = new System.Windows.Forms.Label();
this.panelClearCacheAuto = new System.Windows.Forms.Panel();
this.labelCache = new System.Windows.Forms.Label();
this.panelClearCacheAuto = new System.Windows.Forms.Panel();
this.panelConfiguration = new System.Windows.Forms.Panel();
this.labelConfiguration = new System.Windows.Forms.Label();
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
@@ -52,119 +50,133 @@
//
// btnClearCache
//
this.btnClearCache.Location = new System.Drawing.Point(5, 172);
this.btnClearCache.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnClearCache.Location = new System.Drawing.Point(5, 135);
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.TabIndex = 5;
this.btnClearCache.Text = "Clear Cache (calculating)";
this.btnClearCache.Size = new System.Drawing.Size(143, 25);
this.btnClearCache.TabIndex = 3;
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.Name = "checkHardwareAcceleration";
this.checkHardwareAcceleration.Size = new System.Drawing.Size(134, 17);
this.checkHardwareAcceleration.TabIndex = 3;
this.checkHardwareAcceleration.Text = "Hardware Acceleration";
this.checkHardwareAcceleration.UseVisualStyleBackColor = true;
//
// btnEditCefArgs
//
this.btnEditCefArgs.Font = new System.Drawing.Font("Segoe UI", 9F);
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(143, 25);
this.btnEditCefArgs.TabIndex = 0;
this.btnEditCefArgs.Text = "Edit CEF Arguments";
this.btnEditCefArgs.UseVisualStyleBackColor = true;
//
// btnEditCSS
//
this.btnEditCSS.Location = new System.Drawing.Point(155, 3);
this.btnEditCSS.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnEditCSS.Location = new System.Drawing.Point(154, 3);
this.btnEditCSS.Name = "btnEditCSS";
this.btnEditCSS.Size = new System.Drawing.Size(144, 23);
this.btnEditCSS.Size = new System.Drawing.Size(143, 25);
this.btnEditCSS.TabIndex = 1;
this.btnEditCSS.Text = "Edit CSS";
this.btnEditCSS.UseVisualStyleBackColor = true;
//
// btnRestartArgs
//
this.btnRestartArgs.Location = new System.Drawing.Point(155, 32);
this.btnRestartArgs.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnRestartArgs.Location = new System.Drawing.Point(154, 32);
this.btnRestartArgs.Name = "btnRestartArgs";
this.btnRestartArgs.Size = new System.Drawing.Size(144, 23);
this.btnRestartArgs.Size = new System.Drawing.Size(143, 25);
this.btnRestartArgs.TabIndex = 3;
this.btnRestartArgs.Text = "Restart with Arguments";
this.btnRestartArgs.UseVisualStyleBackColor = true;
//
// btnRestart
//
this.btnRestart.Location = new System.Drawing.Point(155, 3);
this.btnRestart.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnRestart.Location = new System.Drawing.Point(154, 3);
this.btnRestart.Name = "btnRestart";
this.btnRestart.Size = new System.Drawing.Size(144, 23);
this.btnRestart.Size = new System.Drawing.Size(143, 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);
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(143, 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);
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(143, 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);
this.numClearCacheThreshold.Increment = new decimal(new int[] {
50,
0,
0,
0});
this.numClearCacheThreshold.Location = new System.Drawing.Point(210, 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(89, 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);
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(201, 19);
this.checkClearCacheAuto.TabIndex = 0;
this.checkClearCacheAuto.Text = "Clear Cache Automatically When Above";
this.checkClearCacheAuto.Text = "Clear Automatically When Above";
this.checkClearCacheAuto.UseVisualStyleBackColor = true;
//
// 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 Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelApp.Location = new System.Drawing.Point(0, 0);
this.labelApp.Margin = new System.Windows.Forms.Padding(0);
this.labelApp.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelApp.Name = "labelApp";
this.labelApp.Size = new System.Drawing.Size(38, 20);
this.labelApp.Size = new System.Drawing.Size(97, 19);
this.labelApp.TabIndex = 0;
this.labelApp.Text = "App";
this.labelApp.Text = "APPLICATION";
//
// panelAppButtons
//
this.panelAppButtons.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.panelAppButtons.Controls.Add(this.btnOpenDataFolder);
this.panelAppButtons.Controls.Add(this.btnOpenAppFolder);
this.panelAppButtons.Controls.Add(this.btnRestart);
@@ -172,72 +184,57 @@
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(300, 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.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.TabIndex = 2;
this.labelPerformance.Text = "Performance";
//
// panelClearCacheAuto
//
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.Margin = new System.Windows.Forms.Padding(0);
this.panelClearCacheAuto.Name = "panelClearCacheAuto";
this.panelClearCacheAuto.Size = new System.Drawing.Size(322, 26);
this.panelClearCacheAuto.TabIndex = 6;
//
// labelCache
//
this.labelCache.AutoSize = true;
this.labelCache.Location = new System.Drawing.Point(3, 156);
this.labelCache.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
this.labelCache.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelCache.Location = new System.Drawing.Point(0, 112);
this.labelCache.Margin = new System.Windows.Forms.Padding(0, 30, 0, 1);
this.labelCache.Name = "labelCache";
this.labelCache.Size = new System.Drawing.Size(38, 13);
this.labelCache.TabIndex = 4;
this.labelCache.Text = "Cache";
this.labelCache.Size = new System.Drawing.Size(123, 19);
this.labelCache.TabIndex = 2;
this.labelCache.Text = "BROWSER CACHE";
//
// panelClearCacheAuto
//
this.panelClearCacheAuto.Controls.Add(this.checkClearCacheAuto);
this.panelClearCacheAuto.Controls.Add(this.numClearCacheThreshold);
this.panelClearCacheAuto.Location = new System.Drawing.Point(0, 163);
this.panelClearCacheAuto.Margin = new System.Windows.Forms.Padding(0);
this.panelClearCacheAuto.Name = "panelClearCacheAuto";
this.panelClearCacheAuto.Size = new System.Drawing.Size(300, 28);
this.panelClearCacheAuto.TabIndex = 4;
//
// panelConfiguration
//
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, 241);
this.panelConfiguration.Margin = new System.Windows.Forms.Padding(0);
this.panelConfiguration.Name = "panelConfiguration";
this.panelConfiguration.Size = new System.Drawing.Size(322, 29);
this.panelConfiguration.TabIndex = 8;
this.panelConfiguration.Size = new System.Drawing.Size(300, 31);
this.panelConfiguration.TabIndex = 6;
//
// 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.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
this.labelConfiguration.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelConfiguration.Location = new System.Drawing.Point(0, 221);
this.labelConfiguration.Margin = new System.Windows.Forms.Padding(0, 30, 0, 1);
this.labelConfiguration.Name = "labelConfiguration";
this.labelConfiguration.Size = new System.Drawing.Size(104, 20);
this.labelConfiguration.TabIndex = 7;
this.labelConfiguration.Text = "Configuration";
this.labelConfiguration.Size = new System.Drawing.Size(123, 19);
this.labelConfiguration.TabIndex = 5;
this.labelConfiguration.Text = "CONFIGURATION";
//
// 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.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.flowPanel.Controls.Add(this.labelApp);
this.flowPanel.Controls.Add(this.panelAppButtons);
this.flowPanel.Controls.Add(this.labelPerformance);
this.flowPanel.Controls.Add(this.checkHardwareAcceleration);
this.flowPanel.Controls.Add(this.labelCache);
this.flowPanel.Controls.Add(this.btnClearCache);
this.flowPanel.Controls.Add(this.panelClearCacheAuto);
@@ -246,7 +243,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(300, 462);
this.flowPanel.TabIndex = 0;
this.flowPanel.WrapContents = false;
//
@@ -256,7 +253,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(631, 480);
((System.ComponentModel.ISupportInitialize)(this.numClearCacheThreshold)).EndInit();
this.panelAppButtons.ResumeLayout(false);
this.panelClearCacheAuto.ResumeLayout(false);
@@ -271,7 +268,6 @@
#endregion
private System.Windows.Forms.Button btnClearCache;
private System.Windows.Forms.CheckBox checkHardwareAcceleration;
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.Button btnEditCefArgs;
private System.Windows.Forms.Button btnEditCSS;
@@ -281,11 +277,10 @@
private System.Windows.Forms.Button btnOpenDataFolder;
private System.Windows.Forms.Label labelApp;
private System.Windows.Forms.Panel panelAppButtons;
private System.Windows.Forms.Label labelPerformance;
private System.Windows.Forms.Label labelCache;
private System.Windows.Forms.Panel panelClearCacheAuto;
private System.Windows.Forms.Panel panelConfiguration;
private System.Windows.Forms.Label labelConfiguration;
private System.Windows.Forms.Label labelCache;
private Controls.NumericUpDownEx numClearCacheThreshold;
private System.Windows.Forms.CheckBox checkClearCacheAuto;
private System.Windows.Forms.FlowLayoutPanel flowPanel;

View File

@@ -10,36 +10,27 @@ using TweetDuck.Core.Utils;
namespace TweetDuck.Core.Other.Settings{
sealed partial class TabSettingsAdvanced : BaseTabSettings{
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;
// application
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.");
// browser cache
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.");
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;
}
checkClearCacheAuto.Checked = SysConfig.ClearCacheAutomatically;
numClearCacheThreshold.Enabled = checkClearCacheAuto.Checked;
numClearCacheThreshold.SetValueSafe(SysConfig.ClearCacheThreshold);
@@ -48,6 +39,11 @@ namespace TweetDuck.Core.Other.Settings{
string text = task.Status == TaskStatus.RanToCompletion ? (int)Math.Ceiling(task.Result/(1024.0*1024.0))+" MB" : "unknown";
this.InvokeSafe(() => btnClearCache.Text = $"Clear Cache ({text})");
});
// configuration
toolTip.SetToolTip(btnEditCefArgs, "Set custom command line arguments for Chromium Embedded Framework.");
toolTip.SetToolTip(btnEditCSS, "Set custom CSS for browser and notification windows.");
}
public override void OnReady(){
@@ -56,8 +52,6 @@ namespace TweetDuck.Core.Other.Settings{
btnRestart.Click += btnRestart_Click;
btnRestartArgs.Click += btnRestartArgs_Click;
checkHardwareAcceleration.CheckedChanged += checkHardwareAcceleration_CheckedChanged;
btnClearCache.Click += btnClearCache_Click;
checkClearCacheAuto.CheckedChanged += checkClearCacheAuto_CheckedChanged;
@@ -68,9 +62,33 @@ namespace TweetDuck.Core.Other.Settings{
public override void OnClosing(){
SysConfig.ClearCacheAutomatically = checkClearCacheAuto.Checked;
SysConfig.ClearCacheThreshold = (int)numClearCacheThreshold.Value;
SysConfig.Save();
}
#region Application
private void btnOpenAppFolder_Click(object sender, EventArgs e){
using(Process.Start("explorer.exe", "\""+Program.ProgramPath+"\"")){}
}
private void btnOpenDataFolder_Click(object sender, EventArgs e){
using(Process.Start("explorer.exe", "\""+Program.StoragePath+"\"")){}
}
private void btnRestart_Click(object sender, EventArgs e){
Program.Restart();
}
private void btnRestartArgs_Click(object sender, EventArgs e){
using(DialogSettingsRestart dialog = new DialogSettingsRestart(Arguments.GetCurrentClean())){
if (dialog.ShowDialog() == DialogResult.OK){
Program.RestartWithArgs(dialog.Args);
}
}
}
#endregion
#region Browser Cache
private void btnClearCache_Click(object sender, EventArgs e){
btnClearCache.Enabled = false;
BrowserCache.SetClearOnExit();
@@ -81,10 +99,8 @@ namespace TweetDuck.Core.Other.Settings{
numClearCacheThreshold.Enabled = checkClearCacheAuto.Checked;
}
private void checkHardwareAcceleration_CheckedChanged(object sender, EventArgs e){
SysConfig.HardwareAcceleration = checkHardwareAcceleration.Checked;
PromptRestart(); // calls OnClosing
}
#endregion
#region Configuration
private void btnEditCefArgs_Click(object sender, EventArgs e){
DialogSettingsCefArgs form = new DialogSettingsCefArgs();
@@ -98,10 +114,9 @@ namespace TweetDuck.Core.Other.Settings{
if (form.DialogResult == DialogResult.OK){
Config.CustomCefArgs = form.CefArgs;
PromptRestart();
form.Dispose();
}
else form.Dispose();
form.Dispose();
};
form.Show(ParentForm);
@@ -109,7 +124,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);
@@ -131,30 +146,12 @@ namespace TweetDuck.Core.Other.Settings{
NativeMethods.SetFormDisabled(ParentForm, true);
}
private void btnOpenAppFolder_Click(object sender, EventArgs e){
using(Process.Start("explorer.exe", "\""+Program.ProgramPath+"\"")){}
}
private void btnOpenDataFolder_Click(object sender, EventArgs e){
using(Process.Start("explorer.exe", "\""+Program.StoragePath+"\"")){}
}
private void btnRestart_Click(object sender, EventArgs e){
Program.Restart();
}
private void btnRestartArgs_Click(object sender, EventArgs e){
using(DialogSettingsRestart dialog = new DialogSettingsRestart(Arguments.GetCurrentClean())){
if (dialog.ShowDialog() == DialogResult.OK){
Program.RestartWithArgs(dialog.Args);
}
}
}
private void RestoreParentForm(){
if (ParentForm != null){ // when the parent is closed first, ParentForm is null in FormClosed event
NativeMethods.SetFormDisabled(ParentForm, false);
}
}
#endregion
}
}

View File

@@ -40,24 +40,24 @@
//
// panelDataCollection
//
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(300, 28);
this.panelDataCollection.TabIndex = 3;
//
// labelDataCollectionLink
//
this.labelDataCollectionLink.AutoSize = true;
this.labelDataCollectionLink.Font = new System.Drawing.Font("Segoe UI", 9F);
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,29 +67,33 @@
// checkDataCollection
//
this.checkDataCollection.AutoSize = true;
this.checkDataCollection.Font = new System.Drawing.Font("Segoe UI", 9F);
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);
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);
this.labelDataCollectionMessage.Size = new System.Drawing.Size(288, 67);
this.labelDataCollectionMessage.TabIndex = 5;
//
// btnViewReport
//
this.btnViewReport.AutoSize = true;
this.btnViewReport.Location = new System.Drawing.Point(5, 103);
this.btnViewReport.Font = new System.Drawing.Font("Segoe UI", 9F);
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 +101,12 @@
// btnSendFeedback
//
this.btnSendFeedback.AutoSize = true;
this.btnSendFeedback.Font = new System.Drawing.Font("Segoe UI", 9F);
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,23 +114,24 @@
// labelDataCollection
//
this.labelDataCollection.AutoSize = true;
this.labelDataCollection.Location = new System.Drawing.Point(3, 61);
this.labelDataCollection.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
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 Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelFeedback.Location = new System.Drawing.Point(0, 0);
this.labelFeedback.Margin = new System.Windows.Forms.Padding(0);
this.labelFeedback.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelFeedback.Name = "labelFeedback";
this.labelFeedback.Size = new System.Drawing.Size(80, 20);
this.labelFeedback.Size = new System.Drawing.Size(75, 19);
this.labelFeedback.TabIndex = 0;
this.labelFeedback.Text = "Feedback";
this.labelFeedback.Text = "FEEDBACK";
//
// flowPanel
//
@@ -141,7 +147,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(300, 462);
this.flowPanel.TabIndex = 0;
this.flowPanel.WrapContents = false;
//
@@ -151,7 +157,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(631, 480);
this.panelDataCollection.ResumeLayout(false);
this.panelDataCollection.PerformLayout();
this.flowPanel.ResumeLayout(false);

View File

@@ -18,6 +18,8 @@ namespace TweetDuck.Core.Other.Settings{
this.analyticsInfo = analyticsInfo;
this.plugins = plugins;
// feedback
checkDataCollection.Checked = Config.AllowDataCollection;
if (analytics != null){
@@ -33,6 +35,8 @@ namespace TweetDuck.Core.Other.Settings{
btnViewReport.Click += btnViewReport_Click;
}
#region Feedback
private void btnSendFeedback_Click(object sender, EventArgs e){
BrowserUtils.OpenExternalBrowser("https://github.com/chylex/TweetDuck/issues/new");
}
@@ -50,5 +54,7 @@ namespace TweetDuck.Core.Other.Settings{
dialog.ShowDialog();
}
}
#endregion
}
}

View File

@@ -38,26 +38,42 @@
this.panelZoom = new System.Windows.Forms.Panel();
this.checkAnimatedAvatars = new System.Windows.Forms.CheckBox();
this.labelUpdates = new System.Windows.Forms.Label();
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
this.flowPanelLeft = new System.Windows.Forms.FlowLayoutPanel();
this.checkKeepLikeFollowDialogsOpen = new System.Windows.Forms.CheckBox();
this.labelTray = new System.Windows.Forms.Label();
this.comboBoxTrayType = new System.Windows.Forms.ComboBox();
this.labelTrayIcon = new System.Windows.Forms.Label();
this.checkTrayHighlight = new System.Windows.Forms.CheckBox();
this.labelBrowserSettings = new System.Windows.Forms.Label();
this.checkSmoothScrolling = new System.Windows.Forms.CheckBox();
this.checkTouchAdjustment = 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();
this.flowPanelRight = new System.Windows.Forms.FlowLayoutPanel();
this.checkHardwareAcceleration = new System.Windows.Forms.CheckBox();
this.labelLocales = new System.Windows.Forms.Label();
this.checkSpellCheck = new System.Windows.Forms.CheckBox();
this.labelSpellCheckLanguage = new System.Windows.Forms.Label();
this.comboBoxSpellCheckLanguage = new System.Windows.Forms.ComboBox();
this.labelTranslationTarget = new System.Windows.Forms.Label();
this.comboBoxTranslationTarget = new System.Windows.Forms.ComboBox();
this.panelSeparator = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.trackBarZoom)).BeginInit();
this.panelZoom.SuspendLayout();
this.flowPanel.SuspendLayout();
this.flowPanelLeft.SuspendLayout();
this.flowPanelRight.SuspendLayout();
this.SuspendLayout();
//
// checkExpandLinks
//
this.checkExpandLinks.AutoSize = true;
this.checkExpandLinks.Font = new System.Drawing.Font("Segoe UI", 9F);
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;
@@ -65,27 +81,32 @@
// checkUpdateNotifications
//
this.checkUpdateNotifications.AutoSize = true;
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 415);
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
this.checkUpdateNotifications.Font = new System.Drawing.Font("Segoe UI", 9F);
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 393);
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 = 15;
this.checkUpdateNotifications.Size = new System.Drawing.Size(182, 19);
this.checkUpdateNotifications.TabIndex = 13;
this.checkUpdateNotifications.Text = "Check Updates Automatically";
this.checkUpdateNotifications.UseVisualStyleBackColor = true;
//
// btnCheckUpdates
//
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 438);
this.btnCheckUpdates.AutoSize = true;
this.btnCheckUpdates.Font = new System.Drawing.Font("Segoe UI", 9F);
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 417);
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 = 16;
this.btnCheckUpdates.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.btnCheckUpdates.Size = new System.Drawing.Size(128, 25);
this.btnCheckUpdates.TabIndex = 14;
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);
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";
@@ -97,10 +118,11 @@
// checkBestImageQuality
//
this.checkBestImageQuality.AutoSize = true;
this.checkBestImageQuality.Location = new System.Drawing.Point(6, 95);
this.checkBestImageQuality.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
this.checkBestImageQuality.Font = new System.Drawing.Font("Segoe UI", 9F);
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.Size = new System.Drawing.Size(125, 19);
this.checkBestImageQuality.TabIndex = 4;
this.checkBestImageQuality.Text = "Best Image Quality";
this.checkBestImageQuality.UseVisualStyleBackColor = true;
@@ -108,10 +130,11 @@
// checkOpenSearchInFirstColumn
//
this.checkOpenSearchInFirstColumn.AutoSize = true;
this.checkOpenSearchInFirstColumn.Location = new System.Drawing.Point(6, 49);
this.checkOpenSearchInFirstColumn.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
this.checkOpenSearchInFirstColumn.Font = new System.Drawing.Font("Segoe UI", 9F);
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.Size = new System.Drawing.Size(245, 19);
this.checkOpenSearchInFirstColumn.TabIndex = 2;
this.checkOpenSearchInFirstColumn.Text = "Add Search Columns Before First Column";
this.checkOpenSearchInFirstColumn.UseVisualStyleBackColor = true;
@@ -134,11 +157,12 @@
// labelZoom
//
this.labelZoom.AutoSize = true;
this.labelZoom.Location = new System.Drawing.Point(3, 320);
this.labelZoom.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelZoom.Location = new System.Drawing.Point(3, 155);
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 = 12;
this.labelZoom.Size = new System.Drawing.Size(39, 15);
this.labelZoom.TabIndex = 6;
this.labelZoom.Text = "Zoom";
//
// zoomUpdateTimer
@@ -149,32 +173,32 @@
// 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 Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelUI.Location = new System.Drawing.Point(0, 0);
this.labelUI.Margin = new System.Windows.Forms.Padding(0);
this.labelUI.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelUI.Name = "labelUI";
this.labelUI.Size = new System.Drawing.Size(111, 20);
this.labelUI.Size = new System.Drawing.Size(118, 19);
this.labelUI.TabIndex = 0;
this.labelUI.Text = "User Interface";
this.labelUI.Text = "USER INTERFACE";
//
// panelZoom
//
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, 333);
this.panelZoom.Margin = new System.Windows.Forms.Padding(0);
this.panelZoom.Location = new System.Drawing.Point(0, 171);
this.panelZoom.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
this.panelZoom.Name = "panelZoom";
this.panelZoom.Size = new System.Drawing.Size(322, 36);
this.panelZoom.TabIndex = 13;
this.panelZoom.Size = new System.Drawing.Size(300, 35);
this.panelZoom.TabIndex = 7;
//
// checkAnimatedAvatars
//
this.checkAnimatedAvatars.AutoSize = true;
this.checkAnimatedAvatars.Location = new System.Drawing.Point(6, 118);
this.checkAnimatedAvatars.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
this.checkAnimatedAvatars.Font = new System.Drawing.Font("Segoe UI", 9F);
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.Size = new System.Drawing.Size(158, 19);
this.checkAnimatedAvatars.TabIndex = 5;
this.checkAnimatedAvatars.Text = "Enable Animated Avatars";
this.checkAnimatedAvatars.UseVisualStyleBackColor = true;
@@ -182,127 +206,306 @@
// 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, 389);
this.labelUpdates.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
this.labelUpdates.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelUpdates.Location = new System.Drawing.Point(0, 367);
this.labelUpdates.Margin = new System.Windows.Forms.Padding(0, 30, 0, 1);
this.labelUpdates.Name = "labelUpdates";
this.labelUpdates.Size = new System.Drawing.Size(70, 20);
this.labelUpdates.TabIndex = 14;
this.labelUpdates.Text = "Updates";
this.labelUpdates.Size = new System.Drawing.Size(69, 19);
this.labelUpdates.TabIndex = 12;
this.labelUpdates.Text = "UPDATES";
//
// flowPanel
// flowPanelLeft
//
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.labelUI);
this.flowPanel.Controls.Add(this.checkExpandLinks);
this.flowPanel.Controls.Add(this.checkOpenSearchInFirstColumn);
this.flowPanel.Controls.Add(this.checkKeepLikeFollowDialogsOpen);
this.flowPanel.Controls.Add(this.checkBestImageQuality);
this.flowPanel.Controls.Add(this.checkAnimatedAvatars);
this.flowPanel.Controls.Add(this.labelBrowserSettings);
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);
this.flowPanel.Controls.Add(this.checkUpdateNotifications);
this.flowPanel.Controls.Add(this.btnCheckUpdates);
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, 462);
this.flowPanel.TabIndex = 0;
this.flowPanel.WrapContents = false;
this.flowPanelLeft.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.flowPanelLeft.Controls.Add(this.labelUI);
this.flowPanelLeft.Controls.Add(this.checkExpandLinks);
this.flowPanelLeft.Controls.Add(this.checkOpenSearchInFirstColumn);
this.flowPanelLeft.Controls.Add(this.checkKeepLikeFollowDialogsOpen);
this.flowPanelLeft.Controls.Add(this.checkBestImageQuality);
this.flowPanelLeft.Controls.Add(this.checkAnimatedAvatars);
this.flowPanelLeft.Controls.Add(this.labelZoom);
this.flowPanelLeft.Controls.Add(this.panelZoom);
this.flowPanelLeft.Controls.Add(this.labelTray);
this.flowPanelLeft.Controls.Add(this.comboBoxTrayType);
this.flowPanelLeft.Controls.Add(this.labelTrayIcon);
this.flowPanelLeft.Controls.Add(this.checkTrayHighlight);
this.flowPanelLeft.Controls.Add(this.labelUpdates);
this.flowPanelLeft.Controls.Add(this.checkUpdateNotifications);
this.flowPanelLeft.Controls.Add(this.btnCheckUpdates);
this.flowPanelLeft.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowPanelLeft.Location = new System.Drawing.Point(9, 9);
this.flowPanelLeft.Name = "flowPanelLeft";
this.flowPanelLeft.Size = new System.Drawing.Size(300, 462);
this.flowPanelLeft.TabIndex = 0;
this.flowPanelLeft.WrapContents = false;
//
// checkKeepLikeFollowDialogsOpen
//
this.checkKeepLikeFollowDialogsOpen.AutoSize = true;
this.checkKeepLikeFollowDialogsOpen.Location = new System.Drawing.Point(6, 72);
this.checkKeepLikeFollowDialogsOpen.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
this.checkKeepLikeFollowDialogsOpen.Font = new System.Drawing.Font("Segoe UI", 9F);
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.Size = new System.Drawing.Size(190, 19);
this.checkKeepLikeFollowDialogsOpen.TabIndex = 3;
this.checkKeepLikeFollowDialogsOpen.Text = "Keep Like/Follow Dialogs Open";
this.checkKeepLikeFollowDialogsOpen.UseVisualStyleBackColor = true;
//
// labelTray
//
this.labelTray.AutoSize = true;
this.labelTray.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelTray.Location = new System.Drawing.Point(0, 236);
this.labelTray.Margin = new System.Windows.Forms.Padding(0, 30, 0, 1);
this.labelTray.Name = "labelTray";
this.labelTray.Size = new System.Drawing.Size(99, 19);
this.labelTray.TabIndex = 8;
this.labelTray.Text = "SYSTEM TRAY";
//
// comboBoxTrayType
//
this.comboBoxTrayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxTrayType.Font = new System.Drawing.Font("Segoe UI", 9F);
this.comboBoxTrayType.FormattingEnabled = true;
this.comboBoxTrayType.Location = new System.Drawing.Point(5, 260);
this.comboBoxTrayType.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.comboBoxTrayType.Name = "comboBoxTrayType";
this.comboBoxTrayType.Size = new System.Drawing.Size(144, 23);
this.comboBoxTrayType.TabIndex = 9;
//
// labelTrayIcon
//
this.labelTrayIcon.AutoSize = true;
this.labelTrayIcon.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelTrayIcon.Location = new System.Drawing.Point(3, 295);
this.labelTrayIcon.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
this.labelTrayIcon.Name = "labelTrayIcon";
this.labelTrayIcon.Size = new System.Drawing.Size(56, 15);
this.labelTrayIcon.TabIndex = 10;
this.labelTrayIcon.Text = "Tray Icon";
//
// checkTrayHighlight
//
this.checkTrayHighlight.AutoSize = true;
this.checkTrayHighlight.Font = new System.Drawing.Font("Segoe UI", 9F);
this.checkTrayHighlight.Location = new System.Drawing.Point(6, 316);
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
this.checkTrayHighlight.Name = "checkTrayHighlight";
this.checkTrayHighlight.Size = new System.Drawing.Size(114, 19);
this.checkTrayHighlight.TabIndex = 11;
this.checkTrayHighlight.Text = "Enable Highlight";
this.checkTrayHighlight.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, 158);
this.labelBrowserSettings.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
this.labelBrowserSettings.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelBrowserSettings.Location = new System.Drawing.Point(0, 0);
this.labelBrowserSettings.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelBrowserSettings.Name = "labelBrowserSettings";
this.labelBrowserSettings.Size = new System.Drawing.Size(130, 20);
this.labelBrowserSettings.TabIndex = 6;
this.labelBrowserSettings.Text = "Browser Settings";
this.labelBrowserSettings.Size = new System.Drawing.Size(143, 19);
this.labelBrowserSettings.TabIndex = 0;
this.labelBrowserSettings.Text = "BROWSER SETTINGS";
//
// checkSmoothScrolling
//
this.checkSmoothScrolling.AutoSize = true;
this.checkSmoothScrolling.Location = new System.Drawing.Point(6, 184);
this.checkSmoothScrolling.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
this.checkSmoothScrolling.Font = new System.Drawing.Font("Segoe UI", 9F);
this.checkSmoothScrolling.Location = new System.Drawing.Point(6, 26);
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 = 7;
this.checkSmoothScrolling.Size = new System.Drawing.Size(117, 19);
this.checkSmoothScrolling.TabIndex = 1;
this.checkSmoothScrolling.Text = "Smooth Scrolling";
this.checkSmoothScrolling.UseVisualStyleBackColor = true;
//
// checkTouchAdjustment
//
this.checkTouchAdjustment.AutoSize = true;
this.checkTouchAdjustment.Font = new System.Drawing.Font("Segoe UI", 9F);
this.checkTouchAdjustment.Location = new System.Drawing.Point(6, 50);
this.checkTouchAdjustment.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
this.checkTouchAdjustment.Name = "checkTouchAdjustment";
this.checkTouchAdjustment.Size = new System.Drawing.Size(163, 19);
this.checkTouchAdjustment.TabIndex = 2;
this.checkTouchAdjustment.Text = "Touch Screen Adjustment";
this.checkTouchAdjustment.UseVisualStyleBackColor = true;
//
// labelBrowserPath
//
this.labelBrowserPath.AutoSize = true;
this.labelBrowserPath.Location = new System.Drawing.Point(3, 216);
this.labelBrowserPath.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelBrowserPath.Location = new System.Drawing.Point(3, 107);
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 = 8;
this.labelBrowserPath.Size = new System.Drawing.Size(104, 15);
this.labelBrowserPath.TabIndex = 4;
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);
this.comboBoxBrowserPath.FormattingEnabled = true;
this.comboBoxBrowserPath.Location = new System.Drawing.Point(5, 232);
this.comboBoxBrowserPath.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
this.comboBoxBrowserPath.Location = new System.Drawing.Point(5, 126);
this.comboBoxBrowserPath.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.comboBoxBrowserPath.Name = "comboBoxBrowserPath";
this.comboBoxBrowserPath.Size = new System.Drawing.Size(173, 21);
this.comboBoxBrowserPath.TabIndex = 9;
this.comboBoxBrowserPath.Size = new System.Drawing.Size(173, 23);
this.comboBoxBrowserPath.TabIndex = 5;
//
// labelSearchEngine
//
this.labelSearchEngine.AutoSize = true;
this.labelSearchEngine.Location = new System.Drawing.Point(3, 268);
this.labelSearchEngine.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelSearchEngine.Location = new System.Drawing.Point(3, 164);
this.labelSearchEngine.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
this.labelSearchEngine.Name = "labelSearchEngine";
this.labelSearchEngine.Size = new System.Drawing.Size(77, 13);
this.labelSearchEngine.TabIndex = 10;
this.labelSearchEngine.Size = new System.Drawing.Size(82, 15);
this.labelSearchEngine.TabIndex = 6;
this.labelSearchEngine.Text = "Search Engine";
//
// comboBoxSearchEngine
//
this.comboBoxSearchEngine.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxSearchEngine.Font = new System.Drawing.Font("Segoe UI", 9F);
this.comboBoxSearchEngine.FormattingEnabled = true;
this.comboBoxSearchEngine.Location = new System.Drawing.Point(5, 284);
this.comboBoxSearchEngine.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
this.comboBoxSearchEngine.Location = new System.Drawing.Point(5, 183);
this.comboBoxSearchEngine.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.comboBoxSearchEngine.Name = "comboBoxSearchEngine";
this.comboBoxSearchEngine.Size = new System.Drawing.Size(173, 21);
this.comboBoxSearchEngine.TabIndex = 11;
this.comboBoxSearchEngine.Size = new System.Drawing.Size(173, 23);
this.comboBoxSearchEngine.TabIndex = 7;
//
// flowPanelRight
//
this.flowPanelRight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.flowPanelRight.Controls.Add(this.labelBrowserSettings);
this.flowPanelRight.Controls.Add(this.checkSmoothScrolling);
this.flowPanelRight.Controls.Add(this.checkTouchAdjustment);
this.flowPanelRight.Controls.Add(this.checkHardwareAcceleration);
this.flowPanelRight.Controls.Add(this.labelBrowserPath);
this.flowPanelRight.Controls.Add(this.comboBoxBrowserPath);
this.flowPanelRight.Controls.Add(this.labelSearchEngine);
this.flowPanelRight.Controls.Add(this.comboBoxSearchEngine);
this.flowPanelRight.Controls.Add(this.labelLocales);
this.flowPanelRight.Controls.Add(this.checkSpellCheck);
this.flowPanelRight.Controls.Add(this.labelSpellCheckLanguage);
this.flowPanelRight.Controls.Add(this.comboBoxSpellCheckLanguage);
this.flowPanelRight.Controls.Add(this.labelTranslationTarget);
this.flowPanelRight.Controls.Add(this.comboBoxTranslationTarget);
this.flowPanelRight.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowPanelRight.Location = new System.Drawing.Point(322, 9);
this.flowPanelRight.Name = "flowPanelRight";
this.flowPanelRight.Size = new System.Drawing.Size(300, 462);
this.flowPanelRight.TabIndex = 1;
this.flowPanelRight.WrapContents = false;
//
// checkHardwareAcceleration
//
this.checkHardwareAcceleration.AutoSize = true;
this.checkHardwareAcceleration.Font = new System.Drawing.Font("Segoe UI", 9F);
this.checkHardwareAcceleration.Location = new System.Drawing.Point(6, 74);
this.checkHardwareAcceleration.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
this.checkHardwareAcceleration.Name = "checkHardwareAcceleration";
this.checkHardwareAcceleration.Size = new System.Drawing.Size(146, 19);
this.checkHardwareAcceleration.TabIndex = 3;
this.checkHardwareAcceleration.Text = "Hardware Acceleration";
this.checkHardwareAcceleration.UseVisualStyleBackColor = true;
//
// labelLocales
//
this.labelLocales.AutoSize = true;
this.labelLocales.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelLocales.Location = new System.Drawing.Point(0, 236);
this.labelLocales.Margin = new System.Windows.Forms.Padding(0, 27, 0, 1);
this.labelLocales.Name = "labelLocales";
this.labelLocales.Size = new System.Drawing.Size(67, 19);
this.labelLocales.TabIndex = 8;
this.labelLocales.Text = "LOCALES";
//
// checkSpellCheck
//
this.checkSpellCheck.AutoSize = true;
this.checkSpellCheck.Font = new System.Drawing.Font("Segoe UI", 9F);
this.checkSpellCheck.Location = new System.Drawing.Point(6, 262);
this.checkSpellCheck.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
this.checkSpellCheck.Name = "checkSpellCheck";
this.checkSpellCheck.Size = new System.Drawing.Size(125, 19);
this.checkSpellCheck.TabIndex = 9;
this.checkSpellCheck.Text = "Enable Spell Check";
this.checkSpellCheck.UseVisualStyleBackColor = true;
//
// labelSpellCheckLanguage
//
this.labelSpellCheckLanguage.AutoSize = true;
this.labelSpellCheckLanguage.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelSpellCheckLanguage.Location = new System.Drawing.Point(3, 295);
this.labelSpellCheckLanguage.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
this.labelSpellCheckLanguage.Name = "labelSpellCheckLanguage";
this.labelSpellCheckLanguage.Size = new System.Drawing.Size(123, 15);
this.labelSpellCheckLanguage.TabIndex = 10;
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);
this.comboBoxSpellCheckLanguage.FormattingEnabled = true;
this.comboBoxSpellCheckLanguage.Location = new System.Drawing.Point(5, 314);
this.comboBoxSpellCheckLanguage.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.comboBoxSpellCheckLanguage.Name = "comboBoxSpellCheckLanguage";
this.comboBoxSpellCheckLanguage.Size = new System.Drawing.Size(290, 23);
this.comboBoxSpellCheckLanguage.TabIndex = 11;
//
// labelTranslationTarget
//
this.labelTranslationTarget.AutoSize = true;
this.labelTranslationTarget.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelTranslationTarget.Location = new System.Drawing.Point(3, 352);
this.labelTranslationTarget.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
this.labelTranslationTarget.Name = "labelTranslationTarget";
this.labelTranslationTarget.Size = new System.Drawing.Size(142, 15);
this.labelTranslationTarget.TabIndex = 12;
this.labelTranslationTarget.Text = "Bing Translator Language";
//
// comboBoxTranslationTarget
//
this.comboBoxTranslationTarget.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxTranslationTarget.Font = new System.Drawing.Font("Segoe UI", 9F);
this.comboBoxTranslationTarget.FormattingEnabled = true;
this.comboBoxTranslationTarget.Location = new System.Drawing.Point(5, 371);
this.comboBoxTranslationTarget.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.comboBoxTranslationTarget.Name = "comboBoxTranslationTarget";
this.comboBoxTranslationTarget.Size = new System.Drawing.Size(290, 23);
this.comboBoxTranslationTarget.TabIndex = 13;
//
// panelSeparator
//
this.panelSeparator.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.panelSeparator.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(200)))), ((int)(((byte)(200)))), ((int)(((byte)(200)))));
this.panelSeparator.Location = new System.Drawing.Point(312, 0);
this.panelSeparator.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
this.panelSeparator.Name = "panelSeparator";
this.panelSeparator.Size = new System.Drawing.Size(1, 480);
this.panelSeparator.TabIndex = 2;
//
// TabSettingsGeneral
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flowPanel);
this.Controls.Add(this.panelSeparator);
this.Controls.Add(this.flowPanelRight);
this.Controls.Add(this.flowPanelLeft);
this.Name = "TabSettingsGeneral";
this.Size = new System.Drawing.Size(340, 480);
this.Size = new System.Drawing.Size(631, 480);
((System.ComponentModel.ISupportInitialize)(this.trackBarZoom)).EndInit();
this.panelZoom.ResumeLayout(false);
this.flowPanel.ResumeLayout(false);
this.flowPanel.PerformLayout();
this.flowPanelLeft.ResumeLayout(false);
this.flowPanelLeft.PerformLayout();
this.flowPanelRight.ResumeLayout(false);
this.flowPanelRight.PerformLayout();
this.ResumeLayout(false);
}
@@ -323,7 +526,7 @@
private System.Windows.Forms.CheckBox checkBestImageQuality;
private System.Windows.Forms.CheckBox checkOpenSearchInFirstColumn;
private System.Windows.Forms.CheckBox checkAnimatedAvatars;
private System.Windows.Forms.FlowLayoutPanel flowPanel;
private System.Windows.Forms.FlowLayoutPanel flowPanelLeft;
private System.Windows.Forms.CheckBox checkKeepLikeFollowDialogsOpen;
private System.Windows.Forms.Label labelBrowserPath;
private System.Windows.Forms.ComboBox comboBoxBrowserPath;
@@ -331,5 +534,19 @@
private System.Windows.Forms.CheckBox checkSmoothScrolling;
private System.Windows.Forms.Label labelSearchEngine;
private System.Windows.Forms.ComboBox comboBoxSearchEngine;
private System.Windows.Forms.CheckBox checkTouchAdjustment;
private System.Windows.Forms.FlowLayoutPanel flowPanelRight;
private System.Windows.Forms.Panel panelSeparator;
private System.Windows.Forms.Label labelTray;
private System.Windows.Forms.ComboBox comboBoxTrayType;
private System.Windows.Forms.Label labelTrayIcon;
private System.Windows.Forms.CheckBox checkTrayHighlight;
private System.Windows.Forms.Label labelLocales;
private System.Windows.Forms.CheckBox checkSpellCheck;
private System.Windows.Forms.Label labelSpellCheckLanguage;
private System.Windows.Forms.ComboBox comboBoxSpellCheckLanguage;
private System.Windows.Forms.Label labelTranslationTarget;
private System.Windows.Forms.ComboBox comboBoxTranslationTarget;
private System.Windows.Forms.CheckBox checkHardwareAcceleration;
}
}

View File

@@ -7,7 +7,6 @@ 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{
@@ -29,29 +28,61 @@ namespace TweetDuck.Core.Other.Settings{
this.updates = updates;
this.updates.CheckFinished += updates_CheckFinished;
Disposed += (sender, args) => this.updates.CheckFinished -= updates_CheckFinished;
// user interface
toolTip.SetToolTip(checkExpandLinks, "Expands links inside the tweets. If disabled,\r\nthe full links show up in a tooltip instead.");
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).");
toolTip.SetToolTip(checkAnimatedAvatars, "Some old Twitter avatars could be uploaded as animated GIFs.");
toolTip.SetToolTip(checkSmoothScrolling, "Toggles smooth mouse wheel scrolling.");
toolTip.SetToolTip(comboBoxBrowserPath, "Sets the default browser for opening links.");
toolTip.SetToolTip(labelZoomValue, "Changes the zoom level.\r\nAlso affects notifications and screenshots.");
toolTip.SetToolTip(trackBarZoom, toolTip.GetToolTip(labelZoomValue));
toolTip.SetToolTip(checkUpdateNotifications, "Checks for updates every hour.\r\nIf an update is dismissed, it will not appear again.");
toolTip.SetToolTip(btnCheckUpdates, "Forces an update check, even for updates that had been dismissed.");
checkExpandLinks.Checked = Config.ExpandLinksOnHover;
checkOpenSearchInFirstColumn.Checked = Config.OpenSearchInFirstColumn;
checkKeepLikeFollowDialogsOpen.Checked = Config.KeepLikeFollowDialogsOpen;
checkBestImageQuality.Checked = Config.BestImageQuality;
checkAnimatedAvatars.Checked = Config.EnableAnimatedImages;
trackBarZoom.SetValueSafe(Config.ZoomLevel);
labelZoomValue.Text = trackBarZoom.Value+"%";
// system tray
toolTip.SetToolTip(comboBoxTrayType, "Changes behavior of the Tray icon.\r\nRight-click the icon for an action menu.");
toolTip.SetToolTip(checkTrayHighlight, "Highlights the tray icon if there are new tweets.\r\nOnly works for columns with popup or audio notifications.\r\nThe icon resets when the main window is restored.");
comboBoxTrayType.Items.Add("Disabled");
comboBoxTrayType.Items.Add("Display Icon Only");
comboBoxTrayType.Items.Add("Minimize to Tray");
comboBoxTrayType.Items.Add("Close to Tray");
comboBoxTrayType.Items.Add("Combined");
comboBoxTrayType.SelectedIndex = Math.Min(Math.Max((int)Config.TrayBehavior, 0), comboBoxTrayType.Items.Count-1);
checkTrayHighlight.Enabled = Config.TrayBehavior.ShouldDisplayIcon();
checkTrayHighlight.Checked = Config.EnableTrayHighlight;
// updates
toolTip.SetToolTip(checkUpdateNotifications, "Checks for updates every hour.\r\nIf an update is dismissed, it will not appear again.");
toolTip.SetToolTip(btnCheckUpdates, "Forces an update check, even for updates that had been dismissed.");
checkUpdateNotifications.Checked = Config.EnableUpdateCheck;
// browser settings
toolTip.SetToolTip(checkSmoothScrolling, "Toggles smooth mouse wheel scrolling.");
toolTip.SetToolTip(checkTouchAdjustment, "Toggles Chromium touch screen adjustment.\r\nDisabled by default, because it is very imprecise with TweetDeck.");
toolTip.SetToolTip(checkHardwareAcceleration, "Uses graphics card to improve performance.\r\nDisable if you experience visual glitches, or to save a small amount of RAM.");
toolTip.SetToolTip(comboBoxBrowserPath, "Sets the default browser for opening links.");
toolTip.SetToolTip(comboBoxSearchEngine, "Sets the default website for opening searches.");
checkSmoothScrolling.Checked = Config.EnableSmoothScrolling;
checkTouchAdjustment.Checked = Config.EnableTouchAdjustment;
checkHardwareAcceleration.Checked = SysConfig.HardwareAcceleration;
foreach(WindowsUtils.Browser browserInfo in WindowsUtils.FindInstalledBrowsers()){
comboBoxBrowserPath.Items.Add(browserInfo);
@@ -68,11 +99,30 @@ namespace TweetDuck.Core.Other.Settings{
searchEngineIndexDefault = comboBoxSearchEngine.Items.Add("(no engine set)");
searchEngineIndexCustom = comboBoxSearchEngine.Items.Add("(custom url...)");
UpdateSearchEngineSelection();
trackBarZoom.SetValueSafe(Config.ZoomLevel);
labelZoomValue.Text = trackBarZoom.Value+"%";
checkUpdateNotifications.Checked = Config.EnableUpdateCheck;
// locales
toolTip.SetToolTip(checkSpellCheck, "Underlines words that are spelled incorrectly.");
toolTip.SetToolTip(comboBoxSpellCheckLanguage, "Language used for spell check.");
toolTip.SetToolTip(comboBoxTranslationTarget, "Language tweets are translated into.");
checkSpellCheck.Checked = Config.EnableSpellCheck;
try{
foreach(LocaleUtils.Item item in LocaleUtils.SpellCheckLanguages){
comboBoxSpellCheckLanguage.Items.Add(item);
}
}catch{
comboBoxSpellCheckLanguage.Items.Add(new LocaleUtils.Item("en-US"));
}
comboBoxSpellCheckLanguage.SelectedItem = new LocaleUtils.Item(Config.SpellCheckLanguage);
foreach(LocaleUtils.Item item in LocaleUtils.TweetDeckTranslationLocales){
comboBoxTranslationTarget.Items.Add(item);
}
comboBoxTranslationTarget.SelectedItem = new LocaleUtils.Item(Config.TranslationTarget);
}
public override void OnReady(){
@@ -81,20 +131,31 @@ namespace TweetDuck.Core.Other.Settings{
checkKeepLikeFollowDialogsOpen.CheckedChanged += checkKeepLikeFollowDialogsOpen_CheckedChanged;
checkBestImageQuality.CheckedChanged += checkBestImageQuality_CheckedChanged;
checkAnimatedAvatars.CheckedChanged += checkAnimatedAvatars_CheckedChanged;
checkSmoothScrolling.CheckedChanged += checkSmoothScrolling_CheckedChanged;
comboBoxBrowserPath.SelectedIndexChanged += comboBoxBrowserPath_SelectedIndexChanged;
comboBoxSearchEngine.SelectedIndexChanged += comboBoxSearchEngine_SelectedIndexChanged;
trackBarZoom.ValueChanged += trackBarZoom_ValueChanged;
comboBoxTrayType.SelectedIndexChanged += comboBoxTrayType_SelectedIndexChanged;
checkTrayHighlight.CheckedChanged += checkTrayHighlight_CheckedChanged;
checkUpdateNotifications.CheckedChanged += checkUpdateNotifications_CheckedChanged;
btnCheckUpdates.Click += btnCheckUpdates_Click;
checkSmoothScrolling.CheckedChanged += checkSmoothScrolling_CheckedChanged;
checkTouchAdjustment.CheckedChanged += checkTouchAdjustment_CheckedChanged;
checkHardwareAcceleration.CheckedChanged += checkHardwareAcceleration_CheckedChanged;
comboBoxBrowserPath.SelectedIndexChanged += comboBoxBrowserPath_SelectedIndexChanged;
comboBoxSearchEngine.SelectedIndexChanged += comboBoxSearchEngine_SelectedIndexChanged;
checkSpellCheck.CheckedChanged += checkSpellCheck_CheckedChanged;
comboBoxSpellCheckLanguage.SelectedValueChanged += comboBoxSpellCheckLanguage_SelectedValueChanged;
comboBoxTranslationTarget.SelectedValueChanged += comboBoxTranslationTarget_SelectedValueChanged;
}
public override void OnClosing(){
Config.ZoomLevel = trackBarZoom.Value;
}
#region User Interface
private void checkExpandLinks_CheckedChanged(object sender, EventArgs e){
Config.ExpandLinksOnHover = checkExpandLinks.Checked;
}
@@ -116,9 +177,72 @@ namespace TweetDuck.Core.Other.Settings{
BrowserProcessHandler.UpdatePrefs().ContinueWith(task => reloadColumns());
}
private void trackBarZoom_ValueChanged(object sender, EventArgs e){
if (trackBarZoom.AlignValueToTick()){
zoomUpdateTimer.Stop();
zoomUpdateTimer.Start();
labelZoomValue.Text = trackBarZoom.Value+"%";
}
}
private void zoomUpdateTimer_Tick(object sender, EventArgs e){
Config.ZoomLevel = trackBarZoom.Value;
zoomUpdateTimer.Stop();
}
#endregion
#region System Tray
private void comboBoxTrayType_SelectedIndexChanged(object sender, EventArgs e){
Config.TrayBehavior = (TrayIcon.Behavior)comboBoxTrayType.SelectedIndex;
checkTrayHighlight.Enabled = Config.TrayBehavior.ShouldDisplayIcon();
}
private void checkTrayHighlight_CheckedChanged(object sender, EventArgs e){
Config.EnableTrayHighlight = checkTrayHighlight.Checked;
}
#endregion
#region Updates
private void checkUpdateNotifications_CheckedChanged(object sender, EventArgs e){
Config.EnableUpdateCheck = checkUpdateNotifications.Checked;
}
private void btnCheckUpdates_Click(object sender, EventArgs e){
Config.DismissedUpdate = null;
btnCheckUpdates.Enabled = false;
updateCheckEventId = updates.Check(true);
}
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
if (e.EventId == updateCheckEventId){
btnCheckUpdates.Enabled = true;
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);
});
}
}
#endregion
#region Browser Settings
private void checkSmoothScrolling_CheckedChanged(object sender, EventArgs e){
Config.EnableSmoothScrolling = checkSmoothScrolling.Checked;
PromptRestart();
}
private void checkTouchAdjustment_CheckedChanged(object sender, EventArgs e){
Config.EnableTouchAdjustment = checkTouchAdjustment.Checked;
}
private void checkHardwareAcceleration_CheckedChanged(object sender, EventArgs e){
SysConfig.HardwareAcceleration = checkHardwareAcceleration.Checked;
}
private void UpdateBrowserPathSelection(){
@@ -193,51 +317,6 @@ namespace TweetDuck.Core.Other.Settings{
}
}
private void trackBarZoom_ValueChanged(object sender, EventArgs e){
if (trackBarZoom.AlignValueToTick()){
zoomUpdateTimer.Stop();
zoomUpdateTimer.Start();
labelZoomValue.Text = trackBarZoom.Value+"%";
}
}
private void checkUpdateNotifications_CheckedChanged(object sender, EventArgs e){
Config.EnableUpdateCheck = checkUpdateNotifications.Checked;
}
private void btnCheckUpdates_Click(object sender, EventArgs e){
Config.DismissedUpdate = null;
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, UpdateCheckEventArgs e){
this.InvokeAsyncSafe(() => {
if (e.EventId == updateCheckEventId){
btnCheckUpdates.Enabled = true;
e.Result.Handle(update => {
if (!update.IsUpdateNew){
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; }
@@ -251,5 +330,23 @@ namespace TweetDuck.Core.Other.Settings{
public override bool Equals(object obj) => obj is SearchEngine other && Name == other.Name;
public override string ToString() => Name;
}
#endregion
#region Locales
private void checkSpellCheck_CheckedChanged(object sender, EventArgs e){
Config.EnableSpellCheck = checkSpellCheck.Checked;
BrowserProcessHandler.UpdatePrefs();
}
private void comboBoxSpellCheckLanguage_SelectedValueChanged(object sender, EventArgs e){
Config.SpellCheckLanguage = (comboBoxSpellCheckLanguage.SelectedItem as LocaleUtils.Item)?.Code ?? "en-US";
}
private void comboBoxTranslationTarget_SelectedValueChanged(object sender, EventArgs e){
Config.TranslationTarget = (comboBoxTranslationTarget.SelectedItem as LocaleUtils.Item)?.Code ?? "en";
}
#endregion
}
}

View File

@@ -1,155 +0,0 @@
namespace TweetDuck.Core.Other.Settings {
partial class TabSettingsLocales {
/// <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 Component 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.components = new System.ComponentModel.Container();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.checkSpellCheck = new System.Windows.Forms.CheckBox();
this.labelLocales = new System.Windows.Forms.Label();
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
this.labelSpellCheckLanguage = new System.Windows.Forms.Label();
this.comboBoxSpellCheckLanguage = new System.Windows.Forms.ComboBox();
this.labelTranslations = new System.Windows.Forms.Label();
this.labelTranslationTarget = new System.Windows.Forms.Label();
this.comboBoxTranslationTarget = new System.Windows.Forms.ComboBox();
this.flowPanel.SuspendLayout();
this.SuspendLayout();
//
// checkSpellCheck
//
this.checkSpellCheck.AutoSize = true;
this.checkSpellCheck.Location = new System.Drawing.Point(6, 26);
this.checkSpellCheck.Margin = new System.Windows.Forms.Padding(6, 6, 3, 3);
this.checkSpellCheck.Name = "checkSpellCheck";
this.checkSpellCheck.Size = new System.Drawing.Size(119, 17);
this.checkSpellCheck.TabIndex = 1;
this.checkSpellCheck.Text = "Enable Spell Check";
this.checkSpellCheck.UseVisualStyleBackColor = true;
//
// 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.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.TabIndex = 0;
this.labelLocales.Text = "Locales";
//
// 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.labelLocales);
this.flowPanel.Controls.Add(this.checkSpellCheck);
this.flowPanel.Controls.Add(this.labelSpellCheckLanguage);
this.flowPanel.Controls.Add(this.comboBoxSpellCheckLanguage);
this.flowPanel.Controls.Add(this.labelTranslations);
this.flowPanel.Controls.Add(this.labelTranslationTarget);
this.flowPanel.Controls.Add(this.comboBoxTranslationTarget);
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.TabIndex = 0;
this.flowPanel.WrapContents = false;
//
// labelSpellCheckLanguage
//
this.labelSpellCheckLanguage.AutoSize = true;
this.labelSpellCheckLanguage.Location = new System.Drawing.Point(3, 58);
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.TabIndex = 2;
this.labelSpellCheckLanguage.Text = "Spell Check Language";
//
// comboBoxSpellCheckLanguage
//
this.comboBoxSpellCheckLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxSpellCheckLanguage.FormattingEnabled = true;
this.comboBoxSpellCheckLanguage.Location = new System.Drawing.Point(5, 74);
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.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.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.TabIndex = 4;
this.labelTranslations.Text = "Bing Translator";
//
// labelTranslationTarget
//
this.labelTranslationTarget.AutoSize = true;
this.labelTranslationTarget.Location = new System.Drawing.Point(3, 150);
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.TabIndex = 5;
this.labelTranslationTarget.Text = "Target Language";
//
// comboBoxTranslationTarget
//
this.comboBoxTranslationTarget.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxTranslationTarget.FormattingEnabled = true;
this.comboBoxTranslationTarget.Location = new System.Drawing.Point(5, 166);
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.TabIndex = 6;
//
// TabSettingsLocales
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flowPanel);
this.Name = "TabSettingsLocales";
this.Size = new System.Drawing.Size(340, 211);
this.flowPanel.ResumeLayout(false);
this.flowPanel.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.CheckBox checkSpellCheck;
private System.Windows.Forms.Label labelLocales;
private System.Windows.Forms.FlowLayoutPanel flowPanel;
private System.Windows.Forms.ComboBox comboBoxTranslationTarget;
private System.Windows.Forms.Label labelTranslationTarget;
private System.Windows.Forms.ComboBox comboBoxSpellCheckLanguage;
private System.Windows.Forms.Label labelTranslations;
private System.Windows.Forms.Label labelSpellCheckLanguage;
}
}

View File

@@ -1,53 +0,0 @@
using System;
using TweetDuck.Core.Handling.General;
using TweetDuck.Core.Utils;
namespace TweetDuck.Core.Other.Settings{
sealed partial class TabSettingsLocales : BaseTabSettings{
public TabSettingsLocales(){
InitializeComponent();
toolTip.SetToolTip(checkSpellCheck, "Underlines words that are spelled incorrectly.");
toolTip.SetToolTip(comboBoxSpellCheckLanguage, "Language used for spell check.");
toolTip.SetToolTip(comboBoxTranslationTarget, "Language tweets are translated into.");
checkSpellCheck.Checked = Config.EnableSpellCheck;
try{
foreach(LocaleUtils.Item item in LocaleUtils.SpellCheckLanguages){
comboBoxSpellCheckLanguage.Items.Add(item);
}
}catch{
comboBoxSpellCheckLanguage.Items.Add(new LocaleUtils.Item("en-US"));
}
comboBoxSpellCheckLanguage.SelectedItem = new LocaleUtils.Item(Config.SpellCheckLanguage);
foreach(LocaleUtils.Item item in LocaleUtils.TweetDeckTranslationLocales){
comboBoxTranslationTarget.Items.Add(item);
}
comboBoxTranslationTarget.SelectedItem = new LocaleUtils.Item(Config.TranslationTarget);
}
public override void OnReady(){
checkSpellCheck.CheckedChanged += checkSpellCheck_CheckedChanged;
comboBoxSpellCheckLanguage.SelectedValueChanged += comboBoxSpellCheckLanguage_SelectedValueChanged;
comboBoxTranslationTarget.SelectedValueChanged += comboBoxTranslationTarget_SelectedValueChanged;
}
private void checkSpellCheck_CheckedChanged(object sender, EventArgs e){
Config.EnableSpellCheck = checkSpellCheck.Checked;
BrowserProcessHandler.UpdatePrefs();
}
private void comboBoxSpellCheckLanguage_SelectedValueChanged(object sender, EventArgs e){
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 ?? "en";
}
}
}

View File

@@ -64,8 +64,10 @@
this.labelSize = new System.Windows.Forms.Label();
this.panelSize = new System.Windows.Forms.Panel();
this.durationUpdateTimer = new System.Windows.Forms.Timer(this.components);
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
this.flowPanelLeft = new System.Windows.Forms.FlowLayoutPanel();
this.panelScrollSpeed = new System.Windows.Forms.Panel();
this.flowPanelRight = new System.Windows.Forms.FlowLayoutPanel();
this.panelSeparator = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.trackBarEdgeDistance)).BeginInit();
this.tableLayoutDurationButtons.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBarDuration)).BeginInit();
@@ -74,16 +76,18 @@
this.panelLocation.SuspendLayout();
this.panelTimer.SuspendLayout();
this.panelSize.SuspendLayout();
this.flowPanel.SuspendLayout();
this.flowPanelLeft.SuspendLayout();
this.panelScrollSpeed.SuspendLayout();
this.flowPanelRight.SuspendLayout();
this.SuspendLayout();
//
// labelEdgeDistanceValue
//
this.labelEdgeDistanceValue.Font = new System.Drawing.Font("Segoe UI", 9F);
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 +95,43 @@
// labelDisplay
//
this.labelDisplay.AutoSize = true;
this.labelDisplay.Location = new System.Drawing.Point(3, 451);
this.labelDisplay.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelDisplay.Location = new System.Drawing.Point(3, 83);
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.TabIndex = 15;
this.labelDisplay.Size = new System.Drawing.Size(46, 15);
this.labelDisplay.TabIndex = 2;
this.labelDisplay.Text = "Display";
//
// comboBoxDisplay
//
this.comboBoxDisplay.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxDisplay.Font = new System.Drawing.Font("Segoe UI", 9F);
this.comboBoxDisplay.FormattingEnabled = true;
this.comboBoxDisplay.Location = new System.Drawing.Point(5, 467);
this.comboBoxDisplay.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
this.comboBoxDisplay.Location = new System.Drawing.Point(5, 102);
this.comboBoxDisplay.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.comboBoxDisplay.Name = "comboBoxDisplay";
this.comboBoxDisplay.Size = new System.Drawing.Size(144, 21);
this.comboBoxDisplay.TabIndex = 16;
this.comboBoxDisplay.Size = new System.Drawing.Size(144, 23);
this.comboBoxDisplay.TabIndex = 3;
//
// labelEdgeDistance
//
this.labelEdgeDistance.AutoSize = true;
this.labelEdgeDistance.Location = new System.Drawing.Point(3, 503);
this.labelEdgeDistance.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelEdgeDistance.Location = new System.Drawing.Point(3, 140);
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.TabIndex = 17;
this.labelEdgeDistance.Size = new System.Drawing.Size(113, 15);
this.labelEdgeDistance.TabIndex = 4;
this.labelEdgeDistance.Text = "Distance From Edge";
//
// radioLocCustom
//
this.radioLocCustom.Location = new System.Drawing.Point(205, 4);
this.radioLocCustom.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
this.radioLocCustom.Font = new System.Drawing.Font("Segoe UI", 9F);
this.radioLocCustom.Location = new System.Drawing.Point(218, 4);
this.radioLocCustom.Margin = new System.Windows.Forms.Padding(10, 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 +139,11 @@
//
// radioLocBR
//
this.radioLocBR.Location = new System.Drawing.Point(105, 28);
this.radioLocBR.Font = new System.Drawing.Font("Segoe UI", 9F);
this.radioLocBR.Location = new System.Drawing.Point(109, 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(96, 19);
this.radioLocBR.TabIndex = 3;
this.radioLocBR.TabStop = true;
this.radioLocBR.Text = "Bottom Right";
@@ -142,10 +151,11 @@
//
// radioLocBL
//
this.radioLocBL.Font = new System.Drawing.Font("Segoe UI", 9F);
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(96, 19);
this.radioLocBL.TabIndex = 2;
this.radioLocBL.TabStop = true;
this.radioLocBL.Text = "Bottom Left";
@@ -153,10 +163,11 @@
//
// radioLocTR
//
this.radioLocTR.Location = new System.Drawing.Point(105, 4);
this.radioLocTR.Font = new System.Drawing.Font("Segoe UI", 9F);
this.radioLocTR.Location = new System.Drawing.Point(109, 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(96, 19);
this.radioLocTR.TabIndex = 1;
this.radioLocTR.TabStop = true;
this.radioLocTR.Text = "Top Right";
@@ -164,10 +175,11 @@
//
// radioLocTL
//
this.radioLocTL.Font = new System.Drawing.Font("Segoe UI", 9F);
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(96, 19);
this.radioLocTL.TabIndex = 0;
this.radioLocTL.TabStop = true;
this.radioLocTL.Text = "Top Left";
@@ -196,11 +208,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, 353);
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 +222,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);
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 +238,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);
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 +254,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);
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 +266,11 @@
// labelDurationValue
//
this.labelDurationValue.BackColor = System.Drawing.Color.Transparent;
this.labelDurationValue.Font = new System.Drawing.Font("Segoe UI", 9F);
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 +290,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);
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 +302,11 @@
// checkColumnName
//
this.checkColumnName.AutoSize = true;
this.checkColumnName.Font = new System.Drawing.Font("Segoe UI", 9F);
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 +314,33 @@
// labelIdlePause
//
this.labelIdlePause.AutoSize = true;
this.labelIdlePause.Location = new System.Drawing.Point(3, 127);
this.labelIdlePause.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
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(95, 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);
this.comboBoxIdlePause.FormattingEnabled = true;
this.comboBoxIdlePause.Location = new System.Drawing.Point(5, 143);
this.comboBoxIdlePause.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
this.comboBoxIdlePause.Location = new System.Drawing.Point(5, 150);
this.comboBoxIdlePause.Margin = new System.Windows.Forms.Padding(5, 4, 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);
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 +348,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);
this.checkTimerCountDown.Location = new System.Drawing.Point(6, 266);
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 +360,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);
this.checkNotificationTimer.Location = new System.Drawing.Point(6, 242);
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);
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 +383,11 @@
//
// radioSizeCustom
//
this.radioSizeCustom.Font = new System.Drawing.Font("Segoe UI", 9F);
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,42 +396,43 @@
// 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 Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelGeneral.Location = new System.Drawing.Point(0, 0);
this.labelGeneral.Margin = new System.Windows.Forms.Padding(0);
this.labelGeneral.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelGeneral.Name = "labelGeneral";
this.labelGeneral.Size = new System.Drawing.Size(66, 20);
this.labelGeneral.Size = new System.Drawing.Size(69, 19);
this.labelGeneral.TabIndex = 0;
this.labelGeneral.Text = "General";
this.labelGeneral.Text = "GENERAL";
//
// panelEdgeDistance
//
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.Margin = new System.Windows.Forms.Padding(0);
this.panelEdgeDistance.Location = new System.Drawing.Point(0, 156);
this.panelEdgeDistance.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
this.panelEdgeDistance.Name = "panelEdgeDistance";
this.panelEdgeDistance.Size = new System.Drawing.Size(322, 36);
this.panelEdgeDistance.TabIndex = 18;
this.panelEdgeDistance.Size = new System.Drawing.Size(300, 35);
this.panelEdgeDistance.TabIndex = 5;
//
// 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);
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);
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,151 +454,171 @@
// labelScrollSpeed
//
this.labelScrollSpeed.AutoSize = true;
this.labelScrollSpeed.Location = new System.Drawing.Point(3, 629);
this.labelScrollSpeed.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelScrollSpeed.Location = new System.Drawing.Point(3, 275);
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.TabIndex = 21;
this.labelScrollSpeed.Size = new System.Drawing.Size(73, 15);
this.labelScrollSpeed.TabIndex = 8;
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.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
this.labelLocation.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelLocation.Location = new System.Drawing.Point(0, 0);
this.labelLocation.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelLocation.Name = "labelLocation";
this.labelLocation.Size = new System.Drawing.Size(70, 20);
this.labelLocation.TabIndex = 13;
this.labelLocation.Text = "Location";
this.labelLocation.Size = new System.Drawing.Size(79, 19);
this.labelLocation.TabIndex = 0;
this.labelLocation.Text = "LOCATION";
//
// panelLocation
//
this.panelLocation.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.panelLocation.Controls.Add(this.radioLocTL);
this.panelLocation.Controls.Add(this.radioLocTR);
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, 20);
this.panelLocation.Margin = new System.Windows.Forms.Padding(0);
this.panelLocation.Name = "panelLocation";
this.panelLocation.Size = new System.Drawing.Size(322, 49);
this.panelLocation.TabIndex = 14;
this.panelLocation.Size = new System.Drawing.Size(300, 51);
this.panelLocation.TabIndex = 1;
//
// panelTimer
//
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.Margin = new System.Windows.Forms.Padding(0);
this.panelTimer.Location = new System.Drawing.Point(0, 315);
this.panelTimer.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
this.panelTimer.Name = "panelTimer";
this.panelTimer.Size = new System.Drawing.Size(322, 36);
this.panelTimer.Size = new System.Drawing.Size(300, 35);
this.panelTimer.TabIndex = 11;
//
// labelDuration
//
this.labelDuration.AutoSize = true;
this.labelDuration.Location = new System.Drawing.Point(3, 268);
this.labelDuration.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
this.labelDuration.Location = new System.Drawing.Point(3, 299);
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(54, 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.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
this.labelTimer.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelTimer.Location = new System.Drawing.Point(0, 216);
this.labelTimer.Margin = new System.Windows.Forms.Padding(0, 40, 0, 1);
this.labelTimer.Name = "labelTimer";
this.labelTimer.Size = new System.Drawing.Size(48, 20);
this.labelTimer.Size = new System.Drawing.Size(50, 19);
this.labelTimer.TabIndex = 7;
this.labelTimer.Text = "Timer";
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.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
this.labelSize.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelSize.Location = new System.Drawing.Point(0, 216);
this.labelSize.Margin = new System.Windows.Forms.Padding(0, 25, 0, 1);
this.labelSize.Name = "labelSize";
this.labelSize.Size = new System.Drawing.Size(40, 20);
this.labelSize.TabIndex = 19;
this.labelSize.Text = "Size";
this.labelSize.Size = new System.Drawing.Size(36, 19);
this.labelSize.TabIndex = 6;
this.labelSize.Text = "SIZE";
//
// panelSize
//
this.panelSize.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| 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, 236);
this.panelSize.Margin = new System.Windows.Forms.Padding(0);
this.panelSize.Name = "panelSize";
this.panelSize.Size = new System.Drawing.Size(322, 25);
this.panelSize.TabIndex = 20;
this.panelSize.Size = new System.Drawing.Size(300, 27);
this.panelSize.TabIndex = 7;
//
// durationUpdateTimer
//
this.durationUpdateTimer.Interval = 200;
this.durationUpdateTimer.Tick += new System.EventHandler(this.durationUpdateTimer_Tick);
//
// flowPanel
// flowPanelLeft
//
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.labelGeneral);
this.flowPanel.Controls.Add(this.checkColumnName);
this.flowPanel.Controls.Add(this.checkMediaPreviews);
this.flowPanel.Controls.Add(this.checkSkipOnLinkClick);
this.flowPanel.Controls.Add(this.checkNonIntrusive);
this.flowPanel.Controls.Add(this.labelIdlePause);
this.flowPanel.Controls.Add(this.comboBoxIdlePause);
this.flowPanel.Controls.Add(this.labelTimer);
this.flowPanel.Controls.Add(this.checkNotificationTimer);
this.flowPanel.Controls.Add(this.checkTimerCountDown);
this.flowPanel.Controls.Add(this.labelDuration);
this.flowPanel.Controls.Add(this.panelTimer);
this.flowPanel.Controls.Add(this.tableLayoutDurationButtons);
this.flowPanel.Controls.Add(this.labelLocation);
this.flowPanel.Controls.Add(this.panelLocation);
this.flowPanel.Controls.Add(this.labelDisplay);
this.flowPanel.Controls.Add(this.comboBoxDisplay);
this.flowPanel.Controls.Add(this.labelEdgeDistance);
this.flowPanel.Controls.Add(this.panelEdgeDistance);
this.flowPanel.Controls.Add(this.labelSize);
this.flowPanel.Controls.Add(this.panelSize);
this.flowPanel.Controls.Add(this.labelScrollSpeed);
this.flowPanel.Controls.Add(this.panelScrollSpeed);
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.TabIndex = 0;
this.flowPanel.WrapContents = false;
this.flowPanelLeft.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.flowPanelLeft.Controls.Add(this.labelGeneral);
this.flowPanelLeft.Controls.Add(this.checkColumnName);
this.flowPanelLeft.Controls.Add(this.checkMediaPreviews);
this.flowPanelLeft.Controls.Add(this.checkSkipOnLinkClick);
this.flowPanelLeft.Controls.Add(this.checkNonIntrusive);
this.flowPanelLeft.Controls.Add(this.labelIdlePause);
this.flowPanelLeft.Controls.Add(this.comboBoxIdlePause);
this.flowPanelLeft.Controls.Add(this.labelTimer);
this.flowPanelLeft.Controls.Add(this.checkNotificationTimer);
this.flowPanelLeft.Controls.Add(this.checkTimerCountDown);
this.flowPanelLeft.Controls.Add(this.labelDuration);
this.flowPanelLeft.Controls.Add(this.panelTimer);
this.flowPanelLeft.Controls.Add(this.tableLayoutDurationButtons);
this.flowPanelLeft.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowPanelLeft.Location = new System.Drawing.Point(9, 9);
this.flowPanelLeft.Name = "flowPanelLeft";
this.flowPanelLeft.Size = new System.Drawing.Size(300, 461);
this.flowPanelLeft.TabIndex = 0;
this.flowPanelLeft.WrapContents = false;
//
// panelScrollSpeed
//
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.Margin = new System.Windows.Forms.Padding(0);
this.panelScrollSpeed.Location = new System.Drawing.Point(0, 291);
this.panelScrollSpeed.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
this.panelScrollSpeed.Name = "panelScrollSpeed";
this.panelScrollSpeed.Size = new System.Drawing.Size(322, 36);
this.panelScrollSpeed.TabIndex = 22;
this.panelScrollSpeed.Size = new System.Drawing.Size(300, 35);
this.panelScrollSpeed.TabIndex = 9;
//
// flowPanelRight
//
this.flowPanelRight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.flowPanelRight.Controls.Add(this.labelLocation);
this.flowPanelRight.Controls.Add(this.panelLocation);
this.flowPanelRight.Controls.Add(this.labelDisplay);
this.flowPanelRight.Controls.Add(this.comboBoxDisplay);
this.flowPanelRight.Controls.Add(this.labelEdgeDistance);
this.flowPanelRight.Controls.Add(this.panelEdgeDistance);
this.flowPanelRight.Controls.Add(this.labelSize);
this.flowPanelRight.Controls.Add(this.panelSize);
this.flowPanelRight.Controls.Add(this.labelScrollSpeed);
this.flowPanelRight.Controls.Add(this.panelScrollSpeed);
this.flowPanelRight.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowPanelRight.Location = new System.Drawing.Point(322, 9);
this.flowPanelRight.Name = "flowPanelRight";
this.flowPanelRight.Size = new System.Drawing.Size(300, 461);
this.flowPanelRight.TabIndex = 1;
this.flowPanelRight.WrapContents = false;
//
// panelSeparator
//
this.panelSeparator.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.panelSeparator.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(200)))), ((int)(((byte)(200)))), ((int)(((byte)(200)))));
this.panelSeparator.Location = new System.Drawing.Point(312, 0);
this.panelSeparator.Margin = new System.Windows.Forms.Padding(0, 0, 6, 0);
this.panelSeparator.Name = "panelSeparator";
this.panelSeparator.Size = new System.Drawing.Size(1, 480);
this.panelSeparator.TabIndex = 2;
//
// TabSettingsNotifications
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flowPanel);
this.Controls.Add(this.flowPanelRight);
this.Controls.Add(this.flowPanelLeft);
this.Controls.Add(this.panelSeparator);
this.Name = "TabSettingsNotifications";
this.Size = new System.Drawing.Size(340, 697);
this.Size = new System.Drawing.Size(631, 480);
this.ParentChanged += new System.EventHandler(this.TabSettingsNotifications_ParentChanged);
((System.ComponentModel.ISupportInitialize)(this.trackBarEdgeDistance)).EndInit();
this.tableLayoutDurationButtons.ResumeLayout(false);
@@ -582,9 +628,11 @@
this.panelLocation.ResumeLayout(false);
this.panelTimer.ResumeLayout(false);
this.panelSize.ResumeLayout(false);
this.flowPanel.ResumeLayout(false);
this.flowPanel.PerformLayout();
this.flowPanelLeft.ResumeLayout(false);
this.flowPanelLeft.PerformLayout();
this.panelScrollSpeed.ResumeLayout(false);
this.flowPanelRight.ResumeLayout(false);
this.flowPanelRight.PerformLayout();
this.ResumeLayout(false);
}
@@ -630,7 +678,9 @@
private System.Windows.Forms.RadioButton radioSizeCustom;
private System.Windows.Forms.RadioButton radioSizeAuto;
private System.Windows.Forms.CheckBox checkMediaPreviews;
private System.Windows.Forms.FlowLayoutPanel flowPanel;
private System.Windows.Forms.FlowLayoutPanel flowPanelLeft;
private System.Windows.Forms.Panel panelScrollSpeed;
private System.Windows.Forms.FlowLayoutPanel flowPanelRight;
private System.Windows.Forms.Panel panelSeparator;
}
}

View File

@@ -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;
@@ -26,27 +26,21 @@ namespace TweetDuck.Core.Other.Settings{
this.notification.Activated += notification_Activated;
this.notification.Show();
Disposed += (sender, args) => this.notification.Dispose();
// general
toolTip.SetToolTip(checkColumnName, "Shows column name each notification originated\r\nfrom in the notification window title.");
toolTip.SetToolTip(checkMediaPreviews, "Shows image and video thumbnails in the notification window.");
toolTip.SetToolTip(checkSkipOnLinkClick, "Skips current notification when a link\r\ninside the notification is clicked.");
toolTip.SetToolTip(checkNonIntrusive, "When not idle and the cursor is within the notification window area,\r\nit will be delayed until the cursor moves away to prevent accidental clicks.");
toolTip.SetToolTip(comboBoxIdlePause, "Pauses new notifications after going idle for a set amount of time.");
toolTip.SetToolTip(checkTimerCountDown, "The notification timer counts down instead of up.");
toolTip.SetToolTip(labelDurationValue, "Milliseconds per character.");
toolTip.SetToolTip(trackBarDuration, toolTip.GetToolTip(labelDurationValue));
toolTip.SetToolTip(radioLocCustom, "Drag the example notification window to the desired location.");
toolTip.SetToolTip(radioSizeAuto, "Notification size is based on the font size and browser zoom level.");
toolTip.SetToolTip(radioSizeCustom, "Resize the example notification window to the desired size.");
checkColumnName.Checked = Config.DisplayNotificationColumn;
checkMediaPreviews.Checked = Config.NotificationMediaPreviews;
checkSkipOnLinkClick.Checked = Config.NotificationSkipOnLinkClick;
checkNonIntrusive.Checked = Config.NotificationNonIntrusiveMode;
comboBoxIdlePause.Items.Add("Disabled");
comboBoxIdlePause.Items.Add("30 seconds");
comboBoxIdlePause.Items.Add("1 minute");
@@ -54,13 +48,23 @@ namespace TweetDuck.Core.Other.Settings{
comboBoxIdlePause.Items.Add("5 minutes");
comboBoxIdlePause.SelectedIndex = Math.Max(0, Array.FindIndex(IdlePauseSeconds, val => val == Config.NotificationIdlePauseSeconds));
// timer
toolTip.SetToolTip(checkTimerCountDown, "The notification timer counts down instead of up.");
toolTip.SetToolTip(labelDurationValue, "Milliseconds per character.");
toolTip.SetToolTip(trackBarDuration, toolTip.GetToolTip(labelDurationValue));
checkNotificationTimer.Checked = Config.DisplayNotificationTimer;
checkTimerCountDown.Enabled = checkNotificationTimer.Checked;
checkTimerCountDown.Checked = Config.NotificationTimerCountDown;
trackBarDuration.SetValueSafe(Config.NotificationDurationValue);
labelDurationValue.Text = Config.NotificationDurationValue+" ms/c";
// location
toolTip.SetToolTip(radioLocCustom, "Drag the example notification window to the desired location.");
switch(Config.NotificationPosition){
case TweetNotification.Position.TopLeft: radioLocTL.Checked = true; break;
case TweetNotification.Position.TopRight: radioLocTR.Checked = true; break;
@@ -81,6 +85,11 @@ namespace TweetDuck.Core.Other.Settings{
trackBarEdgeDistance.SetValueSafe(Config.NotificationEdgeDistance);
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value+" px";
// size
toolTip.SetToolTip(radioSizeAuto, "Notification size is based on the font size and browser zoom level.");
toolTip.SetToolTip(radioSizeCustom, "Resize the example notification window to the desired size.");
switch(Config.NotificationSize){
case TweetNotification.Size.Auto: radioSizeAuto.Checked = true; break;
case TweetNotification.Size.Custom: radioSizeCustom.Checked = true; break;
@@ -88,8 +97,6 @@ namespace TweetDuck.Core.Other.Settings{
trackBarScrollSpeed.SetValueSafe(Config.NotificationScrollSpeed);
labelScrollSpeedValue.Text = trackBarScrollSpeed.Value+"%";
Disposed += (sender, args) => this.notification.Dispose();
}
public override void OnReady(){
@@ -97,12 +104,10 @@ namespace TweetDuck.Core.Other.Settings{
checkMediaPreviews.CheckedChanged += checkMediaPreviews_CheckedChanged;
checkSkipOnLinkClick.CheckedChanged += checkSkipOnLinkClick_CheckedChanged;
checkNonIntrusive.CheckedChanged += checkNonIntrusive_CheckedChanged;
comboBoxIdlePause.SelectedValueChanged += comboBoxIdlePause_SelectedValueChanged;
checkNotificationTimer.CheckedChanged += checkNotificationTimer_CheckedChanged;
checkTimerCountDown.CheckedChanged += checkTimerCountDown_CheckedChanged;
trackBarDuration.ValueChanged += trackBarDuration_ValueChanged;
btnDurationShort.Click += btnDurationShort_Click;
btnDurationMedium.Click += btnDurationMedium_Click;
@@ -113,13 +118,11 @@ namespace TweetDuck.Core.Other.Settings{
radioLocBL.CheckedChanged += radioLoc_CheckedChanged;
radioLocBR.CheckedChanged += radioLoc_CheckedChanged;
radioLocCustom.Click += radioLocCustom_Click;
comboBoxDisplay.SelectedValueChanged += comboBoxDisplay_SelectedValueChanged;
trackBarEdgeDistance.ValueChanged += trackBarEdgeDistance_ValueChanged;
radioSizeAuto.CheckedChanged += radioSize_CheckedChanged;
radioSizeCustom.Click += radioSizeCustom_Click;
trackBarScrollSpeed.ValueChanged += trackBarScrollSpeed_ValueChanged;
}
@@ -150,6 +153,71 @@ namespace TweetDuck.Core.Other.Settings{
}
}
#region General
private void checkColumnName_CheckedChanged(object sender, EventArgs e){
Config.DisplayNotificationColumn = checkColumnName.Checked;
notification.ShowExampleNotification(false);
}
private void checkMediaPreviews_CheckedChanged(object sender, EventArgs e){
Config.NotificationMediaPreviews = checkMediaPreviews.Checked;
}
private void checkSkipOnLinkClick_CheckedChanged(object sender, EventArgs e){
Config.NotificationSkipOnLinkClick = checkSkipOnLinkClick.Checked;
}
private void checkNonIntrusive_CheckedChanged(object sender, EventArgs e){
Config.NotificationNonIntrusiveMode = checkNonIntrusive.Checked;
}
private void comboBoxIdlePause_SelectedValueChanged(object sender, EventArgs e){
Config.NotificationIdlePauseSeconds = IdlePauseSeconds[comboBoxIdlePause.SelectedIndex];
}
#endregion
#region Timer
private void checkNotificationTimer_CheckedChanged(object sender, EventArgs e){
Config.DisplayNotificationTimer = checkNotificationTimer.Checked;
checkTimerCountDown.Enabled = checkNotificationTimer.Checked;
notification.ShowExampleNotification(true);
}
private void checkTimerCountDown_CheckedChanged(object sender, EventArgs e){
Config.NotificationTimerCountDown = checkTimerCountDown.Checked;
notification.ShowExampleNotification(true);
}
private void trackBarDuration_ValueChanged(object sender, EventArgs e){
durationUpdateTimer.Stop();
durationUpdateTimer.Start();
Config.NotificationDurationValue = trackBarDuration.Value;
labelDurationValue.Text = Config.NotificationDurationValue+" ms/c";
}
private void btnDurationShort_Click(object sender, EventArgs e){
trackBarDuration.Value = 15;
}
private void btnDurationMedium_Click(object sender, EventArgs e){
trackBarDuration.Value = 25;
}
private void btnDurationLong_Click(object sender, EventArgs e){
trackBarDuration.Value = 35;
}
private void durationUpdateTimer_Tick(object sender, EventArgs e){
notification.ShowExampleNotification(true);
durationUpdateTimer.Stop();
}
#endregion
#region Location
private void radioLoc_CheckedChanged(object sender, EventArgs e){
if (radioLocTL.Checked)Config.NotificationPosition = TweetNotification.Position.TopLeft;
else if (radioLocTR.Checked)Config.NotificationPosition = TweetNotification.Position.TopRight;
@@ -181,6 +249,20 @@ namespace TweetDuck.Core.Other.Settings{
}
}
private void comboBoxDisplay_SelectedValueChanged(object sender, EventArgs e){
Config.NotificationDisplay = comboBoxDisplay.SelectedIndex;
notification.ShowExampleNotification(false);
}
private void trackBarEdgeDistance_ValueChanged(object sender, EventArgs e){
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value+" px";
Config.NotificationEdgeDistance = trackBarEdgeDistance.Value;
notification.ShowExampleNotification(false);
}
#endregion
#region Size
private void radioSize_CheckedChanged(object sender, EventArgs e){
if (radioSizeAuto.Checked){
Config.NotificationSize = TweetNotification.Size.Auto;
@@ -198,58 +280,6 @@ namespace TweetDuck.Core.Other.Settings{
notification.ShowExampleNotification(false);
}
private void trackBarDuration_ValueChanged(object sender, EventArgs e){
durationUpdateTimer.Stop();
durationUpdateTimer.Start();
Config.NotificationDurationValue = trackBarDuration.Value;
labelDurationValue.Text = Config.NotificationDurationValue+" ms/c";
}
private void btnDurationShort_Click(object sender, EventArgs e){
trackBarDuration.Value = 15;
}
private void btnDurationMedium_Click(object sender, EventArgs e){
trackBarDuration.Value = 25;
}
private void btnDurationLong_Click(object sender, EventArgs e){
trackBarDuration.Value = 35;
}
private void checkColumnName_CheckedChanged(object sender, EventArgs e){
Config.DisplayNotificationColumn = checkColumnName.Checked;
notification.ShowExampleNotification(false);
}
private void checkNotificationTimer_CheckedChanged(object sender, EventArgs e){
Config.DisplayNotificationTimer = checkNotificationTimer.Checked;
checkTimerCountDown.Enabled = checkNotificationTimer.Checked;
notification.ShowExampleNotification(true);
}
private void checkTimerCountDown_CheckedChanged(object sender, EventArgs e){
Config.NotificationTimerCountDown = checkTimerCountDown.Checked;
notification.ShowExampleNotification(true);
}
private void checkMediaPreviews_CheckedChanged(object sender, EventArgs e){
Config.NotificationMediaPreviews = checkMediaPreviews.Checked;
}
private void checkSkipOnLinkClick_CheckedChanged(object sender, EventArgs e){
Config.NotificationSkipOnLinkClick = checkSkipOnLinkClick.Checked;
}
private void checkNonIntrusive_CheckedChanged(object sender, EventArgs e){
Config.NotificationNonIntrusiveMode = checkNonIntrusive.Checked;
}
private void comboBoxIdlePause_SelectedValueChanged(object sender, EventArgs e){
Config.NotificationIdlePauseSeconds = IdlePauseSeconds[comboBoxIdlePause.SelectedIndex];
}
private void trackBarScrollSpeed_ValueChanged(object sender, EventArgs e){
if (trackBarScrollSpeed.AlignValueToTick()){
labelScrollSpeedValue.Text = trackBarScrollSpeed.Value+"%";
@@ -257,20 +287,6 @@ namespace TweetDuck.Core.Other.Settings{
}
}
private void comboBoxDisplay_SelectedValueChanged(object sender, EventArgs e){
Config.NotificationDisplay = comboBoxDisplay.SelectedIndex;
notification.ShowExampleNotification(false);
}
private void trackBarEdgeDistance_ValueChanged(object sender, EventArgs e){
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value+" px";
Config.NotificationEdgeDistance = trackBarEdgeDistance.Value;
notification.ShowExampleNotification(false);
}
private void durationUpdateTimer_Tick(object sender, EventArgs e){
notification.ShowExampleNotification(true);
durationUpdateTimer.Stop();
}
#endregion
}
}

View File

@@ -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);
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);
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);
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);
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);
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,17 +106,16 @@
// 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 Semibold", 10.5F, System.Drawing.FontStyle.Bold);
this.labelSoundNotification.Location = new System.Drawing.Point(0, 0);
this.labelSoundNotification.Margin = new System.Windows.Forms.Padding(0);
this.labelSoundNotification.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.labelSoundNotification.Name = "labelSoundNotification";
this.labelSoundNotification.Size = new System.Drawing.Size(198, 20);
this.labelSoundNotification.Size = new System.Drawing.Size(160, 19);
this.labelSoundNotification.TabIndex = 0;
this.labelSoundNotification.Text = "Custom Sound Notification";
this.labelSoundNotification.Text = "SOUND NOTIFICATION";
//
// panelSoundNotification
//
this.panelSoundNotification.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.panelSoundNotification.Controls.Add(this.btnPlaySound);
this.panelSoundNotification.Controls.Add(this.tbCustomSound);
this.panelSoundNotification.Controls.Add(this.btnResetSound);
@@ -119,16 +123,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 Semibold", 9F, System.Drawing.FontStyle.Bold);
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(49, 15);
this.labelVolume.TabIndex = 2;
this.labelVolume.Text = "Volume";
//
@@ -147,9 +152,8 @@
//
// 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.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.flowPanel.Controls.Add(this.labelSoundNotification);
this.flowPanel.Controls.Add(this.panelSoundNotification);
this.flowPanel.Controls.Add(this.labelVolume);
@@ -157,7 +161,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, 462);
this.flowPanel.TabIndex = 0;
this.flowPanel.WrapContents = false;
//
@@ -165,8 +169,8 @@
//
this.panelVolume.Controls.Add(this.trackBarVolume);
this.panelVolume.Controls.Add(this.labelVolumeValue);
this.panelVolume.Location = new System.Drawing.Point(0, 100);
this.panelVolume.Margin = new System.Windows.Forms.Padding(0);
this.panelVolume.Location = new System.Drawing.Point(0, 107);
this.panelVolume.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
this.panelVolume.Name = "panelVolume";
this.panelVolume.Size = new System.Drawing.Size(322, 36);
this.panelVolume.TabIndex = 3;
@@ -182,7 +186,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(631, 480);
this.panelSoundNotification.ResumeLayout(false);
this.panelSoundNotification.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Windows.Forms;
using TweetDuck.Core.Controls;
using TweetDuck.Core.Notification;
using TweetDuck.Core.Utils;
namespace TweetDuck.Core.Other.Settings{
sealed partial class TabSettingsSounds : BaseTabSettings{
@@ -14,6 +15,8 @@ namespace TweetDuck.Core.Other.Settings{
this.playSoundNotification = playSoundNotification;
// sound notification
toolTip.SetToolTip(tbCustomSound, "When empty, the default TweetDeck sound notification is used.");
trackBarVolume.SetValueSafe(Config.NotificationSoundVolume);
@@ -21,6 +24,7 @@ namespace TweetDuck.Core.Other.Settings{
tbCustomSound.Text = Config.NotificationSoundPath;
tbCustomSound_TextChanged(tbCustomSound, EventArgs.Empty);
NativeMethods.SendMessage(tbCustomSound.Handle, NativeMethods.EM_SETCUEBANNER, 0, "(default TweetDeck sound)");
}
public override void OnReady(){
@@ -35,6 +39,8 @@ namespace TweetDuck.Core.Other.Settings{
Config.NotificationSoundVolume = trackBarVolume.Value;
}
#region Sound Notification
private bool RefreshCanPlay(){
bool isEmpty = string.IsNullOrEmpty(tbCustomSound.Text);
bool canPlay = isEmpty || File.Exists(tbCustomSound.Text);
@@ -84,5 +90,7 @@ namespace TweetDuck.Core.Other.Settings{
Config.NotificationSoundVolume = trackBarVolume.Value;
volumeUpdateTimer.Stop();
}
#endregion
}
}

View File

@@ -1,115 +0,0 @@
namespace TweetDuck.Core.Other.Settings {
partial class TabSettingsTray {
/// <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 Component 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.components = new System.ComponentModel.Container();
this.checkTrayHighlight = new System.Windows.Forms.CheckBox();
this.comboBoxTrayType = new System.Windows.Forms.ComboBox();
this.labelTrayIcon = new System.Windows.Forms.Label();
this.labelTray = new System.Windows.Forms.Label();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
this.flowPanel.SuspendLayout();
this.SuspendLayout();
//
// 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.Name = "checkTrayHighlight";
this.checkTrayHighlight.Size = new System.Drawing.Size(103, 17);
this.checkTrayHighlight.TabIndex = 3;
this.checkTrayHighlight.Text = "Enable Highlight";
this.checkTrayHighlight.UseVisualStyleBackColor = true;
//
// comboBoxTrayType
//
this.comboBoxTrayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
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.TabIndex = 1;
//
// labelTrayIcon
//
this.labelTrayIcon.AutoSize = true;
this.labelTrayIcon.Location = new System.Drawing.Point(3, 58);
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.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.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.TabIndex = 0;
this.labelTray.Text = "System Tray";
//
// 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.labelTray);
this.flowPanel.Controls.Add(this.comboBoxTrayType);
this.flowPanel.Controls.Add(this.labelTrayIcon);
this.flowPanel.Controls.Add(this.checkTrayHighlight);
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.TabIndex = 0;
this.flowPanel.WrapContents = false;
//
// TabSettingsTray
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flowPanel);
this.Name = "TabSettingsTray";
this.Size = new System.Drawing.Size(340, 115);
this.flowPanel.ResumeLayout(false);
this.flowPanel.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.CheckBox checkTrayHighlight;
private System.Windows.Forms.ComboBox comboBoxTrayType;
private System.Windows.Forms.Label labelTrayIcon;
private System.Windows.Forms.Label labelTray;
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.FlowLayoutPanel flowPanel;
}
}

View File

@@ -1,36 +0,0 @@
using System;
namespace TweetDuck.Core.Other.Settings{
sealed partial class TabSettingsTray : BaseTabSettings{
public TabSettingsTray(){
InitializeComponent();
toolTip.SetToolTip(comboBoxTrayType, "Changes behavior of the Tray icon.\r\nRight-click the icon for an action menu.");
toolTip.SetToolTip(checkTrayHighlight, "Highlights the tray icon if there are new tweets.\r\nOnly works for columns with popup or audio notifications.\r\nThe icon resets when the main window is restored.");
comboBoxTrayType.Items.Add("Disabled");
comboBoxTrayType.Items.Add("Display Icon Only");
comboBoxTrayType.Items.Add("Minimize to Tray");
comboBoxTrayType.Items.Add("Close to Tray");
comboBoxTrayType.Items.Add("Combined");
comboBoxTrayType.SelectedIndex = Math.Min(Math.Max((int)Config.TrayBehavior, 0), comboBoxTrayType.Items.Count-1);
checkTrayHighlight.Enabled = Config.TrayBehavior.ShouldDisplayIcon();
checkTrayHighlight.Checked = Config.EnableTrayHighlight;
}
public override void OnReady(){
comboBoxTrayType.SelectedIndexChanged += comboBoxTrayType_SelectedIndexChanged;
checkTrayHighlight.CheckedChanged += checkTrayHighlight_CheckedChanged;
}
private void comboBoxTrayType_SelectedIndexChanged(object sender, EventArgs e){
Config.TrayBehavior = (TrayIcon.Behavior)comboBoxTrayType.SelectedIndex;
checkTrayHighlight.Enabled = Config.TrayBehavior.ShouldDisplayIcon();
}
private void checkTrayHighlight_CheckedChanged(object sender, EventArgs e){
Config.EnableTrayHighlight = checkTrayHighlight.Checked;
}
}
}

View File

@@ -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){

View File

@@ -4,6 +4,7 @@ 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;
@@ -38,15 +39,17 @@ namespace TweetDuck.Core{
private string prevSoundNotificationPath = null;
public TweetDeckBrowser(FormBrowser owner, TweetDeckBridge bridge){
public TweetDeckBrowser(FormBrowser owner, TweetDeckBridge tdBridge, UpdateBridge updateBridge){
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
};
this.browser.LoadingStateChanged += browser_LoadingStateChanged;
@@ -54,7 +57,8 @@ namespace TweetDuck.Core{
this.browser.FrameLoadEnd += browser_FrameLoadEnd;
this.browser.LoadError += browser_LoadError;
this.browser.RegisterAsyncJsObject("$TD", bridge);
this.browser.RegisterAsyncJsObject("$TD", tdBridge);
this.browser.RegisterAsyncJsObject("$TDU", updateBridge);
this.browser.BrowserSettings.BackgroundColor = (uint)TwitterUtils.BackgroundColor.ToArgb();
this.browser.Dock = DockStyle.None;
@@ -142,21 +146,28 @@ namespace TweetDuck.Core{
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
IFrame frame = e.Frame;
if (frame.IsMain && TwitterUtils.IsTweetDeckWebsite(frame)){
UpdateProperties();
TweetDeckBridge.RestoreSessionData(frame);
ScriptLoader.ExecuteFile(frame, "code.js", browser);
ScriptLoader.ExecuteFile(frame, "update.js", browser);
if (frame.IsMain){
if (TwitterUtils.IsTweetDeckWebsite(frame)){
UpdateProperties();
TweetDeckBridge.RestoreSessionData(frame);
ScriptLoader.ExecuteFile(frame, "code.js", browser);
InjectBrowserCSS();
ReinjectCustomCSS(Program.UserConfig.CustomBrowserCSS);
UserConfig_SoundNotificationInfoChanged(null, EventArgs.Empty);
InjectBrowserCSS();
ReinjectCustomCSS(Program.UserConfig.CustomBrowserCSS);
UserConfig_SoundNotificationInfoChanged(null, EventArgs.Empty);
TweetDeckBridge.ResetStaticProperties();
TweetDeckBridge.ResetStaticProperties();
if (Program.UserConfig.FirstRun){
ScriptLoader.ExecuteFile(frame, "introduction.js", browser);
if (Arguments.HasFlag(Arguments.ArgIgnoreGDPR)){
ScriptLoader.ExecuteScript(frame, "TD.storage.Account.prototype.requiresConsent = function(){ return false; }", "gen:gdpr");
}
if (Program.UserConfig.FirstRun){
ScriptLoader.ExecuteFile(frame, "introduction.js", browser);
}
}
ScriptLoader.ExecuteFile(frame, "update.js", browser);
}
}
@@ -166,7 +177,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");
@@ -215,7 +226,7 @@ namespace TweetDuck.Core{
}
public void InjectBrowserCSS(){
browser.ExecuteScriptAsync("TDGF_injectBrowserCSS", ScriptLoader.LoadResource("styles/browser.css", false, browser)?.TrimEnd() ?? string.Empty);
browser.ExecuteScriptAsync("TDGF_injectBrowserCSS", ScriptLoader.LoadResource("styles/browser.css", browser)?.TrimEnd() ?? string.Empty);
}
public void ReinjectCustomCSS(string css){
@@ -253,5 +264,9 @@ namespace TweetDuck.Core{
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();
}
}
}

View File

@@ -11,17 +11,34 @@ 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";
args["disable-gpu-vsync"] = "1";
}
if (!Program.UserConfig.EnableSmoothScrolling){
if (Program.UserConfig.EnableSmoothScrolling){
args["disable-threaded-scrolling"] = "1";
if (args.TryGetValue("disable-features", out string disabledFeatures)){
args["disable-features"] = "TouchpadAndWheelScrollLatching,"+disabledFeatures;
}
else{
args["disable-features"] = "TouchpadAndWheelScrollLatching";
}
}
else{
args["disable-smooth-scrolling"] = "1";
}
if (!Program.UserConfig.EnableTouchAdjustment){
args["disable-touch-adjustment"] = "1";
}
args["disable-pdf-extension"] = "1";
args["disable-plugins-discovery"] = "1";
@@ -167,7 +184,7 @@ namespace TweetDuck.Core.Utils{
WindowsUtils.EnsureTLS12();
WebClient client = new WebClient{ Proxy = null };
client.Headers[HttpRequestHeader.UserAgent] = HeaderUserAgent;
client.Headers[HttpRequestHeader.UserAgent] = UserAgentVanilla;
return client;
}

View File

@@ -17,6 +17,7 @@ namespace TweetDuck.Core.Utils{
public const int GWL_STYLE = -16;
public const int SB_HORZ = 0;
public const int EM_SETCUEBANNER = 0x1501;
public const int WM_MOUSE_LL = 14;
public const int WM_MOUSEWHEEL = 0x020A;
@@ -52,6 +53,9 @@ namespace TweetDuck.Core.Utils{
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern bool SetWindowPos(int hWnd, int hWndOrder, int x, int y, int width, int height, uint flags);
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
[DllImport("user32.dll")]
public static extern bool PostMessage(IntPtr hWnd, uint msg, UIntPtr wParam, IntPtr lParam);
@@ -71,6 +75,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);

View File

@@ -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;
}

View File

@@ -76,22 +76,14 @@ namespace TweetDuck.Core.Utils{
string firstImageLink = GetMediaLink(urls[0], quality);
int qualityIndex = firstImageLink.IndexOf(':', firstImageLink.LastIndexOf('/'));
string file = GetImageFileName(firstImageLink);
string ext = Path.GetExtension(file); // includes dot
string[] fileNameParts = qualityIndex == -1 ? new string[]{
Path.ChangeExtension(file, null)
} : new string[]{
username,
Path.ChangeExtension(file, null),
firstImageLink.Substring(qualityIndex+1)
};
string filename = GetImageFileName(firstImageLink);
string ext = Path.GetExtension(filename); // includes dot
using(SaveFileDialog dialog = new SaveFileDialog{
AutoUpgradeEnabled = true,
OverwritePrompt = urls.Length == 1,
Title = "Save Image",
FileName = $"{string.Join(" ", fileNameParts.Where(part => !string.IsNullOrEmpty(part)))}{ext}",
FileName = qualityIndex == -1 ? filename : $"{username} {Path.ChangeExtension(filename, null)} {firstImageLink.Substring(qualityIndex+1)}".Trim()+ext,
Filter = (urls.Length == 1 ? "Image" : "Images")+(string.IsNullOrEmpty(ext) ? " (unknown)|*.*" : $" (*{ext})|*{ext}")
}){
if (dialog.ShowDialog() == DialogResult.OK){
@@ -122,12 +114,12 @@ namespace TweetDuck.Core.Utils{
AutoUpgradeEnabled = true,
OverwritePrompt = true,
Title = "Save Video",
FileName = string.IsNullOrEmpty(username) ? filename : $"{username} {filename}",
FileName = string.IsNullOrEmpty(username) ? filename : $"{username} {filename}".TrimStart(),
Filter = "Video"+(string.IsNullOrEmpty(ext) ? " (unknown)|*.*" : $" (*{ext})|*{ext}")
}){
if (dialog.ShowDialog() == DialogResult.OK){
BrowserUtils.DownloadFileAsync(url, dialog.FileName, null, ex => {
FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK);
FormMessage.Error("Video Download", "An error occurred while downloading the video: "+ex.Message, FormMessage.OK);
});
}
}

View File

@@ -15,10 +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; }
private static bool HasMicrosoftBeenBroughtTo2008Yet;
public static bool IsAeroEnabled => IsWindows8OrNewer || (NativeMethods.DwmIsCompositionEnabled(out bool isCompositionEnabled) == 0 && isCompositionEnabled);
static WindowsUtils(){
using(Process me = Process.GetCurrentProcess()){
@@ -26,7 +28,9 @@ 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(){

View 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){

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using TweetDuck.Core.Utils;
@@ -65,6 +64,8 @@ namespace TweetDuck.Data.Serialization{
}
public void Write(string file, T obj){
LinkedList<string> errors = new LinkedList<string>();
WindowsUtils.CreateDirectoryForFile(file);
using(StreamWriter writer = new StreamWriter(new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None))){
@@ -78,15 +79,21 @@ namespace TweetDuck.Data.Serialization{
if (serializer.TryWriteType(type, value, out string converted)){
if (converted != null){
writer.Write($"{prop.Key} {EscapeLine(converted)}");
writer.Write(prop.Key);
writer.Write(' ');
writer.Write(EscapeLine(converted));
writer.Write(NewLineReal);
}
}
else{
throw new SerializationException($"Invalid serialization type, conversion failed for: {type}");
errors.AddLast($"Missing converter for type: {type}");
}
}
}
if (errors.First != null){
throw new SerializationSoftException(errors.ToArray());
}
}
public void Read(string file, T obj){
@@ -103,6 +110,7 @@ namespace TweetDuck.Data.Serialization{
throw new FormatException("Input appears to be a binary file.");
}
LinkedList<string> errors = new LinkedList<string>();
int currentPos = 0;
do{
@@ -125,7 +133,8 @@ namespace TweetDuck.Data.Serialization{
int space = line.IndexOf(' ');
if (space == -1){
throw new SerializationException($"Invalid file format, missing separator: {line}");
errors.AddLast($"Missing separator on line: {line}");
continue;
}
string property = line.Substring(0, space);
@@ -140,10 +149,14 @@ namespace TweetDuck.Data.Serialization{
info.SetValue(obj, converted);
}
else{
throw new SerializationException($"Invalid file format, cannot convert value: {value} (property: {property})");
errors.AddLast($"Failed reading property {property} with value: {value}");
}
}
}while(currentPos != -1);
if (errors.First != null){
throw new SerializationSoftException(errors.ToArray());
}
}
public void ReadIfExists(string file, T obj){

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
namespace TweetDuck.Data.Serialization{
sealed class SerializationSoftException : Exception{
public IList<string> Errors { get; }
public SerializationSoftException(IList<string> errors) : base(string.Join(Environment.NewLine, errors)){
this.Errors = errors;
}
}
}

View File

@@ -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();
@@ -33,6 +34,8 @@
this.labelVersion = new System.Windows.Forms.Label();
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);
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);
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);
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);
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);
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,22 +140,25 @@
//
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);
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;
//
// btnConfigure
//
this.btnConfigure.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnConfigure.Location = new System.Drawing.Point(382, 80);
this.btnConfigure.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
this.btnConfigure.Location = new System.Drawing.Point(451, 30);
this.btnConfigure.Name = "btnConfigure";
this.btnConfigure.Size = new System.Drawing.Size(68, 23);
this.btnConfigure.TabIndex = 4;
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);
@@ -151,13 +168,30 @@
this.labelType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| 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.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Bold);
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);
@@ -165,22 +199,20 @@
this.Controls.Add(this.labelType);
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();
}
@@ -196,5 +228,7 @@
private System.Windows.Forms.Label labelVersion;
private System.Windows.Forms.Button btnConfigure;
private Core.Controls.LabelVertical labelType;
private System.Windows.Forms.Timer timerLayout;
private System.Windows.Forms.Panel panelBorder;
}
}

View File

@@ -9,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();
@@ -20,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);
}
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();
}
}
@@ -74,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);
}
@@ -86,7 +114,8 @@ namespace TweetDuck.Plugins.Controls{
labelName.ForeColor = textColor;
labelDescription.ForeColor = textColor;
btnToggleState.Text = isEnabled ? "Disable" : "Enable";
btnConfigure.Visible = isEnabled && pluginManager.IsPluginConfigurable(plugin);
btnConfigure.Visible = isConfigurable;
btnConfigure.Enabled = isEnabled;
}
else{
labelName.ForeColor = Color.DarkRed;

View File

@@ -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);
}
}

View File

@@ -24,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";

View File

@@ -4,7 +4,6 @@ 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; }
@@ -85,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{
@@ -119,14 +124,14 @@ namespace TweetDuck.Plugins{
public sealed class Builder{
private static readonly Version DefaultRequiredVersion = new Version(0, 0, 0, 0);
public string Name { get; private set; }
public string Description { get; private set; } = string.Empty;
public string Author { get; private set; } = "(anonymous)";
public string Version { get; private set; } = "(unknown)";
public string Website { get; private set; } = string.Empty;
public string ConfigFile { get; private set; } = string.Empty;
public string ConfigDefault { get; private set; } = string.Empty;
public Version RequiredVersion { get; private set; } = DefaultRequiredVersion;
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;
public PluginEnvironment Environments { get; private set; } = PluginEnvironment.None;
@@ -142,36 +147,10 @@ namespace TweetDuck.Plugins{
this.identifier = group.GetIdentifierPrefix()+name;
}
public void SetFromTag(string tag, string value){
switch(tag){
case "NAME": this.Name = value; break;
case "DESCRIPTION": this.Description = value; break;
case "AUTHOR": this.Author = value; break;
case "VERSION": this.Version = value; break;
case "WEBSITE": this.Website = value; break;
case "CONFIGFILE": this.ConfigFile = value; break;
case "CONFIGDEFAULT": this.ConfigDefault = value; break;
case "REQUIRES": SetRequiredVersion(value); break;
default: throw new FormatException("Invalid metadata tag: "+tag);
}
}
public void AddEnvironment(PluginEnvironment environment){
this.Environments |= environment;
}
private void SetRequiredVersion(string versionStr){
if (System.Version.TryParse(versionStr, out Version version)){
this.RequiredVersion = version;
}
else if (versionStr == VersionWildcard){
this.RequiredVersion = DefaultRequiredVersion;
}
else{
throw new FormatException("Plugin contains invalid minimum version: "+versionStr);
}
}
public Plugin BuildAndSetup(){
Plugin plugin = new Plugin(group, identifier, pathRoot, pathData, this);
@@ -183,6 +162,15 @@ namespace TweetDuck.Plugins{
throw new InvalidOperationException("Plugin has no script files");
}
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");
}
else if (!string.IsNullOrEmpty(plugin.Version)){
throw new InvalidOperationException("Official plugins cannot have a version identifier");
}
}
// setup
string configPath = plugin.ConfigPath, defaultConfigPath = plugin.DefaultConfigPath;

View File

@@ -32,7 +32,7 @@ namespace TweetDuck.Plugins{
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){
builder.SetFromTag(currentTag, currentContents);
SetProperty(builder, currentTag, currentContents);
}
currentTag = line.Substring(1, line.Length-2).ToUpper();
@@ -52,5 +52,19 @@ namespace TweetDuck.Plugins{
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);
}
}
}
}

View File

@@ -4,6 +4,7 @@ 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;
@@ -12,15 +13,7 @@ using TweetDuck.Resources;
namespace TweetDuck.Plugins{
sealed class PluginManager{
private static IReadOnlyDictionary<PluginEnvironment, string> LoadSetupScripts(){
return PluginEnvironmentExtensions.Map(
ScriptLoader.LoadResource("plugins.js"),
ScriptLoader.LoadResource("plugins.browser.js"),
ScriptLoader.LoadResource("plugins.notification.js")
);
}
private static readonly IReadOnlyDictionary<PluginEnvironment, string> PluginSetupScripts = LoadSetupScripts();
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");
@@ -54,8 +47,8 @@ namespace TweetDuck.Plugins{
Config.PluginChangedState += Config_PluginChangedState;
}
public void Register(ITweetDeckBrowser browser, PluginEnvironment environment, bool asMainBrowser = false){
browser.OnFrameLoaded(frame => ExecutePlugins(frame, environment));
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){
@@ -152,14 +145,11 @@ namespace TweetDuck.Plugins{
Reloaded?.Invoke(this, new PluginErrorEventArgs(loadErrors));
}
private 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){

View File

@@ -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.13.4";
public static readonly bool IsPortable = File.Exists("makeportable");
public const string VersionTag = "1.15.1";
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");
@@ -46,11 +45,14 @@ namespace TweetDuck{
private static readonly LockManager LockManager = new LockManager(Path.Combine(StoragePath, ".lock"));
private static bool HasCleanedUp;
public static UserConfig UserConfig { get; private set; }
public static SystemConfig SystemConfig { get; private set; }
public static Reporter Reporter { get; }
public static CultureInfo Culture { get; }
public static Reporter Reporter { get; }
public static ConfigManager Config { get; }
// TODO
public static UserConfig UserConfig => Config.User;
public static SystemConfig SystemConfig => Config.System;
static Program(){
Culture = CultureInfo.CurrentCulture;
@@ -63,6 +65,8 @@ namespace TweetDuck{
Reporter = new Reporter(ErrorLogFilePath);
Reporter.SetupUnhandledExceptionHandler("TweetDuck Has Failed :(");
Config = new ConfigManager();
}
[STAThread]
@@ -114,8 +118,7 @@ namespace TweetDuck{
}
}
UserConfig = UserConfig.Load(UserConfigFilePath);
SystemConfig = SystemConfig.Load(SystemConfigFilePath);
Config.LoadAll();
if (Arguments.HasFlag(Arguments.ArgImportCookies)){
ProfileManager.ImportCookies();
@@ -134,7 +137,7 @@ namespace TweetDuck{
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
CefSettings settings = new CefSettings{
UserAgent = BrowserUtils.HeaderUserAgent,
UserAgent = BrowserUtils.UserAgentChrome,
BrowserSubprocessPath = BrandName+".Browser.exe",
CachePath = StoragePath,
UserDataPath = CefDataPath,
@@ -143,27 +146,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(InstallerPath){
AllowPreReleases = Arguments.HasFlag(Arguments.ArgDebugUpdates),
DismissedUpdate = UserConfig.DismissedUpdate
};
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)){
@@ -219,7 +217,7 @@ namespace TweetDuck{
private static void ExitCleanup(){
if (HasCleanedUp)return;
UserConfig.Save();
Config.SaveAll();
Cef.Shutdown();
BrowserCache.Exit();

View File

@@ -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

View File

@@ -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>

View File

@@ -119,18 +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\spinner.apng;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>..\Resources\Images\spinner.apng;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

View File

@@ -9,53 +9,53 @@
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 this command 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 64.0.0-CI2508 -Source https://www.myget.org/F/cefsharp/api/v3/index.json
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:
#### 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
- **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 "EmbedAllSources" parameter is not supported by the "Csc" task
1. Open `C:\Program Files (x86)\Visual Studio\2017\<edition>\MSBuild\15.0\Bin\Microsoft.CSharp.CurrentVersion.targets` in a text editor
2. Remove line that says `EmbedAllSources="$(EmbedAllSources)"`
3. Hope the next Visual Studio update fixes it...
### 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**
@@ -67,8 +67,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`.

View File

@@ -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;
}
}
}

View 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",
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
Resources/Images/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -2,14 +2,18 @@
Debug plugin
[description]
- Enables debug functionality and tests
- Only included in debug configuration
Enables debug functionality and tests.
Text line 2.
Text line 3.
Text line 4.
Text line 5.
Text line 6.
[author]
chylex
[version]
1.1
1.2
[website]
https://tweetduck.chylex.com

View File

@@ -2,6 +2,7 @@ enabled(){
this.isDebugging = false;
this.onKeyDown = (e) => {
// ==========================
// F4 key - toggle debug mode
// ==========================
@@ -11,8 +12,6 @@ enabled(){
$(".nav-user-info").first().css("background-color", this.isDebugging ? "#5A6B75" : "#292F33");
}
// Debug mode handling
else if (this.isDebugging){
e.preventDefault();
@@ -22,15 +21,16 @@ enabled(){
// ===================================
if (e.keyCode === 78 || e.keyCode === 83){
var col = TD.controller.columnManager.getAllOrdered()[0];
let col = TD.controller.columnManager.getAllOrdered()[0];
let model = col.model;
var prevPopup = col.model.getHasNotification();
var prevSound = col.model.getHasSound();
let prevPopup = model.getHasNotification();
let prevSound = model.getHasSound();
col.model.setHasNotification(e.keyCode === 78);
col.model.setHasSound(e.keyCode === 83);
model.setHasNotification(e.keyCode === 78);
model.setHasSound(e.keyCode === 83);
$.publish("/notifications/new",[{
$.publish("/notifications/new", [{
column: col,
items: [
col.updateArray[Math.floor(Math.random()*col.updateArray.length)]
@@ -38,8 +38,8 @@ enabled(){
}]);
setTimeout(function(){
col.model.setHasNotification(prevPopup);
col.model.setHasSound(prevSound);
model.setHasNotification(prevPopup);
model.setHasSound(prevSound);
}, 1);
}
@@ -61,3 +61,7 @@ ready(){
disabled(){
$(document).off("keydown", this.onKeyDown);
}
configure(){
alert("Configure triggered");
}

Some files were not shown because too many files have changed in this diff Show More