private bool _DoFavRetweetFlags = false;
private bool osResumed = false;
- private Dictionary<string, IMultimediaShareService> pictureService;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
private string _postBrowserStatusText = "";
public long? inReplyToId = null;
public string inReplyToName = null;
public string imageService = ""; //画像投稿サービス名
- public string imagePath = "";
+ public string[] imagePath = null;
public PostingStatus()
{
}
SettingDialog.UseAtIdSupplement = _cfgCommon.UseAtIdSupplement;
SettingDialog.UseHashSupplement = _cfgCommon.UseHashSupplement;
SettingDialog.PreviewEnable = _cfgCommon.PreviewEnable;
+ SettingDialog.StatusAreaAtBottom = _cfgCommon.StatusAreaAtBottom;
AtIdSupl = new AtIdSupplement(SettingAtIdList.Load().AtIdList, "@");
SettingDialog.IsMonospace = _cfgCommon.IsMonospace;
AllrepliesToolStripMenuItem.Checked = tw.AllAtReply;
//画像投稿サービス
- this.CreatePictureServices();
- SetImageServiceCombo();
- ImageSelectionPanel.Enabled = false;
-
- SelectImageServiceComboItem(_cfgCommon.UseImageServiceName, _cfgCommon.UseImageService);
+ ImageSelector.Initialize(tw, SettingDialog.TwitterConfiguration, _cfgCommon.UseImageServiceName, _cfgCommon.UseImageService);
//ウィンドウ設定
this.ClientSize = _cfgLocal.FormSize;
// NameLabel のフォントを OTBaseForm.GlobalFont に変更
this.NameLabel.Font = this.ReplaceToGlobalFont(this.NameLabel.Font);
+ // 必要であれば、発言一覧と発言詳細部・入力欄の上下を入れ替える
+ SplitContainer1.IsPanelInverted = !SettingDialog.StatusAreaAtBottom;
+
//全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定)
if (SettingDialog.UnreadManage == false)
{
}
}
- private void CreatePictureServices()
- {
- if (this.pictureService != null) this.pictureService.Clear();
- this.pictureService = null;
- this.pictureService = new Dictionary<string, IMultimediaShareService> {
- {"TwitPic", new TwitPic(tw)},
- {"img.ly", new imgly(tw)},
- {"yfrog", new yfrog(tw)},
- {"Twitter", new TwitterPhoto(tw)},
- {"ついっぷるフォト", new TwipplePhoto(tw)},
- {"Imgur", new Imgur(tw)},
- };
- }
-
private void ListTab_DrawItem(object sender, DrawItemEventArgs e)
{
string txt;
doGetFollowersMenu();
GetTimeline(MyCommon.WORKERTYPE.NoRetweetIds, 0, 0, "");
GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
- if (InvokeRequired && !IsDisposed) this.Invoke(new MethodInvoker(this.TrimPostChain));
}
if (osResumed)
{
GetTimeline(MyCommon.WORKERTYPE.List, 1, 0, "");
doGetFollowersMenu();
GetTimeline(MyCommon.WORKERTYPE.Configuration, 0, 0, "");
- if (InvokeRequired && !IsDisposed) this.Invoke(new MethodInvoker(this.TrimPostChain));
}
}
}
if (SettingDialog.UnreadManage) _statuses.SetReadAllTab(true, _curTab.Text, _curItemIndex);
//キャッシュの書き換え
- ChangeCacheStyleRead(true, _curItemIndex, _curTab); //既読へ(フォント、文字色)
+ ChangeCacheStyleRead(true, _curItemIndex); //既読へ(フォント、文字色)
ColorizeList();
_colorize = true;
}
- private void ChangeCacheStyleRead(bool Read, int Index, TabPage Tab)
+ private void ChangeCacheStyleRead(bool Read, int Index)
{
//Read:true=既読 false=未読
//未読管理していなかったら既読として扱う
ListViewItem itm = null;
PostClass post = null;
- if (Tab.Equals(this._curTab))
- {
- this.TryGetListViewItemCache(Index, out itm, out post);
- }
+ this.TryGetListViewItemCache(Index, out itm, out post);
if (itm == null || post == null)
{
- itm = ((DetailsListView)Tab.Tag).Items[Index];
- post = _statuses[Tab.Text, Index];
+ itm = ((DetailsListView)_curTab.Tag).Items[Index];
+ post = _statuses[_curTab.Text, Index];
}
- ChangeItemStyleRead(Read, itm, post, ((DetailsListView)Tab.Tag));
+ ChangeItemStyleRead(Read, itm, post, ((DetailsListView)_curTab.Tag));
}
private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView DList)
{
if (StatusText.Text.Trim().Length == 0)
{
- if (!ImageSelectionPanel.Enabled)
+ if (!ImageSelector.Enabled)
{
DoRefresh();
return;
args.status.inReplyToId = _reply_to_id;
args.status.inReplyToName = _reply_to_name;
- if (ImageSelectionPanel.Visible)
+ if (ImageSelector.Visible)
{
//画像投稿
- if (!TryGetSelectedMedia(out args.status.imageService, out args.status.imagePath))
+ if (!ImageSelector.TryGetSelectedMedia(out args.status.imageService, out args.status.imagePath))
return;
}
case MyCommon.WORKERTYPE.PostMessage:
bw.ReportProgress(200);
- if (string.IsNullOrEmpty(args.status.imagePath))
+ if (args.status.imagePath == null || args.status.imagePath.Length == 0 || string.IsNullOrEmpty(args.status.imagePath[0]))
{
ret = tw.PostStatus(args.status.status, args.status.inReplyToId);
}
else
{
- ret = this.pictureService[args.status.imageService].Upload(ref args.status.imagePath,
- ref args.status.status,
- args.status.inReplyToId);
+ var service = ImageSelector.GetService(args.status.imageService);
+ try
+ {
+ service.PostStatusAsync(args.status.status, args.status.inReplyToId, args.status.imagePath)
+ .Wait();
+ }
+ catch (AggregateException ex)
+ {
+ ret = ex.InnerException.Message;
+ }
}
bw.ReportProgress(300);
rslt.status = args.status;
{
post = _statuses[rslt.sIds[i]];
}
- ChangeCacheStyleRead(post.IsRead, idx, _curTab);
+ ChangeCacheStyleRead(post.IsRead, idx);
}
if (idx == _curItemIndex) DispSelectedPost(true); //選択アイテム再表示
}
//_waitFollower = false
if (SettingDialog.TwitterConfiguration.PhotoSizeLimit != 0)
{
- pictureService["Twitter"].Configuration("MaxUploadFilesize", SettingDialog.TwitterConfiguration.PhotoSizeLimit);
+ foreach (var service in this.ImageSelector.GetServices())
+ {
+ service.UpdateTwitterConfiguration(this.SettingDialog.TwitterConfiguration);
+ }
}
this.PurgeListViewItemCache();
if (_curList != null) _curList.Refresh();
}
}
+ private async Task RefreshMuteUserIdsAsync()
+ {
+ this.StatusLabel.Text = Properties.Resources.UpdateMuteUserIds_Start;
+
+ try
+ {
+ await tw.RefreshMuteUserIdsAsync();
+ }
+ catch (WebApiException ex)
+ {
+ this.StatusLabel.Text = string.Format(Properties.Resources.UpdateMuteUserIds_Error, ex.Message);
+ return;
+ }
+
+ this.StatusLabel.Text = Properties.Resources.UpdateMuteUserIds_Finish;
+ }
+
private void RemovePostFromFavTab(Int64[] ids)
{
string favTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).TabName;
}
foreach (int idx in _curList.SelectedIndices)
{
- ChangeCacheStyleRead(true, idx, _curTab);
+ ChangeCacheStyleRead(true, idx);
}
ColorizeList();
}
}
foreach (int idx in _curList.SelectedIndices)
{
- ChangeCacheStyleRead(false, idx, _curTab);
+ ChangeCacheStyleRead(false, idx);
}
ColorizeList();
}
SettingDialog.ProxyPort,
SettingDialog.ProxyUser,
SettingDialog.ProxyPassword);
- this.CreatePictureServices();
+
+ ImageSelector.Reset(tw, SettingDialog.TwitterConfiguration);
try
{
// タブの表示位置の決定
SetTabAlignment();
+ SplitContainer1.IsPanelInverted = !SettingDialog.StatusAreaAtBottom;
+
var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance;
imgazyobizinet.Enabled = this.SettingDialog.EnableImgAzyobuziNet;
imgazyobizinet.DisabledInDM = this.SettingDialog.ImgAzyobuziNetDisabledInDM;
if (uid != tw.Username) this.doGetFollowersMenu();
- SetImageServiceCombo();
if (SettingDialog.IsNotifyUseGrowl) gh.RegisterGrowl();
try
{
/// </summary>
private void SetTabAlignment()
{
- ListTab.Alignment = (SettingDialog.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top);
+ var newAlignment = SettingDialog.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top;
+ if (ListTab.Alignment == newAlignment) return;
+
+ //現在の選択状態を退避
+ Dictionary<string, long[]> selId = new Dictionary<string, long[]>();
+ Dictionary<string, long[]> focusedId = new Dictionary<string, long[]>();
+ SaveSelectedStatus(selId, focusedId);
+
+ ListTab.Alignment = newAlignment;
+
+ //選択状態を復帰
+ foreach (TabPage tab in ListTab.TabPages)
+ {
+ DetailsListView lst = (DetailsListView)tab.Tag;
+ using (ControlTransaction.Update(lst))
+ {
+ this.SelectListItem(lst,
+ _statuses.IndexOf(tab.Text, selId[tab.Text]),
+ _statuses.IndexOf(tab.Text, focusedId[tab.Text]));
+ }
+ }
}
private void ApplyListViewIconSize(MyCommon.IconSizes iconSz)
// pLen += m.Result("${url}").Length - SettingDialog.TwitterConfiguration.ShortUrlLength;
//}
}
- if (ImageSelectionPanel.Visible && ImageSelectedPicture.Tag != null && !string.IsNullOrEmpty(this.ImageService))
+ if (ImageSelector.Visible && !string.IsNullOrEmpty(ImageSelector.ServiceName))
{
pLen -= SettingDialog.TwitterConfiguration.CharactersReservedPerMedia;
}
{
if (e.State == 0) return;
e.DrawDefault = false;
+
+ SolidBrush brs2 = null;
if (!e.Item.Selected) //e.ItemStateでうまく判定できない???
{
- SolidBrush brs2 = null;
-
if (e.Item.BackColor == _clSelf)
brs2 = _brsBackColorMine;
else if (e.Item.BackColor == _clAtSelf)
brs2 = _brsBackColorAtTo;
else
brs2 = _brsBackColorNone;
-
- e.Graphics.FillRectangle(brs2, e.Bounds);
}
else
{
//選択中の行
if (((Control)sender).Focused)
- e.Graphics.FillRectangle(_brsHighLight, e.Bounds);
+ brs2 = _brsHighLight;
else
- e.Graphics.FillRectangle(_brsDeactiveSelection, e.Bounds);
+ brs2 = _brsDeactiveSelection;
}
- if ((e.State & ListViewItemStates.Focused) == ListViewItemStates.Focused) e.DrawFocusRectangle();
+ e.Graphics.FillRectangle(brs2, e.Bounds);
+ e.DrawFocusRectangle();
this.DrawListViewItemIcon(e);
}
//アイコン以外の列
RectangleF rct = e.Bounds;
rct.Width = e.Header.Width;
+ int fontHeight = e.Item.Font.Height;
if (_iconCol)
{
- rct.Y += e.Item.Font.Height;
- rct.Height -= e.Item.Font.Height;
+ rct.Y += fontHeight;
+ rct.Height -= fontHeight;
}
int heightDiff;
- int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, e.Item.Font.Height, out heightDiff));
+ int drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out heightDiff));
- //if (heightDiff > e.Item.Font.Height * 0.7)
+ //if (heightDiff > fontHeight * 0.7)
//{
- // rct.Height += e.Item.Font.Height;
+ // rct.Height += fontHeight;
// drawLineCount += 1;
//}
if (!_iconCol && drawLineCount <= 1)
{
//rct.Inflate(0, heightDiff / -2);
- //rct.Height += e.Item.Font.Height / 2;
+ //rct.Height += fontHeight / 2;
}
- else if (heightDiff < e.Item.Font.Height * 0.7)
+ else if (heightDiff < fontHeight * 0.7)
{
//最終行が70%以上欠けていたら、最終行は表示しない
- //rct.Height = (float)((e.Item.Font.Height * drawLineCount) + (e.Item.Font.Height / 2));
- rct.Height = (e.Item.Font.Height * drawLineCount) - 1;
+ //rct.Height = (float)((fontHeight * drawLineCount) + (fontHeight / 2));
+ rct.Height = (fontHeight * drawLineCount) - 1;
}
else
{
//if (!_iconCol && drawLineCount > 1)
//{
- // rct.Y += e.Item.Font.Height * 0.2;
- // if (heightDiff >= e.Item.Font.Height * 0.8) rct.Height -= e.Item.Font.Height * 0.2;
+ // rct.Y += fontHeight * 0.2;
+ // if (heightDiff >= fontHeight * 0.8) rct.Height -= fontHeight * 0.2;
//}
if (rct.Width > 0)
if (_iconCol)
{
- RectangleF rctB = e.Bounds;
+ Rectangle rctB = e.Bounds;
rctB.Width = e.Header.Width;
- rctB.Height = e.Item.Font.Height;
+ rctB.Height = fontHeight;
using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
{
TextRenderer.DrawText(e.Graphics,
e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]",
fnt,
- Rectangle.Round(rctB),
+ rctB,
color,
TextFormatFlags.SingleLine |
TextFormatFlags.EndEllipsis |
private void DrawListViewItemIcon(DrawListViewItemEventArgs e)
{
+ if (_iconSz == 0) return;
+
ImageListViewItem item = (ImageListViewItem)e.Item;
//e.Bounds.Leftが常に0を指すから自前で計算
Rectangle itemRect = item.Bounds;
- itemRect.Width = e.Item.ListView.Columns[0].Width;
+ var col0 = e.Item.ListView.Columns[0];
+ itemRect.Width = col0.Width;
- foreach (ColumnHeader clm in e.Item.ListView.Columns)
+ if (col0.DisplayIndex > 0)
{
- if (clm.DisplayIndex < e.Item.ListView.Columns[0].DisplayIndex)
- itemRect.X += clm.Width;
+ foreach (ColumnHeader clm in e.Item.ListView.Columns)
+ {
+ if (clm.DisplayIndex < col0.DisplayIndex)
+ itemRect.X += clm.Width;
+ }
}
// ディスプレイの DPI 設定を考慮したアイコンサイズ
var realStateSize = new SizeF(16 * this.currentScaleFactor.Width, 16 * this.currentScaleFactor.Height).ToSize();
Rectangle iconRect;
- Rectangle stateRect;
- if (item.Image != null)
+ var img = item.Image;
+ if (img != null)
{
iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, realIconSize), itemRect);
iconRect.Offset(0, Math.Max(0, (itemRect.Height - realIconSize.Height) / 2));
- stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect);
+
+ if (iconRect.Width > 0)
+ {
+ e.Graphics.FillRectangle(Brushes.White, iconRect);
+ e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
+ try
+ {
+ e.Graphics.DrawImage(img.Image, iconRect);
+ }
+ catch (ArgumentException)
+ {
+ item.RefreshImageAsync();
+ }
+ }
}
else
{
iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(1, 1)), itemRect);
//iconRect.Offset(0, Math.Max(0, (itemRect.Height - realIconSize.Height) / 2));
- stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect);
- }
-
- var img = item.Image;
- if (img != null && iconRect.Width > 0)
- {
- e.Graphics.FillRectangle(Brushes.White, iconRect);
- e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
- try
- {
- e.Graphics.DrawImage(img.Image, iconRect);
- }
- catch (ArgumentException)
- {
- item.RefreshImageAsync();
- }
}
if (item.StateImageIndex > -1)
{
+ Rectangle stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect);
if (stateRect.Width > 0)
{
//e.Graphics.FillRectangle(Brushes.White, stateRect);
int idx = -1;
DetailsListView lst = null;
- if (ImageSelectionPanel.Enabled)
+ if (ImageSelector.Enabled)
return;
//現在タブから最終タブまで探索
if (this.thumbnailTokenSource != null)
{
var oldTokenSource = this.thumbnailTokenSource;
- oldTokenSource.Cancel();
+
+ // TODO: キャンセルを行うとUIスレッドが阻害される問題を調査
+ //oldTokenSource.Cancel();
+
this.thumbnailTask.ContinueWith(_ => oldTokenSource.Dispose());
}
private void GoBackSelectPostChain()
{
- try
+ if (this.selectPostChains.Count > 1)
{
- this.selectPostChains.Pop();
- Tuple<TabPage, PostClass> tabPostPair = this.selectPostChains.Pop();
- if (!this.ListTab.TabPages.Contains(tabPostPair.Item1)) return;
- this.ListTab.SelectedTab = tabPostPair.Item1;
- if (tabPostPair.Item2 != null && this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId) > -1)
+ var idx = -1;
+ TabPage tp = null;
+
+ do
{
- this.SelectListItem(this._curList, this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId));
- this._curList.EnsureVisible(this._statuses.Tabs[this._curTab.Text].IndexOf(tabPostPair.Item2.StatusId));
+ try
+ {
+ this.selectPostChains.Pop();
+ var tabPostPair = this.selectPostChains.Peek();
+
+ if (!this.ListTab.TabPages.Contains(tabPostPair.Item1)) continue; //該当タブが存在しないので無視
+
+ if (tabPostPair.Item2 != null)
+ {
+ idx = this._statuses.Tabs[tabPostPair.Item1.Text].IndexOf(tabPostPair.Item2.StatusId);
+ if (idx == -1) continue; //該当ポストが存在しないので無視
+ }
+
+ tp = tabPostPair.Item1;
+
+ this.selectPostChains.Pop();
+ }
+ catch (InvalidOperationException)
+ {
+ }
+
+ break;
}
- }
- catch (InvalidOperationException)
- {
+ while (this.selectPostChains.Count > 1);
+
+ if (tp == null)
+ {
+ //状態がおかしいので処理を中断
+ //履歴が残り1つであればクリアしておく
+ if (this.selectPostChains.Count == 1)
+ this.selectPostChains.Clear();
+ return;
+ }
+
+ DetailsListView lst = (DetailsListView)tp.Tag;
+ this.ListTab.SelectedTab = tp;
+ if (idx > -1)
+ {
+ SelectListItem(lst, idx);
+ lst.EnsureVisible(idx);
+ }
+ lst.Focus();
}
}
private void PushSelectPostChain()
{
- if (this.selectPostChains.Count == 0 || (this.selectPostChains.Peek().Item1.Text != this._curTab.Text || this._curPost != this.selectPostChains.Peek().Item2))
+ int count = this.selectPostChains.Count;
+ if (count > 0)
{
- this.selectPostChains.Push(Tuple.Create(this._curTab, _curPost));
+ var p = this.selectPostChains.Peek();
+ if (p.Item1 == this._curTab)
+ {
+ if (p.Item2 == this._curPost) return; //最新の履歴と同一
+ if (p.Item2 == null) this.selectPostChains.Pop(); //置き換えるため削除
+ }
}
+ if (count >= 2500) TrimPostChain();
+ this.selectPostChains.Push(Tuple.Create(this._curTab, this._curPost));
}
private void TrimPostChain()
{
- if (this.selectPostChains.Count < 2000) return;
- Stack<Tuple<TabPage, PostClass>> p = new Stack<Tuple<TabPage, PostClass>>();
+ if (this.selectPostChains.Count <= 2000) return;
+ var p = new Stack<Tuple<TabPage, PostClass>>(2000);
for (int i = 0; i < 2000; i++)
{
p.Push(this.selectPostChains.Pop());
_cfgCommon.UseAtIdSupplement = SettingDialog.UseAtIdSupplement;
_cfgCommon.UseHashSupplement = SettingDialog.UseHashSupplement;
_cfgCommon.PreviewEnable = SettingDialog.PreviewEnable;
+ _cfgCommon.StatusAreaAtBottom = SettingDialog.StatusAreaAtBottom;
_cfgCommon.Language = SettingDialog.Language;
_cfgCommon.SortOrder = (int)_statuses.SortOrder;
_cfgCommon.AllAtReply = tw.AllAtReply;
_cfgCommon.OpenUserTimeline = SettingDialog.OpenUserTimeline;
_cfgCommon.ListCountApi = SettingDialog.ListCountApi;
- _cfgCommon.UseImageService = ImageServiceCombo.SelectedIndex;
- _cfgCommon.UseImageServiceName = this.ImageService;
+ _cfgCommon.UseImageService = ImageSelector.ServiceIndex;
+ _cfgCommon.UseImageServiceName = ImageSelector.ServiceName;
_cfgCommon.ListDoubleClickAction = SettingDialog.ListDoubleClickAction;
_cfgCommon.UserAppointUrl = SettingDialog.UserAppointUrl;
_cfgCommon.HideDuplicatedRetweets = SettingDialog.HideDuplicatedRetweets;
}
catch (WebApiException ex)
{
- var message = ex.InnerException.Message;
+ var message = ex.Message;
MessageBox.Show(this, string.Format(Properties.Resources.OpenURL_LoadFailed, message),
Properties.Resources.OpenURL_Caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
{
if (this._curPost == null) return;
- var imageUrl = this._curPost.ImageUrl;
- try
+ await this.UserPicture.SetImageFromTask(async () =>
{
- var image = await this.IconCache.DownloadImageAsync(imageUrl, force: true);
+ var imageUrl = this._curPost.ImageUrl;
- this.ClearUserPicture();
- this.UserPicture.Image = image.Clone();
- }
- catch (Exception)
- {
- this.UserPicture.ShowErrorImage();
- try
- {
- throw;
- }
- catch (HttpRequestException) { }
- catch (InvalidImageException) { }
- catch (TaskCanceledException) { }
- }
+ var image = await this.IconCache.DownloadImageAsync(imageUrl, force: true)
+ .ConfigureAwait(false);
+
+ return await image.CloneAsync()
+ .ConfigureAwait(false);
+ });
}
private void SaveOriginalSizeIconPictureToolStripMenuItem_Click(object sender, EventArgs e)
if (this.IsNetworkAvailable())
{
+ this.RefreshMuteUserIdsAsync();
GetTimeline(MyCommon.WORKERTYPE.BlockIds, 0, 0, "");
GetTimeline(MyCommon.WORKERTYPE.NoRetweetIds, 0, 0, "");
if (SettingDialog.StartupFollowers)
Match m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?<hash>.+)$");
if (m.Success)
{
- HashMgr.SetPermanentHash("#" + m.Result("${hash}"));
+ HashMgr.SetPermanentHash("#" + Uri.UnescapeDataString(m.Result("${hash}")));
HashStripSplitButton.Text = HashMgr.UseHash;
HashToggleMenuItem.Checked = true;
HashToggleToolStripMenuItem.Checked = true;
{
public Twitter tw;
public string id;
- public TwitterDataModel.User user;
+ public TwitterUser user;
}
private void GetUserInfo_DoWork(object sender, DoWorkEventArgs e)
private void doShowUserStatus(string id, bool ShowInputDialog)
{
- TwitterDataModel.User user = null;
+ TwitterUser user = null;
GetUserInfoArgs args = new GetUserInfoArgs();
if (ShowInputDialog)
{
}
}
- private void doShowUserStatus(TwitterDataModel.User user)
+ private async void doShowUserStatus(TwitterUser user)
{
- using (ShowUserInfo userinfo = new ShowUserInfo())
+ using (var userDialog = new UserInfoDialog(this, this.tw))
{
- userinfo.Owner = this;
- userinfo.User = user;
- userinfo.ShowDialog(this);
+ var showUserTask = userDialog.ShowUserAsync(user);
+ userDialog.ShowDialog(this);
+
this.Activate();
this.BringToFront();
+
+ // ユーザー情報の表示が完了するまで userDialog を破棄しない
+ await showUserTask;
}
}
this._apiGauge.BorderSides = ToolStripStatusLabelBorderSides.Right;
this.StatusStrip1.Items.Insert(2, this._apiGauge);
+ this.ImageSelector.Visible = false;
+ this.ImageSelector.Enabled = false;
+ this.ImageSelector.FilePickDialog = OpenFileDialog1;
+
this.ReplaceAppName();
}
#region "画像投稿"
private void ImageSelectMenuItem_Click(object sender, EventArgs e)
{
- if (ImageSelectionPanel.Visible)
- {
- CloseImageSelectionPanel();
- }
+ if (ImageSelector.Visible)
+ ImageSelector.EndSelection();
else
- {
- OpenImageSelectionPanel();
- ImageFromSelectedFile(true);
- ImagefilePathText.Focus();
- }
- }
-
- private void OpenImageSelectionPanel()
- {
- ImageSelectionPanel.Visible = true;
- ImageSelectionPanel.Enabled = true;
- TimelinePanel.Visible = false;
- TimelinePanel.Enabled = false;
- }
-
- private void CloseImageSelectionPanel()
- {
- ImagefilePathText.CausesValidation = false;
- TimelinePanel.Visible = true;
- TimelinePanel.Enabled = true;
- ImageSelectionPanel.Visible = false;
- ImageSelectionPanel.Enabled = false;
- ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
- ClearImageSelectedPicture(false);
- ImagefilePathText.CausesValidation = true;
+ ImageSelector.BeginSelection();
}
private void SelectMedia_DragEnter(DragEventArgs e)
{
- string filename = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
- FileInfo fl = new FileInfo(filename);
- string ext = fl.Extension;
-
- if (!string.IsNullOrEmpty(this.ImageService) &&
- this.pictureService[this.ImageService].CheckValidFilesize(ext, fl.Length))
+ if (ImageSelector.HasUploadableService(((string[])e.Data.GetData(DataFormats.FileDrop, false))[0]))
{
e.Effect = DragDropEffects.Copy;
return;
}
- foreach (string svc in ImageServiceCombo.Items)
- {
- if (!string.IsNullOrEmpty(svc) &&
- this.pictureService[svc].CheckValidFilesize(ext, fl.Length))
- {
- //ImageServiceCombo.SelectedItem = svc;
- e.Effect = DragDropEffects.Copy;
- return;
- }
- }
e.Effect = DragDropEffects.None;
}
{
this.Activate();
this.BringToFront();
- OpenImageSelectionPanel();
- ImagefilePathText.Text = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];
- ImageFromSelectedFile(false);
+ ImageSelector.BeginSelection(((string[])e.Data.GetData(DataFormats.FileDrop, false))[0]);
StatusText.Focus();
}
- private void FilePickButton_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrEmpty(this.ImageService)) return;
- OpenFileDialog1.Filter = this.pictureService[this.ImageService].GetFileOpenDialogFilter();
- OpenFileDialog1.Title = Properties.Resources.PickPictureDialog1;
- OpenFileDialog1.FileName = "";
-
- try
- {
- this.AllowDrop = false;
- if (OpenFileDialog1.ShowDialog() == DialogResult.Cancel) return;
- }
- finally
- {
- this.AllowDrop = true;
- }
-
- ImagefilePathText.Text = OpenFileDialog1.FileName;
- ImageFromSelectedFile(false);
- }
-
- private void ImagefilePathText_Validating(object sender, CancelEventArgs e)
- {
- if (ImageCancelButton.Focused)
- {
- ImagefilePathText.CausesValidation = false;
- return;
- }
-
- ImageFromSelectedFile(false);
- }
-
- private void ImageFromSelectedFile(bool suppressMsgBox)
- {
- try
- {
- ClearImageSelectedPicture(true);
-
- ImagefilePathText.Text = ImagefilePathText.Text.Trim();
- if (string.IsNullOrEmpty(ImagefilePathText.Text) || string.IsNullOrEmpty(this.ImageService))
- {
- ImagefilePathText.Text = "";
- return;
- }
-
- FileInfo fl = new FileInfo(ImagefilePathText.Text);
- string ext = fl.Extension;
- var imageService = this.pictureService[this.ImageService];
-
- if (!imageService.CheckValidExtension(ext))
- {
- //画像以外の形式
- ImagefilePathText.Text = "";
- if (!suppressMsgBox)
- {
- MessageBox.Show(
- string.Format(Properties.Resources.PostPictureWarn3, this.ImageService, MakeAvailableServiceText(ext, fl.Length), ext),
- Properties.Resources.PostPictureWarn4,
- MessageBoxButtons.OK,
- MessageBoxIcon.Warning);
- }
- return;
- }
-
- if (!imageService.CheckValidFilesize(ext, fl.Length))
- {
- // ファイルサイズが大きすぎる
- ImagefilePathText.Text = "";
- if (!suppressMsgBox)
- {
- MessageBox.Show(
- string.Format(Properties.Resources.PostPictureWarn5, this.ImageService, MakeAvailableServiceText(ext, fl.Length)),
- Properties.Resources.PostPictureWarn4,
- MessageBoxButtons.OK,
- MessageBoxIcon.Warning);
- }
- return;
- }
-
- switch (imageService.GetFileType(ext))
- {
- case MyCommon.UploadFileType.Invalid:
- ImagefilePathText.Text = "";
- break;
- case MyCommon.UploadFileType.Picture:
- Image img = null;
- using (FileStream fs = new FileStream(ImagefilePathText.Text, FileMode.Open, FileAccess.Read))
- {
- img = Image.FromStream(fs);
- }
- ImageSelectedPicture.Image = (new HttpVarious()).CheckValidImage(
- img,
- img.Width,
- img.Height);
- ImageSelectedPicture.Tag = MyCommon.UploadFileType.Picture;
- break;
- case MyCommon.UploadFileType.MultiMedia:
- ImageSelectedPicture.Image = Properties.Resources.MultiMediaImage;
- ImageSelectedPicture.Tag = MyCommon.UploadFileType.MultiMedia;
- break;
- default:
- ImagefilePathText.Text = "";
- break;
- }
- }
- catch (FileNotFoundException)
- {
- ClearImageSelectedPicture(true);
- ImagefilePathText.Text = "";
- if (!suppressMsgBox) MessageBox.Show("File not found.");
- }
- catch (Exception)
- {
- ClearImageSelectedPicture(true);
- ImagefilePathText.Text = "";
- if (!suppressMsgBox) MessageBox.Show("The type of this file is not image.");
- }
- }
-
- private string MakeAvailableServiceText(string ext, long fileSize)
+ private void ImageSelector_BeginSelecting(object sender, EventArgs e)
{
- StringBuilder sb = new StringBuilder();
-
- foreach (string svc in ImageServiceCombo.Items)
- {
- if (!string.IsNullOrEmpty(svc) &&
- this.pictureService[svc].CheckValidFilesize(ext, fileSize))
- {
- if (sb.Length > 0) sb.Append(", ");
- sb.Append(svc);
- }
- }
- if (sb.Length == 0)
- return Properties.Resources.PostPictureWarn6;
-
- return sb.ToString();
- }
-
- private void ClearImageSelectedPicture(bool invalidate)
- {
- Image oldImage = null;
- if (this.ImageSelectedPicture.Image != null)
- {
- if (this.ImageSelectedPicture.Image != ImageSelectedPicture.InitialImage &&
- this.ImageSelectedPicture.Image != Properties.Resources.MultiMediaImage)
- {
- oldImage = this.ImageSelectedPicture.Image;
- }
- }
- if (invalidate)
- {
- this.ImageSelectedPicture.Image = ImageSelectedPicture.InitialImage;
- this.ImageSelectedPicture.Tag = MyCommon.UploadFileType.Invalid;
- }
- else
- {
- this.ImageSelectedPicture.Image = null;
- this.ImageSelectedPicture.Tag = null;
- }
- if (oldImage != null) oldImage.Dispose();
- }
-
- private void ImageCancelButton_Click(object sender, EventArgs e)
- {
- CloseImageSelectionPanel();
- }
-
- private void ImageSelection_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Escape)
- {
- CloseImageSelectionPanel();
- }
- }
-
- private void ImageSelection_KeyPress(object sender, KeyPressEventArgs e)
- {
- if (Convert.ToInt32(e.KeyChar) == 0x1B)
- {
- ImagefilePathText.CausesValidation = false;
- e.Handled = true;
- }
- }
-
- private void ImageSelection_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
- {
- if (e.KeyCode == Keys.Escape)
- {
- ImagefilePathText.CausesValidation = false;
- }
- }
-
- private bool TryGetSelectedMedia(out string imageService, out string imagePath)
- {
- if (ImageSelectedPicture.Image != ImageSelectedPicture.InitialImage &&
- ImageServiceCombo.SelectedIndex > -1 &&
- !string.IsNullOrEmpty(ImagefilePathText.Text))
- {
- if (MessageBox.Show(string.Format(Properties.Resources.PostPictureConfirm1, this.ImageService),
- Properties.Resources.PostPictureConfirm2,
- MessageBoxButtons.OKCancel,
- MessageBoxIcon.Question,
- MessageBoxDefaultButton.Button1)
- == DialogResult.OK)
- {
- imageService = ImageServiceCombo.Text;
- imagePath = ImagefilePathText.Text;
- CloseImageSelectionPanel();
- ImagefilePathText.Text = "";
- return true;
- }
- }
- else
- {
- MessageBox.Show(Properties.Resources.PostPictureWarn1, Properties.Resources.PostPictureWarn2);
- }
-
- CloseImageSelectionPanel();
- imageService = null;
- imagePath = null;
- return false;
+ TimelinePanel.Visible = false;
+ TimelinePanel.Enabled = false;
}
- private void SetImageServiceCombo()
+ private void ImageSelector_EndSelecting(object sender, EventArgs e)
{
- string svc = "";
- if (ImageServiceCombo.SelectedIndex > -1) svc = ImageServiceCombo.SelectedItem.ToString();
- ImageServiceCombo.Items.Clear();
-
- // Add service names to combobox
- foreach (var key in pictureService.Keys)
- {
- ImageServiceCombo.Items.Add(key);
- }
-
- SelectImageServiceComboItem(svc);
+ TimelinePanel.Visible = true;
+ TimelinePanel.Enabled = true;
+ ((DetailsListView)ListTab.SelectedTab.Tag).Focus();
}
- private void SelectImageServiceComboItem(string svc, int? index = null)
+ private void ImageSelector_FilePickDialogOpening(object sender, EventArgs e)
{
- int idx;
- if (string.IsNullOrEmpty(svc))
- {
- idx = index ?? 0;
- }
- else
- {
- idx = ImageServiceCombo.Items.IndexOf(svc);
- if (idx == -1) idx = index ?? 0;
- }
-
- try
- {
- ImageServiceCombo.SelectedIndex = idx;
- }
- catch (ArgumentOutOfRangeException)
- {
- ImageServiceCombo.SelectedIndex = 0;
- }
+ this.AllowDrop = false;
}
- private string ImageService
+ private void ImageSelector_FilePickDialogClosed(object sender, EventArgs e)
{
- get { return ImageServiceCombo.SelectedItem.ToString(); }
+ this.AllowDrop = true;
}
- private void ImageServiceCombo_SelectedIndexChanged(object sender, EventArgs e)
+ private void ImageSelector_SelectedServiceChanged(object sender, EventArgs e)
{
- if (ImageSelectedPicture.Tag != null && !string.IsNullOrEmpty(this.ImageService))
+ if (ImageSelector.Visible)
{
- try
- {
- FileInfo fi = new FileInfo(ImagefilePathText.Text.Trim());
- string ext = fi.Extension;
- var imageService = this.pictureService[this.ImageService];
- if (!imageService.CheckValidFilesize(ext, fi.Length))
- {
- ClearImageSelectedPicture(true);
- ImagefilePathText.Text = "";
- }
- }
- catch (Exception)
- {
- ClearImageSelectedPicture(true);
- ImagefilePathText.Text = "";
- }
_modifySettingCommon = true;
SaveConfigsAll(true);
- if (this.ImageService == "Twitter")
- {
+
+ if (ImageSelector.ServiceName.Equals("Twitter"))
this.StatusText_TextChanged(null, null);
- }
}
}
- private void ImageSelectionPanel_VisibleChanged(object sender, EventArgs e)
+ private void ImageSelector_VisibleChanged(object sender, EventArgs e)
{
this.StatusText_TextChanged(null, null);
}