This dialog lets users bring up an issue with us. It can include a description, a screenshot, and the file they were working on. It can try to send directly via internet. If this fails, it can make a single zip file and direct the user to email that to us.
Inheritance: System.Windows.Forms.Form
        /// <summary>
        /// We've had a number of user reports that suggest that files were either missing or inaccessible.
        /// The idea here is to check a set of files and folders at the start of each launch, and generate
        /// a useful report if anything is missing.
        /// </summary>
        /// <returns>true if all is well. Application should exit if this returns false.</returns>
        public static bool CheckIntegrity()
        {
            var errors = new StringBuilder();
            var files  = new[] { "Bloom.chm", "PdfDroplet.exe",
#if Chorus
                                 "Chorus.exe",
#endif
                                 "BloomPdfMaker.exe", "optipng.exe" };

            string[] dirs;
            if (SIL.PlatformUtilities.Platform.IsWindows)
            {
                dirs = new[] { "AndikaNewBasic", "localization", "xslts", "icons" }
            }
            ;
            else
            {
                dirs = new[] { "localization", "xslts", "icons" }
            };

            foreach (var fileName in files)
            {
                if (!Platform.IsWindows && fileName == "optipng.exe")
                {
                    // optipng is provided by a package dependency, will be found as /usr/bin/optipng (no .exe)
                    continue;
                }
                if (FileLocator.GetFileDistributedWithApplication(true, fileName) == null)
                {
                    //In a code directory, the FileLocator considers the solution the root, so it can't find files in output\debug
                    if (!RobustFile.Exists(Path.Combine(FileLocator.DirectoryOfTheApplicationExecutable, fileName)))
                    {
                        //maybe it's an exe in distfiles?
                        if (fileName.EndsWith(".exe") && RobustFile.Exists(Path.Combine(FileLocator.DirectoryOfApplicationOrSolution, "DistFiles")))
                        {
                            continue;
                        }
                        errors.AppendFormat("<p>Missing File: {0}</p>{1}", fileName, Environment.NewLine);
                    }
                }
            }
            foreach (var directory in dirs)
            {
                if (FileLocator.GetDirectoryDistributedWithApplication(true, directory) == null)
                {
                    errors.AppendFormat("<p>Missing Directory: {0}</p>{1}", directory, Environment.NewLine);
                }
            }
            if (errors.Length == 0)
            {
                return(true);
            }

            using (var dlg = new BloomIntegrityDialog())
            {
                var    messagePath = BloomFileLocator.GetBestLocalizableFileDistributedWithApplication(false, "IntegrityFailureAdvice-en.htm");
                string message;
                if (messagePath == null)                // maybe we can't even get at this file we need for a good description of the problem
                {
                    message = "Bloom cannot find some of its own files, and cannot continue. After you submit this report, we will contact you and help you work this out. In the meantime, you can run the Bloom installer again.";
                }
                else
                {
                    var installFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
                                        .CombineForPath(Application.ProductName);
                    message = RobustFile.ReadAllText(messagePath).Replace("{{installFolder}}", installFolder); //new
                    message = message.Replace("{installFolder}", installFolder);                               //old
                }

                message = message + Environment.NewLine + Environment.NewLine + errors.ToString();
                dlg.htmlTextBox1.HtmlText = message;
                dlg.ShowDialog();
            }
            using (var dlg = new ProblemReporterDialog())
            {
                dlg.Summary     = "Bloom Integrity Check Failed: {0}";
                dlg.Description = "Please answer any of these questions that you understand:"
                                  + Environment.NewLine + Environment.NewLine
                                  + "Did you install Bloom just now, or maybe allow it to update?"
                                  + Environment.NewLine + Environment.NewLine
                                  + "Is your computer locked down against installing new software?"
                                  + Environment.NewLine + Environment.NewLine
                                  + "What antivirus program do you use?"
                                  + Environment.NewLine + Environment.NewLine
                                  + "--------------------------------------------"
                                  + Environment.NewLine + Environment.NewLine
                                  + "The following information is for Bloom developers to see just what is and isn't missing:"
                                  + Environment.NewLine + Environment.NewLine
                                  + errors.ToString()
                                  + GetDirectoryListing(FileLocator.DirectoryOfTheApplicationExecutable)
                                  + Environment.NewLine + Environment.NewLine
                                  + "Detected Antivirus Program(s): " + InstalledAntivirusPrograms();

#if !__MonoCS__
                try
                {
                    var logPath =
                        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
                        .CombineForPath(Application.ProductName, "SquirrelSetup.log");
                    dlg.Description += "=Squirrel Log=" + Environment.NewLine;
                    dlg.Description += logPath + Environment.NewLine;
                    if (RobustFile.Exists(logPath))
                    {
                        dlg.Description += RobustFile.ReadAllText(logPath);
                    }
                    else
                    {
                        dlg.Description += logPath + "not found";
                    }
                }
                catch (Exception error)
                {
                    dlg.Description += error.Message;
                }
#endif
                dlg.ShowDialog();
            }

            return(false);            //Force termination of the current process.
        }
        //autofac uses this
        public WorkspaceView(WorkspaceModel model,
							 Control libraryView,
							 EditingView.Factory editingViewFactory,
							 PublishView.Factory pdfViewFactory,
							 CollectionSettingsDialog.Factory settingsDialogFactory,
							 EditBookCommand editBookCommand,
							SendReceiveCommand sendReceiveCommand,
							 SelectedTabAboutToChangeEvent selectedTabAboutToChangeEvent,
							SelectedTabChangedEvent selectedTabChangedEvent,
							LocalizationChangedEvent localizationChangedEvent,
							 FeedbackDialog.Factory feedbackDialogFactory,
							ProblemReporterDialog.Factory problemReportDialogFactory,
							//ChorusSystem chorusSystem,
							LocalizationManager localizationManager

			)
        {
            _model = model;
            _settingsDialogFactory = settingsDialogFactory;
            _selectedTabAboutToChangeEvent = selectedTabAboutToChangeEvent;
            _selectedTabChangedEvent = selectedTabChangedEvent;
            _localizationChangedEvent = localizationChangedEvent;
            _feedbackDialogFactory = feedbackDialogFactory;
            _problemReportDialogFactory = problemReportDialogFactory;
            //_chorusSystem = chorusSystem;
            _localizationManager = localizationManager;
            _model.UpdateDisplay += new System.EventHandler(OnUpdateDisplay);
            InitializeComponent();

            _checkForNewVersionMenuItem.Visible = SIL.PlatformUtilities.Platform.IsWindows;

            _toolStrip.Renderer = new NoBorderToolStripRenderer();

            //we have a number of buttons which don't make sense for the remote (therefore vulnerable) low-end user
            //_settingsLauncherHelper.CustomSettingsControl = _toolStrip;

            _settingsLauncherHelper.ManageComponent(_settingsButton);

            //NB: the rest of these aren't really settings, but we're using that feature to simplify this menu down to what makes sense for the easily-confused user
            _settingsLauncherHelper.ManageComponent(_openCreateCollectionButton);
            _settingsLauncherHelper.ManageComponent(_keyBloomConceptsMenuItem);
            _settingsLauncherHelper.ManageComponent(_makeASuggestionMenuItem);
            _settingsLauncherHelper.ManageComponent(_webSiteMenuItem);
            _settingsLauncherHelper.ManageComponent(_showLogMenuItem);
            _settingsLauncherHelper.ManageComponent(_releaseNotesMenuItem);
            _settingsLauncherHelper.ManageComponent(_divider2);
            _settingsLauncherHelper.ManageComponent(_divider3);
            _settingsLauncherHelper.ManageComponent(_divider4);

            OnSettingsProtectionChanged(this, null);//initial setup
            SettingsProtectionSettings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnSettingsProtectionChanged);

            _uiLanguageMenu.Visible = true;
            _settingsLauncherHelper.ManageComponent(_uiLanguageMenu);

            editBookCommand.Subscribe(OnEditBook);
            sendReceiveCommand.Subscribe(OnSendReceive);

            //Cursor = Cursors.AppStarting;
            Application.Idle += new EventHandler(Application_Idle);
            Text = _model.ProjectName;

            //SetupTabIcons();

            //
            // _collectionView
            //
            this._collectionView = (LibraryView) libraryView;
            this._collectionView.Dock = System.Windows.Forms.DockStyle.Fill;

            //
            // _editingView
            //
            this._editingView = editingViewFactory();
            this._editingView.Dock = System.Windows.Forms.DockStyle.Fill;

            //
            // _pdfView
            //
            this._publishView = pdfViewFactory();
            this._publishView.Dock = System.Windows.Forms.DockStyle.Fill;

            _collectionTab.Tag = _collectionView;
            _publishTab.Tag = _publishView;
            _editTab.Tag = _editingView;

            this._collectionTab.Text = _collectionView.CollectionTabLabel;

            SetTabVisibility(_publishTab, false);
            SetTabVisibility(_editTab, false);

            //			if (Program.StartUpWithFirstOrNewVersionBehavior)
            //			{
            //				_tabStrip.SelectedTab = _infoTab;
            //				SelectPage(_infoView);
            //			}
            //			else
            //			{
                _tabStrip.SelectedTab = _collectionTab;
                SelectPage(_collectionView);
            //			}

            if (SIL.PlatformUtilities.Platform.IsMono)
            {
                // Without this adjustment, we lose some controls on smaller resolutions.
                AdjustToolPanelLocation(true);
                // in mono auto-size causes the height of the tab strip to be too short
                _tabStrip.AutoSize = false;
            }

            SetupUILanguageMenu();
            _viewInitialized = false;
        }
        /// <summary>
        /// Support the "Report a Problem" button when it shows up in the preview window as part of
        /// a page reporting that we can't open the book for some reason.
        /// </summary>
        private void _previewBrowser_OnBrowserClick(object sender, EventArgs e)
        {
            if (GetAnchorHref(e).EndsWith("ReportProblem"))
            {
                using (var dlg = new ProblemReporterDialog(null,_bookSelection))
                {
                    dlg.SetDefaultIncludeBookSetting(true);
                    dlg.Description =
                        "This book had a problem. Please tell us anything that might be helpful in diagnosing the problem here:" +
                        Environment.NewLine;

                    try
                    {
                        dlg.Description += Environment.NewLine + Environment.NewLine + Environment.NewLine;
                        if(_bookSelection.CurrentSelection.Storage != null)
                        {
                            dlg.Description += _bookSelection.CurrentSelection.Storage.ErrorMessagesHtml;
                        }
                    }
                    catch (Exception)
                    {
                        //no use chasing errors generated getting error info
                    }
                    dlg.ShowInTaskbar = true;
                    dlg.ShowDialog();
                }
            }
        }
        /// <summary>
        /// We've had a number of user reports that suggest that files were either missing or inaccessible.
        /// The idea here is to check a set of files and folders at the start of each launch, and generate
        /// a useful report if anything is missing.
        /// </summary>
        /// <returns>true if all is well. Application should exit if this returns false.</returns>
        public static bool CheckIntegrity()
        {
            var errors = new StringBuilder();
            var files = new[] { "Bloom.chm", "PdfDroplet.exe",
            #if Chorus
                "Chorus.exe",
            #endif
                "BloomPdfMaker.exe", "optipng.exe" };

                string[] dirs;
            if (SIL.PlatformUtilities.Platform.IsWindows)
                dirs = new[] { "AndikaNewBasic", "localization", "xslts" };
            else
                dirs = new[] { "localization", "xslts" };

            foreach(var fileName in files)
            {
                if(!Platform.IsWindows && fileName == "optipng.exe")
                {
                    // optipng is provided by a package dependency, will be found as /usr/bin/optipng (no .exe)
                    continue;
                }
                if(FileLocator.GetFileDistributedWithApplication(true, fileName) == null)
                {
                    //In a code directory, the FileLocator considers the solution the root, so it can't find files in output\debug
                    if(!RobustFile.Exists(Path.Combine(FileLocator.DirectoryOfTheApplicationExecutable, fileName)))
                    {
                        //maybe it's an exe in distfiles?
                        if(fileName.EndsWith(".exe") && RobustFile.Exists(Path.Combine(FileLocator.DirectoryOfApplicationOrSolution, "DistFiles")))
                        {
                            continue;
                        }
                        errors.AppendFormat("Missing File: {0}{1}{1}", fileName, Environment.NewLine);
                    }
                }
            }
            foreach(var directory in dirs)
            {
                if(FileLocator.GetDirectoryDistributedWithApplication(true, directory) == null)
                {
                    errors.AppendFormat("Missing Directory: {0}{1}{1}", directory, Environment.NewLine);
                }
            }
            if(errors.Length == 0)
                return true;

            using(var dlg = new BloomIntegrityDialog())
            {
                var messagePath = BloomFileLocator.GetBestLocalizableFileDistributedWithApplication(false,"IntegrityFailureAdvice-en.md");
                string message;
                if(messagePath == null) // maybe we can't even get at this file we need for a good description of the problem
                {
                    message = "Bloom cannot find some of its own files, and cannot continue. After you submit this report, we will contact you and help you work this out. In the meantime, you can run the Bloom installer again.";
                }
                else
                {
                    var installFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
                            .CombineForPath(Application.ProductName);
                    message = RobustFile.ReadAllText(messagePath).Replace("{installFolder}", installFolder);
                }

                message = message + Environment.NewLine + Environment.NewLine + errors.ToString();
                dlg.markDownTextBox1.MarkDownText = message;
                dlg.ShowDialog();
            }
            using(var dlg = new ProblemReporterDialog())
            {
                dlg.Summary = "Bloom Integrity Check Failed: {0}";
                dlg.Description = "Please answer any of these questions that you understand:"
                                  + Environment.NewLine + Environment.NewLine
                                  + "Did you install Bloom just now, or maybe allow it to update?"
                                  + Environment.NewLine + Environment.NewLine
                                  + "Is your computer locked down against installing new software?"
                                  + Environment.NewLine + Environment.NewLine
                                  + "What antivirus program do you use?"
                                  + Environment.NewLine + Environment.NewLine
                                  + "--------------------------------------------"
                                  + Environment.NewLine + Environment.NewLine
                                  + "The following information is for Bloom developers to see just what is and isn't missing:"
                                  + Environment.NewLine + Environment.NewLine
                                  + errors.ToString()
                                  + GetDirectoryListing(FileLocator.DirectoryOfTheApplicationExecutable)
                                  + Environment.NewLine + Environment.NewLine
                                  + "Detected Antivirus Program(s): " + InstalledAntivirusPrograms();

            #if !__MonoCS__

                try
                {
                    var logPath =
                        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
                            .CombineForPath(Application.ProductName, "SquirrelSetup.log");
                    dlg.Description += "=Squirrel Log=" + Environment.NewLine;
                    dlg.Description += logPath + Environment.NewLine;
                    if(RobustFile.Exists(logPath))
                    {
                        dlg.Description += RobustFile.ReadAllText(logPath);
                    }
                    else
                    {
                        dlg.Description += logPath + "not found";
                    }
                }
                catch(Exception error)
                {
                    dlg.Description += error.Message;
                }
            #endif
                dlg.ShowDialog();
            }

            return false; //Force termination of the current process.
        }