private bool CheckForHyperLink(string line, AcePosition pos) { var matches = HrefRegex.Matches(line); if (matches.Count > 0) { foreach (Match match in matches) { string val = match.Value; if (match.Index <= pos.column && match.Index + val.Length > pos.column) { var url = StringUtils.ExtractString(val, "](", ")"); var editorSyntax = mmFileUtils.GetEditorSyntaxFromFileType(url); MenuItem mi2; if (url.Contains("(http")) { mi2 = new MenuItem { Header = "Navigate Hyperlink" }; mi2.Click += (o, args) => { if (!string.IsNullOrEmpty(url)) { try { ShellUtils.GoUrl(url); } catch { Model.Window.ShowStatusError("Invalid link: Couldn't navigate to " + url); } } }; ContextMenu.Items.Add(mi2); } else if (!string.IsNullOrEmpty(editorSyntax)) { mi2 = new MenuItem { Header = "Open Document in new Tab" }; mi2.Click += (o, args) => { if (!string.IsNullOrEmpty(url)) { if (!url.Contains(":/")) { url = Path.Combine(Path.GetDirectoryName(Model.ActiveDocument.Filename), url); } try { Model.Window.ActivateTab(url, openIfNotFound: true); } catch { Model.Window.ShowStatusError("Invalid link: Couldn't open " + url); } } }; ContextMenu.Items.Add(mi2); } mi2 = new MenuItem { Header = "Edit Hyperlink" }; mi2.Click += (o, args) => { Model.ActiveEditor.AceEditor.SetSelectionRange(pos.row, match.Index, pos.row, match.Index + val.Length); Model.ActiveEditor.EditorSelectionOperation("hyperlink", val); }; ContextMenu.Items.Add(mi2); if (val.Contains("](#")) { mi2 = new MenuItem { Header = "Jump to Anchor" }; mi2.Click += (o, args) => { var anchor = StringUtils.ExtractString(val, "](#", ")"); var docModel = new DocumentOutlineModel(); int lineNo = docModel.FindHeaderHeadline(Model.ActiveEditor?.GetMarkdown(), anchor); if (lineNo != -1) { Model.ActiveEditor.GotoLine(lineNo); } }; ContextMenu.Items.Add(mi2); } var mi = new MenuItem { Header = "Remove Hyperlink" }; mi.Click += (o, args) => { Model.ActiveEditor.AceEditor.SetSelectionRange(pos.row, match.Index, pos.row, match.Index + val.Length); string text = StringUtils.ExtractString(val, "[", "]"); Model.ActiveEditor.SetSelection(text); }; ContextMenu.Items.Add(mi); return(true); } } } return(false); }
/// <summary> /// Creates a context menu. /// </summary> /// <param name="parms"></param> /// <param name="model"></param> /// <param name="webBrowser"></param> public void ShowContextMenu(PositionAndDocumentType parms, AppModel model, WebBrowser webBrowser) { var ctm = new ContextMenu(); var mi = new MenuItem() { Header = "View in Web _Browser", Command = model.Commands.ViewInExternalBrowserCommand, InputGestureText = model.Commands.ViewInExternalBrowserCommand.KeyboardShortcut }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Refresh _Browser", Command = model.Commands.RefreshPreviewCommand, InputGestureText = "F5" }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "View Html _Source", Command = model.Commands.ViewHtmlSourceCommand }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); mi = new MenuItem() { Header = "Save As _Html", Command = model.Commands.SaveAsHtmlCommand, }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Save As _Pdf", Command = model.Commands.GeneratePdfCommand, }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "P_rint...", Command = model.Commands.PrintPreviewCommand, }; ctm.Items.Add(mi); bool separatorAdded = false; if (!string.IsNullOrEmpty(parms.Id)) { ctm.Items.Add(new Separator()); separatorAdded = true; mi = new MenuItem() { Header = "Copy Id to Clipboard: #" + parms.Id, }; mi.Click += (s, e) => { ClipboardHelper.SetText("#" + parms.Id); }; ctm.Items.Add(mi); } if (!string.IsNullOrEmpty(parms.Src)) { if (!separatorAdded) { ctm.Items.Add(new Separator()); separatorAdded = true; } mi = new MenuItem() { Header = "Edit Image in Image editor" }; mi.Click += (o, args) => { var image = HttpUtility.UrlDecode(parms.Src.Replace("file:///", "")); image = mmFileUtils.NormalizeFilenameWithBasePath(image, Path.GetDirectoryName(model.ActiveDocument.Filename)); mmFileUtils.OpenImageInImageEditor(image); }; ctm.Items.Add(mi); } if (!string.IsNullOrEmpty(parms.Href)) { // Navigate relative hash links in the document if (parms.Href.StartsWith("#") && parms.Href.Length > 1) { if (!separatorAdded) { ctm.Items.Add(new Separator()); separatorAdded = true; } var docModel = new DocumentOutlineModel(); int lineNo = docModel.FindHeaderHeadline(model.ActiveEditor?.GetMarkdown(), parms.Href?.Substring(1)); if (lineNo > -1) { mi = new MenuItem() { Header = "Jump to: " + parms.Href, CommandParameter = parms.Href.Substring(1) }; mi.Click += (s, e) => { var mitem = s as MenuItem; var anchor = mitem.CommandParameter as string; if (string.IsNullOrEmpty(anchor)) { return; } docModel = new DocumentOutlineModel(); lineNo = docModel.FindHeaderHeadline(model.ActiveEditor?.GetMarkdown(), anchor); if (lineNo != -1) { model.ActiveEditor.GotoLine(lineNo); } }; ctm.Items.Add(mi); } } } ctm.Items.Add(new Separator()); mi = new MenuItem() { Header = "Edit Preview _Theme", Command = model.Commands.EditPreviewThemeCommand, }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Configure Preview Syncing", Command = model.Commands.PreviewSyncModeCommand, }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); mi = new MenuItem() { Header = "Toggle Preview Window", Command = model.Commands.TogglePreviewBrowserCommand, IsCheckable = true, InputGestureText = model.Commands.TogglePreviewBrowserCommand.KeyboardShortcut, IsChecked = model.IsPreviewBrowserVisible }; ctm.Items.Add(mi); webBrowser.ContextMenu = ctm; ctm.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint; ctm.PlacementTarget = webBrowser; ctm.IsOpen = true; }
private bool CheckForHyperLink(string line, AcePosition pos) { var matches = HrefRegex.Matches(line); if (matches.Count > 0) { foreach (Match match in matches) { string val = match.Value; if (match.Index <= pos.column && match.Index + val.Length > pos.column) { var mi2 = new MenuItem { Header = "Edit Hyperlink" }; mi2.Click += (o, args) => { Model.ActiveEditor.AceEditor.SetSelectionRange(pos.row, match.Index, pos.row, match.Index + val.Length); Model.ActiveEditor.EditorSelectionOperation("hyperlink", val); }; ContextMenu.Items.Add(mi2); if (val.Contains("](#")) { mi2 = new MenuItem { Header = "Jump to Anchor" }; mi2.Click += (o, args) => { var anchor = StringUtils.ExtractString(val, "](#", ")"); var docModel = new DocumentOutlineModel(); int lineNo = docModel.FindHeaderHeadline(Model.ActiveEditor?.GetMarkdown(), anchor); if (lineNo != -1) { Model.ActiveEditor.GotoLine(lineNo); } }; ContextMenu.Items.Add(mi2); } var mi = new MenuItem { Header = "Remove Hyperlink" }; mi.Click += (o, args) => { Model.ActiveEditor.AceEditor.SetSelectionRange(pos.row, match.Index, pos.row, match.Index + val.Length); string text = StringUtils.ExtractString(val, "[", "]"); Model.ActiveEditor.SetSelection(text); }; ContextMenu.Items.Add(mi); return(true); } } } return(false); }
/// <summary> /// Creates a context menu. /// </summary> /// <param name="parms"></param> /// <param name="model"></param> /// <param name="webBrowser"></param> public void ShowContextMenu(PositionAndDocumentType parms, AppModel model, WebBrowser webBrowser) { var ctm = new ContextMenu(); MenuItem mi; // Image Selected if (!string.IsNullOrEmpty(parms.Src)) { mi = new MenuItem() { Header = "Copy Image to Clipboard" }; mi.Click += (o, args) => { string image = null; bool deleteFile = false; if (parms.Src.StartsWith("https://") || parms.Src.StartsWith("http://")) { image = HttpUtils.DownloadImageToFile(parms.Src); if (string.IsNullOrEmpty(image)) { model.Window.ShowStatusError("Unable to copy image from URL to clipboard: " + parms.Src); return; } deleteFile = true; } else { try { image = new Uri(parms.Src).LocalPath; } catch { image = FileUtils.NormalizePath(parms.Src); } image = mmFileUtils.NormalizeFilenameWithBasePath(image, Path.GetDirectoryName(model.ActiveDocument.Filename)); } try { BitmapSource bmpSrc; using (var bmp = new Bitmap(image)) { bmpSrc = WindowUtilities.BitmapToBitmapSource(bmp); Clipboard.SetImage(bmpSrc); } model.Window.ShowStatusSuccess("Image copied to clipboard."); } catch (Exception ex) { model.Window.ShowStatusError("Couldn't copy image to clipboard: " + ex.Message); } finally { if (deleteFile && File.Exists(image)) { File.Delete(image); } } }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Edit Image in Image editor" }; mi.Click += (o, args) => { string image = null; if (parms.Src.StartsWith("https://") || parms.Src.StartsWith("http://")) { image = HttpUtils.DownloadImageToFile(parms.Src); if (string.IsNullOrEmpty(image)) { model.Window.ShowStatusError("Unable to copy image from URL to clipboard: " + parms.Src); return; } } else { try { image = new Uri(parms.Src).LocalPath; } catch { image = FileUtils.NormalizePath(parms.Src); } image = mmFileUtils.NormalizeFilenameWithBasePath(image, Path.GetDirectoryName(model.ActiveDocument.Filename)); } mmFileUtils.OpenImageInImageEditor(image); }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); } // HREF link selected if (!string.IsNullOrEmpty(parms.Href)) { // Navigate relative hash links in the document if (parms.Href.StartsWith("#") && parms.Href.Length > 1) { var docModel = new DocumentOutlineModel(); int lineNo = docModel.FindHeaderHeadline(model.ActiveEditor?.GetMarkdown(), parms.Href?.Substring(1)); if (lineNo > -1) { mi = new MenuItem() { Header = "Jump to: " + parms.Href, CommandParameter = parms.Href.Substring(1) }; mi.Click += (s, e) => { var mitem = s as MenuItem; var anchor = mitem.CommandParameter as string; if (string.IsNullOrEmpty(anchor)) { return; } docModel = new DocumentOutlineModel(); lineNo = docModel.FindHeaderHeadline(model.ActiveEditor?.GetMarkdown(), anchor); if (lineNo != -1) { model.ActiveEditor.GotoLine(lineNo); } }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); } } } // ID to clipboard if (!string.IsNullOrEmpty(parms.Id)) { mi = new MenuItem() { Header = "Copy Id to Clipboard: #" + parms.Id, }; mi.Click += (s, e) => { ClipboardHelper.SetText("#" + parms.Id); model.Window.ShowStatusSuccess("'#" + parms.Id + "' copied to the clipboard."); }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); } mi = new MenuItem() { Header = "View in Web _Browser", Command = model.Commands.ViewInExternalBrowserCommand, InputGestureText = model.Commands.ViewInExternalBrowserCommand.KeyboardShortcut }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Refresh _Browser", Command = model.Commands.RefreshPreviewCommand, InputGestureText = "F5" }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "View Html _Source", Command = model.Commands.ViewHtmlSourceCommand }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); mi = new MenuItem() { Header = "Save As _Html", Command = model.Commands.SaveAsHtmlCommand, }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Save As _PDF", Command = model.Commands.GeneratePdfCommand, }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "P_rint...", Command = model.Commands.PrintPreviewCommand, }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); mi = new MenuItem() { Header = "Edit Preview _Theme", Command = model.Commands.EditPreviewThemeCommand, }; ctm.Items.Add(mi); mi = new MenuItem() { Header = "Configure Preview Syncing", Command = model.Commands.PreviewSyncModeCommand, }; ctm.Items.Add(mi); ctm.Items.Add(new Separator()); mi = new MenuItem() { Header = "Toggle Preview Window", Command = model.Commands.TogglePreviewBrowserCommand, IsCheckable = true, InputGestureText = model.Commands.TogglePreviewBrowserCommand.KeyboardShortcut, IsChecked = model.IsPreviewBrowserVisible }; ctm.Items.Add(mi); webBrowser.ContextMenu = ctm; ContextMenuOpening?.Invoke(this, ctm); ctm.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint; ctm.PlacementTarget = webBrowser; ctm.IsOpen = true; }