OSDN Git Service

C#7.0で追加されたType switchの構文を使用する
[opentween/open-tween.git] / OpenTween / FilterDialog.cs
index ba7dc88..d7a86e5 100644 (file)
@@ -36,6 +36,7 @@ using System.Linq.Expressions;
 using System.Text.RegularExpressions;
 using System.IO;
 using System.Collections.Specialized;
+using OpenTween.Models;
 
 namespace OpenTween
 {
@@ -43,7 +44,7 @@ namespace OpenTween
     {
         private EDITMODE _mode;
         private bool _directAdd;
-        private bool _moveRules = false;
+        private MultiSelectionState _multiSelState = MultiSelectionState.None;
         private TabInformations _sts;
         private string _cur;
         private List<string> idlist = new List<string>();
@@ -55,6 +56,36 @@ namespace OpenTween
             None,
         }
 
+        private enum EnableButtonMode
+        {
+            NotSelected,
+            Enable,
+            Disable,
+        }
+
+        [Flags]
+        private enum MultiSelectionState
+        {
+            None = 0,
+            MoveSelected = 1,
+            SelectAll = 2,
+        }
+
+        private EnableButtonMode RuleEnableButtonMode
+        {
+            get { return this._ruleEnableButtonMode; }
+            set
+            {
+                this._ruleEnableButtonMode = value;
+
+                this.buttonRuleToggleEnabled.Text = value == FilterDialog.EnableButtonMode.Enable
+                    ? Properties.Resources.EnableButtonCaption
+                    : Properties.Resources.DisableButtonCaption;
+                this.buttonRuleToggleEnabled.Enabled = value != EnableButtonMode.NotSelected;
+            }
+        }
+        private EnableButtonMode _ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected;
+
         public FilterDialog()
         {
             InitializeComponent();
@@ -64,10 +95,12 @@ namespace OpenTween
         {
             if (ListTabs.Items.Count == 0) return;
 
+            ListFilters.Items.Clear();
+
             var tab = _sts.Tabs[tabName];
 
-            ListFilters.Items.Clear();
-            ListFilters.Items.AddRange(tab.GetFilters());
+            if (tab is FilterTabModel filterTab)
+                ListFilters.Items.AddRange(filterTab.GetFilters());
 
             if (ListFilters.Items.Count > 0)
                 ListFilters.SelectedIndex = 0;
@@ -117,45 +150,43 @@ namespace OpenTween
             GroupTab.Enabled = true;
             ListFilters.Enabled = true;
             EditFilterGroup.Enabled = false;
-            switch (tab.TabType)
+
+            if (tab.IsDistributableTabType)
             {
-                case MyCommon.TabUsageType.Home:
-                case MyCommon.TabUsageType.DirectMessage:
-                case MyCommon.TabUsageType.Favorites:
-                case MyCommon.TabUsageType.PublicSearch:
-                case MyCommon.TabUsageType.Lists:
-                case MyCommon.TabUsageType.Related:
-                case MyCommon.TabUsageType.UserTimeline:
-                    ButtonNew.Enabled = false;
+                ButtonNew.Enabled = true;
+                if (ListFilters.SelectedIndex > -1)
+                {
+                    ButtonEdit.Enabled = true;
+                    ButtonDelete.Enabled = true;
+                    ButtonRuleUp.Enabled = true;
+                    ButtonRuleDown.Enabled = true;
+                    ButtonRuleCopy.Enabled = true;
+                    ButtonRuleMove.Enabled = true;
+                    buttonRuleToggleEnabled.Enabled = true;
+                }
+                else
+                {
                     ButtonEdit.Enabled = false;
                     ButtonDelete.Enabled = false;
                     ButtonRuleUp.Enabled = false;
                     ButtonRuleDown.Enabled = false;
                     ButtonRuleCopy.Enabled = false;
                     ButtonRuleMove.Enabled = false;
-                    break;
-                default:
-                    ButtonNew.Enabled = true;
-                    if (ListFilters.SelectedIndex > -1)
-                    {
-                        ButtonEdit.Enabled = true;
-                        ButtonDelete.Enabled = true;
-                        ButtonRuleUp.Enabled = true;
-                        ButtonRuleDown.Enabled = true;
-                        ButtonRuleCopy.Enabled = true;
-                        ButtonRuleMove.Enabled = true;
-                    }
-                    else
-                    {
-                        ButtonEdit.Enabled = false;
-                        ButtonDelete.Enabled = false;
-                        ButtonRuleUp.Enabled = false;
-                        ButtonRuleDown.Enabled = false;
-                        ButtonRuleCopy.Enabled = false;
-                        ButtonRuleMove.Enabled = false;
-                    }
-                    break;
+                    buttonRuleToggleEnabled.Enabled = false;
+                }
             }
+            else
+            {
+                ButtonNew.Enabled = false;
+                ButtonEdit.Enabled = false;
+                ButtonDelete.Enabled = false;
+                ButtonRuleUp.Enabled = false;
+                ButtonRuleDown.Enabled = false;
+                ButtonRuleCopy.Enabled = false;
+                ButtonRuleMove.Enabled = false;
+                buttonRuleToggleEnabled.Enabled = false;
+            }
+
             switch (tab.TabType)
             {
                 case MyCommon.TabUsageType.Home:
@@ -188,6 +219,9 @@ namespace OpenTween
                 case MyCommon.TabUsageType.Mute:
                     LabelTabType.Text = "Mute";
                     break;
+                case MyCommon.TabUsageType.SearchResults:
+                    LabelTabType.Text = "SearchResults";
+                    break;
                 default:
                     LabelTabType.Text = "UNKNOWN";
                     break;
@@ -218,6 +252,7 @@ namespace OpenTween
             ButtonRuleDown.Enabled = false;
             ButtonRuleCopy.Enabled = false;
             ButtonRuleMove.Enabled = false;
+            buttonRuleToggleEnabled.Enabled = false;
             ButtonDelete.Enabled = false;
             ButtonClose.Enabled = false;
             EditFilterGroup.Enabled = true;
@@ -277,6 +312,7 @@ namespace OpenTween
             ButtonRuleDown.Enabled = false;
             ButtonRuleCopy.Enabled = false;
             ButtonRuleMove.Enabled = false;
+            buttonRuleToggleEnabled.Enabled = false;
             ButtonDelete.Enabled = false;
             ButtonClose.Enabled = false;
             EditFilterGroup.Enabled = true;
@@ -339,6 +375,7 @@ namespace OpenTween
             ButtonRuleDown.Enabled = false;
             ButtonRuleCopy.Enabled = false;
             ButtonRuleMove.Enabled = false;
+            buttonRuleToggleEnabled.Enabled = false;
             EditFilterGroup.Enabled = true;
             ListTabs.Enabled = false;
             GroupTab.Enabled = false;
@@ -355,18 +392,18 @@ namespace OpenTween
 
             if (selectedCount == 1)
             {
-                tmp = string.Format(Properties.Resources.ButtonDelete_ClickText1, Environment.NewLine, ListFilters.SelectedItem.ToString());
+                tmp = string.Format(Properties.Resources.ButtonDelete_ClickText1, Environment.NewLine, ListFilters.SelectedItem);
             }
             else
             {
-                tmp = string.Format(Properties.Resources.ButtonDelete_ClickText3, selectedCount.ToString());
+                tmp = string.Format(Properties.Resources.ButtonDelete_ClickText3, selectedCount);
             }
 
             var rslt = MessageBox.Show(tmp, Properties.Resources.ButtonDelete_ClickText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
             if (rslt == DialogResult.Cancel) return;
 
             var indices = ListFilters.SelectedIndices.Cast<int>().Reverse().ToArray();  // 後ろの要素から削除
-            var tab = _sts.Tabs[ListTabs.SelectedItem.ToString()];
+            var tab = (FilterTabModel)_sts.Tabs[ListTabs.SelectedItem.ToString()];
 
             using (ControlTransaction.Update(ListFilters))
             {
@@ -398,6 +435,7 @@ namespace OpenTween
                 ButtonRuleDown.Enabled = true;
                 ButtonRuleCopy.Enabled = true;
                 ButtonRuleMove.Enabled = true;
+                buttonRuleToggleEnabled.Enabled = true;
             }
             else
             {
@@ -407,6 +445,7 @@ namespace OpenTween
                 ButtonRuleDown.Enabled = false;
                 ButtonRuleCopy.Enabled = false;
                 ButtonRuleMove.Enabled = false;
+                buttonRuleToggleEnabled.Enabled = false;
             }
             ButtonClose.Enabled = true;
             if (_directAdd)
@@ -502,6 +541,7 @@ namespace OpenTween
                 ButtonRuleDown.Enabled = true;
                 ButtonRuleCopy.Enabled = true;
                 ButtonRuleMove.Enabled = true;
+                buttonRuleToggleEnabled.Enabled = true;
             }
             else
             {
@@ -544,6 +584,7 @@ namespace OpenTween
                 ButtonRuleDown.Enabled = false;
                 ButtonRuleCopy.Enabled = false;
                 ButtonRuleMove.Enabled = false;
+                buttonRuleToggleEnabled.Enabled = false;
             }
         }
 
@@ -571,7 +612,7 @@ namespace OpenTween
                 return;
             }
 
-            var tab = this._sts.Tabs[(string)this.ListTabs.SelectedItem];
+            var tab = (FilterTabModel)this._sts.Tabs[(string)this.ListTabs.SelectedItem];
             int i = ListFilters.SelectedIndex;
 
             PostFilterRule ft;
@@ -823,8 +864,25 @@ namespace OpenTween
 
         private void ListFilters_SelectedIndexChanged(object sender, EventArgs e)
         {
-            if (!_moveRules)
-                ShowDetail();
+            if (_multiSelState != MultiSelectionState.None)  //複数選択処理中は無視する
+                return;
+
+            ShowDetail();
+
+            var selectedCount = this.ListFilters.SelectedIndices.Count;
+            if (selectedCount == 0)
+            {
+                this.RuleEnableButtonMode = EnableButtonMode.NotSelected;
+            }
+            else
+            {
+                if (selectedCount == 1 ||
+                    this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
+                {
+                    var topItem = (PostFilterRule)this.ListFilters.SelectedItem;
+                    this.RuleEnableButtonMode = topItem.Enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
+                }
+            }
         }
 
         private void ButtonClose_Click(object sender, EventArgs e)
@@ -863,11 +921,18 @@ namespace OpenTween
         {
             _sts = TabInformations.GetInstance();
             ListTabs.Items.Clear();
-            foreach (string key in _sts.Tabs.Keys)
+            foreach (var tab in this._sts.Tabs.Values)
             {
-                ListTabs.Items.Add(key);
+                if (tab.TabType == MyCommon.TabUsageType.Mute)
+                    continue;
+
+                this.ListTabs.Items.Add(tab.TabName);
             }
 
+            var muteTab = this._sts.GetTabByType(MyCommon.TabUsageType.Mute);
+            if (muteTab != null)
+                this.ListTabs.Items.Add(muteTab.TabName);
+
             ComboSound.Items.Clear();
             ComboSound.Items.Add("");
             DirectoryInfo oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar);
@@ -917,13 +982,13 @@ namespace OpenTween
                 ListFilters.Items.Clear();
         }
 
-        private void ButtonAddTab_Click(object sender, EventArgs e)
+        private async void ButtonAddTab_Click(object sender, EventArgs e)
         {
             string tabName = null;
             MyCommon.TabUsageType tabType;
             using (InputTabName inputName = new InputTabName())
             {
-                inputName.TabName = _sts.GetUniqueTabName();
+                inputName.TabName = _sts.MakeTabName("MyTab");
                 inputName.IsShowUsage = true;
                 inputName.ShowDialog();
                 if (inputName.DialogResult == DialogResult.Cancel) return;
@@ -936,10 +1001,22 @@ namespace OpenTween
                 ListElement list = null;
                 if (tabType == MyCommon.TabUsageType.Lists)
                 {
-                    string rslt = ((TweenMain)this.Owner).TwitterInstance.GetListsApi();
-                    if (!string.IsNullOrEmpty(rslt))
+                    try
                     {
-                        MessageBox.Show("Failed to get lists. (" + rslt + ")");
+                        using (var dialog = new WaitingDialog(Properties.Resources.ListsGetting))
+                        {
+                            var cancellationToken = dialog.EnableCancellation();
+
+                            var task = ((TweenMain)this.Owner).TwitterInstance.GetListsApi();
+                            await dialog.WaitForAsync(this, task);
+
+                            cancellationToken.ThrowIfCancellationRequested();
+                        }
+                    }
+                    catch (OperationCanceledException) { return; }
+                    catch (WebApiException ex)
+                    {
+                        MessageBox.Show("Failed to get lists. (" + ex.Message + ")");
                     }
                     using (ListAvailable listAvail = new ListAvailable())
                     {
@@ -948,7 +1025,24 @@ namespace OpenTween
                         list = listAvail.SelectedList;
                     }
                 }
-                if (!_sts.AddTab(tabName, tabType, list) || !((TweenMain)this.Owner).AddNewTab(tabName, false, tabType, list))
+
+                TabModel tab;
+                switch (tabType)
+                {
+                    case MyCommon.TabUsageType.UserDefined:
+                        tab = new FilterTabModel(tabName);
+                        break;
+                    case MyCommon.TabUsageType.PublicSearch:
+                        tab = new PublicSearchTabModel(tabName);
+                        break;
+                    case MyCommon.TabUsageType.Lists:
+                        tab = new ListTimelineTabModel(tabName, list);
+                        break;
+                    default:
+                        return;
+                }
+
+                if (!_sts.AddTab(tab) || !((TweenMain)this.Owner).AddNewTab(tab, startup: false))
                 {
                     string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName);
                     MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
@@ -956,8 +1050,19 @@ namespace OpenTween
                 }
                 else
                 {
-                    //成功
-                    ListTabs.Items.Add(tabName);
+                    // タブ作成成功
+
+                    // 末尾のタブを取得する
+                    var lastIdx = this.ListTabs.Items.Count - 1;
+                    var lastTab = lastIdx != -1
+                        ? this._sts.Tabs[(string)this.ListTabs.Items[lastIdx]]
+                        : null;
+
+                    // 末尾がミュートタブであればその手前に追加する
+                    if (lastTab != null && lastTab.TabType == MyCommon.TabUsageType.Mute)
+                        this.ListTabs.Items.Insert(lastIdx, tabName);
+                    else
+                        this.ListTabs.Items.Add(tabName);
                 }
             }
         }
@@ -982,12 +1087,14 @@ namespace OpenTween
         {
             if (ListTabs.SelectedIndex > -1 && !string.IsNullOrEmpty(ListTabs.SelectedItem.ToString()))
             {
-                string tb = ListTabs.SelectedItem.ToString();
                 int idx = ListTabs.SelectedIndex;
-                if (((TweenMain)this.Owner).TabRename(ref tb))
+
+                var origTabName = (string)this.ListTabs.SelectedItem;
+                string newTabName;
+                if (((TweenMain)this.Owner).TabRename(origTabName, out newTabName))
                 {
                     ListTabs.Items.RemoveAt(idx);
-                    ListTabs.Items.Insert(idx, tb);
+                    ListTabs.Items.Insert(idx, newTabName);
                     ListTabs.SelectedIndex = idx;
                 }
             }
@@ -1125,11 +1232,11 @@ namespace OpenTween
             }
 
             var lastSelIdx = indices[0] + diff;
-            var tab = _sts.Tabs[ListTabs.Items[tabIdx].ToString()];
+            var tab = (FilterTabModel)_sts.Tabs[ListTabs.Items[tabIdx].ToString()];
 
             try
             {
-                _moveRules = true;  // SelectedIndexChanged を無視する
+                _multiSelState |= MultiSelectionState.MoveSelected;
 
                 using (ControlTransaction.Update(ListFilters))
                 {
@@ -1158,15 +1265,37 @@ namespace OpenTween
             }
             finally
             {
-                _moveRules = false;
+                _multiSelState &= ~MultiSelectionState.MoveSelected;
+            }
+        }
+
+        private void buttonRuleToggleEnabled_Click(object sender, EventArgs e)
+        {
+            if (this.RuleEnableButtonMode == EnableButtonMode.NotSelected)
+                return;
+
+            var enabled = this.RuleEnableButtonMode == EnableButtonMode.Enable;
+
+            foreach (var idx in this.ListFilters.SelectedIndices.Cast<int>())
+            {
+                var filter = (PostFilterRule)this.ListFilters.Items[idx];
+                if (filter.Enabled != enabled)
+                {
+                    filter.Enabled = enabled;
+
+                    var itemRect = this.ListFilters.GetItemRectangle(idx);
+                    this.ListFilters.Invalidate(itemRect);
+                }
             }
+
+            this.RuleEnableButtonMode = enabled ? EnableButtonMode.Disable : EnableButtonMode.Enable;
         }
 
         private void ButtonRuleCopy_Click(object sender, EventArgs e)
         {
             if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
             {
-                TabClass[] selectedTabs;
+                TabModel[] selectedTabs;
                 using (TabsDialog dialog = new TabsDialog(_sts))
                 {
                     dialog.MultiSelect = true;
@@ -1182,9 +1311,10 @@ namespace OpenTween
 
                 foreach (int idx in ListFilters.SelectedIndices)
                 {
-                    filters.Add(_sts.Tabs[tabname].FilterArray[idx].Clone());
+                    var tab = (FilterTabModel)_sts.Tabs[tabname];
+                    filters.Add(tab.FilterArray[idx].Clone());
                 }
-                foreach (var tb in selectedTabs)
+                foreach (var tb in selectedTabs.Cast<FilterTabModel>())
                 {
                     if (tb.TabName == tabname) continue;
 
@@ -1202,7 +1332,7 @@ namespace OpenTween
         {
             if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
             {
-                TabClass[] selectedTabs;
+                TabModel[] selectedTabs;
                 using (var dialog = new TabsDialog(_sts))
                 {
                     dialog.MultiSelect = true;
@@ -1217,10 +1347,11 @@ namespace OpenTween
 
                 foreach (int idx in ListFilters.SelectedIndices)
                 {
-                    filters.Add(_sts.Tabs[tabname].FilterArray[idx].Clone());
+                    var tab = (FilterTabModel)_sts.Tabs[tabname];
+                    filters.Add(tab.FilterArray[idx].Clone());
                 }
                 if (selectedTabs.Length == 1 && selectedTabs[0].TabName == tabname) return;
-                foreach (var tb in selectedTabs)
+                foreach (var tb in selectedTabs.Cast<FilterTabModel>())
                 {
                     if (tb.TabName == tabname) continue;
 
@@ -1234,7 +1365,8 @@ namespace OpenTween
                 {
                     if (ListFilters.GetSelected(idx))
                     {
-                        _sts.Tabs[ListTabs.SelectedItem.ToString()].RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
+                        var tab = (FilterTabModel)_sts.Tabs[ListTabs.SelectedItem.ToString()];
+                        tab.RemoveFilter((PostFilterRule)ListFilters.Items[idx]);
                         ListFilters.Items.RemoveAt(idx);
                     }
                 }
@@ -1302,22 +1434,59 @@ namespace OpenTween
         {
             e.DrawBackground();
 
-            var filter = (PostFilterRule)this.ListFilters.Items[e.Index];
+            if (e.Index != -1)
+            {
+                var filter = (PostFilterRule)this.ListFilters.Items[e.Index];
+                var isSelected = e.State.HasFlag(DrawItemState.Selected);
 
-            Brush textBrush;
-            if (filter.Enabled)
-                textBrush = SystemBrushes.ControlText;
-            else
-                textBrush = SystemBrushes.GrayText;
+                Brush textBrush;
+                if (isSelected)
+                    textBrush = SystemBrushes.HighlightText;
+                else if (filter.Enabled)
+                    textBrush = SystemBrushes.WindowText;
+                else
+                    textBrush = SystemBrushes.GrayText;
 
-            e.Graphics.DrawString(filter.ToString(), e.Font, textBrush, e.Bounds);
+                e.Graphics.DrawString(filter.ToString(), e.Font, textBrush, e.Bounds);
+            }
 
             e.DrawFocusRectangle();
         }
 
-        protected override void OnFontChanged(EventArgs e)
+        private void ListFilters_KeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Control && e.KeyCode == Keys.A)
+            {
+                var itemCount = this.ListFilters.Items.Count;
+                if (itemCount == 0) return;
+
+                using (ControlTransaction.Update(this.ListFilters))
+                {
+                    if (itemCount > 1)
+                    {
+                        try
+                        {
+                            _multiSelState |= MultiSelectionState.SelectAll;
+
+                            for (int i = 1; i < itemCount; i++)
+                            {
+                                this.ListFilters.SetSelected(i, true);
+                            }
+                        }
+                        finally
+                        {
+                            _multiSelState &= ~MultiSelectionState.SelectAll;
+                        }
+                    }
+
+                    this.ListFilters.SetSelected(0, true);
+                }
+            }
+        }
+
+        protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
         {
-            base.OnFontChanged(e);
+            base.ScaleControl(factor, specified);
             this.ListFilters.ItemHeight = this.ListFilters.Font.Height;
         }
     }