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 MultiSelectionState _multiSelState = MultiSelectionState.None;
47 private TabInformations _sts;
49 private List<string> idlist = new List<string>();
58 private enum EnableButtonMode
66 private enum MultiSelectionState
73 private EnableButtonMode RuleEnableButtonMode
75 get { return this._ruleEnableButtonMode; }
78 this._ruleEnableButtonMode = value;
80 this.buttonRuleToggleEnabled.Text = value == FilterDialog.EnableButtonMode.Enable
81 ? Properties.Resources.EnableButtonCaption
82 : Properties.Resources.DisableButtonCaption;
83 this.buttonRuleToggleEnabled.Enabled = value != EnableButtonMode.NotSelected;
86 private EnableButtonMode _ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected;
90 InitializeComponent();
93 private void SetFilters(string tabName)
95 if (ListTabs.Items.Count == 0) return;
97 var tab = _sts.Tabs[tabName];
99 ListFilters.Items.Clear();
100 ListFilters.Items.AddRange(tab.GetFilters());
102 if (ListFilters.Items.Count > 0)
103 ListFilters.SelectedIndex = 0;
107 if (tab.IsDefaultTabType)
109 CheckProtected.Checked = true;
110 CheckProtected.Enabled = false;
114 CheckProtected.Checked = tab.Protected;
115 CheckProtected.Enabled = true;
118 CheckManageRead.Checked = tab.UnreadManage;
119 CheckNotifyNew.Checked = tab.Notify;
121 int idx = ComboSound.Items.IndexOf(tab.SoundFile);
122 if (idx == -1) idx = 0;
123 ComboSound.SelectedIndex = idx;
125 if (_directAdd) return;
127 if (tab.TabType == MyCommon.TabUsageType.Mute)
129 this.CheckManageRead.Enabled = false;
130 this.CheckNotifyNew.Enabled = false;
131 this.ComboSound.Enabled = false;
133 this.GroupBox1.Visible = false;
134 this.labelMuteTab.Visible = true;
138 this.CheckManageRead.Enabled = true;
139 this.CheckNotifyNew.Enabled = true;
140 this.ComboSound.Enabled = true;
142 this.GroupBox1.Visible = true;
143 this.labelMuteTab.Visible = false;
146 ListTabs.Enabled = true;
147 GroupTab.Enabled = true;
148 ListFilters.Enabled = true;
149 EditFilterGroup.Enabled = false;
152 case MyCommon.TabUsageType.Home:
153 case MyCommon.TabUsageType.DirectMessage:
154 case MyCommon.TabUsageType.Favorites:
155 case MyCommon.TabUsageType.PublicSearch:
156 case MyCommon.TabUsageType.Lists:
157 case MyCommon.TabUsageType.Related:
158 case MyCommon.TabUsageType.UserTimeline:
159 ButtonNew.Enabled = false;
160 ButtonEdit.Enabled = false;
161 ButtonDelete.Enabled = false;
162 ButtonRuleUp.Enabled = false;
163 ButtonRuleDown.Enabled = false;
164 ButtonRuleCopy.Enabled = false;
165 ButtonRuleMove.Enabled = false;
166 buttonRuleToggleEnabled.Enabled = false;
169 ButtonNew.Enabled = true;
170 if (ListFilters.SelectedIndex > -1)
172 ButtonEdit.Enabled = true;
173 ButtonDelete.Enabled = true;
174 ButtonRuleUp.Enabled = true;
175 ButtonRuleDown.Enabled = true;
176 ButtonRuleCopy.Enabled = true;
177 ButtonRuleMove.Enabled = true;
178 buttonRuleToggleEnabled.Enabled = true;
182 ButtonEdit.Enabled = false;
183 ButtonDelete.Enabled = false;
184 ButtonRuleUp.Enabled = false;
185 ButtonRuleDown.Enabled = false;
186 ButtonRuleCopy.Enabled = false;
187 ButtonRuleMove.Enabled = false;
188 buttonRuleToggleEnabled.Enabled = false;
194 case MyCommon.TabUsageType.Home:
195 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Home;
197 case MyCommon.TabUsageType.Mentions:
198 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Mentions;
200 case MyCommon.TabUsageType.DirectMessage:
201 LabelTabType.Text = Properties.Resources.TabUsageTypeName_DirectMessage;
203 case MyCommon.TabUsageType.Favorites:
204 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Favorites;
206 case MyCommon.TabUsageType.UserDefined:
207 LabelTabType.Text = Properties.Resources.TabUsageTypeName_UserDefined;
209 case MyCommon.TabUsageType.PublicSearch:
210 LabelTabType.Text = Properties.Resources.TabUsageTypeName_PublicSearch;
212 case MyCommon.TabUsageType.Lists:
213 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Lists;
215 case MyCommon.TabUsageType.Related:
216 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Related;
218 case MyCommon.TabUsageType.UserTimeline:
219 LabelTabType.Text = Properties.Resources.TabUsageTypeName_UserTimeline;
221 case MyCommon.TabUsageType.Mute:
222 LabelTabType.Text = "Mute";
224 case MyCommon.TabUsageType.SearchResults:
225 LabelTabType.Text = "SearchResults";
228 LabelTabType.Text = "UNKNOWN";
231 ButtonRenameTab.Enabled = true;
232 if (tab.IsDefaultTabType || tab.Protected)
234 ButtonDeleteTab.Enabled = false;
238 ButtonDeleteTab.Enabled = true;
240 ButtonClose.Enabled = true;
243 public void SetCurrent(string TabName)
248 public void AddNewFilter(string id, string msg)
251 ButtonNew.Enabled = false;
252 ButtonEdit.Enabled = false;
253 ButtonRuleUp.Enabled = false;
254 ButtonRuleDown.Enabled = false;
255 ButtonRuleCopy.Enabled = false;
256 ButtonRuleMove.Enabled = false;
257 buttonRuleToggleEnabled.Enabled = false;
258 ButtonDelete.Enabled = false;
259 ButtonClose.Enabled = false;
260 EditFilterGroup.Enabled = true;
261 ListTabs.Enabled = false;
262 GroupTab.Enabled = false;
263 ListFilters.Enabled = false;
265 RadioAND.Checked = true;
266 RadioPLUS.Checked = false;
271 MSG2.Text = id + msg;
273 TextSource.Text = "";
276 MSG2.Enabled = false;
277 CheckRegex.Checked = false;
278 CheckURL.Checked = false;
279 CheckCaseSensitive.Checked = false;
280 CheckRetweet.Checked = false;
281 CheckLambda.Checked = false;
283 RadioExAnd.Checked = true;
284 RadioExPLUS.Checked = false;
291 TextExSource.Text = "";
292 ExUID.Enabled = true;
293 ExMSG1.Enabled = true;
294 ExMSG2.Enabled = false;
295 CheckExRegex.Checked = false;
296 CheckExURL.Checked = false;
297 CheckExCaseSensitive.Checked = false;
298 CheckExRetweet.Checked = false;
299 CheckExLambDa.Checked = false;
301 OptCopy.Checked = true;
302 CheckMark.Checked = true;
304 _mode = EDITMODE.AddNew;
308 private void ButtonNew_Click(object sender, EventArgs e)
310 ButtonNew.Enabled = false;
311 ButtonEdit.Enabled = false;
312 ButtonClose.Enabled = false;
313 ButtonRuleUp.Enabled = false;
314 ButtonRuleDown.Enabled = false;
315 ButtonRuleCopy.Enabled = false;
316 ButtonRuleMove.Enabled = false;
317 buttonRuleToggleEnabled.Enabled = false;
318 ButtonDelete.Enabled = false;
319 ButtonClose.Enabled = false;
320 EditFilterGroup.Enabled = true;
321 ListTabs.Enabled = false;
322 GroupTab.Enabled = false;
323 ListFilters.Enabled = false;
325 RadioAND.Checked = true;
326 RadioPLUS.Checked = false;
330 TextSource.Text = "";
333 MSG2.Enabled = false;
334 CheckRegex.Checked = false;
335 CheckURL.Checked = false;
336 CheckCaseSensitive.Checked = false;
337 CheckRetweet.Checked = false;
338 CheckLambda.Checked = false;
340 RadioExAnd.Checked = true;
341 RadioExPLUS.Checked = false;
345 TextExSource.Text = "";
346 ExUID.Enabled = true;
347 ExMSG1.Enabled = true;
348 ExMSG2.Enabled = false;
349 CheckExRegex.Checked = false;
350 CheckExURL.Checked = false;
351 CheckExCaseSensitive.Checked = false;
352 CheckExRetweet.Checked = false;
353 CheckExLambDa.Checked = false;
355 OptCopy.Checked = true;
356 CheckMark.Checked = true;
358 _mode = EDITMODE.AddNew;
361 private void ButtonEdit_Click(object sender, EventArgs e)
363 if (ListFilters.SelectedIndex == -1) return;
367 int idx = ListFilters.SelectedIndex;
368 ListFilters.SelectedIndex = -1;
369 ListFilters.SelectedIndex = idx;
370 ListFilters.Enabled = false;
372 ButtonNew.Enabled = false;
373 ButtonEdit.Enabled = false;
374 ButtonDelete.Enabled = false;
375 ButtonClose.Enabled = false;
376 ButtonRuleUp.Enabled = false;
377 ButtonRuleDown.Enabled = false;
378 ButtonRuleCopy.Enabled = false;
379 ButtonRuleMove.Enabled = false;
380 buttonRuleToggleEnabled.Enabled = false;
381 EditFilterGroup.Enabled = true;
382 ListTabs.Enabled = false;
383 GroupTab.Enabled = false;
385 _mode = EDITMODE.Edit;
388 private void ButtonDelete_Click(object sender, EventArgs e)
390 var selectedCount = ListFilters.SelectedIndices.Count;
391 if (selectedCount == 0) return;
395 if (selectedCount == 1)
397 tmp = string.Format(Properties.Resources.ButtonDelete_ClickText1, Environment.NewLine, ListFilters.SelectedItem.ToString());
401 tmp = string.Format(Properties.Resources.ButtonDelete_ClickText3, selectedCount.ToString());
404 var rslt = MessageBox.Show(tmp, Properties.Resources.ButtonDelete_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
405 if (rslt == DialogResult.Cancel) return;
407 var indices = ListFilters.SelectedIndices.Cast<int>().Reverse().ToArray(); // 後ろの要素から削除
408 var tab = _sts.Tabs[ListTabs.SelectedItem.ToString()];
410 using (ControlTransaction.Update(ListFilters))
412 foreach (var idx in indices)
414 tab.RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
415 ListFilters.Items.RemoveAt(idx);
420 private void ButtonCancel_Click(object sender, EventArgs e)
422 ListTabs.Enabled = true;
423 GroupTab.Enabled = true;
424 ListFilters.Enabled = true;
426 if (ListFilters.SelectedIndex != -1)
430 EditFilterGroup.Enabled = false;
431 ButtonNew.Enabled = true;
432 if (ListFilters.SelectedIndex > -1)
434 ButtonEdit.Enabled = true;
435 ButtonDelete.Enabled = true;
436 ButtonRuleUp.Enabled = true;
437 ButtonRuleDown.Enabled = true;
438 ButtonRuleCopy.Enabled = true;
439 ButtonRuleMove.Enabled = true;
440 buttonRuleToggleEnabled.Enabled = true;
444 ButtonEdit.Enabled = false;
445 ButtonDelete.Enabled = false;
446 ButtonRuleUp.Enabled = false;
447 ButtonRuleDown.Enabled = false;
448 ButtonRuleCopy.Enabled = false;
449 ButtonRuleMove.Enabled = false;
450 buttonRuleToggleEnabled.Enabled = false;
452 ButtonClose.Enabled = true;
459 private void ShowDetail()
461 if (_directAdd) return;
463 if (ListFilters.SelectedIndex > -1)
465 PostFilterRule fc = (PostFilterRule)ListFilters.SelectedItem;
468 RadioAND.Checked = true;
469 RadioPLUS.Checked = false;
472 MSG2.Enabled = false;
473 UID.Text = fc.FilterName;
475 MSG1.Text = string.Join(" ", fc.FilterBody);
481 RadioPLUS.Checked = true;
482 RadioAND.Checked = false;
484 MSG1.Enabled = false;
488 MSG2.Text = string.Join(" ", fc.FilterBody);
491 TextSource.Text = fc.FilterSource;
492 CheckRegex.Checked = fc.UseRegex;
493 CheckURL.Checked = fc.FilterByUrl;
494 CheckCaseSensitive.Checked = fc.CaseSensitive;
495 CheckRetweet.Checked = fc.FilterRt;
496 CheckLambda.Checked = fc.UseLambda;
498 if (fc.ExUseNameField)
500 RadioExAnd.Checked = true;
501 RadioExPLUS.Checked = false;
502 ExUID.Enabled = true;
503 ExMSG1.Enabled = true;
504 ExMSG2.Enabled = false;
505 ExUID.Text = fc.ExFilterName;
507 ExMSG1.Text = string.Join(" ", fc.ExFilterBody);
513 RadioExPLUS.Checked = true;
514 RadioExAnd.Checked = false;
515 ExUID.Enabled = false;
516 ExMSG1.Enabled = false;
517 ExMSG2.Enabled = true;
520 ExMSG2.Text = string.Join(" ", fc.ExFilterBody);
523 TextExSource.Text = fc.ExFilterSource;
524 CheckExRegex.Checked = fc.ExUseRegex;
525 CheckExURL.Checked = fc.ExFilterByUrl;
526 CheckExCaseSensitive.Checked = fc.ExCaseSensitive;
527 CheckExRetweet.Checked = fc.ExFilterRt;
528 CheckExLambDa.Checked = fc.ExUseLambda;
532 OptMove.Checked = true;
536 OptCopy.Checked = true;
538 CheckMark.Checked = fc.MarkMatches;
540 ButtonEdit.Enabled = true;
541 ButtonDelete.Enabled = true;
542 ButtonRuleUp.Enabled = true;
543 ButtonRuleDown.Enabled = true;
544 ButtonRuleCopy.Enabled = true;
545 ButtonRuleMove.Enabled = true;
546 buttonRuleToggleEnabled.Enabled = true;
550 RadioAND.Checked = true;
551 RadioPLUS.Checked = false;
554 MSG2.Enabled = false;
558 TextSource.Text = "";
559 CheckRegex.Checked = false;
560 CheckURL.Checked = false;
561 CheckCaseSensitive.Checked = false;
562 CheckRetweet.Checked = false;
563 CheckLambda.Checked = false;
565 RadioExAnd.Checked = true;
566 RadioExPLUS.Checked = false;
567 ExUID.Enabled = true;
568 ExMSG1.Enabled = true;
569 ExMSG2.Enabled = false;
573 TextExSource.Text = "";
574 CheckExRegex.Checked = false;
575 CheckExURL.Checked = false;
576 CheckExCaseSensitive.Checked = false;
577 CheckExRetweet.Checked = false;
578 CheckExLambDa.Checked = false;
580 OptCopy.Checked = true;
581 CheckMark.Checked = true;
583 ButtonEdit.Enabled = false;
584 ButtonDelete.Enabled = false;
585 ButtonRuleUp.Enabled = false;
586 ButtonRuleDown.Enabled = false;
587 ButtonRuleCopy.Enabled = false;
588 ButtonRuleMove.Enabled = false;
589 buttonRuleToggleEnabled.Enabled = false;
593 private void RadioAND_CheckedChanged(object sender, EventArgs e)
595 bool flg = RadioAND.Checked;
601 private void ButtonOK_Click(object sender, EventArgs e)
603 bool isBlankMatch = false;
604 bool isBlankExclude = false;
607 if (!CheckMatchRule(out isBlankMatch) || !CheckExcludeRule(out isBlankExclude))
611 if (isBlankMatch && isBlankExclude)
613 MessageBox.Show(Properties.Resources.ButtonOK_ClickText1, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
617 var tab = this._sts.Tabs[(string)this.ListTabs.SelectedItem];
618 int i = ListFilters.SelectedIndex;
621 if (_mode == EDITMODE.AddNew)
622 ft = new PostFilterRule();
624 ft = (PostFilterRule)this.ListFilters.SelectedItem;
626 if (tab.TabType != MyCommon.TabUsageType.Mute)
628 ft.MoveMatches = OptMove.Checked;
629 ft.MarkMatches = CheckMark.Checked;
633 ft.MoveMatches = true;
634 ft.MarkMatches = false;
638 if (RadioAND.Checked)
640 ft.FilterName = UID.Text;
641 TweenMain owner = (TweenMain)this.Owner;
642 int cnt = owner.AtIdSupl.ItemCount;
643 owner.AtIdSupl.AddItem("@" + ft.FilterName);
644 if (cnt != owner.AtIdSupl.ItemCount)
646 owner.ModifySettingAtId = true;
648 ft.UseNameField = true;
654 ft.UseNameField = false;
657 ft.FilterSource = TextSource.Text;
659 if (CheckRegex.Checked || CheckLambda.Checked)
661 ft.FilterBody = new[] { bdy };
665 ft.FilterBody = bdy.Split(' ', ' ')
666 .Where(x => !string.IsNullOrEmpty(x))
670 ft.UseRegex = CheckRegex.Checked;
671 ft.FilterByUrl = CheckURL.Checked;
672 ft.CaseSensitive = CheckCaseSensitive.Checked;
673 ft.FilterRt = CheckRetweet.Checked;
674 ft.UseLambda = CheckLambda.Checked;
677 if (RadioExAnd.Checked)
679 ft.ExFilterName = ExUID.Text;
680 ft.ExUseNameField = true;
685 ft.ExFilterName = "";
686 ft.ExUseNameField = false;
689 ft.ExFilterSource = TextExSource.Text;
691 if (CheckExRegex.Checked || CheckExLambDa.Checked)
693 ft.ExFilterBody = new[] { bdy };
697 ft.ExFilterBody = bdy.Split(' ', ' ')
698 .Where(x => !string.IsNullOrEmpty(x))
702 ft.ExUseRegex = CheckExRegex.Checked;
703 ft.ExFilterByUrl = CheckExURL.Checked;
704 ft.ExCaseSensitive = CheckExCaseSensitive.Checked;
705 ft.ExFilterRt = CheckExRetweet.Checked;
706 ft.ExUseLambda = CheckExLambDa.Checked;
708 if (_mode == EDITMODE.AddNew)
710 if (!tab.AddFilter(ft))
711 MessageBox.Show(Properties.Resources.ButtonOK_ClickText4, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Error);
714 SetFilters(tab.TabName);
715 ListFilters.SelectedIndex = -1;
716 if (_mode == EDITMODE.AddNew)
718 ListFilters.SelectedIndex = ListFilters.Items.Count - 1;
722 ListFilters.SelectedIndex = i;
724 _mode = EDITMODE.None;
732 private bool IsValidLambdaExp(string text)
735 // TODO DynamicQuery相当のGPLv3互換なライブラリで置換する
738 private bool IsValidRegexp(string text)
746 MessageBox.Show(Properties.Resources.ButtonOK_ClickText3 + ex.Message, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
752 private bool CheckMatchRule(out bool isBlank)
755 if (RadioAND.Checked)
757 if (string.IsNullOrEmpty(UID.Text) && string.IsNullOrEmpty(MSG1.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false)
762 if (CheckLambda.Checked)
764 if (!IsValidLambdaExp(UID.Text))
768 if (!IsValidLambdaExp(MSG1.Text))
773 else if (CheckRegex.Checked)
775 if (!IsValidRegexp(UID.Text))
779 if (!IsValidRegexp(MSG1.Text))
787 if (string.IsNullOrEmpty(MSG2.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false)
792 if (CheckLambda.Checked && !IsValidLambdaExp(MSG2.Text))
796 else if (CheckRegex.Checked && !IsValidRegexp(MSG2.Text))
802 if (CheckRegex.Checked && !IsValidRegexp(TextSource.Text))
809 private bool CheckExcludeRule(out bool isBlank)
812 if (RadioExAnd.Checked)
814 if (string.IsNullOrEmpty(ExUID.Text) && string.IsNullOrEmpty(ExMSG1.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false)
819 if (CheckExLambDa.Checked)
821 if (!IsValidLambdaExp(ExUID.Text))
825 if (!IsValidLambdaExp(ExMSG1.Text))
830 else if (CheckExRegex.Checked)
832 if (!IsValidRegexp(ExUID.Text))
836 if (!IsValidRegexp(ExMSG1.Text))
844 if (string.IsNullOrEmpty(ExMSG2.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false)
849 if (CheckExLambDa.Checked && !IsValidLambdaExp(ExMSG2.Text))
853 else if (CheckExRegex.Checked && !IsValidRegexp(ExMSG2.Text))
859 if (CheckExRegex.Checked && !IsValidRegexp(TextExSource.Text))
867 private void ListFilters_SelectedIndexChanged(object sender, EventArgs e)
869 if (_multiSelState != MultiSelectionState.None) //複数選択処理中は無視する
874 var selectedCount = this.ListFilters.SelectedIndices.Count;
875 if (selectedCount == 0)
877 this.RuleEnableButtonMode = EnableButtonMode.NotSelected;
881 if (selectedCount == 1 ||
882 this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
884 var topItem = (PostFilterRule)this.ListFilters.SelectedItem;
885 this.RuleEnableButtonMode = topItem.Enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
890 private void ButtonClose_Click(object sender, EventArgs e)
895 private void FilterDialog_FormClosed(object sender, FormClosedEventArgs e)
900 private void FilterDialog_KeyDown(object sender, KeyEventArgs e)
902 if (e.KeyCode == Keys.Escape)
904 if (EditFilterGroup.Enabled)
905 ButtonCancel_Click(null, null);
907 ButtonClose_Click(null, null);
911 private void ListFilters_DoubleClick(object sender, EventArgs e)
913 var idx = ListFilters.SelectedIndex;
914 if (idx == -1) return;
916 var midx = ListFilters.IndexFromPoint(ListFilters.PointToClient(Control.MousePosition));
917 if (midx == ListBox.NoMatches || idx != midx) return;
919 ButtonEdit_Click(sender, e);
922 private void FilterDialog_Shown(object sender, EventArgs e)
924 _sts = TabInformations.GetInstance();
925 ListTabs.Items.Clear();
926 foreach (var tab in this._sts.Tabs.Values)
928 if (tab.TabType == MyCommon.TabUsageType.Mute)
931 this.ListTabs.Items.Add(tab.TabName);
934 var muteTab = this._sts.GetTabByType(MyCommon.TabUsageType.Mute);
936 this.ListTabs.Items.Add(muteTab.TabName);
938 ComboSound.Items.Clear();
939 ComboSound.Items.Add("");
940 DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
941 if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds")))
943 oDir = oDir.GetDirectories("Sounds")[0];
945 foreach (FileInfo oFile in oDir.GetFiles("*.wav"))
947 ComboSound.Items.Add(oFile.Name);
951 foreach (string tmp in ((TweenMain)this.Owner).AtIdSupl.GetItemList())
953 idlist.Add(tmp.Remove(0, 1)); // @文字削除
955 UID.AutoCompleteCustomSource.Clear();
956 UID.AutoCompleteCustomSource.AddRange(idlist.ToArray());
958 ExUID.AutoCompleteCustomSource.Clear();
959 ExUID.AutoCompleteCustomSource.AddRange(idlist.ToArray());
962 if (ListTabs.Items.Count > 0)
966 for (int i = 0; i < ListTabs.Items.Count; i++)
968 if (_cur == ListTabs.Items[i].ToString())
970 ListTabs.SelectedIndex = i;
971 //tabdialog.TabList.Items.Remove(_cur);
979 private void ListTabs_SelectedIndexChanged(object sender, EventArgs e)
981 if (ListTabs.SelectedIndex > -1)
982 SetFilters(ListTabs.SelectedItem.ToString());
984 ListFilters.Items.Clear();
987 private void ButtonAddTab_Click(object sender, EventArgs e)
989 string tabName = null;
990 MyCommon.TabUsageType tabType;
991 using (InputTabName inputName = new InputTabName())
993 inputName.TabName = _sts.MakeTabName("MyTab");
994 inputName.IsShowUsage = true;
995 inputName.ShowDialog();
996 if (inputName.DialogResult == DialogResult.Cancel) return;
997 tabName = inputName.TabName;
998 tabType = inputName.Usage;
1000 if (!string.IsNullOrEmpty(tabName))
1003 ListElement list = null;
1004 if (tabType == MyCommon.TabUsageType.Lists)
1008 ((TweenMain)this.Owner).TwitterInstance.GetListsApi();
1010 catch (WebApiException ex)
1012 MessageBox.Show("Failed to get lists. (" + ex.Message + ")");
1014 using (ListAvailable listAvail = new ListAvailable())
1016 if (listAvail.ShowDialog(this) == DialogResult.Cancel) return;
1017 if (listAvail.SelectedList == null) return;
1018 list = listAvail.SelectedList;
1021 if (!_sts.AddTab(tabName, tabType, list) || !((TweenMain)this.Owner).AddNewTab(tabName, false, tabType, list))
1023 string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
1024 MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
1032 var lastIdx = this.ListTabs.Items.Count - 1;
1033 var lastTab = lastIdx != -1
1034 ? this._sts.Tabs[(string)this.ListTabs.Items[lastIdx]]
1037 // 末尾がミュートタブであればその手前に追加する
1038 if (lastTab != null && lastTab.TabType == MyCommon.TabUsageType.Mute)
1039 this.ListTabs.Items.Insert(lastIdx, tabName);
1041 this.ListTabs.Items.Add(tabName);
1046 private void ButtonDeleteTab_Click(object sender, EventArgs e)
1048 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1050 string tb = ListTabs.SelectedItem.ToString();
1051 int idx = ListTabs.SelectedIndex;
1052 if (((TweenMain)this.Owner).RemoveSpecifiedTab(tb, true))
1054 ListTabs.Items.RemoveAt(idx);
1056 if (idx < 0) idx = 0;
1057 ListTabs.SelectedIndex = idx;
1062 private void ButtonRenameTab_Click(object sender, EventArgs e)
1064 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1066 string tb = ListTabs.SelectedItem.ToString();
1067 int idx = ListTabs.SelectedIndex;
1068 if (((TweenMain)this.Owner).TabRename(ref tb))
1070 ListTabs.Items.RemoveAt(idx);
1071 ListTabs.Items.Insert(idx, tb);
1072 ListTabs.SelectedIndex = idx;
1077 private void CheckManageRead_CheckedChanged(object sender, EventArgs e)
1079 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1081 ((TweenMain)this.Owner).ChangeTabUnreadManage(
1082 ListTabs.SelectedItem.ToString(),
1083 CheckManageRead.Checked);
1087 private void ButtonUp_Click(object sender, EventArgs e)
1089 if (this.ListTabs.SelectedIndex == -1 || this.ListTabs.SelectedIndex == 0)
1092 var selectedTabName = (string)this.ListTabs.SelectedItem;
1093 var selectedTab = this._sts.Tabs[selectedTabName];
1095 var targetTabName = (string)this.ListTabs.Items[this.ListTabs.SelectedIndex - 1];
1096 var targetTab = this._sts.Tabs[targetTabName];
1099 if (selectedTab.TabType == MyCommon.TabUsageType.Mute || targetTab.TabType == MyCommon.TabUsageType.Mute)
1102 var tweenMain = (TweenMain)this.Owner;
1103 tweenMain.ReOrderTab(selectedTabName, targetTabName, true);
1105 // ListTab のアイテム並び替え
1106 // 選択が解除されてしまうのを防ぐため SelectedIndex のアイテムは操作せず前後のアイテムを移動する
1107 var idx = this.ListTabs.SelectedIndex;
1108 this.ListTabs.Items.RemoveAt(idx - 1);
1109 this.ListTabs.Items.Insert(idx, targetTabName);
1112 private void ButtonDown_Click(object sender, EventArgs e)
1114 if (this.ListTabs.SelectedIndex == -1 || this.ListTabs.SelectedIndex == this.ListTabs.Items.Count - 1)
1117 var selectedTabName = (string)this.ListTabs.SelectedItem;
1118 var selectedTab = this._sts.Tabs[selectedTabName];
1120 var targetTabName = (string)this.ListTabs.Items[this.ListTabs.SelectedIndex + 1];
1121 var targetTab = this._sts.Tabs[targetTabName];
1124 if (selectedTab.TabType == MyCommon.TabUsageType.Mute || targetTab.TabType == MyCommon.TabUsageType.Mute)
1127 var tweenMain = (TweenMain)this.Owner;
1128 tweenMain.ReOrderTab(selectedTabName, targetTabName, false);
1130 // ListTab のアイテム並び替え
1131 // 選択が解除されてしまうのを防ぐため SelectedIndex のアイテムは操作せず前後のアイテムを移動する
1132 var idx = this.ListTabs.SelectedIndex;
1133 this.ListTabs.Items.RemoveAt(idx + 1);
1134 this.ListTabs.Items.Insert(idx, targetTabName);
1137 private void CheckLocked_CheckedChanged(object sender, EventArgs e)
1139 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1141 _sts.Tabs[ListTabs.SelectedItem.ToString()].Protected = CheckProtected.Checked;
1142 ButtonDeleteTab.Enabled = !CheckProtected.Checked;
1146 private void CheckNotifyNew_CheckedChanged(object sender, EventArgs e)
1148 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1150 _sts.Tabs[ListTabs.SelectedItem.ToString()].Notify = CheckNotifyNew.Checked;
1154 private void ComboSound_SelectedIndexChanged(object sender, EventArgs e)
1156 if (ListTabs.SelectedIndex > -1 && string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1158 string filename = "";
1159 if (ComboSound.SelectedIndex > -1) filename = ComboSound.SelectedItem.ToString();
1160 _sts.Tabs[ListTabs.SelectedItem.ToString()].SoundFile = filename;
1164 private void RadioExAnd_CheckedChanged(object sender, EventArgs e)
1166 bool flg = RadioExAnd.Checked;
1167 ExUID.Enabled = flg;
1168 ExMSG1.Enabled = flg;
1169 ExMSG2.Enabled = !flg;
1172 private void OptMove_CheckedChanged(object sender, EventArgs e)
1174 CheckMark.Enabled = !OptMove.Checked;
1177 private void ButtonRuleUp_Click(object sender, EventArgs e)
1179 MoveSelectedRules(up: true);
1182 private void ButtonRuleDown_Click(object sender, EventArgs e)
1184 MoveSelectedRules(up: false);
1187 private void MoveSelectedRules(bool up)
1189 var tabIdx = ListTabs.SelectedIndex;
1191 ListFilters.SelectedIndices.Count == 0) return;
1193 var indices = ListFilters.SelectedIndices.Cast<int>().ToArray();
1198 if (indices[0] <= 0) return;
1203 if (indices[indices.Length - 1] >= ListFilters.Items.Count - 1) return;
1205 Array.Reverse(indices); // 逆順にして、下にある要素から処理する
1208 var lastSelIdx = indices[0] + diff;
1209 var tab = _sts.Tabs[ListTabs.Items[tabIdx].ToString()];
1213 _multiSelState |= MultiSelectionState.MoveSelected;
1215 using (ControlTransaction.Update(ListFilters))
1217 ListFilters.SelectedIndices.Clear();
1219 foreach (var idx in indices)
1221 var tidx = idx + diff;
1222 var target = (PostFilterRule)ListFilters.Items[tidx];
1224 // 移動先にある要素と位置を入れ替える
1225 ListFilters.Items.RemoveAt(tidx);
1226 ListFilters.Items.Insert(idx, target);
1228 // 移動方向の先頭要素以外なら選択する
1229 if (tidx != lastSelIdx)
1230 ListFilters.SelectedIndex = tidx;
1233 tab.FilterArray = ListFilters.Items.Cast<PostFilterRule>().ToArray();
1235 // 移動方向の先頭要素は最後に選択する
1237 ListFilters.SelectedIndex = lastSelIdx;
1242 _multiSelState &= ~MultiSelectionState.MoveSelected;
1246 private void buttonRuleToggleEnabled_Click(object sender, EventArgs e)
1248 if (this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
1251 var enabled = this.RuleEnableButtonMode == EnableButtonMode.Enable;
1253 foreach (var idx in this.ListFilters.SelectedIndices.Cast<int>())
1255 var filter = (PostFilterRule)this.ListFilters.Items[idx];
1256 if (filter.Enabled != enabled)
1258 filter.Enabled = enabled;
1260 var itemRect = this.ListFilters.GetItemRectangle(idx);
1261 this.ListFilters.Invalidate(itemRect);
1265 this.RuleEnableButtonMode = enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
1268 private void ButtonRuleCopy_Click(object sender, EventArgs e)
1270 if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
1272 TabClass[] selectedTabs;
1273 using (TabsDialog dialog = new TabsDialog(_sts))
1275 dialog.MultiSelect = true;
1276 dialog.Text = Properties.Resources.ButtonRuleCopy_ClickText1;
1278 if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
1280 selectedTabs = dialog.SelectedTabs;
1283 string tabname = ListTabs.SelectedItem.ToString();
1284 List<PostFilterRule> filters = new List<PostFilterRule>();
1286 foreach (int idx in ListFilters.SelectedIndices)
1288 filters.Add(_sts.Tabs[tabname].FilterArray[idx].Clone());
1290 foreach (var tb in selectedTabs)
1292 if (tb.TabName == tabname) continue;
1294 foreach (PostFilterRule flt in filters)
1296 if (!tb.FilterArray.Contains(flt))
1297 tb.AddFilter(flt.Clone());
1300 SetFilters(tabname);
1304 private void ButtonRuleMove_Click(object sender, EventArgs e)
1306 if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
1308 TabClass[] selectedTabs;
1309 using (var dialog = new TabsDialog(_sts))
1311 dialog.MultiSelect = true;
1312 dialog.Text = Properties.Resources.ButtonRuleMove_ClickText1;
1314 if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
1316 selectedTabs = dialog.SelectedTabs;
1318 string tabname = ListTabs.SelectedItem.ToString();
1319 List<PostFilterRule> filters = new List<PostFilterRule>();
1321 foreach (int idx in ListFilters.SelectedIndices)
1323 filters.Add(_sts.Tabs[tabname].FilterArray[idx].Clone());
1325 if (selectedTabs.Length == 1 && selectedTabs[0].TabName == tabname) return;
1326 foreach (var tb in selectedTabs)
1328 if (tb.TabName == tabname) continue;
1330 foreach (PostFilterRule flt in filters)
1332 if (!tb.FilterArray.Contains(flt))
1333 tb.AddFilter(flt.Clone());
1336 for (int idx = ListFilters.Items.Count - 1; idx >= 0; idx--)
1338 if (ListFilters.GetSelected(idx))
1340 _sts.Tabs[ListTabs.SelectedItem.ToString()].RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
1341 ListFilters.Items.RemoveAt(idx);
1344 SetFilters(tabname);
1348 private void FilterTextBox_KeyDown(object sender, KeyEventArgs e)
1350 if (e.KeyCode == Keys.Space && e.Modifiers == (Keys.Shift | Keys.Control))
1352 TweenMain main = (TweenMain)this.Owner;
1353 TextBox tbox = (TextBox)sender;
1354 if (tbox.SelectionStart > 0)
1356 int endidx = tbox.SelectionStart - 1;
1357 string startstr = "";
1358 for (int i = tbox.SelectionStart - 1; i >= 0; i--)
1360 char c = tbox.Text[i];
1361 if (Char.IsLetterOrDigit(c) || c == '_')
1367 startstr = tbox.Text.Substring(i + 1, endidx - i);
1368 main.ShowSuplDialog(tbox, main.AtIdSupl, startstr.Length + 1, startstr);
1372 startstr = tbox.Text.Substring(i + 1, endidx - i);
1373 main.ShowSuplDialog(tbox, main.HashSupl, startstr.Length + 1, startstr);
1385 private void FilterTextBox_KeyPress(object sender, KeyPressEventArgs e)
1387 TweenMain main = (TweenMain)this.Owner;
1388 TextBox tbox = (TextBox)sender;
1389 if (e.KeyChar == '@')
1391 //if (!SettingDialog.UseAtIdSupplement) return;
1393 main.ShowSuplDialog(tbox, main.AtIdSupl);
1396 else if (e.KeyChar == '#')
1398 //if (!SettingDialog.UseHashSupplement) return;
1399 main.ShowSuplDialog(tbox, main.HashSupl);
1404 private void ListFilters_DrawItem(object sender, DrawItemEventArgs e)
1410 var filter = (PostFilterRule)this.ListFilters.Items[e.Index];
1411 var isSelected = e.State.HasFlag(DrawItemState.Selected);
1415 textBrush = SystemBrushes.HighlightText;
1416 else if (filter.Enabled)
1417 textBrush = SystemBrushes.WindowText;
1419 textBrush = SystemBrushes.GrayText;
1421 e.Graphics.DrawString(filter.ToString(), e.Font, textBrush, e.Bounds);
1424 e.DrawFocusRectangle();
1427 private void ListFilters_KeyDown(object sender, KeyEventArgs e)
1429 if (e.Control && e.KeyCode == Keys.A)
1431 var itemCount = this.ListFilters.Items.Count;
1432 if (itemCount == 0) return;
1434 using (ControlTransaction.Update(this.ListFilters))
1440 _multiSelState |= MultiSelectionState.SelectAll;
1442 for (int i = 1; i < itemCount; i++)
1444 this.ListFilters.SetSelected(i, true);
1449 _multiSelState &= ~MultiSelectionState.SelectAll;
1453 this.ListFilters.SetSelected(0, true);
1458 protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
1460 base.ScaleControl(factor, specified);
1461 this.ListFilters.ItemHeight = this.ListFilters.Font.Height;