OSDN Git Service

Merge branch 'cleanup-settingdialog'
[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
52         private bool _ValidationError = false;
53         private long? InitialUserId;
54         private string _pin;
55
56         public AppendSettingDialog()
57         {
58             this.InitializeComponent();
59
60             this.BasedPanel.StartAuthButton.Click += this.StartAuthButton_Click;
61             this.BasedPanel.CreateAccountButton.Click += this.CreateAccountButton_Click;
62             this.GetPeriodPanel.CheckPostAndGet.CheckedChanged += this.CheckPostAndGet_CheckedChanged;
63             this.ActionPanel.UReadMng.CheckedChanged += this.UReadMng_CheckedChanged;
64
65             this.Icon = Properties.Resources.MIcon;
66         }
67
68         public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal)
69         {
70             this.BasedPanel.LoadConfig(settingCommon);
71             this.GetPeriodPanel.LoadConfig(settingCommon);
72             this.StartupPanel.LoadConfig(settingCommon);
73             this.TweetPrvPanel.LoadConfig(settingCommon);
74             this.TweetActPanel.LoadConfig(settingCommon, settingLocal);
75             this.ActionPanel.LoadConfig(settingCommon, settingLocal);
76             this.FontPanel.LoadConfig(settingLocal);
77             this.FontPanel2.LoadConfig(settingLocal);
78             this.PreviewPanel.LoadConfig(settingCommon);
79             this.GetCountPanel.LoadConfig(settingCommon);
80             this.ShortUrlPanel.LoadConfig(settingCommon);
81             this.ProxyPanel.LoadConfig(settingLocal);
82             this.CooperatePanel.LoadConfig(settingCommon);
83             this.ConnectionPanel.LoadConfig(settingCommon);
84             this.NotifyPanel.LoadConfig(settingCommon);
85
86             var activeUser = settingCommon.UserAccounts.FirstOrDefault(x => x.UserId == this.tw.UserId);
87             if (activeUser != null)
88             {
89                 this.BasedPanel.AuthUserCombo.SelectedItem = activeUser;
90                 this.InitialUserId = activeUser.UserId;
91             }
92         }
93
94         public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal)
95         {
96             this.BasedPanel.SaveConfig(settingCommon);
97             this.GetPeriodPanel.SaveConfig(settingCommon);
98             this.StartupPanel.SaveConfig(settingCommon);
99             this.TweetPrvPanel.SaveConfig(settingCommon);
100             this.TweetActPanel.SaveConfig(settingCommon, settingLocal);
101             this.ActionPanel.SaveConfig(settingCommon, settingLocal);
102             this.FontPanel.SaveConfig(settingLocal);
103             this.FontPanel2.SaveConfig(settingLocal);
104             this.PreviewPanel.SaveConfig(settingCommon);
105             this.GetCountPanel.SaveConfig(settingCommon);
106             this.ShortUrlPanel.SaveConfig(settingCommon);
107             this.ProxyPanel.SaveConfig(settingLocal);
108             this.CooperatePanel.SaveConfig(settingCommon);
109             this.ConnectionPanel.SaveConfig(settingCommon);
110             this.NotifyPanel.SaveConfig(settingCommon);
111
112             var userAccountIdx = this.BasedPanel.AuthUserCombo.SelectedIndex;
113             if (userAccountIdx != -1)
114             {
115                 var u = settingCommon.UserAccounts[userAccountIdx];
116                 this.tw.Initialize(u.Token, u.TokenSecret, u.Username, u.UserId);
117
118                 if (u.UserId == 0)
119                 {
120                     this.tw.VerifyCredentials();
121                     u.UserId = this.tw.UserId;
122                 }
123             }
124             else
125             {
126                 this.tw.ClearAuthInfo();
127                 this.tw.Initialize("", "", "", 0);
128             }
129         }
130
131         private void TreeViewSetting_BeforeSelect(object sender, TreeViewCancelEventArgs e)
132         {
133             if (this.TreeViewSetting.SelectedNode == null) return;
134             var pnl = (SettingPanelBase)this.TreeViewSetting.SelectedNode.Tag;
135             if (pnl == null) return;
136             pnl.Enabled = false;
137             pnl.Visible = false;
138         }
139
140         private void TreeViewSetting_AfterSelect(object sender, TreeViewEventArgs e)
141         {
142             if (e.Node == null) return;
143             var pnl = (SettingPanelBase)e.Node.Tag;
144             if (pnl == null) return;
145             pnl.Enabled = true;
146             pnl.Visible = true;
147
148             if (pnl.Name == "PreviewPanel")
149             {
150                 if (GrowlHelper.IsDllExists)
151                 {
152                     this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = true;
153                 }
154                 else
155                 {
156                     this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = false;
157                 }
158             }
159         }
160
161         private void Save_Click(object sender, EventArgs e)
162         {
163             if (MyCommon.IsNetworkAvailable() &&
164                 (this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex == (int)MyCommon.UrlConverter.Bitly || this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex == (int)MyCommon.UrlConverter.Jmp))
165             {
166                 // bit.ly 短縮機能実装のプライバシー問題の暫定対応
167                 // bit.ly 使用時はログインIDとAPIキーの指定を必須とする
168                 // 参照: http://sourceforge.jp/projects/opentween/lists/archive/dev/2012-January/000020.html
169                 if (string.IsNullOrEmpty(this.ShortUrlPanel.TextBitlyId.Text) || string.IsNullOrEmpty(this.ShortUrlPanel.TextBitlyPw.Text))
170                 {
171                     MessageBox.Show("bit.ly のログイン名とAPIキーの指定は必須項目です。", Application.ProductName);
172                     _ValidationError = true;
173                     TreeViewSetting.SelectedNode = TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"]; // 動作タブを選択
174                     TreeViewSetting.Select();
175                     this.ShortUrlPanel.TextBitlyId.Focus();
176                     return;
177                 }
178
179                 if (!BitlyValidation(this.ShortUrlPanel.TextBitlyId.Text, this.ShortUrlPanel.TextBitlyPw.Text))
180                 {
181                     MessageBox.Show(Properties.Resources.SettingSave_ClickText1);
182                     _ValidationError = true;
183                     TreeViewSetting.SelectedNode = TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"]; // 動作タブを選択
184                     TreeViewSetting.Select();
185                     this.ShortUrlPanel.TextBitlyId.Focus();
186                     return;
187                 }
188                 else
189                 {
190                     _ValidationError = false;
191                 }
192             }
193             else
194             {
195                 _ValidationError = false;
196             }
197         }
198
199         private void Setting_FormClosing(object sender, FormClosingEventArgs e)
200         {
201             if (MyCommon._endingFlag) return;
202
203             if (tw != null && string.IsNullOrEmpty(tw.Username) && e.CloseReason == CloseReason.None)
204             {
205                 if (MessageBox.Show(Properties.Resources.Setting_FormClosing1, "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
206                 {
207                     e.Cancel = true;
208                 }
209             }
210             if (_ValidationError)
211             {
212                 e.Cancel = true;
213             }
214             if (e.Cancel == false && TreeViewSetting.SelectedNode != null)
215             {
216                 var curPanel = (SettingPanelBase)TreeViewSetting.SelectedNode.Tag;
217                 curPanel.Visible = false;
218                 curPanel.Enabled = false;
219             }
220         }
221
222         private void Setting_Load(object sender, EventArgs e)
223         {
224             this.TreeViewSetting.Nodes["BasedNode"].Tag = BasedPanel;
225             this.TreeViewSetting.Nodes["BasedNode"].Nodes["PeriodNode"].Tag = GetPeriodPanel;
226             this.TreeViewSetting.Nodes["BasedNode"].Nodes["StartUpNode"].Tag = StartupPanel;
227             this.TreeViewSetting.Nodes["BasedNode"].Nodes["GetCountNode"].Tag = GetCountPanel;
228             this.TreeViewSetting.Nodes["ActionNode"].Tag = ActionPanel;
229             this.TreeViewSetting.Nodes["ActionNode"].Nodes["TweetActNode"].Tag = TweetActPanel;
230             this.TreeViewSetting.Nodes["PreviewNode"].Tag = PreviewPanel;
231             this.TreeViewSetting.Nodes["PreviewNode"].Nodes["TweetPrvNode"].Tag = TweetPrvPanel;
232             this.TreeViewSetting.Nodes["PreviewNode"].Nodes["NotifyNode"].Tag = NotifyPanel;
233             this.TreeViewSetting.Nodes["FontNode"].Tag = FontPanel;
234             this.TreeViewSetting.Nodes["FontNode"].Nodes["FontNode2"].Tag = FontPanel2;
235             this.TreeViewSetting.Nodes["ConnectionNode"].Tag = ConnectionPanel;
236             this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["ProxyNode"].Tag = ProxyPanel;
237             this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["CooperateNode"].Tag = CooperatePanel;
238             this.TreeViewSetting.Nodes["ConnectionNode"].Nodes["ShortUrlNode"].Tag = ShortUrlPanel;
239
240             this.TreeViewSetting.SelectedNode = this.TreeViewSetting.Nodes[0];
241             this.TreeViewSetting.ExpandAll();
242
243             ActiveControl = BasedPanel.StartAuthButton;
244         }
245
246         private void UReadMng_CheckedChanged(object sender, EventArgs e)
247         {
248             if (this.ActionPanel.UReadMng.Checked == true)
249             {
250                 this.StartupPanel.StartupReaded.Enabled = true;
251             }
252             else
253             {
254                 this.StartupPanel.StartupReaded.Enabled = false;
255             }
256         }
257
258         private bool StartAuth()
259         {
260             //現在の設定内容で通信
261             ProxyType ptype;
262             if (this.ProxyPanel.RadioProxyNone.Checked)
263             {
264                 ptype = ProxyType.None;
265             }
266             else if (this.ProxyPanel.RadioProxyIE.Checked)
267             {
268                 ptype = ProxyType.IE;
269             }
270             else
271             {
272                 ptype = ProxyType.Specified;
273             }
274             string padr = this.ProxyPanel.TextProxyAddress.Text.Trim();
275             int pport = int.Parse(this.ProxyPanel.TextProxyPort.Text.Trim());
276             string pusr = this.ProxyPanel.TextProxyUser.Text.Trim();
277             string ppw = this.ProxyPanel.TextProxyPassword.Text.Trim();
278
279             //通信基底クラス初期化
280             Networking.DefaultTimeout = TimeSpan.FromSeconds(20);
281             Networking.SetWebProxy(ptype, padr, pport, pusr, ppw);
282             HttpTwitter.TwitterUrl = this.ConnectionPanel.TwitterAPIText.Text.Trim();
283             tw.Initialize("", "", "", 0);
284             string pinPageUrl = "";
285             string rslt = tw.StartAuthentication(ref pinPageUrl);
286             if (string.IsNullOrEmpty(rslt))
287             {
288                 string pin = AuthDialog.DoAuth(this, pinPageUrl);
289                 if (!string.IsNullOrEmpty(pin))
290                 {
291                     this._pin = pin;
292                     return true;
293                 }
294                 else
295                 {
296                     return false;
297                 }
298             }
299             else
300             {
301                 MessageBox.Show(Properties.Resources.AuthorizeButton_Click2 + Environment.NewLine + rslt, "Authenticate", MessageBoxButtons.OK);
302                 return false;
303             }
304         }
305
306         private bool PinAuth()
307         {
308             string pin = this._pin;   //PIN Code
309
310             string rslt = tw.Authenticate(pin);
311             if (string.IsNullOrEmpty(rslt))
312             {
313                 MessageBox.Show(Properties.Resources.AuthorizeButton_Click1, "Authenticate", MessageBoxButtons.OK);
314                 int idx = -1;
315                 UserAccount user = new UserAccount();
316                 user.Username = tw.Username;
317                 user.UserId = tw.UserId;
318                 user.Token = tw.AccessToken;
319                 user.TokenSecret = tw.AccessTokenSecret;
320
321                 foreach (object u in this.BasedPanel.AuthUserCombo.Items)
322                 {
323                     if (((UserAccount)u).Username.ToLower() == tw.Username.ToLower())
324                     {
325                         idx = this.BasedPanel.AuthUserCombo.Items.IndexOf(u);
326                         break;
327                     }
328                 }
329                 if (idx > -1)
330                 {
331                     this.BasedPanel.AuthUserCombo.Items.RemoveAt(idx);
332                     this.BasedPanel.AuthUserCombo.Items.Insert(idx, user);
333                     this.BasedPanel.AuthUserCombo.SelectedIndex = idx;
334                 }
335                 else
336                 {
337                     this.BasedPanel.AuthUserCombo.SelectedIndex = this.BasedPanel.AuthUserCombo.Items.Add(user);
338                 }
339                 return true;
340             }
341             else
342             {
343                 MessageBox.Show(Properties.Resources.AuthorizeButton_Click2 + Environment.NewLine + rslt, "Authenticate", MessageBoxButtons.OK);
344                 return false;
345             }
346         }
347
348         private void StartAuthButton_Click(object sender, EventArgs e)
349         {
350             if (StartAuth())
351             {
352                 if (PinAuth())
353                 {
354                 }
355             }
356         }
357
358         private void CheckPostAndGet_CheckedChanged(object sender, EventArgs e)
359         {
360             this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamEnabled;
361         }
362
363         private void Setting_Shown(object sender, EventArgs e)
364         {
365             do
366             {
367                 Thread.Sleep(10);
368                 if (this.Disposing || this.IsDisposed) return;
369             } while (!this.IsHandleCreated);
370             this.TopMost = this.PreviewPanel.CheckAlwaysTop.Checked;
371
372             this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamEnabled;
373             this.GetPeriodPanel.LabelUserStreamActive.Visible = tw.UserStreamEnabled;
374         }
375
376         private bool BitlyValidation(string id, string apikey)
377         {
378             if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(apikey))
379             {
380                 return false;
381             }
382
383             string req = "http://api.bit.ly/v3/validate";
384             string content = "";
385             Dictionary<string, string> param = new Dictionary<string, string>();
386
387             param.Add("login", ApplicationSettings.BitlyLoginId);
388             param.Add("apiKey", ApplicationSettings.BitlyApiKey);
389             param.Add("x_login", id);
390             param.Add("x_apiKey", apikey);
391             param.Add("format", "txt");
392
393             if (!(new HttpVarious()).PostData(req, param, out content))
394             {
395                 return true;             // 通信エラーの場合はとりあえずチェックを通ったことにする
396             }
397             else if (content.Trim() == "1")
398             {
399                 return true;             // 検証成功
400             }
401             else if (content.Trim() == "0")
402             {
403                 return false;            // 検証失敗 APIキーとIDの組み合わせが違う
404             }
405             else
406             {
407                 return true;             // 規定外応答:通信エラーの可能性があるためとりあえずチェックを通ったことにする
408             }
409         }
410
411         private void Cancel_Click(object sender, EventArgs e)
412         {
413             _ValidationError = false;
414         }
415
416         private void OpenUrl(string url)
417         {
418             string myPath = url;
419             string path = this.ActionPanel.BrowserPathText.Text;
420             try
421             {
422                 if (!string.IsNullOrEmpty(path))
423                 {
424                     if (path.StartsWith("\"") && path.Length > 2 && path.IndexOf("\"", 2) > -1)
425                     {
426                         int sep = path.IndexOf("\"", 2);
427                         string browserPath = path.Substring(1, sep - 1);
428                         string arg = "";
429                         if (sep < path.Length - 1)
430                         {
431                             arg = path.Substring(sep + 1);
432                         }
433                         myPath = arg + " " + myPath;
434                         System.Diagnostics.Process.Start(browserPath, myPath);
435                     }
436                     else
437                     {
438                         System.Diagnostics.Process.Start(path, myPath);
439                     }
440                 }
441                 else
442                 {
443                     System.Diagnostics.Process.Start(myPath);
444                 }
445             }
446             catch(Exception)
447             {
448             }
449         }
450
451         private void CreateAccountButton_Click(object sender, EventArgs e)
452         {
453             this.OpenUrl("https://twitter.com/signup");
454         }
455
456         private void GetPeriodPanel_IntervalChanged(object sender, IntervalChangedEventArgs e)
457         {
458             if (this.IntervalChanged != null)
459                 this.IntervalChanged(sender, e);
460         }
461     }
462
463     public class IntervalChangedEventArgs : EventArgs
464     {
465         public bool UserStream;
466         public bool Timeline;
467         public bool Reply;
468         public bool DirectMessage;
469         public bool PublicSearch;
470         public bool Lists;
471         public bool UserTimeline;
472     }
473 }