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-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.
28 using System.Collections.Generic;
29 using System.ComponentModel;
34 using System.Windows.Forms;
35 using System.Linq.Expressions;
36 using System.Text.RegularExpressions;
38 using System.Collections.Specialized;
42 public partial class FilterDialog : OTBaseForm
44 private EDITMODE _mode;
45 private bool _directAdd;
46 private bool _moveRules = false;
47 private TabInformations _sts;
49 private List<string> idlist = new List<string>();
58 private enum EnableButtonMode
65 private EnableButtonMode RuleEnableButtonMode
67 get { return this._ruleEnableButtonMode; }
70 this._ruleEnableButtonMode = value;
72 this.buttonRuleToggleEnabled.Text = value == FilterDialog.EnableButtonMode.Enable
73 ? Properties.Resources.EnableButtonCaption
74 : Properties.Resources.DisableButtonCaption;
75 this.buttonRuleToggleEnabled.Enabled = value != EnableButtonMode.NotSelected;
78 private EnableButtonMode _ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected;
82 InitializeComponent();
85 private void SetFilters(string tabName)
87 if (ListTabs.Items.Count == 0) return;
89 var tab = _sts.Tabs[tabName];
91 ListFilters.Items.Clear();
92 ListFilters.Items.AddRange(tab.GetFilters());
94 if (ListFilters.Items.Count > 0)
95 ListFilters.SelectedIndex = 0;
99 if (tab.IsDefaultTabType)
101 CheckProtected.Checked = true;
102 CheckProtected.Enabled = false;
106 CheckProtected.Checked = tab.Protected;
107 CheckProtected.Enabled = true;
110 CheckManageRead.Checked = tab.UnreadManage;
111 CheckNotifyNew.Checked = tab.Notify;
113 int idx = ComboSound.Items.IndexOf(tab.SoundFile);
114 if (idx == -1) idx = 0;
115 ComboSound.SelectedIndex = idx;
117 if (_directAdd) return;
119 if (tab.TabType == MyCommon.TabUsageType.Mute)
121 this.CheckManageRead.Enabled = false;
122 this.CheckNotifyNew.Enabled = false;
123 this.ComboSound.Enabled = false;
125 this.GroupBox1.Visible = false;
126 this.labelMuteTab.Visible = true;
130 this.CheckManageRead.Enabled = true;
131 this.CheckNotifyNew.Enabled = true;
132 this.ComboSound.Enabled = true;
134 this.GroupBox1.Visible = true;
135 this.labelMuteTab.Visible = false;
138 ListTabs.Enabled = true;
139 GroupTab.Enabled = true;
140 ListFilters.Enabled = true;
141 EditFilterGroup.Enabled = false;
144 case MyCommon.TabUsageType.Home:
145 case MyCommon.TabUsageType.DirectMessage:
146 case MyCommon.TabUsageType.Favorites:
147 case MyCommon.TabUsageType.PublicSearch:
148 case MyCommon.TabUsageType.Lists:
149 case MyCommon.TabUsageType.Related:
150 case MyCommon.TabUsageType.UserTimeline:
151 ButtonNew.Enabled = false;
152 ButtonEdit.Enabled = false;
153 ButtonDelete.Enabled = false;
154 ButtonRuleUp.Enabled = false;
155 ButtonRuleDown.Enabled = false;
156 ButtonRuleCopy.Enabled = false;
157 ButtonRuleMove.Enabled = false;
158 buttonRuleToggleEnabled.Enabled = false;
161 ButtonNew.Enabled = true;
162 if (ListFilters.SelectedIndex > -1)
164 ButtonEdit.Enabled = true;
165 ButtonDelete.Enabled = true;
166 ButtonRuleUp.Enabled = true;
167 ButtonRuleDown.Enabled = true;
168 ButtonRuleCopy.Enabled = true;
169 ButtonRuleMove.Enabled = true;
170 buttonRuleToggleEnabled.Enabled = true;
174 ButtonEdit.Enabled = false;
175 ButtonDelete.Enabled = false;
176 ButtonRuleUp.Enabled = false;
177 ButtonRuleDown.Enabled = false;
178 ButtonRuleCopy.Enabled = false;
179 ButtonRuleMove.Enabled = false;
180 buttonRuleToggleEnabled.Enabled = false;
186 case MyCommon.TabUsageType.Home:
187 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Home;
189 case MyCommon.TabUsageType.Mentions:
190 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Mentions;
192 case MyCommon.TabUsageType.DirectMessage:
193 LabelTabType.Text = Properties.Resources.TabUsageTypeName_DirectMessage;
195 case MyCommon.TabUsageType.Favorites:
196 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Favorites;
198 case MyCommon.TabUsageType.UserDefined:
199 LabelTabType.Text = Properties.Resources.TabUsageTypeName_UserDefined;
201 case MyCommon.TabUsageType.PublicSearch:
202 LabelTabType.Text = Properties.Resources.TabUsageTypeName_PublicSearch;
204 case MyCommon.TabUsageType.Lists:
205 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Lists;
207 case MyCommon.TabUsageType.Related:
208 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Related;
210 case MyCommon.TabUsageType.UserTimeline:
211 LabelTabType.Text = Properties.Resources.TabUsageTypeName_UserTimeline;
213 case MyCommon.TabUsageType.Mute:
214 LabelTabType.Text = "Mute";
217 LabelTabType.Text = "UNKNOWN";
220 ButtonRenameTab.Enabled = true;
221 if (tab.IsDefaultTabType || tab.Protected)
223 ButtonDeleteTab.Enabled = false;
227 ButtonDeleteTab.Enabled = true;
229 ButtonClose.Enabled = true;
232 public void SetCurrent(string TabName)
237 public void AddNewFilter(string id, string msg)
240 ButtonNew.Enabled = false;
241 ButtonEdit.Enabled = false;
242 ButtonRuleUp.Enabled = false;
243 ButtonRuleDown.Enabled = false;
244 ButtonRuleCopy.Enabled = false;
245 ButtonRuleMove.Enabled = false;
246 buttonRuleToggleEnabled.Enabled = false;
247 ButtonDelete.Enabled = false;
248 ButtonClose.Enabled = false;
249 EditFilterGroup.Enabled = true;
250 ListTabs.Enabled = false;
251 GroupTab.Enabled = false;
252 ListFilters.Enabled = false;
254 RadioAND.Checked = true;
255 RadioPLUS.Checked = false;
260 MSG2.Text = id + msg;
262 TextSource.Text = "";
265 MSG2.Enabled = false;
266 CheckRegex.Checked = false;
267 CheckURL.Checked = false;
268 CheckCaseSensitive.Checked = false;
269 CheckRetweet.Checked = false;
270 CheckLambda.Checked = false;
272 RadioExAnd.Checked = true;
273 RadioExPLUS.Checked = false;
280 TextExSource.Text = "";
281 ExUID.Enabled = true;
282 ExMSG1.Enabled = true;
283 ExMSG2.Enabled = false;
284 CheckExRegex.Checked = false;
285 CheckExURL.Checked = false;
286 CheckExCaseSensitive.Checked = false;
287 CheckExRetweet.Checked = false;
288 CheckExLambDa.Checked = false;
290 OptCopy.Checked = true;
291 CheckMark.Checked = true;
293 _mode = EDITMODE.AddNew;
297 private void ButtonNew_Click(object sender, EventArgs e)
299 ButtonNew.Enabled = false;
300 ButtonEdit.Enabled = false;
301 ButtonClose.Enabled = false;
302 ButtonRuleUp.Enabled = false;
303 ButtonRuleDown.Enabled = false;
304 ButtonRuleCopy.Enabled = false;
305 ButtonRuleMove.Enabled = false;
306 buttonRuleToggleEnabled.Enabled = false;
307 ButtonDelete.Enabled = false;
308 ButtonClose.Enabled = false;
309 EditFilterGroup.Enabled = true;
310 ListTabs.Enabled = false;
311 GroupTab.Enabled = false;
312 ListFilters.Enabled = false;
314 RadioAND.Checked = true;
315 RadioPLUS.Checked = false;
319 TextSource.Text = "";
322 MSG2.Enabled = false;
323 CheckRegex.Checked = false;
324 CheckURL.Checked = false;
325 CheckCaseSensitive.Checked = false;
326 CheckRetweet.Checked = false;
327 CheckLambda.Checked = false;
329 RadioExAnd.Checked = true;
330 RadioExPLUS.Checked = false;
334 TextExSource.Text = "";
335 ExUID.Enabled = true;
336 ExMSG1.Enabled = true;
337 ExMSG2.Enabled = false;
338 CheckExRegex.Checked = false;
339 CheckExURL.Checked = false;
340 CheckExCaseSensitive.Checked = false;
341 CheckExRetweet.Checked = false;
342 CheckExLambDa.Checked = false;
344 OptCopy.Checked = true;
345 CheckMark.Checked = true;
347 _mode = EDITMODE.AddNew;
350 private void ButtonEdit_Click(object sender, EventArgs e)
352 if (ListFilters.SelectedIndex == -1) return;
356 int idx = ListFilters.SelectedIndex;
357 ListFilters.SelectedIndex = -1;
358 ListFilters.SelectedIndex = idx;
359 ListFilters.Enabled = false;
361 ButtonNew.Enabled = false;
362 ButtonEdit.Enabled = false;
363 ButtonDelete.Enabled = false;
364 ButtonClose.Enabled = false;
365 ButtonRuleUp.Enabled = false;
366 ButtonRuleDown.Enabled = false;
367 ButtonRuleCopy.Enabled = false;
368 ButtonRuleMove.Enabled = false;
369 buttonRuleToggleEnabled.Enabled = false;
370 EditFilterGroup.Enabled = true;
371 ListTabs.Enabled = false;
372 GroupTab.Enabled = false;
374 _mode = EDITMODE.Edit;
377 private void ButtonDelete_Click(object sender, EventArgs e)
379 var selectedCount = ListFilters.SelectedIndices.Count;
380 if (selectedCount == 0) return;
384 if (selectedCount == 1)
386 tmp = string.Format(Properties.Resources.ButtonDelete_ClickText1, Environment.NewLine, ListFilters.SelectedItem.ToString());
390 tmp = string.Format(Properties.Resources.ButtonDelete_ClickText3, selectedCount.ToString());
393 var rslt = MessageBox.Show(tmp, Properties.Resources.ButtonDelete_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
394 if (rslt == DialogResult.Cancel) return;
396 var indices = ListFilters.SelectedIndices.Cast<int>().Reverse().ToArray(); // 後ろの要素から削除
397 var tab = _sts.Tabs[ListTabs.SelectedItem.ToString()];
399 using (ControlTransaction.Update(ListFilters))
401 foreach (var idx in indices)
403 tab.RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
404 ListFilters.Items.RemoveAt(idx);
409 private void ButtonCancel_Click(object sender, EventArgs e)
411 ListTabs.Enabled = true;
412 GroupTab.Enabled = true;
413 ListFilters.Enabled = true;
415 if (ListFilters.SelectedIndex != -1)
419 EditFilterGroup.Enabled = false;
420 ButtonNew.Enabled = true;
421 if (ListFilters.SelectedIndex > -1)
423 ButtonEdit.Enabled = true;
424 ButtonDelete.Enabled = true;
425 ButtonRuleUp.Enabled = true;
426 ButtonRuleDown.Enabled = true;
427 ButtonRuleCopy.Enabled = true;
428 ButtonRuleMove.Enabled = true;
429 buttonRuleToggleEnabled.Enabled = true;
433 ButtonEdit.Enabled = false;
434 ButtonDelete.Enabled = false;
435 ButtonRuleUp.Enabled = false;
436 ButtonRuleDown.Enabled = false;
437 ButtonRuleCopy.Enabled = false;
438 ButtonRuleMove.Enabled = false;
439 buttonRuleToggleEnabled.Enabled = false;
441 ButtonClose.Enabled = true;
448 private void ShowDetail()
450 if (_directAdd) return;
452 if (ListFilters.SelectedIndex > -1)
454 PostFilterRule fc = (PostFilterRule)ListFilters.SelectedItem;
457 RadioAND.Checked = true;
458 RadioPLUS.Checked = false;
461 MSG2.Enabled = false;
462 UID.Text = fc.FilterName;
464 MSG1.Text = string.Join(" ", fc.FilterBody);
470 RadioPLUS.Checked = true;
471 RadioAND.Checked = false;
473 MSG1.Enabled = false;
477 MSG2.Text = string.Join(" ", fc.FilterBody);
480 TextSource.Text = fc.FilterSource;
481 CheckRegex.Checked = fc.UseRegex;
482 CheckURL.Checked = fc.FilterByUrl;
483 CheckCaseSensitive.Checked = fc.CaseSensitive;
484 CheckRetweet.Checked = fc.FilterRt;
485 CheckLambda.Checked = fc.UseLambda;
487 if (fc.ExUseNameField)
489 RadioExAnd.Checked = true;
490 RadioExPLUS.Checked = false;
491 ExUID.Enabled = true;
492 ExMSG1.Enabled = true;
493 ExMSG2.Enabled = false;
494 ExUID.Text = fc.ExFilterName;
496 ExMSG1.Text = string.Join(" ", fc.ExFilterBody);
502 RadioExPLUS.Checked = true;
503 RadioExAnd.Checked = false;
504 ExUID.Enabled = false;
505 ExMSG1.Enabled = false;
506 ExMSG2.Enabled = true;
509 ExMSG2.Text = string.Join(" ", fc.ExFilterBody);
512 TextExSource.Text = fc.ExFilterSource;
513 CheckExRegex.Checked = fc.ExUseRegex;
514 CheckExURL.Checked = fc.ExFilterByUrl;
515 CheckExCaseSensitive.Checked = fc.ExCaseSensitive;
516 CheckExRetweet.Checked = fc.ExFilterRt;
517 CheckExLambDa.Checked = fc.ExUseLambda;
521 OptMove.Checked = true;
525 OptCopy.Checked = true;
527 CheckMark.Checked = fc.MarkMatches;
529 ButtonEdit.Enabled = true;
530 ButtonDelete.Enabled = true;
531 ButtonRuleUp.Enabled = true;
532 ButtonRuleDown.Enabled = true;
533 ButtonRuleCopy.Enabled = true;
534 ButtonRuleMove.Enabled = true;
535 buttonRuleToggleEnabled.Enabled = true;
539 RadioAND.Checked = true;
540 RadioPLUS.Checked = false;
543 MSG2.Enabled = false;
547 TextSource.Text = "";
548 CheckRegex.Checked = false;
549 CheckURL.Checked = false;
550 CheckCaseSensitive.Checked = false;
551 CheckRetweet.Checked = false;
552 CheckLambda.Checked = false;
554 RadioExAnd.Checked = true;
555 RadioExPLUS.Checked = false;
556 ExUID.Enabled = true;
557 ExMSG1.Enabled = true;
558 ExMSG2.Enabled = false;
562 TextExSource.Text = "";
563 CheckExRegex.Checked = false;
564 CheckExURL.Checked = false;
565 CheckExCaseSensitive.Checked = false;
566 CheckExRetweet.Checked = false;
567 CheckExLambDa.Checked = false;
569 OptCopy.Checked = true;
570 CheckMark.Checked = true;
572 ButtonEdit.Enabled = false;
573 ButtonDelete.Enabled = false;
574 ButtonRuleUp.Enabled = false;
575 ButtonRuleDown.Enabled = false;
576 ButtonRuleCopy.Enabled = false;
577 ButtonRuleMove.Enabled = false;
578 buttonRuleToggleEnabled.Enabled = false;
582 private void RadioAND_CheckedChanged(object sender, EventArgs e)
584 bool flg = RadioAND.Checked;
590 private void ButtonOK_Click(object sender, EventArgs e)
592 bool isBlankMatch = false;
593 bool isBlankExclude = false;
596 if (!CheckMatchRule(out isBlankMatch) || !CheckExcludeRule(out isBlankExclude))
600 if (isBlankMatch && isBlankExclude)
602 MessageBox.Show(Properties.Resources.ButtonOK_ClickText1, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
606 var tab = this._sts.Tabs[(string)this.ListTabs.SelectedItem];
607 int i = ListFilters.SelectedIndex;
610 if (_mode == EDITMODE.AddNew)
611 ft = new PostFilterRule();
613 ft = (PostFilterRule)this.ListFilters.SelectedItem;
615 if (tab.TabType != MyCommon.TabUsageType.Mute)
617 ft.MoveMatches = OptMove.Checked;
618 ft.MarkMatches = CheckMark.Checked;
622 ft.MoveMatches = true;
623 ft.MarkMatches = false;
627 if (RadioAND.Checked)
629 ft.FilterName = UID.Text;
630 TweenMain owner = (TweenMain)this.Owner;
631 int cnt = owner.AtIdSupl.ItemCount;
632 owner.AtIdSupl.AddItem("@" + ft.FilterName);
633 if (cnt != owner.AtIdSupl.ItemCount)
635 owner.ModifySettingAtId = true;
637 ft.UseNameField = true;
643 ft.UseNameField = false;
646 ft.FilterSource = TextSource.Text;
648 if (CheckRegex.Checked || CheckLambda.Checked)
650 ft.FilterBody = new[] { bdy };
654 ft.FilterBody = bdy.Split(' ', ' ')
655 .Where(x => !string.IsNullOrEmpty(x))
659 ft.UseRegex = CheckRegex.Checked;
660 ft.FilterByUrl = CheckURL.Checked;
661 ft.CaseSensitive = CheckCaseSensitive.Checked;
662 ft.FilterRt = CheckRetweet.Checked;
663 ft.UseLambda = CheckLambda.Checked;
666 if (RadioExAnd.Checked)
668 ft.ExFilterName = ExUID.Text;
669 ft.ExUseNameField = true;
674 ft.ExFilterName = "";
675 ft.ExUseNameField = false;
678 ft.ExFilterSource = TextExSource.Text;
680 if (CheckExRegex.Checked || CheckExLambDa.Checked)
682 ft.ExFilterBody = new[] { bdy };
686 ft.ExFilterBody = bdy.Split(' ', ' ')
687 .Where(x => !string.IsNullOrEmpty(x))
691 ft.ExUseRegex = CheckExRegex.Checked;
692 ft.ExFilterByUrl = CheckExURL.Checked;
693 ft.ExCaseSensitive = CheckExCaseSensitive.Checked;
694 ft.ExFilterRt = CheckExRetweet.Checked;
695 ft.ExUseLambda = CheckExLambDa.Checked;
697 if (_mode == EDITMODE.AddNew)
699 if (!tab.AddFilter(ft))
700 MessageBox.Show(Properties.Resources.ButtonOK_ClickText4, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Error);
703 SetFilters(tab.TabName);
704 ListFilters.SelectedIndex = -1;
705 if (_mode == EDITMODE.AddNew)
707 ListFilters.SelectedIndex = ListFilters.Items.Count - 1;
711 ListFilters.SelectedIndex = i;
713 _mode = EDITMODE.None;
721 private bool IsValidLambdaExp(string text)
724 // TODO DynamicQuery相当のGPLv3互換なライブラリで置換する
727 private bool IsValidRegexp(string text)
735 MessageBox.Show(Properties.Resources.ButtonOK_ClickText3 + ex.Message, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
741 private bool CheckMatchRule(out bool isBlank)
744 if (RadioAND.Checked)
746 if (string.IsNullOrEmpty(UID.Text) && string.IsNullOrEmpty(MSG1.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false)
751 if (CheckLambda.Checked)
753 if (!IsValidLambdaExp(UID.Text))
757 if (!IsValidLambdaExp(MSG1.Text))
762 else if (CheckRegex.Checked)
764 if (!IsValidRegexp(UID.Text))
768 if (!IsValidRegexp(MSG1.Text))
776 if (string.IsNullOrEmpty(MSG2.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false)
781 if (CheckLambda.Checked && !IsValidLambdaExp(MSG2.Text))
785 else if (CheckRegex.Checked && !IsValidRegexp(MSG2.Text))
791 if (CheckRegex.Checked && !IsValidRegexp(TextSource.Text))
798 private bool CheckExcludeRule(out bool isBlank)
801 if (RadioExAnd.Checked)
803 if (string.IsNullOrEmpty(ExUID.Text) && string.IsNullOrEmpty(ExMSG1.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false)
808 if (CheckExLambDa.Checked)
810 if (!IsValidLambdaExp(ExUID.Text))
814 if (!IsValidLambdaExp(ExMSG1.Text))
819 else if (CheckExRegex.Checked)
821 if (!IsValidRegexp(ExUID.Text))
825 if (!IsValidRegexp(ExMSG1.Text))
833 if (string.IsNullOrEmpty(ExMSG2.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false)
838 if (CheckExLambDa.Checked && !IsValidLambdaExp(ExMSG2.Text))
842 else if (CheckExRegex.Checked && !IsValidRegexp(ExMSG2.Text))
848 if (CheckExRegex.Checked && !IsValidRegexp(TextExSource.Text))
856 private void ListFilters_SelectedIndexChanged(object sender, EventArgs e)
863 var selectedCount = this.ListFilters.SelectedIndices.Count;
864 if (selectedCount == 0)
866 this.RuleEnableButtonMode = EnableButtonMode.NotSelected;
870 if (selectedCount == 1 ||
871 this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
873 var topItem = (PostFilterRule)this.ListFilters.SelectedItem;
874 this.RuleEnableButtonMode = topItem.Enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
879 private void ButtonClose_Click(object sender, EventArgs e)
884 private void FilterDialog_FormClosed(object sender, FormClosedEventArgs e)
889 private void FilterDialog_KeyDown(object sender, KeyEventArgs e)
891 if (e.KeyCode == Keys.Escape)
893 if (EditFilterGroup.Enabled)
894 ButtonCancel_Click(null, null);
896 ButtonClose_Click(null, null);
900 private void ListFilters_DoubleClick(object sender, EventArgs e)
902 var idx = ListFilters.SelectedIndex;
903 if (idx == -1) return;
905 var midx = ListFilters.IndexFromPoint(ListFilters.PointToClient(Control.MousePosition));
906 if (midx == ListBox.NoMatches || idx != midx) return;
908 ButtonEdit_Click(sender, e);
911 private void FilterDialog_Shown(object sender, EventArgs e)
913 _sts = TabInformations.GetInstance();
914 ListTabs.Items.Clear();
915 foreach (var tab in this._sts.Tabs.Values)
917 if (tab.TabType == MyCommon.TabUsageType.Mute)
920 this.ListTabs.Items.Add(tab.TabName);
923 var muteTab = this._sts.GetTabByType(MyCommon.TabUsageType.Mute);
925 this.ListTabs.Items.Add(muteTab.TabName);
927 ComboSound.Items.Clear();
928 ComboSound.Items.Add("");
929 DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
930 if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds")))
932 oDir = oDir.GetDirectories("Sounds")[0];
934 foreach (FileInfo oFile in oDir.GetFiles("*.wav"))
936 ComboSound.Items.Add(oFile.Name);
940 foreach (string tmp in ((TweenMain)this.Owner).AtIdSupl.GetItemList())
942 idlist.Add(tmp.Remove(0, 1)); // @文字削除
944 UID.AutoCompleteCustomSource.Clear();
945 UID.AutoCompleteCustomSource.AddRange(idlist.ToArray());
947 ExUID.AutoCompleteCustomSource.Clear();
948 ExUID.AutoCompleteCustomSource.AddRange(idlist.ToArray());
951 if (ListTabs.Items.Count > 0)
955 for (int i = 0; i < ListTabs.Items.Count; i++)
957 if (_cur == ListTabs.Items[i].ToString())
959 ListTabs.SelectedIndex = i;
960 //tabdialog.TabList.Items.Remove(_cur);
968 private void ListTabs_SelectedIndexChanged(object sender, EventArgs e)
970 if (ListTabs.SelectedIndex > -1)
971 SetFilters(ListTabs.SelectedItem.ToString());
973 ListFilters.Items.Clear();
976 private void ButtonAddTab_Click(object sender, EventArgs e)
978 string tabName = null;
979 MyCommon.TabUsageType tabType;
980 using (InputTabName inputName = new InputTabName())
982 inputName.TabName = _sts.GetUniqueTabName();
983 inputName.IsShowUsage = true;
984 inputName.ShowDialog();
985 if (inputName.DialogResult == DialogResult.Cancel) return;
986 tabName = inputName.TabName;
987 tabType = inputName.Usage;
989 if (!string.IsNullOrEmpty(tabName))
992 ListElement list = null;
993 if (tabType == MyCommon.TabUsageType.Lists)
995 string rslt = ((TweenMain)this.Owner).TwitterInstance.GetListsApi();
996 if (!string.IsNullOrEmpty(rslt))
998 MessageBox.Show("Failed to get lists. (" + rslt + ")");
1000 using (ListAvailable listAvail = new ListAvailable())
1002 if (listAvail.ShowDialog(this) == DialogResult.Cancel) return;
1003 if (listAvail.SelectedList == null) return;
1004 list = listAvail.SelectedList;
1007 if (!_sts.AddTab(tabName, tabType, list) || !((TweenMain)this.Owner).AddNewTab(tabName, false, tabType, list))
1009 string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
1010 MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
1018 var lastIdx = this.ListTabs.Items.Count - 1;
1019 var lastTab = lastIdx != -1
1020 ? this._sts.Tabs[(string)this.ListTabs.Items[lastIdx]]
1023 // 末尾がミュートタブであればその手前に追加する
1024 if (lastTab != null && lastTab.TabType == MyCommon.TabUsageType.Mute)
1025 this.ListTabs.Items.Insert(lastIdx, tabName);
1027 this.ListTabs.Items.Add(tabName);
1032 private void ButtonDeleteTab_Click(object sender, EventArgs e)
1034 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1036 string tb = ListTabs.SelectedItem.ToString();
1037 int idx = ListTabs.SelectedIndex;
1038 if (((TweenMain)this.Owner).RemoveSpecifiedTab(tb, true))
1040 ListTabs.Items.RemoveAt(idx);
1042 if (idx < 0) idx = 0;
1043 ListTabs.SelectedIndex = idx;
1048 private void ButtonRenameTab_Click(object sender, EventArgs e)
1050 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1052 string tb = ListTabs.SelectedItem.ToString();
1053 int idx = ListTabs.SelectedIndex;
1054 if (((TweenMain)this.Owner).TabRename(ref tb))
1056 ListTabs.Items.RemoveAt(idx);
1057 ListTabs.Items.Insert(idx, tb);
1058 ListTabs.SelectedIndex = idx;
1063 private void CheckManageRead_CheckedChanged(object sender, EventArgs e)
1065 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1067 ((TweenMain)this.Owner).ChangeTabUnreadManage(
1068 ListTabs.SelectedItem.ToString(),
1069 CheckManageRead.Checked);
1073 private void ButtonUp_Click(object sender, EventArgs e)
1075 if (this.ListTabs.SelectedIndex == -1 || this.ListTabs.SelectedIndex == 0)
1078 var selectedTabName = (string)this.ListTabs.SelectedItem;
1079 var selectedTab = this._sts.Tabs[selectedTabName];
1081 var targetTabName = (string)this.ListTabs.Items[this.ListTabs.SelectedIndex - 1];
1082 var targetTab = this._sts.Tabs[targetTabName];
1085 if (selectedTab.TabType == MyCommon.TabUsageType.Mute || targetTab.TabType == MyCommon.TabUsageType.Mute)
1088 var tweenMain = (TweenMain)this.Owner;
1089 tweenMain.ReOrderTab(selectedTabName, targetTabName, true);
1091 // ListTab のアイテム並び替え
1092 // 選択が解除されてしまうのを防ぐため SelectedIndex のアイテムは操作せず前後のアイテムを移動する
1093 var idx = this.ListTabs.SelectedIndex;
1094 this.ListTabs.Items.RemoveAt(idx - 1);
1095 this.ListTabs.Items.Insert(idx, targetTabName);
1098 private void ButtonDown_Click(object sender, EventArgs e)
1100 if (this.ListTabs.SelectedIndex == -1 || this.ListTabs.SelectedIndex == this.ListTabs.Items.Count - 1)
1103 var selectedTabName = (string)this.ListTabs.SelectedItem;
1104 var selectedTab = this._sts.Tabs[selectedTabName];
1106 var targetTabName = (string)this.ListTabs.Items[this.ListTabs.SelectedIndex + 1];
1107 var targetTab = this._sts.Tabs[targetTabName];
1110 if (selectedTab.TabType == MyCommon.TabUsageType.Mute || targetTab.TabType == MyCommon.TabUsageType.Mute)
1113 var tweenMain = (TweenMain)this.Owner;
1114 tweenMain.ReOrderTab(selectedTabName, targetTabName, false);
1116 // ListTab のアイテム並び替え
1117 // 選択が解除されてしまうのを防ぐため SelectedIndex のアイテムは操作せず前後のアイテムを移動する
1118 var idx = this.ListTabs.SelectedIndex;
1119 this.ListTabs.Items.RemoveAt(idx + 1);
1120 this.ListTabs.Items.Insert(idx, targetTabName);
1123 private void CheckLocked_CheckedChanged(object sender, EventArgs e)
1125 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1127 _sts.Tabs[ListTabs.SelectedItem.ToString()].Protected = CheckProtected.Checked;
1128 ButtonDeleteTab.Enabled = !CheckProtected.Checked;
1132 private void CheckNotifyNew_CheckedChanged(object sender, EventArgs e)
1134 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1136 _sts.Tabs[ListTabs.SelectedItem.ToString()].Notify = CheckNotifyNew.Checked;
1140 private void ComboSound_SelectedIndexChanged(object sender, EventArgs e)
1142 if (ListTabs.SelectedIndex > -1 && string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1144 string filename = "";
1145 if (ComboSound.SelectedIndex > -1) filename = ComboSound.SelectedItem.ToString();
1146 _sts.Tabs[ListTabs.SelectedItem.ToString()].SoundFile = filename;
1150 private void RadioExAnd_CheckedChanged(object sender, EventArgs e)
1152 bool flg = RadioExAnd.Checked;
1153 ExUID.Enabled = flg;
1154 ExMSG1.Enabled = flg;
1155 ExMSG2.Enabled = !flg;
1158 private void OptMove_CheckedChanged(object sender, EventArgs e)
1160 CheckMark.Enabled = !OptMove.Checked;
1163 private void ButtonRuleUp_Click(object sender, EventArgs e)
1165 MoveSelectedRules(up: true);
1168 private void ButtonRuleDown_Click(object sender, EventArgs e)
1170 MoveSelectedRules(up: false);
1173 private void MoveSelectedRules(bool up)
1175 var tabIdx = ListTabs.SelectedIndex;
1177 ListFilters.SelectedIndices.Count == 0) return;
1179 var indices = ListFilters.SelectedIndices.Cast<int>().ToArray();
1184 if (indices[0] <= 0) return;
1189 if (indices[indices.Length - 1] >= ListFilters.Items.Count - 1) return;
1191 Array.Reverse(indices); // 逆順にして、下にある要素から処理する
1194 var lastSelIdx = indices[0] + diff;
1195 var tab = _sts.Tabs[ListTabs.Items[tabIdx].ToString()];
1199 _moveRules = true; // SelectedIndexChanged を無視する
1201 using (ControlTransaction.Update(ListFilters))
1203 ListFilters.SelectedIndices.Clear();
1205 foreach (var idx in indices)
1207 var tidx = idx + diff;
1208 var target = (PostFilterRule)ListFilters.Items[tidx];
1210 // 移動先にある要素と位置を入れ替える
1211 ListFilters.Items.RemoveAt(tidx);
1212 ListFilters.Items.Insert(idx, target);
1214 // 移動方向の先頭要素以外なら選択する
1215 if (tidx != lastSelIdx)
1216 ListFilters.SelectedIndex = tidx;
1219 tab.FilterArray = ListFilters.Items.Cast<PostFilterRule>().ToArray();
1221 // 移動方向の先頭要素は最後に選択する
1223 ListFilters.SelectedIndex = lastSelIdx;
1232 private void buttonRuleToggleEnabled_Click(object sender, EventArgs e)
1234 if (this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
1237 var enabled = this.RuleEnableButtonMode == EnableButtonMode.Enable;
1239 foreach (var idx in this.ListFilters.SelectedIndices.Cast<int>())
1241 var filter = (PostFilterRule)this.ListFilters.Items[idx];
1242 if (filter.Enabled != enabled)
1244 filter.Enabled = enabled;
1246 var itemRect = this.ListFilters.GetItemRectangle(idx);
1247 this.ListFilters.Invalidate(itemRect);
1251 this.RuleEnableButtonMode = enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
1254 private void ButtonRuleCopy_Click(object sender, EventArgs e)
1256 if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
1258 TabClass[] selectedTabs;
1259 using (TabsDialog dialog = new TabsDialog(_sts))
1261 dialog.MultiSelect = true;
1262 dialog.Text = Properties.Resources.ButtonRuleCopy_ClickText1;
1264 if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
1266 selectedTabs = dialog.SelectedTabs;
1269 string tabname = ListTabs.SelectedItem.ToString();
1270 List<PostFilterRule> filters = new List<PostFilterRule>();
1272 foreach (int idx in ListFilters.SelectedIndices)
1274 filters.Add(_sts.Tabs[tabname].FilterArray[idx].Clone());
1276 foreach (var tb in selectedTabs)
1278 if (tb.TabName == tabname) continue;
1280 foreach (PostFilterRule flt in filters)
1282 if (!tb.FilterArray.Contains(flt))
1283 tb.AddFilter(flt.Clone());
1286 SetFilters(tabname);
1290 private void ButtonRuleMove_Click(object sender, EventArgs e)
1292 if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
1294 TabClass[] selectedTabs;
1295 using (var dialog = new TabsDialog(_sts))
1297 dialog.MultiSelect = true;
1298 dialog.Text = Properties.Resources.ButtonRuleMove_ClickText1;
1300 if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
1302 selectedTabs = dialog.SelectedTabs;
1304 string tabname = ListTabs.SelectedItem.ToString();
1305 List<PostFilterRule> filters = new List<PostFilterRule>();
1307 foreach (int idx in ListFilters.SelectedIndices)
1309 filters.Add(_sts.Tabs[tabname].FilterArray[idx].Clone());
1311 if (selectedTabs.Length == 1 && selectedTabs[0].TabName == tabname) return;
1312 foreach (var tb in selectedTabs)
1314 if (tb.TabName == tabname) continue;
1316 foreach (PostFilterRule flt in filters)
1318 if (!tb.FilterArray.Contains(flt))
1319 tb.AddFilter(flt.Clone());
1322 for (int idx = ListFilters.Items.Count - 1; idx >= 0; idx--)
1324 if (ListFilters.GetSelected(idx))
1326 _sts.Tabs[ListTabs.SelectedItem.ToString()].RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
1327 ListFilters.Items.RemoveAt(idx);
1330 SetFilters(tabname);
1334 private void FilterTextBox_KeyDown(object sender, KeyEventArgs e)
1336 if (e.KeyCode == Keys.Space && e.Modifiers == (Keys.Shift | Keys.Control))
1338 TweenMain main = (TweenMain)this.Owner;
1339 TextBox tbox = (TextBox)sender;
1340 if (tbox.SelectionStart > 0)
1342 int endidx = tbox.SelectionStart - 1;
1343 string startstr = "";
1344 for (int i = tbox.SelectionStart - 1; i >= 0; i--)
1346 char c = tbox.Text[i];
1347 if (Char.IsLetterOrDigit(c) || c == '_')
1353 startstr = tbox.Text.Substring(i + 1, endidx - i);
1354 main.ShowSuplDialog(tbox, main.AtIdSupl, startstr.Length + 1, startstr);
1358 startstr = tbox.Text.Substring(i + 1, endidx - i);
1359 main.ShowSuplDialog(tbox, main.HashSupl, startstr.Length + 1, startstr);
1371 private void FilterTextBox_KeyPress(object sender, KeyPressEventArgs e)
1373 TweenMain main = (TweenMain)this.Owner;
1374 TextBox tbox = (TextBox)sender;
1375 if (e.KeyChar == '@')
1377 //if (!SettingDialog.UseAtIdSupplement) return;
1379 main.ShowSuplDialog(tbox, main.AtIdSupl);
1382 else if (e.KeyChar == '#')
1384 //if (!SettingDialog.UseHashSupplement) return;
1385 main.ShowSuplDialog(tbox, main.HashSupl);
1390 private void ListFilters_DrawItem(object sender, DrawItemEventArgs e)
1396 var filter = (PostFilterRule)this.ListFilters.Items[e.Index];
1397 var isSelected = e.State.HasFlag(DrawItemState.Selected);
1401 textBrush = SystemBrushes.HighlightText;
1402 else if (filter.Enabled)
1403 textBrush = SystemBrushes.WindowText;
1405 textBrush = SystemBrushes.GrayText;
1407 e.Graphics.DrawString(filter.ToString(), e.Font, textBrush, e.Bounds);
1410 e.DrawFocusRectangle();
1413 protected override void OnFontChanged(EventArgs e)
1415 base.OnFontChanged(e);
1416 this.ListFilters.ItemHeight = this.ListFilters.Font.Height;