<Compile Include="Thumbnail\Services\SimpleThumbnailServiceTest.cs" />
<Compile Include="Thumbnail\Services\TinamiTest.cs" />
<Compile Include="ToolStripAPIGaugeTest.cs" />
+ <Compile Include="TweenMainText.cs" />
<Compile Include="TweetFormatterTest.cs" />
<Compile Include="TweetThumbnailTest.cs" />
<Compile Include="TwitterTest.cs" />
--- /dev/null
+// OpenTween - Client of Twitter
+// Copyright (c) 2014 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using Xunit;
+using Xunit.Extensions;
+
+namespace OpenTween
+{
+ public class TweenMainText
+ {
+ [Fact]
+ public void GetUrlFromDataObject_XMozUrlTest()
+ {
+ var dataBytes = Encoding.Unicode.GetBytes("https://twitter.com/\nTwitter\0");
+ using (var memstream = new MemoryStream(dataBytes))
+ {
+ var data = new DataObject("text/x-moz-url", memstream);
+
+ var expected = new Tuple<string, string>("https://twitter.com/", "Twitter");
+ Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data));
+ }
+ }
+
+ [Fact]
+ public void GetUrlFromDataObject_IESiteModeToUrlTest()
+ {
+ var dataBytes = Encoding.Unicode.GetBytes("https://twitter.com/\0Twitter\0");
+ using (var memstream = new MemoryStream(dataBytes))
+ {
+ var data = new DataObject("IESiteModeToUrl", memstream);
+
+ var expected = new Tuple<string, string>("https://twitter.com/", "Twitter");
+ Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data));
+ }
+ }
+
+ [Fact]
+ public void GetUrlFromDataObject_UniformResourceLocatorWTest()
+ {
+ var dataBytes = Encoding.Unicode.GetBytes("https://twitter.com/\0");
+ using (var memstream = new MemoryStream(dataBytes))
+ {
+ var data = new DataObject("UniformResourceLocatorW", memstream);
+
+ var expected = new Tuple<string, string>("https://twitter.com/", null);
+ Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data));
+ }
+ }
+
+ [Fact]
+ public void GetUrlFromDataObject_UnknownFormatTest()
+ {
+ using (var memstream = new MemoryStream(new byte[0]))
+ {
+ var data = new DataObject("application/x-hogehoge", memstream);
+
+ Assert.Throws<NotSupportedException>(() => TweenMain.GetUrlFromDataObject(data));
+ }
+ }
+ }
+}
* NEW: ファイルメニューに「ツイートURLを開く」を追加
- https://twitter.com/*****/statuses/1234567890 のような形式のURLを直接開くことが出来ます
* NEW: プロフィール画像の右クリックメニューに「再読み込み」を追加
+ * NEW: ブラウザからのD&Dに対応 (Firefox, Chrome で動作します)
+ - アドレスバーの Favicon やリンクなどを D&D すると投稿欄にURLとタイトルが入力されます
* CHG: 投稿するツイートの末尾の全角スペースを除去しない
* FIX: サムネイル画像の取得をキャンセルするとエラーが発生する場合がある問題の修正
* FIX: サムネイル画像の読み込み中に画面の更新が遅くなる問題の修正
this.BringToFront();
StatusText.Focus();
}
+ else if (e.Data.GetDataPresent("UniformResourceLocatorW"))
+ {
+ var url = GetUrlFromDataObject(e.Data);
+
+ if (url.Item2 == null)
+ this.StatusText.Text += " / " + url.Item1;
+ else
+ this.StatusText.Text += " / " + url.Item2 + " " + url.Item1;
+ }
else if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
string data = (string)e.Data.GetData(DataFormats.StringFormat, true);
}
}
+ /// <summary>
+ /// IDataObject から URL とタイトルの対を取得します
+ /// </summary>
+ /// <remarks>
+ /// タイトルのみ取得できなかった場合は Value2 が null のタプルを返すことがあります。
+ /// </remarks>
+ /// <exception cref="ArgumentException">不正なフォーマットが入力された場合</exception>
+ /// <exception cref="NotSupportedException">サポートされていないデータが入力された場合</exception>
+ internal static Tuple<string, string> GetUrlFromDataObject(IDataObject data)
+ {
+ if (data.GetDataPresent("text/x-moz-url"))
+ {
+ // Firefox, Google Chrome で利用可能
+ // 参照: https://developer.mozilla.org/ja/docs/DragDrop/Recommended_Drag_Types
+
+ using (var stream = (MemoryStream)data.GetData("text/x-moz-url"))
+ {
+ var lines = Encoding.Unicode.GetString(stream.ToArray()).TrimEnd('\0').Split('\n');
+ if (lines.Length < 2)
+ throw new ArgumentException("不正な text/x-moz-url フォーマットです", "data");
+
+ return new Tuple<string, string>(lines[0], lines[1]);
+ }
+ }
+ else if (data.GetDataPresent("IESiteModeToUrl"))
+ {
+ // Internet Exproler 用
+ // 保護モードが有効なデフォルトの IE では DragDrop イベントが発火しないため使えない
+
+ using (var stream = (MemoryStream)data.GetData("IESiteModeToUrl"))
+ {
+ var lines = Encoding.Unicode.GetString(stream.ToArray()).TrimEnd('\0').Split('\0');
+ if (lines.Length < 2)
+ throw new ArgumentException("不正な IESiteModeToUrl フォーマットです", "data");
+
+ return new Tuple<string, string>(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);
+ }
+ }
+
+ throw new NotSupportedException("サポートされていないデータ形式です: " + data.GetFormats()[0]);
+ }
+
private void TweenMain_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
}
e.Effect = DragDropEffects.None;
}
+ else if (e.Data.GetDataPresent("UniformResourceLocatorW"))
+ {
+ e.Effect = DragDropEffects.Copy;
+ }
else if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
e.Effect = DragDropEffects.Copy;