///<summary>Tries to log the text passed in to a centralized DBM log.  Displays an error message to the user if anything goes wrong.
 ///Always sets the current Cursor state back to Cursors.Default once finished.</summary>
 private void SaveLogToFile(string logText)
 {
     try {
         DatabaseMaintenances.SaveLogToFile(logText);
     }
     catch (Exception ex) {
         Cursor = Cursors.Default;
         MessageBox.Show(ex.Message);
     }
     Cursor = Cursors.Default;
 }
        private void Run(DbmMode modeCur)
        {
            if (_patNum < 1)
            {
                MsgBox.Show(this, "Select a patient first.");
                return;
            }
            Cursor = Cursors.WaitCursor;
            //Clear out the result column for all rows before every "run"
            for (int i = 0; i < gridMain.Rows.Count; i++)
            {
                gridMain.Rows[i].Cells[2].Text = "";              //Don't use UpdateResultTextForRow here because users will see the rows clearing out one by one.
            }
            bool          verbose = checkShow.Checked;
            StringBuilder logText = new StringBuilder();
            //Create a thread that will show a window and then stay open until the closing phrase is thrown from this form.
            Action actionCloseCheckTableProgress    = ODProgressOld.ShowProgressStatus("CheckTableProgress", this);
            ODTuple <string, bool> tableCheckResult = DatabaseMaintenances.MySQLTables(verbose, modeCur);

            actionCloseCheckTableProgress();
            logText.Append(tableCheckResult.Item1);
            //No database maintenance methods should be run unless this passes.
            if (!tableCheckResult.Item2)
            {
                Cursor = Cursors.Default;
                MsgBoxCopyPaste msgBoxCP = new MsgBoxCopyPaste(tableCheckResult.Item1); //the Tuples result is already translated.
                msgBoxCP.Show();                                                        //Let this window be non-modal so that they can keep it open while they fix their problems.
                return;
            }
            if (gridMain.SelectedIndices.Length < 1)
            {
                //No rows are selected so the user wants to run all checks.
                gridMain.SetSelected(true);
            }
            string result;

            int[] selectedIndices = gridMain.SelectedIndices;
            for (int i = 0; i < selectedIndices.Length; i++)
            {
                long          userNum          = 0;
                DbmMethodAttr methodAttributes = (DbmMethodAttr)Attribute.GetCustomAttribute(_listDbmMethodsGrid[selectedIndices[i]], typeof(DbmMethodAttr));
                //We always send verbose and modeCur into all DBM methods.
                List <object> parameters = new List <object>()
                {
                    verbose, modeCur
                };
                //There are optional paramaters available to some methods and adding them in the following order is very important.
                if (methodAttributes.HasUserNum)
                {
                    parameters.Add(userNum);
                }
                if (methodAttributes.HasPatNum)
                {
                    parameters.Add(_patNum);
                }
                gridMain.ScrollToIndexBottom(selectedIndices[i]);
                UpdateResultTextForRow(selectedIndices[i], Lan.g("FormDatabaseMaintenance", "Running") + "...");
                try {
                    result = (string)_listDbmMethodsGrid[selectedIndices[i]].Invoke(null, parameters.ToArray());
                    if (modeCur == DbmMode.Fix)
                    {
                        DatabaseMaintenances.UpdateDateLastRun(_listDbmMethodsGrid[selectedIndices[i]].Name);
                    }
                }
                catch (Exception ex) {
                    if (ex.InnerException != null)
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();                        //This preserves the stack trace of the InnerException.
                    }
                    throw;
                }
                string status = "";
                if (result == "")               //Only possible if running a check / fix in non-verbose mode and nothing happened or needs to happen.
                {
                    status = Lan.g("FormDatabaseMaintenance", "Done.  No maintenance needed.");
                }
                UpdateResultTextForRow(selectedIndices[i], result + status);
                logText.Append(result);
            }
            gridMain.SetSelected(selectedIndices, true);           //Reselect all rows that were originally selected.
            try {
                DatabaseMaintenances.SaveLogToFile(logText.ToString());
            }
            catch (Exception ex) {
                Cursor = Cursors.Default;
                MessageBox.Show(ex.Message);
            }
            Cursor = Cursors.Default;
            if (modeCur == DbmMode.Fix)
            {
                //_isCacheInvalid=true;//Flag cache to be invalidated on closing.  Some DBM fixes alter cached tables.
            }
        }