mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-09-14 01:32:10 +02:00
Compare commits
516 Commits
Author | SHA1 | Date | |
---|---|---|---|
5dc2e71976 | |||
28eb7d0810 | |||
c641a92d89 | |||
3e57cc045f | |||
c60a8ddf66 | |||
8becef3e45 | |||
3237634e3b | |||
2a4a659e39 | |||
fcaa47c0a8 | |||
68ea17ccbd | |||
80308c7102 | |||
6f4a99a7cb | |||
ac245f5128 | |||
7f9e9e27a0 | |||
abf58a4aec | |||
5d9a700a6e | |||
3662b1eb1d | |||
34449da2b8 | |||
42f367f822 | |||
781ca0bb77 | |||
ebe5d50dae | |||
00d6dc5626 | |||
a1648c307f | |||
b8f170ae39 | |||
073f1da5b4 | |||
6310711136 | |||
fcac7a4ce1 | |||
c2b1aef810 | |||
c8ab26275c | |||
a1fd6a2b6b | |||
561c08e0cc | |||
4658e30e89 | |||
225e6b369a | |||
0e9094a19f | |||
2da0e03c6c | |||
9a6fac5fc8 | |||
b541f0a896 | |||
cec7cce077 | |||
fb13695ca5 | |||
20c76d06f7 | |||
339a11f649 | |||
0989400d87 | |||
52aacf602d | |||
54d70a6a17 | |||
d980e09e0f | |||
2e4cb12817 | |||
7b91cb2e96 | |||
95c04a8abc | |||
25822fefdb | |||
d800ee2d28 | |||
2a51371aca | |||
ee5d1a47dc | |||
b330b74347 | |||
11fa13f0bb | |||
21400d72b3 | |||
a710cb9d4f | |||
3326ad52ce | |||
c9560df851 | |||
74cb45118e | |||
c79bf19e51 | |||
961bec0a2f | |||
89e4977cd1 | |||
bfe16475db | |||
915d36867c | |||
48435af407 | |||
86b6ec5212 | |||
775e70bc45 | |||
9f565447d0 | |||
88d27bc29d | |||
172ae87ac6 | |||
91d572235e | |||
64d32dcb75 | |||
564b4283b6 | |||
ca4d374a81 | |||
a753806d7b | |||
bd1692cea3 | |||
b7ce089f08 | |||
8a6b47c5db | |||
9f1fc4df18 | |||
c018a2a7bc | |||
a1aebab114 | |||
e30702e1d8 | |||
008ff4b055 | |||
d7bba22e19 | |||
2b9a910533 | |||
118ebcc627 | |||
c741767b11 | |||
4a09358e14 | |||
3f4ea1af08 | |||
35bb196832 | |||
cb5b50dd42 | |||
8652272526 | |||
0f32504fde | |||
4735c21fc0 | |||
ecbcbcaed4 | |||
1677b73ff8 | |||
5929067a3d | |||
d06834617b | |||
9d048efe06 | |||
6a379bc2cd | |||
9f415b11b5 | |||
b9b9193222 | |||
867c2d1632 | |||
5447afc3f5 | |||
b5e58db242 | |||
8ab99619d6 | |||
4c7660ee65 | |||
c1b9bde7b0 | |||
0e8c6c066f | |||
9e44a86be0 | |||
b61479f84f | |||
e3c709b005 | |||
b2b3dba504 | |||
4d05441aa8 | |||
419b3ee850 | |||
4c31e72d29 | |||
e3b2ff7f0e | |||
4c5f5e2cce | |||
39ae9b8ba0 | |||
5c7eb0535d | |||
235718390b | |||
5d4b72f224 | |||
dc76ae9d1f | |||
e44f4bb003 | |||
1fc1370d41 | |||
80a669c989 | |||
801c9eba2d | |||
f9704d2836 | |||
39687171e9 | |||
1d73691ef4 | |||
f8678d2515 | |||
fb108ea18d | |||
a7229a0677 | |||
d0dd112b98 | |||
1e07120eb5 | |||
fcd1f76cff | |||
e400d86d75 | |||
dca3410a5b | |||
9b314e2953 | |||
5635daf66d | |||
7e2e1645e9 | |||
4990afcdbb | |||
c11f36dfef | |||
abddf61c88 | |||
37fec7e952 | |||
0f6a93ae8f | |||
25eae334b0 | |||
74377d01ce | |||
6e78ba1e7b | |||
39e0dedf27 | |||
bbe2c88802 | |||
586b31b63e | |||
041abe6d7e | |||
a69b3cd05f | |||
b48213e79e | |||
5bbc14aca5 | |||
8ccbf502e8 | |||
c426ca97e2 | |||
d9eef86a8b | |||
3fed921748 | |||
02827d53a2 | |||
1ad5fde9ae | |||
909d5ed99c | |||
b9096df218 | |||
1137485c55 | |||
61b1155a03 | |||
35624bcb1c | |||
6e262334ed | |||
829d69485a | |||
0d32c168eb | |||
38d6d93f65 | |||
9a280492c2 | |||
d49ee79c90 | |||
73b83af6b1 | |||
064673ef23 | |||
81bf93e5ab | |||
26d5a8ce08 | |||
c6f5c8d91f | |||
63a1928468 | |||
27c2aee8b9 | |||
5219d29aca | |||
84955352dd | |||
8e05c30063 | |||
6f98bcafec | |||
4afac91bce | |||
6e6312f6d7 | |||
df4c4e443d | |||
ff40474f92 | |||
aca06ee805 | |||
ba8e29a9f8 | |||
583da2bd9f | |||
0ea07016b4 | |||
616421db9a | |||
293ddacd19 | |||
13945ec937 | |||
4ea6f336f8 | |||
58296aa266 | |||
742df9dff3 | |||
011e1f5922 | |||
8f67d69325 | |||
9ac133b605 | |||
538b2d26cd | |||
cc3895c423 | |||
79454bfc3b | |||
734c7572bb | |||
9f93fbb161 | |||
c78c63285e | |||
c8cbf70a28 | |||
2b116d6756 | |||
da611153cf | |||
fd9bf4468a | |||
fa234eb9d6 | |||
dbfebf6a32 | |||
7b91e31485 | |||
e882fc8b5e | |||
5a54195cac | |||
a442adf8d5 | |||
38466878db | |||
7c86e4e743 | |||
41cbfb8d39 | |||
7c394f4b20 | |||
c1a35e1053 | |||
cddce8596f | |||
c75058b1da | |||
1a73fcdb39 | |||
8e0c4f5308 | |||
51e2791cc7 | |||
130159f06c | |||
42d1140b55 | |||
dfd987041a | |||
790d1787fd | |||
2a6a607c7b | |||
b3521d2a18 | |||
dee99caa7d | |||
cf525a3929 | |||
18d658f7e1 | |||
1c42ab77d8 | |||
33d5638bb0 | |||
8ce92df87a | |||
80654449af | |||
eee1622801 | |||
4c54876ecf | |||
1cbcd5c2da | |||
55253e284e | |||
e9795cd697 | |||
be76d9a6dc | |||
d7cdaf2870 | |||
48ed0e01d1 | |||
dca31dedde | |||
ab7356b991 | |||
a46a673cf8 | |||
c8d52539ca | |||
ed9267b6ba | |||
b7c02d1cf8 | |||
fb66beb29f | |||
8c3bf6bbc3 | |||
b943078132 | |||
e727617bf1 | |||
ffaea6dcbe | |||
bf1f72a2a4 | |||
be0df7c5b0 | |||
5ab769e74d | |||
d22ddb1731 | |||
9fed8c022b | |||
a315ed90af | |||
1ebf3c9af2 | |||
0e4c923c23 | |||
63835b9f99 | |||
ff17f7c132 | |||
f4631c9b38 | |||
35931023ae | |||
6d93381760 | |||
f1bdd5f1b2 | |||
1c3e2fbad7 | |||
29a02db07d | |||
f1db1ba708 | |||
c1420bac88 | |||
8e527fbbdf | |||
5ec1bcfe3f | |||
7226461cd0 | |||
6d6f383c92 | |||
e1a6328d09 | |||
6e4153911a | |||
342f74646e | |||
fe5191d3b5 | |||
504cf97c6c | |||
f8c494c9c1 | |||
b90d7f721a | |||
7936af6c9a | |||
52d01e3dd7 | |||
d30d70395a | |||
491a3ae525 | |||
1eae380b08 | |||
f091b2526e | |||
7548e2e202 | |||
d9b9afbf2d | |||
8036659003 | |||
f9fb4668c2 | |||
7047924947 | |||
8f6be3911a | |||
0d95b8eb44 | |||
61d2d124ff | |||
7b218b2544 | |||
87ac7daf76 | |||
6b4817df36 | |||
22d99da2e1 | |||
47b6cf7068 | |||
606c9512f8 | |||
aef9c591e9 | |||
71f67e9191 | |||
636f2b3017 | |||
2de5b5c6e4 | |||
0cbcc8c9f3 | |||
96146e3dc8 | |||
5aaae51be1 | |||
b98625fdbc | |||
09a748e9dc | |||
87b07c6d5b | |||
f39e668f8d | |||
6ea95342a0 | |||
c594bf5757 | |||
cd3b198c6f | |||
b249b5f46e | |||
bbe3b48bcc | |||
3bcd056197 | |||
6387ab41b3 | |||
4df16b7f15 | |||
ed387a2873 | |||
9e225530a6 | |||
7b23686dc6 | |||
4de31453fd | |||
4c59526e39 | |||
9ec1764194 | |||
47afa32902 | |||
2a09487b55 | |||
563c856dd3 | |||
69ea242408 | |||
d6e0e0726f | |||
73d460d40a | |||
1f27d96ac9 | |||
93e9f28d69 | |||
ec2e26752a | |||
fadd95f3e6 | |||
00acc677e6 | |||
1a799881e8 | |||
f75677593a | |||
19e3bd19f0 | |||
85701b0a3c | |||
014cb18dcb | |||
e71e1c853f | |||
ee9d9196f5 | |||
53c8272e01 | |||
7f7b6b1e2a | |||
405777e0f5 | |||
df2b624cb5 | |||
8a48d5c2f9 | |||
c55ee71442 | |||
3f82745f5b | |||
404187a1ae | |||
2b7b3f586b | |||
04959a3493 | |||
97cf4932ae | |||
b0d88a0a37 | |||
67a2e40622 | |||
3a28556c7f | |||
9ecc92b9a5 | |||
ca023be98a | |||
11a1423f76 | |||
79f6df121b | |||
71eade7e86 | |||
5f81d29036 | |||
ec1cb5dc5f | |||
fd969e2d55 | |||
37e33b77ff | |||
f7ed7703b4 | |||
4bb35295ca | |||
1e4f673f9e | |||
7cadb1c403 | |||
37148f5093 | |||
f6bc26789f | |||
b3f5a88525 | |||
1e538d2b28 | |||
7d7bfb7b01 | |||
41d86ba440 | |||
3df474a8a5 | |||
a50d6e8f47 | |||
6081e5b9c1 | |||
66ccea920c | |||
470d63093f | |||
eae0507831 | |||
92af85d3bb | |||
7635af5730 | |||
a838e89695 | |||
b22289a8b9 | |||
45b3ff52c6 | |||
4464991f4c | |||
b0d2f77583 | |||
b211a4405d | |||
8823016d2c | |||
859fdc7ec1 | |||
028d5ed01f | |||
5fd5a2a436 | |||
79a7e7470c | |||
9ecef78aed | |||
65a837a6e1 | |||
6e4db4acea | |||
26fb977d05 | |||
b42cd1c048 | |||
467f7cd12f | |||
66699ce9df | |||
cf7d903932 | |||
a7ab67925c | |||
a474ba4260 | |||
09e5636e86 | |||
2295a875be | |||
82a2455afc | |||
268de676ee | |||
8fe26c07f1 | |||
da3921b1ca | |||
4dd2e787d1 | |||
ce005ae6c2 | |||
1513f46a11 | |||
7543eeb0f4 | |||
873242120c | |||
98f8095a65 | |||
785571a550 | |||
0c4bd4044e | |||
0319543dce | |||
82d70b2d7f | |||
62d18e010a | |||
fc77b85083 | |||
50a8893f4f | |||
9252b3040e | |||
d5141ed020 | |||
7ff9e23283 | |||
89854d527c | |||
6ff0cad2a8 | |||
349cfbd2d5 | |||
40303ef74a | |||
6c652122c2 | |||
3658e3a2aa | |||
2b20fcfcd1 | |||
554d427fef | |||
7cf5b23306 | |||
b26a6098eb | |||
7ad927bdaf | |||
4ed30b3619 | |||
edfa9264d5 | |||
f7516b593f | |||
83ff998f9d | |||
47381e0df4 | |||
ba62d57485 | |||
c014c4bc24 | |||
5d1a3fede2 | |||
53b584fe45 | |||
f53d974400 | |||
c4b4ef19cd | |||
3bfc360362 | |||
584f16d375 | |||
b3d84c3217 | |||
dd14ad470e | |||
85b90574b8 | |||
ee5d172468 | |||
7ca4b94361 | |||
31f1546483 | |||
d8a88a19af | |||
12af79de05 | |||
2260dd419d | |||
61a940cc82 | |||
1bbc1e0d7e | |||
921294eeb3 | |||
baaa90f49d | |||
4e25381770 | |||
272877d0ed | |||
555b947bf7 | |||
da29811b16 | |||
241f67fd4d | |||
eb4ce18e31 | |||
ae99fee440 | |||
d116ac5e56 | |||
28db1f4253 | |||
034312e676 | |||
da83d73ba6 | |||
02e8dc3440 | |||
cac6d1f889 | |||
68fa3294d4 | |||
9b983de8c9 | |||
3a37ee719b | |||
61359c2faa | |||
7f7c5ab35b | |||
a1b483d20a | |||
04cd662d78 | |||
da597f076f | |||
fab3efdcf5 | |||
a55509a34d | |||
84fb1c5b2b | |||
391a90e1df | |||
e0fe39195d | |||
385fead81a | |||
648d1b9aa9 | |||
3f0028913d | |||
45e6ec8b0f | |||
a3fbaa0b34 | |||
7102cbfb3b | |||
c3db3ce0f2 | |||
7a1e7637ff | |||
04a78a02d3 | |||
cb61dc742f | |||
cd53f6e757 | |||
c64f7daa8d | |||
e70d792654 | |||
9ae533f907 | |||
cfe92f18e3 | |||
e2a34ea28e | |||
ec8000360e | |||
57b0821e19 |
108
.gitignore
vendored
108
.gitignore
vendored
@@ -1,6 +1,12 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# TweetDuck installer builds
|
||||
bld/*
|
||||
!bld/*.iss
|
||||
!bld/*.bat
|
||||
!bld/Resources
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
@@ -19,16 +25,9 @@ x64/
|
||||
x86/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
bld/*
|
||||
!bld/gen_full.iss
|
||||
!bld/gen_port.iss
|
||||
!bld/gen_upd.iss
|
||||
!bld/Resources
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
@@ -38,11 +37,6 @@ bld/*
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
@@ -71,27 +65,12 @@ artifacts/
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
@@ -118,33 +97,9 @@ nCrunchTemp_*
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
@@ -157,17 +112,6 @@ publish/
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
@@ -189,9 +133,6 @@ ClientBin/
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
@@ -200,40 +141,3 @@ Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
46
Configuration/Arguments.cs
Normal file
46
Configuration/Arguments.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Configuration{
|
||||
static class Arguments{
|
||||
// public args
|
||||
public const string ArgDataFolder = "-datafolder";
|
||||
public const string ArgLocale = "-locale";
|
||||
public const string ArgLogging = "-log";
|
||||
public const string ArgDebugUpdates = "-debugupdates";
|
||||
|
||||
// internal args
|
||||
public const string ArgRestart = "-restart";
|
||||
public const string ArgImportCookies = "-importcookies";
|
||||
public const string ArgUpdated = "-updated";
|
||||
|
||||
// class data and methods
|
||||
private static readonly CommandLineArgs Current = CommandLineArgs.FromStringArray('-', Environment.GetCommandLineArgs());
|
||||
|
||||
public static bool HasFlag(string flag){
|
||||
return Current.HasFlag(flag);
|
||||
}
|
||||
|
||||
public static string GetValue(string key, string defaultValue){
|
||||
return Current.GetValue(key, defaultValue);
|
||||
}
|
||||
|
||||
public static CommandLineArgs GetCurrentClean(){
|
||||
CommandLineArgs args = Current.Clone();
|
||||
args.RemoveFlag(ArgRestart);
|
||||
args.RemoveFlag(ArgImportCookies);
|
||||
args.RemoveFlag(ArgUpdated);
|
||||
return args;
|
||||
}
|
||||
|
||||
public static CommandLineArgs GetCurrentForInstaller(){
|
||||
CommandLineArgs args = GetCurrentClean();
|
||||
args.AddFlag(ArgUpdated);
|
||||
return args;
|
||||
}
|
||||
|
||||
public static string GetCurrentForInstallerCmd(){
|
||||
return GetCurrentForInstaller().ToString().Replace("\"", "::");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +1,15 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Configuration{
|
||||
namespace TweetDuck.Configuration{
|
||||
sealed class LockManager{
|
||||
public enum Result{
|
||||
Success, HasProcess, Fail
|
||||
}
|
||||
|
||||
public Process LockingProcess { get; private set; }
|
||||
|
||||
private readonly string file;
|
||||
@@ -14,111 +19,158 @@ namespace TweetDck.Configuration{
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
private bool CreateLockFile(){
|
||||
private void CreateLockFileStream(){
|
||||
lockStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||
WriteIntToStream(lockStream, GetCurrentProcessId());
|
||||
lockStream.Flush(true);
|
||||
}
|
||||
|
||||
private bool ReleaseLockFileStream(){
|
||||
if (lockStream != null){
|
||||
lockStream.Dispose();
|
||||
lockStream = null;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Result TryCreateLockFile(){
|
||||
if (lockStream != null){
|
||||
throw new InvalidOperationException("Lock file already exists.");
|
||||
}
|
||||
|
||||
try{
|
||||
lockStream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||
|
||||
byte[] id = BitConverter.GetBytes(Process.GetCurrentProcess().Id);
|
||||
lockStream.Write(id, 0, id.Length);
|
||||
lockStream.Flush();
|
||||
|
||||
if (LockingProcess != null){
|
||||
LockingProcess.Close();
|
||||
LockingProcess = null;
|
||||
CreateLockFileStream();
|
||||
return Result.Success;
|
||||
}catch(DirectoryNotFoundException){
|
||||
try{
|
||||
CreateLockFileStream();
|
||||
return Result.Success;
|
||||
}catch{
|
||||
ReleaseLockFileStream();
|
||||
return Result.Fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
}catch(Exception){
|
||||
if (lockStream != null){
|
||||
lockStream.Close();
|
||||
lockStream.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}catch(IOException){
|
||||
return Result.HasProcess;
|
||||
}catch{
|
||||
ReleaseLockFileStream();
|
||||
return Result.Fail;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Lock(){
|
||||
if (lockStream != null)return true;
|
||||
|
||||
try{
|
||||
byte[] bytes = new byte[4];
|
||||
|
||||
using(FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
|
||||
fileStream.Read(bytes, 0, 4);
|
||||
}
|
||||
|
||||
int pid = BitConverter.ToInt32(bytes, 0);
|
||||
|
||||
try{
|
||||
Process foundProcess = Process.GetProcessById(pid);
|
||||
|
||||
using(Process currentProcess = Process.GetCurrentProcess()){
|
||||
if (foundProcess.ProcessName == currentProcess.ProcessName || foundProcess.MainWindowTitle == Program.BrandName){
|
||||
LockingProcess = foundProcess;
|
||||
}
|
||||
}
|
||||
}catch(ArgumentException){}
|
||||
|
||||
return LockingProcess == null && CreateLockFile();
|
||||
}catch(DirectoryNotFoundException){
|
||||
string dir = Path.GetDirectoryName(file);
|
||||
|
||||
if (dir != null){
|
||||
Directory.CreateDirectory(dir);
|
||||
return CreateLockFile();
|
||||
}
|
||||
}catch(FileNotFoundException){
|
||||
return CreateLockFile();
|
||||
}catch(Exception){
|
||||
return false;
|
||||
public Result Lock(){
|
||||
if (lockStream != null){
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
return false;
|
||||
Result initialResult = TryCreateLockFile();
|
||||
|
||||
if (initialResult == Result.HasProcess){
|
||||
try{
|
||||
int pid;
|
||||
|
||||
using(FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
|
||||
pid = ReadIntFromStream(fileStream);
|
||||
}
|
||||
|
||||
try{
|
||||
Process foundProcess = Process.GetProcessById(pid);
|
||||
|
||||
using(Process currentProcess = Process.GetCurrentProcess()){
|
||||
if (foundProcess.MainModule.FileVersionInfo.InternalName == currentProcess.MainModule.FileVersionInfo.InternalName){
|
||||
LockingProcess = foundProcess;
|
||||
}
|
||||
else{
|
||||
foundProcess.Close();
|
||||
}
|
||||
}
|
||||
}catch{
|
||||
// GetProcessById throws ArgumentException if the process is missing
|
||||
// Process.MainModule can throw exceptions in some cases
|
||||
}
|
||||
|
||||
return LockingProcess == null ? Result.Fail : Result.HasProcess;
|
||||
}catch{
|
||||
return Result.Fail;
|
||||
}
|
||||
}
|
||||
|
||||
return initialResult;
|
||||
}
|
||||
|
||||
public bool Unlock(){
|
||||
bool result = true;
|
||||
|
||||
if (lockStream != null){
|
||||
lockStream.Dispose();
|
||||
|
||||
if (ReleaseLockFileStream()){
|
||||
try{
|
||||
File.Delete(file);
|
||||
}catch(Exception e){
|
||||
Program.Reporter.Log(e.ToString());
|
||||
result = false;
|
||||
}
|
||||
|
||||
lockStream = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool CloseLockingProcess(int timeout){
|
||||
public bool CloseLockingProcess(int closeTimeout, int killTimeout){
|
||||
if (LockingProcess != null){
|
||||
LockingProcess.CloseMainWindow();
|
||||
try{
|
||||
if (LockingProcess.CloseMainWindow()){
|
||||
WindowsUtils.TrySleepUntil(CheckLockingProcessExited, closeTimeout, 250);
|
||||
}
|
||||
|
||||
for(int waited = 0; waited < timeout && !LockingProcess.HasExited;){
|
||||
LockingProcess.Refresh();
|
||||
if (!LockingProcess.HasExited){
|
||||
LockingProcess.Kill();
|
||||
WindowsUtils.TrySleepUntil(CheckLockingProcessExited, killTimeout, 250);
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
waited += 100;
|
||||
}
|
||||
if (LockingProcess.HasExited){
|
||||
LockingProcess.Dispose();
|
||||
LockingProcess = null;
|
||||
return true;
|
||||
}
|
||||
}catch(Exception ex){
|
||||
if (ex is InvalidOperationException || ex is Win32Exception){
|
||||
if (LockingProcess != null){
|
||||
LockingProcess.Refresh();
|
||||
|
||||
if (LockingProcess.HasExited){
|
||||
LockingProcess.Dispose();
|
||||
LockingProcess = null;
|
||||
return true;
|
||||
bool hasExited = LockingProcess.HasExited;
|
||||
LockingProcess.Dispose();
|
||||
return hasExited;
|
||||
}
|
||||
}
|
||||
else throw;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckLockingProcessExited(){
|
||||
LockingProcess.Refresh();
|
||||
return LockingProcess.HasExited;
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
|
||||
private static void WriteIntToStream(Stream stream, int value){
|
||||
byte[] id = BitConverter.GetBytes(value);
|
||||
stream.Write(id, 0, id.Length);
|
||||
}
|
||||
|
||||
private static int ReadIntFromStream(Stream stream){
|
||||
byte[] bytes = new byte[4];
|
||||
stream.Read(bytes, 0, 4);
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
}
|
||||
|
||||
private static int GetCurrentProcessId(){
|
||||
using(Process process = Process.GetCurrentProcess()){
|
||||
return process.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
66
Configuration/SystemConfig.cs
Normal file
66
Configuration/SystemConfig.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TweetDuck.Configuration{
|
||||
sealed class SystemConfig{
|
||||
public static readonly bool IsHardwareAccelerationSupported = File.Exists(Path.Combine(Program.ProgramPath, "libEGL.dll")) &&
|
||||
File.Exists(Path.Combine(Program.ProgramPath, "libGLESv2.dll"));
|
||||
|
||||
public bool HardwareAcceleration{
|
||||
get => hardwareAcceleration && IsHardwareAccelerationSupported;
|
||||
set => hardwareAcceleration = value;
|
||||
}
|
||||
|
||||
private readonly string file;
|
||||
|
||||
private bool hardwareAcceleration;
|
||||
|
||||
private SystemConfig(string file){
|
||||
this.file = file;
|
||||
|
||||
HardwareAcceleration = true;
|
||||
}
|
||||
|
||||
private void WriteToStream(Stream stream){
|
||||
stream.WriteByte((byte)(HardwareAcceleration ? 1 : 0));
|
||||
}
|
||||
|
||||
private void ReadFromStream(Stream stream){
|
||||
HardwareAcceleration = stream.ReadByte() > 0;
|
||||
}
|
||||
|
||||
public bool Save(){
|
||||
try{
|
||||
string directory = Path.GetDirectoryName(file);
|
||||
if (directory == null)return false;
|
||||
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
using(Stream stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None)){
|
||||
WriteToStream(stream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}catch(Exception e){
|
||||
Program.Reporter.HandleException("Configuration Error", "Could not save the system configuration file.", true, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static SystemConfig Load(string file){
|
||||
SystemConfig config = new SystemConfig(file);
|
||||
|
||||
try{
|
||||
using(Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)){
|
||||
config.ReadFromStream(stream);
|
||||
}
|
||||
}catch(FileNotFoundException){
|
||||
}catch(DirectoryNotFoundException){
|
||||
}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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,88 +1,95 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using TweetDck.Core;
|
||||
using TweetDck.Core.Handling;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDuck.Core;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Configuration{
|
||||
namespace TweetDuck.Configuration{
|
||||
[Serializable]
|
||||
sealed class UserConfig{
|
||||
private static readonly IFormatter Formatter = new BinaryFormatter{
|
||||
Binder = new SerializationCompatibilityHandler()
|
||||
};
|
||||
private static readonly IFormatter Formatter = new BinaryFormatter{ Binder = new LegacyBinder() };
|
||||
|
||||
private const int CurrentFileVersion = 5;
|
||||
private class LegacyBinder : SerializationBinder{
|
||||
public override Type BindToType(string assemblyName, string typeName){
|
||||
return Type.GetType(string.Format("{0}, {1}", typeName.Replace("TweetDck", "TweetDuck"), assemblyName.Replace("TweetDck", "TweetDuck")));
|
||||
}
|
||||
}
|
||||
|
||||
private const int CurrentFileVersion = 10;
|
||||
|
||||
// START OF CONFIGURATION
|
||||
|
||||
public bool IgnoreMigration { get; set; }
|
||||
public bool IgnoreUninstallCheck { get; set; }
|
||||
|
||||
public WindowState BrowserWindow { get; set; }
|
||||
public bool DisplayNotificationColumn { get; set; }
|
||||
public bool DisplayNotificationTimer { get; set; }
|
||||
public bool NotificationTimerCountDown { get; set; }
|
||||
public bool NotificationSkipOnLinkClick { get; set; }
|
||||
public bool NotificationNonIntrusiveMode { get; set; }
|
||||
|
||||
public TweetNotification.Duration NotificationDuration { get; set; }
|
||||
public TweetNotification.Position NotificationPosition { get; set; }
|
||||
public Point CustomNotificationPosition { get; set; }
|
||||
public int NotificationEdgeDistance { get; set; }
|
||||
public int NotificationDisplay { get; set; }
|
||||
public int NotificationIdlePauseSeconds { get; set; }
|
||||
public int NotificationDurationValue { get; set; }
|
||||
public bool NotificationLegacyLoad { get; set; }
|
||||
public int NotificationScrollSpeed { get; set; }
|
||||
|
||||
public bool EnableSpellCheck { get; set; }
|
||||
public bool ExpandLinksOnHover { get; set; }
|
||||
public bool SwitchAccountSelectors { get; set; }
|
||||
public bool EnableTrayHighlight { get; set; }
|
||||
|
||||
public bool EnableUpdateCheck { get; set; }
|
||||
public string DismissedUpdate { get; set; }
|
||||
|
||||
public PluginConfig Plugins { get; private set; }
|
||||
|
||||
public WindowState PluginsWindow { get; set; }
|
||||
|
||||
public string CustomCefArgs { get; set; }
|
||||
public string CustomBrowserCSS { get; set; }
|
||||
public string CustomNotificationCSS { get; set; }
|
||||
|
||||
public bool IsCustomNotificationPositionSet{
|
||||
get{
|
||||
return CustomNotificationPosition.X != -32000 && CustomNotificationPosition.X != 32000;
|
||||
}
|
||||
public bool IsCustomNotificationPositionSet => CustomNotificationPosition != ControlExtensions.InvisibleLocation;
|
||||
|
||||
public string NotificationSoundPath{
|
||||
get => string.IsNullOrEmpty(notificationSoundPath) ? string.Empty : notificationSoundPath;
|
||||
set => notificationSoundPath = value;
|
||||
}
|
||||
|
||||
|
||||
public bool MuteNotifications{
|
||||
get{
|
||||
return muteNotifications;
|
||||
}
|
||||
get => muteNotifications;
|
||||
|
||||
set{
|
||||
if (muteNotifications == value)return;
|
||||
|
||||
muteNotifications = value;
|
||||
|
||||
if (MuteToggled != null){
|
||||
MuteToggled(this, new EventArgs());
|
||||
if (muteNotifications != value){
|
||||
muteNotifications = value;
|
||||
MuteToggled?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TrayIcon.Behavior TrayBehavior{
|
||||
get{
|
||||
return trayBehavior;
|
||||
}
|
||||
public int ZoomLevel{
|
||||
get => zoomLevel;
|
||||
|
||||
set{
|
||||
if (trayBehavior == value)return;
|
||||
if (zoomLevel != value){
|
||||
zoomLevel = value;
|
||||
ZoomLevelChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trayBehavior = value;
|
||||
public double ZoomMultiplier => zoomLevel/100.0;
|
||||
|
||||
if (TrayBehaviorChanged != null){
|
||||
TrayBehaviorChanged(this, new EventArgs());
|
||||
public TrayIcon.Behavior TrayBehavior{
|
||||
get => trayBehavior;
|
||||
|
||||
set{
|
||||
if (trayBehavior != value){
|
||||
trayBehavior = value;
|
||||
TrayBehaviorChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +99,9 @@ namespace TweetDck.Configuration{
|
||||
[field:NonSerialized]
|
||||
public event EventHandler MuteToggled;
|
||||
|
||||
[field:NonSerialized]
|
||||
public event EventHandler ZoomLevelChanged;
|
||||
|
||||
[field:NonSerialized]
|
||||
public event EventHandler TrayBehaviorChanged;
|
||||
|
||||
@@ -100,26 +110,27 @@ namespace TweetDck.Configuration{
|
||||
|
||||
private int fileVersion;
|
||||
private bool muteNotifications;
|
||||
private int zoomLevel;
|
||||
private string notificationSoundPath;
|
||||
private TrayIcon.Behavior trayBehavior;
|
||||
|
||||
private UserConfig(string file){
|
||||
this.file = file;
|
||||
|
||||
BrowserWindow = new WindowState();
|
||||
ZoomLevel = 100;
|
||||
DisplayNotificationTimer = true;
|
||||
NotificationDuration = TweetNotification.Duration.Medium;
|
||||
NotificationNonIntrusiveMode = true;
|
||||
NotificationPosition = TweetNotification.Position.TopRight;
|
||||
CustomNotificationPosition = new Point(-32000, -32000);
|
||||
CustomNotificationPosition = ControlExtensions.InvisibleLocation;
|
||||
NotificationEdgeDistance = 8;
|
||||
NotificationDurationValue = 25;
|
||||
NotificationScrollSpeed = 100;
|
||||
EnableUpdateCheck = true;
|
||||
ExpandLinksOnHover = true;
|
||||
SwitchAccountSelectors = true;
|
||||
EnableTrayHighlight = true;
|
||||
Plugins = new PluginConfig();
|
||||
PluginsWindow = new WindowState();
|
||||
|
||||
Plugins.DisableOfficialFromConfig("clear-columns");
|
||||
Plugins.DisableOfficialFromConfig("reply-account");
|
||||
}
|
||||
|
||||
private void UpgradeFile(){
|
||||
@@ -141,27 +152,41 @@ namespace TweetDck.Configuration{
|
||||
|
||||
if (fileVersion == 2){
|
||||
BrowserWindow = new WindowState();
|
||||
Plugins = new PluginConfig();
|
||||
PluginsWindow = new WindowState();
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 3){
|
||||
EnableTrayHighlight = true;
|
||||
|
||||
switch(NotificationDuration){
|
||||
case TweetNotification.Duration.Short: NotificationDurationValue = 15; break;
|
||||
case TweetNotification.Duration.Medium: NotificationDurationValue = 25; break;
|
||||
case TweetNotification.Duration.Long: NotificationDurationValue = 35; break;
|
||||
case TweetNotification.Duration.VeryLong: NotificationDurationValue = 45; break;
|
||||
}
|
||||
|
||||
NotificationDurationValue = 25;
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 4){
|
||||
Plugins.DisableOfficialFromConfig("clear-columns");
|
||||
Plugins.DisableOfficialFromConfig("reply-account");
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 5){
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 6){
|
||||
NotificationNonIntrusiveMode = true;
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 7){
|
||||
ZoomLevel = 100;
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 8){
|
||||
SwitchAccountSelectors = true;
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
if (fileVersion == 9){
|
||||
NotificationScrollSpeed = 100;
|
||||
++fileVersion;
|
||||
}
|
||||
|
||||
@@ -205,11 +230,8 @@ namespace TweetDck.Configuration{
|
||||
config.file = file;
|
||||
}
|
||||
}
|
||||
|
||||
if (config != null){
|
||||
config.UpgradeFile();
|
||||
}
|
||||
|
||||
config?.UpgradeFile();
|
||||
break;
|
||||
}catch(FileNotFoundException){
|
||||
}catch(DirectoryNotFoundException){
|
||||
@@ -220,7 +242,7 @@ namespace TweetDck.Configuration{
|
||||
Program.Reporter.Log(e.ToString());
|
||||
}
|
||||
else if (firstException != null){
|
||||
Program.Reporter.HandleException("Configuration Error", "Could not open the backup configuration file. If you continue, you may lose your settings and list of enabled plugins.", true, e);
|
||||
Program.Reporter.HandleException("Configuration Error", "Could not open the backup configuration file. If you continue, your program options will be reset.", true, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,13 +257,5 @@ namespace TweetDck.Configuration{
|
||||
public static string GetBackupFile(string file){
|
||||
return file+".bak";
|
||||
}
|
||||
|
||||
private class SerializationCompatibilityHandler : SerializationBinder{
|
||||
public override Type BindToType(string assemblyName, string typeName){
|
||||
assemblyName = assemblyName.Replace("TweetDick", "TweetDuck");
|
||||
typeName = typeName.Replace("TweetDick", "TweetDck");
|
||||
return Type.GetType(string.Format(CultureInfo.CurrentCulture, "{0}, {1}", typeName, assemblyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup></configuration>
|
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<package id="cef.redist.x64" version="3.2785.1478" targetFramework="net452" />
|
||||
<package id="cef.redist.x86" version="3.2785.1478" targetFramework="net452" />
|
||||
<package id="CefSharp.Common" version="53.0.0-pre01" targetFramework="net452" />
|
||||
<package id="CefSharp.WinForms" version="53.0.0-pre01" targetFramework="net452" />
|
||||
<package id="Microsoft.VC120.CRT.JetBrains" version="12.0.21005.2" targetFramework="net452" />
|
||||
</packages>
|
19
Core/Bridge/CallbackBridge.cs
Normal file
19
Core/Bridge/CallbackBridge.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
|
||||
namespace TweetDuck.Core.Bridge{
|
||||
sealed class CallbackBridge{
|
||||
private readonly Control owner;
|
||||
private readonly Action safeCallback;
|
||||
|
||||
public CallbackBridge(Control owner, Action safeCallback){
|
||||
this.owner = owner;
|
||||
this.safeCallback = safeCallback;
|
||||
}
|
||||
|
||||
public void Trigger(){
|
||||
owner.InvokeSafe(safeCallback);
|
||||
}
|
||||
}
|
||||
}
|
45
Core/Bridge/PropertyBridge.cs
Normal file
45
Core/Bridge/PropertyBridge.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace TweetDuck.Core.Bridge{
|
||||
static class PropertyBridge{
|
||||
[Flags]
|
||||
public enum Properties{
|
||||
ExpandLinksOnHover = 1,
|
||||
MuteNotifications = 2,
|
||||
HasCustomNotificationSound = 4,
|
||||
SkipOnLinkClick = 8,
|
||||
SwitchAccountSelectors = 16,
|
||||
AllBrowser = ExpandLinksOnHover | SwitchAccountSelectors | MuteNotifications | HasCustomNotificationSound,
|
||||
AllNotification = ExpandLinksOnHover | SkipOnLinkClick
|
||||
}
|
||||
|
||||
public static string GenerateScript(Properties properties){
|
||||
StringBuilder build = new StringBuilder();
|
||||
build.Append("(function(c){");
|
||||
|
||||
if (properties.HasFlag(Properties.ExpandLinksOnHover)){
|
||||
build.Append("c.expandLinksOnHover=").Append(Program.UserConfig.ExpandLinksOnHover ? "true;" : "false;");
|
||||
}
|
||||
|
||||
if (properties.HasFlag(Properties.SwitchAccountSelectors)){
|
||||
build.Append("c.switchAccountSelectors=").Append(Program.UserConfig.SwitchAccountSelectors ? "true;" : "false;");
|
||||
}
|
||||
|
||||
if (properties.HasFlag(Properties.MuteNotifications)){
|
||||
build.Append("c.muteNotifications=").Append(Program.UserConfig.MuteNotifications ? "true;" : "false;");
|
||||
}
|
||||
|
||||
if (properties.HasFlag(Properties.HasCustomNotificationSound)){
|
||||
build.Append("c.hasCustomNotificationSound=").Append(Program.UserConfig.NotificationSoundPath.Length > 0 ? "true;" : "false;");
|
||||
}
|
||||
|
||||
if (properties.HasFlag(Properties.SkipOnLinkClick)){
|
||||
build.Append("c.skipOnLinkClick=").Append(Program.UserConfig.NotificationSkipOnLinkClick ? "true;" : "false;");
|
||||
}
|
||||
|
||||
build.Append("})(window.$TDX=window.$TDX||{})");
|
||||
return build.ToString();
|
||||
}
|
||||
}
|
||||
}
|
118
Core/Bridge/TweetDeckBridge.cs
Normal file
118
Core/Bridge/TweetDeckBridge.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Bridge{
|
||||
sealed class TweetDeckBridge{
|
||||
public static string LastRightClickedLink = string.Empty;
|
||||
public static string LastHighlightedTweet = string.Empty;
|
||||
public static string LastHighlightedQuotedTweet = string.Empty;
|
||||
|
||||
public static void ResetStaticProperties(){
|
||||
LastRightClickedLink = LastHighlightedTweet = LastHighlightedQuotedTweet = string.Empty;
|
||||
}
|
||||
|
||||
private readonly FormBrowser form;
|
||||
private readonly FormNotificationMain notification;
|
||||
|
||||
public TweetDeckBridge(FormBrowser form, FormNotificationMain notification){
|
||||
this.form = form;
|
||||
this.notification = notification;
|
||||
}
|
||||
|
||||
public void LoadFontSizeClass(string fsClass){
|
||||
form.InvokeAsyncSafe(() => {
|
||||
TweetNotification.SetFontSizeClass(fsClass);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadNotificationHeadContents(string headContents){
|
||||
form.InvokeAsyncSafe(() => {
|
||||
TweetNotification.SetHeadTag(headContents);
|
||||
});
|
||||
}
|
||||
|
||||
public void SetLastRightClickedLink(string link){
|
||||
form.InvokeAsyncSafe(() => LastRightClickedLink = link);
|
||||
}
|
||||
|
||||
public void SetLastHighlightedTweet(string link, string quotedLink){
|
||||
form.InvokeAsyncSafe(() => {
|
||||
LastHighlightedTweet = link;
|
||||
LastHighlightedQuotedTweet = quotedLink;
|
||||
});
|
||||
}
|
||||
|
||||
public void OpenContextMenu(){
|
||||
form.InvokeAsyncSafe(form.OpenContextMenu);
|
||||
}
|
||||
|
||||
public void OnTweetPopup(string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){
|
||||
notification.InvokeAsyncSafe(() => {
|
||||
form.OnTweetNotification();
|
||||
notification.ShowNotification(new TweetNotification(columnName, tweetHtml, tweetCharacters, tweetUrl, quoteUrl));
|
||||
});
|
||||
}
|
||||
|
||||
public void OnTweetSound(){
|
||||
form.InvokeAsyncSafe(() => {
|
||||
form.OnTweetNotification();
|
||||
form.PlayNotificationSound();
|
||||
});
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text, bool showInNotification){
|
||||
if (showInNotification){
|
||||
notification.InvokeAsyncSafe(() => notification.DisplayTooltip(text));
|
||||
}
|
||||
else{
|
||||
form.InvokeAsyncSafe(() => form.DisplayTooltip(text));
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadNextNotification(){
|
||||
notification.InvokeAsyncSafe(notification.FinishCurrentNotification);
|
||||
}
|
||||
|
||||
public void ScreenshotTweet(string html, int width, int height){
|
||||
form.InvokeAsyncSafe(() => form.OnTweetScreenshotReady(html, width, height));
|
||||
}
|
||||
|
||||
public void FixClipboard(){
|
||||
form.InvokeAsyncSafe(WindowsUtils.ClipboardStripHtmlStyles);
|
||||
}
|
||||
|
||||
public int GetIdleSeconds(){
|
||||
return NativeMethods.GetIdleSeconds();
|
||||
}
|
||||
|
||||
public void OpenBrowser(string url){
|
||||
BrowserUtils.OpenExternalBrowser(url);
|
||||
}
|
||||
|
||||
public void Alert(string type, string contents){
|
||||
MessageBoxIcon icon;
|
||||
|
||||
switch(type){
|
||||
case "error": icon = MessageBoxIcon.Error; break;
|
||||
case "warning": icon = MessageBoxIcon.Warning; break;
|
||||
case "info": icon = MessageBoxIcon.Information; break;
|
||||
default: icon = MessageBoxIcon.None; break;
|
||||
}
|
||||
|
||||
MessageBox.Show(contents, Program.BrandName+" Browser Message", MessageBoxButtons.OK, icon);
|
||||
}
|
||||
|
||||
public void CrashDebug(string message){
|
||||
#if DEBUG
|
||||
Log(message);
|
||||
System.Diagnostics.Debugger.Break();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Log(string data){
|
||||
System.Diagnostics.Debug.WriteLine(data);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Controls{
|
||||
namespace TweetDuck.Core.Controls{
|
||||
static class ControlExtensions{
|
||||
public static readonly Point InvisibleLocation = new Point(-32000, -32000);
|
||||
|
||||
public static void InvokeSafe(this Control control, Action func){
|
||||
if (control.InvokeRequired){
|
||||
control.Invoke(func);
|
||||
@@ -14,6 +17,14 @@ namespace TweetDck.Core.Controls{
|
||||
}
|
||||
}
|
||||
|
||||
public static void InvokeAsyncSafe(this Control control, Action func){
|
||||
control.BeginInvoke(func);
|
||||
}
|
||||
|
||||
public static bool IsFullyOutsideView(this Form form){
|
||||
return !Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(form.Bounds));
|
||||
}
|
||||
|
||||
public static void MoveToCenter(this Form targetForm, Form parentForm){
|
||||
targetForm.Location = new Point(parentForm.Location.X+parentForm.Width/2-targetForm.Width/2, parentForm.Location.Y+parentForm.Height/2-targetForm.Height/2);
|
||||
}
|
||||
@@ -36,6 +47,14 @@ namespace TweetDck.Core.Controls{
|
||||
}
|
||||
}
|
||||
|
||||
public static bool AlignValueToTick(this TrackBar trackBar){
|
||||
if (trackBar.Value % trackBar.SmallChange != 0){
|
||||
trackBar.Value = trackBar.SmallChange*(int)Math.Floor(((double)trackBar.Value/trackBar.SmallChange)+0.5);
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
public static void SetElevated(this Button button){
|
||||
button.Text = " "+button.Text;
|
||||
button.FlatStyle = FlatStyle.System;
|
||||
|
@@ -1,13 +1,9 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Controls{
|
||||
namespace TweetDuck.Core.Controls{
|
||||
class FlatButton : Button{
|
||||
protected override bool ShowFocusCues{
|
||||
get{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
protected override bool ShowFocusCues => false;
|
||||
|
||||
public FlatButton(){
|
||||
GotFocus += FlatButton_GotFocus;
|
||||
|
3
Core/Controls/FlatProgressBar.Designer.cs
generated
3
Core/Controls/FlatProgressBar.Designer.cs
generated
@@ -1,3 +0,0 @@
|
||||
namespace TweetDck.Core.Controls{
|
||||
partial class FlatProgressBar{}
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Controls{
|
||||
sealed partial class FlatProgressBar : ProgressBar{
|
||||
namespace TweetDuck.Core.Controls{
|
||||
sealed class FlatProgressBar : ProgressBar{
|
||||
private readonly SolidBrush brush;
|
||||
|
||||
public FlatProgressBar(){
|
||||
|
23
Core/Controls/LabelVertical.cs
Normal file
23
Core/Controls/LabelVertical.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDuck.Core.Controls{
|
||||
sealed class LabelVertical : Label{
|
||||
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
|
||||
|
||||
using(Brush brush = new SolidBrush(ForeColor)){
|
||||
foreach(char chr in Text){
|
||||
string str = chr.ToString();
|
||||
float x = (ClientRectangle.Width-e.Graphics.MeasureString(str, Font).Width)/2F;
|
||||
|
||||
e.Graphics.DrawString(str, Font, brush, x, y);
|
||||
y += LineHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
Core/Controls/TabButton.Designer.cs
generated
3
Core/Controls/TabButton.Designer.cs
generated
@@ -1,3 +0,0 @@
|
||||
namespace TweetDck.Core.Controls{
|
||||
partial class TabButton{}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Controls{
|
||||
sealed partial class TabButton : FlatButton{
|
||||
public Action Callback { get; private set; }
|
||||
|
||||
public void SetupButton(int locationX, int sizeWidth, string title, Action callback){
|
||||
Callback = callback;
|
||||
|
||||
SuspendLayout();
|
||||
FlatAppearance.BorderColor = Color.DimGray;
|
||||
FlatAppearance.MouseDownBackColor = Color.White;
|
||||
FlatAppearance.MouseOverBackColor = Color.White;
|
||||
FlatStyle = FlatStyle.Flat;
|
||||
Location = new Point(locationX, 0);
|
||||
Margin = new Padding(0);
|
||||
Size = new Size(sizeWidth, 30);
|
||||
Text = title;
|
||||
UseVisualStyleBackColor = true;
|
||||
ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
}
|
68
Core/Controls/TabPanel.Designer.cs
generated
68
Core/Controls/TabPanel.Designer.cs
generated
@@ -1,68 +0,0 @@
|
||||
namespace TweetDck.Core.Controls {
|
||||
partial class TabPanel {
|
||||
/// <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.panelButtons = new System.Windows.Forms.Panel();
|
||||
this.panelContent = new System.Windows.Forms.Panel();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panelButtons
|
||||
//
|
||||
this.panelButtons.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panelButtons.Location = new System.Drawing.Point(0, 0);
|
||||
this.panelButtons.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelButtons.Name = "panelButtons";
|
||||
this.panelButtons.Size = new System.Drawing.Size(640, 30);
|
||||
this.panelButtons.TabIndex = 0;
|
||||
//
|
||||
// panelContent
|
||||
//
|
||||
this.panelContent.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.panelContent.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.panelContent.Location = new System.Drawing.Point(0, 29);
|
||||
this.panelContent.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelContent.Name = "panelContent";
|
||||
this.panelContent.Size = new System.Drawing.Size(640, 451);
|
||||
this.panelContent.TabIndex = 1;
|
||||
//
|
||||
// TabPanel
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.panelContent);
|
||||
this.Controls.Add(this.panelButtons);
|
||||
this.Name = "TabPanel";
|
||||
this.Size = new System.Drawing.Size(640, 480);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panelButtons;
|
||||
private System.Windows.Forms.Panel panelContent;
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Controls{
|
||||
sealed partial class TabPanel : UserControl{
|
||||
public IEnumerable<TabButton> Buttons{
|
||||
get{
|
||||
return panelButtons.Controls.Cast<TabButton>();
|
||||
}
|
||||
}
|
||||
|
||||
public TabButton ActiveButton { get; private set; }
|
||||
|
||||
// ReSharper disable once ConvertToAutoPropertyWithPrivateSetter
|
||||
public Panel Content{
|
||||
get{
|
||||
return panelContent;
|
||||
}
|
||||
}
|
||||
|
||||
private int btnWidth;
|
||||
|
||||
public TabPanel(){
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void SetupTabPanel(int buttonWidth){
|
||||
this.btnWidth = buttonWidth;
|
||||
}
|
||||
|
||||
public TabButton AddButton(string title, Action callback){
|
||||
TabButton button = new TabButton();
|
||||
button.SetupButton((btnWidth-1)*panelButtons.Controls.Count, btnWidth, title, callback);
|
||||
button.Click += (sender, args) => SelectTab((TabButton)sender);
|
||||
|
||||
panelButtons.Controls.Add(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
public void SelectTab(TabButton button){
|
||||
if (ActiveButton != null){
|
||||
ActiveButton.BackColor = SystemColors.Control;
|
||||
}
|
||||
|
||||
button.BackColor = Color.White;
|
||||
button.Callback();
|
||||
|
||||
ActiveButton = button;
|
||||
}
|
||||
|
||||
public void ReplaceContent(Control newControl){
|
||||
newControl.Dock = DockStyle.Fill;
|
||||
Content.SuspendLayout();
|
||||
Content.Controls.Clear();
|
||||
Content.Controls.Add(newControl);
|
||||
Content.ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
}
|
12
Core/FormBrowser.Designer.cs
generated
12
Core/FormBrowser.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core {
|
||||
namespace TweetDuck.Core {
|
||||
sealed partial class FormBrowser {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -24,26 +24,24 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.trayIcon = new TweetDck.Core.TrayIcon();
|
||||
this.trayIcon = new TweetDuck.Core.TrayIcon(this.components);
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// trayIcon
|
||||
//
|
||||
this.trayIcon.Visible = false;
|
||||
//
|
||||
// FormBrowser
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = TweetDuck.Core.Utils.BrowserUtils.BackgroundColor;
|
||||
this.ClientSize = new System.Drawing.Size(324, 386);
|
||||
this.Icon = Properties.Resources.icon;
|
||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||
this.Location = TweetDuck.Core.Controls.ControlExtensions.InvisibleLocation;
|
||||
this.MinimumSize = new System.Drawing.Size(340, 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.ResizeEnd += new System.EventHandler(this.FormBrowser_ResizeEnd);
|
||||
this.Resize += new System.EventHandler(this.FormBrowser_Resize);
|
||||
this.ResumeLayout(false);
|
||||
|
@@ -1,71 +1,99 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using TweetDck.Configuration;
|
||||
using TweetDck.Core.Handling;
|
||||
using TweetDck.Core.Other;
|
||||
using TweetDck.Resources;
|
||||
using TweetDck.Core.Controls;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDck.Updates;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDck.Plugins.Enums;
|
||||
using TweetDck.Plugins.Events;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Notification.Screenshot;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Other.Settings;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
using TweetDuck.Plugins.Events;
|
||||
using TweetDuck.Resources;
|
||||
using TweetDuck.Updates;
|
||||
using TweetDuck.Updates.Events;
|
||||
using TweetLib.Audio.Utils;
|
||||
|
||||
namespace TweetDck.Core{
|
||||
namespace TweetDuck.Core{
|
||||
sealed partial class FormBrowser : Form{
|
||||
private static UserConfig Config{
|
||||
get{
|
||||
return Program.UserConfig;
|
||||
}
|
||||
}
|
||||
private static UserConfig Config => Program.UserConfig;
|
||||
|
||||
public string UpdateInstallerPath { get; private set; }
|
||||
|
||||
private readonly ChromiumWebBrowser browser;
|
||||
private readonly PluginManager plugins;
|
||||
private readonly UpdateHandler updates;
|
||||
private readonly FormNotificationTweet notification;
|
||||
private readonly ContextMenu contextMenu;
|
||||
|
||||
private FormSettings currentFormSettings;
|
||||
private FormAbout currentFormAbout;
|
||||
private FormPlugins currentFormPlugins;
|
||||
private bool isLoaded;
|
||||
|
||||
private bool isBrowserReady;
|
||||
private FormWindowState prevState;
|
||||
|
||||
public FormBrowser(PluginManager pluginManager){
|
||||
private TweetScreenshotManager notificationScreenshotManager;
|
||||
private SoundNotification soundNotification;
|
||||
|
||||
public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName;
|
||||
|
||||
this.plugins = pluginManager;
|
||||
this.plugins.Reloaded += plugins_Reloaded;
|
||||
this.plugins.Config.PluginChangedState += plugins_PluginChangedState;
|
||||
this.plugins.PluginChangedState += plugins_PluginChangedState;
|
||||
|
||||
FormNotification notification = CreateNotificationForm(true);
|
||||
notification.CanMoveWindow = () => false;
|
||||
notification.Show();
|
||||
this.contextMenu = ContextMenuBrowser.CreateMenu(this);
|
||||
|
||||
this.notification = new FormNotificationTweet(this, plugins){
|
||||
#if DEBUG
|
||||
CanMoveWindow = () => (ModifierKeys & Keys.Alt) == Keys.Alt
|
||||
#else
|
||||
CanMoveWindow = () => false
|
||||
#endif
|
||||
};
|
||||
|
||||
this.notification.Show();
|
||||
|
||||
this.browser = new ChromiumWebBrowser("https://tweetdeck.twitter.com/"){
|
||||
MenuHandler = new ContextMenuBrowser(this),
|
||||
DialogHandler = new DialogHandlerBrowser(this),
|
||||
LifeSpanHandler = new LifeSpanHandler()
|
||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||
LifeSpanHandler = new LifeSpanHandler(),
|
||||
RequestHandler = new RequestHandlerBrowser()
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
this.browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
||||
#endif
|
||||
|
||||
this.browser.LoadingStateChanged += Browser_LoadingStateChanged;
|
||||
this.browser.FrameLoadEnd += Browser_FrameLoadEnd;
|
||||
this.browser.RegisterJsObject("$TD", new TweetDeckBridge(this, notification));
|
||||
this.browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||
this.browser.FrameLoadStart += browser_FrameLoadStart;
|
||||
this.browser.FrameLoadEnd += browser_FrameLoadEnd;
|
||||
this.browser.LoadError += browser_LoadError;
|
||||
this.browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge(this, notification));
|
||||
this.browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
||||
|
||||
|
||||
browser.BrowserSettings.BackgroundColor = (uint)BrowserUtils.BackgroundColor.ToArgb();
|
||||
browser.Dock = DockStyle.None;
|
||||
browser.Location = ControlExtensions.InvisibleLocation;
|
||||
Controls.Add(browser);
|
||||
|
||||
Disposed += (sender, args) => browser.Dispose();
|
||||
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
|
||||
|
||||
Disposed += (sender, args) => {
|
||||
browser.Dispose();
|
||||
contextMenu.Dispose();
|
||||
|
||||
notificationScreenshotManager?.Dispose();
|
||||
soundNotification?.Dispose();
|
||||
};
|
||||
|
||||
this.trayIcon.ClickRestore += trayIcon_ClickRestore;
|
||||
this.trayIcon.ClickClose += trayIcon_ClickClose;
|
||||
@@ -73,60 +101,110 @@ namespace TweetDck.Core{
|
||||
|
||||
UpdateTrayIcon();
|
||||
|
||||
this.updates = new UpdateHandler(browser, this);
|
||||
Config.MuteToggled += Config_MuteToggled;
|
||||
Config.ZoomLevelChanged += Config_ZoomLevelChanged;
|
||||
|
||||
this.updates = new UpdateHandler(browser, this, updaterSettings);
|
||||
this.updates.UpdateAccepted += updates_UpdateAccepted;
|
||||
this.updates.UpdateDismissed += updates_UpdateDismissed;
|
||||
|
||||
RestoreWindow();
|
||||
}
|
||||
|
||||
private bool TryBringToFront<T>() where T : Form{
|
||||
T form = Application.OpenForms.OfType<T>().FirstOrDefault();
|
||||
|
||||
if (form != null){
|
||||
form.BringToFront();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
private void ShowChildForm(Form form){
|
||||
form.VisibleChanged += (sender, args) => form.MoveToCenter(this);
|
||||
form.Show(this);
|
||||
form.Shown += (sender, args) => form.MoveToCenter(this);
|
||||
}
|
||||
|
||||
private void ForceClose(){
|
||||
public void ForceClose(){
|
||||
trayIcon.Visible = false; // checked in FormClosing event
|
||||
Close();
|
||||
}
|
||||
|
||||
public FormNotification CreateNotificationForm(bool autoHide){
|
||||
return new FormNotification(this, plugins, autoHide);
|
||||
}
|
||||
|
||||
// window setup
|
||||
|
||||
private void SetupWindow(){
|
||||
private void RestoreWindow(){
|
||||
Config.BrowserWindow.Restore(this, true);
|
||||
prevState = WindowState;
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
private void OnBrowserReady(){
|
||||
if (!isBrowserReady){
|
||||
browser.Location = Point.Empty;
|
||||
browser.Dock = DockStyle.Fill;
|
||||
isBrowserReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTrayIcon(){
|
||||
trayIcon.Visible = Config.TrayBehavior.ShouldDisplayIcon();
|
||||
}
|
||||
|
||||
// active event handlers
|
||||
|
||||
private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
||||
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
||||
if (!e.IsLoading){
|
||||
browser.AddWordToDictionary("tweetdeck");
|
||||
browser.AddWordToDictionary("TweetDeck");
|
||||
browser.AddWordToDictionary("tweetduck");
|
||||
browser.AddWordToDictionary("TweetDuck");
|
||||
browser.AddWordToDictionary("TD");
|
||||
foreach(string word in BrowserUtils.DictionaryWords){
|
||||
browser.AddWordToDictionary(word);
|
||||
}
|
||||
|
||||
Invoke(new Action(SetupWindow));
|
||||
browser.LoadingStateChanged -= Browser_LoadingStateChanged;
|
||||
BeginInvoke(new Action(OnBrowserReady));
|
||||
browser.LoadingStateChanged -= browser_LoadingStateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
private void browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e){
|
||||
if (e.Frame.IsMain){
|
||||
if (Config.ZoomLevel != 100){
|
||||
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel);
|
||||
}
|
||||
|
||||
if (BrowserUtils.IsTwitterWebsite(e.Frame)){
|
||||
ScriptLoader.ExecuteFile(e.Frame, "twitter.js");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
if (e.Frame.IsMain && BrowserUtils.IsTweetDeckWebsite(e.Frame)){
|
||||
e.Frame.ExecuteJavaScriptAsync(BrowserUtils.BackgroundColorFix);
|
||||
|
||||
UpdateProperties(PropertyBridge.Properties.AllBrowser);
|
||||
ScriptLoader.ExecuteFile(e.Frame, "code.js");
|
||||
ReinjectCustomCSS(Config.CustomBrowserCSS);
|
||||
|
||||
if (plugins.HasAnyPlugin(PluginEnvironment.Browser)){
|
||||
ScriptLoader.ExecuteFile(e.Frame, PluginManager.PluginBrowserScriptFile);
|
||||
ScriptLoader.ExecuteFile(e.Frame, PluginManager.PluginGlobalScriptFile);
|
||||
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Browser, true);
|
||||
}
|
||||
|
||||
TweetDeckBridge.ResetStaticProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void browser_LoadError(object sender, LoadErrorEventArgs e){
|
||||
if (e.ErrorCode == CefErrorCode.Aborted){
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.FailedUrl.StartsWith("http://td/")){
|
||||
string errorPage = ScriptLoader.LoadResource("pages/error.html", true);
|
||||
|
||||
if (errorPage != null){
|
||||
browser.LoadHtml(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode)), "http://td/error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +234,7 @@ namespace TweetDck.Core{
|
||||
private void FormBrowser_ResizeEnd(object sender, EventArgs e){ // also triggers when the window moves
|
||||
if (!isLoaded)return;
|
||||
|
||||
if (Location.X != -32000){
|
||||
if (Location != ControlExtensions.InvisibleLocation){
|
||||
Config.BrowserWindow.Save(this);
|
||||
Config.Save();
|
||||
}
|
||||
@@ -171,62 +249,92 @@ namespace TweetDck.Core{
|
||||
}
|
||||
}
|
||||
|
||||
private void FormBrowser_FormClosed(object sender, FormClosedEventArgs e){
|
||||
if (isLoaded && UpdateInstallerPath == null){
|
||||
updates.CleanupDownload();
|
||||
}
|
||||
}
|
||||
|
||||
private void Config_MuteToggled(object sender, EventArgs e){
|
||||
UpdateProperties(PropertyBridge.Properties.MuteNotifications);
|
||||
}
|
||||
|
||||
private void Config_ZoomLevelChanged(object sender, EventArgs e){
|
||||
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel);
|
||||
}
|
||||
|
||||
private void Config_TrayBehaviorChanged(object sender, EventArgs e){
|
||||
if (!isLoaded)return;
|
||||
|
||||
UpdateTrayIcon();
|
||||
}
|
||||
|
||||
private void trayIcon_ClickRestore(object sender, EventArgs e){
|
||||
if (!isLoaded)return;
|
||||
|
||||
isLoaded = false;
|
||||
Show();
|
||||
SetupWindow();
|
||||
RestoreWindow();
|
||||
Activate();
|
||||
UpdateTrayIcon();
|
||||
}
|
||||
|
||||
private void trayIcon_ClickClose(object sender, EventArgs e){
|
||||
if (!isLoaded)return;
|
||||
|
||||
ForceClose();
|
||||
}
|
||||
|
||||
private void plugins_Reloaded(object sender, PluginLoadEventArgs e){
|
||||
ReloadBrowser();
|
||||
private void plugins_Reloaded(object sender, PluginErrorEventArgs e){
|
||||
browser.GetBrowser().Reload();
|
||||
}
|
||||
|
||||
private void plugins_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
browser.ExecuteScriptAsync("window.TDPF_setPluginState", e.Plugin, e.IsEnabled ? 1 : 0); // ExecuteScriptAsync cannot handle boolean values as of yet
|
||||
browser.ExecuteScriptAsync("window.TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
||||
}
|
||||
|
||||
private void updates_UpdateAccepted(object sender, UpdateAcceptedEventArgs e){
|
||||
Hide();
|
||||
|
||||
FormUpdateDownload downloadForm = new FormUpdateDownload(e.UpdateInfo);
|
||||
downloadForm.MoveToCenter(this);
|
||||
downloadForm.ShowDialog();
|
||||
|
||||
if (downloadForm.UpdateStatus == FormUpdateDownload.Status.Succeeded){
|
||||
UpdateInstallerPath = downloadForm.InstallerPath;
|
||||
ForceClose();
|
||||
foreach(Form form in Application.OpenForms.Cast<Form>().Reverse()){
|
||||
if (form is FormSettings || form is FormPlugins || form is FormAbout){
|
||||
form.Close();
|
||||
}
|
||||
}
|
||||
else if (downloadForm.UpdateStatus == FormUpdateDownload.Status.Manual){
|
||||
|
||||
updates.BeginUpdateDownload(this, e.UpdateInfo, update => {
|
||||
if (update.DownloadStatus == UpdateDownloadStatus.Done){
|
||||
UpdateInstallerPath = update.InstallerPath;
|
||||
}
|
||||
|
||||
ForceClose();
|
||||
}
|
||||
else{
|
||||
Show();
|
||||
});
|
||||
}
|
||||
|
||||
private void updates_UpdateDismissed(object sender, UpdateDismissedEventArgs e){
|
||||
Config.DismissedUpdate = e.VersionTag;
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
private void soundNotification_PlaybackError(object sender, PlaybackErrorEventArgs e){
|
||||
e.Ignore = true;
|
||||
|
||||
using(FormMessage form = new FormMessage("Notification Sound Error", "Could not play custom notification sound."+Environment.NewLine+e.Message, MessageBoxIcon.Error)){
|
||||
form.CancelButton = form.AddButton("Ignore");
|
||||
|
||||
Button btnOpenSettings = form.AddButton("View Options");
|
||||
btnOpenSettings.Width += 16;
|
||||
btnOpenSettings.Location = new Point(btnOpenSettings.Location.X-16, btnOpenSettings.Location.Y);
|
||||
|
||||
if (form.ShowDialog() == DialogResult.OK && form.ClickedButton == btnOpenSettings){
|
||||
OpenSettings(typeof(TabSettingsSounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m){
|
||||
if (isLoaded && m.Msg == Program.WindowRestoreMessage){
|
||||
trayIcon_ClickRestore(trayIcon, new EventArgs());
|
||||
using(Process process = Process.GetCurrentProcess()){
|
||||
if (process.Id == m.WParam.ToInt32()){
|
||||
trayIcon_ClickRestore(trayIcon, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLoaded && m.Msg == 0x210 && (m.WParam.ToInt32() & 0xFFFF) == 0x020B){ // WM_PARENTNOTIFY, WM_XBUTTONDOWN
|
||||
if (isBrowserReady && m.Msg == NativeMethods.WM_PARENTNOTIFY && (m.WParam.ToInt32() & 0xFFFF) == NativeMethods.WM_XBUTTONDOWN){
|
||||
browser.ExecuteScriptAsync("TDGF_onMouseClickExtra", (m.WParam.ToInt32() >> 16) & 0xFFFF);
|
||||
return;
|
||||
}
|
||||
@@ -234,63 +342,107 @@ namespace TweetDck.Core{
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
// notification helpers
|
||||
|
||||
public FormNotificationMain CreateNotificationForm(bool enableContextMenu){
|
||||
return new FormNotificationMain(this, plugins, enableContextMenu);
|
||||
}
|
||||
|
||||
public void PauseNotification(){
|
||||
notification.PauseNotification();
|
||||
}
|
||||
|
||||
public void ResumeNotification(){
|
||||
notification.ResumeNotification();
|
||||
}
|
||||
|
||||
// javascript calls
|
||||
|
||||
public void ReinjectCustomCSS(string css){
|
||||
browser.ExecuteScriptAsync("TDGF_reinjectCustomCSS", css?.Replace(Environment.NewLine, " ") ?? string.Empty);
|
||||
}
|
||||
|
||||
public void UpdateProperties(PropertyBridge.Properties properties){
|
||||
browser.ExecuteScriptAsync(PropertyBridge.GenerateScript(properties));
|
||||
}
|
||||
|
||||
public void ReloadToTweetDeck(){
|
||||
browser.ExecuteScriptAsync("window.location.href = 'https://tweetdeck.twitter.com'");
|
||||
}
|
||||
|
||||
// callback handlers
|
||||
|
||||
public void OpenContextMenu(){
|
||||
contextMenu.Show(this, PointToClient(Cursor.Position));
|
||||
}
|
||||
|
||||
public void OpenSettings(){
|
||||
if (currentFormSettings != null){
|
||||
currentFormSettings.BringToFront();
|
||||
}
|
||||
else{
|
||||
OpenSettings(null);
|
||||
}
|
||||
|
||||
public void OpenSettings(Type startTab){
|
||||
if (!TryBringToFront<FormSettings>()){
|
||||
bool prevEnableUpdateCheck = Config.EnableUpdateCheck;
|
||||
|
||||
currentFormSettings = new FormSettings(this, plugins, updates);
|
||||
|
||||
currentFormSettings.FormClosed += (sender, args) => {
|
||||
currentFormSettings = null;
|
||||
FormSettings form = new FormSettings(this, plugins, updates, startTab);
|
||||
|
||||
form.FormClosed += (sender, args) => {
|
||||
if (!prevEnableUpdateCheck && Config.EnableUpdateCheck){
|
||||
Config.DismissedUpdate = string.Empty;
|
||||
Config.Save();
|
||||
updates.DismissUpdate(string.Empty);
|
||||
updates.Check(false);
|
||||
}
|
||||
|
||||
if (!Config.EnableTrayHighlight){
|
||||
trayIcon.HasNotifications = false;
|
||||
}
|
||||
|
||||
UpdateProperties(PropertyBridge.Properties.ExpandLinksOnHover | PropertyBridge.Properties.SwitchAccountSelectors | PropertyBridge.Properties.HasCustomNotificationSound);
|
||||
form.Dispose();
|
||||
};
|
||||
|
||||
ShowChildForm(currentFormSettings);
|
||||
ShowChildForm(form);
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenAbout(){
|
||||
if (currentFormAbout != null){
|
||||
currentFormAbout.BringToFront();
|
||||
}
|
||||
else{
|
||||
currentFormAbout = new FormAbout();
|
||||
currentFormAbout.FormClosed += (sender, args) => currentFormAbout = null;
|
||||
ShowChildForm(currentFormAbout);
|
||||
if (!TryBringToFront<FormAbout>()){
|
||||
ShowChildForm(new FormAbout());
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenPlugins(){
|
||||
if (currentFormPlugins != null){
|
||||
currentFormPlugins.BringToFront();
|
||||
}
|
||||
else{
|
||||
currentFormPlugins = new FormPlugins(plugins);
|
||||
currentFormPlugins.FormClosed += (sender, args) => currentFormPlugins = null;
|
||||
ShowChildForm(currentFormPlugins);
|
||||
if (!TryBringToFront<FormPlugins>()){
|
||||
ShowChildForm(new FormPlugins(plugins));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTweetNotification(){
|
||||
public void OnTweetNotification(){ // may be called multiple times, once for each type of notification
|
||||
if (Config.EnableTrayHighlight && !ContainsFocus){
|
||||
trayIcon.HasNotifications = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayNotificationSound(){
|
||||
if (Config.NotificationSoundPath.Length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
if (soundNotification == null){
|
||||
soundNotification = new SoundNotification();
|
||||
soundNotification.PlaybackError += soundNotification_PlaybackError;
|
||||
}
|
||||
|
||||
soundNotification.Play(Config.NotificationSoundPath);
|
||||
}
|
||||
|
||||
public void OnTweetScreenshotReady(string html, int width, int height){
|
||||
if (notificationScreenshotManager == null){
|
||||
notificationScreenshotManager = new TweetScreenshotManager(this);
|
||||
}
|
||||
|
||||
notificationScreenshotManager.Trigger(html, width, height);
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text){
|
||||
if (string.IsNullOrEmpty(text)){
|
||||
toolTip.Hide(this);
|
||||
@@ -302,16 +454,8 @@ namespace TweetDck.Core{
|
||||
}
|
||||
}
|
||||
|
||||
public void OnImagePasted(){
|
||||
browser.ExecuteScriptAsync("TDGF_tryPasteImage", new object[0]);
|
||||
}
|
||||
|
||||
public void OnImagePastedFinish(){
|
||||
browser.ExecuteScriptAsync("TDGF_tryPasteImageFinish", new object[0]);
|
||||
}
|
||||
|
||||
public void ReloadBrowser(){
|
||||
browser.ExecuteScriptAsync("window.location.reload()");
|
||||
public void TriggerTweetScreenshot(){
|
||||
browser.ExecuteScriptAsync("TDGF_triggerScreenshot()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,375 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using TweetDck.Configuration;
|
||||
using TweetDck.Core.Handling;
|
||||
using TweetDck.Resources;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDck.Plugins.Enums;
|
||||
|
||||
namespace TweetDck.Core{
|
||||
sealed partial class FormNotification : Form{
|
||||
private const string NotificationScriptFile = "notification.js";
|
||||
|
||||
private static readonly string NotificationScriptIdentifier = ScriptLoader.GetRootIdentifier(NotificationScriptFile);
|
||||
private static readonly string PluginScriptIdentifier = ScriptLoader.GetRootIdentifier(PluginManager.PluginNotificationScriptFile);
|
||||
|
||||
public Func<bool> CanMoveWindow = () => true;
|
||||
|
||||
private readonly Form owner;
|
||||
private readonly PluginManager plugins;
|
||||
private readonly ChromiumWebBrowser browser;
|
||||
|
||||
private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4);
|
||||
private readonly bool autoHide;
|
||||
private int timeLeft, totalTime;
|
||||
|
||||
private readonly NativeMethods.HookProc mouseHookDelegate;
|
||||
private IntPtr mouseHook;
|
||||
|
||||
private bool? prevDisplayTimer;
|
||||
private int? prevFontSize;
|
||||
|
||||
private bool RequiresResize{
|
||||
get{
|
||||
return !prevDisplayTimer.HasValue || !prevFontSize.HasValue || prevDisplayTimer != Program.UserConfig.DisplayNotificationTimer || prevFontSize != TweetNotification.FontSizeLevel;
|
||||
}
|
||||
|
||||
set{
|
||||
if (value){
|
||||
prevDisplayTimer = null;
|
||||
prevFontSize = null;
|
||||
}
|
||||
else{
|
||||
prevDisplayTimer = Program.UserConfig.DisplayNotificationTimer;
|
||||
prevFontSize = TweetNotification.FontSizeLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly string notificationJS;
|
||||
private readonly string pluginJS;
|
||||
|
||||
protected override bool ShowWithoutActivation{
|
||||
get{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool FreezeTimer { get; set; }
|
||||
public bool ContextMenuOpen { get; set; }
|
||||
public string CurrentUrl { get; private set; }
|
||||
public string CurrentQuotedTweetUrl { get; set; }
|
||||
|
||||
public EventHandler Initialized;
|
||||
private bool isInitialized;
|
||||
|
||||
private static int BaseClientWidth{
|
||||
get{
|
||||
int level = TweetNotification.FontSizeLevel;
|
||||
return level == 0 ? 284 : (int)Math.Round(284.0*(1.0+0.05*level));
|
||||
}
|
||||
}
|
||||
|
||||
private static int BaseClientHeight{
|
||||
get{
|
||||
int level = TweetNotification.FontSizeLevel;
|
||||
return level == 0 ? 118 : (int)Math.Round(118.0*(1.0+0.075*level));
|
||||
}
|
||||
}
|
||||
|
||||
public FormNotification(FormBrowser owner, PluginManager pluginManager, bool autoHide){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName;
|
||||
|
||||
this.owner = owner;
|
||||
this.plugins = pluginManager;
|
||||
this.autoHide = autoHide;
|
||||
|
||||
owner.FormClosed += (sender, args) => Close();
|
||||
|
||||
notificationJS = ScriptLoader.LoadResource(NotificationScriptFile);
|
||||
pluginJS = ScriptLoader.LoadResource(PluginManager.PluginNotificationScriptFile);
|
||||
|
||||
browser = new ChromiumWebBrowser("about:blank"){
|
||||
MenuHandler = new ContextMenuNotification(this, autoHide),
|
||||
LifeSpanHandler = new LifeSpanHandler()
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
||||
#endif
|
||||
|
||||
browser.IsBrowserInitializedChanged += Browser_IsBrowserInitializedChanged;
|
||||
browser.FrameLoadEnd += Browser_FrameLoadEnd;
|
||||
browser.RegisterJsObject("$TD", new TweetDeckBridge(owner, this));
|
||||
browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
||||
|
||||
panelBrowser.Controls.Add(browser);
|
||||
|
||||
if (autoHide){
|
||||
Program.UserConfig.MuteToggled += Config_MuteToggled;
|
||||
Disposed += (sender, args) => Program.UserConfig.MuteToggled -= Config_MuteToggled;
|
||||
}
|
||||
|
||||
mouseHookDelegate = MouseHookProc;
|
||||
|
||||
Disposed += FormNotification_Disposed;
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m){
|
||||
if (m.Msg == 0x0112 && (m.WParam.ToInt32() & 0xFFF0) == 0xF010 && !CanMoveWindow()){ // WM_SYSCOMMAND, SC_MOVE
|
||||
return;
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
// mouse wheel hook
|
||||
|
||||
private void StartMouseHook(){
|
||||
if (mouseHook == IntPtr.Zero){
|
||||
mouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, mouseHookDelegate, IntPtr.Zero, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void StopMouseHook(){
|
||||
if (mouseHook != IntPtr.Zero){
|
||||
NativeMethods.UnhookWindowsHookEx(mouseHook);
|
||||
mouseHook = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam){
|
||||
if (!ContainsFocus && wParam.ToInt32() == NativeMethods.WH_MOUSEWHEEL && browser.Bounds.Contains(PointToClient(Cursor.Position))){
|
||||
// fuck it, Activate() doesn't work with this
|
||||
Point prevPos = Cursor.Position;
|
||||
Cursor.Position = PointToScreen(new Point(0, -1));
|
||||
NativeMethods.SimulateMouseClick(NativeMethods.MouseButton.Left);
|
||||
Cursor.Position = prevPos;
|
||||
}
|
||||
|
||||
return NativeMethods.CallNextHookEx(mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void timerHideProgress_Tick(object sender, EventArgs e){
|
||||
if (Bounds.Contains(Cursor.Position) || FreezeTimer || ContextMenuOpen)return;
|
||||
|
||||
timeLeft -= timerProgress.Interval;
|
||||
|
||||
int value = (int)Math.Round(1025.0*(totalTime-timeLeft)/totalTime);
|
||||
progressBarTimer.SetValueInstant(Math.Min(1000, Math.Max(0, Program.UserConfig.NotificationTimerCountDown ? 1000-value : value)));
|
||||
|
||||
if (timeLeft <= 0){
|
||||
FinishCurrentTweet();
|
||||
}
|
||||
}
|
||||
|
||||
private void Config_MuteToggled(object sender, EventArgs e){
|
||||
if (Program.UserConfig.MuteNotifications){
|
||||
HideNotification(true);
|
||||
}
|
||||
else if (tweetQueue.Count > 0){
|
||||
LoadNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private void Browser_IsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs e){
|
||||
if (e.IsBrowserInitialized && Initialized != null){
|
||||
Initialized(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
if (!e.Frame.IsMain)return;
|
||||
|
||||
if (!isInitialized && !Program.UserConfig.NotificationLegacyLoad){
|
||||
isInitialized = true;
|
||||
|
||||
if (Initialized != null){
|
||||
Initialized(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
else if (notificationJS != null && browser.Address != "about:blank"){
|
||||
ScriptLoader.ExecuteScript(e.Frame, notificationJS, NotificationScriptIdentifier);
|
||||
|
||||
if (plugins.HasAnyPlugin(PluginEnvironment.Notification)){
|
||||
ScriptLoader.ExecuteScript(e.Frame, pluginJS, PluginScriptIdentifier);
|
||||
ScriptLoader.ExecuteFile(e.Frame, PluginManager.PluginGlobalScriptFile);
|
||||
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Notification, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FormNotification_FormClosing(object sender, FormClosingEventArgs e){
|
||||
if (e.CloseReason == CloseReason.UserClosing){
|
||||
HideNotification(false);
|
||||
tweetQueue.Clear();
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void FormNotification_Disposed(object sender, EventArgs e){
|
||||
browser.Dispose();
|
||||
StopMouseHook();
|
||||
}
|
||||
|
||||
// notification methods
|
||||
|
||||
public void ShowNotification(TweetNotification notification){
|
||||
if (Program.UserConfig.MuteNotifications){
|
||||
tweetQueue.Enqueue(notification);
|
||||
}
|
||||
else{
|
||||
tweetQueue.Enqueue(notification);
|
||||
UpdateTitle();
|
||||
|
||||
if (totalTime == 0){
|
||||
LoadNextNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowNotificationForSettings(bool reset){
|
||||
if (reset){
|
||||
LoadTweet(TweetNotification.ExampleTweet);
|
||||
}
|
||||
else{
|
||||
MoveToVisibleLocation();
|
||||
}
|
||||
}
|
||||
|
||||
public void HideNotification(bool loadBlank){
|
||||
if (loadBlank || Program.UserConfig.NotificationLegacyLoad){
|
||||
browser.LoadHtml("", "about:blank");
|
||||
}
|
||||
|
||||
Location = new Point(-32000, -32000);
|
||||
progressBarTimer.Value = Program.UserConfig.NotificationTimerCountDown ? 1000 : 0;
|
||||
timerProgress.Stop();
|
||||
totalTime = 0;
|
||||
|
||||
StopMouseHook();
|
||||
}
|
||||
|
||||
public void OnNotificationReady(){
|
||||
UpdateTitle();
|
||||
MoveToVisibleLocation();
|
||||
timerProgress.Start();
|
||||
}
|
||||
|
||||
public void FinishCurrentTweet(){
|
||||
if (tweetQueue.Count > 0){
|
||||
LoadNextNotification();
|
||||
}
|
||||
else if (autoHide){
|
||||
HideNotification(true);
|
||||
}
|
||||
else{
|
||||
timerProgress.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadNextNotification(){
|
||||
LoadTweet(tweetQueue.Dequeue());
|
||||
}
|
||||
|
||||
private void LoadTweet(TweetNotification tweet){
|
||||
CurrentUrl = tweet.Url;
|
||||
CurrentQuotedTweetUrl = string.Empty; // load from JS
|
||||
|
||||
timerProgress.Stop();
|
||||
totalTime = timeLeft = tweet.GetDisplayDuration(Program.UserConfig.NotificationDurationValue);
|
||||
progressBarTimer.Value = Program.UserConfig.NotificationTimerCountDown ? 1000 : 0;
|
||||
|
||||
browser.LoadHtml(tweet.GenerateHtml(), "http://tweetdeck.twitter.com/?"+DateTime.Now.Ticks);
|
||||
|
||||
if (Program.UserConfig.NotificationLegacyLoad){
|
||||
OnNotificationReady();
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveToVisibleLocation(){
|
||||
UserConfig config = Program.UserConfig;
|
||||
|
||||
if (RequiresResize){
|
||||
RequiresResize = false;
|
||||
|
||||
if (config.DisplayNotificationTimer){
|
||||
ClientSize = new Size(BaseClientWidth, BaseClientHeight+4);
|
||||
progressBarTimer.Visible = true;
|
||||
}
|
||||
else{
|
||||
ClientSize = new Size(BaseClientWidth, BaseClientHeight);
|
||||
progressBarTimer.Visible = false;
|
||||
}
|
||||
|
||||
panelBrowser.Height = BaseClientHeight;
|
||||
}
|
||||
|
||||
Screen screen = Screen.FromControl(owner);
|
||||
|
||||
if (config.NotificationDisplay > 0 && config.NotificationDisplay <= Screen.AllScreens.Length){
|
||||
screen = Screen.AllScreens[config.NotificationDisplay-1];
|
||||
}
|
||||
|
||||
bool needsReactivating = Location.X == -32000;
|
||||
int edgeDist = config.NotificationEdgeDistance;
|
||||
|
||||
switch(config.NotificationPosition){
|
||||
case TweetNotification.Position.TopLeft:
|
||||
Location = new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+edgeDist);
|
||||
break;
|
||||
|
||||
case TweetNotification.Position.TopRight:
|
||||
Location = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
|
||||
break;
|
||||
|
||||
case TweetNotification.Position.BottomLeft:
|
||||
Location = new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
|
||||
break;
|
||||
|
||||
case TweetNotification.Position.BottomRight:
|
||||
Location = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
|
||||
break;
|
||||
|
||||
case TweetNotification.Position.Custom:
|
||||
if (!config.IsCustomNotificationPositionSet){
|
||||
config.CustomNotificationPosition = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
|
||||
config.Save();
|
||||
}
|
||||
|
||||
Location = config.CustomNotificationPosition;
|
||||
break;
|
||||
}
|
||||
|
||||
if (needsReactivating){
|
||||
NativeMethods.SetFormPos(this, NativeMethods.HWND_TOPMOST, NativeMethods.SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
StartMouseHook();
|
||||
}
|
||||
|
||||
private void UpdateTitle(){
|
||||
Text = tweetQueue.Count > 0 ? Program.BrandName+" ("+tweetQueue.Count+" more left)" : Program.BrandName;
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text){
|
||||
if (string.IsNullOrEmpty(text)){
|
||||
toolTip.Hide(this);
|
||||
}
|
||||
else{
|
||||
Point position = PointToClient(Cursor.Position);
|
||||
position.Offset(20, 5);
|
||||
toolTip.Show(text, this, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +1,11 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class BrowserProcessHandler : IBrowserProcessHandler{
|
||||
void IBrowserProcessHandler.OnContextInitialized(){
|
||||
using(IRequestContext ctx = Cef.GetGlobalRequestContext()){
|
||||
string err;
|
||||
ctx.SetPreference("browser.enable_spellchecking", Program.UserConfig.EnableSpellCheck, out err);
|
||||
ctx.SetPreference("browser.enable_spellchecking", Program.UserConfig.EnableSpellCheck, out string _);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,21 +1,43 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
namespace TweetDuck.Core.Handling{
|
||||
abstract class ContextMenuBase : IContextMenuHandler{
|
||||
private static readonly Lazy<Regex> RegexTwitterAccount = new Lazy<Regex>(() => new Regex(@"^https?://twitter\.com/([^/]+)/?$", RegexOptions.Compiled), false);
|
||||
protected static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak"));
|
||||
|
||||
private const int MenuOpenLinkUrl = 26500;
|
||||
private const int MenuCopyLinkUrl = 26501;
|
||||
private const int MenuOpenImage = 26502;
|
||||
private const int MenuSaveImage = 26503;
|
||||
private const int MenuCopyImageUrl = 26504;
|
||||
private const int MenuCopyUsername = 26502;
|
||||
private const int MenuOpenImage = 26503;
|
||||
private const int MenuSaveImage = 26504;
|
||||
private const int MenuCopyImageUrl = 26505;
|
||||
private const int MenuOpenDevTools = 26599;
|
||||
|
||||
private readonly Form form;
|
||||
|
||||
protected ContextMenuBase(Form form){
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Link) && !parameters.UnfilteredLinkUrl.EndsWith("tweetdeck.twitter.com/#", StringComparison.Ordinal)){
|
||||
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open link in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy link address");
|
||||
if (RegexTwitterAccount.Value.IsMatch(parameters.UnfilteredLinkUrl)){
|
||||
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open account in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy account address");
|
||||
model.AddItem((CefMenuCommand)MenuCopyUsername, "Copy account username");
|
||||
}
|
||||
else{
|
||||
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open link in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy link address");
|
||||
}
|
||||
|
||||
model.AddSeparator();
|
||||
}
|
||||
|
||||
@@ -34,7 +56,7 @@ namespace TweetDck.Core.Handling{
|
||||
break;
|
||||
|
||||
case MenuCopyLinkUrl:
|
||||
Clipboard.SetText(string.IsNullOrEmpty(TweetDeckBridge.LastRightClickedLink) ? parameters.UnfilteredLinkUrl : TweetDeckBridge.LastRightClickedLink, TextDataFormat.UnicodeText);
|
||||
SetClipboardText(string.IsNullOrEmpty(TweetDeckBridge.LastRightClickedLink) ? parameters.UnfilteredLinkUrl : TweetDeckBridge.LastRightClickedLink);
|
||||
break;
|
||||
|
||||
case MenuOpenImage:
|
||||
@@ -57,7 +79,7 @@ namespace TweetDck.Core.Handling{
|
||||
}
|
||||
|
||||
if (saveTarget != null){
|
||||
BrowserUtils.DownloadFileAsync(parameters.SourceUrl, saveTarget, ex => {
|
||||
BrowserUtils.DownloadFileAsync(parameters.SourceUrl, saveTarget, null, ex => {
|
||||
MessageBox.Show("An error occurred while downloading the image: "+ex.Message, Program.BrandName+" Has Failed :(", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
});
|
||||
}
|
||||
@@ -65,7 +87,16 @@ namespace TweetDck.Core.Handling{
|
||||
break;
|
||||
|
||||
case MenuCopyImageUrl:
|
||||
Clipboard.SetText(parameters.SourceUrl, TextDataFormat.UnicodeText);
|
||||
SetClipboardText(parameters.SourceUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyUsername:
|
||||
Match match = RegexTwitterAccount.Value.Match(parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
||||
break;
|
||||
|
||||
case MenuOpenDevTools:
|
||||
browserControl.ShowDevTools();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -78,6 +109,14 @@ namespace TweetDck.Core.Handling{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void SetClipboardText(string text){
|
||||
form.InvokeAsyncSafe(() => WindowsUtils.SetClipboard(text, TextDataFormat.UnicodeText));
|
||||
}
|
||||
|
||||
protected void AddDebugMenuItems(IMenuModel model){
|
||||
model.AddItem((CefMenuCommand)MenuOpenDevTools, "Open dev tools");
|
||||
}
|
||||
|
||||
protected static void RemoveSeparatorIfLast(IMenuModel model){
|
||||
if (model.Count > 0 && model.GetTypeAt(model.Count-1) == MenuItemType.Separator){
|
||||
model.RemoveAt(model.Count-1);
|
||||
|
@@ -1,9 +1,10 @@
|
||||
using CefSharp;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class ContextMenuBrowser : ContextMenuBase{
|
||||
private const int MenuGlobal = 26600;
|
||||
private const int MenuMute = 26601;
|
||||
@@ -15,13 +16,20 @@ namespace TweetDck.Core.Handling{
|
||||
private const int MenuCopyTweetUrl = 26611;
|
||||
private const int MenuOpenQuotedTweetUrl = 26612;
|
||||
private const int MenuCopyQuotedTweetUrl = 26613;
|
||||
private const int MenuScreenshotTweet = 26614;
|
||||
|
||||
private const string TitleReloadBrowser = "Reload browser";
|
||||
private const string TitleMuteNotifications = "Mute notifications";
|
||||
private const string TitleSettings = "Options";
|
||||
private const string TitlePlugins = "Plugins";
|
||||
private const string TitleAboutProgram = "About "+Program.BrandName;
|
||||
|
||||
private readonly FormBrowser form;
|
||||
|
||||
private string lastHighlightedTweet;
|
||||
private string lastHighlightedQuotedTweet;
|
||||
|
||||
public ContextMenuBrowser(FormBrowser form){
|
||||
public ContextMenuBrowser(FormBrowser form) : base(form){
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
@@ -32,12 +40,16 @@ namespace TweetDck.Core.Handling{
|
||||
model.Remove(CefMenuCommand.ViewSource);
|
||||
RemoveSeparatorIfLast(model);
|
||||
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Selection)){
|
||||
model.AddSeparator();
|
||||
}
|
||||
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
|
||||
lastHighlightedTweet = TweetDeckBridge.LastHighlightedTweet;
|
||||
lastHighlightedQuotedTweet = TweetDeckBridge.LastHighlightedQuotedTweet;
|
||||
|
||||
if (!BrowserUtils.IsTweetDeckWebsite(frame)){
|
||||
if (!BrowserUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
|
||||
lastHighlightedTweet = string.Empty;
|
||||
lastHighlightedQuotedTweet = string.Empty;
|
||||
}
|
||||
@@ -45,6 +57,7 @@ namespace TweetDck.Core.Handling{
|
||||
if (!string.IsNullOrEmpty(lastHighlightedTweet) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||
model.AddItem((CefMenuCommand)MenuOpenTweetUrl, "Open tweet in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||
model.AddItem((CefMenuCommand)MenuScreenshotTweet, "Screenshot tweet to clipboard");
|
||||
|
||||
if (!string.IsNullOrEmpty(lastHighlightedQuotedTweet)){
|
||||
model.AddSeparator();
|
||||
@@ -60,15 +73,22 @@ namespace TweetDck.Core.Handling{
|
||||
|
||||
IMenuModel globalMenu = model.Count == 0 ? model : model.AddSubMenu((CefMenuCommand)MenuGlobal, Program.BrandName);
|
||||
|
||||
globalMenu.AddItem(CefMenuCommand.Reload, "Reload browser");
|
||||
globalMenu.AddCheckItem((CefMenuCommand)MenuMute, "Mute notifications");
|
||||
globalMenu.AddItem(CefMenuCommand.Reload, TitleReloadBrowser);
|
||||
globalMenu.AddCheckItem((CefMenuCommand)MenuMute, TitleMuteNotifications);
|
||||
globalMenu.SetChecked((CefMenuCommand)MenuMute, Program.UserConfig.MuteNotifications);
|
||||
globalMenu.AddSeparator();
|
||||
|
||||
globalMenu.AddItem((CefMenuCommand)MenuSettings, "Settings");
|
||||
globalMenu.AddItem((CefMenuCommand)MenuPlugins, "Plugins");
|
||||
globalMenu.AddItem((CefMenuCommand)MenuAbout, "About "+Program.BrandName);
|
||||
globalMenu.AddItem((CefMenuCommand)MenuSettings, TitleSettings);
|
||||
globalMenu.AddItem((CefMenuCommand)MenuPlugins, TitlePlugins);
|
||||
globalMenu.AddItem((CefMenuCommand)MenuAbout, TitleAboutProgram);
|
||||
|
||||
if (HasDevTools){
|
||||
globalMenu.AddSeparator();
|
||||
AddDebugMenuItems(globalMenu);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveSeparatorIfLast(model);
|
||||
}
|
||||
|
||||
public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
||||
@@ -78,27 +98,23 @@ namespace TweetDck.Core.Handling{
|
||||
|
||||
switch((int)commandId){
|
||||
case (int)CefMenuCommand.Reload:
|
||||
frame.ExecuteJavaScriptAsync("window.location.href = 'https://tweetdeck.twitter.com'");
|
||||
form.InvokeAsyncSafe(form.ReloadToTweetDeck);
|
||||
return true;
|
||||
|
||||
case MenuSettings:
|
||||
form.InvokeSafe(form.OpenSettings);
|
||||
form.InvokeAsyncSafe(form.OpenSettings);
|
||||
return true;
|
||||
|
||||
case MenuAbout:
|
||||
form.InvokeSafe(form.OpenAbout);
|
||||
form.InvokeAsyncSafe(form.OpenAbout);
|
||||
return true;
|
||||
|
||||
case MenuPlugins:
|
||||
form.InvokeSafe(form.OpenPlugins);
|
||||
form.InvokeAsyncSafe(form.OpenPlugins);
|
||||
return true;
|
||||
|
||||
case MenuMute:
|
||||
form.InvokeSafe(() => {
|
||||
Program.UserConfig.MuteNotifications = !Program.UserConfig.MuteNotifications;
|
||||
Program.UserConfig.Save();
|
||||
});
|
||||
|
||||
form.InvokeAsyncSafe(ToggleMuteNotifications);
|
||||
return true;
|
||||
|
||||
case MenuOpenTweetUrl:
|
||||
@@ -106,7 +122,11 @@ namespace TweetDck.Core.Handling{
|
||||
return true;
|
||||
|
||||
case MenuCopyTweetUrl:
|
||||
Clipboard.SetText(lastHighlightedTweet, TextDataFormat.UnicodeText);
|
||||
SetClipboardText(lastHighlightedTweet);
|
||||
return true;
|
||||
|
||||
case MenuScreenshotTweet:
|
||||
form.InvokeAsyncSafe(form.TriggerTweetScreenshot);
|
||||
return true;
|
||||
|
||||
case MenuOpenQuotedTweetUrl:
|
||||
@@ -114,11 +134,33 @@ namespace TweetDck.Core.Handling{
|
||||
return true;
|
||||
|
||||
case MenuCopyQuotedTweetUrl:
|
||||
Clipboard.SetText(lastHighlightedQuotedTweet, TextDataFormat.UnicodeText);
|
||||
SetClipboardText(lastHighlightedQuotedTweet);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ContextMenu CreateMenu(FormBrowser form){
|
||||
ContextMenu menu = new ContextMenu();
|
||||
|
||||
menu.MenuItems.Add(TitleReloadBrowser, (sender, args) => form.ReloadToTweetDeck());
|
||||
menu.MenuItems.Add(TitleMuteNotifications, (sender, args) => ToggleMuteNotifications());
|
||||
menu.MenuItems.Add("-");
|
||||
menu.MenuItems.Add(TitleSettings, (sender, args) => form.OpenSettings());
|
||||
menu.MenuItems.Add(TitlePlugins, (sender, args) => form.OpenPlugins());
|
||||
menu.MenuItems.Add(TitleAboutProgram, (sender, args) => form.OpenAbout());
|
||||
|
||||
menu.Popup += (sender, args) => {
|
||||
menu.MenuItems[1].Checked = Program.UserConfig.MuteNotifications;
|
||||
};
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private static void ToggleMuteNotifications(){
|
||||
Program.UserConfig.MuteNotifications = !Program.UserConfig.MuteNotifications;
|
||||
Program.UserConfig.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,18 +1,18 @@
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDck.Core.Controls;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class ContextMenuNotification : ContextMenuBase{
|
||||
private const int MenuSkipTweet = 26600;
|
||||
private const int MenuFreeze = 26601;
|
||||
private const int MenuCopyTweetUrl = 26602;
|
||||
private const int MenuCopyQuotedTweetUrl = 26603;
|
||||
|
||||
private readonly FormNotification form;
|
||||
private readonly FormNotificationBase form;
|
||||
private readonly bool enableCustomMenu;
|
||||
|
||||
public ContextMenuNotification(FormNotification form, bool enableCustomMenu){
|
||||
public ContextMenuNotification(FormNotificationBase form, bool enableCustomMenu) : base(form){
|
||||
this.form = form;
|
||||
this.enableCustomMenu = enableCustomMenu;
|
||||
}
|
||||
@@ -20,27 +20,37 @@ namespace TweetDck.Core.Handling{
|
||||
public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
model.Clear();
|
||||
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Selection)){
|
||||
model.AddItem(CefMenuCommand.Copy, "Copy");
|
||||
model.AddSeparator();
|
||||
}
|
||||
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
|
||||
if (enableCustomMenu){
|
||||
model.AddItem((CefMenuCommand)MenuSkipTweet, "Skip tweet");
|
||||
model.AddCheckItem((CefMenuCommand)MenuFreeze, "Freeze");
|
||||
model.SetChecked((CefMenuCommand)MenuFreeze, form.FreezeTimer);
|
||||
model.AddSeparator();
|
||||
|
||||
if (!string.IsNullOrEmpty(form.CurrentUrl)){
|
||||
if (!string.IsNullOrEmpty(form.CurrentTweetUrl)){
|
||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||
|
||||
if (!string.IsNullOrEmpty(form.CurrentQuotedTweetUrl)){
|
||||
if (!string.IsNullOrEmpty(form.CurrentQuoteUrl)){
|
||||
model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
}
|
||||
|
||||
model.AddSeparator();
|
||||
}
|
||||
}
|
||||
|
||||
if (HasDevTools){
|
||||
AddDebugMenuItems(model);
|
||||
}
|
||||
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
RemoveSeparatorIfLast(model);
|
||||
|
||||
form.InvokeSafe(() => form.ContextMenuOpen = true);
|
||||
form.InvokeAsyncSafe(() => form.ContextMenuOpen = true);
|
||||
}
|
||||
|
||||
public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
||||
@@ -50,19 +60,19 @@ namespace TweetDck.Core.Handling{
|
||||
|
||||
switch((int)commandId){
|
||||
case MenuSkipTweet:
|
||||
form.InvokeSafe(form.FinishCurrentTweet);
|
||||
form.InvokeAsyncSafe(form.FinishCurrentNotification);
|
||||
return true;
|
||||
|
||||
case MenuFreeze:
|
||||
form.InvokeSafe(() => form.FreezeTimer = !form.FreezeTimer);
|
||||
form.InvokeAsyncSafe(() => form.FreezeTimer = !form.FreezeTimer);
|
||||
return true;
|
||||
|
||||
case MenuCopyTweetUrl:
|
||||
Clipboard.SetText(form.CurrentUrl, TextDataFormat.UnicodeText);
|
||||
SetClipboardText(form.CurrentTweetUrl);
|
||||
return true;
|
||||
|
||||
case MenuCopyQuotedTweetUrl:
|
||||
Clipboard.SetText(form.CurrentQuotedTweetUrl, TextDataFormat.UnicodeText);
|
||||
SetClipboardText(form.CurrentQuoteUrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,7 +81,7 @@ namespace TweetDck.Core.Handling{
|
||||
|
||||
public override void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){
|
||||
base.OnContextMenuDismissed(browserControl, browser, frame);
|
||||
form.InvokeSafe(() => form.ContextMenuOpen = false);
|
||||
form.InvokeAsyncSafe(() => form.ContextMenuOpen = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,27 +0,0 @@
|
||||
using CefSharp;
|
||||
using System.Collections.Generic;
|
||||
using TweetDck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
class DialogHandlerBrowser : IDialogHandler{
|
||||
private readonly FormBrowser form;
|
||||
|
||||
public DialogHandlerBrowser(FormBrowser form){
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
public bool OnFileDialog(IWebBrowser browserControl, IBrowser browser, CefFileDialogMode mode, string title, string defaultFilePath, List<string> acceptFilters, int selectedAcceptFilter, IFileDialogCallback callback){
|
||||
if (!string.IsNullOrEmpty(TweetDeckBridge.ClipboardImagePath)){
|
||||
callback.Continue(selectedAcceptFilter, new List<string>{ TweetDeckBridge.ClipboardImagePath });
|
||||
|
||||
form.InvokeSafe(() => {
|
||||
TweetDeckBridge.ClipboardImagePath = string.Empty;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
60
Core/Handling/JavaScriptDialogHandler.cs
Normal file
60
Core/Handling/JavaScriptDialogHandler.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other;
|
||||
|
||||
namespace TweetDuck.Core.Handling {
|
||||
class JavaScriptDialogHandler : IJsDialogHandler{
|
||||
bool IJsDialogHandler.OnJSDialog(IWebBrowser browserControl, IBrowser browser, string originUrl, CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback, ref bool suppressMessage){
|
||||
((ChromiumWebBrowser)browserControl).InvokeSafe(() => {
|
||||
FormMessage form = new FormMessage(Program.BrandName, messageText, MessageBoxIcon.None);
|
||||
TextBox input = null;
|
||||
|
||||
if (dialogType == CefJsDialogType.Alert){
|
||||
form.AcceptButton = form.AddButton("OK");
|
||||
}
|
||||
else if (dialogType == CefJsDialogType.Confirm){
|
||||
form.CancelButton = form.AddButton("No", DialogResult.No);
|
||||
form.AcceptButton = form.AddButton("Yes");
|
||||
}
|
||||
else if (dialogType == CefJsDialogType.Prompt){
|
||||
form.CancelButton = form.AddButton("Cancel", DialogResult.Cancel);
|
||||
form.AcceptButton = form.AddButton("OK");
|
||||
|
||||
input = new TextBox{
|
||||
Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom,
|
||||
Location = new Point(27, form.ActionPanelY-46),
|
||||
Size = new Size(form.ClientSize.Width-54, 20)
|
||||
};
|
||||
|
||||
form.Controls.Add(input);
|
||||
form.ActiveControl = input;
|
||||
form.Height += input.Size.Height+input.Margin.Vertical;
|
||||
}
|
||||
|
||||
bool success = form.ShowDialog() == DialogResult.OK;
|
||||
|
||||
if (input == null){
|
||||
callback.Continue(success);
|
||||
}
|
||||
else{
|
||||
callback.Continue(success, input.Text);
|
||||
input.Dispose();
|
||||
}
|
||||
|
||||
form.Dispose();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IJsDialogHandler.OnJSBeforeUnload(IWebBrowser browserControl, IBrowser browser, string message, bool isReload, IJsDialogCallback callback){
|
||||
return false;
|
||||
}
|
||||
|
||||
void IJsDialogHandler.OnResetDialogState(IWebBrowser browserControl, IBrowser browser){}
|
||||
void IJsDialogHandler.OnDialogClosed(IWebBrowser browserControl, IBrowser browser){}
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
using CefSharp;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class LifeSpanHandler : ILifeSpanHandler{
|
||||
public bool OnBeforePopup(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser){
|
||||
newBrowser = null;
|
||||
|
68
Core/Handling/RequestHandler.cs
Normal file
68
Core/Handling/RequestHandler.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using CefSharp;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
abstract class RequestHandler : IRequestHandler{
|
||||
// Browser
|
||||
|
||||
public virtual void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser){}
|
||||
|
||||
public virtual void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){}
|
||||
|
||||
public virtual bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect){
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture){
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resources
|
||||
|
||||
public virtual CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback){
|
||||
return CefReturnValue.Continue;
|
||||
}
|
||||
|
||||
public virtual void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl){}
|
||||
|
||||
public virtual bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response){
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response){
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength){}
|
||||
|
||||
// JavaScript & Plugins
|
||||
|
||||
public virtual bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback){
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath){}
|
||||
|
||||
// Auth
|
||||
|
||||
public virtual bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback){
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback){
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback){
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
17
Core/Handling/RequestHandlerBrowser.cs
Normal file
17
Core/Handling/RequestHandlerBrowser.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using CefSharp;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class RequestHandlerBrowser : RequestHandler{
|
||||
public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){
|
||||
browser.Reload();
|
||||
}
|
||||
|
||||
public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback){
|
||||
if (request.ResourceType == ResourceType.Script && request.Url.Contains("analytics.")){
|
||||
return CefReturnValue.Cancel;
|
||||
}
|
||||
|
||||
return CefReturnValue.Continue;
|
||||
}
|
||||
}
|
||||
}
|
63
Core/Handling/ResourceHandlerNotification.cs
Normal file
63
Core/Handling/ResourceHandlerNotification.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using CefSharp;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class ResourceHandlerNotification : IResourceHandler{
|
||||
private readonly NameValueCollection headers = new NameValueCollection(0);
|
||||
private MemoryStream dataIn;
|
||||
|
||||
public void SetHTML(string html){
|
||||
dataIn?.Dispose();
|
||||
dataIn = ResourceHandler.GetMemoryStream(html, Encoding.UTF8);
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
if (dataIn != null){
|
||||
dataIn.Dispose();
|
||||
dataIn = null;
|
||||
}
|
||||
}
|
||||
|
||||
bool IResourceHandler.ProcessRequest(IRequest request, ICallback callback){
|
||||
callback.Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
void IResourceHandler.GetResponseHeaders(IResponse response, out long responseLength, out string redirectUrl){
|
||||
redirectUrl = null;
|
||||
|
||||
response.MimeType = "text/html";
|
||||
response.StatusCode = 200;
|
||||
response.StatusText = "OK";
|
||||
response.ResponseHeaders = headers;
|
||||
responseLength = dataIn?.Length ?? -1;
|
||||
}
|
||||
|
||||
bool IResourceHandler.ReadResponse(Stream dataOut, out int bytesRead, ICallback callback){
|
||||
callback.Dispose();
|
||||
|
||||
try{
|
||||
int length = (int)dataIn.Length;
|
||||
|
||||
dataIn.CopyTo(dataOut, length);
|
||||
bytesRead = length;
|
||||
return true;
|
||||
}catch{ // catch IOException, possibly NullReferenceException if dataIn is null
|
||||
bytesRead = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IResourceHandler.CanGetCookie(Cookie cookie){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IResourceHandler.CanSetCookie(Cookie cookie){
|
||||
return true;
|
||||
}
|
||||
|
||||
void IResourceHandler.Cancel(){}
|
||||
}
|
||||
}
|
@@ -1,178 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
class TweetDeckBridge{
|
||||
public static string LastRightClickedLink = string.Empty;
|
||||
public static string LastHighlightedTweet = string.Empty;
|
||||
public static string LastHighlightedQuotedTweet = string.Empty;
|
||||
public static string ClipboardImagePath = string.Empty;
|
||||
|
||||
private readonly FormBrowser form;
|
||||
private readonly FormNotification notification;
|
||||
|
||||
public string BrandName{
|
||||
get{
|
||||
return Program.BrandName;
|
||||
}
|
||||
}
|
||||
|
||||
public string VersionTag{
|
||||
get{
|
||||
return Program.VersionTag;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MuteNotifications{
|
||||
get{
|
||||
return Program.UserConfig.MuteNotifications;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ExpandLinksOnHover{
|
||||
get{
|
||||
return Program.UserConfig.ExpandLinksOnHover;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasCustomBrowserCSS{
|
||||
get{
|
||||
return !string.IsNullOrEmpty(Program.UserConfig.CustomBrowserCSS);
|
||||
}
|
||||
}
|
||||
|
||||
public string CustomBrowserCSS{
|
||||
get{
|
||||
return Program.UserConfig.CustomBrowserCSS;
|
||||
}
|
||||
}
|
||||
|
||||
public TweetDeckBridge(FormBrowser form, FormNotification notification){
|
||||
this.form = form;
|
||||
this.notification = notification;
|
||||
}
|
||||
|
||||
public void LoadFontSizeClass(string fsClass){
|
||||
form.InvokeSafe(() => {
|
||||
TweetNotification.SetFontSizeClass(fsClass);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadNotificationHeadContents(string headContents){
|
||||
form.InvokeSafe(() => {
|
||||
TweetNotification.SetHeadTag(headContents);
|
||||
});
|
||||
}
|
||||
|
||||
public void SetLastRightClickedLink(string link){
|
||||
form.InvokeSafe(() => LastRightClickedLink = link);
|
||||
}
|
||||
|
||||
public void SetLastHighlightedTweet(string link, string quotedLink){
|
||||
form.InvokeSafe(() => {
|
||||
LastHighlightedTweet = link;
|
||||
LastHighlightedQuotedTweet = quotedLink;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetNotificationQuotedTweet(string link){
|
||||
notification.InvokeSafe(() => notification.CurrentQuotedTweetUrl = link);
|
||||
}
|
||||
|
||||
public void OpenSettingsMenu(){
|
||||
form.InvokeSafe(form.OpenSettings);
|
||||
}
|
||||
|
||||
public void OpenPluginsMenu(){
|
||||
form.InvokeSafe(form.OpenPlugins);
|
||||
}
|
||||
|
||||
public void OnTweetPopup(string tweetHtml, string tweetUrl, int tweetCharacters){
|
||||
notification.InvokeSafe(() => {
|
||||
form.OnTweetNotification();
|
||||
notification.ShowNotification(new TweetNotification(tweetHtml, tweetUrl, tweetCharacters));
|
||||
});
|
||||
}
|
||||
|
||||
public void OnTweetSound(){
|
||||
form.InvokeSafe(form.OnTweetNotification);
|
||||
}
|
||||
|
||||
public void OnNotificationReady(){
|
||||
if (!Program.UserConfig.NotificationLegacyLoad){
|
||||
notification.InvokeSafe(notification.OnNotificationReady);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text, bool showInNotification){
|
||||
if (showInNotification){
|
||||
notification.InvokeSafe(() => notification.DisplayTooltip(text));
|
||||
}
|
||||
else{
|
||||
form.InvokeSafe(() => form.DisplayTooltip(text));
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadNextNotification(){
|
||||
notification.InvokeSafe(notification.FinishCurrentTweet);
|
||||
}
|
||||
|
||||
public void TryPasteImage(){
|
||||
form.InvokeSafe(() => {
|
||||
if (Clipboard.ContainsImage()){
|
||||
Image img = Clipboard.GetImage();
|
||||
if (img == null)return;
|
||||
|
||||
try{
|
||||
Directory.CreateDirectory(Program.TemporaryPath);
|
||||
|
||||
ClipboardImagePath = Path.Combine(Program.TemporaryPath, "TD-Img-"+DateTime.Now.Ticks+".png");
|
||||
img.Save(ClipboardImagePath, ImageFormat.Png);
|
||||
|
||||
form.OnImagePasted();
|
||||
}catch(Exception e){
|
||||
Program.Reporter.HandleException("Clipboard Image Error", "Could not paste image from clipboard.", true, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ClickUploadImage(int offsetX, int offsetY){
|
||||
form.InvokeSafe(() => {
|
||||
Point prevPos = Cursor.Position;
|
||||
|
||||
Cursor.Position = form.PointToScreen(new Point(offsetX, offsetY));
|
||||
NativeMethods.SimulateMouseClick(NativeMethods.MouseButton.Left);
|
||||
Cursor.Position = prevPos;
|
||||
|
||||
form.OnImagePastedFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public void OpenBrowser(string url){
|
||||
BrowserUtils.OpenExternalBrowser(url);
|
||||
}
|
||||
|
||||
public void Alert(string type, string contents){
|
||||
MessageBoxIcon icon;
|
||||
|
||||
switch(type){
|
||||
case "error": icon = MessageBoxIcon.Error; break;
|
||||
case "warning": icon = MessageBoxIcon.Warning; break;
|
||||
case "info": icon = MessageBoxIcon.Information; break;
|
||||
default: icon = MessageBoxIcon.None; break;
|
||||
}
|
||||
|
||||
MessageBox.Show(contents, Program.BrandName+" Browser Message", MessageBoxButtons.OK, icon);
|
||||
}
|
||||
|
||||
public void Log(string data){
|
||||
System.Diagnostics.Debug.WriteLine(data);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace TweetDck.Core.Handling{
|
||||
sealed class TweetNotification{
|
||||
private static string FontSizeClass { get; set; }
|
||||
private static string HeadTag { get; set; }
|
||||
|
||||
private static string DefaultFontSizeClass{
|
||||
get{
|
||||
return "medium";
|
||||
}
|
||||
}
|
||||
|
||||
private static string DefaultHeadTag{
|
||||
get{
|
||||
return @"<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'>";
|
||||
}
|
||||
}
|
||||
|
||||
private static string CustomCSS{
|
||||
get{
|
||||
return @".scroll-styled-v::-webkit-scrollbar{width:8px}.scroll-styled-v::-webkit-scrollbar-thumb{border-radius:0}a[data-full-url]{word-break:break-all}#td-skip{opacity:0;cursor:pointer;transition:opacity 0.15s ease}.td-hover #td-skip{opacity:0.75}#td-skip:hover{opacity:1}";
|
||||
}
|
||||
}
|
||||
|
||||
public static int FontSizeLevel{
|
||||
get{
|
||||
switch(FontSizeClass){
|
||||
case "largest": return 4;
|
||||
case "large": return 3;
|
||||
case "medium": return 2;
|
||||
case "small": return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static TweetNotification ExampleTweet{
|
||||
get{
|
||||
StringBuilder build = new StringBuilder();
|
||||
build.Append(@"<article><div class='js-stream-item-content item-box js-show-detail'><div class='js-tweet tweet'>");
|
||||
build.Append(@"<header class='tweet-header'>");
|
||||
build.Append(@"<time class='tweet-timestamp js-timestamp pull-right txt-mute'><a target='_blank' rel='url' href='https://twitter.com/chylexmc' class='txt-small'>0s</a></time>");
|
||||
build.Append(@"<a target='_blank' rel='user' href='https://twitter.com/chylexmc' class='account-link link-complex block'>");
|
||||
build.Append(@"<div class='obj-left item-img tweet-img'><img width='48' height='48' alt='chylexmc's avatar' src='https://pbs.twimg.com/profile_images/765161905312980992/AhDP9iY-_normal.jpg' class='tweet-avatar avatar pull-right'></div>");
|
||||
build.Append(@"<div class='nbfc'><span class='account-inline txt-ellipsis'><b class='fullname link-complex-target'>chylex</b> <span class='username txt-mute'>@chylexmc</span></span></div>");
|
||||
build.Append(@"</a>");
|
||||
build.Append(@"</header>");
|
||||
build.Append(@"<div class='tweet-body'><p class='js-tweet-text tweet-text with-linebreaks'>This is an example tweet, which lets you test the location and duration of popup notifications.</p></div>");
|
||||
|
||||
#if DEBUG
|
||||
build.Append(@"<div style='margin-top:64px'>Scrollbar test padding...</div>");
|
||||
#endif
|
||||
|
||||
build.Append(@"</div></div></article>");
|
||||
|
||||
return new TweetNotification(build.ToString(), "", 95, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetFontSizeClass(string newFSClass){
|
||||
FontSizeClass = newFSClass;
|
||||
}
|
||||
|
||||
public static void SetHeadTag(string headContents){
|
||||
HeadTag = headContents;
|
||||
}
|
||||
|
||||
public enum Position{
|
||||
TopLeft, TopRight, BottomLeft, BottomRight, Custom
|
||||
}
|
||||
|
||||
public enum Duration{
|
||||
Short, Medium, Long, VeryLong
|
||||
}
|
||||
|
||||
public string Url{
|
||||
get{
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly string html;
|
||||
private readonly string url;
|
||||
private readonly int characters;
|
||||
private readonly bool isExample;
|
||||
|
||||
public TweetNotification(string html, string url, int characters) : this(html, url, characters, false){}
|
||||
|
||||
private TweetNotification(string html, string url, int characters, bool isExample){
|
||||
this.html = html;
|
||||
this.url = url;
|
||||
this.characters = characters;
|
||||
this.isExample = isExample;
|
||||
}
|
||||
|
||||
public int GetDisplayDuration(int value){
|
||||
return 2000+Math.Max(1000, value*characters);
|
||||
}
|
||||
|
||||
public string GenerateHtml(){
|
||||
StringBuilder build = new StringBuilder();
|
||||
build.Append("<!DOCTYPE html>");
|
||||
build.Append("<html class='os-windows txt-base-").Append(FontSizeClass ?? DefaultFontSizeClass).Append("'>");
|
||||
build.Append("<head>").Append(HeadTag ?? DefaultHeadTag).Append("<style type='text/css'>").Append(CustomCSS).Append("</style>");
|
||||
|
||||
if (!string.IsNullOrEmpty(Program.UserConfig.CustomNotificationCSS)){
|
||||
build.Append("<style type='text/css'>").Append(Program.UserConfig.CustomNotificationCSS).Append("</style>");
|
||||
}
|
||||
|
||||
build.Append("</head>");
|
||||
build.Append("<body class='hearty'").Append(isExample ? " td-example-notification" : "").Append("><div class='app-columns-container'><div class='column scroll-styled-v' style='width:100%;overflow-y:auto'>");
|
||||
build.Append(html);
|
||||
build.Append("</div></div></body>");
|
||||
build.Append("</html>");
|
||||
return build.ToString();
|
||||
}
|
||||
}
|
||||
}
|
52
Core/Notification/FormNotificationBase.Designer.cs
generated
Normal file
52
Core/Notification/FormNotificationBase.Designer.cs
generated
Normal file
@@ -0,0 +1,52 @@
|
||||
namespace TweetDuck.Core.Notification {
|
||||
partial class FormNotificationBase {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// FormNotification
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.ClientSize = new System.Drawing.Size(284, 122);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Location = TweetDuck.Core.Controls.ControlExtensions.InvisibleLocation;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormNotification";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
}
|
||||
}
|
211
Core/Notification/FormNotificationBase.cs
Normal file
211
Core/Notification/FormNotificationBase.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using CefSharp;
|
||||
using CefSharp.WinForms;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
partial class FormNotificationBase : Form{
|
||||
protected Point PrimaryLocation{
|
||||
get{
|
||||
UserConfig config = Program.UserConfig;
|
||||
Screen screen;
|
||||
|
||||
if (config.NotificationDisplay > 0 && config.NotificationDisplay <= Screen.AllScreens.Length){
|
||||
screen = Screen.AllScreens[config.NotificationDisplay-1];
|
||||
}
|
||||
else{
|
||||
screen = Screen.FromControl(owner);
|
||||
}
|
||||
|
||||
int edgeDist = config.NotificationEdgeDistance;
|
||||
|
||||
switch(config.NotificationPosition){
|
||||
case TweetNotification.Position.TopLeft:
|
||||
return new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+edgeDist);
|
||||
|
||||
case TweetNotification.Position.TopRight:
|
||||
return new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
|
||||
|
||||
case TweetNotification.Position.BottomLeft:
|
||||
return new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
|
||||
|
||||
case TweetNotification.Position.BottomRight:
|
||||
return new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
|
||||
|
||||
case TweetNotification.Position.Custom:
|
||||
if (!config.IsCustomNotificationPositionSet){
|
||||
config.CustomNotificationPosition = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
|
||||
config.Save();
|
||||
}
|
||||
|
||||
return config.CustomNotificationPosition;
|
||||
}
|
||||
|
||||
return Location;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNotificationVisible => Location != ControlExtensions.InvisibleLocation;
|
||||
|
||||
public new Point Location{
|
||||
get => base.Location;
|
||||
|
||||
set{
|
||||
Visible = (base.Location = value) != ControlExtensions.InvisibleLocation;
|
||||
|
||||
if (WindowsUtils.ShouldAvoidToolWindow){
|
||||
FormBorderStyle = Visible ? FormBorderStyle.FixedSingle : FormBorderStyle.FixedToolWindow; // workaround for alt+tab
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Func<bool> CanMoveWindow = () => true;
|
||||
protected override bool ShowWithoutActivation => true;
|
||||
|
||||
protected readonly Form owner;
|
||||
protected readonly ChromiumWebBrowser browser;
|
||||
|
||||
private readonly ResourceHandlerNotification resourceHandler = new ResourceHandlerNotification();
|
||||
|
||||
private string currentColumn;
|
||||
private int pauseCounter;
|
||||
|
||||
public bool IsPaused => pauseCounter > 0;
|
||||
|
||||
public bool FreezeTimer { get; set; }
|
||||
public bool ContextMenuOpen { get; set; }
|
||||
public string CurrentTweetUrl { get; private set; }
|
||||
public string CurrentQuoteUrl { get; private set; }
|
||||
|
||||
public event EventHandler Initialized;
|
||||
|
||||
public FormNotificationBase(Form owner, bool enableContextMenu){
|
||||
InitializeComponent();
|
||||
|
||||
this.owner = owner;
|
||||
this.owner.FormClosed += owner_FormClosed;
|
||||
|
||||
this.browser = new ChromiumWebBrowser("about:blank"){
|
||||
MenuHandler = new ContextMenuNotification(this, enableContextMenu),
|
||||
LifeSpanHandler = new LifeSpanHandler()
|
||||
};
|
||||
|
||||
this.browser.Dock = DockStyle.None;
|
||||
this.browser.ClientSize = ClientSize;
|
||||
this.browser.IsBrowserInitializedChanged += Browser_IsBrowserInitializedChanged;
|
||||
|
||||
#if DEBUG
|
||||
this.browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
||||
#endif
|
||||
|
||||
DefaultResourceHandlerFactory handlerFactory = (DefaultResourceHandlerFactory)browser.ResourceHandlerFactory;
|
||||
handlerFactory.RegisterHandler("https://tweetdeck.twitter.com", this.resourceHandler);
|
||||
|
||||
Controls.Add(browser);
|
||||
|
||||
Disposed += (sender, args) => {
|
||||
this.browser.Dispose();
|
||||
this.owner.FormClosed -= owner_FormClosed;
|
||||
};
|
||||
|
||||
// ReSharper disable once VirtualMemberCallInContructor
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m){
|
||||
if (m.Msg == 0x0112 && (m.WParam.ToInt32() & 0xFFF0) == 0xF010 && !CanMoveWindow()){ // WM_SYSCOMMAND, SC_MOVE
|
||||
return;
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void owner_FormClosed(object sender, FormClosedEventArgs e){
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Browser_IsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs e){
|
||||
if (e.IsBrowserInitialized){
|
||||
Initialized?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
// notification methods
|
||||
|
||||
public virtual void HideNotification(bool loadBlank){
|
||||
if (loadBlank){
|
||||
browser.Load("about:blank");
|
||||
}
|
||||
|
||||
Location = ControlExtensions.InvisibleLocation;
|
||||
currentColumn = null;
|
||||
}
|
||||
|
||||
public virtual void FinishCurrentNotification(){}
|
||||
|
||||
public virtual void PauseNotification(){
|
||||
if (pauseCounter++ == 0 && IsNotificationVisible){
|
||||
Location = ControlExtensions.InvisibleLocation;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ResumeNotification(){
|
||||
if (pauseCounter > 0){
|
||||
--pauseCounter;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual string GetTweetHTML(TweetNotification tweet){
|
||||
string bodyClasses = browser.Bounds.Contains(PointToClient(Cursor.Position)) ? "td-hover" : string.Empty;
|
||||
return tweet.GenerateHtml(bodyClasses);
|
||||
}
|
||||
|
||||
protected virtual void LoadTweet(TweetNotification tweet){
|
||||
CurrentTweetUrl = tweet.TweetUrl;
|
||||
CurrentQuoteUrl = tweet.QuoteUrl;
|
||||
currentColumn = tweet.Column;
|
||||
|
||||
resourceHandler.SetHTML(GetTweetHTML(tweet));
|
||||
browser.Load("https://tweetdeck.twitter.com");
|
||||
}
|
||||
|
||||
protected virtual void SetNotificationSize(int width, int height){
|
||||
browser.ClientSize = ClientSize = new Size((int)Math.Round(width*Program.UserConfig.ZoomMultiplier), (int)Math.Round(height*Program.UserConfig.ZoomMultiplier));
|
||||
}
|
||||
|
||||
protected virtual void OnNotificationReady(){
|
||||
MoveToVisibleLocation();
|
||||
}
|
||||
|
||||
protected virtual void UpdateTitle(){
|
||||
Text = string.IsNullOrEmpty(currentColumn) || !Program.UserConfig.DisplayNotificationColumn ? Program.BrandName : Program.BrandName+" - "+currentColumn;
|
||||
}
|
||||
|
||||
public void MoveToVisibleLocation(){
|
||||
bool needsReactivating = Location == ControlExtensions.InvisibleLocation;
|
||||
Location = PrimaryLocation;
|
||||
|
||||
if (needsReactivating){
|
||||
NativeMethods.SetFormPos(this, NativeMethods.HWND_TOPMOST, NativeMethods.SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisplayTooltip(string text){
|
||||
if (string.IsNullOrEmpty(text)){
|
||||
toolTip.Hide(this);
|
||||
}
|
||||
else{
|
||||
Point position = PointToClient(Cursor.Position);
|
||||
position.Offset(20, 5);
|
||||
toolTip.Show(text, this, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,5 @@
|
||||
using TweetDck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Core {
|
||||
sealed partial class FormNotification {
|
||||
namespace TweetDuck.Core.Notification {
|
||||
partial class FormNotificationMain {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
@@ -26,22 +24,15 @@ namespace TweetDck.Core {
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.panelBrowser = new System.Windows.Forms.Panel();
|
||||
this.timerDisplayDelay = new System.Windows.Forms.Timer(this.components);
|
||||
this.timerProgress = new System.Windows.Forms.Timer(this.components);
|
||||
this.progressBarTimer = new TweetDck.Core.Controls.FlatProgressBar();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.progressBarTimer = new TweetDuck.Core.Controls.FlatProgressBar();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panelBrowser
|
||||
// timerDisplayDelay
|
||||
//
|
||||
this.panelBrowser.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelBrowser.BackColor = System.Drawing.Color.White;
|
||||
this.panelBrowser.Location = new System.Drawing.Point(0, 0);
|
||||
this.panelBrowser.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelBrowser.Name = "panelBrowser";
|
||||
this.panelBrowser.Size = new System.Drawing.Size(284, 118);
|
||||
this.panelBrowser.TabIndex = 0;
|
||||
this.timerDisplayDelay.Interval = 17;
|
||||
this.timerDisplayDelay.Tick += new System.EventHandler(this.timerDisplayDelay_Tick);
|
||||
//
|
||||
// timerProgress
|
||||
//
|
||||
@@ -68,15 +59,6 @@ namespace TweetDck.Core {
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.ClientSize = new System.Drawing.Size(284, 122);
|
||||
this.Controls.Add(this.progressBarTimer);
|
||||
this.Controls.Add(this.panelBrowser);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormNotification";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormNotification_FormClosing);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
@@ -84,9 +66,8 @@ namespace TweetDck.Core {
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panelBrowser;
|
||||
private System.Windows.Forms.Timer timerDisplayDelay;
|
||||
protected System.Windows.Forms.Timer timerProgress;
|
||||
private Controls.FlatProgressBar progressBarTimer;
|
||||
private System.Windows.Forms.Timer timerProgress;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
}
|
||||
}
|
284
Core/Notification/FormNotificationMain.cs
Normal file
284
Core/Notification/FormNotificationMain.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
partial class FormNotificationMain : FormNotificationBase{
|
||||
private const string NotificationScriptFile = "notification.js";
|
||||
|
||||
private static readonly string NotificationScriptIdentifier = ScriptLoader.GetRootIdentifier(NotificationScriptFile);
|
||||
private static readonly string PluginScriptIdentifier = ScriptLoader.GetRootIdentifier(PluginManager.PluginNotificationScriptFile);
|
||||
|
||||
private static readonly string NotificationJS, PluginJS;
|
||||
|
||||
static FormNotificationMain(){
|
||||
NotificationJS = ScriptLoader.LoadResource(NotificationScriptFile);
|
||||
PluginJS = ScriptLoader.LoadResource(PluginManager.PluginNotificationScriptFile);
|
||||
}
|
||||
|
||||
private static int BaseClientWidth{
|
||||
get{
|
||||
int level = TweetNotification.FontSizeLevel;
|
||||
int width = level == 0 ? 284 : (int)Math.Round(284.0*(1.0+0.05*level));
|
||||
return (int)Math.Round(width*Program.UserConfig.ZoomMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
private static int BaseClientHeight{
|
||||
get{
|
||||
int level = TweetNotification.FontSizeLevel;
|
||||
int height = level == 0 ? 118 : (int)Math.Round(118.0*(1.0+0.075*level));
|
||||
return (int)Math.Round(height*Program.UserConfig.ZoomMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly PluginManager plugins;
|
||||
|
||||
protected int timeLeft, totalTime;
|
||||
protected bool pausedDuringNotification;
|
||||
|
||||
private readonly NativeMethods.HookProc mouseHookDelegate;
|
||||
private IntPtr mouseHook;
|
||||
private bool blockXButtonUp;
|
||||
|
||||
private bool? prevDisplayTimer;
|
||||
private int? prevFontSize;
|
||||
|
||||
private bool RequiresResize{
|
||||
get{
|
||||
return !prevDisplayTimer.HasValue || !prevFontSize.HasValue || prevDisplayTimer != Program.UserConfig.DisplayNotificationTimer || prevFontSize != TweetNotification.FontSizeLevel;
|
||||
}
|
||||
|
||||
set{
|
||||
if (value){
|
||||
prevDisplayTimer = null;
|
||||
prevFontSize = null;
|
||||
}
|
||||
else{
|
||||
prevDisplayTimer = Program.UserConfig.DisplayNotificationTimer;
|
||||
prevFontSize = TweetNotification.FontSizeLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FormNotificationMain(FormBrowser owner, PluginManager pluginManager, bool enableContextMenu) : base(owner, enableContextMenu){
|
||||
InitializeComponent();
|
||||
|
||||
this.plugins = pluginManager;
|
||||
|
||||
browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge(owner, this));
|
||||
browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
||||
|
||||
browser.LoadingStateChanged += Browser_LoadingStateChanged;
|
||||
browser.FrameLoadEnd += Browser_FrameLoadEnd;
|
||||
|
||||
mouseHookDelegate = MouseHookProc;
|
||||
Disposed += (sender, args) => StopMouseHook(true);
|
||||
}
|
||||
|
||||
// mouse wheel hook
|
||||
|
||||
private void StartMouseHook(){
|
||||
if (mouseHook == IntPtr.Zero){
|
||||
mouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.WM_MOUSE_LL, mouseHookDelegate, IntPtr.Zero, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void StopMouseHook(bool force){
|
||||
if (mouseHook != IntPtr.Zero && (force || !blockXButtonUp)){
|
||||
NativeMethods.UnhookWindowsHookEx(mouseHook);
|
||||
mouseHook = IntPtr.Zero;
|
||||
blockXButtonUp = false;
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam){
|
||||
if (nCode == 0){
|
||||
int eventType = wParam.ToInt32();
|
||||
|
||||
if (eventType == NativeMethods.WM_MOUSEWHEEL && browser.Bounds.Contains(PointToClient(Cursor.Position))){
|
||||
int distance = (int)Math.Round(NativeMethods.GetMouseHookData(lParam)*(Program.UserConfig.NotificationScrollSpeed/100.0));
|
||||
|
||||
browser.SendMouseWheelEvent(0, 0, 0, distance, CefEventFlags.None);
|
||||
return NativeMethods.HOOK_HANDLED;
|
||||
}
|
||||
else if (eventType == NativeMethods.WM_XBUTTONDOWN && DesktopBounds.Contains(Cursor.Position)){
|
||||
int extraButton = NativeMethods.GetMouseHookData(lParam);
|
||||
|
||||
if (extraButton == 2){ // forward button
|
||||
this.InvokeAsyncSafe(FinishCurrentNotification);
|
||||
}
|
||||
else if (extraButton == 1){ // back button
|
||||
this.InvokeAsyncSafe(Close);
|
||||
}
|
||||
|
||||
blockXButtonUp = true;
|
||||
return NativeMethods.HOOK_HANDLED;
|
||||
}
|
||||
else if (eventType == NativeMethods.WM_XBUTTONUP && blockXButtonUp){
|
||||
blockXButtonUp = false;
|
||||
|
||||
if (!Visible){
|
||||
StopMouseHook(false);
|
||||
}
|
||||
|
||||
return NativeMethods.HOOK_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
return NativeMethods.CallNextHookEx(mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void FormNotification_FormClosing(object sender, FormClosingEventArgs e){
|
||||
if (e.CloseReason == CloseReason.UserClosing){
|
||||
HideNotification(true);
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
||||
if (!e.IsLoading && browser.Address != "about:blank"){
|
||||
this.InvokeSafe(() => {
|
||||
Visible = true; // ensures repaint before moving the window to a visible location
|
||||
timerDisplayDelay.Start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||
if (e.Frame.IsMain && NotificationJS != null && browser.Address != "about:blank"){
|
||||
e.Frame.ExecuteJavaScriptAsync(PropertyBridge.GenerateScript(PropertyBridge.Properties.AllNotification));
|
||||
ScriptLoader.ExecuteScript(e.Frame, NotificationJS, NotificationScriptIdentifier);
|
||||
|
||||
if (plugins.HasAnyPlugin(PluginEnvironment.Notification)){
|
||||
ScriptLoader.ExecuteScript(e.Frame, PluginJS, PluginScriptIdentifier);
|
||||
ScriptLoader.ExecuteFile(e.Frame, PluginManager.PluginGlobalScriptFile);
|
||||
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Notification, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void timerDisplayDelay_Tick(object sender, EventArgs e){
|
||||
OnNotificationReady();
|
||||
timerDisplayDelay.Stop();
|
||||
}
|
||||
|
||||
private void timerHideProgress_Tick(object sender, EventArgs e){
|
||||
if (Bounds.Contains(Cursor.Position) || FreezeTimer || ContextMenuOpen)return;
|
||||
|
||||
timeLeft -= timerProgress.Interval;
|
||||
|
||||
int value = (int)Math.Round(1025.0*(totalTime-timeLeft)/totalTime);
|
||||
progressBarTimer.SetValueInstant(Math.Min(1000, Math.Max(0, Program.UserConfig.NotificationTimerCountDown ? 1000-value : value)));
|
||||
|
||||
if (timeLeft <= 0){
|
||||
FinishCurrentNotification();
|
||||
}
|
||||
}
|
||||
|
||||
// notification methods
|
||||
|
||||
public virtual void ShowNotification(TweetNotification notification){
|
||||
LoadTweet(notification);
|
||||
}
|
||||
|
||||
public void ShowNotificationForSettings(bool reset){
|
||||
if (reset){
|
||||
LoadTweet(TweetNotification.ExampleTweet);
|
||||
}
|
||||
else{
|
||||
PrepareAndDisplayWindow();
|
||||
}
|
||||
|
||||
UpdateTitle();
|
||||
}
|
||||
|
||||
public override void HideNotification(bool loadBlank){
|
||||
base.HideNotification(loadBlank);
|
||||
|
||||
progressBarTimer.Value = Program.UserConfig.NotificationTimerCountDown ? 1000 : 0;
|
||||
timerProgress.Stop();
|
||||
totalTime = 0;
|
||||
|
||||
StopMouseHook(false);
|
||||
}
|
||||
|
||||
public override void FinishCurrentNotification(){
|
||||
timerProgress.Stop();
|
||||
}
|
||||
|
||||
public override void PauseNotification(){
|
||||
if (!IsPaused){
|
||||
pausedDuringNotification = IsNotificationVisible;
|
||||
timerProgress.Stop();
|
||||
StopMouseHook(true);
|
||||
}
|
||||
|
||||
base.PauseNotification();
|
||||
}
|
||||
|
||||
public override void ResumeNotification(){
|
||||
bool wasPaused = IsPaused;
|
||||
base.ResumeNotification();
|
||||
|
||||
if (wasPaused && !IsPaused && pausedDuringNotification){
|
||||
OnNotificationReady();
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetTweetHTML(TweetNotification tweet){
|
||||
string html = base.GetTweetHTML(tweet);
|
||||
|
||||
foreach(InjectedHTML injection in plugins.Bridge.NotificationInjections){
|
||||
html = injection.Inject(html);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
protected override void LoadTweet(TweetNotification tweet){
|
||||
timerProgress.Stop();
|
||||
totalTime = timeLeft = tweet.GetDisplayDuration(Program.UserConfig.NotificationDurationValue);
|
||||
progressBarTimer.Value = Program.UserConfig.NotificationTimerCountDown ? 1000 : 0;
|
||||
|
||||
base.LoadTweet(tweet);
|
||||
}
|
||||
|
||||
protected override void SetNotificationSize(int width, int height){
|
||||
if (Program.UserConfig.DisplayNotificationTimer){
|
||||
ClientSize = new Size(width, height+4);
|
||||
progressBarTimer.Visible = true;
|
||||
}
|
||||
else{
|
||||
ClientSize = new Size(width, height);
|
||||
progressBarTimer.Visible = false;
|
||||
}
|
||||
|
||||
browser.ClientSize = new Size(width, height);
|
||||
}
|
||||
|
||||
private void PrepareAndDisplayWindow(){
|
||||
if (RequiresResize){
|
||||
RequiresResize = false;
|
||||
SetNotificationSize(BaseClientWidth, BaseClientHeight);
|
||||
}
|
||||
|
||||
MoveToVisibleLocation();
|
||||
StartMouseHook();
|
||||
}
|
||||
|
||||
protected override void OnNotificationReady(){
|
||||
PrepareAndDisplayWindow();
|
||||
timerProgress.Start();
|
||||
}
|
||||
}
|
||||
}
|
53
Core/Notification/FormNotificationTweet.Designer.cs
generated
Normal file
53
Core/Notification/FormNotificationTweet.Designer.cs
generated
Normal file
@@ -0,0 +1,53 @@
|
||||
namespace TweetDuck.Core.Notification {
|
||||
partial class FormNotificationTweet {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.timerCursorCheck = new System.Windows.Forms.Timer(this.components);
|
||||
this.timerIdlePauseCheck = new System.Windows.Forms.Timer(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// timerCursorCheck
|
||||
//
|
||||
this.timerCursorCheck.Interval = 200;
|
||||
this.timerCursorCheck.Tick += new System.EventHandler(this.timerCursorCheck_Tick);
|
||||
//
|
||||
// timerIdlePauseCheck
|
||||
//
|
||||
this.timerIdlePauseCheck.Interval = 750;
|
||||
this.timerIdlePauseCheck.Tick += new System.EventHandler(this.timerIdlePauseCheck_Tick);
|
||||
//
|
||||
// FormNotificationTweet
|
||||
//
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormNotificationTweet_FormClosing);
|
||||
this.ResumeLayout(true);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Timer timerCursorCheck;
|
||||
private System.Windows.Forms.Timer timerIdlePauseCheck;
|
||||
}
|
||||
}
|
141
Core/Notification/FormNotificationTweet.cs
Normal file
141
Core/Notification/FormNotificationTweet.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using TweetDuck.Plugins;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
sealed partial class FormNotificationTweet : FormNotificationMain{
|
||||
private const int NonIntrusiveIdleLimit = 30;
|
||||
private const int TrimMinimum = 32;
|
||||
|
||||
private bool IsCursorOverNotificationArea => new Rectangle(PrimaryLocation, Size).Contains(Cursor.Position);
|
||||
|
||||
private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4);
|
||||
private bool needsTrim;
|
||||
|
||||
public FormNotificationTweet(FormBrowser owner, PluginManager pluginManager) : base(owner, pluginManager, true){
|
||||
InitializeComponent();
|
||||
|
||||
Program.UserConfig.MuteToggled += Config_MuteToggled;
|
||||
Disposed += (sender, args) => Program.UserConfig.MuteToggled -= Config_MuteToggled;
|
||||
|
||||
if (Program.UserConfig.MuteNotifications){
|
||||
PauseNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private void FormNotificationTweet_FormClosing(object sender, FormClosingEventArgs e){
|
||||
if (e.CloseReason == CloseReason.UserClosing){
|
||||
tweetQueue.Clear(); // already canceled
|
||||
TrimQueue();
|
||||
}
|
||||
}
|
||||
|
||||
private void TrimQueue(){
|
||||
if (needsTrim){
|
||||
tweetQueue.TrimExcess();
|
||||
needsTrim = false;
|
||||
}
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void Config_MuteToggled(object sender, EventArgs e){
|
||||
if (Program.UserConfig.MuteNotifications){
|
||||
PauseNotification();
|
||||
}
|
||||
else{
|
||||
ResumeNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private void timerCursorCheck_Tick(object sender, EventArgs e){
|
||||
if (!IsCursorOverNotificationArea){
|
||||
ResumeNotification();
|
||||
timerCursorCheck.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void timerIdlePauseCheck_Tick(object sender, EventArgs e){
|
||||
if (NativeMethods.GetIdleSeconds() < Program.UserConfig.NotificationIdlePauseSeconds){
|
||||
ResumeNotification();
|
||||
timerIdlePauseCheck.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
// notification methods
|
||||
|
||||
public override void ShowNotification(TweetNotification notification){
|
||||
if (IsPaused){
|
||||
tweetQueue.Enqueue(notification);
|
||||
}
|
||||
else{
|
||||
tweetQueue.Enqueue(notification);
|
||||
UpdateTitle();
|
||||
|
||||
if (totalTime == 0){
|
||||
LoadNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
needsTrim |= tweetQueue.Count >= TrimMinimum;
|
||||
}
|
||||
|
||||
public override void FinishCurrentNotification(){
|
||||
if (tweetQueue.Count > 0){
|
||||
LoadNextNotification();
|
||||
}
|
||||
else{
|
||||
HideNotification(true);
|
||||
TrimQueue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ResumeNotification(){
|
||||
bool wasPaused = IsPaused;
|
||||
base.ResumeNotification();
|
||||
|
||||
if (wasPaused && !IsPaused && !pausedDuringNotification && tweetQueue.Count > 0){
|
||||
LoadNextNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadNextNotification(){
|
||||
if (!IsNotificationVisible){
|
||||
if (Program.UserConfig.NotificationNonIntrusiveMode && IsCursorOverNotificationArea && NativeMethods.GetIdleSeconds() < NonIntrusiveIdleLimit){
|
||||
if (!timerCursorCheck.Enabled){
|
||||
PauseNotification();
|
||||
timerCursorCheck.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (Program.UserConfig.NotificationIdlePauseSeconds > 0 && NativeMethods.GetIdleSeconds() >= Program.UserConfig.NotificationIdlePauseSeconds){
|
||||
if (!timerIdlePauseCheck.Enabled){
|
||||
PauseNotification();
|
||||
timerIdlePauseCheck.Start();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LoadTweet(tweetQueue.Dequeue());
|
||||
}
|
||||
|
||||
protected override void UpdateTitle(){
|
||||
base.UpdateTitle();
|
||||
|
||||
if (tweetQueue.Count > 0){
|
||||
Text = Text+" ("+tweetQueue.Count+" more left)";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNotificationReady(){
|
||||
UpdateTitle();
|
||||
base.OnNotificationReady();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Notification.Screenshot{
|
||||
sealed class FormNotificationScreenshotable : FormNotificationBase{
|
||||
public FormNotificationScreenshotable(Action callback, Form owner) : base(owner, false){
|
||||
browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new CallbackBridge(this, callback));
|
||||
|
||||
browser.FrameLoadEnd += (sender, args) => {
|
||||
if (args.Frame.IsMain && browser.Address != "about:blank"){
|
||||
ScriptLoader.ExecuteScript(args.Frame, "window.setTimeout($TD_NotificationScreenshot.trigger, 67)", "gen:screenshot");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override string GetTweetHTML(TweetNotification tweet){
|
||||
return tweet.GenerateHtml(enableCustomCSS: false);
|
||||
}
|
||||
|
||||
public void LoadNotificationForScreenshot(TweetNotification tweet, int width, int height){
|
||||
LoadTweet(tweet);
|
||||
SetNotificationSize(width, height);
|
||||
}
|
||||
|
||||
public void TakeScreenshot(){
|
||||
IntPtr context = NativeMethods.GetDC(this.Handle);
|
||||
|
||||
if (context == IntPtr.Zero){
|
||||
MessageBox.Show("Could not retrieve a graphics context handle for the notification window to take the screenshot.", "Screenshot Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
else{
|
||||
using(Bitmap bmp = new Bitmap(ClientSize.Width, ClientSize.Height, PixelFormat.Format32bppRgb)){
|
||||
try{
|
||||
NativeMethods.RenderSourceIntoBitmap(context, bmp);
|
||||
}finally{
|
||||
NativeMethods.ReleaseDC(this.Handle, context);
|
||||
}
|
||||
|
||||
Clipboard.SetImage(bmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
75
Core/Notification/Screenshot/TweetScreenshotManager.cs
Normal file
75
Core/Notification/Screenshot/TweetScreenshotManager.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
// Uncomment to keep screenshot windows visible for debugging
|
||||
// #define NO_HIDE_SCREENSHOTS
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
|
||||
namespace TweetDuck.Core.Notification.Screenshot{
|
||||
sealed class TweetScreenshotManager : IDisposable{
|
||||
private readonly Form owner;
|
||||
private readonly Timer timeout;
|
||||
private readonly Timer disposer;
|
||||
|
||||
private FormNotificationScreenshotable screenshot;
|
||||
|
||||
public TweetScreenshotManager(Form owner){
|
||||
this.owner = owner;
|
||||
|
||||
this.timeout = new Timer{ Interval = 8000 };
|
||||
this.timeout.Tick += timeout_Tick;
|
||||
|
||||
this.disposer = new Timer{ Interval = 1 };
|
||||
this.disposer.Tick += disposer_Tick;
|
||||
}
|
||||
|
||||
private void timeout_Tick(object sender, EventArgs e){
|
||||
timeout.Stop();
|
||||
screenshot.Location = ControlExtensions.InvisibleLocation;
|
||||
disposer.Start();
|
||||
}
|
||||
|
||||
private void disposer_Tick(object sender, EventArgs e){
|
||||
disposer.Stop();
|
||||
screenshot.Dispose();
|
||||
screenshot = null;
|
||||
}
|
||||
|
||||
public void Trigger(string html, int width, int height){
|
||||
if (screenshot != null){
|
||||
return;
|
||||
}
|
||||
|
||||
screenshot = new FormNotificationScreenshotable(Callback, owner){
|
||||
CanMoveWindow = () => false
|
||||
};
|
||||
|
||||
screenshot.LoadNotificationForScreenshot(new TweetNotification(string.Empty, html, 0, string.Empty, string.Empty), width, height);
|
||||
screenshot.Show();
|
||||
timeout.Start();
|
||||
}
|
||||
|
||||
private void Callback(){
|
||||
if (!timeout.Enabled){
|
||||
return;
|
||||
}
|
||||
|
||||
timeout.Stop();
|
||||
screenshot.TakeScreenshot();
|
||||
|
||||
#if !(DEBUG && NO_HIDE_SCREENSHOTS)
|
||||
screenshot.Location = ControlExtensions.InvisibleLocation;
|
||||
disposer.Start();
|
||||
#else
|
||||
screenshot.MoveToVisibleLocation();
|
||||
screenshot.FormClosed += (sender, args) => disposer.Start();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
timeout.Dispose();
|
||||
disposer.Dispose();
|
||||
screenshot?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
29
Core/Notification/SoundNotification.cs
Normal file
29
Core/Notification/SoundNotification.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using TweetLib.Audio;
|
||||
using TweetLib.Audio.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
sealed class SoundNotification : IDisposable{
|
||||
public string SupportedFormats => player.SupportedFormats;
|
||||
public event EventHandler<PlaybackErrorEventArgs> PlaybackError;
|
||||
|
||||
private readonly AudioPlayer player;
|
||||
|
||||
public SoundNotification(){
|
||||
this.player = AudioPlayer.New();
|
||||
this.player.PlaybackError += Player_PlaybackError;
|
||||
}
|
||||
|
||||
public void Play(string file){
|
||||
player.Play(file);
|
||||
}
|
||||
|
||||
private void Player_PlaybackError(object sender, PlaybackErrorEventArgs e){
|
||||
PlaybackError?.Invoke(this, e);
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
player.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
106
Core/Notification/TweetNotification.cs
Normal file
106
Core/Notification/TweetNotification.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using TweetDuck.Resources;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
sealed class TweetNotification{
|
||||
private static string FontSizeClass { get; set; }
|
||||
private static string HeadTag { get; set; }
|
||||
|
||||
private const string DefaultFontSizeClass = "medium";
|
||||
private const string DefaultHeadTag = @"<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 const string CustomCSS = @"body:before{content:none}body{overflow-y:auto}.scroll-styled-v::-webkit-scrollbar{width:7px}.scroll-styled-v::-webkit-scrollbar-thumb{border-radius:0}.scroll-styled-v::-webkit-scrollbar-track{border-left:0}#td-skip{opacity:0;cursor:pointer;transition:opacity 0.15s ease}.td-hover #td-skip{opacity:0.75}#td-skip:hover{opacity:1}";
|
||||
|
||||
public static int FontSizeLevel{
|
||||
get{
|
||||
switch(FontSizeClass){
|
||||
case "largest": return 4;
|
||||
case "large": return 3;
|
||||
case "medium": return 2;
|
||||
case "small": return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string ExampleTweetHTML;
|
||||
|
||||
public static TweetNotification ExampleTweet{
|
||||
get{
|
||||
if (ExampleTweetHTML == null){
|
||||
ExampleTweetHTML = ScriptLoader.LoadResource("pages/example.html", true);
|
||||
|
||||
#if DEBUG
|
||||
ExampleTweetHTML = ExampleTweetHTML.Replace("</p>", @"</p><div style='margin-top:256px'>Scrollbar test padding...</div>");
|
||||
#endif
|
||||
}
|
||||
|
||||
return new TweetNotification("Home", ExampleTweetHTML, 95, string.Empty, string.Empty, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetFontSizeClass(string newFSClass){
|
||||
FontSizeClass = newFSClass;
|
||||
}
|
||||
|
||||
public static void SetHeadTag(string headContents){
|
||||
HeadTag = headContents;
|
||||
}
|
||||
|
||||
public enum Position{
|
||||
TopLeft, TopRight, BottomLeft, BottomRight, Custom
|
||||
}
|
||||
|
||||
public string Column { get; }
|
||||
public string TweetUrl { get; }
|
||||
public string QuoteUrl { get; }
|
||||
|
||||
private readonly string html;
|
||||
private readonly int characters;
|
||||
private readonly bool isExample;
|
||||
|
||||
public TweetNotification(string column, string html, int characters, string tweetUrl, string quoteUrl) : this(column, html, characters, tweetUrl, quoteUrl, false){}
|
||||
|
||||
private TweetNotification(string column, string html, int characters, string tweetUrl, string quoteUrl, bool isExample){
|
||||
this.Column = column;
|
||||
this.TweetUrl = tweetUrl;
|
||||
this.QuoteUrl = quoteUrl;
|
||||
|
||||
this.html = html;
|
||||
this.characters = characters;
|
||||
this.isExample = isExample;
|
||||
}
|
||||
|
||||
public int GetDisplayDuration(int value){
|
||||
return 2000+Math.Max(1000, value*characters);
|
||||
}
|
||||
|
||||
public string GenerateHtml(string bodyClasses = null, bool enableCustomCSS = true){
|
||||
StringBuilder build = new StringBuilder();
|
||||
build.Append("<!DOCTYPE html>");
|
||||
build.Append("<html class='os-windows txt-base-").Append(FontSizeClass ?? DefaultFontSizeClass).Append("'>");
|
||||
build.Append("<head>").Append(HeadTag ?? DefaultHeadTag);
|
||||
|
||||
if (enableCustomCSS){
|
||||
build.Append("<style type='text/css'>").Append(CustomCSS).Append("</style>");
|
||||
|
||||
if (!string.IsNullOrEmpty(Program.UserConfig.CustomNotificationCSS)){
|
||||
build.Append("<style type='text/css'>").Append(Program.UserConfig.CustomNotificationCSS).Append("</style>");
|
||||
}
|
||||
}
|
||||
|
||||
build.Append("</head>");
|
||||
build.Append("<body class='scroll-styled-v");
|
||||
|
||||
if (!string.IsNullOrEmpty(bodyClasses)){
|
||||
build.Append(' ').Append(bodyClasses);
|
||||
}
|
||||
|
||||
build.Append('\'').Append(isExample ? " td-example-notification" : "").Append("><div class='column' style='width:100%;height:auto;overflow:initial;'>");
|
||||
build.Append(html);
|
||||
build.Append("</div></body>");
|
||||
build.Append("</html>");
|
||||
return build.ToString();
|
||||
}
|
||||
}
|
||||
}
|
17
Core/Other/FormAbout.Designer.cs
generated
17
Core/Other/FormAbout.Designer.cs
generated
@@ -1,6 +1,4 @@
|
||||
using TweetDck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Core.Other {
|
||||
namespace TweetDuck.Core.Other {
|
||||
sealed partial class FormAbout {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -57,7 +55,7 @@ namespace TweetDck.Core.Other {
|
||||
this.labelDescription.Location = new System.Drawing.Point(114, 12);
|
||||
this.labelDescription.Name = "labelDescription";
|
||||
this.labelDescription.Size = new System.Drawing.Size(232, 109);
|
||||
this.labelDescription.TabIndex = 1;
|
||||
this.labelDescription.TabIndex = 0;
|
||||
//
|
||||
// labelTips
|
||||
//
|
||||
@@ -68,7 +66,8 @@ namespace TweetDck.Core.Other {
|
||||
this.labelTips.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelTips.Name = "labelTips";
|
||||
this.labelTips.Size = new System.Drawing.Size(99, 16);
|
||||
this.labelTips.TabIndex = 3;
|
||||
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);
|
||||
@@ -83,7 +82,8 @@ namespace TweetDck.Core.Other {
|
||||
this.labelWebsite.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelWebsite.Name = "labelWebsite";
|
||||
this.labelWebsite.Size = new System.Drawing.Size(117, 16);
|
||||
this.labelWebsite.TabIndex = 2;
|
||||
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);
|
||||
@@ -104,7 +104,7 @@ namespace TweetDck.Core.Other {
|
||||
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.TabIndex = 4;
|
||||
this.tablePanelLinks.TabIndex = 1;
|
||||
//
|
||||
// labelIssues
|
||||
//
|
||||
@@ -115,7 +115,8 @@ namespace TweetDck.Core.Other {
|
||||
this.labelIssues.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelIssues.Name = "labelIssues";
|
||||
this.labelIssues.Size = new System.Drawing.Size(118, 16);
|
||||
this.labelIssues.TabIndex = 4;
|
||||
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);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Other{
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormAbout : Form{
|
||||
private const string TipsLink = "https://github.com/chylex/TweetDuck/wiki";
|
||||
private const string IssuesLink = "https://github.com/chylex/TweetDuck/issues";
|
||||
@@ -19,7 +19,7 @@ namespace TweetDck.Core.Other{
|
||||
}
|
||||
|
||||
private void OnLinkClicked(object sender, LinkLabelLinkClickedEventArgs e){
|
||||
BrowserUtils.OpenExternalBrowser(e.Link.LinkData as string);
|
||||
BrowserUtils.OpenExternalBrowserUnsafe(e.Link.LinkData as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
Core/Other/FormMessage.Designer.cs
generated
9
Core/Other/FormMessage.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other {
|
||||
namespace TweetDuck.Core.Other {
|
||||
partial class FormMessage {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -33,7 +33,7 @@
|
||||
this.panelActions.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.panelActions.Location = new System.Drawing.Point(0, 84);
|
||||
this.panelActions.Name = "panelActions";
|
||||
this.panelActions.Size = new System.Drawing.Size(233, 49);
|
||||
this.panelActions.Size = new System.Drawing.Size(98, 49);
|
||||
this.panelActions.TabIndex = 0;
|
||||
//
|
||||
// labelMessage
|
||||
@@ -42,8 +42,8 @@
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelMessage.AutoSize = true;
|
||||
this.labelMessage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelMessage.Location = new System.Drawing.Point(62, 33);
|
||||
this.labelMessage.Font = System.Drawing.SystemFonts.MessageBoxFont;
|
||||
this.labelMessage.Location = new System.Drawing.Point(62, 34);
|
||||
this.labelMessage.Margin = new System.Windows.Forms.Padding(53, 24, 27, 24);
|
||||
this.labelMessage.MaximumSize = new System.Drawing.Size(600, 0);
|
||||
this.labelMessage.MinimumSize = new System.Drawing.Size(0, 24);
|
||||
@@ -66,6 +66,7 @@
|
||||
this.Name = "FormMessage";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.SizeChanged += new System.EventHandler(this.FormMessage_SizeChanged);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@@ -2,10 +2,17 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Other{
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormMessage : Form{
|
||||
public Button ClickedButton { get; private set; }
|
||||
|
||||
public int ActionPanelY => panelActions.Location.Y;
|
||||
|
||||
private int ClientWidth{
|
||||
get => ClientSize.Width;
|
||||
set => ClientSize = new Size(value, ClientSize.Height);
|
||||
}
|
||||
|
||||
private readonly Icon icon;
|
||||
private readonly bool isReady;
|
||||
|
||||
@@ -19,7 +26,7 @@ namespace TweetDck.Core.Other{
|
||||
|
||||
this.prevLabelWidth = labelMessage.Width;
|
||||
this.prevLabelHeight = labelMessage.Height;
|
||||
this.minFormWidth = 18;
|
||||
this.minFormWidth = 40;
|
||||
|
||||
switch(messageIcon){
|
||||
case MessageBoxIcon.Information:
|
||||
@@ -40,7 +47,7 @@ namespace TweetDck.Core.Other{
|
||||
|
||||
default:
|
||||
icon = null;
|
||||
labelMessage.Location = new Point(labelMessage.Location.X-32, labelMessage.Location.Y);
|
||||
labelMessage.Location = new Point(labelMessage.Location.X-38, labelMessage.Location.Y);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -50,10 +57,15 @@ namespace TweetDck.Core.Other{
|
||||
this.labelMessage.Text = text;
|
||||
}
|
||||
|
||||
public Button AddButton(string title){
|
||||
private void FormMessage_SizeChanged(object sender, EventArgs e){
|
||||
RecalculateButtonLocation();
|
||||
}
|
||||
|
||||
public Button AddButton(string title, DialogResult result = DialogResult.OK){
|
||||
Button button = new Button{
|
||||
Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
|
||||
Location = new Point(Width-112-buttonCount*96, 12),
|
||||
Anchor = AnchorStyles.Bottom,
|
||||
Font = SystemFonts.MessageBoxFont,
|
||||
Location = new Point(0, 12),
|
||||
Size = new Size(88, 26),
|
||||
TabIndex = buttonCount,
|
||||
Text = title,
|
||||
@@ -62,16 +74,17 @@ namespace TweetDck.Core.Other{
|
||||
|
||||
button.Click += (sender, args) => {
|
||||
ClickedButton = (Button)sender;
|
||||
DialogResult = DialogResult.OK;
|
||||
DialogResult = result;
|
||||
Close();
|
||||
};
|
||||
|
||||
panelActions.Controls.Add(button);
|
||||
++buttonCount;
|
||||
|
||||
minFormWidth += 96;
|
||||
Width = Math.Max(realFormWidth, minFormWidth);
|
||||
ClientWidth = Math.Max(realFormWidth, minFormWidth);
|
||||
RecalculateButtonLocation();
|
||||
|
||||
++buttonCount;
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -79,7 +92,14 @@ namespace TweetDck.Core.Other{
|
||||
panelActions.Controls.Add(control);
|
||||
|
||||
minFormWidth += control.Width+control.Margin.Horizontal;
|
||||
Width = Math.Max(realFormWidth, minFormWidth);
|
||||
ClientWidth = Math.Max(realFormWidth, minFormWidth);
|
||||
}
|
||||
|
||||
private void RecalculateButtonLocation(){
|
||||
for(int index = 0; index < buttonCount; index++){
|
||||
Control control = panelActions.Controls[index];
|
||||
control.Location = new Point(ClientWidth-97-index*96, control.Location.Y);
|
||||
}
|
||||
}
|
||||
|
||||
private void labelMessage_SizeChanged(object sender, EventArgs e){
|
||||
@@ -98,8 +118,8 @@ namespace TweetDck.Core.Other{
|
||||
prevLabelHeight -= 8;
|
||||
}
|
||||
|
||||
realFormWidth = Width-(icon == null ? 32+35+(labelMessage.Margin.Left-labelMessage.Margin.Right) : 0)+labelMessage.Margin.Right+labelMessage.Width-prevLabelWidth;
|
||||
Width = Math.Max(realFormWidth, minFormWidth);
|
||||
realFormWidth = ClientWidth-(icon == null ? 50 : 0)+labelMessage.Width-prevLabelWidth;
|
||||
ClientWidth = Math.Max(realFormWidth, minFormWidth);
|
||||
Height += labelMessage.Height-prevLabelHeight;
|
||||
|
||||
prevLabelWidth = labelMessage.Width;
|
||||
|
26
Core/Other/FormPlugins.Designer.cs
generated
26
Core/Other/FormPlugins.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other {
|
||||
namespace TweetDuck.Core.Other {
|
||||
partial class FormPlugins {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -26,7 +26,7 @@
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.btnReload = new System.Windows.Forms.Button();
|
||||
this.btnOpenFolder = new System.Windows.Forms.Button();
|
||||
this.tabPanelPlugins = new TweetDck.Core.Controls.TabPanel();
|
||||
this.flowLayoutPlugins = new TweetDuck.Plugins.Controls.PluginListFlowLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnClose
|
||||
@@ -68,26 +68,30 @@
|
||||
this.btnOpenFolder.UseVisualStyleBackColor = true;
|
||||
this.btnOpenFolder.Click += new System.EventHandler(this.btnOpenFolder_Click);
|
||||
//
|
||||
// tabPanelPlugins
|
||||
// flowLayoutPlugins
|
||||
//
|
||||
this.tabPanelPlugins.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
this.flowLayoutPlugins.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.tabPanelPlugins.Location = new System.Drawing.Point(12, 12);
|
||||
this.tabPanelPlugins.Name = "tabPanelPlugins";
|
||||
this.tabPanelPlugins.Size = new System.Drawing.Size(680, 421);
|
||||
this.tabPanelPlugins.TabIndex = 4;
|
||||
this.flowLayoutPlugins.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
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.TabIndex = 0;
|
||||
this.flowLayoutPlugins.WrapContents = false;
|
||||
this.flowLayoutPlugins.Resize += new System.EventHandler(this.flowLayoutPlugins_Resize);
|
||||
//
|
||||
// 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.Controls.Add(this.tabPanelPlugins);
|
||||
this.Controls.Add(this.flowLayoutPlugins);
|
||||
this.Controls.Add(this.btnOpenFolder);
|
||||
this.Controls.Add(this.btnReload);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Icon = global::TweetDck.Properties.Resources.icon;
|
||||
this.Icon = global::TweetDuck.Properties.Resources.icon;
|
||||
this.MinimumSize = new System.Drawing.Size(480, 320);
|
||||
this.Name = "FormPlugins";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
@@ -101,6 +105,6 @@
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.Button btnReload;
|
||||
private System.Windows.Forms.Button btnOpenFolder;
|
||||
private TweetDck.Core.Controls.TabPanel tabPanelPlugins;
|
||||
private Plugins.Controls.PluginListFlowLayout flowLayoutPlugins;
|
||||
}
|
||||
}
|
@@ -3,20 +3,13 @@ using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDck.Plugins.Controls;
|
||||
using TweetDck.Plugins.Enums;
|
||||
using TweetDck.Plugins.Events;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Controls;
|
||||
|
||||
namespace TweetDck.Core.Other{
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormPlugins : Form{
|
||||
private readonly PluginManager pluginManager;
|
||||
private readonly TabButton tabBtnOfficial, tabBtnCustom;
|
||||
private readonly PluginListFlowLayout flowLayoutPlugins;
|
||||
|
||||
private PluginGroup? selectedGroup;
|
||||
|
||||
|
||||
public FormPlugins(){
|
||||
InitializeComponent();
|
||||
|
||||
@@ -25,22 +18,10 @@ namespace TweetDck.Core.Other{
|
||||
|
||||
public FormPlugins(PluginManager pluginManager) : this(){
|
||||
this.pluginManager = pluginManager;
|
||||
this.pluginManager.Reloaded += pluginManager_Reloaded;
|
||||
|
||||
this.flowLayoutPlugins = new PluginListFlowLayout();
|
||||
this.flowLayoutPlugins.Resize += flowLayoutPlugins_Resize;
|
||||
|
||||
this.tabPanelPlugins.SetupTabPanel(90);
|
||||
this.tabPanelPlugins.ReplaceContent(flowLayoutPlugins);
|
||||
|
||||
this.tabBtnOfficial = tabPanelPlugins.AddButton("", () => SelectGroup(PluginGroup.Official));
|
||||
this.tabBtnCustom = tabPanelPlugins.AddButton("", () => SelectGroup(PluginGroup.Custom));
|
||||
|
||||
this.tabPanelPlugins.SelectTab(tabBtnOfficial);
|
||||
this.pluginManager_Reloaded(pluginManager, null);
|
||||
|
||||
Shown += (sender, args) => {
|
||||
Program.UserConfig.PluginsWindow.Restore(this, false);
|
||||
ReloadPluginList();
|
||||
};
|
||||
|
||||
FormClosed += (sender, args) => {
|
||||
@@ -49,40 +30,29 @@ namespace TweetDck.Core.Other{
|
||||
};
|
||||
}
|
||||
|
||||
private void SelectGroup(PluginGroup group){
|
||||
if (selectedGroup.HasValue && selectedGroup == group)return;
|
||||
|
||||
selectedGroup = group;
|
||||
|
||||
ReloadPluginTab();
|
||||
private int GetPluginOrderIndex(Plugin plugin){
|
||||
return !plugin.CanRun ? 0 : pluginManager.Config.IsEnabled(plugin) ? 1 : 2;
|
||||
}
|
||||
|
||||
public void ReloadPluginTab(){
|
||||
if (!selectedGroup.HasValue)return;
|
||||
|
||||
private void ReloadPluginList(){
|
||||
flowLayoutPlugins.SuspendLayout();
|
||||
flowLayoutPlugins.Controls.Clear();
|
||||
|
||||
Plugin[] plugins = pluginManager.GetPluginsByGroup(selectedGroup.Value).OrderBy(plugin => !plugin.CanRun ? 0 : pluginManager.Config.IsEnabled(plugin) ? 1 : 2).ThenBy(plugin => plugin.Name).ToArray();
|
||||
foreach(Plugin plugin in pluginManager.Plugins.OrderBy(GetPluginOrderIndex).ThenBy(plugin => plugin.Name)){
|
||||
flowLayoutPlugins.Controls.Add(new PluginControl(pluginManager, plugin));
|
||||
|
||||
for(int index = 0; index < plugins.Length; index++){
|
||||
flowLayoutPlugins.Controls.Add(new PluginControl(pluginManager, plugins[index]));
|
||||
|
||||
if (index < plugins.Length-1){
|
||||
flowLayoutPlugins.Controls.Add(new Panel{
|
||||
BackColor = Color.DimGray,
|
||||
Size = new Size(1, 1)
|
||||
});
|
||||
}
|
||||
flowLayoutPlugins.Controls.Add(new Panel{
|
||||
BackColor = Color.DimGray,
|
||||
Margin = new Padding(0),
|
||||
Size = new Size(1, 1)
|
||||
});
|
||||
}
|
||||
|
||||
flowLayoutPlugins_Resize(flowLayoutPlugins, new EventArgs());
|
||||
flowLayoutPlugins.ResumeLayout(true);
|
||||
}
|
||||
|
||||
private void pluginManager_Reloaded(object sender, PluginLoadEventArgs e){
|
||||
tabBtnOfficial.Text = "Official: "+pluginManager.CountPluginByGroup(PluginGroup.Official);
|
||||
tabBtnCustom.Text = "Custom: "+pluginManager.CountPluginByGroup(PluginGroup.Custom);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
private void flowLayoutPlugins_Resize(object sender, EventArgs e){
|
||||
@@ -100,7 +70,8 @@ namespace TweetDck.Core.Other{
|
||||
foreach(Control control in flowLayoutPlugins.Controls){
|
||||
control.Width = flowLayoutPlugins.Width-control.Margin.Horizontal-horizontalOffset;
|
||||
}
|
||||
|
||||
|
||||
lastControl.Visible = !showScrollBar;
|
||||
flowLayoutPlugins.Focus();
|
||||
}
|
||||
|
||||
@@ -111,7 +82,7 @@ namespace TweetDck.Core.Other{
|
||||
private void btnReload_Click(object sender, EventArgs e){
|
||||
if (MessageBox.Show("This will also reload the browser window. Do you want to proceed?", "Reloading Plugins", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
pluginManager.Reload();
|
||||
ReloadPluginTab();
|
||||
ReloadPluginList();
|
||||
}
|
||||
}
|
||||
|
||||
|
74
Core/Other/FormSettings.Designer.cs
generated
74
Core/Other/FormSettings.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other {
|
||||
namespace TweetDuck.Core.Other {
|
||||
sealed partial class FormSettings {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -24,52 +24,72 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.btnClose = new System.Windows.Forms.Button();
|
||||
this.labelTip = new System.Windows.Forms.Label();
|
||||
this.tabPanel = new TweetDck.Core.Controls.TabPanel();
|
||||
this.panelContents = new System.Windows.Forms.Panel();
|
||||
this.panelButtons = new System.Windows.Forms.Panel();
|
||||
this.btnManageOptions = new System.Windows.Forms.Button();
|
||||
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(443, 331);
|
||||
this.btnClose.Location = new System.Drawing.Point(449, 447);
|
||||
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.TabIndex = 4;
|
||||
this.btnClose.TabIndex = 3;
|
||||
this.btnClose.Text = "Close";
|
||||
this.btnClose.UseVisualStyleBackColor = true;
|
||||
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||
//
|
||||
// labelTip
|
||||
// panelContents
|
||||
//
|
||||
this.labelTip.AutoSize = true;
|
||||
this.labelTip.Location = new System.Drawing.Point(12, 333);
|
||||
this.labelTip.Name = "labelTip";
|
||||
this.labelTip.Size = new System.Drawing.Size(310, 13);
|
||||
this.labelTip.TabIndex = 5;
|
||||
this.labelTip.Text = "Tip: Move your cursor over an option to see detailed explanation";
|
||||
//
|
||||
// tabPanel
|
||||
//
|
||||
this.tabPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
this.panelContents.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.Location = new System.Drawing.Point(12, 12);
|
||||
this.tabPanel.Name = "tabPanel";
|
||||
this.tabPanel.Size = new System.Drawing.Size(480, 313);
|
||||
this.tabPanel.TabIndex = 3;
|
||||
this.panelContents.AutoScroll = true;
|
||||
this.panelContents.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
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, 429);
|
||||
this.panelContents.TabIndex = 1;
|
||||
//
|
||||
// panelButtons
|
||||
//
|
||||
this.panelButtons.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.panelButtons.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
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, 429);
|
||||
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, 447);
|
||||
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.TabIndex = 4;
|
||||
this.btnManageOptions.Text = "Manage Options";
|
||||
this.btnManageOptions.UseVisualStyleBackColor = true;
|
||||
this.btnManageOptions.Click += new System.EventHandler(this.btnManageOptions_Click);
|
||||
//
|
||||
// FormSettings
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(504, 366);
|
||||
this.Controls.Add(this.labelTip);
|
||||
this.ClientSize = new System.Drawing.Size(510, 482);
|
||||
this.Controls.Add(this.btnManageOptions);
|
||||
this.Controls.Add(this.panelContents);
|
||||
this.Controls.Add(this.panelButtons);
|
||||
this.Controls.Add(this.btnClose);
|
||||
this.Controls.Add(this.tabPanel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Icon = Properties.Resources.icon;
|
||||
this.Icon = global::TweetDuck.Properties.Resources.icon;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormSettings";
|
||||
@@ -81,9 +101,9 @@
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Controls.TabPanel tabPanel;
|
||||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.Label labelTip;
|
||||
private System.Windows.Forms.Panel panelContents;
|
||||
private System.Windows.Forms.Panel panelButtons;
|
||||
private System.Windows.Forms.Button btnManageOptions;
|
||||
}
|
||||
}
|
@@ -1,50 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Other.Settings;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDck.Updates;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other.Settings;
|
||||
using TweetDuck.Core.Other.Settings.Dialogs;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Updates;
|
||||
|
||||
namespace TweetDck.Core.Other{
|
||||
namespace TweetDuck.Core.Other{
|
||||
sealed partial class FormSettings : Form{
|
||||
private readonly Dictionary<Type, BaseTabSettings> tabs = new Dictionary<Type, BaseTabSettings>(4);
|
||||
private readonly FormBrowser browser;
|
||||
private readonly PluginManager plugins;
|
||||
|
||||
public FormSettings(FormBrowser browserForm, PluginManager plugins, UpdateHandler updates){
|
||||
private readonly Dictionary<Type, SettingsTab> tabs = new Dictionary<Type, SettingsTab>(4);
|
||||
private SettingsTab currentTab;
|
||||
|
||||
public FormSettings(FormBrowser browser, PluginManager plugins, UpdateHandler updates, Type startTab){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Settings";
|
||||
Text = Program.BrandName+" Options";
|
||||
|
||||
this.tabPanel.SetupTabPanel(100);
|
||||
this.tabPanel.AddButton("General", SelectTab<TabSettingsGeneral>);
|
||||
this.tabPanel.AddButton("Notifications", () => SelectTab(() => new TabSettingsNotifications(browserForm.CreateNotificationForm(false))));
|
||||
this.tabPanel.AddButton("Updates", () => SelectTab(() => new TabSettingsUpdates(updates)));
|
||||
this.tabPanel.AddButton("Advanced", () => SelectTab(() => new TabSettingsAdvanced(browserForm.ReloadBrowser, plugins)));
|
||||
this.tabPanel.SelectTab(tabPanel.Buttons.First());
|
||||
}
|
||||
this.browser = browser;
|
||||
this.browser.PauseNotification();
|
||||
|
||||
private void SelectTab<T>() where T : BaseTabSettings, new(){
|
||||
SelectTab(() => new T());
|
||||
}
|
||||
this.plugins = plugins;
|
||||
|
||||
private void SelectTab<T>(Func<T> constructor) where T : BaseTabSettings{
|
||||
BaseTabSettings control;
|
||||
AddButton("General", () => new TabSettingsGeneral(updates));
|
||||
AddButton("Notifications", () => new TabSettingsNotifications(browser.CreateNotificationForm(false)));
|
||||
AddButton("Sounds", () => new TabSettingsSounds());
|
||||
AddButton("Advanced", () => new TabSettingsAdvanced(browser.ReinjectCustomCSS));
|
||||
|
||||
if (tabs.TryGetValue(typeof(T), out control)){
|
||||
tabPanel.ReplaceContent(control);
|
||||
}
|
||||
else{
|
||||
control = tabs[typeof(T)] = constructor();
|
||||
control.Ready = true;
|
||||
tabPanel.ReplaceContent(control);
|
||||
}
|
||||
SelectTab(tabs[startTab ?? typeof(TabSettingsGeneral)]);
|
||||
}
|
||||
|
||||
private void FormSettings_FormClosing(object sender, FormClosingEventArgs e){
|
||||
foreach(SettingsTab tab in tabs.Values){
|
||||
if (tab.IsInitialized){
|
||||
tab.Control.OnClosing();
|
||||
tab.Control.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Program.UserConfig.Save();
|
||||
browser.ResumeNotification();
|
||||
}
|
||||
|
||||
foreach(BaseTabSettings control in tabs.Values){
|
||||
control.Dispose();
|
||||
private void btnManageOptions_Click(object sender, EventArgs e){
|
||||
using(DialogSettingsManage dialog = new DialogSettingsManage(plugins)){
|
||||
if (dialog.ShowDialog() == DialogResult.OK && dialog.ShouldReloadUI){
|
||||
foreach(SettingsTab tab in tabs.Values){
|
||||
tab.Control = null;
|
||||
}
|
||||
|
||||
SelectTab(currentTab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,10 +62,87 @@ namespace TweetDck.Core.Other{
|
||||
Close();
|
||||
}
|
||||
|
||||
public void ReloadUI(){
|
||||
tabs.Clear();
|
||||
tabPanel.Content.Controls.Clear();
|
||||
tabPanel.ActiveButton.Callback();
|
||||
private void AddButton<T>(string title, Func<T> constructor) where T : BaseTabSettings{
|
||||
const int btnHeight = 39;
|
||||
|
||||
FlatButton btn = new FlatButton{
|
||||
BackColor = SystemColors.Control,
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
Location = new Point(0, (btnHeight+1)*(panelButtons.Controls.Count/2)),
|
||||
Margin = new Padding(0),
|
||||
Size = new Size(panelButtons.Width, btnHeight),
|
||||
Text = title,
|
||||
UseVisualStyleBackColor = true
|
||||
};
|
||||
|
||||
btn.FlatAppearance.BorderSize = 0;
|
||||
btn.FlatAppearance.MouseDownBackColor = Color.FromArgb(179, 213, 232);
|
||||
btn.FlatAppearance.MouseOverBackColor = Color.FromArgb(216, 230, 237);
|
||||
|
||||
panelButtons.Controls.Add(btn);
|
||||
|
||||
panelButtons.Controls.Add(new Panel{
|
||||
BackColor = Color.DimGray,
|
||||
Location = new Point(0, panelButtons.Controls[panelButtons.Controls.Count-1].Location.Y+btnHeight),
|
||||
Margin = new Padding(0),
|
||||
Size = new Size(panelButtons.Width, 1)
|
||||
});
|
||||
|
||||
tabs.Add(typeof(T), new SettingsTab(btn, constructor));
|
||||
|
||||
btn.Click += (sender, args) => SelectTab<T>();
|
||||
}
|
||||
|
||||
private void SelectTab<T>() where T : BaseTabSettings{
|
||||
SelectTab(tabs[typeof(T)]);
|
||||
}
|
||||
|
||||
private void SelectTab(SettingsTab tab){
|
||||
if (currentTab != null){
|
||||
currentTab.Button.BackColor = SystemColors.Control;
|
||||
}
|
||||
|
||||
tab.Button.BackColor = tab.Button.FlatAppearance.MouseDownBackColor;
|
||||
|
||||
if (!tab.IsInitialized){
|
||||
foreach(Control control in tab.Control.InteractiveControls){
|
||||
control.MouseLeave += control_MouseLeave;
|
||||
}
|
||||
|
||||
tab.Control.OnReady();
|
||||
}
|
||||
|
||||
panelContents.SuspendLayout();
|
||||
panelContents.VerticalScroll.Value = 0; // https://gfycat.com/GrotesqueTastyAstarte
|
||||
panelContents.Controls.Clear();
|
||||
panelContents.Controls.Add(tab.Control);
|
||||
panelContents.ResumeLayout(true);
|
||||
panelContents.Focus();
|
||||
|
||||
currentTab = tab;
|
||||
}
|
||||
|
||||
private void control_MouseLeave(object sender, EventArgs e){
|
||||
panelContents.Focus();
|
||||
}
|
||||
|
||||
private class SettingsTab{
|
||||
public Button Button { get; }
|
||||
|
||||
public BaseTabSettings Control{
|
||||
get => control ?? (control = constructor());
|
||||
set => control = value;
|
||||
}
|
||||
|
||||
public bool IsInitialized => control != null;
|
||||
|
||||
private readonly Func<BaseTabSettings> constructor;
|
||||
private BaseTabSettings control;
|
||||
|
||||
public SettingsTab(Button button, Func<BaseTabSettings> constructor){
|
||||
this.Button = button;
|
||||
this.constructor = constructor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
Core/Other/Settings/BaseTabSettings.Designer.cs
generated
3
Core/Other/Settings/BaseTabSettings.Designer.cs
generated
@@ -1,3 +0,0 @@
|
||||
namespace TweetDck.Core.Other.Settings{
|
||||
partial class BaseTabSettings{}
|
||||
}
|
@@ -1,22 +1,31 @@
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings{
|
||||
partial class BaseTabSettings : UserControl{
|
||||
protected static UserConfig Config{
|
||||
namespace TweetDuck.Core.Other.Settings{
|
||||
class BaseTabSettings : UserControl{
|
||||
protected static UserConfig Config => Program.UserConfig;
|
||||
|
||||
public IEnumerable<Control> InteractiveControls{
|
||||
get{
|
||||
return Program.UserConfig;
|
||||
foreach(Panel panel in Controls.OfType<Panel>()){
|
||||
foreach(Control control in panel.Controls){
|
||||
yield return control;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Ready { get; set; }
|
||||
|
||||
public BaseTabSettings(){
|
||||
Padding = new Padding(6);
|
||||
}
|
||||
|
||||
public virtual void OnReady(){}
|
||||
public virtual void OnClosing(){}
|
||||
|
||||
protected static void PromptRestart(){
|
||||
if (MessageBox.Show("The application must restart for the setting to take place. Do you want to restart now?", Program.BrandName+" Settings", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes){
|
||||
if (MessageBox.Show("The application must restart for the option to take place. Do you want to restart now?", Program.BrandName+" Options", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes){
|
||||
Program.Restart();
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other.Settings.Dialogs {
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs {
|
||||
partial class DialogSettingsCSS {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -23,6 +23,7 @@
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.textBoxBrowserCSS = new System.Windows.Forms.TextBox();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.btnApply = new System.Windows.Forms.Button();
|
||||
@@ -31,6 +32,8 @@
|
||||
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.timerTestBrowser = new System.Windows.Forms.Timer(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
@@ -49,8 +52,9 @@
|
||||
this.textBoxBrowserCSS.Name = "textBoxBrowserCSS";
|
||||
this.textBoxBrowserCSS.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.textBoxBrowserCSS.Size = new System.Drawing.Size(373, 253);
|
||||
this.textBoxBrowserCSS.TabIndex = 0;
|
||||
this.textBoxBrowserCSS.TabIndex = 1;
|
||||
this.textBoxBrowserCSS.WordWrap = false;
|
||||
this.textBoxBrowserCSS.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBoxBrowserCSS_KeyUp);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
@@ -59,7 +63,7 @@
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.TabIndex = 1;
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
@@ -71,7 +75,7 @@
|
||||
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.TabIndex = 2;
|
||||
this.btnApply.TabIndex = 1;
|
||||
this.btnApply.Text = "Apply";
|
||||
this.btnApply.UseVisualStyleBackColor = true;
|
||||
this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
|
||||
@@ -98,7 +102,7 @@
|
||||
this.splitContainer.Size = new System.Drawing.Size(760, 269);
|
||||
this.splitContainer.SplitterDistance = 373;
|
||||
this.splitContainer.SplitterWidth = 5;
|
||||
this.splitContainer.TabIndex = 5;
|
||||
this.splitContainer.TabIndex = 0;
|
||||
//
|
||||
// labelBrowser
|
||||
//
|
||||
@@ -107,7 +111,7 @@
|
||||
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 = 1;
|
||||
this.labelBrowser.TabIndex = 0;
|
||||
this.labelBrowser.Text = "Browser";
|
||||
//
|
||||
// labelNotification
|
||||
@@ -117,7 +121,7 @@
|
||||
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 = 2;
|
||||
this.labelNotification.TabIndex = 0;
|
||||
this.labelNotification.Text = "Notification";
|
||||
//
|
||||
// textBoxNotificationCSS
|
||||
@@ -131,7 +135,7 @@
|
||||
this.textBoxNotificationCSS.Multiline = true;
|
||||
this.textBoxNotificationCSS.Name = "textBoxNotificationCSS";
|
||||
this.textBoxNotificationCSS.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.textBoxNotificationCSS.Size = new System.Drawing.Size(378, 253);
|
||||
this.textBoxNotificationCSS.Size = new System.Drawing.Size(372, 253);
|
||||
this.textBoxNotificationCSS.TabIndex = 1;
|
||||
this.textBoxNotificationCSS.WordWrap = false;
|
||||
//
|
||||
@@ -139,22 +143,41 @@
|
||||
//
|
||||
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(9, 292);
|
||||
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 = 6;
|
||||
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.AutoSize = true;
|
||||
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);
|
||||
//
|
||||
// timerTestBrowser
|
||||
//
|
||||
this.timerTestBrowser.Interval = 500;
|
||||
this.timerTestBrowser.Tick += new System.EventHandler(this.timerTestBrowser_Tick);
|
||||
//
|
||||
// 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.Controls.Add(this.btnApply);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.MinimumSize = new System.Drawing.Size(500, 160);
|
||||
this.MinimumSize = new System.Drawing.Size(600, 160);
|
||||
this.Name = "DialogSettingsCSS";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
@@ -179,5 +202,7 @@
|
||||
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.Timer timerTestBrowser;
|
||||
}
|
||||
}
|
@@ -1,25 +1,21 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings.Dialogs{
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
sealed partial class DialogSettingsCSS : Form{
|
||||
public string BrowserCSS{
|
||||
get{
|
||||
return textBoxBrowserCSS.Text;
|
||||
}
|
||||
}
|
||||
|
||||
public string NotificationCSS{
|
||||
get{
|
||||
return textBoxNotificationCSS.Text;
|
||||
}
|
||||
}
|
||||
public string BrowserCSS => textBoxBrowserCSS.Text;
|
||||
public string NotificationCSS => textBoxNotificationCSS.Text;
|
||||
|
||||
public DialogSettingsCSS(){
|
||||
private readonly Action<string> reinjectBrowserCSS;
|
||||
|
||||
public DialogSettingsCSS(Action<string> reinjectBrowserCSS){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Settings - CSS";
|
||||
Text = Program.BrandName+" Options - CSS";
|
||||
|
||||
this.reinjectBrowserCSS = reinjectBrowserCSS;
|
||||
|
||||
textBoxBrowserCSS.EnableMultilineShortcuts();
|
||||
textBoxBrowserCSS.Text = Program.UserConfig.CustomBrowserCSS ?? "";
|
||||
@@ -28,6 +24,20 @@ namespace TweetDck.Core.Other.Settings.Dialogs{
|
||||
textBoxNotificationCSS.Text = Program.UserConfig.CustomNotificationCSS ?? "";
|
||||
}
|
||||
|
||||
private void textBoxBrowserCSS_KeyUp(object sender, KeyEventArgs e){
|
||||
timerTestBrowser.Stop();
|
||||
timerTestBrowser.Start();
|
||||
}
|
||||
|
||||
private void timerTestBrowser_Tick(object sender, EventArgs e){
|
||||
reinjectBrowserCSS(textBoxBrowserCSS.Text);
|
||||
timerTestBrowser.Stop();
|
||||
}
|
||||
|
||||
private void btnOpenWiki_Click(object sender, EventArgs e){
|
||||
BrowserUtils.OpenExternalBrowserUnsafe("https://github.com/chylex/TweetDuck/wiki");
|
||||
}
|
||||
|
||||
private void btnApply_Click(object sender, EventArgs e){
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other.Settings.Dialogs {
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs {
|
||||
partial class DialogSettingsCefArgs {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -40,7 +40,7 @@
|
||||
this.textBoxArgs.Multiline = true;
|
||||
this.textBoxArgs.Name = "textBoxArgs";
|
||||
this.textBoxArgs.Size = new System.Drawing.Size(460, 193);
|
||||
this.textBoxArgs.TabIndex = 0;
|
||||
this.textBoxArgs.TabIndex = 1;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
@@ -49,7 +49,7 @@
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.TabIndex = 1;
|
||||
this.btnCancel.TabIndex = 3;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
@@ -74,7 +74,7 @@
|
||||
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.TabIndex = 3;
|
||||
this.btnHelp.TabIndex = 4;
|
||||
this.btnHelp.Text = "List of Chromium Args";
|
||||
this.btnHelp.UseVisualStyleBackColor = true;
|
||||
this.btnHelp.Click += new System.EventHandler(this.btnHelp_Click);
|
||||
@@ -86,7 +86,7 @@
|
||||
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.TabIndex = 4;
|
||||
this.labelWarning.TabIndex = 0;
|
||||
this.labelWarning.Text = "Warning: Some arguments may cause the program to stop working, edit at your own r" +
|
||||
"isk.";
|
||||
//
|
||||
|
@@ -1,20 +1,16 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings.Dialogs{
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
sealed partial class DialogSettingsCefArgs : Form{
|
||||
public string CefArgs{
|
||||
get{
|
||||
return textBoxArgs.Text;
|
||||
}
|
||||
}
|
||||
public string CefArgs => textBoxArgs.Text;
|
||||
|
||||
public DialogSettingsCefArgs(){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Settings - CEF Arguments";
|
||||
Text = Program.BrandName+" Options - CEF Arguments";
|
||||
|
||||
textBoxArgs.EnableMultilineShortcuts();
|
||||
textBoxArgs.Text = Program.UserConfig.CustomCefArgs ?? "";
|
||||
@@ -22,7 +18,7 @@ namespace TweetDck.Core.Other.Settings.Dialogs{
|
||||
}
|
||||
|
||||
private void btnHelp_Click(object sender, EventArgs e){
|
||||
BrowserUtils.OpenExternalBrowser("http://peter.sh/experiments/chromium-command-line-switches/");
|
||||
BrowserUtils.OpenExternalBrowserUnsafe("http://peter.sh/experiments/chromium-command-line-switches/");
|
||||
}
|
||||
|
||||
private void btnApply_Click(object sender, EventArgs e){
|
||||
@@ -35,7 +31,7 @@ namespace TweetDck.Core.Other.Settings.Dialogs{
|
||||
}
|
||||
|
||||
int count = CommandLineArgsParser.ReadCefArguments(CefArgs).Count;
|
||||
string prompt = count == 0 && !string.IsNullOrWhiteSpace(prevArgs) ? "All arguments will be removed from the settings. Continue?" : count+(count == 1 ? " argument" : " arguments")+" will be added to the settings. Continue?";
|
||||
string prompt = count == 0 && !string.IsNullOrWhiteSpace(prevArgs) ? "All current arguments will be removed. Continue?" : count+(count == 1 ? " argument was" : " arguments were")+" detected. Continue?";
|
||||
|
||||
if (MessageBox.Show(prompt, "Confirm CEF Arguments", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK){
|
||||
DialogResult = DialogResult.OK;
|
||||
|
203
Core/Other/Settings/Dialogs/DialogSettingsManage.Designer.cs
generated
Normal file
203
Core/Other/Settings/Dialogs/DialogSettingsManage.Designer.cs
generated
Normal file
@@ -0,0 +1,203 @@
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs {
|
||||
partial class DialogSettingsManage {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.btnContinue = new System.Windows.Forms.Button();
|
||||
this.cbConfig = new System.Windows.Forms.CheckBox();
|
||||
this.cbSession = new System.Windows.Forms.CheckBox();
|
||||
this.cbPluginData = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.panelExport = new System.Windows.Forms.Panel();
|
||||
this.panelDecision = new System.Windows.Forms.Panel();
|
||||
this.radioReset = new System.Windows.Forms.RadioButton();
|
||||
this.radioExport = new System.Windows.Forms.RadioButton();
|
||||
this.radioImport = new System.Windows.Forms.RadioButton();
|
||||
this.panelExport.SuspendLayout();
|
||||
this.panelDecision.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Location = new System.Drawing.Point(176, 97);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.TabIndex = 4;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// btnContinue
|
||||
//
|
||||
this.btnContinue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnContinue.AutoSize = true;
|
||||
this.btnContinue.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnContinue.Enabled = false;
|
||||
this.btnContinue.Location = new System.Drawing.Point(125, 97);
|
||||
this.btnContinue.Name = "btnContinue";
|
||||
this.btnContinue.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnContinue.Size = new System.Drawing.Size(45, 23);
|
||||
this.btnContinue.TabIndex = 3;
|
||||
this.btnContinue.Text = "Next";
|
||||
this.btnContinue.UseVisualStyleBackColor = true;
|
||||
this.btnContinue.Click += new System.EventHandler(this.btnContinue_Click);
|
||||
//
|
||||
// cbConfig
|
||||
//
|
||||
this.cbConfig.AutoSize = true;
|
||||
this.cbConfig.Location = new System.Drawing.Point(0, 3);
|
||||
this.cbConfig.Name = "cbConfig";
|
||||
this.cbConfig.Size = new System.Drawing.Size(104, 17);
|
||||
this.cbConfig.TabIndex = 0;
|
||||
this.cbConfig.Text = "Program Options";
|
||||
this.toolTip.SetToolTip(this.cbConfig, "Interface, notification, and update options.");
|
||||
this.cbConfig.UseVisualStyleBackColor = true;
|
||||
this.cbConfig.CheckedChanged += new System.EventHandler(this.cbConfig_CheckedChanged);
|
||||
//
|
||||
// cbSession
|
||||
//
|
||||
this.cbSession.AutoSize = true;
|
||||
this.cbSession.Location = new System.Drawing.Point(0, 27);
|
||||
this.cbSession.Name = "cbSession";
|
||||
this.cbSession.Size = new System.Drawing.Size(92, 17);
|
||||
this.cbSession.TabIndex = 1;
|
||||
this.cbSession.Text = "Login Session";
|
||||
this.toolTip.SetToolTip(this.cbSession, "A token that allows logging into the\r\ncurrent TweetDeck account.");
|
||||
this.cbSession.UseVisualStyleBackColor = true;
|
||||
this.cbSession.CheckedChanged += new System.EventHandler(this.cbSession_CheckedChanged);
|
||||
//
|
||||
// cbPluginData
|
||||
//
|
||||
this.cbPluginData.AutoSize = true;
|
||||
this.cbPluginData.Location = new System.Drawing.Point(0, 51);
|
||||
this.cbPluginData.Name = "cbPluginData";
|
||||
this.cbPluginData.Size = new System.Drawing.Size(81, 17);
|
||||
this.cbPluginData.TabIndex = 2;
|
||||
this.cbPluginData.Text = "Plugin Data";
|
||||
this.toolTip.SetToolTip(this.cbPluginData, "Data files generated by plugins.\r\nDoes not include the plugins themselves.");
|
||||
this.cbPluginData.UseVisualStyleBackColor = true;
|
||||
this.cbPluginData.CheckedChanged += new System.EventHandler(this.cbPluginData_CheckedChanged);
|
||||
//
|
||||
// panelExport
|
||||
//
|
||||
this.panelExport.Controls.Add(this.cbConfig);
|
||||
this.panelExport.Controls.Add(this.cbPluginData);
|
||||
this.panelExport.Controls.Add(this.cbSession);
|
||||
this.panelExport.Location = new System.Drawing.Point(12, 12);
|
||||
this.panelExport.Name = "panelExport";
|
||||
this.panelExport.Size = new System.Drawing.Size(220, 79);
|
||||
this.panelExport.TabIndex = 5;
|
||||
this.panelExport.Visible = false;
|
||||
//
|
||||
// panelDecision
|
||||
//
|
||||
this.panelDecision.Controls.Add(this.radioReset);
|
||||
this.panelDecision.Controls.Add(this.radioExport);
|
||||
this.panelDecision.Controls.Add(this.radioImport);
|
||||
this.panelDecision.Location = new System.Drawing.Point(12, 12);
|
||||
this.panelDecision.Name = "panelDecision";
|
||||
this.panelDecision.Size = new System.Drawing.Size(220, 79);
|
||||
this.panelDecision.TabIndex = 6;
|
||||
//
|
||||
// radioReset
|
||||
//
|
||||
this.radioReset.AutoSize = true;
|
||||
this.radioReset.Location = new System.Drawing.Point(3, 49);
|
||||
this.radioReset.Name = "radioReset";
|
||||
this.radioReset.Size = new System.Drawing.Size(104, 17);
|
||||
this.radioReset.TabIndex = 2;
|
||||
this.radioReset.TabStop = true;
|
||||
this.radioReset.Text = "Restore Defaults";
|
||||
this.radioReset.UseVisualStyleBackColor = true;
|
||||
this.radioReset.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// radioExport
|
||||
//
|
||||
this.radioExport.AutoSize = true;
|
||||
this.radioExport.Location = new System.Drawing.Point(3, 26);
|
||||
this.radioExport.Name = "radioExport";
|
||||
this.radioExport.Size = new System.Drawing.Size(87, 17);
|
||||
this.radioExport.TabIndex = 1;
|
||||
this.radioExport.TabStop = true;
|
||||
this.radioExport.Text = "Export Profile";
|
||||
this.radioExport.UseVisualStyleBackColor = true;
|
||||
this.radioExport.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// radioImport
|
||||
//
|
||||
this.radioImport.AutoSize = true;
|
||||
this.radioImport.Location = new System.Drawing.Point(3, 3);
|
||||
this.radioImport.Name = "radioImport";
|
||||
this.radioImport.Size = new System.Drawing.Size(86, 17);
|
||||
this.radioImport.TabIndex = 0;
|
||||
this.radioImport.TabStop = true;
|
||||
this.radioImport.Text = "Import Profile";
|
||||
this.radioImport.UseVisualStyleBackColor = true;
|
||||
this.radioImport.CheckedChanged += new System.EventHandler(this.radioDecision_CheckedChanged);
|
||||
//
|
||||
// DialogSettingsManage
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(244, 132);
|
||||
this.Controls.Add(this.panelDecision);
|
||||
this.Controls.Add(this.panelExport);
|
||||
this.Controls.Add(this.btnContinue);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(200, 170);
|
||||
this.Name = "DialogSettingsManage";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Manage Options";
|
||||
this.panelExport.ResumeLayout(false);
|
||||
this.panelExport.PerformLayout();
|
||||
this.panelDecision.ResumeLayout(false);
|
||||
this.panelDecision.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Button btnContinue;
|
||||
private System.Windows.Forms.CheckBox cbConfig;
|
||||
private System.Windows.Forms.CheckBox cbSession;
|
||||
private System.Windows.Forms.CheckBox cbPluginData;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.Panel panelExport;
|
||||
private System.Windows.Forms.Panel panelDecision;
|
||||
private System.Windows.Forms.RadioButton radioReset;
|
||||
private System.Windows.Forms.RadioButton radioExport;
|
||||
private System.Windows.Forms.RadioButton radioImport;
|
||||
}
|
||||
}
|
170
Core/Other/Settings/Dialogs/DialogSettingsManage.cs
Normal file
170
Core/Other/Settings/Dialogs/DialogSettingsManage.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Other.Settings.Export;
|
||||
using TweetDuck.Plugins;
|
||||
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
sealed partial class DialogSettingsManage : Form{
|
||||
private enum State{
|
||||
Deciding, Import, Export
|
||||
}
|
||||
|
||||
public ExportFileFlags Flags{
|
||||
get => selectedFlags;
|
||||
|
||||
set{
|
||||
// this will call events and SetFlag, which also updates the UI
|
||||
cbConfig.Checked = value.HasFlag(ExportFileFlags.Config);
|
||||
cbSession.Checked = value.HasFlag(ExportFileFlags.Session);
|
||||
cbPluginData.Checked = value.HasFlag(ExportFileFlags.PluginData);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldReloadUI { get; private set; }
|
||||
|
||||
private readonly PluginManager plugins;
|
||||
private State currentState;
|
||||
|
||||
private ExportManager importManager;
|
||||
private ExportFileFlags selectedFlags = ExportFileFlags.None;
|
||||
|
||||
public DialogSettingsManage(PluginManager plugins){
|
||||
InitializeComponent();
|
||||
|
||||
this.plugins = plugins;
|
||||
this.currentState = State.Deciding;
|
||||
}
|
||||
|
||||
private void radioDecision_CheckedChanged(object sender, EventArgs e){
|
||||
btnContinue.Enabled = true;
|
||||
}
|
||||
|
||||
private void cbConfig_CheckedChanged(object sender, EventArgs e){
|
||||
SetFlag(ExportFileFlags.Config, cbConfig.Checked);
|
||||
}
|
||||
|
||||
private void cbSession_CheckedChanged(object sender, EventArgs e){
|
||||
SetFlag(ExportFileFlags.Session, cbSession.Checked);
|
||||
}
|
||||
|
||||
private void cbPluginData_CheckedChanged(object sender, EventArgs e){
|
||||
SetFlag(ExportFileFlags.PluginData, cbPluginData.Checked);
|
||||
}
|
||||
|
||||
private void btnContinue_Click(object sender, EventArgs e){
|
||||
string file;
|
||||
|
||||
switch(currentState){
|
||||
case State.Deciding:
|
||||
// Reset
|
||||
if (radioReset.Checked){
|
||||
if (MessageBox.Show("This will reset all of your program options. Plugins will not be affected. Do you want to proceed?", "Reset "+Program.BrandName+" Options", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
Program.ResetConfig();
|
||||
|
||||
ShouldReloadUI = true;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Import
|
||||
else if (radioImport.Checked){
|
||||
using(OpenFileDialog dialog = new OpenFileDialog{
|
||||
AutoUpgradeEnabled = true,
|
||||
DereferenceLinks = true,
|
||||
Title = "Import "+Program.BrandName+" Profile",
|
||||
Filter = Program.BrandName+" Profile (*.tdsettings)|*.tdsettings"
|
||||
}){
|
||||
if (dialog.ShowDialog() != DialogResult.OK){
|
||||
return;
|
||||
}
|
||||
|
||||
file = dialog.FileName;
|
||||
}
|
||||
|
||||
importManager = new ExportManager(file, plugins);
|
||||
currentState = State.Import;
|
||||
|
||||
Text = "Import Profile";
|
||||
Flags = importManager.GetImportFlags();
|
||||
|
||||
cbConfig.Enabled = cbConfig.Checked;
|
||||
cbSession.Enabled = cbSession.Checked;
|
||||
cbPluginData.Enabled = cbPluginData.Checked;
|
||||
}
|
||||
|
||||
// Export
|
||||
else if (radioExport.Checked){
|
||||
currentState = State.Export;
|
||||
|
||||
Text = "Export Profile";
|
||||
btnContinue.Text = "Export Profile";
|
||||
Flags = ExportFileFlags.All & ~ExportFileFlags.Session;
|
||||
}
|
||||
|
||||
// Continue...
|
||||
panelDecision.Visible = false;
|
||||
panelExport.Visible = true;
|
||||
break;
|
||||
|
||||
case State.Import:
|
||||
if (importManager.Import(Flags)){
|
||||
if (!importManager.IsRestarting){
|
||||
ShouldReloadUI = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Program.Reporter.HandleException("Profile Import Error", "An exception happened while importing "+Program.BrandName+" profile.", true, importManager.LastException);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
break;
|
||||
|
||||
case State.Export:
|
||||
using(SaveFileDialog dialog = new SaveFileDialog{
|
||||
AddExtension = true,
|
||||
AutoUpgradeEnabled = true,
|
||||
OverwritePrompt = true,
|
||||
DefaultExt = "tdsettings",
|
||||
FileName = Program.BrandName+".tdsettings",
|
||||
Title = "Export "+Program.BrandName+" Profile",
|
||||
Filter = Program.BrandName+" Profile (*.tdsettings)|*.tdsettings"
|
||||
}){
|
||||
if (dialog.ShowDialog() != DialogResult.OK){
|
||||
return;
|
||||
}
|
||||
|
||||
file = dialog.FileName;
|
||||
}
|
||||
|
||||
Program.UserConfig.Save();
|
||||
ExportManager manager = new ExportManager(file, plugins);
|
||||
|
||||
if (!manager.Export(Flags)){
|
||||
Program.Reporter.HandleException("Profile Export Error", "An exception happened while exporting "+Program.BrandName+" profile.", true, manager.LastException);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e){
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void SetFlag(ExportFileFlags flag, bool enable){
|
||||
selectedFlags = enable ? selectedFlags | flag : selectedFlags & ~flag;
|
||||
btnContinue.Enabled = selectedFlags != ExportFileFlags.None;
|
||||
|
||||
if (currentState == State.Import){
|
||||
btnContinue.Text = selectedFlags.HasFlag(ExportFileFlags.Session) ? "Import && Restart" : "Import Profile";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
161
Core/Other/Settings/Dialogs/DialogSettingsRestart.Designer.cs
generated
Normal file
161
Core/Other/Settings/Dialogs/DialogSettingsRestart.Designer.cs
generated
Normal file
@@ -0,0 +1,161 @@
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs {
|
||||
partial class DialogSettingsRestart {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.btnRestart = new System.Windows.Forms.Button();
|
||||
this.cbLogging = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.cbDebugUpdates = new System.Windows.Forms.CheckBox();
|
||||
this.labelLocale = new System.Windows.Forms.Label();
|
||||
this.comboLocale = new System.Windows.Forms.ComboBox();
|
||||
this.labelDataFolder = new System.Windows.Forms.Label();
|
||||
this.tbDataFolder = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.AutoSize = true;
|
||||
this.btnCancel.Location = new System.Drawing.Point(160, 171);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnCancel.Size = new System.Drawing.Size(56, 23);
|
||||
this.btnCancel.TabIndex = 7;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// btnRestart
|
||||
//
|
||||
this.btnRestart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnRestart.AutoSize = true;
|
||||
this.btnRestart.Location = new System.Drawing.Point(97, 171);
|
||||
this.btnRestart.Name = "btnRestart";
|
||||
this.btnRestart.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnRestart.Size = new System.Drawing.Size(57, 23);
|
||||
this.btnRestart.TabIndex = 6;
|
||||
this.btnRestart.Text = "Restart";
|
||||
this.btnRestart.UseVisualStyleBackColor = true;
|
||||
this.btnRestart.Click += new System.EventHandler(this.btnRestart_Click);
|
||||
//
|
||||
// cbLogging
|
||||
//
|
||||
this.cbLogging.AutoSize = true;
|
||||
this.cbLogging.Location = new System.Drawing.Point(12, 12);
|
||||
this.cbLogging.Name = "cbLogging";
|
||||
this.cbLogging.Size = new System.Drawing.Size(64, 17);
|
||||
this.cbLogging.TabIndex = 0;
|
||||
this.cbLogging.Text = "Logging";
|
||||
this.toolTip.SetToolTip(this.cbLogging, "Logging JavaScript output into a\r\ndebug.txt file in the data folder.");
|
||||
this.cbLogging.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// cbDebugUpdates
|
||||
//
|
||||
this.cbDebugUpdates.AutoSize = true;
|
||||
this.cbDebugUpdates.Location = new System.Drawing.Point(12, 35);
|
||||
this.cbDebugUpdates.Name = "cbDebugUpdates";
|
||||
this.cbDebugUpdates.Size = new System.Drawing.Size(127, 17);
|
||||
this.cbDebugUpdates.TabIndex = 1;
|
||||
this.cbDebugUpdates.Text = "Pre-Release Updates";
|
||||
this.toolTip.SetToolTip(this.cbDebugUpdates, "Allows updating to pre-releases.");
|
||||
this.cbDebugUpdates.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelLocale
|
||||
//
|
||||
this.labelLocale.AutoSize = true;
|
||||
this.labelLocale.Location = new System.Drawing.Point(12, 67);
|
||||
this.labelLocale.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelLocale.Name = "labelLocale";
|
||||
this.labelLocale.Size = new System.Drawing.Size(39, 13);
|
||||
this.labelLocale.TabIndex = 2;
|
||||
this.labelLocale.Text = "Locale";
|
||||
//
|
||||
// comboLocale
|
||||
//
|
||||
this.comboLocale.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.comboLocale.FormattingEnabled = true;
|
||||
this.comboLocale.Location = new System.Drawing.Point(15, 83);
|
||||
this.comboLocale.Name = "comboLocale";
|
||||
this.comboLocale.Size = new System.Drawing.Size(201, 21);
|
||||
this.comboLocale.TabIndex = 3;
|
||||
//
|
||||
// labelDataFolder
|
||||
//
|
||||
this.labelDataFolder.AutoSize = true;
|
||||
this.labelDataFolder.Location = new System.Drawing.Point(12, 119);
|
||||
this.labelDataFolder.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelDataFolder.Name = "labelDataFolder";
|
||||
this.labelDataFolder.Size = new System.Drawing.Size(62, 13);
|
||||
this.labelDataFolder.TabIndex = 4;
|
||||
this.labelDataFolder.Text = "Data Folder";
|
||||
//
|
||||
// tbDataFolder
|
||||
//
|
||||
this.tbDataFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tbDataFolder.Location = new System.Drawing.Point(15, 135);
|
||||
this.tbDataFolder.Name = "tbDataFolder";
|
||||
this.tbDataFolder.Size = new System.Drawing.Size(201, 20);
|
||||
this.tbDataFolder.TabIndex = 5;
|
||||
//
|
||||
// DialogSettingsRestart
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(228, 206);
|
||||
this.Controls.Add(this.tbDataFolder);
|
||||
this.Controls.Add(this.labelDataFolder);
|
||||
this.Controls.Add(this.comboLocale);
|
||||
this.Controls.Add(this.labelLocale);
|
||||
this.Controls.Add(this.cbDebugUpdates);
|
||||
this.Controls.Add(this.cbLogging);
|
||||
this.Controls.Add(this.btnRestart);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "DialogSettingsRestart";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Button btnRestart;
|
||||
private System.Windows.Forms.CheckBox cbLogging;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.CheckBox cbDebugUpdates;
|
||||
private System.Windows.Forms.Label labelLocale;
|
||||
private System.Windows.Forms.ComboBox comboLocale;
|
||||
private System.Windows.Forms.Label labelDataFolder;
|
||||
private System.Windows.Forms.TextBox tbDataFolder;
|
||||
}
|
||||
}
|
62
Core/Other/Settings/Dialogs/DialogSettingsRestart.cs
Normal file
62
Core/Other/Settings/Dialogs/DialogSettingsRestart.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
sealed partial class DialogSettingsRestart : Form{
|
||||
private const string DefaultLocale = "en-US";
|
||||
|
||||
public CommandLineArgs Args { get; private set; }
|
||||
|
||||
public DialogSettingsRestart(CommandLineArgs currentArgs){
|
||||
InitializeComponent();
|
||||
|
||||
try{
|
||||
object[] locales = Directory.EnumerateFiles(Path.Combine(Program.ProgramPath, "locales"), "*.pak", SearchOption.TopDirectoryOnly).Select(Path.GetFileNameWithoutExtension).ToArray<object>();
|
||||
comboLocale.Items.AddRange(locales);
|
||||
}catch{
|
||||
comboLocale.Items.Add(DefaultLocale);
|
||||
}
|
||||
|
||||
cbLogging.Checked = currentArgs.HasFlag(Arguments.ArgLogging);
|
||||
cbDebugUpdates.Checked = currentArgs.HasFlag(Arguments.ArgDebugUpdates);
|
||||
comboLocale.SelectedItem = currentArgs.GetValue(Arguments.ArgLocale, DefaultLocale);
|
||||
tbDataFolder.Text = currentArgs.GetValue(Arguments.ArgDataFolder, string.Empty);
|
||||
|
||||
Text = Program.BrandName+" Arguments";
|
||||
}
|
||||
|
||||
private void btnRestart_Click(object sender, EventArgs e){
|
||||
Args = new CommandLineArgs();
|
||||
|
||||
if (cbLogging.Checked){
|
||||
Args.AddFlag(Arguments.ArgLogging);
|
||||
}
|
||||
|
||||
if (cbDebugUpdates.Checked){
|
||||
Args.AddFlag(Arguments.ArgDebugUpdates);
|
||||
}
|
||||
|
||||
string locale = comboLocale.SelectedItem as string;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(locale) && locale != DefaultLocale){
|
||||
Args.SetValue(Arguments.ArgLocale, locale);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tbDataFolder.Text)){
|
||||
Args.SetValue(Arguments.ArgDataFolder, tbDataFolder.Text);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e){
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings.Export{
|
||||
namespace TweetDuck.Core.Other.Settings.Export{
|
||||
class CombinedFileStream : IDisposable{
|
||||
public const char KeySeparator = '|';
|
||||
|
||||
@@ -63,6 +63,26 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
return new Entry(Encoding.UTF8.GetString(name), contents);
|
||||
}
|
||||
|
||||
public string SkipFile(){
|
||||
int nameLength = stream.ReadByte();
|
||||
|
||||
if (nameLength == -1){
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] name = new byte[nameLength];
|
||||
stream.Read(name, 0, nameLength);
|
||||
|
||||
byte[] contentLength = new byte[4];
|
||||
stream.Read(contentLength, 0, 4);
|
||||
|
||||
stream.Position += BitConverter.ToInt32(contentLength, 0);
|
||||
|
||||
string keyName = Encoding.UTF8.GetString(name);
|
||||
int separatorIndex = keyName.IndexOf(KeySeparator);
|
||||
return separatorIndex == -1 ? keyName : keyName.Substring(0, separatorIndex);
|
||||
}
|
||||
|
||||
public void Flush(){
|
||||
stream.Flush();
|
||||
}
|
||||
@@ -72,7 +92,7 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
}
|
||||
|
||||
public class Entry{
|
||||
public string Identifier { get; private set; }
|
||||
public string Identifier { get; }
|
||||
|
||||
public string KeyName{
|
||||
get{
|
||||
@@ -101,8 +121,11 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
|
||||
public void WriteToFile(string path, bool createDirectory){
|
||||
if (createDirectory){
|
||||
// ReSharper disable once AssignNullToNotNullAttribute
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
string dir = Path.GetDirectoryName(path);
|
||||
|
||||
if (!string.IsNullOrEmpty(dir)){
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllBytes(path, contents);
|
||||
|
12
Core/Other/Settings/Export/ExportFileFlags.cs
Normal file
12
Core/Other/Settings/Export/ExportFileFlags.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace TweetDuck.Core.Other.Settings.Export{
|
||||
[Flags]
|
||||
enum ExportFileFlags{
|
||||
None = 0,
|
||||
Config = 1,
|
||||
Session = 2,
|
||||
PluginData = 4,
|
||||
All = Config|Session|PluginData
|
||||
}
|
||||
}
|
@@ -3,10 +3,11 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDck.Plugins.Enums;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings.Export{
|
||||
namespace TweetDuck.Core.Other.Settings.Export{
|
||||
sealed class ExportManager{
|
||||
private static readonly string CookiesPath = Path.Combine(Program.StoragePath, "Cookies");
|
||||
private static readonly string TempCookiesPath = Path.Combine(Program.StoragePath, "CookiesTmp");
|
||||
@@ -22,22 +23,28 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
this.plugins = plugins;
|
||||
}
|
||||
|
||||
public bool Export(bool includeSession){
|
||||
public bool Export(ExportFileFlags flags){
|
||||
try{
|
||||
using(CombinedFileStream stream = new CombinedFileStream(new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None))){
|
||||
stream.WriteFile("config", Program.ConfigFilePath);
|
||||
if (flags.HasFlag(ExportFileFlags.Config)){
|
||||
stream.WriteFile("config", Program.UserConfigFilePath);
|
||||
}
|
||||
|
||||
foreach(Plugin plugin in plugins.Plugins){
|
||||
foreach(PathInfo path in EnumerateFilesRelative(plugin.GetPluginFolder(PluginFolder.Data))){
|
||||
try{
|
||||
stream.WriteFile(new string[]{ "plugin.data", plugin.Identifier, path.Relative }, path.Full);
|
||||
}catch(ArgumentOutOfRangeException e){
|
||||
MessageBox.Show("Could not include a plugin file in the export. "+e.Message, "Export Profile", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
if (flags.HasFlag(ExportFileFlags.PluginData)){
|
||||
stream.WriteFile("plugin.config", Program.PluginConfigFilePath);
|
||||
|
||||
foreach(Plugin plugin in plugins.Plugins){
|
||||
foreach(PathInfo path in EnumerateFilesRelative(plugin.GetPluginFolder(PluginFolder.Data))){
|
||||
try{
|
||||
stream.WriteFile(new string[]{ "plugin.data", plugin.Identifier, path.Relative }, path.Full);
|
||||
}catch(ArgumentOutOfRangeException e){
|
||||
MessageBox.Show("Could not include a plugin file in the export. "+e.Message, "Export Profile", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (includeSession){
|
||||
if (flags.HasFlag(ExportFileFlags.Session)){
|
||||
stream.WriteFile("cookies", CookiesPath);
|
||||
}
|
||||
|
||||
@@ -51,9 +58,40 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
}
|
||||
}
|
||||
|
||||
public bool Import(){
|
||||
public ExportFileFlags GetImportFlags(){
|
||||
ExportFileFlags flags = ExportFileFlags.None;
|
||||
|
||||
try{
|
||||
using(CombinedFileStream stream = new CombinedFileStream(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None))){
|
||||
string key;
|
||||
|
||||
while((key = stream.SkipFile()) != null){
|
||||
switch(key){
|
||||
case "config":
|
||||
flags |= ExportFileFlags.Config;
|
||||
break;
|
||||
|
||||
case "plugin.config":
|
||||
case "plugin.data":
|
||||
flags |= ExportFileFlags.PluginData;
|
||||
break;
|
||||
|
||||
case "cookies":
|
||||
flags |= ExportFileFlags.Session;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Exception e){
|
||||
LastException = e;
|
||||
flags = ExportFileFlags.None;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public bool Import(ExportFileFlags flags){
|
||||
try{
|
||||
bool updatedPlugins = false;
|
||||
HashSet<string> missingPlugins = new HashSet<string>();
|
||||
|
||||
using(CombinedFileStream stream = new CombinedFileStream(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None))){
|
||||
@@ -62,26 +100,34 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
while((entry = stream.ReadFile()) != null){
|
||||
switch(entry.KeyName){
|
||||
case "config":
|
||||
entry.WriteToFile(Program.ConfigFilePath);
|
||||
Program.ReloadConfig();
|
||||
if (flags.HasFlag(ExportFileFlags.Config)){
|
||||
entry.WriteToFile(Program.UserConfigFilePath);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "plugin.config":
|
||||
if (flags.HasFlag(ExportFileFlags.PluginData)){
|
||||
entry.WriteToFile(Program.PluginConfigFilePath);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "plugin.data":
|
||||
string[] value = entry.KeyValue;
|
||||
if (flags.HasFlag(ExportFileFlags.PluginData)){
|
||||
string[] value = entry.KeyValue;
|
||||
|
||||
entry.WriteToFile(Path.Combine(Program.PluginDataPath, value[0], value[1]), true);
|
||||
entry.WriteToFile(Path.Combine(Program.PluginDataPath, value[0], value[1]), true);
|
||||
|
||||
if (plugins.IsPluginInstalled(value[0])){
|
||||
updatedPlugins = true;
|
||||
}
|
||||
else{
|
||||
missingPlugins.Add(value[0]);
|
||||
if (!plugins.IsPluginInstalled(value[0])){
|
||||
missingPlugins.Add(value[0]);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "cookies":
|
||||
if (MessageBox.Show("Do you want to import the login session? This will restart "+Program.BrandName+".", "Importing "+Program.BrandName+" Profile", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
if (flags.HasFlag(ExportFileFlags.Session)){
|
||||
entry.WriteToFile(Path.Combine(Program.StoragePath, TempCookiesPath));
|
||||
IsRestarting = true;
|
||||
}
|
||||
@@ -96,10 +142,10 @@ namespace TweetDck.Core.Other.Settings.Export{
|
||||
}
|
||||
|
||||
if (IsRestarting){
|
||||
Program.Restart(new string[]{ "-importcookies" });
|
||||
Program.Restart(new string[]{ Arguments.ArgImportCookies });
|
||||
}
|
||||
else if (updatedPlugins){
|
||||
plugins.Reload();
|
||||
else{
|
||||
Program.ReloadConfig();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
276
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
276
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other.Settings {
|
||||
namespace TweetDuck.Core.Other.Settings {
|
||||
partial class TabSettingsAdvanced {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -29,193 +29,194 @@
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.btnEditCefArgs = new System.Windows.Forms.Button();
|
||||
this.btnEditCSS = new System.Windows.Forms.Button();
|
||||
this.btnRestartLog = new System.Windows.Forms.Button();
|
||||
this.btnRestartArgs = new System.Windows.Forms.Button();
|
||||
this.btnRestart = new System.Windows.Forms.Button();
|
||||
this.btnReset = new System.Windows.Forms.Button();
|
||||
this.btnImport = new System.Windows.Forms.Button();
|
||||
this.btnExport = new System.Windows.Forms.Button();
|
||||
this.groupPerformance = new System.Windows.Forms.GroupBox();
|
||||
this.groupConfiguration = new System.Windows.Forms.GroupBox();
|
||||
this.groupApp = new System.Windows.Forms.GroupBox();
|
||||
this.btnOpenAppFolder = new System.Windows.Forms.Button();
|
||||
this.groupPerformance.SuspendLayout();
|
||||
this.groupConfiguration.SuspendLayout();
|
||||
this.groupApp.SuspendLayout();
|
||||
this.btnOpenDataFolder = new System.Windows.Forms.Button();
|
||||
this.labelApp = new System.Windows.Forms.Label();
|
||||
this.panelApp = new System.Windows.Forms.Panel();
|
||||
this.labelPerformance = new System.Windows.Forms.Label();
|
||||
this.panelPerformance = new System.Windows.Forms.Panel();
|
||||
this.panelConfiguration = new System.Windows.Forms.Panel();
|
||||
this.labelConfiguration = new System.Windows.Forms.Label();
|
||||
this.panelApp.SuspendLayout();
|
||||
this.panelPerformance.SuspendLayout();
|
||||
this.panelConfiguration.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnClearCache
|
||||
//
|
||||
this.btnClearCache.Location = new System.Drawing.Point(6, 44);
|
||||
this.btnClearCache.Location = new System.Drawing.Point(5, 28);
|
||||
this.btnClearCache.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.btnClearCache.Name = "btnClearCache";
|
||||
this.btnClearCache.Size = new System.Drawing.Size(171, 23);
|
||||
this.btnClearCache.TabIndex = 14;
|
||||
this.btnClearCache.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnClearCache.TabIndex = 1;
|
||||
this.btnClearCache.Text = "Clear Cache (calculating)";
|
||||
this.toolTip.SetToolTip(this.btnClearCache, "Clearing cache will free up space taken by downloaded images and other resources." +
|
||||
"");
|
||||
this.btnClearCache.UseVisualStyleBackColor = true;
|
||||
this.btnClearCache.Click += new System.EventHandler(this.btnClearCache_Click);
|
||||
//
|
||||
// checkHardwareAcceleration
|
||||
//
|
||||
this.checkHardwareAcceleration.AutoSize = true;
|
||||
this.checkHardwareAcceleration.Location = new System.Drawing.Point(6, 21);
|
||||
this.checkHardwareAcceleration.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.checkHardwareAcceleration.Location = new System.Drawing.Point(6, 5);
|
||||
this.checkHardwareAcceleration.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkHardwareAcceleration.Name = "checkHardwareAcceleration";
|
||||
this.checkHardwareAcceleration.Size = new System.Drawing.Size(134, 17);
|
||||
this.checkHardwareAcceleration.TabIndex = 12;
|
||||
this.checkHardwareAcceleration.TabIndex = 0;
|
||||
this.checkHardwareAcceleration.Text = "Hardware Acceleration";
|
||||
this.toolTip.SetToolTip(this.checkHardwareAcceleration, "Uses your graphics card to improve performance.\r\nDisable if you experience issues" +
|
||||
" with rendering.");
|
||||
this.checkHardwareAcceleration.UseVisualStyleBackColor = true;
|
||||
this.checkHardwareAcceleration.CheckedChanged += new System.EventHandler(this.checkHardwareAcceleration_CheckedChanged);
|
||||
//
|
||||
// btnEditCefArgs
|
||||
//
|
||||
this.btnEditCefArgs.Location = new System.Drawing.Point(6, 19);
|
||||
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(171, 23);
|
||||
this.btnEditCefArgs.TabIndex = 15;
|
||||
this.btnEditCefArgs.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnEditCefArgs.TabIndex = 0;
|
||||
this.btnEditCefArgs.Text = "Edit CEF Arguments";
|
||||
this.toolTip.SetToolTip(this.btnEditCefArgs, "Set custom command line arguments for Chromium Embedded Framework.");
|
||||
this.btnEditCefArgs.UseVisualStyleBackColor = true;
|
||||
this.btnEditCefArgs.Click += new System.EventHandler(this.btnEditCefArgs_Click);
|
||||
//
|
||||
// btnEditCSS
|
||||
//
|
||||
this.btnEditCSS.Location = new System.Drawing.Point(6, 48);
|
||||
this.btnEditCSS.Location = new System.Drawing.Point(155, 3);
|
||||
this.btnEditCSS.Name = "btnEditCSS";
|
||||
this.btnEditCSS.Size = new System.Drawing.Size(171, 23);
|
||||
this.btnEditCSS.TabIndex = 16;
|
||||
this.btnEditCSS.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnEditCSS.TabIndex = 1;
|
||||
this.btnEditCSS.Text = "Edit CSS";
|
||||
this.toolTip.SetToolTip(this.btnEditCSS, "Set custom CSS for browser and notification windows.");
|
||||
this.btnEditCSS.UseVisualStyleBackColor = true;
|
||||
this.btnEditCSS.Click += new System.EventHandler(this.btnEditCSS_Click);
|
||||
//
|
||||
// btnRestartLog
|
||||
// btnRestartArgs
|
||||
//
|
||||
this.btnRestartLog.Location = new System.Drawing.Point(6, 77);
|
||||
this.btnRestartLog.Name = "btnRestartLog";
|
||||
this.btnRestartLog.Size = new System.Drawing.Size(171, 23);
|
||||
this.btnRestartLog.TabIndex = 18;
|
||||
this.btnRestartLog.Text = "Restart with Logging";
|
||||
this.toolTip.SetToolTip(this.btnRestartLog, "Restarts the program and enables logging\r\ninto a debug.txt file in the installati" +
|
||||
"on folder.");
|
||||
this.btnRestartLog.UseVisualStyleBackColor = true;
|
||||
this.btnRestartLog.Click += new System.EventHandler(this.btnRestartLog_Click);
|
||||
this.btnRestartArgs.Location = new System.Drawing.Point(155, 32);
|
||||
this.btnRestartArgs.Name = "btnRestartArgs";
|
||||
this.btnRestartArgs.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnRestartArgs.TabIndex = 3;
|
||||
this.btnRestartArgs.Text = "Restart with Arguments";
|
||||
this.toolTip.SetToolTip(this.btnRestartArgs, "Restarts the program with customizable\r\ncommand line arguments.");
|
||||
this.btnRestartArgs.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnRestart
|
||||
//
|
||||
this.btnRestart.Location = new System.Drawing.Point(6, 48);
|
||||
this.btnRestart.Location = new System.Drawing.Point(155, 3);
|
||||
this.btnRestart.Name = "btnRestart";
|
||||
this.btnRestart.Size = new System.Drawing.Size(171, 23);
|
||||
this.btnRestart.TabIndex = 17;
|
||||
this.btnRestart.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnRestart.TabIndex = 2;
|
||||
this.btnRestart.Text = "Restart the Program";
|
||||
this.toolTip.SetToolTip(this.btnRestart, "Restarts the program using the same command\r\nline arguments that were used at lau" +
|
||||
"nch.");
|
||||
this.btnRestart.UseVisualStyleBackColor = true;
|
||||
this.btnRestart.Click += new System.EventHandler(this.btnRestart_Click);
|
||||
//
|
||||
// btnReset
|
||||
//
|
||||
this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnReset.AutoSize = true;
|
||||
this.btnReset.Location = new System.Drawing.Point(190, 250);
|
||||
this.btnReset.Name = "btnReset";
|
||||
this.btnReset.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnReset.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnReset.TabIndex = 17;
|
||||
this.btnReset.Text = "Restore Defaults";
|
||||
this.btnReset.UseVisualStyleBackColor = true;
|
||||
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
|
||||
//
|
||||
// btnImport
|
||||
//
|
||||
this.btnImport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnImport.AutoSize = true;
|
||||
this.btnImport.Location = new System.Drawing.Point(100, 250);
|
||||
this.btnImport.Name = "btnImport";
|
||||
this.btnImport.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnImport.Size = new System.Drawing.Size(84, 23);
|
||||
this.btnImport.TabIndex = 16;
|
||||
this.btnImport.Text = "Import Profile";
|
||||
this.btnImport.UseVisualStyleBackColor = true;
|
||||
this.btnImport.Click += new System.EventHandler(this.btnImport_Click);
|
||||
//
|
||||
// btnExport
|
||||
//
|
||||
this.btnExport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.btnExport.AutoSize = true;
|
||||
this.btnExport.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnExport.Location = new System.Drawing.Point(9, 250);
|
||||
this.btnExport.Name = "btnExport";
|
||||
this.btnExport.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.btnExport.Size = new System.Drawing.Size(85, 23);
|
||||
this.btnExport.TabIndex = 15;
|
||||
this.btnExport.Text = "Export Profile";
|
||||
this.btnExport.UseVisualStyleBackColor = true;
|
||||
this.btnExport.Click += new System.EventHandler(this.btnExport_Click);
|
||||
//
|
||||
// groupPerformance
|
||||
//
|
||||
this.groupPerformance.Controls.Add(this.checkHardwareAcceleration);
|
||||
this.groupPerformance.Controls.Add(this.btnClearCache);
|
||||
this.groupPerformance.Location = new System.Drawing.Point(9, 9);
|
||||
this.groupPerformance.Name = "groupPerformance";
|
||||
this.groupPerformance.Size = new System.Drawing.Size(183, 74);
|
||||
this.groupPerformance.TabIndex = 18;
|
||||
this.groupPerformance.TabStop = false;
|
||||
this.groupPerformance.Text = "Performance";
|
||||
//
|
||||
// groupConfiguration
|
||||
//
|
||||
this.groupConfiguration.Controls.Add(this.btnEditCSS);
|
||||
this.groupConfiguration.Controls.Add(this.btnEditCefArgs);
|
||||
this.groupConfiguration.Location = new System.Drawing.Point(9, 89);
|
||||
this.groupConfiguration.Name = "groupConfiguration";
|
||||
this.groupConfiguration.Size = new System.Drawing.Size(183, 77);
|
||||
this.groupConfiguration.TabIndex = 19;
|
||||
this.groupConfiguration.TabStop = false;
|
||||
this.groupConfiguration.Text = "Configuration";
|
||||
//
|
||||
// groupApp
|
||||
//
|
||||
this.groupApp.Controls.Add(this.btnOpenAppFolder);
|
||||
this.groupApp.Controls.Add(this.btnRestartLog);
|
||||
this.groupApp.Controls.Add(this.btnRestart);
|
||||
this.groupApp.Location = new System.Drawing.Point(198, 9);
|
||||
this.groupApp.Name = "groupApp";
|
||||
this.groupApp.Size = new System.Drawing.Size(183, 106);
|
||||
this.groupApp.TabIndex = 20;
|
||||
this.groupApp.TabStop = false;
|
||||
this.groupApp.Text = "App";
|
||||
//
|
||||
// btnOpenAppFolder
|
||||
//
|
||||
this.btnOpenAppFolder.Location = new System.Drawing.Point(6, 19);
|
||||
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(171, 23);
|
||||
this.btnOpenAppFolder.TabIndex = 16;
|
||||
this.btnOpenAppFolder.Size = new System.Drawing.Size(144, 23);
|
||||
this.btnOpenAppFolder.TabIndex = 0;
|
||||
this.btnOpenAppFolder.Text = "Open Program Folder";
|
||||
this.toolTip.SetToolTip(this.btnOpenAppFolder, "Opens the folder where the app is located.");
|
||||
this.btnOpenAppFolder.UseVisualStyleBackColor = true;
|
||||
this.btnOpenAppFolder.Click += new System.EventHandler(this.btnOpenAppFolder_Click);
|
||||
//
|
||||
// btnOpenDataFolder
|
||||
//
|
||||
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.TabIndex = 1;
|
||||
this.btnOpenDataFolder.Text = "Open Data Folder";
|
||||
this.toolTip.SetToolTip(this.btnOpenDataFolder, "Opens the folder where your profile data is located.");
|
||||
this.btnOpenDataFolder.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.Location = new System.Drawing.Point(6, 8);
|
||||
this.labelApp.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
this.labelApp.Name = "labelApp";
|
||||
this.labelApp.Size = new System.Drawing.Size(38, 20);
|
||||
this.labelApp.TabIndex = 0;
|
||||
this.labelApp.Text = "App";
|
||||
//
|
||||
// panelApp
|
||||
//
|
||||
this.panelApp.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelApp.Controls.Add(this.btnOpenDataFolder);
|
||||
this.panelApp.Controls.Add(this.btnOpenAppFolder);
|
||||
this.panelApp.Controls.Add(this.btnRestart);
|
||||
this.panelApp.Controls.Add(this.btnRestartArgs);
|
||||
this.panelApp.Location = new System.Drawing.Point(9, 31);
|
||||
this.panelApp.Name = "panelApp";
|
||||
this.panelApp.Size = new System.Drawing.Size(322, 59);
|
||||
this.panelApp.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(6, 114);
|
||||
this.labelPerformance.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelPerformance.Name = "labelPerformance";
|
||||
this.labelPerformance.Size = new System.Drawing.Size(100, 20);
|
||||
this.labelPerformance.TabIndex = 2;
|
||||
this.labelPerformance.Text = "Performance";
|
||||
//
|
||||
// panelPerformance
|
||||
//
|
||||
this.panelPerformance.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelPerformance.Controls.Add(this.checkHardwareAcceleration);
|
||||
this.panelPerformance.Controls.Add(this.btnClearCache);
|
||||
this.panelPerformance.Location = new System.Drawing.Point(9, 137);
|
||||
this.panelPerformance.Name = "panelPerformance";
|
||||
this.panelPerformance.Size = new System.Drawing.Size(322, 54);
|
||||
this.panelPerformance.TabIndex = 3;
|
||||
//
|
||||
// panelConfiguration
|
||||
//
|
||||
this.panelConfiguration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelConfiguration.Controls.Add(this.btnEditCSS);
|
||||
this.panelConfiguration.Controls.Add(this.btnEditCefArgs);
|
||||
this.panelConfiguration.Location = new System.Drawing.Point(9, 238);
|
||||
this.panelConfiguration.Name = "panelConfiguration";
|
||||
this.panelConfiguration.Size = new System.Drawing.Size(322, 29);
|
||||
this.panelConfiguration.TabIndex = 5;
|
||||
//
|
||||
// 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(6, 215);
|
||||
this.labelConfiguration.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelConfiguration.Name = "labelConfiguration";
|
||||
this.labelConfiguration.Size = new System.Drawing.Size(104, 20);
|
||||
this.labelConfiguration.TabIndex = 4;
|
||||
this.labelConfiguration.Text = "Configuration";
|
||||
//
|
||||
// TabSettingsAdvanced
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.groupApp);
|
||||
this.Controls.Add(this.groupConfiguration);
|
||||
this.Controls.Add(this.groupPerformance);
|
||||
this.Controls.Add(this.btnReset);
|
||||
this.Controls.Add(this.btnImport);
|
||||
this.Controls.Add(this.btnExport);
|
||||
this.Controls.Add(this.labelConfiguration);
|
||||
this.Controls.Add(this.panelConfiguration);
|
||||
this.Controls.Add(this.panelPerformance);
|
||||
this.Controls.Add(this.labelPerformance);
|
||||
this.Controls.Add(this.panelApp);
|
||||
this.Controls.Add(this.labelApp);
|
||||
this.Name = "TabSettingsAdvanced";
|
||||
this.Size = new System.Drawing.Size(478, 282);
|
||||
this.groupPerformance.ResumeLayout(false);
|
||||
this.groupPerformance.PerformLayout();
|
||||
this.groupConfiguration.ResumeLayout(false);
|
||||
this.groupApp.ResumeLayout(false);
|
||||
this.Size = new System.Drawing.Size(340, 277);
|
||||
this.panelApp.ResumeLayout(false);
|
||||
this.panelPerformance.ResumeLayout(false);
|
||||
this.panelPerformance.PerformLayout();
|
||||
this.panelConfiguration.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@@ -226,16 +227,17 @@
|
||||
private System.Windows.Forms.Button btnClearCache;
|
||||
private System.Windows.Forms.CheckBox checkHardwareAcceleration;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.Button btnReset;
|
||||
private System.Windows.Forms.Button btnImport;
|
||||
private System.Windows.Forms.Button btnExport;
|
||||
private System.Windows.Forms.GroupBox groupPerformance;
|
||||
private System.Windows.Forms.GroupBox groupConfiguration;
|
||||
private System.Windows.Forms.Button btnEditCefArgs;
|
||||
private System.Windows.Forms.Button btnEditCSS;
|
||||
private System.Windows.Forms.GroupBox groupApp;
|
||||
private System.Windows.Forms.Button btnRestartLog;
|
||||
private System.Windows.Forms.Button btnRestartArgs;
|
||||
private System.Windows.Forms.Button btnRestart;
|
||||
private System.Windows.Forms.Button btnOpenAppFolder;
|
||||
private System.Windows.Forms.Button btnOpenDataFolder;
|
||||
private System.Windows.Forms.Label labelApp;
|
||||
private System.Windows.Forms.Panel panelApp;
|
||||
private System.Windows.Forms.Label labelPerformance;
|
||||
private System.Windows.Forms.Panel panelPerformance;
|
||||
private System.Windows.Forms.Panel panelConfiguration;
|
||||
private System.Windows.Forms.Label labelConfiguration;
|
||||
}
|
||||
}
|
||||
|
@@ -1,24 +1,27 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDck.Core.Other.Settings.Dialogs;
|
||||
using TweetDck.Core.Other.Settings.Export;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDck.Plugins;
|
||||
using TweetDuck.Configuration;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Other.Settings.Dialogs;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings{
|
||||
namespace TweetDuck.Core.Other.Settings{
|
||||
partial class TabSettingsAdvanced : BaseTabSettings{
|
||||
private readonly Action browserReloadAction;
|
||||
private readonly PluginManager plugins;
|
||||
private readonly Action<string> reinjectBrowserCSS;
|
||||
|
||||
public TabSettingsAdvanced(Action browserReloadAction, PluginManager plugins){
|
||||
public TabSettingsAdvanced(Action<string> reinjectBrowserCSS){
|
||||
InitializeComponent();
|
||||
|
||||
this.browserReloadAction = browserReloadAction;
|
||||
this.plugins = plugins;
|
||||
this.reinjectBrowserCSS = reinjectBrowserCSS;
|
||||
|
||||
checkHardwareAcceleration.Checked = HardwareAcceleration.IsEnabled;
|
||||
if (SystemConfig.IsHardwareAccelerationSupported){
|
||||
checkHardwareAcceleration.Checked = Program.SystemConfig.HardwareAcceleration;
|
||||
}
|
||||
else{
|
||||
checkHardwareAcceleration.Enabled = false;
|
||||
checkHardwareAcceleration.Checked = false;
|
||||
}
|
||||
|
||||
BrowserCache.CalculateCacheSize(bytes => this.InvokeSafe(() => {
|
||||
if (bytes == -1L){
|
||||
@@ -30,9 +33,20 @@ namespace TweetDck.Core.Other.Settings{
|
||||
}));
|
||||
}
|
||||
|
||||
private void btnClearCache_Click(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
public override void OnReady(){
|
||||
btnClearCache.Click += btnClearCache_Click;
|
||||
checkHardwareAcceleration.CheckedChanged += checkHardwareAcceleration_CheckedChanged;
|
||||
|
||||
btnEditCefArgs.Click += btnEditCefArgs_Click;
|
||||
btnEditCSS.Click += btnEditCSS_Click;
|
||||
|
||||
btnOpenAppFolder.Click += btnOpenAppFolder_Click;
|
||||
btnOpenDataFolder.Click += btnOpenDataFolder_Click;
|
||||
btnRestart.Click += btnRestart_Click;
|
||||
btnRestartArgs.Click += btnRestartArgs_Click;
|
||||
}
|
||||
|
||||
private void btnClearCache_Click(object sender, EventArgs e){
|
||||
btnClearCache.Enabled = false;
|
||||
BrowserCache.SetClearOnExit();
|
||||
|
||||
@@ -40,133 +54,74 @@ namespace TweetDck.Core.Other.Settings{
|
||||
}
|
||||
|
||||
private void checkHardwareAcceleration_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
bool succeeded = false;
|
||||
|
||||
if (checkHardwareAcceleration.Checked){
|
||||
if (HardwareAcceleration.CanEnable){
|
||||
succeeded = HardwareAcceleration.Enable();
|
||||
}
|
||||
else{
|
||||
MessageBox.Show("Cannot enable hardware acceleration, the libraries libEGL.dll and libGLESv2.dll could not be restored.", Program.BrandName+" Settings", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
else{
|
||||
succeeded = HardwareAcceleration.Disable();
|
||||
}
|
||||
|
||||
if (succeeded){
|
||||
PromptRestart();
|
||||
}
|
||||
else{
|
||||
checkHardwareAcceleration.CheckedChanged -= checkHardwareAcceleration_CheckedChanged;
|
||||
checkHardwareAcceleration.Checked = HardwareAcceleration.IsEnabled;
|
||||
checkHardwareAcceleration.CheckedChanged += checkHardwareAcceleration_CheckedChanged;
|
||||
}
|
||||
Program.SystemConfig.HardwareAcceleration = checkHardwareAcceleration.Checked;
|
||||
Program.SystemConfig.Save();
|
||||
PromptRestart();
|
||||
}
|
||||
|
||||
private void btnEditCefArgs_Click(object sender, EventArgs e){
|
||||
DialogSettingsCefArgs form = new DialogSettingsCefArgs();
|
||||
|
||||
if (form.ShowDialog(ParentForm) == DialogResult.OK){
|
||||
Config.CustomCefArgs = form.CefArgs;
|
||||
form.Dispose();
|
||||
PromptRestart();
|
||||
}
|
||||
else{
|
||||
form.Dispose();
|
||||
}
|
||||
form.VisibleChanged += (sender2, args2) => {
|
||||
form.MoveToCenter(ParentForm);
|
||||
};
|
||||
|
||||
form.FormClosed += (sender2, args2) => {
|
||||
NativeMethods.SetFormDisabled(ParentForm, false);
|
||||
|
||||
if (form.DialogResult == DialogResult.OK){
|
||||
Config.CustomCefArgs = form.CefArgs;
|
||||
PromptRestart();
|
||||
form.Dispose();
|
||||
}
|
||||
else form.Dispose();
|
||||
};
|
||||
|
||||
form.Show(ParentForm);
|
||||
NativeMethods.SetFormDisabled(ParentForm, true);
|
||||
}
|
||||
|
||||
private void btnEditCSS_Click(object sender, EventArgs e){
|
||||
using(DialogSettingsCSS form = new DialogSettingsCSS()){
|
||||
if (form.ShowDialog(ParentForm) == DialogResult.OK){
|
||||
bool hasChangedBrowser = form.BrowserCSS != Config.CustomBrowserCSS;
|
||||
DialogSettingsCSS form = new DialogSettingsCSS(reinjectBrowserCSS);
|
||||
|
||||
form.VisibleChanged += (sender2, args2) => {
|
||||
form.MoveToCenter(ParentForm);
|
||||
};
|
||||
|
||||
form.FormClosed += (sender2, args2) => {
|
||||
NativeMethods.SetFormDisabled(ParentForm, false);
|
||||
|
||||
if (form.DialogResult == DialogResult.OK){
|
||||
Config.CustomBrowserCSS = form.BrowserCSS;
|
||||
Config.CustomNotificationCSS = form.NotificationCSS;
|
||||
|
||||
if (hasChangedBrowser && MessageBox.Show("The browser CSS has changed, do you want to reload it?", "Browser CSS Changed", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
browserReloadAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnExport_Click(object sender, EventArgs e){
|
||||
DialogResult resultSaveCredentials = MessageBox.Show("Do you want to include your login session? This will not save your password into the file, but it will allow anyone with the file to login into TweetDeck as you.", "Export "+Program.BrandName+" Settings", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3);
|
||||
if (resultSaveCredentials == DialogResult.Cancel)return;
|
||||
|
||||
bool saveCredentials = resultSaveCredentials == DialogResult.Yes;
|
||||
string file;
|
||||
|
||||
using(SaveFileDialog dialog = new SaveFileDialog{
|
||||
AddExtension = true,
|
||||
AutoUpgradeEnabled = true,
|
||||
OverwritePrompt = true,
|
||||
DefaultExt = "tdsettings",
|
||||
FileName = Program.BrandName+".tdsettings",
|
||||
Title = "Export "+Program.BrandName+" Settings",
|
||||
Filter = Program.BrandName+" Settings (*.tdsettings)|*.tdsettings"
|
||||
}){
|
||||
file = dialog.ShowDialog() == DialogResult.OK ? dialog.FileName : null;
|
||||
}
|
||||
|
||||
if (file != null){
|
||||
Program.UserConfig.Save();
|
||||
|
||||
ExportManager manager = new ExportManager(file, plugins);
|
||||
|
||||
if (!manager.Export(saveCredentials)){
|
||||
Program.Reporter.HandleException("Profile Export Error", "An exception happened while exporting "+Program.BrandName+" settings.", true, manager.LastException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnImport_Click(object sender, EventArgs e){
|
||||
string file;
|
||||
|
||||
using(OpenFileDialog dialog = new OpenFileDialog{
|
||||
AutoUpgradeEnabled = true,
|
||||
DereferenceLinks = true,
|
||||
Title = "Import "+Program.BrandName+" Settings",
|
||||
Filter = Program.BrandName+" Settings (*.tdsettings)|*.tdsettings"
|
||||
}){
|
||||
file = dialog.ShowDialog() == DialogResult.OK ? dialog.FileName : null;
|
||||
}
|
||||
|
||||
if (file != null){
|
||||
ExportManager manager = new ExportManager(file, plugins);
|
||||
|
||||
if (manager.Import()){
|
||||
if (!manager.IsRestarting){
|
||||
((FormSettings)ParentForm).ReloadUI();
|
||||
}
|
||||
}
|
||||
else{
|
||||
Program.Reporter.HandleException("Profile Import Error", "An exception happened while importing "+Program.BrandName+" settings.", true, manager.LastException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnReset_Click(object sender, EventArgs e){
|
||||
if (MessageBox.Show("This will reset all of your settings, including disabled plugins. Do you want to proceed?", "Reset "+Program.BrandName+" Settings", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
Program.ResetConfig();
|
||||
((FormSettings)ParentForm).ReloadUI();
|
||||
}
|
||||
reinjectBrowserCSS(Config.CustomBrowserCSS); // reinject on cancel too, because the CSS is updated while typing
|
||||
form.Dispose();
|
||||
};
|
||||
|
||||
form.Show(ParentForm);
|
||||
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 btnRestartLog_Click(object sender, EventArgs e){
|
||||
Program.Restart(new string[]{ "-log" });
|
||||
private void btnRestartArgs_Click(object sender, EventArgs e){
|
||||
using(DialogSettingsRestart dialog = new DialogSettingsRestart(Arguments.GetCurrentClean())){
|
||||
if (dialog.ShowDialog() == DialogResult.OK){
|
||||
Program.RestartWithArgs(dialog.Args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
257
Core/Other/Settings/TabSettingsGeneral.Designer.cs
generated
257
Core/Other/Settings/TabSettingsGeneral.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other.Settings {
|
||||
namespace TweetDuck.Core.Other.Settings {
|
||||
partial class TabSettingsGeneral {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -29,110 +29,256 @@
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.checkTrayHighlight = new System.Windows.Forms.CheckBox();
|
||||
this.checkSpellCheck = new System.Windows.Forms.CheckBox();
|
||||
this.groupTray = new System.Windows.Forms.GroupBox();
|
||||
this.checkUpdateNotifications = new System.Windows.Forms.CheckBox();
|
||||
this.btnCheckUpdates = new System.Windows.Forms.Button();
|
||||
this.labelZoomValue = new System.Windows.Forms.Label();
|
||||
this.checkSwitchAccountSelectors = new System.Windows.Forms.CheckBox();
|
||||
this.labelTrayIcon = new System.Windows.Forms.Label();
|
||||
this.groupInterface = new System.Windows.Forms.GroupBox();
|
||||
this.groupTray.SuspendLayout();
|
||||
this.groupInterface.SuspendLayout();
|
||||
this.trackBarZoom = new System.Windows.Forms.TrackBar();
|
||||
this.labelZoom = new System.Windows.Forms.Label();
|
||||
this.zoomUpdateTimer = new System.Windows.Forms.Timer(this.components);
|
||||
this.labelUI = new System.Windows.Forms.Label();
|
||||
this.panelUI = new System.Windows.Forms.Panel();
|
||||
this.labelTray = new System.Windows.Forms.Label();
|
||||
this.panelUpdates = new System.Windows.Forms.Panel();
|
||||
this.panelTray = new System.Windows.Forms.Panel();
|
||||
this.labelUpdates = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarZoom)).BeginInit();
|
||||
this.panelUI.SuspendLayout();
|
||||
this.panelUpdates.SuspendLayout();
|
||||
this.panelTray.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// checkExpandLinks
|
||||
//
|
||||
this.checkExpandLinks.AutoSize = true;
|
||||
this.checkExpandLinks.Location = new System.Drawing.Point(9, 21);
|
||||
this.checkExpandLinks.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.checkExpandLinks.Location = new System.Drawing.Point(6, 5);
|
||||
this.checkExpandLinks.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkExpandLinks.Name = "checkExpandLinks";
|
||||
this.checkExpandLinks.Size = new System.Drawing.Size(166, 17);
|
||||
this.checkExpandLinks.TabIndex = 14;
|
||||
this.checkExpandLinks.TabIndex = 0;
|
||||
this.checkExpandLinks.Text = "Expand Links When Hovered";
|
||||
this.toolTip.SetToolTip(this.checkExpandLinks, "Expands links inside the tweets. If disabled,\r\nthe full links show up in a toolti" +
|
||||
"p instead.");
|
||||
this.checkExpandLinks.UseVisualStyleBackColor = true;
|
||||
this.checkExpandLinks.CheckedChanged += new System.EventHandler(this.checkExpandLinks_CheckedChanged);
|
||||
//
|
||||
// comboBoxTrayType
|
||||
//
|
||||
this.comboBoxTrayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxTrayType.FormattingEnabled = true;
|
||||
this.comboBoxTrayType.Location = new System.Drawing.Point(6, 19);
|
||||
this.comboBoxTrayType.Location = new System.Drawing.Point(5, 5);
|
||||
this.comboBoxTrayType.Margin = new System.Windows.Forms.Padding(5, 5, 3, 3);
|
||||
this.comboBoxTrayType.Name = "comboBoxTrayType";
|
||||
this.comboBoxTrayType.Size = new System.Drawing.Size(171, 21);
|
||||
this.comboBoxTrayType.TabIndex = 13;
|
||||
this.comboBoxTrayType.Size = new System.Drawing.Size(144, 21);
|
||||
this.comboBoxTrayType.TabIndex = 0;
|
||||
this.toolTip.SetToolTip(this.comboBoxTrayType, "Changes behavior of the Tray icon.\r\nRight-click the icon for an action menu.");
|
||||
this.comboBoxTrayType.SelectedIndexChanged += new System.EventHandler(this.comboBoxTrayType_SelectedIndexChanged);
|
||||
//
|
||||
// checkTrayHighlight
|
||||
//
|
||||
this.checkTrayHighlight.AutoSize = true;
|
||||
this.checkTrayHighlight.Location = new System.Drawing.Point(9, 70);
|
||||
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.checkTrayHighlight.Location = new System.Drawing.Point(6, 56);
|
||||
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkTrayHighlight.Name = "checkTrayHighlight";
|
||||
this.checkTrayHighlight.Size = new System.Drawing.Size(103, 17);
|
||||
this.checkTrayHighlight.TabIndex = 15;
|
||||
this.checkTrayHighlight.TabIndex = 2;
|
||||
this.checkTrayHighlight.Text = "Enable Highlight";
|
||||
this.toolTip.SetToolTip(this.checkTrayHighlight, "Highlights the tray icon if there are new tweets.\r\nOnly works for columns with po" +
|
||||
"pup or audio notifications.\r\nThe icon resets when the main window is restored.");
|
||||
this.checkTrayHighlight.UseVisualStyleBackColor = true;
|
||||
this.checkTrayHighlight.CheckedChanged += new System.EventHandler(this.checkTrayHighlight_CheckedChanged);
|
||||
//
|
||||
// checkSpellCheck
|
||||
//
|
||||
this.checkSpellCheck.AutoSize = true;
|
||||
this.checkSpellCheck.Location = new System.Drawing.Point(9, 44);
|
||||
this.checkSpellCheck.Location = new System.Drawing.Point(6, 51);
|
||||
this.checkSpellCheck.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkSpellCheck.Name = "checkSpellCheck";
|
||||
this.checkSpellCheck.Size = new System.Drawing.Size(119, 17);
|
||||
this.checkSpellCheck.TabIndex = 15;
|
||||
this.checkSpellCheck.TabIndex = 2;
|
||||
this.checkSpellCheck.Text = "Enable Spell Check";
|
||||
this.toolTip.SetToolTip(this.checkSpellCheck, "Underlines words that are spelled incorrectly.");
|
||||
this.checkSpellCheck.UseVisualStyleBackColor = true;
|
||||
this.checkSpellCheck.CheckedChanged += new System.EventHandler(this.checkSpellCheck_CheckedChanged);
|
||||
//
|
||||
// groupTray
|
||||
// checkUpdateNotifications
|
||||
//
|
||||
this.groupTray.Controls.Add(this.checkTrayHighlight);
|
||||
this.groupTray.Controls.Add(this.labelTrayIcon);
|
||||
this.groupTray.Controls.Add(this.comboBoxTrayType);
|
||||
this.groupTray.Location = new System.Drawing.Point(9, 86);
|
||||
this.groupTray.Name = "groupTray";
|
||||
this.groupTray.Size = new System.Drawing.Size(183, 93);
|
||||
this.groupTray.TabIndex = 15;
|
||||
this.groupTray.TabStop = false;
|
||||
this.groupTray.Text = "System Tray";
|
||||
this.checkUpdateNotifications.AutoSize = true;
|
||||
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 5);
|
||||
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkUpdateNotifications.Name = "checkUpdateNotifications";
|
||||
this.checkUpdateNotifications.Size = new System.Drawing.Size(165, 17);
|
||||
this.checkUpdateNotifications.TabIndex = 0;
|
||||
this.checkUpdateNotifications.Text = "Check Updates Automatically";
|
||||
this.toolTip.SetToolTip(this.checkUpdateNotifications, "Checks for updates every hour.\r\nIf an update is dismissed, it will not appear aga" +
|
||||
"in.");
|
||||
this.checkUpdateNotifications.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnCheckUpdates
|
||||
//
|
||||
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 28);
|
||||
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 = 1;
|
||||
this.btnCheckUpdates.Text = "Check Updates Now";
|
||||
this.toolTip.SetToolTip(this.btnCheckUpdates, "Forces an update check, even for updates that had been dismissed.");
|
||||
this.btnCheckUpdates.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelZoomValue
|
||||
//
|
||||
this.labelZoomValue.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelZoomValue.Location = new System.Drawing.Point(141, 100);
|
||||
this.labelZoomValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelZoomValue.Name = "labelZoomValue";
|
||||
this.labelZoomValue.Size = new System.Drawing.Size(38, 13);
|
||||
this.labelZoomValue.TabIndex = 5;
|
||||
this.labelZoomValue.Text = "100%";
|
||||
this.labelZoomValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
this.toolTip.SetToolTip(this.labelZoomValue, "Changes the zoom level.\r\nAlso affects notifications and screenshots.");
|
||||
//
|
||||
// checkSwitchAccountSelectors
|
||||
//
|
||||
this.checkSwitchAccountSelectors.AutoSize = true;
|
||||
this.checkSwitchAccountSelectors.Location = new System.Drawing.Point(6, 28);
|
||||
this.checkSwitchAccountSelectors.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkSwitchAccountSelectors.Name = "checkSwitchAccountSelectors";
|
||||
this.checkSwitchAccountSelectors.Size = new System.Drawing.Size(172, 17);
|
||||
this.checkSwitchAccountSelectors.TabIndex = 1;
|
||||
this.checkSwitchAccountSelectors.Text = "Shift Selects Multiple Accounts";
|
||||
this.toolTip.SetToolTip(this.checkSwitchAccountSelectors, "When (re)tweeting, click to select a single account or hold Shift to\r\nselect mult" +
|
||||
"iple accounts, instead of TweetDeck\'s default behavior.");
|
||||
this.checkSwitchAccountSelectors.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelTrayIcon
|
||||
//
|
||||
this.labelTrayIcon.AutoSize = true;
|
||||
this.labelTrayIcon.Location = new System.Drawing.Point(6, 52);
|
||||
this.labelTrayIcon.Location = new System.Drawing.Point(3, 38);
|
||||
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 = 14;
|
||||
this.labelTrayIcon.TabIndex = 1;
|
||||
this.labelTrayIcon.Text = "Tray Icon";
|
||||
//
|
||||
// groupInterface
|
||||
// trackBarZoom
|
||||
//
|
||||
this.groupInterface.Controls.Add(this.checkSpellCheck);
|
||||
this.groupInterface.Controls.Add(this.checkExpandLinks);
|
||||
this.groupInterface.Location = new System.Drawing.Point(9, 9);
|
||||
this.groupInterface.Name = "groupInterface";
|
||||
this.groupInterface.Size = new System.Drawing.Size(183, 71);
|
||||
this.groupInterface.TabIndex = 16;
|
||||
this.groupInterface.TabStop = false;
|
||||
this.groupInterface.Text = "User Interface";
|
||||
this.trackBarZoom.AutoSize = false;
|
||||
this.trackBarZoom.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.trackBarZoom.LargeChange = 25;
|
||||
this.trackBarZoom.Location = new System.Drawing.Point(3, 99);
|
||||
this.trackBarZoom.Maximum = 200;
|
||||
this.trackBarZoom.Minimum = 50;
|
||||
this.trackBarZoom.Name = "trackBarZoom";
|
||||
this.trackBarZoom.Size = new System.Drawing.Size(148, 30);
|
||||
this.trackBarZoom.SmallChange = 5;
|
||||
this.trackBarZoom.TabIndex = 4;
|
||||
this.trackBarZoom.TickFrequency = 25;
|
||||
this.trackBarZoom.Value = 100;
|
||||
//
|
||||
// labelZoom
|
||||
//
|
||||
this.labelZoom.AutoSize = true;
|
||||
this.labelZoom.Location = new System.Drawing.Point(3, 83);
|
||||
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 = 3;
|
||||
this.labelZoom.Text = "Zoom";
|
||||
//
|
||||
// zoomUpdateTimer
|
||||
//
|
||||
this.zoomUpdateTimer.Interval = 250;
|
||||
this.zoomUpdateTimer.Tick += new System.EventHandler(this.zoomUpdateTimer_Tick);
|
||||
//
|
||||
// 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.Location = new System.Drawing.Point(6, 8);
|
||||
this.labelUI.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
this.labelUI.Name = "labelUI";
|
||||
this.labelUI.Size = new System.Drawing.Size(111, 20);
|
||||
this.labelUI.TabIndex = 0;
|
||||
this.labelUI.Text = "User Interface";
|
||||
//
|
||||
// panelUI
|
||||
//
|
||||
this.panelUI.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelUI.Controls.Add(this.checkExpandLinks);
|
||||
this.panelUI.Controls.Add(this.checkSwitchAccountSelectors);
|
||||
this.panelUI.Controls.Add(this.checkSpellCheck);
|
||||
this.panelUI.Controls.Add(this.labelZoom);
|
||||
this.panelUI.Controls.Add(this.labelZoomValue);
|
||||
this.panelUI.Controls.Add(this.trackBarZoom);
|
||||
this.panelUI.Location = new System.Drawing.Point(9, 31);
|
||||
this.panelUI.Name = "panelUI";
|
||||
this.panelUI.Size = new System.Drawing.Size(322, 134);
|
||||
this.panelUI.TabIndex = 1;
|
||||
//
|
||||
// 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(5, 189);
|
||||
this.labelTray.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelTray.Name = "labelTray";
|
||||
this.labelTray.Size = new System.Drawing.Size(96, 20);
|
||||
this.labelTray.TabIndex = 2;
|
||||
this.labelTray.Text = "System Tray";
|
||||
//
|
||||
// panelUpdates
|
||||
//
|
||||
this.panelUpdates.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelUpdates.Controls.Add(this.checkUpdateNotifications);
|
||||
this.panelUpdates.Controls.Add(this.btnCheckUpdates);
|
||||
this.panelUpdates.Location = new System.Drawing.Point(9, 335);
|
||||
this.panelUpdates.Name = "panelUpdates";
|
||||
this.panelUpdates.Size = new System.Drawing.Size(322, 55);
|
||||
this.panelUpdates.TabIndex = 5;
|
||||
//
|
||||
// panelTray
|
||||
//
|
||||
this.panelTray.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelTray.Controls.Add(this.checkTrayHighlight);
|
||||
this.panelTray.Controls.Add(this.comboBoxTrayType);
|
||||
this.panelTray.Controls.Add(this.labelTrayIcon);
|
||||
this.panelTray.Location = new System.Drawing.Point(9, 212);
|
||||
this.panelTray.Name = "panelTray";
|
||||
this.panelTray.Size = new System.Drawing.Size(322, 76);
|
||||
this.panelTray.TabIndex = 3;
|
||||
//
|
||||
// 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(6, 312);
|
||||
this.labelUpdates.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelUpdates.Name = "labelUpdates";
|
||||
this.labelUpdates.Size = new System.Drawing.Size(70, 20);
|
||||
this.labelUpdates.TabIndex = 4;
|
||||
this.labelUpdates.Text = "Updates";
|
||||
//
|
||||
// TabSettingsGeneral
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.groupInterface);
|
||||
this.Controls.Add(this.groupTray);
|
||||
this.Controls.Add(this.labelUpdates);
|
||||
this.Controls.Add(this.panelTray);
|
||||
this.Controls.Add(this.panelUpdates);
|
||||
this.Controls.Add(this.labelTray);
|
||||
this.Controls.Add(this.panelUI);
|
||||
this.Controls.Add(this.labelUI);
|
||||
this.Name = "TabSettingsGeneral";
|
||||
this.Size = new System.Drawing.Size(478, 282);
|
||||
this.groupTray.ResumeLayout(false);
|
||||
this.groupTray.PerformLayout();
|
||||
this.groupInterface.ResumeLayout(false);
|
||||
this.groupInterface.PerformLayout();
|
||||
this.Size = new System.Drawing.Size(340, 400);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarZoom)).EndInit();
|
||||
this.panelUI.ResumeLayout(false);
|
||||
this.panelUI.PerformLayout();
|
||||
this.panelUpdates.ResumeLayout(false);
|
||||
this.panelUpdates.PerformLayout();
|
||||
this.panelTray.ResumeLayout(false);
|
||||
this.panelTray.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@@ -141,10 +287,21 @@
|
||||
private System.Windows.Forms.CheckBox checkExpandLinks;
|
||||
private System.Windows.Forms.ComboBox comboBoxTrayType;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.GroupBox groupTray;
|
||||
private System.Windows.Forms.GroupBox groupInterface;
|
||||
private System.Windows.Forms.Label labelTrayIcon;
|
||||
private System.Windows.Forms.CheckBox checkTrayHighlight;
|
||||
private System.Windows.Forms.CheckBox checkSpellCheck;
|
||||
private System.Windows.Forms.CheckBox checkUpdateNotifications;
|
||||
private System.Windows.Forms.Button btnCheckUpdates;
|
||||
private System.Windows.Forms.Label labelZoom;
|
||||
private System.Windows.Forms.Label labelZoomValue;
|
||||
private System.Windows.Forms.TrackBar trackBarZoom;
|
||||
private System.Windows.Forms.Timer zoomUpdateTimer;
|
||||
private System.Windows.Forms.CheckBox checkSwitchAccountSelectors;
|
||||
private System.Windows.Forms.Label labelUI;
|
||||
private System.Windows.Forms.Panel panelUI;
|
||||
private System.Windows.Forms.Label labelTray;
|
||||
private System.Windows.Forms.Panel panelUpdates;
|
||||
private System.Windows.Forms.Panel panelTray;
|
||||
private System.Windows.Forms.Label labelUpdates;
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,20 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Updates;
|
||||
using TweetDuck.Updates.Events;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings{
|
||||
namespace TweetDuck.Core.Other.Settings{
|
||||
partial class TabSettingsGeneral : BaseTabSettings{
|
||||
public TabSettingsGeneral(){
|
||||
private readonly UpdateHandler updates;
|
||||
private int updateCheckEventId = -1;
|
||||
|
||||
public TabSettingsGeneral(UpdateHandler updates){
|
||||
InitializeComponent();
|
||||
|
||||
this.updates = updates;
|
||||
this.updates.CheckFinished += updates_CheckFinished;
|
||||
Disposed += (sender, args) => this.updates.CheckFinished -= updates_CheckFinished;
|
||||
|
||||
comboBoxTrayType.Items.Add("Disabled");
|
||||
comboBoxTrayType.Items.Add("Display Icon Only");
|
||||
@@ -11,35 +22,94 @@ namespace TweetDck.Core.Other.Settings{
|
||||
comboBoxTrayType.Items.Add("Close to Tray");
|
||||
comboBoxTrayType.Items.Add("Combined");
|
||||
comboBoxTrayType.SelectedIndex = Math.Min(Math.Max((int)Config.TrayBehavior, 0), comboBoxTrayType.Items.Count-1);
|
||||
|
||||
toolTip.SetToolTip(trackBarZoom, toolTip.GetToolTip(labelZoomValue));
|
||||
trackBarZoom.SetValueSafe(Config.ZoomLevel);
|
||||
labelZoomValue.Text = trackBarZoom.Value+"%";
|
||||
|
||||
checkExpandLinks.Checked = Config.ExpandLinksOnHover;
|
||||
checkSwitchAccountSelectors.Checked = Config.SwitchAccountSelectors;
|
||||
checkSpellCheck.Checked = Config.EnableSpellCheck;
|
||||
checkTrayHighlight.Checked = Config.EnableTrayHighlight;
|
||||
|
||||
checkUpdateNotifications.Checked = Config.EnableUpdateCheck;
|
||||
}
|
||||
|
||||
public override void OnReady(){
|
||||
checkExpandLinks.CheckedChanged += checkExpandLinks_CheckedChanged;
|
||||
checkSwitchAccountSelectors.CheckedChanged += checkSwitchAccountSelectors_CheckedChanged;
|
||||
checkSpellCheck.CheckedChanged += checkSpellCheck_CheckedChanged;
|
||||
trackBarZoom.ValueChanged += trackBarZoom_ValueChanged;
|
||||
|
||||
comboBoxTrayType.SelectedIndexChanged += comboBoxTrayType_SelectedIndexChanged;
|
||||
checkTrayHighlight.CheckedChanged += checkTrayHighlight_CheckedChanged;
|
||||
|
||||
checkUpdateNotifications.CheckedChanged += checkUpdateNotifications_CheckedChanged;
|
||||
btnCheckUpdates.Click += btnCheckUpdates_Click;
|
||||
}
|
||||
|
||||
public override void OnClosing(){
|
||||
Config.ZoomLevel = trackBarZoom.Value;
|
||||
}
|
||||
|
||||
private void checkExpandLinks_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.ExpandLinksOnHover = checkExpandLinks.Checked;
|
||||
}
|
||||
|
||||
private void checkSpellCheck_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
private void checkSwitchAccountSelectors_CheckedChanged(object sender, EventArgs e){
|
||||
Config.SwitchAccountSelectors = checkSwitchAccountSelectors.Checked;
|
||||
}
|
||||
|
||||
private void checkSpellCheck_CheckedChanged(object sender, EventArgs e){
|
||||
Config.EnableSpellCheck = checkSpellCheck.Checked;
|
||||
PromptRestart();
|
||||
}
|
||||
|
||||
private void comboBoxTrayType_SelectedIndexChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
private void trackBarZoom_ValueChanged(object sender, EventArgs e){
|
||||
if (trackBarZoom.AlignValueToTick()){
|
||||
zoomUpdateTimer.Stop();
|
||||
zoomUpdateTimer.Start();
|
||||
labelZoomValue.Text = trackBarZoom.Value+"%";
|
||||
}
|
||||
}
|
||||
|
||||
private void comboBoxTrayType_SelectedIndexChanged(object sender, EventArgs e){
|
||||
Config.TrayBehavior = (TrayIcon.Behavior)comboBoxTrayType.SelectedIndex;
|
||||
}
|
||||
|
||||
private void checkTrayHighlight_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.EnableTrayHighlight = checkTrayHighlight.Checked;
|
||||
}
|
||||
|
||||
private void checkUpdateNotifications_CheckedChanged(object sender, EventArgs e){
|
||||
Config.EnableUpdateCheck = checkUpdateNotifications.Checked;
|
||||
}
|
||||
|
||||
private void btnCheckUpdates_Click(object sender, EventArgs e){
|
||||
updateCheckEventId = updates.Check(true);
|
||||
|
||||
if (updateCheckEventId == -1){
|
||||
MessageBox.Show("Sorry, your system is no longer supported.", "Unsupported System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
else{
|
||||
btnCheckUpdates.Enabled = false;
|
||||
updates.DismissUpdate(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
|
||||
if (e.EventId == updateCheckEventId){
|
||||
btnCheckUpdates.Enabled = true;
|
||||
|
||||
if (!e.UpdateAvailable){
|
||||
MessageBox.Show("Your version of "+Program.BrandName+" is up to date.", "No Updates Available", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void zoomUpdateTimer_Tick(object sender, EventArgs e){
|
||||
Config.ZoomLevel = trackBarZoom.Value;
|
||||
zoomUpdateTimer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
465
Core/Other/Settings/TabSettingsNotifications.Designer.cs
generated
465
Core/Other/Settings/TabSettingsNotifications.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core.Other.Settings {
|
||||
namespace TweetDuck.Core.Other.Settings {
|
||||
partial class TabSettingsNotifications {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -24,7 +24,6 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.groupNotificationLocation = new System.Windows.Forms.GroupBox();
|
||||
this.labelEdgeDistanceValue = new System.Windows.Forms.Label();
|
||||
this.labelDisplay = new System.Windows.Forms.Label();
|
||||
this.comboBoxDisplay = new System.Windows.Forms.ComboBox();
|
||||
@@ -35,64 +34,60 @@
|
||||
this.radioLocTR = new System.Windows.Forms.RadioButton();
|
||||
this.radioLocTL = new System.Windows.Forms.RadioButton();
|
||||
this.trackBarEdgeDistance = new System.Windows.Forms.TrackBar();
|
||||
this.groupNotificationDuration = new System.Windows.Forms.GroupBox();
|
||||
this.tableLayoutDurationButtons = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.btnDurationMedium = new TweetDck.Core.Controls.FlatButton();
|
||||
this.btnDurationLong = new TweetDck.Core.Controls.FlatButton();
|
||||
this.btnDurationShort = new TweetDck.Core.Controls.FlatButton();
|
||||
this.btnDurationMedium = new TweetDuck.Core.Controls.FlatButton();
|
||||
this.btnDurationLong = new TweetDuck.Core.Controls.FlatButton();
|
||||
this.btnDurationShort = new TweetDuck.Core.Controls.FlatButton();
|
||||
this.labelDurationValue = new System.Windows.Forms.Label();
|
||||
this.trackBarDuration = new System.Windows.Forms.TrackBar();
|
||||
this.groupUserInterface = new System.Windows.Forms.GroupBox();
|
||||
this.checkSkipOnLinkClick = new System.Windows.Forms.CheckBox();
|
||||
this.checkColumnName = new System.Windows.Forms.CheckBox();
|
||||
this.labelIdlePause = new System.Windows.Forms.Label();
|
||||
this.comboBoxIdlePause = new System.Windows.Forms.ComboBox();
|
||||
this.checkNonIntrusive = new System.Windows.Forms.CheckBox();
|
||||
this.checkTimerCountDown = new System.Windows.Forms.CheckBox();
|
||||
this.checkLegacyLoad = new System.Windows.Forms.CheckBox();
|
||||
this.checkNotificationTimer = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.groupNotificationLocation.SuspendLayout();
|
||||
this.labelGeneral = new System.Windows.Forms.Label();
|
||||
this.panelGeneral = new System.Windows.Forms.Panel();
|
||||
this.labelScrollSpeedValue = new System.Windows.Forms.Label();
|
||||
this.trackBarScrollSpeed = new System.Windows.Forms.TrackBar();
|
||||
this.labelScrollSpeed = new System.Windows.Forms.Label();
|
||||
this.labelLocation = new System.Windows.Forms.Label();
|
||||
this.panelLocation = new System.Windows.Forms.Panel();
|
||||
this.panelTimer = new System.Windows.Forms.Panel();
|
||||
this.labelDuration = new System.Windows.Forms.Label();
|
||||
this.labelTimer = new System.Windows.Forms.Label();
|
||||
this.labelMiscellaneous = new System.Windows.Forms.Label();
|
||||
this.panelMiscellaneous = new System.Windows.Forms.Panel();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarEdgeDistance)).BeginInit();
|
||||
this.groupNotificationDuration.SuspendLayout();
|
||||
this.tableLayoutDurationButtons.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarDuration)).BeginInit();
|
||||
this.groupUserInterface.SuspendLayout();
|
||||
this.panelGeneral.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarScrollSpeed)).BeginInit();
|
||||
this.panelLocation.SuspendLayout();
|
||||
this.panelTimer.SuspendLayout();
|
||||
this.panelMiscellaneous.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// groupNotificationLocation
|
||||
//
|
||||
this.groupNotificationLocation.Controls.Add(this.labelEdgeDistanceValue);
|
||||
this.groupNotificationLocation.Controls.Add(this.labelDisplay);
|
||||
this.groupNotificationLocation.Controls.Add(this.comboBoxDisplay);
|
||||
this.groupNotificationLocation.Controls.Add(this.labelEdgeDistance);
|
||||
this.groupNotificationLocation.Controls.Add(this.radioLocCustom);
|
||||
this.groupNotificationLocation.Controls.Add(this.radioLocBR);
|
||||
this.groupNotificationLocation.Controls.Add(this.radioLocBL);
|
||||
this.groupNotificationLocation.Controls.Add(this.radioLocTR);
|
||||
this.groupNotificationLocation.Controls.Add(this.radioLocTL);
|
||||
this.groupNotificationLocation.Controls.Add(this.trackBarEdgeDistance);
|
||||
this.groupNotificationLocation.Location = new System.Drawing.Point(198, 9);
|
||||
this.groupNotificationLocation.Name = "groupNotificationLocation";
|
||||
this.groupNotificationLocation.Size = new System.Drawing.Size(183, 264);
|
||||
this.groupNotificationLocation.TabIndex = 1;
|
||||
this.groupNotificationLocation.TabStop = false;
|
||||
this.groupNotificationLocation.Text = "Location";
|
||||
//
|
||||
// labelEdgeDistanceValue
|
||||
//
|
||||
this.labelEdgeDistanceValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelEdgeDistanceValue.Location = new System.Drawing.Point(143, 214);
|
||||
this.labelEdgeDistanceValue.Location = new System.Drawing.Point(147, 129);
|
||||
this.labelEdgeDistanceValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelEdgeDistanceValue.Name = "labelEdgeDistanceValue";
|
||||
this.labelEdgeDistanceValue.Size = new System.Drawing.Size(34, 13);
|
||||
this.labelEdgeDistanceValue.TabIndex = 11;
|
||||
this.labelEdgeDistanceValue.TabIndex = 9;
|
||||
this.labelEdgeDistanceValue.Text = "0 px";
|
||||
this.labelEdgeDistanceValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// labelDisplay
|
||||
//
|
||||
this.labelDisplay.AutoSize = true;
|
||||
this.labelDisplay.Location = new System.Drawing.Point(3, 148);
|
||||
this.labelDisplay.Location = new System.Drawing.Point(3, 60);
|
||||
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 = 8;
|
||||
this.labelDisplay.TabIndex = 5;
|
||||
this.labelDisplay.Text = "Display";
|
||||
//
|
||||
// comboBoxDisplay
|
||||
@@ -101,115 +96,94 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.comboBoxDisplay.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxDisplay.FormattingEnabled = true;
|
||||
this.comboBoxDisplay.Location = new System.Drawing.Point(6, 164);
|
||||
this.comboBoxDisplay.Location = new System.Drawing.Point(5, 76);
|
||||
this.comboBoxDisplay.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxDisplay.Name = "comboBoxDisplay";
|
||||
this.comboBoxDisplay.Size = new System.Drawing.Size(171, 21);
|
||||
this.comboBoxDisplay.TabIndex = 7;
|
||||
this.comboBoxDisplay.SelectedValueChanged += new System.EventHandler(this.comboBoxDisplay_SelectedValueChanged);
|
||||
this.comboBoxDisplay.Size = new System.Drawing.Size(144, 21);
|
||||
this.comboBoxDisplay.TabIndex = 6;
|
||||
//
|
||||
// labelEdgeDistance
|
||||
//
|
||||
this.labelEdgeDistance.AutoSize = true;
|
||||
this.labelEdgeDistance.Location = new System.Drawing.Point(3, 197);
|
||||
this.labelEdgeDistance.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
|
||||
this.labelEdgeDistance.Location = new System.Drawing.Point(3, 112);
|
||||
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 = 6;
|
||||
this.labelEdgeDistance.TabIndex = 7;
|
||||
this.labelEdgeDistance.Text = "Distance From Edge";
|
||||
//
|
||||
// radioLocCustom
|
||||
//
|
||||
this.radioLocCustom.AutoSize = true;
|
||||
this.radioLocCustom.Location = new System.Drawing.Point(7, 116);
|
||||
this.radioLocCustom.Location = new System.Drawing.Point(205, 4);
|
||||
this.radioLocCustom.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocCustom.Name = "radioLocCustom";
|
||||
this.radioLocCustom.Size = new System.Drawing.Size(60, 17);
|
||||
this.radioLocCustom.Size = new System.Drawing.Size(65, 41);
|
||||
this.radioLocCustom.TabIndex = 4;
|
||||
this.radioLocCustom.TabStop = true;
|
||||
this.radioLocCustom.Text = "Custom";
|
||||
this.toolTip.SetToolTip(this.radioLocCustom, "Drag the notification window to the desired location.");
|
||||
this.radioLocCustom.UseVisualStyleBackColor = true;
|
||||
this.radioLocCustom.CheckedChanged += new System.EventHandler(this.radioLoc_CheckedChanged);
|
||||
//
|
||||
// radioLocBR
|
||||
//
|
||||
this.radioLocBR.AutoSize = true;
|
||||
this.radioLocBR.Location = new System.Drawing.Point(7, 92);
|
||||
this.radioLocBR.Location = new System.Drawing.Point(105, 28);
|
||||
this.radioLocBR.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocBR.Name = "radioLocBR";
|
||||
this.radioLocBR.Size = new System.Drawing.Size(86, 17);
|
||||
this.radioLocBR.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocBR.TabIndex = 3;
|
||||
this.radioLocBR.TabStop = true;
|
||||
this.radioLocBR.Text = "Bottom Right";
|
||||
this.radioLocBR.UseVisualStyleBackColor = true;
|
||||
this.radioLocBR.CheckedChanged += new System.EventHandler(this.radioLoc_CheckedChanged);
|
||||
//
|
||||
// radioLocBL
|
||||
//
|
||||
this.radioLocBL.AutoSize = true;
|
||||
this.radioLocBL.Location = new System.Drawing.Point(7, 68);
|
||||
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(79, 17);
|
||||
this.radioLocBL.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocBL.TabIndex = 2;
|
||||
this.radioLocBL.TabStop = true;
|
||||
this.radioLocBL.Text = "Bottom Left";
|
||||
this.radioLocBL.UseVisualStyleBackColor = true;
|
||||
this.radioLocBL.CheckedChanged += new System.EventHandler(this.radioLoc_CheckedChanged);
|
||||
//
|
||||
// radioLocTR
|
||||
//
|
||||
this.radioLocTR.AutoSize = true;
|
||||
this.radioLocTR.Location = new System.Drawing.Point(7, 44);
|
||||
this.radioLocTR.Location = new System.Drawing.Point(105, 4);
|
||||
this.radioLocTR.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||
this.radioLocTR.Name = "radioLocTR";
|
||||
this.radioLocTR.Size = new System.Drawing.Size(72, 17);
|
||||
this.radioLocTR.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocTR.TabIndex = 1;
|
||||
this.radioLocTR.TabStop = true;
|
||||
this.radioLocTR.Text = "Top Right";
|
||||
this.radioLocTR.UseVisualStyleBackColor = true;
|
||||
this.radioLocTR.CheckedChanged += new System.EventHandler(this.radioLoc_CheckedChanged);
|
||||
//
|
||||
// radioLocTL
|
||||
//
|
||||
this.radioLocTL.AutoSize = true;
|
||||
this.radioLocTL.Location = new System.Drawing.Point(7, 20);
|
||||
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(65, 17);
|
||||
this.radioLocTL.Size = new System.Drawing.Size(92, 17);
|
||||
this.radioLocTL.TabIndex = 0;
|
||||
this.radioLocTL.TabStop = true;
|
||||
this.radioLocTL.Text = "Top Left";
|
||||
this.radioLocTL.UseVisualStyleBackColor = true;
|
||||
this.radioLocTL.CheckedChanged += new System.EventHandler(this.radioLoc_CheckedChanged);
|
||||
//
|
||||
// trackBarEdgeDistance
|
||||
//
|
||||
this.trackBarEdgeDistance.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.trackBarEdgeDistance.AutoSize = false;
|
||||
this.trackBarEdgeDistance.LargeChange = 8;
|
||||
this.trackBarEdgeDistance.Location = new System.Drawing.Point(6, 213);
|
||||
this.trackBarEdgeDistance.Location = new System.Drawing.Point(5, 128);
|
||||
this.trackBarEdgeDistance.Maximum = 40;
|
||||
this.trackBarEdgeDistance.Minimum = 8;
|
||||
this.trackBarEdgeDistance.Name = "trackBarEdgeDistance";
|
||||
this.trackBarEdgeDistance.Size = new System.Drawing.Size(141, 45);
|
||||
this.trackBarEdgeDistance.Size = new System.Drawing.Size(148, 30);
|
||||
this.trackBarEdgeDistance.SmallChange = 2;
|
||||
this.trackBarEdgeDistance.TabIndex = 5;
|
||||
this.trackBarEdgeDistance.TabIndex = 8;
|
||||
this.trackBarEdgeDistance.TickFrequency = 4;
|
||||
this.trackBarEdgeDistance.Value = 8;
|
||||
this.trackBarEdgeDistance.ValueChanged += new System.EventHandler(this.trackBarEdgeDistance_ValueChanged);
|
||||
//
|
||||
// groupNotificationDuration
|
||||
//
|
||||
this.groupNotificationDuration.Controls.Add(this.tableLayoutDurationButtons);
|
||||
this.groupNotificationDuration.Controls.Add(this.labelDurationValue);
|
||||
this.groupNotificationDuration.Controls.Add(this.trackBarDuration);
|
||||
this.groupNotificationDuration.Location = new System.Drawing.Point(9, 106);
|
||||
this.groupNotificationDuration.Name = "groupNotificationDuration";
|
||||
this.groupNotificationDuration.Size = new System.Drawing.Size(183, 89);
|
||||
this.groupNotificationDuration.TabIndex = 9;
|
||||
this.groupNotificationDuration.TabStop = false;
|
||||
this.groupNotificationDuration.Text = "Duration";
|
||||
//
|
||||
// tableLayoutDurationButtons
|
||||
//
|
||||
this.tableLayoutDurationButtons.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tableLayoutDurationButtons.ColumnCount = 3;
|
||||
this.tableLayoutDurationButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 32F));
|
||||
this.tableLayoutDurationButtons.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 36F));
|
||||
@@ -217,7 +191,7 @@
|
||||
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(6, 56);
|
||||
this.tableLayoutDurationButtons.Location = new System.Drawing.Point(3, 113);
|
||||
this.tableLayoutDurationButtons.Name = "tableLayoutDurationButtons";
|
||||
this.tableLayoutDurationButtons.RowCount = 1;
|
||||
this.tableLayoutDurationButtons.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
@@ -235,10 +209,9 @@
|
||||
this.btnDurationMedium.Margin = new System.Windows.Forms.Padding(1);
|
||||
this.btnDurationMedium.Name = "btnDurationMedium";
|
||||
this.btnDurationMedium.Size = new System.Drawing.Size(59, 25);
|
||||
this.btnDurationMedium.TabIndex = 2;
|
||||
this.btnDurationMedium.TabIndex = 1;
|
||||
this.btnDurationMedium.Text = "Medium";
|
||||
this.btnDurationMedium.UseVisualStyleBackColor = true;
|
||||
this.btnDurationMedium.Click += new System.EventHandler(this.btnDurationMedium_Click);
|
||||
//
|
||||
// btnDurationLong
|
||||
//
|
||||
@@ -251,10 +224,9 @@
|
||||
this.btnDurationLong.Margin = new System.Windows.Forms.Padding(1);
|
||||
this.btnDurationLong.Name = "btnDurationLong";
|
||||
this.btnDurationLong.Size = new System.Drawing.Size(54, 25);
|
||||
this.btnDurationLong.TabIndex = 1;
|
||||
this.btnDurationLong.TabIndex = 2;
|
||||
this.btnDurationLong.Text = "Long";
|
||||
this.btnDurationLong.UseVisualStyleBackColor = true;
|
||||
this.btnDurationLong.Click += new System.EventHandler(this.btnDurationLong_Click);
|
||||
//
|
||||
// btnDurationShort
|
||||
//
|
||||
@@ -270,111 +242,294 @@
|
||||
this.btnDurationShort.TabIndex = 0;
|
||||
this.btnDurationShort.Text = "Short";
|
||||
this.btnDurationShort.UseVisualStyleBackColor = true;
|
||||
this.btnDurationShort.Click += new System.EventHandler(this.btnDurationShort_Click);
|
||||
//
|
||||
// labelDurationValue
|
||||
//
|
||||
this.labelDurationValue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelDurationValue.BackColor = System.Drawing.Color.Transparent;
|
||||
this.labelDurationValue.Location = new System.Drawing.Point(129, 20);
|
||||
this.labelDurationValue.Location = new System.Drawing.Point(147, 77);
|
||||
this.labelDurationValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelDurationValue.Name = "labelDurationValue";
|
||||
this.labelDurationValue.Size = new System.Drawing.Size(48, 13);
|
||||
this.labelDurationValue.TabIndex = 13;
|
||||
this.labelDurationValue.TabIndex = 4;
|
||||
this.labelDurationValue.Text = "0 ms/c";
|
||||
this.labelDurationValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
this.toolTip.SetToolTip(this.labelDurationValue, "Milliseconds per character.");
|
||||
//
|
||||
// trackBarDuration
|
||||
//
|
||||
this.trackBarDuration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.trackBarDuration.Location = new System.Drawing.Point(6, 19);
|
||||
this.trackBarDuration.AutoSize = false;
|
||||
this.trackBarDuration.Location = new System.Drawing.Point(3, 76);
|
||||
this.trackBarDuration.Maximum = 60;
|
||||
this.trackBarDuration.Minimum = 10;
|
||||
this.trackBarDuration.Name = "trackBarDuration";
|
||||
this.trackBarDuration.Size = new System.Drawing.Size(128, 45);
|
||||
this.trackBarDuration.TabIndex = 12;
|
||||
this.trackBarDuration.Size = new System.Drawing.Size(148, 30);
|
||||
this.trackBarDuration.TabIndex = 3;
|
||||
this.trackBarDuration.TickFrequency = 5;
|
||||
this.trackBarDuration.Value = 25;
|
||||
this.trackBarDuration.ValueChanged += new System.EventHandler(this.trackBarDuration_ValueChanged);
|
||||
//
|
||||
// groupUserInterface
|
||||
// checkSkipOnLinkClick
|
||||
//
|
||||
this.groupUserInterface.Controls.Add(this.checkTimerCountDown);
|
||||
this.groupUserInterface.Controls.Add(this.checkLegacyLoad);
|
||||
this.groupUserInterface.Controls.Add(this.checkNotificationTimer);
|
||||
this.groupUserInterface.Location = new System.Drawing.Point(9, 9);
|
||||
this.groupUserInterface.Name = "groupUserInterface";
|
||||
this.groupUserInterface.Size = new System.Drawing.Size(183, 91);
|
||||
this.groupUserInterface.TabIndex = 10;
|
||||
this.groupUserInterface.TabStop = false;
|
||||
this.groupUserInterface.Text = "General";
|
||||
this.checkSkipOnLinkClick.AutoSize = true;
|
||||
this.checkSkipOnLinkClick.Location = new System.Drawing.Point(6, 28);
|
||||
this.checkSkipOnLinkClick.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkSkipOnLinkClick.Name = "checkSkipOnLinkClick";
|
||||
this.checkSkipOnLinkClick.Size = new System.Drawing.Size(113, 17);
|
||||
this.checkSkipOnLinkClick.TabIndex = 1;
|
||||
this.checkSkipOnLinkClick.Text = "Skip On Link Click";
|
||||
this.toolTip.SetToolTip(this.checkSkipOnLinkClick, "Skips current notification when a link\r\ninside the notification is clicked.");
|
||||
this.checkSkipOnLinkClick.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkColumnName
|
||||
//
|
||||
this.checkColumnName.AutoSize = true;
|
||||
this.checkColumnName.Location = new System.Drawing.Point(6, 5);
|
||||
this.checkColumnName.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkColumnName.Name = "checkColumnName";
|
||||
this.checkColumnName.Size = new System.Drawing.Size(129, 17);
|
||||
this.checkColumnName.TabIndex = 0;
|
||||
this.checkColumnName.Text = "Display Column Name";
|
||||
this.toolTip.SetToolTip(this.checkColumnName, "Shows column name each notification originated\r\nfrom in the notification window t" +
|
||||
"itle.");
|
||||
this.checkColumnName.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// labelIdlePause
|
||||
//
|
||||
this.labelIdlePause.AutoSize = true;
|
||||
this.labelIdlePause.Location = new System.Drawing.Point(3, 60);
|
||||
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.TabIndex = 2;
|
||||
this.labelIdlePause.Text = "Pause When Idle";
|
||||
//
|
||||
// comboBoxIdlePause
|
||||
//
|
||||
this.comboBoxIdlePause.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxIdlePause.FormattingEnabled = true;
|
||||
this.comboBoxIdlePause.Location = new System.Drawing.Point(5, 76);
|
||||
this.comboBoxIdlePause.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxIdlePause.Name = "comboBoxIdlePause";
|
||||
this.comboBoxIdlePause.Size = new System.Drawing.Size(144, 21);
|
||||
this.comboBoxIdlePause.TabIndex = 3;
|
||||
this.toolTip.SetToolTip(this.comboBoxIdlePause, "Pauses new notifications after going idle for a set amount of time.");
|
||||
//
|
||||
// checkNonIntrusive
|
||||
//
|
||||
this.checkNonIntrusive.AutoSize = true;
|
||||
this.checkNonIntrusive.Location = new System.Drawing.Point(6, 5);
|
||||
this.checkNonIntrusive.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkNonIntrusive.Name = "checkNonIntrusive";
|
||||
this.checkNonIntrusive.Size = new System.Drawing.Size(128, 17);
|
||||
this.checkNonIntrusive.TabIndex = 0;
|
||||
this.checkNonIntrusive.Text = "Non-Intrusive Popups";
|
||||
this.toolTip.SetToolTip(this.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.");
|
||||
this.checkNonIntrusive.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkTimerCountDown
|
||||
//
|
||||
this.checkTimerCountDown.AutoSize = true;
|
||||
this.checkTimerCountDown.Location = new System.Drawing.Point(6, 44);
|
||||
this.checkTimerCountDown.Location = new System.Drawing.Point(6, 28);
|
||||
this.checkTimerCountDown.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
|
||||
this.checkTimerCountDown.Name = "checkTimerCountDown";
|
||||
this.checkTimerCountDown.Size = new System.Drawing.Size(119, 17);
|
||||
this.checkTimerCountDown.TabIndex = 6;
|
||||
this.checkTimerCountDown.TabIndex = 1;
|
||||
this.checkTimerCountDown.Text = "Timer Counts Down";
|
||||
this.toolTip.SetToolTip(this.checkTimerCountDown, "The notification timer counts down instead of up.");
|
||||
this.checkTimerCountDown.UseVisualStyleBackColor = true;
|
||||
this.checkTimerCountDown.CheckedChanged += new System.EventHandler(this.checkTimerCountDown_CheckedChanged);
|
||||
//
|
||||
// checkLegacyLoad
|
||||
//
|
||||
this.checkLegacyLoad.AutoSize = true;
|
||||
this.checkLegacyLoad.Location = new System.Drawing.Point(6, 67);
|
||||
this.checkLegacyLoad.Name = "checkLegacyLoad";
|
||||
this.checkLegacyLoad.Size = new System.Drawing.Size(139, 17);
|
||||
this.checkLegacyLoad.TabIndex = 5;
|
||||
this.checkLegacyLoad.Text = "Legacy Loading System";
|
||||
this.toolTip.SetToolTip(this.checkLegacyLoad, "Try enabling if notifications do not display.\r\nMight cause delays and visual arti" +
|
||||
"facts.");
|
||||
this.checkLegacyLoad.UseVisualStyleBackColor = true;
|
||||
this.checkLegacyLoad.CheckedChanged += new System.EventHandler(this.checkLegacyLoad_CheckedChanged);
|
||||
//
|
||||
// checkNotificationTimer
|
||||
//
|
||||
this.checkNotificationTimer.AutoSize = true;
|
||||
this.checkNotificationTimer.Location = new System.Drawing.Point(6, 21);
|
||||
this.checkNotificationTimer.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.checkNotificationTimer.Location = new System.Drawing.Point(6, 5);
|
||||
this.checkNotificationTimer.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3);
|
||||
this.checkNotificationTimer.Name = "checkNotificationTimer";
|
||||
this.checkNotificationTimer.Size = new System.Drawing.Size(145, 17);
|
||||
this.checkNotificationTimer.TabIndex = 4;
|
||||
this.checkNotificationTimer.TabIndex = 0;
|
||||
this.checkNotificationTimer.Text = "Display Notification Timer";
|
||||
this.toolTip.SetToolTip(this.checkNotificationTimer, "Shows how much time is left before the current notification disappears.");
|
||||
this.checkNotificationTimer.UseVisualStyleBackColor = true;
|
||||
this.checkNotificationTimer.CheckedChanged += new System.EventHandler(this.checkNotificationTimer_CheckedChanged);
|
||||
//
|
||||
// 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.Location = new System.Drawing.Point(6, 8);
|
||||
this.labelGeneral.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
this.labelGeneral.Name = "labelGeneral";
|
||||
this.labelGeneral.Size = new System.Drawing.Size(66, 20);
|
||||
this.labelGeneral.TabIndex = 0;
|
||||
this.labelGeneral.Text = "General";
|
||||
//
|
||||
// panelGeneral
|
||||
//
|
||||
this.panelGeneral.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelGeneral.Controls.Add(this.checkColumnName);
|
||||
this.panelGeneral.Controls.Add(this.checkSkipOnLinkClick);
|
||||
this.panelGeneral.Controls.Add(this.labelIdlePause);
|
||||
this.panelGeneral.Controls.Add(this.comboBoxIdlePause);
|
||||
this.panelGeneral.Location = new System.Drawing.Point(9, 31);
|
||||
this.panelGeneral.Name = "panelGeneral";
|
||||
this.panelGeneral.Size = new System.Drawing.Size(322, 103);
|
||||
this.panelGeneral.TabIndex = 1;
|
||||
//
|
||||
// labelScrollSpeedValue
|
||||
//
|
||||
this.labelScrollSpeedValue.Location = new System.Drawing.Point(147, 54);
|
||||
this.labelScrollSpeedValue.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.labelScrollSpeedValue.Name = "labelScrollSpeedValue";
|
||||
this.labelScrollSpeedValue.Size = new System.Drawing.Size(34, 13);
|
||||
this.labelScrollSpeedValue.TabIndex = 3;
|
||||
this.labelScrollSpeedValue.Text = "100%";
|
||||
this.labelScrollSpeedValue.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// trackBarScrollSpeed
|
||||
//
|
||||
this.trackBarScrollSpeed.AutoSize = false;
|
||||
this.trackBarScrollSpeed.LargeChange = 25;
|
||||
this.trackBarScrollSpeed.Location = new System.Drawing.Point(5, 53);
|
||||
this.trackBarScrollSpeed.Maximum = 200;
|
||||
this.trackBarScrollSpeed.Minimum = 25;
|
||||
this.trackBarScrollSpeed.Name = "trackBarScrollSpeed";
|
||||
this.trackBarScrollSpeed.Size = new System.Drawing.Size(148, 30);
|
||||
this.trackBarScrollSpeed.SmallChange = 25;
|
||||
this.trackBarScrollSpeed.TabIndex = 2;
|
||||
this.trackBarScrollSpeed.TickFrequency = 25;
|
||||
this.trackBarScrollSpeed.Value = 100;
|
||||
//
|
||||
// labelScrollSpeed
|
||||
//
|
||||
this.labelScrollSpeed.AutoSize = true;
|
||||
this.labelScrollSpeed.Location = new System.Drawing.Point(3, 37);
|
||||
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 = 1;
|
||||
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(6, 158);
|
||||
this.labelLocation.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelLocation.Name = "labelLocation";
|
||||
this.labelLocation.Size = new System.Drawing.Size(70, 20);
|
||||
this.labelLocation.TabIndex = 2;
|
||||
this.labelLocation.Text = "Location";
|
||||
//
|
||||
// panelLocation
|
||||
//
|
||||
this.panelLocation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelLocation.Controls.Add(this.labelEdgeDistanceValue);
|
||||
this.panelLocation.Controls.Add(this.radioLocTL);
|
||||
this.panelLocation.Controls.Add(this.labelDisplay);
|
||||
this.panelLocation.Controls.Add(this.trackBarEdgeDistance);
|
||||
this.panelLocation.Controls.Add(this.comboBoxDisplay);
|
||||
this.panelLocation.Controls.Add(this.radioLocTR);
|
||||
this.panelLocation.Controls.Add(this.labelEdgeDistance);
|
||||
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(9, 181);
|
||||
this.panelLocation.Name = "panelLocation";
|
||||
this.panelLocation.Size = new System.Drawing.Size(322, 165);
|
||||
this.panelLocation.TabIndex = 3;
|
||||
//
|
||||
// panelTimer
|
||||
//
|
||||
this.panelTimer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelTimer.Controls.Add(this.labelDuration);
|
||||
this.panelTimer.Controls.Add(this.checkNotificationTimer);
|
||||
this.panelTimer.Controls.Add(this.tableLayoutDurationButtons);
|
||||
this.panelTimer.Controls.Add(this.checkTimerCountDown);
|
||||
this.panelTimer.Controls.Add(this.labelDurationValue);
|
||||
this.panelTimer.Controls.Add(this.trackBarDuration);
|
||||
this.panelTimer.Location = new System.Drawing.Point(9, 393);
|
||||
this.panelTimer.Name = "panelTimer";
|
||||
this.panelTimer.Size = new System.Drawing.Size(322, 144);
|
||||
this.panelTimer.TabIndex = 5;
|
||||
//
|
||||
// labelDuration
|
||||
//
|
||||
this.labelDuration.AutoSize = true;
|
||||
this.labelDuration.Location = new System.Drawing.Point(3, 60);
|
||||
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.TabIndex = 2;
|
||||
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(6, 370);
|
||||
this.labelTimer.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelTimer.Name = "labelTimer";
|
||||
this.labelTimer.Size = new System.Drawing.Size(48, 20);
|
||||
this.labelTimer.TabIndex = 4;
|
||||
this.labelTimer.Text = "Timer";
|
||||
//
|
||||
// labelMiscellaneous
|
||||
//
|
||||
this.labelMiscellaneous.AutoSize = true;
|
||||
this.labelMiscellaneous.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelMiscellaneous.Location = new System.Drawing.Point(6, 561);
|
||||
this.labelMiscellaneous.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0);
|
||||
this.labelMiscellaneous.Name = "labelMiscellaneous";
|
||||
this.labelMiscellaneous.Size = new System.Drawing.Size(109, 20);
|
||||
this.labelMiscellaneous.TabIndex = 6;
|
||||
this.labelMiscellaneous.Text = "Miscellaneous";
|
||||
//
|
||||
// panelMiscellaneous
|
||||
//
|
||||
this.panelMiscellaneous.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelMiscellaneous.Controls.Add(this.labelScrollSpeedValue);
|
||||
this.panelMiscellaneous.Controls.Add(this.trackBarScrollSpeed);
|
||||
this.panelMiscellaneous.Controls.Add(this.checkNonIntrusive);
|
||||
this.panelMiscellaneous.Controls.Add(this.labelScrollSpeed);
|
||||
this.panelMiscellaneous.Location = new System.Drawing.Point(9, 584);
|
||||
this.panelMiscellaneous.Name = "panelMiscellaneous";
|
||||
this.panelMiscellaneous.Size = new System.Drawing.Size(322, 90);
|
||||
this.panelMiscellaneous.TabIndex = 7;
|
||||
//
|
||||
// TabSettingsNotifications
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.groupUserInterface);
|
||||
this.Controls.Add(this.groupNotificationDuration);
|
||||
this.Controls.Add(this.groupNotificationLocation);
|
||||
this.Controls.Add(this.panelMiscellaneous);
|
||||
this.Controls.Add(this.labelMiscellaneous);
|
||||
this.Controls.Add(this.labelTimer);
|
||||
this.Controls.Add(this.panelLocation);
|
||||
this.Controls.Add(this.labelLocation);
|
||||
this.Controls.Add(this.panelGeneral);
|
||||
this.Controls.Add(this.labelGeneral);
|
||||
this.Controls.Add(this.panelTimer);
|
||||
this.Name = "TabSettingsNotifications";
|
||||
this.Size = new System.Drawing.Size(478, 282);
|
||||
this.Size = new System.Drawing.Size(340, 684);
|
||||
this.ParentChanged += new System.EventHandler(this.TabSettingsNotifications_ParentChanged);
|
||||
this.groupNotificationLocation.ResumeLayout(false);
|
||||
this.groupNotificationLocation.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarEdgeDistance)).EndInit();
|
||||
this.groupNotificationDuration.ResumeLayout(false);
|
||||
this.groupNotificationDuration.PerformLayout();
|
||||
this.tableLayoutDurationButtons.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarDuration)).EndInit();
|
||||
this.groupUserInterface.ResumeLayout(false);
|
||||
this.groupUserInterface.PerformLayout();
|
||||
this.panelGeneral.ResumeLayout(false);
|
||||
this.panelGeneral.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarScrollSpeed)).EndInit();
|
||||
this.panelLocation.ResumeLayout(false);
|
||||
this.panelLocation.PerformLayout();
|
||||
this.panelTimer.ResumeLayout(false);
|
||||
this.panelTimer.PerformLayout();
|
||||
this.panelMiscellaneous.ResumeLayout(false);
|
||||
this.panelMiscellaneous.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox groupNotificationLocation;
|
||||
private System.Windows.Forms.Label labelDisplay;
|
||||
private System.Windows.Forms.ComboBox comboBoxDisplay;
|
||||
private System.Windows.Forms.Label labelEdgeDistance;
|
||||
@@ -384,18 +539,32 @@
|
||||
private System.Windows.Forms.RadioButton radioLocBL;
|
||||
private System.Windows.Forms.RadioButton radioLocTR;
|
||||
private System.Windows.Forms.RadioButton radioLocTL;
|
||||
private System.Windows.Forms.GroupBox groupNotificationDuration;
|
||||
private System.Windows.Forms.GroupBox groupUserInterface;
|
||||
private System.Windows.Forms.CheckBox checkNotificationTimer;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.Label labelEdgeDistanceValue;
|
||||
private System.Windows.Forms.CheckBox checkLegacyLoad;
|
||||
private System.Windows.Forms.CheckBox checkTimerCountDown;
|
||||
private System.Windows.Forms.Label labelDurationValue;
|
||||
private System.Windows.Forms.TrackBar trackBarDuration;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutDurationButtons;
|
||||
private TweetDck.Core.Controls.FlatButton btnDurationMedium;
|
||||
private TweetDck.Core.Controls.FlatButton btnDurationLong;
|
||||
private TweetDck.Core.Controls.FlatButton btnDurationShort;
|
||||
private TweetDuck.Core.Controls.FlatButton btnDurationMedium;
|
||||
private TweetDuck.Core.Controls.FlatButton btnDurationLong;
|
||||
private TweetDuck.Core.Controls.FlatButton btnDurationShort;
|
||||
private System.Windows.Forms.CheckBox checkNonIntrusive;
|
||||
private System.Windows.Forms.Label labelIdlePause;
|
||||
private System.Windows.Forms.ComboBox comboBoxIdlePause;
|
||||
private System.Windows.Forms.CheckBox checkColumnName;
|
||||
private System.Windows.Forms.CheckBox checkSkipOnLinkClick;
|
||||
private System.Windows.Forms.CheckBox checkTimerCountDown;
|
||||
private System.Windows.Forms.CheckBox checkNotificationTimer;
|
||||
private System.Windows.Forms.Label labelGeneral;
|
||||
private System.Windows.Forms.Panel panelGeneral;
|
||||
private System.Windows.Forms.Label labelLocation;
|
||||
private System.Windows.Forms.Panel panelLocation;
|
||||
private System.Windows.Forms.Panel panelTimer;
|
||||
private System.Windows.Forms.Label labelTimer;
|
||||
private System.Windows.Forms.Label labelScrollSpeedValue;
|
||||
private System.Windows.Forms.TrackBar trackBarScrollSpeed;
|
||||
private System.Windows.Forms.Label labelScrollSpeed;
|
||||
private System.Windows.Forms.Label labelMiscellaneous;
|
||||
private System.Windows.Forms.Panel panelMiscellaneous;
|
||||
private System.Windows.Forms.Label labelDuration;
|
||||
}
|
||||
}
|
||||
|
@@ -1,30 +1,33 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Handling;
|
||||
using TweetDck.Core.Controls;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Notification;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings{
|
||||
namespace TweetDuck.Core.Other.Settings{
|
||||
partial class TabSettingsNotifications : BaseTabSettings{
|
||||
private readonly FormNotification notification;
|
||||
private static readonly int[] IdlePauseSeconds = { 0, 30, 60, 120, 300 };
|
||||
|
||||
public TabSettingsNotifications(FormNotification notification){
|
||||
private readonly FormNotificationMain notification;
|
||||
|
||||
public TabSettingsNotifications(FormNotificationMain notification){
|
||||
InitializeComponent();
|
||||
|
||||
this.notification = notification;
|
||||
this.notification.CanMoveWindow = () => radioLocCustom.Checked;
|
||||
|
||||
this.notification.Move += (sender, args) => {
|
||||
if (radioLocCustom.Checked){
|
||||
if (radioLocCustom.Checked && this.notification.Location != ControlExtensions.InvisibleLocation){
|
||||
Config.CustomNotificationPosition = this.notification.Location;
|
||||
}
|
||||
};
|
||||
|
||||
this.notification.Initialized += (sender, args) => {
|
||||
this.InvokeSafe(() => this.notification.ShowNotificationForSettings(true));
|
||||
this.InvokeAsyncSafe(() => this.notification.ShowNotificationForSettings(true));
|
||||
};
|
||||
|
||||
this.notification.Show(this);
|
||||
this.notification.Activated += notification_Activated;
|
||||
this.notification.Show();
|
||||
|
||||
switch(Config.NotificationPosition){
|
||||
case TweetNotification.Position.TopLeft: radioLocTL.Checked = true; break;
|
||||
@@ -34,21 +37,36 @@ namespace TweetDck.Core.Other.Settings{
|
||||
case TweetNotification.Position.Custom: radioLocCustom.Checked = true; break;
|
||||
}
|
||||
|
||||
comboBoxDisplay.Enabled = trackBarEdgeDistance.Enabled = !radioLocCustom.Checked;
|
||||
|
||||
toolTip.SetToolTip(trackBarDuration, toolTip.GetToolTip(labelDurationValue));
|
||||
trackBarDuration.SetValueSafe(Config.NotificationDurationValue);
|
||||
labelDurationValue.Text = Config.NotificationDurationValue+" ms/c";
|
||||
|
||||
comboBoxIdlePause.Items.Add("Disabled");
|
||||
comboBoxIdlePause.Items.Add("30 seconds");
|
||||
comboBoxIdlePause.Items.Add("1 minute");
|
||||
comboBoxIdlePause.Items.Add("2 minutes");
|
||||
comboBoxIdlePause.Items.Add("5 minutes");
|
||||
comboBoxIdlePause.SelectedIndex = Math.Max(0, Array.FindIndex(IdlePauseSeconds, val => val == Config.NotificationIdlePauseSeconds));
|
||||
|
||||
comboBoxDisplay.Items.Add("(Same As "+Program.BrandName+")");
|
||||
|
||||
foreach(Screen screen in Screen.AllScreens){
|
||||
comboBoxDisplay.Items.Add(screen.DeviceName+" ("+screen.Bounds.Width+"x"+screen.Bounds.Height+")");
|
||||
comboBoxDisplay.Items.Add(screen.DeviceName.TrimStart('\\', '.')+" ("+screen.Bounds.Width+"x"+screen.Bounds.Height+")");
|
||||
}
|
||||
|
||||
comboBoxDisplay.SelectedIndex = Math.Min(comboBoxDisplay.Items.Count-1, Config.NotificationDisplay);
|
||||
|
||||
|
||||
checkColumnName.Checked = Config.DisplayNotificationColumn;
|
||||
checkNotificationTimer.Checked = Config.DisplayNotificationTimer;
|
||||
checkTimerCountDown.Enabled = checkNotificationTimer.Checked;
|
||||
checkTimerCountDown.Checked = Config.NotificationTimerCountDown;
|
||||
checkLegacyLoad.Checked = Config.NotificationLegacyLoad;
|
||||
checkSkipOnLinkClick.Checked = Config.NotificationSkipOnLinkClick;
|
||||
checkNonIntrusive.Checked = Config.NotificationNonIntrusiveMode;
|
||||
|
||||
trackBarScrollSpeed.SetValueSafe(Config.NotificationScrollSpeed);
|
||||
labelScrollSpeedValue.Text = trackBarScrollSpeed.Value.ToString(CultureInfo.InvariantCulture)+"%";
|
||||
|
||||
trackBarEdgeDistance.SetValueSafe(Config.NotificationEdgeDistance);
|
||||
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value.ToString(CultureInfo.InvariantCulture)+" px";
|
||||
@@ -56,6 +74,31 @@ namespace TweetDck.Core.Other.Settings{
|
||||
Disposed += (sender, args) => this.notification.Dispose();
|
||||
}
|
||||
|
||||
public override void OnReady(){
|
||||
radioLocTL.CheckedChanged += radioLoc_CheckedChanged;
|
||||
radioLocTR.CheckedChanged += radioLoc_CheckedChanged;
|
||||
radioLocBL.CheckedChanged += radioLoc_CheckedChanged;
|
||||
radioLocBR.CheckedChanged += radioLoc_CheckedChanged;
|
||||
radioLocCustom.Click += radioLocCustom_Click;
|
||||
|
||||
trackBarDuration.ValueChanged += trackBarDuration_ValueChanged;
|
||||
btnDurationShort.Click += btnDurationShort_Click;
|
||||
btnDurationMedium.Click += btnDurationMedium_Click;
|
||||
btnDurationLong.Click += btnDurationLong_Click;
|
||||
|
||||
checkColumnName.CheckedChanged += checkColumnName_CheckedChanged;
|
||||
checkNotificationTimer.CheckedChanged += checkNotificationTimer_CheckedChanged;
|
||||
checkTimerCountDown.CheckedChanged += checkTimerCountDown_CheckedChanged;
|
||||
checkSkipOnLinkClick.CheckedChanged += checkSkipOnLinkClick_CheckedChanged;
|
||||
checkNonIntrusive.CheckedChanged += checkNonIntrusive_CheckedChanged;
|
||||
|
||||
comboBoxIdlePause.SelectedValueChanged += comboBoxIdlePause_SelectedValueChanged;
|
||||
trackBarScrollSpeed.ValueChanged += trackBarScrollSpeed_ValueChanged;
|
||||
|
||||
comboBoxDisplay.SelectedValueChanged += comboBoxDisplay_SelectedValueChanged;
|
||||
trackBarEdgeDistance.ValueChanged += trackBarEdgeDistance_ValueChanged;
|
||||
}
|
||||
|
||||
private void TabSettingsNotifications_ParentChanged(object sender, EventArgs e){
|
||||
if (Parent == null){
|
||||
notification.HideNotification(false);
|
||||
@@ -65,28 +108,43 @@ namespace TweetDck.Core.Other.Settings{
|
||||
}
|
||||
}
|
||||
|
||||
private void radioLoc_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
private void notification_Activated(object sender, EventArgs e){
|
||||
notification.Hide();
|
||||
notification.Activated -= notification_Activated;
|
||||
}
|
||||
|
||||
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;
|
||||
else if (radioLocBL.Checked)Config.NotificationPosition = TweetNotification.Position.BottomLeft;
|
||||
else if (radioLocBR.Checked)Config.NotificationPosition = TweetNotification.Position.BottomRight;
|
||||
else if (radioLocCustom.Checked){
|
||||
if (!Config.IsCustomNotificationPositionSet){
|
||||
Config.CustomNotificationPosition = notification.Location;
|
||||
}
|
||||
|
||||
Config.NotificationPosition = TweetNotification.Position.Custom;
|
||||
}
|
||||
|
||||
comboBoxDisplay.Enabled = trackBarEdgeDistance.Enabled = !radioLocCustom.Checked;
|
||||
comboBoxDisplay.Enabled = trackBarEdgeDistance.Enabled = true;
|
||||
notification.ShowNotificationForSettings(false);
|
||||
}
|
||||
|
||||
private void radioLocCustom_Click(object sender, EventArgs e){
|
||||
if (!Config.IsCustomNotificationPositionSet){
|
||||
Config.CustomNotificationPosition = notification.Location;
|
||||
}
|
||||
|
||||
Config.NotificationPosition = TweetNotification.Position.Custom;
|
||||
|
||||
comboBoxDisplay.Enabled = trackBarEdgeDistance.Enabled = false;
|
||||
notification.ShowNotificationForSettings(false);
|
||||
|
||||
if (notification.IsFullyOutsideView() && MessageBox.Show("The notification seems to be outside of view, would you like to reset its position?", "Notification is outside view", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
Config.NotificationPosition = TweetNotification.Position.TopRight;
|
||||
notification.MoveToVisibleLocation();
|
||||
|
||||
Config.CustomNotificationPosition = notification.Location;
|
||||
|
||||
Config.NotificationPosition = TweetNotification.Position.Custom;
|
||||
notification.MoveToVisibleLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private void trackBarDuration_ValueChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.NotificationDurationValue = trackBarDuration.Value;
|
||||
labelDurationValue.Text = Config.NotificationDurationValue+" ms/c";
|
||||
|
||||
@@ -94,54 +152,58 @@ namespace TweetDck.Core.Other.Settings{
|
||||
}
|
||||
|
||||
private void btnDurationShort_Click(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
trackBarDuration.Value = 15;
|
||||
}
|
||||
|
||||
private void btnDurationMedium_Click(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
trackBarDuration.Value = 25;
|
||||
}
|
||||
|
||||
private void btnDurationLong_Click(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
trackBarDuration.Value = 35;
|
||||
}
|
||||
|
||||
private void checkNotificationTimer_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
private void checkColumnName_CheckedChanged(object sender, EventArgs e){
|
||||
Config.DisplayNotificationColumn = checkColumnName.Checked;
|
||||
notification.ShowNotificationForSettings(false);
|
||||
}
|
||||
|
||||
private void checkNotificationTimer_CheckedChanged(object sender, EventArgs e){
|
||||
Config.DisplayNotificationTimer = checkNotificationTimer.Checked;
|
||||
checkTimerCountDown.Enabled = checkNotificationTimer.Checked;
|
||||
notification.ShowNotificationForSettings(true);
|
||||
}
|
||||
|
||||
private void checkTimerCountDown_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.NotificationTimerCountDown = checkTimerCountDown.Checked;
|
||||
notification.ShowNotificationForSettings(true);
|
||||
}
|
||||
|
||||
private void checkLegacyLoad_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
private void checkSkipOnLinkClick_CheckedChanged(object sender, EventArgs e){
|
||||
Config.NotificationSkipOnLinkClick = checkSkipOnLinkClick.Checked;
|
||||
}
|
||||
|
||||
Config.NotificationLegacyLoad = checkLegacyLoad.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.ToString(CultureInfo.InvariantCulture)+"%";
|
||||
Config.NotificationScrollSpeed = trackBarScrollSpeed.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void comboBoxDisplay_SelectedValueChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.NotificationDisplay = comboBoxDisplay.SelectedIndex;
|
||||
notification.ShowNotificationForSettings(false);
|
||||
}
|
||||
|
||||
private void trackBarEdgeDistance_ValueChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value.ToString(CultureInfo.InvariantCulture)+" px";
|
||||
Config.NotificationEdgeDistance = trackBarEdgeDistance.Value;
|
||||
notification.ShowNotificationForSettings(false);
|
||||
|
130
Core/Other/Settings/TabSettingsSounds.Designer.cs
generated
Normal file
130
Core/Other/Settings/TabSettingsSounds.Designer.cs
generated
Normal file
@@ -0,0 +1,130 @@
|
||||
namespace TweetDuck.Core.Other.Settings {
|
||||
partial class TabSettingsSounds {
|
||||
/// <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.btnPlaySound = new System.Windows.Forms.Button();
|
||||
this.btnResetSound = new System.Windows.Forms.Button();
|
||||
this.btnBrowseSound = new System.Windows.Forms.Button();
|
||||
this.tbCustomSound = new System.Windows.Forms.TextBox();
|
||||
this.labelSoundNotification = new System.Windows.Forms.Label();
|
||||
this.panelSoundNotification = new System.Windows.Forms.Panel();
|
||||
this.panelSoundNotification.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnPlaySound
|
||||
//
|
||||
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.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.TabIndex = 2;
|
||||
this.btnPlaySound.Text = "Play";
|
||||
this.btnPlaySound.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnResetSound
|
||||
//
|
||||
this.btnResetSound.AutoSize = true;
|
||||
this.btnResetSound.Location = new System.Drawing.Point(3, 29);
|
||||
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.TabIndex = 3;
|
||||
this.btnResetSound.Text = "Reset";
|
||||
this.btnResetSound.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnBrowseSound
|
||||
//
|
||||
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.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.TabIndex = 1;
|
||||
this.btnBrowseSound.Text = "Browse...";
|
||||
this.btnBrowseSound.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tbCustomSound
|
||||
//
|
||||
this.tbCustomSound.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tbCustomSound.Location = new System.Drawing.Point(3, 3);
|
||||
this.tbCustomSound.Name = "tbCustomSound";
|
||||
this.tbCustomSound.Size = new System.Drawing.Size(316, 20);
|
||||
this.tbCustomSound.TabIndex = 0;
|
||||
//
|
||||
// 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.Location = new System.Drawing.Point(6, 8);
|
||||
this.labelSoundNotification.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
this.labelSoundNotification.Name = "labelSoundNotification";
|
||||
this.labelSoundNotification.Size = new System.Drawing.Size(198, 20);
|
||||
this.labelSoundNotification.TabIndex = 1;
|
||||
this.labelSoundNotification.Text = "Custom Sound Notification";
|
||||
//
|
||||
// panelSoundNotification
|
||||
//
|
||||
this.panelSoundNotification.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelSoundNotification.Controls.Add(this.btnPlaySound);
|
||||
this.panelSoundNotification.Controls.Add(this.tbCustomSound);
|
||||
this.panelSoundNotification.Controls.Add(this.btnResetSound);
|
||||
this.panelSoundNotification.Controls.Add(this.btnBrowseSound);
|
||||
this.panelSoundNotification.Location = new System.Drawing.Point(9, 31);
|
||||
this.panelSoundNotification.Name = "panelSoundNotification";
|
||||
this.panelSoundNotification.Size = new System.Drawing.Size(322, 56);
|
||||
this.panelSoundNotification.TabIndex = 2;
|
||||
//
|
||||
// TabSettingsSounds
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.panelSoundNotification);
|
||||
this.Controls.Add(this.labelSoundNotification);
|
||||
this.Name = "TabSettingsSounds";
|
||||
this.Size = new System.Drawing.Size(340, 97);
|
||||
this.panelSoundNotification.ResumeLayout(false);
|
||||
this.panelSoundNotification.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.Button btnResetSound;
|
||||
private System.Windows.Forms.Button btnBrowseSound;
|
||||
private System.Windows.Forms.TextBox tbCustomSound;
|
||||
private System.Windows.Forms.Button btnPlaySound;
|
||||
private System.Windows.Forms.Label labelSoundNotification;
|
||||
private System.Windows.Forms.Panel panelSoundNotification;
|
||||
}
|
||||
}
|
67
Core/Other/Settings/TabSettingsSounds.cs
Normal file
67
Core/Other/Settings/TabSettingsSounds.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetLib.Audio.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Other.Settings{
|
||||
partial class TabSettingsSounds : BaseTabSettings{
|
||||
private readonly SoundNotification soundNotification;
|
||||
|
||||
public TabSettingsSounds(){
|
||||
InitializeComponent();
|
||||
|
||||
soundNotification = new SoundNotification();
|
||||
soundNotification.PlaybackError += sound_PlaybackError;
|
||||
|
||||
tbCustomSound.Text = Config.NotificationSoundPath;
|
||||
tbCustomSound_TextChanged(tbCustomSound, new EventArgs());
|
||||
|
||||
Disposed += (sender, args) => soundNotification.Dispose();
|
||||
}
|
||||
|
||||
public override void OnReady(){
|
||||
tbCustomSound.TextChanged += tbCustomSound_TextChanged;
|
||||
btnPlaySound.Click += btnPlaySound_Click;
|
||||
btnBrowseSound.Click += btnBrowseSound_Click;
|
||||
btnResetSound.Click += btnResetSound_Click;
|
||||
}
|
||||
|
||||
public override void OnClosing(){
|
||||
Config.NotificationSoundPath = tbCustomSound.Text;
|
||||
}
|
||||
|
||||
private void tbCustomSound_TextChanged(object sender, EventArgs e){
|
||||
bool isEmpty = string.IsNullOrEmpty(tbCustomSound.Text);
|
||||
tbCustomSound.ForeColor = isEmpty || File.Exists(tbCustomSound.Text) ? SystemColors.WindowText : Color.Maroon;
|
||||
btnPlaySound.Enabled = !isEmpty;
|
||||
btnResetSound.Enabled = !isEmpty;
|
||||
}
|
||||
|
||||
private void btnPlaySound_Click(object sender, EventArgs e){
|
||||
soundNotification.Play(tbCustomSound.Text);
|
||||
}
|
||||
|
||||
private void sound_PlaybackError(object sender, PlaybackErrorEventArgs e){
|
||||
MessageBox.Show("Could not play custom notification sound."+Environment.NewLine+e.Message, "Notification Sound Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
private void btnBrowseSound_Click(object sender, EventArgs e){
|
||||
using(OpenFileDialog dialog = new OpenFileDialog{
|
||||
AutoUpgradeEnabled = true,
|
||||
DereferenceLinks = true,
|
||||
Title = "Custom Notification Sound",
|
||||
Filter = "Sound file ("+soundNotification.SupportedFormats+")|"+soundNotification.SupportedFormats+"|All files (*.*)|*.*"
|
||||
}){
|
||||
if (dialog.ShowDialog() == DialogResult.OK){
|
||||
tbCustomSound.Text = dialog.FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnResetSound_Click(object sender, EventArgs e){
|
||||
tbCustomSound.Text = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
90
Core/Other/Settings/TabSettingsUpdates.Designer.cs
generated
90
Core/Other/Settings/TabSettingsUpdates.Designer.cs
generated
@@ -1,90 +0,0 @@
|
||||
namespace TweetDck.Core.Other.Settings {
|
||||
partial class TabSettingsUpdates {
|
||||
/// <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.btnCheckUpdates = new System.Windows.Forms.Button();
|
||||
this.checkUpdateNotifications = new System.Windows.Forms.CheckBox();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.groupGeneral = new System.Windows.Forms.GroupBox();
|
||||
this.groupGeneral.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// btnCheckUpdates
|
||||
//
|
||||
this.btnCheckUpdates.Location = new System.Drawing.Point(6, 44);
|
||||
this.btnCheckUpdates.Name = "btnCheckUpdates";
|
||||
this.btnCheckUpdates.Size = new System.Drawing.Size(171, 23);
|
||||
this.btnCheckUpdates.TabIndex = 15;
|
||||
this.btnCheckUpdates.Text = "Check Updates Now";
|
||||
this.toolTip.SetToolTip(this.btnCheckUpdates, "Forces an update check, even for updates that had been dismissed.");
|
||||
this.btnCheckUpdates.UseVisualStyleBackColor = true;
|
||||
this.btnCheckUpdates.Click += new System.EventHandler(this.btnCheckUpdates_Click);
|
||||
//
|
||||
// checkUpdateNotifications
|
||||
//
|
||||
this.checkUpdateNotifications.AutoSize = true;
|
||||
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 21);
|
||||
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.checkUpdateNotifications.Name = "checkUpdateNotifications";
|
||||
this.checkUpdateNotifications.Size = new System.Drawing.Size(165, 17);
|
||||
this.checkUpdateNotifications.TabIndex = 14;
|
||||
this.checkUpdateNotifications.Text = "Check Updates Automatically";
|
||||
this.toolTip.SetToolTip(this.checkUpdateNotifications, "Checks for updates every hour.\r\nIf an update is dismissed, it will not appear aga" +
|
||||
"in.");
|
||||
this.checkUpdateNotifications.UseVisualStyleBackColor = true;
|
||||
this.checkUpdateNotifications.CheckedChanged += new System.EventHandler(this.checkUpdateNotifications_CheckedChanged);
|
||||
//
|
||||
// groupGeneral
|
||||
//
|
||||
this.groupGeneral.Controls.Add(this.checkUpdateNotifications);
|
||||
this.groupGeneral.Controls.Add(this.btnCheckUpdates);
|
||||
this.groupGeneral.Location = new System.Drawing.Point(9, 9);
|
||||
this.groupGeneral.Name = "groupGeneral";
|
||||
this.groupGeneral.Size = new System.Drawing.Size(183, 75);
|
||||
this.groupGeneral.TabIndex = 16;
|
||||
this.groupGeneral.TabStop = false;
|
||||
this.groupGeneral.Text = "General";
|
||||
//
|
||||
// TabSettingsUpdates
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.groupGeneral);
|
||||
this.Name = "TabSettingsUpdates";
|
||||
this.Size = new System.Drawing.Size(478, 282);
|
||||
this.groupGeneral.ResumeLayout(false);
|
||||
this.groupGeneral.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button btnCheckUpdates;
|
||||
private System.Windows.Forms.CheckBox checkUpdateNotifications;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.GroupBox groupGeneral;
|
||||
}
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Updates;
|
||||
|
||||
namespace TweetDck.Core.Other.Settings{
|
||||
partial class TabSettingsUpdates : BaseTabSettings{
|
||||
private readonly UpdateHandler updates;
|
||||
private int updateCheckEventId = -1;
|
||||
|
||||
public TabSettingsUpdates(UpdateHandler updates){
|
||||
InitializeComponent();
|
||||
|
||||
this.updates = updates;
|
||||
|
||||
this.updates.CheckFinished += updates_CheckFinished;
|
||||
Disposed += (sender, args) => this.updates.CheckFinished -= updates_CheckFinished;
|
||||
|
||||
checkUpdateNotifications.Checked = Config.EnableUpdateCheck;
|
||||
}
|
||||
|
||||
private void checkUpdateNotifications_CheckedChanged(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.EnableUpdateCheck = checkUpdateNotifications.Checked;
|
||||
}
|
||||
|
||||
private void btnCheckUpdates_Click(object sender, EventArgs e){
|
||||
if (!Ready)return;
|
||||
|
||||
Config.DismissedUpdate = string.Empty;
|
||||
Config.Save();
|
||||
|
||||
updateCheckEventId = updates.Check(true);
|
||||
|
||||
btnCheckUpdates.Enabled = false;
|
||||
}
|
||||
|
||||
private void updates_CheckFinished(object sender, UpdateCheckEventArgs e){
|
||||
if (e.EventId == updateCheckEventId){
|
||||
btnCheckUpdates.Enabled = true;
|
||||
|
||||
if (!e.UpdateAvailable){
|
||||
MessageBox.Show("Your version of "+Program.BrandName+" is up to date.", "No Updates Available", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
50
Core/TrayIcon.Designer.cs
generated
50
Core/TrayIcon.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Core {
|
||||
namespace TweetDuck.Core {
|
||||
partial class TrayIcon {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -25,65 +25,17 @@
|
||||
private void InitializeComponent() {
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
|
||||
this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.restoreToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.muteNotificationsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.contextMenu.SuspendLayout();
|
||||
//
|
||||
// notifyIcon
|
||||
//
|
||||
this.notifyIcon.ContextMenuStrip = this.contextMenu;
|
||||
this.notifyIcon.Icon = global::TweetDck.Properties.Resources.icon_tray;
|
||||
this.notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(this.trayIcon_MouseClick);
|
||||
//
|
||||
// contextMenu
|
||||
//
|
||||
this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.restoreToolStripMenuItem,
|
||||
this.muteNotificationsToolStripMenuItem,
|
||||
this.closeToolStripMenuItem});
|
||||
this.contextMenu.Name = "contextMenuTray";
|
||||
this.contextMenu.ShowCheckMargin = true;
|
||||
this.contextMenu.ShowImageMargin = false;
|
||||
this.contextMenu.ShowItemToolTips = false;
|
||||
this.contextMenu.Size = new System.Drawing.Size(174, 92);
|
||||
this.contextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuTray_Opening);
|
||||
this.contextMenu.Opened += new System.EventHandler(this.contextMenuTray_Opened);
|
||||
//
|
||||
// restoreToolStripMenuItem
|
||||
//
|
||||
this.restoreToolStripMenuItem.Name = "restoreToolStripMenuItem";
|
||||
this.restoreToolStripMenuItem.Size = new System.Drawing.Size(173, 22);
|
||||
this.restoreToolStripMenuItem.Text = "Restore";
|
||||
this.restoreToolStripMenuItem.Click += new System.EventHandler(this.restoreToolStripMenuItem_Click);
|
||||
//
|
||||
// muteNotificationsToolStripMenuItem
|
||||
//
|
||||
this.muteNotificationsToolStripMenuItem.CheckOnClick = true;
|
||||
this.muteNotificationsToolStripMenuItem.Name = "muteNotificationsToolStripMenuItem";
|
||||
this.muteNotificationsToolStripMenuItem.Size = new System.Drawing.Size(173, 22);
|
||||
this.muteNotificationsToolStripMenuItem.Text = "Mute Notifications";
|
||||
this.muteNotificationsToolStripMenuItem.CheckedChanged += new System.EventHandler(this.muteNotificationsToolStripMenuItem_CheckedChanged);
|
||||
//
|
||||
// closeToolStripMenuItem
|
||||
//
|
||||
this.closeToolStripMenuItem.Name = "closeToolStripMenuItem";
|
||||
this.closeToolStripMenuItem.Size = new System.Drawing.Size(173, 22);
|
||||
this.closeToolStripMenuItem.Text = "Close";
|
||||
this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click);
|
||||
//
|
||||
// TrayIcon
|
||||
//
|
||||
this.contextMenu.ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.NotifyIcon notifyIcon;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem restoreToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem muteNotificationsToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core{
|
||||
namespace TweetDuck.Core{
|
||||
partial class TrayIcon : Component{
|
||||
public enum Behavior{ // keep order
|
||||
Disabled, DisplayOnly, MinimizeToTray, CloseToTray, Combined
|
||||
@@ -12,12 +12,15 @@ namespace TweetDck.Core{
|
||||
public event EventHandler ClickClose;
|
||||
|
||||
public bool Visible{
|
||||
get{
|
||||
return notifyIcon.Visible;
|
||||
}
|
||||
get => notifyIcon.Visible;
|
||||
|
||||
set{
|
||||
if (value){
|
||||
notifyIcon.Icon = Properties.Resources.icon_tray;
|
||||
}
|
||||
|
||||
notifyIcon.Visible = value;
|
||||
hasNotifications = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,52 +30,56 @@ namespace TweetDck.Core{
|
||||
}
|
||||
|
||||
set{
|
||||
if (hasNotifications != value){
|
||||
if (hasNotifications != value && Visible){
|
||||
notifyIcon.Icon = value ? Properties.Resources.icon_tray_new : Properties.Resources.icon_tray;
|
||||
hasNotifications = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ContextMenu contextMenu;
|
||||
private bool hasNotifications;
|
||||
|
||||
public TrayIcon(){
|
||||
InitializeComponent();
|
||||
notifyIcon.Text = Program.BrandName;
|
||||
|
||||
this.contextMenu = new ContextMenu();
|
||||
this.contextMenu.MenuItems.Add("Restore", menuItemRestore_Click);
|
||||
this.contextMenu.MenuItems.Add("Mute notifications", menuItemMuteNotifications_Click);
|
||||
this.contextMenu.MenuItems.Add("Close", menuItemClose_Click);
|
||||
this.contextMenu.Popup += contextMenu_Popup;
|
||||
|
||||
this.notifyIcon.ContextMenu = contextMenu;
|
||||
this.notifyIcon.Text = Program.BrandName;
|
||||
}
|
||||
|
||||
public TrayIcon(IContainer container) : this(){
|
||||
container.Add(this);
|
||||
}
|
||||
|
||||
// event handlers
|
||||
|
||||
private void trayIcon_MouseClick(object sender, MouseEventArgs e){
|
||||
if (e.Button == MouseButtons.Left){
|
||||
restoreToolStripMenuItem_Click(sender, e);
|
||||
menuItemRestore_Click(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void contextMenuTray_Opening(object sender, CancelEventArgs e){
|
||||
muteNotificationsToolStripMenuItem.CheckedChanged -= muteNotificationsToolStripMenuItem_CheckedChanged;
|
||||
muteNotificationsToolStripMenuItem.Checked = Program.UserConfig.MuteNotifications;
|
||||
private void contextMenu_Popup(object sender, EventArgs e){
|
||||
contextMenu.MenuItems[1].Checked = Program.UserConfig.MuteNotifications;
|
||||
}
|
||||
|
||||
private void contextMenuTray_Opened(object sender, EventArgs e){
|
||||
muteNotificationsToolStripMenuItem.CheckedChanged += muteNotificationsToolStripMenuItem_CheckedChanged;
|
||||
private void menuItemRestore_Click(object sender, EventArgs e){
|
||||
ClickRestore?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void restoreToolStripMenuItem_Click(object sender, EventArgs e){
|
||||
if (ClickRestore != null){
|
||||
ClickRestore(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void muteNotificationsToolStripMenuItem_CheckedChanged(object sender, EventArgs e){
|
||||
Program.UserConfig.MuteNotifications = muteNotificationsToolStripMenuItem.Checked;
|
||||
private void menuItemMuteNotifications_Click(object sender, EventArgs e){
|
||||
Program.UserConfig.MuteNotifications = !contextMenu.MenuItems[1].Checked;
|
||||
Program.UserConfig.Save();
|
||||
}
|
||||
|
||||
private void closeToolStripMenuItem_Click(object sender, EventArgs e){
|
||||
if (ClickClose != null){
|
||||
ClickClose(this, e);
|
||||
}
|
||||
private void menuItemClose_Click(object sender, EventArgs e){
|
||||
ClickClose?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@ using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
static class BrowserCache{
|
||||
private static bool ClearOnExit { get; set; }
|
||||
|
||||
@@ -31,21 +31,6 @@ namespace TweetDck.Core.Utils{
|
||||
task.Start();
|
||||
}
|
||||
|
||||
public static void ClearOldCacheFiles(){
|
||||
if (!Directory.Exists(CacheFolder)){
|
||||
foreach(string file in Directory.EnumerateFiles(Program.StoragePath).Where(path => {
|
||||
string file = Path.GetFileName(path);
|
||||
return file != null && (file.StartsWith("data_", StringComparison.Ordinal) || file.StartsWith("f_", StringComparison.Ordinal));
|
||||
}).Concat(new[]{ Path.Combine(Program.StoragePath, "index") })){
|
||||
try{
|
||||
File.Delete(file);
|
||||
}catch{
|
||||
// welp, too bad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetClearOnExit(){
|
||||
ClearOnExit = true;
|
||||
}
|
||||
|
@@ -1,12 +1,14 @@
|
||||
using System;
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
static class BrowserUtils{
|
||||
public static string HeaderAcceptLanguage{
|
||||
get{
|
||||
@@ -21,13 +23,36 @@ namespace TweetDck.Core.Utils{
|
||||
}
|
||||
}
|
||||
|
||||
public static string HeaderUserAgent{
|
||||
get{
|
||||
return Program.BrandName+" "+Application.ProductVersion;
|
||||
public static string HeaderUserAgent => Program.BrandName+" "+Application.ProductVersion;
|
||||
|
||||
public static readonly Color BackgroundColor = Color.FromArgb(28, 99, 153);
|
||||
public const string BackgroundColorFix = "let e=document.createElement('style');document.head.appendChild(e);e.innerHTML='body::before{background:#1c6399!important}'";
|
||||
|
||||
public static readonly string[] DictionaryWords = {
|
||||
"tweetdeck", "TweetDeck", "tweetduck", "TweetDuck", "TD"
|
||||
};
|
||||
|
||||
public static bool IsValidUrl(string url){
|
||||
if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri)){
|
||||
string scheme = uri.Scheme;
|
||||
return scheme == Uri.UriSchemeHttp || scheme == Uri.UriSchemeHttps || scheme == Uri.UriSchemeFtp || scheme == Uri.UriSchemeMailto;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void OpenExternalBrowser(string url){
|
||||
if (string.IsNullOrWhiteSpace(url))return;
|
||||
|
||||
if (IsValidUrl(url)){
|
||||
OpenExternalBrowserUnsafe(url);
|
||||
}
|
||||
else{
|
||||
MessageBox.Show("A potentially malicious URL was blocked from opening:"+Environment.NewLine+url, "Blocked URL", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenExternalBrowser(string url){ // TODO implement mailto
|
||||
public static void OpenExternalBrowserUnsafe(string url){
|
||||
using(Process.Start(url)){}
|
||||
}
|
||||
|
||||
@@ -36,23 +61,50 @@ namespace TweetDck.Core.Utils{
|
||||
return string.IsNullOrEmpty(file) ? null : file;
|
||||
}
|
||||
|
||||
public static void DownloadFileAsync(string url, string target, Action<Exception> onFailure){
|
||||
public static string ConvertPascalCaseToScreamingSnakeCase(string str){
|
||||
return Regex.Replace(str, @"(\p{Ll})(\P{Ll})|(\P{Ll})(\P{Ll}\p{Ll})", "$1$3_$2$4").ToUpperInvariant();
|
||||
}
|
||||
|
||||
public static string GetErrorName(CefErrorCode code){
|
||||
return ConvertPascalCaseToScreamingSnakeCase(Enum.GetName(typeof(CefErrorCode), code) ?? string.Empty);
|
||||
}
|
||||
|
||||
public static WebClient DownloadFileAsync(string url, string target, Action onSuccess, Action<Exception> onFailure){
|
||||
WebClient client = new WebClient{ Proxy = null };
|
||||
client.Headers[HttpRequestHeader.UserAgent] = HeaderUserAgent;
|
||||
|
||||
client.DownloadFileCompleted += (sender, args) => {
|
||||
if (args.Error != null){
|
||||
onFailure(args.Error);
|
||||
if (args.Cancelled){
|
||||
try{
|
||||
File.Delete(target);
|
||||
}catch{
|
||||
// didn't want it deleted anyways
|
||||
}
|
||||
}
|
||||
else if (args.Error != null){
|
||||
onFailure?.Invoke(args.Error);
|
||||
}
|
||||
else{
|
||||
onSuccess?.Invoke();
|
||||
}
|
||||
};
|
||||
|
||||
client.DownloadFileAsync(new Uri(url), target);
|
||||
return client;
|
||||
}
|
||||
|
||||
public static void SetZoomLevel(IBrowser browser, int percentage){
|
||||
browser.GetHost().SetZoomLevel(Math.Log(percentage/100.0, 1.2));
|
||||
}
|
||||
|
||||
public static bool IsTweetDeckWebsite(IFrame frame){
|
||||
return frame.Url.Contains("//tweetdeck.twitter.com/");
|
||||
}
|
||||
|
||||
public static bool IsTwitterWebsite(IFrame frame){
|
||||
return frame.Url.Contains("//twitter.com/");
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public static void HandleConsoleMessage(object sender, ConsoleMessageEventArgs e){
|
||||
Debug.WriteLine("[Console] {0} ({1}:{2})", e.Message, e.Source, e.Line);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
class CommandLineArgs{
|
||||
public static CommandLineArgs FromStringArray(char entryChar, string[] array){
|
||||
CommandLineArgs args = new CommandLineArgs();
|
||||
@@ -35,11 +35,7 @@ namespace TweetDck.Core.Utils{
|
||||
private readonly HashSet<string> flags = new HashSet<string>();
|
||||
private readonly Dictionary<string, string> values = new Dictionary<string, string>();
|
||||
|
||||
public int Count{
|
||||
get{
|
||||
return flags.Count+values.Count;
|
||||
}
|
||||
}
|
||||
public int Count => flags.Count+values.Count;
|
||||
|
||||
public void AddFlag(string flag){
|
||||
flags.Add(flag.ToLowerInvariant());
|
||||
@@ -57,9 +53,12 @@ namespace TweetDck.Core.Utils{
|
||||
values[key.ToLowerInvariant()] = value;
|
||||
}
|
||||
|
||||
public bool HasValue(string key){
|
||||
return values.ContainsKey(key.ToLowerInvariant());
|
||||
}
|
||||
|
||||
public string GetValue(string key, string defaultValue){
|
||||
string val;
|
||||
return values.TryGetValue(key.ToLowerInvariant(), out val) ? val : defaultValue;
|
||||
return values.TryGetValue(key.ToLowerInvariant(), out string val) ? val : defaultValue;
|
||||
}
|
||||
|
||||
public void RemoveValue(string key){
|
||||
@@ -101,7 +100,7 @@ namespace TweetDck.Core.Utils{
|
||||
build.Append(kvp.Key).Append(" \"").Append(kvp.Value).Append("\" ");
|
||||
}
|
||||
|
||||
return build.Remove(build.Length-1, 1).ToString();
|
||||
return build.Length == 0 ? string.Empty : build.Remove(build.Length-1, 1).ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,10 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
static class CommandLineArgsParser{
|
||||
private static Regex splitRegex;
|
||||
|
||||
private static Regex SplitRegex{
|
||||
get{
|
||||
return splitRegex ?? (splitRegex = new Regex(@"([^=\s]+(?:=(?:[^ ]*""[^""]*?""[^ ]*|[^ ]*))?)", RegexOptions.Compiled));
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Lazy<Regex> SplitRegex = new Lazy<Regex>(() => new Regex(@"([^=\s]+(?:=(?:[^ ]*""[^""]*?""[^ ]*|[^ ]*))?)", RegexOptions.Compiled), false);
|
||||
|
||||
public static CommandLineArgs ReadCefArguments(string argumentString){
|
||||
CommandLineArgs args = new CommandLineArgs();
|
||||
|
||||
@@ -17,7 +12,7 @@ namespace TweetDck.Core.Utils{
|
||||
return args;
|
||||
}
|
||||
|
||||
foreach(Match match in SplitRegex.Matches(argumentString)){
|
||||
foreach(Match match in SplitRegex.Value.Matches(argumentString)){
|
||||
string matchValue = match.Value;
|
||||
|
||||
int indexEquals = matchValue.IndexOf('=');
|
||||
|
@@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
static class HardwareAcceleration{
|
||||
private static readonly string LibEGL = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libEGL.dll");
|
||||
private static readonly string LibGLES = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libGLESv2.dll");
|
||||
|
||||
private static readonly string DisabledLibEGL = LibEGL+".bak";
|
||||
private static readonly string DisabledLibGLES = LibGLES+".bak";
|
||||
|
||||
public static bool IsEnabled{
|
||||
get{
|
||||
return File.Exists(LibEGL) && File.Exists(LibGLES);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CanEnable{
|
||||
get{
|
||||
return File.Exists(DisabledLibEGL) && File.Exists(DisabledLibGLES);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Enable(){
|
||||
if (IsEnabled)return false;
|
||||
|
||||
try{
|
||||
File.Move(DisabledLibEGL, LibEGL);
|
||||
File.Move(DisabledLibGLES, LibGLES);
|
||||
return true;
|
||||
}catch{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Disable(){
|
||||
if (!IsEnabled)return false;
|
||||
|
||||
try{
|
||||
if (File.Exists(DisabledLibEGL)){
|
||||
File.Delete(DisabledLibEGL);
|
||||
}
|
||||
|
||||
if (File.Exists(DisabledLibGLES)){
|
||||
File.Delete(DisabledLibGLES);
|
||||
}
|
||||
}catch{
|
||||
// woops
|
||||
}
|
||||
|
||||
try{
|
||||
File.Move(LibEGL, DisabledLibEGL);
|
||||
File.Move(LibGLES, DisabledLibGLES);
|
||||
return true;
|
||||
}catch{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
Core/Utils/InjectedHTML.cs
Normal file
37
Core/Utils/InjectedHTML.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace TweetDuck.Core.Utils{
|
||||
class InjectedHTML{
|
||||
public enum Position{
|
||||
Before, After
|
||||
}
|
||||
|
||||
private readonly Position position;
|
||||
private readonly string search;
|
||||
private readonly string html;
|
||||
|
||||
public InjectedHTML(Position position, string search, string html){
|
||||
this.position = position;
|
||||
this.search = search;
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
public string Inject(string targetHTML){
|
||||
int index = targetHTML.IndexOf(search, StringComparison.Ordinal);
|
||||
|
||||
if (index == -1){
|
||||
return targetHTML;
|
||||
}
|
||||
|
||||
int cutIndex;
|
||||
|
||||
switch(position){
|
||||
case Position.Before: cutIndex = index; break;
|
||||
case Position.After: cutIndex = index+search.Length; break;
|
||||
default: return targetHTML;
|
||||
}
|
||||
|
||||
return targetHTML.Insert(cutIndex, html);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,36 +1,70 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
|
||||
static class NativeMethods{
|
||||
public static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
|
||||
public static readonly IntPtr HOOK_HANDLED = new IntPtr(-1);
|
||||
|
||||
public const int HWND_TOPMOST = -1;
|
||||
public const uint SWP_NOACTIVATE = 0x0010;
|
||||
|
||||
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
|
||||
public const int MOUSEEVENTF_LEFTUP = 0x04;
|
||||
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
|
||||
public const int MOUSEEVENTF_RIGHTUP = 0x10;
|
||||
public const int WS_DISABLED = 0x08000000;
|
||||
public const int GWL_STYLE = -16;
|
||||
|
||||
public const int SB_HORZ = 0;
|
||||
public const int BCM_SETSHIELD = 0x160C;
|
||||
|
||||
public const int WH_MOUSE_LL = 14;
|
||||
public const int WH_MOUSEWHEEL = 0x020A;
|
||||
public const int WM_MOUSE_LL = 14;
|
||||
public const int WM_MOUSEWHEEL = 0x020A;
|
||||
public const int WM_XBUTTONDOWN = 0x020B;
|
||||
public const int WM_XBUTTONUP = 0x020C;
|
||||
public const int WM_PARENTNOTIFY = 0x0210;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct LASTINPUTINFO{
|
||||
public static readonly uint Size = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
|
||||
|
||||
public enum MouseButton{
|
||||
Left, Right
|
||||
public uint cbSize;
|
||||
public uint dwTime;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct POINT{
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct MSLLHOOKSTRUCT{
|
||||
public POINT pt;
|
||||
public int mouseData;
|
||||
public int flags;
|
||||
public int time;
|
||||
public UIntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
|
||||
public static extern bool SetWindowPos(int hWnd, int hWndOrder, int x, int y, int width, int height, uint flags);
|
||||
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 void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
|
||||
private static extern bool GetLastInputInfo(ref LASTINPUTINFO info);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetDC(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
[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("user32.dll")]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, IntPtr lParam);
|
||||
@@ -51,29 +85,57 @@ namespace TweetDck.Core.Utils{
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
public static void SetFormPos(Form form, int hWndOrder, uint flags){
|
||||
SetWindowPos(form.Handle.ToInt32(), hWndOrder, form.Left, form.Top, form.Width, form.Height, flags);
|
||||
}
|
||||
|
||||
public static void SimulateMouseClick(MouseButton button){
|
||||
int flagHold, flagRelease;
|
||||
public static void SetFormDisabled(Form form, bool disabled){
|
||||
if (disabled){
|
||||
SetWindowLong(form.Handle, GWL_STYLE, GetWindowLong(form.Handle, GWL_STYLE) | WS_DISABLED);
|
||||
}
|
||||
else{
|
||||
SetWindowLong(form.Handle, GWL_STYLE, GetWindowLong(form.Handle, GWL_STYLE) & ~WS_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
switch(button){
|
||||
case MouseButton.Left:
|
||||
flagHold = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN;
|
||||
flagRelease = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP;
|
||||
break;
|
||||
public static int GetMouseHookData(IntPtr ptr){
|
||||
return Marshal.PtrToStructure<MSLLHOOKSTRUCT>(ptr).mouseData >> 16;
|
||||
}
|
||||
|
||||
case MouseButton.Right:
|
||||
flagHold = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
|
||||
flagRelease = SystemInformation.MouseButtonsSwapped ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
|
||||
break;
|
||||
public static int GetIdleSeconds(){
|
||||
LASTINPUTINFO info = new LASTINPUTINFO();
|
||||
info.cbSize = LASTINPUTINFO.Size;
|
||||
|
||||
default: return;
|
||||
if (!GetLastInputInfo(ref info)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
mouse_event(flagHold, Cursor.Position.X, Cursor.Position.Y, 0, 0);
|
||||
mouse_event(flagRelease, Cursor.Position.X, Cursor.Position.Y, 0, 0);
|
||||
uint ticks;
|
||||
|
||||
unchecked{
|
||||
ticks = (uint)Environment.TickCount;
|
||||
}
|
||||
|
||||
int seconds = (int)Math.Floor(TimeSpan.FromMilliseconds(ticks-info.dwTime).TotalSeconds);
|
||||
return Math.Max(0, seconds); // ignore rollover after several weeks of uptime
|
||||
}
|
||||
|
||||
public static void RenderSourceIntoBitmap(IntPtr source, Bitmap target){
|
||||
using(Graphics graphics = Graphics.FromImage(target)){
|
||||
IntPtr graphicsHandle = graphics.GetHdc();
|
||||
|
||||
try{
|
||||
BitBlt(graphicsHandle, 0, 0, target.Width, target.Height, source, 0, 0, 0x00CC0020);
|
||||
}finally{
|
||||
graphics.ReleaseHdc(graphicsHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
102
Core/Utils/TwoKeyDictionary.cs
Normal file
102
Core/Utils/TwoKeyDictionary.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TweetDuck.Core.Utils{
|
||||
class TwoKeyDictionary<K1, K2, V>{
|
||||
private readonly Dictionary<K1, Dictionary<K2, V>> dict;
|
||||
private readonly int innerCapacity;
|
||||
|
||||
public TwoKeyDictionary() : this(16, 16){}
|
||||
|
||||
public TwoKeyDictionary(int outerCapacity, int innerCapacity){
|
||||
this.dict = new Dictionary<K1, Dictionary<K2, V>>(outerCapacity);
|
||||
this.innerCapacity = innerCapacity;
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
public V this[K1 outerKey, K2 innerKey]{
|
||||
get{ // throws on missing key
|
||||
return dict[outerKey][innerKey];
|
||||
}
|
||||
|
||||
set{
|
||||
if (!dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
|
||||
dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity));
|
||||
}
|
||||
|
||||
innerDict[innerKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<V> InnerValues{
|
||||
get{
|
||||
foreach(Dictionary<K2, V> innerDict in dict.Values){
|
||||
foreach(V value in innerDict.Values){
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
public void Add(K1 outerKey, K2 innerKey, V value){ // throws on duplicate
|
||||
if (!dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
|
||||
dict.Add(outerKey, innerDict = new Dictionary<K2, V>(innerCapacity));
|
||||
}
|
||||
|
||||
innerDict.Add(innerKey, value);
|
||||
}
|
||||
|
||||
public void Clear(){
|
||||
dict.Clear();
|
||||
}
|
||||
|
||||
public void Clear(K1 outerKey){ // throws on missing key, but keeps the key unlike Remove(K1)
|
||||
dict[outerKey].Clear();
|
||||
}
|
||||
|
||||
public bool Contains(K1 outerKey){
|
||||
return dict.ContainsKey(outerKey);
|
||||
}
|
||||
|
||||
public bool Contains(K1 outerKey, K2 innerKey){
|
||||
Dictionary<K2, V> innerDict;
|
||||
return dict.TryGetValue(outerKey, out innerDict) && innerDict.ContainsKey(innerKey);
|
||||
}
|
||||
|
||||
public int Count(){
|
||||
return dict.Values.Sum(d => d.Count);
|
||||
}
|
||||
|
||||
public int Count(K1 outerKey){ // throws on missing key
|
||||
return dict[outerKey].Count;
|
||||
}
|
||||
|
||||
public bool Remove(K1 outerKey){
|
||||
return dict.Remove(outerKey);
|
||||
}
|
||||
|
||||
public bool Remove(K1 outerKey, K2 innerKey){
|
||||
if (dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict) && innerDict.Remove(innerKey)){
|
||||
if (innerDict.Count == 0) {
|
||||
dict.Remove(outerKey);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
public bool TryGetValue(K1 outerKey, K2 innerKey, out V value){
|
||||
if (dict.TryGetValue(outerKey, out Dictionary<K2, V> innerDict)){
|
||||
return innerDict.TryGetValue(innerKey, out value);
|
||||
}
|
||||
else{
|
||||
value = default(V);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
[Serializable]
|
||||
class WindowState{
|
||||
private Rectangle rect;
|
||||
@@ -20,7 +20,7 @@ namespace TweetDck.Core.Utils{
|
||||
form.WindowState = isMaximized ? FormWindowState.Maximized : FormWindowState.Normal;
|
||||
}
|
||||
|
||||
if ((rect == Rectangle.Empty && firstTimeFullscreen) || !Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(form.Bounds))){
|
||||
if ((rect == Rectangle.Empty && firstTimeFullscreen) || form.IsFullyOutsideView()){
|
||||
form.DesktopBounds = Screen.PrimaryScreen.WorkingArea;
|
||||
form.WindowState = FormWindowState.Maximized;
|
||||
Save(form);
|
||||
|
@@ -1,23 +1,33 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Core.Utils{
|
||||
namespace TweetDuck.Core.Utils{
|
||||
static class WindowsUtils{
|
||||
public static bool CheckFolderPermission(string path, FileSystemRights right){
|
||||
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);
|
||||
|
||||
public static bool ShouldAvoidToolWindow { get; }
|
||||
|
||||
static WindowsUtils(){
|
||||
Version ver = Environment.OSVersion.Version;
|
||||
ShouldAvoidToolWindow = ver.Major == 6 && ver.Minor == 2; // windows 8/10
|
||||
}
|
||||
|
||||
public static bool CheckFolderWritePermission(string path){
|
||||
string testFile = Path.Combine(path, ".test");
|
||||
|
||||
try{
|
||||
AuthorizationRuleCollection collection = Directory.GetAccessControl(path).GetAccessRules(true, true, typeof(NTAccount));
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
foreach(FileSystemAccessRule rule in collection){
|
||||
if ((rule.FileSystemRights & right) == right){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch{
|
||||
using(File.Create(testFile)){}
|
||||
File.Delete(testFile);
|
||||
return true;
|
||||
}catch{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -34,5 +44,69 @@ namespace TweetDck.Core.Utils{
|
||||
|
||||
return Process.Start(processInfo);
|
||||
}
|
||||
|
||||
public static bool TrySleepUntil(Func<bool> test, int timeoutMillis, int timeStepMillis){
|
||||
for(int waited = 0; waited < timeoutMillis; waited += timeStepMillis){
|
||||
if (test()){
|
||||
return true;
|
||||
}
|
||||
|
||||
Thread.Sleep(timeStepMillis);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void TryDeleteFolderWhenAble(string path, int timeout){
|
||||
new Thread(() => {
|
||||
TrySleepUntil(() => {
|
||||
try{
|
||||
Directory.Delete(path, true);
|
||||
return true;
|
||||
}catch(DirectoryNotFoundException){
|
||||
return true;
|
||||
}catch{
|
||||
return false;
|
||||
}
|
||||
}, timeout, 500);
|
||||
}).Start();
|
||||
}
|
||||
|
||||
public static void ClipboardStripHtmlStyles(){
|
||||
if (!Clipboard.ContainsText(TextDataFormat.Html)){
|
||||
return;
|
||||
}
|
||||
|
||||
string originalText = Clipboard.GetText(TextDataFormat.UnicodeText);
|
||||
string originalHtml = Clipboard.GetText(TextDataFormat.Html);
|
||||
|
||||
string updatedHtml = RegexStripHtmlStyles.Value.Replace(originalHtml, string.Empty);
|
||||
|
||||
int removed = originalHtml.Length-updatedHtml.Length;
|
||||
updatedHtml = RegexOffsetClipboardHtml.Value.Replace(updatedHtml, match => (int.Parse(match.Value)-removed).ToString().PadLeft(match.Value.Length, '0'));
|
||||
|
||||
DataObject obj = new DataObject();
|
||||
obj.SetText(originalText, TextDataFormat.UnicodeText);
|
||||
obj.SetText(updatedHtml, TextDataFormat.Html);
|
||||
SetClipboardData(obj);
|
||||
}
|
||||
|
||||
public static void SetClipboard(string text, TextDataFormat format){
|
||||
if (string.IsNullOrEmpty(text)){
|
||||
return;
|
||||
}
|
||||
|
||||
DataObject obj = new DataObject();
|
||||
obj.SetText(text, format);
|
||||
SetClipboardData(obj);
|
||||
}
|
||||
|
||||
private static void SetClipboardData(DataObject obj){
|
||||
try{
|
||||
Clipboard.SetDataObject(obj);
|
||||
}catch(ExternalException e){
|
||||
Program.Reporter.HandleException("Clipboard Error", Program.BrandName+" could not access the clipboard as it is currently used by another process.", true, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
77
Migration/FormBackgroundWork.Designer.cs
generated
77
Migration/FormBackgroundWork.Designer.cs
generated
@@ -1,77 +0,0 @@
|
||||
using TweetDck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Migration {
|
||||
partial class FormBackgroundWork {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent() {
|
||||
this.progressBarUseless = new System.Windows.Forms.ProgressBar();
|
||||
this.labelDescription = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// progressBarUseless
|
||||
//
|
||||
this.progressBarUseless.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.progressBarUseless.Location = new System.Drawing.Point(15, 52);
|
||||
this.progressBarUseless.MarqueeAnimationSpeed = 10;
|
||||
this.progressBarUseless.Name = "progressBarUseless";
|
||||
this.progressBarUseless.Size = new System.Drawing.Size(477, 23);
|
||||
this.progressBarUseless.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
|
||||
this.progressBarUseless.TabIndex = 0;
|
||||
//
|
||||
// labelDescription
|
||||
//
|
||||
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.Location = new System.Drawing.Point(12, 12);
|
||||
this.labelDescription.Name = "labelDescription";
|
||||
this.labelDescription.Size = new System.Drawing.Size(480, 37);
|
||||
this.labelDescription.TabIndex = 1;
|
||||
this.labelDescription.Text = "Please, watch this informationless progress bar showcase while some magic happens" +
|
||||
" in the background...";
|
||||
//
|
||||
// FormBackgroundWork
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(504, 87);
|
||||
this.Controls.Add(this.labelDescription);
|
||||
this.Controls.Add(this.progressBarUseless);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Name = "FormBackgroundWork";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "TweetDeck Migration";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ProgressBar progressBarUseless;
|
||||
private System.Windows.Forms.Label labelDescription;
|
||||
}
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TweetDck.Migration{
|
||||
partial class FormBackgroundWork : Form{
|
||||
public FormBackgroundWork(){
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void ShowWorkDialog(Action onBegin){
|
||||
Shown += (sender, args) => onBegin();
|
||||
ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,23 +0,0 @@
|
||||
namespace TweetDck.Migration{
|
||||
enum MigrationDecision{
|
||||
/// <summary>
|
||||
/// Copies the important files and then deletes the TweetDeck folder.
|
||||
/// </summary>
|
||||
Migrate,
|
||||
|
||||
/// <summary>
|
||||
/// Does exactly what <see cref="Migrate"/> does, but also silently uninstalls TweetDeck.
|
||||
/// </summary>
|
||||
MigratePurge,
|
||||
|
||||
/// <summary>
|
||||
/// Does not copy any files and does not ask the user about data migration again.
|
||||
/// </summary>
|
||||
Ignore,
|
||||
|
||||
/// <summary>
|
||||
/// Does not copy any files but asks the user again when the program is re-ran.
|
||||
/// </summary>
|
||||
AskLater
|
||||
}
|
||||
}
|
@@ -1,204 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using TweetDck.Core.Other;
|
||||
using System.Drawing;
|
||||
using TweetDck.Core.Controls;
|
||||
|
||||
namespace TweetDck.Migration{
|
||||
static class MigrationManager{
|
||||
private static readonly string TweetDeckPathParent = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "twitter");
|
||||
private static readonly string TweetDeckPath = Path.Combine(TweetDeckPathParent, "TweetDeck");
|
||||
|
||||
private static readonly string TweetDickStorage = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "TweetDick");
|
||||
|
||||
public static void Run(){
|
||||
if (!Program.IsPortable && Directory.Exists(TweetDickStorage) && !Directory.Exists(Program.StoragePath)){
|
||||
if (MessageBox.Show("Welcome to TweetDuck! Would you like to move your old TweetDick configuration and login data?", "TweetDick Migration", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes){
|
||||
try{
|
||||
Directory.Move(TweetDickStorage, Program.StoragePath);
|
||||
MessageBox.Show("All done! You can now uninstall TweetDick.", "TweetDick Migration", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}catch(Exception ex){
|
||||
Program.Reporter.HandleException("Migration Error", "An unexpected error occurred during the migration process.", true, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Program.UserConfig.IgnoreMigration && Directory.Exists(TweetDeckPath)){
|
||||
MigrationDecision decision;
|
||||
|
||||
const string prompt = "Hey there, I found some TweetDeck data! Do you want to »Migrate« it and delete the old data folder, »Ignore« the prompt, or try "+Program.BrandName+" out first? You may also »Migrate && Purge« which uninstalls TweetDeck too!";
|
||||
|
||||
using(FormMessage formQuestion = new FormMessage("TweetDeck Migration", prompt, MessageBoxIcon.Question)){
|
||||
formQuestion.AddButton("Ask Later");
|
||||
Button btnIgnore = formQuestion.AddButton("Ignore");
|
||||
Button btnMigrate = formQuestion.AddButton("Migrate");
|
||||
Button btnMigrateAndPurge = formQuestion.AddButton("Migrate && Purge");
|
||||
|
||||
btnMigrateAndPurge.Location = new Point(btnMigrateAndPurge.Location.X-20, btnMigrateAndPurge.Location.Y);
|
||||
btnMigrateAndPurge.Width += 20;
|
||||
btnMigrateAndPurge.SetElevated();
|
||||
|
||||
if (formQuestion.ShowDialog() == DialogResult.OK){
|
||||
decision = formQuestion.ClickedButton == btnMigrateAndPurge ? MigrationDecision.MigratePurge :
|
||||
formQuestion.ClickedButton == btnMigrate ? MigrationDecision.Migrate :
|
||||
formQuestion.ClickedButton == btnIgnore ? MigrationDecision.Ignore : MigrationDecision.AskLater;
|
||||
}
|
||||
else{
|
||||
decision = MigrationDecision.AskLater;
|
||||
}
|
||||
}
|
||||
|
||||
switch(decision){
|
||||
case MigrationDecision.MigratePurge:
|
||||
case MigrationDecision.Migrate:
|
||||
FormBackgroundWork formWait = new FormBackgroundWork();
|
||||
|
||||
formWait.ShowWorkDialog(() => {
|
||||
if (!BeginMigration(decision, ex => formWait.Invoke(new Action(() => {
|
||||
formWait.Close();
|
||||
|
||||
if (ex != null){
|
||||
Program.Reporter.HandleException("Migration Error", "An unexpected error occurred during the migration process.", true, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
Program.UserConfig.IgnoreMigration = true;
|
||||
Program.UserConfig.Save();
|
||||
})))){
|
||||
formWait.Close();
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case MigrationDecision.Ignore:
|
||||
Program.UserConfig.IgnoreMigration = true;
|
||||
Program.UserConfig.Save();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!Program.UserConfig.IgnoreUninstallCheck){
|
||||
string guid = MigrationUtils.FindProgramGuidByDisplayName("TweetDeck");
|
||||
|
||||
if (guid != null){
|
||||
const string prompt = "TweetDeck is still installed on your computer, do you want to uninstall it?";
|
||||
|
||||
using(FormMessage formQuestion = new FormMessage("Uninstall TweetDeck", prompt, MessageBoxIcon.Question)){
|
||||
formQuestion.AddButton("No");
|
||||
|
||||
Button btnYes = formQuestion.AddButton("Yes");
|
||||
btnYes.SetElevated();
|
||||
|
||||
if (formQuestion.ShowDialog() == DialogResult.OK && formQuestion.ClickedButton == btnYes && MigrationUtils.RunUninstaller(guid, 0)){
|
||||
CleanupTweetDeck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Program.UserConfig.IgnoreUninstallCheck = true;
|
||||
Program.UserConfig.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool BeginMigration(MigrationDecision decision, Action<Exception> onFinished){
|
||||
if (decision != MigrationDecision.MigratePurge && decision != MigrationDecision.Migrate){
|
||||
return false;
|
||||
}
|
||||
|
||||
Task task = new Task(() => {
|
||||
Directory.CreateDirectory(Program.StoragePath);
|
||||
Directory.CreateDirectory(Path.Combine(Program.StoragePath, "localStorage"));
|
||||
Directory.CreateDirectory(Path.Combine(Program.StoragePath, "Local Storage"));
|
||||
|
||||
CopyFile("Cookies");
|
||||
CopyFile("Cookies-journal");
|
||||
CopyFile("localStorage"+Path.DirectorySeparatorChar+"qrc__0.localstorage");
|
||||
CopyFile("Local Storage"+Path.DirectorySeparatorChar+"https_tweetdeck.twitter.com_0.localstorage");
|
||||
CopyFile("Local Storage"+Path.DirectorySeparatorChar+"https_tweetdeck.twitter.com_0.localstorage-journal");
|
||||
|
||||
if (decision == MigrationDecision.Migrate || decision == MigrationDecision.MigratePurge){
|
||||
// kill process if running
|
||||
Process runningProcess = null;
|
||||
|
||||
try{
|
||||
runningProcess = Process.GetProcessesByName("TweetDeck").FirstOrDefault(process => process.MainWindowHandle != IntPtr.Zero);
|
||||
}catch(Exception){
|
||||
// process not found
|
||||
}
|
||||
|
||||
if (runningProcess != null){
|
||||
runningProcess.CloseMainWindow();
|
||||
|
||||
for(int wait = 0; wait < 100 && !runningProcess.HasExited; wait++){ // 10 seconds
|
||||
runningProcess.Refresh();
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
runningProcess.Close();
|
||||
}
|
||||
|
||||
// delete folders
|
||||
for(int wait = 0; wait < 50; wait++){
|
||||
try{
|
||||
Directory.Delete(TweetDeckPath, true);
|
||||
break;
|
||||
}catch(Exception){
|
||||
// browser subprocess not ended yet, wait
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
Directory.Delete(TweetDeckPathParent, false);
|
||||
}catch(IOException){
|
||||
// most likely not empty, ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (decision == MigrationDecision.MigratePurge){
|
||||
// uninstall in the background
|
||||
string guid = MigrationUtils.FindProgramGuidByDisplayName("TweetDeck");
|
||||
|
||||
if (guid != null && !MigrationUtils.RunUninstaller(guid, 5000)){
|
||||
return;
|
||||
}
|
||||
|
||||
// registry cleanup
|
||||
CleanupTweetDeck();
|
||||
|
||||
// migration finished like a boss
|
||||
}
|
||||
});
|
||||
|
||||
task.ContinueWith(originalTask => onFinished(originalTask.Exception), TaskContinuationOptions.ExecuteSynchronously);
|
||||
task.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void CopyFile(string relativePath){
|
||||
try{
|
||||
File.Copy(Path.Combine(TweetDeckPath, relativePath), Path.Combine(Program.StoragePath, relativePath), true);
|
||||
}catch(FileNotFoundException){
|
||||
}catch(DirectoryNotFoundException){
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanupTweetDeck(){
|
||||
try{
|
||||
Registry.CurrentUser.DeleteSubKeyTree(@"Software\Twitter\TweetDeck", true);
|
||||
Registry.CurrentUser.DeleteSubKey(@"Software\Twitter"); // only if empty
|
||||
}catch(Exception){
|
||||
// not found or too bad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
using TweetDck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Migration{
|
||||
static class MigrationUtils{
|
||||
public static bool RunUninstaller(string guid, int timeout){
|
||||
try{
|
||||
Process uninstaller = WindowsUtils.StartProcess("msiexec.exe", "/x "+guid+" /quiet /qn", true);
|
||||
|
||||
if (uninstaller != null){
|
||||
if (timeout > 0){
|
||||
uninstaller.WaitForExit(timeout); // it appears that the process is restarted or something that triggers this, but it shouldn't be a problem
|
||||
}
|
||||
|
||||
uninstaller.Close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}catch(Exception){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string FindProgramGuidByDisplayName(string displayName){
|
||||
Predicate<RegistryKey> predicate = key => displayName.Equals(key.GetValue("DisplayName") as string, StringComparison.OrdinalIgnoreCase);
|
||||
string guid;
|
||||
|
||||
return FindMatchingSubKey(Registry.LocalMachine, @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall", predicate, out guid) ||
|
||||
FindMatchingSubKey(Registry.LocalMachine, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", predicate, out guid) ||
|
||||
FindMatchingSubKey(Registry.CurrentUser, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", predicate, out guid)
|
||||
? guid : null;
|
||||
}
|
||||
|
||||
private static bool FindMatchingSubKey(RegistryKey keyHandle, string path, Predicate<RegistryKey> predicate, out string guid){
|
||||
string outputId = null;
|
||||
|
||||
try{
|
||||
RegistryKey parentKey = keyHandle.OpenSubKey(path, false);
|
||||
if (parentKey == null)throw new InvalidOperationException();
|
||||
|
||||
foreach(RegistryKey subKey in parentKey.GetSubKeyNames().Select(subName => parentKey.OpenSubKey(subName, false)).Where(subKey => subKey != null)){
|
||||
if (predicate(subKey)){
|
||||
outputId = subKey.Name.Substring(subKey.Name.LastIndexOf('\\')+1);
|
||||
subKey.Close();
|
||||
break;
|
||||
}
|
||||
|
||||
subKey.Close();
|
||||
}
|
||||
|
||||
parentKey.Close();
|
||||
}catch(Exception){
|
||||
guid = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (guid = outputId) != null;
|
||||
}
|
||||
}
|
||||
}
|
58
Plugins/Controls/PluginControl.Designer.cs
generated
58
Plugins/Controls/PluginControl.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Plugins.Controls {
|
||||
namespace TweetDuck.Plugins.Controls {
|
||||
partial class PluginControl {
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -32,6 +32,7 @@
|
||||
this.labelWebsite = new System.Windows.Forms.Label();
|
||||
this.labelVersion = new System.Windows.Forms.Label();
|
||||
this.btnOpenConfig = new System.Windows.Forms.Button();
|
||||
this.labelType = new TweetDuck.Core.Controls.LabelVertical();
|
||||
this.panelDescription.SuspendLayout();
|
||||
this.flowLayoutInfo.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@@ -39,10 +40,10 @@
|
||||
// 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(459, 80);
|
||||
this.btnToggleState.Location = new System.Drawing.Point(456, 80);
|
||||
this.btnToggleState.Name = "btnToggleState";
|
||||
this.btnToggleState.Size = new System.Drawing.Size(65, 23);
|
||||
this.btnToggleState.TabIndex = 0;
|
||||
this.btnToggleState.TabIndex = 5;
|
||||
this.btnToggleState.Text = "Disable";
|
||||
this.btnToggleState.UseVisualStyleBackColor = true;
|
||||
this.btnToggleState.Click += new System.EventHandler(this.btnToggleState_Click);
|
||||
@@ -51,11 +52,12 @@
|
||||
//
|
||||
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(7, 7);
|
||||
this.labelName.Location = new System.Drawing.Point(24, 7);
|
||||
this.labelName.Name = "labelName";
|
||||
this.labelName.Size = new System.Drawing.Size(61, 24);
|
||||
this.labelName.TabIndex = 1;
|
||||
this.labelName.TabIndex = 0;
|
||||
this.labelName.Text = "Name";
|
||||
this.labelName.UseMnemonic = false;
|
||||
//
|
||||
// panelDescription
|
||||
//
|
||||
@@ -64,9 +66,9 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panelDescription.AutoScroll = true;
|
||||
this.panelDescription.Controls.Add(this.labelDescription);
|
||||
this.panelDescription.Location = new System.Drawing.Point(11, 35);
|
||||
this.panelDescription.Location = new System.Drawing.Point(28, 35);
|
||||
this.panelDescription.Name = "panelDescription";
|
||||
this.panelDescription.Size = new System.Drawing.Size(513, 39);
|
||||
this.panelDescription.Size = new System.Drawing.Size(493, 39);
|
||||
this.panelDescription.TabIndex = 2;
|
||||
this.panelDescription.Resize += new System.EventHandler(this.panelDescription_Resize);
|
||||
//
|
||||
@@ -79,8 +81,9 @@
|
||||
this.labelDescription.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.labelDescription.Name = "labelDescription";
|
||||
this.labelDescription.Size = new System.Drawing.Size(13, 39);
|
||||
this.labelDescription.TabIndex = 3;
|
||||
this.labelDescription.TabIndex = 0;
|
||||
this.labelDescription.Text = "a\r\nb\r\nc";
|
||||
this.labelDescription.UseMnemonic = false;
|
||||
//
|
||||
// labelAuthor
|
||||
//
|
||||
@@ -89,8 +92,9 @@
|
||||
this.labelAuthor.Margin = new System.Windows.Forms.Padding(3, 0, 32, 0);
|
||||
this.labelAuthor.Name = "labelAuthor";
|
||||
this.labelAuthor.Size = new System.Drawing.Size(38, 13);
|
||||
this.labelAuthor.TabIndex = 3;
|
||||
this.labelAuthor.TabIndex = 0;
|
||||
this.labelAuthor.Text = "Author";
|
||||
this.labelAuthor.UseMnemonic = false;
|
||||
//
|
||||
// flowLayoutInfo
|
||||
//
|
||||
@@ -98,10 +102,10 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowLayoutInfo.Controls.Add(this.labelAuthor);
|
||||
this.flowLayoutInfo.Controls.Add(this.labelWebsite);
|
||||
this.flowLayoutInfo.Location = new System.Drawing.Point(11, 85);
|
||||
this.flowLayoutInfo.Location = new System.Drawing.Point(28, 85);
|
||||
this.flowLayoutInfo.Name = "flowLayoutInfo";
|
||||
this.flowLayoutInfo.Size = new System.Drawing.Size(368, 18);
|
||||
this.flowLayoutInfo.TabIndex = 4;
|
||||
this.flowLayoutInfo.Size = new System.Drawing.Size(348, 18);
|
||||
this.flowLayoutInfo.TabIndex = 3;
|
||||
this.flowLayoutInfo.WrapContents = false;
|
||||
//
|
||||
// labelWebsite
|
||||
@@ -113,8 +117,9 @@
|
||||
this.labelWebsite.Location = new System.Drawing.Point(76, 0);
|
||||
this.labelWebsite.Name = "labelWebsite";
|
||||
this.labelWebsite.Size = new System.Drawing.Size(46, 13);
|
||||
this.labelWebsite.TabIndex = 5;
|
||||
this.labelWebsite.TabIndex = 1;
|
||||
this.labelWebsite.Text = "Website";
|
||||
this.labelWebsite.UseMnemonic = false;
|
||||
this.labelWebsite.Click += new System.EventHandler(this.labelWebsite_Click);
|
||||
//
|
||||
// labelVersion
|
||||
@@ -124,36 +129,52 @@
|
||||
this.labelVersion.Location = new System.Drawing.Point(14, 12);
|
||||
this.labelVersion.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
|
||||
this.labelVersion.Name = "labelVersion";
|
||||
this.labelVersion.Size = new System.Drawing.Size(513, 13);
|
||||
this.labelVersion.TabIndex = 5;
|
||||
this.labelVersion.Size = new System.Drawing.Size(510, 13);
|
||||
this.labelVersion.TabIndex = 1;
|
||||
this.labelVersion.Text = "Version";
|
||||
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
this.labelVersion.UseMnemonic = false;
|
||||
//
|
||||
// btnOpenConfig
|
||||
//
|
||||
this.btnOpenConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOpenConfig.Location = new System.Drawing.Point(385, 80);
|
||||
this.btnOpenConfig.Location = new System.Drawing.Point(382, 80);
|
||||
this.btnOpenConfig.Name = "btnOpenConfig";
|
||||
this.btnOpenConfig.Size = new System.Drawing.Size(68, 23);
|
||||
this.btnOpenConfig.TabIndex = 6;
|
||||
this.btnOpenConfig.TabIndex = 4;
|
||||
this.btnOpenConfig.Text = "Configure";
|
||||
this.btnOpenConfig.UseVisualStyleBackColor = true;
|
||||
this.btnOpenConfig.Click += new System.EventHandler(this.btnOpenConfig_Click);
|
||||
//
|
||||
// labelType
|
||||
//
|
||||
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.LineHeight = 9;
|
||||
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.Text = "TYPE";
|
||||
//
|
||||
// PluginControl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.labelType);
|
||||
this.Controls.Add(this.btnOpenConfig);
|
||||
this.Controls.Add(this.flowLayoutInfo);
|
||||
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.Name = "PluginControl";
|
||||
this.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.Padding = new System.Windows.Forms.Padding(3, 3, 6, 3);
|
||||
this.Size = new System.Drawing.Size(530, 109);
|
||||
this.panelDescription.ResumeLayout(false);
|
||||
this.panelDescription.PerformLayout();
|
||||
@@ -175,5 +196,6 @@
|
||||
private System.Windows.Forms.Label labelWebsite;
|
||||
private System.Windows.Forms.Label labelVersion;
|
||||
private System.Windows.Forms.Button btnOpenConfig;
|
||||
private Core.Controls.LabelVertical labelType;
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,10 @@ using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
|
||||
namespace TweetDck.Plugins.Controls{
|
||||
namespace TweetDuck.Plugins.Controls{
|
||||
partial class PluginControl : UserControl{
|
||||
private readonly PluginManager pluginManager;
|
||||
private readonly Plugin plugin;
|
||||
@@ -30,7 +31,7 @@ namespace TweetDck.Plugins.Controls{
|
||||
labelDescription.Visible = false;
|
||||
}
|
||||
|
||||
panelDescription_Resize(panelDescription, new EventArgs());
|
||||
panelDescription_Resize(panelDescription, null);
|
||||
}
|
||||
|
||||
private void panelDescription_Resize(object sender, EventArgs e){
|
||||
@@ -61,13 +62,22 @@ namespace TweetDck.Plugins.Controls{
|
||||
}
|
||||
|
||||
private void UpdatePluginState(){
|
||||
bool isEnabled = plugin.CanRun && pluginManager.Config.IsEnabled(plugin);
|
||||
bool isEnabled = pluginManager.Config.IsEnabled(plugin) && plugin.CanRun;
|
||||
Color textColor = isEnabled ? Color.Black : Color.FromArgb(90, 90, 90);
|
||||
|
||||
labelVersion.ForeColor = textColor;
|
||||
labelAuthor.ForeColor = textColor;
|
||||
labelWebsite.ForeColor = isEnabled ? Color.Blue : Color.FromArgb(90, 90, 249);
|
||||
|
||||
if (plugin.Group == PluginGroup.Official){
|
||||
labelType.Text = "OFFICIAL";
|
||||
labelType.BackColor = isEnabled ? Color.FromArgb(154, 195, 217) : Color.FromArgb(185, 185, 185);
|
||||
}
|
||||
else{
|
||||
labelType.Text = "CUSTOM";
|
||||
labelType.BackColor = isEnabled ? Color.FromArgb(208, 154, 217) : Color.FromArgb(185, 185, 185);
|
||||
}
|
||||
|
||||
if (plugin.CanRun){
|
||||
labelName.ForeColor = textColor;
|
||||
labelDescription.ForeColor = textColor;
|
||||
|
@@ -1,3 +0,0 @@
|
||||
namespace TweetDck.Plugins.Controls{
|
||||
partial class PluginListFlowLayout{}
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
using System.Windows.Forms;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDck.Plugins.Controls{
|
||||
sealed partial class PluginListFlowLayout : FlowLayoutPanel{
|
||||
namespace TweetDuck.Plugins.Controls{
|
||||
sealed class PluginListFlowLayout : FlowLayoutPanel{
|
||||
public PluginListFlowLayout(){
|
||||
FlowDirection = FlowDirection.TopDown;
|
||||
WrapContents = false;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TweetDck.Plugins.Enums{
|
||||
namespace TweetDuck.Plugins.Enums{
|
||||
[Flags]
|
||||
enum PluginEnvironment{
|
||||
None = 0,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Plugins.Enums{
|
||||
namespace TweetDuck.Plugins.Enums{
|
||||
enum PluginFolder{
|
||||
Root, Data
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace TweetDck.Plugins.Enums{
|
||||
namespace TweetDuck.Plugins.Enums{
|
||||
enum PluginGroup{
|
||||
Official, Custom
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace TweetDck.Plugins.Events{
|
||||
namespace TweetDuck.Plugins.Events{
|
||||
class PluginChangedStateEventArgs : EventArgs{
|
||||
public Plugin Plugin { get; private set; }
|
||||
public bool IsEnabled { get; private set; }
|
||||
public Plugin Plugin { get; }
|
||||
public bool IsEnabled { get; }
|
||||
|
||||
public PluginChangedStateEventArgs(Plugin plugin, bool isEnabled){
|
||||
this.Plugin = plugin;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user