1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 // (c) 2008-2011 Moz (@syo68k)
4 // (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 // (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 // (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 // (c) 2011 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
10 // This file is part of OpenTween.
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General Public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
28 using System.Collections.Generic;
29 using System.ComponentModel;
34 using System.Windows.Forms;
35 using System.Threading;
37 using System.Resources;
39 using OpenTween.Connection;
40 using OpenTween.Thumbnail;
41 using System.Threading.Tasks;
42 using OpenTween.Setting.Panel;
46 public partial class AppendSettingDialog : OTBaseForm
48 public event EventHandler<IntervalChangedEventArgs> IntervalChanged;
51 internal TwitterApi twitterApi;
53 private bool _ValidationError = false;
55 public AppendSettingDialog()
57 this.InitializeComponent();
59 this.BasedPanel.StartAuthButton.Click += this.StartAuthButton_Click;
60 this.BasedPanel.CreateAccountButton.Click += this.CreateAccountButton_Click;
61 this.GetPeriodPanel.CheckPostAndGet.CheckedChanged += this.CheckPostAndGet_CheckedChanged;
62 this.ActionPanel.UReadMng.CheckedChanged += this.UReadMng_CheckedChanged;
64 this.Icon = Properties.Resources.MIcon;
67 public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal)
69 this.BasedPanel.LoadConfig(settingCommon);
70 this.GetPeriodPanel.LoadConfig(settingCommon);
71 this.StartupPanel.LoadConfig(settingCommon);
72 this.TweetPrvPanel.LoadConfig(settingCommon);
73 this.TweetActPanel.LoadConfig(settingCommon, settingLocal);
74 this.ActionPanel.LoadConfig(settingCommon, settingLocal);
75 this.FontPanel.LoadConfig(settingLocal);
76 this.FontPanel2.LoadConfig(settingLocal);
77 this.PreviewPanel.LoadConfig(settingCommon);
78 this.GetCountPanel.LoadConfig(settingCommon);
79 this.ShortUrlPanel.LoadConfig(settingCommon);
80 this.ProxyPanel.LoadConfig(settingLocal);
81 this.CooperatePanel.LoadConfig(settingCommon);
82 this.ConnectionPanel.LoadConfig(settingCommon);
83 this.NotifyPanel.LoadConfig(settingCommon);
85 var activeUser = settingCommon.UserAccounts.FirstOrDefault(x => x.UserId == this.tw.UserId);
86 if (activeUser != null)
88 this.BasedPanel.AuthUserCombo.SelectedItem = activeUser;
92 public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal)
94 this.BasedPanel.SaveConfig(settingCommon);
95 this.GetPeriodPanel.SaveConfig(settingCommon);
96 this.StartupPanel.SaveConfig(settingCommon);
97 this.TweetPrvPanel.SaveConfig(settingCommon);
98 this.TweetActPanel.SaveConfig(settingCommon, settingLocal);
99 this.ActionPanel.SaveConfig(settingCommon, settingLocal);
100 this.FontPanel.SaveConfig(settingLocal);
101 this.FontPanel2.SaveConfig(settingLocal);
102 this.PreviewPanel.SaveConfig(settingCommon);
103 this.GetCountPanel.SaveConfig(settingCommon);
104 this.ShortUrlPanel.SaveConfig(settingCommon);
105 this.ProxyPanel.SaveConfig(settingLocal);
106 this.CooperatePanel.SaveConfig(settingCommon);
107 this.ConnectionPanel.SaveConfig(settingCommon);
108 this.NotifyPanel.SaveConfig(settingCommon);
110 var userAccountIdx = this.BasedPanel.AuthUserCombo.SelectedIndex;
111 if (userAccountIdx != -1)
113 var u = settingCommon.UserAccounts[userAccountIdx];
114 this.tw.Initialize(u.Token, u.TokenSecret, u.Username, u.UserId);
118 this.tw.VerifyCredentials();
119 u.UserId = this.tw.UserId;
124 this.tw.ClearAuthInfo();
125 this.tw.Initialize("", "", "", 0);
129 private void TreeViewSetting_BeforeSelect(object sender, TreeViewCancelEventArgs e)
131 if (this.TreeViewSetting.SelectedNode == null) return;
132 var pnl = (SettingPanelBase)this.TreeViewSetting.SelectedNode.Tag;
133 if (pnl == null) return;
138 private void TreeViewSetting_AfterSelect(object sender, TreeViewEventArgs e)
140 if (e.Node == null) return;
141 var pnl = (SettingPanelBase)e.Node.Tag;
142 if (pnl == null) return;
146 if (pnl.Name == "PreviewPanel")
148 if (GrowlHelper.IsDllExists)
150 this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = true;
154 this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = false;
159 private void Save_Click(object sender, EventArgs e)
161 if (MyCommon.IsNetworkAvailable() &&
162 (this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex == (int)MyCommon.UrlConverter.Bitly || this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex == (int)MyCommon.UrlConverter.Jmp))
164 // bit.ly 短縮機能実装のプライバシー問題の暫定対応
165 // bit.ly 使用時はログインIDとAPIキーの指定を必須とする
166 // 参照: http://sourceforge.jp/projects/opentween/lists/archive/dev/2012-January/000020.html
167 if (string.IsNullOrEmpty(this.ShortUrlPanel.TextBitlyId.Text) || string.IsNullOrEmpty(this.ShortUrlPanel.TextBitlyPw.Text))
169 MessageBox.Show("bit.ly のログイン名とAPIキーの指定は必須項目です。", Application.ProductName);
170 _ValidationError = true;
171 TreeViewSetting.SelectedNode = TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"]; // 動作タブを選択
172 TreeViewSetting.Select();
173 this.ShortUrlPanel.TextBitlyId.Focus();
177 if (!BitlyValidation(this.ShortUrlPanel.TextBitlyId.Text, this.ShortUrlPanel.TextBitlyPw.Text))
179 MessageBox.Show(Properties.Resources.SettingSave_ClickText1);
180 _ValidationError = true;
181 TreeViewSetting.SelectedNode = TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"]; // 動作タブを選択
182 TreeViewSetting.Select();
183 this.ShortUrlPanel.TextBitlyId.Focus();
188 _ValidationError = false;
193 _ValidationError = false;
197 private void Setting_FormClosing(object sender, FormClosingEventArgs e)
199 if (MyCommon._endingFlag) return;
201 if (this.BasedPanel.AuthUserCombo.SelectedIndex == -1 && e.CloseReason == CloseReason.None)
203 if (MessageBox.Show(Properties.Resources.Setting_FormClosing1, "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
208 if (_ValidationError)
212 if (e.Cancel == false && TreeViewSetting.SelectedNode != null)
214 var curPanel = (SettingPanelBase)TreeViewSetting.SelectedNode.Tag;
215 curPanel.Visible = false;
216 curPanel.Enabled = false;
220 private void Setting_Load(object sender, EventArgs e)
222 this.TreeViewSetting.Nodes["BasedNode"].Tag = BasedPanel;
223 this.TreeViewSetting.Nodes["BasedNode"].Nodes["PeriodNode"].Tag = GetPeriodPanel;
224 this.TreeViewSetting.Nodes["BasedNode"].Nodes["StartUpNode"].Tag = StartupPanel;
225 this.TreeViewSetting.Nodes["BasedNode"].Nodes["GetCountNode"].Tag = GetCountPanel;
226 this.TreeViewSetting.Nodes["ActionNode"].Tag = ActionPanel;
227 this.TreeViewSetting.Nodes["ActionNode"].Nodes["TweetActNode"].Tag = TweetActPanel;
228 this.TreeViewSetting.Nodes["PreviewNode"].Tag = PreviewPanel;
229 this.TreeViewSetting.Nodes["PreviewNode"].Nodes["TweetPrvNode"].Tag = TweetPrvPanel;
230 this.TreeViewSetting.Nodes["PreviewNode"].Nodes["NotifyNode"].Tag = NotifyPanel;
231 this.TreeViewSetting.Nodes["FontNode"].Tag = FontPanel;
232 this.TreeViewSetting.Nodes["FontNode"].Nodes["FontNode2"].Tag = FontPanel2;
233 this.TreeViewSetting.Nodes["ConnectionNode"].Tag = ConnectionPanel;
234 this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["ProxyNode"].Tag = ProxyPanel;
235 this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["CooperateNode"].Tag = CooperatePanel;
236 this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"].Tag = ShortUrlPanel;
238 this.TreeViewSetting.SelectedNode = this.TreeViewSetting.Nodes[0];
239 this.TreeViewSetting.ExpandAll();
241 ActiveControl = BasedPanel.StartAuthButton;
244 private void UReadMng_CheckedChanged(object sender, EventArgs e)
246 if (this.ActionPanel.UReadMng.Checked == true)
248 this.StartupPanel.StartupReaded.Enabled = true;
252 this.StartupPanel.StartupReaded.Enabled = false;
256 private void StartAuthButton_Click(object sender, EventArgs e)
260 this.ApplyNetworkSettings();
262 var newAccount = this.PinAuth();
263 if (newAccount == null)
266 var authUserCombo = this.BasedPanel.AuthUserCombo;
268 var oldAccount = authUserCombo.Items.Cast<UserAccount>()
269 .FirstOrDefault(x => x.UserId == this.tw.UserId);
272 if (oldAccount != null)
274 idx = authUserCombo.Items.IndexOf(oldAccount);
275 authUserCombo.Items[idx] = newAccount;
279 idx = authUserCombo.Items.Add(newAccount);
282 authUserCombo.SelectedIndex = idx;
284 MessageBox.Show(this, Properties.Resources.AuthorizeButton_Click1,
285 "Authenticate", MessageBoxButtons.OK);
287 catch (WebApiException ex)
289 var message = Properties.Resources.AuthorizeButton_Click2 + Environment.NewLine + ex.Message;
290 MessageBox.Show(this, message, "Authenticate", MessageBoxButtons.OK);
295 /// 現在設定画面に入力されているネットワーク関係の設定を適用します
297 public void ApplyNetworkSettings()
300 if (this.ProxyPanel.RadioProxyNone.Checked)
301 proxyType = ProxyType.None;
302 else if (this.ProxyPanel.RadioProxyIE.Checked)
303 proxyType = ProxyType.IE;
305 proxyType = ProxyType.Specified;
307 var proxyAddress = this.ProxyPanel.TextProxyAddress.Text.Trim();
308 var proxyPort = int.Parse(this.ProxyPanel.TextProxyPort.Text.Trim());
309 var proxyUser = this.ProxyPanel.TextProxyUser.Text.Trim();
310 var proxyPassword = this.ProxyPanel.TextProxyPassword.Text.Trim();
311 Networking.SetWebProxy(proxyType, proxyAddress, proxyPort, proxyUser, proxyPassword);
313 var timeout = int.Parse(this.ConnectionPanel.ConnectionTimeOut.Text.Trim());
314 Networking.DefaultTimeout = TimeSpan.FromSeconds(timeout);
316 Networking.ForceIPv4 = this.ConnectionPanel.checkBoxForceIPv4.Checked;
318 HttpTwitter.TwitterUrl = this.ConnectionPanel.TwitterAPIText.Text.Trim();
321 private UserAccount PinAuth()
323 this.tw.Initialize("", "", "", 0);
325 var pinPageUrl = this.tw.StartAuthentication();
327 var pin = AuthDialog.DoAuth(this, pinPageUrl);
328 if (string.IsNullOrEmpty(pin))
329 return null; // キャンセルされた場合
331 this.tw.Authenticate(pin);
333 return new UserAccount
335 Username = this.tw.Username,
336 UserId = this.tw.UserId,
337 Token = this.tw.AccessToken,
338 TokenSecret = this.tw.AccessTokenSecret,
342 private void CheckPostAndGet_CheckedChanged(object sender, EventArgs e)
344 this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamActive;
347 private void Setting_Shown(object sender, EventArgs e)
352 if (this.Disposing || this.IsDisposed) return;
353 } while (!this.IsHandleCreated);
354 this.TopMost = this.PreviewPanel.CheckAlwaysTop.Checked;
356 this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamActive;
357 this.GetPeriodPanel.LabelUserStreamActive.Visible = tw.UserStreamActive;
360 private bool BitlyValidation(string id, string apikey)
362 if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(apikey))
367 string req = "http://api.bit.ly/v3/validate";
369 Dictionary<string, string> param = new Dictionary<string, string>();
371 param.Add("login", ApplicationSettings.BitlyLoginId);
372 param.Add("apiKey", ApplicationSettings.BitlyApiKey);
373 param.Add("x_login", id);
374 param.Add("x_apiKey", apikey);
375 param.Add("format", "txt");
377 if (!(new HttpVarious()).PostData(req, param, out content))
379 return true; // 通信エラーの場合はとりあえずチェックを通ったことにする
381 else if (content.Trim() == "1")
385 else if (content.Trim() == "0")
387 return false; // 検証失敗 APIキーとIDの組み合わせが違う
391 return true; // 規定外応答:通信エラーの可能性があるためとりあえずチェックを通ったことにする
395 private void Cancel_Click(object sender, EventArgs e)
397 _ValidationError = false;
400 private void OpenUrl(string url)
403 string path = this.ActionPanel.BrowserPathText.Text;
406 if (!string.IsNullOrEmpty(path))
408 if (path.StartsWith("\"", StringComparison.Ordinal) && path.Length > 2 && path.IndexOf("\"", 2, StringComparison.Ordinal) > -1)
410 int sep = path.IndexOf("\"", 2, StringComparison.Ordinal);
411 string browserPath = path.Substring(1, sep - 1);
413 if (sep < path.Length - 1)
415 arg = path.Substring(sep + 1);
417 myPath = arg + " " + myPath;
418 System.Diagnostics.Process.Start(browserPath, myPath);
422 System.Diagnostics.Process.Start(path, myPath);
427 System.Diagnostics.Process.Start(myPath);
435 private void CreateAccountButton_Click(object sender, EventArgs e)
437 this.OpenUrl("https://twitter.com/signup");
440 private void GetPeriodPanel_IntervalChanged(object sender, IntervalChangedEventArgs e)
442 this.IntervalChanged?.Invoke(sender, e);
446 public class IntervalChangedEventArgs : EventArgs
448 public bool UserStream;
449 public bool Timeline;
451 public bool DirectMessage;
452 public bool PublicSearch;
454 public bool UserTimeline;
456 public static IntervalChangedEventArgs ResetAll
460 return new IntervalChangedEventArgs()
465 DirectMessage = true,