OSDN Git Service

Merge remote-tracking branch 'naminodarie/SortedRetweet'
authorKimura Youichi <kim.upsilon@bucyou.net>
Mon, 1 Aug 2016 15:01:32 +0000 (00:01 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Mon, 1 Aug 2016 15:01:40 +0000 (00:01 +0900)
1  2 
OpenTween/Tween.cs

diff --combined OpenTween/Tween.cs
@@@ -259,10 -259,6 +259,10 @@@ namespace OpenTwee
          private PostClass _curPost;
          private bool _isColumnChanged = false;
  
 +        // 各タブの発言一覧のスクロール位置・選択状態を保持するフィールド
 +        private IDictionary<string, ListViewScroll> listViewScroll = new Dictionary<string, ListViewScroll>();
 +        private IDictionary<string, ListViewSelection> listViewSelection = new Dictionary<string, ListViewSelection>();
 +
          private const int MAX_WORKER_THREADS = 20;
          private SemaphoreSlim workerSemaphore = new SemaphoreSlim(MAX_WORKER_THREADS);
          private CancellationTokenSource workerCts = new CancellationTokenSource();
  
          private void RefreshTimeline()
          {
 +            var curTabModel = this._statuses.Tabs[this._curTab.Text];
 +
              // 現在表示中のタブのスクロール位置を退避
 -            var curListScroll = this.SaveListViewScroll(this._curList, this._statuses.Tabs[this._curTab.Text]);
 +            var curListScroll = this.SaveListViewScroll(this._curList, curTabModel);
  
 -            // タブのリスト上の選択位置などを退避
 -            var listSelections = this.SaveListViewSelection();
 +            // 現在表示中のタブのリスト上の選択位置などを退避
 +            var curListSelection = this.SaveListViewSelection(this._curList, curTabModel);
  
              //更新確定
              PostClass[] notifyPosts;
  
              if (MyCommon._endingFlag) return;
  
 -            //リストに反映&選択状態復元
 -            try
 +            if (this._cfgCommon.TabIconDisp)
              {
 -                foreach (TabPage tab in ListTab.TabPages)
 +                foreach (var tabPage in this.ListTab.TabPages.Cast<TabPage>())
                  {
 -                    DetailsListView lst = (DetailsListView)tab.Tag;
 -                    TabModel tabInfo = _statuses.Tabs[tab.Text];
 -                    if (isDelete || lst.VirtualListSize != tabInfo.AllCount)
 -                    {
 -                        using (ControlTransaction.Update(lst))
 -                        {
 -                            if (lst.Equals(_curList))
 -                            {
 -                                this.PurgeListViewItemCache();
 -                            }
 -                            try
 -                            {
 -                                lst.VirtualListSize = tabInfo.AllCount; //リスト件数更新
 -                            }
 -                            catch (Exception)
 -                            {
 -                                //アイコン描画不具合あり?
 -                            }
 -
 -                            // 選択位置などを復元
 -                            this.RestoreListViewSelection(lst, tabInfo, listSelections[tabInfo.TabName]);
 -                        }
 -                    }
 -                    if (tabInfo.UnreadCount > 0)
 -                        if (this._cfgCommon.TabIconDisp)
 -                            if (tab.ImageIndex == -1) tab.ImageIndex = 0; //タブアイコン
 +                    var tabModel = this._statuses.Tabs[tabPage.Text];
 +                    if (tabModel.UnreadCount > 0)
 +                        tabPage.ImageIndex = 0; // 未読アイコン
                  }
 -                if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
              }
 -            catch (Exception)
 +            else
              {
 -                //ex.Data["Msg"] = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString();
 -                //throw;
 +                this.ListTab.Refresh();
              }
  
 -            // スクロール位置を復元
 -            this.RestoreListViewScroll(this._curList, this._statuses.Tabs[this._curTab.Text], curListScroll);
 +            // リストに反映&選択状態復元
 +            if (this._curList.VirtualListSize != curTabModel.AllCount || isDelete)
 +            {
 +                using (ControlTransaction.Update(this._curList))
 +                {
 +                    this.PurgeListViewItemCache();
 +
 +                    // リスト件数更新
 +                    this._curList.VirtualListSize = curTabModel.AllCount;
 +
 +                    // 選択位置などを復元
 +                    this.RestoreListViewSelection(this._curList, curTabModel, curListSelection);
 +                }
 +
 +                // スクロール位置の復元は Begin/EndUpdate の外で行う
 +                // 参照: https://github.com/opentween/OpenTween/commit/7dbf6491
 +                this.RestoreListViewScroll(this._curList, curTabModel, curListScroll);
 +            }
  
              //新着通知
              NotifyNewPosts(notifyPosts, soundFile, addCount, newMentionOrDm);
                  var listView = (DetailsListView)tabPage.Tag;
                  var tab = _statuses.Tabs[tabPage.Text];
  
 -                ListViewSelection listStatus;
 -                if (listView.VirtualListSize != 0)
 -                {
 -                    listStatus = new ListViewSelection
 -                    {
 -                        SelectedStatusIds = this.GetSelectedStatusIds(listView, tab),
 -                        FocusedStatusId = this.GetFocusedStatusId(listView, tab),
 -                        SelectionMarkStatusId = this.GetSelectionMarkStatusId(listView, tab),
 -                    };
 -                }
 -                else
 -                {
 -                    listStatus = new ListViewSelection
 -                    {
 -                        SelectedStatusIds = new long[0],
 -                        SelectionMarkStatusId = null,
 -                        FocusedStatusId = null,
 -                    };
 -                }
 -
 -                listsDict[tab.TabName] = listStatus;
 +                listsDict[tab.TabName] = this.SaveListViewSelection(listView, tab);
              }
  
              return listsDict;
          }
  
 +        /// <summary>
 +        /// <see cref="ListView"/> の選択状態を <see cref="ListViewSelection"/> として返します
 +        /// </summary>
 +        private ListViewSelection SaveListViewSelection(DetailsListView listView, TabModel tab)
 +        {
 +            if (listView.VirtualListSize == 0)
 +            {
 +                return new ListViewSelection
 +                {
 +                    SelectedStatusIds = new long[0],
 +                    SelectionMarkStatusId = null,
 +                    FocusedStatusId = null,
 +                };
 +            }
 +
 +            return new ListViewSelection
 +            {
 +                SelectedStatusIds = this.GetSelectedStatusIds(listView, tab),
 +                FocusedStatusId = this.GetFocusedStatusId(listView, tab),
 +                SelectionMarkStatusId = this.GetSelectionMarkStatusId(listView, tab),
 +            };
 +        }
 +
          private long[] GetSelectedStatusIds(DetailsListView listView, TabModel tab)
          {
              var selectedIndices = listView.SelectedIndices;
  
              p.Report("Posting...");
  
-             var retweetTasks = from statusId in statusIds
-                                select this.tw.PostRetweet(statusId, read);
-             await Task.WhenAll(retweetTasks)
-                 .ConfigureAwait(false);
+             foreach (var statusId in statusIds)
+             {
+                 await this.tw.PostRetweet(statusId, read).ConfigureAwait(false);
+             }
  
              if (ct.IsCancellationRequested)
                  return;
          {
              SetListProperty();
  
 +            if (this._curList != null)
 +            {
 +                var beforeSelectedList = this._curList;
 +                var beforeSelectedTabModel = this._statuses.Tabs[this._curTab.Text];
 +
 +                // 発言一覧のスクロール位置・選択状態を退避
 +                this.listViewScroll[beforeSelectedTabModel.TabName] = this.SaveListViewScroll(beforeSelectedList, beforeSelectedTabModel);
 +                this.listViewSelection[beforeSelectedTabModel.TabName] = this.SaveListViewSelection(beforeSelectedList, beforeSelectedTabModel);
 +            }
 +
              this.PurgeListViewItemCache();
  
              _curTab = _tab;
              _curList = (DetailsListView)_tab.Tag;
 +
 +            var curTabModel = this._statuses.Tabs[this._curTab.Text];
 +
 +            this._curList.VirtualListSize = curTabModel.AllCount;
 +
 +            // 発言一覧のスクロール位置を復元
 +            ListViewScroll scrollInfo;
 +            if (this.listViewScroll.TryGetValue(curTabModel.TabName, out scrollInfo))
 +                this.RestoreListViewScroll(this._curList, curTabModel, scrollInfo);
 +
 +            // 発言一覧の選択状態を復元
 +            ListViewSelection selectionInfo;
 +            if (this.listViewSelection.TryGetValue(curTabModel.TabName, out selectionInfo))
 +                this.RestoreListViewSelection(this._curList, curTabModel, selectionInfo);
 +
              if (_curList.SelectedIndices.Count > 0)
              {
                  _curItemIndex = _curList.SelectedIndices[0];