diff --git a/Greenshot/Destinations/PickerDestination.cs b/Greenshot/Destinations/PickerDestination.cs index aeb44303e..15795534f 100644 --- a/Greenshot/Destinations/PickerDestination.cs +++ b/Greenshot/Destinations/PickerDestination.cs @@ -39,7 +39,7 @@ namespace Greenshot.Destinations { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PickerDestination)); private static CoreConfiguration conf = IniConfig.GetIniSection(); public const string DESIGNATION = "Picker"; - private ILanguage lang = Language.GetInstance(); + private static ILanguage lang = Language.GetInstance(); public override string Designation { get { @@ -65,7 +65,7 @@ namespace Greenshot.Destinations { } } - public override bool ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { + public static ContextMenuStrip CreatePickerMenu(bool addDynamics, ISurface surface, ICaptureDetails captureDetails, IEnumerable destinations) { ContextMenuStrip menu = new ContextMenuStrip(); menu.Closing += delegate(object source, ToolStripDropDownClosingEventArgs eventArgs) { LOG.DebugFormat("Close reason: {0}", eventArgs.CloseReason); @@ -73,16 +73,9 @@ namespace Greenshot.Destinations { eventArgs.Cancel = true; } }; - - foreach(IDestination destination in DestinationHelper.GetAllDestinations()) { - if ("Picker".Equals(destination.Designation)) { - continue; - } - if (!destination.isActive) { - continue; - } + foreach (IDestination destination in destinations) { // Fix foreach loop variable for the delegate - ToolStripMenuItem item = destination.GetMenuItem( + ToolStripMenuItem item = destination.GetMenuItem(addDynamics, delegate(object sender, EventArgs e) { ToolStripMenuItem toolStripMenuItem = sender as ToolStripMenuItem; if (toolStripMenuItem == null) { @@ -107,7 +100,6 @@ namespace Greenshot.Destinations { menu.Items.Add(item); } } - // Close menu.Items.Add(new ToolStripSeparator()); ToolStripMenuItem closeItem = new ToolStripMenuItem(lang.GetString(LangKey.editor_close)); @@ -119,10 +111,15 @@ namespace Greenshot.Destinations { surface.Dispose(); }; menu.Items.Add(closeItem); - + + return menu; + } + + public static void ShowMenuAtCursor(ContextMenuStrip menu) { // find a suitable location Point location = Cursor.Position; Rectangle menuRectangle = new Rectangle(location, menu.Size); + menuRectangle.Intersect(WindowCapture.GetScreenBounds()); if (menuRectangle.Height < menu.Height) { location.Offset(-40, -(menuRectangle.Height - menu.Height)); @@ -131,6 +128,22 @@ namespace Greenshot.Destinations { } menu.Show(location); menu.Focus(); + } + + public override bool ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { + List destinations = new List(); + foreach(IDestination destination in DestinationHelper.GetAllDestinations()) { + if ("Picker".Equals(destination.Designation)) { + continue; + } + if (!destination.isActive) { + continue; + } + destinations.Add(destination); + } + + ContextMenuStrip menu = CreatePickerMenu(true, surface, captureDetails, destinations); + ShowMenuAtCursor(menu); return true; } } diff --git a/Greenshot/Destinations/PowerpointDestination.cs b/Greenshot/Destinations/PowerpointDestination.cs index af3cf5dde..7c9983003 100644 --- a/Greenshot/Destinations/PowerpointDestination.cs +++ b/Greenshot/Destinations/PowerpointDestination.cs @@ -110,6 +110,16 @@ namespace Greenshot.Destinations { yield return new PowerpointDestination(presentationName); } } + /// + /// Helper method for adding the normal "empty" PowerpointDestination + /// + /// + private IEnumerable AllDynamicDestinations() { + yield return new PowerpointDestination(); + foreach (string presentationName in PowerpointExporter.GetPowerpointPresentations()) { + yield return new PowerpointDestination(presentationName); + } + } public override bool ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { string tmpFile = captureDetails.Filename; @@ -123,7 +133,13 @@ namespace Greenshot.Destinations { if (presentationName != null) { PowerpointExporter.ExportToPresentation(presentationName, tmpFile, imageSize, captureDetails.Title); } else { - PowerpointExporter.InsertIntoNewPresentation(tmpFile, imageSize, captureDetails.Title); + if (manuallyInitiated) { + PowerpointExporter.InsertIntoNewPresentation(tmpFile, imageSize, captureDetails.Title); + } else { + ContextMenuStrip menu = PickerDestination.CreatePickerMenu(false, surface, captureDetails, AllDynamicDestinations()); + PickerDestination.ShowMenuAtCursor(menu); + return false; + } } surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description)); surface.Modified = false; diff --git a/Greenshot/Destinations/WordDestination.cs b/Greenshot/Destinations/WordDestination.cs index b278d4926..22c08fd79 100644 --- a/Greenshot/Destinations/WordDestination.cs +++ b/Greenshot/Destinations/WordDestination.cs @@ -112,6 +112,17 @@ namespace Greenshot.Destinations { } } + /// + /// Helper method for adding the normal "empty" WordDestination + /// + /// + private IEnumerable AllDynamicDestinations() { + yield return new WordDestination(); + foreach (string wordCaption in WordExporter.GetWordDocuments()) { + yield return new WordDestination(wordCaption); + } + } + public override bool ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { string tmpFile = captureDetails.Filename; if (tmpFile == null || surface.Modified) { @@ -122,19 +133,13 @@ namespace Greenshot.Destinations { if (documentCaption != null) { WordExporter.InsertIntoExistingDocument(documentCaption, tmpFile); } else { - bool exported = false; - if (!manuallyInitiated) { - // Insert into current document, if only one is open! - List currentDocuments = WordExporter.GetWordDocuments(); - if (currentDocuments.Count == 1) { - WordExporter.InsertIntoExistingDocument(currentDocuments[0], tmpFile); - exported = true; - } - } - if (!exported) { + if (manuallyInitiated) { WordExporter.InsertIntoNewDocument(tmpFile); + } else { + ContextMenuStrip menu = PickerDestination.CreatePickerMenu(false, surface, captureDetails, AllDynamicDestinations()); + PickerDestination.ShowMenuAtCursor(menu); + return false; } - } surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description)); surface.Modified = false; diff --git a/Greenshot/Forms/ImageEditorForm.cs b/Greenshot/Forms/ImageEditorForm.cs index d063f0c5c..7d9c7fa79 100644 --- a/Greenshot/Forms/ImageEditorForm.cs +++ b/Greenshot/Forms/ImageEditorForm.cs @@ -242,7 +242,7 @@ namespace Greenshot { continue; } - ToolStripMenuItem item = destination.GetMenuItem(new EventHandler(DestinationToolStripMenuItemClick)); + ToolStripMenuItem item = destination.GetMenuItem(true, new EventHandler(DestinationToolStripMenuItemClick)); item.ShortcutKeys = destination.EditorShortcutKeys; if (item != null) { fileStripMenuItem.DropDownItems.Add(item); diff --git a/GreenshotInterop/OfficeExport/PowerpointExporter.cs b/GreenshotInterop/OfficeExport/PowerpointExporter.cs index 990c206ac..458fff471 100644 --- a/GreenshotInterop/OfficeExport/PowerpointExporter.cs +++ b/GreenshotInterop/OfficeExport/PowerpointExporter.cs @@ -116,6 +116,8 @@ namespace Greenshot.Interop.Office { LOG.WarnFormat("Problem setting the title to a text-range: {0}", ex.Message); } } + presentation.Application.ActiveWindow.View.GotoSlide(slide.SlideNumber); + presentation.Application.Activate(); } } @@ -125,6 +127,7 @@ namespace Greenshot.Interop.Office { powerpointApplication.Visible = true; IPresentation presentation = powerpointApplication.Presentations.Add(MsoTriState.msoTrue); AddPictureToPresentation(presentation, tmpFile, imageSize, title); + presentation.Application.Activate(); } } } diff --git a/GreenshotInterop/OfficeInterop/PowerpointInterop.cs b/GreenshotInterop/OfficeInterop/PowerpointInterop.cs index a01a67585..e97b26c0c 100644 --- a/GreenshotInterop/OfficeInterop/PowerpointInterop.cs +++ b/GreenshotInterop/OfficeInterop/PowerpointInterop.cs @@ -31,6 +31,8 @@ namespace Greenshot.Interop.Office { IPresentation ActivePresentation { get; } IPresentations Presentations { get; } bool Visible { get; set; } + void Activate(); + IPowerpointWindow ActiveWindow { get; } } // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.slides_members.aspx @@ -39,10 +41,22 @@ namespace Greenshot.Interop.Office { ISlide Add(int Index, int layout); } + // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.documentwindow.view.aspx + public interface IPowerpointWindow : Common { + void Activate(); + IPowerpointView View { get; } + } + // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.view_members.aspx + public interface IPowerpointView : Common { + IZoom Zoom { get; } + void GotoSlide(int index); + } + // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.presentation_members.aspx public interface IPresentation : Common { string Name { get; } ISlides Slides { get; } + IPowerpointApplication Application { get; } } // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.presentations_members.aspx diff --git a/GreenshotInterop/OfficeInterop/WordInterop.cs b/GreenshotInterop/OfficeInterop/WordInterop.cs index 559c08dd8..d02b281c5 100644 --- a/GreenshotInterop/OfficeInterop/WordInterop.cs +++ b/GreenshotInterop/OfficeInterop/WordInterop.cs @@ -43,12 +43,12 @@ namespace Greenshot.Interop.Office { public interface IWordDocument : Common { void Activate(); IWordApplication Application { get; } - WordWindow ActiveWindow { get; } + IWordWindow ActiveWindow { get; } } // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.window_members.aspx - public interface WordWindow : Common { - Pane ActivePane { get; } + public interface IWordWindow : Common { + IPane ActivePane { get; } void Activate(); string Caption { get; @@ -56,17 +56,17 @@ namespace Greenshot.Interop.Office { } // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.pane_members.aspx - public interface Pane : Common { - View View { get; } + public interface IPane : Common { + IWordView View { get; } } // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.view_members.aspx - public interface View : Common { - Zoom Zoom { get; } + public interface IWordView : Common { + IZoom Zoom { get; } } // See: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.zoom_members.aspx - public interface Zoom : Common { + public interface IZoom : Common { int Percentage { get; set; } } diff --git a/GreenshotPlugin/Core/AbstractDestination.cs b/GreenshotPlugin/Core/AbstractDestination.cs index 779d36ceb..90828d113 100644 --- a/GreenshotPlugin/Core/AbstractDestination.cs +++ b/GreenshotPlugin/Core/AbstractDestination.cs @@ -112,13 +112,13 @@ namespace GreenshotPlugin.Core { /// /// /// ToolStripMenuItem - public virtual ToolStripMenuItem GetMenuItem(EventHandler destinationClickHandler) { + public virtual ToolStripMenuItem GetMenuItem(bool addDynamics, EventHandler destinationClickHandler) { ToolStripMenuItem basisMenuItem; basisMenuItem = new ToolStripMenuItem(Description); basisMenuItem.Image = DisplayIcon; basisMenuItem.Tag = this; basisMenuItem.Text = Description; - if (isDynamic) { + if (isDynamic && addDynamics) { basisMenuItem.DropDownOpening += delegate (object source, EventArgs eventArgs) { if (basisMenuItem.DropDownItems.Count == 0) { List subDestinations = new List(); diff --git a/GreenshotPlugin/Interfaces/IDestination.cs b/GreenshotPlugin/Interfaces/IDestination.cs index 2dbac489f..23827fadb 100644 --- a/GreenshotPlugin/Interfaces/IDestination.cs +++ b/GreenshotPlugin/Interfaces/IDestination.cs @@ -66,9 +66,10 @@ namespace Greenshot.Plugin { /// /// Return a menu item /// - /// + /// Resolve the dynamic destinations too? + /// Handler which is called when clicked /// ToolStripMenuItem - ToolStripMenuItem GetMenuItem(EventHandler destinationClickHandler); + ToolStripMenuItem GetMenuItem(bool addDynamics, EventHandler destinationClickHandler); /// /// Gets the ShortcutKeys for the Editor