mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-16 09:15:47 +02:00
145 lines
6.4 KiB
C#
145 lines
6.4 KiB
C#
using CefSharp;
|
|
using System;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
using System.Windows.Forms;
|
|
using TweetDuck.Core.Bridge;
|
|
using TweetDuck.Core.Controls;
|
|
using TweetDuck.Core.Utils;
|
|
|
|
namespace TweetDuck.Core.Handling{
|
|
abstract class ContextMenuBase : IContextMenuHandler{
|
|
private static readonly Lazy<Regex> RegexTwitterAccount = new Lazy<Regex>(() => new Regex(@"^https?://twitter\.com/([^/]+)/?$", RegexOptions.Compiled), false);
|
|
protected static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak"));
|
|
|
|
private const int MenuOpenLinkUrl = 26500;
|
|
private const int MenuCopyLinkUrl = 26501;
|
|
private const int MenuCopyUsername = 26502;
|
|
private const int MenuOpenImage = 26503;
|
|
private const int MenuSaveImage = 26504;
|
|
private const int MenuCopyImageUrl = 26505;
|
|
private const int MenuOpenDevTools = 26599;
|
|
|
|
private readonly Form form;
|
|
|
|
protected ContextMenuBase(Form form){
|
|
this.form = form;
|
|
}
|
|
|
|
public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
|
if (parameters.TypeFlags.HasFlag(ContextMenuType.Link) && !parameters.UnfilteredLinkUrl.EndsWith("tweetdeck.twitter.com/#", StringComparison.Ordinal)){
|
|
if (RegexTwitterAccount.Value.IsMatch(parameters.UnfilteredLinkUrl)){
|
|
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open account in browser");
|
|
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy account address");
|
|
model.AddItem((CefMenuCommand)MenuCopyUsername, "Copy account username");
|
|
}
|
|
else{
|
|
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open link in browser");
|
|
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy link address");
|
|
}
|
|
|
|
model.AddSeparator();
|
|
}
|
|
|
|
if (parameters.TypeFlags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents){
|
|
model.AddItem((CefMenuCommand)MenuOpenImage, "Open image in browser");
|
|
model.AddItem((CefMenuCommand)MenuSaveImage, "Save image as...");
|
|
model.AddItem((CefMenuCommand)MenuCopyImageUrl, "Copy image address");
|
|
model.AddSeparator();
|
|
}
|
|
}
|
|
|
|
public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
|
switch((int)commandId){
|
|
case MenuOpenLinkUrl:
|
|
BrowserUtils.OpenExternalBrowser(parameters.LinkUrl);
|
|
break;
|
|
|
|
case MenuCopyLinkUrl:
|
|
SetClipboardText(string.IsNullOrEmpty(TweetDeckBridge.LastRightClickedLink) ? parameters.UnfilteredLinkUrl : TweetDeckBridge.LastRightClickedLink);
|
|
break;
|
|
|
|
case MenuOpenImage:
|
|
BrowserUtils.OpenExternalBrowser(parameters.SourceUrl);
|
|
break;
|
|
|
|
case MenuSaveImage:
|
|
string fileName = GetImageFileName(parameters.SourceUrl);
|
|
string extension = Path.GetExtension(fileName);
|
|
string saveTarget;
|
|
|
|
using(SaveFileDialog dialog = new SaveFileDialog{
|
|
AutoUpgradeEnabled = true,
|
|
OverwritePrompt = true,
|
|
Title = "Save image",
|
|
FileName = fileName,
|
|
Filter = "Image ("+(string.IsNullOrEmpty(extension) ? "unknown" : extension)+")|*.*"
|
|
}){
|
|
saveTarget = dialog.ShowDialog() == DialogResult.OK ? dialog.FileName : null;
|
|
}
|
|
|
|
if (saveTarget != null){
|
|
BrowserUtils.DownloadFileAsync(parameters.SourceUrl, saveTarget, null, ex => {
|
|
MessageBox.Show("An error occurred while downloading the image: "+ex.Message, Program.BrandName+" Has Failed :(", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
});
|
|
}
|
|
|
|
break;
|
|
|
|
case MenuCopyImageUrl:
|
|
SetClipboardText(parameters.SourceUrl);
|
|
break;
|
|
|
|
case MenuCopyUsername:
|
|
Match match = RegexTwitterAccount.Value.Match(parameters.UnfilteredLinkUrl);
|
|
SetClipboardText(match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
|
break;
|
|
|
|
case MenuOpenDevTools:
|
|
browserControl.ShowDevTools();
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public virtual void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){}
|
|
|
|
public virtual bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback){
|
|
return false;
|
|
}
|
|
|
|
protected void SetClipboardText(string text){
|
|
form.InvokeAsyncSafe(() => WindowsUtils.SetClipboard(text, TextDataFormat.UnicodeText));
|
|
}
|
|
|
|
protected static void AddDebugMenuItems(IMenuModel model){
|
|
model.AddItem((CefMenuCommand)MenuOpenDevTools, "Open dev tools");
|
|
}
|
|
|
|
protected static void RemoveSeparatorIfLast(IMenuModel model){
|
|
if (model.Count > 0 && model.GetTypeAt(model.Count-1) == MenuItemType.Separator){
|
|
model.RemoveAt(model.Count-1);
|
|
}
|
|
}
|
|
|
|
protected static void AddSeparator(IMenuModel model){
|
|
if (model.Count > 0 && model.GetTypeAt(model.Count-1) != MenuItemType.Separator){ // do not add separators if there is nothing to separate
|
|
model.AddSeparator();
|
|
}
|
|
}
|
|
|
|
private static string GetImageFileName(string url){
|
|
// twimg adds a colon after file extension
|
|
int dot = url.LastIndexOf('.');
|
|
|
|
if (dot != -1){
|
|
url = StringUtils.ExtractBefore(url, ':', dot);
|
|
}
|
|
|
|
// return file name
|
|
return BrowserUtils.GetFileNameFromUrl(url) ?? "unknown";
|
|
}
|
|
}
|
|
}
|