X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=OpenTween%2FTween.cs;h=860a2af863b65d9f97a7c0f805a80c1f8d44220f;hb=91c59331;hp=0579ecdd902d28b29f90dc786fbafced47ef8d26;hpb=218d2b8f6604c8b0311737944a03ed689a01ce00;p=opentween%2Fopen-tween.git diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 0579ecdd..860a2af8 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -250,8 +250,6 @@ namespace OpenTween } } - private int _curItemIndex; - private PostClass _curPost; private bool _isColumnChanged = false; private const int MAX_WORKER_THREADS = 20; @@ -291,9 +289,9 @@ namespace OpenTween { public long OriginalId; public long InReplyToId; - public TabPage OriginalTab; + public TabModel OriginalTab; - public ReplyChain(long originalId, long inReplyToId, TabPage originalTab) + public ReplyChain(long originalId, long inReplyToId, TabModel originalTab) { this.OriginalId = originalId; this.InReplyToId = inReplyToId; @@ -302,7 +300,7 @@ namespace OpenTween } private Stack replyChains; //[, ]でのリプライ移動の履歴 - private Stack<(TabPage, PostClass)> selectPostChains = new Stack<(TabPage, PostClass)>(); //ポスト選択履歴 + private Stack<(TabModel, PostClass)> selectPostChains = new Stack<(TabModel, PostClass)>(); //ポスト選択履歴 public TabModel CurrentTab => this._statuses.SelectedTab; @@ -316,6 +314,9 @@ namespace OpenTween public DetailsListView CurrentListView => (DetailsListView)this.CurrentTabPage.Tag; + public PostClass CurrentPost + => this.CurrentTab.SelectedPost; + //検索処理タイプ internal enum SEARCHTYPE { @@ -1056,21 +1057,16 @@ namespace OpenTween if (this._statuses.GetTabByType() == null) this._statuses.AddTab(new FavoritesTabModel()); - if (this._statuses.GetTabByType() == null) + if (this._statuses.MuteTab == null) this._statuses.AddTab(new MuteTabModel()); - foreach (var tab in _statuses.Tabs.Values) + foreach (var tab in _statuses.Tabs) { - // ミュートタブは表示しない - if (tab.TabType == MyCommon.TabUsageType.Mute) - continue; - if (!AddNewTab(tab, startup: true)) throw new TabException(Properties.Resources.TweenMain_LoadText1); } this._statuses.SelectTab(this.ListTab.SelectedTab.Text); - _curItemIndex = -1; MyCommon.TwitterApiInfo.AccessLimitUpdated += TwitterApiStatus_AccessLimitUpdated; Microsoft.Win32.SystemEvents.TimeChanged += SystemEvents_TimeChanged; @@ -1595,21 +1591,12 @@ namespace OpenTween return new ListViewSelection { - SelectedStatusIds = this.GetSelectedStatusIds(listView, tab), + SelectedStatusIds = tab.SelectedStatusIds, FocusedStatusId = this.GetFocusedStatusId(listView, tab), SelectionMarkStatusId = this.GetSelectionMarkStatusId(listView, tab), }; } - private long[] GetSelectedStatusIds(DetailsListView listView, TabModel tab) - { - var selectedIndices = listView.SelectedIndices; - if (selectedIndices.Count > 0 && selectedIndices.Count < 61) - return tab.GetStatusIdAt(selectedIndices.Cast()); - else - return null; - } - private long? GetFocusedStatusId(DetailsListView listView, TabModel tab) { var index = listView.FocusedItem?.Index ?? -1; @@ -1932,25 +1919,24 @@ namespace OpenTween private void MyList_SelectedIndexChanged(object sender, EventArgs e) { var listView = this.CurrentListView; - if (!listView.Equals(sender) || listView.SelectedIndices.Count != 1) return; + if (listView != sender) + return; - _curItemIndex = listView.SelectedIndices[0]; - if (_curItemIndex > listView.VirtualListSize - 1) return; + var indices = listView.SelectedIndices.Cast().ToArray(); + this.CurrentTab.SelectPosts(indices); - try - { - this._curPost = GetCurTabPost(_curItemIndex); - } - catch (ArgumentException) - { + if (listView.SelectedIndices.Count != 1) return; - } + + var index = listView.SelectedIndices[0]; + if (index > listView.VirtualListSize - 1) return; this.PushSelectPostChain(); - this._statuses.SetReadAllTab(_curPost.StatusId, read: true); + var post = this.CurrentPost; + this._statuses.SetReadAllTab(post.StatusId, read: true); //キャッシュの書き換え - ChangeCacheStyleRead(true, _curItemIndex); //既読へ(フォント、文字色) + ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) ColorizeList(); _colorize = true; @@ -2027,7 +2013,7 @@ namespace OpenTween if (_anchorFlag) _post = _anchorPost; else - _post = _curPost; + _post = this.CurrentPost; if (_post == null) return; @@ -2052,7 +2038,7 @@ namespace OpenTween if (_anchorFlag) _post = _anchorPost; else - _post = _curPost; + _post = this.CurrentPost; PostClass tPost = GetCurTabPost(Index); @@ -2133,7 +2119,8 @@ namespace OpenTween } } - if (this.ExistCurrentPost && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", _curPost.ScreenName, _curPost.TextFromApi)) + var currentPost = this.CurrentPost; + if (this.ExistCurrentPost && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", currentPost.ScreenName, currentPost.TextFromApi)) { DialogResult rtResult = MessageBox.Show(string.Format(Properties.Resources.PostButton_Click1, Environment.NewLine), "Retweet", @@ -2487,7 +2474,8 @@ namespace OpenTween this.ChangeCacheStyleRead(post.IsRead, idx); } - if (statusId == this._curPost.StatusId) + var currentPost = this.CurrentPost; + if (currentPost != null && statusId == currentPost.StatusId) await this.DispSelectedPost(true); // 選択アイテム再表示 } } @@ -2601,7 +2589,8 @@ namespace OpenTween } } - if (successIds.Contains(this._curPost.StatusId)) + var currentPost = this.CurrentPost; + if (currentPost != null && successIds.Contains(currentPost.StatusId)) await this.DispSelectedPost(true); // 選択アイテム再表示 } } @@ -2967,8 +2956,9 @@ namespace OpenTween await this.FavoriteChange(true); break; case 2: - if (_curPost != null) - await this.ShowUserStatus(_curPost.ScreenName, false); + var post = this.CurrentPost; + if (post != null) + await this.ShowUserStatus(post.ScreenName, false); break; case 3: await ShowUserTimeline(); @@ -3004,13 +2994,13 @@ namespace OpenTween private async Task FavoriteChange(bool FavAdd, bool multiFavoriteChangeDialogEnable = true) { var tab = this.CurrentTab; - var listView = this.CurrentListView; + var posts = tab.SelectedPosts; //trueでFavAdd,falseでFavRemove - if (tab.TabType == MyCommon.TabUsageType.DirectMessage || listView.SelectedIndices.Count == 0 + if (tab.TabType == MyCommon.TabUsageType.DirectMessage || posts.Length == 0 || !this.ExistCurrentPost) return; - if (listView.SelectedIndices.Count > 1) + if (posts.Length > 1) { if (FavAdd) { @@ -3036,7 +3026,7 @@ namespace OpenTween if (FavAdd) { - var selectedPost = this.GetCurTabPost(listView.SelectedIndices[0]); + var selectedPost = posts.Single(); if (selectedPost.IsFav) { this.StatusLabel.Text = Properties.Resources.FavAddToolStripMenuItem_ClickText4; @@ -3047,10 +3037,7 @@ namespace OpenTween } else { - var selectedPosts = listView.SelectedIndices.Cast() - .Select(x => this.GetCurTabPost(x)) - .Where(x => x.IsFav); - + var selectedPosts = posts.Where(x => x.IsFav); var statusIds = selectedPosts.Select(x => x.StatusId).ToArray(); if (statusIds.Length == 0) { @@ -3076,18 +3063,18 @@ namespace OpenTween private async void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e) { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 0) - await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + GetCurTabPost(listView.SelectedIndices[0]).ScreenName); - else if (listView.SelectedIndices.Count == 0) + var post = this.CurrentPost; + if (post != null) + await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + post.ScreenName); + else await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl); } private async void MoveToFavToolStripMenuItem_Click(object sender, EventArgs e) { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 0) - await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + "#!/" + GetCurTabPost(listView.SelectedIndices[0]).ScreenName + "/favorites"); + var post = this.CurrentPost; + if (post != null) + await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + "#!/" + post.ScreenName + "/favorites"); } private void TweenMain_ClientSizeChanged(object sender, EventArgs e) @@ -3207,9 +3194,10 @@ namespace OpenTween this.PurgeListViewItemCache(); var tab = this.CurrentTab; - if (tab.AllCount > 0 && this._curPost != null) + var post = this.CurrentPost; + if (tab.AllCount > 0 && post != null) { - var idx = tab.IndexOf(this._curPost.StatusId); + var idx = tab.IndexOf(post.StatusId); if (idx > -1) { this.SelectListItem(list, idx); @@ -3263,7 +3251,8 @@ namespace OpenTween UnreadStripMenuItem.Enabled = true; } var tab = this.CurrentTab; - if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || _curPost.IsDm) + var post = this.CurrentPost; + if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post.IsDm) { FavAddToolStripMenuItem.Enabled = false; FavRemoveToolStripMenuItem.Enabled = false; @@ -3283,7 +3272,7 @@ namespace OpenTween StatusOpenMenuItem.Enabled = true; ShowRelatedStatusesMenuItem.Enabled = true; //PublicSearchの時問題出るかも - if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId)) + if (!post.CanRetweetBy(this.twitterApi.CurrentUserId)) { ReTweetStripMenuItem.Enabled = false; ReTweetUnofficialStripMenuItem.Enabled = false; @@ -3308,8 +3297,7 @@ namespace OpenTween //{ // RefreshMoreStripMenuItem.Enabled = false; //} - if (!this.ExistCurrentPost - || _curPost.InReplyToStatusId == null) + if (!this.ExistCurrentPost || post.InReplyToStatusId == null) { RepliedStatusOpenMenuItem.Enabled = false; } @@ -3317,7 +3305,7 @@ namespace OpenTween { RepliedStatusOpenMenuItem.Enabled = true; } - if (!this.ExistCurrentPost || string.IsNullOrEmpty(_curPost.RetweetedBy)) + if (!this.ExistCurrentPost || string.IsNullOrEmpty(post.RetweetedBy)) { MoveToRTHomeMenuItem.Enabled = false; } @@ -3328,8 +3316,8 @@ namespace OpenTween if (this.ExistCurrentPost) { - this.DeleteStripMenuItem.Enabled = this._curPost.CanDeleteBy(this.tw.UserId); - if (this._curPost.RetweetedByUserId == this.tw.UserId) + this.DeleteStripMenuItem.Enabled = post.CanDeleteBy(this.tw.UserId); + if (post.RetweetedByUserId == this.tw.UserId) this.DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText2; else this.DeleteStripMenuItem.Text = Properties.Resources.DeleteMenuText1; @@ -3344,15 +3332,10 @@ namespace OpenTween private async Task doStatusDelete() { - var currentListView = this.CurrentListView; - - if (currentListView.SelectedIndices.Count == 0) + var posts = this.CurrentTab.SelectedPosts; + if (posts.Length == 0) return; - var posts = currentListView.SelectedIndices.Cast() - .Select(x => this.GetCurTabPost(x)) - .ToArray(); - // 選択されたツイートの中に削除可能なものが一つでもあるか if (!posts.Any(x => x.CanDeleteBy(this.tw.UserId))) return; @@ -3365,6 +3348,7 @@ namespace OpenTween if (ret != DialogResult.OK) return; + var currentListView = this.CurrentListView; var focusedIndex = currentListView.FocusedItem?.Index ?? currentListView.TopItem?.Index ?? 0; using (ControlTransaction.Cursor(this, Cursors.WaitCursor)) @@ -3423,8 +3407,6 @@ namespace OpenTween this.StatusLabel.Text = Properties.Resources.DeleteStripMenuItem_ClickText3; // 失敗 this.PurgeListViewItemCache(); - this._curPost = null; - this._curItemIndex = -1; foreach (var tabPage in this.ListTab.TabPages.Cast()) { @@ -3435,7 +3417,7 @@ namespace OpenTween { listView.VirtualListSize = tab.AllCount; - if (tabPage == this.CurrentTabPage) + if (tab.TabName == this.CurrentTabName) { listView.SelectedIndices.Clear(); @@ -3471,14 +3453,13 @@ namespace OpenTween private void ReadedStripMenuItem_Click(object sender, EventArgs e) { - var listView = this.CurrentListView; - using (ControlTransaction.Update(listView)) + using (ControlTransaction.Update(this.CurrentListView)) { var tab = this.CurrentTab; - foreach (int idx in listView.SelectedIndices) + foreach (var statusId in tab.SelectedStatusIds) { - var post = tab[idx]; - this._statuses.SetReadAllTab(post.StatusId, read: true); + this._statuses.SetReadAllTab(statusId, read: true); + var idx = tab.IndexOf(statusId); ChangeCacheStyleRead(true, idx); } ColorizeList(); @@ -3498,14 +3479,13 @@ namespace OpenTween private void UnreadStripMenuItem_Click(object sender, EventArgs e) { - var listView = this.CurrentListView; - using (ControlTransaction.Update(listView)) + using (ControlTransaction.Update(this.CurrentListView)) { var tab = this.CurrentTab; - foreach (int idx in listView.SelectedIndices) + foreach (var statusId in tab.SelectedStatusIds) { - var post = tab[idx]; - this._statuses.SetReadAllTab(post.StatusId, read: false); + this._statuses.SetReadAllTab(statusId, read: false); + var idx = tab.IndexOf(statusId); ChangeCacheStyleRead(false, idx); } ColorizeList(); @@ -3934,26 +3914,26 @@ namespace OpenTween //追加したタブをアクティブに ListTab.SelectedIndex = ListTab.TabPages.Count - 1; //検索条件の設定 - ComboBox cmb = (ComboBox)ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"]; + var tabPage = this.CurrentTabPage; + ComboBox cmb = (ComboBox)tabPage.Controls["panelSearch"].Controls["comboSearch"]; cmb.Items.Add(searchWord); cmb.Text = searchWord; SaveConfigsTabs(); //検索実行 - this.SearchButton_Click(ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"], null); + this.SearchButton_Click(tabPage.Controls["panelSearch"].Controls["comboSearch"], null); } private async Task ShowUserTimeline() { if (!this.ExistCurrentPost) return; - await this.AddNewTabForUserTimeline(_curPost.ScreenName); + await this.AddNewTabForUserTimeline(this.CurrentPost.ScreenName); } private void SearchComboBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { - var relTp = this.CurrentTabPage; - RemoveSpecifiedTab(relTp.Text, false); + RemoveSpecifiedTab(this.CurrentTabName, false); SaveConfigsTabs(); e.SuppressKeyPress = true; } @@ -4230,7 +4210,7 @@ namespace OpenTween using (ControlTransaction.Layout(this)) using (ControlTransaction.Layout(_tabPage, false)) { - if (this.ListTab.SelectedTab == _tabPage) + if (this.CurrentTabName == TabName) { this.ListTab.SelectTab((this._beforeSelectedTab != null && this.ListTab.TabPages.Contains(this._beforeSelectedTab)) ? this._beforeSelectedTab : this.ListTab.TabPages[0]); this._beforeSelectedTab = null; @@ -4299,12 +4279,7 @@ namespace OpenTween _listCustom.SmallImageList = null; _listCustom.ListViewItemSorter = null; - //キャッシュのクリア - if (this.CurrentTabPage.Equals(_tabPage)) - { - _curItemIndex = -1; - _curPost = null; - } + // キャッシュのクリア this.PurgeListViewItemCache(); } @@ -4339,7 +4314,7 @@ namespace OpenTween if (!dragEnableRectangle.Contains(e.Location)) { //タブが多段の場合にはMouseDownの前の段階で選択されたタブの段が変わっているので、このタイミングでカーソルの位置からタブを判定出来ない。 - tn = ListTab.SelectedTab.Text; + tn = this.CurrentTabName; } if (string.IsNullOrEmpty(tn)) return; @@ -4377,8 +4352,9 @@ namespace OpenTween SetMainWindowTitle(); SetStatusLabelUrl(); SetApiStatusLabel(); - if (ListTab.Focused || ((Control)ListTab.SelectedTab.Tag).Focused) this.Tag = ListTab.Tag; - TabMenuControl(ListTab.SelectedTab.Text); + if (ListTab.Focused || ((Control)this.CurrentTabPage.Tag).Focused) + this.Tag = ListTab.Tag; + TabMenuControl(this.CurrentTabName); this.PushSelectPostChain(); await DispSelectedPost(); } @@ -4402,21 +4378,19 @@ namespace OpenTween } } - var currentTabPage = this.CurrentTabPage; - //列幅、列並びを他のタブに設定 foreach (TabPage tb in ListTab.TabPages) { - if (!tb.Equals(currentTabPage)) + if (tb.Text == this.CurrentTabName) + continue; + + if (tb.Tag != null && tb.Controls.Count > 0) { - if (tb.Tag != null && tb.Controls.Count > 0) + DetailsListView lst = (DetailsListView)tb.Tag; + for (int i = 0; i < lst.Columns.Count; i++) { - DetailsListView lst = (DetailsListView)tb.Tag; - for (int i = 0; i < lst.Columns.Count; i++) - { - lst.Columns[dispOrder[i]].DisplayIndex = i; - lst.Columns[i].Width = currentListView.Columns[i].Width; - } + lst.Columns[dispOrder[i]].DisplayIndex = i; + lst.Columns[i].Width = currentListView.Columns[i].Width; } } } @@ -4792,10 +4766,11 @@ namespace OpenTween } // A cache miss, so create a new ListViewItem and pass it back. - TabPage tb = (TabPage)((DetailsListView)sender).Parent; + var tabPage = (TabPage)((DetailsListView)sender).Parent; + var tab = this._statuses.Tabs[tabPage.Text]; try { - e.Item = this.CreateItem(tb, _statuses.Tabs[tb.Text][e.ItemIndex], e.ItemIndex); + e.Item = this.CreateItem(tab, tab[e.ItemIndex], e.ItemIndex); } catch (Exception) { @@ -4822,10 +4797,10 @@ namespace OpenTween var cacheLength = endIndex - startIndex + 1; - var tabPage = this.CurrentTabPage; + var tab = this.CurrentTab; var posts = tabInfo[startIndex, endIndex]; //配列で取得 var listItems = Enumerable.Range(0, cacheLength) - .Select(x => this.CreateItem(tabPage, posts[x], startIndex + x)) + .Select(x => this.CreateItem(tab, posts[x], startIndex + x)) .ToArray(); var listCache = new ListViewItemCache @@ -4846,7 +4821,7 @@ namespace OpenTween private void PurgeListViewItemCache() => Interlocked.Exchange(ref this._listItemCache, null); - private ListViewItem CreateItem(TabPage Tab, PostClass Post, int Index) + private ListViewItem CreateItem(TabModel tab, PostClass Post, int Index) { StringBuilder mk = new StringBuilder(); //if (Post.IsDeleted) mk.Append("×"); @@ -4883,10 +4858,15 @@ namespace OpenTween itm.Tag = Post; bool read = Post.IsRead; - //未読管理していなかったら既読として扱う - if (!_statuses.Tabs[Tab.Text].UnreadManage || !SettingManager.Common.UnreadManage) read = true; + // 未読管理していなかったら既読として扱う + if (!tab.UnreadManage || !SettingManager.Common.UnreadManage) + read = true; + ChangeItemStyleRead(read, itm, Post, null); - if (Tab.Equals(this.CurrentTabPage)) ColorizeList(itm, Index); + + if (tab.TabName == this.CurrentTabName) + this.ColorizeList(itm, Index); + return itm; } @@ -4898,8 +4878,6 @@ namespace OpenTween using (ControlTransaction.Cursor(this, Cursors.WaitCursor)) { this.PurgeListViewItemCache(); - this._curPost = null; - this._curItemIndex = -1; this._statuses.FilterAll(); foreach (TabPage tabPage in this.ListTab.TabPages) @@ -5213,8 +5191,7 @@ namespace OpenTween return; } - var listView = this.CurrentListView; - var selectedIndex = listView.SelectedIndices.Count != 0 ? listView.SelectedIndices[0] : -1; + var selectedIndex = tab.SelectedIndex; int startIndex; switch (searchType) @@ -5261,6 +5238,7 @@ namespace OpenTween return; } + var listView = this.CurrentListView; this.SelectListItem(listView, foundIndex); listView.EnsureVisible(foundIndex); } @@ -5507,12 +5485,9 @@ namespace OpenTween private async void StatusOpenMenuItem_Click(object sender, EventArgs e) { var tab = this.CurrentTab; - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 0 && tab.TabType != MyCommon.TabUsageType.DirectMessage) - { - var post = tab[listView.SelectedIndices[0]]; + var post = this.CurrentPost; + if (post != null && tab.TabType != MyCommon.TabUsageType.DirectMessage) await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(post)); - } } private async void VerUpMenuItem_Click(object sender, EventArgs e) @@ -5671,18 +5646,19 @@ namespace OpenTween private async Task DispSelectedPost(bool forceupdate) { - if (this.CurrentListView.SelectedIndices.Count == 0 || _curPost == null) + var currentPost = this.CurrentPost; + if (currentPost == null) return; var oldDisplayPost = this.displayPost; - this.displayPost = this._curPost; + this.displayPost = currentPost; - if (!forceupdate && this._curPost.Equals(oldDisplayPost)) + if (!forceupdate && currentPost.Equals(oldDisplayPost)) return; var loadTasks = new List { - this.tweetDetailsView.ShowPostDetails(this._curPost), + this.tweetDetailsView.ShowPostDetails(currentPost), }; this.SplitContainer3.Panel2Collapsed = true; @@ -5693,7 +5669,7 @@ namespace OpenTween oldTokenSource?.Cancel(); var token = this.thumbnailTokenSource.Token; - loadTasks.Add(this.tweetThumbnail1.ShowThumbnailAsync(_curPost, token)); + loadTasks.Add(this.tweetThumbnail1.ShowThumbnailAsync(currentPost, token)); } try @@ -5717,7 +5693,7 @@ namespace OpenTween var tab = this.CurrentTab; if (tab.TabType == MyCommon.TabUsageType.PublicSearch) { - Control pnl = ListTab.SelectedTab.Controls["panelSearch"]; + Control pnl = this.CurrentTabPage.Controls["panelSearch"]; if (pnl.Controls["comboSearch"].Focused || pnl.Controls["comboLang"].Focused || pnl.Controls["buttonSearch"].Focused) return; @@ -6085,8 +6061,8 @@ namespace OpenTween .Do(() => this.doReTweetOfficial(isConfirm: true)), ShortcutCommand.Create(Keys.Alt | Keys.P) - .OnlyWhen(() => this._curPost != null) - .Do(() => this.doShowUserStatus(_curPost.ScreenName, ShowInputDialog: false)), + .OnlyWhen(() => this.CurrentPost != null) + .Do(() => this.doShowUserStatus(this.CurrentPost.ScreenName, ShowInputDialog: false)), ShortcutCommand.Create(Keys.Alt | Keys.Up) .Do(() => this.tweetDetailsView.ScrollDownPostBrowser(forward: false)), @@ -6137,11 +6113,12 @@ namespace OpenTween ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.Up) .FocusedOn(FocusedControl.StatusText) .Do(() => { - var listView = this.CurrentListView; - if (listView.VirtualListSize != 0 && - listView.SelectedIndices.Count > 0 && listView.SelectedIndices[0] > 0) + var tab = this.CurrentTab; + var selectedIndex = tab.SelectedIndex; + if (selectedIndex != -1 && selectedIndex > 0) { - var idx = listView.SelectedIndices[0] - 1; + var listView = this.CurrentListView; + var idx = selectedIndex - 1; SelectListItem(listView, idx); listView.EnsureVisible(idx); } @@ -6150,11 +6127,12 @@ namespace OpenTween ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.Down) .FocusedOn(FocusedControl.StatusText) .Do(() => { - var listView = this.CurrentListView; - if (listView.VirtualListSize != 0 && listView.SelectedIndices.Count > 0 - && listView.SelectedIndices[0] < listView.VirtualListSize - 1) + var tab = this.CurrentTab; + var selectedIndex = tab.SelectedIndex; + if (selectedIndex != -1 && selectedIndex < tab.AllCount - 1) { - var idx = listView.SelectedIndices[0] + 1; + var listView = this.CurrentListView; + var idx = selectedIndex + 1; SelectListItem(listView, idx); listView.EnsureVisible(idx); } @@ -6311,9 +6289,8 @@ namespace OpenTween var tab = this.CurrentTab; bool IsProtected = false; var isDm = tab.TabType == MyCommon.TabUsageType.DirectMessage; - foreach (int idx in this.CurrentListView.SelectedIndices) + foreach (var post in tab.SelectedPosts) { - var post = tab[idx]; if (post.IsDeleted) continue; if (!isDm) { @@ -6352,11 +6329,8 @@ namespace OpenTween return; var copyUrls = new List(); - foreach (int idx in this.CurrentListView.SelectedIndices) - { - var post = tab[idx]; + foreach (var post in tab.SelectedPosts) copyUrls.Add(MyCommon.GetStatusUrl(post)); - } if (copyUrls.Count == 0) return; @@ -6373,46 +6347,50 @@ namespace OpenTween private void GoFav(bool forward) { - var listView = this.CurrentListView; - if (listView.VirtualListSize == 0) return; + var tab = this.CurrentTab; + if (tab.AllCount == 0) + return; + + var selectedIndex = tab.SelectedIndex; + int fIdx = 0; int toIdx = 0; int stp = 1; if (forward) { - if (listView.SelectedIndices.Count == 0) + if (selectedIndex == -1) { fIdx = 0; } else { - fIdx = listView.SelectedIndices[0] + 1; - if (fIdx > listView.VirtualListSize - 1) return; + fIdx = selectedIndex + 1; + if (fIdx > tab.AllCount - 1) return; } - toIdx = listView.VirtualListSize; + toIdx = tab.AllCount; stp = 1; } else { - if (listView.SelectedIndices.Count == 0) + if (selectedIndex == -1) { - fIdx = listView.VirtualListSize - 1; + fIdx = tab.AllCount - 1; } else { - fIdx = listView.SelectedIndices[0] - 1; + fIdx = selectedIndex - 1; if (fIdx < 0) return; } toIdx = -1; stp = -1; } - var tab = this.CurrentTab; for (int idx = fIdx; idx != toIdx; idx += stp) { if (tab[idx].IsFav) { + var listView = this.CurrentListView; SelectListItem(listView, idx); listView.EnsureVisible(idx); break; @@ -6422,18 +6400,15 @@ namespace OpenTween private void GoSamePostToAnotherTab(bool left) { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count == 0) - return; - var tab = this.CurrentTab; // Directタブは対象外(見つかるはずがない) if (tab.TabType == MyCommon.TabUsageType.DirectMessage) return; - var selectedIndex = listView.SelectedIndices[0]; - var selectedStatusId = tab.GetStatusIdAt(selectedIndex); + var selectedStatusId = tab.SelectedStatusId; + if (selectedStatusId == -1) + return; int fIdx, toIdx, stp; @@ -6478,7 +6453,7 @@ namespace OpenTween if (foundIndex != -1) { ListTab.SelectedIndex = tabidx; - listView = this.CurrentListView; + var listView = this.CurrentListView; SelectListItem(listView, foundIndex); listView.EnsureVisible(foundIndex); return; @@ -6488,12 +6463,13 @@ namespace OpenTween private void GoPost(bool forward) { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count == 0 || _curPost == null) + var tab = this.CurrentTab; + var currentPost = this.CurrentPost; + + if (currentPost == null) return; - var tab = this.CurrentTab; - var selectedIndex = listView.SelectedIndices[0]; + var selectedIndex = tab.SelectedIndex; int fIdx, toIdx, stp; @@ -6513,13 +6489,13 @@ namespace OpenTween } string name = ""; - if (_curPost.RetweetedId == null) + if (currentPost.RetweetedId == null) { - name = _curPost.ScreenName; + name = currentPost.ScreenName; } else { - name = _curPost.RetweetedBy; + name = currentPost.RetweetedBy; } for (int idx = fIdx; idx != toIdx; idx += stp) { @@ -6528,6 +6504,7 @@ namespace OpenTween { if (post.ScreenName == name) { + var listView = this.CurrentListView; SelectListItem(listView, idx); listView.EnsureVisible(idx); break; @@ -6537,6 +6514,7 @@ namespace OpenTween { if (post.RetweetedBy == name) { + var listView = this.CurrentListView; SelectListItem(listView, idx); listView.EnsureVisible(idx); break; @@ -6547,12 +6525,11 @@ namespace OpenTween private void GoRelPost(bool forward) { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count == 0) - return; - var tab = this.CurrentTab; - var selectedIndex = listView.SelectedIndices[0]; + var selectedIndex = tab.SelectedIndex; + + if (selectedIndex == -1) + return; int fIdx, toIdx, stp; @@ -6573,8 +6550,9 @@ namespace OpenTween if (!_anchorFlag) { - if (_curPost == null) return; - _anchorPost = _curPost; + var currentPost = this.CurrentPost; + if (currentPost == null) return; + _anchorPost = currentPost; _anchorFlag = true; } else @@ -6594,6 +6572,7 @@ namespace OpenTween post.ReplyToList.Any(x => x.UserId == _anchorPost.UserId) || post.ReplyToList.Any(x => x.UserId == _anchorPost.RetweetedByUserId)) { + var listView = this.CurrentListView; SelectListItem(listView, idx); listView.EnsureVisible(idx); break; @@ -6710,21 +6689,25 @@ namespace OpenTween private async Task GoInReplyToPostTree() { - if (_curPost == null) return; - var curTabClass = this.CurrentTab; + var currentPost = this.CurrentPost; + + if (currentPost == null) + return; - if (curTabClass.TabType == MyCommon.TabUsageType.PublicSearch && _curPost.InReplyToStatusId == null && _curPost.TextFromApi.Contains("@")) + if (curTabClass.TabType == MyCommon.TabUsageType.PublicSearch && currentPost.InReplyToStatusId == null && currentPost.TextFromApi.Contains("@")) { try { - var post = await tw.GetStatusApi(false, _curPost.StatusId); + var post = await tw.GetStatusApi(false, currentPost.StatusId); - _curPost.InReplyToStatusId = post.InReplyToStatusId; - _curPost.InReplyToUser = post.InReplyToUser; - _curPost.IsReply = post.IsReply; + currentPost.InReplyToStatusId = post.InReplyToStatusId; + currentPost.InReplyToUser = post.InReplyToUser; + currentPost.IsReply = post.IsReply; this.PurgeListViewItemCache(); - this.CurrentListView.RedrawItems(_curItemIndex, _curItemIndex, false); + + var index = curTabClass.SelectedIndex; + this.CurrentListView.RedrawItems(index, index, false); } catch (WebApiException ex) { @@ -6732,21 +6715,20 @@ namespace OpenTween } } - if (!(this.ExistCurrentPost && _curPost.InReplyToUser != null && _curPost.InReplyToStatusId != null)) return; + if (!(this.ExistCurrentPost && currentPost.InReplyToUser != null && currentPost.InReplyToStatusId != null)) return; - if (replyChains == null || (replyChains.Count > 0 && replyChains.Peek().InReplyToId != _curPost.StatusId)) + if (replyChains == null || (replyChains.Count > 0 && replyChains.Peek().InReplyToId != currentPost.StatusId)) { replyChains = new Stack(); } - replyChains.Push(new ReplyChain(_curPost.StatusId, _curPost.InReplyToStatusId.Value, this.CurrentTabPage)); + replyChains.Push(new ReplyChain(currentPost.StatusId, currentPost.InReplyToStatusId.Value, curTabClass)); int inReplyToIndex; string inReplyToTabName; - long inReplyToId = _curPost.InReplyToStatusId.Value; - string inReplyToUser = _curPost.InReplyToUser; - //Dictionary curTabPosts = curTabClass.Posts; + var inReplyToId = currentPost.InReplyToStatusId.Value; + var inReplyToUser = currentPost.InReplyToUser; - var inReplyToPosts = from tab in _statuses.Tabs.Values + var inReplyToPosts = from tab in _statuses.Tabs orderby tab != curTabClass from post in tab.Posts.Values where post.StatusId == inReplyToId @@ -6761,7 +6743,7 @@ namespace OpenTween { await Task.Run(async () => { - var post = await tw.GetStatusApi(false, _curPost.InReplyToStatusId.Value) + var post = await tw.GetStatusApi(false, currentPost.InReplyToStatusId.Value) .ConfigureAwait(false); post.IsRead = true; @@ -6791,7 +6773,7 @@ namespace OpenTween TabPage tabPage = this.ListTab.TabPages.Cast().First((tp) => { return tp.Text == inReplyToTabName; }); DetailsListView listView = (DetailsListView)tabPage.Tag; - if (this.CurrentTabPage != tabPage) + if (this.CurrentTabName != inReplyToTabName) { this.ListTab.SelectTab(tabPage); } @@ -6802,23 +6784,24 @@ namespace OpenTween private void GoBackInReplyToPostTree(bool parallel = false, bool isForward = true) { - if (_curPost == null) return; - var curTabClass = this.CurrentTab; - //Dictionary curTabPosts = curTabClass.Posts; + var currentPost = this.CurrentPost; + + if (currentPost == null) + return; if (parallel) { - if (_curPost.InReplyToStatusId != null) + if (currentPost.InReplyToStatusId != null) { var posts = from t in _statuses.Tabs - from p in t.Value.Posts - where p.Value.StatusId != _curPost.StatusId && p.Value.InReplyToStatusId == _curPost.InReplyToStatusId - let indexOf = t.Value.IndexOf(p.Value.StatusId) + from p in t.Posts + where p.Value.StatusId != currentPost.StatusId && p.Value.InReplyToStatusId == currentPost.InReplyToStatusId + let indexOf = t.IndexOf(p.Value.StatusId) where indexOf > -1 orderby isForward ? indexOf : indexOf * -1 - orderby t.Value != curTabClass - select new {Tab = t.Value, Post = p.Value, Index = indexOf}; + orderby t != curTabClass + select new {Tab = t, Post = p.Value, Index = indexOf}; try { var postList = posts.ToList(); @@ -6830,7 +6813,8 @@ namespace OpenTween postList.RemoveAt(index); } } - var post = postList.FirstOrDefault((pst) => { return pst.Tab == curTabClass && isForward ? pst.Index > _curItemIndex : pst.Index < _curItemIndex; }); + var currentIndex = this.CurrentTab.SelectedIndex; + var post = postList.FirstOrDefault((pst) => { return pst.Tab == curTabClass && isForward ? pst.Index > currentIndex : pst.Index < currentIndex; }); if (post == null) post = postList.FirstOrDefault((pst) => { return pst.Tab != curTabClass; }); if (post == null) post = postList.First(); this.ListTab.SelectTab(this.ListTab.TabPages.Cast().First((tp) => { return tp.Text == post.Tab.TabName; })); @@ -6849,13 +6833,13 @@ namespace OpenTween if (replyChains == null || replyChains.Count < 1) { var posts = from t in _statuses.Tabs - from p in t.Value.Posts - where p.Value.InReplyToStatusId == _curPost.StatusId - let indexOf = t.Value.IndexOf(p.Value.StatusId) + from p in t.Posts + where p.Value.InReplyToStatusId == currentPost.StatusId + let indexOf = t.IndexOf(p.Value.StatusId) where indexOf > -1 orderby indexOf - orderby t.Value != curTabClass - select new {Tab = t.Value, Index = indexOf}; + orderby t != curTabClass + select new {Tab = t, Index = indexOf}; try { var post = posts.First(); @@ -6872,26 +6856,35 @@ namespace OpenTween else { ReplyChain chainHead = replyChains.Pop(); - if (chainHead.InReplyToId == _curPost.StatusId) + if (chainHead.InReplyToId == currentPost.StatusId) { - int idx = _statuses.Tabs[chainHead.OriginalTab.Text].IndexOf(chainHead.OriginalId); - if (idx == -1) + var tab = chainHead.OriginalTab; + if (!this._statuses.Tabs.Contains(tab)) { replyChains = null; } else { - try + var idx = tab.IndexOf(chainHead.OriginalId); + if (idx == -1) { - ListTab.SelectTab(chainHead.OriginalTab); + replyChains = null; } - catch (Exception) + else { - replyChains = null; + var tabPage = this.ListTab.TabPages.Cast().First(x => x.Text == tab.TabName); + try + { + ListTab.SelectTab(tabPage); + } + catch (Exception) + { + replyChains = null; + } + var listView = this.CurrentListView; + SelectListItem(listView, idx); + listView.EnsureVisible(idx); } - var listView = this.CurrentListView; - SelectListItem(listView, idx); - listView.EnsureVisible(idx); } } else @@ -6908,24 +6901,25 @@ namespace OpenTween if (this.selectPostChains.Count > 1) { var idx = -1; - TabPage tp = null; + TabModel foundTab = null; do { try { this.selectPostChains.Pop(); - var (tabPage, post) = this.selectPostChains.Peek(); + var (tab, post) = this.selectPostChains.Peek(); - if (!this.ListTab.TabPages.Contains(tabPage)) continue; //該当タブが存在しないので無視 + if (!this._statuses.Tabs.Contains(tab)) + continue; // 該当タブが存在しないので無視 if (post != null) { - idx = this._statuses.Tabs[tabPage.Text].IndexOf(post.StatusId); + idx = tab.IndexOf(post.StatusId); if (idx == -1) continue; //該当ポストが存在しないので無視 } - tp = tabPage; + foundTab = tab; this.selectPostChains.Pop(); } @@ -6937,7 +6931,7 @@ namespace OpenTween } while (this.selectPostChains.Count > 1); - if (tp == null) + if (foundTab == null) { //状態がおかしいので処理を中断 //履歴が残り1つであればクリアしておく @@ -6946,8 +6940,10 @@ namespace OpenTween return; } - DetailsListView lst = (DetailsListView)tp.Tag; - this.ListTab.SelectedTab = tp; + var tabPage = this.ListTab.TabPages.Cast().First(x => x.Text == foundTab.TabName); + var lst = (DetailsListView)tabPage.Tag; + this.ListTab.SelectedTab = tabPage; + if (idx > -1) { SelectListItem(lst, idx); @@ -6959,25 +6955,27 @@ namespace OpenTween private void PushSelectPostChain() { - var currentTabPage = this.CurrentTabPage; + var currentTab = this.CurrentTab; + var currentPost = this.CurrentPost; + int count = this.selectPostChains.Count; if (count > 0) { - var (tabPage, post) = this.selectPostChains.Peek(); - if (tabPage == currentTabPage) + var (tab, post) = this.selectPostChains.Peek(); + if (tab == currentTab) { - if (post == this._curPost) return; //最新の履歴と同一 + if (post == currentPost) return; //最新の履歴と同一 if (post == null) this.selectPostChains.Pop(); //置き換えるため削除 } } if (count >= 2500) TrimPostChain(); - this.selectPostChains.Push((currentTabPage, this._curPost)); + this.selectPostChains.Push((currentTab, currentPost)); } private void TrimPostChain() { if (this.selectPostChains.Count <= 2000) return; - var p = new Stack<(TabPage, PostClass)>(2000); + var p = new Stack<(TabModel, PostClass)>(2000); for (int i = 0; i < 2000; i++) { p.Push(this.selectPostChains.Pop()); @@ -6992,37 +6990,45 @@ namespace OpenTween private bool GoStatus(long statusId) { if (statusId == 0) return false; - for (int tabidx = 0; tabidx < ListTab.TabCount; tabidx++) - { - if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType != MyCommon.TabUsageType.DirectMessage && _statuses.Tabs[ListTab.TabPages[tabidx].Text].Contains(statusId)) - { - int idx = _statuses.Tabs[ListTab.TabPages[tabidx].Text].IndexOf(statusId); - ListTab.SelectedIndex = tabidx; - var listView = this.CurrentListView; - SelectListItem(listView, idx); - listView.EnsureVisible(idx); - return true; - } - } - return false; + + var tab = this._statuses.Tabs + .Where(x => x.TabType != MyCommon.TabUsageType.DirectMessage) + .Where(x => x.Contains(statusId)) + .FirstOrDefault(); + + if (tab == null) + return false; + + var index = tab.IndexOf(statusId); + + var tabPage = this.ListTab.TabPages.Cast().First(x => x.Text == tab.TabName); + this.ListTab.SelectedTab = tabPage; + + var listView = this.CurrentListView; + this.SelectListItem(listView, index); + listView.EnsureVisible(index); + + return true; } private bool GoDirectMessage(long statusId) { if (statusId == 0) return false; - for (int tabidx = 0; tabidx < ListTab.TabCount; tabidx++) - { - if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType == MyCommon.TabUsageType.DirectMessage && _statuses.Tabs[ListTab.TabPages[tabidx].Text].Contains(statusId)) - { - int idx = _statuses.Tabs[ListTab.TabPages[tabidx].Text].IndexOf(statusId); - ListTab.SelectedIndex = tabidx; - var listView = this.CurrentListView; - SelectListItem(listView, idx); - listView.EnsureVisible(idx); - return true; - } - } - return false; + + var tab = this._statuses.GetTabByType(); + var index = tab.IndexOf(statusId); + + if (index == -1) + return false; + + var tabPage = this.ListTab.TabPages.Cast().First(x => x.Text == tab.TabName); + this.ListTab.SelectedTab = tabPage; + + var listView = this.CurrentListView; + this.SelectListItem(listView, index); + listView.EnsureVisible(index); + + return true; } private void MyList_MouseClick(object sender, MouseEventArgs e) @@ -7187,7 +7193,7 @@ namespace OpenTween var tabs = this.ListTab.TabPages.Cast() .Select(x => this._statuses.Tabs[x.Text]) - .Append(this._statuses.GetTabByType(MyCommon.TabUsageType.Mute)); + .Append(this._statuses.MuteTab); foreach (var tab in tabs) { @@ -7274,11 +7280,10 @@ namespace OpenTween if (!SaveFileDialog1.ValidateNames) return; using (StreamWriter sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8)) { - var listView = this.CurrentListView; if (rslt == DialogResult.Yes) { //All - for (int idx = 0; idx < listView.VirtualListSize; idx++) + for (int idx = 0; idx < tab.AllCount; idx++) { var post = tab[idx]; string protect = ""; @@ -7295,9 +7300,8 @@ namespace OpenTween } else { - foreach (int idx in listView.SelectedIndices) + foreach (var post in this.CurrentTab.SelectedPosts) { - var post = tab[idx]; string protect = ""; if (post.IsProtect) protect = "Protect"; sw.WriteLine(post.Nickname + "\t" + @@ -7460,16 +7464,20 @@ namespace OpenTween using (ControlTransaction.Layout(this.ListTab)) { - var mTp = this.ListTab.TabPages[targetIndex]; - this.ListTab.TabPages.Remove(mTp); + var tab = this._statuses.Tabs[targetIndex]; + var tabPage = this.ListTab.TabPages[targetIndex]; + + this.ListTab.TabPages.Remove(tabPage); if (targetIndex < baseIndex) baseIndex--; - if (isBeforeBaseTab) - ListTab.TabPages.Insert(baseIndex, mTp); - else - ListTab.TabPages.Insert(baseIndex + 1, mTp); + if (!isBeforeBaseTab) + baseIndex++; + + this._statuses.MoveTab(baseIndex, tab); + + ListTab.TabPages.Insert(baseIndex, tabPage); } SaveConfigsTabs(); @@ -7483,24 +7491,26 @@ namespace OpenTween if (!this.ExistCurrentPost) return; var tab = this.CurrentTab; - var listView = this.CurrentListView; + var selectedPosts = tab.SelectedPosts; // 複数あてリプライはReplyではなく通常ポスト //↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない) //090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。 //090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k) - if (listView.SelectedIndices.Count > 0) + if (selectedPosts.Length > 0) { // アイテムが1件以上選択されている - if (listView.SelectedIndices.Count == 1 && !isAll && this.ExistCurrentPost) + if (selectedPosts.Length == 1 && !isAll && this.ExistCurrentPost) { + var post = selectedPosts.Single(); + // 単独ユーザー宛リプライまたはDM if ((tab.TabType == MyCommon.TabUsageType.DirectMessage && isAuto) || (!isAuto && !isReply)) { // ダイレクトメッセージ this.inReplyTo = null; - StatusText.Text = "D " + _curPost.ScreenName + " " + StatusText.Text; + StatusText.Text = "D " + post.ScreenName + " " + StatusText.Text; StatusText.SelectionStart = StatusText.Text.Length; StatusText.Focus(); return; @@ -7508,12 +7518,12 @@ namespace OpenTween if (string.IsNullOrEmpty(StatusText.Text)) { //空の場合 - var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId; - var inReplyToScreenName = this._curPost.ScreenName; + var inReplyToStatusId = post.RetweetedId ?? post.StatusId; + var inReplyToScreenName = post.ScreenName; this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); // ステータステキストが入力されていない場合先頭に@ユーザー名を追加する - StatusText.Text = "@" + _curPost.ScreenName + " "; + StatusText.Text = "@" + post.ScreenName + " "; } else { @@ -7522,13 +7532,13 @@ namespace OpenTween if (isAuto) { //1件選んでEnter or DoubleClick - if (StatusText.Text.Contains("@" + _curPost.ScreenName + " ")) + if (StatusText.Text.Contains("@" + post.ScreenName + " ")) { - if (this.inReplyTo?.ScreenName == _curPost.ScreenName) + if (this.inReplyTo?.ScreenName == post.ScreenName) { //返信先書き換え - var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId; - var inReplyToScreenName = this._curPost.ScreenName; + var inReplyToStatusId = post.RetweetedId ?? post.StatusId; + var inReplyToScreenName = post.ScreenName; this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); } return; @@ -7540,15 +7550,15 @@ namespace OpenTween { // 複数リプライ this.inReplyTo = null; - StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " "); + StatusText.Text = StatusText.Text.Insert(2, "@" + post.ScreenName + " "); } else { // 単独リプライ - var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId; - var inReplyToScreenName = this._curPost.ScreenName; + var inReplyToStatusId = post.RetweetedId ?? post.StatusId; + var inReplyToScreenName = post.ScreenName; this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); - StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text; + StatusText.Text = "@" + post.ScreenName + " " + StatusText.Text; } } else @@ -7556,15 +7566,14 @@ namespace OpenTween //文頭@ // 複数リプライ this.inReplyTo = null; - StatusText.Text = ". @" + _curPost.ScreenName + " " + StatusText.Text; - //StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text; + StatusText.Text = ". @" + post.ScreenName + " " + StatusText.Text; } } else { //1件選んでCtrl-Rの場合(返信先操作せず) int sidx = StatusText.SelectionStart; - string id = "@" + _curPost.ScreenName + " "; + string id = "@" + post.ScreenName + " "; if (sidx > 0) { if (StatusText.Text.Substring(sidx - 1, 1) != " ") @@ -7611,9 +7620,8 @@ namespace OpenTween sTxt = ". " + sTxt; this.inReplyTo = null; } - for (int cnt = 0; cnt < listView.SelectedIndices.Count; cnt++) + foreach (var post in selectedPosts) { - PostClass post = tab[listView.SelectedIndices[cnt]]; if (!sTxt.Contains("@" + post.ScreenName + " ")) { sTxt = sTxt.Insert(2, "@" + post.ScreenName + " "); @@ -7625,15 +7633,15 @@ namespace OpenTween else { //C-S-r or C-r - if (listView.SelectedIndices.Count > 1) + + if (selectedPosts.Length > 1) { //複数ポスト選択 string ids = ""; int sidx = StatusText.SelectionStart; - for (int cnt = 0; cnt < listView.SelectedIndices.Count; cnt++) + foreach (var post in selectedPosts) { - PostClass post = tab[listView.SelectedIndices[cnt]]; if (!ids.Contains("@" + post.ScreenName + " ") && post.UserId != tw.UserId) { ids += "@" + post.ScreenName + " "; @@ -7690,7 +7698,7 @@ namespace OpenTween string ids = ""; int sidx = StatusText.SelectionStart; - PostClass post = _curPost; + var post = selectedPosts.Single(); if (!ids.Contains("@" + post.ScreenName + " ") && post.UserId != tw.UserId) { ids += "@" + post.ScreenName + " "; @@ -7718,8 +7726,8 @@ namespace OpenTween if (string.IsNullOrEmpty(StatusText.Text)) { //未入力の場合のみ返信先付加 - var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId; - var inReplyToScreenName = this._curPost.ScreenName; + var inReplyToStatusId = post.RetweetedId ?? post.StatusId; + var inReplyToScreenName = post.ScreenName; this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); StatusText.Text = ids; @@ -8079,7 +8087,7 @@ namespace OpenTween if (tabUsage == MyCommon.TabUsageType.PublicSearch) { ListTab.SelectedIndex = ListTab.TabPages.Count - 1; - ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus(); + this.CurrentTabPage.Controls["panelSearch"].Controls["comboSearch"].Focus(); } if (tabUsage == MyCommon.TabUsageType.Lists) { @@ -8097,13 +8105,13 @@ namespace OpenTween fltDialog.Owner = this; //選択発言を元にフィルタ追加 - foreach (int idx in this.CurrentListView.SelectedIndices) + foreach (var post in this.CurrentTab.SelectedPosts) { //タブ選択(or追加) if (!SelectTab(out var tabName)) return; fltDialog.SetCurrent(tabName); - var post = this.CurrentTab[idx]; + if (post.RetweetedId == null) { fltDialog.AddNewFilter(post.ScreenName, post.TextFromApi); @@ -8119,10 +8127,6 @@ namespace OpenTween this.ApplyPostFilters(); SaveConfigsTabs(); - - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 0) - _curPost = this.CurrentTab[listView.SelectedIndices[0]]; } protected override bool ProcessDialogKey(Keys keyData) @@ -8221,14 +8225,14 @@ namespace OpenTween private void IDRuleMenuItem_Click(object sender, EventArgs e) { - var listView = this.CurrentListView; + var tab = this.CurrentTab; + var selectedPosts = tab.SelectedPosts; - //未選択なら処理終了 - if (listView.SelectedIndices.Count == 0) return; + // 未選択なら処理終了 + if (selectedPosts.Length == 0) + return; - var tab = this.CurrentTab; - var screenNameArray = listView.SelectedIndices.Cast() - .Select(x => tab[x]) + var screenNameArray = selectedPosts .Select(x => x.RetweetedId != null ? x.RetweetedBy : x.ScreenName) .ToArray(); @@ -8249,13 +8253,13 @@ namespace OpenTween private void SourceRuleMenuItem_Click(object sender, EventArgs e) { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count == 0) + var tab = this.CurrentTab; + var selectedPosts = tab.SelectedPosts; + + if (selectedPosts.Length == 0) return; - var tab = this.CurrentTab; - var sourceArray = listView.SelectedIndices.Cast() - .Select(x => tab[x].Source).ToArray(); + var sourceArray = selectedPosts.Select(x => x.Source).ToArray(); this.AddFilterRuleBySource(sourceArray); } @@ -8350,7 +8354,7 @@ namespace OpenTween tabName = dialog.SelectedTab?.TabName; } - ListTab.SelectedTab.Focus(); + this.CurrentTabPage.Focus(); //新規タブを選択→タブ作成 if (tabName == null) { @@ -8567,8 +8571,6 @@ namespace OpenTween _anchorPost = null; _anchorFlag = false; this.PurgeListViewItemCache(); - _curItemIndex = -1; - _curPost = null; } foreach (TabPage tb in ListTab.TabPages) { @@ -8598,7 +8600,7 @@ namespace OpenTween SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver && SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus) { - foreach (var tab in _statuses.Tabs.Values) + foreach (var tab in _statuses.Tabs) { ur += tab.UnreadCount; al += tab.AllCount; @@ -8661,7 +8663,7 @@ namespace OpenTween StringBuilder slbl = new StringBuilder(256); try { - foreach (var tab in _statuses.Tabs.Values) + foreach (var tab in _statuses.Tabs) { ur += tab.UnreadCount; al += tab.AllCount; @@ -9012,28 +9014,29 @@ namespace OpenTween private async Task doRepliedStatusOpen() { - if (this.ExistCurrentPost && _curPost.InReplyToUser != null && _curPost.InReplyToStatusId != null) + var currentPost = this.CurrentPost; + if (this.ExistCurrentPost && currentPost.InReplyToUser != null && currentPost.InReplyToStatusId != null) { if (MyCommon.IsKeyDown(Keys.Shift)) { - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId.Value)); + await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); return; } - if (_statuses.ContainsKey(_curPost.InReplyToStatusId.Value)) + if (_statuses.ContainsKey(currentPost.InReplyToStatusId.Value)) { - PostClass repPost = _statuses[_curPost.InReplyToStatusId.Value]; + PostClass repPost = _statuses[currentPost.InReplyToStatusId.Value]; MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi); } else { foreach (TabModel tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch)) { - if (tb == null || !tb.Contains(_curPost.InReplyToStatusId.Value)) break; - PostClass repPost = _statuses[_curPost.InReplyToStatusId.Value]; + if (tb == null || !tb.Contains(currentPost.InReplyToStatusId.Value)) break; + PostClass repPost = _statuses[currentPost.InReplyToStatusId.Value]; MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi); return; } - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId.Value)); + await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); } } } @@ -9328,20 +9331,18 @@ namespace OpenTween private void MenuStrip1_MenuDeactivate(object sender, EventArgs e) { + var currentTabPage = this.CurrentTabPage; if (this.Tag != null) // 設定された戻り先へ遷移 { - if (this.Tag == this.ListTab.SelectedTab) - ((Control)this.ListTab.SelectedTab.Tag).Select(); + if (this.Tag == currentTabPage) + ((Control)currentTabPage.Tag).Select(); else ((Control)this.Tag).Select(); } else // 戻り先が指定されていない (初期状態) 場合はタブに遷移 { - if (ListTab.SelectedIndex > -1 && ListTab.SelectedTab.HasChildren) - { - this.Tag = ListTab.SelectedTab.Tag; - ((Control)this.Tag).Select(); - } + this.Tag = currentTabPage.Tag; + ((Control)this.Tag).Select(); } // フォーカスがメニューに遷移したかどうかを表すフラグを降ろす MenuStrip1.Tag = null; @@ -9733,16 +9734,6 @@ namespace OpenTween this._statuses.SelectTab(_tab.Text); var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 0) - { - _curItemIndex = listView.SelectedIndices[0]; - _curPost = GetCurTabPost(_curItemIndex); - } - else - { - _curItemIndex = -1; - _curPost = null; - } _anchorPost = null; _anchorFlag = false; @@ -9942,23 +9933,24 @@ namespace OpenTween //公式RT if (this.ExistCurrentPost) { - if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId)) + var selectedPosts = this.CurrentTab.SelectedPosts; + + if (selectedPosts.Any(x => !x.CanRetweetBy(this.twitterApi.CurrentUserId))) { - if (this._curPost.IsProtect) + if (selectedPosts.Any(x => x.IsProtect)) MessageBox.Show("Protected."); _DoFavRetweetFlags = false; return; } - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 15) + if (selectedPosts.Length > 15) { MessageBox.Show(Properties.Resources.RetweetLimitText); _DoFavRetweetFlags = false; return; } - else if (listView.SelectedIndices.Count > 1) + else if (selectedPosts.Length > 1) { string QuestionText = Properties.Resources.RetweetQuestion2; if (_DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText1; @@ -9984,13 +9976,7 @@ namespace OpenTween } } - var statusIds = new List(); - foreach (int idx in listView.SelectedIndices) - { - PostClass post = GetCurTabPost(idx); - if (post.CanRetweetBy(this.twitterApi.CurrentUserId)) - statusIds.Add(post.StatusId); - } + var statusIds = selectedPosts.Select(x => x.StatusId).ToList(); await this.RetweetAsync(statusIds); } @@ -10019,11 +10005,12 @@ namespace OpenTween private async Task FavoritesRetweetUnofficial() { - if (this.ExistCurrentPost && !_curPost.IsDm) + var post = this.CurrentPost; + if (this.ExistCurrentPost && !post.IsDm) { _DoFavRetweetFlags = true; var favoriteTask = this.FavoriteChange(true); - if (!_curPost.IsProtect && _DoFavRetweetFlags) + if (!post.IsProtect && _DoFavRetweetFlags) { _DoFavRetweetFlags = false; doReTweetUnofficial(); @@ -10069,7 +10056,7 @@ namespace OpenTween { this.tweetDetailsView.DumpPostClass = this.DumpPostClassToolStripMenuItem.Checked; - if (_curPost != null) + if (this.CurrentPost != null) await this.DispSelectedPost(true); } @@ -10182,7 +10169,7 @@ namespace OpenTween private async void FollowCommandMenuItem_Click(object sender, EventArgs e) { - var id = _curPost?.ScreenName ?? ""; + var id = this.CurrentPost?.ScreenName ?? ""; await this.FollowCommand(id); } @@ -10222,7 +10209,7 @@ namespace OpenTween private async void RemoveCommandMenuItem_Click(object sender, EventArgs e) { - var id = _curPost?.ScreenName ?? ""; + var id = this.CurrentPost?.ScreenName ?? ""; await this.RemoveCommand(id, false); } @@ -10265,7 +10252,7 @@ namespace OpenTween private async void FriendshipMenuItem_Click(object sender, EventArgs e) { - var id = _curPost?.ScreenName ?? ""; + var id = this.CurrentPost?.ScreenName ?? ""; await this.ShowFriendship(id); } @@ -10420,10 +10407,11 @@ namespace OpenTween { if (this.ExistCurrentPost) { - if (_curPost.IsDm || - !StatusText.Enabled) return; + var post = this.CurrentPost; + if (post.IsDm || !StatusText.Enabled) + return; - if (_curPost.IsProtect) + if (post.IsProtect) { MessageBox.Show("Protected."); return; @@ -10433,7 +10421,7 @@ namespace OpenTween this.inReplyTo = null; - StatusText.Text += " " + MyCommon.GetStatusUrl(_curPost); + StatusText.Text += " " + MyCommon.GetStatusUrl(post); (this.StatusText.SelectionStart, this.StatusText.SelectionLength) = selection; StatusText.Focus(); @@ -10445,25 +10433,26 @@ namespace OpenTween //RT @id:内容 if (this.ExistCurrentPost) { - if (_curPost.IsDm || !StatusText.Enabled) + var post = this.CurrentPost; + if (post.IsDm || !StatusText.Enabled) return; - if (_curPost.IsProtect) + if (post.IsProtect) { MessageBox.Show("Protected."); return; } - string rtdata = _curPost.Text; + string rtdata = post.Text; rtdata = CreateRetweetUnofficial(rtdata, this.StatusText.Multiline); var selection = (this.StatusText.SelectionStart, this.StatusText.SelectionLength); // 投稿時に in_reply_to_status_id を付加する - var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId; - var inReplyToScreenName = this._curPost.ScreenName; + var inReplyToStatusId = post.RetweetedId ?? post.StatusId; + var inReplyToScreenName = post.ScreenName; this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); - StatusText.Text += " RT @" + _curPost.ScreenName + ": " + rtdata; + StatusText.Text += " RT @" + post.ScreenName + ": " + rtdata; (this.StatusText.SelectionStart, this.StatusText.SelectionLength) = selection; StatusText.Focus(); @@ -10583,7 +10572,8 @@ namespace OpenTween // 関連発言なら既存のタブを置き換える tb.TabName = relatedTab.TabName; this.ClearTab(tb.TabName, false); - _statuses.Tabs[tb.TabName] = tb; + + this._statuses.ReplaceTab(tb); for (int i = 0; i < ListTab.TabPages.Count; i++) { @@ -10646,15 +10636,9 @@ namespace OpenTween private async Task doMoveToRTHome() { - var listView = this.CurrentListView; - if (listView.SelectedIndices.Count > 0) - { - PostClass post = GetCurTabPost(listView.SelectedIndices[0]); - if (post.RetweetedId != null) - { - await this.OpenUriInBrowserAsync("https://twitter.com/" + GetCurTabPost(listView.SelectedIndices[0]).RetweetedBy); - } - } + var post = this.CurrentPost; + if (post != null && post.RetweetedId != null) + await this.OpenUriInBrowserAsync("https://twitter.com/" + post.RetweetedBy); } private async void MoveToRTHomeMenuItem_Click(object sender, EventArgs e) @@ -10662,7 +10646,7 @@ namespace OpenTween private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e) { - var screenName = this._curPost?.ScreenName; + var screenName = this.CurrentPost?.ScreenName; if (screenName != null) this.ListManageUserContext(screenName); } @@ -10812,7 +10796,8 @@ namespace OpenTween } var tab = this.CurrentTab; - if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || _curPost.IsDm) + var post = this.CurrentPost; + if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post.IsDm) { this.FavOpMenuItem.Enabled = false; this.UnFavOpMenuItem.Enabled = false; @@ -10831,7 +10816,7 @@ namespace OpenTween this.OpenStatusOpMenuItem.Enabled = true; this.ShowRelatedStatusesMenuItem2.Enabled = true; //PublicSearchの時問題出るかも - if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId)) + if (!post.CanRetweetBy(this.twitterApi.CurrentUserId)) { this.RtOpMenuItem.Enabled = false; this.RtUnOpMenuItem.Enabled = false; @@ -10857,8 +10842,7 @@ namespace OpenTween { this.RefreshPrevOpMenuItem.Enabled = false; } - if (!this.ExistCurrentPost - || _curPost.InReplyToStatusId == null) + if (!this.ExistCurrentPost || post.InReplyToStatusId == null) { OpenRepSourceOpMenuItem.Enabled = false; } @@ -10866,7 +10850,7 @@ namespace OpenTween { OpenRepSourceOpMenuItem.Enabled = true; } - if (!this.ExistCurrentPost || string.IsNullOrEmpty(_curPost.RetweetedBy)) + if (!this.ExistCurrentPost || string.IsNullOrEmpty(post.RetweetedBy)) { OpenRterHomeMenuItem.Enabled = false; } @@ -10877,7 +10861,7 @@ namespace OpenTween if (this.ExistCurrentPost) { - this.DelOpMenuItem.Enabled = this._curPost.CanDeleteBy(this.tw.UserId); + this.DelOpMenuItem.Enabled = post.CanDeleteBy(this.tw.UserId); } } @@ -10939,8 +10923,10 @@ namespace OpenTween this.CopySTOTMenuItem.Enabled = true; this.CopyURLMenuItem.Enabled = true; this.CopyUserIdStripMenuItem.Enabled = true; - if (_curPost.IsDm) this.CopyURLMenuItem.Enabled = false; - if (_curPost.IsProtect) this.CopySTOTMenuItem.Enabled = false; + + var post = this.CurrentPost; + if (post.IsDm) this.CopyURLMenuItem.Enabled = false; + if (post.IsProtect) this.CopySTOTMenuItem.Enabled = false; } } @@ -10948,7 +10934,7 @@ namespace OpenTween => this.SetNotifyIconText(); private async void UserStatusToolStripMenuItem_Click(object sender, EventArgs e) - => await this.ShowUserStatus(this._curPost?.ScreenName ?? ""); + => await this.ShowUserStatus(this.CurrentPost?.ScreenName ?? ""); private async Task doShowUserStatus(string id, bool ShowInputDialog) { @@ -11017,9 +11003,10 @@ namespace OpenTween private async void ShowProfileMenuItem_Click(object sender, EventArgs e) { - if (_curPost != null) + var post = this.CurrentPost; + if (post != null) { - await this.ShowUserStatus(_curPost.ScreenName, false); + await this.ShowUserStatus(post.ScreenName, false); } } @@ -11028,7 +11015,8 @@ namespace OpenTween if (!this.ExistCurrentPost) return; - var statusId = this._curPost.RetweetedId ?? this._curPost.StatusId; + var post = this.CurrentPost; + var statusId = post.RetweetedId ?? post.StatusId; TwitterStatus status; using (var dialog = new WaitingDialog(Properties.Resources.RtCountMenuItem_ClickText1)) @@ -11109,9 +11097,6 @@ namespace OpenTween private void SplitContainer2_MouseDoubleClick(object sender, MouseEventArgs e) => this.MultiLinePullDownMenuItem.PerformClick(); - public PostClass CurPost - => this._curPost; - #region "画像投稿" private void ImageSelectMenuItem_Click(object sender, EventArgs e) { @@ -11223,7 +11208,8 @@ namespace OpenTween private void MenuItemCommand_DropDownOpening(object sender, EventArgs e) { - if (this.ExistCurrentPost && !_curPost.IsDm) + var post = this.CurrentPost; + if (this.ExistCurrentPost && !post.IsDm) RtCountMenuItem.Enabled = true; else RtCountMenuItem.Enabled = false; @@ -11239,8 +11225,9 @@ namespace OpenTween private void CopyUserId() { - if (_curPost == null) return; - string clstr = _curPost.ScreenName; + var post = this.CurrentPost; + if (post == null) return; + var clstr = post.ScreenName; try { Clipboard.SetDataObject(clstr, false, 5, 100); @@ -11253,11 +11240,12 @@ namespace OpenTween private async void ShowRelatedStatusesMenuItem_Click(object sender, EventArgs e) { - if (this.ExistCurrentPost && !_curPost.IsDm) + var post = this.CurrentPost; + if (this.ExistCurrentPost && !post.IsDm) { try { - await this.OpenRelatedTab(this._curPost); + await this.OpenRelatedTab(post); } catch (TabException ex) { @@ -11373,7 +11361,8 @@ namespace OpenTween { this.PurgeListViewItemCache(); this.CurrentListView.Update(); - if (_curPost != null && _curPost.StatusId == e.StatusId) + var post = this.CurrentPost; + if (post != null && post.StatusId == e.StatusId) await this.DispSelectedPost(true); } }); @@ -11696,9 +11685,8 @@ namespace OpenTween { get { - if (_curPost == null) return false; - if (_curPost.IsDeleted) return false; - return true; + var post = this.CurrentPost; + return post != null && !post.IsDeleted; } } @@ -11707,7 +11695,7 @@ namespace OpenTween private string GetUserIdFromCurPostOrInput(string caption) { - var id = _curPost?.ScreenName ?? ""; + var id = this.CurrentPost?.ScreenName ?? ""; using (InputTabName inputName = new InputTabName()) { @@ -11781,12 +11769,13 @@ namespace OpenTween { if (SettingManager.Common.UserAppointUrl.Contains("{ID}") || SettingManager.Common.UserAppointUrl.Contains("{STATUS}")) { - if (_curPost != null) + var post = this.CurrentPost; + if (post != null) { string xUrl = SettingManager.Common.UserAppointUrl; - xUrl = xUrl.Replace("{ID}", _curPost.ScreenName); + xUrl = xUrl.Replace("{ID}", post.ScreenName); - var statusId = _curPost.RetweetedId ?? _curPost.StatusId; + var statusId = post.RetweetedId ?? post.StatusId; xUrl = xUrl.Replace("{STATUS}", statusId.ToString()); await this.OpenUriInBrowserAsync(xUrl);