Code quality changes

This commit is contained in:
Robin 2016-09-22 20:40:13 +02:00
parent f07ed83722
commit 610f45d082
189 changed files with 4609 additions and 5203 deletions

View file

@ -26,6 +26,7 @@ using Greenshot.Drawing.Fields;
using GreenshotPlugin.UnmanagedHelpers; using GreenshotPlugin.UnmanagedHelpers;
using Greenshot.IniFile; using Greenshot.IniFile;
using Greenshot.Core; using Greenshot.Core;
using GreenshotPlugin.Effects;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Configuration { namespace Greenshot.Configuration {
@ -99,9 +100,10 @@ namespace Greenshot.Configuration {
} else { } else {
LastUsedFieldValues.Add(requestedField, fieldValue); LastUsedFieldValues.Add(requestedField, fieldValue);
} }
Field returnField = new Field(fieldType, requestingType); return new Field(fieldType, requestingType)
returnField.Value = fieldValue; {
return returnField; Value = fieldValue
};
} }
public void UpdateLastFieldValue(IField field) public void UpdateLastFieldValue(IField field)

View file

@ -41,8 +41,9 @@ namespace Greenshot.Controls {
CheckedChanged += BindableToolStripButton_CheckedChanged; CheckedChanged += BindableToolStripButton_CheckedChanged;
} }
private void BindableToolStripButton_CheckedChanged(object sender, EventArgs e) { private void BindableToolStripButton_CheckedChanged(object sender, EventArgs e)
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Checked")); {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Checked"));
} }
} }
} }

View file

@ -41,11 +41,9 @@ namespace Greenshot.Controls {
SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged; SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
} }
private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) { private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
if(PropertyChanged != null) { {
PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedItem"));
}
} }
} }
} }

View file

@ -48,7 +48,7 @@ namespace Greenshot.Controls {
if(Tag == null || !Tag.Equals(clickedItem.Tag)) { if(Tag == null || !Tag.Equals(clickedItem.Tag)) {
Tag = clickedItem.Tag; Tag = clickedItem.Tag;
Image = clickedItem.Image; Image = clickedItem.Image;
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTag")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTag"));
} }
base.OnDropDownItemClicked(e); base.OnDropDownItemClicked(e);
} }
@ -63,7 +63,7 @@ namespace Greenshot.Controls {
} }
} }
Tag = tag; Tag = tag;
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTag")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedTag"));
} }
} }
} }

View file

@ -72,14 +72,16 @@ namespace Greenshot.Controls {
colorDialog.Color = SelectedColor; colorDialog.Color = SelectedColor;
// Using the parent to make sure the dialog doesn't show on another window // Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent); colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult != DialogResult.Cancel) { if (colorDialog.DialogResult == DialogResult.Cancel)
if (!colorDialog.Color.Equals(SelectedColor)) { {
SelectedColor = colorDialog.Color; return;
if(PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor"));
}
}
} }
if (colorDialog.Color.Equals(SelectedColor))
{
return;
}
SelectedColor = colorDialog.Color;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor"));
} }
} }
} }

View file

@ -29,18 +29,16 @@ namespace Greenshot.Controls {
/// ToolStripProfessionalRenderer which draws the Check correctly when the icons are larger /// ToolStripProfessionalRenderer which draws the Check correctly when the icons are larger
/// </summary> /// </summary>
public class ContextMenuToolStripProfessionalRenderer : ToolStripProfessionalRenderer { public class ContextMenuToolStripProfessionalRenderer : ToolStripProfessionalRenderer {
private static readonly CoreConfiguration coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static Image scaledCheckbox; private static Image _scaledCheckbox;
protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) { protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e) {
if (scaledCheckbox == null || scaledCheckbox.Size != coreConfiguration.IconSize) { if (_scaledCheckbox == null || _scaledCheckbox.Size != CoreConfig.IconSize) {
if (scaledCheckbox != null) { _scaledCheckbox?.Dispose();
scaledCheckbox.Dispose(); _scaledCheckbox = ImageHelper.ResizeImage(e.Image, true, CoreConfig.IconSize.Width, CoreConfig.IconSize.Height, null);
}
scaledCheckbox = ImageHelper.ResizeImage(e.Image, true, coreConfiguration.IconSize.Width, coreConfiguration.IconSize.Height, null);
} }
Rectangle old = e.ImageRectangle; Rectangle old = e.ImageRectangle;
ToolStripItemImageRenderEventArgs clone = new ToolStripItemImageRenderEventArgs(e.Graphics, e.Item, scaledCheckbox, new Rectangle(old.X, 0, old.Width, old.Height)); ToolStripItemImageRenderEventArgs clone = new ToolStripItemImageRenderEventArgs(e.Graphics, e.Item, _scaledCheckbox, new Rectangle(old.X, 0, old.Width, old.Height));
base.OnRenderItemCheck(clone); base.OnRenderItemCheck(clone);
} }
} }

View file

@ -84,9 +84,7 @@ namespace Greenshot.Controls {
if (_cursor != null) { if (_cursor != null) {
_cursor.Dispose(); _cursor.Dispose();
} }
if (_movableShowColorForm != null) { _movableShowColorForm?.Dispose();
_movableShowColorForm.Dispose();
}
} }
_movableShowColorForm = null; _movableShowColorForm = null;
_cursor = null; _cursor = null;
@ -114,10 +112,7 @@ namespace Greenshot.Controls {
{ {
//Release Capture should consume MouseUp when canceled with the escape key //Release Capture should consume MouseUp when canceled with the escape key
User32.ReleaseCapture(); User32.ReleaseCapture();
if (PipetteUsed != null) PipetteUsed?.Invoke(this, new PipetteUsedArgs(_movableShowColorForm.color));
{
PipetteUsed(this, new PipetteUsedArgs(_movableShowColorForm.color));
}
} }
base.OnMouseUp(e); base.OnMouseUp(e);
} }

View file

@ -70,14 +70,16 @@ namespace Greenshot.Controls {
colorDialog.Color = SelectedColor; colorDialog.Color = SelectedColor;
// Using the parent to make sure the dialog doesn't show on another window // Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent); colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult != DialogResult.Cancel) { if (colorDialog.DialogResult == DialogResult.Cancel)
if (!colorDialog.Color.Equals(SelectedColor)) { {
SelectedColor = colorDialog.Color; return;
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor"));
}
}
} }
if (colorDialog.Color.Equals(SelectedColor))
{
return;
}
SelectedColor = colorDialog.Color;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedColor"));
} }
} }
} }

View file

@ -34,16 +34,13 @@ namespace Greenshot.Controls {
{ {
} }
public NumericUpDown NumericUpDown public NumericUpDown NumericUpDown => Control as NumericUpDown;
{
get {return Control as NumericUpDown;}
}
public decimal Value public decimal Value
{ {
get { return NumericUpDown.Value; } get { return NumericUpDown.Value; }
set { NumericUpDown.Value = value;} set { NumericUpDown.Value = value;}
} }
public decimal Minimum { public decimal Minimum {
get { return NumericUpDown.Minimum; } get { return NumericUpDown.Minimum; }
set { NumericUpDown.Minimum = value; } set { NumericUpDown.Minimum = value; }
@ -74,8 +71,9 @@ namespace Greenshot.Controls {
NumericUpDown.ValueChanged -= _valueChanged; NumericUpDown.ValueChanged -= _valueChanged;
} }
private void _valueChanged(object sender, EventArgs e) { private void _valueChanged(object sender, EventArgs e)
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Value")); {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
} }
} }
} }

View file

@ -66,7 +66,7 @@ namespace Greenshot.Destinations {
} }
} }
public override bool isDynamic { public override bool IsDynamic {
get { get {
return true; return true;
} }

View file

@ -32,76 +32,56 @@ namespace Greenshot.Destinations {
/// Description of EmailDestination. /// Description of EmailDestination.
/// </summary> /// </summary>
public class EmailDestination : AbstractDestination { public class EmailDestination : AbstractDestination {
private static readonly Image mailIcon = GreenshotResources.getImage("Email.Image"); private static readonly Image MailIcon = GreenshotResources.getImage("Email.Image");
private static bool isActiveFlag; private static bool _isActiveFlag;
private static string mapiClient; private static string _mapiClient;
public const string DESIGNATION = "EMail"; public const string DESIGNATION = "EMail";
static EmailDestination() { static EmailDestination() {
// Logic to decide what email implementation we use // Logic to decide what email implementation we use
if (EmailConfigHelper.HasMAPI()) { if (EmailConfigHelper.HasMapi()) {
isActiveFlag = true; _isActiveFlag = true;
mapiClient = EmailConfigHelper.GetMapiClient(); _mapiClient = EmailConfigHelper.GetMapiClient();
if (!string.IsNullOrEmpty(mapiClient)) { if (!string.IsNullOrEmpty(_mapiClient)) {
// Active as we have a mapi client, can be disabled later // Active as we have a mapi client, can be disabled later
isActiveFlag = true; _isActiveFlag = true;
} }
} }
} }
public EmailDestination() { public override string Designation => DESIGNATION;
}
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description { public override string Description {
get { get {
// Make sure there is some kind of "mail" name // Make sure there is some kind of "mail" name
if (mapiClient == null) { if (_mapiClient == null) {
mapiClient = Language.GetString(LangKey.editor_email); _mapiClient = Language.GetString(LangKey.editor_email);
} }
return mapiClient; return _mapiClient;
} }
} }
public override int Priority { public override int Priority => 3;
get {
return 3;
}
}
public override bool isActive { public override bool IsActive {
get { get {
if (isActiveFlag) { if (_isActiveFlag) {
// Disable if the office plugin is installed and the client is outlook // Disable if the office plugin is installed and the client is outlook
// TODO: Change this! It always creates an exception, as the plugin has not been loaded the type is not there :( // TODO: Change this! It always creates an exception, as the plugin has not been loaded the type is not there :(
Type outlookdestination = Type.GetType("GreenshotOfficePlugin.OutlookDestination,GreenshotOfficePlugin"); Type outlookdestination = Type.GetType("GreenshotOfficePlugin.OutlookDestination,GreenshotOfficePlugin");
if (outlookdestination != null) { if (outlookdestination != null) {
if (mapiClient.ToLower().Contains("microsoft outlook")) { if (_mapiClient.ToLower().Contains("microsoft outlook")) {
isActiveFlag = false; _isActiveFlag = false;
} }
} }
} }
return base.isActive && isActiveFlag; return base.IsActive && _isActiveFlag;
} }
} }
public override Keys EditorShortcutKeys { public override Keys EditorShortcutKeys => Keys.Control | Keys.E;
get {
return Keys.Control | Keys.E;
}
}
public override Image DisplayIcon { public override Image DisplayIcon => MailIcon;
get {
return mailIcon;
}
}
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);

View file

@ -35,60 +35,40 @@ namespace Greenshot.Destinations {
/// Description of FileSaveAsDestination. /// Description of FileSaveAsDestination.
/// </summary> /// </summary>
public class FileDestination : AbstractDestination { public class FileDestination : AbstractDestination {
private static readonly ILog LOG = LogManager.GetLogger(typeof(FileDestination)); private static readonly ILog Log = LogManager.GetLogger(typeof(FileDestination));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "FileNoDialog"; public const string DESIGNATION = "FileNoDialog";
public override string Designation { public override string Designation => DESIGNATION;
get {
return DESIGNATION;
}
}
public override string Description { public override string Description => Language.GetString(LangKey.quicksettings_destination_file);
get {
return Language.GetString(LangKey.quicksettings_destination_file);
}
}
public override int Priority { public override int Priority => 0;
get {
return 0;
}
}
public override Keys EditorShortcutKeys { public override Keys EditorShortcutKeys => Keys.Control | Keys.S;
get {
return Keys.Control | Keys.S;
}
}
public override Image DisplayIcon { public override Image DisplayIcon => GreenshotResources.getImage("Save.Image");
get {
return GreenshotResources.getImage("Save.Image");
}
}
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
bool outputMade; bool outputMade;
bool overwrite; bool overwrite;
string fullPath; string fullPath;
// Get output settings from the configuration // Get output settings from the configuration
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(); SurfaceOutputSettings outputSettings = new SurfaceOutputSettings();
if (captureDetails != null && captureDetails.Filename != null) { if (captureDetails?.Filename != null) {
// As we save a pre-selected file, allow to overwrite. // As we save a pre-selected file, allow to overwrite.
overwrite = true; overwrite = true;
LOG.InfoFormat("Using previous filename"); Log.InfoFormat("Using previous filename");
fullPath = captureDetails.Filename; fullPath = captureDetails.Filename;
outputSettings.Format = ImageOutput.FormatForFilename(fullPath); outputSettings.Format = ImageOutput.FormatForFilename(fullPath);
} else { } else {
fullPath = CreateNewFilename(captureDetails); fullPath = CreateNewFilename(captureDetails);
// As we generate a file, the configuration tells us if we allow to overwrite // As we generate a file, the configuration tells us if we allow to overwrite
overwrite = conf.OutputFileAllowOverwrite; overwrite = CoreConfig.OutputFileAllowOverwrite;
} }
if (conf.OutputFilePromptQuality) { if (CoreConfig.OutputFilePromptQuality) {
QualityDialog qualityDialog = new QualityDialog(outputSettings); QualityDialog qualityDialog = new QualityDialog(outputSettings);
qualityDialog.ShowDialog(); qualityDialog.ShowDialog();
} }
@ -96,16 +76,16 @@ namespace Greenshot.Destinations {
// Catching any exception to prevent that the user can't write in the directory. // Catching any exception to prevent that the user can't write in the directory.
// This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642 // This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642
try { try {
ImageOutput.Save(surface, fullPath, overwrite, outputSettings, conf.OutputFileCopyPathToClipboard); ImageOutput.Save(surface, fullPath, overwrite, outputSettings, CoreConfig.OutputFileCopyPathToClipboard);
outputMade = true; outputMade = true;
} catch (ArgumentException ex1) { } catch (ArgumentException ex1) {
// Our generated filename exists, display 'save-as' // Our generated filename exists, display 'save-as'
LOG.InfoFormat("Not overwriting: {0}", ex1.Message); Log.InfoFormat("Not overwriting: {0}", ex1.Message);
// when we don't allow to overwrite present a new SaveWithDialog // when we don't allow to overwrite present a new SaveWithDialog
fullPath = ImageOutput.SaveWithDialog(surface, captureDetails); fullPath = ImageOutput.SaveWithDialog(surface, captureDetails);
outputMade = fullPath != null; outputMade = fullPath != null;
} catch (Exception ex2) { } catch (Exception ex2) {
LOG.Error("Error saving screenshot!", ex2); Log.Error("Error saving screenshot!", ex2);
// Show the problem // Show the problem
MessageBox.Show(Language.GetString(LangKey.error_save), Language.GetString(LangKey.error)); MessageBox.Show(Language.GetString(LangKey.error_save), Language.GetString(LangKey.error));
// when save failed we present a SaveWithDialog // when save failed we present a SaveWithDialog
@ -120,7 +100,7 @@ namespace Greenshot.Destinations {
{ {
captureDetails.Filename = fullPath; captureDetails.Filename = fullPath;
} }
conf.OutputFileAsFullpath = fullPath; CoreConfig.OutputFileAsFullpath = fullPath;
} }
ProcessExport(exportInformation, surface); ProcessExport(exportInformation, surface);
@ -129,18 +109,18 @@ namespace Greenshot.Destinations {
private static string CreateNewFilename(ICaptureDetails captureDetails) { private static string CreateNewFilename(ICaptureDetails captureDetails) {
string fullPath; string fullPath;
LOG.InfoFormat("Creating new filename"); Log.InfoFormat("Creating new filename");
string pattern = conf.OutputFileFilenamePattern; string pattern = CoreConfig.OutputFileFilenamePattern;
if (string.IsNullOrEmpty(pattern)) { if (string.IsNullOrEmpty(pattern)) {
pattern = "greenshot ${capturetime}"; pattern = "greenshot ${capturetime}";
} }
string filename = FilenameHelper.GetFilenameFromPattern(pattern, conf.OutputFileFormat, captureDetails); string filename = FilenameHelper.GetFilenameFromPattern(pattern, CoreConfig.OutputFileFormat, captureDetails);
string filepath = FilenameHelper.FillVariables(conf.OutputFilePath, false); string filepath = FilenameHelper.FillVariables(CoreConfig.OutputFilePath, false);
try { try {
fullPath = Path.Combine(filepath, filename); fullPath = Path.Combine(filepath, filename);
} catch (ArgumentException) { } catch (ArgumentException) {
// configured filename or path not valid, show error message... // configured filename or path not valid, show error message...
LOG.InfoFormat("Generated path or filename not valid: {0}, {1}", filepath, filename); Log.InfoFormat("Generated path or filename not valid: {0}, {1}", filepath, filename);
MessageBox.Show(Language.GetString(LangKey.error_save_invalid_chars), Language.GetString(LangKey.error)); MessageBox.Show(Language.GetString(LangKey.error_save_invalid_chars), Language.GetString(LangKey.error));
// ... lets get the pattern fixed.... // ... lets get the pattern fixed....

View file

@ -24,35 +24,19 @@ using Greenshot.Configuration;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using Greenshot.Plugin; using Greenshot.Plugin;
using Greenshot.Helpers; using Greenshot.Helpers;
using Greenshot.IniFile;
using log4net;
namespace Greenshot.Destinations { namespace Greenshot.Destinations {
/// <summary> /// <summary>
/// The PickerDestination shows a context menu with all possible destinations, so the user can "pick" one /// The PickerDestination shows a context menu with all possible destinations, so the user can "pick" one
/// </summary> /// </summary>
public class PickerDestination : AbstractDestination { public class PickerDestination : AbstractDestination {
private static ILog LOG = LogManager.GetLogger(typeof(PickerDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "Picker"; public const string DESIGNATION = "Picker";
public override string Designation { public override string Designation => DESIGNATION;
get {
return DESIGNATION;
}
}
public override string Description { public override string Description => Language.GetString(LangKey.settings_destination_picker);
get {
return Language.GetString(LangKey.settings_destination_picker);
}
}
public override int Priority { public override int Priority => 1;
get {
return 1;
}
}
/// <summary> /// <summary>
@ -68,7 +52,7 @@ namespace Greenshot.Destinations {
if ("Picker".Equals(destination.Designation)) { if ("Picker".Equals(destination.Designation)) {
continue; continue;
} }
if (!destination.isActive) { if (!destination.IsActive) {
continue; continue;
} }
destinations.Add(destination); destinations.Add(destination);

View file

@ -76,7 +76,7 @@ namespace Greenshot.Destinations {
} }
} }
public override bool isDynamic { public override bool IsDynamic {
get { get {
return true; return true;
} }

View file

@ -45,13 +45,7 @@ namespace Greenshot.Drawing.Adorners
/// <summary> /// <summary>
/// Returns the cursor for when the mouse is over the adorner /// Returns the cursor for when the mouse is over the adorner
/// </summary> /// </summary>
public override Cursor Cursor public override Cursor Cursor => Cursors.SizeAll;
{
get
{
return Cursors.SizeAll;
}
}
/// <summary> /// <summary>
/// Handle the mouse down /// Handle the mouse down
@ -147,7 +141,6 @@ namespace Greenshot.Drawing.Adorners
public override void Paint(PaintEventArgs paintEventArgs) public override void Paint(PaintEventArgs paintEventArgs)
{ {
Graphics targetGraphics = paintEventArgs.Graphics; Graphics targetGraphics = paintEventArgs.Graphics;
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
var bounds = Bounds; var bounds = Bounds;
GraphicsState state = targetGraphics.Save(); GraphicsState state = targetGraphics.Save();

View file

@ -168,7 +168,6 @@ namespace Greenshot.Drawing.Adorners
public override void Paint(PaintEventArgs paintEventArgs) public override void Paint(PaintEventArgs paintEventArgs)
{ {
Graphics targetGraphics = paintEventArgs.Graphics; Graphics targetGraphics = paintEventArgs.Graphics;
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
var bounds = Bounds; var bounds = Bounds;
GraphicsState state = targetGraphics.Save(); GraphicsState state = targetGraphics.Save();

View file

@ -95,7 +95,6 @@ namespace Greenshot.Drawing.Adorners
public override void Paint(PaintEventArgs paintEventArgs) public override void Paint(PaintEventArgs paintEventArgs)
{ {
Graphics targetGraphics = paintEventArgs.Graphics; Graphics targetGraphics = paintEventArgs.Graphics;
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
var bounds = Bounds; var bounds = Bounds;
targetGraphics.FillRectangle(Brushes.Green, bounds.X, bounds.Y, bounds.Width, bounds.Height); targetGraphics.FillRectangle(Brushes.Green, bounds.X, bounds.Y, bounds.Width, bounds.Height);

View file

@ -383,12 +383,12 @@ namespace Greenshot.Drawing
Rectangle drawingRect = new Rectangle(Bounds.Location, Bounds.Size); Rectangle drawingRect = new Rectangle(Bounds.Location, Bounds.Size);
drawingRect.Intersect(clipRectangle); drawingRect.Intersect(clipRectangle);
if(filter is MagnifierFilter) { if(filter is MagnifierFilter) {
// quick&dirty bugfix, because MagnifierFilter behaves differently when drawn only partially // quick&dirty bugfix, because MagnifierFilter behaves differently when drawn only partially
// what we should actually do to resolve this is add a better magnifier which is not that special // what we should actually do to resolve this is add a better magnifier which is not that special
filter.Apply(graphics, bmp, Bounds, renderMode); filter.Apply(graphics, bmp, Bounds, renderMode);
} else { } else {
filter.Apply(graphics, bmp, drawingRect, renderMode); filter.Apply(graphics, bmp, drawingRect, renderMode);
} }
} }
} }
} }
@ -517,7 +517,7 @@ namespace Greenshot.Drawing
/// <param name="e"></param> /// <param name="e"></param>
public void HandleFieldChanged(object sender, FieldChangedEventArgs e) { public void HandleFieldChanged(object sender, FieldChangedEventArgs e) {
LOG.DebugFormat("Field {0} changed", e.Field.FieldType); LOG.DebugFormat("Field {0} changed", e.Field.FieldType);
if (e.Field.FieldType == FieldType.SHADOW) { if (Equals(e.Field.FieldType, FieldType.SHADOW)) {
accountForShadowChange = true; accountForShadowChange = true;
} }
} }

View file

@ -20,6 +20,7 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Runtime.Serialization; using System.Runtime.Serialization;
@ -37,52 +38,55 @@ namespace Greenshot.Drawing.Fields
public abstract class AbstractFieldHolder : IFieldHolder public abstract class AbstractFieldHolder : IFieldHolder
{ {
private static readonly ILog LOG = LogManager.GetLogger(typeof(AbstractFieldHolder)); private static readonly ILog LOG = LogManager.GetLogger(typeof(AbstractFieldHolder));
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
private readonly IDictionary<IField, PropertyChangedEventHandler> _handlers = new Dictionary<IField, PropertyChangedEventHandler>();
/// <summary> /// <summary>
/// called when a field's value has changed /// called when a field's value has changed
/// </summary> /// </summary>
[NonSerialized] [NonSerialized]
private FieldChangedEventHandler fieldChanged; private FieldChangedEventHandler _fieldChanged;
public event FieldChangedEventHandler FieldChanged public event FieldChangedEventHandler FieldChanged
{ {
add { fieldChanged += value; } add { _fieldChanged += value; }
remove { fieldChanged -= value; } remove { _fieldChanged -= value; }
} }
// we keep two Collections of our fields, dictionary for quick access, list for serialization // we keep two Collections of our fields, dictionary for quick access, list for serialization
// this allows us to use default serialization // this allows us to use default serialization
[NonSerialized] [NonSerialized]
private IDictionary<IFieldType, IField> fieldsByType = new Dictionary<IFieldType, IField>(); private IDictionary<IFieldType, IField> _fieldsByType = new Dictionary<IFieldType, IField>();
private IList<IField> fields = new List<IField>(); private readonly IList<IField> fields = new List<IField>();
public AbstractFieldHolder() { }
[OnDeserialized] [OnDeserialized]
private void OnDeserialized(StreamingContext context) private void OnDeserialized(StreamingContext context)
{ {
fieldsByType = new Dictionary<IFieldType, IField>(); _fieldsByType = new Dictionary<IFieldType, IField>();
// listen to changing properties // listen to changing properties
foreach (Field field in fields) foreach (var field in fields)
{ {
field.PropertyChanged += delegate { field.PropertyChanged += delegate {
if (fieldChanged != null) _fieldChanged?.Invoke(this, new FieldChangedEventArgs(field));
{
fieldChanged(this, new FieldChangedEventArgs(field));
}
}; };
fieldsByType[field.FieldType] = field; _fieldsByType[field.FieldType] = field;
} }
} }
public void AddField(Type requestingType, IFieldType fieldType, object fieldValue) public void AddField(Type requestingType, IFieldType fieldType, object fieldValue)
{ {
AddField(editorConfiguration.CreateField(requestingType, fieldType, fieldValue)); AddField(EditorConfig.CreateField(requestingType, fieldType, fieldValue));
} }
public virtual void AddField(IField field) public virtual void AddField(IField field)
{ {
if (fieldsByType != null && fieldsByType.ContainsKey(field.FieldType)) fields.Add(field);
if (_fieldsByType == null)
{
return;
}
if (_fieldsByType.ContainsKey(field.FieldType))
{ {
if (LOG.IsDebugEnabled) if (LOG.IsDebugEnabled)
{ {
@ -90,21 +94,21 @@ namespace Greenshot.Drawing.Fields
} }
} }
fields.Add(field); _fieldsByType[field.FieldType] = field;
fieldsByType[field.FieldType] = field;
field.PropertyChanged += delegate { if (fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); }; _handlers[field] = (sender, args) =>
{
_fieldChanged?.Invoke(this, new FieldChangedEventArgs(field));
};
field.PropertyChanged += _handlers[field];
} }
public void RemoveField(IField field) public void RemoveField(IField field)
{ {
fields.Remove(field); fields.Remove(field);
fieldsByType.Remove(field.FieldType); _fieldsByType.Remove(field.FieldType);
field.PropertyChanged -= delegate { field.PropertyChanged -= _handlers[field];
if (fieldChanged != null) _handlers.Remove(field);
{
fieldChanged(this, new FieldChangedEventArgs(field));
}
};
} }
public IList<IField> GetFields() public IList<IField> GetFields()
@ -117,7 +121,7 @@ namespace Greenshot.Drawing.Fields
{ {
try try
{ {
return fieldsByType[fieldType]; return _fieldsByType[fieldType];
} }
catch (KeyNotFoundException e) catch (KeyNotFoundException e)
{ {
@ -169,19 +173,19 @@ namespace Greenshot.Drawing.Fields
public bool HasField(IFieldType fieldType) public bool HasField(IFieldType fieldType)
{ {
return fieldsByType.ContainsKey(fieldType); return _fieldsByType.ContainsKey(fieldType);
} }
public bool HasFieldValue(IFieldType fieldType) public bool HasFieldValue(IFieldType fieldType)
{ {
return HasField(fieldType) && fieldsByType[fieldType].HasValue; return HasField(fieldType) && _fieldsByType[fieldType].HasValue;
} }
public void SetFieldValue(IFieldType fieldType, object value) public void SetFieldValue(IFieldType fieldType, object value)
{ {
try try
{ {
fieldsByType[fieldType].Value = value; _fieldsByType[fieldType].Value = value;
} }
catch (KeyNotFoundException e) catch (KeyNotFoundException e)
{ {
@ -191,10 +195,7 @@ namespace Greenshot.Drawing.Fields
protected void OnFieldChanged(object sender, FieldChangedEventArgs e) protected void OnFieldChanged(object sender, FieldChangedEventArgs e)
{ {
if (fieldChanged != null) _fieldChanged?.Invoke(sender, e);
{
fieldChanged(sender, e);
}
} }
} }
} }

View file

@ -34,7 +34,7 @@ namespace Greenshot.Drawing.Fields
[Serializable()] [Serializable()]
public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder
{ {
private FieldChangedEventHandler fieldChangedEventHandler; private readonly FieldChangedEventHandler _fieldChangedEventHandler;
[NonSerialized] [NonSerialized]
private EventHandler childrenChanged; private EventHandler childrenChanged;
@ -48,7 +48,7 @@ namespace Greenshot.Drawing.Fields
public AbstractFieldHolderWithChildren() public AbstractFieldHolderWithChildren()
{ {
fieldChangedEventHandler = OnFieldChanged; _fieldChangedEventHandler = OnFieldChanged;
} }
[OnDeserialized()] [OnDeserialized()]
@ -57,28 +57,28 @@ namespace Greenshot.Drawing.Fields
// listen to changing properties // listen to changing properties
foreach (IFieldHolder fieldHolder in Children) foreach (IFieldHolder fieldHolder in Children)
{ {
fieldHolder.FieldChanged += fieldChangedEventHandler; fieldHolder.FieldChanged += _fieldChangedEventHandler;
} }
if (childrenChanged != null) childrenChanged(this, EventArgs.Empty); childrenChanged?.Invoke(this, EventArgs.Empty);
} }
public void AddChild(IFieldHolder fieldHolder) public void AddChild(IFieldHolder fieldHolder)
{ {
Children.Add(fieldHolder); Children.Add(fieldHolder);
fieldHolder.FieldChanged += fieldChangedEventHandler; fieldHolder.FieldChanged += _fieldChangedEventHandler;
if (childrenChanged != null) childrenChanged(this, EventArgs.Empty); childrenChanged?.Invoke(this, EventArgs.Empty);
} }
public void RemoveChild(IFieldHolder fieldHolder) public void RemoveChild(IFieldHolder fieldHolder)
{ {
Children.Remove(fieldHolder); Children.Remove(fieldHolder);
fieldHolder.FieldChanged -= fieldChangedEventHandler; fieldHolder.FieldChanged -= _fieldChangedEventHandler;
if (childrenChanged != null) childrenChanged(this, EventArgs.Empty); childrenChanged?.Invoke(this, EventArgs.Empty);
} }
public new IList<IField> GetFields() public new IList<IField> GetFields()
{ {
List<IField> ret = new List<IField>(); var ret = new List<IField>();
ret.AddRange(base.GetFields()); ret.AddRange(base.GetFields());
foreach (IFieldHolder fh in Children) foreach (IFieldHolder fh in Children)
{ {

View file

@ -129,7 +129,7 @@ namespace Greenshot.Drawing.Fields.Binding {
targetPropertyInfo.SetValue(targetObject, bValue, null); targetPropertyInfo.SetValue(targetObject, bValue, null);
} }
} catch (Exception e) { } catch (Exception e) {
throw new MemberAccessException("Could not set property '"+targetProperty+"' to '"+bValue+"' ["+(bValue!=null?bValue.GetType().Name:"")+"] on "+targetObject+". Probably other type than expected, IBindingCoverter to the rescue.", e); throw new MemberAccessException("Could not set property '"+targetProperty+"' to '"+bValue+"' ["+(bValue?.GetType().Name ?? "")+"] on "+targetObject+". Probably other type than expected, IBindingCoverter to the rescue.", e);
} }
} }

View file

@ -47,10 +47,7 @@ namespace Greenshot.Drawing.Fields
if (!Equals(_myValue, value)) if (!Equals(_myValue, value))
{ {
_myValue = value; _myValue = value;
if (PropertyChanged != null) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
{
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
} }
} }
} }
@ -93,10 +90,7 @@ namespace Greenshot.Drawing.Fields
/// <summary> /// <summary>
/// Returns true if this field holds a value other than null. /// Returns true if this field holds a value other than null.
/// </summary> /// </summary>
public bool HasValue public bool HasValue => Value != null;
{
get { return Value != null; }
}
/// <summary> /// <summary>
/// Creates a flat clone of this Field. The fields value itself is not cloned. /// Creates a flat clone of this Field. The fields value itself is not cloned.
@ -104,9 +98,7 @@ namespace Greenshot.Drawing.Fields
/// <returns></returns> /// <returns></returns>
public Field Clone() public Field Clone()
{ {
Field ret = new Field(FieldType, Scope); return new Field(FieldType, Scope) {Value = Value};
ret.Value = Value;
return ret;
} }
public override int GetHashCode() public override int GetHashCode()
@ -123,7 +115,7 @@ namespace Greenshot.Drawing.Fields
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
Field other = obj as Field; var other = obj as Field;
if (other == null) if (other == null)
{ {
return false; return false;

View file

@ -24,7 +24,6 @@ using Greenshot.IniFile;
using Greenshot.Plugin; using Greenshot.Plugin;
using Greenshot.Plugin.Drawing; using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
using log4net;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@ -41,26 +40,25 @@ namespace Greenshot.Drawing.Fields
/// Properties that do not apply for ALL selected elements are null (or 0 respectively) /// Properties that do not apply for ALL selected elements are null (or 0 respectively)
/// If the property values of the selected elements differ, the value of the last bound element wins. /// If the property values of the selected elements differ, the value of the last bound element wins.
/// </summary> /// </summary>
public class FieldAggregator : AbstractFieldHolder public sealed class FieldAggregator : AbstractFieldHolder
{ {
private IDrawableContainerList boundContainers; private readonly IDrawableContainerList _boundContainers;
private bool internalUpdateRunning = false; private bool _internalUpdateRunning;
private enum Status { IDLE, BINDING, UPDATING }; private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
private static readonly ILog LOG = LogManager.GetLogger(typeof(FieldAggregator));
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
public FieldAggregator(ISurface parent) public FieldAggregator(ISurface parent)
{ {
foreach (FieldType fieldType in FieldType.Values) foreach (var fieldType in FieldType.Values)
{ {
Field field = new Field(fieldType, GetType()); var field = new Field(fieldType, GetType());
AddField(field); AddField(field);
} }
boundContainers = new DrawableContainerList(); _boundContainers = new DrawableContainerList
boundContainers.Parent = parent; {
Parent = parent
};
} }
public override void AddField(IField field) public override void AddField(IField field)
@ -71,7 +69,7 @@ namespace Greenshot.Drawing.Fields
public void BindElements(IDrawableContainerList dcs) public void BindElements(IDrawableContainerList dcs)
{ {
foreach (DrawableContainer dc in dcs) foreach (var dc in dcs)
{ {
BindElement(dc); BindElement(dc);
} }
@ -80,14 +78,15 @@ namespace Greenshot.Drawing.Fields
public void BindElement(IDrawableContainer dc) public void BindElement(IDrawableContainer dc)
{ {
DrawableContainer container = dc as DrawableContainer; DrawableContainer container = dc as DrawableContainer;
if (container != null && !boundContainers.Contains(container)) if (container == null || _boundContainers.Contains(container))
{ {
boundContainers.Add(container); return;
container.ChildrenChanged += delegate {
UpdateFromBoundElements();
};
UpdateFromBoundElements();
} }
_boundContainers.Add(container);
container.ChildrenChanged += delegate {
UpdateFromBoundElements();
};
UpdateFromBoundElements();
} }
public void BindAndUpdateElement(IDrawableContainer dc) public void BindAndUpdateElement(IDrawableContainer dc)
@ -103,8 +102,8 @@ namespace Greenshot.Drawing.Fields
{ {
return; return;
} }
internalUpdateRunning = true; _internalUpdateRunning = true;
foreach (Field field in GetFields()) foreach (var field in GetFields())
{ {
if (container.HasField(field.FieldType) && field.HasValue) if (container.HasField(field.FieldType) && field.HasValue)
{ {
@ -112,14 +111,14 @@ namespace Greenshot.Drawing.Fields
container.SetFieldValue(field.FieldType, field.Value); container.SetFieldValue(field.FieldType, field.Value);
} }
} }
internalUpdateRunning = false; _internalUpdateRunning = false;
} }
public void UnbindElement(IDrawableContainer dc) public void UnbindElement(IDrawableContainer dc)
{ {
if (boundContainers.Contains(dc)) if (_boundContainers.Contains(dc))
{ {
boundContainers.Remove(dc); _boundContainers.Remove(dc);
UpdateFromBoundElements(); UpdateFromBoundElements();
} }
} }
@ -127,7 +126,7 @@ namespace Greenshot.Drawing.Fields
public void Clear() public void Clear()
{ {
ClearFields(); ClearFields();
boundContainers.Clear(); _boundContainers.Clear();
UpdateFromBoundElements(); UpdateFromBoundElements();
} }
@ -136,12 +135,12 @@ namespace Greenshot.Drawing.Fields
/// </summary> /// </summary>
private void ClearFields() private void ClearFields()
{ {
internalUpdateRunning = true; _internalUpdateRunning = true;
foreach (Field field in GetFields()) foreach (var field in GetFields())
{ {
field.Value = null; field.Value = null;
} }
internalUpdateRunning = false; _internalUpdateRunning = false;
} }
/// <summary> /// <summary>
@ -152,27 +151,27 @@ namespace Greenshot.Drawing.Fields
private void UpdateFromBoundElements() private void UpdateFromBoundElements()
{ {
ClearFields(); ClearFields();
internalUpdateRunning = true; _internalUpdateRunning = true;
foreach (var field in FindCommonFields()) foreach (var field in FindCommonFields())
{ {
SetFieldValue(field.FieldType, field.Value); SetFieldValue(field.FieldType, field.Value);
} }
internalUpdateRunning = false; _internalUpdateRunning = false;
} }
private IList<IField> FindCommonFields() private IList<IField> FindCommonFields()
{ {
IList<IField> returnFields = null; IList<IField> returnFields = null;
if (boundContainers.Count > 0) if (_boundContainers.Count > 0)
{ {
// take all fields from the least selected container... // take all fields from the least selected container...
DrawableContainer leastSelectedContainer = boundContainers[boundContainers.Count - 1] as DrawableContainer; DrawableContainer leastSelectedContainer = _boundContainers[_boundContainers.Count - 1] as DrawableContainer;
if (leastSelectedContainer != null) if (leastSelectedContainer != null)
{ {
returnFields = leastSelectedContainer.GetFields(); returnFields = leastSelectedContainer.GetFields();
for (int i = 0; i < boundContainers.Count - 1; i++) for (int i = 0; i < _boundContainers.Count - 1; i++)
{ {
DrawableContainer dc = boundContainers[i] as DrawableContainer; DrawableContainer dc = _boundContainers[i] as DrawableContainer;
if (dc != null) if (dc != null)
{ {
IList<IField> fieldsToRemove = new List<IField>(); IList<IField> fieldsToRemove = new List<IField>();
@ -184,7 +183,7 @@ namespace Greenshot.Drawing.Fields
fieldsToRemove.Add(field); fieldsToRemove.Add(field);
} }
} }
foreach (IField field in fieldsToRemove) foreach (var field in fieldsToRemove)
{ {
returnFields.Remove(field); returnFields.Remove(field);
} }
@ -192,31 +191,30 @@ namespace Greenshot.Drawing.Fields
} }
} }
} }
if (returnFields == null) return returnFields ?? new List<IField>();
{
returnFields = new List<IField>();
}
return returnFields;
} }
public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea) public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea)
{ {
IField field = (IField)sender; IField field = (IField)sender;
if (!internalUpdateRunning && field.Value != null) if (_internalUpdateRunning || field.Value == null)
{ {
foreach (DrawableContainer drawableContainer in boundContainers) return;
}
foreach (var drawableContainer1 in _boundContainers)
{
var drawableContainer = (DrawableContainer) drawableContainer1;
if (!drawableContainer.HasField(field.FieldType))
{ {
if (drawableContainer.HasField(field.FieldType)) continue;
{
IField drawableContainerField = drawableContainer.GetField(field.FieldType);
// Notify before change, so we can e.g. invalidate the area
drawableContainer.BeforeFieldChange(drawableContainerField, field.Value);
drawableContainerField.Value = field.Value;
// update last used from DC field, so that scope is honored
editorConfiguration.UpdateLastFieldValue(drawableContainerField);
}
} }
IField drawableContainerField = drawableContainer.GetField(field.FieldType);
// Notify before change, so we can e.g. invalidate the area
drawableContainer.BeforeFieldChange(drawableContainerField, field.Value);
drawableContainerField.Value = field.Value;
// update last used from DC field, so that scope is honored
EditorConfig.UpdateLastFieldValue(drawableContainerField);
} }
} }

View file

@ -72,10 +72,9 @@ namespace Greenshot.Drawing.Filters {
public abstract void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode); public abstract void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode);
protected void OnPropertyChanged(string propertyName) { protected void OnPropertyChanged(string propertyName)
if (propertyChanged != null) { {
propertyChanged(this, new PropertyChangedEventArgs(propertyName)); propertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }
} }

View file

@ -34,7 +34,7 @@ namespace Greenshot.Drawing {
/// </summary> /// </summary>
[Serializable] [Serializable]
public class FreehandContainer : DrawableContainer { public class FreehandContainer : DrawableContainer {
private static readonly float [] POINT_OFFSET = new float[]{0.5f, 0.25f, 0.75f}; private static readonly float [] PointOffset = {0.5f, 0.25f, 0.75f};
[NonSerialized] [NonSerialized]
private GraphicsPath freehandPath = new GraphicsPath(); private GraphicsPath freehandPath = new GraphicsPath();
@ -77,10 +77,9 @@ namespace Greenshot.Drawing {
/// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param> /// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param>
protected override void Dispose(bool disposing) { protected override void Dispose(bool disposing) {
base.Dispose(disposing); base.Dispose(disposing);
if (disposing) { if (disposing)
if (freehandPath != null) { {
freehandPath.Dispose(); freehandPath?.Dispose();
}
} }
freehandPath = null; freehandPath = null;
} }
@ -133,9 +132,7 @@ namespace Greenshot.Drawing {
private void RecalculatePath() { private void RecalculatePath() {
isRecalculated = true; isRecalculated = true;
// Dispose the previous path, if we have one // Dispose the previous path, if we have one
if (freehandPath != null) { freehandPath?.Dispose();
freehandPath.Dispose();
}
freehandPath = new GraphicsPath(); freehandPath = new GraphicsPath();
// Here we can put some cleanup... like losing all the uninteresting points. // Here we can put some cleanup... like losing all the uninteresting points.
@ -143,7 +140,7 @@ namespace Greenshot.Drawing {
int index = 0; int index = 0;
while ((capturePoints.Count - 1) % 3 != 0) { while ((capturePoints.Count - 1) % 3 != 0) {
// duplicate points, first at 50% than 25% than 75% // duplicate points, first at 50% than 25% than 75%
capturePoints.Insert((int)(capturePoints.Count*POINT_OFFSET[index]), capturePoints[(int)(capturePoints.Count*POINT_OFFSET[index++])]); capturePoints.Insert((int)(capturePoints.Count*PointOffset[index]), capturePoints[(int)(capturePoints.Count*PointOffset[index++])]);
} }
freehandPath.AddBeziers(capturePoints.ToArray()); freehandPath.AddBeziers(capturePoints.ToArray());
} else if (capturePoints.Count == 2) { } else if (capturePoints.Count == 2) {
@ -228,9 +225,9 @@ namespace Greenshot.Drawing {
/// <returns></returns> /// <returns></returns>
public override bool Equals(object obj) { public override bool Equals(object obj) {
bool ret = false; bool ret = false;
if(obj != null && GetType().Equals(obj.GetType())) { if(obj != null && GetType() == obj.GetType()) {
FreehandContainer other = obj as FreehandContainer; FreehandContainer other = obj as FreehandContainer;
if(freehandPath.Equals(other.freehandPath)) { if(other != null && freehandPath.Equals(other.freehandPath)) {
ret = true; ret = true;
} }
} }

View file

@ -57,7 +57,7 @@ namespace Greenshot.Drawing {
if (!sender.Equals(this)) { if (!sender.Equals(this)) {
return; return;
} }
if (e.Field.FieldType == FieldType.PREPARED_FILTER_HIGHLIGHT) { if (Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_HIGHLIGHT)) {
ConfigurePreparedFilters(); ConfigurePreparedFilters();
} }
} }
@ -72,12 +72,16 @@ namespace Greenshot.Drawing {
Add(new HighlightFilter(this)); Add(new HighlightFilter(this));
break; break;
case PreparedFilter.AREA_HIGHLIGHT: case PreparedFilter.AREA_HIGHLIGHT:
AbstractFilter bf = new BrightnessFilter(this); var brightnessFilter = new BrightnessFilter(this)
bf.Invert = true; {
Add(bf); Invert = true
bf = new BlurFilter(this); };
bf.Invert = true; Add(brightnessFilter);
Add(bf); var blurFilter = new BlurFilter(this)
{
Invert = true
};
Add(blurFilter);
break; break;
case PreparedFilter.GRAYSCALE: case PreparedFilter.GRAYSCALE:
AbstractFilter f = new GrayscaleFilter(this); AbstractFilter f = new GrayscaleFilter(this);

View file

@ -32,7 +32,7 @@ namespace Greenshot.Drawing {
/// </summary> /// </summary>
[Serializable] [Serializable]
public class IconContainer : DrawableContainer, IIconContainer { public class IconContainer : DrawableContainer, IIconContainer {
private static readonly ILog LOG = LogManager.GetLogger(typeof(IconContainer)); private static readonly ILog Log = LogManager.GetLogger(typeof(IconContainer));
protected Icon icon; protected Icon icon;
@ -57,9 +57,7 @@ namespace Greenshot.Drawing {
public Icon Icon { public Icon Icon {
set { set {
if (icon != null) { icon?.Dispose();
icon.Dispose();
}
icon = (Icon)value.Clone(); icon = (Icon)value.Clone();
Width = value.Width; Width = value.Width;
Height = value.Height; Height = value.Height;
@ -72,10 +70,9 @@ namespace Greenshot.Drawing {
* When disposing==true all non-managed resources should be freed too! * When disposing==true all non-managed resources should be freed too!
*/ */
protected override void Dispose(bool disposing) { protected override void Dispose(bool disposing) {
if (disposing) { if (disposing)
if (icon != null) { {
icon.Dispose(); icon?.Dispose();
}
} }
icon = null; icon = null;
base.Dispose(disposing); base.Dispose(disposing);
@ -85,7 +82,7 @@ namespace Greenshot.Drawing {
if (File.Exists(filename)) { if (File.Exists(filename)) {
using (Icon fileIcon = new Icon(filename)) { using (Icon fileIcon = new Icon(filename)) {
Icon = fileIcon; Icon = fileIcon;
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width); Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
} }
} }
} }
@ -100,16 +97,8 @@ namespace Greenshot.Drawing {
} }
} }
public override bool HasDefaultSize { public override bool HasDefaultSize => true;
get {
return true;
}
}
public override Size DefaultSize { public override Size DefaultSize => icon.Size;
get {
return icon.Size;
}
}
} }
} }

View file

@ -28,6 +28,7 @@ using System.Drawing.Drawing2D;
using Greenshot.Core; using Greenshot.Core;
using log4net; using log4net;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using GreenshotPlugin.Effects;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Drawing { namespace Greenshot.Drawing {

View file

@ -52,7 +52,7 @@ namespace Greenshot.Drawing {
protected void ObfuscateContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) { protected void ObfuscateContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) {
if(sender.Equals(this)) { if(sender.Equals(this)) {
if(e.Field.FieldType == FieldType.PREPARED_FILTER_OBFUSCATE) { if(Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_OBFUSCATE)) {
ConfigurePreparedFilters(); ConfigurePreparedFilters();
} }
} }

View file

@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
@ -27,6 +28,7 @@ namespace Greenshot.Drawing {
/// TODO: currently this is only used in the capture form, we might move this code directly to there! /// TODO: currently this is only used in the capture form, we might move this code directly to there!
/// </summary> /// </summary>
public abstract class RoundedRectangle { public abstract class RoundedRectangle {
[Flags]
public enum RectangleCorners { public enum RectangleCorners {
None = 0, TopLeft = 1, TopRight = 2, None = 0, TopLeft = 1, TopRight = 2,
BottomLeft = 4, BottomRight = 8, BottomLeft = 4, BottomRight = 8,

View file

@ -84,9 +84,11 @@ namespace Greenshot.Drawing {
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext context)
{ {
Init(); Init();
_stringFormat = new StringFormat(); _stringFormat = new StringFormat
_stringFormat.Alignment = StringAlignment.Center; {
_stringFormat.LineAlignment = StringAlignment.Center; Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
} }
/// <summary> /// <summary>
@ -98,20 +100,14 @@ namespace Greenshot.Drawing {
{ {
return; return;
} }
if (Parent != null) { ((Surface) Parent)?.RemoveStepLabel(this);
((Surface)Parent).RemoveStepLabel(this);
}
base.SwitchParent(newParent); base.SwitchParent(newParent);
if (newParent != null) { if (newParent != null) {
((Surface)Parent)?.AddStepLabel(this); ((Surface)Parent)?.AddStepLabel(this);
} }
} }
public override Size DefaultSize { public override Size DefaultSize => new Size(30, 30);
get {
return new Size(30, 30);
}
}
public override bool InitContent() { public override bool InitContent() {
_defaultEditMode = EditStatus.IDLE; _defaultEditMode = EditStatus.IDLE;
@ -148,14 +144,13 @@ namespace Greenshot.Drawing {
if (!disposing) { if (!disposing) {
return; return;
} }
if (Parent != null) ((Surface) Parent)?.RemoveStepLabel(this);
if (_stringFormat == null)
{ {
((Surface)Parent).RemoveStepLabel(this); return;
}
if (_stringFormat != null) {
_stringFormat.Dispose();
_stringFormat = null;
} }
_stringFormat.Dispose();
_stringFormat = null;
} }
public override bool HandleMouseMove(int x, int y) { public override bool HandleMouseMove(int x, int y) {

View file

@ -40,6 +40,7 @@ using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms; using System.Windows.Forms;
using GreenshotPlugin.Effects;
namespace Greenshot.Drawing namespace Greenshot.Drawing
{ {
@ -48,9 +49,9 @@ namespace Greenshot.Drawing
/// </summary> /// </summary>
public sealed class Surface : Control, ISurface public sealed class Surface : Control, ISurface
{ {
private static ILog LOG = LogManager.GetLogger(typeof(Surface)); private static readonly ILog LOG = LogManager.GetLogger(typeof(Surface));
public static int Count = 0; public static int Count;
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
// Property to identify the Surface ID // Property to identify the Surface ID
private Guid _uniqueId = Guid.NewGuid(); private Guid _uniqueId = Guid.NewGuid();
@ -276,11 +277,6 @@ namespace Greenshot.Drawing
/// </summary> /// </summary>
private IDrawableContainer _cursorContainer; private IDrawableContainer _cursorContainer;
/// <summary>
/// the capture details, needed with serialization
/// </summary>
private ICaptureDetails _captureDetails;
/// <summary> /// <summary>
/// the modified flag specifies if the surface has had modifications after the last export. /// the modified flag specifies if the surface has had modifications after the last export.
/// Initial state is modified, as "it's not saved" /// Initial state is modified, as "it's not saved"
@ -325,31 +321,19 @@ namespace Greenshot.Drawing
/// <summary> /// <summary>
/// The cursor container has it's own accessor so we can find and remove this (when needed) /// The cursor container has it's own accessor so we can find and remove this (when needed)
/// </summary> /// </summary>
public IDrawableContainer CursorContainer public IDrawableContainer CursorContainer => _cursorContainer;
{
get
{
return _cursorContainer;
}
}
/// <summary> /// <summary>
/// A simple getter to ask if this surface has a cursor /// A simple getter to ask if this surface has a cursor
/// </summary> /// </summary>
public bool HasCursor public bool HasCursor => _cursorContainer != null;
{
get
{
return _cursorContainer != null;
}
}
/// <summary> /// <summary>
/// A simple helper method to remove the cursor from the surface /// A simple helper method to remove the cursor from the surface
/// </summary> /// </summary>
public void RemoveCursor() public void RemoveCursor()
{ {
RemoveElement(_cursorContainer, true); RemoveElement(_cursorContainer);
_cursorContainer = null; _cursorContainer = null;
} }
@ -409,8 +393,10 @@ namespace Greenshot.Drawing
_drawingMode = value; _drawingMode = value;
if (_drawingModeChanged != null) if (_drawingModeChanged != null)
{ {
SurfaceDrawingModeEventArgs eventArgs = new SurfaceDrawingModeEventArgs(); SurfaceDrawingModeEventArgs eventArgs = new SurfaceDrawingModeEventArgs
eventArgs.DrawingMode = _drawingMode; {
DrawingMode = _drawingMode
};
_drawingModeChanged.Invoke(this, eventArgs); _drawingModeChanged.Invoke(this, eventArgs);
} }
DeselectAllElements(); DeselectAllElements();
@ -445,22 +431,12 @@ namespace Greenshot.Drawing
/// <summary> /// <summary>
/// Property for accessing the capture details /// Property for accessing the capture details
/// </summary> /// </summary>
public ICaptureDetails CaptureDetails public ICaptureDetails CaptureDetails { get; set; }
{
get
{
return _captureDetails;
}
set
{
_captureDetails = value;
}
}
/// <summary> /// <summary>
/// Base Surface constructor /// Base Surface constructor
/// </summary> /// </summary>
public Surface() : base() public Surface()
{ {
_fieldAggregator = new FieldAggregator(this); _fieldAggregator = new FieldAggregator(this);
Count++; Count++;
@ -537,7 +513,7 @@ namespace Greenshot.Drawing
// Make sure the image is NOT disposed, we took the reference directly into ourselves // Make sure the image is NOT disposed, we took the reference directly into ourselves
((Capture)capture).NullImage(); ((Capture)capture).NullImage();
_captureDetails = capture.CaptureDetails; CaptureDetails = capture.CaptureDetails;
} }
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
@ -615,46 +591,22 @@ namespace Greenshot.Drawing
/// <summary> /// <summary>
/// Returns if the surface can do a undo /// Returns if the surface can do a undo
/// </summary> /// </summary>
public bool CanUndo public bool CanUndo => _undoStack.Count > 0;
{
get
{
return _undoStack.Count > 0;
}
}
/// <summary> /// <summary>
/// Returns if the surface can do a redo /// Returns if the surface can do a redo
/// </summary> /// </summary>
public bool CanRedo public bool CanRedo => _redoStack.Count > 0;
{
get
{
return _redoStack.Count > 0;
}
}
/// <summary> /// <summary>
/// Get the language key for the undo action /// Get the language key for the undo action
/// </summary> /// </summary>
public LangKey UndoActionLanguageKey public LangKey UndoActionLanguageKey => LangKey.none;
{
get
{
return LangKey.none;
}
}
/// <summary> /// <summary>
/// Get the language key for redo action /// Get the language key for redo action
/// </summary> /// </summary>
public LangKey RedoActionLanguageKey public LangKey RedoActionLanguageKey => LangKey.none;
{
get
{
return LangKey.none;
}
}
/// <summary> /// <summary>
/// Make an action undo-able /// Make an action undo-able
@ -722,9 +674,7 @@ namespace Greenshot.Drawing
IDrawableContainerList loadedElements = (IDrawableContainerList)binaryRead.Deserialize(streamRead); IDrawableContainerList loadedElements = (IDrawableContainerList)binaryRead.Deserialize(streamRead);
loadedElements.Parent = this; loadedElements.Parent = this;
// Make sure the steplabels are sorted accoring to their number // Make sure the steplabels are sorted accoring to their number
_stepLabels.Sort(delegate (StepLabelContainer p1, StepLabelContainer p2) { _stepLabels.Sort((p1, p2) => p1.Number.CompareTo(p2.Number));
return p1.Number.CompareTo(p2.Number);
});
DeselectAllElements(); DeselectAllElements();
AddElements(loadedElements); AddElements(loadedElements);
SelectElements(loadedElements); SelectElements(loadedElements);
@ -799,10 +749,12 @@ namespace Greenshot.Drawing
#region Plugin interface implementations #region Plugin interface implementations
public IImageContainer AddImageContainer(Image image, int x, int y) public IImageContainer AddImageContainer(Image image, int x, int y)
{ {
ImageContainer bitmapContainer = new ImageContainer(this); ImageContainer bitmapContainer = new ImageContainer(this)
bitmapContainer.Image = image; {
bitmapContainer.Left = x; Image = image,
bitmapContainer.Top = y; Left = x,
Top = y
};
AddElement(bitmapContainer); AddElement(bitmapContainer);
return bitmapContainer; return bitmapContainer;
} }
@ -818,10 +770,12 @@ namespace Greenshot.Drawing
} }
public IIconContainer AddIconContainer(Icon icon, int x, int y) public IIconContainer AddIconContainer(Icon icon, int x, int y)
{ {
IconContainer iconContainer = new IconContainer(this); IconContainer iconContainer = new IconContainer(this)
iconContainer.Icon = icon; {
iconContainer.Left = x; Icon = icon,
iconContainer.Top = y; Left = x,
Top = y
};
AddElement(iconContainer); AddElement(iconContainer);
return iconContainer; return iconContainer;
} }
@ -836,10 +790,12 @@ namespace Greenshot.Drawing
} }
public ICursorContainer AddCursorContainer(Cursor cursor, int x, int y) public ICursorContainer AddCursorContainer(Cursor cursor, int x, int y)
{ {
CursorContainer cursorContainer = new CursorContainer(this); CursorContainer cursorContainer = new CursorContainer(this)
cursorContainer.Cursor = cursor; {
cursorContainer.Left = x; Cursor = cursor,
cursorContainer.Top = y; Left = x,
Top = y
};
AddElement(cursorContainer); AddElement(cursorContainer);
return cursorContainer; return cursorContainer;
} }
@ -855,8 +811,7 @@ namespace Greenshot.Drawing
public ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor) public ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor)
{ {
TextContainer textContainer = new TextContainer(this); TextContainer textContainer = new TextContainer(this) {Text = text};
textContainer.Text = text;
textContainer.SetFieldValue(FieldType.FONT_FAMILY, family.Name); textContainer.SetFieldValue(FieldType.FONT_FAMILY, family.Name);
textContainer.SetFieldValue(FieldType.FONT_BOLD, bold); textContainer.SetFieldValue(FieldType.FONT_BOLD, bold);
textContainer.SetFieldValue(FieldType.FONT_ITALIC, italic); textContainer.SetFieldValue(FieldType.FONT_ITALIC, italic);
@ -1069,10 +1024,12 @@ namespace Greenshot.Drawing
{ {
if (_surfaceMessage != null) if (_surfaceMessage != null)
{ {
SurfaceMessageEventArgs eventArgs = new SurfaceMessageEventArgs(); var eventArgs = new SurfaceMessageEventArgs
eventArgs.Message = message; {
eventArgs.MessageType = messageType; Message = message,
eventArgs.Surface = this; MessageType = messageType,
Surface = this
};
_surfaceMessage(source, eventArgs); _surfaceMessage(source, eventArgs);
} }
} }
@ -1133,10 +1090,7 @@ namespace Greenshot.Drawing
{ {
_elements.Transform(matrix); _elements.Transform(matrix);
} }
if (_surfaceSizeChanged != null) _surfaceSizeChanged?.Invoke(this, null);
{
_surfaceSizeChanged(this, null);
}
Invalidate(); Invalidate();
} }
/// <summary> /// <summary>
@ -1196,8 +1150,7 @@ namespace Greenshot.Drawing
IDrawableContainer rightClickedContainer = _elements.ClickableElementAt(_mouseStart.X, _mouseStart.Y); IDrawableContainer rightClickedContainer = _elements.ClickableElementAt(_mouseStart.X, _mouseStart.Y);
if (rightClickedContainer != null) if (rightClickedContainer != null)
{ {
selectedList = new DrawableContainerList(ID); selectedList = new DrawableContainerList(ID) {rightClickedContainer};
selectedList.Add(rightClickedContainer);
} }
} }
if (selectedList != null && selectedList.Count > 0) if (selectedList != null && selectedList.Count > 0)
@ -1231,7 +1184,10 @@ namespace Greenshot.Drawing
// if a new element has been drawn, set location and register it // if a new element has been drawn, set location and register it
if (_drawingElement != null) if (_drawingElement != null)
{ {
_drawingElement.Status = _undrawnElement.DefaultEditMode; if (_undrawnElement != null)
{
_drawingElement.Status = _undrawnElement.DefaultEditMode;
}
if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y)) if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y))
{ {
_drawingElement.Left = _mouseStart.X; _drawingElement.Left = _mouseStart.X;
@ -1362,14 +1318,7 @@ namespace Greenshot.Drawing
Point currentMouse = e.Location; Point currentMouse = e.Location;
if (DrawingMode != DrawingModes.None) Cursor = DrawingMode != DrawingModes.None ? Cursors.Cross : Cursors.Default;
{
Cursor = Cursors.Cross;
}
else
{
Cursor = Cursors.Default;
}
if (_mouseDown) if (_mouseDown)
{ {
@ -1597,8 +1546,7 @@ namespace Greenshot.Drawing
Invalidate(); Invalidate();
if (_movingElementChanged != null) if (_movingElementChanged != null)
{ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs {Elements = cloned};
eventArgs.Elements = cloned;
_movingElementChanged(this, eventArgs); _movingElementChanged(this, eventArgs);
} }
} }
@ -1663,13 +1611,7 @@ namespace Greenshot.Drawing
/// Returns if this surface has selected elements /// Returns if this surface has selected elements
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool HasSelectedElements public bool HasSelectedElements => (selectedElements != null && selectedElements.Count > 0);
{
get
{
return (selectedElements != null && selectedElements.Count > 0);
}
}
/// <summary> /// <summary>
/// Remove all the selected elements /// Remove all the selected elements
@ -1764,29 +1706,14 @@ namespace Greenshot.Drawing
if (dcs != null) if (dcs != null)
{ {
// Make element(s) only move 10,10 if the surface is the same // Make element(s) only move 10,10 if the surface is the same
Point moveOffset;
bool isSameSurface = (dcs.ParentID == _uniqueId); bool isSameSurface = (dcs.ParentID == _uniqueId);
dcs.Parent = this; dcs.Parent = this;
if (isSameSurface) var moveOffset = isSameSurface ? new Point(10, 10) : Point.Empty;
{
moveOffset = new Point(10, 10);
}
else
{
moveOffset = Point.Empty;
}
// Here a fix for bug #1475, first calculate the bounds of the complete IDrawableContainerList // Here a fix for bug #1475, first calculate the bounds of the complete IDrawableContainerList
Rectangle drawableContainerListBounds = Rectangle.Empty; Rectangle drawableContainerListBounds = Rectangle.Empty;
foreach (IDrawableContainer element in dcs) foreach (var element in dcs)
{ {
if (drawableContainerListBounds == Rectangle.Empty) drawableContainerListBounds = drawableContainerListBounds == Rectangle.Empty ? element.DrawingBounds : Rectangle.Union(drawableContainerListBounds, element.DrawingBounds);
{
drawableContainerListBounds = element.DrawingBounds;
}
else
{
drawableContainerListBounds = Rectangle.Union(drawableContainerListBounds, element.DrawingBounds);
}
} }
// And find a location inside the target surface to paste to // And find a location inside the target surface to paste to
bool containersCanFit = drawableContainerListBounds.Width < Bounds.Width && drawableContainerListBounds.Height < Bounds.Height; bool containersCanFit = drawableContainerListBounds.Width < Bounds.Width && drawableContainerListBounds.Height < Bounds.Height;
@ -1797,15 +1724,7 @@ namespace Greenshot.Drawing
if (!Bounds.Contains(containersLocation)) if (!Bounds.Contains(containersLocation))
{ {
// Easy fix for same surface // Easy fix for same surface
if (isSameSurface) moveOffset = isSameSurface ? new Point(-10, -10) : new Point(-drawableContainerListBounds.Location.X + 10, -drawableContainerListBounds.Location.Y + 10);
{
moveOffset = new Point(-10, -10);
}
else
{
// For different surface, which is most likely smaller, we move to "10,10"
moveOffset = new Point(-drawableContainerListBounds.Location.X + 10, -drawableContainerListBounds.Location.Y + 10);
}
} }
} }
else else
@ -1932,8 +1851,10 @@ namespace Greenshot.Drawing
} }
if (_movingElementChanged != null) if (_movingElementChanged != null)
{ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs
eventArgs.Elements = selectedElements; {
Elements = selectedElements
};
_movingElementChanged(this, eventArgs); _movingElementChanged(this, eventArgs);
} }
Invalidate(); Invalidate();
@ -1962,8 +1883,10 @@ namespace Greenshot.Drawing
FieldAggregator.BindElement(container); FieldAggregator.BindElement(container);
if (generateEvents && _movingElementChanged != null) if (generateEvents && _movingElementChanged != null)
{ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs
eventArgs.Elements = selectedElements; {
Elements = selectedElements
};
_movingElementChanged(this, eventArgs); _movingElementChanged(this, eventArgs);
} }
if (invalidate) if (invalidate)
@ -1988,14 +1911,14 @@ namespace Greenshot.Drawing
public void SelectElements(IDrawableContainerList elements) public void SelectElements(IDrawableContainerList elements)
{ {
SuspendLayout(); SuspendLayout();
foreach (DrawableContainer element in elements) foreach (var drawableContainer in elements)
{ {
var element = (DrawableContainer) drawableContainer;
SelectElement(element, false, false); SelectElement(element, false, false);
} }
if (_movingElementChanged != null) if (_movingElementChanged != null)
{ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs(); SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs {Elements = selectedElements};
eventArgs.Elements = selectedElements;
_movingElementChanged(this, eventArgs); _movingElementChanged(this, eventArgs);
} }
ResumeLayout(); ResumeLayout();
@ -2070,13 +1993,7 @@ namespace Greenshot.Drawing
/// <summary> /// <summary>
/// Property for accessing the elements on the surface /// Property for accessing the elements on the surface
/// </summary> /// </summary>
public IDrawableContainerList Elements public IDrawableContainerList Elements => _elements;
{
get
{
return _elements;
}
}
/// <summary> /// <summary>
/// pulls selected elements up one level in hierarchy /// pulls selected elements up one level in hierarchy

View file

@ -26,6 +26,7 @@ using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Text; using System.Drawing.Text;
@ -321,47 +322,47 @@ namespace Greenshot.Drawing
UpdateFormat(); UpdateFormat();
} }
private Font CreateFont(string fontFamily, bool fontBold, bool fontItalic, float fontSize) private Font CreateFont(string fontFamilyName, bool fontBold, bool fontItalic, float fontSize)
{ {
FontStyle fs = FontStyle.Regular; FontStyle fontStyle = FontStyle.Regular;
bool hasStyle = false; bool hasStyle = false;
using (FontFamily fam = new FontFamily(fontFamily)) using (var fontFamily = new FontFamily(fontFamilyName))
{ {
bool boldAvailable = fam.IsStyleAvailable(FontStyle.Bold); bool boldAvailable = fontFamily.IsStyleAvailable(FontStyle.Bold);
if (fontBold && boldAvailable) if (fontBold && boldAvailable)
{ {
fs |= FontStyle.Bold; fontStyle |= FontStyle.Bold;
hasStyle = true; hasStyle = true;
} }
bool italicAvailable = fam.IsStyleAvailable(FontStyle.Italic); bool italicAvailable = fontFamily.IsStyleAvailable(FontStyle.Italic);
if (fontItalic && italicAvailable) if (fontItalic && italicAvailable)
{ {
fs |= FontStyle.Italic; fontStyle |= FontStyle.Italic;
hasStyle = true; hasStyle = true;
} }
if (!hasStyle) if (!hasStyle)
{ {
bool regularAvailable = fam.IsStyleAvailable(FontStyle.Regular); bool regularAvailable = fontFamily.IsStyleAvailable(FontStyle.Regular);
if (regularAvailable) if (regularAvailable)
{ {
fs = FontStyle.Regular; fontStyle = FontStyle.Regular;
} }
else else
{ {
if (boldAvailable) if (boldAvailable)
{ {
fs = FontStyle.Bold; fontStyle = FontStyle.Bold;
} }
else if (italicAvailable) else if (italicAvailable)
{ {
fs = FontStyle.Italic; fontStyle = FontStyle.Italic;
} }
} }
} }
return new Font(fam, fontSize, fs, GraphicsUnit.Pixel); return new Font(fontFamily, fontSize, fontStyle, GraphicsUnit.Pixel);
} }
} }
@ -400,7 +401,7 @@ namespace Greenshot.Drawing
catch (Exception) catch (Exception)
{ {
// When this happens... the PC is broken // When this happens... the PC is broken
ex.Data.Add("fontFamily", fontFamily); ex.Data.Add("fontFamilyName", fontFamily);
ex.Data.Add("fontBold", fontBold); ex.Data.Add("fontBold", fontBold);
ex.Data.Add("fontItalic", fontItalic); ex.Data.Add("fontItalic", fontItalic);
ex.Data.Add("fontSize", fontSize); ex.Data.Add("fontSize", fontSize);
@ -534,6 +535,14 @@ namespace Greenshot.Drawing
/// <param name="font"></param> /// <param name="font"></param>
public static void DrawText(Graphics graphics, Rectangle drawingRectange, int lineThickness, Color fontColor, bool drawShadow, StringFormat stringFormat, string text, Font font) public static void DrawText(Graphics graphics, Rectangle drawingRectange, int lineThickness, Color fontColor, bool drawShadow, StringFormat stringFormat, string text, Font font)
{ {
#if DEBUG
Debug.Assert(font != null);
#else
if (font == null)
{
return;
}
#endif
int textOffset = lineThickness > 0 ? (int)Math.Ceiling(lineThickness / 2d) : 0; int textOffset = lineThickness > 0 ? (int)Math.Ceiling(lineThickness / 2d) : 0;
// draw shadow before anything else // draw shadow before anything else
if (drawShadow) if (drawShadow)

View file

@ -152,7 +152,7 @@ namespace Greenshot {
Version v = Assembly.GetExecutingAssembly().GetName().Version; Version v = Assembly.GetExecutingAssembly().GetName().Version;
// Format is like this: AssemblyVersion("Major.Minor.Build.Revision")] // Format is like this: AssemblyVersion("Major.Minor.Build.Revision")]
lblTitle.Text = "Greenshot " + v.Major + "." + v.Minor + "." + v.Build + " Build " + v.Revision + (IniConfig.IsPortable ? " Portable" : "") + (" (" + OSInfo.Bits) + " bit)"; lblTitle.Text = "Greenshot " + v.Major + "." + v.Minor + "." + v.Build + " Build " + v.Revision + (IniConfig.IsPortable ? " Portable" : "") + (" (" + OsInfo.Bits) + " bit)";
//Random rand = new Random(); //Random rand = new Random();

View file

@ -43,7 +43,7 @@ namespace Greenshot.Forms {
public sealed partial class CaptureForm : AnimatingForm { public sealed partial class CaptureForm : AnimatingForm {
private enum FixMode {None, Initiated, Horizontal, Vertical}; private enum FixMode {None, Initiated, Horizontal, Vertical};
private static readonly ILog LOG = LogManager.GetLogger(typeof(CaptureForm)); private static readonly ILog Log = LogManager.GetLogger(typeof(CaptureForm));
private static readonly CoreConfiguration Conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration Conf = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly Brush GreenOverlayBrush = new SolidBrush(Color.FromArgb(50, Color.MediumSeaGreen)); private static readonly Brush GreenOverlayBrush = new SolidBrush(Color.FromArgb(50, Color.MediumSeaGreen));
private static readonly Pen OverlayPen = new Pen(Color.FromArgb(50, Color.Black)); private static readonly Pen OverlayPen = new Pen(Color.FromArgb(50, Color.Black));
@ -79,29 +79,17 @@ namespace Greenshot.Forms {
/// <summary> /// <summary>
/// Property to access the selected capture rectangle /// Property to access the selected capture rectangle
/// </summary> /// </summary>
public Rectangle CaptureRectangle { public Rectangle CaptureRectangle => _captureRect;
get {
return _captureRect;
}
}
/// <summary> /// <summary>
/// Property to access the used capture mode /// Property to access the used capture mode
/// </summary> /// </summary>
public CaptureMode UsedCaptureMode { public CaptureMode UsedCaptureMode => _captureMode;
get {
return _captureMode;
}
}
/// <summary> /// <summary>
/// Get the selected window /// Get the selected window
/// </summary> /// </summary>
public WindowDetails SelectedCaptureWindow { public WindowDetails SelectedCaptureWindow => _selectedCaptureWindow;
get {
return _selectedCaptureWindow;
}
}
/// <summary> /// <summary>
/// This should prevent childs to draw backgrounds /// This should prevent childs to draw backgrounds
@ -117,11 +105,11 @@ namespace Greenshot.Forms {
private void ClosedHandler(object sender, EventArgs e) { private void ClosedHandler(object sender, EventArgs e) {
_currentForm = null; _currentForm = null;
LOG.Debug("Remove CaptureForm from currentForm"); Log.Debug("Remove CaptureForm from currentForm");
} }
private void ClosingHandler(object sender, EventArgs e) { private void ClosingHandler(object sender, EventArgs e) {
LOG.Debug("Closing captureform"); Log.Debug("Closing captureform");
WindowDetails.UnregisterIgnoreHandle(Handle); WindowDetails.UnregisterIgnoreHandle(Handle);
} }
@ -132,7 +120,7 @@ namespace Greenshot.Forms {
/// <param name="windows"></param> /// <param name="windows"></param>
public CaptureForm(ICapture capture, List<WindowDetails> windows) { public CaptureForm(ICapture capture, List<WindowDetails> windows) {
if (_currentForm != null) { if (_currentForm != null) {
LOG.Warn("Found currentForm, Closing already opened CaptureForm"); Log.Warn("Found currentForm, Closing already opened CaptureForm");
_currentForm.Close(); _currentForm.Close();
_currentForm = null; _currentForm = null;
Application.DoEvents(); Application.DoEvents();
@ -190,8 +178,10 @@ namespace Greenshot.Forms {
// Initialize the zoom with a invalid position // Initialize the zoom with a invalid position
_zoomAnimator = new RectangleAnimator(Rectangle.Empty, new Rectangle(int.MaxValue, int.MaxValue, 0, 0), FramesForMillis(1000), EasingType.Quintic, EasingMode.EaseOut); _zoomAnimator = new RectangleAnimator(Rectangle.Empty, new Rectangle(int.MaxValue, int.MaxValue, 0, 0), FramesForMillis(1000), EasingType.Quintic, EasingMode.EaseOut);
VerifyZoomAnimation(_cursorPos, false); VerifyZoomAnimation(_cursorPos, false);
} else if (_zoomAnimator != null) { }
_zoomAnimator.ChangeDestination(new Rectangle(Point.Empty, Size.Empty), FramesForMillis(1000)); else
{
_zoomAnimator?.ChangeDestination(new Rectangle(Point.Empty, Size.Empty), FramesForMillis(1000));
} }
} }
@ -441,16 +431,14 @@ namespace Greenshot.Forms {
Point cursorPosition = Cursor.Position; Point cursorPosition = Cursor.Position;
_selectedCaptureWindow = null; _selectedCaptureWindow = null;
lock (_windows) { lock (_windows) {
foreach (WindowDetails window in _windows) { foreach (var window in _windows) {
if (window.Contains(cursorPosition)) { if (!window.Contains(cursorPosition))
// Only go over the children if we are in window mode {
if (CaptureMode.Window == _captureMode) { continue;
_selectedCaptureWindow = window.FindChildUnderPoint(cursorPosition);
} else {
_selectedCaptureWindow = window;
}
break;
} }
// Only go over the children if we are in window mode
_selectedCaptureWindow = CaptureMode.Window == _captureMode ? window.FindChildUnderPoint(cursorPosition) : window;
break;
} }
} }
@ -619,8 +607,10 @@ namespace Greenshot.Forms {
if (_isZoomerTransparent) { if (_isZoomerTransparent) {
//create a color matrix object to change the opacy //create a color matrix object to change the opacy
ColorMatrix opacyMatrix = new ColorMatrix(); ColorMatrix opacyMatrix = new ColorMatrix
opacyMatrix.Matrix33 = Conf.ZoomerOpacity; {
Matrix33 = Conf.ZoomerOpacity
};
attributes = new ImageAttributes(); attributes = new ImageAttributes();
attributes.SetColorMatrix(opacyMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); attributes.SetColorMatrix(opacyMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
} else { } else {
@ -695,9 +685,7 @@ namespace Greenshot.Forms {
// Horizontal middle + 1 to right // Horizontal middle + 1 to right
graphics.DrawRectangle(pen, destinationRectangle.X + halfWidthEnd + 2 * padding, drawAtHeight, halfWidthEnd - 2 * padding - 1, pixelThickness); graphics.DrawRectangle(pen, destinationRectangle.X + halfWidthEnd + 2 * padding, drawAtHeight, halfWidthEnd - 2 * padding - 1, pixelThickness);
} }
if (attributes != null) { attributes?.Dispose();
attributes.Dispose();
}
} }
/// <summary> /// <summary>
@ -718,14 +706,7 @@ namespace Greenshot.Forms {
if (_mouseDown || _captureMode == CaptureMode.Window || IsAnimating(_windowAnimator)) { if (_mouseDown || _captureMode == CaptureMode.Window || IsAnimating(_windowAnimator)) {
_captureRect.Intersect(new Rectangle(Point.Empty, _capture.ScreenBounds.Size)); // crop what is outside the screen _captureRect.Intersect(new Rectangle(Point.Empty, _capture.ScreenBounds.Size)); // crop what is outside the screen
Rectangle fixedRect; var fixedRect = IsAnimating(_windowAnimator) ? _windowAnimator.Current : _captureRect;
//if (captureMode == CaptureMode.Window) {
if (IsAnimating(_windowAnimator)) {
// Use the animator
fixedRect = _windowAnimator.Current;
} else {
fixedRect = _captureRect;
}
// TODO: enable when the screen capture code works reliable // TODO: enable when the screen capture code works reliable
//if (capture.CaptureDetails.CaptureMode == CaptureMode.Video) { //if (capture.CaptureDetails.CaptureMode == CaptureMode.Video) {
@ -827,7 +808,7 @@ namespace Greenshot.Forms {
if (_showDebugInfo && _selectedCaptureWindow != null) if (_showDebugInfo && _selectedCaptureWindow != null)
{ {
string title = string.Format("#{0:X} - {1}", _selectedCaptureWindow.Handle.ToInt64(), _selectedCaptureWindow.Text.Length > 0 ? _selectedCaptureWindow.Text : _selectedCaptureWindow.Process.ProcessName); string title = $"#{_selectedCaptureWindow.Handle.ToInt64():X} - {(_selectedCaptureWindow.Text.Length > 0 ? _selectedCaptureWindow.Text : _selectedCaptureWindow.Process.ProcessName)}";
PointF debugLocation = new PointF(fixedRect.X, fixedRect.Y); PointF debugLocation = new PointF(fixedRect.X, fixedRect.Y);
graphics.DrawString(title, sizeFont, Brushes.DarkOrange, debugLocation); graphics.DrawString(title, sizeFont, Brushes.DarkOrange, debugLocation);
} }

View file

@ -144,7 +144,7 @@ namespace Greenshot {
this.textBoxRed.TabIndex = 2; this.textBoxRed.TabIndex = 2;
this.textBoxRed.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxRed.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxRed.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxRed.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxRed.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged); this.textBoxRed.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxRed.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxRed.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxRed.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxRed.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// //
@ -156,7 +156,7 @@ namespace Greenshot {
this.textBoxGreen.TabIndex = 3; this.textBoxGreen.TabIndex = 3;
this.textBoxGreen.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxGreen.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxGreen.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxGreen.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxGreen.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged); this.textBoxGreen.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxGreen.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxGreen.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxGreen.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxGreen.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// //
@ -168,7 +168,7 @@ namespace Greenshot {
this.textBoxBlue.TabIndex = 4; this.textBoxBlue.TabIndex = 4;
this.textBoxBlue.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxBlue.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxBlue.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxBlue.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxBlue.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged); this.textBoxBlue.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxBlue.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxBlue.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxBlue.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxBlue.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// //
@ -189,7 +189,7 @@ namespace Greenshot {
this.textBoxAlpha.TabIndex = 5; this.textBoxAlpha.TabIndex = 5;
this.textBoxAlpha.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxAlpha.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxAlpha.Click += new System.EventHandler(this.TextBoxGotFocus); this.textBoxAlpha.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxAlpha.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged); this.textBoxAlpha.TextChanged += new System.EventHandler(this.TextBoxRgbTextChanged);
this.textBoxAlpha.GotFocus += new System.EventHandler(this.TextBoxGotFocus); this.textBoxAlpha.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxAlpha.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown); this.textBoxAlpha.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
// //

View file

@ -34,8 +34,8 @@ namespace Greenshot {
/// Description of ColorDialog. /// Description of ColorDialog.
/// </summary> /// </summary>
public partial class ColorDialog : BaseForm { public partial class ColorDialog : BaseForm {
private static ColorDialog uniqueInstance; private static ColorDialog _uniqueInstance;
private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
private ColorDialog() { private ColorDialog() {
SuspendLayout(); SuspendLayout();
@ -47,11 +47,9 @@ namespace Greenshot {
UpdateRecentColorsButtonRow(); UpdateRecentColorsButtonRow();
} }
public static ColorDialog GetInstance() { public static ColorDialog GetInstance()
if (uniqueInstance == null) { {
uniqueInstance = new ColorDialog(); return _uniqueInstance ?? (_uniqueInstance = new ColorDialog());
}
return uniqueInstance;
} }
private readonly List<Button> _colorButtons = new List<Button>(); private readonly List<Button> _colorButtons = new List<Button>();
@ -108,13 +106,15 @@ namespace Greenshot {
} }
private Button CreateColorButton(Color color, int x, int y, int w, int h) { private Button CreateColorButton(Color color, int x, int y, int w, int h) {
Button b = new Button(); Button b = new Button
b.BackColor = color; {
BackColor = color,
FlatStyle = FlatStyle.Flat,
Location = new Point(x, y),
Size = new Size(w, h),
TabStop = false
};
b.FlatAppearance.BorderSize = 0; b.FlatAppearance.BorderSize = 0;
b.FlatStyle = FlatStyle.Flat;
b.Location = new Point(x, y);
b.Size = new Size(w, h);
b.TabStop = false;
b.Click += ColorButtonClick; b.Click += ColorButtonClick;
_toolTip.SetToolTip(b, ColorTranslator.ToHtml(color) + " | R:" + color.R + ", G:" + color.G + ", B:" + color.B); _toolTip.SetToolTip(b, ColorTranslator.ToHtml(color) + " | R:" + color.R + ", G:" + color.G + ", B:" + color.B);
return b; return b;
@ -133,8 +133,8 @@ namespace Greenshot {
#region update user interface #region update user interface
private void UpdateRecentColorsButtonRow() { private void UpdateRecentColorsButtonRow() {
for (int i = 0; i < editorConfiguration.RecentColors.Count && i < 12; i++) { for (int i = 0; i < EditorConfig.RecentColors.Count && i < 12; i++) {
_recentColorButtons[i].BackColor = editorConfiguration.RecentColors[i]; _recentColorButtons[i].BackColor = EditorConfig.RecentColors[i];
_recentColorButtons[i].Enabled = true; _recentColorButtons[i].Enabled = true;
} }
} }
@ -155,10 +155,10 @@ namespace Greenshot {
} }
private void AddToRecentColors(Color c) { private void AddToRecentColors(Color c) {
editorConfiguration.RecentColors.Remove(c); EditorConfig.RecentColors.Remove(c);
editorConfiguration.RecentColors.Insert(0, c); EditorConfig.RecentColors.Insert(0, c);
if (editorConfiguration.RecentColors.Count > 12) { if (EditorConfig.RecentColors.Count > 12) {
editorConfiguration.RecentColors.RemoveRange(12, editorConfiguration.RecentColors.Count - 12); EditorConfig.RecentColors.RemoveRange(12, EditorConfig.RecentColors.Count - 12);
} }
UpdateRecentColorsButtonRow(); UpdateRecentColorsButtonRow();
} }
@ -172,14 +172,14 @@ namespace Greenshot {
} }
TextBox textBox = (TextBox)sender; TextBox textBox = (TextBox)sender;
string text = textBox.Text.Replace("#", ""); string text = textBox.Text.Replace("#", "");
int i = 0; int i;
Color c; Color c;
if (Int32.TryParse(text, NumberStyles.AllowHexSpecifier, Thread.CurrentThread.CurrentCulture, out i)) { if (int.TryParse(text, NumberStyles.AllowHexSpecifier, Thread.CurrentThread.CurrentCulture, out i)) {
c = Color.FromArgb(i); c = Color.FromArgb(i);
} else { } else {
KnownColor knownColor; try
try { {
knownColor = (KnownColor)Enum.Parse(typeof(KnownColor), text, true); var knownColor = (KnownColor)Enum.Parse(typeof(KnownColor), text, true);
c = Color.FromKnownColor(knownColor); c = Color.FromKnownColor(knownColor);
} catch (Exception) { } catch (Exception) {
return; return;
@ -189,7 +189,7 @@ namespace Greenshot {
PreviewColor(opaqueColor, textBox); PreviewColor(opaqueColor, textBox);
} }
private void TextBoxRGBTextChanged(object sender, EventArgs e) { private void TextBoxRgbTextChanged(object sender, EventArgs e) {
if (_updateInProgress) { if (_updateInProgress) {
return; return;
} }
@ -228,10 +228,16 @@ namespace Greenshot {
#region helper functions #region helper functions
private int GetColorPartIntFromString(string s) { private int GetColorPartIntFromString(string s) {
int ret = 0; int ret;
Int32.TryParse(s, out ret); int.TryParse(s, out ret);
if (ret < 0) ret = 0; if (ret < 0)
else if (ret > 255) ret = 255; {
ret = 0;
}
else if (ret > 255)
{
ret = 255;
}
return ret; return ret;
} }

View file

@ -21,14 +21,14 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Core; using GreenshotPlugin.Effects;
namespace Greenshot.Forms { namespace Greenshot.Forms {
public partial class DropShadowSettingsForm : BaseForm { public partial class DropShadowSettingsForm : BaseForm {
private readonly DropShadowEffect effect; private readonly DropShadowEffect _effect;
public DropShadowSettingsForm(DropShadowEffect effect) { public DropShadowSettingsForm(DropShadowEffect effect) {
this.effect = effect; _effect = effect;
InitializeComponent(); InitializeComponent();
ShowSettings(); ShowSettings();
} }
@ -37,16 +37,16 @@ namespace Greenshot.Forms {
/// Apply the settings from the effect to the view /// Apply the settings from the effect to the view
/// </summary> /// </summary>
private void ShowSettings() { private void ShowSettings() {
trackBar1.Value = (int)(effect.Darkness * 40); trackBar1.Value = (int)(_effect.Darkness * 40);
offsetX.Value = effect.ShadowOffset.X; offsetX.Value = _effect.ShadowOffset.X;
offsetY.Value = effect.ShadowOffset.Y; offsetY.Value = _effect.ShadowOffset.Y;
thickness.Value = effect.ShadowSize; thickness.Value = _effect.ShadowSize;
} }
private void ButtonOK_Click(object sender, EventArgs e) { private void ButtonOK_Click(object sender, EventArgs e) {
effect.Darkness = (float)trackBar1.Value / (float)40; _effect.Darkness = trackBar1.Value / (float)40;
effect.ShadowOffset = new Point((int)offsetX.Value, (int)offsetY.Value); _effect.ShadowOffset = new Point((int)offsetX.Value, (int)offsetY.Value);
effect.ShadowSize = (int)thickness.Value; _effect.ShadowSize = (int)thickness.Value;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
} }

View file

@ -19,8 +19,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration; using Greenshot.Configuration;
using Greenshot.Core;
using Greenshot.Destinations; using Greenshot.Destinations;
using Greenshot.Drawing; using Greenshot.Drawing;
using Greenshot.Drawing.Fields; using Greenshot.Drawing.Fields;
@ -33,26 +40,19 @@ using Greenshot.Plugin;
using Greenshot.Plugin.Drawing; using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Controls; using GreenshotPlugin.Controls;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using GreenshotPlugin.Effects;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
using GreenshotPlugin.UnmanagedHelpers; using GreenshotPlugin.UnmanagedHelpers;
using log4net; using log4net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace Greenshot { namespace Greenshot {
/// <summary> /// <summary>
/// Description of ImageEditorForm. /// Description of ImageEditorForm.
/// </summary> /// </summary>
public partial class ImageEditorForm : BaseForm, IImageEditor { public partial class ImageEditorForm : BaseForm, IImageEditor {
private static readonly ILog LOG = LogManager.GetLogger(typeof(ImageEditorForm)); private static readonly ILog Log = LogManager.GetLogger(typeof(ImageEditorForm));
private static readonly EditorConfiguration EditorConfiguration = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
private static readonly List<string> IgnoreDestinations = new List<string>() { PickerDestination.DESIGNATION, EditorDestination.DESIGNATION }; private static readonly List<string> IgnoreDestinations = new List<string> { PickerDestination.DESIGNATION, EditorDestination.DESIGNATION };
private static readonly List<IImageEditor> EditorList = new List<IImageEditor>(); private static readonly List<IImageEditor> EditorList = new List<IImageEditor>();
private Surface _surface; private Surface _surface;
@ -69,18 +69,14 @@ namespace Greenshot {
/// <summary> /// <summary>
/// An Implementation for the IImageEditor, this way Plugins have access to the HWND handles wich can be used with Win32 API calls. /// An Implementation for the IImageEditor, this way Plugins have access to the HWND handles wich can be used with Win32 API calls.
/// </summary> /// </summary>
public IWin32Window WindowHandle { public IWin32Window WindowHandle => this;
get { return this; }
}
public static List<IImageEditor> Editors { public static List<IImageEditor> Editors {
get { get {
try { try {
EditorList.Sort(delegate(IImageEditor e1, IImageEditor e2) { EditorList.Sort((e1, e2) => string.Compare(e1.Surface.CaptureDetails.Title, e2.Surface.CaptureDetails.Title, StringComparison.Ordinal));
return string.Compare(e1.Surface.CaptureDetails.Title, e2.Surface.CaptureDetails.Title, StringComparison.Ordinal);
});
} catch(Exception ex) { } catch(Exception ex) {
LOG.Warn("Sorting of editors failed.", ex); Log.Warn("Sorting of editors failed.", ex);
} }
return EditorList; return EditorList;
} }
@ -104,7 +100,7 @@ namespace Greenshot {
}; };
// Make sure the editor is placed on the same location as the last editor was on close // Make sure the editor is placed on the same location as the last editor was on close
// But only if this still exists, else it will be reset (BUG-1812 // But only if this still exists, else it will be reset (BUG-1812)
WindowPlacement editorWindowPlacement = EditorConfiguration.GetEditorPlacement(); WindowPlacement editorWindowPlacement = EditorConfiguration.GetEditorPlacement();
Rectangle screenbounds = WindowCapture.GetScreenBounds(); Rectangle screenbounds = WindowCapture.GetScreenBounds();
if (!screenbounds.Contains(editorWindowPlacement.NormalPosition)) if (!screenbounds.Contains(editorWindowPlacement.NormalPosition))
@ -132,11 +128,13 @@ namespace Greenshot {
/// Remove the current surface /// Remove the current surface
/// </summary> /// </summary>
private void RemoveSurface() { private void RemoveSurface() {
if (_surface != null) { if (_surface == null)
panel1.Controls.Remove(_surface); {
_surface.Dispose(); return;
_surface = null;
} }
panel1.Controls.Remove(_surface);
_surface.Dispose();
_surface = null;
} }
/// <summary> /// <summary>
@ -174,7 +172,7 @@ namespace Greenshot {
BindFieldControls(); BindFieldControls();
RefreshEditorControls(); RefreshEditorControls();
// Fix title // Fix title
if (_surface != null && _surface.CaptureDetails != null && _surface.CaptureDetails.Title != null) { if (_surface?.CaptureDetails?.Title != null) {
Text = _surface.CaptureDetails.Title + " - " + Language.GetString(LangKey.editor_title); Text = _surface.CaptureDetails.Title + " - " + Language.GetString(LangKey.editor_title);
} }
} }
@ -249,7 +247,7 @@ namespace Greenshot {
if (destination.Priority <= 2) { if (destination.Priority <= 2) {
continue; continue;
} }
if (!destination.isActive) { if (!destination.IsActive) {
continue; continue;
} }
if (destination.DisplayIcon == null) { if (destination.DisplayIcon == null) {
@ -258,15 +256,15 @@ namespace Greenshot {
try { try {
AddDestinationButton(destination); AddDestinationButton(destination);
} catch (Exception addingException) { } catch (Exception addingException) {
LOG.WarnFormat("Problem adding destination {0}", destination.Designation); Log.WarnFormat("Problem adding destination {0}", destination.Designation);
LOG.Warn("Exception: ", addingException); Log.Warn("Exception: ", addingException);
} }
} }
}); });
} }
private void AddDestinationButton(IDestination toolstripDestination) { private void AddDestinationButton(IDestination toolstripDestination) {
if (toolstripDestination.isDynamic) { if (toolstripDestination.IsDynamic) {
ToolStripSplitButton destinationButton = new ToolStripSplitButton ToolStripSplitButton destinationButton = new ToolStripSplitButton
{ {
DisplayStyle = ToolStripItemDisplayStyle.Image, DisplayStyle = ToolStripItemDisplayStyle.Image,
@ -302,9 +300,11 @@ namespace Greenshot {
subDestinations.Sort(); subDestinations.Sort();
foreach(IDestination subDestination in subDestinations) { foreach(IDestination subDestination in subDestinations) {
IDestination closureFixedDestination = subDestination; IDestination closureFixedDestination = subDestination;
ToolStripMenuItem destinationMenuItem = new ToolStripMenuItem(closureFixedDestination.Description); ToolStripMenuItem destinationMenuItem = new ToolStripMenuItem(closureFixedDestination.Description)
destinationMenuItem.Tag = closureFixedDestination; {
destinationMenuItem.Image = closureFixedDestination.DisplayIcon; Tag = closureFixedDestination,
Image = closureFixedDestination.DisplayIcon
};
destinationMenuItem.Click += delegate { destinationMenuItem.Click += delegate {
closureFixedDestination.ExportCapture(true, _surface, _surface.CaptureDetails); closureFixedDestination.ExportCapture(true, _surface, _surface.CaptureDetails);
}; };
@ -351,7 +351,7 @@ namespace Greenshot {
if (IgnoreDestinations.Contains(destination.Designation)) { if (IgnoreDestinations.Contains(destination.Designation)) {
continue; continue;
} }
if (!destination.isActive) { if (!destination.IsActive) {
continue; continue;
} }
@ -375,20 +375,20 @@ namespace Greenshot {
/// <param name="eventArgs"></param> /// <param name="eventArgs"></param>
private void SurfaceMessageReceived(object sender, SurfaceMessageEventArgs eventArgs) { private void SurfaceMessageReceived(object sender, SurfaceMessageEventArgs eventArgs) {
if (InvokeRequired) { if (InvokeRequired) {
Invoke(new SurfaceMessageReceivedThreadSafeDelegate(SurfaceMessageReceived), new object[] { sender, eventArgs }); Invoke(new SurfaceMessageReceivedThreadSafeDelegate(SurfaceMessageReceived), sender, eventArgs);
} else { } else {
string dateTime = DateTime.Now.ToLongTimeString(); string dateTime = DateTime.Now.ToLongTimeString();
// TODO: Fix that we only open files, like in the tooltip // TODO: Fix that we only open files, like in the tooltip
switch (eventArgs.MessageType) { switch (eventArgs.MessageType) {
case SurfaceMessageTyp.FileSaved: case SurfaceMessageTyp.FileSaved:
// Put the event message on the status label and attach the context menu // Put the event message on the status label and attach the context menu
updateStatusLabel(dateTime + " - " + eventArgs.Message, fileSavedStatusContextMenu); UpdateStatusLabel(dateTime + " - " + eventArgs.Message, fileSavedStatusContextMenu);
// Change title // Change title
Text = eventArgs.Surface.LastSaveFullPath + " - " + Language.GetString(LangKey.editor_title); Text = eventArgs.Surface.LastSaveFullPath + " - " + Language.GetString(LangKey.editor_title);
break; break;
default: default:
// Put the event message on the status label // Put the event message on the status label
updateStatusLabel(dateTime + " - " + eventArgs.Message); UpdateStatusLabel(dateTime + " - " + eventArgs.Message);
break; break;
} }
} }
@ -434,7 +434,7 @@ namespace Greenshot {
if (fullpath == null) { if (fullpath == null) {
return; return;
} }
updateStatusLabel(Language.GetFormattedString(LangKey.editor_imagesaved, fullpath), fileSavedStatusContextMenu); UpdateStatusLabel(Language.GetFormattedString(LangKey.editor_imagesaved, fullpath), fileSavedStatusContextMenu);
Text = Path.GetFileName(fullpath) + " - " + Language.GetString(LangKey.editor_title); Text = Path.GetFileName(fullpath) + " - " + Language.GetString(LangKey.editor_title);
} }
@ -489,9 +489,7 @@ namespace Greenshot {
return _surface.GetImageForExport(); return _surface.GetImageForExport();
} }
public ICaptureDetails CaptureDetails { public ICaptureDetails CaptureDetails => _surface.CaptureDetails;
get { return _surface.CaptureDetails; }
}
public ToolStripMenuItem GetPluginMenuItem() { public ToolStripMenuItem GetPluginMenuItem() {
return pluginToolStripMenuItem; return pluginToolStripMenuItem;
@ -902,7 +900,7 @@ namespace Greenshot {
if (IgnoreDestinations.Contains(destination.Designation)) { if (IgnoreDestinations.Contains(destination.Designation)) {
continue; continue;
} }
if (!destination.isActive) { if (!destination.IsActive) {
continue; continue;
} }
@ -943,9 +941,9 @@ namespace Greenshot {
redoToolStripMenuItem.Enabled = canRedo; redoToolStripMenuItem.Enabled = canRedo;
string redoAction = ""; string redoAction = "";
if (canRedo) { if (canRedo) {
if (_surface.RedoActionLanguageKey != LangKey.none) { if (_surface.RedoActionLanguageKey != LangKey.none) {
redoAction = Language.GetString(_surface.RedoActionLanguageKey); redoAction = Language.GetString(_surface.RedoActionLanguageKey);
} }
} }
string redoText = Language.GetFormattedString(LangKey.editor_redo, redoAction); string redoText = Language.GetFormattedString(LangKey.editor_redo, redoAction);
btnRedo.Text = redoText; btnRedo.Text = redoText;
@ -981,23 +979,18 @@ namespace Greenshot {
#endregion #endregion
#region status label handling #region status label handling
private void updateStatusLabel(string text, ContextMenuStrip contextMenu) { private void UpdateStatusLabel(string text, ContextMenuStrip contextMenu = null) {
statusLabel.Text = text; statusLabel.Text = text;
statusStrip1.ContextMenuStrip = contextMenu; statusStrip1.ContextMenuStrip = contextMenu;
} }
private void updateStatusLabel(string text) {
updateStatusLabel(text, null);
}
private void ClearStatusLabel() { private void ClearStatusLabel() {
updateStatusLabel(null, null); UpdateStatusLabel(null);
} }
private void StatusLabelClicked(object sender, MouseEventArgs e) { private void StatusLabelClicked(object sender, MouseEventArgs e) {
ToolStrip ss = (StatusStrip)((ToolStripStatusLabel)sender).Owner; ToolStrip ss = (StatusStrip)((ToolStripStatusLabel)sender).Owner;
if(ss.ContextMenuStrip != null) { ss.ContextMenuStrip?.Show(ss, e.X, e.Y);
ss.ContextMenuStrip.Show(ss, e.X, e.Y);
}
} }
private void CopyPathMenuItemClick(object sender, EventArgs e) { private void CopyPathMenuItemClick(object sender, EventArgs e) {
@ -1005,14 +998,19 @@ namespace Greenshot {
} }
private void OpenDirectoryMenuItemClick(object sender, EventArgs e) { private void OpenDirectoryMenuItemClick(object sender, EventArgs e) {
ProcessStartInfo psi = new ProcessStartInfo("explorer") var path = Path.GetDirectoryName(_surface.LastSaveFullPath);
if (path == null)
{ {
Arguments = Path.GetDirectoryName(_surface.LastSaveFullPath), return;
}
var processStartInfo = new ProcessStartInfo("explorer")
{
Arguments = path,
UseShellExecute = false UseShellExecute = false
}; };
using (Process p = new Process()) { using (var process = new Process()) {
p.StartInfo = psi; process.StartInfo = processStartInfo;
p.Start(); process.Start();
} }
} }
#endregion #endregion
@ -1082,16 +1080,16 @@ namespace Greenshot {
/// </summary> /// </summary>
private void RefreshEditorControls() { private void RefreshEditorControls() {
int stepLabels = _surface.CountStepLabels(null); int stepLabels = _surface.CountStepLabels(null);
Image icon; Image icon;
if (stepLabels <= 20) { if (stepLabels <= 20) {
icon = (Image)resources.GetObject(string.Format("btnStepLabel{0:00}.Image", stepLabels)); icon = (Image)resources.GetObject($"btnStepLabel{stepLabels:00}.Image");
} else { } else {
icon = (Image)resources.GetObject("btnStepLabel20+.Image"); icon = (Image)resources.GetObject("btnStepLabel20+.Image");
} }
btnStepLabel.Image = icon; btnStepLabel.Image = icon;
addCounterToolStripMenuItem.Image = icon; addCounterToolStripMenuItem.Image = icon;
FieldAggregator props = _surface.FieldAggregator; FieldAggregator props = _surface.FieldAggregator;
// if a confirmable element is selected, we must disable most of the controls // if a confirmable element is selected, we must disable most of the controls
// since we demand confirmation or cancel for confirmable element // since we demand confirmation or cancel for confirmable element
if (props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag)props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE) if (props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag)props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE)
@ -1156,33 +1154,51 @@ namespace Greenshot {
fontItalicButton.Checked = _originalItalicCheckState; fontItalicButton.Checked = _originalItalicCheckState;
} }
FontFamily fam = fontFamilyComboBox.FontFamily; var fontFamily = fontFamilyComboBox.FontFamily;
bool boldAvailable = fam.IsStyleAvailable(FontStyle.Bold); bool boldAvailable = fontFamily.IsStyleAvailable(FontStyle.Bold);
if(!boldAvailable) { if (fontBoldButton != null)
_originalBoldCheckState = fontBoldButton.Checked; {
fontBoldButton.Checked = false; if (!boldAvailable)
} {
fontBoldButton.Enabled = boldAvailable; _originalBoldCheckState = fontBoldButton.Checked;
fontBoldButton.Checked = false;
}
fontBoldButton.Enabled = boldAvailable;
}
bool italicAvailable = fam.IsStyleAvailable(FontStyle.Italic); bool italicAvailable = fontFamily.IsStyleAvailable(FontStyle.Italic);
if(!italicAvailable) fontItalicButton.Checked = false; if (fontItalicButton != null)
fontItalicButton.Enabled = italicAvailable; {
if (!italicAvailable)
{
fontItalicButton.Checked = false;
}
fontItalicButton.Enabled = italicAvailable;
}
bool regularAvailable = fam.IsStyleAvailable(FontStyle.Regular); bool regularAvailable = fontFamily.IsStyleAvailable(FontStyle.Regular);
if(!regularAvailable) { if (regularAvailable)
if(boldAvailable) { {
fontBoldButton.Checked = true; return;
} else if(italicAvailable) { }
fontItalicButton.Checked = true; if (boldAvailable) {
} if (fontBoldButton != null)
} {
} fontBoldButton.Checked = true;
}
} else if(italicAvailable) {
if (fontItalicButton != null)
{
fontItalicButton.Checked = true;
}
}
}
private void FieldAggregatorFieldChanged(object sender, FieldChangedEventArgs e) { private void FieldAggregatorFieldChanged(object sender, FieldChangedEventArgs e) {
// in addition to selection, deselection of elements, we need to // in addition to selection, deselection of elements, we need to
// refresh toolbar if prepared filter mode is changed // refresh toolbar if prepared filter mode is changed
if(e.Field.FieldType == FieldType.PREPARED_FILTER_HIGHLIGHT) { if(Equals(e.Field.FieldType, FieldType.PREPARED_FILTER_HIGHLIGHT)) {
RefreshFieldControls(); RefreshFieldControls();
} }
} }
@ -1204,9 +1220,11 @@ namespace Greenshot {
} }
private void SaveElementsToolStripMenuItemClick(object sender, EventArgs e) { private void SaveElementsToolStripMenuItemClick(object sender, EventArgs e) {
SaveFileDialog saveFileDialog = new SaveFileDialog(); SaveFileDialog saveFileDialog = new SaveFileDialog
saveFileDialog.Filter = "Greenshot templates (*.gst)|*.gst"; {
saveFileDialog.FileName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(coreConfiguration.OutputFileFilenamePattern, _surface.CaptureDetails); Filter = "Greenshot templates (*.gst)|*.gst",
FileName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(coreConfiguration.OutputFileFilenamePattern, _surface.CaptureDetails)
};
DialogResult dialogResult = saveFileDialog.ShowDialog(); DialogResult dialogResult = saveFileDialog.ShowDialog();
if(dialogResult.Equals(DialogResult.OK)) { if(dialogResult.Equals(DialogResult.OK)) {
using (Stream streamWrite = File.OpenWrite(saveFileDialog.FileName)) { using (Stream streamWrite = File.OpenWrite(saveFileDialog.FileName)) {
@ -1216,8 +1234,10 @@ namespace Greenshot {
} }
private void LoadElementsToolStripMenuItemClick(object sender, EventArgs e) { private void LoadElementsToolStripMenuItemClick(object sender, EventArgs e) {
OpenFileDialog openFileDialog = new OpenFileDialog(); OpenFileDialog openFileDialog = new OpenFileDialog
openFileDialog.Filter = "Greenshot templates (*.gst)|*.gst"; {
Filter = "Greenshot templates (*.gst)|*.gst"
};
if (openFileDialog.ShowDialog() == DialogResult.OK) { if (openFileDialog.ShowDialog() == DialogResult.OK) {
using (Stream streamRead = File.OpenRead(openFileDialog.FileName)) { using (Stream streamRead = File.OpenRead(openFileDialog.FileName)) {
_surface.LoadElementsFromStream(streamRead); _surface.LoadElementsFromStream(streamRead);
@ -1228,23 +1248,27 @@ namespace Greenshot {
private void DestinationToolStripMenuItemClick(object sender, EventArgs e) { private void DestinationToolStripMenuItemClick(object sender, EventArgs e) {
IDestination clickedDestination = null; IDestination clickedDestination = null;
if (sender is Control) { var control = sender as Control;
Control clickedControl = sender as Control; if (control != null) {
Control clickedControl = control;
if (clickedControl.ContextMenuStrip != null) { if (clickedControl.ContextMenuStrip != null) {
clickedControl.ContextMenuStrip.Show(Cursor.Position); clickedControl.ContextMenuStrip.Show(Cursor.Position);
return; return;
} }
clickedDestination = (IDestination)clickedControl.Tag; clickedDestination = (IDestination)clickedControl.Tag;
} else if (sender is ToolStripMenuItem) {
ToolStripMenuItem clickedMenuItem = sender as ToolStripMenuItem;
clickedDestination = (IDestination)clickedMenuItem.Tag;
} }
if (clickedDestination != null) { else
ExportInformation exportInformation = clickedDestination.ExportCapture(true, _surface, _surface.CaptureDetails); {
if (exportInformation != null && exportInformation.ExportMade) { var item = sender as ToolStripMenuItem;
_surface.Modified = false; if (item != null) {
ToolStripMenuItem clickedMenuItem = item;
clickedDestination = (IDestination)clickedMenuItem.Tag;
} }
} }
ExportInformation exportInformation = clickedDestination?.ExportCapture(true, _surface, _surface.CaptureDetails);
if (exportInformation != null && exportInformation.ExportMade) {
_surface.Modified = false;
}
} }
protected void FilterPresetDropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) { protected void FilterPresetDropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) {
@ -1284,7 +1308,7 @@ namespace Greenshot {
windowToCapture = CaptureHelper.SelectCaptureWindow(windowToCapture); windowToCapture = CaptureHelper.SelectCaptureWindow(windowToCapture);
if (windowToCapture != null) { if (windowToCapture != null) {
capture = CaptureHelper.CaptureWindow(windowToCapture, capture, coreConfiguration.WindowCaptureMode); capture = CaptureHelper.CaptureWindow(windowToCapture, capture, coreConfiguration.WindowCaptureMode);
if (capture != null && capture.CaptureDetails != null && capture.Image != null) { if (capture?.CaptureDetails != null && capture.Image != null) {
((Bitmap)capture.Image).SetResolution(capture.CaptureDetails.DpiX, capture.CaptureDetails.DpiY); ((Bitmap)capture.Image).SetResolution(capture.CaptureDetails.DpiX, capture.CaptureDetails.DpiY);
_surface.AddImageContainer((Bitmap)capture.Image, 100, 100); _surface.AddImageContainer((Bitmap)capture.Image, 100, 100);
} }
@ -1292,11 +1316,9 @@ namespace Greenshot {
WindowDetails.ToForeground(Handle); WindowDetails.ToForeground(Handle);
} }
if (capture!= null) { capture?.Dispose();
capture.Dispose();
}
} catch (Exception exception) { } catch (Exception exception) {
LOG.Error(exception); Log.Error(exception);
} }
} }
@ -1440,17 +1462,13 @@ namespace Greenshot {
} }
private void ImageEditorFormResize(object sender, EventArgs e) { private void ImageEditorFormResize(object sender, EventArgs e) {
if (Surface == null || Surface.Image == null || panel1 == null) { if (Surface?.Image == null || panel1 == null) {
return; return;
} }
Size imageSize = Surface.Image.Size; Size imageSize = Surface.Image.Size;
Size currentClientSize = panel1.ClientSize; Size currentClientSize = panel1.ClientSize;
var canvas = Surface as Control; var canvas = Surface as Control;
if (canvas == null) Panel panel = (Panel) canvas?.Parent;
{
return;
}
Panel panel = (Panel)canvas.Parent;
if (panel == null) { if (panel == null) {
return; return;
} }

View file

@ -162,7 +162,7 @@ namespace Greenshot {
// //
this.contextmenu_captureiefromlist.Name = "contextmenu_captureiefromlist"; this.contextmenu_captureiefromlist.Name = "contextmenu_captureiefromlist";
this.contextmenu_captureiefromlist.Size = new System.Drawing.Size(170, 22); this.contextmenu_captureiefromlist.Size = new System.Drawing.Size(170, 22);
this.contextmenu_captureiefromlist.DropDownOpening += new System.EventHandler(this.CaptureIEMenuDropDownOpening); this.contextmenu_captureiefromlist.DropDownOpening += new System.EventHandler(this.CaptureIeMenuDropDownOpening);
// //
// toolStripOtherSourcesSeparator // toolStripOtherSourcesSeparator
// //

View file

@ -56,15 +56,14 @@ namespace Greenshot {
private static CoreConfiguration _conf; private static CoreConfiguration _conf;
public static string LogFileLocation; public static string LogFileLocation;
public static void Start(string[] args) { public static void Start(string[] arguments) {
bool isAlreadyRunning = false; var filesToOpen = new List<string>();
List<string> filesToOpen = new List<string>();
// Set the Thread name, is better than "1" // Set the Thread name, is better than "1"
Thread.CurrentThread.Name = Application.ProductName; Thread.CurrentThread.Name = Application.ProductName;
// Init Log4NET // Init Log4NET
LogFileLocation = LogHelper.InitializeLog4NET(); LogFileLocation = LogHelper.InitializeLog4Net();
// Get logger // Get logger
LOG = LogManager.GetLogger(typeof(MainForm)); LOG = LogManager.GetLogger(typeof(MainForm));
@ -84,18 +83,19 @@ namespace Greenshot {
// check whether there's an local instance running already // check whether there's an local instance running already
_applicationMutex = ResourceMutex.Create("F48E86D3-E34C-4DB7-8F8F-9A0EA55F0D08", "Greenshot", false); _applicationMutex = ResourceMutex.Create("F48E86D3-E34C-4DB7-8F8F-9A0EA55F0D08", "Greenshot", false);
isAlreadyRunning = !_applicationMutex.IsLocked; var isAlreadyRunning = !_applicationMutex.IsLocked;
if (args.Length > 0 && LOG.IsDebugEnabled) { if (arguments.Length > 0 && LOG.IsDebugEnabled) {
StringBuilder argumentString = new StringBuilder(); StringBuilder argumentString = new StringBuilder();
for(int argumentNr = 0; argumentNr < args.Length; argumentNr++) { foreach (string argument in arguments)
argumentString.Append("[").Append(args[argumentNr]).Append("] "); {
argumentString.Append("[").Append(argument).Append("] ");
} }
LOG.Debug("Greenshot arguments: " + argumentString); LOG.Debug("Greenshot arguments: " + argumentString);
} }
for(int argumentNr = 0; argumentNr < args.Length; argumentNr++) { for(int argumentNr = 0; argumentNr < arguments.Length; argumentNr++) {
string argument = args[argumentNr]; string argument = arguments[argumentNr];
// Help // Help
if (argument.ToLower().Equals("/help") || argument.ToLower().Equals("/h") || argument.ToLower().Equals("/?")) { if (argument.ToLower().Equals("/help") || argument.ToLower().Equals("/h") || argument.ToLower().Equals("/?")) {
// Try to attach to the console // Try to attach to the console
@ -104,7 +104,7 @@ namespace Greenshot {
if (!attachedToConsole) { if (!attachedToConsole) {
Kernel32.AllocConsole(); Kernel32.AllocConsole();
} }
StringBuilder helpOutput = new StringBuilder(); var helpOutput = new StringBuilder();
helpOutput.AppendLine(); helpOutput.AppendLine();
helpOutput.AppendLine("Greenshot commandline options:"); helpOutput.AppendLine("Greenshot commandline options:");
helpOutput.AppendLine(); helpOutput.AppendLine();
@ -173,14 +173,14 @@ namespace Greenshot {
// Language // Language
if (argument.ToLower().Equals("/language")) { if (argument.ToLower().Equals("/language")) {
_conf.Language = args[++argumentNr]; _conf.Language = arguments[++argumentNr];
IniConfig.Save(); IniConfig.Save();
continue; continue;
} }
// Setting the INI-directory // Setting the INI-directory
if (argument.ToLower().Equals("/inidirectory")) { if (argument.ToLower().Equals("/inidirectory")) {
IniConfig.IniDirectory = args[++argumentNr]; IniConfig.IniDirectory = arguments[++argumentNr];
continue; continue;
} }
@ -296,11 +296,7 @@ namespace Greenshot {
} }
private static MainForm _instance; private static MainForm _instance;
public static MainForm Instance { public static MainForm Instance => _instance;
get {
return _instance;
}
}
private readonly CopyData _copyData; private readonly CopyData _copyData;
@ -313,11 +309,7 @@ namespace Greenshot {
// Timer for the double click test // Timer for the double click test
private readonly Timer _doubleClickTimer = new Timer(); private readonly Timer _doubleClickTimer = new Timer();
public NotifyIcon NotifyIcon { public NotifyIcon NotifyIcon => notifyIcon;
get {
return notifyIcon;
}
}
public MainForm(CopyDataTransport dataTransport) { public MainForm(CopyDataTransport dataTransport) {
_instance = this; _instance = this;
@ -341,12 +333,12 @@ namespace Greenshot {
contextmenu_settings.Visible = !_conf.DisableSettings; contextmenu_settings.Visible = !_conf.DisableSettings;
// Make sure all hotkeys pass this window! // Make sure all hotkeys pass this window!
HotkeyControl.RegisterHotkeyHWND(Handle); HotkeyControl.RegisterHotkeyHwnd(Handle);
RegisterHotkeys(); RegisterHotkeys();
new ToolTip(); new ToolTip();
UpdateUI(); UpdateUi();
// This forces the registration of all destinations inside Greenshot itself. // This forces the registration of all destinations inside Greenshot itself.
DestinationHelper.GetAllDestinations(); DestinationHelper.GetAllDestinations();
@ -452,7 +444,7 @@ namespace Greenshot {
IniConfig.Reload(); IniConfig.Reload();
Invoke((MethodInvoker) delegate { Invoke((MethodInvoker) delegate {
// Even update language when needed // Even update language when needed
UpdateUI(); UpdateUi();
// Update the hotkey // Update the hotkey
// Make sure the current hotkeys are disabled // Make sure the current hotkeys are disabled
HotkeyControl.UnregisterHotkeys(); HotkeyControl.UnregisterHotkeys();
@ -480,9 +472,10 @@ namespace Greenshot {
} }
} }
public ContextMenuStrip MainMenu { /// <summary>
get {return contextMenu;} /// Main context menu
} /// </summary>
public ContextMenuStrip MainMenu => contextMenu;
protected override void WndProc(ref Message m) { protected override void WndProc(ref Message m) {
if (HotkeyControl.HandleMessages(ref m)) { if (HotkeyControl.HandleMessages(ref m)) {
@ -659,7 +652,7 @@ namespace Greenshot {
} }
#endregion #endregion
public void UpdateUI() { public void UpdateUi() {
// As the form is never loaded, call ApplyLanguage ourselves // As the form is never loaded, call ApplyLanguage ourselves
ApplyLanguage(); ApplyLanguage();
@ -693,8 +686,10 @@ namespace Greenshot {
} }
private void CaptureFile() { private void CaptureFile() {
var openFileDialog = new OpenFileDialog(); var openFileDialog = new OpenFileDialog
openFileDialog.Filter = "Image files (*.greenshot, *.png, *.jpg, *.gif, *.bmp, *.ico, *.tiff, *.wmf)|*.greenshot; *.png; *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.tiff; *.tif; *.wmf"; {
Filter = "Image files (*.greenshot, *.png, *.jpg, *.gif, *.bmp, *.ico, *.tiff, *.wmf)|*.greenshot; *.png; *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.tiff; *.tif; *.wmf"
};
if (openFileDialog.ShowDialog() == DialogResult.OK) { if (openFileDialog.ShowDialog() == DialogResult.OK) {
if (File.Exists(openFileDialog.FileName)) { if (File.Exists(openFileDialog.FileName)) {
CaptureHelper.CaptureFile(openFileDialog.FileName); CaptureHelper.CaptureFile(openFileDialog.FileName);
@ -712,7 +707,7 @@ namespace Greenshot {
private void CaptureIE() { private void CaptureIE() {
if (_conf.IECapture) { if (_conf.IECapture) {
CaptureHelper.CaptureIE(true, null); CaptureHelper.CaptureIe(true, null);
} }
} }
@ -734,7 +729,7 @@ namespace Greenshot {
// IE context menu code // IE context menu code
try { try {
if (_conf.IECapture && IECaptureHelper.IsIERunning()) { if (_conf.IECapture && IeCaptureHelper.IsIeRunning()) {
contextmenu_captureie.Enabled = true; contextmenu_captureie.Enabled = true;
contextmenu_captureiefromlist.Enabled = true; contextmenu_captureiefromlist.Enabled = true;
} else { } else {
@ -773,12 +768,12 @@ namespace Greenshot {
/// <summary> /// <summary>
/// Build a selectable list of IE tabs when we enter the menu item /// Build a selectable list of IE tabs when we enter the menu item
/// </summary> /// </summary>
private void CaptureIEMenuDropDownOpening(object sender, EventArgs e) { private void CaptureIeMenuDropDownOpening(object sender, EventArgs e) {
if (!_conf.IECapture) { if (!_conf.IECapture) {
return; return;
} }
try { try {
List<KeyValuePair<WindowDetails, string>> tabs = IECaptureHelper.GetBrowserTabs(); List<KeyValuePair<WindowDetails, string>> tabs = IeCaptureHelper.GetBrowserTabs();
contextmenu_captureiefromlist.DropDownItems.Clear(); contextmenu_captureiefromlist.DropDownItems.Clear();
if (tabs.Count > 0) { if (tabs.Count > 0) {
contextmenu_captureie.Enabled = true; contextmenu_captureie.Enabled = true;
@ -793,12 +788,12 @@ namespace Greenshot {
if (title.Length > _conf.MaxMenuItemLength) { if (title.Length > _conf.MaxMenuItemLength) {
title = title.Substring(0, Math.Min(title.Length, _conf.MaxMenuItemLength)); title = title.Substring(0, Math.Min(title.Length, _conf.MaxMenuItemLength));
} }
ToolStripItem captureIETabItem = contextmenu_captureiefromlist.DropDownItems.Add(title); var captureIeTabItem = contextmenu_captureiefromlist.DropDownItems.Add(title);
int index = counter.ContainsKey(tabData.Key) ? counter[tabData.Key] : 0; int index = counter.ContainsKey(tabData.Key) ? counter[tabData.Key] : 0;
captureIETabItem.Image = tabData.Key.DisplayIcon; captureIeTabItem.Image = tabData.Key.DisplayIcon;
captureIETabItem.Tag = new KeyValuePair<WindowDetails, int>(tabData.Key, index++); captureIeTabItem.Tag = new KeyValuePair<WindowDetails, int>(tabData.Key, index++);
captureIETabItem.Click += Contextmenu_captureiefromlist_Click; captureIeTabItem.Click += Contextmenu_captureiefromlist_Click;
contextmenu_captureiefromlist.DropDownItems.Add(captureIETabItem); contextmenu_captureiefromlist.DropDownItems.Add(captureIeTabItem);
if (counter.ContainsKey(tabData.Key)) { if (counter.ContainsKey(tabData.Key)) {
counter[tabData.Key] = index; counter[tabData.Key] = index;
} else { } else {
@ -823,10 +818,9 @@ namespace Greenshot {
ToolStripMenuItem captureScreenMenuItem = (ToolStripMenuItem)sender; ToolStripMenuItem captureScreenMenuItem = (ToolStripMenuItem)sender;
captureScreenMenuItem.DropDownItems.Clear(); captureScreenMenuItem.DropDownItems.Clear();
if (Screen.AllScreens.Length > 1) { if (Screen.AllScreens.Length > 1) {
ToolStripMenuItem captureScreenItem;
Rectangle allScreensBounds = WindowCapture.GetScreenBounds(); Rectangle allScreensBounds = WindowCapture.GetScreenBounds();
captureScreenItem = new ToolStripMenuItem(Language.GetString(LangKey.contextmenu_capturefullscreen_all)); var captureScreenItem = new ToolStripMenuItem(Language.GetString(LangKey.contextmenu_capturefullscreen_all));
captureScreenItem.Click += delegate { captureScreenItem.Click += delegate {
BeginInvoke((MethodInvoker)delegate { BeginInvoke((MethodInvoker)delegate {
CaptureHelper.CaptureFullscreen(false, ScreenCaptureMode.FullScreen); CaptureHelper.CaptureFullscreen(false, ScreenCaptureMode.FullScreen);
@ -893,17 +887,18 @@ namespace Greenshot {
} }
} }
private void HideThumbnailOnLeave(object sender, EventArgs e) { private void HideThumbnailOnLeave(object sender, EventArgs e)
if (_thumbnailForm != null) { {
_thumbnailForm.Hide(); _thumbnailForm?.Hide();
}
} }
private void CleanupThumbnail() { private void CleanupThumbnail() {
if (_thumbnailForm != null) { if (_thumbnailForm == null)
_thumbnailForm.Close(); {
_thumbnailForm = null; return;
} }
_thumbnailForm.Close();
_thumbnailForm = null;
} }
public void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler) { public void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler) {
@ -938,15 +933,11 @@ namespace Greenshot {
} }
private void CaptureClipboardToolStripMenuItemClick(object sender, EventArgs e) { private void CaptureClipboardToolStripMenuItemClick(object sender, EventArgs e) {
BeginInvoke((MethodInvoker)delegate { BeginInvoke((MethodInvoker)CaptureHelper.CaptureClipboard);
CaptureHelper.CaptureClipboard();
});
} }
private void OpenFileToolStripMenuItemClick(object sender, EventArgs e) { private void OpenFileToolStripMenuItemClick(object sender, EventArgs e) {
BeginInvoke((MethodInvoker)delegate { BeginInvoke((MethodInvoker)CaptureFile);
CaptureFile();
});
} }
private void CaptureFullScreenToolStripMenuItemClick(object sender, EventArgs e) { private void CaptureFullScreenToolStripMenuItemClick(object sender, EventArgs e) {
@ -996,12 +987,12 @@ namespace Greenshot {
ieWindowToCapture.Restore(); ieWindowToCapture.Restore();
} }
try { try {
IECaptureHelper.ActivateIETab(ieWindowToCapture, tabData.Value); IeCaptureHelper.ActivateIeTab(ieWindowToCapture, tabData.Value);
} catch (Exception exception) { } catch (Exception exception) {
LOG.Error(exception); LOG.Error(exception);
} }
try { try {
CaptureHelper.CaptureIE(false, ieWindowToCapture); CaptureHelper.CaptureIe(false, ieWindowToCapture);
} catch (Exception exception) { } catch (Exception exception) {
LOG.Error(exception); LOG.Error(exception);
} }
@ -1025,9 +1016,7 @@ namespace Greenshot {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void Contextmenu_settingsClick(object sender, EventArgs e) { private void Contextmenu_settingsClick(object sender, EventArgs e) {
BeginInvoke((MethodInvoker)delegate { BeginInvoke((MethodInvoker)ShowSetting);
ShowSetting();
});
} }
/// <summary> /// <summary>
@ -1110,10 +1099,12 @@ namespace Greenshot {
// Only add if the value is not fixed // Only add if the value is not fixed
if (!_conf.Values["CaptureMousepointer"].IsFixed) { if (!_conf.Values["CaptureMousepointer"].IsFixed) {
// For the capture mousecursor option // For the capture mousecursor option
ToolStripMenuSelectListItem captureMouseItem = new ToolStripMenuSelectListItem(); ToolStripMenuSelectListItem captureMouseItem = new ToolStripMenuSelectListItem
captureMouseItem.Text = Language.GetString("settings_capture_mousepointer"); {
captureMouseItem.Checked = _conf.CaptureMousepointer; Text = Language.GetString("settings_capture_mousepointer"),
captureMouseItem.CheckOnClick = true; Checked = _conf.CaptureMousepointer,
CheckOnClick = true
};
captureMouseItem.CheckStateChanged += CheckStateChangedHandler; captureMouseItem.CheckStateChanged += CheckStateChangedHandler;
contextmenu_quicksettings.DropDownItems.Add(captureMouseItem); contextmenu_quicksettings.DropDownItems.Add(captureMouseItem);
@ -1121,10 +1112,12 @@ namespace Greenshot {
ToolStripMenuSelectList selectList; ToolStripMenuSelectList selectList;
if (!_conf.Values["Destinations"].IsFixed) { if (!_conf.Values["Destinations"].IsFixed) {
// screenshot destination // screenshot destination
selectList = new ToolStripMenuSelectList("destinations", true); selectList = new ToolStripMenuSelectList("destinations", true)
selectList.Text = Language.GetString(LangKey.settings_destination); {
Text = Language.GetString(LangKey.settings_destination)
};
// Working with IDestination: // Working with IDestination:
foreach (IDestination destination in DestinationHelper.GetAllDestinations()) { foreach (var destination in DestinationHelper.GetAllDestinations()) {
selectList.AddItem(destination.Description, destination, _conf.OutputDestinations.Contains(destination.Designation)); selectList.AddItem(destination.Description, destination, _conf.OutputDestinations.Contains(destination.Designation));
} }
selectList.CheckedChanged += QuickSettingDestinationChanged; selectList.CheckedChanged += QuickSettingDestinationChanged;
@ -1133,19 +1126,23 @@ namespace Greenshot {
if (!_conf.Values["WindowCaptureMode"].IsFixed) { if (!_conf.Values["WindowCaptureMode"].IsFixed) {
// Capture Modes // Capture Modes
selectList = new ToolStripMenuSelectList("capturemodes", false); selectList = new ToolStripMenuSelectList("capturemodes", false)
selectList.Text = Language.GetString(LangKey.settings_window_capture_mode); {
Text = Language.GetString(LangKey.settings_window_capture_mode)
};
string enumTypeName = typeof(WindowCaptureMode).Name; string enumTypeName = typeof(WindowCaptureMode).Name;
foreach (WindowCaptureMode captureMode in Enum.GetValues(typeof(WindowCaptureMode))) { foreach (WindowCaptureMode captureMode in Enum.GetValues(typeof(WindowCaptureMode))) {
selectList.AddItem(Language.GetString(enumTypeName + "." + captureMode.ToString()), captureMode, _conf.WindowCaptureMode == captureMode); selectList.AddItem(Language.GetString(enumTypeName + "." + captureMode), captureMode, _conf.WindowCaptureMode == captureMode);
} }
selectList.CheckedChanged += QuickSettingCaptureModeChanged; selectList.CheckedChanged += QuickSettingCaptureModeChanged;
contextmenu_quicksettings.DropDownItems.Add(selectList); contextmenu_quicksettings.DropDownItems.Add(selectList);
} }
// print options // print options
selectList = new ToolStripMenuSelectList("printoptions",true); selectList = new ToolStripMenuSelectList("printoptions", true)
selectList.Text = Language.GetString(LangKey.settings_printoptions); {
Text = Language.GetString(LangKey.settings_printoptions)
};
IniValue iniValue; IniValue iniValue;
foreach(string propertyName in _conf.Values.Keys) { foreach(string propertyName in _conf.Values.Keys) {
@ -1162,8 +1159,10 @@ namespace Greenshot {
} }
// effects // effects
selectList = new ToolStripMenuSelectList("effects",true); selectList = new ToolStripMenuSelectList("effects", true)
selectList.Text = Language.GetString(LangKey.settings_visualization); {
Text = Language.GetString(LangKey.settings_visualization)
};
iniValue = _conf.Values["PlayCameraSound"]; iniValue = _conf.Values["PlayCameraSound"];
if (!iniValue.IsFixed) { if (!iniValue.IsFixed) {
@ -1383,7 +1382,7 @@ namespace Greenshot {
// Close all open forms (except this), use a separate List to make sure we don't get a "InvalidOperationException: Collection was modified" // Close all open forms (except this), use a separate List to make sure we don't get a "InvalidOperationException: Collection was modified"
List<Form> formsToClose = new List<Form>(); List<Form> formsToClose = new List<Form>();
foreach(Form form in Application.OpenForms) { foreach(Form form in Application.OpenForms) {
if (form.Handle != Handle && !form.GetType().Equals(typeof(ImageEditorForm))) { if (form.Handle != Handle && form.GetType() != typeof(ImageEditorForm)) {
formsToClose.Add(form); formsToClose.Add(form);
} }
} }
@ -1459,9 +1458,11 @@ namespace Greenshot {
if (UpdateHelper.IsUpdateCheckNeeded()) { if (UpdateHelper.IsUpdateCheckNeeded()) {
LOG.Debug("BackgroundWorkerTimerTick checking for update"); LOG.Debug("BackgroundWorkerTimerTick checking for update");
// Start update check in the background // Start update check in the background
Thread backgroundTask = new Thread (UpdateHelper.CheckAndAskForUpdate); var backgroundTask = new Thread(UpdateHelper.CheckAndAskForUpdate)
backgroundTask.Name = "Update check"; {
backgroundTask.IsBackground = true; Name = "Update check",
IsBackground = true
};
backgroundTask.Start(); backgroundTask.Start();
} }
} }

View file

@ -86,7 +86,7 @@ namespace Greenshot.Forms {
/// <param name="screenCoordinates">Point with the coordinates</param> /// <param name="screenCoordinates">Point with the coordinates</param>
/// <returns>Color at the specified screenCoordinates</returns> /// <returns>Color at the specified screenCoordinates</returns>
private static Color GetPixelColor(Point screenCoordinates) { private static Color GetPixelColor(Point screenCoordinates) {
using (SafeWindowDCHandle screenDC = SafeWindowDCHandle.FromDesktop()) { using (SafeWindowDcHandle screenDC = SafeWindowDcHandle.FromDesktop()) {
try { try {
uint pixel = GDI32.GetPixel(screenDC, screenCoordinates.X, screenCoordinates.Y); uint pixel = GDI32.GetPixel(screenDC, screenCoordinates.X, screenCoordinates.Y);
Color color = Color.FromArgb(255, (int)(pixel & 0xFF), (int)(pixel & 0xFF00) >> 8, (int)(pixel & 0xFF0000) >> 16); Color color = Color.FromArgb(255, (int)(pixel & 0xFF), (int)(pixel & 0xFF00) >> 8, (int)(pixel & 0xFF0000) >> 16);

View file

@ -21,137 +21,130 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Core;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using GreenshotPlugin.Effects;
namespace Greenshot.Forms { namespace Greenshot.Forms {
/// <summary> /// <summary>
/// A form to set the resize settings /// A form to set the resize settings
/// </summary> /// </summary>
public partial class ResizeSettingsForm : BaseForm { public partial class ResizeSettingsForm : BaseForm {
private readonly ResizeEffect effect; private readonly ResizeEffect _effect;
private readonly string value_pixel; private readonly string _valuePercent;
private readonly string value_percent; private double _newWidth, _newHeight;
private double newWidth, newHeight;
public ResizeSettingsForm(ResizeEffect effect) { public ResizeSettingsForm(ResizeEffect effect) {
this.effect = effect; _effect = effect;
InitializeComponent(); InitializeComponent();
value_pixel = Language.GetString("editor_resize_pixel"); var valuePixel = Language.GetString("editor_resize_pixel");
value_percent = Language.GetString("editor_resize_percent"); _valuePercent = Language.GetString("editor_resize_percent");
combobox_width.Items.Add(value_pixel); combobox_width.Items.Add(valuePixel);
combobox_width.Items.Add(value_percent); combobox_width.Items.Add(_valuePercent);
combobox_width.SelectedItem = value_pixel; combobox_width.SelectedItem = valuePixel;
combobox_height.Items.Add(value_pixel); combobox_height.Items.Add(valuePixel);
combobox_height.Items.Add(value_percent); combobox_height.Items.Add(_valuePercent);
combobox_height.SelectedItem = value_pixel; combobox_height.SelectedItem = valuePixel;
textbox_width.Text = effect.Width.ToString(); textbox_width.Text = effect.Width.ToString();
textbox_height.Text = effect.Height.ToString(); textbox_height.Text = effect.Height.ToString();
newWidth = effect.Width; _newWidth = effect.Width;
newHeight = effect.Height; _newHeight = effect.Height;
combobox_width.SelectedIndexChanged += new EventHandler(combobox_SelectedIndexChanged); combobox_width.SelectedIndexChanged += combobox_SelectedIndexChanged;
combobox_height.SelectedIndexChanged += new EventHandler(combobox_SelectedIndexChanged); combobox_height.SelectedIndexChanged += combobox_SelectedIndexChanged;
checkbox_aspectratio.Checked = effect.MaintainAspectRatio; checkbox_aspectratio.Checked = effect.MaintainAspectRatio;
} }
private void buttonOK_Click(object sender, EventArgs e) { private void buttonOK_Click(object sender, EventArgs e) {
if (newWidth != effect.Width || newHeight != effect.Height) { if (_newWidth != _effect.Width || _newHeight != _effect.Height) {
effect.Width = (int)newWidth; _effect.Width = (int)_newWidth;
effect.Height = (int)newHeight; _effect.Height = (int)_newHeight;
effect.MaintainAspectRatio = checkbox_aspectratio.Checked; _effect.MaintainAspectRatio = checkbox_aspectratio.Checked;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
} }
private bool validate(object sender) { private static bool Validate(object sender) {
TextBox textbox = sender as TextBox; TextBox textbox = sender as TextBox;
if (textbox != null) { if (textbox != null) {
double numberEntered; double numberEntered;
if (!double.TryParse(textbox.Text, out numberEntered)) { if (!double.TryParse(textbox.Text, out numberEntered)) {
textbox.BackColor = Color.Red; textbox.BackColor = Color.Red;
return false; return false;
} else {
textbox.BackColor = Color.White;
} }
textbox.BackColor = Color.White;
} }
return true; return true;
} }
private void displayWidth() { private void DisplayWidth() {
double displayValue; double displayValue;
if (value_percent.Equals(combobox_width.SelectedItem)) { if (_valuePercent.Equals(combobox_width.SelectedItem)) {
displayValue = (double)newWidth / (double)effect.Width * 100d; displayValue = _newWidth / _effect.Width * 100d;
} else { } else {
displayValue = newWidth; displayValue = _newWidth;
} }
textbox_width.Text = ((int)displayValue).ToString(); textbox_width.Text = ((int)displayValue).ToString();
} }
private void displayHeight() { private void DisplayHeight() {
double displayValue; double displayValue;
if (value_percent.Equals(combobox_height.SelectedItem)) { if (_valuePercent.Equals(combobox_height.SelectedItem)) {
displayValue = (double)newHeight / (double)effect.Height * 100d; displayValue = _newHeight / _effect.Height * 100d;
} else { } else {
displayValue = newHeight; displayValue = _newHeight;
} }
textbox_height.Text = ((int)displayValue).ToString(); textbox_height.Text = ((int)displayValue).ToString();
} }
private void textbox_KeyUp(object sender, KeyEventArgs e) { private void textbox_KeyUp(object sender, KeyEventArgs e) {
if (!validate(sender)) { if (!Validate(sender)) {
return; return;
} }
TextBox textbox = sender as TextBox; TextBox textbox = sender as TextBox;
if (textbox.Text.Length == 0) { if (string.IsNullOrEmpty(textbox?.Text)) {
return; return;
} }
bool isWidth = textbox == textbox_width; bool isWidth = textbox == textbox_width;
if (!checkbox_aspectratio.Checked) { if (!checkbox_aspectratio.Checked) {
if (isWidth) { if (isWidth) {
newWidth = double.Parse(textbox_width.Text); _newWidth = double.Parse(textbox_width.Text);
} else { } else {
newHeight = double.Parse(textbox_height.Text); _newHeight = double.Parse(textbox_height.Text);
} }
return; return;
} }
bool isPercent = false; var isPercent = _valuePercent.Equals(isWidth ? combobox_width.SelectedItem : combobox_height.SelectedItem);
if (isWidth) {
isPercent = value_percent.Equals(combobox_width.SelectedItem);
} else {
isPercent = value_percent.Equals(combobox_height.SelectedItem);
}
double percent; double percent;
if (isWidth) { if (isWidth) {
if (isPercent) { if (isPercent) {
percent = double.Parse(textbox_width.Text); percent = double.Parse(textbox_width.Text);
newWidth = (double)effect.Width / 100d * percent; _newWidth = _effect.Width / 100d * percent;
} else { } else {
newWidth = double.Parse(textbox_width.Text); _newWidth = double.Parse(textbox_width.Text);
percent = (double)double.Parse(textbox_width.Text) / (double)effect.Width * 100d; percent = double.Parse(textbox_width.Text) / _effect.Width * 100d;
} }
if (checkbox_aspectratio.Checked) { if (checkbox_aspectratio.Checked) {
newHeight = (double)effect.Height / 100d * percent; _newHeight = _effect.Height / 100d * percent;
displayHeight(); DisplayHeight();
} }
} else { } else {
if (isPercent) { if (isPercent) {
percent = double.Parse(textbox_height.Text); percent = double.Parse(textbox_height.Text);
newHeight = (double)effect.Height / 100d * percent; _newHeight = _effect.Height / 100d * percent;
} else { } else {
newHeight = double.Parse(textbox_height.Text); _newHeight = double.Parse(textbox_height.Text);
percent = (double)double.Parse(textbox_height.Text) / (double)effect.Height * 100d; percent = double.Parse(textbox_height.Text) / _effect.Height * 100d;
} }
if (checkbox_aspectratio.Checked) { if (checkbox_aspectratio.Checked) {
newWidth = (double)effect.Width / 100d * percent; _newWidth = _effect.Width / 100d * percent;
displayWidth(); DisplayWidth();
} }
} }
} }
private void textbox_Validating(object sender, System.ComponentModel.CancelEventArgs e) { private void textbox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
validate(sender); Validate(sender);
} }
/// <summary> /// <summary>
@ -160,11 +153,11 @@ namespace Greenshot.Forms {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private void combobox_SelectedIndexChanged(object sender, EventArgs e) { private void combobox_SelectedIndexChanged(object sender, EventArgs e) {
if (validate(textbox_width)) { if (Validate(textbox_width)) {
displayWidth(); DisplayWidth();
} }
if (validate(textbox_height)) { if (Validate(textbox_height)) {
displayHeight(); DisplayHeight();
} }
} }
} }

View file

@ -43,8 +43,7 @@ namespace Greenshot {
/// Description of SettingsForm. /// Description of SettingsForm.
/// </summary> /// </summary>
public partial class SettingsForm : BaseForm { public partial class SettingsForm : BaseForm {
private static readonly ILog LOG = LogManager.GetLogger(typeof(SettingsForm)); private static readonly ILog Log = LogManager.GetLogger(typeof(SettingsForm));
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
private readonly ToolTip _toolTip = new ToolTip(); private readonly ToolTip _toolTip = new ToolTip();
private bool _inHotkey; private bool _inHotkey;
@ -59,11 +58,7 @@ namespace Greenshot {
base.OnLoad(e); base.OnLoad(e);
// Fix for Vista/XP differences // Fix for Vista/XP differences
if (Environment.OSVersion.Version.Major >= 6) { trackBarJpegQuality.BackColor = Environment.OSVersion.Version.Major >= 6 ? SystemColors.Window : SystemColors.Control;
trackBarJpegQuality.BackColor = SystemColors.Window;
} else {
trackBarJpegQuality.BackColor = SystemColors.Control;
}
// This makes it possible to still capture the settings screen // This makes it possible to still capture the settings screen
fullscreen_hotkeyControl.Enter += EnterHotkeyControl; fullscreen_hotkeyControl.Enter += EnterHotkeyControl;
@ -78,7 +73,7 @@ namespace Greenshot {
lastregion_hotkeyControl.Leave += LeaveHotkeyControl; lastregion_hotkeyControl.Leave += LeaveHotkeyControl;
DisplayPluginTab(); DisplayPluginTab();
UpdateUI(); UpdateUi();
ExpertSettingsEnableState(false); ExpertSettingsEnableState(false);
DisplaySettings(); DisplaySettings();
CheckSettings(); CheckSettings();
@ -116,9 +111,9 @@ namespace Greenshot {
/// <param name="comboBox">ComboBox to populate</param> /// <param name="comboBox">ComboBox to populate</param>
/// <param name="availableValues"></param> /// <param name="availableValues"></param>
/// <param name="selectedValue"></param> /// <param name="selectedValue"></param>
private void PopulateComboBox<ET>(ComboBox comboBox, ET[] availableValues, ET selectedValue) where ET : struct { private void PopulateComboBox<TEnum>(ComboBox comboBox, TEnum[] availableValues, TEnum selectedValue) where TEnum : struct {
comboBox.Items.Clear(); comboBox.Items.Clear();
foreach(ET enumValue in availableValues) { foreach(TEnum enumValue in availableValues) {
comboBox.Items.Add(Language.Translate(enumValue)); comboBox.Items.Add(Language.Translate(enumValue));
} }
comboBox.SelectedItem = Language.Translate(selectedValue); comboBox.SelectedItem = Language.Translate(selectedValue);
@ -130,13 +125,13 @@ namespace Greenshot {
/// </summary> /// </summary>
/// <param name="comboBox">Combobox to get the value from</param> /// <param name="comboBox">Combobox to get the value from</param>
/// <returns>The generics value of the combobox</returns> /// <returns>The generics value of the combobox</returns>
private ET GetSelected<ET>(ComboBox comboBox) { private TEnum GetSelected<TEnum>(ComboBox comboBox) {
string enumTypeName = typeof(ET).Name; string enumTypeName = typeof(TEnum).Name;
string selectedValue = comboBox.SelectedItem as string; string selectedValue = comboBox.SelectedItem as string;
ET[] availableValues = (ET[])Enum.GetValues(typeof(ET)); TEnum[] availableValues = (TEnum[])Enum.GetValues(typeof(TEnum));
ET returnValue = availableValues[0]; TEnum returnValue = availableValues[0];
foreach(ET enumValue in availableValues) { foreach(TEnum enumValue in availableValues) {
string translation = Language.GetString(enumTypeName + "." + enumValue.ToString()); string translation = Language.GetString(enumTypeName + "." + enumValue);
if (translation.Equals(selectedValue)) { if (translation.Equals(selectedValue)) {
returnValue = enumValue; returnValue = enumValue;
break; break;
@ -196,7 +191,7 @@ namespace Greenshot {
/// <summary> /// <summary>
/// Update the UI to reflect the language and other text settings /// Update the UI to reflect the language and other text settings
/// </summary> /// </summary>
private void UpdateUI() { private void UpdateUi() {
if (coreConfiguration.HideExpertSettings) { if (coreConfiguration.HideExpertSettings) {
tabcontrol.Controls.Remove(tab_expert); tabcontrol.Controls.Remove(tab_expert);
} }
@ -230,13 +225,12 @@ namespace Greenshot {
} }
private bool CheckFilenamePattern() { private bool CheckFilenamePattern() {
bool settingsOk = true;
string filename = FilenameHelper.GetFilenameFromPattern(textbox_screenshotname.Text, coreConfiguration.OutputFileFormat, null); string filename = FilenameHelper.GetFilenameFromPattern(textbox_screenshotname.Text, coreConfiguration.OutputFileFormat, null);
// we allow dynamically created subfolders, need to check for them, too // we allow dynamically created subfolders, need to check for them, too
string[] pathParts = filename.Split(Path.DirectorySeparatorChar); string[] pathParts = filename.Split(Path.DirectorySeparatorChar);
string filenamePart = pathParts[pathParts.Length-1]; string filenamePart = pathParts[pathParts.Length-1];
settingsOk = FilenameHelper.IsFilenameValid(filenamePart); var settingsOk = FilenameHelper.IsFilenameValid(filenamePart);
for (int i = 0; settingsOk && i<pathParts.Length-1; i++) { for (int i = 0; settingsOk && i<pathParts.Length-1; i++) {
settingsOk = FilenameHelper.IsDirectoryNameValid(pathParts[i]); settingsOk = FilenameHelper.IsDirectoryNameValid(pathParts[i]);
@ -248,10 +242,7 @@ namespace Greenshot {
} }
private bool CheckStorageLocationPath() { private bool CheckStorageLocationPath() {
bool settingsOk = true; bool settingsOk = Directory.Exists(FilenameHelper.FillVariables(textbox_storagelocation.Text, false));
if(!Directory.Exists(FilenameHelper.FillVariables(textbox_storagelocation.Text, false))) {
settingsOk = false;
}
DisplayTextBoxValidity(textbox_storagelocation, settingsOk); DisplayTextBoxValidity(textbox_storagelocation, settingsOk);
return settingsOk; return settingsOk;
} }
@ -259,11 +250,7 @@ namespace Greenshot {
private void DisplayTextBoxValidity(GreenshotTextBox textbox, bool valid) { private void DisplayTextBoxValidity(GreenshotTextBox textbox, bool valid) {
if (valid) { if (valid) {
// "Added" feature #3547158 // "Added" feature #3547158
if (Environment.OSVersion.Version.Major >= 6) { textbox.BackColor = Environment.OSVersion.Version.Major >= 6 ? SystemColors.Window : SystemColors.Control;
textbox.BackColor = SystemColors.Window;
} else {
textbox.BackColor = SystemColors.Control;
}
} else { } else {
textbox.BackColor = Color.Red; textbox.BackColor = Color.Red;
} }
@ -464,7 +451,7 @@ namespace Greenshot {
} }
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Warn("Problem checking registry, ignoring for now: ", e); Log.Warn("Problem checking registry, ignoring for now: ", e);
} }
} }
@ -480,7 +467,7 @@ namespace Greenshot {
MainForm.RegisterHotkeys(); MainForm.RegisterHotkeys();
// Make sure the current language & settings are reflected in the Main-context menu // Make sure the current language & settings are reflected in the Main-context menu
MainForm.Instance.UpdateUI(); MainForm.Instance.UpdateUi();
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} else { } else {
tabcontrol.SelectTab(tab_output); tabcontrol.SelectTab(tab_output);
@ -511,7 +498,7 @@ namespace Greenshot {
} }
private void Listview_pluginsSelectedIndexChanged(object sender, EventArgs e) { private void Listview_pluginsSelectedIndexChanged(object sender, EventArgs e) {
button_pluginconfigure.Enabled = PluginHelper.Instance.isSelectedItemConfigurable(listview_plugins); button_pluginconfigure.Enabled = PluginHelper.Instance.IsSelectedItemConfigurable(listview_plugins);
} }
private void Button_pluginconfigureClick(object sender, EventArgs e) { private void Button_pluginconfigureClick(object sender, EventArgs e) {
@ -523,11 +510,11 @@ namespace Greenshot {
//EmailFormat selectedEmailFormat = GetSelected<EmailFormat>(combobox_emailformat); //EmailFormat selectedEmailFormat = GetSelected<EmailFormat>(combobox_emailformat);
WindowCaptureMode selectedWindowCaptureMode = GetSelected<WindowCaptureMode>(combobox_window_capture_mode); WindowCaptureMode selectedWindowCaptureMode = GetSelected<WindowCaptureMode>(combobox_window_capture_mode);
if (combobox_language.SelectedItem != null) { if (combobox_language.SelectedItem != null) {
LOG.Debug("Setting language to: " + (string)combobox_language.SelectedValue); Log.Debug("Setting language to: " + (string)combobox_language.SelectedValue);
Language.CurrentLanguage = (string)combobox_language.SelectedValue; Language.CurrentLanguage = (string)combobox_language.SelectedValue;
} }
// Reflect language changes to the settings form // Reflect language changes to the settings form
UpdateUI(); UpdateUi();
// Reflect Language changes form // Reflect Language changes form
ApplyLanguage(); ApplyLanguage();
@ -652,7 +639,7 @@ namespace Greenshot {
return 1; return 1;
} }
if (firstDestination != null && firstDestination.Priority == secondDestination.Priority) { if (firstDestination != null && firstDestination.Priority == secondDestination.Priority) {
return firstDestination.Description.CompareTo(secondDestination.Description); return string.Compare(firstDestination.Description, secondDestination.Description, StringComparison.Ordinal);
} }
if (firstDestination != null) { if (firstDestination != null) {
return firstDestination.Priority - secondDestination.Priority; return firstDestination.Priority - secondDestination.Priority;

View file

@ -31,11 +31,11 @@ namespace Greenshot.Forms {
/// <summary> /// <summary>
/// the ToolStripMenuSelectList makes it possible to have a single or multi-check menu /// the ToolStripMenuSelectList makes it possible to have a single or multi-check menu
/// </summary> /// </summary>
public class ToolStripMenuSelectList : ToolStripMenuItem { public sealed class ToolStripMenuSelectList : ToolStripMenuItem {
private static readonly CoreConfiguration coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private readonly bool multiCheckAllowed; private readonly bool _multiCheckAllowed;
private bool updateInProgress; private bool _updateInProgress;
private static Image defaultImage; private static Image _defaultImage;
/// <summary> /// <summary>
/// Occurs when one of the list's child element's Checked state changes. /// Occurs when one of the list's child element's Checked state changes.
@ -49,14 +49,12 @@ namespace Greenshot.Forms {
public ToolStripMenuSelectList(object identifier, bool allowMultiCheck) { public ToolStripMenuSelectList(object identifier, bool allowMultiCheck) {
Identifier = identifier; Identifier = identifier;
CheckOnClick = false; CheckOnClick = false;
multiCheckAllowed = allowMultiCheck; _multiCheckAllowed = allowMultiCheck;
if (defaultImage == null || defaultImage.Size != coreConfiguration.IconSize) { if (_defaultImage == null || _defaultImage.Size != CoreConfig.IconSize) {
if (defaultImage != null) { _defaultImage?.Dispose();
defaultImage.Dispose(); _defaultImage = ImageHelper.CreateEmpty(CoreConfig.IconSize.Width, CoreConfig.IconSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Color.Transparent, 96f, 96f);
}
defaultImage = ImageHelper.CreateEmpty(coreConfiguration.IconSize.Width, coreConfiguration.IconSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Color.Transparent, 96f, 96f);
} }
Image = defaultImage; Image = _defaultImage;
} }
public ToolStripMenuSelectList() : this(null,false) {} public ToolStripMenuSelectList() : this(null,false) {}
public ToolStripMenuSelectList(object identifier) : this(identifier,false) {} public ToolStripMenuSelectList(object identifier) : this(identifier,false) {}
@ -70,7 +68,7 @@ namespace Greenshot.Forms {
IEnumerator items = DropDownItems.GetEnumerator(); IEnumerator items = DropDownItems.GetEnumerator();
while (items.MoveNext()) { while (items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current; ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current;
if (tsmi.Checked) { if (tsmi != null && tsmi.Checked) {
return tsmi; return tsmi;
} }
} }
@ -80,9 +78,9 @@ namespace Greenshot.Forms {
IEnumerator items = DropDownItems.GetEnumerator(); IEnumerator items = DropDownItems.GetEnumerator();
while (items.MoveNext()) { while (items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current; ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current;
if (!multiCheckAllowed && !tsmi.Equals(value)) { if (tsmi != null && !_multiCheckAllowed && !tsmi.Equals(value)) {
tsmi.Checked = false; tsmi.Checked = false;
} else if (tsmi.Equals(value)) { } else if (tsmi != null && tsmi.Equals(value)) {
tsmi.Checked = true; tsmi.Checked = true;
} }
} }
@ -98,30 +96,31 @@ namespace Greenshot.Forms {
IEnumerator items = DropDownItems.GetEnumerator(); IEnumerator items = DropDownItems.GetEnumerator();
while(items.MoveNext()) { while(items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current; ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current;
if (tsmi.Checked) { if (tsmi != null && tsmi.Checked) {
sel.Add(tsmi); sel.Add(tsmi);
} }
} }
return sel.ToArray(); return sel.ToArray();
} }
set { set {
if (!multiCheckAllowed) { if (!_multiCheckAllowed) {
throw new ArgumentException("Writing to checkedItems is only allowed in multi-check mode. Either set allowMultiCheck to true or use set SelectedItem instead of SelectedItems."); throw new ArgumentException("Writing to checkedItems is only allowed in multi-check mode. Either set allowMultiCheck to true or use set SelectedItem instead of SelectedItems.");
} }
IEnumerator items = DropDownItems.GetEnumerator(); IEnumerator items = DropDownItems.GetEnumerator();
IEnumerator sel = value.GetEnumerator(); IEnumerator sel = value.GetEnumerator();
while (items.MoveNext()) { while (items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current; var toolStripMenuSelectListItem = (ToolStripMenuSelectListItem)items.Current;
while (sel.MoveNext()) { if (toolStripMenuSelectListItem == null)
if (tsmi.Equals(sel.Current)) { {
tsmi.Checked = true; continue;
} else { }
tsmi.Checked = false; while (sel.MoveNext())
} {
if (!multiCheckAllowed && !tsmi.Equals(sel.Current)) { toolStripMenuSelectListItem.Checked = toolStripMenuSelectListItem.Equals(sel.Current);
tsmi.Checked = false; if (!_multiCheckAllowed && !toolStripMenuSelectListItem.Equals(sel.Current)) {
} else if (tsmi.Equals(value)) { toolStripMenuSelectListItem.Checked = false;
tsmi.Checked = true; } else if (toolStripMenuSelectListItem.Equals(value)) {
toolStripMenuSelectListItem.Checked = true;
} }
} }
} }
@ -129,19 +128,17 @@ namespace Greenshot.Forms {
} }
private void ItemCheckStateChanged(object sender, EventArgs e) { private void ItemCheckStateChanged(object sender, EventArgs e) {
if (updateInProgress) { if (_updateInProgress) {
return; return;
} }
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)sender; var toolStripMenuSelectListItem = (ToolStripMenuSelectListItem)sender;
updateInProgress = true; _updateInProgress = true;
if (tsmi.Checked && !multiCheckAllowed) { if (toolStripMenuSelectListItem.Checked && !_multiCheckAllowed) {
UncheckAll(); UncheckAll();
tsmi.Checked = true; toolStripMenuSelectListItem.Checked = true;
}
updateInProgress = false;
if (CheckedChanged != null) {
CheckedChanged(this, new ItemCheckedChangedEventArgs(tsmi));
} }
_updateInProgress = false;
CheckedChanged?.Invoke(this, new ItemCheckedChangedEventArgs(toolStripMenuSelectListItem));
} }
/// <summary> /// <summary>
@ -151,26 +148,28 @@ namespace Greenshot.Forms {
/// <param name="image">the icon to be displayed</param> /// <param name="image">the icon to be displayed</param>
/// <param name="data">the data to be returned when an item is queried</param> /// <param name="data">the data to be returned when an item is queried</param>
/// <param name="isChecked">whether the item is initially checked</param> /// <param name="isChecked">whether the item is initially checked</param>
public void AddItem(string label, Image image, Object data, bool isChecked) { public void AddItem(string label, Image image, object data, bool isChecked) {
ToolStripMenuSelectListItem newItem = new ToolStripMenuSelectListItem(); var toolStripMenuSelectListItem = new ToolStripMenuSelectListItem
newItem.Text = label; {
Text = label
};
if (image == null) { if (image == null) {
image = defaultImage; image = _defaultImage;
} }
newItem.DisplayStyle = ToolStripItemDisplayStyle.Text; toolStripMenuSelectListItem.DisplayStyle = ToolStripItemDisplayStyle.Text;
newItem.Image = image; toolStripMenuSelectListItem.Image = image;
newItem.CheckOnClick = true; toolStripMenuSelectListItem.CheckOnClick = true;
newItem.CheckStateChanged += ItemCheckStateChanged; toolStripMenuSelectListItem.CheckStateChanged += ItemCheckStateChanged;
newItem.Data = data; toolStripMenuSelectListItem.Data = data;
if (isChecked) { if (isChecked) {
if (!multiCheckAllowed) { if (!_multiCheckAllowed) {
updateInProgress = true; _updateInProgress = true;
UncheckAll(); UncheckAll();
updateInProgress = false; _updateInProgress = false;
} }
newItem.Checked = isChecked; toolStripMenuSelectListItem.Checked = true;
} }
DropDownItems.Add(newItem); DropDownItems.Add(toolStripMenuSelectListItem);
} }
/// <summary> /// <summary>
@ -187,7 +186,7 @@ namespace Greenshot.Forms {
/// </summary> /// </summary>
/// <param name="label">the label to be displayed</param> /// <param name="label">the label to be displayed</param>
/// <param name="data">the data to be returned when an item is queried</param> /// <param name="data">the data to be returned when an item is queried</param>
public void AddItem(string label, Object data) { public void AddItem(string label, object data) {
AddItem(label, null, data, false); AddItem(label, null, data, false);
} }
@ -216,7 +215,7 @@ namespace Greenshot.Forms {
/// <param name="label">the label to be displayed</param> /// <param name="label">the label to be displayed</param>
/// <param name="data">the data to be returned when an item is queried</param> /// <param name="data">the data to be returned when an item is queried</param>
/// <param name="isChecked">whether the item is initially checked</param> /// <param name="isChecked">whether the item is initially checked</param>
public void AddItem(string label, Object data, bool isChecked) { public void AddItem(string label, object data, bool isChecked) {
AddItem(label, null, data, isChecked); AddItem(label, null, data, isChecked);
} }
@ -234,8 +233,13 @@ namespace Greenshot.Forms {
/// </summary> /// </summary>
public void UncheckAll() { public void UncheckAll() {
IEnumerator items = DropDownItems.GetEnumerator(); IEnumerator items = DropDownItems.GetEnumerator();
while (items.MoveNext()) { while (items.MoveNext())
((ToolStripMenuSelectListItem)items.Current).Checked = false; {
var toolStripMenuSelectListItem = (ToolStripMenuSelectListItem)items.Current;
if (toolStripMenuSelectListItem != null)
{
toolStripMenuSelectListItem.Checked = false;
}
} }
} }
} }

View file

@ -21,41 +21,41 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Core; using GreenshotPlugin.Effects;
namespace Greenshot.Forms { namespace Greenshot.Forms {
public partial class TornEdgeSettingsForm : BaseForm { public partial class TornEdgeSettingsForm : BaseForm {
private readonly TornEdgeEffect effect; private readonly TornEdgeEffect _effect;
public TornEdgeSettingsForm(TornEdgeEffect effect) { public TornEdgeSettingsForm(TornEdgeEffect effect) {
this.effect = effect; _effect = effect;
InitializeComponent(); InitializeComponent();
ShowSettings(); ShowSettings();
} }
private void ShowSettings() { private void ShowSettings() {
shadowCheckbox.Checked = effect.GenerateShadow; shadowCheckbox.Checked = _effect.GenerateShadow;
// Fix to prevent BUG-1753 // Fix to prevent BUG-1753
shadowDarkness.Value = Math.Max(shadowDarkness.Minimum, Math.Min(shadowDarkness.Maximum, (int)(effect.Darkness * shadowDarkness.Maximum))); shadowDarkness.Value = Math.Max(shadowDarkness.Minimum, Math.Min(shadowDarkness.Maximum, (int)(_effect.Darkness * shadowDarkness.Maximum)));
offsetX.Value = effect.ShadowOffset.X; offsetX.Value = _effect.ShadowOffset.X;
offsetY.Value = effect.ShadowOffset.Y; offsetY.Value = _effect.ShadowOffset.Y;
toothsize.Value = effect.ToothHeight; toothsize.Value = _effect.ToothHeight;
verticaltoothrange.Value = effect.VerticalToothRange; verticaltoothrange.Value = _effect.VerticalToothRange;
horizontaltoothrange.Value = effect.HorizontalToothRange; horizontaltoothrange.Value = _effect.HorizontalToothRange;
top.Checked = effect.Edges[0]; top.Checked = _effect.Edges[0];
right.Checked = effect.Edges[1]; right.Checked = _effect.Edges[1];
bottom.Checked = effect.Edges[2]; bottom.Checked = _effect.Edges[2];
left.Checked = effect.Edges[3]; left.Checked = _effect.Edges[3];
} }
private void ButtonOK_Click(object sender, EventArgs e) { private void ButtonOK_Click(object sender, EventArgs e) {
effect.Darkness = (float)shadowDarkness.Value / (float)40; _effect.Darkness = shadowDarkness.Value / (float)40;
effect.ShadowOffset = new Point((int)offsetX.Value, (int)offsetY.Value); _effect.ShadowOffset = new Point((int)offsetX.Value, (int)offsetY.Value);
effect.ShadowSize = (int)thickness.Value; _effect.ShadowSize = (int)thickness.Value;
effect.ToothHeight = (int)toothsize.Value; _effect.ToothHeight = (int)toothsize.Value;
effect.VerticalToothRange = (int)verticaltoothrange.Value; _effect.VerticalToothRange = (int)verticaltoothrange.Value;
effect.HorizontalToothRange = (int)horizontaltoothrange.Value; _effect.HorizontalToothRange = (int)horizontaltoothrange.Value;
effect.Edges = new bool[] { top.Checked, right.Checked, bottom.Checked, left.Checked }; _effect.Edges = new[] { top.Checked, right.Checked, bottom.Checked, left.Checked };
effect.GenerateShadow = shadowCheckbox.Checked; _effect.GenerateShadow = shadowCheckbox.Checked;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
@ -68,35 +68,35 @@ namespace Greenshot.Forms {
private void all_CheckedChanged(object sender, EventArgs e) { private void all_CheckedChanged(object sender, EventArgs e) {
AnySideChangeChecked(top, all.Checked); AnySideChangeChecked(top, all.Checked);
AnySideChangeChecked(right, all.Checked); AnySideChangeChecked(right, all.Checked);
AnySideChangeChecked(bottom, all.Checked); AnySideChangeChecked(bottom, all.Checked);
AnySideChangeChecked(left, all.Checked); AnySideChangeChecked(left, all.Checked);
} }
private void AnySideCheckedChanged(object sender, EventArgs e) { private void AnySideCheckedChanged(object sender, EventArgs e) {
all.CheckedChanged -= all_CheckedChanged; all.CheckedChanged -= all_CheckedChanged;
all.Checked = top.Checked && right.Checked && bottom.Checked && left.Checked; all.Checked = top.Checked && right.Checked && bottom.Checked && left.Checked;
all.CheckedChanged += all_CheckedChanged; all.CheckedChanged += all_CheckedChanged;
} }
/// <summary> /// <summary>
/// changes the Checked property of top/right/bottom/left checkboxes without triggering AnySideCheckedChange /// changes the Checked property of top/right/bottom/left checkboxes without triggering AnySideCheckedChange
/// </summary> /// </summary>
/// <param name="cb">Checkbox to change Checked</param> /// <param name="cb">Checkbox to change Checked</param>
/// <param name="status">true to check</param> /// <param name="status">true to check</param>
private void AnySideChangeChecked(CheckBox cb, bool status) { private void AnySideChangeChecked(CheckBox cb, bool status) {
if (status != cb.Checked) { if (status != cb.Checked) {
cb.CheckedChanged -= AnySideCheckedChanged; cb.CheckedChanged -= AnySideCheckedChanged;
cb.Checked = status; cb.Checked = status;
cb.CheckedChanged += AnySideCheckedChanged; cb.CheckedChanged += AnySideCheckedChanged;
} }
} }
private void TornEdgeSettingsForm_Load(object sender, EventArgs e) private void TornEdgeSettingsForm_Load(object sender, EventArgs e)
{ {
} }
} }
} }

View file

@ -29,21 +29,14 @@ namespace Greenshot.Help
/// <summary> /// <summary>
/// Description of HelpFileLoader. /// Description of HelpFileLoader.
/// </summary> /// </summary>
public sealed class HelpFileLoader public static class HelpFileLoader
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(HelpFileLoader));
private static readonly ILog LOG = LogManager.GetLogger(typeof(HelpFileLoader)); private const string ExtHelpUrl = @"http://getgreenshot.org/help/";
private const string EXT_HELP_URL = @"http://getgreenshot.org/help/";
private HelpFileLoader() {
}
public static void LoadHelp() { public static void LoadHelp() {
string uri = FindOnlineHelpUrl(Language.CurrentLanguage); string uri = FindOnlineHelpUrl(Language.CurrentLanguage) ?? Language.HelpFilePath;
if(uri == null) {
uri = Language.HelpFilePath;
}
Process.Start(uri); Process.Start(uri);
} }
@ -51,7 +44,7 @@ namespace Greenshot.Help
private static string FindOnlineHelpUrl(string currentIETF) { private static string FindOnlineHelpUrl(string currentIETF) {
string ret = null; string ret = null;
string extHelpUrlForCurrrentIETF = EXT_HELP_URL; string extHelpUrlForCurrrentIETF = ExtHelpUrl;
if(!currentIETF.Equals("en-US")) { if(!currentIETF.Equals("en-US")) {
extHelpUrlForCurrrentIETF += currentIETF.ToLower() + "/"; extHelpUrlForCurrrentIETF += currentIETF.ToLower() + "/";
@ -60,16 +53,16 @@ namespace Greenshot.Help
HttpStatusCode? httpStatusCode = GetHttpStatus(extHelpUrlForCurrrentIETF); HttpStatusCode? httpStatusCode = GetHttpStatus(extHelpUrlForCurrrentIETF);
if(httpStatusCode == HttpStatusCode.OK) { if(httpStatusCode == HttpStatusCode.OK) {
ret = extHelpUrlForCurrrentIETF; ret = extHelpUrlForCurrrentIETF;
} else if(httpStatusCode != null && !extHelpUrlForCurrrentIETF.Equals(EXT_HELP_URL)) { } else if(httpStatusCode != null && !extHelpUrlForCurrrentIETF.Equals(ExtHelpUrl)) {
LOG.DebugFormat("Localized online help not found at {0}, will try {1} as fallback", extHelpUrlForCurrrentIETF, EXT_HELP_URL); Log.DebugFormat("Localized online help not found at {0}, will try {1} as fallback", extHelpUrlForCurrrentIETF, ExtHelpUrl);
httpStatusCode = GetHttpStatus(EXT_HELP_URL); httpStatusCode = GetHttpStatus(ExtHelpUrl);
if(httpStatusCode == HttpStatusCode.OK) { if(httpStatusCode == HttpStatusCode.OK) {
ret = EXT_HELP_URL; ret = ExtHelpUrl;
} else { } else {
LOG.WarnFormat("{0} returned status {1}", EXT_HELP_URL, httpStatusCode); Log.WarnFormat("{0} returned status {1}", ExtHelpUrl, httpStatusCode);
} }
} else if(httpStatusCode == null){ } else if(httpStatusCode == null){
LOG.Info("Internet connection does not seem to be available, will load help from file system."); Log.Info("Internet connection does not seem to be available, will load help from file system.");
} }
return ret; return ret;
@ -88,11 +81,7 @@ namespace Greenshot.Help
return res.StatusCode; return res.StatusCode;
} }
} catch (WebException e) { } catch (WebException e) {
if (e.Response != null) return ((HttpWebResponse) e.Response)?.StatusCode;
{
return ((HttpWebResponse)e.Response).StatusCode;
}
return null;
} }
} }
} }

View file

@ -41,8 +41,8 @@ namespace Greenshot.Helpers {
/// CaptureHelper contains all the capture logic /// CaptureHelper contains all the capture logic
/// </summary> /// </summary>
public class CaptureHelper : IDisposable { public class CaptureHelper : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(CaptureHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(CaptureHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
// TODO: when we get the screen capture code working correctly, this needs to be enabled // TODO: when we get the screen capture code working correctly, this needs to be enabled
//private static ScreenCaptureHelper screenCapture = null; //private static ScreenCaptureHelper screenCapture = null;
private List<WindowDetails> _windows = new List<WindowDetails>(); private List<WindowDetails> _windows = new List<WindowDetails>();
@ -78,7 +78,7 @@ namespace Greenshot.Helpers {
_selectedCaptureWindow = null; _selectedCaptureWindow = null;
_capture = null; _capture = null;
// Empty working set after capturing // Empty working set after capturing
if (conf.MinimizeWorkingSetSize) { if (CoreConfig.MinimizeWorkingSetSize) {
PsAPI.EmptyWorkingSet(); PsAPI.EmptyWorkingSet();
} }
} }
@ -114,7 +114,7 @@ namespace Greenshot.Helpers {
} }
} }
public static void CaptureIE(bool captureMouse, WindowDetails windowToCapture) { public static void CaptureIe(bool captureMouse, WindowDetails windowToCapture) {
using (CaptureHelper captureHelper = new CaptureHelper(CaptureMode.IE, captureMouse)) { using (CaptureHelper captureHelper = new CaptureHelper(CaptureMode.IE, captureMouse)) {
captureHelper.SelectedCaptureWindow = windowToCapture; captureHelper.SelectedCaptureWindow = windowToCapture;
captureHelper.MakeCapture(); captureHelper.MakeCapture();
@ -192,7 +192,7 @@ namespace Greenshot.Helpers {
} }
private void DoCaptureFeedback() { private void DoCaptureFeedback() {
if(conf.PlayCameraSound) { if(CoreConfig.PlayCameraSound) {
SoundHelper.Play(); SoundHelper.Play();
} }
} }
@ -224,11 +224,11 @@ namespace Greenshot.Helpers {
// This fixes a problem when a balloon is still visible and a capture needs to be taken // This fixes a problem when a balloon is still visible and a capture needs to be taken
// forcefully removes the balloon! // forcefully removes the balloon!
if (!conf.HideTrayicon) { if (!CoreConfig.HideTrayicon) {
MainForm.Instance.NotifyIcon.Visible = false; MainForm.Instance.NotifyIcon.Visible = false;
MainForm.Instance.NotifyIcon.Visible = true; MainForm.Instance.NotifyIcon.Visible = true;
} }
LOG.Debug(String.Format("Capturing with mode {0} and using Cursor {1}", _captureMode, _captureMouseCursor)); Log.Debug($"Capturing with mode {_captureMode} and using Cursor {_captureMouseCursor}");
_capture.CaptureDetails.CaptureMode = _captureMode; _capture.CaptureDetails.CaptureMode = _captureMode;
// Get the windows details in a seperate thread, only for those captures that have a Feedback // Get the windows details in a seperate thread, only for those captures that have a Feedback
@ -251,27 +251,24 @@ namespace Greenshot.Helpers {
} }
// Delay for the Context menu // Delay for the Context menu
if (conf.CaptureDelay > 0) { if (CoreConfig.CaptureDelay > 0) {
Thread.Sleep(conf.CaptureDelay); Thread.Sleep(CoreConfig.CaptureDelay);
} else { } else {
conf.CaptureDelay = 0; CoreConfig.CaptureDelay = 0;
} }
// Capture Mousecursor if we are not loading from file or clipboard, only show when needed // Capture Mousecursor if we are not loading from file or clipboard, only show when needed
if (_captureMode != CaptureMode.File && _captureMode != CaptureMode.Clipboard) { if (_captureMode != CaptureMode.File && _captureMode != CaptureMode.Clipboard)
{
_capture = WindowCapture.CaptureCursor(_capture); _capture = WindowCapture.CaptureCursor(_capture);
if (_captureMouseCursor) { _capture.CursorVisible = _captureMouseCursor && CoreConfig.CaptureMousepointer;
_capture.CursorVisible = conf.CaptureMousepointer;
} else {
_capture.CursorVisible = false;
}
} }
switch(_captureMode) { switch(_captureMode) {
case CaptureMode.Window: case CaptureMode.Window:
_capture = WindowCapture.CaptureScreen(_capture); _capture = WindowCapture.CaptureScreen(_capture);
_capture.CaptureDetails.AddMetaData("source", "Screen"); _capture.CaptureDetails.AddMetaData("source", "Screen");
SetDPI(); SetDpi();
CaptureWithFeedback(); CaptureWithFeedback();
break; break;
case CaptureMode.ActiveWindow: case CaptureMode.ActiveWindow:
@ -285,13 +282,13 @@ namespace Greenshot.Helpers {
_capture.CaptureDetails.AddMetaData("source", "Screen"); _capture.CaptureDetails.AddMetaData("source", "Screen");
_capture.CaptureDetails.Title = "Screen"; _capture.CaptureDetails.Title = "Screen";
} }
SetDPI(); SetDpi();
HandleCapture(); HandleCapture();
break; break;
case CaptureMode.IE: case CaptureMode.IE:
if (IECaptureHelper.CaptureIE(_capture, SelectedCaptureWindow) != null) { if (IeCaptureHelper.CaptureIe(_capture, SelectedCaptureWindow) != null) {
_capture.CaptureDetails.AddMetaData("source", "Internet Explorer"); _capture.CaptureDetails.AddMetaData("source", "Internet Explorer");
SetDPI(); SetDpi();
HandleCapture(); HandleCapture();
} }
break; break;
@ -310,8 +307,8 @@ namespace Greenshot.Helpers {
} }
break; break;
case ScreenCaptureMode.Fixed: case ScreenCaptureMode.Fixed:
if (conf.ScreenToCapture > 0 && conf.ScreenToCapture <= Screen.AllScreens.Length) { if (CoreConfig.ScreenToCapture > 0 && CoreConfig.ScreenToCapture <= Screen.AllScreens.Length) {
_capture = WindowCapture.CaptureRectangle(_capture, Screen.AllScreens[conf.ScreenToCapture].Bounds); _capture = WindowCapture.CaptureRectangle(_capture, Screen.AllScreens[CoreConfig.ScreenToCapture].Bounds);
captureTaken = true; captureTaken = true;
} }
break; break;
@ -322,7 +319,7 @@ namespace Greenshot.Helpers {
if (!captureTaken) { if (!captureTaken) {
_capture = WindowCapture.CaptureScreen(_capture); _capture = WindowCapture.CaptureScreen(_capture);
} }
SetDPI(); SetDpi();
HandleCapture(); HandleCapture();
break; break;
case CaptureMode.Clipboard: case CaptureMode.Clipboard:
@ -363,13 +360,13 @@ namespace Greenshot.Helpers {
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Error(e.Message, e); Log.Error(e.Message, e);
MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename)); MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
} }
try { try {
fileImage = ImageHelper.LoadImage(filename); fileImage = ImageHelper.LoadImage(filename);
} catch (Exception e) { } catch (Exception e) {
LOG.Error(e.Message, e); Log.Error(e.Message, e);
MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename)); MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
} }
} }
@ -395,8 +392,8 @@ namespace Greenshot.Helpers {
} }
break; break;
case CaptureMode.LastRegion: case CaptureMode.LastRegion:
if (!conf.LastCapturedRegion.IsEmpty) { if (!CoreConfig.LastCapturedRegion.IsEmpty) {
_capture = WindowCapture.CaptureRectangle(_capture, conf.LastCapturedRegion); _capture = WindowCapture.CaptureRectangle(_capture, CoreConfig.LastCapturedRegion);
// TODO: Reactive / check if the elements code is activated // TODO: Reactive / check if the elements code is activated
//if (windowDetailsThread != null) { //if (windowDetailsThread != null) {
// windowDetailsThread.Join(); // windowDetailsThread.Join();
@ -404,7 +401,7 @@ namespace Greenshot.Helpers {
// Set capture title, fixing bug #3569703 // Set capture title, fixing bug #3569703
foreach (WindowDetails window in WindowDetails.GetVisibleWindows()) { foreach (WindowDetails window in WindowDetails.GetVisibleWindows()) {
Point estimatedLocation = new Point(conf.LastCapturedRegion.X + conf.LastCapturedRegion.Width / 2, conf.LastCapturedRegion.Y + conf.LastCapturedRegion.Height / 2); Point estimatedLocation = new Point(CoreConfig.LastCapturedRegion.X + CoreConfig.LastCapturedRegion.Width / 2, CoreConfig.LastCapturedRegion.Y + CoreConfig.LastCapturedRegion.Height / 2);
if (window.Contains(estimatedLocation)) { if (window.Contains(estimatedLocation)) {
_selectedCaptureWindow = window; _selectedCaptureWindow = window;
_capture.CaptureDetails.Title = _selectedCaptureWindow.Text; _capture.CaptureDetails.Title = _selectedCaptureWindow.Text;
@ -416,7 +413,7 @@ namespace Greenshot.Helpers {
//capture.MoveElements(capture.ScreenBounds.Location.X - capture.Location.X, capture.ScreenBounds.Location.Y - capture.Location.Y); //capture.MoveElements(capture.ScreenBounds.Location.X - capture.Location.X, capture.ScreenBounds.Location.Y - capture.Location.Y);
_capture.CaptureDetails.AddMetaData("source", "screen"); _capture.CaptureDetails.AddMetaData("source", "screen");
SetDPI(); SetDpi();
HandleCapture(); HandleCapture();
} }
break; break;
@ -425,25 +422,23 @@ namespace Greenshot.Helpers {
if (Rectangle.Empty.Equals(_captureRect)) { if (Rectangle.Empty.Equals(_captureRect)) {
_capture = WindowCapture.CaptureScreen(_capture); _capture = WindowCapture.CaptureScreen(_capture);
_capture.CaptureDetails.AddMetaData("source", "screen"); _capture.CaptureDetails.AddMetaData("source", "screen");
SetDPI(); SetDpi();
CaptureWithFeedback(); CaptureWithFeedback();
} else { } else {
_capture = WindowCapture.CaptureRectangle(_capture, _captureRect); _capture = WindowCapture.CaptureRectangle(_capture, _captureRect);
_capture.CaptureDetails.AddMetaData("source", "screen"); _capture.CaptureDetails.AddMetaData("source", "screen");
SetDPI(); SetDpi();
HandleCapture(); HandleCapture();
} }
break; break;
default: default:
LOG.Warn("Unknown capture mode: " + _captureMode); Log.Warn("Unknown capture mode: " + _captureMode);
break; break;
} }
// Wait for thread, otherwise we can't dipose the CaptureHelper // Wait for thread, otherwise we can't dipose the CaptureHelper
if (retrieveWindowDetailsThread != null) { retrieveWindowDetailsThread?.Join();
retrieveWindowDetailsThread.Join();
}
if (_capture != null) { if (_capture != null) {
LOG.Debug("Disposing capture"); Log.Debug("Disposing capture");
_capture.Dispose(); _capture.Dispose();
} }
} }
@ -471,7 +466,7 @@ namespace Greenshot.Helpers {
} }
private void RetrieveWindowDetails() { private void RetrieveWindowDetails() {
LOG.Debug("start RetrieveWindowDetails"); Log.Debug("start RetrieveWindowDetails");
// Start Enumeration of "active" windows // Start Enumeration of "active" windows
foreach (var window in WindowDetails.GetVisibleWindows()) { foreach (var window in WindowDetails.GetVisibleWindows()) {
// Make sure the details are retrieved once // Make sure the details are retrieved once
@ -479,7 +474,7 @@ namespace Greenshot.Helpers {
// Force children retrieval, sometimes windows close on losing focus and this is solved by caching // Force children retrieval, sometimes windows close on losing focus and this is solved by caching
int goLevelDeep = 3; int goLevelDeep = 3;
if (conf.WindowCaptureAllChildLocations) { if (CoreConfig.WindowCaptureAllChildLocations) {
goLevelDeep = 20; goLevelDeep = 20;
} }
window.GetChildren(goLevelDeep); window.GetChildren(goLevelDeep);
@ -487,11 +482,11 @@ namespace Greenshot.Helpers {
_windows.Add(window); _windows.Add(window);
} }
} }
LOG.Debug("end RetrieveWindowDetails"); Log.Debug("end RetrieveWindowDetails");
} }
private void AddConfiguredDestination() { private void AddConfiguredDestination() {
foreach(string destinationDesignation in conf.OutputDestinations) { foreach(string destinationDesignation in CoreConfig.OutputDestinations) {
IDestination destination = DestinationHelper.GetDestination(destinationDesignation); IDestination destination = DestinationHelper.GetDestination(destinationDesignation);
if (destination != null) { if (destination != null) {
_capture.CaptureDetails.AddDestination(destination); _capture.CaptureDetails.AddDestination(destination);
@ -507,7 +502,7 @@ namespace Greenshot.Helpers {
private void OpenCaptureOnClick(object sender, EventArgs e) { private void OpenCaptureOnClick(object sender, EventArgs e) {
SurfaceMessageEventArgs eventArgs = MainForm.Instance.NotifyIcon.Tag as SurfaceMessageEventArgs; SurfaceMessageEventArgs eventArgs = MainForm.Instance.NotifyIcon.Tag as SurfaceMessageEventArgs;
if (eventArgs == null) { if (eventArgs == null) {
LOG.Warn("OpenCaptureOnClick called without SurfaceMessageEventArgs"); Log.Warn("OpenCaptureOnClick called without SurfaceMessageEventArgs");
RemoveEventHandler(sender, e); RemoveEventHandler(sender, e);
return; return;
} }
@ -515,14 +510,19 @@ namespace Greenshot.Helpers {
if (surface != null && eventArgs.MessageType == SurfaceMessageTyp.FileSaved) { if (surface != null && eventArgs.MessageType == SurfaceMessageTyp.FileSaved) {
if (!string.IsNullOrEmpty(surface.LastSaveFullPath)) { if (!string.IsNullOrEmpty(surface.LastSaveFullPath)) {
string errorMessage = null; string errorMessage = null;
var path = Path.GetDirectoryName(surface.LastSaveFullPath);
try { try {
ProcessStartInfo psi = new ProcessStartInfo("explorer.exe"); if (path != null)
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath); {
psi.UseShellExecute = false; var processStartInfo = new ProcessStartInfo("explorer.exe")
using (Process p = new Process()) { {
p.StartInfo = psi; Arguments = path,
p.Start(); UseShellExecute = false
};
using (var process = new Process()) {
process.StartInfo = processStartInfo;
process.Start();
}
} }
} catch (Exception ex) { } catch (Exception ex) {
errorMessage = ex.Message; errorMessage = ex.Message;
@ -531,28 +531,41 @@ namespace Greenshot.Helpers {
if (errorMessage != null) { if (errorMessage != null) {
try { try {
string windowsPath = Environment.GetEnvironmentVariable("SYSTEMROOT"); string windowsPath = Environment.GetEnvironmentVariable("SYSTEMROOT");
string explorerPath = Path.Combine(windowsPath, "explorer.exe"); if (windowsPath != null)
if (File.Exists(explorerPath)) { {
ProcessStartInfo psi = new ProcessStartInfo(explorerPath); string explorerPath = Path.Combine(windowsPath, "explorer.exe");
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath); if (File.Exists(explorerPath))
psi.UseShellExecute = false; {
using (Process p = new Process()) { var lastSaveDirectory = Path.GetDirectoryName(surface.LastSaveFullPath);
p.StartInfo = psi; if (lastSaveDirectory != null)
p.Start(); {
var processStartInfo = new ProcessStartInfo(explorerPath)
{
Arguments = lastSaveDirectory,
UseShellExecute = false
};
using (var process = new Process()) {
process.StartInfo = processStartInfo;
process.Start();
}
}
errorMessage = null;
} }
errorMessage = null;
} }
} catch { }
catch
{
// ignored
} }
} }
if (errorMessage != null) { if (errorMessage != null) {
MessageBox.Show(string.Format("{0}\r\nexplorer.exe {1}", errorMessage, surface.LastSaveFullPath), "explorer.exe", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show($"{errorMessage}\r\nexplorer.exe {surface.LastSaveFullPath}", "explorer.exe", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} else if (surface != null && !string.IsNullOrEmpty(surface.UploadUrl)) { } else if (!string.IsNullOrEmpty(surface?.UploadUrl)) {
Process.Start(surface.UploadUrl); Process.Start(surface.UploadUrl);
} }
LOG.DebugFormat("Deregistering the BalloonTipClicked"); Log.DebugFormat("Deregistering the BalloonTipClicked");
RemoveEventHandler(sender, e); RemoveEventHandler(sender, e);
} }
@ -568,7 +581,11 @@ namespace Greenshot.Helpers {
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="eventArgs"></param> /// <param name="eventArgs"></param>
private void SurfaceMessageReceived(object sender, SurfaceMessageEventArgs eventArgs) { private void SurfaceMessageReceived(object sender, SurfaceMessageEventArgs eventArgs) {
if (eventArgs == null || string.IsNullOrEmpty(eventArgs.Message)) { if (string.IsNullOrEmpty(eventArgs?.Message)) {
return;
}
if (MainForm.Instance == null)
{
return; return;
} }
switch (eventArgs.MessageType) { switch (eventArgs.MessageType) {
@ -602,13 +619,13 @@ namespace Greenshot.Helpers {
outputMade = true; outputMade = true;
} else { } else {
// Make sure the resolution is set correctly! // Make sure the resolution is set correctly!
if (_capture.CaptureDetails != null && _capture.Image != null) { if (_capture.CaptureDetails != null) {
((Bitmap)_capture.Image).SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY); ((Bitmap) _capture.Image)?.SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
} }
DoCaptureFeedback(); DoCaptureFeedback();
} }
LOG.Debug("A capture of: " + _capture.CaptureDetails.Title); Log.Debug("A capture of: " + _capture.CaptureDetails.Title);
// check if someone has passed a destination // check if someone has passed a destination
if (_capture.CaptureDetails.CaptureDestinations == null || _capture.CaptureDetails.CaptureDestinations.Count == 0) { if (_capture.CaptureDetails.CaptureDestinations == null || _capture.CaptureDetails.CaptureDestinations.Count == 0) {
@ -616,18 +633,20 @@ namespace Greenshot.Helpers {
} }
// Create Surface with capture, this way elements can be added automatically (like the mouse cursor) // Create Surface with capture, this way elements can be added automatically (like the mouse cursor)
Surface surface = new Surface(_capture); Surface surface = new Surface(_capture)
surface.Modified = !outputMade; {
Modified = !outputMade
};
// Register notify events if this is wanted // Register notify events if this is wanted
if (conf.ShowTrayNotification && !conf.HideTrayicon) { if (CoreConfig.ShowTrayNotification && !CoreConfig.HideTrayicon) {
surface.SurfaceMessage += SurfaceMessageReceived; surface.SurfaceMessage += SurfaceMessageReceived;
} }
// Let the processors do their job // Let the processors do their job
foreach(IProcessor processor in ProcessorHelper.GetAllProcessors()) { foreach(IProcessor processor in ProcessorHelper.GetAllProcessors()) {
if (processor.isActive) { if (processor.isActive) {
LOG.InfoFormat("Calling processor {0}", processor.Description); Log.InfoFormat("Calling processor {0}", processor.Description);
processor.ProcessCapture(surface, _capture.CaptureDetails); processor.ProcessCapture(surface, _capture.CaptureDetails);
} }
} }
@ -659,7 +678,7 @@ namespace Greenshot.Helpers {
if (PickerDestination.DESIGNATION.Equals(destination.Designation)) { if (PickerDestination.DESIGNATION.Equals(destination.Designation)) {
continue; continue;
} }
LOG.InfoFormat("Calling destination {0}", destination.Description); Log.InfoFormat("Calling destination {0}", destination.Description);
ExportInformation exportInformation = destination.ExportCapture(false, surface, captureDetails); ExportInformation exportInformation = destination.ExportCapture(false, surface, captureDetails);
if (EditorDestination.DESIGNATION.Equals(destination.Designation) && exportInformation.ExportMade) { if (EditorDestination.DESIGNATION.Equals(destination.Designation) && exportInformation.ExportMade) {
@ -674,21 +693,21 @@ namespace Greenshot.Helpers {
private bool CaptureActiveWindow() { private bool CaptureActiveWindow() {
bool presupplied = false; bool presupplied = false;
LOG.Debug("CaptureActiveWindow"); Log.Debug("CaptureActiveWindow");
if (_selectedCaptureWindow != null) { if (_selectedCaptureWindow != null) {
LOG.Debug("Using supplied window"); Log.Debug("Using supplied window");
presupplied = true; presupplied = true;
} else { } else {
_selectedCaptureWindow = WindowDetails.GetActiveWindow(); _selectedCaptureWindow = WindowDetails.GetActiveWindow();
if (_selectedCaptureWindow != null) { if (_selectedCaptureWindow != null) {
if (LOG.IsDebugEnabled) if (Log.IsDebugEnabled)
{ {
LOG.DebugFormat("Capturing window: {0} with {1}", _selectedCaptureWindow.Text, _selectedCaptureWindow.WindowRectangle); Log.DebugFormat("Capturing window: {0} with {1}", _selectedCaptureWindow.Text, _selectedCaptureWindow.WindowRectangle);
} }
} }
} }
if (_selectedCaptureWindow == null || (!presupplied && _selectedCaptureWindow.Iconic)) { if (_selectedCaptureWindow == null || (!presupplied && _selectedCaptureWindow.Iconic)) {
LOG.Warn("No window to capture!"); Log.Warn("No window to capture!");
// Nothing to capture, code up in the stack will capture the full screen // Nothing to capture, code up in the stack will capture the full screen
return false; return false;
} }
@ -699,13 +718,13 @@ namespace Greenshot.Helpers {
} }
_selectedCaptureWindow = SelectCaptureWindow(_selectedCaptureWindow); _selectedCaptureWindow = SelectCaptureWindow(_selectedCaptureWindow);
if (_selectedCaptureWindow == null) { if (_selectedCaptureWindow == null) {
LOG.Warn("No window to capture, after SelectCaptureWindow!"); Log.Warn("No window to capture, after SelectCaptureWindow!");
// Nothing to capture, code up in the stack will capture the full screen // Nothing to capture, code up in the stack will capture the full screen
return false; return false;
} }
// Fix for Bug #3430560 // Fix for Bug #3430560
conf.LastCapturedRegion = _selectedCaptureWindow.WindowRectangle; CoreConfig.LastCapturedRegion = _selectedCaptureWindow.WindowRectangle;
bool returnValue = CaptureWindow(_selectedCaptureWindow, _capture, conf.WindowCaptureMode) != null; bool returnValue = CaptureWindow(_selectedCaptureWindow, _capture, CoreConfig.WindowCaptureMode) != null;
return returnValue; return returnValue;
} }
@ -718,7 +737,7 @@ namespace Greenshot.Helpers {
public static WindowDetails SelectCaptureWindow(WindowDetails windowToCapture) { public static WindowDetails SelectCaptureWindow(WindowDetails windowToCapture) {
Rectangle windowRectangle = windowToCapture.WindowRectangle; Rectangle windowRectangle = windowToCapture.WindowRectangle;
if (windowRectangle.Width == 0 || windowRectangle.Height == 0) { if (windowRectangle.Width == 0 || windowRectangle.Height == 0) {
LOG.WarnFormat("Window {0} has nothing to capture, using workaround to find other window of same process.", windowToCapture.Text); Log.WarnFormat("Window {0} has nothing to capture, using workaround to find other window of same process.", windowToCapture.Text);
// Trying workaround, the size 0 arrises with e.g. Toad.exe, has a different Window when minimized // Trying workaround, the size 0 arrises with e.g. Toad.exe, has a different Window when minimized
WindowDetails linkedWindow = WindowDetails.GetLinkedWindow(windowToCapture); WindowDetails linkedWindow = WindowDetails.GetLinkedWindow(windowToCapture);
if (linkedWindow != null) { if (linkedWindow != null) {
@ -735,18 +754,18 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <param name="process">Proces to check for the presentation framework</param> /// <param name="process">Proces to check for the presentation framework</param>
/// <returns>true if the process uses WPF</returns> /// <returns>true if the process uses WPF</returns>
private static bool isWPF(Process process) { private static bool IsWpf(Process process) {
if (process != null) { if (process != null) {
try { try {
foreach (ProcessModule module in process.Modules) { foreach (ProcessModule module in process.Modules) {
if (module.ModuleName.StartsWith("PresentationFramework")) { if (module.ModuleName.StartsWith("PresentationFramework")) {
LOG.InfoFormat("Found that Process {0} uses {1}, assuming it's using WPF", process.ProcessName, module.FileName); Log.InfoFormat("Found that Process {0} uses {1}, assuming it's using WPF", process.ProcessName, module.FileName);
return true; return true;
} }
} }
} catch (Exception) { } catch (Exception) {
// Access denied on the modules // Access denied on the modules
LOG.WarnFormat("No access on the modules from process {0}, assuming WPF is used.", process.ProcessName); Log.WarnFormat("No access on the modules from process {0}, assuming WPF is used.", process.ProcessName);
return true; return true;
} }
} }
@ -776,14 +795,14 @@ namespace Greenshot.Helpers {
// 2) Is Windows >= Vista & DWM enabled: use DWM // 2) Is Windows >= Vista & DWM enabled: use DWM
// 3) Otherwise use GDI (Screen might be also okay but might lose content) // 3) Otherwise use GDI (Screen might be also okay but might lose content)
if (isAutoMode) { if (isAutoMode) {
if (conf.IECapture && IECaptureHelper.IsIEWindow(windowToCapture)) { if (CoreConfig.IECapture && IeCaptureHelper.IsIeWindow(windowToCapture)) {
try { try {
ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow, windowToCapture); ICapture ieCapture = IeCaptureHelper.CaptureIe(captureForWindow, windowToCapture);
if (ieCapture != null) { if (ieCapture != null) {
return ieCapture; return ieCapture;
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message); Log.WarnFormat("Problem capturing IE, skipping to normal capture. Exception message was: {0}", ex.Message);
} }
} }
@ -792,9 +811,9 @@ namespace Greenshot.Helpers {
// Change to GDI, if allowed // Change to GDI, if allowed
if (!windowToCapture.IsMetroApp && WindowCapture.IsGdiAllowed(process)) { if (!windowToCapture.IsMetroApp && WindowCapture.IsGdiAllowed(process)) {
if (!dwmEnabled && isWPF(process)) { if (!dwmEnabled && IsWpf(process)) {
// do not use GDI, as DWM is not enabled and the application uses PresentationFramework.dll -> isWPF // do not use GDI, as DWM is not enabled and the application uses PresentationFramework.dll -> isWPF
LOG.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName); Log.InfoFormat("Not using GDI for windows of process {0}, as the process uses WPF", process.ProcessName);
} else { } else {
windowCaptureMode = WindowCaptureMode.GDI; windowCaptureMode = WindowCaptureMode.GDI;
} }
@ -820,7 +839,7 @@ namespace Greenshot.Helpers {
windowCaptureMode = WindowCaptureMode.Screen; windowCaptureMode = WindowCaptureMode.Screen;
} }
LOG.InfoFormat("Capturing window with mode {0}", windowCaptureMode); Log.InfoFormat("Capturing window with mode {0}", windowCaptureMode);
bool captureTaken = false; bool captureTaken = false;
windowRectangle.Intersect(captureForWindow.ScreenBounds); windowRectangle.Intersect(captureForWindow.ScreenBounds);
// Try to capture // Try to capture
@ -852,7 +871,7 @@ namespace Greenshot.Helpers {
// "easy compare", both have the same size // "easy compare", both have the same size
// If GDI has more black, use the screen capture. // If GDI has more black, use the screen capture.
if (blackPercentageGdi > blackPercentageScreen) { if (blackPercentageGdi > blackPercentageScreen) {
LOG.Debug("Using screen capture, as GDI had additional black."); Log.Debug("Using screen capture, as GDI had additional black.");
// changeing the image will automatically dispose the previous // changeing the image will automatically dispose the previous
tmpCapture.Image = screenCapture.Image; tmpCapture.Image = screenCapture.Image;
// Make sure it's not disposed, else the picture is gone! // Make sure it's not disposed, else the picture is gone!
@ -861,7 +880,7 @@ namespace Greenshot.Helpers {
} else if (screenPixels < gdiPixels) { } else if (screenPixels < gdiPixels) {
// Screen capture is cropped, window is outside of screen // Screen capture is cropped, window is outside of screen
if (blackPercentageGdi > 50 && blackPercentageGdi > blackPercentageScreen) { if (blackPercentageGdi > 50 && blackPercentageGdi > blackPercentageScreen) {
LOG.Debug("Using screen capture, as GDI had additional black."); Log.Debug("Using screen capture, as GDI had additional black.");
// changeing the image will automatically dispose the previous // changeing the image will automatically dispose the previous
tmpCapture.Image = screenCapture.Image; tmpCapture.Image = screenCapture.Image;
// Make sure it's not disposed, else the picture is gone! // Make sure it's not disposed, else the picture is gone!
@ -869,7 +888,7 @@ namespace Greenshot.Helpers {
} }
} else { } else {
// Use the GDI capture by doing nothing // Use the GDI capture by doing nothing
LOG.Debug("This should not happen, how can there be more screen as GDI pixels?"); Log.Debug("This should not happen, how can there be more screen as GDI pixels?");
} }
} }
} }
@ -910,7 +929,7 @@ namespace Greenshot.Helpers {
captureForWindow = WindowCapture.CaptureRectangleFromDesktopScreen(captureForWindow, windowRectangle); captureForWindow = WindowCapture.CaptureRectangleFromDesktopScreen(captureForWindow, windowRectangle);
captureTaken = true; captureTaken = true;
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Problem capturing", e); Log.Error("Problem capturing", e);
return null; return null;
} }
break; break;
@ -918,16 +937,15 @@ namespace Greenshot.Helpers {
} }
} }
if (captureForWindow != null) { if (captureForWindow != null)
if (windowToCapture != null) { {
captureForWindow.CaptureDetails.Title = windowToCapture.Text; captureForWindow.CaptureDetails.Title = windowToCapture.Text;
}
} }
return captureForWindow; return captureForWindow;
} }
private void SetDPI() { private void SetDpi() {
// Workaround for proble with DPI retrieval, the FromHwnd activates the window... // Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow(); WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
// Workaround for changed DPI settings in Windows 7 // Workaround for changed DPI settings in Windows 7
@ -935,12 +953,10 @@ namespace Greenshot.Helpers {
_capture.CaptureDetails.DpiX = graphics.DpiX; _capture.CaptureDetails.DpiX = graphics.DpiX;
_capture.CaptureDetails.DpiY = graphics.DpiY; _capture.CaptureDetails.DpiY = graphics.DpiY;
} }
if (previouslyActiveWindow != null) { // Set previouslyActiveWindow as foreground window
// Set previouslyActiveWindow as foreground window previouslyActiveWindow?.ToForeground();
previouslyActiveWindow.ToForeground(); if (_capture.CaptureDetails != null) {
} ((Bitmap) _capture.Image)?.SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
if (_capture.CaptureDetails != null && _capture.Image != null) {
((Bitmap)_capture.Image).SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
} }
} }
@ -958,7 +974,7 @@ namespace Greenshot.Helpers {
using (CaptureForm captureForm = new CaptureForm(_capture, _windows)) { using (CaptureForm captureForm = new CaptureForm(_capture, _windows)) {
// Make sure the form is hidden after showing, even if an exception occurs, so all errors will be shown // Make sure the form is hidden after showing, even if an exception occurs, so all errors will be shown
DialogResult result = DialogResult.Cancel; DialogResult result;
try { try {
result = captureForm.ShowDialog(MainForm.Instance); result = captureForm.ShowDialog(MainForm.Instance);
} finally { } finally {
@ -980,7 +996,7 @@ namespace Greenshot.Helpers {
// Important here is that the location needs to be offsetted back to screen coordinates! // Important here is that the location needs to be offsetted back to screen coordinates!
Rectangle tmpRectangle = _captureRect; Rectangle tmpRectangle = _captureRect;
tmpRectangle.Offset(_capture.ScreenBounds.Location.X, _capture.ScreenBounds.Location.Y); tmpRectangle.Offset(_capture.ScreenBounds.Location.X, _capture.ScreenBounds.Location.Y);
conf.LastCapturedRegion = tmpRectangle; CoreConfig.LastCapturedRegion = tmpRectangle;
HandleCapture(); HandleCapture();
} }
} }

View file

@ -39,9 +39,8 @@ namespace Greenshot.Helpers {
[Serializable()] [Serializable()]
public class CopyDataTransport { public class CopyDataTransport {
private readonly List<KeyValuePair<CommandEnum, string>> _commands; private readonly List<KeyValuePair<CommandEnum, string>> _commands;
public List<KeyValuePair<CommandEnum, string>> Commands { public List<KeyValuePair<CommandEnum, string>> Commands => _commands;
get {return _commands;}
}
public CopyDataTransport() { public CopyDataTransport() {
_commands = new List<KeyValuePair<CommandEnum, string>>(); _commands = new List<KeyValuePair<CommandEnum, string>>();
} }
@ -100,9 +99,9 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <param name="m">The Windows Message information.</param> /// <param name="m">The Windows Message information.</param>
protected override void WndProc (ref Message m ) { protected override void WndProc (ref Message m ) {
if (m.Msg == WM_COPYDATA) { if (m.Msg == WM_COPYDATA)
COPYDATASTRUCT cds = new COPYDATASTRUCT(); {
cds = (COPYDATASTRUCT) Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT)); var cds = (COPYDATASTRUCT) Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
if (cds.cbData > 0) { if (cds.cbData > 0) {
byte[] data = new byte[cds.cbData]; byte[] data = new byte[cds.cbData];
Marshal.Copy(cds.lpData, data, 0, cds.cbData); Marshal.Copy(cds.lpData, data, 0, cds.cbData);
@ -120,9 +119,7 @@ namespace Greenshot.Helpers {
// WM_DESTROY fires before OnHandleChanged and is // WM_DESTROY fires before OnHandleChanged and is
// a better place to ensure that we've cleared // a better place to ensure that we've cleared
// everything up. // everything up.
if (_channels != null) { _channels?.OnHandleChange();
_channels.OnHandleChange();
}
base.OnHandleChange(); base.OnHandleChange();
} }
base.WndProc(ref m); base.WndProc(ref m);
@ -134,10 +131,7 @@ namespace Greenshot.Helpers {
/// <param name="e">The data which has been received.</param> /// <param name="e">The data which has been received.</param>
protected void OnCopyDataReceived(CopyDataReceivedEventArgs e) protected void OnCopyDataReceived(CopyDataReceivedEventArgs e)
{ {
if (CopyDataReceived != null) CopyDataReceived?.Invoke(this, e);
{
CopyDataReceived(this, e);
}
} }
/// <summary> /// <summary>
@ -149,20 +143,14 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
protected override void OnHandleChange () { protected override void OnHandleChange () {
// need to clear up everything we had set. // need to clear up everything we had set.
if (_channels != null) { _channels?.OnHandleChange();
_channels.OnHandleChange();
}
base.OnHandleChange(); base.OnHandleChange();
} }
/// <summary> /// <summary>
/// Gets the collection of channels. /// Gets the collection of channels.
/// </summary> /// </summary>
public CopyDataChannels Channels { public CopyDataChannels Channels => _channels;
get {
return _channels;
}
}
public void Dispose() { public void Dispose() {
Dispose(true); Dispose(true);
@ -204,7 +192,7 @@ namespace Greenshot.Helpers {
/// <summary> /// <summary>
/// Gets the channel name that this data was sent on. /// Gets the channel name that this data was sent on.
/// </summary> /// </summary>
public string ChannelName { get; } = ""; public string ChannelName { get; }
/// <summary> /// <summary>
/// Gets the data object which was sent. /// Gets the data object which was sent.
@ -274,11 +262,8 @@ namespace Greenshot.Helpers {
/// <summary> /// <summary>
/// Returns the CopyDataChannel for the specified channelName /// Returns the CopyDataChannel for the specified channelName
/// </summary> /// </summary>
public CopyDataChannel this[string channelName] { public CopyDataChannel this[string channelName] => (CopyDataChannel) Dictionary[channelName];
get {
return (CopyDataChannel) Dictionary[channelName];
}
}
/// <summary> /// <summary>
/// Adds a new channel on which this application can send and /// Adds a new channel on which this application can send and
/// receive messages. /// receive messages.
@ -320,7 +305,7 @@ namespace Greenshot.Helpers {
/// <param name="key">The channelName</param> /// <param name="key">The channelName</param>
/// <param name="data">The CopyDataChannel object which has /// <param name="data">The CopyDataChannel object which has
/// just been removed</param> /// just been removed</param>
protected override void OnRemoveComplete ( Object key , Object data ) { protected override void OnRemoveComplete ( object key , object data ) {
( (CopyDataChannel) data).Dispose(); ( (CopyDataChannel) data).Dispose();
OnRemove(key, data); OnRemove(key, data);
} }

View file

@ -31,9 +31,9 @@ namespace Greenshot.Helpers {
/// Description of DestinationHelper. /// Description of DestinationHelper.
/// </summary> /// </summary>
public static class DestinationHelper { public static class DestinationHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(DestinationHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(DestinationHelper));
private static readonly Dictionary<string, IDestination> RegisteredDestinations = new Dictionary<string, IDestination>(); private static readonly Dictionary<string, IDestination> RegisteredDestinations = new Dictionary<string, IDestination>();
private static readonly CoreConfiguration coreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
/// Initialize the destinations /// Initialize the destinations
static DestinationHelper() { static DestinationHelper() {
@ -47,15 +47,15 @@ namespace Greenshot.Helpers {
try { try {
destination = (IDestination)Activator.CreateInstance(destinationType); destination = (IDestination)Activator.CreateInstance(destinationType);
} catch (Exception e) { } catch (Exception e) {
LOG.ErrorFormat("Can't create instance of {0}", destinationType); Log.ErrorFormat("Can't create instance of {0}", destinationType);
LOG.Error(e); Log.Error(e);
continue; continue;
} }
if (destination.isActive) { if (destination.IsActive) {
LOG.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation); Log.DebugFormat("Found destination {0} with designation {1}", destinationType.Name, destination.Designation);
RegisterDestination(destination); RegisterDestination(destination);
} else { } else {
LOG.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation); Log.DebugFormat("Ignoring destination {0} with designation {1}", destinationType.Name, destination.Designation);
} }
} }
} }
@ -66,7 +66,7 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <param name="destination"></param> /// <param name="destination"></param>
public static void RegisterDestination(IDestination destination) { public static void RegisterDestination(IDestination destination) {
if (coreConfig.ExcludeDestinations == null || !coreConfig.ExcludeDestinations.Contains(destination.Designation)) { if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) {
// don't test the key, an exception should happen wenn it's not unique // don't test the key, an exception should happen wenn it's not unique
RegisteredDestinations.Add(destination.Designation, destination); RegisteredDestinations.Add(destination.Designation, destination);
} }
@ -82,13 +82,13 @@ namespace Greenshot.Helpers {
IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute]; IGreenshotPlugin plugin = PluginHelper.Instance.Plugins[pluginAttribute];
try { try {
foreach (IDestination destination in plugin.Destinations()) { foreach (IDestination destination in plugin.Destinations()) {
if (coreConfig.ExcludeDestinations == null || !coreConfig.ExcludeDestinations.Contains(destination.Designation)) { if (CoreConfig.ExcludeDestinations == null || !CoreConfig.ExcludeDestinations.Contains(destination.Designation)) {
destinations.Add(destination); destinations.Add(destination);
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.ErrorFormat("Couldn't get destinations from the plugin {0}", pluginAttribute.Name); Log.ErrorFormat("Couldn't get destinations from the plugin {0}", pluginAttribute.Name);
LOG.Error(ex); Log.Error(ex);
} }
} }
destinations.Sort(); destinations.Sort();
@ -136,7 +136,7 @@ namespace Greenshot.Helpers {
/// <param name="captureDetails"></param> /// <param name="captureDetails"></param>
public static ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails) { public static ExportInformation ExportCapture(bool manuallyInitiated, string designation, ISurface surface, ICaptureDetails captureDetails) {
IDestination destination = GetDestination(designation); IDestination destination = GetDestination(designation);
if (destination != null && destination.isActive) { if (destination != null && destination.IsActive) {
return destination.ExportCapture(manuallyInitiated, surface, captureDetails); return destination.ExportCapture(manuallyInitiated, surface, captureDetails);
} }
return null; return null;

View file

@ -62,7 +62,7 @@ namespace Greenshot.Helpers
if (IniConfig.IsPortable) { if (IniConfig.IsPortable) {
environment.Append(" Portable"); environment.Append(" Portable");
} }
environment.Append(" (" + OSInfo.Bits + " bit)"); environment.Append(" (" + OsInfo.Bits + " bit)");
if (newline) if (newline)
{ {
@ -98,7 +98,7 @@ namespace Greenshot.Helpers
{ {
environment.Append(", "); environment.Append(", ");
} }
environment.Append(string.Format("OS: {0} {1} {2} (x{3}) {4}", OSInfo.Name, OSInfo.Edition, OSInfo.ServicePack, OSInfo.Bits, OSInfo.VersionString)); environment.Append(string.Format("OS: {0} {1} {2} (x{3}) {4}", OsInfo.Name, OsInfo.Edition, OsInfo.ServicePack, OsInfo.Bits, OsInfo.VersionString));
if (newline) if (newline)
{ {
environment.AppendLine(); environment.AppendLine();
@ -152,9 +152,9 @@ namespace Greenshot.Helpers
StringBuilder report = new StringBuilder(); StringBuilder report = new StringBuilder();
report.AppendLine("Exception: " + ex.GetType().ToString()); report.AppendLine("Exception: " + ex.GetType());
report.AppendLine("Message: " + ex.Message); report.AppendLine("Message: " + ex.Message);
if (ex.Data != null && ex.Data.Count > 0) if (ex.Data.Count > 0)
{ {
report.AppendLine(); report.AppendLine();
report.AppendLine("Additional Information:"); report.AppendLine("Additional Information:");
@ -207,7 +207,7 @@ namespace Greenshot.Helpers
/// Provides detailed information about the host operating system. /// Provides detailed information about the host operating system.
/// Code is available at: http://www.csharp411.com/determine-windows-version-and-edition-with-c/ /// Code is available at: http://www.csharp411.com/determine-windows-version-and-edition-with-c/
/// </summary> /// </summary>
public static class OSInfo public static class OsInfo
{ {
#region BITS #region BITS
/// <summary> /// <summary>
@ -261,16 +261,7 @@ namespace Greenshot.Helpers
} }
else if (productType == VER_NT_SERVER) else if (productType == VER_NT_SERVER)
{ {
if ((suiteMask & VER_SUITE_ENTERPRISE) != 0) edition = (suiteMask & VER_SUITE_ENTERPRISE) != 0 ? "Enterprise Server" : "Standard Server";
{
// Windows NT 4.0 Server Enterprise
edition = "Enterprise Server";
}
else
{
// Windows NT 4.0 Server
edition = "Standard Server";
}
} }
} }
#endregion VERSION 4 #endregion VERSION 4
@ -470,7 +461,7 @@ namespace Greenshot.Helpers
#endregion EDITION #endregion EDITION
#region NAME #region NAME
private static string s_Name; private static string _name;
/// <summary> /// <summary>
/// Gets the name of the operating system running on this computer. /// Gets the name of the operating system running on this computer.
/// </summary> /// </summary>
@ -478,16 +469,18 @@ namespace Greenshot.Helpers
{ {
get get
{ {
if (s_Name != null) if (_name != null)
{ {
return s_Name; //***** RETURN *****// return _name; //***** RETURN *****//
} }
string name = "unknown"; string name = "unknown";
OperatingSystem osVersion = Environment.OSVersion; OperatingSystem osVersion = Environment.OSVersion;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX(); OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX)); {
dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX))
};
if (GetVersionEx(ref osVersionInfo)) if (GetVersionEx(ref osVersionInfo))
{ {
@ -514,14 +507,7 @@ namespace Greenshot.Helpers
} }
break; break;
case 10: case 10:
if (csdVersion == "A") name = csdVersion == "A" ? "Windows 98 Second Edition" : "Windows 98";
{
name = "Windows 98 Second Edition";
}
else
{
name = "Windows 98";
}
break; break;
case 90: case 90:
name = "Windows Me"; name = "Windows Me";
@ -629,7 +615,7 @@ namespace Greenshot.Helpers
} }
} }
s_Name = name; _name = name;
return name; return name;
} }
} }
@ -735,9 +721,11 @@ namespace Greenshot.Helpers
get get
{ {
string servicePack = string.Empty; string servicePack = string.Empty;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX(); OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX
{
dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX))
};
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
if (GetVersionEx(ref osVersionInfo)) if (GetVersionEx(ref osVersionInfo))
{ {
@ -754,13 +742,8 @@ namespace Greenshot.Helpers
/// <summary> /// <summary>
/// Gets the build version number of the operating system running on this computer. /// Gets the build version number of the operating system running on this computer.
/// </summary> /// </summary>
public static int BuildVersion public static int BuildVersion => Environment.OSVersion.Version.Build;
{
get
{
return Environment.OSVersion.Version.Build;
}
}
#endregion BUILD #endregion BUILD
#region FULL #region FULL

View file

@ -34,8 +34,6 @@ namespace Greenshot.Helpers {
/// <param name="y2">The point on the y-axis of the second point</param> /// <param name="y2">The point on the y-axis of the second point</param>
/// <returns></returns> /// <returns></returns>
public static int Distance2D(int x1, int y1, int x2, int y2) { public static int Distance2D(int x1, int y1, int x2, int y2) {
//Our end result
int result = 0;
//Take x2-x1, then square it //Take x2-x1, then square it
double part1 = Math.Pow(x2 - x1, 2); double part1 = Math.Pow(x2 - x1, 2);
//Take y2-y1, then square it //Take y2-y1, then square it
@ -43,9 +41,7 @@ namespace Greenshot.Helpers {
//Add both of the parts together //Add both of the parts together
double underRadical = part1 + part2; double underRadical = part1 + part2;
//Get the square root of the parts //Get the square root of the parts
result = (int)Math.Sqrt(underRadical); return (int)Math.Sqrt(underRadical);
//Return our result
return result;
} }
/// <summary> /// <summary>

View file

@ -22,6 +22,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Greenshot.Configuration; using Greenshot.Configuration;
using Greenshot.Helpers.IEInterop; using Greenshot.Helpers.IEInterop;
@ -41,18 +42,18 @@ namespace Greenshot.Helpers {
/// On top I modified it to use the already available code in Greenshot. /// On top I modified it to use the already available code in Greenshot.
/// Many thanks to all the people who contributed here! /// Many thanks to all the people who contributed here!
/// </summary> /// </summary>
public static class IECaptureHelper { public static class IeCaptureHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(IECaptureHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(IeCaptureHelper));
private static readonly CoreConfiguration configuration = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
// Helper method to activate a certain IE Tab // Helper method to activate a certain IE Tab
public static void ActivateIETab(WindowDetails ieWindowDetails, int tabIndex) { public static void ActivateIeTab(WindowDetails ieWindowDetails, int tabIndex) {
WindowDetails directUIWindowDetails = IEHelper.GetDirectUI(ieWindowDetails); WindowDetails directUiWindowDetails = IEHelper.GetDirectUI(ieWindowDetails);
if(directUIWindowDetails != null) { if(directUiWindowDetails != null) {
// Bring window to the front // Bring window to the front
ieWindowDetails.Restore(); ieWindowDetails.Restore();
// Get accessible // Get accessible
Accessible ieAccessible = new Accessible(directUIWindowDetails.Handle); Accessible ieAccessible = new Accessible(directUiWindowDetails.Handle);
// Activate Tab // Activate Tab
ieAccessible.ActivateIETab(tabIndex); ieAccessible.ActivateIETab(tabIndex);
} }
@ -64,13 +65,13 @@ namespace Greenshot.Helpers {
/// <param name="someWindow">WindowDetails to check</param> /// <param name="someWindow">WindowDetails to check</param>
/// <param name="minimumPercentage">min percentage</param> /// <param name="minimumPercentage">min percentage</param>
/// <returns></returns> /// <returns></returns>
public static bool IsMostlyIEWindow(WindowDetails someWindow, int minimumPercentage) { public static bool IsMostlyIeWindow(WindowDetails someWindow, int minimumPercentage) {
WindowDetails ieWindow = someWindow.GetChild("Internet Explorer_Server"); WindowDetails ieWindow = someWindow.GetChild("Internet Explorer_Server");
if (ieWindow != null) { if (ieWindow != null) {
Rectangle wholeClient = someWindow.ClientRectangle; Rectangle wholeClient = someWindow.ClientRectangle;
Rectangle partClient = ieWindow.ClientRectangle; Rectangle partClient = ieWindow.ClientRectangle;
int percentage = (int)(100*(float)(partClient.Width * partClient.Height) / (float)(wholeClient.Width * wholeClient.Height)); int percentage = (int)(100*(float)(partClient.Width * partClient.Height) / (wholeClient.Width * wholeClient.Height));
LOG.InfoFormat("Window {0}, ie part {1}, percentage {2}", wholeClient, partClient, percentage); Log.InfoFormat("Window {0}, ie part {1}, percentage {2}", wholeClient, partClient, percentage);
if (percentage > minimumPercentage) { if (percentage > minimumPercentage) {
return true; return true;
} }
@ -83,11 +84,11 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <param name="someWindow"></param> /// <param name="someWindow"></param>
/// <returns></returns> /// <returns></returns>
public static bool IsIEWindow(WindowDetails someWindow) { public static bool IsIeWindow(WindowDetails someWindow) {
if ("IEFrame".Equals(someWindow.ClassName)) { if ("IEFrame".Equals(someWindow.ClassName)) {
return true; return true;
} }
if (configuration.WindowClassesToCheckForIE != null && configuration.WindowClassesToCheckForIE.Contains(someWindow.ClassName)) { if (CoreConfig.WindowClassesToCheckForIE != null && CoreConfig.WindowClassesToCheckForIE.Contains(someWindow.ClassName)) {
return someWindow.GetChild("Internet Explorer_Server") != null; return someWindow.GetChild("Internet Explorer_Server") != null;
} }
return false; return false;
@ -97,16 +98,16 @@ namespace Greenshot.Helpers {
/// Get Windows displaying an IE /// Get Windows displaying an IE
/// </summary> /// </summary>
/// <returns>IEnumerable WindowDetails</returns> /// <returns>IEnumerable WindowDetails</returns>
public static IEnumerable<WindowDetails> GetIEWindows() { public static IEnumerable<WindowDetails> GetIeWindows() {
foreach (WindowDetails possibleIEWindow in WindowDetails.GetAllWindows()) { foreach (var possibleIeWindow in WindowDetails.GetAllWindows()) {
if (possibleIEWindow.Text.Length == 0) { if (possibleIeWindow.Text.Length == 0) {
continue; continue;
} }
if (possibleIEWindow.ClientRectangle.IsEmpty) { if (possibleIeWindow.ClientRectangle.IsEmpty) {
continue; continue;
} }
if (IsIEWindow(possibleIEWindow)) { if (IsIeWindow(possibleIeWindow)) {
yield return possibleIEWindow; yield return possibleIeWindow;
} }
} }
} }
@ -115,11 +116,9 @@ namespace Greenshot.Helpers {
/// Simple check if IE is running /// Simple check if IE is running
/// </summary> /// </summary>
/// <returns>bool</returns> /// <returns>bool</returns>
public static bool IsIERunning() { public static bool IsIeRunning()
foreach (WindowDetails ieWindow in GetIEWindows()) { {
return true; return GetIeWindows().Any();
}
return false;
} }
/// <summary> /// <summary>
@ -127,44 +126,46 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <returns>List with KeyValuePair of WindowDetails and string</returns> /// <returns>List with KeyValuePair of WindowDetails and string</returns>
public static List<KeyValuePair<WindowDetails, string>> GetBrowserTabs() { public static List<KeyValuePair<WindowDetails, string>> GetBrowserTabs() {
List<IntPtr> ieHandleList = new List<IntPtr>(); var ieHandleList = new List<IntPtr>();
Dictionary<WindowDetails, List<string>> browserWindows = new Dictionary<WindowDetails, List<string>>(); var browserWindows = new Dictionary<WindowDetails, List<string>>();
// Find the IE windows // Find the IE windows
foreach (WindowDetails ieWindow in GetIEWindows()) { foreach (var ieWindow in GetIeWindows()) {
try { try {
if (!ieHandleList.Contains(ieWindow.Handle)) { if (ieHandleList.Contains(ieWindow.Handle))
if ("IEFrame".Equals(ieWindow.ClassName)) { {
WindowDetails directUIWD = IEHelper.GetDirectUI(ieWindow); continue;
if (directUIWD != null) {
Accessible accessible = new Accessible(directUIWD.Handle);
browserWindows.Add(ieWindow, accessible.IETabCaptions);
}
} else if (configuration.WindowClassesToCheckForIE != null && configuration.WindowClassesToCheckForIE.Contains(ieWindow.ClassName)) {
List<string> singleWindowText = new List<string>();
try {
IHTMLDocument2 document2 = GetHtmlDocument(ieWindow);
string title = document2.title;
Marshal.ReleaseComObject(document2);
if (string.IsNullOrEmpty(title)) {
singleWindowText.Add(ieWindow.Text);
} else {
singleWindowText.Add(ieWindow.Text + " - " + title);
}
} catch {
singleWindowText.Add(ieWindow.Text);
}
browserWindows.Add(ieWindow, singleWindowText);
}
ieHandleList.Add(ieWindow.Handle);
} }
if ("IEFrame".Equals(ieWindow.ClassName)) {
var directUiwd = IEHelper.GetDirectUI(ieWindow);
if (directUiwd != null) {
var accessible = new Accessible(directUiwd.Handle);
browserWindows.Add(ieWindow, accessible.IETabCaptions);
}
} else if (CoreConfig.WindowClassesToCheckForIE != null && CoreConfig.WindowClassesToCheckForIE.Contains(ieWindow.ClassName)) {
var singleWindowText = new List<string>();
try {
var document2 = GetHtmlDocument(ieWindow);
string title = document2.title;
Marshal.ReleaseComObject(document2);
if (string.IsNullOrEmpty(title)) {
singleWindowText.Add(ieWindow.Text);
} else {
singleWindowText.Add(ieWindow.Text + " - " + title);
}
} catch {
singleWindowText.Add(ieWindow.Text);
}
browserWindows.Add(ieWindow, singleWindowText);
}
ieHandleList.Add(ieWindow.Handle);
} catch (Exception) { } catch (Exception) {
LOG.Warn("Can't get Info from " + ieWindow.ClassName); Log.Warn("Can't get Info from " + ieWindow.ClassName);
} }
} }
List<KeyValuePair<WindowDetails, string>> returnList = new List<KeyValuePair<WindowDetails, string>>(); var returnList = new List<KeyValuePair<WindowDetails, string>>();
foreach(WindowDetails windowDetails in browserWindows.Keys) { foreach(var windowDetails in browserWindows.Keys) {
foreach(string tab in browserWindows[windowDetails]) { foreach(string tab in browserWindows[windowDetails]) {
returnList.Add(new KeyValuePair<WindowDetails, string>(windowDetails, tab)); returnList.Add(new KeyValuePair<WindowDetails, string>(windowDetails, tab));
} }
@ -178,35 +179,30 @@ namespace Greenshot.Helpers {
/// <param name="mainWindow"></param> /// <param name="mainWindow"></param>
/// <returns></returns> /// <returns></returns>
private static IHTMLDocument2 GetHtmlDocument(WindowDetails mainWindow) { private static IHTMLDocument2 GetHtmlDocument(WindowDetails mainWindow) {
WindowDetails ieServer; var ieServer = "Internet Explorer_Server".Equals(mainWindow.ClassName) ? mainWindow : mainWindow.GetChild("Internet Explorer_Server");
if ("Internet Explorer_Server".Equals(mainWindow.ClassName)) {
ieServer = mainWindow;
} else {
ieServer = mainWindow.GetChild("Internet Explorer_Server");
}
if (ieServer == null) { if (ieServer == null) {
LOG.WarnFormat("No Internet Explorer_Server for {0}", mainWindow.Text); Log.WarnFormat("No Internet Explorer_Server for {0}", mainWindow.Text);
return null; return null;
} }
IHTMLDocument2 document2 = null;
uint windowMessage = User32.RegisterWindowMessage("WM_HTML_GETOBJECT"); uint windowMessage = User32.RegisterWindowMessage("WM_HTML_GETOBJECT");
if (windowMessage == 0) { if (windowMessage == 0) {
LOG.WarnFormat("Couldn't register WM_HTML_GETOBJECT"); Log.WarnFormat("Couldn't register WM_HTML_GETOBJECT");
return null; return null;
} }
LOG.DebugFormat("Trying WM_HTML_GETOBJECT on {0}", ieServer.ClassName); Log.DebugFormat("Trying WM_HTML_GETOBJECT on {0}", ieServer.ClassName);
UIntPtr response; UIntPtr response;
User32.SendMessageTimeout(ieServer.Handle, windowMessage, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 5000, out response); User32.SendMessageTimeout(ieServer.Handle, windowMessage, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 5000, out response);
IHTMLDocument2 document2;
if (response != UIntPtr.Zero) { if (response != UIntPtr.Zero) {
document2 = (IHTMLDocument2)Accessible.ObjectFromLresult(response, typeof(IHTMLDocument).GUID, IntPtr.Zero); document2 = (IHTMLDocument2)Accessible.ObjectFromLresult(response, typeof(IHTMLDocument).GUID, IntPtr.Zero);
if (document2 == null) { if (document2 == null) {
LOG.Error("No IHTMLDocument2 found"); Log.Error("No IHTMLDocument2 found");
return null; return null;
} }
} else { } else {
LOG.Error("No answer on WM_HTML_GETOBJECT."); Log.Error("No answer on WM_HTML_GETOBJECT.");
return null; return null;
} }
return document2; return document2;
@ -227,23 +223,23 @@ namespace Greenshot.Helpers {
IHTMLDocument2 alternativeReturnDocument2 = null; IHTMLDocument2 alternativeReturnDocument2 = null;
// Find the IE windows // Find the IE windows
foreach (WindowDetails ieWindow in GetIEWindows()) { foreach (WindowDetails ieWindow in GetIeWindows()) {
LOG.DebugFormat("Processing {0} - {1}", ieWindow.ClassName, ieWindow.Text); Log.DebugFormat("Processing {0} - {1}", ieWindow.ClassName, ieWindow.Text);
Accessible ieAccessible = null; Accessible ieAccessible = null;
WindowDetails directUIWD = IEHelper.GetDirectUI(ieWindow); WindowDetails directUiwd = IEHelper.GetDirectUI(ieWindow);
if (directUIWD != null) { if (directUiwd != null) {
ieAccessible = new Accessible(directUIWD.Handle); ieAccessible = new Accessible(directUiwd.Handle);
} }
if (ieAccessible == null) { if (ieAccessible == null) {
if (browserWindow != null) { if (browserWindow != null) {
LOG.InfoFormat("Active Window is {0}", browserWindow.Text); Log.InfoFormat("Active Window is {0}", browserWindow.Text);
} }
if (!ieWindow.Equals(browserWindow)) { if (!ieWindow.Equals(browserWindow)) {
LOG.WarnFormat("No ieAccessible for {0}", ieWindow.Text); Log.WarnFormat("No ieAccessible for {0}", ieWindow.Text);
continue; continue;
} }
LOG.DebugFormat("No ieAccessible, but the active window is an IE window: {0}, ", ieWindow.Text); Log.DebugFormat("No ieAccessible, but the active window is an IE window: {0}, ", ieWindow.Text);
} }
try { try {
@ -256,9 +252,7 @@ namespace Greenshot.Helpers {
// Get the content window handle for the shellWindow.Document // Get the content window handle for the shellWindow.Document
IOleWindow oleWindow = (IOleWindow)document2; IOleWindow oleWindow = (IOleWindow)document2;
IntPtr contentWindowHandle = IntPtr.Zero; IntPtr contentWindowHandle = IntPtr.Zero;
if (oleWindow != null) { oleWindow?.GetWindow(out contentWindowHandle);
oleWindow.GetWindow(out contentWindowHandle);
}
if (contentWindowHandle != IntPtr.Zero) { if (contentWindowHandle != IntPtr.Zero) {
// Get the HTMLDocument to check the hasFocus // Get the HTMLDocument to check the hasFocus
@ -266,7 +260,7 @@ namespace Greenshot.Helpers {
IHTMLDocument4 document4 = (IHTMLDocument4)document2; IHTMLDocument4 document4 = (IHTMLDocument4)document2;
if (document4.hasFocus()) { if (document4.hasFocus()) {
LOG.DebugFormat("Matched focused document: {0}", document2.title); Log.DebugFormat("Matched focused document: {0}", document2.title);
// Look no further, we got what we wanted! // Look no further, we got what we wanted!
returnDocument2 = document2; returnDocument2 = document2;
returnWindow = new WindowDetails(contentWindowHandle); returnWindow = new WindowDetails(contentWindowHandle);
@ -279,7 +273,7 @@ namespace Greenshot.Helpers {
break; break;
} }
if (ieAccessible != null && returnWindow == null && document2.title.Equals(ieAccessible.IEActiveTabCaption) ) { if (ieAccessible != null && returnWindow == null && document2.title.Equals(ieAccessible.IEActiveTabCaption) ) {
LOG.DebugFormat("Title: {0}", document2.title); Log.DebugFormat("Title: {0}", document2.title);
returnDocument2 = document2; returnDocument2 = document2;
returnWindow = new WindowDetails(contentWindowHandle); returnWindow = new WindowDetails(contentWindowHandle);
} else { } else {
@ -292,8 +286,8 @@ namespace Greenshot.Helpers {
} }
} }
} catch (Exception e) { } catch (Exception e) {
LOG.ErrorFormat("Major problem: Problem retrieving Document from {0}", ieWindow.Text); Log.ErrorFormat("Major problem: Problem retrieving Document from {0}", ieWindow.Text);
LOG.Error(e); Log.Error(e);
} }
} }
@ -307,8 +301,8 @@ namespace Greenshot.Helpers {
try { try {
returnDocumentContainer = new DocumentContainer(returnDocument2, returnWindow); returnDocumentContainer = new DocumentContainer(returnDocument2, returnWindow);
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Major problem: Problem retrieving Document."); Log.Error("Major problem: Problem retrieving Document.");
LOG.Error(e); Log.Error(e);
} }
} }
@ -320,8 +314,8 @@ namespace Greenshot.Helpers {
try { try {
returnDocumentContainer = new DocumentContainer(alternativeReturnDocument2, alternativeReturnWindow); returnDocumentContainer = new DocumentContainer(alternativeReturnDocument2, alternativeReturnWindow);
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Major problem: Problem retrieving Document."); Log.Error("Major problem: Problem retrieving Document.");
LOG.Error(e); Log.Error(e);
} }
} }
return returnDocumentContainer; return returnDocumentContainer;
@ -332,8 +326,8 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <param name="capture">ICapture where the capture needs to be stored</param> /// <param name="capture">ICapture where the capture needs to be stored</param>
/// <returns>ICapture with the content (if any)</returns> /// <returns>ICapture with the content (if any)</returns>
public static ICapture CaptureIE(ICapture capture) { public static ICapture CaptureIe(ICapture capture) {
return CaptureIE(capture, WindowDetails.GetActiveWindow()); return CaptureIe(capture, WindowDetails.GetActiveWindow());
} }
/// <summary> /// <summary>
/// Here the logic for capturing the IE Content is located /// Here the logic for capturing the IE Content is located
@ -341,7 +335,7 @@ namespace Greenshot.Helpers {
/// <param name="capture">ICapture where the capture needs to be stored</param> /// <param name="capture">ICapture where the capture needs to be stored</param>
/// <param name="windowToCapture">window to use</param> /// <param name="windowToCapture">window to use</param>
/// <returns>ICapture with the content (if any)</returns> /// <returns>ICapture with the content (if any)</returns>
public static ICapture CaptureIE(ICapture capture, WindowDetails windowToCapture) { public static ICapture CaptureIe(ICapture capture, WindowDetails windowToCapture) {
if (windowToCapture == null) { if (windowToCapture == null) {
windowToCapture = WindowDetails.GetActiveWindow(); windowToCapture = WindowDetails.GetActiveWindow();
} }
@ -355,15 +349,15 @@ namespace Greenshot.Helpers {
// Nothing found // Nothing found
if (documentContainer == null) { if (documentContainer == null) {
LOG.Debug("Nothing to capture found"); Log.Debug("Nothing to capture found");
return null; return null;
} }
try { try {
LOG.DebugFormat("Window class {0}", documentContainer.ContentWindow.ClassName); Log.DebugFormat("Window class {0}", documentContainer.ContentWindow.ClassName);
LOG.DebugFormat("Window location {0}", documentContainer.ContentWindow.Location); Log.DebugFormat("Window location {0}", documentContainer.ContentWindow.Location);
} catch (Exception ex) { } catch (Exception ex) {
LOG.Warn("Error while logging information.", ex); Log.Warn("Error while logging information.", ex);
} }
// bitmap to return // bitmap to return
@ -372,12 +366,12 @@ namespace Greenshot.Helpers {
Size pageSize = PrepareCapture(documentContainer, capture); Size pageSize = PrepareCapture(documentContainer, capture);
returnBitmap = CapturePage(documentContainer, pageSize); returnBitmap = CapturePage(documentContainer, pageSize);
} catch (Exception captureException) { } catch (Exception captureException) {
LOG.Error("Exception found, ignoring and returning nothing! Error was: ", captureException); Log.Error("Exception found, ignoring and returning nothing! Error was: ", captureException);
} }
// TODO: Enable when the elements are usable again. // TODO: Enable when the elements are usable again.
// Capture the element on the page // Capture the element on the page
//try { //try {
// if (configuration.IEFieldCapture && capture.CaptureDetails.HasDestination("Editor")) { // if (CoreConfig.IEFieldCapture && capture.CaptureDetails.HasDestination("Editor")) {
// // clear the current elements, as they are for the window itself // // clear the current elements, as they are for the window itself
// capture.Elements.Clear(); // capture.Elements.Clear();
// CaptureElement documentCaptureElement = documentContainer.CreateCaptureElements(pageSize); // CaptureElement documentCaptureElement = documentContainer.CreateCaptureElements(pageSize);
@ -414,13 +408,9 @@ namespace Greenshot.Helpers {
// The URL is available unter "document2.url" and can be used to enhance the meta-data etc. // The URL is available unter "document2.url" and can be used to enhance the meta-data etc.
capture.CaptureDetails.AddMetaData("url", documentContainer.Url); capture.CaptureDetails.AddMetaData("url", documentContainer.Url);
// Store the title of the page // Store the title of the page
if (documentContainer.Name != null) { capture.CaptureDetails.Title = documentContainer.Name ?? windowToCapture.Text;
capture.CaptureDetails.Title = documentContainer.Name;
} else {
capture.CaptureDetails.Title = windowToCapture.Text;
}
} catch (Exception ex) { } catch (Exception ex) {
LOG.Warn("Problems getting some attributes...", ex); Log.Warn("Problems getting some attributes...", ex);
} }
// Store the URL of the page // Store the URL of the page
@ -446,7 +436,7 @@ namespace Greenshot.Helpers {
} }
capture.CaptureDetails.AddMetaData("URL_PORT", uri.Port.ToString()); capture.CaptureDetails.AddMetaData("URL_PORT", uri.Port.ToString());
} catch(Exception e) { } catch(Exception e) {
LOG.Warn("Exception when trying to use url in metadata "+documentContainer.Url,e); Log.Warn("Exception when trying to use url in metadata "+documentContainer.Url,e);
} }
} }
try { try {
@ -454,7 +444,7 @@ namespace Greenshot.Helpers {
capture.MoveMouseLocation(-documentContainer.ViewportRectangle.X, -documentContainer.ViewportRectangle.Y); capture.MoveMouseLocation(-documentContainer.ViewportRectangle.X, -documentContainer.ViewportRectangle.Y);
// Used to be: capture.MoveMouseLocation(-(capture.Location.X + documentContainer.CaptureOffset.X), -(capture.Location.Y + documentContainer.CaptureOffset.Y)); // Used to be: capture.MoveMouseLocation(-(capture.Location.X + documentContainer.CaptureOffset.X), -(capture.Location.Y + documentContainer.CaptureOffset.Y));
} catch (Exception ex) { } catch (Exception ex) {
LOG.Warn("Error while correcting the mouse offset.", ex); Log.Warn("Error while correcting the mouse offset.", ex);
} }
} finally { } finally {
// Always close the background form // Always close the background form
@ -480,7 +470,7 @@ namespace Greenshot.Helpers {
movedFrame = false; movedFrame = false;
foreach(DocumentContainer currentFrame in documentContainer.Frames) { foreach(DocumentContainer currentFrame in documentContainer.Frames) {
foreach(DocumentContainer otherFrame in documentContainer.Frames) { foreach(DocumentContainer otherFrame in documentContainer.Frames) {
if (otherFrame.ID == currentFrame.ID) { if (otherFrame.Id == currentFrame.Id) {
continue; continue;
} }
// check if we need to move // check if we need to move
@ -494,16 +484,16 @@ namespace Greenshot.Helpers {
if ((horizalResize || horizalMove) && leftOf) { if ((horizalResize || horizalMove) && leftOf) {
// Current frame resized horizontally, so move other horizontally // Current frame resized horizontally, so move other horizontally
LOG.DebugFormat("Moving Frame {0} horizontally to the right of {1}", otherFrame.Name, currentFrame.Name); Log.DebugFormat("Moving Frame {0} horizontally to the right of {1}", otherFrame.Name, currentFrame.Name);
otherFrame.DestinationLeft = currentFrame.DestinationRight; otherFrame.DestinationLeft = currentFrame.DestinationRight;
movedFrame = true; movedFrame = true;
} else if ((verticalResize || verticalMove) && belowOf){ } else if ((verticalResize || verticalMove) && belowOf){
// Current frame resized vertically, so move other vertically // Current frame resized vertically, so move other vertically
LOG.DebugFormat("Moving Frame {0} vertically to the bottom of {1}", otherFrame.Name, currentFrame.Name); Log.DebugFormat("Moving Frame {0} vertically to the bottom of {1}", otherFrame.Name, currentFrame.Name);
otherFrame.DestinationTop = currentFrame.DestinationBottom; otherFrame.DestinationTop = currentFrame.DestinationBottom;
movedFrame = true; movedFrame = true;
} else { } else {
LOG.DebugFormat("Frame {0} intersects with {1}", otherFrame.Name, currentFrame.Name); Log.DebugFormat("Frame {0} intersects with {1}", otherFrame.Name, currentFrame.Name);
} }
} }
} }
@ -539,11 +529,11 @@ namespace Greenshot.Helpers {
// Limit the size as the editor currently can't work with sizes > short.MaxValue // Limit the size as the editor currently can't work with sizes > short.MaxValue
if (pageWidth > short.MaxValue) { if (pageWidth > short.MaxValue) {
LOG.WarnFormat("Capture has a width of {0} which bigger than the maximum supported {1}, cutting width to the maxium.", pageWidth, short.MaxValue); Log.WarnFormat("Capture has a width of {0} which bigger than the maximum supported {1}, cutting width to the maxium.", pageWidth, short.MaxValue);
pageWidth = Math.Min(pageWidth, short.MaxValue); pageWidth = Math.Min(pageWidth, short.MaxValue);
} }
if (pageHeight > short.MaxValue) { if (pageHeight > short.MaxValue) {
LOG.WarnFormat("Capture has a height of {0} which bigger than the maximum supported {1}, cutting height to the maxium", pageHeight, short.MaxValue); Log.WarnFormat("Capture has a height of {0} which bigger than the maximum supported {1}, cutting height to the maxium", pageHeight, short.MaxValue);
pageHeight = Math.Min(pageHeight, short.MaxValue); pageHeight = Math.Min(pageHeight, short.MaxValue);
} }
return new Size(pageWidth, pageHeight); return new Size(pageWidth, pageHeight);
@ -563,7 +553,7 @@ namespace Greenshot.Helpers {
using (Graphics graphicsTarget = Graphics.FromImage(returnBitmap)) { using (Graphics graphicsTarget = Graphics.FromImage(returnBitmap)) {
// Clear the target with the backgroundcolor // Clear the target with the backgroundcolor
Color clearColor = documentContainer.BackgroundColor; Color clearColor = documentContainer.BackgroundColor;
LOG.DebugFormat("Clear color: {0}", clearColor); Log.DebugFormat("Clear color: {0}", clearColor);
graphicsTarget.Clear(clearColor); graphicsTarget.Clear(clearColor);
// Get the base document & draw it // Get the base document & draw it
@ -597,7 +587,7 @@ namespace Greenshot.Helpers {
int pageWidth = documentContainer.ScrollWidth; int pageWidth = documentContainer.ScrollWidth;
int pageHeight = documentContainer.ScrollHeight; int pageHeight = documentContainer.ScrollHeight;
if (pageWidth * pageHeight == 0) { if (pageWidth * pageHeight == 0) {
LOG.WarnFormat("Empty page for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url); Log.WarnFormat("Empty page for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
return; return;
} }
@ -605,7 +595,7 @@ namespace Greenshot.Helpers {
int viewportWidth = documentContainer.ClientWidth; int viewportWidth = documentContainer.ClientWidth;
int viewportHeight = documentContainer.ClientHeight; int viewportHeight = documentContainer.ClientHeight;
if (viewportWidth * viewportHeight == 0) { if (viewportWidth * viewportHeight == 0) {
LOG.WarnFormat("Empty viewport for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url); Log.WarnFormat("Empty viewport for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
return; return;
} }
@ -613,7 +603,7 @@ namespace Greenshot.Helpers {
int startLeft = documentContainer.ScrollLeft; int startLeft = documentContainer.ScrollLeft;
int startTop = documentContainer.ScrollTop; int startTop = documentContainer.ScrollTop;
LOG.DebugFormat("Capturing {4} with total size {0},{1} displayed with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name); Log.DebugFormat("Capturing {4} with total size {0},{1} displayed with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name);
// Variable used for looping horizontally // Variable used for looping horizontally
int horizontalPage = 0; int horizontalPage = 0;
@ -640,34 +630,34 @@ namespace Greenshot.Helpers {
Rectangle clientRectangle = new Rectangle(documentContainer.SourceLocation, viewPortSize); Rectangle clientRectangle = new Rectangle(documentContainer.SourceLocation, viewPortSize);
Image fragment = contentWindowDetails.PrintWindow(); Image fragment = contentWindowDetails.PrintWindow();
if (fragment != null) { if (fragment != null) {
LOG.DebugFormat("Captured fragment size: {0}x{1}", fragment.Width, fragment.Height); Log.DebugFormat("Captured fragment size: {0}x{1}", fragment.Width, fragment.Height);
try { try {
// cut all junk, due to IE "border" we need to remove some parts // cut all junk, due to IE "border" we need to remove some parts
Rectangle viewportRect = documentContainer.ViewportRectangle; Rectangle viewportRect = documentContainer.ViewportRectangle;
if (!viewportRect.IsEmpty) { if (!viewportRect.IsEmpty) {
LOG.DebugFormat("Cropping to viewport: {0}", viewportRect); Log.DebugFormat("Cropping to viewport: {0}", viewportRect);
ImageHelper.Crop(ref fragment, ref viewportRect); ImageHelper.Crop(ref fragment, ref viewportRect);
} }
LOG.DebugFormat("Cropping to clientRectangle: {0}", clientRectangle); Log.DebugFormat("Cropping to clientRectangle: {0}", clientRectangle);
// Crop to clientRectangle // Crop to clientRectangle
if (ImageHelper.Crop(ref fragment, ref clientRectangle)) { if (ImageHelper.Crop(ref fragment, ref clientRectangle)) {
Point targetLocation = new Point(documentContainer.DestinationLocation.X, documentContainer.DestinationLocation.Y); Point targetLocation = new Point(documentContainer.DestinationLocation.X, documentContainer.DestinationLocation.Y);
LOG.DebugFormat("Fragment targetLocation is {0}", targetLocation); Log.DebugFormat("Fragment targetLocation is {0}", targetLocation);
targetLocation.Offset(targetOffset); targetLocation.Offset(targetOffset);
LOG.DebugFormat("After offsetting the fragment targetLocation is {0}", targetLocation); Log.DebugFormat("After offsetting the fragment targetLocation is {0}", targetLocation);
LOG.DebugFormat("Drawing fragment of size {0} to {1}", fragment.Size, targetLocation); Log.DebugFormat("Drawing fragment of size {0} to {1}", fragment.Size, targetLocation);
graphicsTarget.DrawImage(fragment, targetLocation); graphicsTarget.DrawImage(fragment, targetLocation);
graphicsTarget.Flush(); graphicsTarget.Flush();
} else { } else {
// somehow we are capturing nothing!? // somehow we are capturing nothing!?
LOG.WarnFormat("Crop of {0} failed?", documentContainer.Name); Log.WarnFormat("Crop of {0} failed?", documentContainer.Name);
break; break;
} }
} finally { } finally {
fragment.Dispose(); fragment.Dispose();
} }
} else { } else {
LOG.WarnFormat("Capture of {0} failed!", documentContainer.Name); Log.WarnFormat("Capture of {0} failed!", documentContainer.Name);
} }
verticalPage++; verticalPage++;
} }

View file

@ -36,15 +36,12 @@ namespace Greenshot.Helpers.IEInterop {
private static readonly Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046"); private static readonly Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
private static readonly Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E"); private static readonly Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
private static int _counter; private static int _counter;
private readonly int _id = _counter++;
private IHTMLDocument2 _document2; private IHTMLDocument2 _document2;
private IHTMLDocument3 _document3; private IHTMLDocument3 _document3;
private Point _sourceLocation; private Point _sourceLocation;
private Point _destinationLocation; private Point _destinationLocation;
private Point _startLocation = Point.Empty; private Point _startLocation = Point.Empty;
private Rectangle _viewportRectangle = Rectangle.Empty; private Rectangle _viewportRectangle = Rectangle.Empty;
private string _name;
private string _url;
private bool _isDtd; private bool _isDtd;
private DocumentContainer _parent; private DocumentContainer _parent;
private WindowDetails _contentWindow; private WindowDetails _contentWindow;
@ -58,7 +55,7 @@ namespace Greenshot.Helpers.IEInterop {
IHTMLDocument2 document2 = GetDocumentFromWindow(frameWindow); IHTMLDocument2 document2 = GetDocumentFromWindow(frameWindow);
try { try {
LOG.DebugFormat("frameWindow.name {0}", frameWindow.name); LOG.DebugFormat("frameWindow.name {0}", frameWindow.name);
_name = frameWindow.name; Name = frameWindow.name;
} catch { } catch {
// Ignore // Ignore
} }
@ -91,7 +88,7 @@ namespace Greenshot.Helpers.IEInterop {
public DocumentContainer(IHTMLDocument2 document2, WindowDetails contentWindow) { public DocumentContainer(IHTMLDocument2 document2, WindowDetails contentWindow) {
Init(document2, contentWindow); Init(document2, contentWindow);
LOG.DebugFormat("Creating DocumentContainer for Document {0} found in window with rectangle {1}", _name, SourceRectangle); LOG.DebugFormat("Creating DocumentContainer for Document {0} found in window with rectangle {1}", Name, SourceRectangle);
} }
/// <summary> /// <summary>
@ -119,7 +116,7 @@ namespace Greenshot.Helpers.IEInterop {
//compatibility mode affects how height is computed //compatibility mode affects how height is computed
_isDtd = false; _isDtd = false;
try { try {
if (_document3 != null && (_document3.documentElement != null) && !document5.compatMode.Equals("BackCompat")) { if (_document3?.documentElement != null && !document5.compatMode.Equals("BackCompat")) {
_isDtd = true; _isDtd = true;
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -176,15 +173,15 @@ namespace Greenshot.Helpers.IEInterop {
try { try {
LOG.DebugFormat("Calculated location {0} for {1}", _startLocation, document2.title); LOG.DebugFormat("Calculated location {0} for {1}", _startLocation, document2.title);
if (_name == null) { if (Name == null) {
_name = document2.title; Name = document2.title;
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Warn("Problem while trying to get document title!", e); LOG.Warn("Problem while trying to get document title!", e);
} }
try { try {
_url = document2.url; Url = document2.url;
} catch (Exception e) { } catch (Exception e) {
LOG.Warn("Problem while trying to get document url!", e); LOG.Warn("Problem while trying to get document url!", e);
} }
@ -202,7 +199,7 @@ namespace Greenshot.Helpers.IEInterop {
DocumentContainer frameData = new DocumentContainer(frameWindow, contentWindow, this); DocumentContainer frameData = new DocumentContainer(frameWindow, contentWindow, this);
// check if frame is hidden // check if frame is hidden
if (!frameData.IsHidden) { if (!frameData.IsHidden) {
LOG.DebugFormat("Creating DocumentContainer for Frame {0} found in window with rectangle {1}", frameData._name, frameData.SourceRectangle); LOG.DebugFormat("Creating DocumentContainer for Frame {0} found in window with rectangle {1}", frameData.Name, frameData.SourceRectangle);
_frames.Add(frameData); _frames.Add(frameData);
} else { } else {
LOG.DebugFormat("Skipping frame {0}", frameData.Name); LOG.DebugFormat("Skipping frame {0}", frameData.Name);
@ -341,17 +338,9 @@ namespace Greenshot.Helpers.IEInterop {
} }
} }
public Rectangle ViewportRectangle { public Rectangle ViewportRectangle => _viewportRectangle;
get {
return _viewportRectangle;
}
}
public WindowDetails ContentWindow { public WindowDetails ContentWindow => _contentWindow;
get {
return _contentWindow;
}
}
public DocumentContainer Parent { public DocumentContainer Parent {
get { get {
@ -391,12 +380,7 @@ namespace Greenshot.Helpers.IEInterop {
/// <param name="attribute">Attribute to set</param> /// <param name="attribute">Attribute to set</param>
/// <param name="value">Value to set</param> /// <param name="value">Value to set</param>
public void SetAttribute(string attribute, string value) { public void SetAttribute(string attribute, string value) {
IHTMLElement element = null; var element = !_isDtd ? _document2.body : _document3.documentElement;
if (!_isDtd) {
element = _document2.body;
} else {
element = _document3.documentElement;
}
element.setAttribute(attribute, value, 1); element.setAttribute(attribute, value, 1);
// Release IHTMLElement com object // Release IHTMLElement com object
releaseCom(element); releaseCom(element);
@ -408,12 +392,7 @@ namespace Greenshot.Helpers.IEInterop {
/// <param name="attribute">Attribute to get</param> /// <param name="attribute">Attribute to get</param>
/// <returns>object with the attribute value</returns> /// <returns>object with the attribute value</returns>
public object GetAttribute(string attribute) { public object GetAttribute(string attribute) {
IHTMLElement element; var element = !_isDtd ? _document2.body : _document3.documentElement;
if (!_isDtd) {
element = _document2.body;
} else {
element = _document3.documentElement;
}
var retVal = element.getAttribute(attribute, 1); var retVal = element.getAttribute(attribute, 1);
// Release IHTMLElement com object // Release IHTMLElement com object
releaseCom(element); releaseCom(element);
@ -428,53 +407,21 @@ namespace Greenshot.Helpers.IEInterop {
return retVal; return retVal;
} }
public int ID { public int Id { get; } = _counter++;
get {
return _id;
}
}
public string Name { public string Name { get; private set; }
get {
return _name;
}
}
public string Url { public string Url { get; private set; }
get {
return _url;
}
}
public bool IsHidden { public bool IsHidden => ClientWidth == 0 || ClientHeight == 0;
get {
return ClientWidth == 0 || ClientHeight == 0;
}
}
public int ClientWidth { public int ClientWidth => ScaleX(GetAttributeAsInt("clientWidth"));
get {
return ScaleX(GetAttributeAsInt("clientWidth"));
}
}
public int ClientHeight { public int ClientHeight => ScaleY(GetAttributeAsInt("clientHeight"));
get {
return ScaleY(GetAttributeAsInt("clientHeight"));
}
}
public int ScrollWidth { public int ScrollWidth => ScaleX(GetAttributeAsInt("scrollWidth"));
get {
return ScaleX(GetAttributeAsInt("scrollWidth"));
}
}
public int ScrollHeight { public int ScrollHeight => ScaleY(GetAttributeAsInt("scrollHeight"));
get {
return ScaleY(GetAttributeAsInt("scrollHeight"));
}
}
public Point SourceLocation { public Point SourceLocation {
get { get {
@ -485,41 +432,17 @@ namespace Greenshot.Helpers.IEInterop {
} }
} }
public Size SourceSize { public Size SourceSize => new Size(ClientWidth, ClientHeight);
get {
return new Size(ClientWidth, ClientHeight);
}
}
public Rectangle SourceRectangle { public Rectangle SourceRectangle => new Rectangle(SourceLocation, SourceSize);
get {
return new Rectangle(SourceLocation, SourceSize);
}
}
public int SourceLeft { public int SourceLeft => _sourceLocation.X;
get {
return _sourceLocation.X;
}
}
public int SourceTop { public int SourceTop => _sourceLocation.Y;
get {
return _sourceLocation.Y;
}
}
public int SourceRight { public int SourceRight => _sourceLocation.X + ClientWidth;
get {
return _sourceLocation.X + ClientWidth;
}
}
public int SourceBottom { public int SourceBottom => _sourceLocation.Y + ClientHeight;
get {
return _sourceLocation.Y + ClientHeight;
}
}
public Point DestinationLocation { public Point DestinationLocation {
get { get {
@ -531,17 +454,9 @@ namespace Greenshot.Helpers.IEInterop {
} }
public Size DestinationSize { public Size DestinationSize => new Size(ScrollWidth, ScrollHeight);
get {
return new Size(ScrollWidth, ScrollHeight);
}
}
public Rectangle DestinationRectangle { public Rectangle DestinationRectangle => new Rectangle(DestinationLocation, DestinationSize);
get {
return new Rectangle(DestinationLocation, DestinationSize);
}
}
public int DestinationLeft { public int DestinationLeft {
get { get {
@ -561,17 +476,9 @@ namespace Greenshot.Helpers.IEInterop {
} }
} }
public int DestinationRight { public int DestinationRight => _destinationLocation.X + ScrollWidth;
get {
return _destinationLocation.X + ScrollWidth;
}
}
public int DestinationBottom { public int DestinationBottom => _destinationLocation.Y + ScrollHeight;
get {
return _destinationLocation.Y + ScrollHeight;
}
}
public int ScrollLeft { public int ScrollLeft {
get{ get{
@ -591,10 +498,6 @@ namespace Greenshot.Helpers.IEInterop {
} }
} }
public IList<DocumentContainer> Frames { public IList<DocumentContainer> Frames => _frames;
get {
return _frames;
}
}
} }
} }

View file

@ -43,8 +43,8 @@ namespace Greenshot.Helpers {
/// Represents an email message to be sent through MAPI. /// Represents an email message to be sent through MAPI.
/// </summary> /// </summary>
public class MapiMailMessage : IDisposable { public class MapiMailMessage : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(MapiMailMessage)); private static readonly ILog Log = LogManager.GetLogger(typeof(MapiMailMessage));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
/// <summary> /// <summary>
/// Helper Method for creating an Email with Attachment /// Helper Method for creating an Email with Attachment
@ -54,14 +54,14 @@ namespace Greenshot.Helpers {
public static void SendImage(string fullPath, string title) { public static void SendImage(string fullPath, string title) {
using (MapiMailMessage message = new MapiMailMessage(title, null)) { using (MapiMailMessage message = new MapiMailMessage(title, null)) {
message.Files.Add(fullPath); message.Files.Add(fullPath);
if (!string.IsNullOrEmpty(conf.MailApiTo)) { if (!string.IsNullOrEmpty(CoreConfig.MailApiTo)) {
message._recipientCollection.Add(new Recipient(conf.MailApiTo, RecipientType.To)); message.Recipients.Add(new Recipient(CoreConfig.MailApiTo, RecipientType.To));
} }
if (!string.IsNullOrEmpty(conf.MailApiCC)) { if (!string.IsNullOrEmpty(CoreConfig.MailApiCC)) {
message._recipientCollection.Add(new Recipient(conf.MailApiCC, RecipientType.CC)); message.Recipients.Add(new Recipient(CoreConfig.MailApiCC, RecipientType.CC));
} }
if (!string.IsNullOrEmpty(conf.MailApiBCC)) { if (!string.IsNullOrEmpty(CoreConfig.MailApiBCC)) {
message._recipientCollection.Add(new Recipient(conf.MailApiBCC, RecipientType.BCC)); message.Recipients.Add(new Recipient(CoreConfig.MailApiBCC, RecipientType.BCC));
} }
message.ShowDialog(); message.ShowDialog();
} }
@ -80,10 +80,10 @@ namespace Greenshot.Helpers {
// Store the list of currently active windows, so we can make sure we show the email window later! // Store the list of currently active windows, so we can make sure we show the email window later!
var windowsBefore = WindowDetails.GetVisibleWindows(); var windowsBefore = WindowDetails.GetVisibleWindows();
//bool isEmailSend = false; //bool isEmailSend = false;
//if (EmailConfigHelper.HasOutlook() && (conf.OutputEMailFormat == EmailFormat.OUTLOOK_HTML || conf.OutputEMailFormat == EmailFormat.OUTLOOK_TXT)) { //if (EmailConfigHelper.HasOutlook() && (CoreConfig.OutputEMailFormat == EmailFormat.OUTLOOK_HTML || CoreConfig.OutputEMailFormat == EmailFormat.OUTLOOK_TXT)) {
// isEmailSend = OutlookExporter.ExportToOutlook(tmpFile, captureDetails); // isEmailSend = OutlookExporter.ExportToOutlook(tmpFile, captureDetails);
//} //}
if (/*!isEmailSend &&*/ EmailConfigHelper.HasMAPI()) { if (/*!isEmailSend &&*/ EmailConfigHelper.HasMapi()) {
// Fallback to MAPI // Fallback to MAPI
// Send the email // Send the email
SendImage(tmpFile, captureDetails.Title); SendImage(tmpFile, captureDetails.Title);
@ -132,9 +132,6 @@ namespace Greenshot.Helpers {
#region Member Variables #region Member Variables
private string _subject;
private string _body;
private RecipientCollection _recipientCollection;
private readonly ManualResetEvent _manualResetEvent; private readonly ManualResetEvent _manualResetEvent;
#endregion Member Variables #endregion Member Variables
@ -146,7 +143,7 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
public MapiMailMessage() { public MapiMailMessage() {
Files = new List<string>(); Files = new List<string>();
_recipientCollection = new RecipientCollection(); Recipients = new RecipientCollection();
_manualResetEvent = new ManualResetEvent(false); _manualResetEvent = new ManualResetEvent(false);
} }
@ -154,15 +151,15 @@ namespace Greenshot.Helpers {
/// Creates a new mail message with the specified subject. /// Creates a new mail message with the specified subject.
/// </summary> /// </summary>
public MapiMailMessage(string subject) : this() { public MapiMailMessage(string subject) : this() {
_subject = subject; Subject = subject;
} }
/// <summary> /// <summary>
/// Creates a new mail message with the specified subject and body. /// Creates a new mail message with the specified subject and body.
/// </summary> /// </summary>
public MapiMailMessage(string subject, string body) : this() { public MapiMailMessage(string subject, string body) : this() {
_subject = subject; Subject = subject;
_body = body; Body = body;
} }
#endregion Constructors #endregion Constructors
@ -172,35 +169,17 @@ namespace Greenshot.Helpers {
/// <summary> /// <summary>
/// Gets or sets the subject of this mail message. /// Gets or sets the subject of this mail message.
/// </summary> /// </summary>
public string Subject { public string Subject { get; set; }
get {
return _subject;
}
set {
_subject = value;
}
}
/// <summary> /// <summary>
/// Gets or sets the body of this mail message. /// Gets or sets the body of this mail message.
/// </summary> /// </summary>
public string Body { public string Body { get; set; }
get {
return _body;
}
set {
_body = value;
}
}
/// <summary> /// <summary>
/// Gets the recipient list for this mail message. /// Gets the recipient list for this mail message.
/// </summary> /// </summary>
public RecipientCollection Recipients { public RecipientCollection Recipients { get; private set; }
get {
return _recipientCollection;
}
}
/// <summary> /// <summary>
/// Gets the file list for this mail message. /// Gets the file list for this mail message.
@ -216,11 +195,13 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
public void ShowDialog() { public void ShowDialog() {
// Create the mail message in an STA thread // Create the mail message in an STA thread
Thread t = new Thread(_ShowMail); var thread = new Thread(_ShowMail)
t.IsBackground = true; {
t.Name = "Create MAPI mail"; IsBackground = true,
t.SetApartmentState(ApartmentState.STA); Name = "Create MAPI mail"
t.Start(); };
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
// only return when the new thread has built it's interop representation // only return when the new thread has built it's interop representation
_manualResetEvent.WaitOne(); _manualResetEvent.WaitOne();
@ -240,10 +221,7 @@ namespace Greenshot.Helpers {
if (!disposing) { if (!disposing) {
return; return;
} }
if (_manualResetEvent != null) { _manualResetEvent?.Close();
_manualResetEvent.Close();
}
} }
/// <summary> /// <summary>
@ -252,12 +230,12 @@ namespace Greenshot.Helpers {
private void _ShowMail() { private void _ShowMail() {
var message = new MapiHelperInterop.MapiMessage(); var message = new MapiHelperInterop.MapiMessage();
using (var interopRecipients = _recipientCollection.GetInteropRepresentation()) { using (var interopRecipients = Recipients.GetInteropRepresentation()) {
message.Subject = _subject; message.Subject = Subject;
message.NoteText = _body; message.NoteText = Body;
message.Recipients = interopRecipients.Handle; message.Recipients = interopRecipients.Handle;
message.RecipientCount = _recipientCollection.Count; message.RecipientCount = Recipients.Count;
// Check if we need to add attachments // Check if we need to add attachments
if (Files.Count > 0) { if (Files.Count > 0) {
@ -284,14 +262,14 @@ namespace Greenshot.Helpers {
return; return;
} }
string errorText = GetMapiError(errorCode); string errorText = GetMapiError(errorCode);
LOG.Error("Error sending MAPI Email. Error: " + errorText + " (code = " + errorCode + ")."); Log.Error("Error sending MAPI Email. Error: " + errorText + " (code = " + errorCode + ").");
MessageBox.Show(errorText, "Mail (MAPI) destination", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(errorText, "Mail (MAPI) destination", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Recover from bad settings, show again // Recover from bad settings, show again
if (errorCode != MAPI_CODES.INVALID_RECIPS) if (errorCode != MAPI_CODES.INVALID_RECIPS)
{ {
return; return;
} }
_recipientCollection = new RecipientCollection(); Recipients = new RecipientCollection();
_ShowMail(); _ShowMail();
} }
} }
@ -340,8 +318,8 @@ namespace Greenshot.Helpers {
position = -1 position = -1
}; };
IntPtr runptr = ptra; IntPtr runptr = ptra;
for (int i = 0; i < Files.Count; i++) { foreach (string path in Files)
string path = Files[i]; {
mfd.name = Path.GetFileName(path); mfd.name = Path.GetFileName(path);
mfd.path = path; mfd.path = path;
Marshal.StructureToPtr(mfd, runptr, false); Marshal.StructureToPtr(mfd, runptr, false);
@ -664,11 +642,7 @@ namespace Greenshot.Helpers {
/// <summary> /// <summary>
/// Returns the recipient stored in this collection at the specified index. /// Returns the recipient stored in this collection at the specified index.
/// </summary> /// </summary>
public Recipient this[int index] { public Recipient this[int index] => (Recipient)List[index];
get {
return (Recipient)List[index];
}
}
internal InteropRecipientCollection GetInteropRepresentation() { internal InteropRecipientCollection GetInteropRepresentation() {
return new InteropRecipientCollection(this); return new InteropRecipientCollection(this);
@ -680,7 +654,6 @@ namespace Greenshot.Helpers {
internal struct InteropRecipientCollection : IDisposable { internal struct InteropRecipientCollection : IDisposable {
#region Member Variables #region Member Variables
private IntPtr _handle;
private int _count; private int _count;
#endregion Member Variables #endregion Member Variables
@ -695,16 +668,16 @@ namespace Greenshot.Helpers {
_count = outer.Count; _count = outer.Count;
if (_count == 0) { if (_count == 0) {
_handle = IntPtr.Zero; Handle = IntPtr.Zero;
return; return;
} }
// allocate enough memory to hold all recipients // allocate enough memory to hold all recipients
int size = Marshal.SizeOf(typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc)); int size = Marshal.SizeOf(typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc));
_handle = Marshal.AllocHGlobal(_count * size); Handle = Marshal.AllocHGlobal(_count * size);
// place all interop recipients into the memory just allocated // place all interop recipients into the memory just allocated
IntPtr ptr = _handle; IntPtr ptr = Handle;
foreach (Recipient native in outer) { foreach (Recipient native in outer) {
MapiMailMessage.MapiHelperInterop.MapiRecipDesc interop = native.GetInteropRepresentation(); MapiMailMessage.MapiHelperInterop.MapiRecipDesc interop = native.GetInteropRepresentation();
@ -718,11 +691,7 @@ namespace Greenshot.Helpers {
#region Public Properties #region Public Properties
public IntPtr Handle { public IntPtr Handle { get; private set; }
get {
return _handle;
}
}
#endregion Public Properties #endregion Public Properties
@ -732,21 +701,21 @@ namespace Greenshot.Helpers {
/// Disposes of resources. /// Disposes of resources.
/// </summary> /// </summary>
public void Dispose() { public void Dispose() {
if (_handle != IntPtr.Zero) { if (Handle != IntPtr.Zero) {
Type type = typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc); Type type = typeof(MapiMailMessage.MapiHelperInterop.MapiRecipDesc);
int size = Marshal.SizeOf(type); int size = Marshal.SizeOf(type);
// destroy all the structures in the memory area // destroy all the structures in the memory area
IntPtr ptr = _handle; IntPtr ptr = Handle;
for (int i = 0; i < _count; i++) { for (int i = 0; i < _count; i++) {
Marshal.DestroyStructure(ptr, type); Marshal.DestroyStructure(ptr, type);
ptr = new IntPtr(ptr.ToInt64() + size); ptr = new IntPtr(ptr.ToInt64() + size);
} }
// free the memory // free the memory
Marshal.FreeHGlobal(_handle); Marshal.FreeHGlobal(Handle);
_handle = IntPtr.Zero; Handle = IntPtr.Zero;
_count = 0; _count = 0;
} }
} }

View file

@ -35,42 +35,31 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
[Serializable] [Serializable]
public class PluginHelper : IGreenshotHost { public class PluginHelper : IGreenshotHost {
private static readonly ILog LOG = LogManager.GetLogger(typeof(PluginHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(PluginHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly string pluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName); private static readonly string PluginPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName);
private static readonly string applicationPath = Path.GetDirectoryName(Application.ExecutablePath); private static readonly string ApplicationPath = Path.GetDirectoryName(Application.ExecutablePath);
private static readonly string pafPath = Path.Combine(Application.StartupPath, @"App\Greenshot"); private static readonly string PafPath = Path.Combine(Application.StartupPath, @"App\Greenshot");
private static readonly IDictionary<PluginAttribute, IGreenshotPlugin> plugins = new SortedDictionary<PluginAttribute, IGreenshotPlugin>(); private static readonly IDictionary<PluginAttribute, IGreenshotPlugin> plugins = new SortedDictionary<PluginAttribute, IGreenshotPlugin>();
private static readonly PluginHelper instance = new PluginHelper(); private static readonly PluginHelper instance = new PluginHelper();
public static PluginHelper Instance {
get { public static PluginHelper Instance => instance;
return instance;
}
}
private PluginHelper() { private PluginHelper() {
PluginUtils.Host = this; PluginUtils.Host = this;
} }
public Form GreenshotForm { public Form GreenshotForm => MainForm.Instance;
get {
return MainForm.Instance;
}
}
public NotifyIcon NotifyIcon { public NotifyIcon NotifyIcon => MainForm.Instance.NotifyIcon;
get {
return MainForm.Instance.NotifyIcon;
}
}
public bool HasPlugins() { public bool HasPlugins() {
return plugins != null && plugins.Count > 0; return plugins != null && plugins.Count > 0;
} }
public void Shutdown() { public void Shutdown() {
foreach(IGreenshotPlugin plugin in plugins.Values) { foreach(var plugin in plugins.Values) {
plugin.Shutdown(); plugin.Shutdown();
plugin.Dispose(); plugin.Dispose();
} }
@ -79,34 +68,39 @@ namespace Greenshot.Helpers {
// Add plugins to the Listview // Add plugins to the Listview
public void FillListview(ListView listview) { public void FillListview(ListView listview) {
foreach(PluginAttribute pluginAttribute in plugins.Keys) { foreach(var pluginAttribute in plugins.Keys) {
ListViewItem item = new ListViewItem(pluginAttribute.Name); var item = new ListViewItem(pluginAttribute.Name)
{
Tag = pluginAttribute
};
item.SubItems.Add(pluginAttribute.Version); item.SubItems.Add(pluginAttribute.Version);
item.SubItems.Add(pluginAttribute.CreatedBy); item.SubItems.Add(pluginAttribute.CreatedBy);
item.SubItems.Add(pluginAttribute.DllFile); item.SubItems.Add(pluginAttribute.DllFile);
item.Tag = pluginAttribute;
listview.Items.Add(item); listview.Items.Add(item);
} }
} }
public bool isSelectedItemConfigurable(ListView listview) { public bool IsSelectedItemConfigurable(ListView listview) {
if (listview.SelectedItems.Count > 0) { if (listview.SelectedItems.Count <= 0)
PluginAttribute pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag; {
if (pluginAttribute != null) { return false;
return pluginAttribute.Configurable;
}
} }
return false; var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
return pluginAttribute != null && pluginAttribute.Configurable;
} }
public void ConfigureSelectedItem(ListView listview) { public void ConfigureSelectedItem(ListView listview) {
if (listview.SelectedItems.Count > 0) { if (listview.SelectedItems.Count <= 0)
PluginAttribute pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag; {
if (pluginAttribute != null) { return;
IGreenshotPlugin plugin = plugins[pluginAttribute];
plugin.Configure();
}
} }
var pluginAttribute = (PluginAttribute)listview.SelectedItems[0].Tag;
if (pluginAttribute == null)
{
return;
}
var plugin = plugins[pluginAttribute];
plugin.Configure();
} }
#region Implementation of IGreenshotPluginHost #region Implementation of IGreenshotPluginHost
@ -115,6 +109,8 @@ namespace Greenshot.Helpers {
/// Create a Thumbnail /// Create a Thumbnail
/// </summary> /// </summary>
/// <param name="image">Image of which we need a Thumbnail</param> /// <param name="image">Image of which we need a Thumbnail</param>
/// <param name="width">Thumbnail width</param>
/// <param name="height">Thumbnail height</param>
/// <returns>Image with Thumbnail</returns> /// <returns>Image with Thumbnail</returns>
public Image GetThumbnail(Image image, int width, int height) { public Image GetThumbnail(Image image, int width, int height) {
return image.GetThumbnailImage(width, height, ThumbnailCallback, IntPtr.Zero); return image.GetThumbnailImage(width, height, ThumbnailCallback, IntPtr.Zero);
@ -128,15 +124,9 @@ namespace Greenshot.Helpers {
return true; return true;
} }
public ContextMenuStrip MainMenu { public ContextMenuStrip MainMenu => MainForm.Instance.MainMenu;
get {
return MainForm.Instance.MainMenu;
}
}
public IDictionary<PluginAttribute, IGreenshotPlugin> Plugins { public IDictionary<PluginAttribute, IGreenshotPlugin> Plugins => plugins;
get {return plugins;}
}
public IDestination GetDestination(string designation) { public IDestination GetDestination(string designation) {
return DestinationHelper.GetDestination(designation); return DestinationHelper.GetDestination(designation);
@ -161,7 +151,7 @@ namespace Greenshot.Helpers {
/// <summary> /// <summary>
/// Use the supplied image, and handle it as if it's captured. /// Use the supplied image, and handle it as if it's captured.
/// </summary> /// </summary>
/// <param name="imageToImport">Image to handle</param> /// <param name="captureToImport">Image to handle</param>
public void ImportCapture(ICapture captureToImport) { public void ImportCapture(ICapture captureToImport) {
MainForm.Instance.BeginInvoke((MethodInvoker)delegate { MainForm.Instance.BeginInvoke((MethodInvoker)delegate {
CaptureHelper.ImportCapture(captureToImport); CaptureHelper.ImportCapture(captureToImport);
@ -173,10 +163,14 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ICapture GetCapture(Image imageToCapture) { public ICapture GetCapture(Image imageToCapture) {
Capture capture = new Capture(imageToCapture); var capture = new Capture(imageToCapture)
capture.CaptureDetails = new CaptureDetails(); {
capture.CaptureDetails.CaptureMode = CaptureMode.Import; CaptureDetails = new CaptureDetails
capture.CaptureDetails.Title = "Imported"; {
CaptureMode = CaptureMode.Import,
Title = "Imported"
}
};
return capture; return capture;
} }
#endregion #endregion
@ -220,9 +214,8 @@ namespace Greenshot.Helpers {
pluginFiles.Add(pluginFile); pluginFiles.Add(pluginFile);
} }
} catch (UnauthorizedAccessException) { } catch (UnauthorizedAccessException) {
return;
} catch (Exception ex) { } catch (Exception ex) {
LOG.Error("Error loading plugin: ", ex); Log.Error("Error loading plugin: ", ex);
} }
} }
} }
@ -234,10 +227,10 @@ namespace Greenshot.Helpers {
List<string> pluginFiles = new List<string>(); List<string> pluginFiles = new List<string>();
if (IniConfig.IsPortable) { if (IniConfig.IsPortable) {
findPluginsOnPath(pluginFiles, pafPath); findPluginsOnPath(pluginFiles, PafPath);
} else { } else {
findPluginsOnPath(pluginFiles, pluginPath); findPluginsOnPath(pluginFiles, PluginPath);
findPluginsOnPath(pluginFiles, applicationPath); findPluginsOnPath(pluginFiles, ApplicationPath);
} }
Dictionary<string, PluginAttribute> tmpAttributes = new Dictionary<string, PluginAttribute>(); Dictionary<string, PluginAttribute> tmpAttributes = new Dictionary<string, PluginAttribute>();
@ -277,36 +270,36 @@ namespace Greenshot.Helpers {
} }
if (checkPluginAttribute != null) { if (checkPluginAttribute != null) {
LOG.WarnFormat("Duplicate plugin {0} found", pluginAttribute.Name); Log.WarnFormat("Duplicate plugin {0} found", pluginAttribute.Name);
if (isNewer(pluginAttribute.Version, checkPluginAttribute.Version)) { if (isNewer(pluginAttribute.Version, checkPluginAttribute.Version)) {
// Found is newer // Found is newer
tmpAttributes[pluginAttribute.Name] = pluginAttribute; tmpAttributes[pluginAttribute.Name] = pluginAttribute;
tmpAssemblies[pluginAttribute.Name] = assembly; tmpAssemblies[pluginAttribute.Name] = assembly;
LOG.InfoFormat("Loading the newer plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile); Log.InfoFormat("Loading the newer plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
} else { } 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); 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; continue;
} }
if (conf.ExcludePlugins != null && conf.ExcludePlugins.Contains(pluginAttribute.Name)) { if (CoreConfig.ExcludePlugins != null && CoreConfig.ExcludePlugins.Contains(pluginAttribute.Name)) {
LOG.WarnFormat("Exclude list: {0}", conf.ExcludePlugins.ToArray()); 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); Log.WarnFormat("Skipping the excluded plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
continue; continue;
} }
if (conf.IncludePlugins != null && conf.IncludePlugins.Count > 0 && !conf.IncludePlugins.Contains(pluginAttribute.Name)) { if (CoreConfig.IncludePlugins != null && CoreConfig.IncludePlugins.Count > 0 && !CoreConfig.IncludePlugins.Contains(pluginAttribute.Name)) {
// Whitelist is set // Whitelist is set
LOG.WarnFormat("Include list: {0}", conf.IncludePlugins.ToArray()); 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); Log.WarnFormat("Skipping the not included plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
continue; continue;
} }
LOG.InfoFormat("Loading the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile); Log.InfoFormat("Loading the plugin {0} with version {1} from {2}", pluginAttribute.Name, pluginAttribute.Version, pluginAttribute.DllFile);
tmpAttributes[pluginAttribute.Name] = pluginAttribute; tmpAttributes[pluginAttribute.Name] = pluginAttribute;
tmpAssemblies[pluginAttribute.Name] = assembly; tmpAssemblies[pluginAttribute.Name] = assembly;
} else { } else {
LOG.ErrorFormat("Can't find the needed Plugin Attribute ({0}) in the assembly of the file \"{1}\", skipping this file.", typeof(PluginAttribute), pluginFile); Log.ErrorFormat("Can't find the needed Plugin Attribute ({0}) in the assembly of the file \"{1}\", skipping this file.", typeof(PluginAttribute), pluginFile);
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Warn("Can't load file: " + pluginFile, e); Log.Warn("Can't load file: " + pluginFile, e);
} }
} }
foreach(string pluginName in tmpAttributes.Keys) { foreach(string pluginName in tmpAttributes.Keys) {
@ -315,7 +308,7 @@ namespace Greenshot.Helpers {
Assembly assembly = tmpAssemblies[pluginName]; Assembly assembly = tmpAssemblies[pluginName];
Type entryType = assembly.GetType(pluginAttribute.EntryType); Type entryType = assembly.GetType(pluginAttribute.EntryType);
if (entryType == null) { if (entryType == null) {
LOG.ErrorFormat("Can't find the in the PluginAttribute referenced type {0} in \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile); Log.ErrorFormat("Can't find the in the PluginAttribute referenced type {0} in \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
continue; continue;
} }
try { try {
@ -324,16 +317,16 @@ namespace Greenshot.Helpers {
if (plugin.Initialize(this, pluginAttribute)) { if (plugin.Initialize(this, pluginAttribute)) {
plugins.Add(pluginAttribute, plugin); plugins.Add(pluginAttribute, plugin);
} else { } else {
LOG.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name); Log.InfoFormat("Plugin {0} not initialized!", pluginAttribute.Name);
} }
} else { } else {
LOG.ErrorFormat("Can't create an instance of the in the PluginAttribute referenced type {0} from \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile); Log.ErrorFormat("Can't create an instance of the in the PluginAttribute referenced type {0} from \"{1}\"", pluginAttribute.EntryType, pluginAttribute.DllFile);
} }
} catch(Exception e) { } catch(Exception e) {
LOG.Error("Can't load Plugin: " + pluginAttribute.Name, e); Log.Error("Can't load Plugin: " + pluginAttribute.Name, e);
} }
} catch(Exception e) { } catch(Exception e) {
LOG.Error("Can't load Plugin: " + pluginName, e); Log.Error("Can't load Plugin: " + pluginName, e);
} }
} }
} }

View file

@ -28,7 +28,7 @@ using Greenshot.Forms;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using Greenshot.IniFile; using Greenshot.IniFile;
using Greenshot.Core; using GreenshotPlugin.Effects;
using log4net; using log4net;
namespace Greenshot.Helpers { namespace Greenshot.Helpers {
@ -36,21 +36,21 @@ namespace Greenshot.Helpers {
/// Description of PrintHelper. /// Description of PrintHelper.
/// </summary> /// </summary>
public class PrintHelper : IDisposable { public class PrintHelper : IDisposable {
private static readonly ILog LOG = LogManager.GetLogger(typeof(PrintHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(PrintHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private ISurface surface; private ISurface _surface;
private readonly ICaptureDetails captureDetails; private readonly ICaptureDetails _captureDetails;
private PrintDocument printDocument = new PrintDocument(); private PrintDocument _printDocument = new PrintDocument();
private PrintDialog printDialog = new PrintDialog(); private PrintDialog _printDialog = new PrintDialog();
public PrintHelper(ISurface surface, ICaptureDetails captureDetails) { public PrintHelper(ISurface surface, ICaptureDetails captureDetails) {
this.surface = surface; _surface = surface;
this.captureDetails = captureDetails; _captureDetails = captureDetails;
printDialog.UseEXDialog = true; _printDialog.UseEXDialog = true;
printDocument.DocumentName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(conf.OutputFileFilenamePattern, captureDetails); _printDocument.DocumentName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(CoreConfig.OutputFileFilenamePattern, captureDetails);
printDocument.PrintPage += DrawImageForPrint; _printDocument.PrintPage += DrawImageForPrint;
printDialog.Document = printDocument; _printDialog.Document = _printDocument;
} }
/** /**
@ -75,16 +75,12 @@ namespace Greenshot.Helpers {
*/ */
protected virtual void Dispose(bool disposing) { protected virtual void Dispose(bool disposing) {
if (disposing) { if (disposing) {
if (printDocument != null) { _printDocument?.Dispose();
printDocument.Dispose(); _printDialog?.Dispose();
}
if (printDialog != null) {
printDialog.Dispose();
}
} }
surface = null; _surface = null;
printDocument = null; _printDocument = null;
printDialog = null; _printDialog = null;
} }
/// <summary> /// <summary>
@ -97,15 +93,15 @@ namespace Greenshot.Helpers {
DialogResult? printOptionsResult = ShowPrintOptionsDialog(); DialogResult? printOptionsResult = ShowPrintOptionsDialog();
try { try {
if (printOptionsResult == null || printOptionsResult == DialogResult.OK) { if (printOptionsResult == null || printOptionsResult == DialogResult.OK) {
printDocument.PrinterSettings.PrinterName = printerName; _printDocument.PrinterSettings.PrinterName = printerName;
if (!IsColorPrint()) { if (!IsColorPrint()) {
printDocument.DefaultPageSettings.Color = false; _printDocument.DefaultPageSettings.Color = false;
} }
printDocument.Print(); _printDocument.Print();
returnPrinterSettings = printDocument.PrinterSettings; returnPrinterSettings = _printDocument.PrinterSettings;
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Error("An error ocurred while trying to print", e); Log.Error("An error ocurred while trying to print", e);
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error)); MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
} }
return returnPrinterSettings; return returnPrinterSettings;
@ -118,18 +114,18 @@ namespace Greenshot.Helpers {
/// <returns>printer settings if actually printed, or null if print was cancelled or has failed</returns> /// <returns>printer settings if actually printed, or null if print was cancelled or has failed</returns>
public PrinterSettings PrintWithDialog() { public PrinterSettings PrintWithDialog() {
PrinterSettings returnPrinterSettings = null; PrinterSettings returnPrinterSettings = null;
if (printDialog.ShowDialog() == DialogResult.OK) { if (_printDialog.ShowDialog() == DialogResult.OK) {
DialogResult? printOptionsResult = ShowPrintOptionsDialog(); DialogResult? printOptionsResult = ShowPrintOptionsDialog();
try { try {
if (printOptionsResult == null || printOptionsResult == DialogResult.OK) { if (printOptionsResult == null || printOptionsResult == DialogResult.OK) {
if (!IsColorPrint()) { if (!IsColorPrint()) {
printDocument.DefaultPageSettings.Color = false; _printDocument.DefaultPageSettings.Color = false;
} }
printDocument.Print(); _printDocument.Print();
returnPrinterSettings = printDialog.PrinterSettings; returnPrinterSettings = _printDialog.PrinterSettings;
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Error("An error ocurred while trying to print", e); Log.Error("An error ocurred while trying to print", e);
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error)); MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
} }
@ -138,7 +134,7 @@ namespace Greenshot.Helpers {
} }
private bool IsColorPrint() { private bool IsColorPrint() {
return !conf.OutputPrintGrayscale && !conf.OutputPrintMonochrome; return !CoreConfig.OutputPrintGrayscale && !CoreConfig.OutputPrintMonochrome;
} }
/// <summary> /// <summary>
@ -147,7 +143,7 @@ namespace Greenshot.Helpers {
/// <returns>result of the print dialog, or null if the dialog has not been displayed by config</returns> /// <returns>result of the print dialog, or null if the dialog has not been displayed by config</returns>
private DialogResult? ShowPrintOptionsDialog() { private DialogResult? ShowPrintOptionsDialog() {
DialogResult? ret = null; DialogResult? ret = null;
if (conf.OutputPrintPromptOptions) { if (CoreConfig.OutputPrintPromptOptions) {
using (PrintOptionsDialog printOptionsDialog = new PrintOptionsDialog()) { using (PrintOptionsDialog printOptionsDialog = new PrintOptionsDialog()) {
ret = printOptionsDialog.ShowDialog(); ret = printOptionsDialog.ShowDialog();
} }
@ -164,16 +160,16 @@ namespace Greenshot.Helpers {
ApplyEffects(printOutputSettings); ApplyEffects(printOutputSettings);
Image image; Image image;
bool disposeImage = ImageOutput.CreateImageFromSurface(surface, printOutputSettings, out image); bool disposeImage = ImageOutput.CreateImageFromSurface(_surface, printOutputSettings, out image);
try { try {
ContentAlignment alignment = conf.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft; ContentAlignment alignment = CoreConfig.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft;
// prepare timestamp // prepare timestamp
float footerStringWidth = 0; float footerStringWidth = 0;
float footerStringHeight = 0; float footerStringHeight = 0;
string footerString = null; //DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString(); string footerString = null; //DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
if (conf.OutputPrintFooter) { if (CoreConfig.OutputPrintFooter) {
footerString = FilenameHelper.FillPattern(conf.OutputPrintFooterPattern, captureDetails, false); footerString = FilenameHelper.FillPattern(CoreConfig.OutputPrintFooterPattern, _captureDetails, false);
using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) { using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) {
footerStringWidth = e.Graphics.MeasureString(footerString, f).Width; footerStringWidth = e.Graphics.MeasureString(footerString, f).Width;
footerStringHeight = e.Graphics.MeasureString(footerString, f).Height; footerStringHeight = e.Graphics.MeasureString(footerString, f).Height;
@ -194,7 +190,7 @@ namespace Greenshot.Helpers {
GraphicsUnit gu = GraphicsUnit.Pixel; GraphicsUnit gu = GraphicsUnit.Pixel;
RectangleF imageRect = image.GetBounds(ref gu); RectangleF imageRect = image.GetBounds(ref gu);
// rotate the image if it fits the page better // rotate the image if it fits the page better
if (conf.OutputPrintAllowRotate) { if (CoreConfig.OutputPrintAllowRotate) {
if ((pageRect.Width > pageRect.Height && imageRect.Width < imageRect.Height) || (pageRect.Width < pageRect.Height && imageRect.Width > imageRect.Height)) { if ((pageRect.Width > pageRect.Height && imageRect.Width < imageRect.Height) || (pageRect.Width < pageRect.Height && imageRect.Width > imageRect.Height)) {
image.RotateFlip(RotateFlipType.Rotate270FlipNone); image.RotateFlip(RotateFlipType.Rotate270FlipNone);
imageRect = image.GetBounds(ref gu); imageRect = image.GetBounds(ref gu);
@ -206,16 +202,16 @@ namespace Greenshot.Helpers {
RectangleF printRect = new RectangleF(0, 0, imageRect.Width, imageRect.Height); RectangleF printRect = new RectangleF(0, 0, imageRect.Width, imageRect.Height);
// scale the image to fit the page better // scale the image to fit the page better
if (conf.OutputPrintAllowEnlarge || conf.OutputPrintAllowShrink) { if (CoreConfig.OutputPrintAllowEnlarge || CoreConfig.OutputPrintAllowShrink) {
SizeF resizedRect = ScaleHelper.GetScaledSize(imageRect.Size, pageRect.Size, false); SizeF resizedRect = ScaleHelper.GetScaledSize(imageRect.Size, pageRect.Size, false);
if ((conf.OutputPrintAllowShrink && resizedRect.Width < printRect.Width) || conf.OutputPrintAllowEnlarge && resizedRect.Width > printRect.Width) { if ((CoreConfig.OutputPrintAllowShrink && resizedRect.Width < printRect.Width) || CoreConfig.OutputPrintAllowEnlarge && resizedRect.Width > printRect.Width) {
printRect.Size = resizedRect; printRect.Size = resizedRect;
} }
} }
// align the image // align the image
printRect = ScaleHelper.GetAlignedRectangle(printRect, new RectangleF(0, 0, pageRect.Width, pageRect.Height), alignment); printRect = ScaleHelper.GetAlignedRectangle(printRect, new RectangleF(0, 0, pageRect.Width, pageRect.Height), alignment);
if (conf.OutputPrintFooter) { if (CoreConfig.OutputPrintFooter) {
//printRect = new RectangleF(0, 0, printRect.Width, printRect.Height - (dateStringHeight * 2)); //printRect = new RectangleF(0, 0, printRect.Width, printRect.Height - (dateStringHeight * 2));
using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) { using (Font f = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)) {
e.Graphics.DrawString(footerString, f, Brushes.Black, pageRect.Width / 2 - footerStringWidth / 2, pageRect.Height); e.Graphics.DrawString(footerString, f, Brushes.Black, pageRect.Width / 2 - footerStringWidth / 2, pageRect.Height);
@ -224,9 +220,8 @@ namespace Greenshot.Helpers {
e.Graphics.DrawImage(image, printRect, imageRect, GraphicsUnit.Pixel); e.Graphics.DrawImage(image, printRect, imageRect, GraphicsUnit.Pixel);
} finally { } finally {
if (disposeImage && image != null) { if (disposeImage) {
image.Dispose(); image?.Dispose();
image = null;
} }
} }
} }
@ -234,14 +229,14 @@ namespace Greenshot.Helpers {
private void ApplyEffects(SurfaceOutputSettings printOutputSettings) { private void ApplyEffects(SurfaceOutputSettings printOutputSettings) {
// TODO: // TODO:
// add effects here // add effects here
if (conf.OutputPrintMonochrome) { if (CoreConfig.OutputPrintMonochrome) {
byte threshold = conf.OutputPrintMonochromeThreshold; byte threshold = CoreConfig.OutputPrintMonochromeThreshold;
printOutputSettings.Effects.Add(new MonochromeEffect(threshold)); printOutputSettings.Effects.Add(new MonochromeEffect(threshold));
printOutputSettings.ReduceColors = true; printOutputSettings.ReduceColors = true;
} }
// the invert effect should probably be the last // the invert effect should probably be the last
if (conf.OutputPrintInverted) { if (CoreConfig.OutputPrintInverted) {
printOutputSettings.Effects.Add(new InvertEffect()); printOutputSettings.Effects.Add(new InvertEffect());
} }
} }

View file

@ -36,10 +36,10 @@ namespace Greenshot.Helpers {
/// See: http://www.codeproject.com/KB/audio-video/soundplayerbug.aspx?msg=2487569 /// See: http://www.codeproject.com/KB/audio-video/soundplayerbug.aspx?msg=2487569
/// </summary> /// </summary>
public static class SoundHelper { public static class SoundHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(SoundHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(SoundHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static GCHandle? _gcHandle; private static GCHandle? _gcHandle;
private static byte[] _soundBuffer; private static byte[] _soundBuffer;
public static void Initialize() { public static void Initialize() {
if (_gcHandle == null) { if (_gcHandle == null) {
@ -47,49 +47,49 @@ namespace Greenshot.Helpers {
ResourceManager resources = new ResourceManager("Greenshot.Sounds", Assembly.GetExecutingAssembly()); ResourceManager resources = new ResourceManager("Greenshot.Sounds", Assembly.GetExecutingAssembly());
_soundBuffer = (byte[])resources.GetObject("camera"); _soundBuffer = (byte[])resources.GetObject("camera");
if (conf.NotificationSound != null && conf.NotificationSound.EndsWith(".wav")) { if (CoreConfig.NotificationSound != null && CoreConfig.NotificationSound.EndsWith(".wav")) {
try { try {
if (File.Exists(conf.NotificationSound)) { if (File.Exists(CoreConfig.NotificationSound)) {
_soundBuffer = File.ReadAllBytes(conf.NotificationSound); _soundBuffer = File.ReadAllBytes(CoreConfig.NotificationSound);
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.WarnFormat("couldn't load {0}: {1}", conf.NotificationSound, ex.Message); Log.WarnFormat("couldn't load {0}: {1}", CoreConfig.NotificationSound, ex.Message);
} }
} }
// Pin sound so it can't be moved by the Garbage Collector, this was the cause for the bad sound // Pin sound so it can't be moved by the Garbage Collector, this was the cause for the bad sound
_gcHandle = GCHandle.Alloc(_soundBuffer, GCHandleType.Pinned); _gcHandle = GCHandle.Alloc(_soundBuffer, GCHandleType.Pinned);
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error initializing.", e); Log.Error("Error initializing.", e);
} }
} }
} }
public static void Play() { public static void Play() {
if (_soundBuffer != null) { if (_soundBuffer != null) {
//Thread playSoundThread = new Thread(delegate() { //Thread playSoundThread = new Thread(delegate() {
SoundFlags flags = SoundFlags.SND_ASYNC | SoundFlags.SND_MEMORY | SoundFlags.SND_NOWAIT | SoundFlags.SND_NOSTOP; SoundFlags flags = SoundFlags.SND_ASYNC | SoundFlags.SND_MEMORY | SoundFlags.SND_NOWAIT | SoundFlags.SND_NOSTOP;
try { try {
WinMM.PlaySound(_gcHandle.Value.AddrOfPinnedObject(), (UIntPtr)0, (uint)flags); if (_gcHandle != null) WinMM.PlaySound(_gcHandle.Value.AddrOfPinnedObject(), (UIntPtr)0, (uint)flags);
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error in play.", e); Log.Error("Error in play.", e);
} }
//}); //});
//playSoundThread.Name = "Play camera sound"; //playSoundThread.Name = "Play camera sound";
//playSoundThread.IsBackground = true; //playSoundThread.IsBackground = true;
//playSoundThread.Start(); //playSoundThread.Start();
} }
} }
public static void Deinitialize() { public static void Deinitialize() {
try { try {
if (_gcHandle != null) { if (_gcHandle != null) {
WinMM.PlaySound((byte[])null, (UIntPtr)0, (uint)0); WinMM.PlaySound(null, (UIntPtr)0, 0);
_gcHandle.Value.Free(); _gcHandle.Value.Free();
_gcHandle = null; _gcHandle = null;
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error in deinitialize.", e); Log.Error("Error in deinitialize.", e);
} }
} }
} }
} }

View file

@ -29,12 +29,12 @@ namespace Greenshot.Helpers {
/// A helper class for the startup registry /// A helper class for the startup registry
/// </summary> /// </summary>
public static class StartupHelper { public static class StartupHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(StartupHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(StartupHelper));
private const string RUNKEY6432 = @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run"; private const string RunKey6432 = @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run";
private const string RUNKEY = @"Software\Microsoft\Windows\CurrentVersion\Run"; private const string RunKey = @"Software\Microsoft\Windows\CurrentVersion\Run";
private const string APPLICATIONNAME = "Greenshot"; private const string ApplicationName = "Greenshot";
private static string GetExecutablePath() { private static string GetExecutablePath() {
return "\"" + Application.ExecutablePath + "\""; return "\"" + Application.ExecutablePath + "\"";
@ -46,7 +46,8 @@ namespace Greenshot.Helpers {
/// <returns>true if Greenshot can write key</returns> /// <returns>true if Greenshot can write key</returns>
public static bool CanWriteRunAll() { public static bool CanWriteRunAll() {
try { try {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY, true)) { using (Registry.LocalMachine.OpenSubKey(RunKey, true))
{
} }
} catch { } catch {
return false; return false;
@ -60,7 +61,8 @@ namespace Greenshot.Helpers {
/// <returns>true if Greenshot can write key</returns> /// <returns>true if Greenshot can write key</returns>
public static bool CanWriteRunUser() { public static bool CanWriteRunUser() {
try { try {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, true)) { using (Registry.CurrentUser.OpenSubKey(RunKey, true))
{
} }
} catch { } catch {
return false; return false;
@ -72,24 +74,27 @@ namespace Greenshot.Helpers {
/// Return the RUN key value of the local machine /// Return the RUN key value of the local machine
/// </summary> /// </summary>
/// <returns>the RUN key value of the local machine</returns> /// <returns>the RUN key value of the local machine</returns>
public static Object GetRunAllValue() { public static object GetRunAllValue()
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY, false)) { {
if (key != null) { using (var key = Registry.LocalMachine.OpenSubKey(RunKey, false))
object runValue = key.GetValue(APPLICATIONNAME); {
if (runValue != null) { object runValue = key?.GetValue(ApplicationName);
return runValue; if (runValue != null)
} {
return runValue;
} }
} }
// for 64-bit systems we need to check the 32-bit keys too // for 64-bit systems we need to check the 32-bit keys too
if (IntPtr.Size == 8) { if (IntPtr.Size != 8)
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY6432, false)) { {
if (key != null) { return null;
object runValue = key.GetValue(APPLICATIONNAME); }
if (runValue != null) { using (var key = Registry.LocalMachine.OpenSubKey(RunKey6432, false))
return runValue; {
} object runValue = key?.GetValue(ApplicationName);
} if (runValue != null)
{
return runValue;
} }
} }
return null; return null;
@ -99,24 +104,22 @@ namespace Greenshot.Helpers {
/// Return the RUN key value of the current user /// Return the RUN key value of the current user
/// </summary> /// </summary>
/// <returns>the RUN key value of the current user</returns> /// <returns>the RUN key value of the current user</returns>
public static Object GetRunUserValue() { public static object GetRunUserValue() {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, false)) { using (var key = Registry.CurrentUser.OpenSubKey(RunKey, false)) {
if (key != null) { object runValue = key?.GetValue(ApplicationName);
object runValue = key.GetValue(APPLICATIONNAME); if (runValue != null) {
if (runValue != null) { return runValue;
return runValue;
}
} }
} }
// for 64-bit systems we need to check the 32-bit keys too // for 64-bit systems we need to check the 32-bit keys too
if (IntPtr.Size == 8) { if (IntPtr.Size != 8)
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY6432, false)) { {
if (key != null) { return null;
object runValue = key.GetValue(APPLICATIONNAME); }
if (runValue != null) { using (var key = Registry.CurrentUser.OpenSubKey(RunKey6432, false)) {
return runValue; object runValue = key?.GetValue(ApplicationName);
} if (runValue != null) {
} return runValue;
} }
} }
return null; return null;
@ -130,7 +133,7 @@ namespace Greenshot.Helpers {
try { try {
return GetRunAllValue() != null; return GetRunAllValue() != null;
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error retrieving RunAllValue", e); Log.Error("Error retrieving RunAllValue", e);
} }
return false; return false;
} }
@ -140,11 +143,11 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
/// <returns>true if there is a run key</returns> /// <returns>true if there is a run key</returns>
public static bool HasRunUser() { public static bool HasRunUser() {
Object runValue = null; object runValue = null;
try { try {
runValue = GetRunUserValue(); runValue = GetRunUserValue();
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error retrieving RunUserValue", e); Log.Error("Error retrieving RunUserValue", e);
} }
return runValue != null; return runValue != null;
} }
@ -153,24 +156,29 @@ namespace Greenshot.Helpers {
/// Delete the RUN key for the localmachine ("ALL") /// Delete the RUN key for the localmachine ("ALL")
/// </summary> /// </summary>
public static void DeleteRunAll() { public static void DeleteRunAll() {
if (HasRunAll()) { if (!HasRunAll())
try { {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY, true)) { return;
key.DeleteValue(APPLICATIONNAME); }
} try {
} catch (Exception e) { using (var key = Registry.LocalMachine.OpenSubKey(RunKey, true)) {
LOG.Error("Error in deleteRunAll.", e); key?.DeleteValue(ApplicationName);
} }
try { } catch (Exception e) {
// for 64-bit systems we need to delete the 32-bit keys too Log.Error("Error in deleteRunAll.", e);
if (IntPtr.Size == 8) { }
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(RUNKEY6432, false)) { try
key.DeleteValue(APPLICATIONNAME); {
} // for 64-bit systems we need to delete the 32-bit keys too
} if (IntPtr.Size != 8)
} catch (Exception e) { {
LOG.Error("Error in deleteRunAll.", e); return;
} }
using (var key = Registry.LocalMachine.OpenSubKey(RunKey6432, false)) {
key?.DeleteValue(ApplicationName);
}
} catch (Exception e) {
Log.Error("Error in deleteRunAll.", e);
} }
} }
@ -178,24 +186,29 @@ namespace Greenshot.Helpers {
/// Delete the RUN key for the current user /// Delete the RUN key for the current user
/// </summary> /// </summary>
public static void DeleteRunUser() { public static void DeleteRunUser() {
if (HasRunUser()) { if (!HasRunUser())
try { {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, true)) { return;
key.DeleteValue(APPLICATIONNAME); }
} try {
} catch (Exception e) { using (var key = Registry.CurrentUser.OpenSubKey(RunKey, true)) {
LOG.Error("Error in deleteRunUser.", e); key?.DeleteValue(ApplicationName);
} }
try { } catch (Exception e) {
// for 64-bit systems we need to delete the 32-bit keys too Log.Error("Error in deleteRunUser.", e);
if (IntPtr.Size == 8) { }
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY6432, false)) { try
key.DeleteValue(APPLICATIONNAME); {
} // for 64-bit systems we need to delete the 32-bit keys too
} if (IntPtr.Size != 8)
} catch (Exception e) { {
LOG.Error("Error in deleteRunUser.", e); return;
} }
using (var key = Registry.CurrentUser.OpenSubKey(RunKey6432, false)) {
key?.DeleteValue(ApplicationName);
}
} catch (Exception e) {
Log.Error("Error in deleteRunUser.", e);
} }
} }
@ -204,11 +217,12 @@ namespace Greenshot.Helpers {
/// </summary> /// </summary>
public static void SetRunUser() { public static void SetRunUser() {
try { try {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RUNKEY, true)) { using (var key = Registry.CurrentUser.OpenSubKey(RunKey, true))
key.SetValue(APPLICATIONNAME, GetExecutablePath()); {
key?.SetValue(ApplicationName, GetExecutablePath());
} }
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error in setRunUser.", e); Log.Error("Error in setRunUser.", e);
} }
} }
@ -221,19 +235,22 @@ namespace Greenshot.Helpers {
string lnkName = Path.GetFileNameWithoutExtension(Application.ExecutablePath) + ".lnk"; string lnkName = Path.GetFileNameWithoutExtension(Application.ExecutablePath) + ".lnk";
string startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup); string startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
if (Directory.Exists(startupPath)) { if (Directory.Exists(startupPath)) {
LOG.DebugFormat("Startup path: {0}", startupPath); Log.DebugFormat("Startup path: {0}", startupPath);
if (File.Exists(Path.Combine(startupPath, lnkName))) { if (File.Exists(Path.Combine(startupPath, lnkName))) {
return true; return true;
} }
} }
string startupAll = Environment.GetEnvironmentVariable("ALLUSERSPROFILE") + @"\Microsoft\Windows\Start Menu\Programs\Startup"; string startupAll = Environment.GetEnvironmentVariable("ALLUSERSPROFILE") + @"\Microsoft\Windows\Start Menu\Programs\Startup";
if (Directory.Exists(startupAll)) { if (Directory.Exists(startupAll)) {
LOG.DebugFormat("Startup all path: {0}", startupAll); Log.DebugFormat("Startup all path: {0}", startupAll);
if (File.Exists(Path.Combine(startupAll, lnkName))) { if (File.Exists(Path.Combine(startupAll, lnkName))) {
return true; return true;
} }
} }
} catch { }
catch
{
// ignored
} }
return false; return false;
} }

View file

@ -34,35 +34,37 @@ namespace Greenshot.Experimental {
/// Description of RssFeedHelper. /// Description of RssFeedHelper.
/// </summary> /// </summary>
public static class UpdateHelper { public static class UpdateHelper {
private static readonly ILog LOG = LogManager.GetLogger(typeof(UpdateHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(UpdateHelper));
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private const string STABLE_DOWNLOAD_LINK = "http://getgreenshot.org/downloads/"; private const string StableDownloadLink = "http://getgreenshot.org/downloads/";
private const string VERSION_HISTORY_LINK = "http://getgreenshot.org/version-history/"; private const string VersionHistoryLink = "http://getgreenshot.org/version-history/";
private static readonly object LockObject = new object(); private static readonly object LockObject = new object();
private static RssFile _latestGreenshot; private static RssFile _latestGreenshot;
private static string _downloadLink = STABLE_DOWNLOAD_LINK; private static string _downloadLink = StableDownloadLink;
/// <summary> /// <summary>
/// Is an update check needed? /// Is an update check needed?
/// </summary> /// </summary>
/// <returns>bool true if yes</returns> /// <returns>bool true if yes</returns>
public static bool IsUpdateCheckNeeded() { public static bool IsUpdateCheckNeeded() {
lock (LockObject) { lock (LockObject)
if (conf.UpdateCheckInterval == 0) { {
if (CoreConfig.UpdateCheckInterval == 0)
{
return false; return false;
} }
if (conf.LastUpdateCheck != null) { DateTime checkTime = CoreConfig.LastUpdateCheck;
DateTime checkTime = conf.LastUpdateCheck; checkTime = checkTime.AddDays(CoreConfig.UpdateCheckInterval);
checkTime = checkTime.AddDays(conf.UpdateCheckInterval); if (DateTime.Now.CompareTo(checkTime) < 0)
if (DateTime.Now.CompareTo(checkTime) < 0) { {
LOG.DebugFormat("No need to check RSS feed for updates, feed check will be after {0}", checkTime); Log.DebugFormat("No need to check RSS feed for updates, feed check will be after {0}", checkTime);
return false; return false;
} }
LOG.DebugFormat("Update check is due, last check was {0} check needs to be made after {1} (which is one {2} later)", conf.LastUpdateCheck, checkTime, conf.UpdateCheckInterval); Log.DebugFormat("Update check is due, last check was {0} check needs to be made after {1} (which is one {2} later)", CoreConfig.LastUpdateCheck, checkTime, CoreConfig.UpdateCheckInterval);
if (!RssHelper.IsRSSModifiedAfter(conf.LastUpdateCheck)) { if (!RssHelper.IsRssModifiedAfter(CoreConfig.LastUpdateCheck))
LOG.DebugFormat("RSS feed has not been updated since after {0}", conf.LastUpdateCheck); {
return false; Log.DebugFormat("RSS feed has not been updated since after {0}", CoreConfig.LastUpdateCheck);
} return false;
} }
} }
return true; return true;
@ -79,15 +81,15 @@ namespace Greenshot.Experimental {
try { try {
_latestGreenshot = null; _latestGreenshot = null;
ProcessRSSInfo(currentVersion); ProcessRssInfo(currentVersion);
if (_latestGreenshot != null) { if (_latestGreenshot != null) {
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick; MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick; MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info); MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"), ToolTipIcon.Info);
} }
conf.LastUpdateCheck = DateTime.Now; CoreConfig.LastUpdateCheck = DateTime.Now;
} catch (Exception e) { } catch (Exception e) {
LOG.Error("An error occured while checking for updates, the error will be ignored: ", e); Log.Error("An error occured while checking for updates, the error will be ignored: ", e);
} }
} }
} }
@ -112,9 +114,9 @@ namespace Greenshot.Experimental {
} }
} }
private static void ProcessRSSInfo(Version currentVersion) { private static void ProcessRssInfo(Version currentVersion) {
// Reset latest Greenshot // Reset latest Greenshot
IList<RssFile> rssFiles = RssHelper.readRSS(); IList<RssFile> rssFiles = RssHelper.ReadRss();
if (rssFiles == null) { if (rssFiles == null) {
return; return;
@ -124,29 +126,29 @@ namespace Greenshot.Experimental {
foreach(RssFile rssFile in rssFiles) { foreach(RssFile rssFile in rssFiles) {
if (rssFile.File.StartsWith("Greenshot")) { if (rssFile.File.StartsWith("Greenshot")) {
// check for exe // check for exe
if (!rssFile.isExe) { if (!rssFile.IsExe) {
continue; continue;
} }
// do we have a version? // do we have a version?
if (rssFile.Version == null) { if (rssFile.Version == null) {
LOG.DebugFormat("Skipping unversioned exe {0} which is published at {1} : {2}", rssFile.File, rssFile.Pubdate.ToLocalTime(), rssFile.Link); Log.DebugFormat("Skipping unversioned exe {0} which is published at {1} : {2}", rssFile.File, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
continue; continue;
} }
// if the file is unstable, we will skip it when: // if the file is unstable, we will skip it when:
// the current version is a release or release candidate AND check unstable is turned off. // the current version is a release or release candidate AND check unstable is turned off.
if (rssFile.isUnstable) { if (rssFile.IsUnstable) {
// Skip if we shouldn't check unstables // Skip if we shouldn't check unstables
if ((conf.BuildState == BuildStates.RELEASE) && !conf.CheckForUnstable) { if ((CoreConfig.BuildState == BuildStates.RELEASE) && !CoreConfig.CheckForUnstable) {
continue; continue;
} }
} }
// if the file is a release candidate, we will skip it when: // if the file is a release candidate, we will skip it when:
// the current version is a release AND check unstable is turned off. // the current version is a release AND check unstable is turned off.
if (rssFile.isReleaseCandidate) { if (rssFile.IsReleaseCandidate) {
if (conf.BuildState == BuildStates.RELEASE && !conf.CheckForUnstable) { if (CoreConfig.BuildState == BuildStates.RELEASE && !CoreConfig.CheckForUnstable) {
continue; continue;
} }
} }
@ -154,19 +156,19 @@ namespace Greenshot.Experimental {
// Compare versions // Compare versions
int versionCompare = rssFile.Version.CompareTo(currentVersion); int versionCompare = rssFile.Version.CompareTo(currentVersion);
if (versionCompare > 0) { if (versionCompare > 0) {
LOG.DebugFormat("Found newer Greenshot '{0}' with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link); Log.DebugFormat("Found newer Greenshot '{0}' with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
if (_latestGreenshot == null || rssFile.Version.CompareTo(_latestGreenshot.Version) > 0) { if (_latestGreenshot == null || rssFile.Version.CompareTo(_latestGreenshot.Version) > 0) {
_latestGreenshot = rssFile; _latestGreenshot = rssFile;
if (rssFile.isReleaseCandidate || rssFile.isUnstable) { if (rssFile.IsReleaseCandidate || rssFile.IsUnstable) {
_downloadLink = VERSION_HISTORY_LINK; _downloadLink = VersionHistoryLink;
} else { } else {
_downloadLink = STABLE_DOWNLOAD_LINK; _downloadLink = StableDownloadLink;
} }
} }
} else if (versionCompare < 0) { } else if (versionCompare < 0) {
LOG.DebugFormat("Skipping older greenshot with version {0}", rssFile.Version); Log.DebugFormat("Skipping older greenshot with version {0}", rssFile.Version);
} else if (versionCompare == 0) { } else if (versionCompare == 0) {
LOG.DebugFormat("Found current version as exe {0} with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link); Log.DebugFormat("Found current version as exe {0} with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
} }
} }
} }

View file

@ -24,13 +24,9 @@ using System.Windows.Forms;
namespace Greenshot.Helpers { namespace Greenshot.Helpers {
public class WindowWrapper : IWin32Window { public class WindowWrapper : IWin32Window {
public WindowWrapper(IntPtr handle) { public WindowWrapper(IntPtr handle) {
_hwnd = handle; Handle = handle;
} }
public IntPtr Handle { public IntPtr Handle { get; }
get { return _hwnd; }
}
private readonly IntPtr _hwnd;
} }
} }

View file

@ -46,10 +46,7 @@ namespace Greenshot.Memento
{ {
if (disposing) if (disposing)
{ {
if (_containerList != null) _containerList?.Dispose();
{
_containerList.Dispose();
}
} }
_containerList = null; _containerList = null;
_surface = null; _surface = null;
@ -62,9 +59,6 @@ namespace Greenshot.Memento
public IMemento Restore() public IMemento Restore()
{ {
// Store the selected state, as it's overwritten by the RemoveElement
bool selected = _containerList.Selected;
var oldState = new DeleteElementsMemento(_surface, _containerList); var oldState = new DeleteElementsMemento(_surface, _containerList);
_surface.RemoveElements(_containerList, false); _surface.RemoveElements(_containerList, false);

View file

@ -30,8 +30,8 @@ namespace Greenshot.Memento
public class ChangeFieldHolderMemento : IMemento public class ChangeFieldHolderMemento : IMemento
{ {
private IDrawableContainer _drawableContainer; private IDrawableContainer _drawableContainer;
private IField _fieldToBeChanged; private readonly IField _fieldToBeChanged;
private object _oldValue; private readonly object _oldValue;
public ChangeFieldHolderMemento(IDrawableContainer drawableContainer, IField fieldToBeChanged) public ChangeFieldHolderMemento(IDrawableContainer drawableContainer, IField fieldToBeChanged)
{ {
@ -49,10 +49,7 @@ namespace Greenshot.Memento
{ {
if (disposing) if (disposing)
{ {
if (_drawableContainer != null) _drawableContainer?.Dispose();
{
_drawableContainer.Dispose();
}
} }
_drawableContainer = null; _drawableContainer = null;
} }

View file

@ -46,10 +46,7 @@ namespace Greenshot.Memento
{ {
if (disposing) if (disposing)
{ {
if (_containerList != null) _containerList?.Dispose();
{
_containerList.Dispose();
}
} }
_containerList = null; _containerList = null;
_surface = null; _surface = null;

View file

@ -31,30 +31,32 @@ namespace Greenshot.Memento
/// </summary> /// </summary>
public class DrawableContainerBoundsChangeMemento : IMemento public class DrawableContainerBoundsChangeMemento : IMemento
{ {
private List<Point> points = new List<Point>(); private readonly List<Point> _points = new List<Point>();
private List<Size> sizes = new List<Size>(); private readonly List<Size> _sizes = new List<Size>();
private IDrawableContainerList listOfdrawableContainer; private IDrawableContainerList _listOfdrawableContainer;
private void StoreBounds() private void StoreBounds()
{ {
foreach (IDrawableContainer drawableContainer in listOfdrawableContainer) foreach (IDrawableContainer drawableContainer in _listOfdrawableContainer)
{ {
points.Add(drawableContainer.Location); _points.Add(drawableContainer.Location);
sizes.Add(drawableContainer.Size); _sizes.Add(drawableContainer.Size);
} }
} }
public DrawableContainerBoundsChangeMemento(IDrawableContainerList listOfdrawableContainer) public DrawableContainerBoundsChangeMemento(IDrawableContainerList listOfdrawableContainer)
{ {
this.listOfdrawableContainer = listOfdrawableContainer; _listOfdrawableContainer = listOfdrawableContainer;
StoreBounds(); StoreBounds();
} }
public DrawableContainerBoundsChangeMemento(IDrawableContainer drawableContainer) public DrawableContainerBoundsChangeMemento(IDrawableContainer drawableContainer)
{ {
listOfdrawableContainer = new DrawableContainerList(); _listOfdrawableContainer = new DrawableContainerList
listOfdrawableContainer.Add(drawableContainer); {
listOfdrawableContainer.Parent = drawableContainer.Parent; drawableContainer
};
_listOfdrawableContainer.Parent = drawableContainer.Parent;
StoreBounds(); StoreBounds();
} }
@ -67,12 +69,9 @@ namespace Greenshot.Memento
{ {
if (disposing) if (disposing)
{ {
if (listOfdrawableContainer != null) _listOfdrawableContainer?.Dispose();
{
listOfdrawableContainer.Dispose();
}
} }
listOfdrawableContainer = null; _listOfdrawableContainer = null;
} }
public bool Merge(IMemento otherMemento) public bool Merge(IMemento otherMemento)
@ -80,7 +79,7 @@ namespace Greenshot.Memento
var other = otherMemento as DrawableContainerBoundsChangeMemento; var other = otherMemento as DrawableContainerBoundsChangeMemento;
if (other != null) if (other != null)
{ {
if (ObjectExtensions.CompareLists<IDrawableContainer>(listOfdrawableContainer, other.listOfdrawableContainer)) if (ObjectExtensions.CompareLists(_listOfdrawableContainer, other._listOfdrawableContainer))
{ {
// Lists are equal, as we have the state already we can ignore the new memento // Lists are equal, as we have the state already we can ignore the new memento
return true; return true;
@ -91,16 +90,16 @@ namespace Greenshot.Memento
public IMemento Restore() public IMemento Restore()
{ {
var oldState = new DrawableContainerBoundsChangeMemento(listOfdrawableContainer); var oldState = new DrawableContainerBoundsChangeMemento(_listOfdrawableContainer);
for (int index = 0; index < listOfdrawableContainer.Count; index++) for (int index = 0; index < _listOfdrawableContainer.Count; index++)
{ {
IDrawableContainer drawableContainer = listOfdrawableContainer[index]; IDrawableContainer drawableContainer = _listOfdrawableContainer[index];
// Before // Before
drawableContainer.Invalidate(); drawableContainer.Invalidate();
drawableContainer.Left = points[index].X; drawableContainer.Left = _points[index].X;
drawableContainer.Top = points[index].Y; drawableContainer.Top = _points[index].Y;
drawableContainer.Width = sizes[index].Width; drawableContainer.Width = _sizes[index].Width;
drawableContainer.Height = sizes[index].Height; drawableContainer.Height = _sizes[index].Height;
// After // After
drawableContainer.Invalidate(); drawableContainer.Invalidate();
drawableContainer.Parent.Modified = true; drawableContainer.Parent.Modified = true;

View file

@ -68,7 +68,7 @@ namespace GreenshotBoxPlugin {
/// </summary> /// </summary>
/// <returns>bool true if OK was pressed, false if cancel</returns> /// <returns>bool true if OK was pressed, false if cancel</returns>
public bool ShowConfigDialog() { public bool ShowConfigDialog() {
DialogResult result = new SettingsForm(this).ShowDialog(); DialogResult result = new SettingsForm().ShowDialog();
if (result == DialogResult.OK) { if (result == DialogResult.OK) {
return true; return true;
} }

View file

@ -33,7 +33,7 @@ namespace GreenshotBoxPlugin {
/// Description of ImgurUtils. /// Description of ImgurUtils.
/// </summary> /// </summary>
public static class BoxUtils { public static class BoxUtils {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxUtils)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(BoxUtils));
private static readonly BoxConfiguration Config = IniConfig.GetIniSection<BoxConfiguration>(); private static readonly BoxConfiguration Config = IniConfig.GetIniSection<BoxConfiguration>();
private const string UploadFileUri = "https://upload.box.com/api/2.0/files/content"; private const string UploadFileUri = "https://upload.box.com/api/2.0/files/content";
private const string FilesUri = "https://www.box.com/api/2.0/files/{0}"; private const string FilesUri = "https://www.box.com/api/2.0/files/{0}";
@ -66,21 +66,23 @@ namespace GreenshotBoxPlugin {
public static string UploadToBox(SurfaceContainer image, string title, string filename) { public static string UploadToBox(SurfaceContainer image, string title, string filename) {
// Fill the OAuth2Settings // Fill the OAuth2Settings
OAuth2Settings settings = new OAuth2Settings(); var settings = new OAuth2Settings
{
AuthUrlPattern = "https://app.box.com/api/oauth2/authorize?client_id={ClientId}&response_type=code&state={State}&redirect_uri={RedirectUrl}",
TokenUrl = "https://api.box.com/oauth2/token",
CloudServiceName = "Box",
ClientId = BoxCredentials.ClientId,
ClientSecret = BoxCredentials.ClientSecret,
RedirectUrl = "https://www.box.com/home/",
BrowserSize = new Size(1060, 600),
AuthorizeMode = OAuth2AuthorizeMode.EmbeddedBrowser,
RefreshToken = Config.RefreshToken,
AccessToken = Config.AccessToken,
AccessTokenExpires = Config.AccessTokenExpires
};
settings.AuthUrlPattern = "https://app.box.com/api/oauth2/authorize?client_id={ClientId}&response_type=code&state={State}&redirect_uri={RedirectUrl}";
settings.TokenUrl = "https://api.box.com/oauth2/token";
settings.CloudServiceName = "Box";
settings.ClientId = BoxCredentials.ClientId;
settings.ClientSecret = BoxCredentials.ClientSecret;
settings.RedirectUrl = "https://www.box.com/home/";
settings.BrowserSize = new Size(1060, 600);
settings.AuthorizeMode = OAuth2AuthorizeMode.EmbeddedBrowser;
// Copy the settings from the config, which is kept in memory and on the disk // Copy the settings from the config, which is kept in memory and on the disk
settings.RefreshToken = Config.RefreshToken;
settings.AccessToken = Config.AccessToken;
settings.AccessTokenExpires = Config.AccessTokenExpires;
try { try {
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, UploadFileUri, settings); var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, UploadFileUri, settings);
@ -92,17 +94,17 @@ namespace GreenshotBoxPlugin {
var response = NetworkHelper.GetResponseAsString(webRequest); var response = NetworkHelper.GetResponseAsString(webRequest);
LOG.DebugFormat("Box response: {0}", response); Log.DebugFormat("Box response: {0}", response);
var upload = JsonSerializer.Deserialize<Upload>(response); var upload = JsonSerializer.Deserialize<Upload>(response);
if (upload == null || upload.Entries == null || upload.Entries.Count == 0) return null; if (upload?.Entries == null || upload.Entries.Count == 0) return null;
if (Config.UseSharedLink) { if (Config.UseSharedLink) {
string filesResponse = HttpPut(string.Format(FilesUri, upload.Entries[0].Id), "{\"shared_link\": {\"access\": \"open\"}}", settings); string filesResponse = HttpPut(string.Format(FilesUri, upload.Entries[0].Id), "{\"shared_link\": {\"access\": \"open\"}}", settings);
var file = JsonSerializer.Deserialize<FileEntry>(filesResponse); var file = JsonSerializer.Deserialize<FileEntry>(filesResponse);
return file.SharedLink.Url; return file.SharedLink.Url;
} }
return string.Format("http://www.box.com/files/0/f/0/1/f_{0}", upload.Entries[0].Id); return $"http://www.box.com/files/0/f/0/1/f_{upload.Entries[0].Id}";
} finally { } finally {
// Copy the settings back to the config, so they are stored. // Copy the settings back to the config, so they are stored.
Config.RefreshToken = settings.RefreshToken; Config.RefreshToken = settings.RefreshToken;

View file

@ -26,7 +26,7 @@ namespace GreenshotBoxPlugin {
/// Description of PasswordRequestForm. /// Description of PasswordRequestForm.
/// </summary> /// </summary>
public partial class SettingsForm : BoxForm { public partial class SettingsForm : BoxForm {
public SettingsForm(BoxConfiguration config) { public SettingsForm() {
// //
// The InitializeComponent() call is required for Windows Forms designer support. // The InitializeComponent() call is required for Windows Forms designer support.
// //

View file

@ -222,19 +222,17 @@ namespace Confluence {
} }
} }
public bool IsLoggedIn { public bool IsLoggedIn => _loggedIn;
get {
return _loggedIn;
}
}
public void AddAttachment(long pageId, string mime, string comment, string filename, IBinaryContainer image) { public void AddAttachment(long pageId, string mime, string comment, string filename, IBinaryContainer image) {
CheckCredentials(); CheckCredentials();
RemoteAttachment attachment = new RemoteAttachment();
// Comment is ignored, see: http://jira.atlassian.com/browse/CONF-9395 // Comment is ignored, see: http://jira.atlassian.com/browse/CONF-9395
attachment.comment = comment; var attachment = new RemoteAttachment
attachment.fileName = filename; {
attachment.contentType = mime; comment = comment,
fileName = filename,
contentType = mime
};
_confluence.addAttachment(_credentials, pageId, attachment, image.ToByteArray()); _confluence.addAttachment(_credentials, pageId, attachment, image.ToByteArray());
} }
@ -284,7 +282,6 @@ namespace Confluence {
public IEnumerable<Page> GetPageChildren(Page parentPage) { public IEnumerable<Page> GetPageChildren(Page parentPage) {
CheckCredentials(); CheckCredentials();
List<Page> returnPages = new List<Page>();
RemotePageSummary[] pages = _confluence.getChildren(_credentials, parentPage.Id); RemotePageSummary[] pages = _confluence.getChildren(_credentials, parentPage.Id);
foreach(RemotePageSummary page in pages) { foreach(RemotePageSummary page in pages) {
yield return new Page(page); yield return new Page(page);

View file

@ -84,15 +84,15 @@ namespace GreenshotConfluencePlugin {
} }
} }
public override bool isDynamic { public override bool IsDynamic {
get { get {
return true; return true;
} }
} }
public override bool isActive { public override bool IsActive {
get { get {
return base.isActive && !string.IsNullOrEmpty(ConfluenceConfig.Url); return base.IsActive && !string.IsNullOrEmpty(ConfluenceConfig.Url);
} }
} }
@ -127,7 +127,7 @@ namespace GreenshotConfluencePlugin {
string filename = FilenameHelper.GetFilenameWithoutExtensionFromPattern(CoreConfig.OutputFileFilenamePattern, captureDetails); string filename = FilenameHelper.GetFilenameWithoutExtensionFromPattern(CoreConfig.OutputFileFilenamePattern, captureDetails);
if (selectedPage == null) { if (selectedPage == null) {
ConfluenceUpload confluenceUpload = new ConfluenceUpload(filename); ConfluenceUpload confluenceUpload = new ConfluenceUpload(filename);
Nullable<bool> dialogResult = confluenceUpload.ShowDialog(); bool? dialogResult = confluenceUpload.ShowDialog();
if (dialogResult.HasValue && dialogResult.Value) { if (dialogResult.HasValue && dialogResult.Value) {
selectedPage = confluenceUpload.SelectedPage; selectedPage = confluenceUpload.SelectedPage;
if (confluenceUpload.IsOpenPageSelected) { if (confluenceUpload.IsOpenPageSelected) {

View file

@ -124,7 +124,7 @@ namespace GreenshotConfluencePlugin {
ConfluenceConfiguration clonedConfig = _config.Clone(); ConfluenceConfiguration clonedConfig = _config.Clone();
ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig); ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig);
string url = _config.Url; string url = _config.Url;
Nullable<bool> dialogResult = configForm.ShowDialog(); bool? dialogResult = configForm.ShowDialog();
if (dialogResult.HasValue && dialogResult.Value) { if (dialogResult.HasValue && dialogResult.Value) {
// copy the new object to the old... // copy the new object to the old...
clonedConfig.CloneTo(_config); clonedConfig.CloneTo(_config);

View file

@ -95,7 +95,6 @@ namespace GreenshotConfluencePlugin {
pages.Add(page); pages.Add(page);
} }
continue;
} catch (Exception ex) { } catch (Exception ex) {
// Preventing security problems // Preventing security problems
LOG.DebugFormat("Couldn't get page details for space {0} / title {1}", space, title); LOG.DebugFormat("Couldn't get page details for space {0} / title {1}", space, title);
@ -133,7 +132,7 @@ namespace GreenshotConfluencePlugin {
if (pattern.ProgrammaticName != "ValuePatternIdentifiers.Pattern") { if (pattern.ProgrammaticName != "ValuePatternIdentifiers.Pattern") {
continue; continue;
} }
string url = (docElement.GetCurrentPattern(pattern) as ValuePattern).Current.Value.ToString(); string url = (docElement.GetCurrentPattern(pattern) as ValuePattern).Current.Value;
if (!string.IsNullOrEmpty(url)) { if (!string.IsNullOrEmpty(url)) {
urls.Add(url); urls.Add(url);
break; break;

View file

@ -30,11 +30,9 @@ using GreenshotPlugin.Core;
namespace GreenshotConfluencePlugin { namespace GreenshotConfluencePlugin {
public class EnumDisplayer : IValueConverter { public class EnumDisplayer : IValueConverter {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(EnumDisplayer)); private Type _type;
private IDictionary _displayValues;
private Type type; private IDictionary _reverseValues;
private IDictionary displayValues;
private IDictionary reverseValues;
public EnumDisplayer() { public EnumDisplayer() {
} }
@ -44,22 +42,30 @@ namespace GreenshotConfluencePlugin {
} }
public Type Type { public Type Type {
get { return type; } get { return _type; }
set { set {
if (!value.IsEnum) { if (!value.IsEnum) {
throw new ArgumentException("parameter is not an Enumerated type", "value"); throw new ArgumentException("parameter is not an Enumerated type", nameof(value));
} }
type = value; _type = value;
} }
} }
public ReadOnlyCollection<string> DisplayNames { public ReadOnlyCollection<string> DisplayNames {
get { get {
reverseValues = (IDictionary) Activator.CreateInstance(typeof(Dictionary<,>).GetGenericTypeDefinition().MakeGenericType(typeof(string),type)); var genericTypeDefinition = typeof(Dictionary<,>).GetGenericTypeDefinition();
if (genericTypeDefinition != null)
{
_reverseValues = (IDictionary) Activator.CreateInstance(genericTypeDefinition.MakeGenericType(typeof(string),_type));
}
displayValues = (IDictionary)Activator.CreateInstance(typeof(Dictionary<,>).GetGenericTypeDefinition().MakeGenericType(type, typeof(string))); var typeDefinition = typeof(Dictionary<,>).GetGenericTypeDefinition();
if (typeDefinition != null)
{
_displayValues = (IDictionary)Activator.CreateInstance(typeDefinition.MakeGenericType(_type, typeof(string)));
}
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); var fields = _type.GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (var field in fields) { foreach (var field in fields) {
DisplayKeyAttribute[] a = (DisplayKeyAttribute[])field.GetCustomAttributes(typeof(DisplayKeyAttribute), false); DisplayKeyAttribute[] a = (DisplayKeyAttribute[])field.GetCustomAttributes(typeof(DisplayKeyAttribute), false);
@ -67,25 +73,19 @@ namespace GreenshotConfluencePlugin {
object enumValue = field.GetValue(null); object enumValue = field.GetValue(null);
string displayString; string displayString;
if (displayKey != null && Language.hasKey(displayKey)) { if (displayKey != null && Language.HasKey(displayKey)) {
displayString = Language.GetString(displayKey); displayString = Language.GetString(displayKey);
} }
if (displayKey != null) { displayString = displayKey ?? enumValue.ToString();
displayString = displayKey;
} else {
displayString = enumValue.ToString();
}
if (displayString != null) { _displayValues.Add(enumValue, displayString);
displayValues.Add(enumValue, displayString); _reverseValues.Add(displayString, enumValue);
reverseValues.Add(displayString, enumValue);
}
} }
return new List<string>((IEnumerable<string>)displayValues.Values).AsReadOnly(); return new List<string>((IEnumerable<string>)_displayValues.Values).AsReadOnly();
} }
} }
private string GetDisplayKeyValue(DisplayKeyAttribute[] a) { private static string GetDisplayKeyValue(DisplayKeyAttribute[] a) {
if (a == null || a.Length == 0) { if (a == null || a.Length == 0) {
return null; return null;
} }
@ -94,11 +94,11 @@ namespace GreenshotConfluencePlugin {
} }
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) {
return displayValues[value]; return _displayValues[value];
} }
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
return reverseValues[value]; return _reverseValues[value];
} }
} }
} }

View file

@ -26,16 +26,11 @@ namespace GreenshotConfluencePlugin {
/// Interaction logic for ConfluenceConfigurationForm.xaml /// Interaction logic for ConfluenceConfigurationForm.xaml
/// </summary> /// </summary>
public partial class ConfluenceConfigurationForm : Window { public partial class ConfluenceConfigurationForm : Window {
private readonly ConfluenceConfiguration config; public ConfluenceConfiguration Config { get; }
public ConfluenceConfiguration Config {
get {
return config;
}
}
public ConfluenceConfigurationForm(ConfluenceConfiguration config) { public ConfluenceConfigurationForm(ConfluenceConfiguration config) {
DataContext = config; DataContext = config;
this.config = config; Config = config;
InitializeComponent(); InitializeComponent();
} }

View file

@ -26,12 +26,12 @@ namespace GreenshotConfluencePlugin {
/// <summary> /// <summary>
/// Interaction logic for ConfluencePagePicker.xaml /// Interaction logic for ConfluencePagePicker.xaml
/// </summary> /// </summary>
public partial class ConfluencePagePicker : System.Windows.Controls.Page { public partial class ConfluencePagePicker
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ConfluencePagePicker)); {
private readonly ConfluenceUpload confluenceUpload = null; private readonly ConfluenceUpload _confluenceUpload;
public ConfluencePagePicker(ConfluenceUpload confluenceUpload, List<Page> pagesToPick) { public ConfluencePagePicker(ConfluenceUpload confluenceUpload, List<Page> pagesToPick) {
this.confluenceUpload = confluenceUpload; _confluenceUpload = confluenceUpload;
DataContext = pagesToPick; DataContext = pagesToPick;
InitializeComponent(); InitializeComponent();
} }
@ -42,11 +42,11 @@ namespace GreenshotConfluencePlugin {
private void SelectionChanged() { private void SelectionChanged() {
if (PageListView.HasItems && PageListView.SelectedItems.Count > 0) { if (PageListView.HasItems && PageListView.SelectedItems.Count > 0) {
confluenceUpload.SelectedPage = (Page)PageListView.SelectedItem; _confluenceUpload.SelectedPage = (Page)PageListView.SelectedItem;
// Make sure the uploader knows we selected an already opened page // Make sure the uploader knows we selected an already opened page
confluenceUpload.IsOpenPageSelected = true; _confluenceUpload.IsOpenPageSelected = true;
} else { } else {
confluenceUpload.SelectedPage = null; _confluenceUpload.SelectedPage = null;
} }
} }

View file

@ -26,7 +26,7 @@ namespace TranslationByMarkupExtension
manager.LanguageChanged += OnLanguageChanged; manager.LanguageChanged += OnLanguageChanged;
} }
protected override void StopListening(Object source) protected override void StopListening(object source)
{ {
var manager = (TranslationManager)source; var manager = (TranslationManager)source;
manager.LanguageChanged -= OnLanguageChanged; manager.LanguageChanged -= OnLanguageChanged;

View file

@ -1,38 +1,30 @@
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
namespace TranslationByMarkupExtension { namespace TranslationByMarkupExtension {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class LanguageXMLTranslationProvider : ITranslationProvider { public class LanguageXMLTranslationProvider : ITranslationProvider {
#region Private Members #region Private Members
#endregion #endregion
#region Construction #region Construction
/// <summary> #endregion
/// Initializes a new instance of the <see cref="ResxTranslationProvider"/> class.
/// </summary>
/// <param name="baseName">Name of the base.</param>
/// <param name="assembly">The assembly.</param>
public LanguageXMLTranslationProvider() {
}
#endregion #region ITranslationProvider Members
#region ITranslationProvider Members /// <summary>
/// See <see cref="ITranslationProvider.Translate" />
/// <summary> /// </summary>
/// See <see cref="ITranslationProvider.Translate" /> public object Translate(string key) {
/// </summary> if (Language.HasKey("confluence", key)) {
public object Translate(string key) {
if (Language.hasKey("confluence", key)) {
return Language.GetString("confluence", key); return Language.GetString("confluence", key);
} }
return key; return key;
} }
#endregion #endregion
} }
} }

View file

@ -3,62 +3,55 @@ using System.ComponentModel;
using System.Windows; using System.Windows;
namespace TranslationByMarkupExtension { namespace TranslationByMarkupExtension {
public class TranslationData : IWeakEventListener, INotifyPropertyChanged { public class TranslationData : IWeakEventListener, INotifyPropertyChanged {
#region Private Members #region Private Members
private readonly string _key; private readonly string _key;
#endregion #endregion
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="TranslationData"/> class. /// Initializes a new instance of the <see cref="TranslationData"/> class.
/// </summary> /// </summary>
/// <param name="key">The key.</param> /// <param name="key">The key.</param>
public TranslationData( string key) { public TranslationData( string key) {
_key = key; _key = key;
LanguageChangedEventManager.AddListener(TranslationManager.Instance, this); LanguageChangedEventManager.AddListener(TranslationManager.Instance, this);
} }
/// <summary> /// <summary>
/// Releases unmanaged resources and performs other cleanup operations before the /// Releases unmanaged resources and performs other cleanup operations before the
/// <see cref="TranslationData"/> is reclaimed by garbage collection. /// <see cref="TranslationData"/> is reclaimed by garbage collection.
/// </summary> /// </summary>
~TranslationData() { ~TranslationData() {
LanguageChangedEventManager.RemoveListener(TranslationManager.Instance, this); LanguageChangedEventManager.RemoveListener(TranslationManager.Instance, this);
} }
public object Value { public object Value => TranslationManager.Instance.Translate(_key);
get {
return TranslationManager.Instance.Translate(_key);
}
}
#region IWeakEventListener Members #region IWeakEventListener Members
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{ {
if (managerType == typeof(LanguageChangedEventManager)) if (managerType == typeof(LanguageChangedEventManager))
{ {
OnLanguageChanged(sender, e); OnLanguageChanged(sender, e);
return true; return true;
} }
return false; return false;
} }
private void OnLanguageChanged(object sender, EventArgs e) private void OnLanguageChanged(object sender, EventArgs e)
{ {
if( PropertyChanged != null ) PropertyChanged?.Invoke( this, new PropertyChangedEventArgs("Value"));
{ }
PropertyChanged( this, new PropertyChangedEventArgs("Value"));
}
}
#endregion #endregion
#region INotifyPropertyChanged Members #region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
#endregion #endregion
} }
} }

View file

@ -1,55 +1,45 @@
using System; using System;
namespace TranslationByMarkupExtension { namespace TranslationByMarkupExtension {
public class TranslationManager { public class TranslationManager {
private static TranslationManager _translationManager; private static TranslationManager _translationManager;
public event EventHandler LanguageChanged; public event EventHandler LanguageChanged;
/*public CultureInfo CurrentLanguage { /*public CultureInfo CurrentLanguage {
get { return Thread.CurrentThread.CurrentUICulture; } get { return Thread.CurrentThread.CurrentUICulture; }
set { set {
if( value != Thread.CurrentThread.CurrentUICulture) { if( value != Thread.CurrentThread.CurrentUICulture) {
Thread.CurrentThread.CurrentUICulture = value; Thread.CurrentThread.CurrentUICulture = value;
OnLanguageChanged(); OnLanguageChanged();
}
}
}
public IEnumerable<CultureInfo> Languages {
get {
if( TranslationProvider != null) {
return TranslationProvider.Languages;
}
return Enumerable.Empty<CultureInfo>();
}
}*/
public static TranslationManager Instance {
get {
if (_translationManager == null) {
_translationManager = new TranslationManager();
} }
return _translationManager; }
} }
}
public ITranslationProvider TranslationProvider { get; set; } public IEnumerable<CultureInfo> Languages {
get {
if( TranslationProvider != null) {
return TranslationProvider.Languages;
}
return Enumerable.Empty<CultureInfo>();
}
}*/
private void OnLanguageChanged() { public static TranslationManager Instance => _translationManager ?? (_translationManager = new TranslationManager());
if (LanguageChanged != null) {
LanguageChanged(this, EventArgs.Empty);
}
}
public object Translate(string key) { public ITranslationProvider TranslationProvider { get; set; }
if( TranslationProvider != null) {
object translatedValue = TranslationProvider.Translate(key); private void OnLanguageChanged()
if( translatedValue != null) { {
return translatedValue; LanguageChanged?.Invoke(this, EventArgs.Empty);
} }
}
return string.Format("!{0}!", key); public object Translate(string key) {
} object translatedValue = TranslationProvider?.Translate(key);
} if( translatedValue != null) {
return translatedValue;
}
return $"!{key}!";
}
}
} }

View file

@ -23,27 +23,19 @@ using System.Drawing;
using Greenshot.IniFile; using Greenshot.IniFile;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
namespace GreenshotDropboxPlugin { namespace GreenshotDropboxPlugin {
internal class DropboxDestination : AbstractDestination { internal class DropboxDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(DropboxDestination)); private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
private static readonly DropboxPluginConfiguration config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
private readonly DropboxPlugin plugin = null; private readonly DropboxPlugin _plugin;
public DropboxDestination(DropboxPlugin plugin) { public DropboxDestination(DropboxPlugin plugin) {
this.plugin = plugin; _plugin = plugin;
} }
public override string Designation { public override string Designation => "Dropbox";
get {
return "Dropbox";
}
}
public override string Description { public override string Description => Language.GetString("dropbox", LangKey.upload_menu_item);
get {
return Language.GetString("dropbox", LangKey.upload_menu_item);
}
}
public override Image DisplayIcon { public override Image DisplayIcon {
get { get {
@ -55,11 +47,11 @@ namespace GreenshotDropboxPlugin {
public override ExportInformation ExportCapture(bool manually, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manually, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
string uploadUrl; string uploadUrl;
bool uploaded = plugin.Upload(captureDetails, surface, out uploadUrl); bool uploaded = _plugin.Upload(captureDetails, surface, out uploadUrl);
if (uploaded) { if (uploaded) {
exportInformation.Uri = uploadUrl; exportInformation.Uri = uploadUrl;
exportInformation.ExportMade = true; exportInformation.ExportMade = true;
if (config.AfterUploadLinkToClipBoard) { if (DropboxConfig.AfterUploadLinkToClipBoard) {
ClipboardHelper.SetClipboardData(uploadUrl); ClipboardHelper.SetClipboardData(uploadUrl);
} }
} }

View file

@ -55,9 +55,6 @@ namespace GreenshotDropboxPlugin {
} }
} }
public DropboxPlugin() {
}
public IEnumerable<IDestination> Destinations() { public IEnumerable<IDestination> Destinations() {
yield return new DropboxDestination(this); yield return new DropboxDestination(this);
} }
@ -123,7 +120,8 @@ namespace GreenshotDropboxPlugin {
try { try {
string dropboxUrl = null; string dropboxUrl = null;
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("dropbox", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("dropbox", LangKey.communication_wait),
delegate() { delegate
{
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails)); string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
dropboxUrl = DropboxUtils.UploadToDropbox(surfaceToUpload, outputSettings, filename); dropboxUrl = DropboxUtils.UploadToDropbox(surfaceToUpload, outputSettings, filename);
} }

View file

@ -30,36 +30,38 @@ namespace GreenshotDropboxPlugin {
/// Description of DropboxUtils. /// Description of DropboxUtils.
/// </summary> /// </summary>
public class DropboxUtils { public class DropboxUtils {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(DropboxUtils)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxUtils));
private static readonly DropboxPluginConfiguration config = IniConfig.GetIniSection<DropboxPluginConfiguration>(); private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
private DropboxUtils() { private DropboxUtils() {
} }
public static string UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string filename) { public static string UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string filename) {
OAuthSession oAuth = new OAuthSession(DropBoxCredentials.CONSUMER_KEY, DropBoxCredentials.CONSUMER_SECRET); var oAuth = new OAuthSession(DropBoxCredentials.CONSUMER_KEY, DropBoxCredentials.CONSUMER_SECRET)
oAuth.BrowserSize = new Size(1080, 650); {
oAuth.CheckVerifier = false; BrowserSize = new Size(1080, 650),
oAuth.AccessTokenUrl = "https://api.dropbox.com/1/oauth/access_token"; CheckVerifier = false,
oAuth.AuthorizeUrl = "https://api.dropbox.com/1/oauth/authorize"; AccessTokenUrl = "https://api.dropbox.com/1/oauth/access_token",
oAuth.RequestTokenUrl = "https://api.dropbox.com/1/oauth/request_token"; AuthorizeUrl = "https://api.dropbox.com/1/oauth/authorize",
oAuth.LoginTitle = "Dropbox authorization"; RequestTokenUrl = "https://api.dropbox.com/1/oauth/request_token",
oAuth.Token = config.DropboxToken; LoginTitle = "Dropbox authorization",
oAuth.TokenSecret = config.DropboxTokenSecret; Token = DropboxConfig.DropboxToken,
TokenSecret = DropboxConfig.DropboxTokenSecret
};
try { try {
SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename); SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
string uploadResponse = oAuth.MakeOAuthRequest(HTTPMethod.POST, "https://api-content.dropbox.com/1/files_put/sandbox/" + OAuthSession.UrlEncode3986(filename), null, null, imageToUpload); string uploadResponse = oAuth.MakeOAuthRequest(HTTPMethod.POST, "https://api-content.dropbox.com/1/files_put/sandbox/" + OAuthSession.UrlEncode3986(filename), null, null, imageToUpload);
LOG.DebugFormat("Upload response: {0}", uploadResponse); Log.DebugFormat("Upload response: {0}", uploadResponse);
} catch (Exception ex) { } catch (Exception ex) {
LOG.Error("Upload error: ", ex); Log.Error("Upload error: ", ex);
throw; throw;
} finally { } finally {
if (!string.IsNullOrEmpty(oAuth.Token)) { if (!string.IsNullOrEmpty(oAuth.Token)) {
config.DropboxToken = oAuth.Token; DropboxConfig.DropboxToken = oAuth.Token;
} }
if (!string.IsNullOrEmpty(oAuth.TokenSecret)) { if (!string.IsNullOrEmpty(oAuth.TokenSecret)) {
config.DropboxTokenSecret = oAuth.TokenSecret; DropboxConfig.DropboxTokenSecret = oAuth.TokenSecret;
} }
} }
@ -67,16 +69,16 @@ namespace GreenshotDropboxPlugin {
try { try {
string responseString = oAuth.MakeOAuthRequest(HTTPMethod.GET, "https://api.dropbox.com/1/shares/sandbox/" + OAuthSession.UrlEncode3986(filename), null, null, null); string responseString = oAuth.MakeOAuthRequest(HTTPMethod.GET, "https://api.dropbox.com/1/shares/sandbox/" + OAuthSession.UrlEncode3986(filename), null, null, null);
if (responseString != null) { if (responseString != null) {
LOG.DebugFormat("Parsing output: {0}", responseString); Log.DebugFormat("Parsing output: {0}", responseString);
IDictionary<string, object> returnValues = JSONHelper.JsonDecode(responseString); IDictionary<string, object> returnValues = JSONHelper.JsonDecode(responseString);
if (returnValues.ContainsKey("url")) { if (returnValues.ContainsKey("url")) {
return returnValues["url"] as string; return returnValues["url"] as string;
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.Error("Can't parse response.", ex); Log.Error("Can't parse response.", ex);
} }
return null; return null;
} }
} }
} }

View file

@ -20,16 +20,12 @@
*/ */
using GreenshotDropboxPlugin.Forms; using GreenshotDropboxPlugin.Forms;
using Greenshot.IniFile;
namespace GreenshotDropboxPlugin { namespace GreenshotDropboxPlugin {
/// <summary> /// <summary>
/// Description of PasswordRequestForm. /// Description of PasswordRequestForm.
/// </summary> /// </summary>
public partial class SettingsForm : DropboxForm { public partial class SettingsForm : DropboxForm {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(SettingsForm));
private static DropboxPluginConfiguration config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
public SettingsForm() { public SettingsForm() {
// //
// The InitializeComponent() call is required for Windows Forms designer support. // The InitializeComponent() call is required for Windows Forms designer support.

View file

@ -31,8 +31,8 @@ namespace ExternalCommand {
/// Description of SettingsFormDetail. /// Description of SettingsFormDetail.
/// </summary> /// </summary>
public partial class SettingsFormDetail : ExternalCommandForm { public partial class SettingsFormDetail : ExternalCommandForm {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(SettingsFormDetail)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(SettingsFormDetail));
private static readonly ExternalCommandConfiguration config = IniConfig.GetIniSection<ExternalCommandConfiguration>(); private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
private readonly string _commando; private readonly string _commando;
private readonly int _commandIndex; private readonly int _commandIndex;
@ -45,9 +45,9 @@ namespace ExternalCommand {
if(commando != null) { if(commando != null) {
textBox_name.Text = commando; textBox_name.Text = commando;
textBox_commandline.Text = config.Commandline[commando]; textBox_commandline.Text = ExternalCommandConfig.Commandline[commando];
textBox_arguments.Text = config.Argument[commando]; textBox_arguments.Text = ExternalCommandConfig.Argument[commando];
_commandIndex = config.Commands.FindIndex(delegate(string s) { return s == commando; }); _commandIndex = ExternalCommandConfig.Commands.FindIndex(s => s == commando);
} else { } else {
textBox_arguments.Text = "\"{0}\""; textBox_arguments.Text = "\"{0}\"";
} }
@ -59,15 +59,15 @@ namespace ExternalCommand {
string commandLine = textBox_commandline.Text; string commandLine = textBox_commandline.Text;
string arguments = textBox_arguments.Text; string arguments = textBox_arguments.Text;
if(_commando != null) { if(_commando != null) {
config.Commands[_commandIndex] = commandName; ExternalCommandConfig.Commands[_commandIndex] = commandName;
config.Commandline.Remove(_commando); ExternalCommandConfig.Commandline.Remove(_commando);
config.Commandline.Add(commandName, commandLine); ExternalCommandConfig.Commandline.Add(commandName, commandLine);
config.Argument.Remove(_commando); ExternalCommandConfig.Argument.Remove(_commando);
config.Argument.Add(commandName, arguments); ExternalCommandConfig.Argument.Add(commandName, arguments);
} else { } else {
config.Commands.Add(commandName); ExternalCommandConfig.Commands.Add(commandName);
config.Commandline.Add(commandName, commandLine); ExternalCommandConfig.Commandline.Add(commandName, commandLine);
config.Argument.Add(commandName, arguments); ExternalCommandConfig.Argument.Add(commandName, arguments);
} }
} }
@ -86,8 +86,8 @@ namespace ExternalCommand {
} }
catch (Exception ex) catch (Exception ex)
{ {
LOG.WarnFormat("Can't get the initial path via {0}", textBox_commandline.Text); Log.WarnFormat("Can't get the initial path via {0}", textBox_commandline.Text);
LOG.Warn("Exception: ", ex); Log.Warn("Exception: ", ex);
} }
if(initialPath != null && Directory.Exists(initialPath)) { if(initialPath != null && Directory.Exists(initialPath)) {
openFileDialog.InitialDirectory = initialPath; openFileDialog.InitialDirectory = initialPath;
@ -95,7 +95,7 @@ namespace ExternalCommand {
initialPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); initialPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
openFileDialog.InitialDirectory = initialPath; openFileDialog.InitialDirectory = initialPath;
} }
LOG.DebugFormat("Starting OpenFileDialog at {0}", initialPath); Log.DebugFormat("Starting OpenFileDialog at {0}", initialPath);
if(openFileDialog.ShowDialog() == DialogResult.OK) { if(openFileDialog.ShowDialog() == DialogResult.OK) {
textBox_commandline.Text = openFileDialog.FileName; textBox_commandline.Text = openFileDialog.FileName;
} }
@ -112,7 +112,7 @@ namespace ExternalCommand {
buttonOk.Enabled = false; buttonOk.Enabled = false;
} }
// Check if commandname is unique // Check if commandname is unique
if(_commando == null && !string.IsNullOrEmpty(textBox_name.Text) && config.Commands.Contains(textBox_name.Text)) { if(_commando == null && !string.IsNullOrEmpty(textBox_name.Text) && ExternalCommandConfig.Commands.Contains(textBox_name.Text)) {
buttonOk.Enabled = false; buttonOk.Enabled = false;
textBox_name.BackColor = Color.Red; textBox_name.BackColor = Color.Red;
} }

View file

@ -70,7 +70,7 @@ namespace GreenshotFlickrPlugin {
/// </summary> /// </summary>
/// <returns>bool true if OK was pressed, false if cancel</returns> /// <returns>bool true if OK was pressed, false if cancel</returns>
public bool ShowConfigDialog() { public bool ShowConfigDialog() {
DialogResult result = new SettingsForm(this).ShowDialog(); DialogResult result = new SettingsForm().ShowDialog();
if (result == DialogResult.OK) { if (result == DialogResult.OK) {
return true; return true;
} }

View file

@ -22,27 +22,17 @@ using System.ComponentModel;
using System.Drawing; using System.Drawing;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using log4net;
namespace GreenshotFlickrPlugin { namespace GreenshotFlickrPlugin {
public class FlickrDestination : AbstractDestination { public class FlickrDestination : AbstractDestination {
private static ILog LOG = LogManager.GetLogger(typeof(FlickrDestination)); private readonly FlickrPlugin _plugin;
private readonly FlickrPlugin plugin;
public FlickrDestination(FlickrPlugin plugin) { public FlickrDestination(FlickrPlugin plugin) {
this.plugin = plugin; _plugin = plugin;
} }
public override string Designation { public override string Designation => "Flickr";
get {
return "Flickr";
}
}
public override string Description { public override string Description => Language.GetString("flickr", LangKey.upload_menu_item);
get {
return Language.GetString("flickr", LangKey.upload_menu_item);
}
}
public override Image DisplayIcon { public override Image DisplayIcon {
get { get {
@ -53,11 +43,11 @@ namespace GreenshotFlickrPlugin {
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
string uploadURL; string uploadUrl;
bool uploaded = plugin.Upload(captureDetails, surface, out uploadURL); bool uploaded = _plugin.Upload(captureDetails, surface, out uploadUrl);
if (uploaded) { if (uploaded) {
exportInformation.ExportMade = true; exportInformation.ExportMade = true;
exportInformation.Uri = uploadURL; exportInformation.Uri = uploadUrl;
} }
ProcessExport(exportInformation, surface); ProcessExport(exportInformation, surface);
return exportInformation; return exportInformation;

View file

@ -37,7 +37,7 @@ namespace GreenshotFlickrPlugin
/// This is the Flickr base code /// This is the Flickr base code
/// </summary> /// </summary>
public class FlickrPlugin : IGreenshotPlugin { public class FlickrPlugin : IGreenshotPlugin {
private static readonly ILog LOG = LogManager.GetLogger(typeof(FlickrPlugin)); private static readonly ILog Log = LogManager.GetLogger(typeof(FlickrPlugin));
private static FlickrConfiguration _config; private static FlickrConfiguration _config;
public static PluginAttribute Attributes; public static PluginAttribute Attributes;
private IGreenshotHost _host; private IGreenshotHost _host;
@ -83,10 +83,12 @@ namespace GreenshotFlickrPlugin
_config = IniConfig.GetIniSection<FlickrConfiguration>(); _config = IniConfig.GetIniSection<FlickrConfiguration>();
_resources = new ComponentResourceManager(typeof(FlickrPlugin)); _resources = new ComponentResourceManager(typeof(FlickrPlugin));
_itemPlugInConfig = new ToolStripMenuItem(); _itemPlugInConfig = new ToolStripMenuItem
_itemPlugInConfig.Text = Language.GetString("flickr", LangKey.Configure); {
_itemPlugInConfig.Tag = _host; Text = Language.GetString("flickr", LangKey.Configure),
_itemPlugInConfig.Image = (Image)_resources.GetObject("flickr"); Tag = _host,
Image = (Image) _resources.GetObject("flickr")
};
_itemPlugInConfig.Click += ConfigMenuClick; _itemPlugInConfig.Click += ConfigMenuClick;
PluginUtils.AddToContextMenu(_host, _itemPlugInConfig); PluginUtils.AddToContextMenu(_host, _itemPlugInConfig);
@ -101,7 +103,7 @@ namespace GreenshotFlickrPlugin
} }
public virtual void Shutdown() { public virtual void Shutdown() {
LOG.Debug("Flickr Plugin shutdown."); Log.Debug("Flickr Plugin shutdown.");
} }
/// <summary> /// <summary>
@ -137,7 +139,7 @@ namespace GreenshotFlickrPlugin
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
LOG.Error("Error uploading.", e); Log.Error("Error uploading.", e);
MessageBox.Show(Language.GetString("flickr", LangKey.upload_failure) + " " + e.Message); MessageBox.Show(Language.GetString("flickr", LangKey.upload_failure) + " " + e.Message);
} }
return false; return false;

View file

@ -57,15 +57,17 @@ namespace GreenshotFlickrPlugin {
/// <param name="filename"></param> /// <param name="filename"></param>
/// <returns>url to image</returns> /// <returns>url to image</returns>
public static string UploadToFlickr(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) { public static string UploadToFlickr(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
OAuthSession oAuth = new OAuthSession(FlickrCredentials.ConsumerKey, FlickrCredentials.ConsumerSecret); var oAuth = new OAuthSession(FlickrCredentials.ConsumerKey, FlickrCredentials.ConsumerSecret)
oAuth.BrowserSize = new Size(520, 800); {
oAuth.CheckVerifier = false; BrowserSize = new Size(520, 800),
oAuth.AccessTokenUrl = FLICKR_ACCESS_TOKEN_URL; CheckVerifier = false,
oAuth.AuthorizeUrl = FLICKR_AUTHORIZE_URL; AccessTokenUrl = FLICKR_ACCESS_TOKEN_URL,
oAuth.RequestTokenUrl = FLICKR_REQUEST_TOKEN_URL; AuthorizeUrl = FLICKR_AUTHORIZE_URL,
oAuth.LoginTitle = "Flickr authorization"; RequestTokenUrl = FLICKR_REQUEST_TOKEN_URL,
oAuth.Token = config.FlickrToken; LoginTitle = "Flickr authorization",
oAuth.TokenSecret = config.FlickrTokenSecret; Token = config.FlickrToken,
TokenSecret = config.FlickrTokenSecret
};
if (string.IsNullOrEmpty(oAuth.Token)) { if (string.IsNullOrEmpty(oAuth.Token)) {
if (!oAuth.Authorize()) { if (!oAuth.Authorize()) {
return null; return null;
@ -85,7 +87,7 @@ namespace GreenshotFlickrPlugin {
signedParameters.Add("is_public", config.IsPublic ? "1" : "0"); signedParameters.Add("is_public", config.IsPublic ? "1" : "0");
signedParameters.Add("is_friend", config.IsFriend ? "1" : "0"); signedParameters.Add("is_friend", config.IsFriend ? "1" : "0");
signedParameters.Add("is_family", config.IsFamily ? "1" : "0"); signedParameters.Add("is_family", config.IsFamily ? "1" : "0");
signedParameters.Add("safety_level", string.Format("{0}", (int)config.SafetyLevel)); signedParameters.Add("safety_level", $"{(int) config.SafetyLevel}");
signedParameters.Add("hidden", config.HiddenFromSearch ? "1" : "2"); signedParameters.Add("hidden", config.HiddenFromSearch ? "1" : "2");
IDictionary<string, object> otherParameters = new Dictionary<string, object>(); IDictionary<string, object> otherParameters = new Dictionary<string, object>();
otherParameters.Add("photo", new SurfaceContainer(surfaceToUpload, outputSettings, filename)); otherParameters.Add("photo", new SurfaceContainer(surfaceToUpload, outputSettings, filename));
@ -125,16 +127,13 @@ namespace GreenshotFlickrPlugin {
XmlNodeList nodes = doc.GetElementsByTagName("photo"); XmlNodeList nodes = doc.GetElementsByTagName("photo");
if (nodes.Count > 0) { if (nodes.Count > 0) {
var item = nodes.Item(0); var item = nodes.Item(0);
if (item != null) { if (item?.Attributes != null) {
if (item.Attributes != null) { string farmId = item.Attributes["farm"].Value;
string farmId = item.Attributes["farm"].Value; string serverId = item.Attributes["server"].Value;
string serverId = item.Attributes["server"].Value; string photoId = item.Attributes["id"].Value;
string photoId = item.Attributes["id"].Value; string secret = item.Attributes["secret"].Value;
string secret = item.Attributes["secret"].Value; return string.Format(FLICKR_FARM_URL, farmId, serverId, photoId, secret);
return string.Format(FLICKR_FARM_URL, farmId, serverId, photoId, secret);
}
} }
} }
} }
} catch (Exception ex) { } catch (Exception ex) {

View file

@ -26,9 +26,7 @@ namespace GreenshotFlickrPlugin {
/// Description of PasswordRequestForm. /// Description of PasswordRequestForm.
/// </summary> /// </summary>
public partial class SettingsForm : FlickrForm { public partial class SettingsForm : FlickrForm {
private string flickrFrob = string.Empty; public SettingsForm() {
public SettingsForm(FlickrConfiguration config) {
// //
// The InitializeComponent() call is required for Windows Forms designer support. // The InitializeComponent() call is required for Windows Forms designer support.
// //

View file

@ -26,7 +26,5 @@ namespace GreenshotImgurPlugin {
/// This class is needed for design-time resolving of the language files /// This class is needed for design-time resolving of the language files
/// </summary> /// </summary>
public class ImgurForm : GreenshotForm { public class ImgurForm : GreenshotForm {
public ImgurForm() : base() {
}
} }
} }

View file

@ -81,8 +81,10 @@ namespace GreenshotImgurPlugin {
listview_imgur_uploads.Columns.Add(column); listview_imgur_uploads.Columns.Add(column);
} }
foreach (ImgurInfo imgurInfo in Config.runtimeImgurHistory.Values) { foreach (ImgurInfo imgurInfo in Config.runtimeImgurHistory.Values) {
ListViewItem item = new ListViewItem(imgurInfo.Hash); var item = new ListViewItem(imgurInfo.Hash)
item.Tag = imgurInfo; {
Tag = imgurInfo
};
item.SubItems.Add(imgurInfo.Title); item.SubItems.Add(imgurInfo.Title);
item.SubItems.Add(imgurInfo.DeleteHash); item.SubItems.Add(imgurInfo.DeleteHash);
item.SubItems.Add(imgurInfo.Timestamp.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo)); item.SubItems.Add(imgurInfo.Timestamp.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo));
@ -101,7 +103,7 @@ namespace GreenshotImgurPlugin {
private void Listview_imgur_uploadsSelectedIndexChanged(object sender, EventArgs e) { private void Listview_imgur_uploadsSelectedIndexChanged(object sender, EventArgs e) {
pictureBox1.Image = pictureBox1.ErrorImage; pictureBox1.Image = pictureBox1.ErrorImage;
if (listview_imgur_uploads.SelectedItems != null && listview_imgur_uploads.SelectedItems.Count > 0) { if (listview_imgur_uploads.SelectedItems.Count > 0) {
deleteButton.Enabled = true; deleteButton.Enabled = true;
openButton.Enabled = true; openButton.Enabled = true;
clipboardButton.Enabled = true; clipboardButton.Enabled = true;
@ -118,25 +120,27 @@ namespace GreenshotImgurPlugin {
} }
private void DeleteButtonClick(object sender, EventArgs e) { private void DeleteButtonClick(object sender, EventArgs e) {
if (listview_imgur_uploads.SelectedItems != null && listview_imgur_uploads.SelectedItems.Count > 0) { if (listview_imgur_uploads.SelectedItems.Count > 0) {
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) { for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) {
ImgurInfo imgurInfo = (ImgurInfo)listview_imgur_uploads.SelectedItems[i].Tag; ImgurInfo imgurInfo = (ImgurInfo)listview_imgur_uploads.SelectedItems[i].Tag;
DialogResult result = MessageBox.Show(Language.GetFormattedString("imgur", LangKey.delete_question, imgurInfo.Title), Language.GetFormattedString("imgur", LangKey.delete_title, imgurInfo.Hash), MessageBoxButtons.YesNo, MessageBoxIcon.Question); DialogResult result = MessageBox.Show(Language.GetFormattedString("imgur", LangKey.delete_question, imgurInfo.Title), Language.GetFormattedString("imgur", LangKey.delete_title, imgurInfo.Hash), MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes) { if (result != DialogResult.Yes)
// Should fix Bug #3378699 {
pictureBox1.Image = pictureBox1.ErrorImage; continue;
try {
new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait),
delegate() {
ImgurUtils.DeleteImgurImage(imgurInfo);
}
);
} catch (Exception ex) {
Log.Warn("Problem communicating with Imgur: ", ex);
}
imgurInfo.Dispose();
} }
// Should fix Bug #3378699
pictureBox1.Image = pictureBox1.ErrorImage;
try {
new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait),
delegate {
ImgurUtils.DeleteImgurImage(imgurInfo);
}
);
} catch (Exception ex) {
Log.Warn("Problem communicating with Imgur: ", ex);
}
imgurInfo.Dispose();
} }
} }
Redraw(); Redraw();
@ -144,14 +148,11 @@ namespace GreenshotImgurPlugin {
private void ClipboardButtonClick(object sender, EventArgs e) { private void ClipboardButtonClick(object sender, EventArgs e) {
StringBuilder links = new StringBuilder(); StringBuilder links = new StringBuilder();
if (listview_imgur_uploads.SelectedItems != null && listview_imgur_uploads.SelectedItems.Count > 0) { if (listview_imgur_uploads.SelectedItems.Count > 0) {
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) { for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++)
{
ImgurInfo imgurInfo = (ImgurInfo)listview_imgur_uploads.SelectedItems[i].Tag; ImgurInfo imgurInfo = (ImgurInfo)listview_imgur_uploads.SelectedItems[i].Tag;
if (Config.UsePageLink) { links.AppendLine(Config.UsePageLink ? imgurInfo.Page : imgurInfo.Original);
links.AppendLine(imgurInfo.Page);
} else {
links.AppendLine(imgurInfo.Original);
}
} }
} }
ClipboardHelper.SetClipboardData(links.ToString()); ClipboardHelper.SetClipboardData(links.ToString());
@ -173,7 +174,7 @@ namespace GreenshotImgurPlugin {
} }
private void OpenButtonClick(object sender, EventArgs e) { private void OpenButtonClick(object sender, EventArgs e) {
if (listview_imgur_uploads.SelectedItems != null && listview_imgur_uploads.SelectedItems.Count > 0) { if (listview_imgur_uploads.SelectedItems.Count > 0) {
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) { for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) {
ImgurInfo imgurInfo = (ImgurInfo)listview_imgur_uploads.SelectedItems[i].Tag; ImgurInfo imgurInfo = (ImgurInfo)listview_imgur_uploads.SelectedItems[i].Tag;
System.Diagnostics.Process.Start(imgurInfo.Page); System.Diagnostics.Process.Start(imgurInfo.Page);
@ -185,11 +186,7 @@ namespace GreenshotImgurPlugin {
// Determine if clicked column is already the column that is being sorted. // Determine if clicked column is already the column that is being sorted.
if (e.Column == _columnSorter.SortColumn) { if (e.Column == _columnSorter.SortColumn) {
// Reverse the current sort direction for this column. // Reverse the current sort direction for this column.
if (_columnSorter.Order == SortOrder.Ascending) { _columnSorter.Order = _columnSorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
_columnSorter.Order = SortOrder.Descending;
} else {
_columnSorter.Order = SortOrder.Ascending;
}
} else { } else {
// Set the column number that is to be sorted; default to ascending. // Set the column number that is to be sorted; default to ascending.
_columnSorter.SortColumn = e.Column; _columnSorter.SortColumn = e.Column;

View file

@ -25,7 +25,8 @@ namespace GreenshotImgurPlugin {
/// Description of PasswordRequestForm. /// Description of PasswordRequestForm.
/// </summary> /// </summary>
public partial class SettingsForm : ImgurForm { public partial class SettingsForm : ImgurForm {
public SettingsForm(ImgurConfiguration config) : base() { public SettingsForm(ImgurConfiguration config)
{
// //
// The InitializeComponent() call is required for Windows Forms designer support. // The InitializeComponent() call is required for Windows Forms designer support.
// //
@ -35,11 +36,7 @@ namespace GreenshotImgurPlugin {
ImgurUtils.LoadHistory(); ImgurUtils.LoadHistory();
if (config.runtimeImgurHistory.Count > 0) { historyButton.Enabled = config.runtimeImgurHistory.Count > 0;
historyButton.Enabled = true;
} else {
historyButton.Enabled = false;
}
} }
private void ButtonHistoryClick(object sender, EventArgs e) { private void ButtonHistoryClick(object sender, EventArgs e) {

View file

@ -98,7 +98,7 @@ namespace GreenshotImgurPlugin {
SettingsForm settingsForm = null; SettingsForm settingsForm = null;
new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait), new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait),
delegate() { delegate {
settingsForm = new SettingsForm(this); settingsForm = new SettingsForm(this);
} }
); );

View file

@ -20,7 +20,6 @@
*/ */
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using Greenshot.IniFile;
using Greenshot.Plugin; using Greenshot.Plugin;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
@ -29,25 +28,15 @@ namespace GreenshotImgurPlugin {
/// Description of ImgurDestination. /// Description of ImgurDestination.
/// </summary> /// </summary>
public class ImgurDestination : AbstractDestination { public class ImgurDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImgurDestination)); private readonly ImgurPlugin _plugin;
private static ImgurConfiguration config = IniConfig.GetIniSection<ImgurConfiguration>();
private readonly ImgurPlugin plugin = null;
public ImgurDestination(ImgurPlugin plugin) { public ImgurDestination(ImgurPlugin plugin) {
this.plugin = plugin; _plugin = plugin;
} }
public override string Designation { public override string Designation => "Imgur";
get {
return "Imgur";
}
}
public override string Description { public override string Description => Language.GetString("imgur", LangKey.upload_menu_item);
get {
return Language.GetString("imgur", LangKey.upload_menu_item);
}
}
public override Image DisplayIcon { public override Image DisplayIcon {
get { get {
@ -59,7 +48,7 @@ namespace GreenshotImgurPlugin {
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
string uploadUrl; string uploadUrl;
exportInformation.ExportMade = plugin.Upload(captureDetails, surface, out uploadUrl); exportInformation.ExportMade = _plugin.Upload(captureDetails, surface, out uploadUrl);
exportInformation.Uri = uploadUrl; exportInformation.Uri = uploadUrl;
ProcessExport(exportInformation, surface); ProcessExport(exportInformation, surface);
return exportInformation; return exportInformation;

View file

@ -29,7 +29,7 @@ namespace GreenshotImgurPlugin
/// </summary> /// </summary>
public class ImgurInfo : IDisposable public class ImgurInfo : IDisposable
{ {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImgurInfo)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurInfo));
public string Hash public string Hash
{ {
@ -37,13 +37,13 @@ namespace GreenshotImgurPlugin
set; set;
} }
private string deleteHash; private string _deleteHash;
public string DeleteHash public string DeleteHash
{ {
get { return deleteHash; } get { return _deleteHash; }
set set
{ {
deleteHash = value; _deleteHash = value;
DeletePage = "https://imgur.com/delete/" + value; DeletePage = "https://imgur.com/delete/" + value;
} }
} }
@ -96,24 +96,17 @@ namespace GreenshotImgurPlugin
set; set;
} }
private Image image; private Image _image;
public Image Image public Image Image
{ {
get { return image; } get { return _image; }
set set
{ {
if (image != null) _image?.Dispose();
{ _image = value;
image.Dispose();
}
image = value;
} }
} }
public ImgurInfo()
{
}
/// <summary> /// <summary>
/// The public accessible Dispose /// The public accessible Dispose
/// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice /// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
@ -133,16 +126,13 @@ namespace GreenshotImgurPlugin
{ {
if (disposing) if (disposing)
{ {
if (image != null) _image?.Dispose();
{
image.Dispose();
}
} }
image = null; _image = null;
} }
public static ImgurInfo ParseResponse(string response) public static ImgurInfo ParseResponse(string response)
{ {
LOG.Debug(response); Log.Debug(response);
// This is actually a hack for BUG-1695 // This is actually a hack for BUG-1695
// The problem is the (C) sign, we send it HTML encoded "&reg;" to Imgur and get it HTML encoded in the XML back // The problem is the (C) sign, we send it HTML encoded "&reg;" to Imgur and get it HTML encoded in the XML back
// Added all the encodings I found quickly, I guess these are not all... but it should fix the issue for now. // Added all the encodings I found quickly, I guess these are not all... but it should fix the issue for now.
@ -161,34 +151,34 @@ namespace GreenshotImgurPlugin
XmlNodeList nodes = doc.GetElementsByTagName("id"); XmlNodeList nodes = doc.GetElementsByTagName("id");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.Hash = nodes.Item(0).InnerText; imgurInfo.Hash = nodes.Item(0)?.InnerText;
} }
nodes = doc.GetElementsByTagName("hash"); nodes = doc.GetElementsByTagName("hash");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.Hash = nodes.Item(0).InnerText; imgurInfo.Hash = nodes.Item(0)?.InnerText;
} }
nodes = doc.GetElementsByTagName("deletehash"); nodes = doc.GetElementsByTagName("deletehash");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.DeleteHash = nodes.Item(0).InnerText; imgurInfo.DeleteHash = nodes.Item(0)?.InnerText;
} }
nodes = doc.GetElementsByTagName("type"); nodes = doc.GetElementsByTagName("type");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.ImageType = nodes.Item(0).InnerText; imgurInfo.ImageType = nodes.Item(0)?.InnerText;
} }
nodes = doc.GetElementsByTagName("title"); nodes = doc.GetElementsByTagName("title");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.Title = nodes.Item(0).InnerText; imgurInfo.Title = nodes.Item(0)?.InnerText;
} }
nodes = doc.GetElementsByTagName("datetime"); nodes = doc.GetElementsByTagName("datetime");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
// Version 3 has seconds since Epoch // Version 3 has seconds since Epoch
double secondsSince; double secondsSince;
if (double.TryParse(nodes.Item(0).InnerText, out secondsSince)) if (double.TryParse(nodes.Item(0)?.InnerText, out secondsSince))
{ {
var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero); var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
imgurInfo.Timestamp = epoch.AddSeconds(secondsSince).DateTime; imgurInfo.Timestamp = epoch.AddSeconds(secondsSince).DateTime;
@ -197,37 +187,30 @@ namespace GreenshotImgurPlugin
nodes = doc.GetElementsByTagName("original"); nodes = doc.GetElementsByTagName("original");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.Original = nodes.Item(0).InnerText.Replace("http:", "https:"); imgurInfo.Original = nodes.Item(0)?.InnerText.Replace("http:", "https:");
} }
// Version 3 API only has Link // Version 3 API only has Link
nodes = doc.GetElementsByTagName("link"); nodes = doc.GetElementsByTagName("link");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.Original = nodes.Item(0).InnerText.Replace("http:", "https:"); imgurInfo.Original = nodes.Item(0)?.InnerText.Replace("http:", "https:");
} }
nodes = doc.GetElementsByTagName("imgur_page"); nodes = doc.GetElementsByTagName("imgur_page");
if (nodes.Count > 0) if (nodes.Count > 0)
{ {
imgurInfo.Page = nodes.Item(0).InnerText.Replace("http:", "https:"); imgurInfo.Page = nodes.Item(0)?.InnerText.Replace("http:", "https:");
} }
else else
{ {
// Version 3 doesn't have a page link in the response // Version 3 doesn't have a page link in the response
imgurInfo.Page = string.Format("https://imgur.com/{0}", imgurInfo.Hash); imgurInfo.Page = $"https://imgur.com/{imgurInfo.Hash}";
} }
nodes = doc.GetElementsByTagName("small_square"); nodes = doc.GetElementsByTagName("small_square");
if (nodes.Count > 0) imgurInfo.SmallSquare = nodes.Count > 0 ? nodes.Item(0)?.InnerText : $"http://i.imgur.com/{imgurInfo.Hash}s.png";
{
imgurInfo.SmallSquare = nodes.Item(0).InnerText;
}
else
{
imgurInfo.SmallSquare = string.Format("http://i.imgur.com/{0}s.png",imgurInfo.Hash);
}
} }
catch (Exception e) catch (Exception e)
{ {
LOG.ErrorFormat("Could not parse Imgur response due to error {0}, response was: {1}", e.Message, response); Log.ErrorFormat("Could not parse Imgur response due to error {0}, response was: {1}", e.Message, response);
} }
return imgurInfo; return imgurInfo;
} }

View file

@ -61,9 +61,6 @@ namespace GreenshotImgurPlugin {
} }
} }
public ImgurPlugin() {
}
public IEnumerable<IDestination> Destinations() { public IEnumerable<IDestination> Destinations() {
yield return new ImgurDestination(this); yield return new ImgurDestination(this);
} }

View file

@ -65,9 +65,9 @@ namespace GreenshotJiraPlugin {
} }
} }
public override bool isActive => base.isActive && !string.IsNullOrEmpty(Config.Url); public override bool IsActive => base.IsActive && !string.IsNullOrEmpty(Config.Url);
public override bool isDynamic => true; public override bool IsDynamic => true;
public override Image DisplayIcon { public override Image DisplayIcon {
get get

View file

@ -23,13 +23,10 @@ using System.Windows.Forms;
using Greenshot.IniFile; using Greenshot.IniFile;
using Greenshot.Plugin; using Greenshot.Plugin;
using System; using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapplo.Log.Facade; using Dapplo.Log.Facade;
using GreenshotJiraPlugin.Forms; using GreenshotJiraPlugin.Forms;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using Svg;
namespace GreenshotJiraPlugin { namespace GreenshotJiraPlugin {
/// <summary> /// <summary>

View file

@ -316,13 +316,9 @@ namespace Greenshot.Interop {
/// </returns> /// </returns>
public override IMessage Invoke(IMessage myMessage) { public override IMessage Invoke(IMessage myMessage) {
IMethodCallMessage callMessage = myMessage as IMethodCallMessage; IMethodCallMessage callMessage = myMessage as IMethodCallMessage;
if (null == callMessage) {
//LOG.DebugFormat("Message type not implemented: {0}", myMessage.GetType().ToString());
return null;
}
MethodInfo method = callMessage.MethodBase as MethodInfo; MethodInfo method = callMessage?.MethodBase as MethodInfo;
if (null == method) { if (method == null) {
//LOG.DebugFormat("Unrecognized Invoke call: {0}", callMessage.MethodBase.ToString()); //LOG.DebugFormat("Unrecognized Invoke call: {0}", callMessage.MethodBase.ToString());
return null; return null;
} }
@ -336,18 +332,8 @@ namespace Greenshot.Interop {
BindingFlags flags = BindingFlags.InvokeMethod; BindingFlags flags = BindingFlags.InvokeMethod;
int argCount = callMessage.ArgCount; int argCount = callMessage.ArgCount;
object invokeObject;
Type invokeType;
Type byValType;
object[] args;
object arg;
COMWrapper[] originalArgs;
COMWrapper wrapper;
ParameterModifier[] argModifiers = null; ParameterModifier[] argModifiers = null;
ParameterInfo[] parameters = null; ParameterInfo[] parameters = null;
ParameterInfo parameter;
if ("Dispose" == methodName && 0 == argCount && typeof(void) == returnType) { if ("Dispose" == methodName && 0 == argCount && typeof(void) == returnType) {
Dispose(); Dispose();
@ -365,9 +351,11 @@ namespace Greenshot.Interop {
return new ReturnMessage(new ArgumentNullException(nameof(handler)), callMessage); return new ReturnMessage(new ArgumentNullException(nameof(handler)), callMessage);
} }
} else { } else {
invokeObject = _comObject; var invokeObject = _comObject;
invokeType = _comType; var invokeType = _comType;
ParameterInfo parameter;
object[] args;
if (methodName.StartsWith("get_")) { if (methodName.StartsWith("get_")) {
// Property Get // Property Get
methodName = methodName.Substring(4); methodName = methodName.Substring(4);
@ -401,6 +389,9 @@ namespace Greenshot.Interop {
} }
// Un-wrap wrapped COM objects before passing to the method // Un-wrap wrapped COM objects before passing to the method
COMWrapper[] originalArgs;
COMWrapper wrapper;
Type byValType;
if (null == args || 0 == args.Length) { if (null == args || 0 == args.Length) {
originalArgs = null; originalArgs = null;
} else { } else {
@ -412,7 +403,7 @@ namespace Greenshot.Interop {
originalArgs[i] = wrapper; originalArgs[i] = wrapper;
args[i] = wrapper._comObject; args[i] = wrapper._comObject;
} }
} else if (0 != outArgsCount && argModifiers[0][i]) { } else if (argModifiers != null && (0 != outArgsCount && argModifiers[0][i])) {
byValType = GetByValType(parameters[i].ParameterType); byValType = GetByValType(parameters[i].ParameterType);
if (byValType.IsInterface) { if (byValType.IsInterface) {
// If we're passing a COM object by reference, and // If we're passing a COM object by reference, and
@ -453,42 +444,48 @@ namespace Greenshot.Interop {
// Handle out args // Handle out args
if (0 != outArgsCount) { if (0 != outArgsCount) {
outArgs = new object[args.Length]; if (args != null && parameters != null)
for (int i = 0; i < parameters.Length; i++) { {
if (!argModifiers[0][i]) { outArgs = new object[args.Length];
continue; for (int i = 0; i < parameters.Length; i++) {
} if (argModifiers != null && !argModifiers[0][i]) {
continue;
arg = args[i];
if (null == arg) {
continue;
}
parameter = parameters[i];
wrapper = null;
byValType = GetByValType(parameter.ParameterType);
if (typeof(decimal) == byValType) {
if (arg is CurrencyWrapper) {
arg = ((CurrencyWrapper)arg).WrappedObject;
} }
} else if (byValType.IsEnum) {
arg = Enum.Parse(byValType, arg.ToString());
} else if (byValType.IsInterface) {
if (Marshal.IsComObject(arg)) {
wrapper = originalArgs[i];
if (null != wrapper && wrapper._comObject != arg) {
wrapper.Dispose();
wrapper = null;
}
if (null == wrapper) { var arg = args[i];
wrapper = new COMWrapper(arg, byValType); if (null == arg) {
} continue;
arg = wrapper.GetTransparentProxy();
} }
parameter = parameters[i];
wrapper = null;
byValType = GetByValType(parameter.ParameterType);
if (typeof(decimal) == byValType) {
if (arg is CurrencyWrapper) {
arg = ((CurrencyWrapper)arg).WrappedObject;
}
} else if (byValType.IsEnum) {
arg = Enum.Parse(byValType, arg.ToString());
} else if (byValType.IsInterface) {
if (Marshal.IsComObject(arg)) {
if (originalArgs != null)
{
wrapper = originalArgs[i];
}
if (null != wrapper && wrapper._comObject != arg) {
wrapper.Dispose();
wrapper = null;
}
if (null == wrapper) {
wrapper = new COMWrapper(arg, byValType);
}
arg = wrapper.GetTransparentProxy();
}
}
outArgs[i] = arg;
} }
outArgs[i] = arg;
} }
} }
} }

View file

@ -24,10 +24,8 @@ namespace Greenshot.Interop {
/// <summary> /// <summary>
/// An attribute to specifiy the ProgID of the COM class to create. (As suggested by Kristen Wegner) /// An attribute to specifiy the ProgID of the COM class to create. (As suggested by Kristen Wegner)
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Interface)]
public sealed class ComProgIdAttribute : Attribute { public sealed class ComProgIdAttribute : Attribute {
private readonly string _value;
/// <summary> /// <summary>
/// Extracts the attribute from the specified type. /// Extracts the attribute from the specified type.
/// </summary> /// </summary>
@ -42,24 +40,24 @@ namespace Greenshot.Interop {
/// </exception> /// </exception>
public static ComProgIdAttribute GetAttribute(Type interfaceType) { public static ComProgIdAttribute GetAttribute(Type interfaceType) {
if (null == interfaceType) { if (null == interfaceType) {
throw new ArgumentNullException("interfaceType"); throw new ArgumentNullException(nameof(interfaceType));
} }
Type attributeType = typeof(ComProgIdAttribute); Type attributeType = typeof(ComProgIdAttribute);
object[] attributes = interfaceType.GetCustomAttributes(attributeType, false); object[] attributes = interfaceType.GetCustomAttributes(attributeType, false);
if (null == attributes || 0 == attributes.Length) { if (0 == attributes.Length) {
Type[] interfaces = interfaceType.GetInterfaces(); Type[] interfaces = interfaceType.GetInterfaces();
for (int i = 0; i < interfaces.Length; i++) { for (int i = 0; i < interfaces.Length; i++) {
interfaceType = interfaces[i]; interfaceType = interfaces[i];
attributes = interfaceType.GetCustomAttributes(attributeType, false); attributes = interfaceType.GetCustomAttributes(attributeType, false);
if (null != attributes && 0 != attributes.Length) { if (0 != attributes.Length) {
break; break;
} }
} }
} }
if (null == attributes || 0 == attributes.Length) { if (0 == attributes.Length) {
return null; return null;
} }
return (ComProgIdAttribute)attributes[0]; return (ComProgIdAttribute)attributes[0];
@ -68,16 +66,12 @@ namespace Greenshot.Interop {
/// <summary>Constructor</summary> /// <summary>Constructor</summary>
/// <param name="value">The COM ProgID.</param> /// <param name="value">The COM ProgID.</param>
public ComProgIdAttribute(string value) { public ComProgIdAttribute(string value) {
_value = value; Value = value;
} }
/// <summary> /// <summary>
/// Returns the COM ProgID /// Returns the COM ProgID
/// </summary> /// </summary>
public string Value { public string Value { get; }
get {
return _value;
}
}
} }
} }

Some files were not shown because too many files have changed in this diff Show more