OSDN Git Service

AppendSettingDialog.SaveConfig内でのVerifyCredentialsの呼び出しを削除
[opentween/open-tween.git] / OpenTween / AppendSettingDialog.cs
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.
9 // 
10 // This file is part of OpenTween.
11 // 
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)
15 // any later version.
16 // 
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
20 // for more details. 
21 // 
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.
26
27 using System;
28 using System.Collections.Generic;
29 using System.ComponentModel;
30 using System.Data;
31 using System.Drawing;
32 using System.Linq;
33 using System.Text;
34 using System.Windows.Forms;
35 using System.Threading;
36 using System.IO;
37 using System.Resources;
38 using OpenTween.Api;
39 using OpenTween.Connection;
40 using OpenTween.Thumbnail;
41 using System.Threading.Tasks;
42 using OpenTween.Setting.Panel;
43
44 namespace OpenTween
45 {
46     public partial class AppendSettingDialog : OTBaseForm
47     {
48         public event EventHandler<IntervalChangedEventArgs> IntervalChanged;
49
50         internal Twitter tw;
51         internal TwitterApi twitterApi;
52
53         private bool _ValidationError = false;
54
55         public AppendSettingDialog()
56         {
57             this.InitializeComponent();
58
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;
63
64             this.Icon = Properties.Resources.MIcon;
65         }
66
67         public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal)
68         {
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);
84
85             var activeUser = settingCommon.UserAccounts.FirstOrDefault(x => x.UserId == this.tw.UserId);
86             if (activeUser != null)
87             {
88                 this.BasedPanel.AuthUserCombo.SelectedItem = activeUser;
89             }
90         }
91
92         public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal)
93         {
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);
109
110             var userAccountIdx = this.BasedPanel.AuthUserCombo.SelectedIndex;
111             if (userAccountIdx != -1)
112             {
113                 var u = settingCommon.UserAccounts[userAccountIdx];
114                 this.tw.Initialize(u.Token, u.TokenSecret, u.Username, u.UserId);
115             }
116             else
117             {
118                 this.tw.ClearAuthInfo();
119                 this.tw.Initialize("", "", "", 0);
120             }
121         }
122
123         private void TreeViewSetting_BeforeSelect(object sender, TreeViewCancelEventArgs e)
124         {
125             if (this.TreeViewSetting.SelectedNode == null) return;
126             var pnl = (SettingPanelBase)this.TreeViewSetting.SelectedNode.Tag;
127             if (pnl == null) return;
128             pnl.Enabled = false;
129             pnl.Visible = false;
130         }
131
132         private void TreeViewSetting_AfterSelect(object sender, TreeViewEventArgs e)
133         {
134             if (e.Node == null) return;
135             var pnl = (SettingPanelBase)e.Node.Tag;
136             if (pnl == null) return;
137             pnl.Enabled = true;
138             pnl.Visible = true;
139
140             if (pnl.Name == "PreviewPanel")
141             {
142                 if (GrowlHelper.IsDllExists)
143                 {
144                     this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = true;
145                 }
146                 else
147                 {
148                     this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = false;
149                 }
150             }
151         }
152
153         private void Save_Click(object sender, EventArgs e)
154         {
155             if (MyCommon.IsNetworkAvailable() &&
156                 (this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex == (int)MyCommon.UrlConverter.Bitly || this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex == (int)MyCommon.UrlConverter.Jmp))
157             {
158                 // bit.ly 短縮機能実装のプライバシー問題の暫定対応
159                 // bit.ly 使用時はログインIDとAPIキーの指定を必須とする
160                 // 参照: http://sourceforge.jp/projects/opentween/lists/archive/dev/2012-January/000020.html
161                 if (string.IsNullOrEmpty(this.ShortUrlPanel.TextBitlyId.Text) || string.IsNullOrEmpty(this.ShortUrlPanel.TextBitlyPw.Text))
162                 {
163                     MessageBox.Show("bit.ly のログイン名とAPIキーの指定は必須項目です。", Application.ProductName);
164                     _ValidationError = true;
165                     TreeViewSetting.SelectedNode = TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"]; // 動作タブを選択
166                     TreeViewSetting.Select();
167                     this.ShortUrlPanel.TextBitlyId.Focus();
168                     return;
169                 }
170
171                 if (!BitlyValidation(this.ShortUrlPanel.TextBitlyId.Text, this.ShortUrlPanel.TextBitlyPw.Text))
172                 {
173                     MessageBox.Show(Properties.Resources.SettingSave_ClickText1);
174                     _ValidationError = true;
175                     TreeViewSetting.SelectedNode = TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"]; // 動作タブを選択
176                     TreeViewSetting.Select();
177                     this.ShortUrlPanel.TextBitlyId.Focus();
178                     return;
179                 }
180                 else
181                 {
182                     _ValidationError = false;
183                 }
184             }
185             else
186             {
187                 _ValidationError = false;
188             }
189         }
190
191         private void Setting_FormClosing(object sender, FormClosingEventArgs e)
192         {
193             if (MyCommon._endingFlag) return;
194
195             if (this.BasedPanel.AuthUserCombo.SelectedIndex == -1 && e.CloseReason == CloseReason.None)
196             {
197                 if (MessageBox.Show(Properties.Resources.Setting_FormClosing1, "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
198                 {
199                     e.Cancel = true;
200                 }
201             }
202             if (_ValidationError)
203             {
204                 e.Cancel = true;
205             }
206             if (e.Cancel == false && TreeViewSetting.SelectedNode != null)
207             {
208                 var curPanel = (SettingPanelBase)TreeViewSetting.SelectedNode.Tag;
209                 curPanel.Visible = false;
210                 curPanel.Enabled = false;
211             }
212         }
213
214         private void Setting_Load(object sender, EventArgs e)
215         {
216             this.TreeViewSetting.Nodes["BasedNode"].Tag = BasedPanel;
217             this.TreeViewSetting.Nodes["BasedNode"].Nodes["PeriodNode"].Tag = GetPeriodPanel;
218             this.TreeViewSetting.Nodes["BasedNode"].Nodes["StartUpNode"].Tag = StartupPanel;
219             this.TreeViewSetting.Nodes["BasedNode"].Nodes["GetCountNode"].Tag = GetCountPanel;
220             this.TreeViewSetting.Nodes["ActionNode"].Tag = ActionPanel;
221             this.TreeViewSetting.Nodes["ActionNode"].Nodes["TweetActNode"].Tag = TweetActPanel;
222             this.TreeViewSetting.Nodes["PreviewNode"].Tag = PreviewPanel;
223             this.TreeViewSetting.Nodes["PreviewNode"].Nodes["TweetPrvNode"].Tag = TweetPrvPanel;
224             this.TreeViewSetting.Nodes["PreviewNode"].Nodes["NotifyNode"].Tag = NotifyPanel;
225             this.TreeViewSetting.Nodes["FontNode"].Tag = FontPanel;
226             this.TreeViewSetting.Nodes["FontNode"].Nodes["FontNode2"].Tag = FontPanel2;
227             this.TreeViewSetting.Nodes["ConnectionNode"].Tag = ConnectionPanel;
228             this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["ProxyNode"].Tag = ProxyPanel;
229             this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["CooperateNode"].Tag = CooperatePanel;
230             this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"].Tag = ShortUrlPanel;
231
232             this.TreeViewSetting.SelectedNode = this.TreeViewSetting.Nodes[0];
233             this.TreeViewSetting.ExpandAll();
234
235             ActiveControl = BasedPanel.StartAuthButton;
236         }
237
238         private void UReadMng_CheckedChanged(object sender, EventArgs e)
239         {
240             if (this.ActionPanel.UReadMng.Checked == true)
241             {
242                 this.StartupPanel.StartupReaded.Enabled = true;
243             }
244             else
245             {
246                 this.StartupPanel.StartupReaded.Enabled = false;
247             }
248         }
249
250         private async void StartAuthButton_Click(object sender, EventArgs e)
251         {
252             using (ControlTransaction.Disabled(this.BasedPanel.StartAuthButton))
253             {
254                 try
255                 {
256                     this.ApplyNetworkSettings();
257
258                     var newAccount = await this.PinAuth();
259                     if (newAccount == null)
260                         return;
261
262                     var authUserCombo = this.BasedPanel.AuthUserCombo;
263
264                     var oldAccount = authUserCombo.Items.Cast<UserAccount>()
265                         .FirstOrDefault(x => x.UserId == this.tw.UserId);
266
267                     int idx;
268                     if (oldAccount != null)
269                     {
270                         idx = authUserCombo.Items.IndexOf(oldAccount);
271                         authUserCombo.Items[idx] = newAccount;
272                     }
273                     else
274                     {
275                         idx = authUserCombo.Items.Add(newAccount);
276                     }
277
278                     authUserCombo.SelectedIndex = idx;
279
280                     MessageBox.Show(this, Properties.Resources.AuthorizeButton_Click1,
281                         "Authenticate", MessageBoxButtons.OK);
282                 }
283                 catch (WebApiException ex)
284                 {
285                     var message = Properties.Resources.AuthorizeButton_Click2 + Environment.NewLine + ex.Message;
286                     MessageBox.Show(this, message, "Authenticate", MessageBoxButtons.OK);
287                 }
288             }
289         }
290
291         /// <summary>
292         /// 現在設定画面に入力されているネットワーク関係の設定を適用します
293         /// </summary>
294         public void ApplyNetworkSettings()
295         {
296             ProxyType proxyType;
297             if (this.ProxyPanel.RadioProxyNone.Checked)
298                 proxyType = ProxyType.None;
299             else if (this.ProxyPanel.RadioProxyIE.Checked)
300                 proxyType = ProxyType.IE;
301             else
302                 proxyType = ProxyType.Specified;
303
304             var proxyAddress = this.ProxyPanel.TextProxyAddress.Text.Trim();
305             var proxyPort = int.Parse(this.ProxyPanel.TextProxyPort.Text.Trim());
306             var proxyUser = this.ProxyPanel.TextProxyUser.Text.Trim();
307             var proxyPassword = this.ProxyPanel.TextProxyPassword.Text.Trim();
308             Networking.SetWebProxy(proxyType, proxyAddress, proxyPort, proxyUser, proxyPassword);
309
310             var timeout = int.Parse(this.ConnectionPanel.ConnectionTimeOut.Text.Trim());
311             Networking.DefaultTimeout = TimeSpan.FromSeconds(timeout);
312
313             Networking.ForceIPv4 = this.ConnectionPanel.checkBoxForceIPv4.Checked;
314
315             HttpTwitter.TwitterUrl = this.ConnectionPanel.TwitterAPIText.Text.Trim();
316         }
317
318         private async Task<UserAccount> PinAuth()
319         {
320             var requestToken = await TwitterApiConnection.GetRequestTokenAsync();
321
322             var pinPageUrl = TwitterApiConnection.GetAuthorizeUri(requestToken);
323
324             var pin = AuthDialog.DoAuth(this, pinPageUrl);
325             if (string.IsNullOrEmpty(pin))
326                 return null; // キャンセルされた場合
327
328             var accessTokenResponse = await TwitterApiConnection.GetAccessTokenAsync(requestToken, pin);
329
330             return new UserAccount
331             {
332                 Username = accessTokenResponse["screen_name"],
333                 UserId = long.Parse(accessTokenResponse["user_id"]),
334                 Token = accessTokenResponse["oauth_token"],
335                 TokenSecret = accessTokenResponse["oauth_token_secret"],
336             };
337         }
338
339         private void CheckPostAndGet_CheckedChanged(object sender, EventArgs e)
340         {
341             this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamActive;
342         }
343
344         private void Setting_Shown(object sender, EventArgs e)
345         {
346             do
347             {
348                 Thread.Sleep(10);
349                 if (this.Disposing || this.IsDisposed) return;
350             } while (!this.IsHandleCreated);
351             this.TopMost = this.PreviewPanel.CheckAlwaysTop.Checked;
352
353             this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamActive;
354             this.GetPeriodPanel.LabelUserStreamActive.Visible = tw.UserStreamActive;
355         }
356
357         private bool BitlyValidation(string id, string apikey)
358         {
359             if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(apikey))
360             {
361                 return false;
362             }
363
364             string req = "http://api.bit.ly/v3/validate";
365             string content = "";
366             Dictionary<string, string> param = new Dictionary<string, string>();
367
368             param.Add("login", ApplicationSettings.BitlyLoginId);
369             param.Add("apiKey", ApplicationSettings.BitlyApiKey);
370             param.Add("x_login", id);
371             param.Add("x_apiKey", apikey);
372             param.Add("format", "txt");
373
374             if (!(new HttpVarious()).PostData(req, param, out content))
375             {
376                 return true;             // 通信エラーの場合はとりあえずチェックを通ったことにする
377             }
378             else if (content.Trim() == "1")
379             {
380                 return true;             // 検証成功
381             }
382             else if (content.Trim() == "0")
383             {
384                 return false;            // 検証失敗 APIキーとIDの組み合わせが違う
385             }
386             else
387             {
388                 return true;             // 規定外応答:通信エラーの可能性があるためとりあえずチェックを通ったことにする
389             }
390         }
391
392         private void Cancel_Click(object sender, EventArgs e)
393         {
394             _ValidationError = false;
395         }
396
397         private void OpenUrl(string url)
398         {
399             string myPath = url;
400             string path = this.ActionPanel.BrowserPathText.Text;
401             try
402             {
403                 if (!string.IsNullOrEmpty(path))
404                 {
405                     if (path.StartsWith("\"", StringComparison.Ordinal) && path.Length > 2 && path.IndexOf("\"", 2, StringComparison.Ordinal) > -1)
406                     {
407                         int sep = path.IndexOf("\"", 2, StringComparison.Ordinal);
408                         string browserPath = path.Substring(1, sep - 1);
409                         string arg = "";
410                         if (sep < path.Length - 1)
411                         {
412                             arg = path.Substring(sep + 1);
413                         }
414                         myPath = arg + " " + myPath;
415                         System.Diagnostics.Process.Start(browserPath, myPath);
416                     }
417                     else
418                     {
419                         System.Diagnostics.Process.Start(path, myPath);
420                     }
421                 }
422                 else
423                 {
424                     System.Diagnostics.Process.Start(myPath);
425                 }
426             }
427             catch(Exception)
428             {
429             }
430         }
431
432         private void CreateAccountButton_Click(object sender, EventArgs e)
433         {
434             this.OpenUrl("https://twitter.com/signup");
435         }
436
437         private void GetPeriodPanel_IntervalChanged(object sender, IntervalChangedEventArgs e)
438         {
439             this.IntervalChanged?.Invoke(sender, e);
440         }
441     }
442
443     public class IntervalChangedEventArgs : EventArgs
444     {
445         public bool UserStream;
446         public bool Timeline;
447         public bool Reply;
448         public bool DirectMessage;
449         public bool PublicSearch;
450         public bool Lists;
451         public bool UserTimeline;
452
453         public static IntervalChangedEventArgs ResetAll
454         {
455             get
456             {
457                 return new IntervalChangedEventArgs()
458                 {
459                     UserStream = true,
460                     Timeline = true,
461                     Reply = true,
462                     DirectMessage = true,
463                     PublicSearch = true,
464                     Lists = true,
465                     UserTimeline = true,
466                 };
467             }
468         }
469     }
470 }