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
private bool soundfileListup = false;
private FormWindowState _formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する
- //設定ファイル関連
- //private SettingToConfig _cfg; //旧
- internal SettingLocal _cfgLocal;
- private SettingCommon _cfgCommon;
-
//twitter解析部
private TwitterApi twitterApi = new TwitterApi();
private Twitter tw;
private PostClass _anchorPost;
private bool _anchorFlag; //true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
- private List<PostingStatus> _history = new List<PostingStatus>(); //発言履歴
+ private List<StatusTextHistory> _history = new List<StatusTextHistory>(); //発言履歴
private int _hisIdx; //発言履歴カレントインデックス
//発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
private Tuple<long, string> inReplyTo = null; // リプライ先のステータスID・スクリーン名
//時速表示用
- private List<DateTime> _postTimestamps = new List<DateTime>();
- private List<DateTime> _favTimestamps = new List<DateTime>();
+ private List<DateTimeUtc> _postTimestamps = new List<DateTimeUtc>();
+ private List<DateTimeUtc> _favTimestamps = new List<DateTimeUtc>();
// 以下DrawItem関連
private SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
private System.Timers.Timer TimerTimeline = new System.Timers.Timer();
private string recommendedStatusFooter;
+ private bool urlMultibyteSplit = false;
+ private bool preventSmsCommand = true;
//URL短縮のUndo用
private struct urlUndo
}
private Stack<ReplyChain> replyChains; //[, ]でのリプライ移動の履歴
- private Stack<Tuple<TabPage, PostClass>> selectPostChains = new Stack<Tuple<TabPage, PostClass>>(); //ポスト選択履歴
+ private Stack<ValueTuple<TabPage, PostClass>> selectPostChains = new Stack<ValueTuple<TabPage, PostClass>>(); //ポスト選択履歴
//検索処理タイプ
internal enum SEARCHTYPE
PrevSearch,
}
- private class PostingStatus
+ private class StatusTextHistory
{
public string status = "";
public long? inReplyToId = null;
public string inReplyToName = null;
public string imageService = ""; //画像投稿サービス名
public IMediaItem[] mediaItems = null;
- public PostingStatus()
+ public StatusTextHistory()
{
}
- public PostingStatus(string status, long? replyToId, string replyToName)
+ public StatusTextHistory(string status, long? replyToId, string replyToName)
{
this.status = status;
this.inReplyToId = replyToId;
if (startup)
{
- var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / this._cfgLocal.ScaleDimension.Width;
+ var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / SettingManager.Local.ScaleDimension.Width;
- columns[0].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width1);
- columns[1].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width3);
+ columns[0].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width1);
+ columns[1].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width3);
columns[0].DisplayIndex = 0;
columns[1].DisplayIndex = 1;
}
if (startup)
{
- var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / this._cfgLocal.ScaleDimension.Width;
+ var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / SettingManager.Local.ScaleDimension.Width;
- columns[0].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width1);
- columns[1].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width2);
- columns[2].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width3);
- columns[3].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width4);
- columns[4].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width5);
- columns[5].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width6);
- columns[6].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width7);
- columns[7].Width = ScaleBy(widthScaleFactor, _cfgLocal.Width8);
+ columns[0].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width1);
+ columns[1].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width2);
+ columns[2].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width3);
+ columns[3].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width4);
+ columns[4].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width5);
+ columns[5].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width6);
+ columns[6].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width7);
+ columns[7].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width8);
var displayIndex = new[] {
- this._cfgLocal.DisplayIndex1, this._cfgLocal.DisplayIndex2,
- this._cfgLocal.DisplayIndex3, this._cfgLocal.DisplayIndex4,
- this._cfgLocal.DisplayIndex5, this._cfgLocal.DisplayIndex6,
- this._cfgLocal.DisplayIndex7, this._cfgLocal.DisplayIndex8
+ SettingManager.Local.DisplayIndex1, SettingManager.Local.DisplayIndex2,
+ SettingManager.Local.DisplayIndex3, SettingManager.Local.DisplayIndex4,
+ SettingManager.Local.DisplayIndex5, SettingManager.Local.DisplayIndex6,
+ SettingManager.Local.DisplayIndex7, SettingManager.Local.DisplayIndex8
};
foreach (var i in Enumerable.Range(0, displayIndex.Length))
LoadConfig();
// 現在の DPI と設定保存時の DPI との比を取得する
- var configScaleFactor = this._cfgLocal.GetConfigScaleFactor(this.CurrentAutoScaleDimensions);
+ var configScaleFactor = SettingManager.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions);
// UIフォント設定
- var fontUIGlobal = this._cfgLocal.FontUIGlobal;
+ var fontUIGlobal = SettingManager.Local.FontUIGlobal;
if (fontUIGlobal != null)
{
OTBaseForm.GlobalFont = fontUIGlobal;
//不正値チェック
if (!MyApplication.StartupOptions.ContainsKey("nolimit"))
{
- if (this._cfgCommon.TimelinePeriod < 15 && this._cfgCommon.TimelinePeriod > 0)
- this._cfgCommon.TimelinePeriod = 15;
+ if (SettingManager.Common.TimelinePeriod < 15 && SettingManager.Common.TimelinePeriod > 0)
+ SettingManager.Common.TimelinePeriod = 15;
- if (this._cfgCommon.ReplyPeriod < 15 && this._cfgCommon.ReplyPeriod > 0)
- this._cfgCommon.ReplyPeriod = 15;
+ if (SettingManager.Common.ReplyPeriod < 15 && SettingManager.Common.ReplyPeriod > 0)
+ SettingManager.Common.ReplyPeriod = 15;
- if (this._cfgCommon.DMPeriod < 15 && this._cfgCommon.DMPeriod > 0)
- this._cfgCommon.DMPeriod = 15;
+ if (SettingManager.Common.DMPeriod < 15 && SettingManager.Common.DMPeriod > 0)
+ SettingManager.Common.DMPeriod = 15;
- if (this._cfgCommon.PubSearchPeriod < 30 && this._cfgCommon.PubSearchPeriod > 0)
- this._cfgCommon.PubSearchPeriod = 30;
+ if (SettingManager.Common.PubSearchPeriod < 30 && SettingManager.Common.PubSearchPeriod > 0)
+ SettingManager.Common.PubSearchPeriod = 30;
- if (this._cfgCommon.UserTimelinePeriod < 15 && this._cfgCommon.UserTimelinePeriod > 0)
- this._cfgCommon.UserTimelinePeriod = 15;
+ if (SettingManager.Common.UserTimelinePeriod < 15 && SettingManager.Common.UserTimelinePeriod > 0)
+ SettingManager.Common.UserTimelinePeriod = 15;
- if (this._cfgCommon.ListsPeriod < 15 && this._cfgCommon.ListsPeriod > 0)
- this._cfgCommon.ListsPeriod = 15;
+ if (SettingManager.Common.ListsPeriod < 15 && SettingManager.Common.ListsPeriod > 0)
+ SettingManager.Common.ListsPeriod = 15;
}
- if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, this._cfgCommon.CountApi))
- this._cfgCommon.CountApi = 60;
- if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, this._cfgCommon.CountApiReply))
- this._cfgCommon.CountApiReply = 40;
+ if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, SettingManager.Common.CountApi))
+ SettingManager.Common.CountApi = 60;
+ if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, SettingManager.Common.CountApiReply))
+ SettingManager.Common.CountApiReply = 40;
- if (this._cfgCommon.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(this._cfgCommon.MoreCountApi))
- this._cfgCommon.MoreCountApi = 200;
- if (this._cfgCommon.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(this._cfgCommon.FirstCountApi))
- this._cfgCommon.FirstCountApi = 100;
+ if (SettingManager.Common.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(SettingManager.Common.MoreCountApi))
+ SettingManager.Common.MoreCountApi = 200;
+ if (SettingManager.Common.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(SettingManager.Common.FirstCountApi))
+ SettingManager.Common.FirstCountApi = 100;
- if (this._cfgCommon.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, this._cfgCommon.FavoritesCountApi))
- this._cfgCommon.FavoritesCountApi = 40;
- if (this._cfgCommon.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, this._cfgCommon.ListCountApi))
- this._cfgCommon.ListCountApi = 100;
- if (this._cfgCommon.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, this._cfgCommon.SearchCountApi))
- this._cfgCommon.SearchCountApi = 100;
- if (this._cfgCommon.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, this._cfgCommon.UserTimelineCountApi))
- this._cfgCommon.UserTimelineCountApi = 20;
+ if (SettingManager.Common.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, SettingManager.Common.FavoritesCountApi))
+ SettingManager.Common.FavoritesCountApi = 40;
+ if (SettingManager.Common.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, SettingManager.Common.ListCountApi))
+ SettingManager.Common.ListCountApi = 100;
+ if (SettingManager.Common.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, SettingManager.Common.SearchCountApi))
+ SettingManager.Common.SearchCountApi = 100;
+ if (SettingManager.Common.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, SettingManager.Common.UserTimelineCountApi))
+ SettingManager.Common.UserTimelineCountApi = 20;
//廃止サービスが選択されていた場合ux.nuへ読み替え
- if (this._cfgCommon.AutoShortUrlFirst < 0)
- this._cfgCommon.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu;
+ if (SettingManager.Common.AutoShortUrlFirst < 0)
+ SettingManager.Common.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu;
- TwitterApiConnection.RestApiHost = this._cfgCommon.TwitterApiHost;
+ TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost;
this.tw = new Twitter(this.twitterApi);
//認証関連
- if (string.IsNullOrEmpty(this._cfgCommon.Token)) this._cfgCommon.UserName = "";
- tw.Initialize(this._cfgCommon.Token, this._cfgCommon.TokenSecret, this._cfgCommon.UserName, this._cfgCommon.UserId);
+ if (string.IsNullOrEmpty(SettingManager.Common.Token)) SettingManager.Common.UserName = "";
+ tw.Initialize(SettingManager.Common.Token, SettingManager.Common.TokenSecret, SettingManager.Common.UserName, SettingManager.Common.UserId);
_initial = true;
}
//Twitter用通信クラス初期化
- Networking.DefaultTimeout = TimeSpan.FromSeconds(this._cfgCommon.DefaultTimeOut);
- Networking.SetWebProxy(this._cfgLocal.ProxyType,
- this._cfgLocal.ProxyAddress, this._cfgLocal.ProxyPort,
- this._cfgLocal.ProxyUser, this._cfgLocal.ProxyPassword);
- Networking.ForceIPv4 = this._cfgCommon.ForceIPv4;
-
- TwitterApiConnection.RestApiHost = this._cfgCommon.TwitterApiHost;
- tw.RestrictFavCheck = this._cfgCommon.RestrictFavCheck;
- tw.ReadOwnPost = this._cfgCommon.ReadOwnPost;
- tw.TrackWord = this._cfgCommon.TrackWord;
+ Networking.DefaultTimeout = TimeSpan.FromSeconds(SettingManager.Common.DefaultTimeOut);
+ Networking.UploadImageTimeout = TimeSpan.FromSeconds(SettingManager.Common.UploadImageTimeout);
+ Networking.SetWebProxy(SettingManager.Local.ProxyType,
+ SettingManager.Local.ProxyAddress, SettingManager.Local.ProxyPort,
+ SettingManager.Local.ProxyUser, SettingManager.Local.ProxyPassword);
+ Networking.ForceIPv4 = SettingManager.Common.ForceIPv4;
+
+ TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost;
+ tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck;
+ tw.ReadOwnPost = SettingManager.Common.ReadOwnPost;
+ tw.TrackWord = SettingManager.Common.TrackWord;
TrackToolStripMenuItem.Checked = !String.IsNullOrEmpty(tw.TrackWord);
- tw.AllAtReply = this._cfgCommon.AllAtReply;
+ tw.AllAtReply = SettingManager.Common.AllAtReply;
AllrepliesToolStripMenuItem.Checked = tw.AllAtReply;
- ShortUrl.Instance.DisableExpanding = !this._cfgCommon.TinyUrlResolve;
- ShortUrl.Instance.BitlyId = this._cfgCommon.BilyUser;
- ShortUrl.Instance.BitlyKey = this._cfgCommon.BitlyPwd;
+ ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve;
+ ShortUrl.Instance.BitlyAccessToken = SettingManager.Common.BitlyAccessToken;
+ ShortUrl.Instance.BitlyId = SettingManager.Common.BilyUser;
+ ShortUrl.Instance.BitlyKey = SettingManager.Common.BitlyPwd;
// アクセストークンが有効であるか確認する
// ここが Twitter API への最初のアクセスになるようにすること
ThumbnailGenerator.InitializeGenerator();
var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance;
- imgazyobizinet.Enabled = this._cfgCommon.EnableImgAzyobuziNet;
- imgazyobizinet.DisabledInDM = this._cfgCommon.ImgAzyobuziNetDisabledInDM;
+ imgazyobizinet.Enabled = SettingManager.Common.EnableImgAzyobuziNet;
+ imgazyobizinet.DisabledInDM = SettingManager.Common.ImgAzyobuziNetDisabledInDM;
Thumbnail.Services.TonTwitterCom.GetApiConnection = () => this.twitterApi.Connection;
//画像投稿サービス
- ImageSelector.Initialize(tw, this.tw.Configuration, _cfgCommon.UseImageServiceName, _cfgCommon.UseImageService);
+ ImageSelector.Initialize(tw, this.tw.Configuration, SettingManager.Common.UseImageServiceName, SettingManager.Common.UseImageService);
//ハッシュタグ/@id関連
- AtIdSupl = new AtIdSupplement(SettingAtIdList.Load().AtIdList, "@");
- HashSupl = new AtIdSupplement(_cfgCommon.HashTags, "#");
+ AtIdSupl = new AtIdSupplement(SettingManager.AtIdList.AtIdList, "@");
+ HashSupl = new AtIdSupplement(SettingManager.Common.HashTags, "#");
HashMgr = new HashtagManage(HashSupl,
- _cfgCommon.HashTags.ToArray(),
- _cfgCommon.HashSelected,
- _cfgCommon.HashIsPermanent,
- _cfgCommon.HashIsHead,
- _cfgCommon.HashIsNotAddToAtReply);
+ SettingManager.Common.HashTags.ToArray(),
+ SettingManager.Common.HashSelected,
+ SettingManager.Common.HashIsPermanent,
+ SettingManager.Common.HashIsHead,
+ SettingManager.Common.HashIsNotAddToAtReply);
if (!string.IsNullOrEmpty(HashMgr.UseHash) && HashMgr.IsPermanent) HashStripSplitButton.Text = HashMgr.UseHash;
//アイコンリスト作成
this.tweetDetailsView.IconCache = this.IconCache;
//フォント&文字色&背景色保持
- _fntUnread = this._cfgLocal.FontUnread;
- _clUnread = this._cfgLocal.ColorUnread;
- _fntReaded = this._cfgLocal.FontRead;
- _clReaded = this._cfgLocal.ColorRead;
- _clFav = this._cfgLocal.ColorFav;
- _clOWL = this._cfgLocal.ColorOWL;
- _clRetweet = this._cfgLocal.ColorRetweet;
- _fntDetail = this._cfgLocal.FontDetail;
- _clDetail = this._cfgLocal.ColorDetail;
- _clDetailLink = this._cfgLocal.ColorDetailLink;
- _clDetailBackcolor = this._cfgLocal.ColorDetailBackcolor;
- _clSelf = this._cfgLocal.ColorSelf;
- _clAtSelf = this._cfgLocal.ColorAtSelf;
- _clTarget = this._cfgLocal.ColorTarget;
- _clAtTarget = this._cfgLocal.ColorAtTarget;
- _clAtFromTarget = this._cfgLocal.ColorAtFromTarget;
- _clAtTo = this._cfgLocal.ColorAtTo;
- _clListBackcolor = this._cfgLocal.ColorListBackcolor;
- _clInputBackcolor = this._cfgLocal.ColorInputBackcolor;
- _clInputFont = this._cfgLocal.ColorInputFont;
- _fntInputFont = this._cfgLocal.FontInputFont;
+ _fntUnread = SettingManager.Local.FontUnread;
+ _clUnread = SettingManager.Local.ColorUnread;
+ _fntReaded = SettingManager.Local.FontRead;
+ _clReaded = SettingManager.Local.ColorRead;
+ _clFav = SettingManager.Local.ColorFav;
+ _clOWL = SettingManager.Local.ColorOWL;
+ _clRetweet = SettingManager.Local.ColorRetweet;
+ _fntDetail = SettingManager.Local.FontDetail;
+ _clDetail = SettingManager.Local.ColorDetail;
+ _clDetailLink = SettingManager.Local.ColorDetailLink;
+ _clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor;
+ _clSelf = SettingManager.Local.ColorSelf;
+ _clAtSelf = SettingManager.Local.ColorAtSelf;
+ _clTarget = SettingManager.Local.ColorTarget;
+ _clAtTarget = SettingManager.Local.ColorAtTarget;
+ _clAtFromTarget = SettingManager.Local.ColorAtFromTarget;
+ _clAtTo = SettingManager.Local.ColorAtTo;
+ _clListBackcolor = SettingManager.Local.ColorListBackcolor;
+ _clInputBackcolor = SettingManager.Local.ColorInputBackcolor;
+ _clInputFont = SettingManager.Local.ColorInputFont;
+ _fntInputFont = SettingManager.Local.FontInputFont;
_brsBackColorMine = new SolidBrush(_clSelf);
_brsBackColorAt = new SolidBrush(_clAtSelf);
//Regex statregex = new Regex("^0*");
this.recommendedStatusFooter = " [TWNv" + Regex.Replace(MyCommon.FileVersion.Replace(".", ""), "^0*", "") + "]";
- _history.Add(new PostingStatus());
+ _history.Add(new StatusTextHistory());
_hisIdx = 0;
this.inReplyTo = null;
UrlDialog.Owner = this;
//新着バルーン通知のチェック状態設定
- NewPostPopMenuItem.Checked = _cfgCommon.NewAllPop;
+ NewPostPopMenuItem.Checked = SettingManager.Common.NewAllPop;
this.NotifyFileMenuItem.Checked = NewPostPopMenuItem.Checked;
//新着取得時のリストスクロールをするか。trueならスクロールしない
- ListLockMenuItem.Checked = _cfgCommon.ListLock;
- this.LockListFileMenuItem.Checked = _cfgCommon.ListLock;
+ ListLockMenuItem.Checked = SettingManager.Common.ListLock;
+ this.LockListFileMenuItem.Checked = SettingManager.Common.ListLock;
//サウンド再生(タブ別設定より優先)
- this.PlaySoundMenuItem.Checked = this._cfgCommon.PlaySound;
- this.PlaySoundFileMenuItem.Checked = this._cfgCommon.PlaySound;
-
- this.IdeographicSpaceToSpaceToolStripMenuItem.Checked = _cfgCommon.WideSpaceConvert;
- this.ToolStripFocusLockMenuItem.Checked = _cfgCommon.FocusLockToStatusText;
+ this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound;
+ this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound;
//ウィンドウ設定
- this.ClientSize = ScaleBy(configScaleFactor, _cfgLocal.FormSize);
+ this.ClientSize = ScaleBy(configScaleFactor, SettingManager.Local.FormSize);
_mySize = this.ClientSize; // サイズ保持(最小化・最大化されたまま終了した場合の対応用)
- _myLoc = _cfgLocal.FormLocation;
+ _myLoc = SettingManager.Local.FormLocation;
//タイトルバー領域
if (this.WindowState != FormWindowState.Minimized)
{
- this.DesktopLocation = _cfgLocal.FormLocation;
- Rectangle tbarRect = new Rectangle(this.Location, new Size(_mySize.Width, SystemInformation.CaptionHeight));
+ Rectangle tbarRect = new Rectangle(this._myLoc, new Size(_mySize.Width, SystemInformation.CaptionHeight));
bool outOfScreen = true;
if (Screen.AllScreens.Length == 1) //ハングするとの報告
{
break;
}
}
+
if (outOfScreen)
- {
- this.DesktopLocation = new Point(0, 0);
- _myLoc = this.DesktopLocation;
- }
+ this._myLoc = new Point(0, 0);
}
+ this.DesktopLocation = this._myLoc;
}
- this.TopMost = this._cfgCommon.AlwaysTop;
- _mySpDis = ScaleBy(configScaleFactor.Height, _cfgLocal.SplitterDistance);
- _mySpDis2 = ScaleBy(configScaleFactor.Height, _cfgLocal.StatusTextHeight);
- if (_cfgLocal.PreviewDistance == -1)
+ this.TopMost = SettingManager.Common.AlwaysTop;
+ _mySpDis = ScaleBy(configScaleFactor.Height, SettingManager.Local.SplitterDistance);
+ _mySpDis2 = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight);
+ if (SettingManager.Local.PreviewDistance == -1)
{
_mySpDis3 = _mySize.Width - ScaleBy(this.CurrentScaleFactor.Width, 150);
if (_mySpDis3 < 1) _mySpDis3 = ScaleBy(this.CurrentScaleFactor.Width, 50);
- _cfgLocal.PreviewDistance = _mySpDis3;
+ SettingManager.Local.PreviewDistance = _mySpDis3;
}
else
{
- _mySpDis3 = ScaleBy(configScaleFactor.Width, _cfgLocal.PreviewDistance);
+ _mySpDis3 = ScaleBy(configScaleFactor.Width, SettingManager.Local.PreviewDistance);
}
- MultiLineMenuItem.Checked = _cfgLocal.StatusMultiline;
//this.Tween_ClientSizeChanged(this, null);
- this.PlaySoundMenuItem.Checked = this._cfgCommon.PlaySound;
- this.PlaySoundFileMenuItem.Checked = this._cfgCommon.PlaySound;
+ this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound;
+ this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound;
//入力欄
StatusText.Font = _fntInputFont;
StatusText.ForeColor = _clInputFont;
// SplitContainer2.Panel2MinSize を一行表示の入力欄の高さに合わせる (MS UI Gothic 12pt (96dpi) の場合は 19px)
- this.StatusText.Multiline = false; // _cfgLocal.StatusMultiline の設定は後で反映される
+ this.StatusText.Multiline = false; // SettingManager.Local.StatusMultiline の設定は後で反映される
this.SplitContainer2.Panel2MinSize = this.StatusText.Height;
// 必要であれば、発言一覧と発言詳細部・入力欄の上下を入れ替える
- SplitContainer1.IsPanelInverted = !this._cfgCommon.StatusAreaAtBottom;
+ SplitContainer1.IsPanelInverted = !SettingManager.Common.StatusAreaAtBottom;
//全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
- if (this._cfgCommon.UnreadManage == false)
+ if (SettingManager.Common.UnreadManage == false)
{
ReadedStripMenuItem.Enabled = false;
UnreadStripMenuItem.Enabled = false;
StatusLabel.AutoToolTip = false;
StatusLabel.ToolTipText = "";
//文字カウンタ初期化
- lblLen.Text = this.GetRestStatusCount(this.FormatStatusText("")).ToString();
+ lblLen.Text = this.GetRestStatusCount(this.FormatStatusTextExtended("")).ToString();
this.JumpReadOpMenuItem.ShortcutKeyDisplayString = "Space";
CopySTOTMenuItem.ShortcutKeyDisplayString = "Ctrl+C";
this.SplitContainer2.Panel2.AccessibleName = "";
////////////////////////////////////////////////////////////////////////////////
- var sortOrder = (SortOrder)_cfgCommon.SortOrder;
+ var sortOrder = (SortOrder)SettingManager.Common.SortOrder;
var mode = ComparerMode.Id;
- switch (_cfgCommon.SortColumn)
+ switch (SettingManager.Common.SortColumn)
{
case 0: //0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク
case 5:
_statuses.SetSortMode(mode, sortOrder);
////////////////////////////////////////////////////////////////////////////////
- ApplyListViewIconSize(this._cfgCommon.IconSize);
+ ApplyListViewIconSize(SettingManager.Common.IconSize);
//<<<<<<<<タブ関連>>>>>>>
// タブの位置を調整する
_curItemIndex = -1;
_curList = (DetailsListView)_curTab.Tag;
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
ListTab.DrawMode = TabDrawMode.Normal;
}
ListTab.ImageList = null;
}
- if (this._cfgCommon.HotkeyEnabled)
+ if (SettingManager.Common.HotkeyEnabled)
{
//////グローバルホットキーの登録
HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
- if ((this._cfgCommon.HotkeyModifier & Keys.Alt) == Keys.Alt)
+ if ((SettingManager.Common.HotkeyModifier & Keys.Alt) == Keys.Alt)
modKey |= HookGlobalHotkey.ModKeys.Alt;
- if ((this._cfgCommon.HotkeyModifier & Keys.Control) == Keys.Control)
+ if ((SettingManager.Common.HotkeyModifier & Keys.Control) == Keys.Control)
modKey |= HookGlobalHotkey.ModKeys.Ctrl;
- if ((this._cfgCommon.HotkeyModifier & Keys.Shift) == Keys.Shift)
+ if ((SettingManager.Common.HotkeyModifier & Keys.Shift) == Keys.Shift)
modKey |= HookGlobalHotkey.ModKeys.Shift;
- if ((this._cfgCommon.HotkeyModifier & Keys.LWin) == Keys.LWin)
+ if ((SettingManager.Common.HotkeyModifier & Keys.LWin) == Keys.LWin)
modKey |= HookGlobalHotkey.ModKeys.Win;
- _hookGlobalHotkey.RegisterOriginalHotkey(this._cfgCommon.HotkeyKey, this._cfgCommon.HotkeyValue, modKey);
+ _hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey);
}
- if (this._cfgCommon.IsUseNotifyGrowl)
+ if (SettingManager.Common.IsUseNotifyGrowl)
gh.RegisterGrowl();
StatusLabel.Text = Properties.Resources.Form1_LoadText1; //画面右下の状態表示を変更
SetMainWindowTitle();
SetNotifyIconText();
- if (!this._cfgCommon.MinimizeToTray || this.WindowState != FormWindowState.Minimized)
+ if (!SettingManager.Common.MinimizeToTray || this.WindowState != FormWindowState.Minimized)
{
this.Visible = true;
}
this.TweenMain_Resize(null, null);
if (saveRequired) SaveConfigsAll(false);
- foreach (var ua in this._cfgCommon.UserAccounts)
+ foreach (var ua in SettingManager.Common.UserAccounts)
{
if (ua.UserId == 0 && ua.Username.ToLowerInvariant() == tw.Username.ToLowerInvariant())
{
private void InitDetailHtmlFormat()
{
- if (this._cfgCommon.IsMonospace)
+ if (SettingManager.Common.IsMonospace)
{
detailHtmlFormatHeader = detailHtmlFormatHeaderMono;
detailHtmlFormatFooter = detailHtmlFormatFooterMono;
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);
- }
- }
-
- _cfgLocal = SettingLocal.Load();
+ SettingManager.Local = SettingManager.Local;
// v1.2.4 以前の設定には ScaleDimension の項目がないため、現在の DPI と同じとして扱う
- if (_cfgLocal.ScaleDimension.IsEmpty)
- _cfgLocal.ScaleDimension = this.CurrentAutoScaleDimensions;
+ if (SettingManager.Local.ScaleDimension.IsEmpty)
+ SettingManager.Local.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)
var refreshTasks = new List<Task>();
////タイマー初期化
- if (ResetTimers.Timeline || homeCounter <= 0 && this._cfgCommon.TimelinePeriod > 0)
+ if (ResetTimers.Timeline || homeCounter <= 0 && SettingManager.Common.TimelinePeriod > 0)
{
- Interlocked.Exchange(ref homeCounter, this._cfgCommon.TimelinePeriod);
+ Interlocked.Exchange(ref homeCounter, SettingManager.Common.TimelinePeriod);
if (!tw.IsUserstreamDataReceived && !ResetTimers.Timeline)
refreshTasks.Add(this.GetHomeTimelineAsync());
ResetTimers.Timeline = false;
}
- if (ResetTimers.Reply || mentionCounter <= 0 && this._cfgCommon.ReplyPeriod > 0)
+ if (ResetTimers.Reply || mentionCounter <= 0 && SettingManager.Common.ReplyPeriod > 0)
{
- Interlocked.Exchange(ref mentionCounter, this._cfgCommon.ReplyPeriod);
+ Interlocked.Exchange(ref mentionCounter, SettingManager.Common.ReplyPeriod);
if (!tw.IsUserstreamDataReceived && !ResetTimers.Reply)
refreshTasks.Add(this.GetReplyAsync());
ResetTimers.Reply = false;
}
- if (ResetTimers.DirectMessage || dmCounter <= 0 && this._cfgCommon.DMPeriod > 0)
+ if (ResetTimers.DirectMessage || dmCounter <= 0 && SettingManager.Common.DMPeriod > 0)
{
- Interlocked.Exchange(ref dmCounter, this._cfgCommon.DMPeriod);
+ Interlocked.Exchange(ref dmCounter, SettingManager.Common.DMPeriod);
if (!tw.IsUserstreamDataReceived && !ResetTimers.DirectMessage)
refreshTasks.Add(this.GetDirectMessagesAsync());
ResetTimers.DirectMessage = false;
}
- if (ResetTimers.PublicSearch || pubSearchCounter <= 0 && this._cfgCommon.PubSearchPeriod > 0)
+ if (ResetTimers.PublicSearch || pubSearchCounter <= 0 && SettingManager.Common.PubSearchPeriod > 0)
{
- Interlocked.Exchange(ref pubSearchCounter, this._cfgCommon.PubSearchPeriod);
+ Interlocked.Exchange(ref pubSearchCounter, SettingManager.Common.PubSearchPeriod);
if (!ResetTimers.PublicSearch)
refreshTasks.Add(this.GetPublicSearchAllAsync());
ResetTimers.PublicSearch = false;
}
- if (ResetTimers.UserTimeline || userTimelineCounter <= 0 && this._cfgCommon.UserTimelinePeriod > 0)
+ if (ResetTimers.UserTimeline || userTimelineCounter <= 0 && SettingManager.Common.UserTimelinePeriod > 0)
{
- Interlocked.Exchange(ref userTimelineCounter, this._cfgCommon.UserTimelinePeriod);
+ Interlocked.Exchange(ref userTimelineCounter, SettingManager.Common.UserTimelinePeriod);
if (!ResetTimers.UserTimeline)
refreshTasks.Add(this.GetUserTimelineAllAsync());
ResetTimers.UserTimeline = false;
}
- if (ResetTimers.Lists || listsCounter <= 0 && this._cfgCommon.ListsPeriod > 0)
+ if (ResetTimers.Lists || listsCounter <= 0 && SettingManager.Common.ListsPeriod > 0)
{
- Interlocked.Exchange(ref listsCounter, this._cfgCommon.ListsPeriod);
+ Interlocked.Exchange(ref listsCounter, SettingManager.Common.ListsPeriod);
if (!ResetTimers.Lists)
refreshTasks.Add(this.GetListTimelineAllAsync());
ResetTimers.Lists = false;
}
- if (ResetTimers.UserStream || usCounter <= 0 && this._cfgCommon.UserstreamPeriod > 0)
+ if (ResetTimers.UserStream || usCounter <= 0 && SettingManager.Common.UserstreamPeriod > 0)
{
- Interlocked.Exchange(ref usCounter, this._cfgCommon.UserstreamPeriod);
+ Interlocked.Exchange(ref usCounter, SettingManager.Common.UserstreamPeriod);
if (this.tw.UserStreamActive)
this.RefreshTimeline();
ResetTimers.UserStream = false;
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();
//更新確定
- PostClass[] notifyPosts;
- string soundFile;
int addCount;
- bool newMentionOrDm;
- bool isDelete;
- addCount = _statuses.SubmitUpdate(out soundFile, out notifyPosts, out newMentionOrDm, out isDelete);
+ addCount = _statuses.SubmitUpdate(out var soundFile, out var notifyPosts,
+ out var newMentionOrDm, out var isDelete);
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 (SettingManager.Common.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>
case ScrollLockMode.FixedToItem:
var topIndex = listScroll.TopItemStatusId != null ? tab.IndexOf(listScroll.TopItemStatusId.Value) : -1;
if (topIndex != -1)
- listView.TopItem = listView.Items[topIndex];
+ {
+ var topItem = listView.Items[topIndex];
+ try
+ {
+ listView.TopItem = topItem;
+ }
+ catch (NullReferenceException)
+ {
+ listView.EnsureVisible(listView.VirtualListSize - 1);
+ listView.EnsureVisible(topIndex);
+ }
+ }
break;
case ScrollLockMode.None:
default:
if (type == MyCommon.EVENTTYPE.None)
return true;
- if (!this._cfgCommon.EventNotifyEnabled)
+ if (!SettingManager.Common.EventNotifyEnabled)
return false;
- return this._cfgCommon.EventNotifyFlag.HasFlag(type);
+ return SettingManager.Common.EventNotifyFlag.HasFlag(type);
}
private bool IsMyEventNotityAsEventType(Twitter.FormattedEvent ev)
if (!ev.IsMe)
return true;
- return this._cfgCommon.IsMyEventNotifyFlag.HasFlag(ev.Eventtype);
+ return SettingManager.Common.IsMyEventNotifyFlag.HasFlag(ev.Eventtype);
}
private bool BalloonRequired(Twitter.FormattedEvent ev)
if (!this.NewPostPopMenuItem.Checked)
{
// 「新着通知が無効でもイベントを通知する」にも該当しない
- if (!this._cfgCommon.ForceEventNotify || ev.Eventtype == MyCommon.EVENTTYPE.None)
+ if (!SettingManager.Common.ForceEventNotify || ev.Eventtype == MyCommon.EVENTTYPE.None)
return false;
}
// 「画面最小化・アイコン時のみバルーンを表示する」が有効
- if (this._cfgCommon.LimitBalloon)
+ if (SettingManager.Common.LimitBalloon)
{
if (this.WindowState != FormWindowState.Minimized && this.Visible && Form.ActiveForm != null)
return false;
private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions)
{
- if (this._cfgCommon.ReadOwnPost)
+ if (SettingManager.Common.ReadOwnPost)
{
if (notifyPosts != null && notifyPosts.Length > 0 && notifyPosts.All(x => x.UserId == tw.UserId))
return;
if (notifyPosts != null && notifyPosts.Length > 0)
{
//Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる
- if (this._cfgCommon.IsUseNotifyGrowl)
+ if (SettingManager.Common.IsUseNotifyGrowl)
{
StringBuilder sb = new StringBuilder();
bool reply = false;
if (post.IsReply && !post.IsExcludeReply) reply = true;
if (post.IsDm) dm = true;
if (sb.Length > 0) sb.Append(System.Environment.NewLine);
- switch (this._cfgCommon.NameBalloon)
+ switch (SettingManager.Common.NameBalloon)
{
case MyCommon.NameBalloonEnum.UserID:
sb.Append(post.ScreenName).Append(" : ");
StringBuilder title = new StringBuilder();
GrowlHelper.NotifyType nt;
- if (this._cfgCommon.DispUsername)
+ if (SettingManager.Common.DispUsername)
{
title.Append(tw.Username);
title.Append(" - ");
if (post.IsReply && !post.IsExcludeReply) reply = true;
if (post.IsDm) dm = true;
if (sb.Length > 0) sb.Append(System.Environment.NewLine);
- switch (this._cfgCommon.NameBalloon)
+ switch (SettingManager.Common.NameBalloon)
{
case MyCommon.NameBalloonEnum.UserID:
sb.Append(post.ScreenName).Append(" : ");
//if (SettingDialog.DispUsername) { NotifyIcon1.BalloonTipTitle = tw.Username + " - "; } else { NotifyIcon1.BalloonTipTitle = ""; }
StringBuilder title = new StringBuilder();
ToolTipIcon ntIcon;
- if (this._cfgCommon.DispUsername)
+ if (SettingManager.Common.DispUsername)
{
title.Append(tw.Username);
title.Append(" - ");
}
//サウンド再生
- if (!_initial && this._cfgCommon.PlaySound && !string.IsNullOrEmpty(soundFile))
+ if (!_initial && SettingManager.Common.PlaySound && !string.IsNullOrEmpty(soundFile))
{
try
{
}
//mentions新着時に画面ブリンク
- if (!_initial && this._cfgCommon.BlinkNewMentions && newMentions && Form.ActiveForm == null)
+ if (!_initial && SettingManager.Common.BlinkNewMentions && newMentions && Form.ActiveForm == null)
{
NativeMethods.FlashMyWindow(this.Handle, NativeMethods.FlashSpecification.FlashTray, 3);
}
//Read:true=既読 false=未読
//未読管理していなかったら既読として扱う
if (!tabInfo.UnreadManage ||
- !this._cfgCommon.UnreadManage) Read = true;
+ !SettingManager.Common.UnreadManage) Read = true;
var listCache = this._listItemCache;
if (listCache == null)
return;
// キャッシュに含まれていないアイテムは対象外
- ListViewItem itm;
- PostClass post;
- if (!listCache.TryGetValue(Index, out itm, out post))
+ if (!listCache.TryGetValue(Index, out var itm, out var post))
return;
ChangeItemStyleRead(Read, itm, post, ((DetailsListView)_curTab.Tag));
cl = _clFav;
else if (Post.RetweetedId != null)
cl = _clRetweet;
- else if (Post.IsOwl && (Post.IsDm || this._cfgCommon.OneWayLove))
+ else if (Post.IsOwl && (Post.IsDm || SettingManager.Common.OneWayLove))
cl = _clOWL;
- else if (Read || !this._cfgCommon.UseUnreadStyle)
+ else if (Read || !SettingManager.Common.UseUnreadStyle)
cl = _clReaded;
else
cl = _clUnread;
if (DList == null || Item.Index == -1)
{
Item.ForeColor = cl;
- if (this._cfgCommon.UseUnreadStyle)
+ if (SettingManager.Common.UseUnreadStyle)
Item.Font = fnt;
}
else
{
DList.Update();
- if (this._cfgCommon.UseUnreadStyle)
+ if (SettingManager.Common.UseUnreadStyle)
DList.ChangeItemFontAndColor(Item.Index, cl, fnt);
else
DList.ChangeItemForeColor(Item.Index, cl);
else if (TargetPost.IsReply)
//自分宛返信
cl = _clAtSelf;
- else if (BasePost.ReplyToList.Contains(TargetPost.ScreenName.ToLowerInvariant()))
+ else if (BasePost.ReplyToList.Any(x => x.Item1 == TargetPost.UserId))
//返信先
cl = _clAtFromTarget;
- else if (TargetPost.ReplyToList.Contains(BasePost.ScreenName.ToLowerInvariant()))
+ else if (TargetPost.ReplyToList.Any(x => x.Item1 == BasePost.UserId))
//その人への返信
cl = _clAtTarget;
else if (TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase))
var inReplyToStatusId = this.inReplyTo?.Item1;
var inReplyToScreenName = this.inReplyTo?.Item2;
- _history[_history.Count - 1] = new PostingStatus(StatusText.Text, inReplyToStatusId, inReplyToScreenName);
+ _history[_history.Count - 1] = new StatusTextHistory(StatusText.Text, inReplyToStatusId, inReplyToScreenName);
- if (this._cfgCommon.Nicoms)
+ if (SettingManager.Common.Nicoms)
{
StatusText.SelectionStart = StatusText.Text.Length;
await UrlConvertAsync(MyCommon.UrlConverter.Nicoms);
StatusText.SelectionStart = StatusText.Text.Length;
CheckReplyTo(StatusText.Text);
- var statusText = this.FormatStatusText(this.StatusText.Text);
+ var status = new PostStatusParams();
+
+ var statusTextCompat = this.FormatStatusText(this.StatusText.Text);
+ if (this.GetRestStatusCount(statusTextCompat) >= 0)
+ {
+ // auto_populate_reply_metadata や attachment_url を使用しなくても 140 字以内に
+ // 収まる場合はこれらのオプションを使用せずに投稿する
+ status.Text = statusTextCompat;
+ status.InReplyToStatusId = this.inReplyTo?.Item1;
+ }
+ else
+ {
+ long[] autoPopulatedUserIds;
+ string attachmentUrl;
+ status.Text = this.FormatStatusTextExtended(this.StatusText.Text, out autoPopulatedUserIds, out attachmentUrl);
+ status.InReplyToStatusId = this.inReplyTo?.Item1;
+
+ status.AttachmentUrl = attachmentUrl;
- if (this.GetRestStatusCount(statusText) < 0)
+ // リプライ先がセットされていても autoPopulatedUserIds が空の場合は auto_populate_reply_metadata を有効にしない
+ // (非公式 RT の場合など)
+ var replyToPost = this.inReplyTo != null ? this._statuses[this.inReplyTo.Item1] : null;
+ if (replyToPost != null && autoPopulatedUserIds.Length != 0)
+ {
+ status.AutoPopulateReplyMetadata = true;
+
+ // ReplyToList のうち autoPopulatedUserIds に含まれていないユーザー ID を抽出
+ status.ExcludeReplyUserIds = replyToPost.ReplyToList.Select(x => x.Item1).Except(autoPopulatedUserIds)
+ .ToArray();
+ }
+ }
+
+ if (this.GetRestStatusCount(status.Text) < 0)
{
// 文字数制限を超えているが強制的に投稿するか
var ret = MessageBox.Show(Properties.Resources.PostLengthOverMessage1, Properties.Resources.PostLengthOverMessage2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
return;
}
- var status = new PostingStatus();
- status.status = statusText;
-
- status.inReplyToId = this.inReplyTo?.Item1;
- status.inReplyToName = this.inReplyTo?.Item2;
+ IMediaUploadService uploadService = null;
+ IMediaItem[] uploadItems = null;
if (ImageSelector.Visible)
{
+ string serviceName;
//画像投稿
- if (!ImageSelector.TryGetSelectedMedia(out status.imageService, out status.mediaItems))
+ if (!ImageSelector.TryGetSelectedMedia(out serviceName, out uploadItems))
return;
+
+ uploadService = this.ImageSelector.GetService(serviceName);
}
this.inReplyTo = null;
StatusText.Text = "";
- _history.Add(new PostingStatus());
+ _history.Add(new StatusTextHistory());
_hisIdx = _history.Count - 1;
- if (!ToolStripFocusLockMenuItem.Checked)
+ if (!SettingManager.Common.FocusLockToStatusText)
((Control)ListTab.SelectedTab.Tag).Focus();
urlUndoBuffer = null;
UrlUndoToolStripMenuItem.Enabled = false; //Undoをできないように設定
await this.OpenUriInBrowserAsync(tmp);
}
- await this.PostMessageAsync(status);
+ await this.PostMessageAsync(status, uploadService, uploadItems);
}
private void EndToolStripMenuItem_Click(object sender, EventArgs e)
private void TweenMain_FormClosing(object sender, FormClosingEventArgs e)
{
- if (!this._cfgCommon.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon._endingFlag == false)
+ if (!SettingManager.Common.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon._endingFlag == false)
{
//_endingFlag=false:フォームの×ボタン
e.Cancel = true;
if (!CheckAccountValid())
throw new WebApiException("Auth error. Check your account");
- PostClass post;
- if (!tab.Posts.TryGetValue(statusId, out post))
+ if (!tab.Posts.TryGetValue(statusId, out var post))
return;
if (post.IsFav)
try
{
- await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId)
- .IgnoreResponse()
- .ConfigureAwait(false);
+ try
+ {
+ await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId)
+ .IgnoreResponse()
+ .ConfigureAwait(false);
+ }
+ catch (TwitterApiException ex)
+ when (ex.ErrorResponse.Errors.All(x => x.Code == TwitterErrorCode.AlreadyFavorited))
+ {
+ // エラーコード 139 のみの場合は成功と見なす
+ }
- if (this._cfgCommon.RestrictFavCheck)
+ if (SettingManager.Common.RestrictFavCheck)
{
var status = await this.twitterApi.StatusesShow(post.RetweetedId ?? post.StatusId)
.ConfigureAwait(false);
throw new WebApiException("NG(Restricted?)");
}
- this._favTimestamps.Add(DateTime.Now);
+ this._favTimestamps.Add(DateTimeUtc.Now);
// TLでも取得済みならfav反映
if (this._statuses.ContainsKey(statusId))
}
// 時速表示用
- var oneHour = DateTime.Now - TimeSpan.FromHours(1);
+ var oneHour = DateTimeUtc.Now - TimeSpan.FromHours(1);
foreach (var i in MyCommon.CountDown(this._favTimestamps.Count - 1, 0))
{
if (this._favTimestamps[i] < oneHour)
}
}
- private async Task PostMessageAsync(PostingStatus status)
+ private async Task PostMessageAsync(PostStatusParams postParams, IMediaUploadService uploadService, IMediaItem[] uploadItems)
{
await this.workerSemaphore.WaitAsync();
{
var progress = new Progress<string>(x => this.StatusLabel.Text = x);
- await this.PostMessageAsyncInternal(progress, this.workerCts.Token, status);
+ await this.PostMessageAsyncInternal(progress, this.workerCts.Token, postParams, uploadService, uploadItems);
}
catch (WebApiException ex)
{
}
}
- private async Task PostMessageAsyncInternal(IProgress<string> p, CancellationToken ct, PostingStatus status)
+ private async Task PostMessageAsyncInternal(IProgress<string> p, CancellationToken ct, PostStatusParams postParams,
+ IMediaUploadService uploadService, IMediaItem[] uploadItems)
{
if (ct.IsCancellationRequested)
return;
{
await Task.Run(async () =>
{
- if (status.mediaItems == null || status.mediaItems.Length == 0)
- {
- await this.tw.PostStatus(status.status, status.inReplyToId)
- .ConfigureAwait(false);
- }
- else
+ var postParamsWithMedia = postParams;
+
+ if (uploadService != null && uploadItems != null && uploadItems.Length > 0)
{
- var service = ImageSelector.GetService(status.imageService);
- await service.PostStatusAsync(status.status, status.inReplyToId, status.mediaItems)
+ postParamsWithMedia = await uploadService.UploadAsync(uploadItems, postParamsWithMedia)
.ConfigureAwait(false);
}
+
+ await this.tw.PostStatus(postParamsWithMedia)
+ .ConfigureAwait(false);
});
p.Report(Properties.Resources.PostWorker_RunWorkerCompletedText4);
p.Report(errMsg);
this._myStatusError = true;
}
+ catch (UnauthorizedAccessException ex)
+ {
+ // アップロード対象のファイルが開けなかった場合など
+ errMsg = $"Err:{ex.Message}(PostMessage)";
+ p.Report(errMsg);
+ this._myStatusError = true;
+ }
finally
{
// 使い終わった MediaItem は破棄する
- if (status.mediaItems != null)
+ if (uploadItems != null)
{
- foreach (var disposableItem in status.mediaItems.OfType<IDisposable>())
+ foreach (var disposableItem in uploadItems.OfType<IDisposable>())
{
disposableItem.Dispose();
}
!errMsg.StartsWith("OK:", StringComparison.Ordinal) &&
!errMsg.StartsWith("Warn:", StringComparison.Ordinal))
{
+ var message = string.Format(Properties.Resources.StatusUpdateFailed, errMsg, postParams.Text);
+
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);
if (ret == DialogResult.Retry)
{
- await this.PostMessageAsync(status);
+ await this.PostMessageAsync(postParams, uploadService, uploadItems);
}
else
{
// 連投モードのときだけEnterイベントが起きないので強制的に背景色を戻す
- if (this.ToolStripFocusLockMenuItem.Checked)
+ if (SettingManager.Common.FocusLockToStatusText)
this.StatusText_Enter(this.StatusText, EventArgs.Empty);
}
return;
}
- this._postTimestamps.Add(DateTime.Now);
+ this._postTimestamps.Add(DateTimeUtc.Now);
- var oneHour = DateTime.Now - TimeSpan.FromHours(1);
+ var oneHour = DateTimeUtc.Now - TimeSpan.FromHours(1);
foreach (var i in MyCommon.CountDown(this._postTimestamps.Count - 1, 0))
{
if (this._postTimestamps[i] < oneHour)
{
this.HashMgr.ClearHashtag();
this.HashStripSplitButton.Text = "#[-]";
+ this.HashTogglePullDownMenuItem.Checked = false;
this.HashToggleMenuItem.Checked = false;
- this.HashToggleToolStripMenuItem.Checked = false;
}
this.SetMainWindowTitle();
- if (this._cfgCommon.PostAndGet)
+ if (SettingManager.Common.PostAndGet)
{
if (this.tw.UserStreamActive)
this.RefreshTimeline();
var progress = new Progress<string>(x => this.StatusLabel.Text = x);
await this.RetweetAsyncInternal(progress, this.workerCts.Token, statusIds);
+
+ if (SettingManager.Common.PostAndGet && !this.tw.UserStreamActive)
+ await this.GetHomeTimelineAsync();
}
catch (WebApiException ex)
{
throw new WebApiException("Auth error. Check your account");
bool read;
- if (!this._cfgCommon.UnreadManage)
+ if (!SettingManager.Common.UnreadManage)
read = true;
else
- read = this._initial && this._cfgCommon.Read;
+ read = this._initial && SettingManager.Common.Read;
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;
p.Report(Properties.Resources.PostWorker_RunWorkerCompletedText4);
- this._postTimestamps.Add(DateTime.Now);
+ this._postTimestamps.Add(DateTimeUtc.Now);
- var oneHour = DateTime.Now - TimeSpan.FromHours(1);
+ var oneHour = DateTimeUtc.Now - TimeSpan.FromHours(1);
foreach (var i in MyCommon.CountDown(this._postTimestamps.Count - 1, 0))
{
if (this._postTimestamps[i] < oneHour)
this._postTimestamps.RemoveAt(i);
}
-
- if (this._cfgCommon.PostAndGet && !this.tw.UserStreamActive)
- await this.GetHomeTimelineAsync();
}
private async Task RefreshFollowerIdsAsync()
private async void MyList_MouseDoubleClick(object sender, MouseEventArgs e)
{
- switch (this._cfgCommon.ListDoubleClickAction)
+ switch (SettingManager.Common.ListDoubleClickAction)
{
case 0:
MakeReplyOrDirectStatus();
private async Task FavoriteChange(bool FavAdd, bool multiFavoriteChangeDialogEnable = true)
{
- TabModel tab;
- if (!this._statuses.Tabs.TryGetValue(this._curTab.Text, out tab))
+ if (!this._statuses.Tabs.TryGetValue(this._curTab.Text, out var tab))
return;
//trueでFavAdd,falseでFavRemove
var listCache = this._listItemCache;
if (listCache != null)
{
- ListViewItem item;
- PostClass post;
- if (listCache.TryGetValue(Index, out item, out post))
+ if (listCache.TryGetValue(Index, out var item, out var post))
return post;
}
/// </summary>
private void SetSortColumn(ComparerMode sortColumn)
{
- if (this._cfgCommon.SortOrderLock)
+ if (SettingManager.Common.SortOrderLock)
return;
this._statuses.ToggleSortOrder(sortColumn);
FavorareMenuItem.Enabled = true;
ShowRelatedStatusesMenuItem.Enabled = true; //PublicSearchの時問題出るかも
- if (_curPost.IsMe)
+ if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId))
{
- ReTweetStripMenuItem.Enabled = false; //公式RTは無効に
- ReTweetUnofficialStripMenuItem.Enabled = true;
- QuoteStripMenuItem.Enabled = true;
- FavoriteRetweetContextMenu.Enabled = false; //公式RTは無効に
- FavoriteRetweetUnofficialContextMenu.Enabled = true;
+ ReTweetStripMenuItem.Enabled = false;
+ ReTweetUnofficialStripMenuItem.Enabled = false;
+ QuoteStripMenuItem.Enabled = false;
+ FavoriteRetweetContextMenu.Enabled = false;
+ FavoriteRetweetUnofficialContextMenu.Enabled = false;
}
else
{
- if (_curPost.IsProtect)
- {
- ReTweetStripMenuItem.Enabled = false;
- ReTweetUnofficialStripMenuItem.Enabled = false;
- QuoteStripMenuItem.Enabled = false;
- FavoriteRetweetContextMenu.Enabled = false;
- FavoriteRetweetUnofficialContextMenu.Enabled = false;
- }
- else
- {
- ReTweetStripMenuItem.Enabled = true;
- ReTweetUnofficialStripMenuItem.Enabled = true;
- QuoteStripMenuItem.Enabled = true;
- FavoriteRetweetContextMenu.Enabled = true;
- FavoriteRetweetUnofficialContextMenu.Enabled = true;
- }
+ ReTweetStripMenuItem.Enabled = true;
+ ReTweetUnofficialStripMenuItem.Enabled = true;
+ QuoteStripMenuItem.Enabled = true;
+ FavoriteRetweetContextMenu.Enabled = true;
+ FavoriteRetweetUnofficialContextMenu.Enabled = true;
}
}
//if (_statuses.Tabs[ListTab.SelectedTab.Text].TabType != MyCommon.TabUsageType.Favorites)
}
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)
}
}
- if (this._cfgCommon.TabIconDisp && tab.UnreadCount == 0)
+ if (SettingManager.Common.TabIconDisp && tab.UnreadCount == 0)
{
if (tabPage.ImageIndex == 0)
tabPage.ImageIndex = -1; // タブアイコン
}
}
- if (!this._cfgCommon.TabIconDisp)
+ if (!SettingManager.Common.TabIconDisp)
this.ListTab.Refresh();
}
}
{
if (_statuses.Tabs[tb.Text].UnreadCount == 0)
{
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
if (tb.ImageIndex == 0) tb.ImageIndex = -1; //タブアイコン
}
}
}
- if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
+ if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
}
private void UnreadStripMenuItem_Click(object sender, EventArgs e)
{
if (_statuses.Tabs[tb.Text].UnreadCount > 0)
{
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
if (tb.ImageIndex == -1) tb.ImageIndex = 0; //タブアイコン
}
}
}
- if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
+ if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
}
private async void RefreshStripMenuItem_Click(object sender, EventArgs e)
{
if (_curTab != null)
{
- TabModel tab;
- if (!this._statuses.Tabs.TryGetValue(this._curTab.Text, out tab))
+ if (!this._statuses.Tabs.TryGetValue(this._curTab.Text, out var tab))
return;
- switch (_statuses.Tabs[_curTab.Text].TabType)
+ switch (tab)
{
- case MyCommon.TabUsageType.Mentions:
+ case MentionsTabModel replyTab:
await this.GetReplyAsync();
break;
- case MyCommon.TabUsageType.DirectMessage:
+ case DirectMessagesTabModel dmTab:
await this.GetDirectMessagesAsync();
break;
- case MyCommon.TabUsageType.Favorites:
+ case FavoritesTabModel favTab:
await this.GetFavoritesAsync();
break;
- //case MyCommon.TabUsageType.Profile:
- //// TODO
- case MyCommon.TabUsageType.PublicSearch:
- var searchTab = (PublicSearchTabModel)tab;
+ case PublicSearchTabModel searchTab:
if (string.IsNullOrEmpty(searchTab.SearchWords)) return;
await this.GetPublicSearchAsync(searchTab);
break;
- case MyCommon.TabUsageType.UserTimeline:
- await this.GetUserTimelineAsync((UserTimelineTabModel)tab);
+ case UserTimelineTabModel userTab:
+ await this.GetUserTimelineAsync(userTab);
break;
- case MyCommon.TabUsageType.Lists:
- var listTab = (ListTimelineTabModel)tab;
+ case ListTimelineTabModel listTab:
if (listTab.ListInfo == null || listTab.ListInfo.Id == 0) return;
await this.GetListTimelineAsync(listTab);
break;
//ページ指定をマイナス1に
if (_curTab != null)
{
- TabModel tab;
- if (!this._statuses.Tabs.TryGetValue(this._curTab.Text, out tab))
+ if (!this._statuses.Tabs.TryGetValue(this._curTab.Text, out var tab))
return;
- switch (_statuses.Tabs[_curTab.Text].TabType)
+ switch (tab)
{
- case MyCommon.TabUsageType.Mentions:
+ case MentionsTabModel replyTab:
await this.GetReplyAsync(loadMore: true);
break;
- case MyCommon.TabUsageType.DirectMessage:
+ case DirectMessagesTabModel dmTab:
await this.GetDirectMessagesAsync(loadMore: true);
break;
- case MyCommon.TabUsageType.Favorites:
+ case FavoritesTabModel favTab:
await this.GetFavoritesAsync(loadMore: true);
break;
- case MyCommon.TabUsageType.Profile:
- //// TODO
- break;
- case MyCommon.TabUsageType.PublicSearch:
- var searchTab = (PublicSearchTabModel)tab;
+ case PublicSearchTabModel searchTab:
if (string.IsNullOrEmpty(searchTab.SearchWords)) return;
await this.GetPublicSearchAsync(searchTab, loadMore: true);
break;
- case MyCommon.TabUsageType.UserTimeline:
- await this.GetUserTimelineAsync((UserTimelineTabModel)tab, loadMore: true);
+ case UserTimelineTabModel userTab:
+ await this.GetUserTimelineAsync(userTab, loadMore: true);
break;
- case MyCommon.TabUsageType.Lists:
- var listTab = (ListTimelineTabModel)tab;
+ case ListTimelineTabModel listTab:
if (listTab.ListInfo == null || listTab.ListInfo.Id == 0) return;
await this.GetListTimelineAsync(listTab, loadMore: true);
break;
settingDialog.tw = this.tw;
settingDialog.twitterApi = this.twitterApi;
- settingDialog.LoadConfig(this._cfgCommon, this._cfgLocal);
+ settingDialog.LoadConfig(SettingManager.Common, SettingManager.Local);
try
{
{
lock (_syncObject)
{
- settingDialog.SaveConfig(this._cfgCommon, this._cfgLocal);
+ settingDialog.SaveConfig(SettingManager.Common, SettingManager.Local);
}
}
}
// 設定画面表示前のユーザー情報
var oldUser = new { tw.AccessToken, tw.AccessTokenSecret, tw.Username, tw.UserId };
- var oldIconSz = this._cfgCommon.IconSize;
+ var oldIconSz = SettingManager.Common.IconSize;
if (ShowSettingDialog() == DialogResult.OK)
{
lock (_syncObject)
{
- tw.RestrictFavCheck = this._cfgCommon.RestrictFavCheck;
- tw.ReadOwnPost = this._cfgCommon.ReadOwnPost;
- ShortUrl.Instance.DisableExpanding = !this._cfgCommon.TinyUrlResolve;
- ShortUrl.Instance.BitlyId = this._cfgCommon.BilyUser;
- ShortUrl.Instance.BitlyKey = this._cfgCommon.BitlyPwd;
- TwitterApiConnection.RestApiHost = this._cfgCommon.TwitterApiHost;
-
- Networking.DefaultTimeout = TimeSpan.FromSeconds(this._cfgCommon.DefaultTimeOut);
- Networking.SetWebProxy(this._cfgLocal.ProxyType,
- this._cfgLocal.ProxyAddress, this._cfgLocal.ProxyPort,
- this._cfgLocal.ProxyUser, this._cfgLocal.ProxyPassword);
- Networking.ForceIPv4 = this._cfgCommon.ForceIPv4;
+ tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck;
+ tw.ReadOwnPost = SettingManager.Common.ReadOwnPost;
+ ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve;
+ ShortUrl.Instance.BitlyAccessToken = SettingManager.Common.BitlyAccessToken;
+ ShortUrl.Instance.BitlyId = SettingManager.Common.BilyUser;
+ ShortUrl.Instance.BitlyKey = SettingManager.Common.BitlyPwd;
+ TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost;
+
+ Networking.DefaultTimeout = TimeSpan.FromSeconds(SettingManager.Common.DefaultTimeOut);
+ Networking.UploadImageTimeout = TimeSpan.FromSeconds(SettingManager.Common.UploadImageTimeout);
+ Networking.SetWebProxy(SettingManager.Local.ProxyType,
+ SettingManager.Local.ProxyAddress, SettingManager.Local.ProxyPort,
+ SettingManager.Local.ProxyUser, SettingManager.Local.ProxyPassword);
+ Networking.ForceIPv4 = SettingManager.Common.ForceIPv4;
ImageSelector.Reset(tw, this.tw.Configuration);
try
{
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
ListTab.DrawItem -= ListTab_DrawItem;
ListTab.DrawMode = TabDrawMode.Normal;
try
{
- if (!this._cfgCommon.UnreadManage)
+ if (!SettingManager.Common.UnreadManage)
{
ReadedStripMenuItem.Enabled = false;
UnreadStripMenuItem.Enabled = false;
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
foreach (TabPage myTab in ListTab.TabPages)
{
// タブの表示位置の決定
SetTabAlignment();
- SplitContainer1.IsPanelInverted = !this._cfgCommon.StatusAreaAtBottom;
+ SplitContainer1.IsPanelInverted = !SettingManager.Common.StatusAreaAtBottom;
var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance;
- imgazyobizinet.Enabled = this._cfgCommon.EnableImgAzyobuziNet;
- imgazyobizinet.DisabledInDM = this._cfgCommon.ImgAzyobuziNetDisabledInDM;
-
- this.PlaySoundMenuItem.Checked = this._cfgCommon.PlaySound;
- this.PlaySoundFileMenuItem.Checked = this._cfgCommon.PlaySound;
- _fntUnread = this._cfgLocal.FontUnread;
- _clUnread = this._cfgLocal.ColorUnread;
- _fntReaded = this._cfgLocal.FontRead;
- _clReaded = this._cfgLocal.ColorRead;
- _clFav = this._cfgLocal.ColorFav;
- _clOWL = this._cfgLocal.ColorOWL;
- _clRetweet = this._cfgLocal.ColorRetweet;
- _fntDetail = this._cfgLocal.FontDetail;
- _clDetail = this._cfgLocal.ColorDetail;
- _clDetailLink = this._cfgLocal.ColorDetailLink;
- _clDetailBackcolor = this._cfgLocal.ColorDetailBackcolor;
- _clSelf = this._cfgLocal.ColorSelf;
- _clAtSelf = this._cfgLocal.ColorAtSelf;
- _clTarget = this._cfgLocal.ColorTarget;
- _clAtTarget = this._cfgLocal.ColorAtTarget;
- _clAtFromTarget = this._cfgLocal.ColorAtFromTarget;
- _clAtTo = this._cfgLocal.ColorAtTo;
- _clListBackcolor = this._cfgLocal.ColorListBackcolor;
- _clInputBackcolor = this._cfgLocal.ColorInputBackcolor;
- _clInputFont = this._cfgLocal.ColorInputFont;
- _fntInputFont = this._cfgLocal.FontInputFont;
+ imgazyobizinet.Enabled = SettingManager.Common.EnableImgAzyobuziNet;
+ imgazyobizinet.DisabledInDM = SettingManager.Common.ImgAzyobuziNetDisabledInDM;
+
+ this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound;
+ this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound;
+ _fntUnread = SettingManager.Local.FontUnread;
+ _clUnread = SettingManager.Local.ColorUnread;
+ _fntReaded = SettingManager.Local.FontRead;
+ _clReaded = SettingManager.Local.ColorRead;
+ _clFav = SettingManager.Local.ColorFav;
+ _clOWL = SettingManager.Local.ColorOWL;
+ _clRetweet = SettingManager.Local.ColorRetweet;
+ _fntDetail = SettingManager.Local.FontDetail;
+ _clDetail = SettingManager.Local.ColorDetail;
+ _clDetailLink = SettingManager.Local.ColorDetailLink;
+ _clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor;
+ _clSelf = SettingManager.Local.ColorSelf;
+ _clAtSelf = SettingManager.Local.ColorAtSelf;
+ _clTarget = SettingManager.Local.ColorTarget;
+ _clAtTarget = SettingManager.Local.ColorAtTarget;
+ _clAtFromTarget = SettingManager.Local.ColorAtFromTarget;
+ _clAtTo = SettingManager.Local.ColorAtTo;
+ _clListBackcolor = SettingManager.Local.ColorListBackcolor;
+ _clInputBackcolor = SettingManager.Local.ColorInputBackcolor;
+ _clInputFont = SettingManager.Local.ColorInputFont;
+ _fntInputFont = SettingManager.Local.FontInputFont;
_brsBackColorMine.Dispose();
_brsBackColorAt.Dispose();
_brsBackColorYou.Dispose();
{
foreach (TabPage tb in ListTab.TabPages)
{
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
if (_statuses.Tabs[tb.Text].UnreadCount == 0)
tb.ImageIndex = -1;
{
var oldIconCol = _iconCol;
- if (this._cfgCommon.IconSize != oldIconSz)
- ApplyListViewIconSize(this._cfgCommon.IconSize);
+ if (SettingManager.Common.IconSize != oldIconSz)
+ ApplyListViewIconSize(SettingManager.Common.IconSize);
foreach (TabPage tp in ListTab.TabPages)
{
using (ControlTransaction.Update(lst))
{
- lst.GridLines = this._cfgCommon.ShowGrid;
+ lst.GridLines = SettingManager.Common.ShowGrid;
lst.Font = _fntReaded;
lst.BackColor = _clListBackcolor;
ListTab.Refresh();
_hookGlobalHotkey.UnregisterAllOriginalHotkey();
- if (this._cfgCommon.HotkeyEnabled)
+ if (SettingManager.Common.HotkeyEnabled)
{
///グローバルホットキーの登録。設定で変更可能にするかも
HookGlobalHotkey.ModKeys modKey = HookGlobalHotkey.ModKeys.None;
- if ((this._cfgCommon.HotkeyModifier & Keys.Alt) == Keys.Alt)
+ if ((SettingManager.Common.HotkeyModifier & Keys.Alt) == Keys.Alt)
modKey |= HookGlobalHotkey.ModKeys.Alt;
- if ((this._cfgCommon.HotkeyModifier & Keys.Control) == Keys.Control)
+ if ((SettingManager.Common.HotkeyModifier & Keys.Control) == Keys.Control)
modKey |= HookGlobalHotkey.ModKeys.Ctrl;
- if ((this._cfgCommon.HotkeyModifier & Keys.Shift) == Keys.Shift)
+ if ((SettingManager.Common.HotkeyModifier & Keys.Shift) == Keys.Shift)
modKey |= HookGlobalHotkey.ModKeys.Shift;
- if ((this._cfgCommon.HotkeyModifier & Keys.LWin) == Keys.LWin)
+ if ((SettingManager.Common.HotkeyModifier & Keys.LWin) == Keys.LWin)
modKey |= HookGlobalHotkey.ModKeys.Win;
- _hookGlobalHotkey.RegisterOriginalHotkey(this._cfgCommon.HotkeyKey, this._cfgCommon.HotkeyValue, modKey);
+ _hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey);
}
- if (this._cfgCommon.IsUseNotifyGrowl) gh.RegisterGrowl();
+ if (SettingManager.Common.IsUseNotifyGrowl) gh.RegisterGrowl();
try
{
StatusText_TextChanged(null, null);
Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid;
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
SaveConfigsAll(false);
if (tw.Username != oldUser.Username)
/// </summary>
private void SetTabAlignment()
{
- var newAlignment = this._cfgCommon.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top;
+ var newAlignment = SettingManager.Common.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top;
if (ListTab.Alignment == newAlignment) return;
// 各タブのリスト上の選択位置などを退避
_listCustom.Font = _fntReaded;
_listCustom.BackColor = _clListBackcolor;
- _listCustom.GridLines = this._cfgCommon.ShowGrid;
+ _listCustom.GridLines = SettingManager.Common.ShowGrid;
_listCustom.AllowDrop = true;
_listCustom.SmallImageList = _listViewImageList;
{
//タブのD&D
- if (!this._cfgCommon.TabMouseLock && e.Button == MouseButtons.Left && _tabDrag)
+ if (!SettingManager.Common.TabMouseLock && e.Button == MouseButtons.Left && _tabDrag)
{
string tn = "";
Rectangle dragEnableRectangle = new Rectangle(_tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2), _tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height);
{
if (e.KeyChar == '@')
{
- if (!this._cfgCommon.UseAtIdSupplement) return;
+ if (!SettingManager.Common.UseAtIdSupplement) return;
//@マーク
int cnt = AtIdSupl.ItemCount;
ShowSuplDialog(StatusText, AtIdSupl);
}
else if (e.KeyChar == '#')
{
- if (!this._cfgCommon.UseHashSupplement) return;
+ if (!SettingManager.Common.UseHashSupplement) return;
ShowSuplDialog(StatusText, HashSupl);
e.Handled = true;
}
{
dialog.ShowDialog();
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
int selStart = owner.SelectionStart;
string fHalf = "";
string eHalf = "";
private void StatusText_TextChanged(object sender, EventArgs e)
{
//文字数カウント
- int pLen = this.GetRestStatusCount(this.FormatStatusText(this.StatusText.Text));
+ int pLen = this.GetRestStatusCount(this.FormatStatusTextExtended(this.StatusText.Text));
lblLen.Text = pLen.ToString();
if (pLen < 0)
{
{
StatusText.ForeColor = _clInputFont;
}
+
+ this.StatusText.AccessibleDescription = string.Format(Properties.Resources.StatusText_AccessibleDescription, pLen);
+
if (string.IsNullOrEmpty(StatusText.Text))
{
this.inReplyTo = null;
}
/// <summary>
+ /// 投稿時に auto_populate_reply_metadata オプションによって自動で追加されるメンションを除去します
+ /// </summary>
+ private string RemoveAutoPopuratedMentions(string statusText, out long[] autoPopulatedUserIds)
+ {
+ List<long> _autoPopulatedUserIds = new List<long>();
+
+ var replyToPost = this.inReplyTo != null ? this._statuses[this.inReplyTo.Item1] : null;
+ if (replyToPost != null)
+ {
+ if (statusText.StartsWith($"@{replyToPost.ScreenName} ", StringComparison.Ordinal))
+ {
+ statusText = statusText.Substring(replyToPost.ScreenName.Length + 2);
+ _autoPopulatedUserIds.Add(replyToPost.UserId);
+
+ foreach (var reply in replyToPost.ReplyToList)
+ {
+ if (statusText.StartsWith($"@{reply.Item2} ", StringComparison.Ordinal))
+ {
+ statusText = statusText.Substring(reply.Item2.Length + 2);
+ _autoPopulatedUserIds.Add(reply.Item1);
+ }
+ }
+ }
+ }
+
+ autoPopulatedUserIds = _autoPopulatedUserIds.ToArray();
+
+ return statusText;
+ }
+
+ /// <summary>
+ /// attachment_url に指定可能な URL が含まれていれば除去
+ /// </summary>
+ private string RemoveAttachmentUrl(string statusText, out string attachmentUrl)
+ {
+ attachmentUrl = null;
+
+ // attachment_url は media_id と同時に使用できない
+ if (this.ImageSelector.Visible && this.ImageSelector.SelectedService is TwitterPhoto)
+ return statusText;
+
+ var match = Twitter.AttachmentUrlRegex.Match(statusText);
+ if (!match.Success)
+ return statusText;
+
+ attachmentUrl = match.Value;
+
+ // マッチした URL を空白に置換
+ statusText = statusText.Substring(0, match.Index);
+
+ // テキストと URL の間にスペースが含まれていれば除去
+ return statusText.TrimEnd(' ');
+ }
+
+ private string FormatStatusTextExtended(string statusText)
+ {
+ long[] autoPopulatedUserIds;
+ string attachmentUrl;
+
+ return this.FormatStatusTextExtended(statusText, out autoPopulatedUserIds, out attachmentUrl);
+ }
+
+ /// <summary>
+ /// <see cref="FormatStatusText"/> に加えて、拡張モードで140字にカウントされない文字列の除去を行います
+ /// </summary>
+ private string FormatStatusTextExtended(string statusText, out long[] autoPopulatedUserIds, out string attachmentUrl)
+ {
+ statusText = this.RemoveAutoPopuratedMentions(statusText, out autoPopulatedUserIds);
+
+ statusText = this.RemoveAttachmentUrl(statusText, out attachmentUrl);
+
+ return this.FormatStatusText(statusText);
+ }
+
+ /// <summary>
/// ツイート投稿前のフッター付与などの前処理を行います
/// </summary>
private string FormatStatusText(string statusText)
{
statusText = statusText.Replace("\r\n", "\n");
- if (this.ToolStripMenuItemUrlMultibyteSplit.Checked)
+ if (this.urlMultibyteSplit)
{
// URLと全角文字の切り離し
statusText = Regex.Replace(statusText, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+", "$& ");
}
- if (this.IdeographicSpaceToSpaceToolStripMenuItem.Checked)
+ if (SettingManager.Common.WideSpaceConvert)
{
// 文中の全角スペースを半角スペース1個にする
statusText = statusText.Replace(" ", " ");
return statusText;
bool disableFooter;
- if (this._cfgCommon.PostShiftEnter)
+ if (SettingManager.Common.PostShiftEnter)
{
disableFooter = MyCommon.IsKeyDown(Keys.Control);
}
else
{
- if (this.StatusText.Multiline && !this._cfgCommon.PostCtrlEnter)
+ if (this.StatusText.Multiline && !SettingManager.Common.PostCtrlEnter)
disableFooter = MyCommon.IsKeyDown(Keys.Control);
else
disableFooter = MyCommon.IsKeyDown(Keys.Shift);
if (statusText.Contains("RT @"))
disableFooter = true;
+ // 自分宛のリプライの場合は先頭の「@screen_name 」の部分を除去する (in_reply_to_status_id は維持される)
+ if (this.inReplyTo != null && this.inReplyTo.Item2 == this.tw.Username)
+ {
+ var mentionSelf = $"@{this.tw.Username} ";
+ if (statusText.StartsWith(mentionSelf, StringComparison.OrdinalIgnoreCase))
+ {
+ if (statusText.Length > mentionSelf.Length || this.GetSelectedImageService() != null)
+ statusText = statusText.Substring(mentionSelf.Length);
+ }
+ }
+
var header = "";
var footer = "";
if (!disableFooter)
{
- if (this._cfgLocal.UseRecommendStatus)
+ if (SettingManager.Local.UseRecommendStatus)
{
// 推奨ステータスを使用する
footer += this.recommendedStatusFooter;
}
- else if (!string.IsNullOrEmpty(this._cfgLocal.StatusText))
+ else if (!string.IsNullOrEmpty(SettingManager.Local.StatusText))
{
// テキストボックスに入力されている文字列を使用する
- footer += " " + this._cfgLocal.StatusText.Trim();
+ footer += " " + SettingManager.Local.StatusText.Trim();
}
}
statusText = header + statusText + footer;
- if (this.ToolStripMenuItemPreventSmsCommand.Checked)
+ if (this.preventSmsCommand)
{
// ツイートが意図せず SMS コマンドとして解釈されることを回避 (D, DM, M のみ)
// 参照: https://support.twitter.com/articles/14020
/// </summary>
private int GetRestStatusCount(string statusText)
{
- //文字数カウント
var remainCount = this.tw.GetTextLengthRemain(statusText);
- if (this.ImageSelector.Visible && !string.IsNullOrEmpty(this.ImageSelector.ServiceName))
+ var uploadService = this.GetSelectedImageService();
+ if (uploadService != null)
{
- remainCount -= this.tw.Configuration.CharactersReservedPerMedia;
+ // TODO: ImageSelector で選択中の画像の枚数が mediaCount 引数に渡るようにする
+ remainCount -= uploadService.GetReservedTextLength(1);
}
return remainCount;
}
+ private IMediaUploadService GetSelectedImageService()
+ => this.ImageSelector.Visible ? this.ImageSelector.SelectedService : null;
+
private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
{
if (sender != this._curList)
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;
- if (listCache.TryGetValue(e.ItemIndex, out item, out cacheItemPost))
+ if (listCache.TryGetValue(e.ItemIndex, out var item, out var cacheItemPost))
{
e.Item = item;
return;
if (tabInfo.AllCount == 0)
return;
+ // インデックスを 0...(tabInfo.AllCount - 1) の範囲内にする
+ int FilterRange(int index)
+ => Math.Max(Math.Min(index, tabInfo.AllCount - 1), 0);
+
// キャッシュ要求(要求範囲±30を作成)
- startIndex = Math.Max(startIndex - 30, 0);
- endIndex = Math.Min(endIndex + 30, tabInfo.AllCount - 1);
+ startIndex = FilterRange(startIndex - 30);
+ endIndex = FilterRange(endIndex + 30);
var cacheLength = endIndex - startIndex + 1;
{
string[] sitem= {"",
Post.Nickname,
- Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
- Post.CreatedAt.ToString(this._cfgCommon.DateTimeFormat),
+ Post.IsDeleted ? "(DELETED)" : Post.AccessibleText.Replace('\n', ' '),
+ Post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat),
Post.ScreenName,
"",
mk.ToString(),
{
string[] sitem = {"",
Post.Nickname,
- Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
- Post.CreatedAt.ToString(this._cfgCommon.DateTimeFormat),
+ Post.IsDeleted ? "(DELETED)" : Post.AccessibleText.Replace('\n', ' '),
+ Post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat),
Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
"",
mk.ToString(),
itm = new ImageListViewItem(sitem, this.IconCache, Post.ImageUrl);
}
itm.StateIndex = Post.StateIndex;
+ itm.Tag = Post;
bool read = Post.IsRead;
//未読管理していなかったら既読として扱う
- if (!_statuses.Tabs[Tab.Text].UnreadManage || !this._cfgCommon.UnreadManage) read = true;
+ if (!_statuses.Tabs[Tab.Text].UnreadManage || !SettingManager.Common.UnreadManage) read = true;
ChangeItemStyleRead(read, itm, Post, null);
if (Tab.Equals(_curTab)) ColorizeList(itm, Index);
return itm;
listview.VirtualListSize = tab.AllCount;
}
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
if (tab.UnreadCount > 0)
tabPage.ImageIndex = 0;
}
}
- if (!this._cfgCommon.TabIconDisp)
+ if (!SettingManager.Common.TabIconDisp)
this.ListTab.Refresh();
SetMainWindowTitle();
if (e.ColumnIndex > 0)
{
//アイコン以外の列
+ var post = (PostClass)e.Item.Tag;
+
RectangleF rct = e.Bounds;
rct.Width = e.Header.Width;
int fontHeight = e.Item.Font.Height;
rct.Height -= fontHeight;
}
- int heightDiff;
- int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out heightDiff));
+ int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out var heightDiff));
//if (heightDiff > fontHeight * 0.7)
//{
using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
{
TextRenderer.DrawText(e.Graphics,
- e.Item.SubItems[2].Text,
+ post.IsDeleted ? "(DELETED)" : post.TextSingleLine,
e.Item.Font,
Rectangle.Round(rct),
color,
TextFormatFlags.NoPrefix);
}
}
- else if (drawLineCount == 1)
- {
- TextRenderer.DrawText(e.Graphics,
- e.SubItem.Text,
- e.Item.Font,
- Rectangle.Round(rct),
- color,
- TextFormatFlags.SingleLine |
- TextFormatFlags.EndEllipsis |
- TextFormatFlags.GlyphOverhangPadding |
- TextFormatFlags.NoPrefix |
- TextFormatFlags.VerticalCenter);
- }
else
{
- TextRenderer.DrawText(e.Graphics,
- e.SubItem.Text,
- 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);
}
{
if (this.SearchDialog.ShowDialog(this) != DialogResult.OK)
{
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
return;
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
var searchOptions = this.SearchDialog.ResultOptions;
if (searchOptions.Type == SearchWordDialog.SearchType.Timeline)
{
about.ShowDialog(this);
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
}
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();
}
_colorize = false;
await this.DispSelectedPost();
//件数関連の場合、タイトル即時書き換え
- if (this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.None &&
- this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.Post &&
- this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
- this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
+ if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None &&
+ SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post &&
+ SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
+ SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
{
SetMainWindowTitle();
}
{
if (_statuses.Tabs[tb.Text].UnreadCount == 0)
{
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
if (tb.ImageIndex == 0) tb.ImageIndex = -1;
}
}
}
- if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
+ if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
}
public string createDetailHtml(string orgdata)
{
- if (this._cfgLocal.UseTwemoji)
+ if (SettingManager.Local.UseTwemoji)
orgdata = EmojiFormatter.ReplaceEmojiToImg(orgdata);
return detailHtmlFormatHeader + orgdata + detailHtmlFormatFooter;
this.SplitContainer3.Panel2Collapsed = true;
- if (this._cfgCommon.PreviewEnable)
+ if (SettingManager.Common.PreviewEnable)
{
var oldTokenSource = Interlocked.Exchange(ref this.thumbnailTokenSource, new CancellationTokenSource());
oldTokenSource?.Cancel();
if (e.Control || e.Shift || e.Alt)
this._anchorFlag = false;
- Task asyncTask;
- if (CommonKeyDown(e.KeyData, FocusedControl.ListTab, out asyncTask))
+ if (CommonKeyDown(e.KeyData, FocusedControl.ListTab, out var asyncTask))
{
e.Handled = true;
e.SuppressKeyPress = true;
{
var inReplyToStatusId = this.inReplyTo?.Item1;
var inReplyToScreenName = this.inReplyTo?.Item2;
- _history[_hisIdx] = new PostingStatus(StatusText.Text, inReplyToStatusId, inReplyToScreenName);
+ _history[_hisIdx] = new StatusTextHistory(StatusText.Text, inReplyToStatusId, inReplyToScreenName);
}
_hisIdx -= 1;
if (_hisIdx < 0) _hisIdx = 0;
var historyItem = this._history[this._hisIdx];
- StatusText.Text = historyItem.status;
- StatusText.SelectionStart = StatusText.Text.Length;
if (historyItem.inReplyToId != null)
this.inReplyTo = Tuple.Create(historyItem.inReplyToId.Value, historyItem.inReplyToName);
else
this.inReplyTo = null;
+ StatusText.Text = historyItem.status;
+ StatusText.SelectionStart = StatusText.Text.Length;
}),
ShortcutCommand.Create(Keys.Control | Keys.Down)
{
var inReplyToStatusId = this.inReplyTo?.Item1;
var inReplyToScreenName = this.inReplyTo?.Item2;
- _history[_hisIdx] = new PostingStatus(StatusText.Text, inReplyToStatusId, inReplyToScreenName);
+ _history[_hisIdx] = new StatusTextHistory(StatusText.Text, inReplyToStatusId, inReplyToScreenName);
}
_hisIdx += 1;
if (_hisIdx > _history.Count - 1) _hisIdx = _history.Count - 1;
var historyItem = this._history[this._hisIdx];
- StatusText.Text = historyItem.status;
- StatusText.SelectionStart = StatusText.Text.Length;
if (historyItem.inReplyToId != null)
this.inReplyTo = Tuple.Create(historyItem.inReplyToId.Value, historyItem.inReplyToName);
else
this.inReplyTo = null;
+ StatusText.Text = historyItem.status;
+ StatusText.SelectionStart = StatusText.Text.Length;
}),
ShortcutCommand.Create(Keys.Control | Keys.PageUp, Keys.Control | Keys.P)
ShortcutCommand.Create(Keys.Control | Keys.Y)
.FocusedOn(FocusedControl.PostBrowser)
.Do(() => {
- MultiLineMenuItem.Checked = !MultiLineMenuItem.Checked;
- MultiLineMenuItem_Click(null, null);
+ var multiline = !SettingManager.Local.StatusMultiline;
+ SettingManager.Local.StatusMultiline = multiline;
+ MultiLineMenuItem.Checked = multiline;
+ MultiLineMenuItem_Click(this.MultiLineMenuItem, EventArgs.Empty);
}),
ShortcutCommand.Create(Keys.Shift | Keys.F3)
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;
+
+ var tab = this._statuses.Tabs[this._curTab.Text];
- if (_statuses.Tabs[_curTab.Text].TabType == MyCommon.TabUsageType.DirectMessage) return; // Directタブは対象外(見つかるはずがない)
- if (_curList.SelectedIndices.Count == 0) return; //未選択も処理しない
+ // Directタブは対象外(見つかるはずがない)
+ if (tab.TabType == MyCommon.TabUsageType.DirectMessage)
+ return;
+
+ var selectedIndex = this._curList.SelectedIndices[0];
+ var selectedStatusId = tab.GetStatusIdAt(selectedIndex);
- targetId = GetCurTabPost(_curList.SelectedIndices[0]).StatusId;
+ 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 ||
(!string.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == _anchorPost.RetweetedBy) ||
- _anchorPost.ReplyToList.Contains(post.ScreenName.ToLowerInvariant()) ||
- _anchorPost.ReplyToList.Contains(post.RetweetedBy.ToLowerInvariant()) ||
- post.ReplyToList.Contains(_anchorPost.ScreenName.ToLowerInvariant()) ||
- post.ReplyToList.Contains(_anchorPost.RetweetedBy.ToLowerInvariant()))
+ _anchorPost.ReplyToList.Any(x => x.Item1 == post.UserId) ||
+ _anchorPost.ReplyToList.Any(x => x.Item1 == post.RetweetedByUserId) ||
+ post.ReplyToList.Any(x => x.Item1 == _anchorPost.UserId) ||
+ post.ReplyToList.Any(x => x.Item1 == _anchorPost.RetweetedByUserId))
{
SelectListItem(_curList, idx);
_curList.EnsureVisible(idx);
try
{
this.selectPostChains.Pop();
- var tabPostPair = this.selectPostChains.Peek();
+ var (tabPage, post) = this.selectPostChains.Peek();
- if (!this.ListTab.TabPages.Contains(tabPostPair.Item1)) continue; //該当タブが存在しないので無視
+ if (!this.ListTab.TabPages.Contains(tabPage)) continue; //該当タブが存在しないので無視
- if (tabPostPair.Item2 != null)
+ if (post != null)
{
- idx = this._statuses.Tabs[tabPostPair.Item1.Text].IndexOf(tabPostPair.Item2.StatusId);
+ idx = this._statuses.Tabs[tabPage.Text].IndexOf(post.StatusId);
if (idx == -1) continue; //該当ポストが存在しないので無視
}
- tp = tabPostPair.Item1;
+ tp = tabPage;
this.selectPostChains.Pop();
}
int count = this.selectPostChains.Count;
if (count > 0)
{
- var p = this.selectPostChains.Peek();
- if (p.Item1 == this._curTab)
+ var (tabPage, post) = this.selectPostChains.Peek();
+ if (tabPage == this._curTab)
{
- if (p.Item2 == this._curPost) return; //最新の履歴と同一
- if (p.Item2 == null) this.selectPostChains.Pop(); //置き換えるため削除
+ if (post == this._curPost) return; //最新の履歴と同一
+ if (post == null) this.selectPostChains.Pop(); //置き換えるため削除
}
}
if (count >= 2500) TrimPostChain();
- this.selectPostChains.Push(Tuple.Create(this._curTab, this._curPost));
+ this.selectPostChains.Push((this._curTab, this._curPost));
}
private void TrimPostChain()
{
if (this.selectPostChains.Count <= 2000) return;
- var p = new Stack<Tuple<TabPage, PostClass>>(2000);
+ var p = new Stack<ValueTuple<TabPage, PostClass>>(2000);
for (int i = 0; i < 2000; i++)
{
p.Push(this.selectPostChains.Pop());
public Color InputBackColor
{
- get { return _clInputBackcolor; }
- set { _clInputBackcolor = value; }
+ get => _clInputBackcolor;
+ set => _clInputBackcolor = value;
}
private void StatusText_Leave(object sender, EventArgs e)
private async void StatusText_KeyDown(object sender, KeyEventArgs e)
{
- Task asyncTask;
- if (CommonKeyDown(e.KeyData, FocusedControl.StatusText, out asyncTask))
+ if (CommonKeyDown(e.KeyData, FocusedControl.StatusText, out var asyncTask))
{
e.Handled = true;
e.SuppressKeyPress = true;
private void SaveConfigsAtId()
{
- if (_ignoreConfigSave || !this._cfgCommon.UseAtIdSupplement && AtIdSupl == null) return;
+ if (_ignoreConfigSave || !SettingManager.Common.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()
ModifySettingCommon = false;
lock (_syncObject)
{
- _cfgCommon.UserName = tw.Username;
- _cfgCommon.UserId = tw.UserId;
- _cfgCommon.Token = tw.AccessToken;
- _cfgCommon.TokenSecret = tw.AccessTokenSecret;
-
- if (IdeographicSpaceToSpaceToolStripMenuItem != null &&
- IdeographicSpaceToSpaceToolStripMenuItem.IsDisposed == false)
- {
- _cfgCommon.WideSpaceConvert = this.IdeographicSpaceToSpaceToolStripMenuItem.Checked;
- }
-
- _cfgCommon.SortOrder = (int)_statuses.SortOrder;
+ SettingManager.Common.UserName = tw.Username;
+ SettingManager.Common.UserId = tw.UserId;
+ SettingManager.Common.Token = tw.AccessToken;
+ SettingManager.Common.TokenSecret = tw.AccessTokenSecret;
+ SettingManager.Common.SortOrder = (int)_statuses.SortOrder;
switch (_statuses.SortMode)
{
case ComparerMode.Nickname: //ニックネーム
- _cfgCommon.SortColumn = 1;
+ SettingManager.Common.SortColumn = 1;
break;
case ComparerMode.Data: //本文
- _cfgCommon.SortColumn = 2;
+ SettingManager.Common.SortColumn = 2;
break;
case ComparerMode.Id: //時刻=発言Id
- _cfgCommon.SortColumn = 3;
+ SettingManager.Common.SortColumn = 3;
break;
case ComparerMode.Name: //名前
- _cfgCommon.SortColumn = 4;
+ SettingManager.Common.SortColumn = 4;
break;
case ComparerMode.Source: //Source
- _cfgCommon.SortColumn = 7;
+ SettingManager.Common.SortColumn = 7;
break;
}
- _cfgCommon.HashTags = HashMgr.HashHistories;
+ SettingManager.Common.HashTags = HashMgr.HashHistories;
if (HashMgr.IsPermanent)
{
- _cfgCommon.HashSelected = HashMgr.UseHash;
+ SettingManager.Common.HashSelected = HashMgr.UseHash;
}
else
{
- _cfgCommon.HashSelected = "";
- }
- _cfgCommon.HashIsHead = HashMgr.IsHead;
- _cfgCommon.HashIsPermanent = HashMgr.IsPermanent;
- _cfgCommon.HashIsNotAddToAtReply = HashMgr.IsNotAddToAtReply;
- if (ToolStripFocusLockMenuItem != null &&
- ToolStripFocusLockMenuItem.IsDisposed == false)
- {
- _cfgCommon.FocusLockToStatusText = this.ToolStripFocusLockMenuItem.Checked;
+ SettingManager.Common.HashSelected = "";
}
- _cfgCommon.TrackWord = tw.TrackWord;
- _cfgCommon.AllAtReply = tw.AllAtReply;
- _cfgCommon.UseImageService = ImageSelector.ServiceIndex;
- _cfgCommon.UseImageServiceName = ImageSelector.ServiceName;
+ SettingManager.Common.HashIsHead = HashMgr.IsHead;
+ SettingManager.Common.HashIsPermanent = HashMgr.IsPermanent;
+ SettingManager.Common.HashIsNotAddToAtReply = HashMgr.IsNotAddToAtReply;
+ SettingManager.Common.TrackWord = tw.TrackWord;
+ SettingManager.Common.AllAtReply = tw.AllAtReply;
+ SettingManager.Common.UseImageService = ImageSelector.ServiceIndex;
+ SettingManager.Common.UseImageServiceName = ImageSelector.ServiceName;
- _cfgCommon.Save();
+ SettingManager.SaveCommon();
}
}
lock (_syncObject)
{
ModifySettingLocal = false;
- _cfgLocal.ScaleDimension = this.CurrentAutoScaleDimensions;
- _cfgLocal.FormSize = _mySize;
- _cfgLocal.FormLocation = _myLoc;
- _cfgLocal.SplitterDistance = _mySpDis;
- _cfgLocal.PreviewDistance = _mySpDis3;
- _cfgLocal.StatusMultiline = StatusText.Multiline;
- _cfgLocal.StatusTextHeight = _mySpDis2;
-
- _cfgLocal.FontUnread = _fntUnread;
- _cfgLocal.ColorUnread = _clUnread;
- _cfgLocal.FontRead = _fntReaded;
- _cfgLocal.ColorRead = _clReaded;
- _cfgLocal.FontDetail = _fntDetail;
- _cfgLocal.ColorDetail = _clDetail;
- _cfgLocal.ColorDetailBackcolor = _clDetailBackcolor;
- _cfgLocal.ColorDetailLink = _clDetailLink;
- _cfgLocal.ColorFav = _clFav;
- _cfgLocal.ColorOWL = _clOWL;
- _cfgLocal.ColorRetweet = _clRetweet;
- _cfgLocal.ColorSelf = _clSelf;
- _cfgLocal.ColorAtSelf = _clAtSelf;
- _cfgLocal.ColorTarget = _clTarget;
- _cfgLocal.ColorAtTarget = _clAtTarget;
- _cfgLocal.ColorAtFromTarget = _clAtFromTarget;
- _cfgLocal.ColorAtTo = _clAtTo;
- _cfgLocal.ColorListBackcolor = _clListBackcolor;
- _cfgLocal.ColorInputBackcolor = _clInputBackcolor;
- _cfgLocal.ColorInputFont = _clInputFont;
- _cfgLocal.FontInputFont = _fntInputFont;
+ SettingManager.Local.ScaleDimension = this.CurrentAutoScaleDimensions;
+ SettingManager.Local.FormSize = _mySize;
+ SettingManager.Local.FormLocation = _myLoc;
+ SettingManager.Local.SplitterDistance = _mySpDis;
+ SettingManager.Local.PreviewDistance = _mySpDis3;
+ SettingManager.Local.StatusMultiline = StatusText.Multiline;
+ SettingManager.Local.StatusTextHeight = _mySpDis2;
+
+ SettingManager.Local.FontUnread = _fntUnread;
+ SettingManager.Local.ColorUnread = _clUnread;
+ SettingManager.Local.FontRead = _fntReaded;
+ SettingManager.Local.ColorRead = _clReaded;
+ SettingManager.Local.FontDetail = _fntDetail;
+ SettingManager.Local.ColorDetail = _clDetail;
+ SettingManager.Local.ColorDetailBackcolor = _clDetailBackcolor;
+ SettingManager.Local.ColorDetailLink = _clDetailLink;
+ SettingManager.Local.ColorFav = _clFav;
+ SettingManager.Local.ColorOWL = _clOWL;
+ SettingManager.Local.ColorRetweet = _clRetweet;
+ SettingManager.Local.ColorSelf = _clSelf;
+ SettingManager.Local.ColorAtSelf = _clAtSelf;
+ SettingManager.Local.ColorTarget = _clTarget;
+ SettingManager.Local.ColorAtTarget = _clAtTarget;
+ SettingManager.Local.ColorAtFromTarget = _clAtFromTarget;
+ SettingManager.Local.ColorAtTo = _clAtTo;
+ SettingManager.Local.ColorListBackcolor = _clListBackcolor;
+ SettingManager.Local.ColorInputBackcolor = _clInputBackcolor;
+ SettingManager.Local.ColorInputFont = _clInputFont;
+ SettingManager.Local.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])
SoundFile = tab.SoundFile,
};
- var filterTab = tab as FilterTabModel;
- if (filterTab != null)
- tabSetting.FilterArray = filterTab.FilterArray;
-
- var userTab = tab as UserTimelineTabModel;
- if (userTab != null)
- tabSetting.User = userTab.ScreenName;
-
- var searchTab = tab as PublicSearchTabModel;
- if (searchTab != null)
+ switch (tab)
{
- tabSetting.SearchWords = searchTab.SearchWords;
- tabSetting.SearchLang = searchTab.SearchLang;
+ case FilterTabModel filterTab:
+ tabSetting.FilterArray = filterTab.FilterArray;
+ break;
+ case UserTimelineTabModel userTab:
+ tabSetting.User = userTab.ScreenName;
+ break;
+ case PublicSearchTabModel searchTab:
+ tabSetting.SearchWords = searchTab.SearchWords;
+ tabSetting.SearchLang = searchTab.SearchLang;
+ break;
+ case ListTimelineTabModel listTab:
+ tabSetting.ListInfo = listTab.ListInfo;
+ break;
}
- var listTab = tab as ListTimelineTabModel;
- 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)
{
- string inputText;
- var ret = InputDialog.Show(this, Properties.Resources.OpenURL_InputText, Properties.Resources.OpenURL_Caption, out inputText);
+ var ret = InputDialog.Show(this, Properties.Resources.OpenURL_InputText, Properties.Resources.OpenURL_Caption, out var inputText);
if (ret != DialogResult.OK)
return;
if (post.IsProtect) protect = "Protect";
sw.WriteLine(post.Nickname + "\t" +
"\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
- post.CreatedAt + "\t" +
+ post.CreatedAt.ToLocalTimeString() + "\t" +
post.ScreenName + "\t" +
post.StatusId + "\t" +
post.ImageUrl + "\t" +
if (post.IsProtect) protect = "Protect";
sw.WriteLine(post.Nickname + "\t" +
"\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
- post.CreatedAt + "\t" +
+ post.CreatedAt.ToLocalTimeString() + "\t" +
post.ScreenName + "\t" +
post.StatusId + "\t" +
post.ImageUrl + "\t" +
}
}
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.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))
+ this.TopMost = SettingManager.Common.AlwaysTop;
+ 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);
+ TabRename(this.ListTab.SelectedTab.Text, out var _);
}
private void ListTab_MouseDown(object sender, MouseEventArgs e)
{
- if (this._cfgCommon.TabMouseLock) return;
+ if (SettingManager.Common.TabMouseLock) return;
if (e.Button == MouseButtons.Left)
{
for (int i = 0; i < ListTab.TabPages.Count; i++)
if ((_statuses.Tabs[ListTab.SelectedTab.Text].TabType == MyCommon.TabUsageType.DirectMessage && isAuto) || (!isAuto && !isReply))
{
// ダイレクトメッセージ
+ this.inReplyTo = null;
StatusText.Text = "D " + _curPost.ScreenName + " " + StatusText.Text;
StatusText.SelectionStart = StatusText.Text.Length;
StatusText.Focus();
- this.inReplyTo = null;
return;
}
if (string.IsNullOrEmpty(StatusText.Text))
{
//空の場合
-
- // ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
- StatusText.Text = "@" + _curPost.ScreenName + " ";
-
var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId;
var inReplyToScreenName = this._curPost.ScreenName;
this.inReplyTo = Tuple.Create(inReplyToStatusId, inReplyToScreenName);
+
+ // ステータステキストが入力されていない場合先頭に@ユーザー名を追加する
+ StatusText.Text = "@" + _curPost.ScreenName + " ";
}
else
{
if (StatusText.Text.StartsWith(". ", StringComparison.Ordinal))
{
// 複数リプライ
- StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " ");
this.inReplyTo = null;
+ StatusText.Text = StatusText.Text.Insert(2, "@" + _curPost.ScreenName + " ");
}
else
{
// 単独リプライ
- StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId;
var inReplyToScreenName = this._curPost.ScreenName;
this.inReplyTo = Tuple.Create(inReplyToStatusId, inReplyToScreenName);
+ StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
}
}
else
{
//文頭@
// 複数リプライ
+ this.inReplyTo = null;
StatusText.Text = ". @" + _curPost.ScreenName + " " + StatusText.Text;
//StatusText.Text = "@" + _curPost.ScreenName + " " + StatusText.Text;
- this.inReplyTo = null;
}
}
else
}
if (isAll)
{
- foreach (string nm in post.ReplyToList)
+ foreach (string nm in post.ReplyToList.Select(x => x.Item2))
{
if (!ids.Contains("@" + nm + " ") &&
!nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
if (ids.Length == 0) return;
if (!StatusText.Text.StartsWith(". ", StringComparison.Ordinal))
{
+ this.inReplyTo = null;
StatusText.Text = ". " + StatusText.Text;
sidx += 2;
- this.inReplyTo = null;
}
if (sidx > 0)
{
{
ids += "@" + post.ScreenName + " ";
}
- foreach (string nm in post.ReplyToList)
+ foreach (string nm in post.ReplyToList.Select(x => x.Item2))
{
if (!ids.Contains("@" + nm + " ") &&
!nm.Equals(tw.Username, StringComparison.CurrentCultureIgnoreCase))
if (string.IsNullOrEmpty(StatusText.Text))
{
//未入力の場合のみ返信先付加
- StatusText.Text = ids;
- StatusText.SelectionStart = ids.Length;
- StatusText.Focus();
-
var inReplyToStatusId = this._curPost.RetweetedId ?? this._curPost.StatusId;
var inReplyToScreenName = this._curPost.ScreenName;
this.inReplyTo = Tuple.Create(inReplyToStatusId, inReplyToScreenName);
+
+ StatusText.Text = ids;
+ StatusText.SelectionStart = ids.Length;
+ StatusText.Focus();
return;
}
}
TabModel tb = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
- if (this._cfgCommon.ReplyIconState != MyCommon.REPLY_ICONSTATE.None && tb != null && tb.UnreadCount > 0)
+ if (SettingManager.Common.ReplyIconState != MyCommon.REPLY_ICONSTATE.None && tb != null && tb.UnreadCount > 0)
{
if (blinkCnt > 0) return;
blink = !blink;
- if (blink || this._cfgCommon.ReplyIconState == MyCommon.REPLY_ICONSTATE.StaticIcon)
+ if (blink || SettingManager.Common.ReplyIconState == MyCommon.REPLY_ICONSTATE.StaticIcon)
{
NotifyIcon1.Icon = ReplyIcon;
}
if (_statuses == null) return;
if (_statuses.Tabs == null) return;
- TabModel tb = _statuses.Tabs[_rclickTabName];
- if (tb == null) return;
+ if (!this._statuses.Tabs.TryGetValue(this._rclickTabName, out var tb))
+ return;
NotifyDispMenuItem.Checked = tb.Notify;
this.NotifyTbMenuItem.Checked = tb.Notify;
return;
_statuses.Tabs[tabName].UnreadManage = isManage;
- if (this._cfgCommon.TabIconDisp)
+ if (SettingManager.Common.TabIconDisp)
{
if (_statuses.Tabs[tabName].UnreadCount > 0)
ListTab.TabPages[idx].ImageIndex = 0;
SetMainWindowTitle();
SetStatusLabelUrl();
- if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
+ if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
}
private void NotifyDispMenuItem_Click(object sender, EventArgs e)
fltDialog.SetCurrent(_rclickTabName);
fltDialog.ShowDialog(this);
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
this.ApplyPostFilters();
SaveConfigsTabs();
tabName = inputName.TabName;
tabUsage = inputName.Usage;
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
if (!string.IsNullOrEmpty(tabName))
{
//List対応
//選択発言を元にフィルタ追加
foreach (int idx in _curList.SelectedIndices)
{
- string tabName;
//タブ選択(or追加)
- if (!SelectTab(out tabName)) return;
+ if (!SelectTab(out var tabName)) return;
fltDialog.SetCurrent(tabName);
if (_statuses.Tabs[_curTab.Text][idx].RetweetedId == null)
fltDialog.AddNewFilter(_statuses.Tabs[_curTab.Text][idx].RetweetedBy, _statuses.Tabs[_curTab.Text][idx].TextFromApi);
}
fltDialog.ShowDialog(this);
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
}
}
bool _NewLine = false;
bool _Post = false;
- if (this._cfgCommon.PostCtrlEnter) //Ctrl+Enter投稿時
+ if (SettingManager.Common.PostCtrlEnter) //Ctrl+Enter投稿時
{
if (StatusText.Multiline)
{
}
}
- else if (this._cfgCommon.PostShiftEnter) //SHift+Enter投稿時
+ else if (SettingManager.Common.PostShiftEnter) //SHift+Enter投稿時
{
if (StatusText.Multiline)
{
public void AddFilterRuleByScreenName(params string[] screenNameArray)
{
//タブ選択(or追加)
- string tabName;
- if (!SelectTab(out tabName)) return;
+ if (!SelectTab(out var tabName)) return;
var tab = (FilterTabModel)this._statuses.Tabs[tabName];
public void AddFilterRuleBySource(params string[] sourceArray)
{
// タブ選択ダイアログを表示(or追加)
- string tabName;
- if (!this.SelectTab(out tabName))
+ if (!this.SelectTab(out var tabName))
return;
var filterTab = (FilterTabModel)this._statuses.Tabs[tabName];
if (inputName.DialogResult == DialogResult.Cancel) return false;
tabName = inputName.TabName;
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
if (!string.IsNullOrEmpty(tabName))
{
var tab = new FilterTabModel(tabName);
{
return;
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
}
}
}
{
if (tb.Text == tabName)
{
- tb.ImageIndex = -1;
((DetailsListView)tb.Tag).VirtualListSize = 0;
+ tb.ImageIndex = -1;
break;
}
}
- if (!this._cfgCommon.TabIconDisp) ListTab.Refresh();
+ if (!SettingManager.Common.TabIconDisp) ListTab.Refresh();
SetMainWindowTitle();
SetStatusLabelUrl();
StringBuilder ttl = new StringBuilder(256);
int ur = 0;
int al = 0;
- if (this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.None &&
- this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.Post &&
- this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
- this._cfgCommon.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
+ if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None &&
+ SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post &&
+ SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver &&
+ SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus)
{
foreach (var tab in _statuses.Tabs.Values)
{
}
}
- if (this._cfgCommon.DispUsername) ttl.Append(tw.Username).Append(" - ");
+ if (SettingManager.Common.DispUsername) ttl.Append(tw.Username).Append(" - ");
ttl.Append(Application.ProductName);
ttl.Append(" ");
- switch (this._cfgCommon.DispLatestPost)
+ switch (SettingManager.Common.DispLatestPost)
{
case MyCommon.DispTitleEnum.Ver:
ttl.Append("Ver:").Append(MyCommon.GetReadableVersion());
var homeTab = this._statuses.GetTabByType<HomeTabModel>();
slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, homeTab.TweetsPerHour);
- if (this._cfgCommon.TimelinePeriod == 0)
+ if (SettingManager.Common.TimelinePeriod == 0)
{
slbl.Append(Properties.Resources.SetStatusLabelText2);
}
else
{
- slbl.Append(this._cfgCommon.TimelinePeriod + Properties.Resources.SetStatusLabelText3);
+ slbl.Append(SettingManager.Common.TimelinePeriod + Properties.Resources.SetStatusLabelText3);
}
return slbl.ToString();
}
StatusLabel.Text = text;
}
- private static StringBuilder ur = new StringBuilder(64);
-
private void SetNotifyIconText()
{
+ var ur = new StringBuilder(64);
+
// タスクトレイアイコンのツールチップテキスト書き換え
// Tween [未読/@]
ur.Remove(0, ur.Length);
- if (this._cfgCommon.DispUsername)
+ if (SettingManager.Common.DispUsername)
{
ur.Append(tw.Username);
ur.Append(" - ");
// 本当にリプライ先指定すべきかどうかの判定
m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?<id>@[a-zA-Z0-9_]+)");
- if (this._cfgCommon.UseAtIdSupplement)
+ if (SettingManager.Common.UseAtIdSupplement)
{
int bCnt = AtIdSupl.ItemCount;
foreach (Match mid in m)
private void TweenMain_Resize(object sender, EventArgs e)
{
- if (!_initialLayout && this._cfgCommon.MinimizeToTray && WindowState == FormWindowState.Minimized)
+ if (!_initialLayout && SettingManager.Common.MinimizeToTray && WindowState == FormWindowState.Minimized)
{
this.Visible = false;
}
- if (_initialLayout && _cfgLocal != null && this.WindowState == FormWindowState.Normal && this.Visible)
+ if (_initialLayout && SettingManager.Local != null && this.WindowState == FormWindowState.Normal && this.Visible)
{
// 現在の DPI と設定保存時の DPI との比を取得する
- var configScaleFactor = this._cfgLocal.GetConfigScaleFactor(this.CurrentAutoScaleDimensions);
+ var configScaleFactor = SettingManager.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions);
- this.ClientSize = ScaleBy(configScaleFactor, _cfgLocal.FormSize);
- //_mySize = this.ClientSize; //サイズ保持(最小化・最大化されたまま終了した場合の対応用)
- this.DesktopLocation = _cfgLocal.FormLocation;
- //_myLoc = this.DesktopLocation; //位置保持(最小化・最大化されたまま終了した場合の対応用)
+ this.ClientSize = ScaleBy(configScaleFactor, SettingManager.Local.FormSize);
// Splitterの位置設定
- var splitterDistance = ScaleBy(configScaleFactor.Height, _cfgLocal.SplitterDistance);
+ var splitterDistance = ScaleBy(configScaleFactor.Height, SettingManager.Local.SplitterDistance);
if (splitterDistance > this.SplitContainer1.Panel1MinSize &&
splitterDistance < this.SplitContainer1.Height - this.SplitContainer1.Panel2MinSize - this.SplitContainer1.SplitterWidth)
{
}
//発言欄複数行
- StatusText.Multiline = _cfgLocal.StatusMultiline;
+ StatusText.Multiline = SettingManager.Local.StatusMultiline;
if (StatusText.Multiline)
{
- var statusTextHeight = ScaleBy(configScaleFactor.Height, _cfgLocal.StatusTextHeight);
+ var statusTextHeight = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight);
int dis = SplitContainer2.Height - statusTextHeight - SplitContainer2.SplitterWidth;
if (dis > SplitContainer2.Panel1MinSize && dis < SplitContainer2.Height - SplitContainer2.Panel2MinSize - SplitContainer2.SplitterWidth)
{
}
}
- var previewDistance = ScaleBy(configScaleFactor.Width, _cfgLocal.PreviewDistance);
+ var previewDistance = ScaleBy(configScaleFactor.Width, SettingManager.Local.PreviewDistance);
if (previewDistance > this.SplitContainer3.Panel1MinSize && previewDistance < this.SplitContainer3.Width - this.SplitContainer3.Panel2MinSize - this.SplitContainer3.SplitterWidth)
{
this.SplitContainer3.SplitterDistance = previewDistance;
this.PlaySoundFileMenuItem.Checked = PlaySoundMenuItem.Checked;
if (PlaySoundMenuItem.Checked)
{
- this._cfgCommon.PlaySound = true;
+ SettingManager.Common.PlaySound = true;
}
else
{
- this._cfgCommon.PlaySound = false;
+ SettingManager.Common.PlaySound = false;
}
ModifySettingCommon = true;
}
if (_statuses.ContainsKey(_curPost.InReplyToStatusId.Value))
{
PostClass repPost = _statuses[_curPost.InReplyToStatusId.Value];
- MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt})" + Environment.NewLine + repPost.TextFromApi);
+ MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
}
else
{
{
if (tb == null || !tb.Contains(_curPost.InReplyToStatusId.Value)) break;
PostClass repPost = _statuses[_curPost.InReplyToStatusId.Value];
- MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt})" + Environment.NewLine + repPost.TextFromApi);
+ MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
return;
}
await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId.Value));
private void SplitContainer2_Panel2_Resize(object sender, EventArgs e)
{
+ if (this._initialLayout)
+ return; // SettingLocal の反映が完了するまで multiline の判定を行わない
+
var multiline = this.SplitContainer2.Panel2.Height > this.SplitContainer2.Panel2MinSize + 2;
if (multiline != this.StatusText.Multiline)
{
this.StatusText.Multiline = multiline;
- MultiLineMenuItem.Checked = multiline;
+ SettingManager.Local.StatusMultiline = multiline;
ModifySettingLocal = true;
}
}
private void MultiLineMenuItem_Click(object sender, EventArgs e)
{
//発言欄複数行
- StatusText.Multiline = MultiLineMenuItem.Checked;
- _cfgLocal.StatusMultiline = MultiLineMenuItem.Checked;
- if (MultiLineMenuItem.Checked)
+ var menuItemChecked = ((ToolStripMenuItem)sender).Checked;
+ StatusText.Multiline = menuItemChecked;
+ SettingManager.Local.StatusMultiline = menuItemChecked;
+ if (menuItemChecked)
{
if (SplitContainer2.Height - _mySpDis2 - SplitContainer2.SplitterWidth < 0)
SplitContainer2.SplitterDistance = 0;
private async Task<bool> UrlConvertAsync(MyCommon.UrlConverter Converter_Type)
{
+ if (Converter_Type == MyCommon.UrlConverter.Bitly || Converter_Type == MyCommon.UrlConverter.Jmp)
+ {
+ // OAuth2 アクセストークンまたは API キー (旧方式) のいずれも設定されていなければ短縮しない
+ if (string.IsNullOrEmpty(SettingManager.Common.BitlyAccessToken) &&
+ (string.IsNullOrEmpty(SettingManager.Common.BilyUser) || string.IsNullOrEmpty(SettingManager.Common.BitlyPwd)))
+ {
+ MessageBox.Show(this, Properties.Resources.UrlConvert_BitlyAuthRequired, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return false;
+ }
+ }
+
//t.coで投稿時自動短縮する場合は、外部サービスでの短縮禁止
//if (SettingDialog.UrlConvertAuto && SettingDialog.ShortenTco) return;
// 文字列が選択されている場合はその文字列について処理
//nico.ms使用、nicovideoにマッチしたら変換
- if (this._cfgCommon.Nicoms && Regex.IsMatch(tmp, nico))
+ if (SettingManager.Common.Nicoms && Regex.IsMatch(tmp, nico))
{
result = nicoms.Shorten(tmp);
}
{
urlUndo undotmp = new urlUndo();
- StatusText.Select(StatusText.Text.IndexOf(tmp, StringComparison.Ordinal), tmp.Length);
+ // 短縮 URL が生成されるまでの間に投稿欄から元の URL が削除されていたら中断する
+ var origUrlIndex = this.StatusText.Text.IndexOf(tmp, StringComparison.Ordinal);
+ if (origUrlIndex == -1)
+ return false;
+
+ StatusText.Select(origUrlIndex, tmp.Length);
StatusText.SelectedText = result;
//undoバッファにセット
StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
//nico.ms使用、nicovideoにマッチしたら変換
- if (this._cfgCommon.Nicoms && Regex.IsMatch(tmp, nico))
+ if (SettingManager.Common.Nicoms && Regex.IsMatch(tmp, nico))
{
result = nicoms.Shorten(tmp);
}
if (!string.IsNullOrEmpty(result))
{
- StatusText.Select(StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length);
+ // 短縮 URL が生成されるまでの間に投稿欄から元の URL が削除されていたら中断する
+ var origUrlIndex = this.StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal);
+ if (origUrlIndex == -1)
+ return false;
+
+ StatusText.Select(origUrlIndex, mt.Result("${url}").Length);
StatusText.SelectedText = result;
//undoバッファにセット
undotmp.Before = mt.Result("${url}");
private async void UrlConvertAutoToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (!await UrlConvertAsync(this._cfgCommon.AutoShortUrlFirst))
+ if (!await UrlConvertAsync(SettingManager.Common.AutoShortUrlFirst))
{
- MyCommon.UrlConverter svc = this._cfgCommon.AutoShortUrlFirst;
+ MyCommon.UrlConverter svc = SettingManager.Common.AutoShortUrlFirst;
Random rnd = new Random();
// 前回使用した短縮URLサービス以外を選択する
do
{
svc = (MyCommon.UrlConverter)rnd.Next(System.Enum.GetNames(typeof(MyCommon.UrlConverter)).Length);
}
- while (svc == this._cfgCommon.AutoShortUrlFirst || svc == MyCommon.UrlConverter.Nicoms || svc == MyCommon.UrlConverter.Unu);
+ while (svc == SettingManager.Common.AutoShortUrlFirst || svc == MyCommon.UrlConverter.Nicoms || svc == MyCommon.UrlConverter.Unu);
await UrlConvertAsync(svc);
}
}
{
this.NotifyFileMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
this.NewPostPopMenuItem.Checked = this.NotifyFileMenuItem.Checked;
- _cfgCommon.NewAllPop = NewPostPopMenuItem.Checked;
+ SettingManager.Common.NewAllPop = NewPostPopMenuItem.Checked;
ModifySettingCommon = true;
}
{
ListLockMenuItem.Checked = ((ToolStripMenuItem)sender).Checked;
this.LockListFileMenuItem.Checked = ListLockMenuItem.Checked;
- _cfgCommon.ListLock = ListLockMenuItem.Checked;
+ SettingManager.Common.ListLock = ListLockMenuItem.Checked;
ModifySettingCommon = true;
}
private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e)
{
DetailsListView lst = (DetailsListView)sender;
- if (_cfgLocal == null) return;
+ if (SettingManager.Local == null) return;
if (_iconCol)
{
- _cfgLocal.Width1 = lst.Columns[0].Width;
- _cfgLocal.Width3 = lst.Columns[1].Width;
+ SettingManager.Local.Width1 = lst.Columns[0].Width;
+ SettingManager.Local.Width3 = lst.Columns[1].Width;
}
else
{
switch (darr[i])
{
case 0:
- _cfgLocal.DisplayIndex1 = i;
+ SettingManager.Local.DisplayIndex1 = i;
break;
case 1:
- _cfgLocal.DisplayIndex2 = i;
+ SettingManager.Local.DisplayIndex2 = i;
break;
case 2:
- _cfgLocal.DisplayIndex3 = i;
+ SettingManager.Local.DisplayIndex3 = i;
break;
case 3:
- _cfgLocal.DisplayIndex4 = i;
+ SettingManager.Local.DisplayIndex4 = i;
break;
case 4:
- _cfgLocal.DisplayIndex5 = i;
+ SettingManager.Local.DisplayIndex5 = i;
break;
case 5:
- _cfgLocal.DisplayIndex6 = i;
+ SettingManager.Local.DisplayIndex6 = i;
break;
case 6:
- _cfgLocal.DisplayIndex7 = i;
+ SettingManager.Local.DisplayIndex7 = i;
break;
case 7:
- _cfgLocal.DisplayIndex8 = i;
+ SettingManager.Local.DisplayIndex8 = i;
break;
}
}
- _cfgLocal.Width1 = lst.Columns[0].Width;
- _cfgLocal.Width2 = lst.Columns[1].Width;
- _cfgLocal.Width3 = lst.Columns[2].Width;
- _cfgLocal.Width4 = lst.Columns[3].Width;
- _cfgLocal.Width5 = lst.Columns[4].Width;
- _cfgLocal.Width6 = lst.Columns[5].Width;
- _cfgLocal.Width7 = lst.Columns[6].Width;
- _cfgLocal.Width8 = lst.Columns[7].Width;
+ SettingManager.Local.Width1 = lst.Columns[0].Width;
+ SettingManager.Local.Width2 = lst.Columns[1].Width;
+ SettingManager.Local.Width3 = lst.Columns[2].Width;
+ SettingManager.Local.Width4 = lst.Columns[3].Width;
+ SettingManager.Local.Width5 = lst.Columns[4].Width;
+ SettingManager.Local.Width6 = lst.Columns[5].Width;
+ SettingManager.Local.Width7 = lst.Columns[6].Width;
+ SettingManager.Local.Width8 = lst.Columns[7].Width;
}
ModifySettingLocal = true;
_isColumnChanged = true;
private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
{
DetailsListView lst = (DetailsListView)sender;
- if (_cfgLocal == null) return;
+ if (SettingManager.Local == null) return;
if (_iconCol)
{
- if (_cfgLocal.Width1 != lst.Columns[0].Width)
+ if (SettingManager.Local.Width1 != lst.Columns[0].Width)
{
- _cfgLocal.Width1 = lst.Columns[0].Width;
+ SettingManager.Local.Width1 = lst.Columns[0].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width3 != lst.Columns[1].Width)
+ if (SettingManager.Local.Width3 != lst.Columns[1].Width)
{
- _cfgLocal.Width3 = lst.Columns[1].Width;
+ SettingManager.Local.Width3 = lst.Columns[1].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
}
else
{
- if (_cfgLocal.Width1 != lst.Columns[0].Width)
+ if (SettingManager.Local.Width1 != lst.Columns[0].Width)
{
- _cfgLocal.Width1 = lst.Columns[0].Width;
+ SettingManager.Local.Width1 = lst.Columns[0].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width2 != lst.Columns[1].Width)
+ if (SettingManager.Local.Width2 != lst.Columns[1].Width)
{
- _cfgLocal.Width2 = lst.Columns[1].Width;
+ SettingManager.Local.Width2 = lst.Columns[1].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width3 != lst.Columns[2].Width)
+ if (SettingManager.Local.Width3 != lst.Columns[2].Width)
{
- _cfgLocal.Width3 = lst.Columns[2].Width;
+ SettingManager.Local.Width3 = lst.Columns[2].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width4 != lst.Columns[3].Width)
+ if (SettingManager.Local.Width4 != lst.Columns[3].Width)
{
- _cfgLocal.Width4 = lst.Columns[3].Width;
+ SettingManager.Local.Width4 = lst.Columns[3].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width5 != lst.Columns[4].Width)
+ if (SettingManager.Local.Width5 != lst.Columns[4].Width)
{
- _cfgLocal.Width5 = lst.Columns[4].Width;
+ SettingManager.Local.Width5 = lst.Columns[4].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width6 != lst.Columns[5].Width)
+ if (SettingManager.Local.Width6 != lst.Columns[5].Width)
{
- _cfgLocal.Width6 = lst.Columns[5].Width;
+ SettingManager.Local.Width6 = lst.Columns[5].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width7 != lst.Columns[6].Width)
+ if (SettingManager.Local.Width7 != lst.Columns[6].Width)
{
- _cfgLocal.Width7 = lst.Columns[6].Width;
+ SettingManager.Local.Width7 = lst.Columns[6].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
- if (_cfgLocal.Width8 != lst.Columns[7].Width)
+ if (SettingManager.Local.Width8 != lst.Columns[7].Width)
{
- _cfgLocal.Width8 = lst.Columns[7].Width;
+ SettingManager.Local.Width8 = lst.Columns[7].Width;
ModifySettingLocal = true;
_isColumnChanged = true;
}
}
else if (e.Data.GetDataPresent("UniformResourceLocatorW"))
{
- var url = GetUrlFromDataObject(e.Data);
+ var (url, title) = GetUrlFromDataObject(e.Data);
string appendText;
- if (url.Item2 == null)
- appendText = url.Item1;
+ if (title == null)
+ appendText = url;
else
- appendText = url.Item2 + " " + url.Item1;
+ appendText = title + " " + url;
if (this.StatusText.TextLength == 0)
this.StatusText.Text = appendText;
/// </remarks>
/// <exception cref="ArgumentException">不正なフォーマットが入力された場合</exception>
/// <exception cref="NotSupportedException">サポートされていないデータが入力された場合</exception>
- internal static Tuple<string, string> GetUrlFromDataObject(IDataObject data)
+ internal static (string Url, string Title) GetUrlFromDataObject(IDataObject data)
{
if (data.GetDataPresent("text/x-moz-url"))
{
if (lines.Length < 2)
throw new ArgumentException("不正な text/x-moz-url フォーマットです", nameof(data));
- return new Tuple<string, string>(lines[0], lines[1]);
+ return (lines[0], lines[1]);
}
}
else if (data.GetDataPresent("IESiteModeToUrl"))
if (lines.Length < 2)
throw new ArgumentException("不正な IESiteModeToUrl フォーマットです", nameof(data));
- return new Tuple<string, string>(lines[0], lines[1]);
+ return (lines[0], lines[1]);
}
}
else if (data.GetDataPresent("UniformResourceLocatorW"))
using (var stream = (MemoryStream)data.GetData("UniformResourceLocatorW"))
{
var url = Encoding.Unicode.GetString(stream.ToArray()).TrimEnd('\0');
- return new Tuple<string, string>(url, null);
+ return (url, null);
}
}
// ユーザープロフィールURL
// フラグが立っている場合は設定と逆の動作をする
- if( this._cfgCommon.OpenUserTimeline && !isReverseSettings ||
- !this._cfgCommon.OpenUserTimeline && isReverseSettings )
+ if( SettingManager.Common.OpenUserTimeline && !isReverseSettings ||
+ !SettingManager.Common.OpenUserTimeline && isReverseSettings )
{
var userUriMatch = Regex.Match(uriStr, "^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)$");
if (userUriMatch.Success)
try
{
- var configBrowserPath = this._cfgLocal.BrowserPath;
+ var configBrowserPath = SettingManager.Local.BrowserPath;
if (!string.IsNullOrEmpty(configBrowserPath))
{
if (configBrowserPath.StartsWith("\"", StringComparison.Ordinal) && configBrowserPath.Length > 2 && configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal) > -1)
_curTab = _tab;
_curList = (DetailsListView)_tab.Tag;
+
if (_curList.SelectedIndices.Count > 0)
{
_curItemIndex = _curList.SelectedIndices[0];
this.RefreshUserStreamsMenu();
- if (this._cfgCommon.UserstreamStartup)
+ if (SettingManager.Common.UserstreamStartup)
tw.StartUserStream();
}
this.GetListTimelineAllAsync(),
};
- if (this._cfgCommon.StartupFollowers)
+ if (SettingManager.Common.StartupFollowers)
loadTasks.Add(this.RefreshFollowerIdsAsync());
- if (this._cfgCommon.GetFav)
+ if (SettingManager.Common.GetFav)
loadTasks.Add(this.GetFavoritesAsync());
var allTasks = Task.WhenAll(loadTasks);
if (ApplicationSettings.VersionInfoUrl != null)
{
//バージョンチェック(引数:起動時チェックの場合はtrue・・・チェック結果のメッセージを表示しない)
- if (this._cfgCommon.StartupVersion)
+ if (SettingManager.Common.StartupVersion)
await this.CheckNewVersion(true);
}
else
// 取得失敗の場合は再試行する
var reloadTasks = new List<Task>();
- if (!tw.GetFollowersSuccess && this._cfgCommon.StartupFollowers)
+ if (!tw.GetFollowersSuccess && SettingManager.Common.StartupFollowers)
reloadTasks.Add(this.RefreshFollowerIdsAsync());
if (!tw.GetNoRetweetSuccess)
//公式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 || _curPost.IsMe)
- {
- _DoFavRetweetFlags = false;
- return;
- }
- if (!this._cfgCommon.RetweetNoConfirm)
+ if (!SettingManager.Common.RetweetNoConfirm)
{
string Questiontext = Properties.Resources.RetweetQuestion1;
if (_DoFavRetweetFlags) Questiontext = Properties.Resources.FavoritesRetweetQuestionText2;
foreach (int idx in _curList.SelectedIndices)
{
PostClass post = GetCurTabPost(idx);
- if (!post.IsMe && !post.IsProtect && !post.IsDm)
+ if (post.CanRetweetBy(this.twitterApi.CurrentUserId))
statusIds.Add(post.StatusId);
}
DebugModeToolStripMenuItem.Visible = false;
}
- private void ToolStripMenuItemUrlAutoShorten_CheckedChanged(object sender, EventArgs e)
+ private void UrlMultibyteSplitMenuItem_CheckedChanged(object sender, EventArgs e)
+ {
+ this.urlMultibyteSplit = ((ToolStripMenuItem)sender).Checked;
+ }
+
+ private void PreventSmsCommandMenuItem_CheckedChanged(object sender, EventArgs e)
+ {
+ this.preventSmsCommand = ((ToolStripMenuItem)sender).Checked;
+ }
+
+ private void UrlAutoShortenMenuItem_CheckedChanged(object sender, EventArgs e)
{
- this._cfgCommon.UrlConvertAuto = ToolStripMenuItemUrlAutoShorten.Checked;
+ SettingManager.Common.UrlConvertAuto = ((ToolStripMenuItem)sender).Checked;
+ }
+
+ private void IdeographicSpaceToSpaceMenuItem_Click(object sender, EventArgs e)
+ {
+ SettingManager.Common.WideSpaceConvert = ((ToolStripMenuItem)sender).Checked;
+ ModifySettingCommon = true;
+ }
+
+ private void FocusLockMenuItem_CheckedChanged(object sender, EventArgs e)
+ {
+ SettingManager.Common.FocusLockToStatusText = ((ToolStripMenuItem)sender).Checked;
+ ModifySettingCommon = true;
+ }
+
+ private void PostModeMenuItem_DropDownOpening(object sender, EventArgs e)
+ {
+ UrlMultibyteSplitMenuItem.Checked = this.urlMultibyteSplit;
+ PreventSmsCommandMenuItem.Checked = this.preventSmsCommand;
+ UrlAutoShortenMenuItem.Checked = SettingManager.Common.UrlConvertAuto;
+ IdeographicSpaceToSpaceMenuItem.Checked = SettingManager.Common.WideSpaceConvert;
+ MultiLineMenuItem.Checked = SettingManager.Local.StatusMultiline;
+ FocusLockMenuItem.Checked = SettingManager.Common.FocusLockToStatusText;
}
private void ContextMenuPostMode_Opening(object sender, CancelEventArgs e)
{
- ToolStripMenuItemUrlAutoShorten.Checked = this._cfgCommon.UrlConvertAuto;
+ UrlMultibyteSplitPullDownMenuItem.Checked = this.urlMultibyteSplit;
+ PreventSmsCommandPullDownMenuItem.Checked = this.preventSmsCommand;
+ UrlAutoShortenPullDownMenuItem.Checked = SettingManager.Common.UrlConvertAuto;
+ IdeographicSpaceToSpacePullDownMenuItem.Checked = SettingManager.Common.WideSpaceConvert;
+ MultiLinePullDownMenuItem.Checked = SettingManager.Local.StatusMultiline;
+ FocusLockPullDownMenuItem.Checked = SettingManager.Common.FocusLockToStatusText;
}
private void TraceOutToolStripMenuItem_Click(object sender, EventArgs e)
private void TabRenameMenuItem_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(_rclickTabName)) return;
- TabRename(ref _rclickTabName);
+
+ TabRename(_rclickTabName, out var _);
}
private async void BitlyToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
- var task = this.twitterApi.FriendshipsCreate(id);
+ var task = this.twitterApi.FriendshipsCreate(id).IgnoreResponse();
await dialog.WaitForAsync(this, task);
}
catch (WebApiException ex)
{
try
{
- var task = this.twitterApi.FriendshipsDestroy(id);
+ var task = this.twitterApi.FriendshipsDestroy(id).IgnoreResponse();
await dialog.WaitForAsync(this, task);
}
catch (WebApiException ex)
return !this.tw.Configuration.NonUsernamePaths.Contains(name.ToLowerInvariant());
}
- private void IdeographicSpaceToSpaceToolStripMenuItem_Click(object sender, EventArgs e)
- {
- ModifySettingCommon = true;
- }
-
- private void ToolStripFocusLockMenuItem_CheckedChanged(object sender, EventArgs e)
- {
- ModifySettingCommon = true;
- }
-
private void doQuoteOfficial()
{
if (this.ExistCurrentPost)
return;
}
- StatusText.Text = " " + MyCommon.GetStatusUrl(_curPost);
+ var selection = (this.StatusText.SelectionStart, this.StatusText.SelectionLength);
this.inReplyTo = null;
- StatusText.SelectionStart = 0;
+ StatusText.Text += " " + MyCommon.GetStatusUrl(_curPost);
+
+ (this.StatusText.SelectionStart, this.StatusText.SelectionLength) = selection;
StatusText.Focus();
}
}
string rtdata = _curPost.Text;
rtdata = CreateRetweetUnofficial(rtdata, this.StatusText.Multiline);
- StatusText.Text = " RT @" + _curPost.ScreenName + ": " + rtdata;
+ 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;
this.inReplyTo = Tuple.Create(inReplyToStatusId, inReplyToScreenName);
- StatusText.SelectionStart = 0;
+ StatusText.Text += " RT @" + _curPost.ScreenName + ": " + rtdata;
+
+ (this.StatusText.SelectionStart, this.StatusText.SelectionLength) = selection;
StatusText.Focus();
}
}
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);
}
{
return;
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
if (rslt == DialogResult.Cancel) return;
if (!string.IsNullOrEmpty(HashMgr.UseHash))
{
HashStripSplitButton.Text = HashMgr.UseHash;
+ HashTogglePullDownMenuItem.Checked = true;
HashToggleMenuItem.Checked = true;
- HashToggleToolStripMenuItem.Checked = true;
}
else
{
HashStripSplitButton.Text = "#[-]";
+ HashTogglePullDownMenuItem.Checked = false;
HashToggleMenuItem.Checked = false;
- HashToggleToolStripMenuItem.Checked = false;
}
//if (HashMgr.IsInsert && HashMgr.UseHash != "")
//{
{
HashStripSplitButton.Text = HashMgr.UseHash;
HashToggleMenuItem.Checked = true;
- HashToggleToolStripMenuItem.Checked = true;
+ HashTogglePullDownMenuItem.Checked = true;
}
else
{
HashStripSplitButton.Text = "#[-]";
HashToggleMenuItem.Checked = false;
- HashToggleToolStripMenuItem.Checked = false;
+ HashTogglePullDownMenuItem.Checked = false;
}
ModifySettingCommon = true;
this.StatusText_TextChanged(null, null);
{
HashMgr.SetPermanentHash("#" + hashtag);
HashStripSplitButton.Text = HashMgr.UseHash;
+ HashTogglePullDownMenuItem.Checked = true;
HashToggleMenuItem.Checked = true;
- HashToggleToolStripMenuItem.Checked = true;
//使用ハッシュタグとして設定
ModifySettingCommon = true;
}
this.OpenFavotterOpMenuItem.Enabled = true;
this.ShowRelatedStatusesMenuItem2.Enabled = true; //PublicSearchの時問題出るかも
- if (_curPost.IsMe)
+ if (!_curPost.CanRetweetBy(this.twitterApi.CurrentUserId))
{
- this.RtOpMenuItem.Enabled = false; //公式RTは無効に
- this.RtUnOpMenuItem.Enabled = true;
- this.QtOpMenuItem.Enabled = true;
- this.FavoriteRetweetMenuItem.Enabled = false; //公式RTは無効に
- this.FavoriteRetweetUnofficialMenuItem.Enabled = true;
+ this.RtOpMenuItem.Enabled = false;
+ this.RtUnOpMenuItem.Enabled = false;
+ this.QtOpMenuItem.Enabled = false;
+ this.FavoriteRetweetMenuItem.Enabled = false;
+ this.FavoriteRetweetUnofficialMenuItem.Enabled = false;
}
else
{
- if (_curPost.IsProtect)
- {
- this.RtOpMenuItem.Enabled = false;
- this.RtUnOpMenuItem.Enabled = false;
- this.QtOpMenuItem.Enabled = false;
- this.FavoriteRetweetMenuItem.Enabled = false;
- this.FavoriteRetweetUnofficialMenuItem.Enabled = false;
- }
- else
- {
- this.RtOpMenuItem.Enabled = true;
- this.RtUnOpMenuItem.Enabled = true;
- this.QtOpMenuItem.Enabled = true;
- this.FavoriteRetweetMenuItem.Enabled = true;
- this.FavoriteRetweetUnofficialMenuItem.Enabled = true;
- }
+ this.RtOpMenuItem.Enabled = true;
+ this.RtUnOpMenuItem.Enabled = true;
+ this.QtOpMenuItem.Enabled = true;
+ this.FavoriteRetweetMenuItem.Enabled = true;
+ this.FavoriteRetweetUnofficialMenuItem.Enabled = true;
}
}
private void SplitContainer2_MouseDoubleClick(object sender, MouseEventArgs e)
{
- this.MultiLineMenuItem.PerformClick();
+ this.MultiLinePullDownMenuItem.PerformClick();
}
public PostClass CurPost
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
/// </summary>
/// <param name="statusId">表示するツイートのID</param>
/// <exception cref="TabException">名前の重複が多すぎてタブを作成できない場合</exception>
- private async Task OpenRelatedTab(long statusId)
+ public async Task OpenRelatedTab(long statusId)
{
var post = this._statuses[statusId];
if (post == null)
}
#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 async void tw_NewPostFromStream(object sender, EventArgs e)
{
- if (this._cfgCommon.ReadOldPosts)
+ if (SettingManager.Common.ReadOldPosts)
{
_statuses.SetReadHomeTab(); //新着時未読クリア
}
this._statuses.DistributePosts();
- if (this._cfgCommon.UserstreamPeriod > 0) return;
+ if (SettingManager.Common.UserstreamPeriod > 0) return;
// userStreamsRefreshing が 0 (インクリメント後は1) であれば RefreshTimeline を実行
if (Interlocked.Increment(ref this.userStreamsRefreshing) == 1)
}
}
- 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;
}
}
//if (SettingDialog.DispUsername) NotifyIcon1.BalloonTipTitle = tw.Username + " - "; else NotifyIcon1.BalloonTipTitle = "";
//NotifyIcon1.BalloonTipTitle += Application.ProductName + " [" + ev.Event.ToUpper() + "] by " + ((string)(!string.IsNullOrEmpty(ev.Username) ? ev.Username : ""), string);
StringBuilder title = new StringBuilder();
- if (this._cfgCommon.DispUsername)
+ if (SettingManager.Common.DispUsername)
{
title.Append(tw.Username);
title.Append(" - ");
text = " ";
}
//NotifyIcon1.ShowBalloonTip(500);
- if (this._cfgCommon.IsUseNotifyGrowl)
+ if (SettingManager.Common.IsUseNotifyGrowl)
{
gh.Notify(GrowlHelper.NotifyType.UserStreamEvent,
ev.Id.ToString(), title.ToString(), text);
}
//サウンド再生
- string snd = this._cfgCommon.EventSoundFile;
- if (!_initial && this._cfgCommon.PlaySound && !string.IsNullOrEmpty(snd))
+ string snd = SettingManager.Common.EventSoundFile;
+ if (!_initial && SettingManager.Common.PlaySound && !string.IsNullOrEmpty(snd))
{
- if ((ev.Eventtype & this._cfgCommon.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev))
+ if ((ev.Eventtype & SettingManager.Common.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev))
{
try
{
{
evtDialog.Activate();
}
- this.TopMost = this._cfgCommon.AlwaysTop;
+ this.TopMost = SettingManager.Common.AlwaysTop;
}
#endregion
private async Task OpenUserAppointUrl()
{
- if (this._cfgCommon.UserAppointUrl != null)
+ if (SettingManager.Common.UserAppointUrl != null)
{
- if (this._cfgCommon.UserAppointUrl.Contains("{ID}") || this._cfgCommon.UserAppointUrl.Contains("{STATUS}"))
+ if (SettingManager.Common.UserAppointUrl.Contains("{ID}") || SettingManager.Common.UserAppointUrl.Contains("{STATUS}"))
{
if (_curPost != null)
{
- string xUrl = this._cfgCommon.UserAppointUrl;
+ string xUrl = SettingManager.Common.UserAppointUrl;
xUrl = xUrl.Replace("{ID}", _curPost.ScreenName);
var statusId = _curPost.RetweetedId ?? _curPost.StatusId;
}
else
{
- await this.OpenUriInBrowserAsync(this._cfgCommon.UserAppointUrl);
+ await this.OpenUriInBrowserAsync(SettingManager.Common.UserAppointUrl);
}
}
}
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();
}
- }));
+ });
}
}
private void ContextMenuColumnHeader_Opening(object sender, CancelEventArgs e)
{
- this.IconSizeNoneToolStripMenuItem.Checked = this._cfgCommon.IconSize == MyCommon.IconSizes.IconNone;
- this.IconSize16ToolStripMenuItem.Checked = this._cfgCommon.IconSize == MyCommon.IconSizes.Icon16;
- this.IconSize24ToolStripMenuItem.Checked = this._cfgCommon.IconSize == MyCommon.IconSizes.Icon24;
- this.IconSize48ToolStripMenuItem.Checked = this._cfgCommon.IconSize == MyCommon.IconSizes.Icon48;
- this.IconSize48_2ToolStripMenuItem.Checked = this._cfgCommon.IconSize == MyCommon.IconSizes.Icon48_2;
+ this.IconSizeNoneToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.IconNone;
+ this.IconSize16ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon16;
+ this.IconSize24ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon24;
+ this.IconSize48ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon48;
+ this.IconSize48_2ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon48_2;
- this.LockListSortOrderToolStripMenuItem.Checked = this._cfgCommon.SortOrderLock;
+ this.LockListSortOrderToolStripMenuItem.Checked = SettingManager.Common.SortOrderLock;
}
private void IconSizeNoneToolStripMenuItem_Click(object sender, EventArgs e)
private void ChangeListViewIconSize(MyCommon.IconSizes iconSize)
{
- if (this._cfgCommon.IconSize == iconSize) return;
+ if (SettingManager.Common.IconSize == iconSize) return;
var oldIconCol = _iconCol;
- this._cfgCommon.IconSize = iconSize;
+ SettingManager.Common.IconSize = iconSize;
ApplyListViewIconSize(iconSize);
if (_iconCol != oldIconCol)
private void LockListSortToolStripMenuItem_Click(object sender, EventArgs e)
{
var state = this.LockListSortOrderToolStripMenuItem.Checked;
- if (this._cfgCommon.SortOrderLock == state) return;
+ if (SettingManager.Common.SortOrderLock == state) return;
- this._cfgCommon.SortOrderLock = state;
+ SettingManager.Common.SortOrderLock = state;
ModifySettingCommon = true;
}