using CefSharp; using System; using System.IO; using System.Windows.Forms; using TweetDck.Core.Bridge; using TweetDck.Core.Controls; using TweetDck.Core.Utils; namespace TweetDck.Core.Handling{ abstract class ContextMenuBase : IContextMenuHandler{ private const int MenuOpenLinkUrl = 26500; private const int MenuCopyLinkUrl = 26501; private const int MenuOpenImage = 26502; private const int MenuSaveImage = 26503; private const int MenuCopyImageUrl = 26504; #if DEBUG private const int MenuOpenDevTools = 26599; protected void AddDebugMenuItems(IMenuModel model){ model.AddItem((CefMenuCommand)MenuOpenDevTools, "Open dev tools"); } #endif 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)){ 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, 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; #if DEBUG case MenuOpenDevTools: browserControl.ShowDevTools(); break; #endif } 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 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){ int colon = url.IndexOf(':', dot); if (colon != -1){ url = url.Substring(0, colon); } } // return file name return BrowserUtils.GetFileNameFromUrl(url) ?? "unknown"; } } }