OSDN Git Service

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