OSDN Git Service

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