OSDN Git Service

自動プロパティを使用する (IDE0032)
[opentween/open-tween.git] / OpenTween / HashtagManage.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) 2012      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.Globalization;
33 using System.Linq;
34 using System.Text;
35 using System.Windows.Forms;
36
37 namespace OpenTween
38 {
39     public partial class HashtagManage : OTBaseForm
40     {
41         public string UseHash { get; private set; } = "";
42         public bool IsPermanent { get; private set; } = false;
43         public bool IsHead { get; private set; } = false;
44         public bool IsNotAddToAtReply { get; private set; } = true;
45
46         /// <summary>
47         /// エラー時にダイアログを表示させない (ユニットテストなどで使用)
48         /// </summary>
49         public bool RunSilent { get; set; }
50
51         //入力補助画面
52         private AtIdSupplement _hashSupl;
53
54         //編集モード
55         private bool _isAdd = false;
56
57         private void ChangeMode(bool isEdit)
58         {
59             this.GroupHashtag.Enabled = !isEdit;
60             this.GroupDetail.Enabled = isEdit;
61             this.TableLayoutButtons.Enabled = !isEdit;
62             if (isEdit)
63                 this.UseHashText.Focus();
64             else
65                 this.HistoryHashList.Focus();
66         }
67
68         private void Cancel_Button_Click(object sender, EventArgs e)
69         {
70             this.DialogResult = DialogResult.Cancel;
71             this.Close();
72         }
73
74         private void AddButton_Click(object sender, EventArgs e)
75         {
76             this.UseHashText.Text = "";
77             ChangeMode(true);
78             _isAdd = true;
79         }
80
81         private void EditButton_Click(object sender, EventArgs e)
82         {
83             if (this.HistoryHashList.SelectedIndices.Count == 0) return;
84             this.UseHashText.Text = this.HistoryHashList.SelectedItems[0].ToString();
85             ChangeMode(true);
86             _isAdd = false;
87         }
88
89         private void DeleteButton_Click(object sender, EventArgs e)
90         {
91             if (this.HistoryHashList.SelectedIndices.Count == 0) return;
92             if (!this.RunSilent &&
93                 MessageBox.Show(Properties.Resources.DeleteHashtagsMessage1,
94                                 "Delete Hashtags",
95                                 MessageBoxButtons.OKCancel,
96                                 MessageBoxIcon.Question) == DialogResult.Cancel)
97             {
98                 return;
99             }
100
101             // 削除によってインデックス番号が変わらないように逆順に処理する
102             var selectedIndices = this.HistoryHashList.SelectedIndices.Cast<int>()
103                 .OrderByDescending(x => x).ToArray();
104
105             foreach (var idx in selectedIndices)
106             {
107                 if (UseHashText.Text == HistoryHashList.Items[idx].ToString()) UseHashText.Text = "";
108                 HistoryHashList.Items.RemoveAt(idx);
109             }
110             if (HistoryHashList.Items.Count > 0)
111             {
112                 HistoryHashList.SelectedIndex = 0;
113             }
114         }
115
116         private void UnSelectButton_Click(object sender, EventArgs e)
117         {
118             do
119             {
120                 HistoryHashList.SelectedIndices.Clear();
121             } while (HistoryHashList.SelectedIndices.Count > 0);
122         }
123
124         private int GetIndexOf(ListBox.ObjectCollection list, string value)
125         {
126             if (string.IsNullOrEmpty(value)) return -1;
127
128             int idx = 0;
129
130             foreach (object l in list)
131             {
132                 string src = l as string;
133                 if (string.IsNullOrEmpty(src))
134                 {
135                     idx += 1;
136                     continue;
137                 }
138                 if (string.Compare(src, value, StringComparison.OrdinalIgnoreCase) == 0)
139                 {
140                     return idx;
141                 }
142                 idx += 1;
143             }
144
145             // Not Found
146             return -1;
147         }
148
149         public void AddHashToHistory(string hash, bool isIgnorePermanent)
150         {
151             hash = hash.Trim();
152             if (!string.IsNullOrEmpty(hash))
153             {
154                 if (isIgnorePermanent || !this.IsPermanent)
155                 {
156                     //無条件に先頭に挿入
157                     int idx = GetIndexOf(HistoryHashList.Items, hash);
158
159                     if (idx != -1) HistoryHashList.Items.RemoveAt(idx);
160                     HistoryHashList.Items.Insert(0, hash);
161                 }
162                 else
163                 {
164                     //固定されていたら2行目に挿入
165                     int idx = GetIndexOf(HistoryHashList.Items, hash);
166                     if (this.IsPermanent)
167                     {
168                         if (idx > 0)
169                         {
170                             //重複アイテムが2行目以降にあれば2行目へ
171                             HistoryHashList.Items.RemoveAt(idx);
172                             HistoryHashList.Items.Insert(1, hash);
173                         }
174                         else if (idx == -1)
175                         {
176                             //重複アイテムなし
177                             if (HistoryHashList.Items.Count == 0)
178                             {
179                                 //リストが空なら追加
180                                 HistoryHashList.Items.Add(hash);
181                             }
182                             else
183                             {
184                                 //リストにアイテムがあれば2行目へ
185                                 HistoryHashList.Items.Insert(1, hash);
186                             }
187                         }
188                     }
189                 }
190             }
191         }
192
193         private void HashtagManage_Shown(object sender, EventArgs e)
194         {
195             //オプション
196             this.CheckPermanent.Checked = this.IsPermanent;
197             this.RadioHead.Checked = this.IsHead;
198             this.RadioLast.Checked = !this.IsHead;
199             //リスト選択
200             if (this.HistoryHashList.Items.Contains(this.UseHash))
201             {
202                 this.HistoryHashList.SelectedItem = this.UseHash;
203             }
204             else
205             {
206                 if (this.HistoryHashList.Items.Count > 0)
207                     this.HistoryHashList.SelectedIndex = 0;
208             }
209             this.ChangeMode(false);
210         }
211
212         public HashtagManage(AtIdSupplement hashSuplForm, string[] history, string permanentHash, bool IsPermanent, bool IsHead, bool IsNotAddToAtReply)
213         {
214             // この呼び出しは、Windows フォーム デザイナで必要です。
215             InitializeComponent();
216
217             // InitializeComponent() 呼び出しの後で初期化を追加します。
218
219             _hashSupl = hashSuplForm;
220             HistoryHashList.Items.AddRange(history);
221             this.UseHash = permanentHash;
222             this.IsPermanent = IsPermanent;
223             this.IsHead = IsHead;
224             this.IsNotAddToAtReply = IsNotAddToAtReply;
225         }
226
227         private void UseHashText_KeyPress(object sender, KeyPressEventArgs e)
228         {
229             if (e.KeyChar == '#')
230             {
231                 _hashSupl.ShowDialog();
232                 if (!string.IsNullOrEmpty(_hashSupl.inputText))
233                 {
234                     string fHalf = "";
235                     string eHalf = "";
236                     int selStart = UseHashText.SelectionStart;
237                     if (selStart > 0)
238                     {
239                         fHalf = UseHashText.Text.Substring(0, selStart);
240                     }
241                     if (selStart < UseHashText.Text.Length)
242                     {
243                         eHalf = UseHashText.Text.Substring(selStart);
244                     }
245                     UseHashText.Text = fHalf + _hashSupl.inputText + eHalf;
246                     UseHashText.SelectionStart = selStart + _hashSupl.inputText.Length;
247                 }
248                 e.Handled = true;
249             }
250         }
251
252         private void HistoryHashList_DoubleClick(object sender, EventArgs e)
253         {
254             this.OK_Button_Click(null, null);
255         }
256
257         public void ToggleHash()
258         {
259             if (string.IsNullOrEmpty(this.UseHash))
260             {
261                 if (this.HistoryHashList.Items.Count > 0)
262                     this.UseHash = this.HistoryHashList.Items[0].ToString();
263             }
264             else
265             {
266                 this.UseHash = "";
267             }
268         }
269
270         public List<string> HashHistories
271         {
272             get
273             {
274                 List<string> hash = new List<string>();
275                 foreach (string item in HistoryHashList.Items)
276                 {
277                     hash.Add(item);
278                 }
279                 return hash;
280             }
281         }
282
283         public void ClearHashtag()
284         {
285             this.UseHash = "";
286         }
287
288         public void SetPermanentHash(string hash)
289         {
290             //固定ハッシュタグの変更
291             this.UseHash = hash.Trim();
292             this.AddHashToHistory(UseHash, false);
293             this.IsPermanent = true;
294         }
295
296         private void PermOK_Button_Click(object sender, EventArgs e)
297         {
298             //ハッシュタグの整形
299             string hashStr = UseHashText.Text;
300             if (!this.AdjustHashtags(ref hashStr, !this.RunSilent)) return;
301
302             UseHashText.Text = hashStr;
303             int idx = 0;
304             if (!this._isAdd && this.HistoryHashList.SelectedIndices.Count > 0)
305             {
306                 idx = this.HistoryHashList.SelectedIndices[0];
307                 this.HistoryHashList.Items.RemoveAt(idx);
308                 do
309                 {
310                     this.HistoryHashList.SelectedIndices.Clear();
311                 } while (this.HistoryHashList.SelectedIndices.Count > 0);
312                 this.HistoryHashList.Items.Insert(idx, hashStr);
313                 this.HistoryHashList.SelectedIndex = idx;
314             }
315             else
316             {
317                 this.AddHashToHistory(hashStr, false);
318                 do
319                 {
320                     this.HistoryHashList.SelectedIndices.Clear();
321                 } while (this.HistoryHashList.SelectedIndices.Count > 0);
322                 this.HistoryHashList.SelectedIndex = this.HistoryHashList.Items.IndexOf(hashStr);
323             }
324
325             ChangeMode(false);
326         }
327
328         private void PermCancel_Button_Click(object sender, EventArgs e)
329         {
330             if (this.HistoryHashList.Items.Count > 0 && this.HistoryHashList.SelectedIndices.Count > 0)
331                 this.UseHashText.Text = this.HistoryHashList.Items[this.HistoryHashList.SelectedIndices[0]].ToString();
332             else
333                 this.UseHashText.Text = "";
334
335             ChangeMode(false);
336         }
337
338         private void HistoryHashList_KeyDown(object sender, KeyEventArgs e)
339         {
340             if (e.KeyCode == Keys.Delete)
341                 this.DeleteButton_Click(null, null);
342             else if (e.KeyCode == Keys.Insert)
343                 this.AddButton_Click(null, null);
344         }
345
346         private bool AdjustHashtags(ref string hashtag, bool isShowWarn)
347         {
348             //ハッシュタグの整形
349             hashtag = hashtag.Trim();
350             if (string.IsNullOrEmpty(hashtag))
351             {
352                 if (isShowWarn) MessageBox.Show("emply hashtag.", "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
353                 return false;
354             }
355             hashtag = hashtag.Replace("#", "#");
356             hashtag = hashtag.Replace(" ", " ");
357             string adjust = "";
358             foreach (string hash in hashtag.Split(' '))
359             {
360                 if (hash.Length > 0)
361                 {
362                     if (!hash.StartsWith("#", StringComparison.Ordinal))
363                     {
364                         if (isShowWarn) MessageBox.Show("Invalid hashtag. -> " + hash, "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
365                         return false;
366                     }
367                     if (hash.Length == 1)
368                     {
369                         if (isShowWarn) MessageBox.Show("empty hashtag.", "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
370                         return false;
371                     }
372                     //使用不可の文字チェックはしない
373                     adjust += hash + " ";
374                 }
375             }
376             hashtag = adjust.Trim();
377             return true;
378         }
379
380         private void OK_Button_Click(object sender, EventArgs e)
381         {
382             string hash = "";
383             foreach (string hs in this.HistoryHashList.SelectedItems)
384             {
385                 hash += hs + " ";
386             }
387             hash = hash.Trim();
388             if (!string.IsNullOrEmpty(hash))
389             {
390                 this.AddHashToHistory(hash, true);
391                 this.IsPermanent = this.CheckPermanent.Checked;
392             }
393             else
394             {
395                 //使用ハッシュが未選択ならば、固定オプション外す
396                 this.IsPermanent = false;
397             }
398             this.IsHead = this.RadioHead.Checked;
399             this.UseHash = hash;
400
401             this.DialogResult = DialogResult.OK;
402             this.Close();
403         }
404
405         private void HashtagManage_KeyDown(object sender, KeyEventArgs e)
406         {
407             if (e.KeyCode == Keys.Enter)
408             {
409                 e.Handled = true;
410                 if (this.GroupDetail.Enabled)
411                     this.PermOK_Button_Click(null, null);
412                 else
413                     this.OK_Button_Click(null, null);
414             }
415             else if (e.KeyCode == Keys.Escape)
416             {
417                 e.Handled = true;
418                 if (this.GroupDetail.Enabled)
419                     this.PermCancel_Button_Click(null, null);
420                 else
421                     this.Cancel_Button_Click(null, null);
422             }
423         }
424
425         private void CheckNotAddToAtReply_CheckedChanged(object sender, EventArgs e)
426         {
427             this.IsNotAddToAtReply = CheckNotAddToAtReply.Checked;
428         }
429     }
430 }