Introduced a very simple "singleton" service-locator, which allowed for a removal of specific implementations which were very limited. With this it's easier to access dependencies.

This commit is contained in:
Krom, Robertus 2020-02-18 13:48:40 +01:00
parent 3ebdf3d2fe
commit 80d8f51fc5
53 changed files with 744 additions and 1230 deletions

View file

@ -48,7 +48,8 @@ namespace Greenshot.Destinations {
/// <returns>true if export was made</returns> /// <returns>true if export was made</returns>
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
List<IDestination> destinations = new List<IDestination>(); List<IDestination> destinations = new List<IDestination>();
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
foreach(var destination in SimpleServiceProvider.Current.GetAllInstances<IDestination>()) {
if ("Picker".Equals(destination.Designation)) { if ("Picker".Equals(destination.Designation)) {
continue; continue;
} }

View file

@ -223,19 +223,18 @@ namespace Greenshot {
using Pen cbBorderPen = new Pen(SystemColors.ActiveBorder); using Pen cbBorderPen = new Pen(SystemColors.ActiveBorder);
// Loop over all items in the propertiesToolStrip // Loop over all items in the propertiesToolStrip
foreach (ToolStripItem item in propertiesToolStrip.Items) { foreach (ToolStripItem item in propertiesToolStrip.Items) {
ToolStripComboBox cb = item as ToolStripComboBox; var cb = item as ToolStripComboBox;
// Only ToolStripComboBox that are visible // Only ToolStripComboBox that are visible
if (cb == null || !cb.Visible) { if (cb == null || !cb.Visible) {
continue; continue;
} }
// Calculate the rectangle if (cb.ComboBox == null) continue;
if (cb.ComboBox != null)
{
Rectangle r = new Rectangle(cb.ComboBox.Location.X - 1, cb.ComboBox.Location.Y - 1, cb.ComboBox.Size.Width + 1, cb.ComboBox.Size.Height + 1);
// Draw the rectangle // Calculate the rectangle
e.Graphics.DrawRectangle(cbBorderPen, r); Rectangle r = new Rectangle(cb.ComboBox.Location.X - 1, cb.ComboBox.Location.Y - 1, cb.ComboBox.Size.Width + 1, cb.ComboBox.Size.Height + 1);
}
// Draw the rectangle
e.Graphics.DrawRectangle(cbBorderPen, r);
} }
} }
@ -705,12 +704,15 @@ namespace Greenshot {
HelpFileLoader.LoadHelp(); HelpFileLoader.LoadHelp();
} }
private void AboutToolStripMenuItemClick(object sender, EventArgs e) { private void AboutToolStripMenuItemClick(object sender, EventArgs e)
MainForm.Instance.ShowAbout(); {
var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
mainForm.ShowAbout();
} }
private void PreferencesToolStripMenuItemClick(object sender, EventArgs e) { private void PreferencesToolStripMenuItemClick(object sender, EventArgs e) {
MainForm.Instance.ShowSetting(); var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
mainForm.ShowSetting();
} }
private void BtnSettingsClick(object sender, EventArgs e) { private void BtnSettingsClick(object sender, EventArgs e) {
@ -1251,7 +1253,8 @@ namespace Greenshot {
private void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e) { private void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e) {
ToolStripMenuItem captureWindowMenuItem = (ToolStripMenuItem)sender; ToolStripMenuItem captureWindowMenuItem = (ToolStripMenuItem)sender;
MainForm.Instance.AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click); var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
mainForm.AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click);
} }
private void Contextmenu_window_Click(object sender, EventArgs e) { private void Contextmenu_window_Click(object sender, EventArgs e) {

View file

@ -302,7 +302,6 @@ namespace Greenshot {
} }
private static MainForm _instance; private static MainForm _instance;
public static MainForm Instance => _instance;
private readonly CopyData _copyData; private readonly CopyData _copyData;
@ -315,13 +314,18 @@ namespace Greenshot {
// Timer for the double click test // Timer for the double click test
private readonly Timer _doubleClickTimer = new Timer(); private readonly Timer _doubleClickTimer = new Timer();
public NotifyIcon NotifyIcon => notifyIcon; public MainForm(CopyDataTransport dataTransport) {
// The most important form is this
SimpleServiceProvider.Current.AddService<Form>(this);
// Also as itself
SimpleServiceProvider.Current.AddService(this);
public MainForm(CopyDataTransport dataTransport) {
_instance = this; _instance = this;
// Factory for surface objects // Factory for surface objects
ImageHelper.SurfaceFactory = () => new Surface(); ISurface SurfaceFactory() => new Surface();
SimpleServiceProvider.Current.AddService((Func<ISurface>) SurfaceFactory);
// //
// The InitializeComponent() call is required for Windows Forms designer support. // The InitializeComponent() call is required for Windows Forms designer support.
@ -333,7 +337,12 @@ namespace Greenshot {
ex.Data.Add("more information here", "http://support.microsoft.com/kb/943140"); ex.Data.Add("more information here", "http://support.microsoft.com/kb/943140");
throw; throw;
} }
// Make the main menu available
SimpleServiceProvider.Current.AddService(contextMenu);
notifyIcon.Icon = GreenshotResources.getGreenshotIcon(); notifyIcon.Icon = GreenshotResources.getGreenshotIcon();
// Make the notify icon available
SimpleServiceProvider.Current.AddService(notifyIcon);
// Disable access to the settings, for feature #3521446 // Disable access to the settings, for feature #3521446
contextmenu_settings.Visible = !_conf.DisableSettings; contextmenu_settings.Visible = !_conf.DisableSettings;
@ -347,9 +356,9 @@ namespace Greenshot {
UpdateUi(); UpdateUi();
// This forces the registration of all destinations inside Greenshot itself. // This forces the registration of all destinations inside Greenshot itself.
DestinationHelper.GetAllDestinations(); DestinationHelper.RegisterInternalDestinations();
// This forces the registration of all processors inside Greenshot itself. // This forces the registration of all processors inside Greenshot itself.
ProcessorHelper.GetAllProcessors(); ProcessorHelper.RegisterInternalProcessors();
// Load all the plugins // Load all the plugins
PluginHelper.Instance.LoadPlugins(); PluginHelper.Instance.LoadPlugins();
@ -645,7 +654,8 @@ namespace Greenshot {
bool success = false; bool success = false;
var warningTitle = Language.GetString(LangKey.warning); var warningTitle = Language.GetString(LangKey.warning);
var message = string.Format(Language.GetString(LangKey.warning_hotkeys), failedKeys, IsOneDriveBlockingHotkey() ? " (OneDrive)": ""); var message = string.Format(Language.GetString(LangKey.warning_hotkeys), failedKeys, IsOneDriveBlockingHotkey() ? " (OneDrive)": "");
DialogResult dr = MessageBox.Show(Instance, message, warningTitle, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
DialogResult dr = MessageBox.Show(mainForm, message, warningTitle, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation);
if (dr == DialogResult.Retry) { if (dr == DialogResult.Retry) {
LOG.DebugFormat("Re-trying to register hotkeys"); LOG.DebugFormat("Re-trying to register hotkeys");
HotkeyControl.UnregisterHotkeys(); HotkeyControl.UnregisterHotkeys();

View file

@ -25,6 +25,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Configuration; using Greenshot.Configuration;
@ -191,37 +192,38 @@ namespace Greenshot {
} }
private void DisplayPluginTab() { private void DisplayPluginTab() {
if (!PluginHelper.Instance.HasPlugins()) { if (!SimpleServiceProvider.Current.GetAllInstances<IGreenshotPlugin>().Any())
tabcontrol.TabPages.Remove(tab_plugins); {
} else { tabcontrol.TabPages.Remove(tab_plugins);
// Draw the Plugin listview return;
listview_plugins.BeginUpdate(); }
listview_plugins.Items.Clear(); // Draw the Plugin listview
listview_plugins.Columns.Clear(); listview_plugins.BeginUpdate();
string[] columns = { listview_plugins.Items.Clear();
Language.GetString("settings_plugins_name"), listview_plugins.Columns.Clear();
Language.GetString("settings_plugins_version"), string[] columns = {
Language.GetString("settings_plugins_createdby"), Language.GetString("settings_plugins_name"),
Language.GetString("settings_plugins_dllpath")}; Language.GetString("settings_plugins_version"),
foreach (string column in columns) { Language.GetString("settings_plugins_createdby"),
listview_plugins.Columns.Add(column); Language.GetString("settings_plugins_dllpath")};
} foreach (string column in columns) {
PluginHelper.Instance.FillListview(listview_plugins); listview_plugins.Columns.Add(column);
// Maximize Column size!
for (int i = 0; i < listview_plugins.Columns.Count; i++) {
listview_plugins.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
int width = listview_plugins.Columns[i].Width;
listview_plugins.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.HeaderSize);
if (width > listview_plugins.Columns[i].Width) {
listview_plugins.Columns[i].Width = width;
}
}
listview_plugins.EndUpdate();
listview_plugins.Refresh();
// Disable the configure button, it will be enabled when a plugin is selected AND isConfigurable
button_pluginconfigure.Enabled = false;
} }
PluginHelper.Instance.FillListView(listview_plugins);
// Maximize Column size!
for (int i = 0; i < listview_plugins.Columns.Count; i++) {
listview_plugins.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
int width = listview_plugins.Columns[i].Width;
listview_plugins.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.HeaderSize);
if (width > listview_plugins.Columns[i].Width) {
listview_plugins.Columns[i].Width = width;
}
}
listview_plugins.EndUpdate();
listview_plugins.Refresh();
// Disable the configure button, it will be enabled when a plugin is selected AND isConfigurable
button_pluginconfigure.Enabled = false;
} }
/// <summary> /// <summary>
@ -333,9 +335,8 @@ namespace Greenshot {
listview_destinations.Items.Clear(); listview_destinations.Items.Clear();
listview_destinations.ListViewItemSorter = new ListviewWithDestinationComparer(); listview_destinations.ListViewItemSorter = new ListviewWithDestinationComparer();
ImageList imageList = new ImageList(); ImageList imageList = new ImageList {ImageSize = coreConfiguration.ScaledIconSize};
imageList.ImageSize = coreConfiguration.ScaledIconSize; listview_destinations.SmallImageList = imageList;
listview_destinations.SmallImageList = imageList;
int imageNr = -1; int imageNr = -1;
foreach (IDestination currentDestination in DestinationHelper.GetAllDestinations()) { foreach (IDestination currentDestination in DestinationHelper.GetAllDestinations()) {
Image destinationImage = currentDestination.DisplayIcon; Image destinationImage = currentDestination.DisplayIcon;
@ -502,7 +503,8 @@ namespace Greenshot {
MainForm.RegisterHotkeys(); MainForm.RegisterHotkeys();
// Make sure the current language & settings are reflected in the Main-context menu // Make sure the current language & settings are reflected in the Main-context menu
MainForm.Instance.UpdateUi(); var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
mainForm?.UpdateUi();
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} else { } else {
tabcontrol.SelectTab(tab_output); tabcontrol.SelectTab(tab_output);

View file

@ -232,9 +232,11 @@ namespace Greenshot.Helpers {
// This fixes a problem when a balloon is still visible and a capture needs to be taken // This fixes a problem when a balloon is still visible and a capture needs to be taken
// forcefully removes the balloon! // forcefully removes the balloon!
if (!CoreConfig.HideTrayicon) { if (!CoreConfig.HideTrayicon)
MainForm.Instance.NotifyIcon.Visible = false; {
MainForm.Instance.NotifyIcon.Visible = true; var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
notifyIcon.Visible = false;
notifyIcon.Visible = true;
} }
Log.Debug($"Capturing with mode {_captureMode} and using Cursor {_captureMouseCursor}"); Log.Debug($"Capturing with mode {_captureMode} and using Cursor {_captureMouseCursor}");
_capture.CaptureDetails.CaptureMode = _captureMode; _capture.CaptureDetails.CaptureMode = _captureMode;
@ -512,7 +514,8 @@ namespace Greenshot.Helpers {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void OpenCaptureOnClick(object sender, EventArgs e) { private void OpenCaptureOnClick(object sender, EventArgs e) {
if (!(MainForm.Instance.NotifyIcon.Tag is SurfaceMessageEventArgs eventArgs)) { var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
if (!(notifyIcon.Tag is SurfaceMessageEventArgs eventArgs)) {
Log.Warn("OpenCaptureOnClick called without SurfaceMessageEventArgs"); Log.Warn("OpenCaptureOnClick called without SurfaceMessageEventArgs");
RemoveEventHandler(sender, e); RemoveEventHandler(sender, e);
return; return;
@ -535,9 +538,10 @@ namespace Greenshot.Helpers {
} }
private void RemoveEventHandler(object sender, EventArgs e) { private void RemoveEventHandler(object sender, EventArgs e) {
MainForm.Instance.NotifyIcon.BalloonTipClicked -= OpenCaptureOnClick; var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
MainForm.Instance.NotifyIcon.BalloonTipClosed -= RemoveEventHandler; notifyIcon.BalloonTipClicked -= OpenCaptureOnClick;
MainForm.Instance.NotifyIcon.Tag = null; notifyIcon.BalloonTipClosed -= RemoveEventHandler;
notifyIcon.Tag = null;
} }
/// <summary> /// <summary>
@ -549,25 +553,22 @@ namespace Greenshot.Helpers {
if (string.IsNullOrEmpty(eventArgs?.Message)) { if (string.IsNullOrEmpty(eventArgs?.Message)) {
return; return;
} }
if (MainForm.Instance == null) var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
{
return;
}
switch (eventArgs.MessageType) { switch (eventArgs.MessageType) {
case SurfaceMessageTyp.Error: case SurfaceMessageTyp.Error:
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Error); notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Error);
break; break;
case SurfaceMessageTyp.Info: case SurfaceMessageTyp.Info:
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info); notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
break; break;
case SurfaceMessageTyp.FileSaved: case SurfaceMessageTyp.FileSaved:
case SurfaceMessageTyp.UploadedUri: case SurfaceMessageTyp.UploadedUri:
// Show a balloon and register an event handler to open the "capture" for if someone clicks the balloon. // Show a balloon and register an event handler to open the "capture" for if someone clicks the balloon.
MainForm.Instance.NotifyIcon.BalloonTipClicked += OpenCaptureOnClick; notifyIcon.BalloonTipClicked += OpenCaptureOnClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += RemoveEventHandler; notifyIcon.BalloonTipClosed += RemoveEventHandler;
// Store for later usage // Store for later usage
MainForm.Instance.NotifyIcon.Tag = eventArgs; notifyIcon.Tag = eventArgs;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info); notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
break; break;
} }
} }
@ -609,12 +610,11 @@ namespace Greenshot.Helpers {
} }
// Let the processors do their job // Let the processors do their job
foreach(IProcessor processor in ProcessorHelper.GetAllProcessors()) { foreach(var processor in SimpleServiceProvider.Current.GetAllInstances<IProcessor>()) {
if (processor.isActive) { if (!processor.isActive) continue;
Log.InfoFormat("Calling processor {0}", processor.Description); Log.InfoFormat("Calling processor {0}", processor.Description);
processor.ProcessCapture(surface, _capture.CaptureDetails); 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) // 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; _capture.Image = null;
@ -915,7 +915,8 @@ namespace Greenshot.Helpers {
// Workaround for proble with DPI retrieval, the FromHwnd activates the window... // Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow(); WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
// Workaround for changed DPI settings in Windows 7 // Workaround for changed DPI settings in Windows 7
using (Graphics graphics = Graphics.FromHwnd(MainForm.Instance.Handle)) { var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
using (Graphics graphics = Graphics.FromHwnd(mainForm.Handle)) {
_capture.CaptureDetails.DpiX = graphics.DpiX; _capture.CaptureDetails.DpiX = graphics.DpiX;
_capture.CaptureDetails.DpiY = graphics.DpiY; _capture.CaptureDetails.DpiY = graphics.DpiY;
} }
@ -942,7 +943,8 @@ namespace Greenshot.Helpers {
// Make sure the form is hidden after showing, even if an exception occurs, so all errors will be shown // Make sure the form is hidden after showing, even if an exception occurs, so all errors will be shown
DialogResult result; DialogResult result;
try { try {
result = captureForm.ShowDialog(MainForm.Instance); var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
result = captureForm.ShowDialog(mainForm);
} finally { } finally {
captureForm.Hide(); captureForm.Hide();
} }

View file

@ -18,9 +18,10 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using Greenshot.IniFile; using Greenshot.IniFile;
@ -32,79 +33,47 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
public static class DestinationHelper { public static class DestinationHelper {
private static readonly ILog Log = LogManager.GetLogger(typeof(DestinationHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(DestinationHelper));
private static readonly Dictionary<string, IDestination> RegisteredDestinations = new Dictionary<string, IDestination>();
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
/// Initialize the destinations /// <summary>
static DestinationHelper() { /// Initialize the internal destinations
/// </summary>
public static void RegisterInternalDestinations() {
foreach(Type destinationType in InterfaceUtils.GetSubclassesOf(typeof(IDestination),true)) { foreach(Type destinationType in InterfaceUtils.GetSubclassesOf(typeof(IDestination),true)) {
// Only take our own // Only take our own
if (!"Greenshot.Destinations".Equals(destinationType.Namespace)) { if (!"Greenshot.Destinations".Equals(destinationType.Namespace)) {
continue; continue;
} }
if (!destinationType.IsAbstract) {
IDestination destination;
try {
destination = (IDestination)Activator.CreateInstance(destinationType);
} catch (Exception e) {
Log.ErrorFormat("Can't create instance of {0}", destinationType);
Log.Error(e);
continue;
}
if (destination.IsActive) {
Log.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation);
RegisterDestination(destination);
} else {
Log.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation);
}
}
}
}
/// <summary> if (destinationType.IsAbstract) continue;
/// Register your destination here, if it doesn't come from a plugin and needs to be available
/// </summary> IDestination destination;
/// <param name="destination"></param> try {
public static void RegisterDestination(IDestination destination) { destination = (IDestination)Activator.CreateInstance(destinationType);
if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) { } catch (Exception e) {
// don't test the key, an exception should happen wenn it's not unique Log.ErrorFormat("Can't create instance of {0}", destinationType);
RegisteredDestinations.Add(destination.Designation, destination); Log.Error(e);
} continue;
}
if (destination.IsActive) {
Log.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation);
SimpleServiceProvider.Current.AddService(destination);
} else {
Log.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation);
}
}
} }
/// <summary> /// <summary>
/// Method to get all the destinations from the plugins /// Method to get all the destinations from the plugins
/// </summary> /// </summary>
/// <returns>List of IDestination</returns> /// <returns>List of IDestination</returns>
private static List<IDestination> GetPluginDestinations() { public static IEnumerable<IDestination> GetAllDestinations()
List<IDestination> destinations = new List<IDestination>(); {
foreach (PluginAttribute pluginAttribute in PluginHelper.Instance.Plugins.Keys) { return SimpleServiceProvider.Current.GetAllInstances<IDestination>()
IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute]; .Where(destination => destination.IsActive)
try { .Where(destination => CoreConfig.ExcludeDestinations == null ||
foreach (IDestination destination in plugin.Destinations()) { !CoreConfig.ExcludeDestinations.Contains(destination.Designation)).OrderBy(p => p.Priority).ThenBy(p => p.Description);
if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) {
destinations.Add(destination);
}
}
} catch (Exception ex) {
Log.ErrorFormat("Couldn't get destinations from the plugin {0}", pluginAttribute.Name);
Log.Error(ex);
}
}
destinations.Sort();
return destinations;
}
/// <summary>
/// Get a list of all destinations, registered or supplied by a plugin
/// </summary>
/// <returns></returns>
public static List<IDestination> GetAllDestinations() {
List<IDestination> destinations = new List<IDestination>();
destinations.AddRange(RegisteredDestinations.Values);
destinations.AddRange(GetPluginDestinations());
destinations.Sort();
return destinations;
} }
/// <summary> /// <summary>
@ -116,10 +85,7 @@ namespace Greenshot.Helpers {
if (designation == null) { if (designation == null) {
return null; return null;
} }
if (RegisteredDestinations.ContainsKey(designation)) { foreach (IDestination destination in GetAllDestinations()) {
return RegisteredDestinations[designation];
}
foreach (IDestination destination in GetPluginDestinations()) {
if (designation.Equals(destination.Designation)) { if (designation.Equals(destination.Designation)) {
return destination; return destination;
} }

View file

@ -22,6 +22,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Plugin; using Greenshot.Plugin;
@ -41,65 +42,61 @@ namespace Greenshot.Helpers {
private static readonly string PluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName); private static readonly string PluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);
private static readonly string ApplicationPath = Path.GetDirectoryName(Application.ExecutablePath); private static readonly string ApplicationPath = Path.GetDirectoryName(Application.ExecutablePath);
private static readonly string PafPath = Path.Combine(Application.StartupPath, @"App\Greenshot"); private static readonly string PafPath = Path.Combine(Application.StartupPath, @"App\Greenshot");
private static readonly IDictionary<PluginAttribute, IGreenshotPlugin> plugins = new SortedDictionary<PluginAttribute, IGreenshotPlugin>();
public static PluginHelper Instance { get; } = new PluginHelper(); public static PluginHelper Instance { get; } = new PluginHelper();
private PluginHelper() { public void Shutdown() {
PluginUtils.Host = this; foreach(var plugin in SimpleServiceProvider.Current.GetAllInstances<IGreenshotPlugin>()) {
}
public Form GreenshotForm => MainForm.Instance;
public NotifyIcon NotifyIcon => MainForm.Instance.NotifyIcon;
public bool HasPlugins() {
return plugins != null && plugins.Count > 0;
}
public void Shutdown() {
foreach(var plugin in plugins.Values) {
plugin.Shutdown(); plugin.Shutdown();
plugin.Dispose(); plugin.Dispose();
} }
plugins.Clear();
} }
// Add plugins to the Listview /// <summary>
public void FillListview(ListView listview) { /// Add plugins to the ListView
foreach(var pluginAttribute in plugins.Keys) { /// </summary>
/// <param name="listView"></param>
public void FillListView(ListView listView) {
foreach (var plugin in SimpleServiceProvider.Current.GetAllInstances<IGreenshotPlugin>())
{
var pluginAttribute = plugin.GetType().GetCustomAttribute<PluginAttribute>();
var item = new ListViewItem(pluginAttribute.Name) var item = new ListViewItem(pluginAttribute.Name)
{ {
Tag = pluginAttribute Tag = pluginAttribute
}; };
item.SubItems.Add(pluginAttribute.Version); var assembly = plugin.GetType().Assembly;
item.SubItems.Add(pluginAttribute.CreatedBy);
item.SubItems.Add(pluginAttribute.DllFile); var company = assembly.GetCustomAttribute<AssemblyCompanyAttribute>();
listview.Items.Add(item); item.SubItems.Add(assembly.GetName().Version.ToString());
item.SubItems.Add(company.Company);
item.SubItems.Add(assembly.Location);
listView.Items.Add(item);
} }
} }
public bool IsSelectedItemConfigurable(ListView listview) { public bool IsSelectedItemConfigurable(ListView listView) {
if (listview.SelectedItems.Count <= 0) if (listView.SelectedItems.Count <= 0)
{ {
return false; return false;
} }
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag; var pluginAttribute = (PluginAttribute)listView.SelectedItems[0].Tag;
return pluginAttribute != null && pluginAttribute.Configurable; return pluginAttribute != null && pluginAttribute.Configurable;
} }
public void ConfigureSelectedItem(ListView listview) { public void ConfigureSelectedItem(ListView listView) {
if (listview.SelectedItems.Count <= 0) if (listView.SelectedItems.Count <= 0)
{ {
return; return;
} }
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag; var pluginAttribute = (PluginAttribute)listView.SelectedItems[0].Tag;
if (pluginAttribute == null) if (pluginAttribute == null)
{ {
return; return;
} }
var plugin = plugins[pluginAttribute];
plugin.Configure(); var plugin = SimpleServiceProvider.Current.GetAllInstances<IGreenshotPlugin>().FirstOrDefault(p =>
p.GetType().GetCustomAttribute<PluginAttribute>().Name == pluginAttribute.Name);
plugin?.Configure();
} }
/// <summary> /// <summary>
@ -121,17 +118,6 @@ namespace Greenshot.Helpers {
return true; return true;
} }
public ContextMenuStrip MainMenu => MainForm.Instance.MainMenu;
public IDictionary<PluginAttribute, IGreenshotPlugin> Plugins => plugins;
public IDestination GetDestination(string designation) {
return DestinationHelper.GetDestination(designation);
}
public List<IDestination> GetAllDestinations() {
return DestinationHelper.GetAllDestinations();
}
public ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails) { public ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails) {
return DestinationHelper.ExportCapture(manuallyInitiated, designation, surface, captureDetails); return DestinationHelper.ExportCapture(manuallyInitiated, designation, surface, captureDetails);
} }
@ -149,8 +135,10 @@ namespace Greenshot.Helpers {
/// Use the supplied image, and handle it as if it's captured. /// Use the supplied image, and handle it as if it's captured.
/// </summary> /// </summary>
/// <param name="captureToImport">Image to handle</param> /// <param name="captureToImport">Image to handle</param>
public void ImportCapture(ICapture captureToImport) { public void ImportCapture(ICapture captureToImport)
MainForm.Instance.BeginInvoke((MethodInvoker)delegate { {
var mainForm = SimpleServiceProvider.Current.GetInstance<Form>();
mainForm.BeginInvoke((MethodInvoker)delegate {
CaptureHelper.ImportCapture(captureToImport); CaptureHelper.ImportCapture(captureToImport);
}); });
} }
@ -171,49 +159,27 @@ namespace Greenshot.Helpers {
return capture; return capture;
} }
public PluginAttribute FindPlugin(string name) {
foreach(PluginAttribute pluginAttribute in plugins.Keys) {
if (name.Equals(pluginAttribute.Name)) {
return pluginAttribute;
}
}
return null;
}
private bool IsNewer(string version1, string version2) { /// <summary>
string [] version1Parts = version1.Split('.');
string [] version2Parts = version2.Split('.');
int parts = Math.Min(version1Parts.Length, version2Parts.Length);
for(int i=0; i < parts; i++) {
int v1 = Convert.ToInt32(version1Parts[i]);
int v2 = Convert.ToInt32(version2Parts[i]);
if (v1 > v2) {
return true;
}
if (v1 < v2) {
return false;
}
}
return false;
}
/// <summary>
/// Private helper to find the plugins in the path /// Private helper to find the plugins in the path
/// </summary> /// </summary>
/// <param name="pluginFiles"></param> /// <param name="path">string</param>
/// <param name="path"></param> /// <returns>IEnumerable with plugin files</returns>
private void FindPluginsOnPath(List<string> pluginFiles, string path) { private IEnumerable<string> FindPluginsOnPath(string path)
if (Directory.Exists(path)) { {
try { var pluginFiles = Enumerable.Empty<string>();
foreach (string pluginFile in Directory.GetFiles(path, "*Plugin.dll", SearchOption.AllDirectories)) { if (!Directory.Exists(path)) return pluginFiles;
pluginFiles.Add(pluginFile); try
} {
} catch (UnauthorizedAccessException) { pluginFiles = Directory.GetFiles(path, "*Plugin.dll", SearchOption.AllDirectories);
} catch (Exception ex) {
Log.Error("Error loading plugin: ", ex); } catch (Exception ex) {
} Log.Error("Error loading plugin: ", ex);
} }
}
return pluginFiles;
}
/// <summary> /// <summary>
/// Load the plugins /// Load the plugins
@ -222,107 +188,54 @@ namespace Greenshot.Helpers {
List<string> pluginFiles = new List<string>(); List<string> pluginFiles = new List<string>();
if (IniConfig.IsPortable) { if (IniConfig.IsPortable) {
FindPluginsOnPath(pluginFiles, PafPath); pluginFiles.AddRange(FindPluginsOnPath(PafPath));
} else { } else {
FindPluginsOnPath(pluginFiles, PluginPath); pluginFiles.AddRange(FindPluginsOnPath(PluginPath));
FindPluginsOnPath(pluginFiles, ApplicationPath); pluginFiles.AddRange(FindPluginsOnPath(ApplicationPath));
} }
Dictionary<string, PluginAttribute> tmpAttributes = new Dictionary<string, PluginAttribute>();
Dictionary<string, Assembly> tmpAssemblies = new Dictionary<string, Assembly>();
// Loop over the list of available files and get the Plugin Attributes // Loop over the list of available files and get the Plugin Attributes
foreach (string pluginFile in pluginFiles) { foreach (string pluginFile in pluginFiles) {
//LOG.DebugFormat("Checking the following file for plugins: {0}", pluginFile);
try { try {
Assembly assembly = Assembly.LoadFrom(pluginFile); Assembly assembly = Assembly.LoadFrom(pluginFile);
PluginAttribute[] pluginAttributes = assembly.GetCustomAttributes(typeof(PluginAttribute), false) as PluginAttribute[];
if (pluginAttributes.Length > 0) {
PluginAttribute pluginAttribute = pluginAttributes[0];
if (string.IsNullOrEmpty(pluginAttribute.Name)) { var assemblyName = assembly.GetName().Name;
AssemblyProductAttribute[] assemblyProductAttributes = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false) as AssemblyProductAttribute[];
if (assemblyProductAttributes.Length > 0) {
pluginAttribute.Name = assemblyProductAttributes[0].Product;
} else {
continue;
}
}
if (string.IsNullOrEmpty(pluginAttribute.CreatedBy)) {
AssemblyCompanyAttribute[] assemblyCompanyAttributes = assembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false) as AssemblyCompanyAttribute[];
if (assemblyCompanyAttributes.Length > 0) {
pluginAttribute.CreatedBy = assemblyCompanyAttributes[0].Company;
} else {
continue;
}
}
pluginAttribute.Version = assembly.GetName().Version.ToString();
pluginAttribute.DllFile = pluginFile;
// check if this plugin is already available var pluginEntryName = $"{assemblyName}.{assemblyName.Replace("Greenshot", string.Empty)}";
PluginAttribute checkPluginAttribute = null; var pluginEntryType = assembly.GetType(pluginEntryName, false, true);
if (tmpAttributes.ContainsKey(pluginAttribute.Name)) { var pluginAttribute = pluginEntryType.GetCustomAttribute<PluginAttribute>();
checkPluginAttribute = tmpAttributes[pluginAttribute.Name];
}
if (checkPluginAttribute != null) { if (CoreConfig.ExcludePlugins != null && CoreConfig.ExcludePlugins.Contains(pluginAttribute.Name))
Log.WarnFormat("Duplicate plugin {0} found", pluginAttribute.Name); {
if (IsNewer(pluginAttribute.Version, checkPluginAttribute.Version)) { Log.WarnFormat("Exclude list: {0}", string.Join(",", CoreConfig.ExcludePlugins));
// Found is newer Log.WarnFormat("Skipping the excluded plugin {0} with version {1} from {2}", pluginAttribute.Name, assembly.GetName().Version, pluginFile);
tmpAttributes[pluginAttribute.Name] = pluginAttribute; continue;
tmpAssemblies[pluginAttribute.Name] = assembly; }
Log.InfoFormat("Loading the newer plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
} else { IGreenshotPlugin plugin = (IGreenshotPlugin)Activator.CreateInstance(pluginEntryType);
Log.InfoFormat("Skipping (as the duplicate is newer or same version) the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile); if (plugin != null)
} {
continue; if (plugin.Initialize())
} {
if (CoreConfig.ExcludePlugins != null && CoreConfig.ExcludePlugins.Contains(pluginAttribute.Name)) { SimpleServiceProvider.Current.AddService(plugin);
Log.WarnFormat("Exclude list: {0}", CoreConfig.ExcludePlugins.ToArray()); }
Log.WarnFormat("Skipping the excluded plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile); else
continue; {
}
if (CoreConfig.IncludePlugins != null && CoreConfig.IncludePlugins.Count > 0 && !CoreConfig.IncludePlugins.Contains(pluginAttribute.Name)) { Log.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name);
// Whitelist is set }
Log.WarnFormat("Include list: {0}", CoreConfig.IncludePlugins.ToArray()); }
Log.WarnFormat("Skipping the not included plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile); else
continue; {
} Log.ErrorFormat("Can't create an instance of {0} from \"{1}\"", assembly.GetName().Name + ".GreenshotPlugin", pluginFile);
Log.InfoFormat("Loading the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile); }
tmpAttributes[pluginAttribute.Name] = pluginAttribute; }
tmpAssemblies[pluginAttribute.Name] = assembly; catch (Exception e)
} else { {
Log.ErrorFormat("Can't find the needed Plugin Attribute ({0}) in the assembly of the file \"{1}\", skipping this file.", typeof(PluginAttribute), pluginFile); Log.ErrorFormat("Can't load Plugin: {0}", pluginFile);
} Log.Error(e);
} catch (Exception e) { }
Log.Warn("Can't load file: " + pluginFile, e);
}
}
foreach(string pluginName in tmpAttributes.Keys) {
try {
PluginAttribute pluginAttribute = tmpAttributes[pluginName];
Assembly assembly = tmpAssemblies[pluginName];
Type entryType = assembly.GetType(pluginAttribute.EntryType);
if (entryType == null) {
Log.ErrorFormat("Can't find the in the PluginAttribute referenced type {0} in \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
continue;
}
try {
IGreenshotPlugin plugin = (IGreenshotPlugin)Activator.CreateInstance(entryType);
if (plugin != null) {
if (plugin.Initialize(this, pluginAttribute)) {
plugins.Add(pluginAttribute, plugin);
} else {
Log.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name);
}
} else {
Log.ErrorFormat("Can't create an instance of the in the PluginAttribute referenced type {0} from \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
}
} catch(Exception e) {
Log.Error("Can't load Plugin: " + pluginAttribute.Name, e);
}
} catch(Exception e) {
Log.Error("Can't load Plugin: " + pluginName, e);
}
} }
} }
} }

View file

@ -31,108 +31,35 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
public static class ProcessorHelper { public static class ProcessorHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(ProcessorHelper)); private static readonly ILog LOG = LogManager.GetLogger(typeof(ProcessorHelper));
private static readonly Dictionary<string, IProcessor> RegisteredProcessors = new Dictionary<string, IProcessor>();
/// Initialize the Processors /// <summary>
static ProcessorHelper() { /// Register the internal processors
foreach(Type ProcessorType in InterfaceUtils.GetSubclassesOf(typeof(IProcessor),true)) { /// </summary>
public static void RegisterInternalProcessors() {
foreach(Type processorType in InterfaceUtils.GetSubclassesOf(typeof(IProcessor),true)) {
// Only take our own // Only take our own
if (!"Greenshot.Processors".Equals(ProcessorType.Namespace)) { if (!"Greenshot.Processors".Equals(processorType.Namespace)) {
continue; continue;
} }
try { try {
if (!ProcessorType.IsAbstract) { if (!processorType.IsAbstract) {
IProcessor Processor; IProcessor processor;
try { try {
Processor = (IProcessor)Activator.CreateInstance(ProcessorType); processor = (IProcessor)Activator.CreateInstance(processorType);
} catch (Exception e) { } catch (Exception e) {
LOG.ErrorFormat("Can't create instance of {0}", ProcessorType); LOG.ErrorFormat("Can't create instance of {0}", processorType);
LOG.Error(e); LOG.Error(e);
continue; continue;
} }
if (Processor.isActive) { if (processor.isActive) {
LOG.DebugFormat("Found Processor {0} with designation {1}", ProcessorType.Name, Processor.Designation); LOG.DebugFormat("Found Processor {0} with designation {1}", processorType.Name, processor.Designation);
RegisterProcessor(Processor); SimpleServiceProvider.Current.AddService(processor);
} else { } else {
LOG.DebugFormat("Ignoring Processor {0} with designation {1}", ProcessorType.Name, Processor.Designation); LOG.DebugFormat("Ignoring Processor {0} with designation {1}", processorType.Name, processor.Designation);
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.ErrorFormat("Error loading processor {0}, message: ", ProcessorType.FullName, ex.Message); LOG.ErrorFormat("Error loading processor {0}, message: ", processorType.FullName, ex.Message);
}
}
}
/// <summary>
/// Register your Processor here, if it doesn't come from a plugin and needs to be available
/// </summary>
/// <param name="Processor"></param>
public static void RegisterProcessor(IProcessor Processor) {
// don't test the key, an exception should happen wenn it's not unique
RegisteredProcessors.Add(Processor.Designation, Processor);
}
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];
try {
var procs = plugin.Processors();
if (procs != null) {
processors.AddRange(procs);
}
} catch (Exception ex) {
LOG.ErrorFormat("Couldn't get processors from the plugin {0}", pluginAttribute.Name);
LOG.Error(ex);
}
}
processors.Sort();
return processors;
}
/// <summary>
/// Get a list of all Processors, registered or supplied by a plugin
/// </summary>
/// <returns></returns>
public static List<IProcessor> GetAllProcessors() {
List<IProcessor> processors = new List<IProcessor>();
processors.AddRange(RegisteredProcessors.Values);
processors.AddRange(GetPluginsProcessors());
processors.Sort();
return processors;
}
/// <summary>
/// Get a Processor by a designation
/// </summary>
/// <param name="designation">Designation of the Processor</param>
/// <returns>IProcessor or null</returns>
public static IProcessor GetProcessor(string designation) {
if (designation == null) {
return null;
}
if (RegisteredProcessors.ContainsKey(designation)) {
return RegisteredProcessors[designation];
}
foreach (IProcessor processor in GetPluginsProcessors()) {
if (designation.Equals(processor.Designation)) {
return processor;
}
}
return null;
}
/// <summary>
/// A simple helper method which will call ProcessCapture for the Processor with the specified designation
/// </summary>
/// <param name="designation"></param>
/// <param name="surface"></param>
/// <param name="captureDetails"></param>
public static void ProcessCapture(string designation, ISurface surface, ICaptureDetails captureDetails) {
if (RegisteredProcessors.ContainsKey(designation)) {
IProcessor Processor = RegisteredProcessors[designation];
if (Processor.isActive) {
Processor.ProcessCapture(surface, captureDetails);
} }
} }
} }

View file

@ -34,7 +34,7 @@ namespace Greenshot.Helpers
/// </summary> /// </summary>
public class ResourceMutex : IDisposable public class ResourceMutex : IDisposable
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(DestinationHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(ResourceMutex));
private readonly string _mutexId; private readonly string _mutexId;
private readonly string _resourceName; private readonly string _resourceName;
private Mutex _applicationMutex; private Mutex _applicationMutex;
@ -82,13 +82,13 @@ namespace Greenshot.Helpers
{ {
// Added Mutex Security, hopefully this prevents the UnauthorizedAccessException more gracefully // Added Mutex Security, hopefully this prevents the UnauthorizedAccessException more gracefully
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var mutexsecurity = new MutexSecurity(); var mutexSecurity = new MutexSecurity();
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow)); mutexSecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow));
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny)); mutexSecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny));
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny)); mutexSecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny));
// 1) Create Mutex // 1) Create Mutex
_applicationMutex = new Mutex(true, _mutexId, out var createdNew, mutexsecurity); _applicationMutex = new Mutex(true, _mutexId, out var createdNew, mutexSecurity);
// 2) if the mutex wasn't created new get the right to it, this returns false if it's already locked // 2) if the mutex wasn't created new get the right to it, this returns false if it's already locked
if (!createdNew && !_applicationMutex.WaitOne(100, false)) if (!createdNew && !_applicationMutex.WaitOne(100, false))
{ {

View file

@ -88,9 +88,11 @@ namespace Greenshot.Experimental {
_latestGreenshot = null; _latestGreenshot = null;
ProcessRssInfo(currentVersion); ProcessRssInfo(currentVersion);
if (_latestGreenshot != null) { if (_latestGreenshot != null) {
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick; var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info); notifyIcon.BalloonTipClicked += HandleBalloonTipClick;
notifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
notifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info);
} }
} catch (Exception e) { } catch (Exception e) {
Log.Error("An error occured while checking for updates, the error will be ignored: ", e); Log.Error("An error occured while checking for updates, the error will be ignored: ", e);
@ -99,8 +101,9 @@ namespace Greenshot.Experimental {
} }
private static void CleanupBalloonTipClick(object sender, EventArgs e) { private static void CleanupBalloonTipClick(object sender, EventArgs e) {
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick; var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick; notifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
notifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
} }
private static void HandleBalloonTipClick(object sender, EventArgs e) { private static void HandleBalloonTipClick(object sender, EventArgs e) {

View file

@ -69,14 +69,14 @@
<h2>Een schermopname maken</h2> <h2>Een schermopname maken</h2>
<p> <p>
U kunt een schermopname maken door op uw toetsenbord de <kbd>Print</kbd>-toets te drukken of U kunt een schermopname maken door op uw toetsenbord de <kbd>Print</kbd>-toets te drukken of
door middel van een rechtermuisklik op het Greenshot-icoon in het systeemvak.</br> door middel van een rechtermuisklik op het Greenshot-icoon in het systeemvak.<br/>
Er zijn meerdere mogelijkheden om een schermopname te maken: Er zijn meerdere mogelijkheden om een schermopname te maken:
</p> </p>
<a name="capture-region"></a> <a name="capture-region"></a>
<h3>Interactief kader <kbd>Print</kbd></h3> <h3>Interactief kader <kbd>Print</kbd></h3>
<p> <p>
Deze "regio"-opnamemodus maakt het mogelijk om een gebied van het beeldscherm te selecteren voor een schermopname.</br> Deze "regio"-opnamemodus maakt het mogelijk om een gebied van het beeldscherm te selecteren voor een schermopname.<br/>
Bij het vastleggen van het opnamegebied verandert de mouse-cursor in een haarkruis. Bij het vastleggen van het opnamegebied verandert de mouse-cursor in een haarkruis.
Positioneer de muis naar een hoek van het gebied waarvan u een schermopname wilt maken en Positioneer de muis naar een hoek van het gebied waarvan u een schermopname wilt maken en
druk op de linkermuisknop en houd deze ingedrukt. Beweeg nu de muis naar de diagonale hoek druk op de linkermuisknop en houd deze ingedrukt. Beweeg nu de muis naar de diagonale hoek
@ -115,7 +115,7 @@
het actieve venster te fotograferen, maar een venster interactief te selecteren. het actieve venster te fotograferen, maar een venster interactief te selecteren.
Als deze optie geactiveerd is, kunt u een venster selecteren door het te klikken. Net als bij Als deze optie geactiveerd is, kunt u een venster selecteren door het te klikken. Net als bij
<a href="#capture-region">Interactief kader</a>, zal Greenshot het te fotograferen <a href="#capture-region">Interactief kader</a>, zal Greenshot het te fotograferen
gebied markeren.</br> Wilt u een deelvenster fotograferen, zoals bijv. een browservenster gebied markeren.<br/> Wilt u een deelvenster fotograferen, zoals bijv. een browservenster
zonder menu of gereedschapsbalk of een enkel onderdeel in een webpagina, zonder menu of gereedschapsbalk of een enkel onderdeel in een webpagina,
positioneer dan de muis over het deelvenster en druk de <kbd>Page Down</kbd>-toets. Hierna positioneer dan de muis over het deelvenster en druk de <kbd>Page Down</kbd>-toets. Hierna
kunt u de specifieke vensterelementen selecteren voor de schermopname. kunt u de specifieke vensterelementen selecteren voor de schermopname.
@ -168,15 +168,15 @@
<p> <p>
Kies een van de vormen in de gereedschapsbalk aan de linkerzijde van de beeldbewerker Kies een van de vormen in de gereedschapsbalk aan de linkerzijde van de beeldbewerker
of van het menu <em>Object</em>. Aan elke toets is tevens een sneltoets gekoppeld of van het menu <em>Object</em>. Aan elke toets is tevens een sneltoets gekoppeld
voor snelle toegang via het toetsenbord.</br> voor snelle toegang via het toetsenbord.<br/>
Beschikbare vormen zijn: rechthoek <kbd>R</kbd>, ellips <kbd>E</kbd>, lijn <kbd>L</kbd> Beschikbare vormen zijn: rechthoek <kbd>R</kbd>, ellips <kbd>E</kbd>, lijn <kbd>L</kbd>
pijl <kbd>A</kbd> en vrije vorm <kbd>F</kbd>.</br> pijl <kbd>A</kbd> en vrije vorm <kbd>F</kbd>.<br/>
Klik en sleep de muis om de positie en de grootte van de vorm te bepalen. Klik en sleep de muis om de positie en de grootte van de vorm te bepalen.
Laat de muisknop los als de vorm van de juiste afmetingen is. Laat de muisknop los als de vorm van de juiste afmetingen is.
</p> </p>
<p> <p>
Getekende vormen kunnen worden verplaatst en vergroot met behulp van de knop <em>Selectie</em> Getekende vormen kunnen worden verplaatst en vergroot met behulp van de knop <em>Selectie</em>
<kbd>ESC</kbd> op de gereedschapsbalk.</br>Voor elk vormtype zijn specifieke <kbd>ESC</kbd> op de gereedschapsbalk.<br>Voor elk vormtype zijn specifieke
opties beschikbaar om de karakteristieken aan te passen (bijv. lijndikte, opties beschikbaar om de karakteristieken aan te passen (bijv. lijndikte,
lijnkleur, vulkleur). U kunt het uiterlijk veranderen voor een bestaand geselecteerd object, lijnkleur, vulkleur). U kunt het uiterlijk veranderen voor een bestaand geselecteerd object,
maar u kunt ook de eigenschappen instellen voor de volgende te tekenen vorm. maar u kunt ook de eigenschappen instellen voor de volgende te tekenen vorm.
@ -188,7 +188,7 @@
<p class="hint"> <p class="hint">
Wilt u een symmetrische vorm tekenen (bijv. een vierkant of een cirkel)? Houd dan tijdens het tekenen Wilt u een symmetrische vorm tekenen (bijv. een vierkant of een cirkel)? Houd dan tijdens het tekenen
de <kbd>Shift</kbd>-toets ingedrukt. Bij het tekenen van pijlen, beperkt de <kbd>Shift</kbd>-toets de <kbd>Shift</kbd>-toets ingedrukt. Bij het tekenen van pijlen, beperkt de <kbd>Shift</kbd>-toets
de mogelijke hoeken tot veelvouden van 15°.</br> de mogelijke hoeken tot veelvouden van 15°.<br/>
Bij het vergroten van een bestaand object zorgt de <kbd>Shift</kbd>-toets ervoor dat de verhoudingen behouden blijven. Bij het vergroten van een bestaand object zorgt de <kbd>Shift</kbd>-toets ervoor dat de verhoudingen behouden blijven.
</p> </p>
<p class="hint"> <p class="hint">
@ -202,8 +202,8 @@
<p> <p>
Het gebruik van de Tekst-functie <kbd>T</kbd> is vergelijkbaar met dat van Het gebruik van de Tekst-functie <kbd>T</kbd> is vergelijkbaar met dat van
<a href="#editor-shapes">Vormen</a> toevoegen. Plaats een tekstkader van de gewenste grootte <a href="#editor-shapes">Vormen</a> toevoegen. Plaats een tekstkader van de gewenste grootte
en typ de tekst.</br> en typ de tekst.<br/>
Dubbelklik een bestaande tekst om deze te bewerken.</br> Dubbelklik een bestaande tekst om deze te bewerken.<br/>
Gebruik <kbd>Return</kbd> of <kbd>Enter</kbd> als u klaar bent met bewerken. Gebruik <kbd>Return</kbd> of <kbd>Enter</kbd> als u klaar bent met bewerken.
</p> </p>
<p class="hint"> <p class="hint">
@ -215,7 +215,7 @@
<h3>Markeren</h3> <h3>Markeren</h3>
<p> <p>
Met de Markeer-functie <kbd>H</kbd>, kunt u een gebied markeren op precies dezelfde wijze Met de Markeer-functie <kbd>H</kbd>, kunt u een gebied markeren op precies dezelfde wijze
als waarmee u een vorm <a href="#editor-shapes">shape</a> tekent.</br> als waarmee u een vorm <a href="#editor-shapes">shape</a> tekent.<br/>
De volgende opties bij het markeren zijn beschilbaar via de meest linkse knop De volgende opties bij het markeren zijn beschilbaar via de meest linkse knop
in de gereedschapsbalk: in de gereedschapsbalk:
</p> </p>
@ -231,8 +231,8 @@
<h3>Maskeren</h3> <h3>Maskeren</h3>
<p> <p>
Delen van een schermopname maskeren is een goed gebruik wanneer persoonlijke gegevens in beeld zijn Delen van een schermopname maskeren is een goed gebruik wanneer persoonlijke gegevens in beeld zijn
die beter privé kunnen blijven, zoals bijv. bankgegevens, namen, wachtwoorden of herkenbare personen.</br> die beter privé kunnen blijven, zoals bijv. bankgegevens, namen, wachtwoorden of herkenbare personen.<br/>
De functie Maskeren <kbd>O</kbd> gebruikt u net als het <a href="#editor-highlight">Markeren</a>.</br> De functie Maskeren <kbd>O</kbd> gebruikt u net als het <a href="#editor-highlight">Markeren</a>.<br/>
Beschikbare opties voor Maskeren zijn: Beschikbare opties voor Maskeren zijn:
</p> </p>
@ -245,7 +245,7 @@
* Afhankelijk van uw computer kan het vervagingseffect de werking van Greenshot's beeldbewerker * Afhankelijk van uw computer kan het vervagingseffect de werking van Greenshot's beeldbewerker
trager maken. Merkt u dat de beeldbewerker bij de toepassing van Vervagen traag en sloom wordt, trager maken. Merkt u dat de beeldbewerker bij de toepassing van Vervagen traag en sloom wordt,
probeer dan de <em>kwaliteit van de voorvertoning</em> in de gereedschapsbalk te verminderen of probeer dan de <em>kwaliteit van de voorvertoning</em> in de gereedschapsbalk te verminderen of
verlaag de waarde voor de <em>Vervagings-radius</em>.</br> verlaag de waarde voor de <em>Vervagings-radius</em>.<br/>
Blijft de functie Vervagen traag reageren, probeer dan de functie Pixeleren te gebuiken. Blijft de functie Vervagen traag reageren, probeer dan de functie Pixeleren te gebuiken.
</p> </p>
@ -262,9 +262,9 @@
<h3>Schermopname bijsnijden</h3> <h3>Schermopname bijsnijden</h3>
<p> <p>
Als u maar een deel van de schermopname nodig hebt, gebruik dan de functie bijsnijden <kbd>C</kbd> Als u maar een deel van de schermopname nodig hebt, gebruik dan de functie bijsnijden <kbd>C</kbd>
om overtollige delen weg te snijden.</br> om overtollige delen weg te snijden.<br/>
Teken hiertoe een rechthoek om het gebied van de schermopname dat behouden moet worden. Teken hiertoe een rechthoek om het gebied van de schermopname dat behouden moet worden.
U kunt de afmetingen van het geselecteerde gebied naar wens aanpassen.</br> U kunt de afmetingen van het geselecteerde gebied naar wens aanpassen.<br/>
Bent u tevreden over het geselecteerde gebied, bevestig het bijsnijden dan in de gereedschapsbalk of toets <kbd>Enter</kbd>. Bent u tevreden over het geselecteerde gebied, bevestig het bijsnijden dan in de gereedschapsbalk of toets <kbd>Enter</kbd>.
U kunt het bijsnijden afbreken met de toets <kbd>ESC</kbd>. U kunt het bijsnijden afbreken met de toets <kbd>ESC</kbd>.
@ -294,7 +294,7 @@
<p> <p>
Als u regelmatig dezelfde elementen toepast in de bewerking van uw schermopnamen Als u regelmatig dezelfde elementen toepast in de bewerking van uw schermopnamen
(bijv. een tekstkader met browsertype en versienummer, of het maskeren van hetzelfde (bijv. een tekstkader met browsertype en versienummer, of het maskeren van hetzelfde
element in verschillende schermopnamen) dan kunt u deze elementen hergebruiken.</br> element in verschillende schermopnamen) dan kunt u deze elementen hergebruiken.<br/>
Kies in het menu <em>Objecten</em>, <em>Objecten opslaan</em> om de huidige elementen op te slaan Kies in het menu <em>Objecten</em>, <em>Objecten opslaan</em> om de huidige elementen op te slaan
voor later gebruik. <em>Objecten laden</em> past deze eerder opgeslagen elementen toe voor later gebruik. <em>Objecten laden</em> past deze eerder opgeslagen elementen toe
op een andere schermopname. op een andere schermopname.
@ -331,7 +331,7 @@
<a name="settings-general"></a> <a name="settings-general"></a>
<h3>Algemene instellingen</h3> <h3>Algemene instellingen</h3>
<ul> <ul>
<li><em>Taal</em>: De taal waarin Greenshot wordt weergegeven.</br> <li><em>Taal</em>: De taal waarin Greenshot wordt weergegeven.<br/>
Aanvullende taalbestanden zijn te downloaden van de <a target="_blank" href="http://getgreenshot.org/downloads/">Greenshot website</a>. </li> Aanvullende taalbestanden zijn te downloaden van de <a target="_blank" href="http://getgreenshot.org/downloads/">Greenshot website</a>. </li>
<li><em>Greenshot met Windows opstarten</em>: Start het programma als de PC wordt opgestart.</li> <li><em>Greenshot met Windows opstarten</em>: Start het programma als de PC wordt opgestart.</li>
<li><em>Sneltoetsen</em>: Hier kunt u de sneltoetsen voor het maken van schermopnames aanpassen.</li> <li><em>Sneltoetsen</em>: Hier kunt u de sneltoetsen voor het maken van schermopnames aanpassen.</li>
@ -414,7 +414,7 @@
<p> <p>
Op dit moment zoeken we geen hulp bij de ontwikkeling. Op dit moment zoeken we geen hulp bij de ontwikkeling.
Maar dit betekent niet dat u niets kunt doen om het Greenshot ontwikkelteam te ondersteunen.</br> Maar dit betekent niet dat u niets kunt doen om het Greenshot ontwikkelteam te ondersteunen.<br/>
Bij voorbaat dank :) Bij voorbaat dank :)
</p> </p>
@ -425,8 +425,8 @@
goede software gratis en vrij toegankelijk te houden. Als Greenshot goede software gratis en vrij toegankelijk te houden. Als Greenshot
u helpt in uw werkzaamheden, als het u (of uw bedrijf) u helpt in uw werkzaamheden, als het u (of uw bedrijf)
tijd en geld bespaart, of u vindt het gewoon een fijn programma en tijd en geld bespaart, of u vindt het gewoon een fijn programma en
u staat positief tegenover het concept van open source software: Ondersteun ons werk dan met een donatie.</br> u staat positief tegenover het concept van open source software: Ondersteun ons werk dan met een donatie.<br/>
Bezoek onze website en lees daar hoe u het Greenshot-team kunt ondersteunen:</br> Bezoek onze website en lees daar hoe u het Greenshot-team kunt ondersteunen:<br/>
<a target="_blank" href="http://getgreenshot.org/support/">http://getgreenshot.org/support/</a> <a target="_blank" href="http://getgreenshot.org/support/">http://getgreenshot.org/support/</a>
</p> </p>
@ -434,7 +434,7 @@
<h3>Vertel het door</h3> <h3>Vertel het door</h3>
<p> <p>
Bevalt Greenshot u? Vertel het dan door: vertel uw vrienden en collega's over Greenshot. Bevalt Greenshot u? Vertel het dan door: vertel uw vrienden en collega's over Greenshot.
En ook uw aanhang en achterban ! :)</br> En ook uw aanhang en achterban ! :)<br/>
Bespreek Greenshot met goede kritieken op software portals of plaats een verwijzing naar Greenshot in uw blog of op uw website. Bespreek Greenshot met goede kritieken op software portals of plaats een verwijzing naar Greenshot in uw blog of op uw website.
</p> </p>
@ -443,10 +443,10 @@
<p> <p>
Is Greenshot niet beschikbaar in uw favoriete taal en u denkt dat u software kunt vertalen dan bent u van harte welkom! Is Greenshot niet beschikbaar in uw favoriete taal en u denkt dat u software kunt vertalen dan bent u van harte welkom!
Als geregisteerde gebruiker bij sourceforge.net kunt u uw vertaling in onze Als geregisteerde gebruiker bij sourceforge.net kunt u uw vertaling in onze
<a href="https://sourceforge.net/tracker/?group_id=191585&atid=1368020">vertalings tracker</a> aanmelden.</br> <a href="https://sourceforge.net/tracker/?group_id=191585&atid=1368020">vertalings tracker</a> aanmelden.<br/>
Voordat u begint is het verstandig om te kijken of Greenshot niet al in de taal vertaald is, zie de Voordat u begint is het verstandig om te kijken of Greenshot niet al in de taal vertaald is, zie de
<a href="#">downloads pagina</a>. Ook kunt u op onze <a href="https://sourceforge.net/tracker/?group_id=191585&atid=1368020">vertalings tracker</a> kijken. <a href="#">downloads pagina</a>. Ook kunt u op onze <a href="https://sourceforge.net/tracker/?group_id=191585&atid=1368020">vertalings tracker</a> kijken.
Het zou namelijk kunnen zijn dat iemand al aan de vertaling werkt of misschien hierover heeft gecommuniceerd.</br> Het zou namelijk kunnen zijn dat iemand al aan de vertaling werkt of misschien hierover heeft gecommuniceerd.<br/>
Merk op dat vertalingen alleen kunnen worden geaccepteerd als ze afkomstig zijn van een geregistreerde Merk op dat vertalingen alleen kunnen worden geaccepteerd als ze afkomstig zijn van een geregistreerde
sourceforge.net-gebruiker. Wij kunnen niet elke vertaling doorgronden en daarom is het belangrijk dat we sourceforge.net-gebruiker. Wij kunnen niet elke vertaling doorgronden en daarom is het belangrijk dat we

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -33,11 +32,10 @@ namespace GreenshotBoxPlugin {
/// <summary> /// <summary>
/// This is the Box base code /// This is the Box base code
/// </summary> /// </summary>
[Plugin("Box", true)]
public class BoxPlugin : IGreenshotPlugin { public class BoxPlugin : IGreenshotPlugin {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxPlugin)); private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxPlugin));
private static BoxConfiguration _config; private static BoxConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources; private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig; private ToolStripMenuItem _itemPlugInConfig;
@ -46,7 +44,7 @@ namespace GreenshotBoxPlugin {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected void Dispose(bool disposing) {
if (disposing) { if (disposing) {
if (_itemPlugInConfig != null) { if (_itemPlugInConfig != null) {
_itemPlugInConfig.Dispose(); _itemPlugInConfig.Dispose();
@ -55,35 +53,22 @@ namespace GreenshotBoxPlugin {
} }
} }
public IEnumerable<IDestination> Destinations() {
yield return new BoxDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param> public bool Initialize() {
/// <param name="pluginAttribute">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute pluginAttribute) {
_host = pluginHost;
Attributes = pluginAttribute;
// Register configuration (don't need the configuration itself) // Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<BoxConfiguration>(); _config = IniConfig.GetIniSection<BoxConfiguration>();
_resources = new ComponentResourceManager(typeof(BoxPlugin)); _resources = new ComponentResourceManager(typeof(BoxPlugin));
SimpleServiceProvider.Current.AddService(new BoxDestination(this));
_itemPlugInConfig = new ToolStripMenuItem { _itemPlugInConfig = new ToolStripMenuItem {
Image = (Image) _resources.GetObject("Box"), Image = (Image) _resources.GetObject("Box"),
Text = Language.GetString("box", LangKey.Configure) Text = Language.GetString("box", LangKey.Configure)
}; };
_itemPlugInConfig.Click += ConfigMenuClick; _itemPlugInConfig.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig); PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
return true; return true;
} }
@ -94,14 +79,14 @@ namespace GreenshotBoxPlugin {
} }
} }
public virtual void Shutdown() { public void Shutdown() {
LOG.Debug("Box Plugin shutdown."); LOG.Debug("Box Plugin shutdown.");
} }
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
} }
@ -119,7 +104,7 @@ namespace GreenshotBoxPlugin {
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails)); string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename); SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("box", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Box", Language.GetString("box", LangKey.communication_wait),
delegate { delegate {
url = BoxUtils.UploadToBox(imageToUpload, captureDetails.Title, filename); url = BoxUtils.UploadToBox(imageToUpload, captureDetails.Title, filename);
} }

View file

@ -27,8 +27,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to upload images to Box")] [assembly: AssemblyDescription("A plugin to upload images to Box")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotBoxPlugin.BoxPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -42,10 +42,6 @@ namespace GreenshotConfluencePlugin {
private static readonly Image ConfluenceIcon; private static readonly Image ConfluenceIcon;
private readonly Page _page; private readonly Page _page;
public static bool IsInitialized {
get;
private set;
}
static ConfluenceDestination() { static ConfluenceDestination() {
IsInitialized = false; IsInitialized = false;
try { try {
@ -61,6 +57,12 @@ namespace GreenshotConfluencePlugin {
} }
} }
public static bool IsInitialized
{
get;
private set;
}
public ConfluenceDestination() { public ConfluenceDestination() {
} }

View file

@ -24,7 +24,6 @@ using Greenshot.IniFile;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using System; using System;
using System.Collections.Generic;
using System.Windows; using System.Windows;
using TranslationByMarkupExtension; using TranslationByMarkupExtension;
@ -42,11 +41,11 @@ namespace GreenshotConfluencePlugin {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected void Dispose(bool disposing) {
//if (disposing) {} //if (disposing) {}
} }
private static void CreateConfluenceConntector() { private static void CreateConfluenceConnector() {
if (_confluenceConnector == null) { if (_confluenceConnector == null) {
if (_config.Url.Contains("soap-axis")) { if (_config.Url.Contains("soap-axis")) {
_confluenceConnector = new ConfluenceConnector(_config.Url, _config.Timeout); _confluenceConnector = new ConfluenceConnector(_config.Url, _config.Timeout);
@ -65,7 +64,7 @@ namespace GreenshotConfluencePlugin {
public static ConfluenceConnector ConfluenceConnector { public static ConfluenceConnector ConfluenceConnector {
get { get {
if (_confluenceConnector == null) { if (_confluenceConnector == null) {
CreateConfluenceConntector(); CreateConfluenceConnector();
} }
try { try {
if (_confluenceConnector != null && !_confluenceConnector.IsLoggedIn) { if (_confluenceConnector != null && !_confluenceConnector.IsLoggedIn) {
@ -78,22 +77,10 @@ namespace GreenshotConfluencePlugin {
} }
} }
public IEnumerable<IDestination> Destinations() {
if (ConfluenceDestination.IsInitialized) {
yield return new ConfluenceDestination();
}
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param> public bool Initialize() {
/// <param name="myAttributes">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
// Register configuration (don't need the configuration itself) // Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<ConfluenceConfiguration>(); _config = IniConfig.GetIniSection<ConfluenceConfiguration>();
if(_config.IsDirty) { if(_config.IsDirty) {
@ -106,10 +93,14 @@ namespace GreenshotConfluencePlugin {
LOG.ErrorFormat("Problem in ConfluencePlugin.Initialize: {0}", ex.Message); LOG.ErrorFormat("Problem in ConfluencePlugin.Initialize: {0}", ex.Message);
return false; return false;
} }
if (ConfluenceDestination.IsInitialized)
{
SimpleServiceProvider.Current.AddService(new ConfluenceDestination());
}
return true; return true;
} }
public virtual void Shutdown() { public void Shutdown() {
LOG.Debug("Confluence Plugin shutdown."); LOG.Debug("Confluence Plugin shutdown.");
if (_confluenceConnector != null) { if (_confluenceConnector != null) {
_confluenceConnector.Logout(); _confluenceConnector.Logout();
@ -120,7 +111,7 @@ namespace GreenshotConfluencePlugin {
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
ConfluenceConfiguration clonedConfig = _config.Clone(); ConfluenceConfiguration clonedConfig = _config.Clone();
ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig); ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig);
string url = _config.Url; string url = _config.Url;

View file

@ -1,33 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/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 Greenshot.Plugin;
using System.Runtime.InteropServices;
// 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.
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotConfluencePlugin.ConfluencePlugin", true)]
// 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)]

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -33,11 +32,10 @@ namespace GreenshotDropboxPlugin {
/// <summary> /// <summary>
/// This is the Dropbox base code /// This is the Dropbox base code
/// </summary> /// </summary>
[Plugin("Dropbox", true)]
public class DropboxPlugin : IGreenshotPlugin { public class DropboxPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin));
private static DropboxPluginConfiguration _config; private static DropboxPluginConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources; private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig; private ToolStripMenuItem _itemPlugInConfig;
@ -46,7 +44,7 @@ namespace GreenshotDropboxPlugin {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected void Dispose(bool disposing) {
if (disposing) { if (disposing) {
if (_itemPlugInConfig != null) { if (_itemPlugInConfig != null) {
_itemPlugInConfig.Dispose(); _itemPlugInConfig.Dispose();
@ -55,37 +53,23 @@ namespace GreenshotDropboxPlugin {
} }
} }
public IEnumerable<IDestination> Destinations() {
yield return new DropboxDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param> public bool Initialize() {
/// <param name="myAttributes">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
_host = pluginHost;
Attributes = myAttributes;
// Register configuration (don't need the configuration itself) // Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<DropboxPluginConfiguration>(); _config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
_resources = new ComponentResourceManager(typeof(DropboxPlugin)); _resources = new ComponentResourceManager(typeof(DropboxPlugin));
SimpleServiceProvider.Current.AddService(new DropboxDestination(this));
_itemPlugInConfig = new ToolStripMenuItem _itemPlugInConfig = new ToolStripMenuItem
{ {
Text = Language.GetString("dropbox", LangKey.Configure), Text = Language.GetString("dropbox", LangKey.Configure),
Tag = _host,
Image = (Image)_resources.GetObject("Dropbox") Image = (Image)_resources.GetObject("Dropbox")
}; };
_itemPlugInConfig.Click += ConfigMenuClick; _itemPlugInConfig.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig); PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
return true; return true;
} }
@ -96,14 +80,14 @@ namespace GreenshotDropboxPlugin {
} }
} }
public virtual void Shutdown() { public void Shutdown() {
Log.Debug("Dropbox Plugin shutdown."); Log.Debug("Dropbox Plugin shutdown.");
} }
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
} }
@ -119,7 +103,7 @@ namespace GreenshotDropboxPlugin {
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false); SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
try { try {
string dropboxUrl = null; string dropboxUrl = null;
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("dropbox", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Dropbox", Language.GetString("dropbox", LangKey.communication_wait),
delegate delegate
{ {
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails)); string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to upload images to Dropbox")] [assembly: AssemblyDescription("A plugin to upload images to Dropbox")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotDropboxPlugin.DropboxPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -32,12 +32,11 @@ namespace ExternalCommand {
/// <summary> /// <summary>
/// An Plugin to run commands after an image was written /// An Plugin to run commands after an image was written
/// </summary> /// </summary>
[Plugin("ExternalCommand", true)]
public class ExternalCommandPlugin : IGreenshotPlugin { public class ExternalCommandPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ExternalCommandPlugin)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ExternalCommandPlugin));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>(); private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
private IGreenshotHost _host;
private PluginAttribute _myAttributes;
private ToolStripMenuItem _itemPlugInRoot; private ToolStripMenuItem _itemPlugInRoot;
public void Dispose() { public void Dispose() {
@ -45,24 +44,19 @@ namespace ExternalCommand {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected virtual void Dispose(bool disposing)
if (disposing) { {
if (_itemPlugInRoot != null) { if (!disposing) return;
_itemPlugInRoot.Dispose(); if (_itemPlugInRoot == null) return;
_itemPlugInRoot = null; _itemPlugInRoot.Dispose();
} _itemPlugInRoot = null;
} }
} private IEnumerable<IDestination> Destinations() {
public IEnumerable<IDestination> Destinations() {
foreach(string command in ExternalCommandConfig.Commands) { foreach(string command in ExternalCommandConfig.Commands) {
yield return new ExternalCommandDestination(command); yield return new ExternalCommandDestination(command);
} }
} }
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Check and eventually fix the command settings /// Check and eventually fix the command settings
@ -91,15 +85,14 @@ namespace ExternalCommand {
Log.WarnFormat("Found 'invalid' commandline {0} for command {1}", ExternalCommandConfig.Commandline[command], command); Log.WarnFormat("Found 'invalid' commandline {0} for command {1}", ExternalCommandConfig.Commandline[command], command);
return false; return false;
} }
SimpleServiceProvider.Current.AddService(Destinations());
return true; return true;
} }
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param> public virtual bool Initialize() {
/// <param name="myAttributes">My own attributes</param> Log.DebugFormat("Initialize called");
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
Log.DebugFormat("Initialize called of {0}", myAttributes.Name);
List<string> commandsToDelete = new List<string>(); List<string> commandsToDelete = new List<string>();
// Check configuration // Check configuration
@ -114,16 +107,12 @@ namespace ExternalCommand {
ExternalCommandConfig.Delete(command); ExternalCommandConfig.Delete(command);
} }
_host = pluginHost; _itemPlugInRoot = new ToolStripMenuItem();
_myAttributes = myAttributes; _itemPlugInRoot.Click += ConfigMenuClick;
_itemPlugInRoot = new ToolStripMenuItem {Tag = _host};
OnIconSizeChanged(this, new PropertyChangedEventArgs("IconSize")); OnIconSizeChanged(this, new PropertyChangedEventArgs("IconSize"));
OnLanguageChanged(this, null); OnLanguageChanged(this, null);
_itemPlugInRoot.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInRoot); PluginUtils.AddToContextMenu(_itemPlugInRoot);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
CoreConfig.PropertyChanged += OnIconSizeChanged; CoreConfig.PropertyChanged += OnIconSizeChanged;
return true; return true;
@ -154,7 +143,7 @@ namespace ExternalCommand {
} }
public virtual void Shutdown() { public virtual void Shutdown() {
Log.Debug("Shutdown of " + _myAttributes.Name); Log.Debug("Shutdown");
} }
private void ConfigMenuClick(object sender, EventArgs eventArgs) { private void ConfigMenuClick(object sender, EventArgs eventArgs) {

View file

@ -1,34 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/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 Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
// 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.
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("ExternalCommand.ExternalCommandPlugin", true)]
// 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)]

View file

@ -20,7 +20,6 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -39,8 +38,6 @@ namespace GreenshotFlickrPlugin
public class FlickrPlugin : IGreenshotPlugin { public class FlickrPlugin : IGreenshotPlugin {
private static readonly ILog Log = LogManager.GetLogger(typeof(FlickrPlugin)); private static readonly ILog Log = LogManager.GetLogger(typeof(FlickrPlugin));
private static FlickrConfiguration _config; private static FlickrConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources; private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig; private ToolStripMenuItem _itemPlugInConfig;
@ -49,7 +46,7 @@ namespace GreenshotFlickrPlugin
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected void Dispose(bool disposing) {
if (!disposing) { if (!disposing) {
return; return;
} }
@ -60,25 +57,10 @@ namespace GreenshotFlickrPlugin
_itemPlugInConfig = null; _itemPlugInConfig = null;
} }
public IEnumerable<IDestination> Destinations() {
yield return new FlickrDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param> public bool Initialize() {
/// <param name="pluginAttribute">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute pluginAttribute) {
_host = pluginHost;
Attributes = pluginAttribute;
// Register configuration (don't need the configuration itself) // Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<FlickrConfiguration>(); _config = IniConfig.GetIniSection<FlickrConfiguration>();
_resources = new ComponentResourceManager(typeof(FlickrPlugin)); _resources = new ComponentResourceManager(typeof(FlickrPlugin));
@ -86,12 +68,11 @@ namespace GreenshotFlickrPlugin
_itemPlugInConfig = new ToolStripMenuItem _itemPlugInConfig = new ToolStripMenuItem
{ {
Text = Language.GetString("flickr", LangKey.Configure), Text = Language.GetString("flickr", LangKey.Configure),
Tag = _host,
Image = (Image) _resources.GetObject("flickr") Image = (Image) _resources.GetObject("flickr")
}; };
_itemPlugInConfig.Click += ConfigMenuClick; _itemPlugInConfig.Click += ConfigMenuClick;
SimpleServiceProvider.Current.AddService(new FlickrDestination(this));
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig); PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
return true; return true;
} }
@ -102,14 +83,14 @@ namespace GreenshotFlickrPlugin
} }
} }
public virtual void Shutdown() { public void Shutdown() {
Log.Debug("Flickr Plugin shutdown."); Log.Debug("Flickr Plugin shutdown.");
} }
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
} }
@ -122,7 +103,7 @@ namespace GreenshotFlickrPlugin
uploadUrl = null; uploadUrl = null;
try { try {
string flickrUrl = null; string flickrUrl = null;
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("flickr", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Flickr", Language.GetString("flickr", LangKey.communication_wait),
delegate { delegate {
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails)); string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
flickrUrl = FlickrUtils.UploadToFlickr(surface, outputSettings, captureDetails.Title, filename); flickrUrl = FlickrUtils.UploadToFlickr(surface, outputSettings, captureDetails.Title, filename);

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to upload images to Flickr")] [assembly: AssemblyDescription("A plugin to upload images to Flickr")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotFlickrPlugin.FlickrPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -146,7 +146,7 @@ namespace GreenshotImgurPlugin {
// Should fix Bug #3378699 // Should fix Bug #3378699
pictureBox1.Image = pictureBox1.ErrorImage; pictureBox1.Image = pictureBox1.ErrorImage;
try { try {
new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Imgur", Language.GetString("imgur", LangKey.communication_wait),
delegate { delegate {
ImgurUtils.DeleteImgurImage(imgurInfo); ImgurUtils.DeleteImgurImage(imgurInfo);
} }

View file

@ -33,11 +33,10 @@ namespace GreenshotImgurPlugin {
/// <summary> /// <summary>
/// This is the ImgurPlugin code /// This is the ImgurPlugin code
/// </summary> /// </summary>
[Plugin("Imgur", true)]
public class ImgurPlugin : IGreenshotPlugin { public class ImgurPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurPlugin)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurPlugin));
private static ImgurConfiguration _config; private static ImgurConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources; private ComponentResourceManager _resources;
private ToolStripMenuItem _historyMenuItem; private ToolStripMenuItem _historyMenuItem;
private ToolStripMenuItem _itemPlugInConfig; private ToolStripMenuItem _itemPlugInConfig;
@ -60,24 +59,15 @@ namespace GreenshotImgurPlugin {
} }
} }
public IEnumerable<IDestination> Destinations() { private IEnumerable<IDestination> Destinations() {
yield return new ImgurDestination(this); yield return new ImgurDestination(this);
} }
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns> /// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) { public bool Initialize() {
_host = pluginHost;
Attributes = myAttributes;
// Get configuration // Get configuration
_config = IniConfig.GetIniSection<ImgurConfiguration>(); _config = IniConfig.GetIniSection<ImgurConfiguration>();
_resources = new ComponentResourceManager(typeof(ImgurPlugin)); _resources = new ComponentResourceManager(typeof(ImgurPlugin));
@ -87,25 +77,21 @@ namespace GreenshotImgurPlugin {
Image = (Image) _resources.GetObject("Imgur") Image = (Image) _resources.GetObject("Imgur")
}; };
_historyMenuItem = new ToolStripMenuItem(Language.GetString("imgur", LangKey.history)) // Provide the IDestination
{ SimpleServiceProvider.Current.AddService(Destinations());
Tag = _host _historyMenuItem = new ToolStripMenuItem(Language.GetString("imgur", LangKey.history));
};
_historyMenuItem.Click += delegate { _historyMenuItem.Click += delegate {
ImgurHistory.ShowHistory(); ImgurHistory.ShowHistory();
}; };
itemPlugInRoot.DropDownItems.Add(_historyMenuItem); itemPlugInRoot.DropDownItems.Add(_historyMenuItem);
_itemPlugInConfig = new ToolStripMenuItem(Language.GetString("imgur", LangKey.configure)) _itemPlugInConfig = new ToolStripMenuItem(Language.GetString("imgur", LangKey.configure));
{
Tag = _host
};
_itemPlugInConfig.Click += delegate { _itemPlugInConfig.Click += delegate {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
}; };
itemPlugInRoot.DropDownItems.Add(_itemPlugInConfig); itemPlugInRoot.DropDownItems.Add(_itemPlugInConfig);
PluginUtils.AddToContextMenu(_host, itemPlugInRoot); PluginUtils.AddToContextMenu(itemPlugInRoot);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
// Enable history if there are items available // Enable history if there are items available
@ -129,7 +115,8 @@ namespace GreenshotImgurPlugin {
} }
try try
{ {
_host.GreenshotForm.BeginInvoke((MethodInvoker)delegate var form = SimpleServiceProvider.Current.GetInstance<Form>();
form.BeginInvoke((MethodInvoker)delegate
{ {
var historyMenuItem = _historyMenuItem; var historyMenuItem = _historyMenuItem;
if (historyMenuItem == null) if (historyMenuItem == null)

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to upload images to Imgur")] [assembly: AssemblyDescription("A plugin to upload images to Imgur")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotImgurPlugin.ImgurPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -55,8 +55,9 @@ namespace GreenshotJiraPlugin {
CoreConfig.PropertyChanged += (sender, args) => CoreConfig.PropertyChanged += (sender, args) =>
{ {
if (args.PropertyName == nameof(CoreConfig.IconSize)) if (args.PropertyName == nameof(CoreConfig.IconSize))
{ {
JiraPlugin.Instance.JiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.ScaledIconSize.Width, Height = CoreConfig.ScaledIconSize.Height }); var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
jiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.ScaledIconSize.Width, Height = CoreConfig.ScaledIconSize.Height });
} }
}; };

View file

@ -40,16 +40,10 @@ namespace GreenshotJiraPlugin {
public class JiraDestination : AbstractDestination { public class JiraDestination : AbstractDestination {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination));
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>(); private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
private readonly JiraPlugin _jiraPlugin;
private readonly Issue _jiraIssue; private readonly Issue _jiraIssue;
public JiraDestination(JiraPlugin jiraPlugin) { public JiraDestination(Issue jiraIssue = null) {
_jiraPlugin = jiraPlugin; _jiraIssue = jiraIssue;
}
public JiraDestination(JiraPlugin jiraPlugin, Issue jiraIssue) {
_jiraPlugin = jiraPlugin;
_jiraIssue = jiraIssue;
} }
public override string Designation => "Jira"; public override string Designation => "Jira";
@ -73,7 +67,7 @@ namespace GreenshotJiraPlugin {
get get
{ {
Image displayIcon = null; Image displayIcon = null;
var jiraConnector = JiraPlugin.Instance.CurrentJiraConnector; var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (jiraConnector != null) if (jiraConnector != null)
{ {
if (_jiraIssue != null) if (_jiraIssue != null)
@ -104,13 +98,13 @@ namespace GreenshotJiraPlugin {
public override IEnumerable<IDestination> DynamicDestinations() public override IEnumerable<IDestination> DynamicDestinations()
{ {
var jiraConnector = JiraPlugin.Instance.CurrentJiraConnector; var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (jiraConnector == null || !jiraConnector.IsLoggedIn) { if (jiraConnector == null || !jiraConnector.IsLoggedIn) {
yield break; yield break;
} }
foreach(var jiraDetails in jiraConnector.Monitor.RecentJiras) foreach(var jiraDetails in jiraConnector.Monitor.RecentJiras)
{ {
yield return new JiraDestination(_jiraPlugin,jiraDetails.JiraIssue); yield return new JiraDestination(jiraDetails.JiraIssue);
} }
} }
@ -118,6 +112,7 @@ namespace GreenshotJiraPlugin {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
string filename = Path.GetFileName(FilenameHelper.GetFilename(Config.UploadFormat, captureDetails)); string filename = Path.GetFileName(FilenameHelper.GetFilename(Config.UploadFormat, captureDetails));
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(Config.UploadFormat, Config.UploadJpegQuality, Config.UploadReduceColors); SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(Config.UploadFormat, Config.UploadJpegQuality, Config.UploadReduceColors);
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (_jiraIssue != null) { if (_jiraIssue != null) {
try { try {
// Run upload in the background // Run upload in the background
@ -125,8 +120,8 @@ namespace GreenshotJiraPlugin {
async () => async () =>
{ {
var surfaceContainer = new SurfaceContainer(surfaceToUpload, outputSettings, filename); var surfaceContainer = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
await _jiraPlugin.JiraConnector.AttachAsync(_jiraIssue.Key, surfaceContainer); await jiraConnector.AttachAsync(_jiraIssue.Key, surfaceContainer);
surfaceToUpload.UploadUrl = _jiraPlugin.JiraConnector.JiraBaseUri.AppendSegments("browse", _jiraIssue.Key).AbsoluteUri; surfaceToUpload.UploadUrl = jiraConnector.JiraBaseUri.AppendSegments("browse", _jiraIssue.Key).AbsoluteUri;
} }
); );
Log.DebugFormat("Uploaded to Jira {0}", _jiraIssue.Key); Log.DebugFormat("Uploaded to Jira {0}", _jiraIssue.Key);
@ -136,12 +131,12 @@ namespace GreenshotJiraPlugin {
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message); MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
} }
} else { } else {
var jiraForm = new JiraForm(_jiraPlugin.JiraConnector); var jiraForm = new JiraForm(jiraConnector);
jiraForm.SetFilename(filename); jiraForm.SetFilename(filename);
var dialogResult = jiraForm.ShowDialog(); var dialogResult = jiraForm.ShowDialog();
if (dialogResult == DialogResult.OK) { if (dialogResult == DialogResult.OK) {
try { try {
surfaceToUpload.UploadUrl = _jiraPlugin.JiraConnector.JiraBaseUri.AppendSegments("browse", jiraForm.GetJiraIssue().Key).AbsoluteUri; surfaceToUpload.UploadUrl = jiraConnector.JiraBaseUri.AppendSegments("browse", jiraForm.GetJiraIssue().Key).AbsoluteUri;
// Run upload in the background // Run upload in the background
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
async () => async () =>

View file

@ -33,11 +33,10 @@ namespace GreenshotJiraPlugin {
/// <summary> /// <summary>
/// This is the JiraPlugin base code /// This is the JiraPlugin base code
/// </summary> /// </summary>
[Plugin("Jira", true)]
public class JiraPlugin : IGreenshotPlugin { public class JiraPlugin : IGreenshotPlugin {
private static readonly ILog Log = LogManager.GetLogger(typeof(JiraPlugin)); private static readonly ILog Log = LogManager.GetLogger(typeof(JiraPlugin));
private JiraConfiguration _config; private JiraConfiguration _config;
private static JiraPlugin _instance;
private JiraConnector _jiraConnector;
public void Dispose() { public void Dispose() {
Dispose(true); Dispose(true);
@ -45,58 +44,27 @@ namespace GreenshotJiraPlugin {
} }
protected void Dispose(bool disposing) { protected void Dispose(bool disposing) {
if (disposing) { if (disposing)
if (JiraConnector != null) { {
JiraConnector.Dispose(); var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
JiraConnector = null; jiraConnector?.Dispose();
}
} }
} }
public static JiraPlugin Instance => _instance;
public JiraPlugin() {
_instance = this;
}
public IEnumerable<IDestination> Destinations() {
yield return new JiraDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
//Needed for a fail-fast
public JiraConnector CurrentJiraConnector => JiraConnector;
public JiraConnector JiraConnector
{
get
{
lock (_instance)
{
if (_jiraConnector == null)
{
JiraConnector = new JiraConnector();
}
}
return _jiraConnector;
}
private set { _jiraConnector = value; }
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns> /// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) { public bool Initialize() {
// Register configuration (don't need the configuration itself) // Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<JiraConfiguration>(); _config = IniConfig.GetIniSection<JiraConfiguration>();
// Make sure the loggin is enable for the corect level. // Provide the JiraConnector
SimpleServiceProvider.Current.AddService(new JiraConnector());
// Provide the IDestination
SimpleServiceProvider.Current.AddService(new JiraDestination());
// Make sure the log is enabled for the correct level.
if (Log.IsDebugEnabled) if (Log.IsDebugEnabled)
{ {
LogSettings.RegisterDefaultLogger<Log4NetLogger>(LogLevels.Verbose); LogSettings.RegisterDefaultLogger<Log4NetLogger>(LogLevels.Verbose);
@ -142,7 +110,8 @@ namespace GreenshotJiraPlugin {
public void Shutdown() { public void Shutdown() {
Log.Debug("Jira Plugin shutdown."); Log.Debug("Jira Plugin shutdown.");
JiraConnector?.Logout(); var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
jiraConnector?.Logout();
} }
/// <summary> /// <summary>
@ -152,12 +121,13 @@ namespace GreenshotJiraPlugin {
string url = _config.Url; string url = _config.Url;
if (ShowConfigDialog()) { if (ShowConfigDialog()) {
// check for re-login // check for re-login
if (JiraConnector != null && JiraConnector.IsLoggedIn && !string.IsNullOrEmpty(url)) { var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (jiraConnector != null && jiraConnector.IsLoggedIn && !string.IsNullOrEmpty(url)) {
if (!url.Equals(_config.Url)) { if (!url.Equals(_config.Url)) {
JiraConnector.Logout(); jiraConnector.Logout();
Task.Run(async () => Task.Run(async () =>
{ {
await JiraConnector.LoginAsync(); await jiraConnector.LoginAsync();
}); });
} }
} }

View file

@ -18,12 +18,33 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
namespace GreenshotOCR
namespace GreenshotPlugin.Core
{ {
public delegate TResult Func<out TResult>(); /// <summary>
public delegate TResult Func<in T, out TResult>(T arg); /// Needed for the drop down, available languages for OCR
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2); /// </summary>
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3); public enum ModiLanguage {
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); CHINESE_SIMPLIFIED = 2052,
CHINESE_TRADITIONAL = 1028,
CZECH = 5,
DANISH = 6,
DUTCH = 19,
ENGLISH = 9,
FINNISH = 11,
FRENCH = 12,
GERMAN = 7,
GREEK = 8,
HUNGARIAN = 14,
ITALIAN = 16,
JAPANESE = 17,
KOREAN = 18,
NORWEGIAN = 20,
POLISH = 21,
PORTUGUESE = 22,
RUSSIAN = 25,
SPANISH = 10,
SWEDISH = 29,
TURKISH = 31,
SYSDEFAULT = 2048
}
} }

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
@ -31,39 +30,14 @@ using GreenshotPlugin.Effects;
//using Microsoft.Win32; //using Microsoft.Win32;
namespace GreenshotOCR { namespace GreenshotOCR {
// Needed for the drop down, available languages for OCR
public enum ModiLanguage {
CHINESE_SIMPLIFIED = 2052,
CHINESE_TRADITIONAL = 1028,
CZECH = 5,
DANISH = 6,
DUTCH = 19,
ENGLISH = 9,
FINNISH = 11,
FRENCH = 12,
GERMAN = 7,
GREEK = 8,
HUNGARIAN = 14,
ITALIAN = 16,
JAPANESE = 17,
KOREAN = 18,
NORWEGIAN = 20,
POLISH = 21,
PORTUGUESE = 22,
RUSSIAN = 25,
SPANISH = 10,
SWEDISH = 29,
TURKISH = 31,
SYSDEFAULT = 2048
}
/// <summary> /// <summary>
/// OCR Plugin Greenshot /// OCR Plugin Greenshot
/// </summary> /// </summary>
[Plugin("Ocr", true)]
public class OcrPlugin : IGreenshotPlugin { public class OcrPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(OcrPlugin)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(OcrPlugin));
private string _ocrCommand; private string _ocrCommand;
private static OCRConfiguration config; private static OCRConfiguration _config;
private PluginAttribute _myAttributes;
private ToolStripMenuItem _ocrMenuItem = new ToolStripMenuItem(); private ToolStripMenuItem _ocrMenuItem = new ToolStripMenuItem();
public void Dispose() { public void Dispose() {
@ -80,24 +54,14 @@ namespace GreenshotOCR {
} }
} }
public IEnumerable<IDestination> Destinations() {
yield return new OCRDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="greenshotHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns> /// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public virtual bool Initialize(IGreenshotHost greenshotHost, PluginAttribute myAttributes) { public bool Initialize() {
Log.Debug("Initialize called of " + myAttributes.Name); Log.Debug("Initialize called");
_myAttributes = myAttributes;
var ocrDirectory = Path.GetDirectoryName(myAttributes.DllFile); var ocrDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
if (ocrDirectory == null) if (ocrDirectory == null)
{ {
return false; return false;
@ -108,11 +72,13 @@ namespace GreenshotOCR {
Log.Warn("No MODI found!"); Log.Warn("No MODI found!");
return false; return false;
} }
// Provide the IDestination
SimpleServiceProvider.Current.AddService(new OCRDestination(this));
// Load configuration // Load configuration
config = IniConfig.GetIniSection<OCRConfiguration>(); _config = IniConfig.GetIniSection<OCRConfiguration>();
if (config.Language != null) { if (_config.Language != null) {
config.Language = config.Language.Replace("miLANG_","").Replace("_"," "); _config.Language = _config.Language.Replace("miLANG_","").Replace("_"," ");
} }
return true; return true;
} }
@ -121,18 +87,18 @@ namespace GreenshotOCR {
/// Implementation of the IGreenshotPlugin.Shutdown /// Implementation of the IGreenshotPlugin.Shutdown
/// </summary> /// </summary>
public void Shutdown() { public void Shutdown() {
Log.Debug("Shutdown of " + _myAttributes.Name); Log.Debug("Shutdown");
} }
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
if (!HasModi()) { if (!HasModi()) {
MessageBox.Show("Sorry, is seems that Microsoft Office Document Imaging (MODI) is not installed, therefor the OCR Plugin cannot work."); MessageBox.Show("Sorry, is seems that Microsoft Office Document Imaging (MODI) is not installed, therefor the OCR Plugin cannot work.");
return; return;
} }
SettingsForm settingsForm = new SettingsForm(Enum.GetNames(typeof(ModiLanguage)), config); SettingsForm settingsForm = new SettingsForm(Enum.GetNames(typeof(ModiLanguage)), _config);
DialogResult result = settingsForm.ShowDialog(); DialogResult result = settingsForm.ShowDialog();
if (result == DialogResult.OK) { if (result == DialogResult.OK) {
// "Re"set hotkeys // "Re"set hotkeys
@ -177,7 +143,7 @@ namespace GreenshotOCR {
string text = ""; string text = "";
try { try {
ProcessStartInfo processStartInfo = new ProcessStartInfo(_ocrCommand, "\"" + filePath + "\" " + config.Language + " " + config.Orientimage + " " + config.StraightenImage) ProcessStartInfo processStartInfo = new ProcessStartInfo(_ocrCommand, "\"" + filePath + "\" " + _config.Language + " " + _config.Orientimage + " " + _config.StraightenImage)
{ {
CreateNoWindow = true, CreateNoWindow = true,
RedirectStandardOutput = true, RedirectStandardOutput = true,

View file

@ -1,34 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/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 Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
// 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.
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotOCR.OcrPlugin", true)]
// 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)]

View file

@ -21,12 +21,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core;
namespace GreenshotOfficePlugin { namespace GreenshotOfficePlugin {
/// <summary> /// <summary>
/// This is the OfficePlugin base code /// This is the OfficePlugin base code
/// </summary> /// </summary>
public class OfficePlugin : IGreenshotPlugin { [Plugin("Office", false)]
public class OfficePlugin : IGreenshotPlugin
{
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OfficePlugin)); private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OfficePlugin));
public void Dispose() { public void Dispose() {
@ -38,7 +41,7 @@ namespace GreenshotOfficePlugin {
// Do nothing // Do nothing
} }
public IEnumerable<IDestination> Destinations() { private IEnumerable<IDestination> Destinations() {
IDestination destination; IDestination destination;
try { try {
destination = new ExcelDestination(); destination = new ExcelDestination();
@ -86,21 +89,17 @@ namespace GreenshotOfficePlugin {
} }
} }
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns> /// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) { public bool Initialize() {
SimpleServiceProvider.Current.AddService(Destinations());
return true; return true;
} }
public virtual void Shutdown() { public void Shutdown() {
LOG.Debug("Office Plugin shutdown."); LOG.Debug("Office Plugin shutdown.");
} }

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to export images to Office applications")] [assembly: AssemblyDescription("A plugin to export images to Office applications")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotOfficePlugin.OfficePlugin", false)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -58,7 +58,7 @@ namespace GreenshotPhotobucketPlugin {
public bool ShowConfigDialog() { public bool ShowConfigDialog() {
SettingsForm settingsForm = null; SettingsForm settingsForm = null;
new PleaseWaitForm().ShowAndWait(PhotobucketPlugin.Attributes.Name, Language.GetString("photobucket", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Photobucket", Language.GetString("photobucket", LangKey.communication_wait),
delegate { delegate {
settingsForm = new SettingsForm(); settingsForm = new SettingsForm();
} }

View file

@ -37,7 +37,7 @@ namespace GreenshotPhotobucketPlugin {
/// </summary> /// </summary>
/// <param name="plugin"></param> /// <param name="plugin"></param>
/// <param name="albumPath">path to the album, null for default</param> /// <param name="albumPath">path to the album, null for default</param>
public PhotobucketDestination(PhotobucketPlugin plugin, string albumPath) { public PhotobucketDestination(PhotobucketPlugin plugin, string albumPath = null) {
_plugin = plugin; _plugin = plugin;
_albumPath = albumPath; _albumPath = albumPath;
} }

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -33,11 +32,10 @@ namespace GreenshotPhotobucketPlugin {
/// <summary> /// <summary>
/// This is the GreenshotPhotobucketPlugin base code /// This is the GreenshotPhotobucketPlugin base code
/// </summary> /// </summary>
[Plugin("Photobucket", true)]
public class PhotobucketPlugin : IGreenshotPlugin { public class PhotobucketPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PhotobucketPlugin)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PhotobucketPlugin));
private static PhotobucketConfiguration _config; private static PhotobucketConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources; private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig; private ToolStripMenuItem _itemPlugInConfig;
@ -46,32 +44,20 @@ namespace GreenshotPhotobucketPlugin {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected void Dispose(bool disposing)
if (disposing) { {
if (_itemPlugInConfig != null) { if (!disposing) return;
_itemPlugInConfig.Dispose(); if (_itemPlugInConfig == null) return;
_itemPlugInConfig = null; _itemPlugInConfig.Dispose();
} _itemPlugInConfig = null;
} }
}
public IEnumerable<IDestination> Destinations() {
yield return new PhotobucketDestination(this, null);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns> /// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) { public bool Initialize() {
_host = pluginHost; SimpleServiceProvider.Current.AddService<IDestination>(new PhotobucketDestination(this));
Attributes = myAttributes;
// Get configuration // Get configuration
_config = IniConfig.GetIniSection<PhotobucketConfiguration>(); _config = IniConfig.GetIniSection<PhotobucketConfiguration>();
@ -79,14 +65,13 @@ namespace GreenshotPhotobucketPlugin {
_itemPlugInConfig = new ToolStripMenuItem(Language.GetString("photobucket", LangKey.configure)) _itemPlugInConfig = new ToolStripMenuItem(Language.GetString("photobucket", LangKey.configure))
{ {
Tag = _host,
Image = (Image)_resources.GetObject("Photobucket") Image = (Image)_resources.GetObject("Photobucket")
}; };
_itemPlugInConfig.Click += delegate { _itemPlugInConfig.Click += delegate {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
}; };
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig); PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
return true; return true;
} }
@ -97,7 +82,7 @@ namespace GreenshotPhotobucketPlugin {
} }
} }
public virtual void Shutdown() { public void Shutdown() {
Log.Debug("Photobucket Plugin shutdown."); Log.Debug("Photobucket Plugin shutdown.");
Language.LanguageChanged -= OnLanguageChanged; Language.LanguageChanged -= OnLanguageChanged;
} }
@ -105,7 +90,7 @@ namespace GreenshotPhotobucketPlugin {
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
} }
@ -124,7 +109,7 @@ namespace GreenshotPhotobucketPlugin {
PhotobucketInfo photobucketInfo = null; PhotobucketInfo photobucketInfo = null;
// Run upload in the background // Run upload in the background
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("photobucket", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Photobucket", Language.GetString("photobucket", LangKey.communication_wait),
delegate { delegate {
photobucketInfo = PhotobucketUtils.UploadToPhotobucket(surfaceToUpload, outputSettings, albumPath, captureDetails.Title, filename); photobucketInfo = PhotobucketUtils.UploadToPhotobucket(surfaceToUpload, outputSettings, albumPath, captureDetails.Title, filename);
} }

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -28,8 +27,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to upload images to Photobucket")] [assembly: AssemblyDescription("A plugin to upload images to Photobucket")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotPhotobucketPlugin.PhotobucketPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -18,7 +18,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -32,11 +31,10 @@ namespace GreenshotPicasaPlugin {
/// <summary> /// <summary>
/// This is the Picasa base code /// This is the Picasa base code
/// </summary> /// </summary>
[Plugin("Picasa", true)]
public class PicasaPlugin : IGreenshotPlugin { public class PicasaPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PicasaPlugin)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PicasaPlugin));
private static PicasaConfiguration _config; private static PicasaConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources; private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInRoot; private ToolStripMenuItem _itemPlugInRoot;
@ -45,7 +43,7 @@ namespace GreenshotPicasaPlugin {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) { protected void Dispose(bool disposing) {
if (disposing) { if (disposing) {
if (_itemPlugInRoot != null) { if (_itemPlugInRoot != null) {
_itemPlugInRoot.Dispose(); _itemPlugInRoot.Dispose();
@ -54,23 +52,11 @@ namespace GreenshotPicasaPlugin {
} }
} }
public IEnumerable<IDestination> Destinations() {
yield return new PicasaDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary> /// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param> public bool Initialize() {
/// <param name="myAttributes">My own attributes</param> SimpleServiceProvider.Current.AddService<IDestination>(new PicasaDestination(this));
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
_host = pluginHost;
Attributes = myAttributes;
// Get configuration // Get configuration
_config = IniConfig.GetIniSection<PicasaConfiguration>(); _config = IniConfig.GetIniSection<PicasaConfiguration>();
@ -79,11 +65,10 @@ namespace GreenshotPicasaPlugin {
_itemPlugInRoot = new ToolStripMenuItem _itemPlugInRoot = new ToolStripMenuItem
{ {
Text = Language.GetString("picasa", LangKey.Configure), Text = Language.GetString("picasa", LangKey.Configure),
Tag = _host,
Image = (Image) _resources.GetObject("Picasa") Image = (Image) _resources.GetObject("Picasa")
}; };
_itemPlugInRoot.Click += ConfigMenuClick; _itemPlugInRoot.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInRoot); PluginUtils.AddToContextMenu(_itemPlugInRoot);
Language.LanguageChanged += OnLanguageChanged; Language.LanguageChanged += OnLanguageChanged;
return true; return true;
} }
@ -94,7 +79,7 @@ namespace GreenshotPicasaPlugin {
} }
} }
public virtual void Shutdown() { public void Shutdown() {
Log.Debug("Picasa Plugin shutdown."); Log.Debug("Picasa Plugin shutdown.");
Language.LanguageChanged -= OnLanguageChanged; Language.LanguageChanged -= OnLanguageChanged;
//host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened); //host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened);
@ -103,7 +88,7 @@ namespace GreenshotPicasaPlugin {
/// <summary> /// <summary>
/// Implementation of the IPlugin.Configure /// Implementation of the IPlugin.Configure
/// </summary> /// </summary>
public virtual void Configure() { public void Configure() {
_config.ShowConfigDialog(); _config.ShowConfigDialog();
} }
@ -115,7 +100,7 @@ namespace GreenshotPicasaPlugin {
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality); SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality);
try { try {
string url = null; string url = null;
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("picasa", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait("Picasa", Language.GetString("picasa", LangKey.communication_wait),
delegate delegate
{ {
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails)); string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plugin to upload images to Picasa")] [assembly: AssemblyDescription("A plugin to upload images to Picasa")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotPicasaPlugin.PicasaPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible. // 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. // If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -260,7 +260,7 @@ namespace GreenshotPlugin.Core {
location.Offset(-40, -10); location.Offset(-40, -10);
} }
// This prevents the problem that the context menu shows in the task-bar // This prevents the problem that the context menu shows in the task-bar
User32.SetForegroundWindow(PluginUtils.Host.NotifyIcon.ContextMenuStrip.Handle); User32.SetForegroundWindow(SimpleServiceProvider.Current.GetInstance<NotifyIcon>().ContextMenuStrip.Handle);
menu.Show(location); menu.Show(location);
menu.Focus(); menu.Focus();

View file

@ -52,16 +52,11 @@ namespace GreenshotPlugin.Core {
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private const int ExifOrientationId = 0x0112; private const int ExifOrientationId = 0x0112;
/// <summary> static ImageHelper()
/// This is a factory method to create a surface, set from the Greenshot main project
/// </summary>
public static Func<ISurface> SurfaceFactory { get; set; }
static ImageHelper()
{ {
StreamConverters["greenshot"] = (stream, s) => StreamConverters["greenshot"] = (stream, s) =>
{ {
var surface = SurfaceFactory(); var surface = SimpleServiceProvider.Current.GetInstance<Func<ISurface>>().Invoke();
return surface.GetImageForExport(); return surface.GetImageForExport();
}; };

View file

@ -45,14 +45,6 @@ namespace GreenshotPlugin.Core {
CoreConfig.PropertyChanged += OnIconSizeChanged; CoreConfig.PropertyChanged += OnIconSizeChanged;
} }
/// <summary>
/// Simple global property to get the Greenshot host
/// </summary>
public static IGreenshotHost Host {
get;
set;
}
/// <summary> /// <summary>
/// Clear icon cache /// Clear icon cache
/// </summary> /// </summary>
@ -220,11 +212,10 @@ namespace GreenshotPlugin.Core {
/// <summary> /// <summary>
/// Helper method to add a plugin MenuItem to the Greenshot context menu /// Helper method to add a plugin MenuItem to the Greenshot context menu
/// </summary> /// </summary>
/// <param name="host">IGreenshotHost</param>
/// <param name="item">ToolStripMenuItem</param> /// <param name="item">ToolStripMenuItem</param>
public static void AddToContextMenu(IGreenshotHost host, ToolStripMenuItem item) { public static void AddToContextMenu(ToolStripMenuItem item) {
// Here we can hang ourselves to the main context menu! // Here we can hang ourselves to the main context menu!
ContextMenuStrip contextMenu = host.MainMenu; var contextMenu = SimpleServiceProvider.Current.GetInstance<ContextMenuStrip>();
bool addedItem = false; bool addedItem = false;
// Try to find a separator, so we insert ourselves after it // Try to find a separator, so we insert ourselves after it

View file

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using GreenshotPlugin.Interfaces;
namespace GreenshotPlugin.Core
{
/// <summary>
/// A really cheap and simple DI system
/// </summary>
public class SimpleServiceProvider : IServiceLocator
{
private readonly Dictionary<Type, List<object>> _services = new Dictionary<Type, List<object>>();
public static IServiceLocator Current { get; } = new SimpleServiceProvider();
public IEnumerable<TService> GetAllInstances<TService>()
{
var typeOfService = typeof(TService);
if (!_services.TryGetValue(typeOfService, out var results))
{
yield break;
}
foreach (TService result in results)
{
yield return result;
}
}
public TService GetInstance<TService>()
{
return GetAllInstances<TService>().SingleOrDefault();
}
public void AddService<TService>(IEnumerable<TService> services)
{
var serviceType = typeof(TService);
if (!_services.TryGetValue(serviceType, out var currentServices))
{
currentServices = new List<object>();
_services.Add(serviceType, currentServices);
}
foreach (var service in services)
{
currentServices.Add(service);
}
}
public void AddService<TService>(params TService[] services)
{
AddService(services.AsEnumerable());
}
}
}

View file

@ -0,0 +1,14 @@
using System.Collections.Generic;
namespace GreenshotPlugin.Interfaces
{
public interface IServiceLocator
{
IEnumerable<TService> GetAllInstances<TService>();
TService GetInstance<TService>();
void AddService<TService>(params TService[] services);
void AddService<TService>(IEnumerable<TService> services);
}
}

View file

@ -0,0 +1,4 @@
namespace Greenshot.Plugin
{
public delegate void HotKeyHandler();
}

View file

@ -0,0 +1,48 @@
using System.Drawing;
namespace Greenshot.Plugin
{
/// <summary>
/// This interface is the GreenshotPluginHost, that which "Hosts" the plugin.
/// For Greenshot this is implemented in the PluginHelper
/// </summary>
public interface IGreenshotHost {
/// <summary>
/// Create a Thumbnail
/// </summary>
/// <param name="image">Image of which we need a Thumbnail</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns>Image with Thumbnail</returns>
Image GetThumbnail(Image image, int width, int height);
/// <summary>
/// Export a surface to the destination with has the supplied designation
/// </summary>
/// <param name="manuallyInitiated"></param>
/// <param name="designation"></param>
/// <param name="surface"></param>
/// <param name="captureDetails"></param>
ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails);
/// <summary>
/// Make region capture with specified Handler
/// </summary>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
/// <param name="destination">IDestination destination</param>
void CaptureRegion(bool captureMouseCursor, IDestination destination);
/// <summary>
/// Use the supplied capture, and handle it as if it's captured.
/// </summary>
/// <param name="captureToImport">ICapture to import</param>
void ImportCapture(ICapture captureToImport);
/// <summary>
/// Use the supplied image, and ICapture a capture object for it
/// </summary>
/// <param name="imageToCapture">Image to create capture for</param>
/// <returns>ICapture</returns>
ICapture GetCapture(Image imageToCapture);
}
}

View file

@ -0,0 +1,25 @@
using System;
namespace Greenshot.Plugin
{
/// <summary>
/// This defines the plugin
/// </summary>
public interface IGreenshotPlugin : IDisposable {
/// <summary>
/// Is called after the plugin is instantiated, the Plugin should keep a copy of the host and pluginAttribute.
/// </summary>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
bool Initialize();
/// <summary>
/// Unload of the plugin
/// </summary>
void Shutdown();
/// <summary>
/// Open the Configuration Form, will/should not be called before handshaking is done
/// </summary>
void Configure();
}
}

View file

@ -19,17 +19,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Greenshot.Plugin; using System;
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following namespace Greenshot.Plugin {
// set of attributes. Change these attribute values to modify the information [Serializable]
// associated with an assembly. [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
// The PluginAttribute describes the "entryType" and if the plugin is configurable public sealed class PluginAttribute : Attribute, IComparable {
[assembly: Plugin("GreenshotJiraPlugin.JiraPlugin", true)] public string Name {
get;
set;
}
// This sets the default COM visibility of types in the assembly to invisible. public bool Configurable {
// If you need to expose a type to COM, use [ComVisible(true)] on that type. get;
[assembly: ComVisible(false)] private set;
}
public PluginAttribute(string name, bool configurable)
{
Name = name;
Configurable = configurable;
}
public int CompareTo(object obj) {
if (obj is PluginAttribute other) {
return string.Compare(Name, other.Name, StringComparison.Ordinal);
}
throw new ArgumentException("object is not a PluginAttribute");
}
}
}

View file

@ -1,267 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2020 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/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.Windows.Forms;
using GreenshotPlugin.Core;
using Greenshot.IniFile;
using GreenshotPlugin.Effects;
namespace Greenshot.Plugin {
[Serializable]
[AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
public sealed class PluginAttribute : Attribute, IComparable {
public string Name {
get;
set;
}
public string CreatedBy {
get;
set;
}
public string Version {
get;
set;
}
public string EntryType {
get;
private set;
}
public bool Configurable {
get;
private set;
}
public string DllFile {
get;
set;
}
public PluginAttribute(string entryType, bool configurable) {
EntryType = entryType;
Configurable = configurable;
}
public int CompareTo(object obj) {
if (obj is PluginAttribute other) {
return Name.CompareTo(other.Name);
}
throw new ArgumentException("object is not a PluginAttribute");
}
}
// Delegates for hooking up events.
public delegate void HotKeyHandler();
public class SurfaceOutputSettings {
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private bool _reduceColors;
private bool _disableReduceColors;
public SurfaceOutputSettings() {
_disableReduceColors = false;
Format = CoreConfig.OutputFileFormat;
JPGQuality = CoreConfig.OutputFileJpegQuality;
ReduceColors = CoreConfig.OutputFileReduceColors;
}
public SurfaceOutputSettings(OutputFormat format) : this() {
Format = format;
}
public SurfaceOutputSettings(OutputFormat format, int quality) : this(format) {
JPGQuality = quality;
}
public SurfaceOutputSettings(OutputFormat format, int quality, bool reduceColors) : this(format, quality) {
ReduceColors = reduceColors;
}
/// <summary>
/// BUG-2056 reported a logical issue, using greenshot format as the default causes issues with the external commands.
/// </summary>
/// <returns>this for fluent API usage</returns>
public SurfaceOutputSettings PreventGreenshotFormat()
{
// If OutputFormat is Greenshot, use PNG instead.
if (Format == OutputFormat.greenshot)
{
Format = OutputFormat.png;
}
return this;
}
public OutputFormat Format {
get;
set;
}
public int JPGQuality {
get;
set;
}
public bool SaveBackgroundOnly {
get;
set;
}
public List<IEffect> Effects { get; } = new List<IEffect>();
public bool ReduceColors {
get {
// Fix for Bug #3468436, force quantizing when output format is gif as this has only 256 colors!
if (OutputFormat.gif.Equals(Format)) {
return true;
}
return _reduceColors;
}
set {
_reduceColors = value;
}
}
/// <summary>
/// Disable the reduce colors option, this overrules the enabling
/// </summary>
public bool DisableReduceColors {
get {
return _disableReduceColors;
}
set {
// Quantizing os needed when output format is gif as this has only 256 colors!
if (!OutputFormat.gif.Equals(Format)) {
_disableReduceColors = value;
}
}
}
}
/// <summary>
/// This interface is the GreenshotPluginHost, that which "Hosts" the plugin.
/// For Greenshot this is implmented in the PluginHelper
/// </summary>
public interface IGreenshotHost {
ContextMenuStrip MainMenu {
get;
}
// This is a reference to the MainForm, can be used for Invoking on the UI thread.
Form GreenshotForm {
get;
}
NotifyIcon NotifyIcon {
get;
}
/// <summary>
/// Create a Thumbnail
/// </summary>
/// <param name="image">Image of which we need a Thumbnail</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns>Image with Thumbnail</returns>
Image GetThumbnail(Image image, int width, int height);
/// <summary>
/// List of available plugins with their PluginAttributes
/// This can be usefull for a plugin manager plugin...
/// </summary>
IDictionary<PluginAttribute, IGreenshotPlugin> Plugins {
get;
}
/// <summary>
/// Get a destination by it's designation
/// </summary>
/// <param name="designation"></param>
/// <returns>IDestination</returns>
IDestination GetDestination(string designation);
/// <summary>
/// Get a list of all available destinations
/// </summary>
/// <returns>List of IDestination</returns>
List<IDestination> GetAllDestinations();
/// <summary>
/// Export a surface to the destination with has the supplied designation
/// </summary>
/// <param name="manuallyInitiated"></param>
/// <param name="designation"></param>
/// <param name="surface"></param>
/// <param name="captureDetails"></param>
ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails);
/// <summary>
/// Make region capture with specified Handler
/// </summary>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
/// <param name="destination">IDestination destination</param>
void CaptureRegion(bool captureMouseCursor, IDestination destination);
/// <summary>
/// Use the supplied capture, and handle it as if it's captured.
/// </summary>
/// <param name="captureToImport">ICapture to import</param>
void ImportCapture(ICapture captureToImport);
/// <summary>
/// Use the supplied image, and ICapture a capture object for it
/// </summary>
/// <param name="imageToCapture">Image to create capture for</param>
/// <returns>ICapture</returns>
ICapture GetCapture(Image imageToCapture);
}
public interface IGreenshotPlugin : IDisposable {
/// <summary>
/// Is called after the plugin is instanciated, the Plugin should keep a copy of the host and pluginAttribute.
/// </summary>
/// <param name="host">The IPluginHost that will be hosting the plugin</param>
/// <param name="pluginAttribute">The PluginAttribute for the actual plugin</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
bool Initialize(IGreenshotHost host, PluginAttribute pluginAttribute);
/// <summary>
/// Unload of the plugin
/// </summary>
void Shutdown();
/// <summary>
/// Open the Configuration Form, will/should not be called before handshaking is done
/// </summary>
void Configure();
/// <summary>
/// Return IDestination's, if the plugin wants to
/// </summary>
IEnumerable<IDestination> Destinations();
/// <summary>
/// Return IProcessor's, if the plugin wants to
/// </summary>
IEnumerable<IProcessor> Processors();
}
}

View file

@ -0,0 +1,91 @@
using System.Collections.Generic;
using Greenshot.IniFile;
using GreenshotPlugin.Core;
using GreenshotPlugin.Effects;
namespace Greenshot.Plugin
{
public class SurfaceOutputSettings {
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private bool _reduceColors;
private bool _disableReduceColors;
public SurfaceOutputSettings() {
_disableReduceColors = false;
Format = CoreConfig.OutputFileFormat;
JPGQuality = CoreConfig.OutputFileJpegQuality;
ReduceColors = CoreConfig.OutputFileReduceColors;
}
public SurfaceOutputSettings(OutputFormat format) : this() {
Format = format;
}
public SurfaceOutputSettings(OutputFormat format, int quality) : this(format) {
JPGQuality = quality;
}
public SurfaceOutputSettings(OutputFormat format, int quality, bool reduceColors) : this(format, quality) {
ReduceColors = reduceColors;
}
/// <summary>
/// BUG-2056 reported a logical issue, using greenshot format as the default causes issues with the external commands.
/// </summary>
/// <returns>this for fluent API usage</returns>
public SurfaceOutputSettings PreventGreenshotFormat()
{
// If OutputFormat is Greenshot, use PNG instead.
if (Format == OutputFormat.greenshot)
{
Format = OutputFormat.png;
}
return this;
}
public OutputFormat Format {
get;
set;
}
public int JPGQuality {
get;
set;
}
public bool SaveBackgroundOnly {
get;
set;
}
public List<IEffect> Effects { get; } = new List<IEffect>();
public bool ReduceColors {
get {
// Fix for Bug #3468436, force quantizing when output format is gif as this has only 256 colors!
if (OutputFormat.gif.Equals(Format)) {
return true;
}
return _reduceColors;
}
set {
_reduceColors = value;
}
}
/// <summary>
/// Disable the reduce colors option, this overrules the enabling
/// </summary>
public bool DisableReduceColors {
get {
return _disableReduceColors;
}
set {
// Quantizing os needed when output format is gif as this has only 256 colors!
if (!OutputFormat.gif.Equals(Format)) {
_disableReduceColors = value;
}
}
}
}
}

View file

@ -597,7 +597,10 @@ namespace Greenshot.Interop {
if (destinationName == null) { if (destinationName == null) {
destinationName = _interceptType.FullName; destinationName = _interceptType.FullName;
} }
DialogResult result = MessageBox.Show(PluginUtils.Host.GreenshotForm, Language.GetFormattedString("com_rejected", destinationName), Language.GetString("com_rejected_title"), MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
var form = SimpleServiceProvider.Current.GetInstance<Form>();
DialogResult result = MessageBox.Show(form, Language.GetFormattedString("com_rejected", destinationName), Language.GetString("com_rejected_title"), MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
if (result == DialogResult.OK) { if (result == DialogResult.OK) {
continue; continue;
} }

View file

@ -7,9 +7,6 @@ using System.Runtime.InteropServices;
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyDescription("A plug-in for Windows 10 only functionality")] [assembly: AssemblyDescription("A plug-in for Windows 10 only functionality")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: Plugin("GreenshotWin10Plugin.Win10Plugin", false)]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.

View file

@ -29,6 +29,7 @@ namespace GreenshotWin10Plugin
/// <summary> /// <summary>
/// This is the Win10Plugin /// This is the Win10Plugin
/// </summary> /// </summary>
[Plugin("Win10", false)]
public class Win10Plugin : IGreenshotPlugin public class Win10Plugin : IGreenshotPlugin
{ {
public void Dispose() public void Dispose()
@ -52,7 +53,7 @@ namespace GreenshotWin10Plugin
/// yields the windows 10 destinations if Windows 10 is detected /// yields the windows 10 destinations if Windows 10 is detected
/// </summary> /// </summary>
/// <returns>IEnumerable with the destinations</returns> /// <returns>IEnumerable with the destinations</returns>
public IEnumerable<IDestination> Destinations() private IEnumerable<IDestination> Destinations()
{ {
if (!WindowsVersion.IsWindows10OrLater) if (!WindowsVersion.IsWindows10OrLater)
{ {
@ -62,19 +63,13 @@ namespace GreenshotWin10Plugin
yield return new Win10ShareDestination(); yield return new Win10ShareDestination();
} }
public IEnumerable<IProcessor> Processors() /// <summary>
{
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize /// Implementation of the IGreenshotPlugin.Initialize
/// </summary> /// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns> /// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) public bool Initialize()
{ {
SimpleServiceProvider.Current.AddService(Destinations());
return true; return true;
} }