private void MenuOpenInRemote_Click(object sender, RoutedEventArgs e)
        {
            var selected = ListChangedItems.SelectedItem as RepositoryStatusItem;

            if (selected == null)
            {
                return;
            }

            using (var repo = CommitModel.GitHelper.OpenRepository(CommitModel.Filename))
            {
                var remoteUrl = repo?.Network.Remotes.FirstOrDefault()?.Url;
                if (remoteUrl == null)
                {
                    return;
                }
                remoteUrl = remoteUrl.Replace(".git", "");

                remoteUrl += "/blob/master/" + selected.Filename;

                StatusBar.ShowStatus("Opening Url: " + remoteUrl);
                ShellUtils.GoUrl(remoteUrl);
            }
        }
Esempio n. 2
0
        private void MenuOpenInExplorer_Click(object sender, RoutedEventArgs e)
        {
            string folder = FolderPath;

            var selected = TreeFolderBrowser.SelectedItem as PathItem;

            if (selected != null)
            {
                folder = selected.FullPath; // Path.GetDirectoryName(selected.FullPath);
            }
            if (string.IsNullOrEmpty(folder))
            {
                return;
            }

            if (selected == null || selected.IsFolder)
            {
                ShellUtils.GoUrl(folder);
            }
            else
            {
                Process.Start("explorer.exe", "/select,\"" + folder + "\"");
            }
        }
        public void MenuOpenInExplorer_Click(object sender, RoutedEventArgs e)
        {
            string folder = Sidebar.FolderPath;

            var selected = TreeFolderBrowser.SelectedItem as PathItem;

            if (selected != null)
            {
                folder = selected.FullPath;     // Path.GetDirectoryName(selected.FullPath);
            }
            if (string.IsNullOrEmpty(folder))
            {
                return;
            }

            if (selected == null || selected.IsFolder)
            {
                ShellUtils.GoUrl(folder);
            }
            else
            {
                ShellUtils.OpenFileInExplorer(folder);
            }
        }
Esempio n. 4
0
        public void BitmapWpfPngSaveTest()
        {
            Assert.IsTrue(System.Windows.Clipboard.ContainsImage(), "No image on clipboard");



            var bmpSource = System.Windows.Clipboard.GetImage();

            using (var fileStream = new FileStream(TempImagePath, FileMode.Create))
            {
                BitmapEncoder encoder = null;
                encoder = new PngBitmapEncoder();

                encoder.Frames.Add(BitmapFrame.Create(bmpSource));
                encoder.Save(fileStream);

                //if (ext == ".png")
                //    mmFileUtils.OptimizePngImage(sd.FileName,5); // async
            }
            Assert.IsTrue(File.Exists(TempImagePath));


            ShellUtils.GoUrl(TempImagePath);
        }
        public void CreateAndAddRemoteTest()
        {
            var path = @"c:\temp\GithubRepos\testRepo2";

            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }

            var  gh     = new GitHelper();
            bool result = gh.CreateRepository(path, "*.saved.md\r\n*.bak\r\n*.tmp");

            Assert.IsTrue(result);
            Assert.IsTrue(Directory.Exists(path));


            var fileToAdd = Path.Combine(path, "test.txt");

            File.WriteAllText(fileToAdd, "test");

            var list = new ObservableCollection <RepositoryStatusItem>()
            {
                new RepositoryStatusItem {
                    Filename = fileToAdd
                }
            };

            gh.OpenRepository(path);
            Assert.IsTrue(gh.Commit(list, "first commit", "ras", "*****@*****.**"), gh.ErrorMessage);

            Assert.IsTrue(gh.AddRemote("https://github.com/RickStrahl/Test5.git", "origin"), gh.ErrorMessage);

            Assert.IsTrue(gh.Push(path, "master"), gh.ErrorMessage);

            ShellUtils.OpenFileInExplorer(path);
        }
        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);
        }
Esempio n. 7
0
 private void WestWindIcon_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
 {
     ShellUtils.GoUrl("http://weblog.west-wind.com");
 }
Esempio n. 8
0
 private void Hyperlink_UrlNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
 {
     ShellUtils.GoUrl("https://markdownmonster.west-wind.com/docs/_4rg0qzg1i.htm");
 }
Esempio n. 9
0
 private void ButtonHelp_Click(object sender, RoutedEventArgs e)
 {
     ShellUtils.GoUrl("https://markdownmonster.west-wind.com/docs/_4nk01yq6q.htm");
 }
Esempio n. 10
0
 /// <summary>
 /// Navigates browser to the Git Web download location
 /// </summary>
 public static void GotoGitDownload()
 {
     ShellUtils.GoUrl("https://git-scm.com/download/win");
 }
Esempio n. 11
0
        public override async void Publish()
        {
            if (!ValidateInput())
            {
                Debug.WriteLine("Invalid input cancelled the operation.");
                return;
            }

            var project = _publishDialog.Project;

            try
            {
                ShellUtils.SaveAllFiles();

                var context = new GCloudContext
                {
                    CredentialsPath = CredentialsStore.Default.CurrentAccountPath,
                    ProjectId       = CredentialsStore.Default.CurrentProjectId,
                    AppName         = GoogleCloudExtensionPackage.ApplicationName,
                    AppVersion      = GoogleCloudExtensionPackage.ApplicationVersion,
                };
                var options = new AppEngineFlexDeployment.DeploymentOptions
                {
                    Version = Version,
                    Promote = Promote,
                    Context = context
                };

                GcpOutputWindow.Activate();
                GcpOutputWindow.Clear();
                GcpOutputWindow.OutputLine(String.Format(Resources.GcePublishStepStartMessage, project.Name));

                _publishDialog.FinishFlow();

                AppEngineFlexDeploymentResult result;
                using (var frozen = StatusbarHelper.Freeze())
                    using (var animationShown = StatusbarHelper.ShowDeployAnimation())
                        using (var progress = StatusbarHelper.ShowProgressBar(Resources.FlexPublishProgressMessage))
                            using (var deployingOperation = ShellUtils.SetShellUIBusy())
                            {
                                result = await AppEngineFlexDeployment.PublishProjectAsync(
                                    project.FullPath,
                                    options,
                                    progress,
                                    GcpOutputWindow.OutputLine);
                            }

                if (result != null)
                {
                    GcpOutputWindow.OutputLine(String.Format(Resources.FlexPublishSuccessMessage, project.Name));
                    StatusbarHelper.SetText(Resources.PublishSuccessStatusMessage);

                    var url = result.GetDeploymentUrl();
                    GcpOutputWindow.OutputLine(String.Format(Resources.PublishUrlMessage, url));
                    if (OpenWebsite)
                    {
                        Process.Start(url);
                    }
                }
                else
                {
                    GcpOutputWindow.OutputLine(String.Format(Resources.FlexPublishFailedMessage, project.Name));
                    StatusbarHelper.SetText(Resources.PublishFailureStatusMessage);
                }
            }
            catch (Exception ex) when(!ErrorHandlerUtils.IsCriticalException(ex))
            {
                GcpOutputWindow.OutputLine(String.Format(Resources.FlexPublishFailedMessage, project.Name));
                StatusbarHelper.SetText(Resources.PublishFailureStatusMessage);
            }
        }
 private OpenGitFile()
 {
     ShellUtils.RegisterWindowCloseEventHandler(OnWindowClose);
 }
        /// <summary>
        ///
        /// mm htmltomarkdown [inputfile] [outputFile] -open
        /// </summary>
        /// <param name="inputFile"></param>
        /// <param name="outputFile"></param>
        /// <param name="openOutputFile"></param>
        public void HtmlToMarkdown()
        {
            Processor.ConsoleHeader();
            string inputFile  = Arguments.InputFile;
            string outputFile = Arguments.OutputFile;

            if (string.IsNullOrEmpty(inputFile) || !File.Exists(inputFile))
            {
                var fd = new OpenFileDialog
                {
                    DefaultExt = ".html",
                    Filter     = "HTML files (*.html, *.htm)|*.html;*.htm|" +
                                 "All files (*.*)|*.*",
                    CheckFileExists  = true,
                    RestoreDirectory = true,
                    Title            = "Open HTML File",
                    InitialDirectory = Environment.CurrentDirectory
                };
                var res = fd.ShowDialog();
                if (res == null)
                {
                    return;
                }
                inputFile = fd.FileName;
            }

            if (string.IsNullOrEmpty(outputFile))
            {
                var fd = new SaveFileDialog
                {
                    DefaultExt = ".md",
                    Filter     = "Markdown files (*.md,*.markdown,*.mdcrypt)|*.md;*.markdown;*.mdcrypt|" +
                                 "All files (*.*)|*.*",
                    CheckFileExists  = false,
                    RestoreDirectory = true,
                    Title            = "Save as Markdown File",
                    InitialDirectory = Path.GetDirectoryName(inputFile),
                    FileName         = Path.ChangeExtension(Path.GetFileName(inputFile), "md")
                };
                var res = fd.ShowDialog();
                if (res == null)
                {
                    return;
                }
                outputFile = fd.FileName;
            }


            string md;

            try
            {
                var html = File.ReadAllText(inputFile);
                md = MarkdownUtilities.HtmlToMarkdown(html, true);
            }
            catch
            {
                ColorConsole.WriteError("Failed: Couldn't read input file.");
                Processor.ConsoleFooter();
                return;
            }


            if (!string.IsNullOrEmpty(outputFile))
            {
                try
                {
                    File.WriteAllText(outputFile, md);
                }
                catch
                {
                    ColorConsole.WriteError("Failed: Couldn't write output file.");
                    Processor.ConsoleFooter();
                    return;
                }

                if (Arguments.OpenOutputFile)
                {
                    ShellUtils.ExecuteProcess("markdownmonster.exe", $"'{outputFile}'");
                }


                ColorConsole.WriteSuccess($"Created Markdown file: {outputFile}");

                Processor.ConsoleFooter();
            }
        }
        /// <summary>
        ///
        /// mm markdowntohtml <inputfile> <outputFile> <rendermode> -open
        /// </summary>
        /// <param name="inputFile"></param>
        /// <param name="outputFile"></param>
        /// <param name="openOutputFile"></param>
        /// <param name="fileMode">html,packagedhtml,zip</param>
        public void MarkdownToHtml()
        {
            Processor.ConsoleHeader();

            string inputFile  = Arguments.InputFile;
            string outputFile = Arguments.OutputFile;

            if (string.IsNullOrEmpty(inputFile) || !File.Exists(inputFile))
            {
                var fd = new OpenFileDialog
                {
                    DefaultExt = ".md",
                    Filter     = "Markdown files (*.md,*.markdown)|*.md;*.markdown|" +
                                 "All files (*.*)|*.*",
                    CheckFileExists  = true,
                    RestoreDirectory = true,
                    Title            = "Open Markdown File",
                    InitialDirectory = Environment.CurrentDirectory
                };
                var res = fd.ShowDialog();
                if (res == null)
                {
                    return;
                }
                inputFile = fd.FileName;
            }

            if (string.IsNullOrEmpty(outputFile))
            {
                var fd = new SaveFileDialog
                {
                    DefaultExt = ".html",
                    Filter     = "HTML files (*.html,*.htm)|*.html;*.htm|" +
                                 "All files (*.*)|*.*",
                    CheckFileExists  = false,
                    RestoreDirectory = true,
                    Title            = "Save as HTML File",
                    InitialDirectory = Path.GetDirectoryName(inputFile),
                    FileName         = Path.ChangeExtension(Path.GetFileName(inputFile), "html")
                };
                var res = fd.ShowDialog();
                if (res == null)
                {
                    return;
                }
                outputFile = fd.FileName;
            }

            string html;
            var    doc = new MarkdownDocument();

            if (!string.IsNullOrEmpty(Arguments.Theme))
            {
                mmApp.Configuration.PreviewTheme = Arguments.Theme;
            }

            try
            {
                if (!doc.Load(inputFile))
                {
                    throw new AccessViolationException();
                }
            }
            catch
            {
                ColorConsole.WriteError("Failed: Couldn't read input file.");
                Processor.ConsoleFooter();
                return;
            }

            try
            {
                string renderMode = Arguments.HtmlRenderMode?.ToLower();

                if (renderMode == "fragment" || renderMode == "raw")
                {
                    try
                    {
                        var parser = new MarkdownParserMarkdig();
                        html = parser.Parse(doc.CurrentText);

                        File.WriteAllText(outputFile, html, new UTF8Encoding(false));
                    }
                    catch
                    {
                        ColorConsole.WriteError("Failed: Couldn't convert Markdown document or generate output file.");
                        Processor.ConsoleFooter();
                        return;
                    }
                }
                else
                {
                    if (doc.RenderHtmlToFile(filename: outputFile) == null)
                    {
                        throw new AccessViolationException();
                    }
                }

                if (renderMode == "packagedhtml")
                {
                    var    packager   = new Westwind.HtmlPackager.HtmlPackager();
                    string outputHtml = packager.PackageHtml(outputFile);
                    try
                    {
                        File.WriteAllText(outputFile, outputHtml);
                    }
                    catch
                    {
                        ColorConsole.WriteError("Failed: Couldn't write output file.");
                        Processor.ConsoleFooter();
                        return;
                    }
                }
                else if (renderMode == "htmlfiles")
                {
                    var packager = new Westwind.HtmlPackager.HtmlPackager();
                    if (!packager.PackageHtmlToFolder(outputFile, outputFile))
                    {
                        ColorConsole.WriteLine("Failed: Create output folder.", ConsoleColor.Red);
                    }
                }
                else if (renderMode == "zip")
                {
                    var packager = new Westwind.HtmlPackager.HtmlPackager();
                    if (!packager.PackageHtmlToZipFile(Path.ChangeExtension(outputFile, "html"), Path.ChangeExtension(outputFile, "zip")))
                    {
                        ColorConsole.WriteError("Failed: Couldn't create Packaged HTML Zip files.");
                    }

                    try
                    {
                        File.Delete(Path.ChangeExtension(outputFile, "html"));
                    }catch {}
                }
            }

            catch
            {
                ColorConsole.WriteError("Failed: Couldn't write output file.");
                Processor.ConsoleFooter();
                return;
            }

            if (Arguments.OpenOutputFile)
            {
                ShellUtils.GoUrl($"{outputFile}");
            }

            ColorConsole.WriteSuccess($"Created file: {outputFile}");
            ColorConsole.WriteSuccess($" Output Mode: {Arguments.HtmlRenderMode}");

            Processor.ConsoleFooter();
        }
Esempio n. 15
0
        protected override void OnStartup(StartupEventArgs e)
        {
            if (_noStart)
            {
                return;
            }

#if true
            var dotnetVersion = MarkdownMonster.Utilities.mmWindowsUtils.GetDotnetVersion();
            if (string.Compare(dotnetVersion, "4.7.2", StringComparison.Ordinal) < 0)
            {
                Task.Run(() => MessageBox.Show("Markdown Monster requires .NET 4.7.2 or later to run.\r\n\r\n" +
                                               "Please download and install the latest .NET Framework version from:\r\n" +
                                               "https://dotnet.microsoft.com/download/dotnet-framework\r\n\r\n" +
                                               "Exiting application and navigating to .NET Runtime Downloads page.",
                                               "Markdown Monster",
                                               MessageBoxButton.OK,
                                               MessageBoxImage.Warning
                                               ));

                Thread.Sleep(10000);
                ShellUtils.GoUrl("https://dotnet.microsoft.com/download/dotnet-framework");

                mmApp.Log("Dotnet Framework Version not met: " + dotnetVersion, logLevel: LogLevels.Warning);
                Environment.Exit(0);
            }
#endif

            if (mmApp.Configuration.System.DisableHardwareAcceleration)
            {
                RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
            }

            // always set directory tocurrent location
            var dir = Assembly.GetExecutingAssembly().Location;
            Directory.SetCurrentDirectory(Path.GetDirectoryName(dir));

            // TODO: TEMPORARY OPERATION: Remove the WebViewerPreview Addin
            var previewAddinPath = Path.Combine(mmApp.Configuration.CommonFolder, "Addins", "WebViewPreviewerAddin");
            if (Directory.Exists(previewAddinPath))
            {
                try
                {
                    Directory.Delete(previewAddinPath, true);
                }catch { }
            }

            if (!mmApp.Configuration.DisableAddins)
            {
                ThreadPool.QueueUserWorkItem(p => LoadAddins());
            }

            ThemeCustomizations();

            ThreadPool.QueueUserWorkItem(p =>
            {
                mmFileUtils.EnsureBrowserEmulationEnabled("MarkdownMonster.exe");
                mmFileUtils.EnsureSystemPath();
                mmFileUtils.EnsureAssociations();

                if (!Directory.Exists(mmApp.Configuration.InternalCommonFolder))
                {
                    Directory.CreateDirectory(mmApp.Configuration.InternalCommonFolder);
                }
            });
        }
Esempio n. 16
0
        /// <summary>
        /// Start the publish operation.
        /// </summary>
        public override async void Publish()
        {
            if (!ValidateInput())
            {
                Debug.WriteLine("Invalid input cancelled the operation.");
                return;
            }

            var project = _publishDialog.Project;

            try
            {
                var verifyGCloudTask = VerifyGCloudDependencies();
                _publishDialog.TrackTask(verifyGCloudTask);
                if (!await verifyGCloudTask)
                {
                    Debug.WriteLine("Aborting deployment, no kubectl was found.");
                    return;
                }

                var gcloudContext = new GCloudContext
                {
                    CredentialsPath = CredentialsStore.Default.CurrentAccountPath,
                    ProjectId       = CredentialsStore.Default.CurrentProjectId,
                    AppName         = GoogleCloudExtensionPackage.ApplicationName,
                    AppVersion      = GoogleCloudExtensionPackage.ApplicationVersion,
                };

                var kubectlContextTask = GCloudWrapper.GetKubectlContextForClusterAsync(
                    cluster: SelectedCluster.Name,
                    zone: SelectedCluster.Zone,
                    context: gcloudContext);
                _publishDialog.TrackTask(kubectlContextTask);

                using (var kubectlContext = await kubectlContextTask)
                {
                    var deploymentExistsTask = KubectlWrapper.DeploymentExistsAsync(DeploymentName, kubectlContext);
                    _publishDialog.TrackTask(deploymentExistsTask);
                    if (await deploymentExistsTask)
                    {
                        if (!UserPromptUtils.ActionPrompt(
                                String.Format(Resources.GkePublishDeploymentAlreadyExistsMessage, DeploymentName),
                                Resources.GkePublishDeploymentAlreadyExistsTitle,
                                actionCaption: Resources.UiUpdateButtonCaption))
                        {
                            return;
                        }
                    }

                    var options = new GkeDeployment.DeploymentOptions
                    {
                        Cluster                     = SelectedCluster.Name,
                        Zone                        = SelectedCluster.Zone,
                        DeploymentName              = DeploymentName,
                        DeploymentVersion           = DeploymentVersion,
                        ExposeService               = ExposeService,
                        GCloudContext               = gcloudContext,
                        KubectlContext              = kubectlContext,
                        Replicas                    = int.Parse(Replicas),
                        WaitingForServiceIpCallback = () => GcpOutputWindow.OutputLine(Resources.GkePublishWaitingForServiceIpMessage)
                    };

                    GcpOutputWindow.Activate();
                    GcpOutputWindow.Clear();
                    GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeployingToGkeMessage, project.Name));

                    _publishDialog.FinishFlow();

                    GkeDeploymentResult result;
                    using (var frozen = StatusbarHelper.Freeze())
                        using (var animationShown = StatusbarHelper.ShowDeployAnimation())
                            using (var progress = StatusbarHelper.ShowProgressBar(Resources.GkePublishDeploymentStatusMessage))
                                using (var deployingOperation = ShellUtils.SetShellUIBusy())
                                {
                                    result = await GkeDeployment.PublishProjectAsync(
                                        project.FullPath,
                                        options,
                                        progress,
                                        GcpOutputWindow.OutputLine);
                                }

                    if (result != null)
                    {
                        GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentSuccessMessage, project.Name));
                        if (result.DeploymentUpdated)
                        {
                            GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentUpdatedMessage, options.DeploymentName));
                        }
                        if (result.DeploymentScaled)
                        {
                            GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentScaledMessage, options.DeploymentName, options.Replicas));
                        }

                        if (result.WasExposed)
                        {
                            if (result.ServiceIpAddress != null)
                            {
                                GcpOutputWindow.OutputLine(
                                    String.Format(Resources.GkePublishServiceIpMessage, DeploymentName, result.ServiceIpAddress));
                            }
                            else
                            {
                                GcpOutputWindow.OutputLine(Resources.GkePublishServiceIpTimeoutMessage);
                            }
                        }
                        StatusbarHelper.SetText(Resources.PublishSuccessStatusMessage);

                        if (OpenWebsite && result.WasExposed && result.ServiceIpAddress != null)
                        {
                            Process.Start($"http://{result.ServiceIpAddress}");
                        }
                    }
                    else
                    {
                        GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentFailureMessage, project.Name));
                        StatusbarHelper.SetText(Resources.PublishFailureStatusMessage);
                    }
                }
            }
            catch (Exception ex) when(!ErrorHandlerUtils.IsCriticalException(ex))
            {
                GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentFailureMessage, project.Name));
                StatusbarHelper.SetText(Resources.PublishFailureStatusMessage);
                _publishDialog.FinishFlow();
            }
        }
Esempio n. 17
0
 private void Register_Click(object sender, RoutedEventArgs routedEventArgs)
 {
     ShellUtils.GoUrl(mmApp.Urls.RegistrationUrl);
 }
Esempio n. 18
0
        /// <summary>
        /// High level method that sends posts to the Weblog
        ///
        /// </summary>
        /// <returns></returns>
        public bool SendPost(WeblogInfo weblogInfo, bool sendAsDraft = false)
        {
            var editor = Model.ActiveEditor;

            if (editor == null)
            {
                return(false);
            }

            var doc = editor.MarkdownDocument;

            WeblogModel.ActivePost = new Post()
            {
                DateCreated = DateTime.Now
            };

            // start by retrieving the current Markdown from the editor
            string markdown = editor.GetMarkdown();



            // Retrieve Meta data from post and clean up the raw markdown
            // so we render without the config data
            var meta = WeblogPostMetadata.GetPostConfigFromMarkdown(markdown, WeblogModel.ActivePost, weblogInfo);

            string html = doc.RenderHtml(meta.MarkdownBody, WeblogAddinConfiguration.Current.RenderLinksOpenExternal);

            WeblogModel.ActivePost.Body       = html;
            WeblogModel.ActivePost.PostId     = meta.PostId;
            WeblogModel.ActivePost.PostStatus = meta.PostStatus;

            // Custom Field Processing:
            // Add custom fields from existing post
            // then add or update our custom fields
            var customFields = new Dictionary <string, CustomField>();

            // load existing custom fields from post online if possible
            if (!string.IsNullOrEmpty(meta.PostId))
            {
                var existingPost = GetPost(meta.PostId, weblogInfo);
                if (existingPost != null && meta.CustomFields != null && existingPost.CustomFields != null)
                {
                    customFields = existingPost.CustomFields
                                   .ToDictionary(cf => cf.Key, cf => cf);
                }
            }
            // add custom fields from Weblog configuration
            if (weblogInfo.CustomFields != null)
            {
                foreach (var kvp in weblogInfo.CustomFields)
                {
                    if (!customFields.ContainsKey(kvp.Key))
                    {
                        AddOrUpdateCustomField(customFields, kvp.Key, kvp.Value);
                    }
                }
            }
            // add custom fields from Meta data
            if (meta.CustomFields != null)
            {
                foreach (var kvp in meta.CustomFields)
                {
                    AddOrUpdateCustomField(customFields, kvp.Key, kvp.Value.Value);
                }
            }
            if (!string.IsNullOrEmpty(markdown))
            {
                AddOrUpdateCustomField(customFields, "mt_markdown", markdown);
            }

            WeblogModel.ActivePost.CustomFields = customFields.Values.ToArray();

            var config = WeblogAddinConfiguration.Current;

            var kv = config.Weblogs.FirstOrDefault(kvl => kvl.Value.Name == meta.WeblogName);

            if (kv.Equals(default(KeyValuePair <string, WeblogInfo>)))
            {
                MessageBox.Show("Invalid Weblog configuration selected.",
                                "Weblog Posting Failed",
                                MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return(false);
            }
            weblogInfo = kv.Value;

            var type = weblogInfo.Type;

            if (type == WeblogTypes.Unknown)
            {
                type = weblogInfo.Type;
            }


            string basePath = Path.GetDirectoryName(doc.Filename);
            string postUrl  = null;

            if (type == WeblogTypes.MetaWeblogApi || type == WeblogTypes.Wordpress)
            {
                MetaWebLogWordpressApiClient client;
                client = new MetaWebLogWordpressApiClient(weblogInfo);

                // if values are already configured don't overwrite them again
                client.DontInferFeaturedImage = meta.DontInferFeaturedImage;
                client.FeaturedImageUrl       = meta.FeaturedImageUrl;
                client.FeatureImageId         = meta.FeaturedImageId;

                if (!client.PublishCompletePost(WeblogModel.ActivePost, basePath,
                                                sendAsDraft, markdown))
                {
                    mmApp.Log($"Error sending post to Weblog at {weblogInfo.ApiUrl}: " + client.ErrorMessage);
                    MessageBox.Show("Error sending post to Weblog: " + client.ErrorMessage,
                                    mmApp.ApplicationName,
                                    MessageBoxButton.OK,
                                    MessageBoxImage.Exclamation);
                    return(false);
                }

                var post = client.GetPost(WeblogModel.ActivePost.PostId);
                if (post != null)
                {
                    postUrl = post.Url;
                }
            }
            if (type == WeblogTypes.Medium)
            {
                var client = new MediumApiClient(weblogInfo);
                var result = client.PublishCompletePost(WeblogModel.ActivePost, basePath, sendAsDraft);
                if (result == null)
                {
                    mmApp.Log($"Error sending post to Weblog at {weblogInfo.ApiUrl}: " + client.ErrorMessage);
                    MessageBox.Show($"Error sending post to Weblog: " + client.ErrorMessage,
                                    mmApp.ApplicationName,
                                    MessageBoxButton.OK,
                                    MessageBoxImage.Exclamation);
                    return(false);
                }

                // this is null
                postUrl = client.PostUrl;
            }

            meta.PostId = WeblogModel.ActivePost.PostId.ToString();

            // retrieve the raw editor markdown
            markdown             = editor.GetMarkdown();
            meta.RawMarkdownBody = markdown;

            // add the meta configuration to it
            markdown = meta.SetPostYaml();

            // write it back out to editor
            editor.SetMarkdown(markdown, updateDirtyFlag: true);

            try
            {
                // preview post
                if (!string.IsNullOrEmpty(weblogInfo.PreviewUrl))
                {
                    var url = weblogInfo.PreviewUrl.Replace("{0}", WeblogModel.ActivePost.PostId.ToString());
                    ShellUtils.GoUrl(url);
                }
                else
                {
                    if (!string.IsNullOrEmpty(postUrl))
                    {
                        ShellUtils.GoUrl(postUrl);
                    }
                    else
                    {
                        ShellUtils.GoUrl(new Uri(weblogInfo.ApiUrl).GetLeftPart(UriPartial.Authority));
                    }
                }
            }
            catch
            {
                mmApp.Log("Failed to display Weblog Url after posting: " +
                          weblogInfo.PreviewUrl ?? postUrl ?? weblogInfo.ApiUrl);
            }

            return(true);
        }
Esempio n. 19
0
 private void Register_Click(object sender, RoutedEventArgs routedEventArgs)
 {
     ShellUtils.GoUrl("https://store.west-wind.com/product/MARKDOWN_MONSTER");
 }
        public override async void Publish()
        {
            if (!ValidateInput())
            {
                Debug.WriteLine("Invalid input cancelled the operation.");
                return;
            }

            var project = _publishDialog.Project;

            try
            {
                var verifyGcloudTask = GCloudWrapperUtils.VerifyGCloudDependencies("beta");
                _publishDialog.TrackTask(verifyGcloudTask);
                if (!await verifyGcloudTask)
                {
                    Debug.WriteLine("Gcloud dependencies not met, aborting publish operation.");
                    return;
                }

                ShellUtils.SaveAllFiles();

                var context = new GCloudContext
                {
                    CredentialsPath = CredentialsStore.Default.CurrentAccountPath,
                    ProjectId       = CredentialsStore.Default.CurrentProjectId,
                    AppName         = GoogleCloudExtensionPackage.ApplicationName,
                    AppVersion      = GoogleCloudExtensionPackage.ApplicationVersion,
                };
                var options = new AppEngineFlexDeployment.DeploymentOptions
                {
                    Version = Version,
                    Promote = Promote,
                    Context = context
                };

                GcpOutputWindow.Activate();
                GcpOutputWindow.Clear();
                GcpOutputWindow.OutputLine(String.Format(Resources.GcePublishStepStartMessage, project.Name));

                _publishDialog.FinishFlow();

                TimeSpan deploymentDuration;
                AppEngineFlexDeploymentResult result;
                using (StatusbarHelper.Freeze())
                    using (StatusbarHelper.ShowDeployAnimation())
                        using (var progress = StatusbarHelper.ShowProgressBar(Resources.FlexPublishProgressMessage))
                            using (ShellUtils.SetShellUIBusy())
                            {
                                var startDeploymentTime = DateTime.Now;
                                result = await AppEngineFlexDeployment.PublishProjectAsync(
                                    project,
                                    options,
                                    progress,
                                    VsVersionUtils.ToolsPathProvider,
                                    GcpOutputWindow.OutputLine);

                                deploymentDuration = DateTime.Now - startDeploymentTime;
                            }

                if (result != null)
                {
                    GcpOutputWindow.OutputLine(String.Format(Resources.FlexPublishSuccessMessage, project.Name));
                    StatusbarHelper.SetText(Resources.PublishSuccessStatusMessage);

                    var url = result.GetDeploymentUrl();
                    GcpOutputWindow.OutputLine(String.Format(Resources.PublishUrlMessage, url));
                    if (OpenWebsite)
                    {
                        Process.Start(url);
                    }

                    EventsReporterWrapper.ReportEvent(GaeDeployedEvent.Create(CommandStatus.Success, deploymentDuration));
                }
                else
                {
                    GcpOutputWindow.OutputLine(String.Format(Resources.FlexPublishFailedMessage, project.Name));
                    StatusbarHelper.SetText(Resources.PublishFailureStatusMessage);

                    EventsReporterWrapper.ReportEvent(GaeDeployedEvent.Create(CommandStatus.Failure));
                }
            }
            catch (Exception ex) when(!ErrorHandlerUtils.IsCriticalException(ex))
            {
                GcpOutputWindow.OutputLine(String.Format(Resources.FlexPublishFailedMessage, project.Name));
                StatusbarHelper.SetText(Resources.PublishFailureStatusMessage);

                EventsReporterWrapper.ReportEvent(GaeDeployedEvent.Create(CommandStatus.Failure));
            }
        }
Esempio n. 21
0
        /// <summary>
        /// High level method that sends posts to the Weblog
        ///
        /// </summary>
        /// <returns></returns>
        public bool SendPost(WeblogTypes type = WeblogTypes.Unknown, bool sendAsDraft = false)
        {
            var editor = Model.ActiveEditor;

            if (editor == null)
            {
                return(false);
            }

            var doc = editor.MarkdownDocument;

            ActivePost = new Post()
            {
                DateCreated = DateTime.Now
            };

            // start by retrieving the current Markdown from the editor
            string markdown = editor.GetMarkdown();

            // Retrieve Meta data from post and clean up the raw markdown
            // so we render without the config data
            var meta = GetPostConfigFromMarkdown(markdown);

            string html = doc.RenderHtml(meta.MarkdownBody, WeblogAddinConfiguration.Current.RenderLinksOpenExternal);

            var config = WeblogAddinConfiguration.Current;

            var kv = config.Weblogs.FirstOrDefault(kvl => kvl.Value.Name == meta.WeblogName);

            if (kv.Equals(default(KeyValuePair <string, WeblogInfo>)))
            {
                MessageBox.Show("Invalid Weblog configuration selected.",
                                "Weblog Posting Failed",
                                MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return(false);
            }
            WeblogInfo weblogInfo = kv.Value;

            if (type == WeblogTypes.Unknown)
            {
                type = weblogInfo.Type;
            }

            MetaWeblogWrapper wrapper;

            if (type == WeblogTypes.MetaWeblogApi)
            {
                wrapper = new MetaWeblogWrapper(weblogInfo.ApiUrl,
                                                weblogInfo.Username,
                                                weblogInfo.DecryptPassword(weblogInfo.Password),
                                                weblogInfo.BlogId);
            }
            else
            {
                wrapper = new WordPressWrapper(weblogInfo.ApiUrl,
                                               weblogInfo.Username,
                                               weblogInfo.DecryptPassword(weblogInfo.Password));
            }


            string body;

            try
            {
                body = SendImages(html, doc.Filename, wrapper, meta);
            }
            catch (Exception ex)
            {
                mmApp.Log($"Error sending images to Weblog at {weblogInfo.ApiUrl}: ", ex);
                return(false);
            }

            if (body == null)
            {
                return(false);
            }

            ActivePost.Body   = body;
            ActivePost.PostID = meta.PostId;

            var customFields = new List <CustomField>();


            customFields.Add(
                new CustomField()
            {
                ID    = "mt_markdown",
                Key   = "mt_markdown",
                Value = meta.MarkdownBody
            });

            if (!string.IsNullOrEmpty(meta.FeaturedImageUrl))
            {
                customFields.Add(
                    new CustomField()
                {
                    ID    = "wp_post_thumbnail",
                    Key   = "wp_post_thumbnail",
                    Value = meta.FeaturedImageUrl
                });
            }
            ActivePost.CustomFields = customFields.ToArray();

            bool isNewPost = IsNewPost(ActivePost.PostID);

            try
            {
                if (!isNewPost)
                {
                    wrapper.EditPost(ActivePost, !sendAsDraft);
                }
                else
                {
                    ActivePost.PostID = wrapper.NewPost(ActivePost, !sendAsDraft);
                }
            }
            catch (Exception ex)
            {
                mmApp.Log($"Error sending post to Weblog at {weblogInfo.ApiUrl}: ", ex);
                MessageBox.Show($"Error sending post to Weblog: " + ex.Message,
                                mmApp.ApplicationName,
                                MessageBoxButton.OK,
                                MessageBoxImage.Exclamation);

                mmApp.Log(ex);
                return(false);
            }

            meta.PostId = ActivePost.PostID.ToString();

            // retrieve the raw editor markdown
            markdown             = editor.GetMarkdown();
            meta.RawMarkdownBody = markdown;

            // add the meta configuration to it
            markdown = SetConfigInMarkdown(meta);

            // write it back out to editor
            editor.SetMarkdown(markdown);

            // preview post
            if (!string.IsNullOrEmpty(weblogInfo.PreviewUrl))
            {
                var url = weblogInfo.PreviewUrl.Replace("{0}", ActivePost.PostID.ToString());
                ShellUtils.GoUrl(url);
            }
            else
            {
                try
                {
                    var postRaw = wrapper.GetPostRaw(ActivePost.PostID);
                    var link    = postRaw.link;
                    if (!string.IsNullOrEmpty(link) && (link.StartsWith("http://") || link.StartsWith("https://")))
                    {
                        ShellUtils.GoUrl(link);
                    }
                    else
                    {
                        // just go to the base domain - assume posts are listed there
                        ShellUtils.GoUrl(new Uri(weblogInfo.ApiUrl).GetLeftPart(UriPartial.Authority));
                    }
                }
                catch { }
            }

            return(true);
        }
Esempio n. 22
0
 private void lblClickClose_Click(object sender, EventArgs e)
 {
     ShellUtils.GoUrl(App.PurchaseUrl);
     Close();
 }
        public void RequestSummaryTest()
        {
            var time = DateTime.UtcNow;

            var requests = new List <HttpRequestData>()
            {
                new HttpRequestData()
                {
                    Url          = "http://localhost/",
                    Timestamp    = time,
                    IsError      = false,
                    TimeTakenMs  = 10,
                    ErrorMessage = "Invalid Server Response",
                    StatusCode   = "500"
                },
                new HttpRequestData()
                {
                    Url         = "http://localhost/wconnect",
                    Timestamp   = time.AddMilliseconds(20),
                    IsError     = false,
                    TimeTakenMs = 95
                },
                new HttpRequestData
                {
                    Url          = "http://localhost/",
                    Timestamp    = time.AddMilliseconds(220),
                    IsError      = false,
                    TimeTakenMs  = 15,
                    ErrorMessage = "Bogus Invalid Server Response",
                    StatusCode   = "500"
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/",
                    Timestamp   = time.AddMilliseconds(1020),
                    TimeTakenMs = 20
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect",
                    Timestamp   = time.AddMilliseconds(1050),
                    TimeTakenMs = 20
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/",
                    Timestamp   = time.AddMilliseconds(1200),
                    TimeTakenMs = 20
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/",
                    Timestamp   = time.AddMilliseconds(3020),
                    TimeTakenMs = 20
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/",
                    Timestamp   = time.AddMilliseconds(3050),
                    TimeTakenMs = 20
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect",
                    Timestamp   = time.AddMilliseconds(3200),
                    TimeTakenMs = 20
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect",
                    Timestamp   = time.AddMilliseconds(3500),
                    TimeTakenMs = 50
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect/testpage",
                    Timestamp   = time.AddMilliseconds(3100),
                    IsError     = false,
                    TimeTakenMs = 50
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect/testpage",
                    IsError     = false,
                    Timestamp   = time.AddMilliseconds(3200),
                    TimeTakenMs = 57
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect/testpage2",
                    Timestamp   = time.AddMilliseconds(3100),
                    TimeTakenMs = 50
                },
                new HttpRequestData
                {
                    Url         = "http://localhost/wconnect/testpage2",
                    Timestamp   = time.AddMilliseconds(3200),
                    TimeTakenMs = 57
                }
            };

            var writer = new RequestWriter(null, requests);


            var parser = new ResultsParser();
            var res    = parser.UrlSummary(writer, 200);

            Assert.IsNotNull(res);
            Assert.IsTrue(res.Count() > 0);

            foreach (var r in res)
            {
                Console.WriteLine(r.Url + ": " + JsonSerializationUtils.Serialize(r.Results, false, true));
            }


            var html = parser.GetResultReportHtml(writer, 10, 2);

            Console.WriteLine(html);

            var file = App.UserDataPath + "html\\_preview.html";

            File.WriteAllText(file, html);
            ShellUtils.GoUrl(file);
        }
Esempio n. 24
0
 private void lnkRegister_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
 {
     ShellUtils.GoUrl(App.PurchaseUrl);
     Close();
 }
Esempio n. 25
0
 private void ButtonCustomFieldHelp_Click(object sender, RoutedEventArgs e)
 {
     ShellUtils.GoUrl(mmApp.GetDocumentionUrl("_4wq1dbsnh"));
 }
Esempio n. 26
0
 public void ShowProperties()
 {
     ShellUtils.ShowFileProperties(FullPathAndFileName);
 }
Esempio n. 27
0
 private void Register_Click(object sender, System.Windows.RoutedEventArgs e)
 {
     ShellUtils.GoUrl("https://store.west-wind.com/product/markdown_monster");
 }
        public void ExecuteProcess()
        {
            int result = ShellUtils.ExecuteProcess("ipconfig.exe", null, 3000, ProcessWindowStyle.Normal);

            Assert.IsTrue(result == 0, "Process should exit with 0");
        }
Esempio n. 29
0
 private void ButtonApiUrlInfo_Click(object sender, RoutedEventArgs e)
 {
     ShellUtils.GoUrl("http://markdownmonster.west-wind.com/docs/_4rg0qzg1i.htm");
 }
Esempio n. 30
0
        private void CreateCommands()
        {
            // SAVE COMMAND
            SaveCommand = new CommandBase((s, e) =>
            {
                var tab = Window.TabControl?.SelectedItem as TabItem;
                if (tab == null)
                {
                    return;
                }
                var doc = tab.Tag as MarkdownDocumentEditor;

                if (doc.MarkdownDocument.Filename == "untitled")
                {
                    SaveAsCommand.Execute(tab);
                }
                else if (!doc.SaveDocument())
                {
                    SaveAsCommand.Execute(tab);
                }

                Window.PreviewMarkdown(doc, keepScrollPosition: true);
            }, (s, e) =>
            {
                if (ActiveDocument == null)
                {
                    return(false);
                }

                return(this.ActiveDocument.IsDirty);
            });

            // SAVEAS COMMAND
            SaveAsCommand = new CommandBase((parameter, e) =>
            {
                bool isEncrypted = parameter != null && parameter.ToString() == "Secure";

                var tab = Window.TabControl?.SelectedItem as TabItem;
                if (tab == null)
                {
                    return;
                }
                var doc = tab.Tag as MarkdownDocumentEditor;
                if (doc == null)
                {
                    return;
                }

                var filename = doc.MarkdownDocument.Filename;
                var folder   = Path.GetDirectoryName(doc.MarkdownDocument.Filename);

                if (filename == "untitled")
                {
                    folder = mmApp.Configuration.LastFolder;

                    var match = Regex.Match(doc.GetMarkdown(), @"^# (\ *)(?<Header>.+)", RegexOptions.Multiline);

                    if (match.Success)
                    {
                        filename = match.Groups["Header"].Value;
                        if (!string.IsNullOrEmpty(filename))
                        {
                            filename = mmFileUtils.SafeFilename(filename);
                        }
                    }
                }

                if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
                {
                    folder = mmApp.Configuration.LastFolder;
                    if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
                    {
                        folder = KnownFolders.GetPath(KnownFolder.Libraries);
                    }
                }


                SaveFileDialog sd = new SaveFileDialog
                {
                    Filter           = "Markdown files (*.md)|*.md|Markdown files (*.markdown)|*.markdown|All files (*.*)|*.*",
                    FilterIndex      = 1,
                    InitialDirectory = folder,
                    FileName         = filename,
                    CheckFileExists  = false,
                    OverwritePrompt  = false,
                    CheckPathExists  = true,
                    RestoreDirectory = true
                };

                bool?result = null;
                try
                {
                    result = sd.ShowDialog();
                }
                catch (Exception ex)
                {
                    mmApp.Log("Unable to save file: " + doc.MarkdownDocument.Filename, ex);
                    MessageBox.Show(
                        $@"Unable to open file:\r\n\r\n" + ex.Message,
                        "An error occurred trying to open a file",
                        MessageBoxButton.OK,
                        MessageBoxImage.Error);
                }

                if (!isEncrypted)
                {
                    doc.MarkdownDocument.Password = null;
                }
                else
                {
                    var pwdDialog = new FilePasswordDialog(doc.MarkdownDocument, false)
                    {
                        Owner = Window
                    };
                    bool?pwdResult = pwdDialog.ShowDialog();
                }

                if (result != null && result.Value)
                {
                    doc.MarkdownDocument.Filename = sd.FileName;
                    if (!doc.SaveDocument())
                    {
                        MessageBox.Show(Window, $"{sd.FileName}\r\n\r\nThis document can't be saved in this location. The file is either locked or you don't have permissions to save it. Please choose another location to save the file.",
                                        "Unable to save Document", MessageBoxButton.OK, MessageBoxImage.Warning);
                        SaveAsCommand.Execute(tab);
                        return;
                    }
                }

                mmApp.Configuration.LastFolder = folder;

                Window.SetWindowTitle();
                Window.PreviewMarkdown(doc, keepScrollPosition: true);
            }, (s, e) =>
            {
                if (ActiveDocument == null)
                {
                    return(false);
                }

                return(true);
            });

            // SAVEASHTML COMMAND
            SaveAsHtmlCommand = new CommandBase((s, e) =>
            {
                var tab = Window.TabControl?.SelectedItem as TabItem;
                var doc = tab?.Tag as MarkdownDocumentEditor;
                if (doc == null)
                {
                    return;
                }

                var folder = Path.GetDirectoryName(doc.MarkdownDocument.Filename);

                SaveFileDialog sd = new SaveFileDialog
                {
                    Filter           = "Html files (Html only) (*.html)|*.html|Html files (Html and dependencies in a folder)|*.html",
                    FilterIndex      = 1,
                    InitialDirectory = folder,
                    FileName         = Path.ChangeExtension(doc.MarkdownDocument.Filename, "html"),
                    CheckFileExists  = false,
                    OverwritePrompt  = false,
                    CheckPathExists  = true,
                    RestoreDirectory = true
                };

                bool?result = null;
                try
                {
                    result = sd.ShowDialog();
                }catch (Exception ex)
                {
                    mmApp.Log("Unable to save html file: " + doc.MarkdownDocument.Filename, ex);
                    MessageBox.Show(
                        $@"Unable to open file:\r\n\r\n" + ex.Message,
                        "An error occurred trying to open a file",
                        MessageBoxButton.OK,
                        MessageBoxImage.Error);
                }

                if (result != null && result.Value)
                {
                    if (sd.FilterIndex != 2)
                    {
                        var html = doc.RenderMarkdown(doc.GetMarkdown(), mmApp.Configuration.MarkdownOptions.RenderLinksAsExternal);

                        if (!doc.MarkdownDocument.WriteFile(sd.FileName, html))
                        {
                            MessageBox.Show(Window,
                                            $"{sd.FileName}\r\n\r\nThis document can't be saved in this location. The file is either locked or you don't have permissions to save it. Please choose another location to save the file.",
                                            "Unable to save Document", MessageBoxButton.OK, MessageBoxImage.Warning);
                            SaveAsHtmlCommand.Execute(null);
                            return;
                        }
                    }
                    else
                    {
                        string msg   = @"This feature is not available yet.

For now, you can use 'View in Web Browser' to view the document in your favorite Web Browser and use 'Save As...' to save the Html document with all CSS and Image dependencies.

Do you want to View in Browser now?
";
                        var mbResult = MessageBox.Show(msg,
                                                       mmApp.ApplicationName,
                                                       MessageBoxButton.YesNo,
                                                       MessageBoxImage.Asterisk,
                                                       MessageBoxResult.Yes);

                        if (mbResult == MessageBoxResult.Yes)
                        {
                            Window.Model.ViewInExternalBrowserCommand.Execute(null);
                        }
                    }
                }

                Window.PreviewMarkdown(doc, keepScrollPosition: true);
            }, (s, e) =>
            {
                if (ActiveDocument == null || ActiveEditor == null)
                {
                    return(false);
                }
                if (ActiveDocument.Filename == "untitled")
                {
                    return(true);
                }
                if (ActiveEditor.EditorSyntax != "markdown")
                {
                    return(false);
                }

                return(true);
            });

            // NEW DOCUMENT COMMAND (ctrl-n)
            NewDocumentCommand = new CommandBase((s, e) =>
            {
                Window.OpenTab("untitled");
            });

            // OPEN DOCUMENT COMMAND
            OpenDocumentCommand = new CommandBase((s, e) =>
            {
                var fd = new OpenFileDialog
                {
                    DefaultExt = ".md",
                    Filter     = "Markdown files (*.md,*.markdown)|*.md;*.markdown|" +
                                 "Html files (*.htm,*.html)|*.htm;*.html|" +
                                 "Javascript files (*.js)|*.js|" +
                                 "Typescript files (*.ts)|*.ts|" +
                                 "Json files (*.json)|*.json|" +
                                 "Css files (*.css)|*.css|" +
                                 "Xml files (*.xml,*.config)|*.xml;*.config|" +
                                 "C# files (*.cs)|*.cs|" +
                                 "C# Razor files (*.cshtml)|*.cshtml|" +
                                 "Foxpro files (*.prg)|*.prg|" +
                                 "Powershell files (*.ps1)|*.ps1|" +
                                 "Php files (*.php)|*.php|" +
                                 "Python files (*.py)|*.py|" +
                                 "All files (*.*)|*.*",
                    CheckFileExists  = true,
                    RestoreDirectory = true,
                    Multiselect      = true,
                    Title            = "Open Markdown File"
                };

                if (!string.IsNullOrEmpty(mmApp.Configuration.LastFolder))
                {
                    fd.InitialDirectory = mmApp.Configuration.LastFolder;
                }

                bool?res = null;
                try
                {
                    res = fd.ShowDialog();
                }
                catch (Exception ex)
                {
                    mmApp.Log("Unable to open file.", ex);
                    MessageBox.Show(
                        $@"Unable to open file:\r\n\r\n" + ex.Message,
                        "An error occurred trying to open a file",
                        MessageBoxButton.OK,
                        MessageBoxImage.Error);
                    return;
                }
                if (res == null || !res.Value)
                {
                    return;
                }

                foreach (var file in fd.FileNames)
                {
                    // TODO: Check AddRecentFile and make sure Tab Selection works
                    Window.OpenTab(file, rebindTabHeaders: true);
                    //Window.AddRecentFile(file);
                }
            });

            // CLOSE ACTIVE DOCUMENT COMMAND
            CloseActiveDocumentCommand = new CommandBase((s, e) =>
            {
                var tab = Window.TabControl.SelectedItem as TabItem;
                if (tab == null)
                {
                    return;
                }

                if (Window.CloseTab(tab))
                {
                    Window.TabControl.Items.Remove(tab);
                }
            }, null)
            {
                Caption = "_Close Document",
                ToolTip = "Closes the active tab and asks to save the document."
            };


            // COMMIT TO GIT Command
            CommitToGitCommand = new CommandBase(async(s, e) =>
            {
                string file = ActiveDocument?.Filename;
                if (string.IsNullOrEmpty(file))
                {
                    return;
                }

                Window.ShowStatus("Committing and pushing to Git...");
                WindowUtilities.DoEvents();

                string error = null;

                bool pushToGit = mmApp.Configuration.GitCommitBehavior == GitCommitBehaviors.CommitAndPush;
                bool result    = await Task.Run(() => mmFileUtils.CommitFileToGit(file, pushToGit, out error));

                if (result)
                {
                    Window.ShowStatus($"File {Path.GetFileName(file)} committed and pushed.", 6000);
                }
                else
                {
                    Window.ShowStatus(error, 7000);
                    Window.SetStatusIcon(FontAwesomeIcon.Warning, Colors.Red);
                }
            }, (s, e) => IsEditorActive);


            // PREVIEW BUTTON COMMAND
            PreviewBrowserCommand = new CommandBase((s, e) =>
            {
                var tab = Window.TabControl.SelectedItem as TabItem;
                if (tab == null)
                {
                    return;
                }

                var editor = tab.Tag as MarkdownDocumentEditor;

                Configuration.IsPreviewVisible = IsPreviewBrowserVisible;

                if (!IsPreviewBrowserVisible && IsPresentationMode)
                {
                    PresentationModeCommand.Execute(null);
                }


                Window.ShowPreviewBrowser(!IsPreviewBrowserVisible);
                if (IsPreviewBrowserVisible)
                {
                    Window.PreviewMarkdown(editor);
                }
            }, null);

            // SHOW FILE BROWSER COMMAND
            ShowFolderBrowserCommand = new CommandBase((s, e) =>
            {
                mmApp.Configuration.FolderBrowser.Visible = !mmApp.Configuration.FolderBrowser.Visible;

                mmApp.Model.Window.ShowFolderBrowser(!mmApp.Configuration.FolderBrowser.Visible);
            });

            // WORD WRAP COMMAND
            WordWrapCommand = new CommandBase((parameter, command) =>
            {
                //MessageBox.Show("alt-z WPF");
                mmApp.Model.Configuration.EditorWrapText = !mmApp.Model.Configuration.EditorWrapText;
                mmApp.Model.ActiveEditor?.SetWordWrap(mmApp.Model.Configuration.EditorWrapText);
            }, (p, c) => IsEditorActive);

            // MARKDOWN EDIT COMMANDS TOOLBAR COMMAND
            ToolbarInsertMarkdownCommand = new CommandBase((s, e) =>
            {
                string action = s as string;

                var editor = Window.GetActiveMarkdownEditor();
                editor?.ProcessEditorUpdateCommand(action);
            }, null);

            // Settings
            SettingsCommand = new CommandBase((s, e) =>
            {
                var file = Path.Combine(mmApp.Configuration.CommonFolder, "MarkdownMonster.json");

                // save settings first so we're looking at current setting
                Configuration.Write();

                string fileText = File.ReadAllText(file);
                if (!fileText.StartsWith("//"))
                {
                    fileText = "// Reference: http://markdownmonster.west-wind.com/docs/_4nk01yq6q.htm\r\n" +
                               fileText;
                    File.WriteAllText(file, fileText);
                }

                Window.OpenTab(file, syntax: "json");
            }, null);

            // DISTRACTION FREE MODE
            DistractionFreeModeCommand = new CommandBase((s, e) =>
            {
                GridLength glToolbar = new GridLength(0);
                GridLength glMenu    = new GridLength(0);
                GridLength glStatus  = new GridLength(0);

                GridLength glFileBrowser = new GridLength(0);

                if (Window.ToolbarGridRow.Height == glToolbar)
                {
                    Window.SaveSettings();

                    glToolbar = GridLength.Auto;
                    glMenu    = GridLength.Auto;
                    glStatus  = GridLength.Auto;

                    //mmApp.Configuration.WindowPosition.IsTabHeaderPanelVisible = true;
                    Window.TabControl.IsHeaderPanelVisible = true;

                    IsPreviewBrowserVisible = true;
                    Window.PreviewMarkdown();

                    Window.WindowState = mmApp.Configuration.WindowPosition.WindowState;

                    IsFullScreen = false;

                    Window.ShowFolderBrowser(!mmApp.Configuration.FolderBrowser.Visible);
                }
                else
                {
                    var tokens = mmApp.Configuration.DistractionFreeModeHideOptions.ToLower().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    if (tokens.All(d => d != "menu"))
                    {
                        glMenu = GridLength.Auto;
                    }

                    if (tokens.All(d => d != "toolbar"))
                    {
                        glToolbar = GridLength.Auto;
                    }

                    if (tokens.All(d => d != "statusbar"))
                    {
                        glStatus = GridLength.Auto;
                    }

                    if (tokens.Any(d => d == "tabs"))
                    {
                        Window.TabControl.IsHeaderPanelVisible = false;
                    }

                    if (tokens.Any(d => d == "preview"))
                    {
                        IsPreviewBrowserVisible = false;
                        Window.ShowPreviewBrowser(hide: true);
                    }

                    mmApp.Configuration.WindowPosition.WindowState = Window.WindowState;
                    if (tokens.Any(d => d == "maximized"))
                    {
                        Window.WindowState = WindowState.Maximized;
                    }

                    Window.ShowFolderBrowser(true);

                    IsFullScreen = true;
                }

                // toolbar
                Window.MainMenuGridRow.Height  = glMenu;
                Window.ToolbarGridRow.Height   = glToolbar;
                Window.StatusBarGridRow.Height = glStatus;
            }, null);

            // PRESENTATION MODE
            PresentationModeCommand = new CommandBase((s, e) =>
            {
                if (IsFullScreen)
                {
                    DistractionFreeModeCommand.Execute(null);
                }

                GridLength gl = new GridLength(0);
                if (Window.WindowGrid.RowDefinitions[1].Height == gl)
                {
                    gl = GridLength.Auto; // toolbar height

                    Window.MainWindowEditorColumn.Width    = new GridLength(1, GridUnitType.Star);
                    Window.MainWindowSeparatorColumn.Width = new GridLength(0);
                    Window.MainWindowPreviewColumn.Width   = new GridLength(mmApp.Configuration.WindowPosition.SplitterPosition);

                    Window.PreviewMarkdown();

                    Window.ShowFolderBrowser(!mmApp.Configuration.FolderBrowser.Visible);

                    IsPresentationMode = false;
                }
                else
                {
                    Window.SaveSettings();

                    mmApp.Configuration.WindowPosition.SplitterPosition =
                        Convert.ToInt32(Window.MainWindowPreviewColumn.Width.Value);

                    // don't allow presentation mode for non-Markdown documents
                    var editor = Window.GetActiveMarkdownEditor();
                    if (editor != null)
                    {
                        var file = editor.MarkdownDocument.Filename.ToLower();
                        var ext  = Path.GetExtension(file);
                        if (file != "untitled" && ext != ".md" && ext != ".htm" && ext != ".html")
                        {
                            // don't allow presentation mode for non markdown files
                            IsPresentationMode      = false;
                            IsPreviewBrowserVisible = false;
                            Window.ShowPreviewBrowser(true);
                            return;
                        }
                    }

                    Window.ShowPreviewBrowser();
                    Window.ShowFolderBrowser(true);

                    Window.MainWindowEditorColumn.Width    = gl;
                    Window.MainWindowSeparatorColumn.Width = gl;
                    Window.MainWindowPreviewColumn.Width   = new GridLength(1, GridUnitType.Star);

                    IsPresentationMode      = true;
                    IsPreviewBrowserVisible = true;
                }

                Window.WindowGrid.RowDefinitions[1].Height = gl;
                //Window.WindowGrid.RowDefinitions[3].Height = gl;
            }, null);

            // EXTERNAL BROWSER VIEW
            ViewInExternalBrowserCommand = new CommandBase((p, e) =>
            {
                if (ActiveDocument == null)
                {
                    return;
                }
                mmFileUtils.ShowExternalBrowser(ActiveDocument.HtmlRenderFilename);
            }, (p, e) => IsPreviewBrowserVisible);

            ViewHtmlSourceCommand = new CommandBase((p, e) =>
            {
                if (ActiveDocument == null)
                {
                    return;
                }
                Window.OpenTab(ActiveDocument.HtmlRenderFilename);
            }, (p, e) => IsPreviewBrowserVisible);


            // PRINT PREVIEW
            PrintPreviewCommand = new CommandBase((s, e) =>
            {
                dynamic dom = Window.PreviewBrowser.Document;
                dom.execCommand("print", true, null);
            }, (s, e) => IsPreviewBrowserVisible);

            // PDF GENERATION PREVIEW
            GeneratePdfCommand = new CommandBase((s, e) =>
            {
                var form = new GeneratePdfWindow()
                {
                    Owner = mmApp.Model.Window
                };
                form.Show();
            }, (s, e) => IsPreviewBrowserVisible);

            // F1 Help Command - Pass option CommandParameter="TopicId"
            HelpCommand = new CommandBase((topicId, e) =>
            {
                string url = mmApp.Urls.DocumentationBaseUrl;

                if (topicId != null)
                {
                    url = mmApp.GetDocumentionUrl(topicId as string);
                }

                ShellUtils.GoUrl(url);
            }, (s, e) => IsPreviewBrowserVisible);
        }