private void HandleCapture() { // Flag to see if the image was "exported" so the FileEditor doesn't // ask to save the file as long as nothing is done. bool outputMade = false; // Make sure the user sees that the capture is made if (_capture.CaptureDetails.CaptureMode == CaptureMode.File || _capture.CaptureDetails.CaptureMode == CaptureMode.Clipboard) { // Maybe not "made" but the original is still there... somehow outputMade = true; } else { // Make sure the resolution is set correctly! if (_capture.CaptureDetails != null && _capture.Image != null) { ((Bitmap)_capture.Image).SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY); } DoCaptureFeedback(); } LOG.Debug("A capture of: " + _capture.CaptureDetails.Title); // check if someone has passed a destination if (_capture.CaptureDetails.CaptureDestinations == null || _capture.CaptureDetails.CaptureDestinations.Count == 0) { AddConfiguredDestination(); } // Create Surface with capture, this way elements can be added automatically (like the mouse cursor) Surface surface = new Surface(_capture); surface.Modified = !outputMade; // Register notify events if this is wanted if (conf.ShowTrayNotification && !conf.HideTrayicon) { surface.SurfaceMessage += SurfaceMessageReceived; } // Let the processors do their job foreach(IProcessor processor in ProcessorHelper.GetAllProcessors()) { if (processor.isActive) { LOG.InfoFormat("Calling processor {0}", processor.Description); processor.ProcessCapture(surface, _capture.CaptureDetails); } } // As the surfaces copies the reference to the image, make sure the image is not being disposed (a trick to save memory) _capture.Image = null; // Get CaptureDetails as we need it even after the capture is disposed ICaptureDetails captureDetails = _capture.CaptureDetails; bool canDisposeSurface = true; if (captureDetails.HasDestination(PickerDestination.DESIGNATION)) { DestinationHelper.ExportCapture(false, PickerDestination.DESIGNATION, surface, captureDetails); captureDetails.CaptureDestinations.Clear(); canDisposeSurface = false; } // Disable capturing _captureMode = CaptureMode.None; // Dispose the capture, we don't need it anymore (the surface copied all information and we got the title (if any)). _capture.Dispose(); _capture = null; int destinationCount = captureDetails.CaptureDestinations.Count; if (destinationCount > 0) { // Flag to detect if we need to create a temp file for the email // or use the file that was written foreach(IDestination destination in captureDetails.CaptureDestinations) { if (PickerDestination.DESIGNATION.Equals(destination.Designation)) { continue; } LOG.InfoFormat("Calling destination {0}", destination.Description); ExportInformation exportInformation = destination.ExportCapture(false, surface, captureDetails); if (EditorDestination.DESIGNATION.Equals(destination.Designation) && exportInformation.ExportMade) { canDisposeSurface = false; } } } if (canDisposeSurface) { surface.Dispose(); } }
private void HandleCapture(string fullPath) { if (capture == null) { StopCapturing(true); } // Flag to see if the image was "exported" so the FileEditor doesn't // ask to save the file as long as nothing is done. bool outputMade = false; // Make sure the user sees that the capture is made if (capture.CaptureDetails.CaptureMode != CaptureMode.File && capture.CaptureDetails.CaptureMode != CaptureMode.Clipboard) { DoCaptureFeedback(); } else { // If File || Clipboard // Maybe not "made" but the original is still there... somehow outputMade = true; } LOG.Debug("A capture of: " + capture.CaptureDetails.Title); // Create event OnCaptureTaken for all Plugins PluginHelper.instance.CreateCaptureTakenEvent(capture); // check if someone has passed a handler if (capture.CaptureDetails.CaptureHandler != null) { CaptureTakenEventArgs eventArgs = new CaptureTakenEventArgs(capture); capture.CaptureDetails.CaptureHandler(this, eventArgs); } else if (capture.CaptureDetails.CaptureDestinations == null || capture.CaptureDetails.CaptureDestinations.Count == 0) { AddConfiguredDestination(capture); } // Create Surface with capture, this way elements can be added automatically (like the mouse cursor) Surface surface = new Surface(capture); // As the surfaces copies the reference to the image, make sure the image is not being disposed (a trick to save memory) capture.Image = null; // Call plugins to do something with the screenshot PluginHelper.instance.CreateSurfaceFromCaptureEvent(capture, surface); // Disable capturing captureMode = CaptureMode.None; // Retrieve important information from the Capture object ICaptureDetails captureDetails = capture.CaptureDetails; List<CaptureDestination> captureDestinations = capture.CaptureDetails.CaptureDestinations; // Dispose the capture, we don't need it anymore (the surface copied all information and we got the title (if any)). capture.Dispose(); capture = null; // Want to add more stuff to the surface?? DO IT HERE! int destinationsCount = captureDestinations.Count; if (captureDestinations.Contains(CaptureDestination.Editor)) { destinationsCount--; } if (destinationsCount > 0) { // Create Image for writing/printing etc and use "using" as all code paths either output the image or copy the image using (Image image = surface.GetImageForExport()) { // Flag to detect if we need to create a temp file for the email // or use the file that was written bool fileWritten = false; if (captureDestinations.Contains(CaptureDestination.espUrl)) { string title = captureDetails.Title; if (string.IsNullOrEmpty(title)) { title = "screen_" + captureDetails.DateTime.ToString("yyyyMMddHHmmssfff"); } using (var ms = new MemoryStream()) { ImageOutput.SaveToStream(image, ms, OutputFormat.png, 1); ms.Seek(0, SeekOrigin.Begin); new EspUrlClient().Upload(ms, title + ".png"); } } if (captureDestinations.Contains(CaptureDestination.File)) { string pattern = conf.OutputFileFilenamePattern; if (pattern == null || string.IsNullOrEmpty(pattern.Trim())) { pattern = "espurl ${capturetime}"; } string filename = FilenameHelper.GetFilenameFromPattern(pattern, conf.OutputFileFormat, captureDetails); string filepath = FilenameHelper.FillVariables(conf.OutputFilePath, false); fullPath = Path.Combine(filepath, filename); // Catching any exception to prevent that the user can't write in the directory. // This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642 try { // TODO: For now we overwrite, but this should be fixed some time ImageOutput.Save(image, fullPath, true); fileWritten = true; outputMade = true; } catch (Exception e) { LOG.Error("Error saving screenshot!", e); // Show the problem MessageBox.Show(lang.GetString(LangKey.error_save), lang.GetString(LangKey.error)); // when save failed we present a SaveWithDialog fullPath = ImageOutput.SaveWithDialog(image, captureDetails); fileWritten = (fullPath != null); } } if (captureDestinations.Contains(CaptureDestination.FileWithDialog)) { fullPath = ImageOutput.SaveWithDialog(image, captureDetails); fileWritten = (fullPath != null); outputMade = outputMade || fileWritten; } if (captureDestinations.Contains(CaptureDestination.Clipboard)) { ClipboardHelper.SetClipboardData(image); outputMade = true; } if (captureDestinations.Contains(CaptureDestination.Printer)) { PrinterSettings printerSettings = new PrintHelper(image, captureDetails).PrintWithDialog(); outputMade = outputMade || printerSettings != null; } if (captureDestinations.Contains(CaptureDestination.EMail)) { if (!fileWritten) { MapiMailMessage.SendImage(image, captureDetails); } else { MapiMailMessage.SendImage(fullPath, captureDetails.Title, false); } // Don't know how to handle a cancel in the email outputMade = true; } } } // Make sure we don't have garbage before opening the screenshot GC.Collect(); GC.WaitForPendingFinalizers(); // If the editor is opened, let it Dispose the surface! if (captureDestinations.Contains(CaptureDestination.Editor)) { try { ImageEditorForm editor = new ImageEditorForm(surface, outputMade); if (!string.IsNullOrEmpty(fullPath)) { editor.SetImagePath(fullPath); } editor.Show(); editor.Activate(); LOG.Debug("Finished opening Editor"); } catch (Exception e) { // Dispose the surface when an error is caught surface.Dispose(); throw e; } } else { // Dispose the surface, we are done with it! surface.Dispose(); } // Make CaptureForm invisible this.Visible = false; // Hiding makes the editor (if any) get focus this.Hide(); }