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.
10 // This file is part of OpenTween.
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)
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
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.
30 using System.Collections.Generic;
31 using System.ComponentModel;
34 using System.Globalization;
37 using System.Windows.Forms;
41 public partial class HashtagManage : OTBaseForm
43 public string UseHash { get; private set; } = "";
45 public bool IsPermanent { get; private set; } = false;
47 public bool IsHead { get; private set; } = false;
49 public bool IsNotAddToAtReply { get; private set; } = true;
52 /// エラー時にダイアログを表示させない (ユニットテストなどで使用)
54 public bool RunSilent { get; set; }
57 private readonly AtIdSupplement hashSupl;
60 private bool isAdd = false;
62 private void ChangeMode(bool isEdit)
64 this.GroupHashtag.Enabled = !isEdit;
65 this.GroupDetail.Enabled = isEdit;
66 this.TableLayoutButtons.Enabled = !isEdit;
68 this.UseHashText.Focus();
70 this.HistoryHashList.Focus();
73 private void Cancel_Button_Click(object sender, EventArgs e)
75 this.DialogResult = DialogResult.Cancel;
79 private void AddButton_Click(object sender, EventArgs e)
81 this.UseHashText.Text = "";
82 this.ChangeMode(true);
86 private void EditButton_Click(object sender, EventArgs e)
88 if (this.HistoryHashList.SelectedIndices.Count == 0) return;
89 this.UseHashText.Text = this.HistoryHashList.SelectedItems[0].ToString();
90 this.ChangeMode(true);
94 private void DeleteButton_Click(object sender, EventArgs e)
96 if (this.HistoryHashList.SelectedIndices.Count == 0) return;
97 if (!this.RunSilent &&
98 MessageBox.Show(Properties.Resources.DeleteHashtagsMessage1,
100 MessageBoxButtons.OKCancel,
101 MessageBoxIcon.Question) == DialogResult.Cancel)
106 // 削除によってインデックス番号が変わらないように逆順に処理する
107 var selectedIndices = this.HistoryHashList.SelectedIndices.Cast<int>()
108 .OrderByDescending(x => x).ToArray();
110 foreach (var idx in selectedIndices)
112 if (this.UseHashText.Text == this.HistoryHashList.Items[idx].ToString()) this.UseHashText.Text = "";
113 this.HistoryHashList.Items.RemoveAt(idx);
115 if (this.HistoryHashList.Items.Count > 0)
117 this.HistoryHashList.SelectedIndex = 0;
121 private void UnSelectButton_Click(object sender, EventArgs e)
125 this.HistoryHashList.SelectedIndices.Clear();
127 while (this.HistoryHashList.SelectedIndices.Count > 0);
130 private int GetIndexOf(ListBox.ObjectCollection list, string value)
132 if (MyCommon.IsNullOrEmpty(value)) return -1;
136 foreach (var l in list)
139 if (MyCommon.IsNullOrEmpty(src))
144 if (string.Compare(src, value, StringComparison.OrdinalIgnoreCase) == 0)
155 public void AddHashToHistory(string hash, bool isIgnorePermanent)
158 if (!MyCommon.IsNullOrEmpty(hash))
160 if (isIgnorePermanent || !this.IsPermanent)
163 var idx = this.GetIndexOf(this.HistoryHashList.Items, hash);
165 if (idx != -1) this.HistoryHashList.Items.RemoveAt(idx);
166 this.HistoryHashList.Items.Insert(0, hash);
171 var idx = this.GetIndexOf(this.HistoryHashList.Items, hash);
172 if (this.IsPermanent)
176 // 重複アイテムが2行目以降にあれば2行目へ
177 this.HistoryHashList.Items.RemoveAt(idx);
178 this.HistoryHashList.Items.Insert(1, hash);
183 if (this.HistoryHashList.Items.Count == 0)
186 this.HistoryHashList.Items.Add(hash);
191 this.HistoryHashList.Items.Insert(1, hash);
199 private void HashtagManage_Shown(object sender, EventArgs e)
202 this.CheckPermanent.Checked = this.IsPermanent;
203 this.RadioHead.Checked = this.IsHead;
204 this.RadioLast.Checked = !this.IsHead;
206 if (this.HistoryHashList.Items.Contains(this.UseHash))
208 this.HistoryHashList.SelectedItem = this.UseHash;
212 if (this.HistoryHashList.Items.Count > 0)
213 this.HistoryHashList.SelectedIndex = 0;
215 this.ChangeMode(false);
218 public HashtagManage(AtIdSupplement hashSuplForm, string[] history, string permanentHash, bool isPermanent, bool isHead, bool isNotAddToAtReply)
220 // この呼び出しは、Windows フォーム デザイナで必要です。
221 this.InitializeComponent();
223 // InitializeComponent() 呼び出しの後で初期化を追加します。
225 this.hashSupl = hashSuplForm;
226 this.HistoryHashList.Items.AddRange(history);
227 this.UseHash = permanentHash;
228 this.IsPermanent = isPermanent;
229 this.IsHead = isHead;
230 this.IsNotAddToAtReply = isNotAddToAtReply;
233 private void UseHashText_KeyPress(object sender, KeyPressEventArgs e)
235 if (e.KeyChar == '#')
237 this.hashSupl.ShowDialog();
238 if (!MyCommon.IsNullOrEmpty(this.hashSupl.InputText))
242 var selStart = this.UseHashText.SelectionStart;
245 fHalf = this.UseHashText.Text.Substring(0, selStart);
247 if (selStart < this.UseHashText.Text.Length)
249 eHalf = this.UseHashText.Text.Substring(selStart);
251 this.UseHashText.Text = fHalf + this.hashSupl.InputText + eHalf;
252 this.UseHashText.SelectionStart = selStart + this.hashSupl.InputText.Length;
258 private void HistoryHashList_DoubleClick(object sender, EventArgs e)
259 => this.OK_Button_Click(this.OK_Button, EventArgs.Empty);
261 public void ToggleHash()
263 if (MyCommon.IsNullOrEmpty(this.UseHash))
265 if (this.HistoryHashList.Items.Count > 0)
266 this.UseHash = this.HistoryHashList.Items[0].ToString();
274 public List<string> HashHistories
278 var hash = new List<string>();
279 foreach (string item in this.HistoryHashList.Items)
287 public void ClearHashtag()
288 => this.UseHash = "";
290 public void SetPermanentHash(string hash)
293 this.UseHash = hash.Trim();
294 this.AddHashToHistory(this.UseHash, false);
295 this.IsPermanent = true;
298 private void PermOK_Button_Click(object sender, EventArgs e)
301 var hashStr = this.UseHashText.Text;
302 if (!this.AdjustHashtags(ref hashStr, !this.RunSilent)) return;
304 this.UseHashText.Text = hashStr;
305 if (!this.isAdd && this.HistoryHashList.SelectedIndices.Count > 0)
307 var idx = this.HistoryHashList.SelectedIndices[0];
308 this.HistoryHashList.Items.RemoveAt(idx);
311 this.HistoryHashList.SelectedIndices.Clear();
313 while (this.HistoryHashList.SelectedIndices.Count > 0);
314 this.HistoryHashList.Items.Insert(idx, hashStr);
315 this.HistoryHashList.SelectedIndex = idx;
319 this.AddHashToHistory(hashStr, false);
322 this.HistoryHashList.SelectedIndices.Clear();
324 while (this.HistoryHashList.SelectedIndices.Count > 0);
325 this.HistoryHashList.SelectedIndex = this.HistoryHashList.Items.IndexOf(hashStr);
328 this.ChangeMode(false);
331 private void PermCancel_Button_Click(object sender, EventArgs e)
333 if (this.HistoryHashList.Items.Count > 0 && this.HistoryHashList.SelectedIndices.Count > 0)
334 this.UseHashText.Text = this.HistoryHashList.Items[this.HistoryHashList.SelectedIndices[0]].ToString();
336 this.UseHashText.Text = "";
338 this.ChangeMode(false);
341 private void HistoryHashList_KeyDown(object sender, KeyEventArgs e)
343 if (e.KeyCode == Keys.Delete)
344 this.DeleteButton_Click(this.DeleteButton, EventArgs.Empty);
345 else if (e.KeyCode == Keys.Insert)
346 this.AddButton_Click(this.AddButton, EventArgs.Empty);
349 private bool AdjustHashtags(ref string hashtag, bool isShowWarn)
352 hashtag = hashtag.Trim();
353 if (MyCommon.IsNullOrEmpty(hashtag))
355 if (isShowWarn) MessageBox.Show("emply hashtag.", "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
358 hashtag = hashtag.Replace("#", "#");
359 hashtag = hashtag.Replace(" ", " ");
361 foreach (var hash in hashtag.Split(' '))
365 if (!hash.StartsWith("#", StringComparison.Ordinal))
367 if (isShowWarn) MessageBox.Show("Invalid hashtag. -> " + hash, "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
370 if (hash.Length == 1)
372 if (isShowWarn) MessageBox.Show("empty hashtag.", "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
376 adjust += hash + " ";
379 hashtag = adjust.Trim();
383 private void OK_Button_Click(object sender, EventArgs e)
386 foreach (string hs in this.HistoryHashList.SelectedItems)
391 if (!MyCommon.IsNullOrEmpty(hash))
393 this.AddHashToHistory(hash, true);
394 this.IsPermanent = this.CheckPermanent.Checked;
398 // 使用ハッシュが未選択ならば、固定オプション外す
399 this.IsPermanent = false;
401 this.IsHead = this.RadioHead.Checked;
404 this.DialogResult = DialogResult.OK;
408 private void HashtagManage_KeyDown(object sender, KeyEventArgs e)
410 if (e.KeyCode == Keys.Enter)
413 if (this.GroupDetail.Enabled)
414 this.PermOK_Button_Click(this.PermOK_Button, EventArgs.Empty);
416 this.OK_Button_Click(this.OK_Button, EventArgs.Empty);
418 else if (e.KeyCode == Keys.Escape)
421 if (this.GroupDetail.Enabled)
422 this.PermCancel_Button_Click(this.PermCancel_Button, EventArgs.Empty);
424 this.Cancel_Button_Click(this.Cancel_Button, EventArgs.Empty);
428 private void CheckNotAddToAtReply_CheckedChanged(object sender, EventArgs e)
429 => this.IsNotAddToAtReply = this.CheckNotAddToAtReply.Checked;