Refactored the Office Destinations, including the Interop & configuration, to the new Office plug-in. Also refactored some code to be more consistent.

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2131 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-10-10 14:18:05 +00:00
commit 4d399a60ac
34 changed files with 739 additions and 365 deletions

View file

@ -27,7 +27,6 @@ using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Helpers;
using Greenshot.Interop.Office;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.IniFile;
@ -39,16 +38,10 @@ namespace Greenshot.Destinations {
public class EmailDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(EmailDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image applicationIcon = null;
private static Image mailIcon = null;
private static Image meetingIcon = null;
private static Image mailIcon = GreenshotPlugin.Core.GreenshotResources.getImage("Email.Image");
private static bool isActiveFlag = false;
private static bool isOutlookUsed = false;
private static string mapiClient = null;
public const string DESIGNATION = "EMail";
private string outlookInspectorCaption;
private OlObjectClass outlookInspectorType;
static EmailDestination() {
// Logic to decide what email implementation we use
@ -57,48 +50,15 @@ namespace Greenshot.Destinations {
mapiClient = EmailConfigHelper.GetMapiClient();
if (!string.IsNullOrEmpty(mapiClient)) {
if (mapiClient.ToLower().Contains("microsoft outlook")) {
isOutlookUsed = true;
}
}
} else if (EmailConfigHelper.HasOutlook()) {
mapiClient = "Microsoft Outlook";
isActiveFlag = true;
isOutlookUsed = true;
}
// Use default email icon
mailIcon = GreenshotPlugin.Core.GreenshotResources.getImage("Email.Image");
if (isOutlookUsed) {
exePath = PluginUtils.GetExePath("OUTLOOK.EXE");
if (exePath != null && File.Exists(exePath)) {
applicationIcon = PluginUtils.GetExeIcon(exePath, 0);
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
if (conf.OutlookAllowExportInMeetings) {
meetingIcon = PluginUtils.GetExeIcon(exePath, 2);
}
} else {
exePath = null;
}
if (exePath == null) {
isOutlookUsed = false;
if (!EmailConfigHelper.HasMAPI()) {
isActiveFlag = false;
}
}
}
if (isActiveFlag && !isOutlookUsed) {
// Use default email icon
applicationIcon = mailIcon;
}
}
public EmailDestination() {
}
public EmailDestination(string outlookInspectorCaption, OlObjectClass outlookInspectorType) {
this.outlookInspectorCaption = outlookInspectorCaption;
this.outlookInspectorType = outlookInspectorType;
}
public override string Designation {
get {
@ -112,12 +72,7 @@ namespace Greenshot.Destinations {
if (mapiClient == null) {
mapiClient = Language.GetString(LangKey.editor_email);
}
if (outlookInspectorCaption == null) {
return mapiClient;
} else {
return outlookInspectorCaption;
}
return mapiClient;
}
}
@ -133,12 +88,6 @@ namespace Greenshot.Destinations {
}
}
public override bool isDynamic {
get {
return isOutlookUsed;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.E;
@ -147,85 +96,15 @@ namespace Greenshot.Destinations {
public override Image DisplayIcon {
get {
if (isOutlookUsed && outlookInspectorCaption != null) {
if (OlObjectClass.olAppointment.Equals(outlookInspectorType)) {
// Make sure we loaded the icon, maybe the configuration has been changed!
if (meetingIcon == null) {
meetingIcon = PluginUtils.GetExeIcon(exePath, 2);
}
return meetingIcon;
} else {
return mailIcon;
}
} else {
return applicationIcon;
}
return mailIcon;
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
if (!isOutlookUsed) {
yield break;
}
Dictionary<string, OlObjectClass> inspectorCaptions = OutlookEmailExporter.RetrievePossibleTargets(conf.OutlookAllowExportInMeetings);
if (inspectorCaptions != null) {
foreach (string inspectorCaption in inspectorCaptions.Keys) {
yield return new EmailDestination(inspectorCaption, inspectorCaptions[inspectorCaption]);
}
}
}
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
if (!isOutlookUsed) {
using (Image image = surface.GetImageForExport()) {
MapiMailMessage.SendImage(image, captureDetails);
exportInformation.ExportMade = true;
}
return exportInformation;
} else {
// Outlook logic
string tmpFile = captureDetails.Filename;
if (tmpFile == null || surface.Modified) {
using (Image image = surface.GetImageForExport()) {
tmpFile = ImageOutput.SaveNamedTmpFile(image, captureDetails, new OutputSettings());
}
} else {
LOG.InfoFormat("Using already available file: {0}", tmpFile);
}
// Create a attachment name for the image
string attachmentName = captureDetails.Title;
if (!string.IsNullOrEmpty(attachmentName)) {
attachmentName = attachmentName.Trim();
}
// Set default if non is set
if (string.IsNullOrEmpty(attachmentName)) {
attachmentName = "Greenshot Capture";
}
// Make sure it's "clean" so it doesn't corrupt the header
attachmentName = Regex.Replace(attachmentName, @"[^\x20\d\w]", "");
if (outlookInspectorCaption != null) {
OutlookEmailExporter.ExportToInspector(outlookInspectorCaption, tmpFile, attachmentName);
exportInformation.ExportMade = true;
} else {
if (!manuallyInitiated) {
Dictionary<string, OlObjectClass> inspectorCaptions = OutlookEmailExporter.RetrievePossibleTargets(conf.OutlookAllowExportInMeetings);
if (inspectorCaptions != null && inspectorCaptions.Count > 0) {
List<IDestination> destinations = new List<IDestination>();
destinations.Add(new EmailDestination());
foreach (string inspectorCaption in inspectorCaptions.Keys) {
destinations.Add(new EmailDestination(inspectorCaption, inspectorCaptions[inspectorCaption]));
}
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
return PickerDestination.ShowPickerMenu(false, surface, captureDetails, destinations);
}
} else {
OutlookEmailExporter.ExportToOutlook(conf.OutlookEmailFormat, tmpFile, FilenameHelper.FillPattern(conf.EmailSubjectPattern, captureDetails, false), attachmentName, conf.EmailTo, conf.EmailCC, conf.EmailBCC);
exportInformation.ExportMade = true;
}
}
using (Image image = surface.GetImageForExport()) {
MapiMailMessage.SendImage(image, captureDetails);
exportInformation.ExportMade = true;
}
ProcessExport(exportInformation, surface);
return exportInformation;

View file

@ -30,7 +30,6 @@ using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Forms;
using Greenshot.IniFile;
using GreenshotPlugin.UnmanagedHelpers;
namespace Greenshot.Destinations {
/// <summary>
@ -59,121 +58,6 @@ namespace Greenshot.Destinations {
}
}
/// <summary>
/// This method will create and show the destination picker menu
/// </summary>
/// <param name="addDynamics">Boolean if the dynamic values also need to be added</param>
/// <param name="surface">The surface which can be exported</param>
/// <param name="captureDetails">Details for the surface</param>
/// <param name="destinations">The list of destinations to show</param>
/// <returns></returns>
public static ExportInformation ShowPickerMenu(bool addDynamics, ISurface surface, ICaptureDetails captureDetails, IEnumerable<IDestination> destinations) {
// Generate an empty ExportInformation object, for when nothing was selected.
ExportInformation exportInformation = new ExportInformation(DESIGNATION, Language.GetString(LangKey.settings_destination_picker));
ContextMenuStrip menu = new ContextMenuStrip();
menu.Closing += delegate(object source, ToolStripDropDownClosingEventArgs eventArgs) {
LOG.DebugFormat("Close reason: {0}", eventArgs.CloseReason);
switch (eventArgs.CloseReason) {
case ToolStripDropDownCloseReason.ItemClicked:
case ToolStripDropDownCloseReason.CloseCalled:
break;
case ToolStripDropDownCloseReason.Keyboard:
// Dispose as the close is clicked
surface.Dispose();
surface = null;
break;
default:
eventArgs.Cancel = true;
break;
}
};
foreach (IDestination destination in destinations) {
// Fix foreach loop variable for the delegate
ToolStripMenuItem item = destination.GetMenuItem(addDynamics,
delegate(object sender, EventArgs e) {
ToolStripMenuItem toolStripMenuItem = sender as ToolStripMenuItem;
if (toolStripMenuItem == null) {
return;
}
IDestination clickedDestination = (IDestination)toolStripMenuItem.Tag;
if (clickedDestination == null) {
return;
}
bool isEditor = EditorDestination.DESIGNATION.Equals(clickedDestination.Designation);
// Make sure the menu is invisible, don't close it
menu.Hide();
// Export
exportInformation = clickedDestination.ExportCapture(true, surface, captureDetails);
if (exportInformation != null && exportInformation.ExportMade) {
LOG.InfoFormat("Export to {0} success, closing menu", exportInformation.DestinationDescription);
// close menu if the destination wasn't the editor
menu.Close();
// Cleanup surface, only if the destination wasn't the editor
if (!isEditor) {
surface.Dispose();
surface = null;
}
} else {
LOG.Info("Export cancelled or failed, showing menu again");
// This prevents the problem that the context menu shows in the task-bar
ShowMenuAtCursor(menu);
}
}
);
if (item != null) {
menu.Items.Add(item);
}
}
// Close
menu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem closeItem = new ToolStripMenuItem(Language.GetString(LangKey.editor_close));
closeItem.Image = ((System.Drawing.Image)(new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm)).GetObject("closeToolStripMenuItem.Image")));
closeItem.Click += delegate {
// This menu entry is the close itself, we can dispose the surface
menu.Close();
// Dispose as the close is clicked
surface.Dispose();
surface = null;
};
menu.Items.Add(closeItem);
ShowMenuAtCursor(menu);
return exportInformation;
}
/// <summary>
/// This method will show the supplied context menu at the mouse cursor, also makes sure it has focus and it's not visible in the taskbar.
/// </summary>
/// <param name="menu"></param>
private 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));
} else {
location.Offset(-40, -10);
}
// This prevents the problem that the context menu shows in the task-bar
User32.SetForegroundWindow(MainForm.instance.notifyIcon.ContextMenuStrip.Handle);
menu.Show(location);
menu.Focus();
// Wait for the menu to close, so we can dispose it.
while (true) {
if (menu.Visible) {
Application.DoEvents();
System.Threading.Thread.Sleep(100);
} else {
menu.Dispose();
break;
}
}
}
/// <summary>
/// Export the capture with the destination picker

View file

@ -650,7 +650,7 @@ namespace Greenshot {
}
void PreferencesToolStripMenuItemClick(object sender, System.EventArgs e) {
MainForm.instance.ShowSetting();
MainForm.Instance.ShowSetting();
}
void BtnSettingsClick(object sender, System.EventArgs e) {
@ -1107,7 +1107,7 @@ namespace Greenshot {
void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e) {
ToolStripMenuItem captureWindowMenuItem = (ToolStripMenuItem)sender;
MainForm.instance.AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click);
MainForm.Instance.AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click);
}
void Contextmenu_window_Click(object sender, EventArgs e) {

View file

@ -288,7 +288,7 @@ namespace Greenshot {
private GreenshotPlugin.Controls.GreenshotToolStripMenuItem contextmenu_capturefullscreen;
private GreenshotPlugin.Controls.GreenshotToolStripMenuItem contextmenu_capturelastregion;
private GreenshotPlugin.Controls.GreenshotToolStripMenuItem contextmenu_capturearea;
public System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.ToolStripSeparator toolStripCloseSeparator;
private GreenshotPlugin.Controls.GreenshotToolStripMenuItem contextmenu_exit;
private System.Windows.Forms.ContextMenuStrip contextMenu;

View file

@ -288,19 +288,30 @@ namespace Greenshot {
}
}
public static MainForm instance = null;
private static MainForm instance = null;
public static MainForm Instance {
get {
return instance;
}
}
private ToolTip tooltip;
private CopyData copyData = null;
// Thumbnail preview
private ThumbnailForm thumbnailForm = null;
private ThumbnailForm thumbnailForm = null;
private IntPtr thumbnailHandle = IntPtr.Zero;
private Rectangle parentMenuBounds = Rectangle.Empty;
// Make sure we have only one settings form
private SettingsForm settingsForm = null;
// Make sure we have only one about form
private AboutForm aboutForm = null;
public NotifyIcon NotifyIcon {
get {
return notifyIcon;
}
}
public MainForm(CopyDataTransport dataTransport) {
instance = this;
@ -330,7 +341,7 @@ namespace Greenshot {
// Do loading on a different Thread to shorten the startup
Thread pluginInitThread = new Thread (delegate() {
// Load all the plugins
PluginHelper.instance.LoadPlugins(this);
PluginHelper.Instance.LoadPlugins(this);
// Check destinations, remove all that don't exist
foreach(string destination in conf.OutputDestinations.ToArray()) {
@ -1142,7 +1153,7 @@ namespace Greenshot {
// Inform all registed plugins
try {
PluginHelper.instance.Shutdown();
PluginHelper.Instance.Shutdown();
} catch (Exception e) {
LOG.Error("Error shutting down plugins!", e);
}

View file

@ -170,7 +170,7 @@ namespace Greenshot {
}
private void DisplayPluginTab() {
if (!PluginHelper.instance.HasPlugins()) {
if (!PluginHelper.Instance.HasPlugins()) {
this.tabcontrol.TabPages.Remove(tab_plugins);
} else {
// Draw the Plugin listview
@ -181,7 +181,7 @@ namespace Greenshot {
foreach (string column in columns) {
listview_plugins.Columns.Add(column);
}
PluginHelper.instance.FillListview(this.listview_plugins);
PluginHelper.Instance.FillListview(this.listview_plugins);
// Maximize Column size!
for (int i = 0; i < listview_plugins.Columns.Count; i++) {
listview_plugins.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
@ -393,7 +393,7 @@ namespace Greenshot {
coreConfiguration.UpdateCheckInterval = (int)numericUpDown_daysbetweencheck.Value;
// Make sure the current language & settings are reflected in the Main-context menu
MainForm.instance.UpdateUI();
MainForm.Instance.UpdateUI();
try {
// Check if the Run for all is set
@ -453,11 +453,11 @@ namespace Greenshot {
}
void Listview_pluginsSelectedIndexChanged(object sender, EventArgs e) {
button_pluginconfigure.Enabled = PluginHelper.instance.isSelectedItemConfigurable(listview_plugins);
button_pluginconfigure.Enabled = PluginHelper.Instance.isSelectedItemConfigurable(listview_plugins);
}
void Button_pluginconfigureClick(object sender, EventArgs e) {
PluginHelper.instance.ConfigureSelectedItem(listview_plugins);
PluginHelper.Instance.ConfigureSelectedItem(listview_plugins);
}
void Combobox_languageSelectedIndexChanged(object sender, EventArgs e) {

View file

@ -70,14 +70,10 @@
<Compile Include="Destinations\ClipboardDestination.cs" />
<Compile Include="Destinations\EditorDestination.cs" />
<Compile Include="Destinations\EmailDestination.cs" />
<Compile Include="Destinations\ExcelDestination.cs" />
<Compile Include="Destinations\FileDestination.cs" />
<Compile Include="Destinations\FileWithDialogDestination.cs" />
<Compile Include="Destinations\OneNoteDestination.cs" />
<Compile Include="Destinations\PickerDestination.cs" />
<Compile Include="Destinations\PowerpointDestination.cs" />
<Compile Include="Destinations\PrinterDestination.cs" />
<Compile Include="Destinations\WordDestination.cs" />
<Compile Include="Drawing\ArrowContainer.cs" />
<Compile Include="Drawing\BitmapContainer.cs" />
<Compile Include="Drawing\CropContainer.cs" />

View file

@ -1,6 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.2.8818
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greenshot", "Greenshot.csproj", "{CD642BF4-D815-4D67-A0B5-C69F0B8231AF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotPlugin", "..\GreenshotPlugin\GreenshotPlugin.csproj", "{5B924697-4DCD-4F98-85F1-105CB84B7341}"
@ -25,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotFlickrPlugin", "..
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotPicasaPlugin", "..\..\Greenshot-Plugins\GreenshotPicasaPlugin\GreenshotPicasaPlugin.csproj", "{1893A2E4-A78A-4713-A8E7-E70058DABEE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotOfficePlugin", "..\GreenshotOfficePlugin\GreenshotOfficePlugin.csproj", "{2167DE58-7C83-4BDA-97CE-FA57BE8FA22B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -131,6 +134,10 @@ Global
{1893A2E4-A78A-4713-A8E7-E70058DABEE0}.Release|Any CPU.Build.0 = Release|Any CPU
{1893A2E4-A78A-4713-A8E7-E70058DABEE0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1893A2E4-A78A-4713-A8E7-E70058DABEE0}.Release|x86.ActiveCfg = Release|x86
{2167DE58-7C83-4BDA-97CE-FA57BE8FA22B}.Debug|x86.Build.0 = Debug|x86
{2167DE58-7C83-4BDA-97CE-FA57BE8FA22B}.Debug|x86.ActiveCfg = Debug|x86
{2167DE58-7C83-4BDA-97CE-FA57BE8FA22B}.Release|Any CPU.Build.0 = Release|x86
{2167DE58-7C83-4BDA-97CE-FA57BE8FA22B}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -163,8 +163,8 @@ namespace Greenshot.Helpers {
// This fixes a problem when a balloon is still visible and a capture needs to be taken
// forcefully removes the balloon!
if (!conf.HideTrayicon) {
MainForm.instance.notifyIcon.Visible = false;
MainForm.instance.notifyIcon.Visible = true;
MainForm.Instance.NotifyIcon.Visible = false;
MainForm.Instance.NotifyIcon.Visible = true;
}
LOG.Debug(String.Format("Capturing with mode {0} and using Cursor {1}", captureMode, captureMouseCursor));
capture.CaptureDetails.CaptureMode = captureMode;
@ -191,7 +191,7 @@ namespace Greenshot.Helpers {
// Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
// Workaround for changed DPI settings in Windows 7
using (Graphics graphics = Graphics.FromHwnd(MainForm.instance.Handle)) {
using (Graphics graphics = Graphics.FromHwnd(MainForm.Instance.Handle)) {
capture.CaptureDetails.DpiX = graphics.DpiX;
capture.CaptureDetails.DpiY = graphics.DpiY;
}
@ -524,10 +524,10 @@ namespace Greenshot.Helpers {
}
switch (eventArgs.MessageType) {
case SurfaceMessageTyp.Error:
MainForm.instance.notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Error);
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Error);
break;
case SurfaceMessageTyp.Info:
MainForm.instance.notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
break;
case SurfaceMessageTyp.FileSaved:
case SurfaceMessageTyp.UploadedUri:
@ -535,8 +535,8 @@ namespace Greenshot.Helpers {
EventHandler balloonTipClosedHandler = null;
balloonTipClosedHandler = delegate(object sender, EventArgs e) {
LOG.DebugFormat("Deregistering the BalloonTipClosed");
MainForm.instance.notifyIcon.BalloonTipClicked -= balloonTipClickedHandler;
MainForm.instance.notifyIcon.BalloonTipClosed -= balloonTipClosedHandler;
MainForm.Instance.NotifyIcon.BalloonTipClicked -= balloonTipClickedHandler;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= balloonTipClosedHandler;
};
balloonTipClickedHandler = delegate(object sender, EventArgs e) {
@ -555,12 +555,12 @@ namespace Greenshot.Helpers {
}
}
LOG.DebugFormat("Deregistering the BalloonTipClicked");
MainForm.instance.notifyIcon.BalloonTipClicked -= balloonTipClickedHandler;
MainForm.instance.notifyIcon.BalloonTipClosed -= balloonTipClosedHandler;
MainForm.Instance.NotifyIcon.BalloonTipClicked -= balloonTipClickedHandler;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= balloonTipClosedHandler;
};
MainForm.instance.notifyIcon.BalloonTipClicked += balloonTipClickedHandler;
MainForm.instance.notifyIcon.BalloonTipClosed += balloonTipClosedHandler;
MainForm.instance.notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
MainForm.Instance.NotifyIcon.BalloonTipClicked += balloonTipClickedHandler;
MainForm.Instance.NotifyIcon.BalloonTipClosed += balloonTipClosedHandler;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
break;
}
};

View file

@ -74,8 +74,8 @@ namespace Greenshot.Helpers {
/// <returns>List<IDestination></returns>
private static List<IDestination> GetPluginDestinations() {
List<IDestination> destinations = new List<IDestination>();
foreach (PluginAttribute pluginAttribute in PluginHelper.instance.Plugins.Keys) {
IGreenshotPlugin plugin = PluginHelper.instance.Plugins[pluginAttribute];
foreach (PluginAttribute pluginAttribute in PluginHelper.Instance.Plugins.Keys) {
IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute];
try {
var dests = plugin.Destinations();
if (dests != null) {

View file

@ -28,7 +28,6 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Interop.Office;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.IniFile;

View file

@ -39,14 +39,26 @@ namespace Greenshot.Helpers {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PluginHelper));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public static string pluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);
public static string applicationPath = Path.GetDirectoryName(Application.ExecutablePath);
public static string pafPath = Path.Combine(Application.StartupPath, @"App\Greenshot");
public static readonly PluginHelper instance = new PluginHelper();
private static string pluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);
private static string applicationPath = Path.GetDirectoryName(Application.ExecutablePath);
private static string pafPath = Path.Combine(Application.StartupPath, @"App\Greenshot");
private static IDictionary<PluginAttribute, IGreenshotPlugin> plugins = new SortedDictionary<PluginAttribute, IGreenshotPlugin>();
private static readonly PluginHelper instance = new PluginHelper();
public static PluginHelper Instance {
get {
return instance;
}
}
private PluginHelper() {
PluginUtils.Host = this;
}
public NotifyIcon NotifyIcon {
get {
return MainForm.Instance.NotifyIcon;
}
}
public bool HasPlugins() {
@ -145,7 +157,7 @@ namespace Greenshot.Helpers {
/// </summary>
/// <param name="imageToImport">Image to handle</param>
public void ImportCapture(ICapture captureToImport) {
MainForm.instance.BeginInvoke((MethodInvoker)delegate {
MainForm.Instance.BeginInvoke((MethodInvoker)delegate {
CaptureHelper.ImportCapture(captureToImport);
});
}

View file

@ -73,8 +73,8 @@ namespace Greenshot.Helpers {
private static List<IProcessor> GetPluginsProcessors() {
List<IProcessor> processors = new List<IProcessor>();
foreach (PluginAttribute pluginAttribute in PluginHelper.instance.Plugins.Keys) {
IGreenshotPlugin plugin = PluginHelper.instance.Plugins[pluginAttribute];
foreach (PluginAttribute pluginAttribute in PluginHelper.Instance.Plugins.Keys) {
IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute];
try {
var procs = plugin.Processors();
if (procs != null) {

View file

@ -78,9 +78,9 @@ namespace Greenshot.Experimental {
try {
UpdateHelper.ProcessRSSInfo(currentVersion);
if (latestGreenshot != null) {
MainForm.instance.notifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.instance.notifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.instance.notifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, latestGreenshot.Version), ToolTipIcon.Info);
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, latestGreenshot.Version), ToolTipIcon.Info);
}
conf.LastUpdateCheck = DateTime.Now;
IniConfig.Save();
@ -91,8 +91,8 @@ namespace Greenshot.Experimental {
}
private static void CleanupBalloonTipClick(object sender, EventArgs e) {
MainForm.instance.notifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.instance.notifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
}
private static void HandleBalloonTipClick(object sender, EventArgs e) {
@ -106,8 +106,8 @@ namespace Greenshot.Experimental {
} catch (Exception) {
MessageBox.Show(Language.GetFormattedString(LangKey.error_openlink, latestGreenshot.Link), Language.GetString(LangKey.error));
} finally {
MainForm.instance.notifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.instance.notifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
}
}

View file

@ -60,6 +60,8 @@ Source: ..\..\Languages\*vi-VN*; DestDir: {app}\Languages; Components: languages
Source: ..\..\Languages\*zh-CN*; DestDir: {app}\Languages; Components: languages\zhCN; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*zh-TW*; DestDir: {app}\Languages; Components: languages\zhTW; Flags: overwritereadonly ignoreversion replacesameversion;
;Office Plugin
Source: ..\..\bin\Release\Plugins\GreenshotOfficePlugin\GreenshotOfficePlugin.gsp; DestDir: {app}\Plugins\GreenshotOfficePlugin; Components: plugins\office; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
;OCR Plugin
Source: ..\..\bin\Release\Plugins\GreenshotOCRPlugin\GreenshotOCRPlugin.gsp; DestDir: {app}\Plugins\GreenshotOCRPlugin; Components: plugins\ocr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: ..\..\bin\Release\Plugins\GreenshotOCRPlugin\GreenshotOCRCommand.exe; DestDir: {app}\Plugins\GreenshotOCRPlugin; Components: plugins\ocr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
@ -159,6 +161,7 @@ Name: startup; Description: {cm:startup}
de.confluence=Confluence Plug-in
de.default=Standard installation
en.office=Microsoft Office Plug-in
de.externalcommand=Öffne mit ein externem Kommando Plug-in
de.imgur=Imgur Plug-in (Siehe: http://imgur.com)
de.jira=Jira Plug-in
@ -170,6 +173,7 @@ de.startup={#ExeName} starten wenn Windows hochfährt
en.confluence=Confluence plug-in
en.default=Default installation
en.office=Microsoft Office plug-in
en.externalcommand=Open with external command plug-in
en.imgur=Imgur plug-in (See: http://imgur.com)
en.jira=Jira plug-in
@ -181,6 +185,7 @@ en.startup=Start {#ExeName} with Windows start
fr.confluence=Greffon Confluence
fr.default=${default}
fr.office=Greffon Microsoft Office
fr.externalcommand=Ouvrir avec le greffon de commande externe
fr.imgur=Greffon Imgur (Voir: http://imgur.com)
fr.jira=Greffon Jira
@ -192,6 +197,7 @@ fr.startup=Démarrer {#ExeName} avec le bouton Démarrer de Windows
nl.confluence=Confluence plug-in
nl.default=Default installation
nl.office=Microsoft Office plug-in
nl.externalcommand=Open met externes commando plug-in
nl.imgur=Imgur plug-in (Zie: http://imgur.com)
nl.jira=Jira plug-in
@ -203,6 +209,7 @@ nl.startup=Start {#ExeName} wanneer Windows opstart
nn.confluence=Confluence-tillegg
nn.default=Default installation
nl.office=Microsoft Office Tillegg
nn.externalcommand=Tillegg for å opne med ekstern kommando
nn.imgur=Imgur-tillegg (sjå http://imgur.com)
nn.jira=Jira-tillegg
@ -220,6 +227,7 @@ Name: "custom"; Description: "{code:CustomInstall}"; Flags: iscustom
[Components]
Name: "greenshot"; Description: "Greenshot"; Types: default full compact custom; Flags: fixed
Name: "plugins\office"; Description: {cm:office}; Types: default full custom; Flags: disablenouninstallwarning
Name: "plugins\ocr"; Description: {cm:ocr}; Types: default full custom; Flags: disablenouninstallwarning
Name: "plugins\jira"; Description: {cm:jira}; Types: full custom; Flags: disablenouninstallwarning
Name: "plugins\imgur"; Description: {cm:imgur}; Types: default full custom; Flags: disablenouninstallwarning

View file

@ -34,7 +34,7 @@ using GreenshotPlugin.Controls;
namespace GreenshotConfluencePlugin {
/// <summary>
/// Description of JiraDestination.
/// Description of ConfluenceDestination.
/// </summary>
public class ConfluenceDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ConfluenceDestination));

View file

@ -110,7 +110,7 @@ namespace GreenshotConfluencePlugin {
}
try {
TranslationManager.Instance.TranslationProvider = new LanguageXMLTranslationProvider();
//resources = new ComponentResourceManager(typeof(JiraPlugin));
//resources = new ComponentResourceManager(typeof(ConfluencePlugin));
} catch (Exception ex) {
LOG.ErrorFormat("Problem in ConfluencePlugin.Initialize: {0}", ex.Message);
return false;

View file

@ -33,7 +33,7 @@ using Greenshot.IniFile;
namespace GreenshotImgurPlugin {
/// <summary>
/// This is the JiraPlugin base code
/// This is the ImgurPlugin code
/// </summary>
public class ImgurPlugin : IGreenshotPlugin {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImgurPlugin));

View file

@ -30,7 +30,7 @@ using Greenshot.Plugin;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Greenshot-Imgur-Plugin")]
[assembly: AssemblyTitle("GreenshotImgurPlugin")]
[assembly: AssemblyDescription("A plugin to upload images to Imgur")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Greenshot")]

View file

@ -24,20 +24,17 @@ using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Interop.Office;
using Greenshot.IniFile;
namespace Greenshot.Destinations {
namespace GreenshotOfficePlugin {
/// <summary>
/// Description of PowerpointDestination.
/// </summary>
public class ExcelDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ExcelDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image applicationIcon = null;
private static Image workbookIcon = null;

View file

@ -25,18 +25,15 @@ using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Interop.Office;
using Greenshot.IniFile;
namespace Greenshot.Destinations {
namespace GreenshotOfficePlugin {
public class OneNoteDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WordDestination));
public const string DESIGNATION = "OneNote";
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image applicationIcon = null;
private static Image notebookIcon = null;

View file

@ -0,0 +1,192 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Greenshot.Interop.Office;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.IniFile;
namespace GreenshotOfficePlugin {
/// <summary>
/// Description of OutlookDestination.
/// </summary>
public class OutlookDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OutlookDestination));
private static OfficeConfiguration conf = IniConfig.GetIniSection<OfficeConfiguration>();
private static string exePath = null;
private static Image applicationIcon = null;
private static Image mailIcon = GreenshotPlugin.Core.GreenshotResources.getImage("Email.Image");
private static Image meetingIcon = null;
private static bool isActiveFlag = false;
private static string mapiClient = "Microsoft Outlook";
public const string DESIGNATION = "Outlook";
private string outlookInspectorCaption;
private OlObjectClass outlookInspectorType;
static OutlookDestination() {
if (EmailConfigHelper.HasOutlook()) {
isActiveFlag = true;
}
exePath = PluginUtils.GetExePath("OUTLOOK.EXE");
if (exePath != null && File.Exists(exePath)) {
applicationIcon = PluginUtils.GetExeIcon(exePath, 0);
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
if (conf.OutlookAllowExportInMeetings) {
meetingIcon = PluginUtils.GetExeIcon(exePath, 2);
}
} else {
exePath = null;
}
if (exePath == null) {
isActiveFlag = false;
}
}
public OutlookDestination() {
}
public OutlookDestination(string outlookInspectorCaption, OlObjectClass outlookInspectorType) {
this.outlookInspectorCaption = outlookInspectorCaption;
this.outlookInspectorType = outlookInspectorType;
}
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
if (outlookInspectorCaption == null) {
return mapiClient;
} else {
return outlookInspectorCaption;
}
}
}
public override int Priority {
get {
return 3;
}
}
public override bool isActive {
get {
return base.isActive && isActiveFlag;
}
}
public override bool isDynamic {
get {
return true;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.E;
}
}
public override Image DisplayIcon {
get {
if (outlookInspectorCaption != null) {
if (OlObjectClass.olAppointment.Equals(outlookInspectorType)) {
// Make sure we loaded the icon, maybe the configuration has been changed!
if (meetingIcon == null) {
meetingIcon = PluginUtils.GetExeIcon(exePath, 2);
}
return meetingIcon;
} else {
return mailIcon;
}
} else {
return applicationIcon;
}
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
Dictionary<string, OlObjectClass> inspectorCaptions = OutlookEmailExporter.RetrievePossibleTargets(conf.OutlookAllowExportInMeetings);
if (inspectorCaptions != null) {
foreach (string inspectorCaption in inspectorCaptions.Keys) {
yield return new OutlookDestination(inspectorCaption, inspectorCaptions[inspectorCaption]);
}
}
}
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
// Outlook logic
string tmpFile = captureDetails.Filename;
if (tmpFile == null || surface.Modified) {
using (Image image = surface.GetImageForExport()) {
tmpFile = ImageOutput.SaveNamedTmpFile(image, captureDetails, new OutputSettings());
}
} else {
LOG.InfoFormat("Using already available file: {0}", tmpFile);
}
// Create a attachment name for the image
string attachmentName = captureDetails.Title;
if (!string.IsNullOrEmpty(attachmentName)) {
attachmentName = attachmentName.Trim();
}
// Set default if non is set
if (string.IsNullOrEmpty(attachmentName)) {
attachmentName = "Greenshot Capture";
}
// Make sure it's "clean" so it doesn't corrupt the header
attachmentName = Regex.Replace(attachmentName, @"[^\x20\d\w]", "");
if (outlookInspectorCaption != null) {
OutlookEmailExporter.ExportToInspector(outlookInspectorCaption, tmpFile, attachmentName);
exportInformation.ExportMade = true;
} else {
if (!manuallyInitiated) {
Dictionary<string, OlObjectClass> inspectorCaptions = OutlookEmailExporter.RetrievePossibleTargets(conf.OutlookAllowExportInMeetings);
if (inspectorCaptions != null && inspectorCaptions.Count > 0) {
List<IDestination> destinations = new List<IDestination>();
destinations.Add(new OutlookDestination());
foreach (string inspectorCaption in inspectorCaptions.Keys) {
destinations.Add(new OutlookDestination(inspectorCaption, inspectorCaptions[inspectorCaption]));
}
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
return ShowPickerMenu(false, surface, captureDetails, destinations);
}
} else {
OutlookEmailExporter.ExportToOutlook(conf.OutlookEmailFormat, tmpFile, FilenameHelper.FillPattern(conf.EmailSubjectPattern, captureDetails, false), attachmentName, conf.EmailTo, conf.EmailCC, conf.EmailBCC);
exportInformation.ExportMade = true;
}
}
ProcessExport(exportInformation, surface);
return exportInformation;
}
}
}

View file

@ -24,20 +24,17 @@ using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Interop.Office;
using Greenshot.IniFile;
namespace Greenshot.Destinations {
namespace GreenshotOfficePlugin {
/// <summary>
/// Description of PowerpointDestination.
/// </summary>
public class PowerpointDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PowerpointDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image applicationIcon = null;
private static Image presentationIcon = null;
@ -134,7 +131,7 @@ namespace Greenshot.Destinations {
destinations.Add(new PowerpointDestination(presentation));
}
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
return PickerDestination.ShowPickerMenu(false, surface, captureDetails, destinations);
return ShowPickerMenu(false, surface, captureDetails, destinations);
}
} else if (!exportInformation.ExportMade) {
PowerpointExporter.InsertIntoNewPresentation(tmpFile, imageSize, captureDetails.Title);

View file

@ -25,20 +25,17 @@ using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Interop.Office;
using Greenshot.IniFile;
namespace Greenshot.Destinations {
namespace GreenshotOfficePlugin {
/// <summary>
/// Description of EmailDestination.
/// </summary>
public class WordDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WordDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image applicationIcon = null;
private static Image documentIcon = null;
@ -143,7 +140,7 @@ namespace Greenshot.Destinations {
destinations.Add(new WordDestination(document));
}
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
return PickerDestination.ShowPickerMenu(false, surface, captureDetails, destinations);
return ShowPickerMenu(false, surface, captureDetails, destinations);
}
}
try {

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{D14382D5-D870-4B55-AC21-6E64A8A68420}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<RootNamespace>GreenshotOfficePlugin</RootNamespace>
<AssemblyName>GreenshotOfficePlugin</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Destinations\OutlookDestination.cs" />
<Compile Include="Destinations\ExcelDestination.cs" />
<Compile Include="Destinations\OneNoteDestination.cs" />
<Compile Include="Destinations\PowerpointDestination.cs" />
<Compile Include="Destinations\WordDestination.cs" />
<Compile Include="OfficeConfiguration.cs" />
<Compile Include="OfficePlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\GreenshotInterop\OfficeExport\ExcelExporter.cs">
<Link>Interop\ExcelExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\OneNoteExporter.cs">
<Link>Interop\OneNoteExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\OutlookEmailExporter.cs">
<Link>Interop\OutlookEmailExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\PowerpointExporter.cs">
<Link>Interop\PowerpointExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\WordExporter.cs">
<Link>Interop\WordExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\ExcelInterop.cs">
<Link>Interop\ExcelInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OfficeInterop.cs">
<Link>Interop\OfficeInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OneNoteInterop.cs">
<Link>Interop\OneNoteInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OutlookInterop.cs">
<Link>Interop\OutlookInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OutlookUtils.cs">
<Link>Interop\OutlookUtils.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\PowerpointInterop.cs">
<Link>Interop\PowerpointInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\WordInterop.cs">
<Link>Interop\WordInterop.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="Properties\AssemblyInfo.cs.template" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
<Name>GreenshotPlugin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Destinations" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<PropertyGroup>
<PreBuildEvent>"$(SolutionDir)\tools\TortoiseSVN\SubWCRev.exe" "$(ProjectDir)\" "$(ProjectDir)\Properties\AssemblyInfo.cs.template" "$(ProjectDir)\Properties\AssemblyInfo.cs"
</PreBuildEvent>
<PostBuildEvent>mkdir "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)"
copy "$(ProjectDir)bin\$(Configuration)\$(ProjectName).pdb" "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\"
copy "$(ProjectDir)bin\$(Configuration)\$(TargetFileName)" "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp"
</PostBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,45 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Greenshot.IniFile;
using Greenshot.Interop.Office;
namespace GreenshotOfficePlugin {
/// <summary>
/// Description of CoreConfiguration.
/// </summary>
[IniSection("Office", Description="Greenshot Office configuration")]
public class OfficeConfiguration : IniSection {
[IniProperty("OutlookEmailFormat", Description = "Default type for emails. (Text, HTML)", DefaultValue="HTML")]
public EmailFormat OutlookEmailFormat;
[IniProperty("EmailSubjectPattern", Description = "Email subject pattern, works like the OutputFileFilenamePattern", DefaultValue = "${title}")]
public string EmailSubjectPattern;
[IniProperty("EmailTo", Description = "Default value for the to in emails that are created", DefaultValue = "")]
public string EmailTo;
[IniProperty("EmailCC", Description = "Default value for the CC in emails that are created", DefaultValue = "")]
public string EmailCC;
[IniProperty("EmailBCC", Description = "Default value for the BCC in emails that are created", DefaultValue = "")]
public string EmailBCC;
[IniProperty("OutlookAllowExportInMeetings", Description = "Allow export in meeting items", DefaultValue = "False")]
public bool OutlookAllowExportInMeetings;
}
}

View file

@ -0,0 +1,90 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Threading;
using Greenshot.Plugin;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using Greenshot.IniFile;
namespace GreenshotOfficePlugin {
/// <summary>
/// This is the OfficePlugin base code
/// </summary>
public class OfficePlugin : IGreenshotPlugin {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OfficePlugin));
public static PluginAttribute Attributes;
private IGreenshotHost host;
public OfficePlugin() {
}
public IEnumerable<IDestination> Destinations() {
yield return new ExcelDestination();
yield return new PowerpointDestination();
yield return new WordDestination();
yield return new OutlookDestination();
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="host">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="captureHost">Use the ICaptureHost interface to register in the MainContextMenu</param>
/// <param name="pluginAttribute">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
this.host = (IGreenshotHost)pluginHost;
Attributes = myAttributes;
return true;
}
public virtual void Shutdown() {
LOG.Debug("Office Plugin shutdown.");
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
}
/// <summary>
/// This will be called when Greenshot is shutting down
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void Closing(object sender, FormClosingEventArgs e) {
LOG.Debug("Application closing, de-registering Office Plugin!");
Shutdown();
}
}
}

View file

@ -0,0 +1,54 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Greenshot.Plugin;
#endregion
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GreenshotOfficePlugin")]
[assembly: AssemblyDescription("A plugin to export images to Office applications")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Greenshot")]
[assembly: AssemblyProduct("Office Plugin")]
[assembly: AssemblyCopyright("Copyright (C) 2007-2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: PluginAttribute("GreenshotOfficePlugin.OfficePlugin", false)]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.3.$WCREV$")]

View file

@ -30,6 +30,7 @@ using Microsoft.Win32;
using Greenshot.Plugin;
using Greenshot.IniFile;
using GreenshotPlugin.UnmanagedHelpers;
namespace GreenshotPlugin.Core {
/// <summary>
@ -200,5 +201,120 @@ namespace GreenshotPlugin.Core {
return Description;
}
/// <summary>
/// This method will create and show the destination picker menu
/// </summary>
/// <param name="addDynamics">Boolean if the dynamic values also need to be added</param>
/// <param name="surface">The surface which can be exported</param>
/// <param name="captureDetails">Details for the surface</param>
/// <param name="destinations">The list of destinations to show</param>
/// <returns></returns>
public ExportInformation ShowPickerMenu(bool addDynamics, ISurface surface, ICaptureDetails captureDetails, IEnumerable<IDestination> destinations) {
// Generate an empty ExportInformation object, for when nothing was selected.
ExportInformation exportInformation = new ExportInformation(Designation, Language.GetString("settings_destination_picker"));
ContextMenuStrip menu = new ContextMenuStrip();
menu.Closing += delegate(object source, ToolStripDropDownClosingEventArgs eventArgs) {
LOG.DebugFormat("Close reason: {0}", eventArgs.CloseReason);
switch (eventArgs.CloseReason) {
case ToolStripDropDownCloseReason.ItemClicked:
case ToolStripDropDownCloseReason.CloseCalled:
break;
case ToolStripDropDownCloseReason.Keyboard:
// Dispose as the close is clicked
surface.Dispose();
surface = null;
break;
default:
eventArgs.Cancel = true;
break;
}
};
foreach (IDestination destination in destinations) {
// Fix foreach loop variable for the delegate
ToolStripMenuItem item = destination.GetMenuItem(addDynamics,
delegate(object sender, EventArgs e) {
ToolStripMenuItem toolStripMenuItem = sender as ToolStripMenuItem;
if (toolStripMenuItem == null) {
return;
}
IDestination clickedDestination = (IDestination)toolStripMenuItem.Tag;
if (clickedDestination == null) {
return;
}
bool isEditor = "Editor".Equals(clickedDestination.Designation);
// Make sure the menu is invisible, don't close it
menu.Hide();
// Export
exportInformation = clickedDestination.ExportCapture(true, surface, captureDetails);
if (exportInformation != null && exportInformation.ExportMade) {
LOG.InfoFormat("Export to {0} success, closing menu", exportInformation.DestinationDescription);
// close menu if the destination wasn't the editor
menu.Close();
// Cleanup surface, only if the destination wasn't the editor
if (!isEditor) {
surface.Dispose();
surface = null;
}
} else {
LOG.Info("Export cancelled or failed, showing menu again");
// This prevents the problem that the context menu shows in the task-bar
ShowMenuAtCursor(menu);
}
}
);
if (item != null) {
menu.Items.Add(item);
}
}
// Close
menu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem closeItem = new ToolStripMenuItem(Language.GetString("editor_close"));
closeItem.Image = GreenshotPlugin.Core.GreenshotResources.getImage("Close.Image");
closeItem.Click += delegate {
// This menu entry is the close itself, we can dispose the surface
menu.Close();
// Dispose as the close is clicked
surface.Dispose();
surface = null;
};
menu.Items.Add(closeItem);
ShowMenuAtCursor(menu);
return exportInformation;
}
/// <summary>
/// This method will show the supplied context menu at the mouse cursor, also makes sure it has focus and it's not visible in the taskbar.
/// </summary>
/// <param name="menu"></param>
private 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));
} else {
location.Offset(-40, -10);
}
// This prevents the problem that the context menu shows in the task-bar
User32.SetForegroundWindow(PluginUtils.Host.NotifyIcon.ContextMenuStrip.Handle);
menu.Show(location);
menu.Focus();
// Wait for the menu to close, so we can dispose it.
while (true) {
if (menu.Visible) {
Application.DoEvents();
System.Threading.Thread.Sleep(100);
} else {
menu.Dispose();
break;
}
}
}
}
}

View file

@ -25,7 +25,6 @@ using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Plugin;
using Greenshot.Interop.Office;
using Greenshot.IniFile;
namespace GreenshotPlugin.Core {
@ -101,19 +100,6 @@ namespace GreenshotPlugin.Core {
[IniProperty("OutputFileAutoReduceColors", Description = "If set to true the amount of colors is counted and if smaller than 256 the color reduction is automatically used.", DefaultValue = "true")]
public bool OutputFileAutoReduceColors;
[IniProperty("OutlookEmailFormat", Description = "Default type for emails. (Text, HTML)", DefaultValue="HTML")]
public EmailFormat OutlookEmailFormat;
[IniProperty("EmailSubjectPattern", Description = "Email subject pattern, works like the OutputFileFilenamePattern", DefaultValue = "${title}")]
public string EmailSubjectPattern;
[IniProperty("EmailTo", Description = "Default value for the to in emails that are created", DefaultValue = "")]
public string EmailTo;
[IniProperty("EmailCC", Description = "Default value for the CC in emails that are created", DefaultValue = "")]
public string EmailCC;
[IniProperty("EmailBCC", Description = "Default value for the BCC in emails that are created", DefaultValue = "")]
public string EmailBCC;
[IniProperty("OutlookAllowExportInMeetings", Description = "Allow export in meeting items", DefaultValue = "False")]
public bool OutlookAllowExportInMeetings;
[IniProperty("OutputFileCopyPathToClipboard", Description="When saving a screenshot, copy the path to the clipboard?", DefaultValue="true")]
public bool OutputFileCopyPathToClipboard;
[IniProperty("OutputFileAsFullpath", Description="SaveAs Full path?")]

View file

@ -379,8 +379,8 @@
<data name="Greenshot.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAIAAAC3ytZVAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALDQAA
Cw0B7QfALAAAETdJREFUeF7tnAl0VNUZx8OeyA4KQfY97JB9JrNkkpCVQABDAiTsmxCCgBgISEgIhAAi
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALDAAA
CwwBP0AiyAAAETdJREFUeF7tnAl0VNUZx8OeyA4KQfY97JB9JrNkkpCVQABDAiTsmxCCgBgISEgIhAAi
4t7WY7Faly5Wq1VOl6P1VOvS6ilWq6dqXXHf9wX6+96dTCYz743zJgwkmjnvcCaPN+/d+7/f/X/L/d/X
bt68eZ9++mlE2yciolu3bhFZWVn2to+GAFBE5ObmtqGhEACKNjgajaENjiYTow2ONjiMmbLNOtqso806
gowk2iZL22RpmyxnarLYgnxQ67gsdO5ISXYmx7qsCamW+FRLbGpKsqN19DhgK0OCw2a3xKVmzUtYevXw
@ -472,8 +472,8 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODgHVgAAAAlwSFlzAAAOvwAA
Dr8BOAVTJAAAABZJREFUGFdjYAABRhAAs4hlkq4DZDgACywAM12jTsYAAAAASUVORK5CYII=
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODgHVgAAAAlwSFlzAAAOvgAA
Dr4B6kKxwAAAABZJREFUGFdjYAABRhAAs4hlkq4DZDgACywAM12jTsYAAAAASUVORK5CYII=
</value>
</data>
<data name="Email.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@ -534,6 +534,18 @@
ug6fz4dsNsvAUA2Mo9Eo/H4/LOsOTqdTYprXEs64x0AwGEQ6nWZgrAYeDcNAIBBAu30r/6Reb0t2MwbC
4TCSySQDj/uAeEyngqnL5fpoNG4QCoUktVpHspsxEIlEkEgk+AKnaoAP8kwwczgcF4fg3g+u9gEu/son
bfJW/NwRDyIAAAAASUVORK5CYII=
</value>
</data>
<data name="Close.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUNJREFUOE+lk79L
QlEcxW9/gqCrm6vg4uYoOAgOrqLk4ioP0r2Glhp0SSjoF1FE0BIUDU3RdIOGoKBVGlpapaHTObeuCPe6
9ITD5fs9n3Pue8JbAWBS/VSQRvPwKR/j3JgaZXVqPv5TzPOXLhYoZDEcQidVWyhw3qzfn3tBAWH7PRjg
uV7HV5JAM6USyX50u86btlrOCwoOCR7Q+Oz1cFcu473dhmbppdFwu8dq1e3EBgU0zB6NXQJvzSaui0U8
VCq4LZWwn8vhLJ+HPDFiowUEzITADsGrQgFHmYzTSTYL7eSJiRZs0timRoTGhC956wXDXtrJEyM2eAIt
t34Be8NgTPLELCuQYe8Z9tK8ZBf+ieuEnxj20rzB26SYF7zCGsGEoVeW6NTMoJFiXlDAkFllqMOwTs2+
IOYFBf/9oFJ9ibr0B4f94vVG3bWDAAAAAElFTkSuQmCC
</value>
</data>
</root>

View file

@ -34,6 +34,14 @@ namespace GreenshotPlugin.Core {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PluginUtils));
private const string PATH_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
/// <summary>
/// Simple global property to get the Greenshot host
/// </summary>
public static IGreenshotHost Host {
get;
set;
}
/// <summary>
/// Get the path of an executable
/// </summary>

View file

@ -116,42 +116,6 @@
<Compile Include="..\GreenshotInterop\Interop\IServiceProvider.cs">
<Link>Interop\IServiceProvider.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\ExcelExporter.cs">
<Link>Interop\ExcelExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\OneNoteExporter.cs">
<Link>Interop\OneNoteExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\OutlookEmailExporter.cs">
<Link>Interop\OutlookEmailExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\PowerpointExporter.cs">
<Link>Interop\PowerpointExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeExport\WordExporter.cs">
<Link>Interop\WordExporter.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\ExcelInterop.cs">
<Link>Interop\ExcelInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OfficeInterop.cs">
<Link>Interop\OfficeInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OneNoteInterop.cs">
<Link>Interop\OneNoteInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OutlookInterop.cs">
<Link>Interop\OutlookInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\OutlookUtils.cs">
<Link>Interop\OutlookUtils.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\PowerpointInterop.cs">
<Link>Interop\PowerpointInterop.cs</Link>
</Compile>
<Compile Include="..\GreenshotInterop\OfficeInterop\WordInterop.cs">
<Link>Interop\WordInterop.cs</Link>
</Compile>
<Compile Include="Controls\FormWithoutActivation.cs">
<SubType>Form</SubType>
</Compile>

View file

@ -129,6 +129,9 @@ namespace Greenshot.Plugin {
get;
}
NotifyIcon NotifyIcon {
get;
}
/// <summary>
/// Create a Thumbnail
/// </summary>