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>
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
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)) {
continue;
}

View file

@ -223,19 +223,18 @@ namespace Greenshot {
using Pen cbBorderPen = new Pen(SystemColors.ActiveBorder);
// Loop over all items in the propertiesToolStrip
foreach (ToolStripItem item in propertiesToolStrip.Items) {
ToolStripComboBox cb = item as ToolStripComboBox;
var cb = item as ToolStripComboBox;
// Only ToolStripComboBox that are visible
if (cb == null || !cb.Visible) {
continue;
}
// Calculate the rectangle
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);
if (cb.ComboBox == null) continue;
// Draw the rectangle
e.Graphics.DrawRectangle(cbBorderPen, r);
}
// Calculate the rectangle
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();
}
private void AboutToolStripMenuItemClick(object sender, EventArgs e) {
MainForm.Instance.ShowAbout();
private void AboutToolStripMenuItemClick(object sender, EventArgs e)
{
var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
mainForm.ShowAbout();
}
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) {
@ -1251,7 +1253,8 @@ namespace Greenshot {
private void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e) {
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) {

View file

@ -302,7 +302,6 @@ namespace Greenshot {
}
private static MainForm _instance;
public static MainForm Instance => _instance;
private readonly CopyData _copyData;
@ -315,13 +314,18 @@ namespace Greenshot {
// Timer for the double click test
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;
// 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.
@ -333,7 +337,12 @@ namespace Greenshot {
ex.Data.Add("more information here", "http://support.microsoft.com/kb/943140");
throw;
}
// Make the main menu available
SimpleServiceProvider.Current.AddService(contextMenu);
notifyIcon.Icon = GreenshotResources.getGreenshotIcon();
// Make the notify icon available
SimpleServiceProvider.Current.AddService(notifyIcon);
// Disable access to the settings, for feature #3521446
contextmenu_settings.Visible = !_conf.DisableSettings;
@ -347,9 +356,9 @@ namespace Greenshot {
UpdateUi();
// This forces the registration of all destinations inside Greenshot itself.
DestinationHelper.GetAllDestinations();
DestinationHelper.RegisterInternalDestinations();
// This forces the registration of all processors inside Greenshot itself.
ProcessorHelper.GetAllProcessors();
ProcessorHelper.RegisterInternalProcessors();
// Load all the plugins
PluginHelper.Instance.LoadPlugins();
@ -645,7 +654,8 @@ namespace Greenshot {
bool success = false;
var warningTitle = Language.GetString(LangKey.warning);
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) {
LOG.DebugFormat("Re-trying to register hotkeys");
HotkeyControl.UnregisterHotkeys();

View file

@ -25,6 +25,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Greenshot.Configuration;
@ -191,37 +192,38 @@ namespace Greenshot {
}
private void DisplayPluginTab() {
if (!PluginHelper.Instance.HasPlugins()) {
tabcontrol.TabPages.Remove(tab_plugins);
} else {
// Draw the Plugin listview
listview_plugins.BeginUpdate();
listview_plugins.Items.Clear();
listview_plugins.Columns.Clear();
string[] columns = {
Language.GetString("settings_plugins_name"),
Language.GetString("settings_plugins_version"),
Language.GetString("settings_plugins_createdby"),
Language.GetString("settings_plugins_dllpath")};
foreach (string column in columns) {
listview_plugins.Columns.Add(column);
}
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;
if (!SimpleServiceProvider.Current.GetAllInstances<IGreenshotPlugin>().Any())
{
tabcontrol.TabPages.Remove(tab_plugins);
return;
}
// Draw the Plugin listview
listview_plugins.BeginUpdate();
listview_plugins.Items.Clear();
listview_plugins.Columns.Clear();
string[] columns = {
Language.GetString("settings_plugins_name"),
Language.GetString("settings_plugins_version"),
Language.GetString("settings_plugins_createdby"),
Language.GetString("settings_plugins_dllpath")};
foreach (string column in columns) {
listview_plugins.Columns.Add(column);
}
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>
@ -333,9 +335,8 @@ namespace Greenshot {
listview_destinations.Items.Clear();
listview_destinations.ListViewItemSorter = new ListviewWithDestinationComparer();
ImageList imageList = new ImageList();
imageList.ImageSize = coreConfiguration.ScaledIconSize;
listview_destinations.SmallImageList = imageList;
ImageList imageList = new ImageList {ImageSize = coreConfiguration.ScaledIconSize};
listview_destinations.SmallImageList = imageList;
int imageNr = -1;
foreach (IDestination currentDestination in DestinationHelper.GetAllDestinations()) {
Image destinationImage = currentDestination.DisplayIcon;
@ -502,7 +503,8 @@ namespace Greenshot {
MainForm.RegisterHotkeys();
// 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;
} else {
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
// forcefully removes the balloon!
if (!CoreConfig.HideTrayicon) {
MainForm.Instance.NotifyIcon.Visible = false;
MainForm.Instance.NotifyIcon.Visible = true;
if (!CoreConfig.HideTrayicon)
{
var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
notifyIcon.Visible = false;
notifyIcon.Visible = true;
}
Log.Debug($"Capturing with mode {_captureMode} and using Cursor {_captureMouseCursor}");
_capture.CaptureDetails.CaptureMode = _captureMode;
@ -512,7 +514,8 @@ namespace Greenshot.Helpers {
/// <param name="sender"></param>
/// <param name="e"></param>
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");
RemoveEventHandler(sender, e);
return;
@ -535,9 +538,10 @@ namespace Greenshot.Helpers {
}
private void RemoveEventHandler(object sender, EventArgs e) {
MainForm.Instance.NotifyIcon.BalloonTipClicked -= OpenCaptureOnClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= RemoveEventHandler;
MainForm.Instance.NotifyIcon.Tag = null;
var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
notifyIcon.BalloonTipClicked -= OpenCaptureOnClick;
notifyIcon.BalloonTipClosed -= RemoveEventHandler;
notifyIcon.Tag = null;
}
/// <summary>
@ -549,25 +553,22 @@ namespace Greenshot.Helpers {
if (string.IsNullOrEmpty(eventArgs?.Message)) {
return;
}
if (MainForm.Instance == null)
{
return;
}
var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
switch (eventArgs.MessageType) {
case SurfaceMessageTyp.Error:
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Error);
notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Error);
break;
case SurfaceMessageTyp.Info:
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
break;
case SurfaceMessageTyp.FileSaved:
case SurfaceMessageTyp.UploadedUri:
// Show a balloon and register an event handler to open the "capture" for if someone clicks the balloon.
MainForm.Instance.NotifyIcon.BalloonTipClicked += OpenCaptureOnClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += RemoveEventHandler;
notifyIcon.BalloonTipClicked += OpenCaptureOnClick;
notifyIcon.BalloonTipClosed += RemoveEventHandler;
// Store for later usage
MainForm.Instance.NotifyIcon.Tag = eventArgs;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
notifyIcon.Tag = eventArgs;
notifyIcon.ShowBalloonTip(10000, "Greenshot", eventArgs.Message, ToolTipIcon.Info);
break;
}
}
@ -609,12 +610,11 @@ namespace Greenshot.Helpers {
}
// Let the processors do their job
foreach(IProcessor processor in ProcessorHelper.GetAllProcessors()) {
if (processor.isActive) {
Log.InfoFormat("Calling processor {0}", processor.Description);
processor.ProcessCapture(surface, _capture.CaptureDetails);
}
}
foreach(var processor in SimpleServiceProvider.Current.GetAllInstances<IProcessor>()) {
if (!processor.isActive) continue;
Log.InfoFormat("Calling processor {0}", processor.Description);
processor.ProcessCapture(surface, _capture.CaptureDetails);
}
// As the surfaces copies the reference to the image, make sure the image is not being disposed (a trick to save memory)
_capture.Image = null;
@ -915,7 +915,8 @@ namespace Greenshot.Helpers {
// Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
// Workaround for changed DPI settings in Windows 7
using (Graphics graphics = Graphics.FromHwnd(MainForm.Instance.Handle)) {
var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
using (Graphics graphics = Graphics.FromHwnd(mainForm.Handle)) {
_capture.CaptureDetails.DpiX = graphics.DpiX;
_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
DialogResult result;
try {
result = captureForm.ShowDialog(MainForm.Instance);
var mainForm = SimpleServiceProvider.Current.GetInstance<MainForm>();
result = captureForm.ShowDialog(mainForm);
} finally {
captureForm.Hide();
}

View file

@ -18,9 +18,10 @@
* 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.Linq;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.IniFile;
@ -32,79 +33,47 @@ namespace Greenshot.Helpers {
/// </summary>
public static class 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>();
/// Initialize the destinations
static DestinationHelper() {
/// <summary>
/// Initialize the internal destinations
/// </summary>
public static void RegisterInternalDestinations() {
foreach(Type destinationType in InterfaceUtils.GetSubclassesOf(typeof(IDestination),true)) {
// Only take our own
if (!"Greenshot.Destinations".Equals(destinationType.Namespace)) {
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>
/// Register your destination here, if it doesn't come from a plugin and needs to be available
/// </summary>
/// <param name="destination"></param>
public static void RegisterDestination(IDestination destination) {
if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) {
// don't test the key, an exception should happen wenn it's not unique
RegisteredDestinations.Add(destination.Designation, destination);
}
if (destinationType.IsAbstract) continue;
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);
SimpleServiceProvider.Current.AddService(destination);
} else {
Log.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation);
}
}
}
/// <summary>
/// Method to get all the destinations from the plugins
/// </summary>
/// <returns>List of IDestination</returns>
private static List<IDestination> GetPluginDestinations() {
List<IDestination> destinations = new List<IDestination>();
foreach (PluginAttribute pluginAttribute in PluginHelper.Instance.Plugins.Keys) {
IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute];
try {
foreach (IDestination destination in plugin.Destinations()) {
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;
public static IEnumerable<IDestination> GetAllDestinations()
{
return SimpleServiceProvider.Current.GetAllInstances<IDestination>()
.Where(destination => destination.IsActive)
.Where(destination => CoreConfig.ExcludeDestinations == null ||
!CoreConfig.ExcludeDestinations.Contains(destination.Designation)).OrderBy(p => p.Priority).ThenBy(p => p.Description);
}
/// <summary>
@ -116,10 +85,7 @@ namespace Greenshot.Helpers {
if (designation == null) {
return null;
}
if (RegisteredDestinations.ContainsKey(designation)) {
return RegisteredDestinations[designation];
}
foreach (IDestination destination in GetPluginDestinations()) {
foreach (IDestination destination in GetAllDestinations()) {
if (designation.Equals(destination.Designation)) {
return destination;
}

View file

@ -22,6 +22,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
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 ApplicationPath = Path.GetDirectoryName(Application.ExecutablePath);
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();
private PluginHelper() {
PluginUtils.Host = this;
}
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) {
public void Shutdown() {
foreach(var plugin in SimpleServiceProvider.Current.GetAllInstances<IGreenshotPlugin>()) {
plugin.Shutdown();
plugin.Dispose();
}
plugins.Clear();
}
// Add plugins to the Listview
public void FillListview(ListView listview) {
foreach(var pluginAttribute in plugins.Keys) {
/// <summary>
/// Add plugins to the ListView
/// </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)
{
Tag = pluginAttribute
};
item.SubItems.Add(pluginAttribute.Version);
item.SubItems.Add(pluginAttribute.CreatedBy);
item.SubItems.Add(pluginAttribute.DllFile);
listview.Items.Add(item);
var assembly = plugin.GetType().Assembly;
var company = assembly.GetCustomAttribute<AssemblyCompanyAttribute>();
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) {
if (listview.SelectedItems.Count <= 0)
public bool IsSelectedItemConfigurable(ListView listView) {
if (listView.SelectedItems.Count <= 0)
{
return false;
}
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
var pluginAttribute = (PluginAttribute)listView.SelectedItems[0].Tag;
return pluginAttribute != null && pluginAttribute.Configurable;
}
public void ConfigureSelectedItem(ListView listview) {
if (listview.SelectedItems.Count <= 0)
public void ConfigureSelectedItem(ListView listView) {
if (listView.SelectedItems.Count <= 0)
{
return;
}
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
var pluginAttribute = (PluginAttribute)listView.SelectedItems[0].Tag;
if (pluginAttribute == null)
{
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>
@ -121,17 +118,6 @@ namespace Greenshot.Helpers {
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) {
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.
/// </summary>
/// <param name="captureToImport">Image to handle</param>
public void ImportCapture(ICapture captureToImport) {
MainForm.Instance.BeginInvoke((MethodInvoker)delegate {
public void ImportCapture(ICapture captureToImport)
{
var mainForm = SimpleServiceProvider.Current.GetInstance<Form>();
mainForm.BeginInvoke((MethodInvoker)delegate {
CaptureHelper.ImportCapture(captureToImport);
});
}
@ -171,49 +159,27 @@ namespace Greenshot.Helpers {
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) {
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>
/// <summary>
/// Private helper to find the plugins in the path
/// </summary>
/// <param name="pluginFiles"></param>
/// <param name="path"></param>
private void FindPluginsOnPath(List<string> pluginFiles, string path) {
if (Directory.Exists(path)) {
try {
foreach (string pluginFile in Directory.GetFiles(path, "*Plugin.dll", SearchOption.AllDirectories)) {
pluginFiles.Add(pluginFile);
}
} catch (UnauthorizedAccessException) {
} catch (Exception ex) {
Log.Error("Error loading plugin: ", ex);
}
}
}
/// <param name="path">string</param>
/// <returns>IEnumerable with plugin files</returns>
private IEnumerable<string> FindPluginsOnPath(string path)
{
var pluginFiles = Enumerable.Empty<string>();
if (!Directory.Exists(path)) return pluginFiles;
try
{
pluginFiles = Directory.GetFiles(path, "*Plugin.dll", SearchOption.AllDirectories);
} catch (Exception ex) {
Log.Error("Error loading plugin: ", ex);
}
return pluginFiles;
}
/// <summary>
/// Load the plugins
@ -222,107 +188,54 @@ namespace Greenshot.Helpers {
List<string> pluginFiles = new List<string>();
if (IniConfig.IsPortable) {
FindPluginsOnPath(pluginFiles, PafPath);
pluginFiles.AddRange(FindPluginsOnPath(PafPath));
} else {
FindPluginsOnPath(pluginFiles, PluginPath);
FindPluginsOnPath(pluginFiles, ApplicationPath);
pluginFiles.AddRange(FindPluginsOnPath(PluginPath));
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
foreach (string pluginFile in pluginFiles) {
//LOG.DebugFormat("Checking the following file for plugins: {0}", pluginFile);
try {
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)) {
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
PluginAttribute checkPluginAttribute = null;
if (tmpAttributes.ContainsKey(pluginAttribute.Name)) {
checkPluginAttribute = tmpAttributes[pluginAttribute.Name];
}
var assemblyName = assembly.GetName().Name;
if (checkPluginAttribute != null) {
Log.WarnFormat("Duplicate plugin {0} found", pluginAttribute.Name);
if (IsNewer(pluginAttribute.Version, checkPluginAttribute.Version)) {
// Found is newer
tmpAttributes[pluginAttribute.Name] = pluginAttribute;
tmpAssemblies[pluginAttribute.Name] = assembly;
Log.InfoFormat("Loading the newer plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
} else {
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);
}
continue;
}
if (CoreConfig.ExcludePlugins != null && CoreConfig.ExcludePlugins.Contains(pluginAttribute.Name)) {
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);
continue;
}
if (CoreConfig.IncludePlugins != null && CoreConfig.IncludePlugins.Count > 0 && !CoreConfig.IncludePlugins.Contains(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);
continue;
}
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;
} else {
Log.ErrorFormat("Can't find the needed Plugin Attribute ({0}) in the assembly of the file \"{1}\", skipping this file.", typeof(PluginAttribute), pluginFile);
}
} 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);
}
var pluginEntryName = $"{assemblyName}.{assemblyName.Replace("Greenshot", string.Empty)}";
var pluginEntryType = assembly.GetType(pluginEntryName, false, true);
var pluginAttribute = pluginEntryType.GetCustomAttribute<PluginAttribute>();
if (CoreConfig.ExcludePlugins != null && CoreConfig.ExcludePlugins.Contains(pluginAttribute.Name))
{
Log.WarnFormat("Exclude list: {0}", string.Join(",", CoreConfig.ExcludePlugins));
Log.WarnFormat("Skipping the excluded plugin {0} with version {1} from {2}", pluginAttribute.Name, assembly.GetName().Version, pluginFile);
continue;
}
IGreenshotPlugin plugin = (IGreenshotPlugin)Activator.CreateInstance(pluginEntryType);
if (plugin != null)
{
if (plugin.Initialize())
{
SimpleServiceProvider.Current.AddService(plugin);
}
else
{
Log.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name);
}
}
else
{
Log.ErrorFormat("Can't create an instance of {0} from \"{1}\"", assembly.GetName().Name + ".GreenshotPlugin", pluginFile);
}
}
catch (Exception e)
{
Log.ErrorFormat("Can't load Plugin: {0}", pluginFile);
Log.Error(e);
}
}
}
}

View file

@ -31,108 +31,35 @@ namespace Greenshot.Helpers {
/// </summary>
public static class ProcessorHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(ProcessorHelper));
private static readonly Dictionary<string, IProcessor> RegisteredProcessors = new Dictionary<string, IProcessor>();
/// Initialize the Processors
static ProcessorHelper() {
foreach(Type ProcessorType in InterfaceUtils.GetSubclassesOf(typeof(IProcessor),true)) {
/// <summary>
/// Register the internal processors
/// </summary>
public static void RegisterInternalProcessors() {
foreach(Type processorType in InterfaceUtils.GetSubclassesOf(typeof(IProcessor),true)) {
// Only take our own
if (!"Greenshot.Processors".Equals(ProcessorType.Namespace)) {
if (!"Greenshot.Processors".Equals(processorType.Namespace)) {
continue;
}
try {
if (!ProcessorType.IsAbstract) {
IProcessor Processor;
if (!processorType.IsAbstract) {
IProcessor processor;
try {
Processor = (IProcessor)Activator.CreateInstance(ProcessorType);
processor = (IProcessor)Activator.CreateInstance(processorType);
} catch (Exception e) {
LOG.ErrorFormat("Can't create instance of {0}", ProcessorType);
LOG.ErrorFormat("Can't create instance of {0}", processorType);
LOG.Error(e);
continue;
}
if (Processor.isActive) {
LOG.DebugFormat("Found Processor {0} with designation {1}", ProcessorType.Name, Processor.Designation);
RegisterProcessor(Processor);
if (processor.isActive) {
LOG.DebugFormat("Found Processor {0} with designation {1}", processorType.Name, processor.Designation);
SimpleServiceProvider.Current.AddService(processor);
} 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) {
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);
LOG.ErrorFormat("Error loading processor {0}, message: ", processorType.FullName, ex.Message);
}
}
}

View file

@ -34,7 +34,7 @@ namespace Greenshot.Helpers
/// </summary>
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 _resourceName;
private Mutex _applicationMutex;
@ -82,13 +82,13 @@ namespace Greenshot.Helpers
{
// Added Mutex Security, hopefully this prevents the UnauthorizedAccessException more gracefully
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var mutexsecurity = new MutexSecurity();
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow));
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny));
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny));
var mutexSecurity = new MutexSecurity();
mutexSecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow));
mutexSecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny));
mutexSecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny));
// 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
if (!createdNew && !_applicationMutex.WaitOne(100, false))
{

View file

@ -88,9 +88,11 @@ namespace Greenshot.Experimental {
_latestGreenshot = null;
ProcessRssInfo(currentVersion);
if (_latestGreenshot != null) {
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info);
var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
notifyIcon.BalloonTipClicked += HandleBalloonTipClick;
notifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
notifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info);
}
} catch (Exception 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) {
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
var notifyIcon = SimpleServiceProvider.Current.GetInstance<NotifyIcon>();
notifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
notifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
}
private static void HandleBalloonTipClick(object sender, EventArgs e) {

View file

@ -69,14 +69,14 @@
<h2>Een schermopname maken</h2>
<p>
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:
</p>
<a name="capture-region"></a>
<h3>Interactief kader <kbd>Print</kbd></h3>
<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.
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
@ -115,7 +115,7 @@
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
<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,
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.
@ -168,15 +168,15 @@
<p>
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
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>
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.
Laat de muisknop los als de vorm van de juiste afmetingen is.
</p>
<p>
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,
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.
@ -188,7 +188,7 @@
<p class="hint">
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 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.
</p>
<p class="hint">
@ -202,8 +202,8 @@
<p>
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
en typ de tekst.</br>
Dubbelklik een bestaande tekst om deze te bewerken.</br>
en typ de tekst.<br/>
Dubbelklik een bestaande tekst om deze te bewerken.<br/>
Gebruik <kbd>Return</kbd> of <kbd>Enter</kbd> als u klaar bent met bewerken.
</p>
<p class="hint">
@ -215,7 +215,7 @@
<h3>Markeren</h3>
<p>
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
in de gereedschapsbalk:
</p>
@ -231,8 +231,8 @@
<h3>Maskeren</h3>
<p>
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>
De functie Maskeren <kbd>O</kbd> gebruikt u net als het <a href="#editor-highlight">Markeren</a>.</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/>
Beschikbare opties voor Maskeren zijn:
</p>
@ -245,7 +245,7 @@
* 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,
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.
</p>
@ -262,9 +262,9 @@
<h3>Schermopname bijsnijden</h3>
<p>
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.
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>.
U kunt het bijsnijden afbreken met de toets <kbd>ESC</kbd>.
@ -294,7 +294,7 @@
<p>
Als u regelmatig dezelfde elementen toepast in de bewerking van uw schermopnamen
(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
voor later gebruik. <em>Objecten laden</em> past deze eerder opgeslagen elementen toe
op een andere schermopname.
@ -331,7 +331,7 @@
<a name="settings-general"></a>
<h3>Algemene instellingen</h3>
<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>
<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>
@ -414,7 +414,7 @@
<p>
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 :)
</p>
@ -425,8 +425,8 @@
goede software gratis en vrij toegankelijk te houden. Als Greenshot
u helpt in uw werkzaamheden, als het u (of uw bedrijf)
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>
Bezoek onze website en lees daar hoe u het Greenshot-team kunt ondersteunen:</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/>
<a target="_blank" href="http://getgreenshot.org/support/">http://getgreenshot.org/support/</a>
</p>
@ -434,7 +434,7 @@
<h3>Vertel het door</h3>
<p>
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.
</p>
@ -443,10 +443,10 @@
<p>
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
<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
<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
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/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
@ -33,11 +32,10 @@ namespace GreenshotBoxPlugin {
/// <summary>
/// This is the Box base code
/// </summary>
[Plugin("Box", true)]
public class BoxPlugin : IGreenshotPlugin {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxPlugin));
private static BoxConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig;
@ -46,7 +44,7 @@ namespace GreenshotBoxPlugin {
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
protected void Dispose(bool disposing) {
if (disposing) {
if (_itemPlugInConfig != null) {
_itemPlugInConfig.Dispose();
@ -55,35 +53,22 @@ namespace GreenshotBoxPlugin {
}
}
public IEnumerable<IDestination> Destinations() {
yield return new BoxDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="pluginAttribute">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute pluginAttribute) {
_host = pluginHost;
Attributes = pluginAttribute;
public bool Initialize() {
// Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<BoxConfiguration>();
_resources = new ComponentResourceManager(typeof(BoxPlugin));
SimpleServiceProvider.Current.AddService(new BoxDestination(this));
_itemPlugInConfig = new ToolStripMenuItem {
Image = (Image) _resources.GetObject("Box"),
Text = Language.GetString("box", LangKey.Configure)
};
_itemPlugInConfig.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig);
PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged;
return true;
}
@ -94,14 +79,14 @@ namespace GreenshotBoxPlugin {
}
}
public virtual void Shutdown() {
public void Shutdown() {
LOG.Debug("Box Plugin shutdown.");
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
_config.ShowConfigDialog();
}
@ -119,7 +104,7 @@ namespace GreenshotBoxPlugin {
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
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 {
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
// associated with an assembly.
[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.
// 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 readonly Page _page;
public static bool IsInitialized {
get;
private set;
}
static ConfluenceDestination() {
IsInitialized = false;
try {
@ -60,7 +56,13 @@ namespace GreenshotConfluencePlugin {
Log.ErrorFormat("Problem in the confluence static initializer: {0}", ex.Message);
}
}
public static bool IsInitialized
{
get;
private set;
}
public ConfluenceDestination() {
}

View file

@ -24,7 +24,6 @@ using Greenshot.IniFile;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using System;
using System.Collections.Generic;
using System.Windows;
using TranslationByMarkupExtension;
@ -42,11 +41,11 @@ namespace GreenshotConfluencePlugin {
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
protected void Dispose(bool disposing) {
//if (disposing) {}
}
private static void CreateConfluenceConntector() {
private static void CreateConfluenceConnector() {
if (_confluenceConnector == null) {
if (_config.Url.Contains("soap-axis")) {
_confluenceConnector = new ConfluenceConnector(_config.Url, _config.Timeout);
@ -65,7 +64,7 @@ namespace GreenshotConfluencePlugin {
public static ConfluenceConnector ConfluenceConnector {
get {
if (_confluenceConnector == null) {
CreateConfluenceConntector();
CreateConfluenceConnector();
}
try {
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>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
public bool Initialize() {
// Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<ConfluenceConfiguration>();
if(_config.IsDirty) {
@ -106,10 +93,14 @@ namespace GreenshotConfluencePlugin {
LOG.ErrorFormat("Problem in ConfluencePlugin.Initialize: {0}", ex.Message);
return false;
}
if (ConfluenceDestination.IsInitialized)
{
SimpleServiceProvider.Current.AddService(new ConfluenceDestination());
}
return true;
}
public virtual void Shutdown() {
public void Shutdown() {
LOG.Debug("Confluence Plugin shutdown.");
if (_confluenceConnector != null) {
_confluenceConnector.Logout();
@ -120,7 +111,7 @@ namespace GreenshotConfluencePlugin {
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
ConfluenceConfiguration clonedConfig = _config.Clone();
ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig);
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/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
@ -33,11 +32,10 @@ namespace GreenshotDropboxPlugin {
/// <summary>
/// This is the Dropbox base code
/// </summary>
[Plugin("Dropbox", true)]
public class DropboxPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin));
private static DropboxPluginConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig;
@ -46,7 +44,7 @@ namespace GreenshotDropboxPlugin {
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
protected void Dispose(bool disposing) {
if (disposing) {
if (_itemPlugInConfig != null) {
_itemPlugInConfig.Dispose();
@ -55,37 +53,23 @@ namespace GreenshotDropboxPlugin {
}
}
public IEnumerable<IDestination> Destinations() {
yield return new DropboxDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
_host = pluginHost;
Attributes = myAttributes;
public bool Initialize() {
// Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
_resources = new ComponentResourceManager(typeof(DropboxPlugin));
SimpleServiceProvider.Current.AddService(new DropboxDestination(this));
_itemPlugInConfig = new ToolStripMenuItem
{
Text = Language.GetString("dropbox", LangKey.Configure),
Tag = _host,
Image = (Image)_resources.GetObject("Dropbox")
};
_itemPlugInConfig.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig);
PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged;
return true;
}
@ -96,14 +80,14 @@ namespace GreenshotDropboxPlugin {
}
}
public virtual void Shutdown() {
public void Shutdown() {
Log.Debug("Dropbox Plugin shutdown.");
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
_config.ShowConfigDialog();
}
@ -119,7 +103,7 @@ namespace GreenshotDropboxPlugin {
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
try {
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
{
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/>.
*/
using Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[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.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.

View file

@ -32,12 +32,11 @@ namespace ExternalCommand {
/// <summary>
/// An Plugin to run commands after an image was written
/// </summary>
[Plugin("ExternalCommand", true)]
public class ExternalCommandPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ExternalCommandPlugin));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
private IGreenshotHost _host;
private PluginAttribute _myAttributes;
private ToolStripMenuItem _itemPlugInRoot;
public void Dispose() {
@ -45,24 +44,19 @@ namespace ExternalCommand {
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (_itemPlugInRoot != null) {
_itemPlugInRoot.Dispose();
_itemPlugInRoot = null;
}
}
}
public IEnumerable<IDestination> Destinations() {
protected virtual void Dispose(bool disposing)
{
if (!disposing) return;
if (_itemPlugInRoot == null) return;
_itemPlugInRoot.Dispose();
_itemPlugInRoot = null;
}
private IEnumerable<IDestination> Destinations() {
foreach(string command in ExternalCommandConfig.Commands) {
yield return new ExternalCommandDestination(command);
}
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// 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);
return false;
}
SimpleServiceProvider.Current.AddService(Destinations());
return true;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
Log.DebugFormat("Initialize called of {0}", myAttributes.Name);
public virtual bool Initialize() {
Log.DebugFormat("Initialize called");
List<string> commandsToDelete = new List<string>();
// Check configuration
@ -114,16 +107,12 @@ namespace ExternalCommand {
ExternalCommandConfig.Delete(command);
}
_host = pluginHost;
_myAttributes = myAttributes;
_itemPlugInRoot = new ToolStripMenuItem {Tag = _host};
_itemPlugInRoot = new ToolStripMenuItem();
_itemPlugInRoot.Click += ConfigMenuClick;
OnIconSizeChanged(this, new PropertyChangedEventArgs("IconSize"));
OnLanguageChanged(this, null);
_itemPlugInRoot.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInRoot);
PluginUtils.AddToContextMenu(_itemPlugInRoot);
Language.LanguageChanged += OnLanguageChanged;
CoreConfig.PropertyChanged += OnIconSizeChanged;
return true;
@ -154,7 +143,7 @@ namespace ExternalCommand {
}
public virtual void Shutdown() {
Log.Debug("Shutdown of " + _myAttributes.Name);
Log.Debug("Shutdown");
}
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.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
@ -39,8 +38,6 @@ namespace GreenshotFlickrPlugin
public class FlickrPlugin : IGreenshotPlugin {
private static readonly ILog Log = LogManager.GetLogger(typeof(FlickrPlugin));
private static FlickrConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig;
@ -49,7 +46,7 @@ namespace GreenshotFlickrPlugin
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
protected void Dispose(bool disposing) {
if (!disposing) {
return;
}
@ -60,25 +57,10 @@ namespace GreenshotFlickrPlugin
_itemPlugInConfig = null;
}
public IEnumerable<IDestination> Destinations() {
yield return new FlickrDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="pluginAttribute">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute pluginAttribute) {
_host = pluginHost;
Attributes = pluginAttribute;
public bool Initialize() {
// Register configuration (don't need the configuration itself)
_config = IniConfig.GetIniSection<FlickrConfiguration>();
_resources = new ComponentResourceManager(typeof(FlickrPlugin));
@ -86,12 +68,11 @@ namespace GreenshotFlickrPlugin
_itemPlugInConfig = new ToolStripMenuItem
{
Text = Language.GetString("flickr", LangKey.Configure),
Tag = _host,
Image = (Image) _resources.GetObject("flickr")
};
_itemPlugInConfig.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig);
SimpleServiceProvider.Current.AddService(new FlickrDestination(this));
PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged;
return true;
}
@ -102,14 +83,14 @@ namespace GreenshotFlickrPlugin
}
}
public virtual void Shutdown() {
public void Shutdown() {
Log.Debug("Flickr Plugin shutdown.");
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
_config.ShowConfigDialog();
}
@ -122,7 +103,7 @@ namespace GreenshotFlickrPlugin
uploadUrl = null;
try {
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 {
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
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/>.
*/
using Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[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.
// 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
pictureBox1.Image = pictureBox1.ErrorImage;
try {
new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait),
new PleaseWaitForm().ShowAndWait("Imgur", Language.GetString("imgur", LangKey.communication_wait),
delegate {
ImgurUtils.DeleteImgurImage(imgurInfo);
}

View file

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

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[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.
// 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) =>
{
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 {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination));
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
private readonly JiraPlugin _jiraPlugin;
private readonly Issue _jiraIssue;
public JiraDestination(JiraPlugin jiraPlugin) {
_jiraPlugin = jiraPlugin;
}
public JiraDestination(JiraPlugin jiraPlugin, Issue jiraIssue) {
_jiraPlugin = jiraPlugin;
_jiraIssue = jiraIssue;
public JiraDestination(Issue jiraIssue = null) {
_jiraIssue = jiraIssue;
}
public override string Designation => "Jira";
@ -73,7 +67,7 @@ namespace GreenshotJiraPlugin {
get
{
Image displayIcon = null;
var jiraConnector = JiraPlugin.Instance.CurrentJiraConnector;
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (jiraConnector != null)
{
if (_jiraIssue != null)
@ -104,13 +98,13 @@ namespace GreenshotJiraPlugin {
public override IEnumerable<IDestination> DynamicDestinations()
{
var jiraConnector = JiraPlugin.Instance.CurrentJiraConnector;
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (jiraConnector == null || !jiraConnector.IsLoggedIn) {
yield break;
}
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);
string filename = Path.GetFileName(FilenameHelper.GetFilename(Config.UploadFormat, captureDetails));
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(Config.UploadFormat, Config.UploadJpegQuality, Config.UploadReduceColors);
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
if (_jiraIssue != null) {
try {
// Run upload in the background
@ -125,8 +120,8 @@ namespace GreenshotJiraPlugin {
async () =>
{
var surfaceContainer = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
await _jiraPlugin.JiraConnector.AttachAsync(_jiraIssue.Key, surfaceContainer);
surfaceToUpload.UploadUrl = _jiraPlugin.JiraConnector.JiraBaseUri.AppendSegments("browse", _jiraIssue.Key).AbsoluteUri;
await jiraConnector.AttachAsync(_jiraIssue.Key, surfaceContainer);
surfaceToUpload.UploadUrl = jiraConnector.JiraBaseUri.AppendSegments("browse", _jiraIssue.Key).AbsoluteUri;
}
);
Log.DebugFormat("Uploaded to Jira {0}", _jiraIssue.Key);
@ -136,12 +131,12 @@ namespace GreenshotJiraPlugin {
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
}
} else {
var jiraForm = new JiraForm(_jiraPlugin.JiraConnector);
var jiraForm = new JiraForm(jiraConnector);
jiraForm.SetFilename(filename);
var dialogResult = jiraForm.ShowDialog();
if (dialogResult == DialogResult.OK) {
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
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
async () =>

View file

@ -33,11 +33,10 @@ namespace GreenshotJiraPlugin {
/// <summary>
/// This is the JiraPlugin base code
/// </summary>
[Plugin("Jira", true)]
public class JiraPlugin : IGreenshotPlugin {
private static readonly ILog Log = LogManager.GetLogger(typeof(JiraPlugin));
private JiraConfiguration _config;
private static JiraPlugin _instance;
private JiraConnector _jiraConnector;
public void Dispose() {
Dispose(true);
@ -45,58 +44,27 @@ namespace GreenshotJiraPlugin {
}
protected void Dispose(bool disposing) {
if (disposing) {
if (JiraConnector != null) {
JiraConnector.Dispose();
JiraConnector = null;
}
if (disposing)
{
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
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>
/// Implementation of the IGreenshotPlugin.Initialize
/// </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>
public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
public bool Initialize() {
// Register configuration (don't need the configuration itself)
_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)
{
LogSettings.RegisterDefaultLogger<Log4NetLogger>(LogLevels.Verbose);
@ -142,7 +110,8 @@ namespace GreenshotJiraPlugin {
public void Shutdown() {
Log.Debug("Jira Plugin shutdown.");
JiraConnector?.Logout();
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
jiraConnector?.Logout();
}
/// <summary>
@ -152,12 +121,13 @@ namespace GreenshotJiraPlugin {
string url = _config.Url;
if (ShowConfigDialog()) {
// 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)) {
JiraConnector.Logout();
jiraConnector.Logout();
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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotPlugin.Core
namespace GreenshotOCR
{
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
}
/// <summary>
/// Needed for the drop down, available languages for OCR
/// </summary>
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
}
}

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
@ -31,39 +30,14 @@ using GreenshotPlugin.Effects;
//using Microsoft.Win32;
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>
/// OCR Plugin Greenshot
/// </summary>
[Plugin("Ocr", true)]
public class OcrPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(OcrPlugin));
private string _ocrCommand;
private static OCRConfiguration config;
private PluginAttribute _myAttributes;
private static OCRConfiguration _config;
private ToolStripMenuItem _ocrMenuItem = new ToolStripMenuItem();
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>
/// Implementation of the IGreenshotPlugin.Initialize
/// </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>
public virtual bool Initialize(IGreenshotHost greenshotHost, PluginAttribute myAttributes) {
Log.Debug("Initialize called of " + myAttributes.Name);
_myAttributes = myAttributes;
public bool Initialize() {
Log.Debug("Initialize called");
var ocrDirectory = Path.GetDirectoryName(myAttributes.DllFile);
var ocrDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
if (ocrDirectory == null)
{
return false;
@ -108,11 +72,13 @@ namespace GreenshotOCR {
Log.Warn("No MODI found!");
return false;
}
// Provide the IDestination
SimpleServiceProvider.Current.AddService(new OCRDestination(this));
// Load configuration
config = IniConfig.GetIniSection<OCRConfiguration>();
_config = IniConfig.GetIniSection<OCRConfiguration>();
if (config.Language != null) {
config.Language = config.Language.Replace("miLANG_","").Replace("_"," ");
if (_config.Language != null) {
_config.Language = _config.Language.Replace("miLANG_","").Replace("_"," ");
}
return true;
}
@ -121,18 +87,18 @@ namespace GreenshotOCR {
/// Implementation of the IGreenshotPlugin.Shutdown
/// </summary>
public void Shutdown() {
Log.Debug("Shutdown of " + _myAttributes.Name);
Log.Debug("Shutdown");
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
if (!HasModi()) {
MessageBox.Show("Sorry, is seems that Microsoft Office Document Imaging (MODI) is not installed, therefor the OCR Plugin cannot work.");
return;
}
SettingsForm settingsForm = new SettingsForm(Enum.GetNames(typeof(ModiLanguage)), config);
SettingsForm settingsForm = new SettingsForm(Enum.GetNames(typeof(ModiLanguage)), _config);
DialogResult result = settingsForm.ShowDialog();
if (result == DialogResult.OK) {
// "Re"set hotkeys
@ -177,7 +143,7 @@ namespace GreenshotOCR {
string text = "";
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,
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.Collections.Generic;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
namespace GreenshotOfficePlugin {
/// <summary>
/// This is the OfficePlugin base code
/// </summary>
public class OfficePlugin : IGreenshotPlugin {
[Plugin("Office", false)]
public class OfficePlugin : IGreenshotPlugin
{
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OfficePlugin));
public void Dispose() {
@ -38,7 +41,7 @@ namespace GreenshotOfficePlugin {
// Do nothing
}
public IEnumerable<IDestination> Destinations() {
private IEnumerable<IDestination> Destinations() {
IDestination destination;
try {
destination = new ExcelDestination();
@ -86,21 +89,17 @@ namespace GreenshotOfficePlugin {
}
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </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>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
public bool Initialize() {
SimpleServiceProvider.Current.AddService(Destinations());
return true;
}
public virtual void Shutdown() {
public void Shutdown() {
LOG.Debug("Office Plugin shutdown.");
}

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[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.
// 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() {
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 {
settingsForm = new SettingsForm();
}

View file

@ -37,7 +37,7 @@ namespace GreenshotPhotobucketPlugin {
/// </summary>
/// <param name="plugin"></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;
_albumPath = albumPath;
}

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
@ -33,11 +32,10 @@ namespace GreenshotPhotobucketPlugin {
/// <summary>
/// This is the GreenshotPhotobucketPlugin base code
/// </summary>
[Plugin("Photobucket", true)]
public class PhotobucketPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PhotobucketPlugin));
private static PhotobucketConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInConfig;
@ -46,32 +44,20 @@ namespace GreenshotPhotobucketPlugin {
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (_itemPlugInConfig != null) {
_itemPlugInConfig.Dispose();
_itemPlugInConfig = null;
}
}
}
public IEnumerable<IDestination> Destinations() {
yield return new PhotobucketDestination(this, null);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
protected void Dispose(bool disposing)
{
if (!disposing) return;
if (_itemPlugInConfig == null) return;
_itemPlugInConfig.Dispose();
_itemPlugInConfig = null;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </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>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
_host = pluginHost;
Attributes = myAttributes;
public bool Initialize() {
SimpleServiceProvider.Current.AddService<IDestination>(new PhotobucketDestination(this));
// Get configuration
_config = IniConfig.GetIniSection<PhotobucketConfiguration>();
@ -79,14 +65,13 @@ namespace GreenshotPhotobucketPlugin {
_itemPlugInConfig = new ToolStripMenuItem(Language.GetString("photobucket", LangKey.configure))
{
Tag = _host,
Image = (Image)_resources.GetObject("Photobucket")
};
_itemPlugInConfig.Click += delegate {
_config.ShowConfigDialog();
};
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig);
PluginUtils.AddToContextMenu(_itemPlugInConfig);
Language.LanguageChanged += OnLanguageChanged;
return true;
}
@ -97,7 +82,7 @@ namespace GreenshotPhotobucketPlugin {
}
}
public virtual void Shutdown() {
public void Shutdown() {
Log.Debug("Photobucket Plugin shutdown.");
Language.LanguageChanged -= OnLanguageChanged;
}
@ -105,7 +90,7 @@ namespace GreenshotPhotobucketPlugin {
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
_config.ShowConfigDialog();
}
@ -124,7 +109,7 @@ namespace GreenshotPhotobucketPlugin {
PhotobucketInfo photobucketInfo = null;
// 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 {
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/>.
*/
using Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
@ -28,8 +27,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[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.
// 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/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
@ -32,11 +31,10 @@ namespace GreenshotPicasaPlugin {
/// <summary>
/// This is the Picasa base code
/// </summary>
[Plugin("Picasa", true)]
public class PicasaPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PicasaPlugin));
private static PicasaConfiguration _config;
public static PluginAttribute Attributes;
private IGreenshotHost _host;
private ComponentResourceManager _resources;
private ToolStripMenuItem _itemPlugInRoot;
@ -45,7 +43,7 @@ namespace GreenshotPicasaPlugin {
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
protected void Dispose(bool disposing) {
if (disposing) {
if (_itemPlugInRoot != null) {
_itemPlugInRoot.Dispose();
@ -54,23 +52,11 @@ namespace GreenshotPicasaPlugin {
}
}
public IEnumerable<IDestination> Destinations() {
yield return new PicasaDestination(this);
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
_host = pluginHost;
Attributes = myAttributes;
public bool Initialize() {
SimpleServiceProvider.Current.AddService<IDestination>(new PicasaDestination(this));
// Get configuration
_config = IniConfig.GetIniSection<PicasaConfiguration>();
@ -79,11 +65,10 @@ namespace GreenshotPicasaPlugin {
_itemPlugInRoot = new ToolStripMenuItem
{
Text = Language.GetString("picasa", LangKey.Configure),
Tag = _host,
Image = (Image) _resources.GetObject("Picasa")
};
_itemPlugInRoot.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInRoot);
PluginUtils.AddToContextMenu(_itemPlugInRoot);
Language.LanguageChanged += OnLanguageChanged;
return true;
}
@ -94,7 +79,7 @@ namespace GreenshotPicasaPlugin {
}
}
public virtual void Shutdown() {
public void Shutdown() {
Log.Debug("Picasa Plugin shutdown.");
Language.LanguageChanged -= OnLanguageChanged;
//host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened);
@ -103,7 +88,7 @@ namespace GreenshotPicasaPlugin {
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
public void Configure() {
_config.ShowConfigDialog();
}
@ -115,7 +100,7 @@ namespace GreenshotPicasaPlugin {
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality);
try {
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
{
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/>.
*/
using Greenshot.Plugin;
using System.Reflection;
using System.Runtime.InteropServices;
@ -27,8 +26,6 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[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.
// 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);
}
// 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.Focus();

View file

@ -52,16 +52,11 @@ namespace GreenshotPlugin.Core {
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private const int ExifOrientationId = 0x0112;
/// <summary>
/// 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()
static ImageHelper()
{
StreamConverters["greenshot"] = (stream, s) =>
{
var surface = SurfaceFactory();
var surface = SimpleServiceProvider.Current.GetInstance<Func<ISurface>>().Invoke();
return surface.GetImageForExport();
};

View file

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

@ -1,35 +1,51 @@
/*
* 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("GreenshotJiraPlugin.JiraPlugin", 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)]
/*
* 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;
namespace Greenshot.Plugin {
[Serializable]
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class PluginAttribute : Attribute, IComparable {
public string Name {
get;
set;
}
public bool Configurable {
get;
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) {
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) {
continue;
}

View file

@ -7,9 +7,6 @@ using System.Runtime.InteropServices;
// associated with an assembly.
[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
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.

View file

@ -29,6 +29,7 @@ namespace GreenshotWin10Plugin
/// <summary>
/// This is the Win10Plugin
/// </summary>
[Plugin("Win10", false)]
public class Win10Plugin : IGreenshotPlugin
{
public void Dispose()
@ -52,7 +53,7 @@ namespace GreenshotWin10Plugin
/// yields the windows 10 destinations if Windows 10 is detected
/// </summary>
/// <returns>IEnumerable with the destinations</returns>
public IEnumerable<IDestination> Destinations()
private IEnumerable<IDestination> Destinations()
{
if (!WindowsVersion.IsWindows10OrLater)
{
@ -62,19 +63,13 @@ namespace GreenshotWin10Plugin
yield return new Win10ShareDestination();
}
public IEnumerable<IProcessor> Processors()
{
yield break;
}
/// <summary>
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </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>
public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes)
public bool Initialize()
{
SimpleServiceProvider.Current.AddService(Destinations());
return true;
}