using System.Net;
using System.Net.Http;
using System.Reflection;
+using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using OpenTween.Connection;
using OpenTween.Models;
using OpenTween.OpenTweenCustomControl;
+using OpenTween.Setting;
using OpenTween.Thumbnail;
namespace OpenTween
//Twitter用通信クラス初期化
Networking.DefaultTimeout = TimeSpan.FromSeconds(this._cfgCommon.DefaultTimeOut);
+ Networking.UploadImageTimeout = TimeSpan.FromSeconds(this._cfgCommon.UploadImageTimeout);
Networking.SetWebProxy(this._cfgLocal.ProxyType,
this._cfgLocal.ProxyAddress, this._cfgLocal.ProxyPort,
this._cfgLocal.ProxyUser, this._cfgLocal.ProxyPassword);
ImageSelector.Initialize(tw, this.tw.Configuration, _cfgCommon.UseImageServiceName, _cfgCommon.UseImageService);
//ハッシュタグ/@id関連
- AtIdSupl = new AtIdSupplement(SettingAtIdList.Load().AtIdList, "@");
+ AtIdSupl = new AtIdSupplement(SettingManager.AtIdList.AtIdList, "@");
HashSupl = new AtIdSupplement(_cfgCommon.HashTags, "#");
HashMgr = new HashtagManage(HashSupl,
_cfgCommon.HashTags.ToArray(),
private void LoadConfig()
{
- _cfgCommon = SettingCommon.Load();
- SettingCommon.Instance = this._cfgCommon;
- if (_cfgCommon.UserAccounts == null || _cfgCommon.UserAccounts.Count == 0)
- {
- _cfgCommon.UserAccounts = new List<UserAccount>();
- if (!string.IsNullOrEmpty(_cfgCommon.UserName))
- {
- UserAccount account = new UserAccount();
- account.Username = _cfgCommon.UserName;
- account.UserId = _cfgCommon.UserId;
- account.Token = _cfgCommon.Token;
- account.TokenSecret = _cfgCommon.TokenSecret;
-
- _cfgCommon.UserAccounts.Add(account);
- }
- }
+ SettingManager.LoadAll();
- _cfgLocal = SettingLocal.Load();
+ this._cfgCommon = SettingManager.Common;
+ this._cfgLocal = SettingManager.Local;
// v1.2.4 以前の設定には ScaleDimension の項目がないため、現在の DPI と同じとして扱う
if (_cfgLocal.ScaleDimension.IsEmpty)
_cfgLocal.ScaleDimension = this.CurrentAutoScaleDimensions;
- var tabsSetting = SettingTabs.Load().Tabs;
- foreach (var tabSetting in tabsSetting)
+ var tabSettings = SettingManager.Tabs;
+ foreach (var tabSetting in tabSettings.Tabs)
{
TabModel tab;
switch (tabSetting.TabType)
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();
if (MyCommon._endingFlag) return;
- //リストに反映&選択状態復元
- try
+ // リストに反映&選択状態復元
+ foreach (var tabPage in this.ListTab.TabPages.Cast<TabPage>())
{
- foreach (TabPage tab in ListTab.TabPages)
+ var listView = (DetailsListView)tabPage.Tag;
+ var tabModel = this._statuses.Tabs[tabPage.Text];
+
+ if (listView.VirtualListSize != tabModel.AllCount || isDelete)
{
- DetailsListView lst = (DetailsListView)tab.Tag;
- TabModel tabInfo = _statuses.Tabs[tab.Text];
- if (isDelete || lst.VirtualListSize != tabInfo.AllCount)
+ using (ControlTransaction.Update(listView))
{
- using (ControlTransaction.Update(lst))
- {
- if (lst.Equals(_curList))
- {
- this.PurgeListViewItemCache();
- }
- try
- {
- lst.VirtualListSize = tabInfo.AllCount; //リスト件数更新
- }
- catch (Exception)
- {
- //アイコン描画不具合あり?
- }
+ if (listView == this._curList)
+ this.PurgeListViewItemCache();
- // 選択位置などを復元
- this.RestoreListViewSelection(lst, tabInfo, listSelections[tabInfo.TabName]);
+ try
+ {
+ // リスト件数更新
+ listView.VirtualListSize = tabModel.AllCount;
+ }
+ catch (NullReferenceException ex)
+ {
+ // WinForms 内部で ListView.set_TopItem が発生させている例外
+ // https://ja.osdn.net/ticket/browse.php?group_id=6526&tid=36588
+ MyCommon.TraceOut(ex, $"TabType: {tabModel.TabType}, Count: {tabModel.AllCount}, ListSize: {listView.VirtualListSize}");
}
+
+ // 選択位置などを復元
+ this.RestoreListViewSelection(listView, tabModel, listSelections[tabModel.TabName]);
}
- if (tabInfo.UnreadCount > 0)
- if (this._cfgCommon.TabIconDisp)
- if (tab.ImageIndex == -1) tab.ImageIndex = 0; //タブアイコン
}
- if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
}
- catch (Exception)
+
+ if (addCount > 0)
{
- //ex.Data["Msg"] = "Ref1, UseAPI=" + SettingDialog.UseAPI.ToString();
- //throw;
+ if (this._cfgCommon.TabIconDisp)
+ {
+ foreach (var tabPage in this.ListTab.TabPages.Cast<TabPage>())
+ {
+ var tabModel = this._statuses.Tabs[tabPage.Text];
+ if (tabModel.UnreadCount > 0 && tabPage.ImageIndex != 0)
+ tabPage.ImageIndex = 0; // 未読アイコン
+ }
+ }
+ else
+ {
+ this.ListTab.Refresh();
+ }
}
// スクロール位置を復元
- this.RestoreListViewScroll(this._curList, this._statuses.Tabs[this._curTab.Text], curListScroll);
+ this.RestoreListViewScroll(this._curList, curTabModel, curListScroll);
//新着通知
NotifyNewPosts(notifyPosts, soundFile, addCount, newMentionOrDm);
if (listScroll.ScrollLockMode == ScrollLockMode.FixedToItem)
{
- var topItem = listView.TopItem;
- if (topItem != null)
- listScroll.TopItemStatusId = tab.GetStatusIdAt(topItem.Index);
+ var topItemIndex = listView.TopItem?.Index ?? -1;
+ if (topItemIndex != -1 && topItemIndex < tab.AllCount)
+ listScroll.TopItemStatusId = tab.GetStatusIdAt(topItemIndex);
}
return listScroll;
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;
private long? GetFocusedStatusId(DetailsListView listView, TabModel tab)
{
- var focusedItem = listView.FocusedItem;
+ var index = listView.FocusedItem?.Index ?? -1;
- return focusedItem != null ? tab.GetStatusIdAt(focusedItem.Index) : (long?)null;
+ return index != -1 && index < tab.AllCount ? tab.GetStatusIdAt(index) : (long?)null;
}
private long? GetSelectionMarkStatusId(DetailsListView listView, TabModel tab)
{
- var selectionMarkIndex = listView.SelectionMark;
+ var index = listView.SelectionMark;
- return selectionMarkIndex != -1 ? tab.GetStatusIdAt(selectionMarkIndex) : (long?)null;
+ return index != -1 && index < tab.AllCount ? tab.GetStatusIdAt(index) : (long?)null;
}
/// <summary>
p.Report(errMsg);
this._myStatusError = true;
}
+ catch (UnauthorizedAccessException ex)
+ {
+ // アップロード対象のファイルが開けなかった場合など
+ errMsg = $"Err:{ex.Message}(PostMessage)";
+ p.Report(errMsg);
+ this._myStatusError = true;
+ }
finally
{
// 使い終わった MediaItem は破棄する
!errMsg.StartsWith("OK:", StringComparison.Ordinal) &&
!errMsg.StartsWith("Warn:", StringComparison.Ordinal))
{
+ var message = string.Format(Properties.Resources.StatusUpdateFailed, errMsg, status.status);
+
var ret = MessageBox.Show(
- string.Format(
- "{0} ---> [ " + errMsg + " ]" + Environment.NewLine +
- "\"" + status.status + "\"" + Environment.NewLine +
- "{1}",
- Properties.Resources.StatusUpdateFailed1,
- Properties.Resources.StatusUpdateFailed2),
+ message,
"Failed to update status",
MessageBoxButtons.RetryCancel,
MessageBoxIcon.Question);
FavorareMenuItem.Enabled = true;
ShowRelatedStatusesMenuItem.Enabled = true; //PublicSearchの時問題出るかも
- if (_curPost.IsProtect)
+ if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId))
{
ReTweetStripMenuItem.Enabled = false;
ReTweetUnofficialStripMenuItem.Enabled = false;
}
else
{
- if (post.RetweetedId != null && post.UserId == this.tw.UserId)
- // 他人に RT された自分のツイート
- await this.twitterApi.StatusesDestroy(post.RetweetedId.Value)
- .IgnoreResponse();
- else
- // 自分のツイート or 自分が RT したツイート
+ if (post.RetweetedByUserId == this.tw.UserId)
+ {
+ // 自分が RT したツイート (自分が RT した自分のツイートも含む)
+ // => RT を取り消し
await this.twitterApi.StatusesDestroy(post.StatusId)
.IgnoreResponse();
+ }
+ else
+ {
+ if (post.UserId == this.tw.UserId)
+ {
+ if (post.RetweetedId != null)
+ // 他人に RT された自分のツイート
+ // => RT 元の自分のツイートを削除
+ await this.twitterApi.StatusesDestroy(post.RetweetedId.Value)
+ .IgnoreResponse();
+ else
+ // 自分のツイート
+ // => ツイートを削除
+ await this.twitterApi.StatusesDestroy(post.StatusId)
+ .IgnoreResponse();
+ }
+ }
}
}
catch (WebApiException ex)
TwitterApiConnection.RestApiHost = this._cfgCommon.TwitterApiHost;
Networking.DefaultTimeout = TimeSpan.FromSeconds(this._cfgCommon.DefaultTimeOut);
+ Networking.UploadImageTimeout = TimeSpan.FromSeconds(this._cfgCommon.UploadImageTimeout);
Networking.SetWebProxy(this._cfgLocal.ProxyType,
this._cfgLocal.ProxyAddress, this._cfgLocal.ProxyPort,
this._cfgLocal.ProxyUser, this._cfgLocal.ProxyPassword);
//文字数カウント
var remainCount = this.tw.GetTextLengthRemain(statusText);
- if (this.ImageSelector.Visible && !string.IsNullOrEmpty(this.ImageSelector.ServiceName))
+ var uploadService = this.ImageSelector.SelectedService;
+ if (this.ImageSelector.Visible && uploadService != null)
{
- remainCount -= this.tw.Configuration.CharactersReservedPerMedia;
+ // TODO: ImageSelector で選択中の画像の枚数が mediaCount 引数に渡るようにする
+ remainCount -= uploadService.GetReservedTextLength(1);
}
return remainCount;
return;
var listCache = this._listItemCache;
- if (listCache != null && listCache.IsSupersetOf(e.StartIndex, e.EndIndex))
+ if (listCache?.TargetList == sender && listCache.IsSupersetOf(e.StartIndex, e.EndIndex))
{
// If the newly requested cache is a subset of the old cache,
// no need to rebuild everything, so do nothing.
private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
var listCache = this._listItemCache;
- if (listCache != null && listCache.TargetList == sender)
+ if (listCache?.TargetList == sender)
{
ListViewItem item;
PostClass cacheItemPost;
using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
{
TextRenderer.DrawText(e.Graphics,
- post.TextSingleLine,
+ post.IsDeleted ? "(DELETED)" : post.TextSingleLine,
e.Item.Font,
Rectangle.Round(rct),
color,
TextFormatFlags.NoPrefix);
}
}
- else if (drawLineCount == 1)
- {
- TextRenderer.DrawText(e.Graphics,
- e.ColumnIndex != 2 ? e.SubItem.Text : post.TextSingleLine,
- e.Item.Font,
- Rectangle.Round(rct),
- color,
- TextFormatFlags.SingleLine |
- TextFormatFlags.EndEllipsis |
- TextFormatFlags.GlyphOverhangPadding |
- TextFormatFlags.NoPrefix |
- TextFormatFlags.VerticalCenter);
- }
else
{
- TextRenderer.DrawText(e.Graphics,
- e.ColumnIndex != 2 ? e.SubItem.Text : post.TextSingleLine,
- e.Item.Font,
- Rectangle.Round(rct),
- color,
- TextFormatFlags.WordBreak |
- TextFormatFlags.EndEllipsis |
- TextFormatFlags.GlyphOverhangPadding |
- TextFormatFlags.NoPrefix);
+ string text;
+ if (e.ColumnIndex != 2)
+ text = e.SubItem.Text;
+ else
+ text = post.IsDeleted ? "(DELETED)" : post.TextSingleLine;
+
+ if (drawLineCount == 1)
+ {
+ TextRenderer.DrawText(e.Graphics,
+ text,
+ e.Item.Font,
+ Rectangle.Round(rct),
+ color,
+ TextFormatFlags.SingleLine |
+ TextFormatFlags.EndEllipsis |
+ TextFormatFlags.GlyphOverhangPadding |
+ TextFormatFlags.NoPrefix |
+ TextFormatFlags.VerticalCenter);
+ }
+ else
+ {
+ TextRenderer.DrawText(e.Graphics,
+ text,
+ e.Item.Font,
+ Rectangle.Round(rct),
+ color,
+ TextFormatFlags.WordBreak |
+ TextFormatFlags.EndEllipsis |
+ TextFormatFlags.GlyphOverhangPadding |
+ TextFormatFlags.NoPrefix);
+ }
}
//if (e.ColumnIndex == 6) this.DrawListViewItemStateIcon(e, rct);
}
private void JumpUnreadMenuItem_Click(object sender, EventArgs e)
{
int bgnIdx = ListTab.TabPages.IndexOf(_curTab);
- int idx = -1;
- DetailsListView lst = null;
if (ImageSelector.Enabled)
return;
+ TabModel foundTab = null;
+ int foundIndex = 0;
+
+ DetailsListView lst = null;
+
//現在タブから最終タブまで探索
for (int i = bgnIdx; i < ListTab.TabPages.Count; i++)
{
- //未読Index取得
- idx = _statuses.Tabs[ListTab.TabPages[i].Text].NextUnreadIndex;
- if (idx > -1)
+ var tabPage = this.ListTab.TabPages[i];
+ var tab = this._statuses.Tabs[tabPage.Text];
+ var unreadIndex = tab.NextUnreadIndex;
+
+ if (unreadIndex != -1)
{
ListTab.SelectedIndex = i;
- lst = (DetailsListView)ListTab.TabPages[i].Tag;
- //_curTab = ListTab.TabPages[i];
+ foundTab = tab;
+ foundIndex = unreadIndex;
+ lst = (DetailsListView)tabPage.Tag;
break;
}
}
//未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索
- if (idx == -1 && bgnIdx > 0)
+ if (foundTab == null && bgnIdx > 0)
{
for (int i = 0; i < bgnIdx; i++)
{
- idx = _statuses.Tabs[ListTab.TabPages[i].Text].NextUnreadIndex;
- if (idx > -1)
+ var tabPage = this.ListTab.TabPages[i];
+ var tab = this._statuses.Tabs[tabPage.Text];
+ var unreadIndex = tab.NextUnreadIndex;
+
+ if (unreadIndex != -1)
{
ListTab.SelectedIndex = i;
- lst = (DetailsListView)ListTab.TabPages[i].Tag;
- //_curTab = ListTab.TabPages[i];
+ foundTab = tab;
+ foundIndex = unreadIndex;
+ lst = (DetailsListView)tabPage.Tag;
break;
}
}
}
- //全部調べたが未読見つからず→先頭タブの最新発言へ
- if (idx == -1)
+ if (foundTab == null)
{
+ //全部調べたが未読見つからず→先頭タブの最新発言へ
ListTab.SelectedIndex = 0;
- lst = (DetailsListView)ListTab.TabPages[0].Tag;
- //_curTab = ListTab.TabPages[0];
+ var tabPage = this.ListTab.TabPages[0];
+ var tab = this._statuses.Tabs[tabPage.Text];
+
+ if (tab.AllCount == 0)
+ return;
+
if (_statuses.SortOrder == SortOrder.Ascending)
- idx = lst.VirtualListSize - 1;
+ foundIndex = tab.AllCount - 1;
else
- idx = 0;
+ foundIndex = 0;
+
+ lst = (DetailsListView)tabPage.Tag;
}
- if (lst.VirtualListSize > 0 && idx > -1 && lst.VirtualListSize > idx)
+ SelectListItem(lst, foundIndex);
+
+ if (_statuses.SortMode == ComparerMode.Id)
{
- SelectListItem(lst, idx);
- if (_statuses.SortMode == ComparerMode.Id)
+ if (_statuses.SortOrder == SortOrder.Ascending && lst.Items[foundIndex].Position.Y > lst.ClientSize.Height - _iconSz - 10 ||
+ _statuses.SortOrder == SortOrder.Descending && lst.Items[foundIndex].Position.Y < _iconSz + 10)
{
- if (_statuses.SortOrder == SortOrder.Ascending && lst.Items[idx].Position.Y > lst.ClientSize.Height - _iconSz - 10 ||
- _statuses.SortOrder == SortOrder.Descending && lst.Items[idx].Position.Y < _iconSz + 10)
- {
- MoveTop();
- }
- else
- {
- lst.EnsureVisible(idx);
- }
+ MoveTop();
}
else
{
- lst.EnsureVisible(idx);
+ lst.EnsureVisible(foundIndex);
}
}
+ else
+ {
+ lst.EnsureVisible(foundIndex);
+ }
+
lst.Focus();
}
foreach (int idx in _curList.SelectedIndices)
{
PostClass post = _statuses.Tabs[_curTab.Text][idx];
- if (post.IsProtect)
- {
- IsProtected = true;
- continue;
- }
if (post.IsDeleted) continue;
if (!isDm)
{
private void CopyIdUri()
{
- string clstr = "";
- StringBuilder sb = new StringBuilder();
- if (this._curTab == null) return;
- if (this._statuses.GetTabByName(this._curTab.Text) == null) return;
- if (this._statuses.GetTabByName(this._curTab.Text).TabType == MyCommon.TabUsageType.DirectMessage) return;
+ if (this._curTab == null)
+ return;
+
+ var tab = this._statuses.GetTabByName(this._curTab.Text);
+ if (tab == null || tab is DirectMessagesTabModel)
+ return;
+
+ var copyUrls = new List<string>();
foreach (int idx in _curList.SelectedIndices)
{
- var post = _statuses.Tabs[_curTab.Text][idx];
- sb.Append(MyCommon.GetStatusUrl(post));
- sb.Append(Environment.NewLine);
+ var post = tab[idx];
+ copyUrls.Add(MyCommon.GetStatusUrl(post));
}
- if (sb.Length > 0)
+
+ if (copyUrls.Count == 0)
+ return;
+
+ try
{
- clstr = sb.ToString();
- try
- {
- Clipboard.SetDataObject(clstr, false, 5, 100);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
+ Clipboard.SetDataObject(string.Join(Environment.NewLine, copyUrls), false, 5, 100);
+ }
+ catch (ExternalException ex)
+ {
+ MessageBox.Show(ex.Message);
}
}
private void GoSamePostToAnotherTab(bool left)
{
- if (_curList.VirtualListSize == 0) return;
- int fIdx = 0;
- int toIdx = 0;
- int stp = 1;
- long targetId = 0;
+ if (this._curList.SelectedIndices.Count == 0)
+ return;
- if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage) return; // Directタブは対象外(見つかるはずがない)
- if (_curList.SelectedIndices.Count == 0) return; //未選択も処理しない
+ var tab = this._statuses.Tabs[this._curTab.Text];
- targetId = GetCurTabPost(_curList.SelectedIndices[0]).StatusId;
+ // Directタブは対象外(見つかるはずがない)
+ if (tab.TabType == MyCommon.TabUsageType.DirectMessage)
+ return;
+
+ var selectedIndex = this._curList.SelectedIndices[0];
+ var selectedStatusId = tab.GetStatusIdAt(selectedIndex);
+
+ int fIdx, toIdx, stp;
if (left)
{
stp = 1;
}
- bool found = false;
for (int tabidx = fIdx; tabidx != toIdx; tabidx += stp)
{
- if (_statuses.Tabs[ListTab.TabPages[tabidx].Text].TabType == MyCommon.TabUsageType.DirectMessage) continue; // Directタブは対象外
- for (int idx = 0; idx < ((DetailsListView)ListTab.TabPages[tabidx].Tag).VirtualListSize; idx++)
+ var targetTab = this._statuses.Tabs[this.ListTab.TabPages[tabidx].Text];
+
+ // Directタブは対象外
+ if (targetTab.TabType == MyCommon.TabUsageType.DirectMessage)
+ continue;
+
+ var foundIndex = targetTab.IndexOf(selectedStatusId);
+ if (foundIndex != -1)
{
- if (_statuses.Tabs[ListTab.TabPages[tabidx].Text][idx].StatusId == targetId)
- {
- ListTab.SelectedIndex = tabidx;
- SelectListItem(_curList, idx);
- _curList.EnsureVisible(idx);
- found = true;
- break;
- }
+ ListTab.SelectedIndex = tabidx;
+ SelectListItem(_curList, foundIndex);
+ _curList.EnsureVisible(foundIndex);
+ return;
}
- if (found) break;
}
}
private void GoPost(bool forward)
{
- if (_curList.SelectedIndices.Count == 0 || _curPost == null) return;
- int fIdx = 0;
- int toIdx = 0;
- int stp = 1;
+ if (_curList.SelectedIndices.Count == 0 || _curPost == null)
+ return;
+
+ var tab = this._statuses.Tabs[this._curTab.Text];
+ var selectedIndex = this._curList.SelectedIndices[0];
+
+ int fIdx, toIdx, stp;
if (forward)
{
- fIdx = _curList.SelectedIndices[0] + 1;
- if (fIdx > _curList.VirtualListSize - 1) return;
- toIdx = _curList.VirtualListSize;
+ fIdx = selectedIndex + 1;
+ if (fIdx > tab.AllCount - 1) return;
+ toIdx = tab.AllCount;
stp = 1;
}
else
{
- fIdx = _curList.SelectedIndices[0] - 1;
+ fIdx = selectedIndex - 1;
if (fIdx < 0) return;
toIdx = -1;
stp = -1;
}
for (int idx = fIdx; idx != toIdx; idx += stp)
{
- if (_statuses.Tabs[_curTab.Text][idx].RetweetedId == null)
+ var post = tab[idx];
+ if (post.RetweetedId == null)
{
- if (_statuses.Tabs[_curTab.Text][idx].ScreenName == name)
+ if (post.ScreenName == name)
{
SelectListItem(_curList, idx);
_curList.EnsureVisible(idx);
}
else
{
- if (_statuses.Tabs[_curTab.Text][idx].RetweetedBy == name)
+ if (post.RetweetedBy == name)
{
SelectListItem(_curList, idx);
_curList.EnsureVisible(idx);
private void GoRelPost(bool forward)
{
- if (_curList.SelectedIndices.Count == 0) return;
+ if (this._curList.SelectedIndices.Count == 0)
+ return;
+
+ var tab = this._statuses.Tabs[this._curTab.Text];
+ var selectedIndex = this._curList.SelectedIndices[0];
+
+ int fIdx, toIdx, stp;
- int fIdx = 0;
- int toIdx = 0;
- int stp = 1;
if (forward)
{
- fIdx = _curList.SelectedIndices[0] + 1;
- if (fIdx > _curList.VirtualListSize - 1) return;
- toIdx = _curList.VirtualListSize;
+ fIdx = selectedIndex + 1;
+ if (fIdx > tab.AllCount - 1) return;
+ toIdx = tab.AllCount;
stp = 1;
}
else
{
- fIdx = _curList.SelectedIndices[0] - 1;
+ fIdx = selectedIndex - 1;
if (fIdx < 0) return;
toIdx = -1;
stp = -1;
for (int idx = fIdx; idx != toIdx; idx += stp)
{
- PostClass post = _statuses.Tabs[_curTab.Text][idx];
+ var post = tab[idx];
if (post.ScreenName == _anchorPost.ScreenName ||
post.RetweetedBy == _anchorPost.ScreenName ||
post.ScreenName == _anchorPost.RetweetedBy ||
if (_ignoreConfigSave || !this._cfgCommon.UseAtIdSupplement && AtIdSupl == null) return;
ModifySettingAtId = false;
- SettingAtIdList cfgAtId = new SettingAtIdList(AtIdSupl.GetItemList());
- cfgAtId.Save();
+ SettingManager.AtIdList.AtIdList = this.AtIdSupl.GetItemList();
+ SettingManager.SaveAtIdList();
}
private void SaveConfigsCommon()
_cfgCommon.UseImageService = ImageSelector.ServiceIndex;
_cfgCommon.UseImageServiceName = ImageSelector.ServiceName;
- _cfgCommon.Save();
+ SettingManager.SaveCommon();
}
}
_cfgLocal.FontInputFont = _fntInputFont;
if (_ignoreConfigSave) return;
- _cfgLocal.Save();
+ SettingManager.SaveLocal();
}
}
private void SaveConfigsTabs()
{
- var tabsSetting = new SettingTabs();
+ var tabSettingList = new List<SettingTabs.SettingTabItem>();
var tabs = this.ListTab.TabPages.Cast<TabPage>()
.Select(x => this._statuses.Tabs[x.Text])
if (listTab != null)
tabSetting.ListInfo = listTab.ListInfo;
- tabsSetting.Tabs.Add(tabSetting);
+ tabSettingList.Add(tabSetting);
}
- tabsSetting.Save();
+ SettingManager.Tabs.Tabs = tabSettingList;
+ SettingManager.SaveTabs();
}
private async void OpenURLFileMenuItem_Click(object sender, EventArgs e)
this.TopMost = this._cfgCommon.AlwaysTop;
}
- public bool TabRename(ref string tabName)
+ public bool TabRename(string origTabName, out string newTabName)
{
//タブ名変更
- string newTabText = null;
+ newTabName = null;
using (InputTabName inputName = new InputTabName())
{
- inputName.TabName = tabName;
+ inputName.TabName = origTabName;
inputName.ShowDialog();
if (inputName.DialogResult == DialogResult.Cancel) return false;
- newTabText = inputName.TabName;
+ newTabName = inputName.TabName;
}
this.TopMost = this._cfgCommon.AlwaysTop;
- if (!string.IsNullOrEmpty(newTabText))
+ if (!string.IsNullOrEmpty(newTabName))
{
//新タブ名存在チェック
for (int i = 0; i < ListTab.TabCount; i++)
{
- if (ListTab.TabPages[i].Text == newTabText)
+ if (ListTab.TabPages[i].Text == newTabName)
{
- string tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabText);
+ string tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabName);
MessageBox.Show(tmp, Properties.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return false;
}
}
- //タブ名を変更
- for (int i = 0; i < ListTab.TabCount; i++)
- {
- if (ListTab.TabPages[i].Text == tabName)
- {
- ListTab.TabPages[i].Text = newTabText;
- break;
- }
- }
- _statuses.RenameTab(tabName, newTabText);
+
+ var tabPage = this.ListTab.TabPages.Cast<TabPage>()
+ .FirstOrDefault(x => x.Text == origTabName);
+
+ // タブ名を変更
+ if (tabPage != null)
+ tabPage.Text = newTabName;
+
+ _statuses.RenameTab(origTabName, newTabName);
SaveConfigsCommon();
SaveConfigsTabs();
- _rclickTabName = newTabText;
- tabName = newTabText;
+ _rclickTabName = newTabName;
return true;
}
else
private void ListTab_DoubleClick(object sender, MouseEventArgs e)
{
- string tn = ListTab.SelectedTab.Text;
- TabRename(ref tn);
+ string _;
+ TabRename(this.ListTab.SelectedTab.Text, out _);
}
private void ListTab_MouseDown(object sender, MouseEventArgs e)
if (_statuses == null) return;
if (_statuses.Tabs == null) return;
- TabModel tb = _statuses.Tabs[_rclickTabName];
- if (tb == null) return;
+ TabModel tb;
+ if (!this._statuses.Tabs.TryGetValue(this._rclickTabName, out tb))
+ return;
NotifyDispMenuItem.Checked = tb.Notify;
this.NotifyTbMenuItem.Checked = tb.Notify;
{
if (tb.Text == tabName)
{
- tb.ImageIndex = -1;
((DetailsListView)tb.Tag).VirtualListSize = 0;
+ tb.ImageIndex = -1;
break;
}
}
_curTab = _tab;
_curList = (DetailsListView)_tab.Tag;
+
if (_curList.SelectedIndices.Count > 0)
{
_curItemIndex = _curList.SelectedIndices[0];
//公式RT
if (this.ExistCurrentPost)
{
- if (_curPost.IsProtect)
+ if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId))
{
- MessageBox.Show("Protected.");
+ if (this._curPost.IsProtect)
+ MessageBox.Show("Protected.");
+
_DoFavRetweetFlags = false;
return;
}
}
else
{
- if (_curPost.IsDm)
- {
- _DoFavRetweetFlags = false;
- return;
- }
if (!this._cfgCommon.RetweetNoConfirm)
{
string Questiontext = Properties.Resources.RetweetQuestion1;
foreach (int idx in _curList.SelectedIndices)
{
PostClass post = GetCurTabPost(idx);
- if (!post.IsProtect && !post.IsDm)
+ if (post.CanRetweetBy(this.twitterApi.CurrentUserId))
statusIds.Add(post.StatusId);
}
private void TabRenameMenuItem_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(_rclickTabName)) return;
- TabRename(ref _rclickTabName);
+
+ string _;
+ TabRename(_rclickTabName, out _);
}
private async void BitlyToolStripMenuItem_Click(object sender, EventArgs e)
await this.doMoveToRTHome();
}
- private async void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e)
+ private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e)
{
var screenName = this._curPost?.ScreenName;
if (screenName != null)
- await this.ListManageUserContext(screenName);
+ this.ListManageUserContext(screenName);
}
- public async Task ListManageUserContext(string screenName)
+ public void ListManageUserContext(string screenName)
{
- if (this._statuses.SubscribableLists.Count == 0)
- {
- try
- {
- using (var dialog = new WaitingDialog(Properties.Resources.ListsGetting))
- {
- var cancellationToken = dialog.EnableCancellation();
-
- var task = this.tw.GetListsApi();
- await dialog.WaitForAsync(this, task);
-
- cancellationToken.ThrowIfCancellationRequested();
- }
- }
- catch (OperationCanceledException) { return; }
- catch (WebApiException ex)
- {
- MessageBox.Show("Failed to get lists. (" + ex.Message + ")");
- return;
- }
- }
-
- using (MyLists listSelectForm = new MyLists(screenName, this.tw))
+ using (var listSelectForm = new MyLists(screenName, this.twitterApi))
{
listSelectForm.ShowDialog(this);
}
this.OpenFavotterOpMenuItem.Enabled = true;
this.ShowRelatedStatusesMenuItem2.Enabled = true; //PublicSearchの時問題出るかも
- if (_curPost.IsProtect)
+ if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId))
{
this.RtOpMenuItem.Enabled = false;
this.RtUnOpMenuItem.Enabled = false;
ModifySettingCommon = true;
SaveConfigsAll(true);
- if (ImageSelector.ServiceName.Equals("Twitter"))
- this.StatusText_TextChanged(null, null);
+ this.StatusText_TextChanged(null, null);
}
}
/// </summary>
private void ProcClipboardFromStatusTextWhenCtrlPlusV()
{
- if (Clipboard.ContainsText())
- {
- // clipboardにテキストがある場合は貼り付け処理
- this.StatusText.Paste(Clipboard.GetText());
- }
- else if (Clipboard.ContainsImage())
+ try
{
- // 画像があるので投稿処理を行う
- if (MessageBox.Show(Properties.Resources.PostPictureConfirm3,
- Properties.Resources.PostPictureWarn4,
- MessageBoxButtons.OKCancel,
- MessageBoxIcon.Question,
- MessageBoxDefaultButton.Button2)
- == DialogResult.OK)
+ if (Clipboard.ContainsText())
+ {
+ // clipboardにテキストがある場合は貼り付け処理
+ this.StatusText.Paste(Clipboard.GetText());
+ }
+ else if (Clipboard.ContainsImage())
{
- // clipboardから画像を取得
- using (var image = Clipboard.GetImage())
+ // 画像があるので投稿処理を行う
+ if (MessageBox.Show(Properties.Resources.PostPictureConfirm3,
+ Properties.Resources.PostPictureWarn4,
+ MessageBoxButtons.OKCancel,
+ MessageBoxIcon.Question,
+ MessageBoxDefaultButton.Button2)
+ == DialogResult.OK)
{
- this.ImageSelector.BeginSelection(image);
+ // clipboardから画像を取得
+ using (var image = Clipboard.GetImage())
+ {
+ this.ImageSelector.BeginSelection(image);
+ }
}
}
}
+ catch (ExternalException ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
}
#endregion
}
#region "Userstream"
- private void tw_PostDeleted(object sender, PostDeletedEventArgs e)
+ private async void tw_PostDeleted(object sender, PostDeletedEventArgs e)
{
try
{
if (InvokeRequired && !IsDisposed)
{
- Invoke((Action) (async () =>
- {
- this._statuses.RemovePostFromAllTabs(e.StatusId, setIsDeleted: true);
- if (_curTab != null && _statuses.Tabs[_curTab.Text].Contains(e.StatusId))
- {
- this.PurgeListViewItemCache();
- ((DetailsListView)_curTab.Tag).Update();
- if (_curPost != null && _curPost.StatusId == e.StatusId)
- await this.DispSelectedPost(true);
- }
- }));
+ await this.InvokeAsync(async () =>
+ {
+ this._statuses.RemovePostFromAllTabs(e.StatusId, setIsDeleted: true);
+ if (_curTab != null && _statuses.Tabs[_curTab.Text].Contains(e.StatusId))
+ {
+ this.PurgeListViewItemCache();
+ ((DetailsListView)_curTab.Tag).Update();
+ if (_curPost != null && _curPost.StatusId == e.StatusId)
+ await this.DispSelectedPost(true);
+ }
+ });
return;
}
}
}
}
- private void tw_UserStreamStarted(object sender, EventArgs e)
+ private async void tw_UserStreamStarted(object sender, EventArgs e)
{
try
{
if (InvokeRequired && !IsDisposed)
{
- Invoke((Action)(() => this.tw_UserStreamStarted(sender, e)));
+ await this.InvokeAsync(() => this.tw_UserStreamStarted(sender, e));
return;
}
}
StatusLabel.Text = "UserStream Started.";
}
- private void tw_UserStreamStopped(object sender, EventArgs e)
+ private async void tw_UserStreamStopped(object sender, EventArgs e)
{
try
{
if (InvokeRequired && !IsDisposed)
{
- Invoke((Action)(() => this.tw_UserStreamStopped(sender, e)));
+ await this.InvokeAsync(() => this.tw_UserStreamStopped(sender, e));
return;
}
}
}
}
- private void tw_UserStreamEventArrived(object sender, UserStreamEventReceivedEventArgs e)
+ private async void tw_UserStreamEventArrived(object sender, UserStreamEventReceivedEventArgs e)
{
try
{
if (InvokeRequired && !IsDisposed)
{
- Invoke((Action)(() => this.tw_UserStreamEventArrived(sender, e)));
+ await this.InvokeAsync(() => this.tw_UserStreamEventArrived(sender, e));
return;
}
}
await this.OpenUserAppointUrl();
}
- private void GrowlHelper_Callback(object sender, GrowlHelper.NotifyCallbackEventArgs e)
+ private async void GrowlHelper_Callback(object sender, GrowlHelper.NotifyCallbackEventArgs e)
{
if (Form.ActiveForm == null)
{
- this.BeginInvoke((Action) (() =>
+ await this.InvokeAsync(() =>
{
this.Visible = true;
if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
{
if (!this.GoStatus(e.StatusId)) this.StatusText.Focus();
}
- }));
+ });
}
}