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;
39 using OpenTween.Models;
43 public partial class FilterDialog : OTBaseForm
45 private EDITMODE _mode;
46 private bool _directAdd;
47 private MultiSelectionState _multiSelState = MultiSelectionState.None;
48 private TabInformations _sts;
50 private List<string> idlist = new List<string>();
59 private enum EnableButtonMode
67 private enum MultiSelectionState
74 private EnableButtonMode RuleEnableButtonMode
76 get { return this._ruleEnableButtonMode; }
79 this._ruleEnableButtonMode = value;
81 this.buttonRuleToggleEnabled.Text = value == FilterDialog.EnableButtonMode.Enable
82 ? Properties.Resources.EnableButtonCaption
83 : Properties.Resources.DisableButtonCaption;
84 this.buttonRuleToggleEnabled.Enabled = value != EnableButtonMode.NotSelected;
87 private EnableButtonMode _ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected;
91 InitializeComponent();
94 private void SetFilters(string tabName)
96 if (ListTabs.Items.Count == 0) return;
98 ListFilters.Items.Clear();
100 var tab = _sts.Tabs[tabName];
102 var filterTab = tab as FilterTabModel;
103 if (filterTab != null)
104 ListFilters.Items.AddRange(filterTab.GetFilters());
106 if (ListFilters.Items.Count > 0)
107 ListFilters.SelectedIndex = 0;
111 if (tab.IsDefaultTabType)
113 CheckProtected.Checked = true;
114 CheckProtected.Enabled = false;
118 CheckProtected.Checked = tab.Protected;
119 CheckProtected.Enabled = true;
122 CheckManageRead.Checked = tab.UnreadManage;
123 CheckNotifyNew.Checked = tab.Notify;
125 int idx = ComboSound.Items.IndexOf(tab.SoundFile);
126 if (idx == -1) idx = 0;
127 ComboSound.SelectedIndex = idx;
129 if (_directAdd) return;
131 if (tab.TabType == MyCommon.TabUsageType.Mute)
133 this.CheckManageRead.Enabled = false;
134 this.CheckNotifyNew.Enabled = false;
135 this.ComboSound.Enabled = false;
137 this.GroupBox1.Visible = false;
138 this.labelMuteTab.Visible = true;
142 this.CheckManageRead.Enabled = true;
143 this.CheckNotifyNew.Enabled = true;
144 this.ComboSound.Enabled = true;
146 this.GroupBox1.Visible = true;
147 this.labelMuteTab.Visible = false;
150 ListTabs.Enabled = true;
151 GroupTab.Enabled = true;
152 ListFilters.Enabled = true;
153 EditFilterGroup.Enabled = false;
155 if (tab.IsDistributableTabType)
157 ButtonNew.Enabled = true;
158 if (ListFilters.SelectedIndex > -1)
160 ButtonEdit.Enabled = true;
161 ButtonDelete.Enabled = true;
162 ButtonRuleUp.Enabled = true;
163 ButtonRuleDown.Enabled = true;
164 ButtonRuleCopy.Enabled = true;
165 ButtonRuleMove.Enabled = true;
166 buttonRuleToggleEnabled.Enabled = true;
170 ButtonEdit.Enabled = false;
171 ButtonDelete.Enabled = false;
172 ButtonRuleUp.Enabled = false;
173 ButtonRuleDown.Enabled = false;
174 ButtonRuleCopy.Enabled = false;
175 ButtonRuleMove.Enabled = false;
176 buttonRuleToggleEnabled.Enabled = false;
181 ButtonNew.Enabled = false;
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;
193 case MyCommon.TabUsageType.Home:
194 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Home;
196 case MyCommon.TabUsageType.Mentions:
197 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Mentions;
199 case MyCommon.TabUsageType.DirectMessage:
200 LabelTabType.Text = Properties.Resources.TabUsageTypeName_DirectMessage;
202 case MyCommon.TabUsageType.Favorites:
203 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Favorites;
205 case MyCommon.TabUsageType.UserDefined:
206 LabelTabType.Text = Properties.Resources.TabUsageTypeName_UserDefined;
208 case MyCommon.TabUsageType.PublicSearch:
209 LabelTabType.Text = Properties.Resources.TabUsageTypeName_PublicSearch;
211 case MyCommon.TabUsageType.Lists:
212 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Lists;
214 case MyCommon.TabUsageType.Related:
215 LabelTabType.Text = Properties.Resources.TabUsageTypeName_Related;
217 case MyCommon.TabUsageType.UserTimeline:
218 LabelTabType.Text = Properties.Resources.TabUsageTypeName_UserTimeline;
220 case MyCommon.TabUsageType.Mute:
221 LabelTabType.Text = "Mute";
223 case MyCommon.TabUsageType.SearchResults:
224 LabelTabType.Text = "SearchResults";
227 LabelTabType.Text = "UNKNOWN";
230 ButtonRenameTab.Enabled = true;
231 if (tab.IsDefaultTabType || tab.Protected)
233 ButtonDeleteTab.Enabled = false;
237 ButtonDeleteTab.Enabled = true;
239 ButtonClose.Enabled = true;
242 public void SetCurrent(string TabName)
247 public void AddNewFilter(string id, string msg)
250 ButtonNew.Enabled = false;
251 ButtonEdit.Enabled = false;
252 ButtonRuleUp.Enabled = false;
253 ButtonRuleDown.Enabled = false;
254 ButtonRuleCopy.Enabled = false;
255 ButtonRuleMove.Enabled = false;
256 buttonRuleToggleEnabled.Enabled = false;
257 ButtonDelete.Enabled = false;
258 ButtonClose.Enabled = false;
259 EditFilterGroup.Enabled = true;
260 ListTabs.Enabled = false;
261 GroupTab.Enabled = false;
262 ListFilters.Enabled = false;
264 RadioAND.Checked = true;
265 RadioPLUS.Checked = false;
270 MSG2.Text = id + msg;
272 TextSource.Text = "";
275 MSG2.Enabled = false;
276 CheckRegex.Checked = false;
277 CheckURL.Checked = false;
278 CheckCaseSensitive.Checked = false;
279 CheckRetweet.Checked = false;
280 CheckLambda.Checked = false;
282 RadioExAnd.Checked = true;
283 RadioExPLUS.Checked = false;
290 TextExSource.Text = "";
291 ExUID.Enabled = true;
292 ExMSG1.Enabled = true;
293 ExMSG2.Enabled = false;
294 CheckExRegex.Checked = false;
295 CheckExURL.Checked = false;
296 CheckExCaseSensitive.Checked = false;
297 CheckExRetweet.Checked = false;
298 CheckExLambDa.Checked = false;
300 OptCopy.Checked = true;
301 CheckMark.Checked = true;
303 _mode = EDITMODE.AddNew;
307 private void ButtonNew_Click(object sender, EventArgs e)
309 ButtonNew.Enabled = false;
310 ButtonEdit.Enabled = false;
311 ButtonClose.Enabled = false;
312 ButtonRuleUp.Enabled = false;
313 ButtonRuleDown.Enabled = false;
314 ButtonRuleCopy.Enabled = false;
315 ButtonRuleMove.Enabled = false;
316 buttonRuleToggleEnabled.Enabled = false;
317 ButtonDelete.Enabled = false;
318 ButtonClose.Enabled = false;
319 EditFilterGroup.Enabled = true;
320 ListTabs.Enabled = false;
321 GroupTab.Enabled = false;
322 ListFilters.Enabled = false;
324 RadioAND.Checked = true;
325 RadioPLUS.Checked = false;
329 TextSource.Text = "";
332 MSG2.Enabled = false;
333 CheckRegex.Checked = false;
334 CheckURL.Checked = false;
335 CheckCaseSensitive.Checked = false;
336 CheckRetweet.Checked = false;
337 CheckLambda.Checked = false;
339 RadioExAnd.Checked = true;
340 RadioExPLUS.Checked = false;
344 TextExSource.Text = "";
345 ExUID.Enabled = true;
346 ExMSG1.Enabled = true;
347 ExMSG2.Enabled = false;
348 CheckExRegex.Checked = false;
349 CheckExURL.Checked = false;
350 CheckExCaseSensitive.Checked = false;
351 CheckExRetweet.Checked = false;
352 CheckExLambDa.Checked = false;
354 OptCopy.Checked = true;
355 CheckMark.Checked = true;
357 _mode = EDITMODE.AddNew;
360 private void ButtonEdit_Click(object sender, EventArgs e)
362 if (ListFilters.SelectedIndex == -1) return;
366 int idx = ListFilters.SelectedIndex;
367 ListFilters.SelectedIndex = -1;
368 ListFilters.SelectedIndex = idx;
369 ListFilters.Enabled = false;
371 ButtonNew.Enabled = false;
372 ButtonEdit.Enabled = false;
373 ButtonDelete.Enabled = false;
374 ButtonClose.Enabled = false;
375 ButtonRuleUp.Enabled = false;
376 ButtonRuleDown.Enabled = false;
377 ButtonRuleCopy.Enabled = false;
378 ButtonRuleMove.Enabled = false;
379 buttonRuleToggleEnabled.Enabled = false;
380 EditFilterGroup.Enabled = true;
381 ListTabs.Enabled = false;
382 GroupTab.Enabled = false;
384 _mode = EDITMODE.Edit;
387 private void ButtonDelete_Click(object sender, EventArgs e)
389 var selectedCount = ListFilters.SelectedIndices.Count;
390 if (selectedCount == 0) return;
394 if (selectedCount == 1)
396 tmp = string.Format(Properties.Resources.ButtonDelete_ClickText1, Environment.NewLine, ListFilters.SelectedItem);
400 tmp = string.Format(Properties.Resources.ButtonDelete_ClickText3, selectedCount);
403 var rslt = MessageBox.Show(tmp, Properties.Resources.ButtonDelete_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
404 if (rslt == DialogResult.Cancel) return;
406 var indices = ListFilters.SelectedIndices.Cast<int>().Reverse().ToArray(); // 後ろの要素から削除
407 var tab = (FilterTabModel)_sts.Tabs[ListTabs.SelectedItem.ToString()];
409 using (ControlTransaction.Update(ListFilters))
411 foreach (var idx in indices)
413 tab.RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
414 ListFilters.Items.RemoveAt(idx);
419 private void ButtonCancel_Click(object sender, EventArgs e)
421 ListTabs.Enabled = true;
422 GroupTab.Enabled = true;
423 ListFilters.Enabled = true;
425 if (ListFilters.SelectedIndex != -1)
429 EditFilterGroup.Enabled = false;
430 ButtonNew.Enabled = true;
431 if (ListFilters.SelectedIndex > -1)
433 ButtonEdit.Enabled = true;
434 ButtonDelete.Enabled = true;
435 ButtonRuleUp.Enabled = true;
436 ButtonRuleDown.Enabled = true;
437 ButtonRuleCopy.Enabled = true;
438 ButtonRuleMove.Enabled = true;
439 buttonRuleToggleEnabled.Enabled = true;
443 ButtonEdit.Enabled = false;
444 ButtonDelete.Enabled = false;
445 ButtonRuleUp.Enabled = false;
446 ButtonRuleDown.Enabled = false;
447 ButtonRuleCopy.Enabled = false;
448 ButtonRuleMove.Enabled = false;
449 buttonRuleToggleEnabled.Enabled = false;
451 ButtonClose.Enabled = true;
458 private void ShowDetail()
460 if (_directAdd) return;
462 if (ListFilters.SelectedIndex > -1)
464 PostFilterRule fc = (PostFilterRule)ListFilters.SelectedItem;
467 RadioAND.Checked = true;
468 RadioPLUS.Checked = false;
471 MSG2.Enabled = false;
472 UID.Text = fc.FilterName;
474 MSG1.Text = string.Join(" ", fc.FilterBody);
480 RadioPLUS.Checked = true;
481 RadioAND.Checked = false;
483 MSG1.Enabled = false;
487 MSG2.Text = string.Join(" ", fc.FilterBody);
490 TextSource.Text = fc.FilterSource;
491 CheckRegex.Checked = fc.UseRegex;
492 CheckURL.Checked = fc.FilterByUrl;
493 CheckCaseSensitive.Checked = fc.CaseSensitive;
494 CheckRetweet.Checked = fc.FilterRt;
495 CheckLambda.Checked = fc.UseLambda;
497 if (fc.ExUseNameField)
499 RadioExAnd.Checked = true;
500 RadioExPLUS.Checked = false;
501 ExUID.Enabled = true;
502 ExMSG1.Enabled = true;
503 ExMSG2.Enabled = false;
504 ExUID.Text = fc.ExFilterName;
506 ExMSG1.Text = string.Join(" ", fc.ExFilterBody);
512 RadioExPLUS.Checked = true;
513 RadioExAnd.Checked = false;
514 ExUID.Enabled = false;
515 ExMSG1.Enabled = false;
516 ExMSG2.Enabled = true;
519 ExMSG2.Text = string.Join(" ", fc.ExFilterBody);
522 TextExSource.Text = fc.ExFilterSource;
523 CheckExRegex.Checked = fc.ExUseRegex;
524 CheckExURL.Checked = fc.ExFilterByUrl;
525 CheckExCaseSensitive.Checked = fc.ExCaseSensitive;
526 CheckExRetweet.Checked = fc.ExFilterRt;
527 CheckExLambDa.Checked = fc.ExUseLambda;
531 OptMove.Checked = true;
535 OptCopy.Checked = true;
537 CheckMark.Checked = fc.MarkMatches;
539 ButtonEdit.Enabled = true;
540 ButtonDelete.Enabled = true;
541 ButtonRuleUp.Enabled = true;
542 ButtonRuleDown.Enabled = true;
543 ButtonRuleCopy.Enabled = true;
544 ButtonRuleMove.Enabled = true;
545 buttonRuleToggleEnabled.Enabled = true;
549 RadioAND.Checked = true;
550 RadioPLUS.Checked = false;
553 MSG2.Enabled = false;
557 TextSource.Text = "";
558 CheckRegex.Checked = false;
559 CheckURL.Checked = false;
560 CheckCaseSensitive.Checked = false;
561 CheckRetweet.Checked = false;
562 CheckLambda.Checked = false;
564 RadioExAnd.Checked = true;
565 RadioExPLUS.Checked = false;
566 ExUID.Enabled = true;
567 ExMSG1.Enabled = true;
568 ExMSG2.Enabled = false;
572 TextExSource.Text = "";
573 CheckExRegex.Checked = false;
574 CheckExURL.Checked = false;
575 CheckExCaseSensitive.Checked = false;
576 CheckExRetweet.Checked = false;
577 CheckExLambDa.Checked = false;
579 OptCopy.Checked = true;
580 CheckMark.Checked = true;
582 ButtonEdit.Enabled = false;
583 ButtonDelete.Enabled = false;
584 ButtonRuleUp.Enabled = false;
585 ButtonRuleDown.Enabled = false;
586 ButtonRuleCopy.Enabled = false;
587 ButtonRuleMove.Enabled = false;
588 buttonRuleToggleEnabled.Enabled = false;
592 private void RadioAND_CheckedChanged(object sender, EventArgs e)
594 bool flg = RadioAND.Checked;
600 private void ButtonOK_Click(object sender, EventArgs e)
602 bool isBlankMatch = false;
603 bool isBlankExclude = false;
606 if (!CheckMatchRule(out isBlankMatch) || !CheckExcludeRule(out isBlankExclude))
610 if (isBlankMatch && isBlankExclude)
612 MessageBox.Show(Properties.Resources.ButtonOK_ClickText1, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
616 var tab = (FilterTabModel)this._sts.Tabs[(string)this.ListTabs.SelectedItem];
617 int i = ListFilters.SelectedIndex;
620 if (_mode == EDITMODE.AddNew)
621 ft = new PostFilterRule();
623 ft = (PostFilterRule)this.ListFilters.SelectedItem;
625 if (tab.TabType != MyCommon.TabUsageType.Mute)
627 ft.MoveMatches = OptMove.Checked;
628 ft.MarkMatches = CheckMark.Checked;
632 ft.MoveMatches = true;
633 ft.MarkMatches = false;
637 if (RadioAND.Checked)
639 ft.FilterName = UID.Text;
640 TweenMain owner = (TweenMain)this.Owner;
641 int cnt = owner.AtIdSupl.ItemCount;
642 owner.AtIdSupl.AddItem("@" + ft.FilterName);
643 if (cnt != owner.AtIdSupl.ItemCount)
645 owner.ModifySettingAtId = true;
647 ft.UseNameField = true;
653 ft.UseNameField = false;
656 ft.FilterSource = TextSource.Text;
658 if (CheckRegex.Checked || CheckLambda.Checked)
660 ft.FilterBody = new[] { bdy };
664 ft.FilterBody = bdy.Split(' ', ' ')
665 .Where(x => !string.IsNullOrEmpty(x))
669 ft.UseRegex = CheckRegex.Checked;
670 ft.FilterByUrl = CheckURL.Checked;
671 ft.CaseSensitive = CheckCaseSensitive.Checked;
672 ft.FilterRt = CheckRetweet.Checked;
673 ft.UseLambda = CheckLambda.Checked;
676 if (RadioExAnd.Checked)
678 ft.ExFilterName = ExUID.Text;
679 ft.ExUseNameField = true;
684 ft.ExFilterName = "";
685 ft.ExUseNameField = false;
688 ft.ExFilterSource = TextExSource.Text;
690 if (CheckExRegex.Checked || CheckExLambDa.Checked)
692 ft.ExFilterBody = new[] { bdy };
696 ft.ExFilterBody = bdy.Split(' ', ' ')
697 .Where(x => !string.IsNullOrEmpty(x))
701 ft.ExUseRegex = CheckExRegex.Checked;
702 ft.ExFilterByUrl = CheckExURL.Checked;
703 ft.ExCaseSensitive = CheckExCaseSensitive.Checked;
704 ft.ExFilterRt = CheckExRetweet.Checked;
705 ft.ExUseLambda = CheckExLambDa.Checked;
707 if (_mode == EDITMODE.AddNew)
709 if (!tab.AddFilter(ft))
710 MessageBox.Show(Properties.Resources.ButtonOK_ClickText4, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Error);
713 SetFilters(tab.TabName);
714 ListFilters.SelectedIndex = -1;
715 if (_mode == EDITMODE.AddNew)
717 ListFilters.SelectedIndex = ListFilters.Items.Count - 1;
721 ListFilters.SelectedIndex = i;
723 _mode = EDITMODE.None;
731 private bool IsValidLambdaExp(string text)
734 // TODO DynamicQuery相当のGPLv3互換なライブラリで置換する
737 private bool IsValidRegexp(string text)
745 MessageBox.Show(Properties.Resources.ButtonOK_ClickText3 + ex.Message, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
751 private bool CheckMatchRule(out bool isBlank)
754 if (RadioAND.Checked)
756 if (string.IsNullOrEmpty(UID.Text) && string.IsNullOrEmpty(MSG1.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false)
761 if (CheckLambda.Checked)
763 if (!IsValidLambdaExp(UID.Text))
767 if (!IsValidLambdaExp(MSG1.Text))
772 else if (CheckRegex.Checked)
774 if (!IsValidRegexp(UID.Text))
778 if (!IsValidRegexp(MSG1.Text))
786 if (string.IsNullOrEmpty(MSG2.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false)
791 if (CheckLambda.Checked && !IsValidLambdaExp(MSG2.Text))
795 else if (CheckRegex.Checked && !IsValidRegexp(MSG2.Text))
801 if (CheckRegex.Checked && !IsValidRegexp(TextSource.Text))
808 private bool CheckExcludeRule(out bool isBlank)
811 if (RadioExAnd.Checked)
813 if (string.IsNullOrEmpty(ExUID.Text) && string.IsNullOrEmpty(ExMSG1.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false)
818 if (CheckExLambDa.Checked)
820 if (!IsValidLambdaExp(ExUID.Text))
824 if (!IsValidLambdaExp(ExMSG1.Text))
829 else if (CheckExRegex.Checked)
831 if (!IsValidRegexp(ExUID.Text))
835 if (!IsValidRegexp(ExMSG1.Text))
843 if (string.IsNullOrEmpty(ExMSG2.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false)
848 if (CheckExLambDa.Checked && !IsValidLambdaExp(ExMSG2.Text))
852 else if (CheckExRegex.Checked && !IsValidRegexp(ExMSG2.Text))
858 if (CheckExRegex.Checked && !IsValidRegexp(TextExSource.Text))
866 private void ListFilters_SelectedIndexChanged(object sender, EventArgs e)
868 if (_multiSelState != MultiSelectionState.None) //複数選択処理中は無視する
873 var selectedCount = this.ListFilters.SelectedIndices.Count;
874 if (selectedCount == 0)
876 this.RuleEnableButtonMode = EnableButtonMode.NotSelected;
880 if (selectedCount == 1 ||
881 this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
883 var topItem = (PostFilterRule)this.ListFilters.SelectedItem;
884 this.RuleEnableButtonMode = topItem.Enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
889 private void ButtonClose_Click(object sender, EventArgs e)
894 private void FilterDialog_FormClosed(object sender, FormClosedEventArgs e)
899 private void FilterDialog_KeyDown(object sender, KeyEventArgs e)
901 if (e.KeyCode == Keys.Escape)
903 if (EditFilterGroup.Enabled)
904 ButtonCancel_Click(null, null);
906 ButtonClose_Click(null, null);
910 private void ListFilters_DoubleClick(object sender, EventArgs e)
912 var idx = ListFilters.SelectedIndex;
913 if (idx == -1) return;
915 var midx = ListFilters.IndexFromPoint(ListFilters.PointToClient(Control.MousePosition));
916 if (midx == ListBox.NoMatches || idx != midx) return;
918 ButtonEdit_Click(sender, e);
921 private void FilterDialog_Shown(object sender, EventArgs e)
923 _sts = TabInformations.GetInstance();
924 ListTabs.Items.Clear();
925 foreach (var tab in this._sts.Tabs.Values)
927 if (tab.TabType == MyCommon.TabUsageType.Mute)
930 this.ListTabs.Items.Add(tab.TabName);
933 var muteTab = this._sts.GetTabByType(MyCommon.TabUsageType.Mute);
935 this.ListTabs.Items.Add(muteTab.TabName);
937 ComboSound.Items.Clear();
938 ComboSound.Items.Add("");
939 DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
940 if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds")))
942 oDir = oDir.GetDirectories("Sounds")[0];
944 foreach (FileInfo oFile in oDir.GetFiles("*.wav"))
946 ComboSound.Items.Add(oFile.Name);
950 foreach (string tmp in ((TweenMain)this.Owner).AtIdSupl.GetItemList())
952 idlist.Add(tmp.Remove(0, 1)); // @文字削除
954 UID.AutoCompleteCustomSource.Clear();
955 UID.AutoCompleteCustomSource.AddRange(idlist.ToArray());
957 ExUID.AutoCompleteCustomSource.Clear();
958 ExUID.AutoCompleteCustomSource.AddRange(idlist.ToArray());
961 if (ListTabs.Items.Count > 0)
965 for (int i = 0; i < ListTabs.Items.Count; i++)
967 if (_cur == ListTabs.Items[i].ToString())
969 ListTabs.SelectedIndex = i;
970 //tabdialog.TabList.Items.Remove(_cur);
978 private void ListTabs_SelectedIndexChanged(object sender, EventArgs e)
980 if (ListTabs.SelectedIndex > -1)
981 SetFilters(ListTabs.SelectedItem.ToString());
983 ListFilters.Items.Clear();
986 private async void ButtonAddTab_Click(object sender, EventArgs e)
988 string tabName = null;
989 MyCommon.TabUsageType tabType;
990 using (InputTabName inputName = new InputTabName())
992 inputName.TabName = _sts.MakeTabName("MyTab");
993 inputName.IsShowUsage = true;
994 inputName.ShowDialog();
995 if (inputName.DialogResult == DialogResult.Cancel) return;
996 tabName = inputName.TabName;
997 tabType = inputName.Usage;
999 if (!string.IsNullOrEmpty(tabName))
1002 ListElement list = null;
1003 if (tabType == MyCommon.TabUsageType.Lists)
1007 using (var dialog = new WaitingDialog(Properties.Resources.ListsGetting))
1009 var cancellationToken = dialog.EnableCancellation();
1011 var task = ((TweenMain)this.Owner).TwitterInstance.GetListsApi();
1012 await dialog.WaitForAsync(this, task);
1014 cancellationToken.ThrowIfCancellationRequested();
1017 catch (OperationCanceledException) { return; }
1018 catch (WebApiException ex)
1020 MessageBox.Show("Failed to get lists. (" + ex.Message + ")");
1022 using (ListAvailable listAvail = new ListAvailable())
1024 if (listAvail.ShowDialog(this) == DialogResult.Cancel) return;
1025 if (listAvail.SelectedList == null) return;
1026 list = listAvail.SelectedList;
1033 case MyCommon.TabUsageType.UserDefined:
1034 tab = new FilterTabModel(tabName);
1036 case MyCommon.TabUsageType.PublicSearch:
1037 tab = new PublicSearchTabModel(tabName);
1039 case MyCommon.TabUsageType.Lists:
1040 tab = new ListTimelineTabModel(tabName, list);
1046 if (!_sts.AddTab(tab) || !((TweenMain)this.Owner).AddNewTab(tab, startup: false))
1048 string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
1049 MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
1057 var lastIdx = this.ListTabs.Items.Count - 1;
1058 var lastTab = lastIdx != -1
1059 ? this._sts.Tabs[(string)this.ListTabs.Items[lastIdx]]
1062 // 末尾がミュートタブであればその手前に追加する
1063 if (lastTab != null && lastTab.TabType == MyCommon.TabUsageType.Mute)
1064 this.ListTabs.Items.Insert(lastIdx, tabName);
1066 this.ListTabs.Items.Add(tabName);
1071 private void ButtonDeleteTab_Click(object sender, EventArgs e)
1073 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1075 string tb = ListTabs.SelectedItem.ToString();
1076 int idx = ListTabs.SelectedIndex;
1077 if (((TweenMain)this.Owner).RemoveSpecifiedTab(tb, true))
1079 ListTabs.Items.RemoveAt(idx);
1081 if (idx < 0) idx = 0;
1082 ListTabs.SelectedIndex = idx;
1087 private void ButtonRenameTab_Click(object sender, EventArgs e)
1089 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1091 int idx = ListTabs.SelectedIndex;
1093 var origTabName = (string)this.ListTabs.SelectedItem;
1095 if (((TweenMain)this.Owner).TabRename(origTabName, out newTabName))
1097 ListTabs.Items.RemoveAt(idx);
1098 ListTabs.Items.Insert(idx, newTabName);
1099 ListTabs.SelectedIndex = idx;
1104 private void CheckManageRead_CheckedChanged(object sender, EventArgs e)
1106 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1108 ((TweenMain)this.Owner).ChangeTabUnreadManage(
1109 ListTabs.SelectedItem.ToString(),
1110 CheckManageRead.Checked);
1114 private void ButtonUp_Click(object sender, EventArgs e)
1116 if (this.ListTabs.SelectedIndex == -1 || this.ListTabs.SelectedIndex == 0)
1119 var selectedTabName = (string)this.ListTabs.SelectedItem;
1120 var selectedTab = this._sts.Tabs[selectedTabName];
1122 var targetTabName = (string)this.ListTabs.Items[this.ListTabs.SelectedIndex - 1];
1123 var targetTab = this._sts.Tabs[targetTabName];
1126 if (selectedTab.TabType == MyCommon.TabUsageType.Mute || targetTab.TabType == MyCommon.TabUsageType.Mute)
1129 var tweenMain = (TweenMain)this.Owner;
1130 tweenMain.ReOrderTab(selectedTabName, targetTabName, true);
1132 // ListTab のアイテム並び替え
1133 // 選択が解除されてしまうのを防ぐため SelectedIndex のアイテムは操作せず前後のアイテムを移動する
1134 var idx = this.ListTabs.SelectedIndex;
1135 this.ListTabs.Items.RemoveAt(idx - 1);
1136 this.ListTabs.Items.Insert(idx, targetTabName);
1139 private void ButtonDown_Click(object sender, EventArgs e)
1141 if (this.ListTabs.SelectedIndex == -1 || this.ListTabs.SelectedIndex == this.ListTabs.Items.Count - 1)
1144 var selectedTabName = (string)this.ListTabs.SelectedItem;
1145 var selectedTab = this._sts.Tabs[selectedTabName];
1147 var targetTabName = (string)this.ListTabs.Items[this.ListTabs.SelectedIndex + 1];
1148 var targetTab = this._sts.Tabs[targetTabName];
1151 if (selectedTab.TabType == MyCommon.TabUsageType.Mute || targetTab.TabType == MyCommon.TabUsageType.Mute)
1154 var tweenMain = (TweenMain)this.Owner;
1155 tweenMain.ReOrderTab(selectedTabName, targetTabName, false);
1157 // ListTab のアイテム並び替え
1158 // 選択が解除されてしまうのを防ぐため SelectedIndex のアイテムは操作せず前後のアイテムを移動する
1159 var idx = this.ListTabs.SelectedIndex;
1160 this.ListTabs.Items.RemoveAt(idx + 1);
1161 this.ListTabs.Items.Insert(idx, targetTabName);
1164 private void CheckLocked_CheckedChanged(object sender, EventArgs e)
1166 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1168 _sts.Tabs[ListTabs.SelectedItem.ToString()].Protected = CheckProtected.Checked;
1169 ButtonDeleteTab.Enabled = !CheckProtected.Checked;
1173 private void CheckNotifyNew_CheckedChanged(object sender, EventArgs e)
1175 if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1177 _sts.Tabs[ListTabs.SelectedItem.ToString()].Notify = CheckNotifyNew.Checked;
1181 private void ComboSound_SelectedIndexChanged(object sender, EventArgs e)
1183 if (ListTabs.SelectedIndex > -1 && string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
1185 string filename = "";
1186 if (ComboSound.SelectedIndex > -1) filename = ComboSound.SelectedItem.ToString();
1187 _sts.Tabs[ListTabs.SelectedItem.ToString()].SoundFile = filename;
1191 private void RadioExAnd_CheckedChanged(object sender, EventArgs e)
1193 bool flg = RadioExAnd.Checked;
1194 ExUID.Enabled = flg;
1195 ExMSG1.Enabled = flg;
1196 ExMSG2.Enabled = !flg;
1199 private void OptMove_CheckedChanged(object sender, EventArgs e)
1201 CheckMark.Enabled = !OptMove.Checked;
1204 private void ButtonRuleUp_Click(object sender, EventArgs e)
1206 MoveSelectedRules(up: true);
1209 private void ButtonRuleDown_Click(object sender, EventArgs e)
1211 MoveSelectedRules(up: false);
1214 private void MoveSelectedRules(bool up)
1216 var tabIdx = ListTabs.SelectedIndex;
1218 ListFilters.SelectedIndices.Count == 0) return;
1220 var indices = ListFilters.SelectedIndices.Cast<int>().ToArray();
1225 if (indices[0] <= 0) return;
1230 if (indices[indices.Length - 1] >= ListFilters.Items.Count - 1) return;
1232 Array.Reverse(indices); // 逆順にして、下にある要素から処理する
1235 var lastSelIdx = indices[0] + diff;
1236 var tab = (FilterTabModel)_sts.Tabs[ListTabs.Items[tabIdx].ToString()];
1240 _multiSelState |= MultiSelectionState.MoveSelected;
1242 using (ControlTransaction.Update(ListFilters))
1244 ListFilters.SelectedIndices.Clear();
1246 foreach (var idx in indices)
1248 var tidx = idx + diff;
1249 var target = (PostFilterRule)ListFilters.Items[tidx];
1251 // 移動先にある要素と位置を入れ替える
1252 ListFilters.Items.RemoveAt(tidx);
1253 ListFilters.Items.Insert(idx, target);
1255 // 移動方向の先頭要素以外なら選択する
1256 if (tidx != lastSelIdx)
1257 ListFilters.SelectedIndex = tidx;
1260 tab.FilterArray = ListFilters.Items.Cast<PostFilterRule>().ToArray();
1262 // 移動方向の先頭要素は最後に選択する
1264 ListFilters.SelectedIndex = lastSelIdx;
1269 _multiSelState &= ~MultiSelectionState.MoveSelected;
1273 private void buttonRuleToggleEnabled_Click(object sender, EventArgs e)
1275 if (this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
1278 var enabled = this.RuleEnableButtonMode == EnableButtonMode.Enable;
1280 foreach (var idx in this.ListFilters.SelectedIndices.Cast<int>())
1282 var filter = (PostFilterRule)this.ListFilters.Items[idx];
1283 if (filter.Enabled != enabled)
1285 filter.Enabled = enabled;
1287 var itemRect = this.ListFilters.GetItemRectangle(idx);
1288 this.ListFilters.Invalidate(itemRect);
1292 this.RuleEnableButtonMode = enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
1295 private void ButtonRuleCopy_Click(object sender, EventArgs e)
1297 if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
1299 TabModel[] selectedTabs;
1300 using (TabsDialog dialog = new TabsDialog(_sts))
1302 dialog.MultiSelect = true;
1303 dialog.Text = Properties.Resources.ButtonRuleCopy_ClickText1;
1305 if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
1307 selectedTabs = dialog.SelectedTabs;
1310 string tabname = ListTabs.SelectedItem.ToString();
1311 List<PostFilterRule> filters = new List<PostFilterRule>();
1313 foreach (int idx in ListFilters.SelectedIndices)
1315 var tab = (FilterTabModel)_sts.Tabs[tabname];
1316 filters.Add(tab.FilterArray[idx].Clone());
1318 foreach (var tb in selectedTabs.Cast<FilterTabModel>())
1320 if (tb.TabName == tabname) continue;
1322 foreach (PostFilterRule flt in filters)
1324 if (!tb.FilterArray.Contains(flt))
1325 tb.AddFilter(flt.Clone());
1328 SetFilters(tabname);
1332 private void ButtonRuleMove_Click(object sender, EventArgs e)
1334 if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
1336 TabModel[] selectedTabs;
1337 using (var dialog = new TabsDialog(_sts))
1339 dialog.MultiSelect = true;
1340 dialog.Text = Properties.Resources.ButtonRuleMove_ClickText1;
1342 if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
1344 selectedTabs = dialog.SelectedTabs;
1346 string tabname = ListTabs.SelectedItem.ToString();
1347 List<PostFilterRule> filters = new List<PostFilterRule>();
1349 foreach (int idx in ListFilters.SelectedIndices)
1351 var tab = (FilterTabModel)_sts.Tabs[tabname];
1352 filters.Add(tab.FilterArray[idx].Clone());
1354 if (selectedTabs.Length == 1 && selectedTabs[0].TabName == tabname) return;
1355 foreach (var tb in selectedTabs.Cast<FilterTabModel>())
1357 if (tb.TabName == tabname) continue;
1359 foreach (PostFilterRule flt in filters)
1361 if (!tb.FilterArray.Contains(flt))
1362 tb.AddFilter(flt.Clone());
1365 for (int idx = ListFilters.Items.Count - 1; idx >= 0; idx--)
1367 if (ListFilters.GetSelected(idx))
1369 var tab = (FilterTabModel)_sts.Tabs[ListTabs.SelectedItem.ToString()];
1370 tab.RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
1371 ListFilters.Items.RemoveAt(idx);
1374 SetFilters(tabname);
1378 private void FilterTextBox_KeyDown(object sender, KeyEventArgs e)
1380 if (e.KeyCode == Keys.Space && e.Modifiers == (Keys.Shift | Keys.Control))
1382 TweenMain main = (TweenMain)this.Owner;
1383 TextBox tbox = (TextBox)sender;
1384 if (tbox.SelectionStart > 0)
1386 int endidx = tbox.SelectionStart - 1;
1387 string startstr = "";
1388 for (int i = tbox.SelectionStart - 1; i >= 0; i--)
1390 char c = tbox.Text[i];
1391 if (Char.IsLetterOrDigit(c) || c == '_')
1397 startstr = tbox.Text.Substring(i + 1, endidx - i);
1398 main.ShowSuplDialog(tbox, main.AtIdSupl, startstr.Length + 1, startstr);
1402 startstr = tbox.Text.Substring(i + 1, endidx - i);
1403 main.ShowSuplDialog(tbox, main.HashSupl, startstr.Length + 1, startstr);
1415 private void FilterTextBox_KeyPress(object sender, KeyPressEventArgs e)
1417 TweenMain main = (TweenMain)this.Owner;
1418 TextBox tbox = (TextBox)sender;
1419 if (e.KeyChar == '@')
1421 //if (!SettingDialog.UseAtIdSupplement) return;
1423 main.ShowSuplDialog(tbox, main.AtIdSupl);
1426 else if (e.KeyChar == '#')
1428 //if (!SettingDialog.UseHashSupplement) return;
1429 main.ShowSuplDialog(tbox, main.HashSupl);
1434 private void ListFilters_DrawItem(object sender, DrawItemEventArgs e)
1440 var filter = (PostFilterRule)this.ListFilters.Items[e.Index];
1441 var isSelected = e.State.HasFlag(DrawItemState.Selected);
1445 textBrush = SystemBrushes.HighlightText;
1446 else if (filter.Enabled)
1447 textBrush = SystemBrushes.WindowText;
1449 textBrush = SystemBrushes.GrayText;
1451 e.Graphics.DrawString(filter.ToString(), e.Font, textBrush, e.Bounds);
1454 e.DrawFocusRectangle();
1457 private void ListFilters_KeyDown(object sender, KeyEventArgs e)
1459 if (e.Control && e.KeyCode == Keys.A)
1461 var itemCount = this.ListFilters.Items.Count;
1462 if (itemCount == 0) return;
1464 using (ControlTransaction.Update(this.ListFilters))
1470 _multiSelState |= MultiSelectionState.SelectAll;
1472 for (int i = 1; i < itemCount; i++)
1474 this.ListFilters.SetSelected(i, true);
1479 _multiSelState &= ~MultiSelectionState.SelectAll;
1483 this.ListFilters.SetSelected(0, true);
1488 protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
1490 base.ScaleControl(factor, specified);
1491 this.ListFilters.ItemHeight = this.ListFilters.Font.Height;