/// <summary> /// This is an event handler called when the user clicks the Export button. /// </summary> private void FileSaveButton_Click(object sender, EventArgs e) { // If no export method is selected, bail. if (cbExportMethod.SelectedItem == null) { MessageBox.Show("No export method selected. Please select an export method.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // Gather the selected results WatcherResultCollection selectedResults = new WatcherResultCollection(); foreach (AlertListViewItem item in alertListView.Items) { WatcherResult result = new WatcherResult(); result.Description = item.Description; result.Severity = item.Severity; result.Title = item.TypeX; result.URL = item.URL; selectedResults.Add(result); } // The export method refers to an instance of the output plugin WatcherOutputPlugin outputPlugin = cbExportMethod.SelectedItem as WatcherOutputPlugin; if (outputPlugin == null) { Trace.TraceError("WatcherResultsControl: Invalid export method selected."); MessageBox.Show("Unable to use the selected export method.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } String filename = String.Empty; String filter = String.Empty; // If this plugin is a file-based export, open a file save dialog and allow // the user to select the output filename. Use the default values provided // by the plugin. // // TODO: Plugin should be interface-based or provide a property to tell whether it is a file-based export or not if (outputPlugin.GetExportDefaults(ref filename, ref filter)) { SaveFileDialog dlg = new SaveFileDialog(); dlg.FileName = filename; dlg.Filter = filter; dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); dlg.FilterIndex = 1; dlg.RestoreDirectory = true; // Display the dialog, and if canceled, abort. if (dlg.ShowDialog() != DialogResult.OK) { Trace.TraceInformation("User canceled export."); return; } // Update the filename selected by the user filename = dlg.FileName; } // This is the export progress dialog shown during the export process // CHANGE - potentially breaking change, removing progress dialog // which seems to be dreadfully slowing down real work. WatcherEngine.ProgressDialog.Show(); WatcherEngine.ProgressDialog.Title = "Export Data"; // Perform the export asynchronously ExportResultsCallback callback = new ExportResultsCallback(ExportResults); callback.BeginInvoke(outputPlugin, selectedResults, filename, // This is the anonymous callback method delegate(IAsyncResult ar) { try { // Tidy up after the export ExportResultsCallback _callback = (ExportResultsCallback)ar.AsyncState; _callback.EndInvoke(ar); // NOTE: This will throw any unhandled exceptions that happened during the call } catch (WatcherException ex) { Trace.TraceError("Exception: {0}", ex.Message); if (ex.Data.Contains("UserAbortedOperation") == false) { // Only show a message box if the user hasn't already seen one (i.e., they've elected to abort the operation) MessageBox.Show(this, String.Format("{0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); } return; } finally { // CHANGE - see above breaking change, removing progress dialog. WatcherEngine.ProgressDialog.Hide(); } MessageBox.Show(this, "Items successfully exported.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); }, // Pass the callback as user data so we can call EndInvoke() when the operation completes // to retrieve the result. callback); }