Improved the support for dragging and dropping images from a website, now also parsing HTML img src information, to be able to download that image. For this we need the HtmlAgilityPack.dll (#294)

Removed a lot of dead code, and remove the old OCR code as we don't even know if it still works.
This commit is contained in:
Robin Krom 2021-03-21 22:34:17 +01:00 committed by GitHub
parent 90cab1e8a3
commit 26fe579d31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
151 changed files with 1138 additions and 8174 deletions

View file

@ -14,10 +14,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Greenshot", "Greenshot\Gree
{697CF066-9077-4F22-99D9-D989CCE7282B} = {697CF066-9077-4F22-99D9-D989CCE7282B} {697CF066-9077-4F22-99D9-D989CCE7282B} = {697CF066-9077-4F22-99D9-D989CCE7282B}
{47F23C86-604E-4CC3-8767-B3D4088F30BB} = {47F23C86-604E-4CC3-8767-B3D4088F30BB} {47F23C86-604E-4CC3-8767-B3D4088F30BB} = {47F23C86-604E-4CC3-8767-B3D4088F30BB}
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50} = {80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50} {80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50} = {80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02} = {D61E6ECE-E0B6-4467-B492-F08A06BA8F02}
{AD7CFFE2-40E7-46CF-A172-D48CF7AE9A12} = {AD7CFFE2-40E7-46CF-A172-D48CF7AE9A12} {AD7CFFE2-40E7-46CF-A172-D48CF7AE9A12} = {AD7CFFE2-40E7-46CF-A172-D48CF7AE9A12}
{1893A2E4-A78A-4713-A8E7-E70058DABEE0} = {1893A2E4-A78A-4713-A8E7-E70058DABEE0} {1893A2E4-A78A-4713-A8E7-E70058DABEE0} = {1893A2E4-A78A-4713-A8E7-E70058DABEE0}
{C6988EE8-2FEE-4349-9F09-F9628A0D8965} = {C6988EE8-2FEE-4349-9F09-F9628A0D8965}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotPlugin", "GreenshotPlugin\GreenshotPlugin.csproj", "{5B924697-4DCD-4F98-85F1-105CB84B7341}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotPlugin", "GreenshotPlugin\GreenshotPlugin.csproj", "{5B924697-4DCD-4F98-85F1-105CB84B7341}"
@ -30,13 +28,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotImgurPlugin", "Gre
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotJiraPlugin", "GreenshotJiraPlugin\GreenshotJiraPlugin.csproj", "{19FEEF09-313F-43C7-819D-F1BCA782B08B}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotJiraPlugin", "GreenshotJiraPlugin\GreenshotJiraPlugin.csproj", "{19FEEF09-313F-43C7-819D-F1BCA782B08B}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotOCRPlugin", "GreenshotOCRPlugin\GreenshotOCRPlugin.csproj", "{C6988EE8-2FEE-4349-9F09-F9628A0D8965}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotOCRCommand", "GreenshotOCRCommand\GreenshotOCRCommand.csproj", "{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}"
ProjectSection(ProjectDependencies) = postProject
{C6988EE8-2FEE-4349-9F09-F9628A0D8965} = {C6988EE8-2FEE-4349-9F09-F9628A0D8965}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotBoxPlugin", "GreenshotBoxPlugin\GreenshotBoxPlugin.csproj", "{697CF066-9077-4F22-99D9-D989CCE7282B}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotBoxPlugin", "GreenshotBoxPlugin\GreenshotBoxPlugin.csproj", "{697CF066-9077-4F22-99D9-D989CCE7282B}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotDropboxPlugin", "GreenshotDropboxPlugin\GreenshotDropboxPlugin.csproj", "{AD7CFFE2-40E7-46CF-A172-D48CF7AE9A12}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotDropboxPlugin", "GreenshotDropboxPlugin\GreenshotDropboxPlugin.csproj", "{AD7CFFE2-40E7-46CF-A172-D48CF7AE9A12}"
@ -51,6 +42,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotPhotobucketPlugin"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotWin10Plugin", "GreenshotWin10Plugin\GreenshotWin10Plugin.csproj", "{9801F62C-540F-4BFE-9211-6405DEDE563B}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotWin10Plugin", "GreenshotWin10Plugin\GreenshotWin10Plugin.csproj", "{9801F62C-540F-4BFE-9211-6405DEDE563B}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{82987F1E-D7E6-4C44-B934-981D366E4672}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
azure-pipelines.yml = azure-pipelines.yml
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -107,22 +104,6 @@ Global
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|Any CPU.Build.0 = Release|Any CPU {19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|Any CPU.Build.0 = Release|Any CPU
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|x86.ActiveCfg = Release|Any CPU {19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|x86.ActiveCfg = Release|Any CPU
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|x86.Build.0 = Release|Any CPU {19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|x86.Build.0 = Release|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|x86.ActiveCfg = Debug|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|x86.Build.0 = Debug|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|Any CPU.Build.0 = Release|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|x86.ActiveCfg = Release|Any CPU
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|x86.Build.0 = Release|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Debug|x86.ActiveCfg = Debug|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Debug|x86.Build.0 = Debug|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Release|Any CPU.Build.0 = Release|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Release|x86.ActiveCfg = Release|Any CPU
{D61E6ECE-E0B6-4467-B492-F08A06BA8F02}.Release|x86.Build.0 = Release|Any CPU
{697CF066-9077-4F22-99D9-D989CCE7282B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {697CF066-9077-4F22-99D9-D989CCE7282B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{697CF066-9077-4F22-99D9-D989CCE7282B}.Debug|Any CPU.Build.0 = Debug|Any CPU {697CF066-9077-4F22-99D9-D989CCE7282B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{697CF066-9077-4F22-99D9-D989CCE7282B}.Debug|x86.ActiveCfg = Debug|Any CPU {697CF066-9077-4F22-99D9-D989CCE7282B}.Debug|x86.ActiveCfg = Debug|Any CPU

View file

@ -25,219 +25,56 @@ namespace Greenshot.Configuration {
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum LangKey { public enum LangKey {
none, none,
about_bugs, contextmenu_capturefullscreen_all,
about_donations,
about_host,
about_icons,
about_license,
about_title,
about_translation,
application_title,
bugreport_cancel,
bugreport_info,
bugreport_title,
clipboard_error,
clipboard_inuse,
colorpicker_alpha,
colorpicker_apply,
colorpicker_blue,
colorpicker_green,
colorpicker_htmlcolor,
colorpicker_recentcolors,
colorpicker_red,
colorpicker_title,
colorpicker_transparent,
config_unauthorizedaccess_write,
contextmenu_about,
contextmenu_capturearea,
contextmenu_captureclipboard,
contextmenu_capturefullscreen,
contextmenu_capturefullscreen_all,
contextmenu_capturefullscreen_left, contextmenu_capturefullscreen_left,
contextmenu_capturefullscreen_top, contextmenu_capturefullscreen_top,
contextmenu_capturefullscreen_right, contextmenu_capturefullscreen_right,
contextmenu_capturefullscreen_bottom, contextmenu_capturefullscreen_bottom,
contextmenu_capturelastregion, contextmenu_captureie,
contextmenu_capturewindow, editor_clipboardfailed,
contextmenu_donate,
contextmenu_exit,
contextmenu_help,
contextmenu_openfile,
contextmenu_quicksettings,
contextmenu_settings,
contextmenu_captureie,
contextmenu_openrecentcapture,
editor_align_bottom,
editor_align_center,
editor_align_horizontal,
editor_align_middle,
editor_align_left,
editor_align_right,
editor_align_top,
editor_align_vertical,
editor_arrange,
editor_arrowheads,
editor_arrowheads_both,
editor_arrowheads_end,
editor_arrowheads_none,
editor_arrowheads_start,
editor_backcolor,
editor_blur_radius,
editor_bold,
editor_brightness,
editor_cancel,
editor_clipboardfailed,
editor_close,
editor_close_on_save, editor_close_on_save,
editor_close_on_save_title, editor_close_on_save_title,
editor_confirm,
editor_copyimagetoclipboard,
editor_copypathtoclipboard,
editor_copytoclipboard, editor_copytoclipboard,
editor_crop,
editor_cursortool,
editor_cuttoclipboard, editor_cuttoclipboard,
editor_deleteelement, editor_deleteelement,
editor_downonelevel, editor_downonelevel,
editor_downtobottom, editor_downtobottom,
editor_drawarrow,
editor_drawellipse,
editor_drawhighlighter,
editor_drawline,
editor_drawfreehand,
editor_drawrectangle,
editor_drawtextbox,
editor_duplicate, editor_duplicate,
editor_edit,
editor_email, editor_email,
editor_file,
editor_fontsize,
editor_forecolor,
editor_highlight_area,
editor_highlight_grayscale,
editor_highlight_mode,
editor_highlight_text,
editor_highlight_magnify,
editor_pixel_size,
editor_imagesaved, editor_imagesaved,
editor_italic,
editor_load_objects,
editor_magnification_factor,
editor_match_capture_size,
editor_obfuscate,
editor_obfuscate_blur,
editor_obfuscate_mode,
editor_obfuscate_pixelize,
editor_object,
editor_opendirinexplorer,
editor_pastefromclipboard,
editor_preview_quality,
editor_print,
editor_save,
editor_save_objects,
editor_saveas,
editor_selectall,
editor_senttoprinter,
editor_shadow,
editor_torn_edge,
editor_border,
editor_grayscale,
editor_effects,
editor_storedtoclipboard,
editor_thickness,
editor_title, editor_title,
editor_uponelevel, editor_uponelevel,
editor_uptotop, editor_uptotop,
editor_autocrop,
editor_undo, editor_undo,
editor_redo, editor_redo,
editor_insertwindow,
editor_resetsize, editor_resetsize,
error, error,
error_multipleinstances, error_multipleinstances,
error_nowriteaccess,
error_openfile, error_openfile,
error_openlink, error_openlink,
error_save, error_save,
error_save_invalid_chars, error_save_invalid_chars,
help_title,
jpegqualitydialog_choosejpegquality,
qualitydialog_dontaskagain,
qualitydialog_title,
settings_reducecolors,
print_error, print_error,
printoptions_allowcenter,
printoptions_allowenlarge,
printoptions_allowrotate,
printoptions_allowshrink,
printoptions_colors,
printoptions_dontaskagain,
printoptions_pagelayout,
printoptions_printcolor,
printoptions_printgrayscale,
printoptions_printmonochrome,
printoptions_timestamp,
printoptions_inverted,
printoptions_title,
quicksettings_destination_file, quicksettings_destination_file,
settings_alwaysshowqualitydialog,
settings_alwaysshowprintoptionsdialog,
settings_applicationsettings,
settings_autostartshortcut,
settings_capture,
settings_capture_mousepointer,
settings_capture_windows_interactive,
settings_copypathtoclipboard,
settings_destination, settings_destination,
settings_destination_clipboard, settings_destination_clipboard,
settings_destination_editor, settings_destination_editor,
settings_destination_email,
settings_destination_file,
settings_destination_fileas, settings_destination_fileas,
settings_destination_printer, settings_destination_printer,
settings_destination_picker, settings_destination_picker,
settings_editor,
settings_filenamepattern, settings_filenamepattern,
settings_general,
settings_iecapture,
settings_jpegquality,
settings_qualitysettings,
settings_language,
settings_message_filenamepattern, settings_message_filenamepattern,
settings_output,
settings_playsound,
settings_plugins,
settings_plugins_name,
settings_plugins_version,
settings_plugins_createdby,
settings_plugins_dllpath,
settings_preferredfilesettings,
settings_primaryimageformat,
settings_printer,
settings_printoptions, settings_printoptions,
settings_registerhotkeys,
settings_showflashlight,
settings_storagelocation,
settings_title,
settings_tooltip_filenamepattern, settings_tooltip_filenamepattern,
settings_tooltip_language, settings_tooltip_language,
settings_tooltip_primaryimageformat, settings_tooltip_primaryimageformat,
settings_tooltip_registerhotkeys,
settings_tooltip_storagelocation, settings_tooltip_storagelocation,
settings_visualization, settings_visualization,
settings_shownotify,
settings_waittime,
settings_windowscapture,
settings_window_capture_mode, settings_window_capture_mode,
settings_network,
settings_checkperiod,
settings_usedefaultproxy,
tooltip_firststart, tooltip_firststart,
warning, warning,
warning_hotkeys, warning_hotkeys,
hotkeys,
wait_ie_capture, wait_ie_capture,
update_found, update_found
exported_to
} }
} }

View file

@ -28,8 +28,6 @@ namespace Greenshot.Controls {
/// See: http://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx /// See: http://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx
/// </summary> /// </summary>
public class MenuStripEx : MenuStrip { public class MenuStripEx : MenuStrip {
private const int WM_MOUSEACTIVATE = 0x21;
private enum NativeConstants : uint { private enum NativeConstants : uint {
MA_ACTIVATE = 1, MA_ACTIVATE = 1,
MA_ACTIVATEANDEAT = 2, MA_ACTIVATEANDEAT = 2,

View file

@ -34,9 +34,7 @@ namespace Greenshot.Drawing {
/// </summary> /// </summary>
[Serializable()] [Serializable()]
public class LineContainer : DrawableContainer { public class LineContainer : DrawableContainer {
public static readonly int MAX_CLICK_DISTANCE_TOLERANCE = 10; public LineContainer(Surface parent) : base(parent) {
public LineContainer(Surface parent) : base(parent) {
Init(); Init();
} }

View file

@ -20,7 +20,6 @@
*/ */
using System; using System;
using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
namespace Greenshot.Drawing { namespace Greenshot.Drawing {
@ -111,25 +110,13 @@ namespace Greenshot.Drawing {
p.CloseFigure(); p.CloseFigure();
return p; return p;
} }
public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners corners) { public static GraphicsPath Create(int x, int y, int width, int height, int radius) {
return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, corners);
}
public static GraphicsPath Create(int x, int y, int width, int height, int radius) {
return Create(x, y, width, height, radius, RectangleCorners.All); return Create(x, y, width, height, radius, RectangleCorners.All);
} }
public static GraphicsPath Create(Rectangle rect, int radius) { public static GraphicsPath Create(int x, int y, int width, int height) {
return Create(rect.X, rect.Y, rect.Width, rect.Height, radius);
}
public static GraphicsPath Create(int x, int y, int width, int height) {
return Create(x, y, width, height, 5); return Create(x, y, width, height, 5);
} }
}
public static GraphicsPath Create(Rectangle rect) {
return Create(rect.X, rect.Y, rect.Width, rect.Height);
}
}
} }

View file

@ -73,12 +73,7 @@ namespace Greenshot.Forms {
/// </summary> /// </summary>
private readonly Fraction[] ZOOM_VALUES = new Fraction[] { (1, 4), (1, 2), (2, 3), (3, 4), (1 ,1), (2, 1), (3, 1), (4, 1), (6, 1) }; private readonly Fraction[] ZOOM_VALUES = new Fraction[] { (1, 4), (1, 2), (2, 3), (3, 4), (1 ,1), (2, 1), (3, 1), (4, 1), (6, 1) };
/// <summary> public static List<IImageEditor> Editors {
/// An Implementation for the IImageEditor, this way Plugins have access to the HWND handles wich can be used with Win32 API calls.
/// </summary>
public IWin32Window WindowHandle => this;
public static List<IImageEditor> Editors {
get { get {
try { try {
EditorList.Sort((e1, e2) => string.Compare(e1.Surface.CaptureDetails.Title, e2.Surface.CaptureDetails.Title, StringComparison.Ordinal)); EditorList.Sort((e1, e2) => string.Compare(e1.Surface.CaptureDetails.Title, e2.Surface.CaptureDetails.Title, StringComparison.Ordinal));

View file

@ -486,12 +486,7 @@ namespace Greenshot.Forms {
} }
} }
/// <summary> protected override void WndProc(ref Message m) {
/// Main context menu
/// </summary>
public ContextMenuStrip MainMenu => contextMenu;
protected override void WndProc(ref Message m) {
if (HotkeyControl.HandleMessages(ref m)) { if (HotkeyControl.HandleMessages(ref m)) {
return; return;
} }

View file

@ -22,7 +22,6 @@
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using GreenshotPlugin.IniFile; using GreenshotPlugin.IniFile;
@ -57,77 +56,8 @@ namespace Greenshot.Forms {
Image = _defaultImage; Image = _defaultImage;
} }
public ToolStripMenuSelectList() : this(null,false) {} public ToolStripMenuSelectList() : this(null,false) {}
public ToolStripMenuSelectList(object identifier) : this(identifier,false) {}
/// <summary> private void ItemCheckStateChanged(object sender, EventArgs e) {
/// gets or sets the currently checked item
/// </summary>
public ToolStripMenuSelectListItem CheckedItem {
get {
IEnumerator items = DropDownItems.GetEnumerator();
while (items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current;
if (tsmi != null && tsmi.Checked) {
return tsmi;
}
}
return null;
}
set {
IEnumerator items = DropDownItems.GetEnumerator();
while (items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current;
if (tsmi != null && !_multiCheckAllowed && !tsmi.Equals(value)) {
tsmi.Checked = false;
} else if (tsmi != null && tsmi.Equals(value)) {
tsmi.Checked = true;
}
}
}
}
/// <summary>
/// gets or sets the currently checked items
/// </summary>
public ToolStripMenuSelectListItem[] CheckedItems {
get {
List<ToolStripMenuSelectListItem> sel = new List<ToolStripMenuSelectListItem>();
IEnumerator items = DropDownItems.GetEnumerator();
while(items.MoveNext()) {
ToolStripMenuSelectListItem tsmi = (ToolStripMenuSelectListItem)items.Current;
if (tsmi != null && tsmi.Checked) {
sel.Add(tsmi);
}
}
return sel.ToArray();
}
set {
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.");
}
IEnumerator items = DropDownItems.GetEnumerator();
IEnumerator sel = value.GetEnumerator();
while (items.MoveNext()) {
var toolStripMenuSelectListItem = (ToolStripMenuSelectListItem)items.Current;
if (toolStripMenuSelectListItem == null)
{
continue;
}
while (sel.MoveNext())
{
toolStripMenuSelectListItem.Checked = toolStripMenuSelectListItem.Equals(sel.Current);
if (!_multiCheckAllowed && !toolStripMenuSelectListItem.Equals(sel.Current)) {
toolStripMenuSelectListItem.Checked = false;
} else if (toolStripMenuSelectListItem.Equals(value)) {
toolStripMenuSelectListItem.Checked = true;
}
}
}
}
}
private void ItemCheckStateChanged(object sender, EventArgs e) {
if (_updateInProgress) { if (_updateInProgress) {
return; return;
} }
@ -172,44 +102,8 @@ namespace Greenshot.Forms {
DropDownItems.Add(toolStripMenuSelectListItem); DropDownItems.Add(toolStripMenuSelectListItem);
} }
/// <summary>
/// adds an item to the select list
/// </summary>
/// <param name="label">the label to be displayed</param>
/// <param name="image">the icon to be displayed</param>
public void AddItem(string label, Image image) {
AddItem(label, image, null, false);
}
/// <summary> /// <summary>
/// adds an item to the select list
/// </summary>
/// <param name="label">the label to be displayed</param>
/// <param name="data">the data to be returned when an item is queried</param>
public void AddItem(string label, object data) {
AddItem(label, null, data, false);
}
/// <summary>
/// adds an item to the select list
/// </summary>
/// <param name="label">the label to be displayed</param>
public void AddItem(string label) {
AddItem(label, null, null, false);
}
/// <summary>
/// adds an item to the select list
/// </summary>
/// <param name="label">the label to be displayed</param>
/// <param name="image">the icon to be displayed</param>
/// <param name="isChecked">whether the item is initially checked</param>
public void AddItem(string label, Image image, bool isChecked) {
AddItem(label, image, null, isChecked);
}
/// <summary>
/// adds an item to the select list /// adds an item to the select list
/// </summary> /// </summary>
/// <param name="label">the label to be displayed</param> /// <param name="label">the label to be displayed</param>
@ -219,16 +113,7 @@ namespace Greenshot.Forms {
AddItem(label, null, data, isChecked); AddItem(label, null, data, isChecked);
} }
/// <summary> /// <summary>
/// adds an item to the select list
/// </summary>
/// <param name="label">the label to be displayed</param>
/// <param name="isChecked">whether the item is initially checked</param>
public void AddItem(string label, bool isChecked) {
AddItem(label, null, null, isChecked);
}
/// <summary>
/// unchecks all items of the list /// unchecks all items of the list
/// </summary> /// </summary>
public void UncheckAll() { public void UncheckAll() {

View file

@ -647,26 +647,6 @@ namespace Greenshot.Helpers
private readonly byte _wProductType; private readonly byte _wProductType;
private readonly byte _wReserved; private readonly byte _wReserved;
/// <summary>
/// The major version number of the operating system.
/// </summary>
public int MajorVersion => _dwMajorVersion;
/// <summary>
/// The minor version number of the operating system.
/// </summary>
public int MinorVersion => _dwMinorVersion;
/// <summary>
/// The build number of the operating system.
/// </summary>
public int BuildNumber => _dwBuildNumber;
/// <summary>
/// The operating system platform. This member can be VER_PLATFORM_WIN32_NT (2).
/// </summary>
public int PlatformId => _dwPlatformId;
/// <summary> /// <summary>
/// A null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system. /// A null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system.
/// If no Service Pack has been installed, the string is empty. /// If no Service Pack has been installed, the string is empty.
@ -784,11 +764,6 @@ namespace Greenshot.Helpers
} }
} }
/// <summary>
/// Gets the build version number of the operating system running on this computer.
/// </summary>
public static int BuildVersion => Environment.OSVersion.Version.Build;
/// <summary> /// <summary>
/// Gets the full version string of the operating system running on this computer. /// Gets the full version string of the operating system running on this computer.
/// </summary> /// </summary>
@ -807,49 +782,5 @@ namespace Greenshot.Helpers
return $"{Environment.OSVersion.Version.Major}.{Environment.OSVersion.Version.Minor} build {Environment.OSVersion.Version.Build}"; return $"{Environment.OSVersion.Version.Major}.{Environment.OSVersion.Version.Minor} build {Environment.OSVersion.Version.Build}";
} }
} }
/// <summary>
/// Gets the full version of the operating system running on this computer.
/// </summary>
public static Version Version
{
get
{
return Environment.OSVersion.Version;
}
}
/// <summary>
/// Gets the major version number of the operating system running on this computer.
/// </summary>
public static int MajorVersion
{
get
{
return Environment.OSVersion.Version.Major;
}
}
/// <summary>
/// Gets the minor version number of the operating system running on this computer.
/// </summary>
public static int MinorVersion
{
get
{
return Environment.OSVersion.Version.Minor;
}
}
/// <summary>
/// Gets the revision version number of the operating system running on this computer.
/// </summary>
public static int RevisionVersion
{
get
{
return Environment.OSVersion.Version.Revision;
}
}
} }
} }

View file

@ -28,7 +28,7 @@ namespace Greenshot.Helpers {
public static class GuiRectangle { public static class GuiRectangle {
public static Rectangle GetGuiRectangle(int x, int y, int w, int h) { public static Rectangle GetGuiRectangle(int x, int y, int w, int h) {
Rectangle rect = new Rectangle(x, y, w, h); var rect = new Rectangle(x, y, w, h);
MakeGuiRectangle(ref rect); MakeGuiRectangle(ref rect);
return rect; return rect;
} }
@ -43,22 +43,5 @@ namespace Greenshot.Helpers {
rect.Height = -rect.Height; rect.Height = -rect.Height;
} }
} }
}
public static RectangleF GetGuiRectangleF(float x, float y, float w, float h) {
RectangleF rect = new RectangleF(x, y, w, h);
MakeGuiRectangleF(ref rect);
return rect;
}
public static void MakeGuiRectangleF(ref RectangleF rect) {
if (rect.Width < 0) {
rect.X += rect.Width;
rect.Width = -rect.Width;
}
if (rect.Height < 0) {
rect.Y += rect.Height;
rect.Height = -rect.Height;
}
}
}
} }

View file

@ -321,15 +321,7 @@ namespace Greenshot.Helpers {
return returnDocumentContainer; return returnDocumentContainer;
} }
/// <summary> /// <summary>
/// Here the logic for capturing the IE Content is located
/// </summary>
/// <param name="capture">ICapture where the capture needs to be stored</param>
/// <returns>ICapture with the content (if any)</returns>
public static ICapture CaptureIe(ICapture capture) {
return CaptureIe(capture, WindowDetails.GetActiveWindow());
}
/// <summary>
/// Here the logic for capturing the IE Content is located /// Here the logic for capturing the IE Content is located
/// </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>

View file

@ -126,14 +126,7 @@ namespace Greenshot.Helpers {
_manualResetEvent = new ManualResetEvent(false); _manualResetEvent = new ManualResetEvent(false);
} }
/// <summary> /// <summary>
/// Creates a new mail message with the specified subject.
/// </summary>
public MapiMailMessage(string subject) : this() {
Subject = subject;
}
/// <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() {
@ -437,21 +430,6 @@ namespace Greenshot.Helpers {
public MapiMailMessage.RecipientType RecipientType = MapiMailMessage.RecipientType.To; public MapiMailMessage.RecipientType RecipientType = MapiMailMessage.RecipientType.To;
/// <summary> /// <summary>
/// Creates a new recipient with the specified address.
/// </summary>
public Recipient(string address) {
Address = address;
}
/// <summary>
/// Creates a new recipient with the specified address and display name.
/// </summary>
public Recipient(string address, string displayName) {
Address = address;
DisplayName = displayName;
}
/// <summary>
/// Creates a new recipient with the specified address and recipient type. /// Creates a new recipient with the specified address and recipient type.
/// </summary> /// </summary>
public Recipient(string address, MapiMailMessage.RecipientType recipientType) { public Recipient(string address, MapiMailMessage.RecipientType recipientType) {
@ -459,15 +437,6 @@ namespace Greenshot.Helpers {
RecipientType = recipientType; RecipientType = recipientType;
} }
/// <summary>
/// Creates a new recipient with the specified address, display name and recipient type.
/// </summary>
public Recipient(string address, string displayName, MapiMailMessage.RecipientType recipientType) {
Address = address;
DisplayName = displayName;
RecipientType = recipientType;
}
/// <summary> /// <summary>
/// Returns an interop representation of a recepient. /// Returns an interop representation of a recepient.
/// </summary> /// </summary>
@ -499,40 +468,7 @@ namespace Greenshot.Helpers {
List.Add(value); List.Add(value);
} }
/// <summary> internal InteropRecipientCollection GetInteropRepresentation() {
/// Adds a new recipient with the specified address to this collection.
/// </summary>
public void Add(string address) {
Add(new Recipient(address));
}
/// <summary>
/// Adds a new recipient with the specified address and display name to this collection.
/// </summary>
public void Add(string address, string displayName) {
Add(new Recipient(address, displayName));
}
/// <summary>
/// Adds a new recipient with the specified address and recipient type to this collection.
/// </summary>
public void Add(string address, MapiMailMessage.RecipientType recipientType) {
Add(new Recipient(address, recipientType));
}
/// <summary>
/// Adds a new recipient with the specified address, display name and recipient type to this collection.
/// </summary>
public void Add(string address, string displayName, MapiMailMessage.RecipientType recipientType) {
Add(new Recipient(address, displayName, recipientType));
}
/// <summary>
/// Returns the recipient stored in this collection at the specified index.
/// </summary>
public Recipient this[int index] => (Recipient)List[index];
internal InteropRecipientCollection GetInteropRepresentation() {
return new InteropRecipientCollection(this); return new InteropRecipientCollection(this);
} }

View file

@ -101,34 +101,8 @@ namespace Greenshot.Helpers {
} }
return newRect; return newRect;
} }
/// <summary> /// <summary>
/// calculates the Rectangle an element must be resized an positioned to, in ordder to fit another element, keeping aspect ratio
/// </summary>
/// <param name="currentRect">the rectangle of the element to be resized/repositioned</param>
/// <param name="targetRect">the target size/position of the element</param>
/// <param name="crop">in case the aspect ratio of currentSize and targetSize differs: shall the scaled size fit into targetSize (i.e. that one of its dimensions is smaller - false) or vice versa (true)</param>
/// <param name="alignment">the System.Drawing.ContentAlignment value indicating how the element is to be aligned should the width or height differ from targetSize</param>
/// <returns>a new RectangleF object indicating the width and height the element should be scaled to and the position that should be applied to it for proper alignment</returns>
public static RectangleF GetScaledRectangle(RectangleF currentRect, RectangleF targetRect, bool crop, ContentAlignment alignment) {
SizeF newSize = GetScaledSize(currentRect.Size, targetRect.Size, crop);
RectangleF newRect = new RectangleF(new Point(0,0), newSize);
return GetAlignedRectangle(newRect, targetRect, alignment);
}
public static void RationalScale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Rational);
}
public static void CenteredScale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Centered);
}
public static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, null);
}
/// <summary>
/// Calculates target size of a given rectangle scaled by dragging one of its handles (corners) /// Calculates target size of a given rectangle scaled by dragging one of its handles (corners)
/// </summary> /// </summary>
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param> /// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
@ -139,7 +113,7 @@ namespace Greenshot.Helpers {
options ??= GetScaleOptions(); options ??= GetScaleOptions();
if ((options & ScaleOptions.Rational) == ScaleOptions.Rational) { if ((options & ScaleOptions.Rational) == ScaleOptions.Rational) {
adjustCoordsForRationalScale(originalRectangle, resizeHandlePosition, ref resizeHandleCoords); AdjustCoordsForRationalScale(originalRectangle, resizeHandlePosition, ref resizeHandleCoords);
} }
if ((options & ScaleOptions.Centered) == ScaleOptions.Centered) { if ((options & ScaleOptions.Centered) == ScaleOptions.Centered) {
@ -147,15 +121,15 @@ namespace Greenshot.Helpers {
float rectCenterX = originalRectangle.Left + originalRectangle.Width / 2; float rectCenterX = originalRectangle.Left + originalRectangle.Width / 2;
float rectCenterY = originalRectangle.Top + originalRectangle.Height / 2; float rectCenterY = originalRectangle.Top + originalRectangle.Height / 2;
// scale rectangle using handle coordinates // scale rectangle using handle coordinates
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords); Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
// mirror handle coordinates via rectangle center coordinates // mirror handle coordinates via rectangle center coordinates
resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX); resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX);
resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY); resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY);
// scale again with opposing handle and mirrored coordinates // scale again with opposing handle and mirrored coordinates
resizeHandlePosition = (Positions)((((int)resizeHandlePosition) + 4) % 8); resizeHandlePosition = (Positions)((((int)resizeHandlePosition) + 4) % 8);
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords); Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
} else { } else {
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords); Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
} }
} }
@ -166,7 +140,7 @@ namespace Greenshot.Helpers {
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param> /// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param> /// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param> /// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
private static void scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) { private static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
switch(resizeHandlePosition) { switch(resizeHandlePosition) {
case Positions.TopLeft: case Positions.TopLeft:
@ -223,7 +197,7 @@ namespace Greenshot.Helpers {
/// <param name="originalRectangle">bounds of the current rectangle</param> /// <param name="originalRectangle">bounds of the current rectangle</param>
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see Position</param> /// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see Position</param>
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper, adjusted coordinates will be written to this reference</param> /// <param name="resizeHandleCoords">coordinates of the used handle/gripper, adjusted coordinates will be written to this reference</param>
private static void adjustCoordsForRationalScale(RectangleF originalRectangle, Positions resizeHandlePosition, ref PointF resizeHandleCoords) { private static void AdjustCoordsForRationalScale(RectangleF originalRectangle, Positions resizeHandlePosition, ref PointF resizeHandleCoords) {
float originalRatio = originalRectangle.Width / originalRectangle.Height; float originalRatio = originalRectangle.Width / originalRectangle.Height;
float newWidth, newHeight, newRatio; float newWidth, newHeight, newRatio;
switch(resizeHandlePosition) { switch(resizeHandlePosition) {
@ -273,12 +247,8 @@ namespace Greenshot.Helpers {
break; break;
} }
} }
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize) { public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
Scale(boundsBeforeResize, cursorX, cursorY, ref boundsAfterResize, null);
}
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior); Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior);
} }
@ -343,15 +313,6 @@ namespace Greenshot.Helpers {
return Math.Round(angle/15)*15; return Math.Round(angle/15)*15;
} }
} }
public class FixedAngleRoundBehavior : IDoubleProcessor { }
private readonly double fixedAngle;
public FixedAngleRoundBehavior(double fixedAngle) {
this.fixedAngle = fixedAngle;
}
public double Process(double angle) {
return fixedAngle;
}
}
}
} }

View file

@ -54,16 +54,8 @@ namespace Greenshot.Helpers {
public static void Enable(ToolStripItem tsi) { public static void Enable(ToolStripItem tsi) {
Endisable(tsi, true, PropagationMode.CHILDREN | PropagationMode.ANCESTORS); Endisable(tsi, true, PropagationMode.CHILDREN | PropagationMode.ANCESTORS);
} }
/// <summary> private static void Endisable(ToolStrip ts, bool enable, PropagationMode mode)
/// Disables the ToolStripItem, including children (ToolStripDropDownItem),
/// but NOT the ancestor (OwnerItem)
/// </summary>
public static void Disable(ToolStripItem tsi) {
Endisable(tsi, false, PropagationMode.CHILDREN);
}
private static void Endisable(ToolStrip ts, bool enable, PropagationMode mode)
{ {
if ((mode & PropagationMode.CHILDREN) != PropagationMode.CHILDREN) return; if ((mode & PropagationMode.CHILDREN) != PropagationMode.CHILDREN) return;

View file

@ -93,17 +93,6 @@ namespace Greenshot.Helpers
_ = BackgroundTask(() => TimeSpan.FromDays(CoreConfig.UpdateCheckInterval), UpdateCheck, _cancellationTokenSource.Token); _ = BackgroundTask(() => TimeSpan.FromDays(CoreConfig.UpdateCheckInterval), UpdateCheck, _cancellationTokenSource.Token);
} }
/// <summary>
/// Stop the update checks
/// </summary>
public void Shutdown()
{
if (!_cancellationTokenSource.IsCancellationRequested)
{
_cancellationTokenSource.Cancel();
}
}
/// <summary> /// <summary>
/// This runs a periodic task in the background /// This runs a periodic task in the background
/// </summary> /// </summary>

View file

@ -25,6 +25,7 @@ Source: {#ReleaseDir}\Dapplo.Http*.dll; DestDir: {app}; Components: greenshot; F
Source: {#ReleaseDir}\Dapplo.Log.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Dapplo.Log.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Svg.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Svg.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Fizzler.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Fizzler.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\HtmlAgilityPack.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: {#ReleaseDir}\Newtonsoft.Json.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\Newtonsoft.Json.dll; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
Source: ..\..\log4net.xml; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion Source: ..\..\log4net.xml; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion
Source: {#ReleaseDir}\checksum.SHA256; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion Source: {#ReleaseDir}\checksum.SHA256; DestDir: {app}; Components: greenshot; Flags: overwritereadonly ignoreversion replacesameversion
@ -78,11 +79,6 @@ Source: ..\..\Languages\*zh-TW*; Excludes: "*installer*,*website*"; DestDir: {ap
;Office Plugin ;Office Plugin
Source: {#BaseDir}\GreenshotOfficePlugin\{#BinDir}\GreenshotOfficePlugin.dll; DestDir: {app}\Plugins\GreenshotOfficePlugin; Components: plugins\office; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion; Source: {#BaseDir}\GreenshotOfficePlugin\{#BinDir}\GreenshotOfficePlugin.dll; DestDir: {app}\Plugins\GreenshotOfficePlugin; Components: plugins\office; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
;OCR Plugin
Source: {#BaseDir}\GreenshotOCRPlugin\{#BinDir}\GreenshotOCRPlugin.dll; DestDir: {app}\Plugins\GreenshotOCRPlugin; Components: plugins\ocr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\GreenshotOCRPlugin\Languages\language_ocr*.xml; DestDir: {app}\Languages\Plugins\GreenshotOCRPlugin; Components: plugins\ocr; Flags: overwritereadonly ignoreversion replacesameversion;
Source: {#BaseDir}\GreenshotOCRCommand\{#BinDir}\GreenshotOCRCommand.exe; DestDir: {app}\Plugins\GreenshotOCRPlugin; Components: plugins\ocr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\GreenshotOCRCommand\{#BinDir}\GreenshotOCRCommand.exe.config; DestDir: {app}\Plugins\GreenshotOCRPlugin; Components: plugins\ocr; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
;JIRA Plugin ;JIRA Plugin
Source: {#BaseDir}\GreenshotJiraPlugin\{#BinDir}\GreenshotJiraPlugin.dll; DestDir: {app}\Plugins\GreenshotJiraPlugin; Components: plugins\jira; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion; Source: {#BaseDir}\GreenshotJiraPlugin\{#BinDir}\GreenshotJiraPlugin.dll; DestDir: {app}\Plugins\GreenshotJiraPlugin; Components: plugins\jira; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
Source: {#BaseDir}\GreenshotJiraPlugin\{#BinDir}\Dapplo.Jira*.dll; DestDir: {app}\Plugins\GreenshotJiraPlugin; Components: plugins\jira; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion; Source: {#BaseDir}\GreenshotJiraPlugin\{#BinDir}\Dapplo.Jira*.dll; DestDir: {app}\Plugins\GreenshotJiraPlugin; Components: plugins\jira; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
@ -260,7 +256,6 @@ en.flickr=Flickr plug-in
en.imgur=Imgur plug-in (See: http://imgur.com) en.imgur=Imgur plug-in (See: http://imgur.com)
en.jira=Jira plug-in en.jira=Jira plug-in
en.language=Additional languages en.language=Additional languages
en.ocr=OCR plug-in (needs Microsoft Office Document Imaging (MODI))
en.office=Microsoft Office plug-in en.office=Microsoft Office plug-in
en.optimize=Optimizing performance, this may take a while. en.optimize=Optimizing performance, this may take a while.
en.photobucket=Photobucket plug-in en.photobucket=Photobucket plug-in
@ -278,7 +273,6 @@ de.externalcommand=Externes Kommando Plug-in
de.imgur=Imgur Plug-in (Siehe: http://imgur.com) de.imgur=Imgur Plug-in (Siehe: http://imgur.com)
de.jira=Jira Plug-in de.jira=Jira Plug-in
de.language=Zusätzliche Sprachen de.language=Zusätzliche Sprachen
de.ocr=OCR Plug-in (benötigt Microsoft Office Document Imaging (MODI))
de.office=Microsoft Office Plug-in de.office=Microsoft Office Plug-in
de.optimize=Optimierung der Leistung, kann etwas dauern. de.optimize=Optimierung der Leistung, kann etwas dauern.
de.startgreenshot={#ExeName} starten de.startgreenshot={#ExeName} starten
@ -291,7 +285,6 @@ es.externalcommand=Extensión para abrir con programas externos
es.imgur=Extensión para Imgur (Ver http://imgur.com) es.imgur=Extensión para Imgur (Ver http://imgur.com)
es.jira=Extensión para Jira es.jira=Extensión para Jira
es.language=Idiomas adicionales es.language=Idiomas adicionales
es.ocr=Extensión para OCR (necesita Microsoft Office Document Imaging (MODI))
es.optimize=Optimizando rendimiento; por favor, espera. es.optimize=Optimizando rendimiento; por favor, espera.
es.startgreenshot=Lanzar {#ExeName} es.startgreenshot=Lanzar {#ExeName}
es.startup=Lanzar {#ExeName} al iniciarse Windows es.startup=Lanzar {#ExeName} al iniciarse Windows
@ -303,7 +296,6 @@ fi.externalcommand=Avaa Ulkoinen komento-liitännäisellä
fi.imgur=Imgur-liitännäinen (Katso: http://imgur.com) fi.imgur=Imgur-liitännäinen (Katso: http://imgur.com)
fi.jira=Jira-liitännäinen fi.jira=Jira-liitännäinen
fi.language=Lisäkielet fi.language=Lisäkielet
fi.ocr=OCR-liitännäinen (Tarvitaan: Microsoft Office Document Imaging (MODI))
fi.office=Microsoft-Office-liitännäinen fi.office=Microsoft-Office-liitännäinen
fi.optimize=Optimoidaan suorituskykyä, tämä voi kestää hetken. fi.optimize=Optimoidaan suorituskykyä, tämä voi kestää hetken.
fi.startgreenshot=Käynnistä {#ExeName} fi.startgreenshot=Käynnistä {#ExeName}
@ -316,7 +308,6 @@ fr.externalcommand=Ouvrir avec le greffon de commande externe
fr.imgur=Greffon Imgur (Voir: http://imgur.com) fr.imgur=Greffon Imgur (Voir: http://imgur.com)
fr.jira=Greffon Jira fr.jira=Greffon Jira
fr.language=Langues additionnelles fr.language=Langues additionnelles
fr.ocr=Greffon OCR (nécessite Document Imaging de Microsoft Office [MODI])
fr.office=Greffon Microsoft Office fr.office=Greffon Microsoft Office
fr.optimize=Optimisation des performances, Ceci peut prendre un certain temps. fr.optimize=Optimisation des performances, Ceci peut prendre un certain temps.
fr.startgreenshot=Démarrer {#ExeName} fr.startgreenshot=Démarrer {#ExeName}
@ -332,7 +323,6 @@ it.flickr=Plugin Flickr
it.imgur=Plugin Imgur (vedi: http://imgur.com) it.imgur=Plugin Imgur (vedi: http://imgur.com)
it.jira=Plugin Jira it.jira=Plugin Jira
it.language=Lingue aggiuntive it.language=Lingue aggiuntive
it.ocr=Plugin OCR (richiede Microsoft Office Document Imaging (MODI))
it.office=Plugin Microsoft Office it.office=Plugin Microsoft Office
it.optimize=Ottimizzazione prestazioni (può richiedere tempo). it.optimize=Ottimizzazione prestazioni (può richiedere tempo).
it.photobucket=Plugin Photobucket it.photobucket=Plugin Photobucket
@ -386,7 +376,6 @@ lt.externalcommand=Pielāgotu darbību spraudnis
lt.imgur=Imgur spraudnis (Vairāk šeit: http://imgur.com) lt.imgur=Imgur spraudnis (Vairāk šeit: http://imgur.com)
lt.jira=Jira spraudnis lt.jira=Jira spraudnis
lt.language=Papildus valodas lt.language=Papildus valodas
lt.ocr=OCR spraudnis (nepieciešams Microsoft Office Document Imaging (MODI))
lt.office=Microsoft Office spraudnis lt.office=Microsoft Office spraudnis
lt.optimize=Uzlaboju veikstpēju, tas prasīs kādu laiciņu. lt.optimize=Uzlaboju veikstpēju, tas prasīs kādu laiciņu.
lt.startgreenshot=Palaist {#ExeName} lt.startgreenshot=Palaist {#ExeName}
@ -399,7 +388,6 @@ lt.externalcommand=Pielāgotu darbību spraudnis
lt.imgur=Imgur spraudnis (Vairāk šeit: http://imgur.com) lt.imgur=Imgur spraudnis (Vairāk šeit: http://imgur.com)
lt.jira=Jira spraudnis lt.jira=Jira spraudnis
lt.language=Papildus valodas lt.language=Papildus valodas
lt.ocr=OCR spraudnis (nepieciešams Microsoft Office Document Imaging (MODI))
lt.office=Microsoft Office spraudnis lt.office=Microsoft Office spraudnis
lt.optimize=Uzlaboju veikstpēju, tas prasīs kādu laiciņu. lt.optimize=Uzlaboju veikstpēju, tas prasīs kādu laiciņu.
lt.startgreenshot=Palaist {#ExeName} lt.startgreenshot=Palaist {#ExeName}
@ -412,7 +400,6 @@ nl.externalcommand=Openen met extern commando plug-in
nl.imgur=Imgur plug-in (zie: http://imgur.com) nl.imgur=Imgur plug-in (zie: http://imgur.com)
nl.jira=Jira plug-in nl.jira=Jira plug-in
nl.language=Extra talen nl.language=Extra talen
nl.ocr=OCR plug-in (vereist Microsoft Office Document Imaging (MODI))
nl.office=Microsoft Office plug-in nl.office=Microsoft Office plug-in
nl.optimize=Prestaties verbeteren, even geduld. nl.optimize=Prestaties verbeteren, even geduld.
nl.startgreenshot={#ExeName} starten nl.startgreenshot={#ExeName} starten
@ -425,7 +412,6 @@ nn.externalcommand=Tillegg for å opne med ekstern kommando
nn.imgur=Imgur-tillegg (sjå http://imgur.com) nn.imgur=Imgur-tillegg (sjå http://imgur.com)
nn.jira=Jira-tillegg nn.jira=Jira-tillegg
nn.language=Andre språk nn.language=Andre språk
nn.ocr=OCR-tillegg (krev Microsoft Office Document Imaging (MODI))
nn.office=Microsoft Office Tillegg nn.office=Microsoft Office Tillegg
nn.optimize=Optimaliserar ytelse, dette kan ta litt tid... nn.optimize=Optimaliserar ytelse, dette kan ta litt tid...
nn.startgreenshot=Start {#ExeName} nn.startgreenshot=Start {#ExeName}
@ -438,7 +424,6 @@ ru.externalcommand=Открыть с плагином с помощью внеш
ru.imgur=Плагин Imgur (смотрите https://imgur.com/) ru.imgur=Плагин Imgur (смотрите https://imgur.com/)
ru.jira=Плагин Jira ru.jira=Плагин Jira
ru.language=Дополнительные языки ru.language=Дополнительные языки
ru.ocr=Плагин OCR (требуется Microsoft Office Document Imaging (MODI))
ru.office=Плагин Microsoft Office ru.office=Плагин Microsoft Office
ru.optimize=Идет оптимизация производительности, это может занять некоторое время. ru.optimize=Идет оптимизация производительности, это может занять некоторое время.
ru.startgreenshot=Запустить {#ExeName} ru.startgreenshot=Запустить {#ExeName}
@ -451,7 +436,6 @@ sr.externalcommand=Отвори са прикључком за спољне на
sr.imgur=Прикључак за Имиџер (http://imgur.com) sr.imgur=Прикључак за Имиџер (http://imgur.com)
sr.jira=Прикључак за Џиру sr.jira=Прикључак за Џиру
sr.language=Додатни језици sr.language=Додатни језици
sr.ocr=OCR прикључак (захтева Microsoft Office Document Imaging (MODI))
sr.optimize=Оптимизујем перформансе… sr.optimize=Оптимизујем перформансе…
sr.startgreenshot=Покрени Гриншот sr.startgreenshot=Покрени Гриншот
sr.startup=Покрени програм са системом sr.startup=Покрени програм са системом
@ -462,7 +446,6 @@ sv.externalcommand=Öppna med externt kommando-insticksprogram
sv.imgur=Imgur-insticksprogram (Se: http://imgur.com) sv.imgur=Imgur-insticksprogram (Se: http://imgur.com)
sv.jira=Jira-insticksprogram sv.jira=Jira-insticksprogram
sv.language=Ytterligare språk sv.language=Ytterligare språk
sv.ocr=OCR-insticksprogram (kräver Microsoft Office Document Imaging (MODI))
sv.optimize=Optimerar prestanda, detta kan ta en stund. sv.optimize=Optimerar prestanda, detta kan ta en stund.
sv.startgreenshot=Starta {#ExeName} sv.startgreenshot=Starta {#ExeName}
sv.startup=Starta {#ExeName} med Windows sv.startup=Starta {#ExeName} med Windows
@ -474,7 +457,6 @@ uk.externalcommand=Плагін запуску зовнішньої команд
uk.imgur=Плагін Imgur (див.: http://imgur.com) uk.imgur=Плагін Imgur (див.: http://imgur.com)
uk.jira=Плагін Jira uk.jira=Плагін Jira
uk.language=Додаткові мови uk.language=Додаткові мови
uk.ocr=Плагін OCR (потребує Microsoft Office Document Imaging (MODI))
uk.optimize=Оптимізація продуктивності, це може забрати час. uk.optimize=Оптимізація продуктивності, це може забрати час.
uk.startgreenshot=Запустити {#ExeName} uk.startgreenshot=Запустити {#ExeName}
uk.startup=Запускати {#ExeName} під час запуску Windows uk.startup=Запускати {#ExeName} під час запуску Windows
@ -486,7 +468,6 @@ cn.externalcommand=使用外部命令打开插件
cn.imgur=Imgur插件( (请访问: http://imgur.com)) cn.imgur=Imgur插件( (请访问: http://imgur.com))
cn.jira=Jira插件 cn.jira=Jira插件
cn.language=其它语言 cn.language=其它语言
cn.ocr=OCR插件(需要Microsoft Office Document Imaging (MODI)的支持)
cn.optimize=正在优化性能,这可能需要一点时间。 cn.optimize=正在优化性能,这可能需要一点时间。
cn.startgreenshot=启动{#ExeName} cn.startgreenshot=启动{#ExeName}
cn.startup=让{#ExeName}随Windows一起启动 cn.startup=让{#ExeName}随Windows一起启动
@ -508,7 +489,6 @@ Name: "plugins\externalcommand"; Description: {cm:externalcommand}; Types: defau
Name: "plugins\flickr"; Description: {cm:flickr}; Types: full custom; Flags: disablenouninstallwarning Name: "plugins\flickr"; Description: {cm:flickr}; Types: full custom; Flags: disablenouninstallwarning
Name: "plugins\imgur"; Description: {cm:imgur}; Types: default full custom; Flags: disablenouninstallwarning Name: "plugins\imgur"; Description: {cm:imgur}; Types: default full custom; Flags: disablenouninstallwarning
Name: "plugins\jira"; Description: {cm:jira}; Types: full custom; Flags: disablenouninstallwarning Name: "plugins\jira"; Description: {cm:jira}; Types: full custom; Flags: disablenouninstallwarning
Name: "plugins\ocr"; Description: {cm:ocr}; Types: default full custom; Flags: disablenouninstallwarning
Name: "plugins\office"; Description: {cm:office}; Types: default full custom; Flags: disablenouninstallwarning Name: "plugins\office"; Description: {cm:office}; Types: default full custom; Flags: disablenouninstallwarning
Name: "plugins\photobucket"; Description: {cm:photobucket}; Types: full custom; Flags: disablenouninstallwarning Name: "plugins\photobucket"; Description: {cm:photobucket}; Types: full custom; Flags: disablenouninstallwarning
Name: "plugins\picasa"; Description: {cm:picasa}; Types: full custom; Flags: disablenouninstallwarning Name: "plugins\picasa"; Description: {cm:picasa}; Types: full custom; Flags: disablenouninstallwarning

View file

@ -29,10 +29,10 @@ using GreenshotPlugin.IniFile;
namespace GreenshotBoxPlugin { namespace GreenshotBoxPlugin {
/// <summary> /// <summary>
/// Description of ImgurUtils. /// Description of BoxUtils.
/// </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";
@ -121,19 +121,7 @@ namespace GreenshotBoxPlugin {
/// A simple helper class for the DataContractJsonSerializer /// A simple helper class for the DataContractJsonSerializer
/// </summary> /// </summary>
internal static class JsonSerializer { internal static class JsonSerializer {
/// <summary> /// <summary>
/// Helper method to serialize object to JSON
/// </summary>
/// <param name="jsonObject">JSON object</param>
/// <returns>string</returns>
public static string Serialize(object jsonObject) {
var serializer = new DataContractJsonSerializer(jsonObject.GetType());
using MemoryStream stream = new MemoryStream();
serializer.WriteObject(stream, jsonObject);
return Encoding.UTF8.GetString(stream.ToArray());
}
/// <summary>
/// Helper method to parse JSON to object /// Helper method to parse JSON to object
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
@ -141,7 +129,7 @@ namespace GreenshotBoxPlugin {
/// <returns></returns> /// <returns></returns>
public static T Deserialize<T>(string jsonString) { public static T Deserialize<T>(string jsonString) {
var deserializer = new DataContractJsonSerializer(typeof(T)); var deserializer = new DataContractJsonSerializer(typeof(T));
using MemoryStream stream = new MemoryStream(); using var stream = new MemoryStream();
byte[] content = Encoding.UTF8.GetBytes(jsonString); byte[] content = Encoding.UTF8.GetBytes(jsonString);
stream.Write(content, 0, content.Length); stream.Write(content, 0, content.Length);
stream.Seek(0, SeekOrigin.Begin); stream.Seek(0, SeekOrigin.Begin);

View file

@ -21,13 +21,8 @@
namespace GreenshotBoxPlugin { namespace GreenshotBoxPlugin {
public enum LangKey { public enum LangKey {
upload_menu_item, upload_menu_item,
settings_title,
label_upload_format,
upload_success,
upload_failure, upload_failure,
communication_wait, communication_wait,
Configure, Configure
label_AfterUpload,
label_AfterUploadLinkToClipBoard
} }
} }

View file

@ -22,14 +22,7 @@
namespace GreenshotConfluencePlugin { namespace GreenshotConfluencePlugin {
public enum LangKey { public enum LangKey {
login_error, login_error,
login_title,
label_url,
label_upload_format,
OK,
CANCEL,
upload_menu_item, upload_menu_item,
upload_success,
upload_failure,
communication_wait communication_wait
} }
} }

View file

@ -29,12 +29,7 @@ namespace GreenshotConfluencePlugin.Support {
public ITranslationProvider TranslationProvider { get; set; } public ITranslationProvider TranslationProvider { get; set; }
private void OnLanguageChanged() public object Translate(string key) {
{
LanguageChanged?.Invoke(this, EventArgs.Empty);
}
public object Translate(string key) {
object translatedValue = TranslationProvider?.Translate(key); object translatedValue = TranslationProvider?.Translate(key);
if( translatedValue != null) { if( translatedValue != null) {
return translatedValue; return translatedValue;

View file

@ -21,13 +21,8 @@
namespace GreenshotDropboxPlugin { namespace GreenshotDropboxPlugin {
public enum LangKey { public enum LangKey {
upload_menu_item, upload_menu_item,
settings_title,
label_upload_format,
upload_success,
upload_failure, upload_failure,
communication_wait, communication_wait,
Configure, Configure
label_AfterUpload, }
label_AfterUploadLinkToClipBoard
}
} }

View file

@ -21,15 +21,8 @@
namespace GreenshotFlickrPlugin { namespace GreenshotFlickrPlugin {
public enum LangKey { public enum LangKey {
upload_menu_item, upload_menu_item,
settings_title,
label_upload_format,
upload_success,
upload_failure, upload_failure,
communication_wait, communication_wait,
Configure, Configure
label_HiddenFromSearch, }
label_SafetyLevel,
label_AfterUpload,
label_AfterUploadLinkToClipBoard
}
} }

View file

@ -22,19 +22,11 @@
namespace GreenshotImgurPlugin { namespace GreenshotImgurPlugin {
public enum LangKey { public enum LangKey {
upload_menu_item, upload_menu_item,
settings_title,
label_url,
label_upload_format,
label_clear,
OK,
CANCEL,
upload_success,
upload_failure, upload_failure,
communication_wait, communication_wait,
delete_question, delete_question,
clear_question, clear_question,
delete_title, delete_title,
use_page_link,
history, history,
configure configure
} }

View file

@ -80,39 +80,7 @@ namespace GreenshotJiraPlugin
return keyObject.ToString(); return keyObject.ToString();
} }
/// <summary> /// <summary>
/// Get an element from the cache, if this is not available call the create function.
/// </summary>
/// <param name="keyObject">object for the key</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>TResult</returns>
public async Task DeleteAsync(TKey keyObject, CancellationToken cancellationToken = default)
{
var key = CreateKey(keyObject);
await _semaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
_cache.Remove(key);
}
finally
{
_semaphoreSlim.Release();
}
}
/// <summary>
/// Get a task element from the cache, if this is not available return null.
/// You probably want to call GetOrCreateAsync
/// </summary>
/// <param name="keyObject">object for the key</param>
/// <returns>Task with TResult, null if no value</returns>
public Task<TResult> GetAsync(TKey keyObject)
{
var key = CreateKey(keyObject);
return _cache.Get(key) as Task<TResult> ?? EmptyValueTask;
}
/// <summary>
/// Get a task element from the cache, if this is not available call the create function. /// Get a task element from the cache, if this is not available call the create function.
/// </summary> /// </summary>
/// <param name="keyObject">object for the key</param> /// <param name="keyObject">object for the key</param>
@ -124,20 +92,7 @@ namespace GreenshotJiraPlugin
return _cache.Get(key) as Task<TResult> ?? GetOrCreateInternalAsync(keyObject, null, cancellationToken); return _cache.Get(key) as Task<TResult> ?? GetOrCreateInternalAsync(keyObject, null, cancellationToken);
} }
/// <summary> /// <summary>
/// Get a task element from the cache, if this is not available call the create function.
/// </summary>
/// <param name="keyObject">object for the key</param>
/// <param name="cacheItemPolicy">CacheItemPolicy for when you want more control over the item</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>Task with TResult</returns>
public Task<TResult> GetOrCreateAsync(TKey keyObject, CacheItemPolicy cacheItemPolicy, CancellationToken cancellationToken = default)
{
var key = CreateKey(keyObject);
return _cache.Get(key) as Task<TResult> ?? GetOrCreateInternalAsync(keyObject, cacheItemPolicy, cancellationToken);
}
/// <summary>
/// This takes care of the real async part of the code. /// This takes care of the real async part of the code.
/// </summary> /// </summary>
/// <param name="keyObject"></param> /// <param name="keyObject"></param>
@ -213,7 +168,7 @@ namespace GreenshotJiraPlugin
/// Override to know when an item is removed, make sure to configure ActivateUpdateCallback / ActivateRemovedCallback /// Override to know when an item is removed, make sure to configure ActivateUpdateCallback / ActivateRemovedCallback
/// </summary> /// </summary>
/// <param name="cacheEntryRemovedArguments">CacheEntryRemovedArguments</param> /// <param name="cacheEntryRemovedArguments">CacheEntryRemovedArguments</param>
protected virtual void RemovedCallback(CacheEntryRemovedArguments cacheEntryRemovedArguments) protected void RemovedCallback(CacheEntryRemovedArguments cacheEntryRemovedArguments)
{ {
_log.Verbose().WriteLine("Item {0} removed due to {1}.", cacheEntryRemovedArguments.CacheItem.Key, cacheEntryRemovedArguments.RemovedReason); _log.Verbose().WriteLine("Item {0} removed due to {1}.", cacheEntryRemovedArguments.CacheItem.Key, cacheEntryRemovedArguments.RemovedReason);
if (cacheEntryRemovedArguments.CacheItem.Value is IDisposable disposable) if (cacheEntryRemovedArguments.CacheItem.Value is IDisposable disposable)
@ -228,7 +183,7 @@ namespace GreenshotJiraPlugin
/// ActivateUpdateCallback / ActivateRemovedCallback /// ActivateUpdateCallback / ActivateRemovedCallback
/// </summary> /// </summary>
/// <param name="cacheEntryUpdateArguments">CacheEntryUpdateArguments</param> /// <param name="cacheEntryUpdateArguments">CacheEntryUpdateArguments</param>
protected virtual void UpdateCallback(CacheEntryUpdateArguments cacheEntryUpdateArguments) protected void UpdateCallback(CacheEntryUpdateArguments cacheEntryUpdateArguments)
{ {
_log.Verbose().WriteLine("Update request for {0} due to {1}.", cacheEntryUpdateArguments.Key, cacheEntryUpdateArguments.RemovedReason); _log.Verbose().WriteLine("Update request for {0} due to {1}.", cacheEntryUpdateArguments.Key, cacheEntryUpdateArguments.RemovedReason);
} }

View file

@ -34,10 +34,7 @@ namespace GreenshotJiraPlugin {
[IniProperty("Url", Description="Base url to Jira system, without anything else", DefaultValue=DefaultUrl)] [IniProperty("Url", Description="Base url to Jira system, without anything else", DefaultValue=DefaultUrl)]
public string Url { get; set; } public string Url { get; set; }
[IniProperty("Timeout", Description="Session timeout in minutes", DefaultValue="30")] [IniProperty("UploadFormat", Description="What file type to use for uploading", DefaultValue="png")]
public int Timeout { get; set; }
[IniProperty("UploadFormat", Description="What file type to use for uploading", DefaultValue="png")]
public OutputFormat UploadFormat { get; set; } public OutputFormat UploadFormat { get; set; }
[IniProperty("UploadJpegQuality", Description="JPEG file save quality in %.", DefaultValue="80")] [IniProperty("UploadJpegQuality", Description="JPEG file save quality in %.", DefaultValue="80")]

View file

@ -30,16 +30,8 @@ namespace GreenshotJiraPlugin {
column_summary, column_summary,
label_comment, label_comment,
label_filename, label_filename,
label_jira,
label_jirafilter, label_jirafilter,
login_error, login_error,
login_title,
settings_title,
label_url,
label_upload_format,
OK,
CANCEL,
upload_success,
upload_failure, upload_failure,
communication_wait, communication_wait,
} }

View file

@ -1,513 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
namespace GreenshotOCRCommand {
/// <summary>
/// Wraps a late-bound COM server.
/// </summary>
public sealed class COMWrapper : RealProxy, IDisposable, IRemotingTypeInfo {
private const int MK_E_UNAVAILABLE = -2147221021;
private const int CO_E_CLASSSTRING = -2147221005;
/// <summary>
/// Holds reference to the actual COM object which is wrapped by this proxy
/// </summary>
private readonly object _comObject;
/// <summary>
/// Type of the COM object, set on constructor after getting the COM reference
/// </summary>
private readonly Type _comType;
/// <summary>
/// The type of which method calls are intercepted and executed on the COM object.
/// </summary>
private readonly Type _interceptType;
/// <summary>
/// Gets a COM object and returns the transparent proxy which intercepts all calls to the object
/// </summary>
/// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
/// <returns>Transparent proxy to the real proxy for the object</returns>
/// <remarks>T must be an interface decorated with the <see cref="ComProgIdAttribute"/>attribute.</remarks>
public static T GetInstance<T>() {
Type type = typeof(T);
if (null == type) {
throw new ArgumentNullException(nameof(T));
}
if (!type.IsInterface) {
throw new ArgumentException("The specified type must be an interface.", nameof(T));
}
ComProgIdAttribute progIdAttribute = ComProgIdAttribute.GetAttribute(type);
if (string.IsNullOrEmpty(progIdAttribute?.Value)) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", nameof(T));
}
string progId = progIdAttribute.Value;
object comObject = null;
try {
comObject = Marshal.GetActiveObject(progId);
} catch (COMException comE) {
if (comE.ErrorCode == MK_E_UNAVAILABLE)
{
Debug.WriteLine($"No current instance of {progId} object available.");
}
else if (comE.ErrorCode == CO_E_CLASSSTRING)
{
Debug.WriteLine($"Unknown progId {progId}");
}
} catch (Exception ex) {
Debug.WriteLine($"Error getting active object for {progId} {ex.Message}");
}
if (comObject != null) {
COMWrapper wrapper = new COMWrapper(comObject, type);
return (T)wrapper.GetTransparentProxy();
}
return default;
}
/// <summary>
/// Gets or creates a COM object and returns the transparent proxy which intercepts all calls to the object
/// The ComProgId can be a normal ComProgId or a GUID prefixed with "clsid:"
/// </summary>
/// <typeparam name="T">Interface which defines the method and properties to intercept</typeparam>
/// <returns>Transparent proxy to the real proxy for the object</returns>
/// <remarks>The type must be an interface decorated with the <see cref="ComProgIdAttribute"/>attribute.</remarks>
public static T GetOrCreateInstance<T>() {
Type type = typeof(T);
if (null == type) {
throw new ArgumentNullException(nameof(T));
}
if (!type.IsInterface) {
throw new ArgumentException("The specified type must be an interface.", nameof(T));
}
ComProgIdAttribute progIdAttribute = ComProgIdAttribute.GetAttribute(type);
if (string.IsNullOrEmpty(progIdAttribute?.Value)) {
throw new ArgumentException("The specified type must define a ComProgId attribute.", nameof(T));
}
object comObject = null;
Type comType = null;
string progId = progIdAttribute.Value;
try {
comObject = Marshal.GetActiveObject(progId);
} catch (COMException comE) {
if (comE.ErrorCode == MK_E_UNAVAILABLE)
{
Debug.WriteLine($"No current instance of {progId} object available.");
}
else if (comE.ErrorCode == CO_E_CLASSSTRING)
{
Debug.WriteLine($"Unknown progId {progId}");
}
} catch (Exception ex) {
Debug.WriteLine($"Error getting active object for {progId} {ex.Message}");
}
// Did we get the current instance? If not, try to create a new
if (comObject == null) {
try {
comType = Type.GetTypeFromProgID(progId, true);
} catch (Exception) {
Debug.WriteLine($"Error getting type for {progId}");
}
if (comType != null) {
try {
comObject = Activator.CreateInstance(comType);
if (comObject != null) {
Debug.WriteLine($"Created new instance of {progId} object.");
}
} catch (Exception ex) {
Debug.WriteLine($"Error creating object for {progId} {ex.Message}");
}
}
}
if (comObject != null) {
COMWrapper wrapper = new COMWrapper(comObject, type);
return (T)wrapper.GetTransparentProxy();
}
return default;
}
/// <summary>
/// Wrap an object and return the transparent proxy which intercepts all calls to the object
/// </summary>
/// <param name="comObject">An object to intercept</param>
/// <param name="type">Interface which defines the method and properties to intercept</param>
/// <returns>Transparent proxy to the real proxy for the object</returns>
private static object Wrap(object comObject, Type type) {
if (null == comObject) {
throw new ArgumentNullException(nameof(comObject));
}
if (null == type) {
throw new ArgumentNullException(nameof(type));
}
COMWrapper wrapper = new COMWrapper(comObject, type);
return wrapper.GetTransparentProxy();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="comObject">
/// The COM object to wrap.
/// </param>
/// <param name="type">
/// The interface type to impersonate.
/// </param>
private COMWrapper(object comObject, Type type)
: base(type) {
_comObject = comObject;
_comType = comObject.GetType();
_interceptType = type;
}
/// <summary>
/// If <see cref="Dispose"/> is not called, we need to make
/// sure that the COM object is still cleaned up.
/// </summary>
~COMWrapper() {
Dispose(false);
}
/// <summary>
/// Cleans up the COM object.
/// </summary>
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Release the COM reference
/// </summary>
/// <param name="disposing">
/// <see langword="true"/> if this was called from the
/// <see cref="IDisposable"/> interface.
/// </param>
private void Dispose(bool disposing) {
if (disposing && null != _comObject) {
if (Marshal.IsComObject(_comObject)) {
try {
while (Marshal.ReleaseComObject(_comObject) > 0)
{
}
} catch (Exception ex) {
Debug.WriteLine($"Problem releasing {_comType}");
Debug.WriteLine("Error: " + ex);
}
}
}
}
/// <summary>
/// Returns a string representing the wrapped object.
/// </summary>
/// <returns>
/// The full name of the intercepted type.
/// </returns>
public override string ToString() {
return _interceptType.FullName;
}
/// <summary>
/// Returns the hash code of the wrapped object.
/// </summary>
/// <returns>
/// The hash code of the wrapped object.
/// </returns>
public override int GetHashCode() {
return _comObject.GetHashCode();
}
/// <summary>
/// Compares this object to another.
/// </summary>
/// <param name="value">
/// The value to compare to.
/// </param>
/// <returns>
/// <see langword="true"/> if the objects are equal.
/// </returns>
public override bool Equals(object value) {
if (null != value && RemotingServices.IsTransparentProxy(value)) {
if (RemotingServices.GetRealProxy(value) is COMWrapper wrapper) {
return _comObject == wrapper._comObject;
}
}
return base.Equals(value);
}
/// <summary>
/// Returns the base type for a reference type.
/// </summary>
/// <param name="byRefType">
/// The reference type.
/// </param>
/// <returns>
/// The base value type.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="byRefType"/> is <see langword="null"/>.
/// </exception>
private static Type GetByValType(Type byRefType) {
if (null == byRefType) {
throw new ArgumentNullException(nameof(byRefType));
}
if (byRefType.IsByRef) {
string name = byRefType.FullName;
name = name.Substring(0, name.Length - 1);
byRefType = byRefType.Assembly.GetType(name, true);
}
return byRefType;
}
/// <summary>
/// Intercept method calls
/// </summary>
/// <param name="myMessage">
/// Contains information about the method being called
/// </param>
/// <returns>
/// A <see cref="ReturnMessage"/>.
/// </returns>
public override IMessage Invoke(IMessage myMessage) {
IMethodCallMessage callMessage = myMessage as IMethodCallMessage;
MethodInfo method = callMessage?.MethodBase as MethodInfo;
if (method == null)
{
if (callMessage != null)
{
Debug.WriteLine($"Unrecognized Invoke call: {callMessage.MethodBase}");
}
return null;
}
object returnValue = null;
object[] outArgs = null;
int outArgsCount = 0;
string methodName = method.Name;
Type returnType = method.ReturnType;
BindingFlags flags = BindingFlags.InvokeMethod;
int argCount = callMessage.ArgCount;
ParameterModifier[] argModifiers = null;
ParameterInfo[] parameters = null;
if ("Dispose" == methodName && 0 == argCount && typeof(void) == returnType) {
Dispose();
} else if ("ToString" == methodName && 0 == argCount && typeof(string) == returnType) {
returnValue = ToString();
} else if ("GetType" == methodName && 0 == argCount && typeof(Type) == returnType) {
returnValue = _interceptType;
} else if ("GetHashCode" == methodName && 0 == argCount && typeof(int) == returnType) {
returnValue = GetHashCode();
} else if ("Equals" == methodName && 1 == argCount && typeof(bool) == returnType) {
returnValue = Equals(callMessage.Args[0]);
} else if (1 == argCount && typeof(void) == returnType && (methodName.StartsWith("add_") || methodName.StartsWith("remove_"))) {
if (!(callMessage.InArgs[0] is Delegate handler)) {
return new ReturnMessage(new ArgumentNullException(nameof(handler)), callMessage);
}
} else {
var invokeObject = _comObject;
var invokeType = _comType;
ParameterInfo parameter;
object[] args;
if (methodName.StartsWith("get_")) {
// Property Get
methodName = methodName.Substring(4);
flags = BindingFlags.GetProperty;
args = callMessage.InArgs;
} else if (methodName.StartsWith("set_")) {
// Property Set
methodName = methodName.Substring(4);
flags = BindingFlags.SetProperty;
args = callMessage.InArgs;
} else {
args = callMessage.Args;
if (null != args && 0 != args.Length) {
// Modifiers for ref / out parameters
argModifiers = new ParameterModifier[1];
argModifiers[0] = new ParameterModifier(args.Length);
parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++) {
parameter = parameters[i];
if (parameter.IsOut || parameter.ParameterType.IsByRef) {
argModifiers[0][i] = true;
outArgsCount++;
}
}
if (0 == outArgsCount) {
argModifiers = null;
}
}
}
// Un-wrap wrapped COM objects before passing to the method
COMWrapper[] originalArgs;
COMWrapper wrapper;
Type byValType;
if (null == args || 0 == args.Length) {
originalArgs = null;
} else {
originalArgs = new COMWrapper[args.Length];
for (int i = 0; i < args.Length; i++) {
if (null != args[i] && RemotingServices.IsTransparentProxy(args[i])) {
wrapper = RemotingServices.GetRealProxy(args[i]) as COMWrapper;
if (null != wrapper) {
originalArgs[i] = wrapper;
args[i] = wrapper._comObject;
}
} else if (argModifiers != null && (0 != outArgsCount && argModifiers[0][i])) {
byValType = GetByValType(parameters[i].ParameterType);
if (byValType.IsInterface) {
// If we're passing a COM object by reference, and
// the parameter is null, we need to pass a
// DispatchWrapper to avoid a type mismatch exception.
if (null == args[i]) {
args[i] = new DispatchWrapper(null);
}
} else if (typeof(decimal) == byValType) {
// If we're passing a decimal value by reference,
// we need to pass a CurrencyWrapper to avoid a
// type mismatch exception.
// http://support.microsoft.com/?kbid=837378
args[i] = new CurrencyWrapper(args[i]);
}
}
}
}
try {
returnValue = invokeType.InvokeMember(methodName, flags, null, invokeObject, args, argModifiers, null, null);
} catch (Exception ex) {
return new ReturnMessage(ex, callMessage);
}
// Handle enum and interface return types
if (null != returnValue) {
if (returnType.IsInterface) {
// Wrap the returned value in an intercepting COM wrapper
if (Marshal.IsComObject(returnValue)) {
returnValue = Wrap(returnValue, returnType);
}
} else if (returnType.IsEnum) {
// Convert to proper Enum type
returnValue = Enum.Parse(returnType, returnValue.ToString());
}
}
// Handle out args
if (0 != outArgsCount) {
if (args != null && parameters != null)
{
outArgs = new object[args.Length];
for (int i = 0; i < parameters.Length; i++) {
if (argModifiers != null && !argModifiers[0][i]) {
continue;
}
var 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)) {
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;
}
}
}
}
return new ReturnMessage(returnValue, outArgs, outArgsCount, callMessage.LogicalCallContext, callMessage);
}
/// <summary>
/// Implementation for the interface IRemotingTypeInfo
/// This makes it possible to cast the COMWrapper
/// </summary>
/// <param name="toType">Type to cast to</param>
/// <param name="o">object to cast</param>
/// <returns></returns>
public bool CanCastTo(Type toType, object o) {
bool returnValue = _interceptType.IsAssignableFrom(toType);
return returnValue;
}
/// <summary>
/// Implementation for the interface IRemotingTypeInfo
/// </summary>
public string TypeName {
get {
throw new NotSupportedException();
}
set {
throw new NotSupportedException();
}
}
}
}

View file

@ -1,78 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotOCRCommand {
/// <summary>
/// An attribute to specifiy the ProgID of the COM class to create. (As suggested by Kristen Wegner)
/// </summary>
[AttributeUsage(AttributeTargets.Interface)]
public sealed class ComProgIdAttribute : Attribute {
/// <summary>
/// Extracts the attribute from the specified type.
/// </summary>
/// <param name="interfaceType">
/// The interface type.
/// </param>
/// <returns>
/// The <see cref="ComProgIdAttribute"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="interfaceType"/> is <see langword="null"/>.
/// </exception>
public static ComProgIdAttribute GetAttribute(Type interfaceType) {
if (null == interfaceType) {
throw new ArgumentNullException(nameof(interfaceType));
}
Type attributeType = typeof(ComProgIdAttribute);
object[] attributes = interfaceType.GetCustomAttributes(attributeType, false);
if (0 == attributes.Length) {
Type[] interfaces = interfaceType.GetInterfaces();
for (int i = 0; i < interfaces.Length; i++) {
interfaceType = interfaces[i];
attributes = interfaceType.GetCustomAttributes(attributeType, false);
if (0 != attributes.Length) {
break;
}
}
}
if (0 == attributes.Length) {
return null;
}
return (ComProgIdAttribute)attributes[0];
}
/// <summary>Constructor</summary>
/// <param name="value">The COM ProgID.</param>
public ComProgIdAttribute(string value) {
Value = value;
}
/// <summary>
/// Returns the COM ProgID
/// </summary>
public string Value { get; }
}
}

View file

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<RootNamespace>GreenshotOCRCommand</RootNamespace>
<AssemblyName>GreenshotOCRCommand</AssemblyName>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
<Reference Include="CustomMarshalers" />
</ItemGroup>
<Target Name="PostBuild" BeforeTargets="PostBuildEvent" Condition="'$(BuildingInsideVisualStudio)' == 'true'">
<Exec Command="xcopy /q /y /d &quot;$(TargetDir)*.exe&quot; &quot;$(SolutionDir)$(SolutionName)\$(OutDir)&quot;" />
</Target>
</Project>

View file

@ -1,29 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
public enum CompressionLevel {
miCOMP_LEVEL_LOW = 0,
miCOMP_LEVEL_MEDIUM = 1,
miCOMP_LEVEL_HIGH = 2
}
}

View file

@ -1,30 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
public enum FileFormat {
miFILE_FORMAT_DEFAULTVALUE = -1,
miFILE_FORMAT_TIFF = 1,
miFILE_FORMAT_TIFF_LOSSLESS = 2,
miFILE_FORMAT_MDI = 4
}
}

View file

@ -1,32 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Base class for the common properties of the Modi interfaces
/// </summary>
public interface ICommon : IDisposable {
IDocument Application { get; }
}
}

View file

@ -1,33 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.CustomMarshalers;
namespace GreenshotOCRCommand.Modi {
[ComImport, Guid("00020400-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDispatch {
void Reserved();
[PreserveSig]
int GetTypeInfo(uint nInfo, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(TypeToTypeInfoMarshaler))] out Type typeInfo);
}
}

View file

@ -1,79 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi {
/// <summary>
/// The MODI Document object represents an ordered collection of document images saved as a single file.
/// You can use the Create method to load an existing MDI or TIF file, or to create an empty document that you can populate with images from other documents.
/// The OCR method performs OCR on all pages in the document, and the OnOCRProgress event reports the status of the operation and allows the user to cancel it.
/// The Dirty property lets you know whether your document has unsaved OCR results or changes.
/// The SaveAs method allows you to specify an image file format and a compression level.
/// You can also use the PrintOut method to print the document to a printer or a file.
/// </summary>
[ComProgId("MODI.Document")]
public interface IDocument : ICommon {
/// <summary>
/// Closes the document.
/// </summary>
/// <param name="saveCall"></param>
void Close(bool saveCall);
/// <summary>
/// The document's collection of pages.
/// </summary>
IImages Images
{
get;
}
/// <summary>
/// Occurs periodically during an optical character recognition (OCR) operation. Returns the estimated percentage of the OCR operation that is complete, and allows the user to cancel the operation.
/// </summary>
// event OnOCRProgress { get; }
/// <summary>
/// Indicates whether the active document has unsaved changes.
/// </summary>
bool Dirty { get; }
/// <summary>
/// Creates a new document.
/// </summary>
/// <param name="file">Optional String. The path and filename of the optional document file that is to be loaded into the new document.</param>
void Create(string file);
/// <summary>
/// Performs optical character recognition (OCR) on the specified document or image.
/// </summary>
/// <param name="language">ModiLanguage</param>
/// <param name="orientimage">Optional Boolean. Specifies whether the OCR engine attempts to determine the orientation of the page. Default is true.</param>
/// <param name="straightenImage">Optional Boolean. Specifies whether the OCR engine attempts to "de-skew" the page to correct for small angles of misalignment from the vertical. Default is true.</param>
void OCR(ModiLanguage language, bool orientimage, bool straightenImage);
/// <summary>
///
/// </summary>
/// <param name="filename"></param>
/// <param name="fileFormat"></param>
/// <param name="compressionLevel"></param>
void SaveAs(string filename, FileFormat fileFormat, CompressionLevel compressionLevel);
}
}

View file

@ -1,41 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Describes the page in a scan
/// </summary>
public interface IImage : ICommon {
ILayout Layout {
get;
}
long BitsPerPixel { get; }
CompressionLevel Compression { get; }
//IPictureDisp Picture { get; }
int PixelHeight { get; }
int PixelWidth { get; }
//IPictureDisp Thumbnail { get; }
int XDPI { get; }
int YDPI { get; }
}
}

View file

@ -1,41 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections;
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Use the Images accessor property of the Document object to return an Images collection.
/// Use the Item property of the Images collection to return an Image object and gain access to its OCR Layout
/// (including recognized Text and Words), the properties that describe its dimensions and format (BitsPerPixel, Compression, PixelHeight, PixelWidth, XDPI, and YDPI),
/// and its Picture and Thumbnail images.
/// </summary>
public interface IImages : ICommon, IEnumerable {
int Count {
get;
}
IImage this [int index] {
get;
}
new IEnumerator GetEnumerator();
}
}

View file

@ -1,55 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Layout of the IImage
/// </summary>
public interface ILayout : ICommon {
/// <summary>
/// Returns the recognized text as a Unicode string.
/// </summary>
string Text {
get;
}
/// <summary>
/// An accessor property that returns the Words collection recognized in the text during an optical character recognition (OCR) operation.
/// </summary>
IWords Words { get; }
/// <summary>
/// Returns the number of characters in the recognized text.
/// </summary>
int NumChars { get; }
/// <summary>
/// Returns the number of words in the recognized text.
/// </summary>
int NumWords { get; }
/// <summary>
/// Returns the language identifier for the recognized text. Read-only Long.
/// </summary>
ModiLanguage Language { get; }
}
}

View file

@ -1,48 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Represents a bounding rectangle in the optical character recognition (OCR) layout.
/// </summary>
public interface IMiRect : ICommon {
/// <summary>
/// The Bottom property represent the distance in pixels from the top edge of the containing image.
/// </summary>
int Bottom { get; }
/// <summary>
/// The Left property represent the distance in pixels from the left edge of the containing image.
/// </summary>
int Left { get; }
/// <summary>
/// The Right property represent the distance in pixels from the left edge of the containing image.
/// </summary>
int Right { get; }
/// <summary>
/// The Top property represent the distance in pixels from the top edge of the containing image.
/// </summary>
int Top { get; }
}
}

View file

@ -1,38 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections;
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Represents the collection of bounding rectangles in the optical character recognition (OCR) layout. A collection of MiRect objects.
/// </summary>
public interface IMiRects : ICommon, IEnumerable {
int Count {
get;
}
IMiRect this [int index] {
get;
}
new IEnumerator GetEnumerator();
}
}

View file

@ -1,65 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// Represents a word recognized in the text during an optical character recognition (OCR) operation.
/// </summary>
public interface IWord : ICommon
{
/// <summary>
/// Returns the index of the specified word in the Words collection of the Layout or IMiSelectableItem object.
/// </summary>
long Id { get; }
/// <summary>
/// Returns the number of the region in the optical character recognition (OCR) layout where the word occurs.
/// </summary>
long RegionId { get; }
/// <summary>
/// Returns the number of the line in the optical character recognition (OCR) layout where the word occurs.
/// </summary>
long LineId { get; }
/// <summary>
/// Returns the recognized text as a Unicode string.
/// </summary>
string Text { get; }
/// <summary>
/// Returns the relative confidence factor reported by the optical character recognition (OCR) engine (on a scale of 0 to 999) after recognizing the specified word.
/// </summary>
short RecognitionConfidence { get; }
/// <summary>
/// Returns the index of the font used by the specified wordthis is the font that was recognized in the text during an optical character recognition (OCR) operation.
/// </summary>
long FontId { get; }
/// <summary>
/// Rectangles
/// </summary>
IMiRects Rects { get; }
}
}

View file

@ -1,43 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections;
namespace GreenshotOCRCommand.Modi
{
/// <summary>
/// The Words collection recognized in the text during an optical character recognition (OCR) operation.
/// </summary>
public interface IWords : ICommon, IEnumerable
{
int Count
{
get;
}
IWord this[int index]
{
get;
}
new IEnumerator GetEnumerator();
}
}

View file

@ -1,48 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRCommand.Modi
{
public enum ModiLanguage {
CHINESE_SIMPLIFIED = 2052,
CHINESE_TRADITIONAL = 1028,
CZECH = 5,
DANISH = 6,
DUTCH = 19,
ENGLISH = 9,
FINNISH = 11,
FRENCH = 12,
GERMAN = 7,
GREEK = 8,
HUNGARIAN = 14,
ITALIAN = 16,
JAPANESE = 17,
KOREAN = 18,
NORWEGIAN = 20,
POLISH = 21,
PORTUGUESE = 22,
RUSSIAN = 25,
SPANISH = 10,
SWEDISH = 29,
TURKISH = 31,
SYSDEFAULT = 2048
}
}

View file

@ -1,121 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using GreenshotOCRCommand.Modi;
namespace GreenshotOCRCommand {
public class Program {
private const string Usage = "<-c> | <path to image.bmp> [language] [orientimage] [straightenImage]";
public static int Main(string[] args) {
if (args.Length == 0) {
Console.WriteLine(Usage);
return -1;
}
string filename = args[0];
ModiLanguage language = ModiLanguage.ENGLISH;
if (args.Length >= 2) {
language = (ModiLanguage)Enum.Parse(typeof(ModiLanguage), args[1]);
}
bool orientimage = true;
if (args.Length >= 3) {
orientimage = bool.Parse(args[2]);
}
bool straightenImage = true;
if (args.Length >= 4) {
straightenImage = bool.Parse(args[3]);
}
try {
if (File.Exists(filename) || "-c".Equals(filename))
{
using var document = COMWrapper.GetOrCreateInstance<IDocument>();
if (document == null) {
Console.WriteLine("MODI not installed");
return -2;
}
if ("-c".Equals(filename)) {
return 0;
}
document.Create(filename);
document.OCR(language, orientimage, straightenImage);
var modiImage = document.Images[0];
var layout = modiImage.Layout;
if (layout != null)
{
#if DEBUG
if (layout.Words != null)
{
foreach (var word in ToEnumerable(layout.Words))
{
if (word.Rects != null)
{
foreach (var rect in ToEnumerable(word.Rects))
{
Debug.WriteLine($"Rect {rect.Left},{rect.Top},{rect.Right},{rect.Bottom} - Word {word.Text} : Confidence: {word.RecognitionConfidence}");
}
}
}
}
#endif
if (layout.Text != null)
{
// For for BUG-1884:
// Although trim is done in the OCR Plugin, it does make sense in the command too.
Console.WriteLine(layout.Text.Trim());
}
}
document.Close(false);
return 0;
}
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
return -1;
}
/// <summary>
/// Helper method
/// </summary>
/// <returns>IEnumerable of IMiRect</returns>
private static IEnumerable<IMiRect> ToEnumerable(IMiRects rects)
{
for (int i = 0; i < rects.Count; i++)
{
yield return rects[i];
}
}
/// <summary>
/// Helper method
/// </summary>
/// <returns>IEnumerable of IWord</returns>
private static IEnumerable<IWord> ToEnumerable(IWords words)
{
for (int i = 0; i < words.Count; i++)
{
yield return words[i];
}
}
}
}

View file

@ -1,36 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Reflection;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind.
[assembly: AssemblyDescription("A small executable to OCR a bitmap")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("d7668e7e-3018-4d27-9aa0-21b1afade1b8")]

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>

View file

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<RootNamespace>GreenshotOCRPlugin</RootNamespace>
<AssemblyName>GreenshotOCRPlugin</AssemblyName>
</PropertyGroup>
<ItemGroup>
<None Include="Languages\language*.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj" />
</ItemGroup>
</Project>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Czech" ietf="cs-CZ" version="1.1.0.2411" languagegroup="">
<resources>
<resource name="language">Jazyk pro OCR</resource>
<resource name="orient_image">Orientaci obrázku</resource>
<resource name="straighten_image">Srovnat obrázek</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Deutsch" ietf="de-DE" version="1.0.0">
<resources>
<resource name="language">
Sprache für OCR
</resource>
<resource name="orient_image">
Bild ausrichten
</resource>
<resource name="straighten_image">
Bild glätten
</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="English" ietf="en-US" version="1.0.0">
<resources>
<resource name="language">
Language for OCR
</resource>
<resource name="orient_image">
Orient image
</resource>
<resource name="straighten_image">
Straighten image
</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Français" ietf="fr-FR" version="1.0.0" languagegroup="">
<resources>
<resource name="language">Langage pour l'OCR</resource>
<resource name="orient_image">Orienter l'image</resource>
<resource name="straighten_image">Redresser l'image</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Bahasa Indonesia" ietf="id-ID" version="1.0.0.0" languagegroup="">
<resources>
<resource name="language">Bahasa untuk OCR</resource>
<resource name="orient_image">Orientasikan gambar</resource>
<resource name="straighten_image">Rapikan gambar</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Italiano" ietf="it-IT" version="1.0.1">
<resources>
<resource name="language">
Lingua OCR
</resource>
<resource name="orient_image">
Orientamento immagine
</resource>
<resource name="straighten_image">
Raddrizza immagine
</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="日本語" ietf="ja-JP" version="1.0.0">
<resources>
<resource name="language">OCRの言語</resource>
<resource name="orient_image">画像の向きを揃える</resource>
<resource name="straighten_image">画像の傾きを補正する</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="language">Tutlayt i OCR</resource>
<resource name="orient_image">Wehhi tugna</resource>
<resource name="straighten_image">Seggwem tugna</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="korean" ietf="ko-KR" version="1.0.0">
<resources>
<resource name="language">
OCR 언어
</resource>
<resource name="orient_image">
가로 이미지
</resource>
<resource name="straighten_image">
세로 이미지
</resource>
</resources>
</language>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Translated by Kārlis Kalviškis (eko@lanet.lv) 2014.12.17. -->
<language description="Latviski" ietf="lv-LV" version="0.1.0">
<resources>
<resource name="language">
OCR valoda
</resource>
<resource name="orient_image">
Pagriezt attēlu
</resource>
<resource name="straighten_image">
Iztaisnot attēlu
</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Nederlands" ietf="nl-NL" version="1.0.0">
<resources>
<resource name="language">
Taal voor OCR
</resource>
<resource name="orient_image">
Beeld richten
</resource>
<resource name="straighten_image">
Beeld vereffenen
</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Polski" ietf="pl-PL" version="1.1.4" languagegroup="2">
<resources>
<resource name="language">Język dla OCR</resource>
<resource name="orient_image">Orientacja obrazu</resource>
<resource name="straighten_image">Wyprostowanie obrazów</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Portuguese (Portugal)" ietf="pt-PT" version="1.0.0">
<resources>
<resource name="language">Idioma para OCR</resource>
<resource name="orient_image">Orientar imagem</resource>
<resource name="straighten_image">Endireitar imagem</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Русский" ietf="ru-RU" version="1.1.4.2622" languagegroup="5">
<resources>
<resource name="language">Язык для OCR</resource>
<resource name="orient_image">Ориентация изображения</resource>
<resource name="straighten_image">Выпрямление изображения</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Slovenčina" ietf="sk-SK" version="1.0.0">
<resources>
<resource name="language">
Jazyk pre OCR
</resource>
<resource name="orient_image">
Orientácia obrázku
</resource>
<resource name="straighten_image">
Narovnať obrázok
</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Српски" ietf="sr-RS" version="1.0.0" languagegroup="">
<resources>
<resource name="language">Језик за препознавање знакова</resource>
<resource name="orient_image">Усмери слику</resource>
<resource name="straighten_image">Исправи слику</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Svenska" ietf="sv-SE" version="1.0.0">
<resources>
<resource name="language">
Språk för OCR
</resource>
<resource name="orient_image">
Orientera bild
</resource>
<resource name="straighten_image">
Släta ut bild
</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Українська" ietf="uk-UA" version="1.0.0">
<resources>
<resource name="language">Мова для ОРТ</resource>
<resource name="orient_image">Орієнтувати зображення</resource>
<resource name="straighten_image">Випрямлення зображення</resource>
</resources>
</language>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="简体中文" ietf="zh-CN" version="1.0.0">
<resources>
<resource name="language">
OCR语言
</resource>
<resource name="orient_image">
图像定位
</resource>
<resource name="straighten_image">
图像矫正
</resource>
</resources>
</language>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="正體中文" ietf="zh-TW" version="1.0.0" languagegroup="9">
<resources>
<resource name="language">OCR 語言</resource>
<resource name="orient_image">定向圖片</resource>
<resource name="straighten_image">拉直圖片</resource>
</resources>
</language>

View file

@ -1,50 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRPlugin
{
/// <summary>
/// Needed for the drop down, available languages for OCR
/// </summary>
public enum ModiLanguage {
CHINESE_SIMPLIFIED = 2052,
CHINESE_TRADITIONAL = 1028,
CZECH = 5,
DANISH = 6,
DUTCH = 19,
ENGLISH = 9,
FINNISH = 11,
FRENCH = 12,
GERMAN = 7,
GREEK = 8,
HUNGARIAN = 14,
ITALIAN = 16,
JAPANESE = 17,
KOREAN = 18,
NORWEGIAN = 20,
POLISH = 21,
PORTUGUESE = 22,
RUSSIAN = 25,
SPANISH = 10,
SWEDISH = 29,
TURKISH = 31,
SYSDEFAULT = 2048
}
}

View file

@ -1,37 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using GreenshotPlugin.IniFile;
namespace GreenshotOCRPlugin {
/// <summary>
/// Description of CoreConfiguration.
/// </summary>
[IniSection("OCR", Description="Greenshot OCR Plugin configuration")]
public class OCRConfiguration : IniSection {
[IniProperty("Language", Description="Language for OCR", DefaultValue="miLANG_ENGLISH")]
public string Language { get; set; }
[IniProperty("orientimage", Description="Orient image?", DefaultValue="true")]
public bool Orientimage { get; set; }
[IniProperty("straightenImage", Description="Straighten image?", DefaultValue="true")]
public bool StraightenImage { get; set; }
}
}

View file

@ -1,60 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Drawing;
using System.IO;
using GreenshotPlugin.Core;
using GreenshotPlugin.Interfaces;
namespace GreenshotOCRPlugin {
/// <summary>
/// Description of OCRDestination.
/// </summary>
public class OCRDestination : AbstractDestination {
private readonly OcrPlugin _plugin;
public override string Designation => "OCR";
public override string Description => "OCR";
public override Image DisplayIcon {
get {
string exePath = PluginUtils.GetExePath("MSPVIEW.EXE");
if (exePath != null && File.Exists(exePath)) {
return PluginUtils.GetCachedExeIcon(exePath, 0);
}
return null;
}
}
public OCRDestination(OcrPlugin plugin) {
_plugin = plugin;
}
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description)
{
ExportMade = _plugin.DoOcr(surface) != null
};
return exportInformation;
}
}
}

View file

@ -1,30 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using GreenshotPlugin.Controls;
namespace GreenshotOCRPlugin {
/// <summary>
/// This class is needed for design-time resolving of the language files
/// </summary>
public class OcrForm : GreenshotForm {
}
}

View file

@ -1,206 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using GreenshotPlugin.Core;
using GreenshotPlugin.Effects;
using GreenshotPlugin.IniFile;
using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Plugin;
//using Microsoft.Win32;
namespace GreenshotOCRPlugin {
/// <summary>
/// OCR Plugin Greenshot
/// </summary>
[Plugin("Ocr", true)]
public class OcrPlugin : IGreenshotPlugin {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(OcrPlugin));
private string _ocrCommand;
private static OCRConfiguration _config;
private ToolStripMenuItem _ocrMenuItem = new ToolStripMenuItem();
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (!disposing) return;
if (_ocrMenuItem == null) return;
_ocrMenuItem.Dispose();
_ocrMenuItem = null;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public bool Initialize() {
Log.Debug("Initialize called");
var ocrDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
if (ocrDirectory == null)
{
return false;
}
_ocrCommand = Path.Combine(ocrDirectory, "greenshotocrcommand.exe");
if (!HasModi()) {
Log.Warn("No MODI found!");
return false;
}
// Provide the IDestination
SimpleServiceProvider.Current.AddService<IDestination>(new OCRDestination(this));
// Load configuration
_config = IniConfig.GetIniSection<OCRConfiguration>();
if (_config.Language != null) {
_config.Language = _config.Language.Replace("miLANG_", string.Empty).Replace("_"," ");
}
return true;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Shutdown
/// </summary>
public void Shutdown() {
Log.Debug("Shutdown");
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public void Configure() {
if (!HasModi()) {
MessageBox.Show("Sorry, is seems that Microsoft Office Document Imaging (MODI) is not installed, therefor the OCR Plugin cannot work.");
return;
}
SettingsForm settingsForm = new SettingsForm(Enum.GetNames(typeof(ModiLanguage)), _config);
DialogResult result = settingsForm.ShowDialog();
if (result == DialogResult.OK) {
// "Re"set hotkeys
IniConfig.Save();
}
}
private const int MinWidth = 130;
private const int MinHeight = 130;
/// <summary>
/// Handling of the CaptureTaken "event" from the ICaptureHost
/// We do the OCR here!
/// </summary>
/// <param name="surface">Has the Image and the capture details</param>
public string DoOcr(ISurface surface) {
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 0, true)
{
ReduceColors = true,
SaveBackgroundOnly = true
};
// We only want the background
// Force Grayscale output
outputSettings.Effects.Add(new GrayscaleEffect());
// Also we need to check the size, resize if needed to 130x130 this is the minimum
if (surface.Image.Width < MinWidth || surface.Image.Height < MinHeight) {
int addedWidth = MinWidth - surface.Image.Width;
if (addedWidth < 0) {
addedWidth = 0;
}
int addedHeight = MinHeight - surface.Image.Height;
if (addedHeight < 0) {
addedHeight = 0;
}
IEffect effect = new ResizeCanvasEffect(addedWidth / 2, addedWidth / 2, addedHeight / 2, addedHeight / 2);
outputSettings.Effects.Add(effect);
}
var filePath = ImageOutput.SaveToTmpFile(surface, outputSettings, null);
Log.Debug("Saved tmp file to: " + filePath);
string text = "";
try {
ProcessStartInfo processStartInfo = new ProcessStartInfo(_ocrCommand, "\"" + filePath + "\" " + _config.Language + " " + _config.Orientimage + " " + _config.StraightenImage)
{
CreateNoWindow = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
using Process process = Process.Start(processStartInfo);
if (process != null)
{
process.WaitForExit(30 * 1000);
if (process.ExitCode == 0) {
text = process.StandardOutput.ReadToEnd();
}
}
} catch (Exception e) {
Log.Error("Error while calling Microsoft Office Document Imaging (MODI) to OCR: ", e);
} finally {
if (File.Exists(filePath)) {
Log.Debug("Cleaning up tmp file: " + filePath);
File.Delete(filePath);
}
}
if (string.IsNullOrEmpty(text)) {
Log.Info("No text returned");
return null;
}
// For for BUG-1884:
text = text.Trim();
try {
Log.DebugFormat("Pasting OCR Text to Clipboard: {0}", text);
// Paste to Clipboard (the Plugin currently doesn't have access to the ClipboardHelper from Greenshot
IDataObject ido = new DataObject();
ido.SetData(DataFormats.Text, true, text);
Clipboard.SetDataObject(ido, true);
} catch (Exception e) {
Log.Error("Problem pasting text to clipboard: ", e);
}
return text;
}
private bool HasModi() {
try
{
using Process process = Process.Start(_ocrCommand, "-c");
if (process != null)
{
process.WaitForExit();
return process.ExitCode == 0;
}
} catch(Exception e) {
Log.DebugFormat("Error trying to initiate MODI: {0}", e.Message);
}
Log.InfoFormat("No Microsoft Office Document Imaging (MODI) found, disabling OCR");
return false;
}
}
}

View file

@ -1,146 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GreenshotOCRPlugin
{
partial class SettingsForm
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.comboBox_languages = new System.Windows.Forms.ComboBox();
this.checkBox_orientImage = new GreenshotPlugin.Controls.GreenshotCheckBox();
this.checkBox_straightenImage = new GreenshotPlugin.Controls.GreenshotCheckBox();
this.label_language = new GreenshotPlugin.Controls.GreenshotLabel();
this.buttonOK = new GreenshotPlugin.Controls.GreenshotButton();
this.buttonCancel = new GreenshotPlugin.Controls.GreenshotButton();
this.SuspendLayout();
//
// comboBox_languages
//
this.comboBox_languages.FormattingEnabled = true;
this.comboBox_languages.Items.AddRange(new object[] {
"English",
"Deutsch"});
this.comboBox_languages.Location = new System.Drawing.Point(74, 12);
this.comboBox_languages.Name = "comboBox_languages";
this.comboBox_languages.Size = new System.Drawing.Size(153, 21);
this.comboBox_languages.TabIndex = 1;
//
// checkBox_orientImage
//
this.checkBox_orientImage.LanguageKey = "ocr.orient_image";
this.checkBox_orientImage.Location = new System.Drawing.Point(13, 68);
this.checkBox_orientImage.Name = "checkBox_orientImage";
this.checkBox_orientImage.PropertyName = "orientimage";
this.checkBox_orientImage.SectionName = "OCR";
this.checkBox_orientImage.Size = new System.Drawing.Size(104, 24);
this.checkBox_orientImage.TabIndex = 3;
this.checkBox_orientImage.UseVisualStyleBackColor = true;
//
// checkBox_straightenImage
//
this.checkBox_straightenImage.LanguageKey = "ocr.straighten_image";
this.checkBox_straightenImage.Location = new System.Drawing.Point(13, 41);
this.checkBox_straightenImage.Name = "checkBox_straightenImage";
this.checkBox_straightenImage.PropertyName = "straightenImage";
this.checkBox_straightenImage.SectionName = "OCR";
this.checkBox_straightenImage.Size = new System.Drawing.Size(109, 24);
this.checkBox_straightenImage.TabIndex = 2;
this.checkBox_straightenImage.UseVisualStyleBackColor = true;
//
// label_language
//
this.label_language.LanguageKey = "ocr.language";
this.label_language.Location = new System.Drawing.Point(13, 15);
this.label_language.Name = "label_language";
this.label_language.Size = new System.Drawing.Size(55, 23);
this.label_language.TabIndex = 3;
//
// buttonOK
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.buttonOK.LanguageKey = "OK";
this.buttonOK.Location = new System.Drawing.Point(12, 98);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(104, 23);
this.buttonOK.TabIndex = 4;
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.ButtonOKClick);
//
// buttonCancel
//
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.LanguageKey = "CANCEL";
this.buttonCancel.Location = new System.Drawing.Point(128, 98);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(104, 23);
this.buttonCancel.TabIndex = 5;
this.buttonCancel.UseVisualStyleBackColor = true;
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(244, 135);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonOK);
this.Controls.Add(this.label_language);
this.Controls.Add(this.checkBox_straightenImage);
this.Controls.Add(this.checkBox_orientImage);
this.Controls.Add(this.comboBox_languages);
this.LanguageKey = "settings_title";
this.Name = "SettingsForm";
this.ResumeLayout(false);
}
private GreenshotPlugin.Controls.GreenshotLabel label_language;
private GreenshotPlugin.Controls.GreenshotButton buttonCancel;
private GreenshotPlugin.Controls.GreenshotButton buttonOK;
private GreenshotPlugin.Controls.GreenshotCheckBox checkBox_orientImage;
private GreenshotPlugin.Controls.GreenshotCheckBox checkBox_straightenImage;
private System.Windows.Forms.ComboBox comboBox_languages;
}
}

View file

@ -1,65 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotOCRPlugin {
/// <summary>
/// Description of SettingsForm.
/// </summary>
public partial class SettingsForm : OcrForm {
private readonly OCRConfiguration _config;
public SettingsForm(string [] languages, OCRConfiguration config) {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
this._config = config;
InitializeComponent();
AcceptButton = buttonOK;
CancelButton = buttonCancel;
comboBox_languages.Items.Clear();
int index=0;
// Preventing Tracker #3234560, although this should not happen...
string languageFromConfig = "ENGLISH";
if (config.Language != null) {
languageFromConfig = config.Language;
}
foreach(string availableLanguage in languages) {
string displayLanguage = availableLanguage.Substring(0, 1).ToUpper() + availableLanguage.Substring(1).ToLower();
comboBox_languages.Items.Add(displayLanguage);
if (availableLanguage.Equals(languageFromConfig, StringComparison.CurrentCultureIgnoreCase)) {
comboBox_languages.SelectedIndex = index;
}
index++;
}
}
private void ButtonOKClick(object sender, EventArgs e) {
string selectedString = (string) comboBox_languages.SelectedItem;
if (selectedString != null) {
_config.Language = selectedString.ToUpper();
}
}
}
}

View file

@ -27,21 +27,6 @@ namespace GreenshotOfficePlugin.Com
return clsId; return clsId;
} }
/// <summary>
/// This converts a clsid (Class ID) into a ProgID (program ID)
/// </summary>
/// <param name="clsId">Guid with the clsid (Class ID)</param>
/// <returns>string with the progid</returns>
public static string ProgIdFromClassId(Guid clsId)
{
if (ProgIDFromCLSID(ref clsId, out string progId).Succeeded())
{
return progId;
}
return null;
}
/// <summary> /// <summary>
/// See more <a href="https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-clsidfromprogid">here</a> /// See more <a href="https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-clsidfromprogid">here</a>
/// </summary> /// </summary>
@ -50,14 +35,5 @@ namespace GreenshotOfficePlugin.Com
/// <returns>HResult</returns> /// <returns>HResult</returns>
[DllImport("ole32.dll", ExactSpelling = true)] [DllImport("ole32.dll", ExactSpelling = true)]
private static extern HResult CLSIDFromProgID([In] [MarshalAs(UnmanagedType.LPWStr)] string progId, [Out] out Guid clsId); private static extern HResult CLSIDFromProgID([In] [MarshalAs(UnmanagedType.LPWStr)] string progId, [Out] out Guid clsId);
/// <summary>
/// See more <a href="https://docs.microsoft.com/en-us/windows/desktop/api/combaseapi/nf-combaseapi-progidfromclsid">here</a>
/// </summary>
/// <param name="clsId">Guid The CLSID for which the ProgID is to be requested.</param>
/// <param name="lplpszProgId">string the ProgID string. The string that represents clsid includes enclosing braces.</param>
/// <returns>HResult</returns>
[DllImport("ole32.dll")]
private static extern HResult ProgIDFromCLSID([In] ref Guid clsId, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgId);
} }
} }

View file

@ -22,13 +22,8 @@
namespace GreenshotPhotobucketPlugin { namespace GreenshotPhotobucketPlugin {
public enum LangKey { public enum LangKey {
upload_menu_item, upload_menu_item,
settings_title,
label_upload_format,
label_clear,
upload_success,
upload_failure, upload_failure,
communication_wait, communication_wait,
use_page_link,
configure configure
} }
} }

View file

@ -20,7 +20,6 @@
*/ */
using System; using System;
using System.Drawing; using System.Drawing;
using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
@ -30,23 +29,8 @@ namespace GreenshotPlugin.Controls {
/// </summary> /// </summary>
public sealed partial class BackgroundForm : Form { public sealed partial class BackgroundForm : Form {
private volatile bool _shouldClose; private volatile bool _shouldClose;
private void BackgroundShowDialog() {
ShowDialog();
}
public static BackgroundForm ShowAndWait(string title, string text) { public BackgroundForm(string title, string text){
BackgroundForm backgroundForm = new BackgroundForm(title, text);
// Show form in background thread
Thread backgroundTask = new Thread (backgroundForm.BackgroundShowDialog);
backgroundForm.Name = "Background form";
backgroundTask.IsBackground = true;
backgroundTask.SetApartmentState(ApartmentState.STA);
backgroundTask.Start();
return backgroundForm;
}
public BackgroundForm(string title, string text){
// //
// The InitializeComponent() call is required for Windows Forms designer support. // The InitializeComponent() call is required for Windows Forms designer support.
// //

View file

@ -426,11 +426,7 @@ namespace GreenshotPlugin.Controls {
_hotkeyHwnd = hWnd; _hotkeyHwnd = hWnd;
} }
public static int RegisterHotKey(string hotkey, HotKeyHandler handler) { /// <summary>
return RegisterHotKey(HotkeyModifiersFromString(hotkey), HotkeyFromString(hotkey),handler);
}
/// <summary>
/// Register a hotkey /// Register a hotkey
/// </summary> /// </summary>
/// <param name="modifierKeyCode">The modifier, e.g.: Modifiers.CTRL, Modifiers.NONE or Modifiers.ALT</param> /// <param name="modifierKeyCode">The modifier, e.g.: Modifiers.CTRL, Modifiers.NONE or Modifiers.ALT</param>
@ -477,21 +473,7 @@ namespace GreenshotPlugin.Controls {
KeyHandlers.Clear(); KeyHandlers.Clear();
} }
public static void UnregisterHotkey(int hotkey) { /// <summary>
bool removeHotkey = false;
foreach(int availableHotkey in KeyHandlers.Keys) {
if (availableHotkey == hotkey) {
UnregisterHotKey(_hotkeyHwnd, hotkey);
removeHotkey = true;
}
}
if (removeHotkey) {
// Remove key handler
KeyHandlers.Remove(hotkey);
}
}
/// <summary>
/// Handle WndProc messages for the hotkey /// Handle WndProc messages for the hotkey
/// </summary> /// </summary>
/// <param name="m"></param> /// <param name="m"></param>

View file

@ -91,35 +91,7 @@ namespace GreenshotPlugin.Core {
} }
} }
public void ActivateIETab(string tabCaptionToActivate) { public void ActivateIETab(int tabIndexToActivate) {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
if (tab.Name == tabCaptionToActivate) {
tab.Activate();
return;
}
}
}
}
}
public void CloseIETab(string tabCaptionToClose) {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
if (tab.Name == tabCaptionToClose) {
foreach (var CloseTab in tab.Children) {
CloseTab.Activate();
}
return;
}
}
}
}
}
public void ActivateIETab(int tabIndexToActivate) {
var index = 0; var index = 0;
foreach (Accessible accessor in Children) { foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) { foreach (var child in accessor.Children) {
@ -138,50 +110,7 @@ namespace GreenshotPlugin.Core {
} }
} }
public string IEActiveTabUrl { public string IEActiveTabCaption {
get {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
object tabIndex = tab.accessible.get_accState(CHILDID_SELF);
if ((int)tabIndex == IE_ACTIVE_TAB) {
var description = tab.accessible.get_accDescription(CHILDID_SELF);
if (!string.IsNullOrEmpty(description)) {
if (description.Contains(Environment.NewLine)) {
var url = description.Substring(description.IndexOf(Environment.NewLine)).Trim();
return url;
}
}
}
}
}
}
return string.Empty;
}
}
public int IEActiveTabIndex {
get {
var index = 0;
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
object tabIndex = tab.accessible.get_accState(0);
if ((int)tabIndex == IE_ACTIVE_TAB) {
return index;
}
index++;
}
}
}
return -1;
}
}
public string IEActiveTabCaption {
get { get {
foreach (Accessible accessor in Children) { foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) { foreach (var child in accessor.Children) {
@ -238,21 +167,8 @@ namespace GreenshotPlugin.Core {
} }
} }
} }
public int IETabCount {
get {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
return child.ChildCount - 1;
}
}
}
return 0;
}
}
private Accessible(IAccessible acc) { private Accessible(IAccessible acc) {
accessible = acc ?? throw new Exception(); accessible = acc ?? throw new Exception();
} }

View file

@ -1,5 +1,25 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using GreenshotPlugin.Interfaces; using GreenshotPlugin.Interfaces;
@ -14,7 +34,6 @@ namespace GreenshotPlugin.Core
/// </summary> /// </summary>
public class Capture : ICapture { public class Capture : ICapture {
private static readonly ILog Log = LogManager.GetLogger(typeof(Capture)); private static readonly ILog Log = LogManager.GetLogger(typeof(Capture));
private List<ICaptureElement> _elements = new List<ICaptureElement>();
private Rectangle _screenBounds; private Rectangle _screenBounds;
/// <summary> /// <summary>
@ -178,15 +197,6 @@ namespace GreenshotPlugin.Core
// TODO: Remove invisible lines/words? // TODO: Remove invisible lines/words?
CaptureDetails.OcrInformation?.Offset(-cropRectangle.Location.X, -cropRectangle.Location.Y); CaptureDetails.OcrInformation?.Offset(-cropRectangle.Location.X, -cropRectangle.Location.Y);
// Remove invisible elements
var visibleElements = new List<ICaptureElement>();
foreach(var captureElement in _elements) {
if (captureElement.Bounds.IntersectsWith(cropRectangle)) {
visibleElements.Add(captureElement);
}
}
_elements = visibleElements;
return true; return true;
} }

View file

@ -1,3 +1,24 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using GreenshotPlugin.Interfaces; using GreenshotPlugin.Interfaces;

View file

@ -1,48 +0,0 @@
using System.Collections.Generic;
using System.Drawing;
using GreenshotPlugin.Interfaces;
namespace GreenshotPlugin.Core
{
/// <summary>
/// A class representing an element in the capture
/// </summary>
public class CaptureElement : ICaptureElement {
public CaptureElement(Rectangle bounds) {
Bounds = bounds;
}
public CaptureElement(string name) {
Name = name;
}
public CaptureElement(string name, Rectangle bounds) {
Name = name;
Bounds = bounds;
}
public List<ICaptureElement> Children { get; set; } = new List<ICaptureElement>();
public string Name {
get;
set;
}
public Rectangle Bounds {
get;
set;
}
// CaptureElements are regarded equal if their bounds are equal. this should be sufficient.
public override bool Equals(object obj) {
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return obj is CaptureElement other && Bounds.Equals(other.Bounds);
}
public override int GetHashCode() {
// TODO: Fix this, this is not right...
return Bounds.GetHashCode();
}
}
}

View file

@ -34,7 +34,9 @@ using System.Runtime.InteropServices;
using GreenshotPlugin.IniFile; using GreenshotPlugin.IniFile;
using GreenshotPlugin.Interfaces; using GreenshotPlugin.Interfaces;
using GreenshotPlugin.Interfaces.Plugin; using GreenshotPlugin.Interfaces.Plugin;
using GreenshotPlugin.Interop;
using log4net; using log4net;
using HtmlDocument = HtmlAgilityPack.HtmlDocument;
namespace GreenshotPlugin.Core { namespace GreenshotPlugin.Core {
/// <summary> /// <summary>
@ -45,7 +47,8 @@ namespace GreenshotPlugin.Core {
private static readonly object ClipboardLockObject = new object(); private static readonly object ClipboardLockObject = new object();
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly string FORMAT_FILECONTENTS = "FileContents"; private static readonly string FORMAT_FILECONTENTS = "FileContents";
private static readonly string FORMAT_PNG = "PNG"; private static readonly string FORMAT_HTML = "text/html";
private static readonly string FORMAT_PNG = "PNG";
private static readonly string FORMAT_PNG_OFFICEART = "PNG+Office Art"; private static readonly string FORMAT_PNG_OFFICEART = "PNG+Office Art";
private static readonly string FORMAT_17 = "Format17"; private static readonly string FORMAT_17 = "Format17";
private static readonly string FORMAT_JPG = "JPG"; private static readonly string FORMAT_JPG = "JPG";
@ -207,17 +210,8 @@ EndSelection:<<<<<<<4
} }
return null; return null;
} }
/// <summary>
/// Wrapper for Clipboard.ContainsText, Created for Bug #3432313
/// </summary>
/// <returns>boolean if there is text on the clipboard</returns>
public static bool ContainsText() {
IDataObject clipboardData = GetDataObject();
return ContainsText(clipboardData);
}
/// <summary> /// <summary>
/// Test if the IDataObject contains Text /// Test if the IDataObject contains Text
/// </summary> /// </summary>
/// <param name="dataObject"></param> /// <param name="dataObject"></param>
@ -246,41 +240,124 @@ EndSelection:<<<<<<<4
/// <param name="dataObject"></param> /// <param name="dataObject"></param>
/// <returns>true if an image is there</returns> /// <returns>true if an image is there</returns>
public static bool ContainsImage(IDataObject dataObject) { public static bool ContainsImage(IDataObject dataObject) {
if (dataObject != null) { if (dataObject == null) return false;
if (dataObject.GetDataPresent(DataFormats.Bitmap)
|| dataObject.GetDataPresent(DataFormats.Dib) if (dataObject.GetDataPresent(DataFormats.Bitmap)
|| dataObject.GetDataPresent(DataFormats.Tiff) || dataObject.GetDataPresent(DataFormats.Dib)
|| dataObject.GetDataPresent(DataFormats.EnhancedMetafile) || dataObject.GetDataPresent(DataFormats.Tiff)
|| dataObject.GetDataPresent(FORMAT_PNG) || dataObject.GetDataPresent(DataFormats.EnhancedMetafile)
|| dataObject.GetDataPresent(FORMAT_17) || dataObject.GetDataPresent(FORMAT_PNG)
|| dataObject.GetDataPresent(FORMAT_JPG) || dataObject.GetDataPresent(FORMAT_17)
|| dataObject.GetDataPresent(FORMAT_JFIF) || dataObject.GetDataPresent(FORMAT_JPG)
|| dataObject.GetDataPresent(FORMAT_JPEG) || dataObject.GetDataPresent(FORMAT_JFIF)
|| dataObject.GetDataPresent(FORMAT_GIF)) { || dataObject.GetDataPresent(FORMAT_JPEG)
return true; || dataObject.GetDataPresent(FORMAT_GIF)) {
} return true;
var imageFiles = GetImageFilenames(dataObject); }
if (imageFiles.Any()) {
return true; var imageFiles = GetImageFilenames(dataObject);
} if (imageFiles.Any()) {
if (dataObject.GetDataPresent(FORMAT_FILECONTENTS)) { return true;
try { }
MemoryStream imageStream = dataObject.GetData(FORMAT_FILECONTENTS) as MemoryStream;
if (IsValidStream(imageStream)) { var fileDescriptor = (MemoryStream)dataObject.GetData("FileGroupDescriptorW");
using (ImageHelper.FromStream(imageStream)) var files = FileDescriptorReader.Read(fileDescriptor);
{ var fileIndex = 0;
// If we get here, there is an image foreach (var fileContentFile in files)
return true; {
} if ((fileContentFile.FileAttributes & FileAttributes.Directory) != 0)
} {
} catch (Exception) { //Do something with directories?
// Ignore //Note that directories do not have FileContents
} //And will throw if we try to read them
} continue;
} }
return false;
var fileData = FileDescriptorReader.GetFileContents(dataObject, fileIndex);
try
{
//Do something with the fileContent Stream
if (IsValidStream(fileData))
{
fileData.Position = 0;
using (ImageHelper.FromStream(fileData))
{
// If we get here, there is an image
return true;
}
}
}
finally
{
fileData?.Dispose();
}
fileIndex++;
}
if (dataObject.GetDataPresent(FORMAT_FILECONTENTS))
{
try
{
var clipboardContent = dataObject.GetData(FORMAT_FILECONTENTS, true);
var imageStream = clipboardContent as MemoryStream;
if (IsValidStream(imageStream))
{
using (ImageHelper.FromStream(imageStream))
{
// If we get here, there is an image
return true;
}
}
}
catch (Exception)
{
// Ignore
}
}
// Try to get the image from the HTML code
var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8);
if (textObject != null)
{
var doc = new HtmlDocument();
doc.LoadHtml(textObject);
var imgNodes = doc.DocumentNode.SelectNodes("//img");
if (imgNodes != null)
{
foreach (var imgNode in imgNodes)
{
var srcAttribute = imgNode.Attributes["src"];
var imageUrl = srcAttribute.Value;
if (!string.IsNullOrEmpty(imageUrl))
{
return true;
}
}
}
}
return false;
} }
/// <summary>
/// Get the specified IDataObject format as a string
/// </summary>
/// <param name="dataObject">IDataObject</param>
/// <param name="format">string</param>
/// <param name="encoding">Encoding</param>
/// <returns>sting</returns>
private static string ContentAsString(IDataObject dataObject, string format, Encoding encoding = null)
{
encoding ??= Encoding.Unicode;
var objectAsFormat = dataObject.GetData(format);
return objectAsFormat switch
{
null => null,
string text => text,
MemoryStream ms => encoding.GetString(ms.ToArray()),
_ => null
};
}
/// <summary> /// <summary>
/// Simple helper to check the stream /// Simple helper to check the stream
/// </summary> /// </summary>
@ -348,9 +425,9 @@ EndSelection:<<<<<<<4
if (formats != null && formats.Contains(FORMAT_PNG_OFFICEART) && formats.Contains(DataFormats.Dib)) { if (formats != null && formats.Contains(FORMAT_PNG_OFFICEART) && formats.Contains(DataFormats.Dib)) {
// Outlook ?? // Outlook ??
Log.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front..."); Log.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front...");
retrieveFormats = new[] { DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, FORMAT_GIF }; retrieveFormats = new[] { DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, FORMAT_GIF, FORMAT_HTML };
} else { } else {
retrieveFormats = new[] { FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_GIF }; retrieveFormats = new[] { FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_GIF, FORMAT_HTML };
} }
foreach (string currentFormat in retrieveFormats) { foreach (string currentFormat in retrieveFormats) {
if (formats != null && formats.Contains(currentFormat)) { if (formats != null && formats.Contains(currentFormat)) {
@ -376,8 +453,32 @@ EndSelection:<<<<<<<4
/// <param name="dataObject">IDataObject</param> /// <param name="dataObject">IDataObject</param>
/// <returns>Image or null</returns> /// <returns>Image or null</returns>
private static Image GetImageForFormat(string format, IDataObject dataObject) { private static Image GetImageForFormat(string format, IDataObject dataObject) {
if (format == FORMAT_HTML)
{
var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8);
if (textObject != null)
{
var doc = new HtmlDocument();
doc.LoadHtml(textObject);
var imgNodes = doc.DocumentNode.SelectNodes("//img");
if (imgNodes != null)
{
foreach (var imgNode in imgNodes)
{
var srcAttribute = imgNode.Attributes["src"];
var imageUrl = srcAttribute.Value;
Log.Debug(imageUrl);
var image = NetworkHelper.DownloadImage(imageUrl);
if (image != null)
{
return image;
}
}
}
}
}
object clipboardObject = GetFromDataObject(dataObject, format); object clipboardObject = GetFromDataObject(dataObject, format);
MemoryStream imageStream = clipboardObject as MemoryStream; var imageStream = clipboardObject as MemoryStream;
if (!IsValidStream(imageStream)) { if (!IsValidStream(imageStream)) {
// TODO: add "HTML Format" support here... // TODO: add "HTML Format" support here...
return clipboardObject as Image; return clipboardObject as Image;
@ -390,14 +491,14 @@ EndSelection:<<<<<<<4
{ {
byte[] dibBuffer = new byte[imageStream.Length]; byte[] dibBuffer = new byte[imageStream.Length];
imageStream.Read(dibBuffer, 0, dibBuffer.Length); imageStream.Read(dibBuffer, 0, dibBuffer.Length);
BITMAPINFOHEADER infoHeader = BinaryStructHelper.FromByteArray<BITMAPINFOHEADER>(dibBuffer); var infoHeader = BinaryStructHelper.FromByteArray<BITMAPINFOHEADER>(dibBuffer);
if (!infoHeader.IsDibV5) { if (!infoHeader.IsDibV5) {
Log.InfoFormat("Using special DIB <v5 format reader with biCompression {0}", infoHeader.biCompression); Log.InfoFormat("Using special DIB <v5 format reader with biCompression {0}", infoHeader.biCompression);
int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER)); int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
uint infoHeaderSize = infoHeader.biSize; uint infoHeaderSize = infoHeader.biSize;
int fileSize = (int)(fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage); int fileSize = (int)(fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage);
BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER var fileHeader = new BITMAPFILEHEADER
{ {
bfType = BITMAPFILEHEADER.BM, bfType = BITMAPFILEHEADER.BM,
bfSize = fileSize, bfSize = fileSize,
@ -408,7 +509,7 @@ EndSelection:<<<<<<<4
byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader); byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);
using MemoryStream bitmapStream = new MemoryStream(); using var bitmapStream = new MemoryStream();
bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize); bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
bitmapStream.Write(dibBuffer, 0, dibBuffer.Length); bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
bitmapStream.Seek(0, SeekOrigin.Begin); bitmapStream.Seek(0, SeekOrigin.Begin);
@ -459,6 +560,7 @@ EndSelection:<<<<<<<4
} catch (Exception streamImageEx) { } catch (Exception streamImageEx) {
Log.Error($"Problem retrieving {format} from clipboard.", streamImageEx); Log.Error($"Problem retrieving {format} from clipboard.", streamImageEx);
} }
return null; return null;
} }
@ -706,16 +808,8 @@ EndSelection:<<<<<<<4
// Use false to make the object disappear when the application stops. // Use false to make the object disappear when the application stops.
SetDataObject(dataObj, true); SetDataObject(dataObj, true);
} }
/// <summary>
/// Retrieve a list of all formats currently on the clipboard
/// </summary>
/// <returns>List of strings with the current formats</returns>
public static List<string> GetFormats() {
return GetFormats(GetDataObject());
}
/// <summary> /// <summary>
/// Retrieve a list of all formats currently in the IDataObject /// Retrieve a list of all formats currently in the IDataObject
/// </summary> /// </summary>
/// <returns>List of string with the current formats</returns> /// <returns>List of string with the current formats</returns>
@ -732,16 +826,7 @@ EndSelection:<<<<<<<4
return new List<string>(); return new List<string>();
} }
/// <summary> /// <summary>
/// Check if there is currently something in the dataObject which has the supplied format
/// </summary>
/// <param name="format">string with format</param>
/// <returns>true if one the format is found</returns>
public static bool ContainsFormat(string format) {
return ContainsFormat(GetDataObject(), new[]{format});
}
/// <summary>
/// Check if there is currently something on the clipboard which has the supplied format /// Check if there is currently something on the clipboard which has the supplied format
/// </summary> /// </summary>
/// <param name="dataObject">IDataObject</param> /// <param name="dataObject">IDataObject</param>
@ -781,17 +866,7 @@ EndSelection:<<<<<<<4
return formatFound; return formatFound;
} }
/// <summary> /// <summary>
/// Get Object of type Type from the clipboard
/// </summary>
/// <param name="type">Type to get</param>
/// <returns>object from clipboard</returns>
public static object GetClipboardData(Type type) {
string format = type.FullName;
return GetClipboardData(format);
}
/// <summary>
/// Get Object for format from IDataObject /// Get Object for format from IDataObject
/// </summary> /// </summary>
/// <param name="dataObj">IDataObject</param> /// <param name="dataObj">IDataObject</param>
@ -837,14 +912,5 @@ EndSelection:<<<<<<<4
} }
return null; return null;
} }
}
/// <summary>
/// Get Object for format from the clipboard
/// </summary>
/// <param name="format">format to get</param>
/// <returns>object from clipboard</returns>
public static object GetClipboardData(string format) {
return GetFromDataObject(GetDataObject(), format);
}
}
} }

View file

@ -305,25 +305,7 @@ namespace GreenshotPlugin.Core {
[IniProperty("WebRequestReadWriteTimeout", Description = "The read/write timeout value for webrequets, these are seconds", DefaultValue = "100")] [IniProperty("WebRequestReadWriteTimeout", Description = "The read/write timeout value for webrequets, these are seconds", DefaultValue = "100")]
public int WebRequestReadWriteTimeout { get; set; } public int WebRequestReadWriteTimeout { get; set; }
/// <summary> public bool UseLargeIcons => IconSize.Width >= 32 || IconSize.Height >= 32;
/// Specifies what THIS build is
/// </summary>
public BuildStates BuildState {
get {
string informationalVersion = Application.ProductVersion;
if (informationalVersion != null) {
if (informationalVersion.ToLowerInvariant().Contains("-rc")) {
return BuildStates.RELEASE_CANDIDATE;
}
if (informationalVersion.ToLowerInvariant().Contains("-unstable")) {
return BuildStates.UNSTABLE;
}
}
return BuildStates.RELEASE;
}
}
public bool UseLargeIcons => IconSize.Width >= 32 || IconSize.Height >= 32;
/// <summary> /// <summary>
/// A helper method which returns true if the supplied experimental feature is enabled /// A helper method which returns true if the supplied experimental feature is enabled

View file

@ -242,68 +242,14 @@ namespace GreenshotPlugin.Core {
} }
} }
/// <summary>Shows the credentials dialog.</summary> /// <summary>Shows the credentials dialog with the specified name.</summary>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show() {
return Show(null, Name, Password, SaveChecked);
}
/// <summary>Shows the credentials dialog with the specified save checkbox status.</summary>
/// <param name="saveChecked">True if the save checkbox is checked.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(bool saveChecked) {
return Show(null, Name, Password, saveChecked);
}
/// <summary>Shows the credentials dialog with the specified name.</summary>
/// <param name="name">The name for the credentials.</param> /// <param name="name">The name for the credentials.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns> /// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(string name) { public DialogResult Show(string name) {
return Show(null, name, Password, SaveChecked); return Show(null, name, Password, SaveChecked);
} }
/// <summary>Shows the credentials dialog with the specified name and password.</summary> /// <summary>Shows the credentials dialog with the specified owner, name, password and save checkbox status.</summary>
/// <param name="name">The name for the credentials.</param>
/// <param name="password">The password for the credentials.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(string name, string password) {
return Show(null, name, password, SaveChecked);
}
/// <summary>Shows the credentials dialog with the specified name, password and save checkbox status.</summary>
/// <param name="name">The name for the credentials.</param>
/// <param name="password">The password for the credentials.</param>
/// <param name="saveChecked">True if the save checkbox is checked.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(string name, string password, bool saveChecked) {
return Show(null, name, password, saveChecked);
}
/// <summary>Shows the credentials dialog with the specified owner.</summary>
/// <param name="owner">The System.Windows.Forms.IWin32Window the dialog will display in front of.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(IWin32Window owner) {
return Show(owner, Name, Password, SaveChecked);
}
/// <summary>Shows the credentials dialog with the specified owner and save checkbox status.</summary>
/// <param name="owner">The System.Windows.Forms.IWin32Window the dialog will display in front of.</param>
/// <param name="saveChecked">True if the save checkbox is checked.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(IWin32Window owner, bool saveChecked) {
return Show(owner, Name, Password, saveChecked);
}
/// <summary>Shows the credentials dialog with the specified owner, name and password.</summary>
/// <param name="owner">The System.Windows.Forms.IWin32Window the dialog will display in front of.</param>
/// <param name="name">The name for the credentials.</param>
/// <param name="password">The password for the credentials.</param>
/// <returns>Returns a DialogResult indicating the user action.</returns>
public DialogResult Show(IWin32Window owner, string name, string password) {
return Show(owner, name, password, SaveChecked);
}
/// <summary>Shows the credentials dialog with the specified owner, name, password and save checkbox status.</summary>
/// <param name="owner">The System.Windows.Forms.IWin32Window the dialog will display in front of.</param> /// <param name="owner">The System.Windows.Forms.IWin32Window the dialog will display in front of.</param>
/// <param name="name">The name for the credentials.</param> /// <param name="name">The name for the credentials.</param>
/// <param name="password">The password for the credentials.</param> /// <param name="password">The password for the credentials.</param>
@ -450,7 +396,6 @@ namespace GreenshotPlugin.Core {
public const int MAX_MESSAGE_LENGTH = 100; public const int MAX_MESSAGE_LENGTH = 100;
public const int MAX_CAPTION_LENGTH = 100; public const int MAX_CAPTION_LENGTH = 100;
public const int MAX_GENERIC_TARGET_LENGTH = 100; public const int MAX_GENERIC_TARGET_LENGTH = 100;
public const int MAX_DOMAIN_TARGET_LENGTH = 100;
public const int MAX_USERNAME_LENGTH = 100; public const int MAX_USERNAME_LENGTH = 100;
public const int MAX_PASSWORD_LENGTH = 100; public const int MAX_PASSWORD_LENGTH = 100;
@ -463,20 +408,12 @@ namespace GreenshotPlugin.Core {
public enum CredFlags { public enum CredFlags {
INCORRECT_PASSWORD = 0x1, INCORRECT_PASSWORD = 0x1,
DO_NOT_PERSIST = 0x2, DO_NOT_PERSIST = 0x2,
REQUEST_ADMINISTRATOR = 0x4,
EXCLUDE_CERTIFICATES = 0x8, EXCLUDE_CERTIFICATES = 0x8,
REQUIRE_CERTIFICATE = 0x10,
SHOW_SAVE_CHECK_BOX = 0x40, SHOW_SAVE_CHECK_BOX = 0x40,
ALWAYS_SHOW_UI = 0x80, ALWAYS_SHOW_UI = 0x80,
REQUIRE_SMARTCARD = 0x100,
PASSWORD_ONLY_OK = 0x200,
VALIDATE_USERNAME = 0x400,
COMPLETE_USERNAME = 0x800,
PERSIST = 0x1000, PERSIST = 0x1000,
SERVER_CREDENTIAL = 0x4000,
EXPECT_CONFIRMATION = 0x20000, EXPECT_CONFIRMATION = 0x20000,
GENERIC_CREDENTIALS = 0x40000, GENERIC_CREDENTIALS = 0x40000,
USERNAME_TARGET_CREDENTIALS = 0x80000,
KEEP_USERNAME = 0x100000, KEEP_USERNAME = 0x100000,
} }

View file

@ -1,8 +1,28 @@
using GreenshotPlugin.Core.Enums; /*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using GreenshotPlugin.Core.Enums;
using GreenshotPlugin.UnmanagedHelpers; using GreenshotPlugin.UnmanagedHelpers;
using log4net; using log4net;
using System; using System;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using GreenshotPlugin.UnmanagedHelpers.Enums; using GreenshotPlugin.UnmanagedHelpers.Enums;
@ -59,23 +79,6 @@ namespace GreenshotPlugin.Core
return dpiScaleFactor * someNumber; return dpiScaleFactor * someNumber;
} }
/// <summary>
/// Scale the supplied number according to the supplied dpi
/// </summary>
/// <param name="number">int with e.g. 16 for 16x16 images</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>Scaled width</returns>
public static int ScaleWithDpi(int number, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiScaleFactor = DpiScaleFactor(dpi);
if (scaleModifier != null)
{
dpiScaleFactor = scaleModifier(dpiScaleFactor);
}
return (int)(dpiScaleFactor * number);
}
/// <summary> /// <summary>
/// Scale the supplied Size according to the supplied dpi /// Scale the supplied Size according to the supplied dpi
/// </summary> /// </summary>
@ -93,79 +96,6 @@ namespace GreenshotPlugin.Core
return new Size((int)(dpiScaleFactor * size.Width), (int)(dpiScaleFactor * size.Height)); return new Size((int)(dpiScaleFactor * size.Width), (int)(dpiScaleFactor * size.Height));
} }
/// <summary>
/// Scale the supplied NativePoint according to the supplied dpi
/// </summary>
/// <param name="size">NativePoint to resize</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativePoint scaled</returns>
public static Point ScaleWithDpi(Point size, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiScaleFactor = DpiScaleFactor(dpi);
if (scaleModifier != null)
{
dpiScaleFactor = scaleModifier(dpiScaleFactor);
}
return new Point((int)(dpiScaleFactor * size.X), (int)(dpiScaleFactor * size.Y));
}
/// <summary>
/// Scale the supplied NativeSizeFloat according to the supplied dpi
/// </summary>
/// <param name="point">PointF</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>PointF</returns>
public static PointF ScaleWithDpi(PointF point, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiScaleFactor = DpiScaleFactor(dpi);
if (scaleModifier != null)
{
dpiScaleFactor = scaleModifier(dpiScaleFactor);
}
return new PointF(dpiScaleFactor * point.X, dpiScaleFactor * point.Y);
}
/// <summary>
/// Scale the supplied NativeSizeFloat according to the supplied dpi
/// </summary>
/// <param name="size">NativeSizeFloat to resize</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativeSize scaled</returns>
public static SizeF ScaleWithDpi(SizeF size, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiScaleFactor = DpiScaleFactor(dpi);
if (scaleModifier != null)
{
dpiScaleFactor = scaleModifier(dpiScaleFactor);
}
return new SizeF(dpiScaleFactor * size.Width, dpiScaleFactor * size.Height);
}
/// <summary>
/// Scale the supplied number to the current dpi
/// </summary>
/// <param name="someNumber">double with e.g. a width like 16 for 16x16 images</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>double with scaled number</returns>
public static float ScaleWithCurrentDpi(float someNumber, Func<float, float> scaleModifier = null)
{
return ScaleWithDpi(someNumber, Dpi, scaleModifier);
}
/// <summary>
/// Scale the supplied number to the current dpi
/// </summary>
/// <param name="someNumber">int with e.g. a width like 16 for 16x16 images</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>int with scaled number</returns>
public static int ScaleWithCurrentDpi(int someNumber, Func<float, float> scaleModifier = null)
{
return ScaleWithDpi(someNumber, Dpi, scaleModifier);
}
/// <summary> /// <summary>
/// Scale the supplied NativeSize to the current dpi /// Scale the supplied NativeSize to the current dpi
/// </summary> /// </summary>
@ -177,282 +107,6 @@ namespace GreenshotPlugin.Core
return ScaleWithDpi(size, Dpi, scaleModifier); return ScaleWithDpi(size, Dpi, scaleModifier);
} }
/// <summary>
/// Scale the supplied NativeSizeFloat to the current dpi
/// </summary>
/// <param name="size">NativeSizeFloat to scale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativeSizeFloat scaled</returns>
public static SizeF ScaleWithCurrentDpi(SizeF size, Func<float, float> scaleModifier = null)
{
return ScaleWithDpi(size, Dpi, scaleModifier);
}
/// <summary>
/// Scale the supplied NativePoint to the current dpi
/// </summary>
/// <param name="point">NativePoint to scale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativePoint scaled</returns>
public static Point ScaleWithCurrentDpi(Point point, Func<float, float> scaleModifier = null)
{
return ScaleWithDpi(point, Dpi, scaleModifier);
}
/// <summary>
/// Scale the supplied PointF to the current dpi
/// </summary>
/// <param name="point">PointF to scale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>PointF scaled</returns>
public static PointF ScaleWithCurrentDpi(PointF point, Func<float, float> scaleModifier = null)
{
return ScaleWithDpi(point, Dpi, scaleModifier);
}
/// <summary>
/// Calculate a DPI unscale factor
/// </summary>
/// <param name="dpi">uint</param>
/// <returns>float</returns>
public static float DpiUnscaleFactor(uint dpi)
{
return (float)DefaultScreenDpi / dpi;
}
/// <summary>
/// Unscale the supplied number according to the supplied dpi
/// </summary>
/// <param name="someNumber">double with e.g. the scaled width</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>double with the unscaled number</returns>
public static float UnscaleWithDpi(float someNumber, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
if (scaleModifier != null)
{
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
}
return dpiUnscaleFactor * someNumber;
}
/// <summary>
/// Unscale the supplied number according to the supplied dpi
/// </summary>
/// <param name="number">int with a scaled width</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>Unscaled width</returns>
public static int UnscaleWithDpi(int number, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
if (scaleModifier != null)
{
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
}
return (int)(dpiUnscaleFactor * number);
}
/// <summary>
/// Unscale the supplied NativeSize according to the supplied dpi
/// </summary>
/// <param name="size">NativeSize to unscale</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>Size unscaled</returns>
public static Size UnscaleWithDpi(Size size, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
if (scaleModifier != null)
{
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
}
return new Size((int)(dpiUnscaleFactor * size.Width), (int)(dpiUnscaleFactor * size.Height));
}
/// <summary>
/// Unscale the supplied Point according to the supplied dpi
/// </summary>
/// <param name="size">Point to unscale</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>Point unscaled</returns>
public static Point UnscaleWithDpi(Point point, uint dpi, Func<float, float> scaleModifier = null)
{
var dpiUnscaleFactor = DpiUnscaleFactor(dpi);
if (scaleModifier != null)
{
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
}
return new Point((int)(dpiUnscaleFactor * point.X), (int)(dpiUnscaleFactor * point.Y));
}
/// <summary>
/// unscale the supplied NativeSizeFloat according to the supplied dpi
/// </summary>
/// <param name="size">NativeSizeFloat to resize</param>
/// <param name="dpi">current dpi, normal is 96.</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>SizeF unscaled</returns>
public static SizeF UnscaleWithDpi(SizeF size, uint dpi, Func<float, float> scaleModifier = null)
{
float dpiUnscaleFactor = DpiUnscaleFactor(dpi);
if (scaleModifier != null)
{
dpiUnscaleFactor = scaleModifier(dpiUnscaleFactor);
}
return new SizeF(dpiUnscaleFactor * size.Width, dpiUnscaleFactor * size.Height);
}
/// <summary>
/// Unscale the supplied number to the current dpi
/// </summary>
/// <param name="someNumber">double with e.g. a width like 16 for 16x16 images</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>double with unscaled number</returns>
public static float UnscaleWithCurrentDpi(float someNumber, Func<float, float> scaleModifier = null)
{
return UnscaleWithDpi(someNumber, Dpi, scaleModifier);
}
/// <summary>
/// Unscale the supplied number to the current dpi
/// </summary>
/// <param name="someNumber">int with e.g. a width like 16 for 16x16 images</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>int with unscaled number</returns>
public static int UnscaleWithCurrentDpi(int someNumber, Func<float, float> scaleModifier = null)
{
return UnscaleWithDpi(someNumber, Dpi, scaleModifier);
}
/// <summary>
/// Unscale the supplied NativeSize to the current dpi
/// </summary>
/// <param name="size">Size to unscale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>Size unscaled</returns>
public static Size UnscaleWithCurrentDpi(Size size, Func<float, float> scaleModifier = null)
{
return UnscaleWithDpi(size, Dpi, scaleModifier);
}
/// <summary>
/// Unscale the supplied NativeSizeFloat to the current dpi
/// </summary>
/// <param name="size">NativeSizeFloat to unscale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativeSizeFloat unscaled</returns>
public static SizeF UnscaleWithCurrentDpi(SizeF size, Func<float, float> scaleModifier = null)
{
return UnscaleWithDpi(size, Dpi, scaleModifier);
}
/// <summary>
/// Unscale the supplied NativePoint to the current dpi
/// </summary>
/// <param name="point">NativePoint to unscale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativePoint unscaled</returns>
public static Point UnscaleWithCurrentDpi(Point point, Func<float, float> scaleModifier = null)
{
return UnscaleWithDpi(point, Dpi, scaleModifier);
}
/// <summary>
/// Unscale the supplied NativePointFloat to the current dpi
/// </summary>
/// <param name="point">NativePointFloat to unscale</param>
/// <param name="scaleModifier">A function which can modify the scale factor</param>
/// <returns>NativePointFloat unscaled</returns>
public static PointF UnscaleWithCurrentDpi(PointF point, Func<float, float> scaleModifier = null)
{
return ScaleWithDpi(point, Dpi, scaleModifier);
}
/// <summary>
/// public wrapper for EnableNonClientDpiScaling, this also checks if the function is available.
/// </summary>
/// <param name="hWnd">IntPtr</param>
/// <returns>true if it worked</returns>
public static bool TryEnableNonClientDpiScaling(IntPtr hWnd)
{
// EnableNonClientDpiScaling is only available on Windows 10 and later
if (!WindowsVersion.IsWindows10OrLater)
{
return false;
}
var result = EnableNonClientDpiScaling(hWnd);
if (result.Succeeded())
{
return true;
}
var error = Win32.GetLastErrorCode();
if (Log.IsDebugEnabled)
{
Log.DebugFormat("Error enabling non client dpi scaling : {0}", Win32.GetMessage(error));
}
return false;
}
/// <summary>
/// Make the current process DPI Aware, this should be done via the manifest but sometimes this is not possible.
/// </summary>
/// <returns>bool true if it was possible to change the DPI awareness</returns>
public static bool EnableDpiAware()
{
// We can only test this for Windows 8.1 or later
if (!WindowsVersion.IsWindows81OrLater)
{
Log.Debug("An application can only be DPI aware starting with Window 8.1 and later.");
return false;
}
if (WindowsVersion.IsWindows10BuildOrLater(15063))
{
if (IsValidDpiAwarenessContext(DpiAwarenessContext.PerMonitorAwareV2))
{
SetProcessDpiAwarenessContext(DpiAwarenessContext.PerMonitorAwareV2);
}
else
{
SetProcessDpiAwarenessContext(DpiAwarenessContext.PerMonitorAwareV2);
}
return true;
}
return SetProcessDpiAwareness(DpiAwareness.PerMonitorAware).Succeeded();
}
/// <summary>
/// Check if the process is DPI Aware, an DpiHandler doesn't make sense if not.
/// </summary>
public static bool IsDpiAware
{
get
{
// We can only test this for Windows 8.1 or later
if (!WindowsVersion.IsWindows81OrLater)
{
Log.Debug("An application can only be DPI aware starting with Window 8.1 and later.");
return false;
}
using var process = Process.GetCurrentProcess();
GetProcessDpiAwareness(process.Handle, out var dpiAwareness);
if (Log.IsDebugEnabled)
{
Log.DebugFormat("Process {0} has a Dpi awareness {1}", process.ProcessName, dpiAwareness);
}
return dpiAwareness != DpiAwareness.Unaware && dpiAwareness != DpiAwareness.Invalid;
}
}
/// <summary> /// <summary>
/// Return the DPI for the screen which the location is located on /// Return the DPI for the screen which the location is located on
/// </summary> /// </summary>
@ -510,40 +164,6 @@ namespace GreenshotPlugin.Core
return (uint)GDI32.GetDeviceCaps(hdc, DeviceCaps.LOGPIXELSX); return (uint)GDI32.GetDeviceCaps(hdc, DeviceCaps.LOGPIXELSX);
} }
/// <summary>
/// See details <a hef="https://msdn.microsoft.com/en-us/library/windows/desktop/dn302113(v=vs.85).aspx">GetProcessDpiAwareness function</a>
/// Retrieves the dots per inch (dpi) awareness of the specified process.
/// </summary>
/// <param name="processHandle">IntPtr with handle of the process that is being queried. If this parameter is NULL, the current process is queried.</param>
/// <param name="value">out DpiAwareness - The DPI awareness of the specified process. Possible values are from the PROCESS_DPI_AWARENESS enumeration.</param>
/// <returns>HResult</returns>
[DllImport("shcore")]
private static extern HResult GetProcessDpiAwareness(IntPtr processHandle, out DpiAwareness value);
/// <summary>
/// Sets the current process to a specified dots per inch (dpi) awareness level. The DPI awareness levels are from the PROCESS_DPI_AWARENESS enumeration.
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx">SetProcessDpiAwareness function</a>
/// </summary>
/// <param name="dpiAwareness">DpiAwareness</param>
/// <returns>HResult</returns>
[DllImport("shcore")]
private static extern HResult SetProcessDpiAwareness(DpiAwareness dpiAwareness);
/// <summary>
/// It is recommended that you set the process-default DPI awareness via application manifest. See Setting the default DPI awareness for a process for more information. Setting the process-default DPI awareness via API call can lead to unexpected application behavior.
///
/// Sets the current process to a specified dots per inch (dpi) awareness context. The DPI awareness contexts are from the DPI_AWARENESS_CONTEXT value.
/// Remarks:
/// This API is a more advanced version of the previously existing SetProcessDpiAwareness API, allowing for the process default to be set to the finer-grained DPI_AWARENESS_CONTEXT values. Most importantly, this allows you to programmatically set Per Monitor v2 as the process default value, which is not possible with the previous API.
///
/// This method sets the default DPI_AWARENESS_CONTEXT for all threads within an application. Individual threads can have their DPI awareness changed from the default with the SetThreadDpiAwarenessContext method.
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt807676(v=vs.85).aspx">SetProcessDpiAwarenessContext function</a>
/// </summary>
/// <param name="dpiAwarenessContext">DpiAwarenessContext</param>
/// <returns>bool</returns>
[DllImport("User32.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
/// <summary> /// <summary>
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748624(v=vs.85).aspx">GetDpiForWindow function</a> /// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748624(v=vs.85).aspx">GetDpiForWindow function</a>
/// Returns the dots per inch (dpi) value for the associated window. /// Returns the dots per inch (dpi) value for the associated window.
@ -566,14 +186,6 @@ namespace GreenshotPlugin.Core
[DllImport("shcore.dll", SetLastError = true)] [DllImport("shcore.dll", SetLastError = true)]
private static extern HResult GetDpiForMonitor(IntPtr hMonitor, MonitorDpiType dpiType, out uint dpiX, out uint dpiY); private static extern HResult GetDpiForMonitor(IntPtr hMonitor, MonitorDpiType dpiType, out uint dpiX, out uint dpiY);
/// <summary>
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748621(v=vs.85).aspx">EnableNonClientDpiScaling function</a>
/// </summary>
/// <param name="hWnd">IntPtr</param>
/// <returns>bool</returns>
[DllImport("User32.dll", SetLastError = true)]
private static extern HResult EnableNonClientDpiScaling(IntPtr hWnd);
/// <summary> /// <summary>
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748623(v=vs.85).aspx">GetDpiForSystem function</a> /// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748623(v=vs.85).aspx">GetDpiForSystem function</a>
/// Returns the system DPI. /// Returns the system DPI.
@ -581,151 +193,5 @@ namespace GreenshotPlugin.Core
/// <returns>uint with the system DPI</returns> /// <returns>uint with the system DPI</returns>
[DllImport("User32.dll")] [DllImport("User32.dll")]
private static extern uint GetDpiForSystem(); private static extern uint GetDpiForSystem();
/// <summary>
/// Converts a point in a window from logical coordinates into physical coordinates, regardless of the dots per inch (dpi) awareness of the caller. For more information about DPI awareness levels, see PROCESS_DPI_AWARENESS.
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn384110(v=vs.85).aspx">LogicalToPhysicalPointForPerMonitorDPI function</a>
/// </summary>
/// <param name="hWnd">IntPtr A handle to the window whose transform is used for the conversion.</param>
/// <param name="point">A pointer to a POINT structure that specifies the logical coordinates to be converted. The new physical coordinates are copied into this structure if the function succeeds.</param>
/// <returns>bool</returns>
[DllImport("User32.dll")]
private static extern bool LogicalToPhysicalPointForPerMonitorDPI(IntPtr hWnd, ref POINT point);
/// <summary>
/// Converts a point in a window from logical coordinates into physical coordinates, regardless of the dots per inch (dpi) awareness of the caller. For more information about DPI awareness levels, see PROCESS_DPI_AWARENESS.
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn384112(v=vs.85).aspx">PhysicalToLogicalPointForPerMonitorDPI function</a>
/// </summary>
/// <param name="hWnd">IntPtr A handle to the window whose transform is used for the conversion.</param>
/// <param name="point">NativePoint A pointer to a POINT structure that specifies the physical/screen coordinates to be converted. The new logical coordinates are copied into this structure if the function succeeds.</param>
/// <returns>bool</returns>
[DllImport("User32.dll")]
private static extern bool PhysicalToLogicalPointForPerMonitorDPI(IntPtr hWnd, ref POINT point);
/// <summary>
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx">SystemParametersInfo function</a>
/// Retrieves the value of one of the system-wide parameters, taking into account the provided DPI value.
/// </summary>
/// <param name="uiAction">
/// SystemParametersInfoActions The system-wide parameter to be retrieved.
/// This function is only intended for use with SPI_GETICONTITLELOGFONT, SPI_GETICONMETRICS, or SPI_GETNONCLIENTMETRICS. See SystemParametersInfo for more information on these values.
/// </param>
/// <param name="uiParam">
/// A parameter whose usage and format depends on the system parameter being queried or set. For more
/// information about system-wide parameters, see the uiAction parameter. If not otherwise indicated, you must specify
/// zero for this parameter.
/// </param>
/// <param name="pvParam">IntPtr</param>
/// <param name="fWinIni">SystemParametersInfoBehaviors</param>
/// <param name="dpi">uint with dpi value</param>
/// <returns>bool</returns>
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfoForDpi(SystemParametersInfoActions uiAction, uint uiParam, IntPtr pvParam, SystemParametersInfoBehaviors fWinIni, uint dpi);
/// <summary>
/// See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt748626(v=vs.85).aspx">GetThreadDpiAwarenessContext function</a>
/// Gets the DPI_AWARENESS_CONTEXT for the current thread.
///
/// This method will return the latest DPI_AWARENESS_CONTEXT sent to SetThreadDpiAwarenessContext. If SetThreadDpiAwarenessContext was never called for this thread, then the return value will equal the default DPI_AWARENESS_CONTEXT for the process.
/// </summary>
/// <returns>DpiAwarenessContext</returns>
[DllImport("User32.dll")]
private static extern DpiAwarenessContext GetThreadDpiAwarenessContext();
/// <summary>
/// Set the DPI awareness for the current thread to the provided value.
/// </summary>
/// <param name="dpiAwarenessContext">DpiAwarenessContext the new value for the current thread</param>
/// <returns>DpiAwarenessContext previous value</returns>
[DllImport("User32.dll")]
private static extern DpiAwarenessContext SetThreadDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
/// <summary>
/// Retrieves the DpiAwareness value from a DpiAwarenessContext.
/// </summary>
/// <param name="dpiAwarenessContext">DpiAwarenessContext</param>
/// <returns>DpiAwareness</returns>
[DllImport("User32.dll")]
private static extern DpiAwareness GetAwarenessFromDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
/// <summary>
/// Retrieves the DPI from a given DPI_AWARENESS_CONTEXT handle. This enables you to determine the DPI of a thread without needed to examine a window created within that thread.
/// </summary>
/// <param name="dpiAwarenessContext">DpiAwarenessContext</param>
/// <returns>uint with dpi value</returns>
[DllImport("User32.dll")]
private static extern uint GetDpiFromDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
/// <summary>
/// Determines if a specified DPI_AWARENESS_CONTEXT is valid and supported by the current system.
/// </summary>
/// <param name="dpiAwarenessContext">DpiAwarenessContext The context that you want to determine if it is supported.</param>
/// <returns>bool true if supported otherwise false</returns>
[DllImport("User32.dll")]
private static extern bool IsValidDpiAwarenessContext(DpiAwarenessContext dpiAwarenessContext);
/// <summary>
/// Returns the DPI_HOSTING_BEHAVIOR of the specified window.
///
/// This API allows you to examine the hosting behavior of a window after it has been created. A window's hosting behavior is the hosting behavior of the thread in which the window was created, as set by a call to SetThreadDpiHostingBehavior. This is a permanent value and cannot be changed after the window is created, even if the thread's hosting behavior is changed.
/// </summary>
/// <returns>DpiHostingBehavior</returns>
[DllImport("User32.dll")]
private static extern DpiHostingBehavior GetWindowDpiHostingBehavior();
/// <summary>
/// See more at <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt845775.aspx">SetThreadDpiHostingBehavior function</a>
/// Sets the thread's DPI_HOSTING_BEHAVIOR. This behavior allows windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT.
///
/// DPI_HOSTING_BEHAVIOR enables a mixed content hosting behavior, which allows parent windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT value. This property only effects new windows created within this thread while the mixed hosting behavior is active. A parent window with this hosting behavior is able to host child windows with different DPI_AWARENESS_CONTEXT values, regardless of whether the child windows have mixed hosting behavior enabled.
///
/// This hosting behavior does not allow for windows with per-monitor DPI_AWARENESS_CONTEXT values to be hosted until windows with DPI_AWARENESS_CONTEXT values of system or unaware.
///
/// To avoid unexpected outcomes, a thread's DPI_HOSTING_BEHAVIOR should be changed to support mixed hosting behaviors only when creating a new window which needs to support those behaviors. Once that window is created, the hosting behavior should be switched back to its default value.
///
/// This API is used to change the thread's DPI_HOSTING_BEHAVIOR from its default value. This is only necessary if your app needs to host child windows from plugins and third-party components that do not support per-monitor-aware context. This is most likely to occur if you are updating complex applications to support per-monitor DPI_AWARENESS_CONTEXT behaviors.
///
/// Enabling mixed hosting behavior will not automatically adjust the thread's DPI_AWARENESS_CONTEXT to be compatible with legacy content. The thread's awareness context must still be manually changed before new windows are created to host such content.
/// </summary>
/// <param name="dpiHostingBehavior">DpiHostingBehavior</param>
/// <returns>previous DpiHostingBehavior</returns>
[DllImport("User32.dll")]
private static extern DpiHostingBehavior SetThreadDpiHostingBehavior(DpiHostingBehavior dpiHostingBehavior);
/// <summary>
///Retrieves the DPI_HOSTING_BEHAVIOR from the current thread.
/// </summary>
/// <returns>DpiHostingBehavior</returns>
[DllImport("User32.dll")]
private static extern DpiHostingBehavior GetThreadDpiHostingBehavior();
/// <summary>
/// Overrides the default per-monitor DPI scaling behavior of a child window in a dialog.
/// This function returns TRUE if the operation was successful, and FALSE otherwise. To get extended error information, call GetLastError.
///
/// Possible errors are ERROR_INVALID_HANDLE if passed an invalid HWND, and ERROR_ACCESS_DENIED if the windows belongs to another process.
///
/// The behaviors are specified as values from the DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS enum. This function follows the typical two-parameter approach to setting flags, where a mask specifies the subset of the flags to be changed.
///
/// It is valid to set these behaviors on any window. It does not matter if the window is currently a child of a dialog at the point in time that SetDialogControlDpiChangeBehavior is called. The behaviors are retained and will take effect only when the window is an immediate child of a dialog that has per-monitor DPI scaling enabled.
///
/// This API influences individual controls within dialogs. The dialog-wide per-monitor DPI scaling behavior is controlled by SetDialogDpiChangeBehavior.
/// </summary>
/// <param name="hWnd">IntPtr A handle for the window whose behavior will be modified.</param>
/// <param name="mask">DialogScalingBehaviors A mask specifying the subset of flags to be changed.</param>
/// <param name="values">DialogScalingBehaviors The desired value to be set for the specified subset of flags.</param>
/// <returns>bool</returns>
[DllImport("User32.dll")]
private static extern bool SetDialogControlDpiChangeBehavior(IntPtr hWnd, DialogScalingBehaviors mask, DialogScalingBehaviors values);
/// <summary>
/// Retrieves and per-monitor DPI scaling behavior overrides of a child window in a dialog.
/// The flags set on the given window. If passed an invalid handle, this function will return zero, and set its last error to ERROR_INVALID_HANDLE.
/// </summary>
/// <param name="hWnd">IntPtr A handle for the window whose behavior will be modified.</param>
/// <returns>DialogScalingBehaviors</returns>
[DllImport("User32.dll")]
private static extern DialogScalingBehaviors GetDialogControlDpiChangeBehavior(IntPtr hWnd);
} }
} }

View file

@ -1,102 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace GreenshotPlugin.Core {
public static class EnumerationExtensions {
public static bool Has<T>(this Enum type, T value) {
Type underlyingType = Enum.GetUnderlyingType(value.GetType());
try {
if (underlyingType == typeof(int)) {
return (((int)(object)type & (int)(object)value) == (int)(object)value);
} else if (underlyingType == typeof(uint)) {
return (((uint)(object)type & (uint)(object)value) == (uint)(object)value);
}
}
catch
{
// ignored
}
return false;
}
public static bool Is<T>(this Enum type, T value) {
Type underlyingType = Enum.GetUnderlyingType(value.GetType());
try
{
if (underlyingType == typeof(int)) {
return (int)(object)type == (int)(object)value;
}
if (underlyingType == typeof(uint)) {
return (uint)(object)type == (uint)(object)value;
}
}
catch
{
// ignored
}
return false;
}
/// <summary>
/// Add a flag to an enum
/// </summary>
/// <param name="type"></param>
/// <param name="value"></param>
/// <returns></returns>
public static T Add<T>(this Enum type, T value) {
Type underlyingType = Enum.GetUnderlyingType(value.GetType());
try
{
if (underlyingType == typeof(int)) {
return (T)(object)(((int)(object)type | (int)(object)value));
}
if (underlyingType == typeof(uint)) {
return (T)(object)(((uint)(object)type | (uint)(object)value));
}
} catch(Exception ex) {
throw new ArgumentException($"Could not append value '{value}' to enumerated type '{typeof(T).Name}'.", ex);
}
throw new ArgumentException($"Could not append value '{value}' to enumerated type '{typeof(T).Name}'.");
}
/// <summary>
/// Remove a flag from an enum type
/// </summary>
/// <param name="type"></param>
/// <param name="value"></param>
/// <returns></returns>
public static T Remove<T>(this Enum type, T value) {
Type underlyingType = Enum.GetUnderlyingType(value.GetType());
try
{
if (underlyingType == typeof(int)) {
return (T)(object)(((int)(object)type & ~(int)(object)value));
}
if (underlyingType == typeof(uint)) {
return (T)(object)(((uint)(object)type & ~(uint)(object)value));
}
} catch(Exception ex) {
throw new ArgumentException($"Could not remove value '{value}' from enumerated type '{typeof(T).Name}'.", ex);
}
throw new ArgumentException($"Could not remove value '{value}' from enumerated type '{typeof(T).Name}'.");
}
}
}

View file

@ -1,34 +0,0 @@
// Copyright (c) Dapplo and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace GreenshotPlugin.Core.Enums
{
/// <summary>
/// In Per Monitor v2 contexts, dialogs will automatically respond to DPI changes by resizing themselves and re-computing the positions of their child windows (here referred to as re-layouting). This enum works in conjunction with SetDialogDpiChangeBehavior in order to override the default DPI scaling behavior for dialogs.
/// This does not affect DPI scaling behavior for the child windows of dialogs(beyond re-layouting), which is controlled by DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.
/// </summary>
[Flags]
public enum DialogDpiChangeBehaviors
{
/// <summary>
/// The default behavior of the dialog manager. In response to a DPI change, the dialog manager will re-layout each control, update the font on each control, resize the dialog, and update the dialog's own font.
/// </summary>
Default = 0,
/// <summary>
/// Prevents the dialog manager from responding to WM_GETDPISCALEDSIZE and WM_DPICHANGED, disabling all default DPI scaling behavior.
/// </summary>
DisableAll = 1,
/// <summary>
/// Prevents the dialog manager from resizing the dialog in response to a DPI change.
/// </summary>
DisableResize = 2,
/// <summary>
/// Prevents the dialog manager from re-layouting all of the dialogue's immediate children HWNDs in response to a DPI change.
/// </summary>
DisableControlRelayout = 3
}
}

View file

@ -1,32 +0,0 @@
// Copyright (c) Dapplo and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
namespace GreenshotPlugin.Core.Enums
{
/// <summary>
/// Describes per-monitor DPI scaling behavior overrides for child windows within dialogs. The values in this enumeration are bitfields and can be combined.
///
/// This enum is used with SetDialogControlDpiChangeBehavior in order to override the default per-monitor DPI scaling behavior for a child window within a dialog.
///
/// These settings only apply to individual controls within dialogs. The dialog-wide per-monitor DPI scaling behavior of a dialog is controlled by DIALOG_DPI_CHANGE_BEHAVIORS.
/// </summary>
[Flags]
public enum DialogScalingBehaviors
{
/// <summary>
/// The default behavior of the dialog manager. The dialog managed will update the font, size, and position of the child window on DPI changes.
/// </summary>
Default = 0,
/// <summary>
/// Prevents the dialog manager from sending an updated font to the child window via WM_SETFONT in response to a DPI change.
/// </summary>
DisableFontUpdate = 1,
/// <summary>
/// Prevents the dialog manager from resizing and repositioning the child window in response to a DPI change.
/// </summary>
DisableRelayout = 2
}
}

View file

@ -1,40 +0,0 @@
// Copyright (c) Dapplo and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace GreenshotPlugin.Core.Enums
{
/// <summary>
/// Identifies the dots per inch (dpi) setting for a thread, process, or window.
/// Can be used everywhere ProcessDpiAwareness is passed.
/// </summary>
public enum DpiAwareness
{
/// <summary>
/// Invalid DPI awareness. This is an invalid DPI awareness value.
/// </summary>
Invalid = -1,
/// <summary>
/// DPI unaware.
/// This process does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI).
/// It will be automatically scaled by the system on any other DPI setting.
/// </summary>
Unaware = 0,
/// <summary>
/// System DPI aware.
/// This process does not scale for DPI changes.
/// It will query for the DPI once and use that value for the lifetime of the process.
/// If the DPI changes, the process will not adjust to the new DPI value.
/// It will be automatically scaled up or down by the system when the DPI changes from the system value.
/// </summary>
SystemAware = 1,
/// <summary>
/// Per monitor DPI aware.
/// This process checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes.
/// These processes are not automatically scaled by the system.
/// </summary>
PerMonitorAware = 2
}
}

View file

@ -1,46 +0,0 @@
// Copyright (c) Dapplo and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace GreenshotPlugin.Core.Enums
{
/// <summary>
/// </summary>
public enum DpiAwarenessContext
{
/// <summary>
/// DPI unaware.
/// This window does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI).
/// It will be automatically scaled by the system on any other DPI setting.
/// </summary>
Unaware = -1,
/// <summary>
/// System DPI aware.
/// This window does not scale for DPI changes.
/// It will query for the DPI once and use that value for the lifetime of the process.
/// If the DPI changes, the process will not adjust to the new DPI value.
/// It will be automatically scaled up or down by the system when the DPI changes from the system value.
/// </summary>
SystemAware = -2,
/// <summary>
/// Per monitor DPI aware.
/// This window checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes.
/// These processes are not automatically scaled by the system.
/// </summary>
PerMonitorAware = -3,
/// <summary>
/// Also known as Per Monitor v2. An advancement over the original per-monitor DPI awareness mode, which enables applications to access new DPI-related scaling behaviors on a per top-level window basis.
/// Per Monitor v2 was made available in the Creators Update of Windows 10, and is not available on earlier versions of the operating system.
/// The additional behaviors introduced are as follows:
/// * Child window DPI change notifications - In Per Monitor v2 contexts, the entire window tree is notified of any DPI changes that occur.
/// * Scaling of non-client area - All windows will automatically have their non-client area drawn in a DPI sensitive fashion. Calls to EnableNonClientDpiScaling are unnecessary.
/// * Scaling of Win32 menus - All NTUSER menus created in Per Monitor v2 contexts will be scaling in a per-monitor fashion.
/// * Dialog Scaling - Win32 dialogs created in Per Monitor v2 contexts will automatically respond to DPI changes.
/// * Improved scaling of comctl32 controls - Various comctl32 controls have improved DPI scaling behavior in Per Monitor v2 contexts.
/// * Improved theming behavior - UxTheme handles opened in the context of a Per Monitor v2 window will operate in terms of the DPI associated with that window.
/// </summary>
PerMonitorAwareV2 = -4
}
}

View file

@ -1,28 +0,0 @@
// Copyright (c) Dapplo and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace GreenshotPlugin.Core.Enums
{
/// <summary>
/// Identifies the DPI hosting behavior for a window.
/// This behavior allows windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT
/// </summary>
public enum DpiHostingBehavior
{
/// <summary>
/// Invalid DPI hosting behavior. This usually occurs if the previous SetThreadDpiHostingBehavior call used an invalid parameter.
/// </summary>
Invalid = -1,
/// <summary>
/// Default DPI hosting behavior. The associated window behaves as normal, and cannot create or re-parent child windows with a different DPI_AWARENESS_CONTEXT.
/// </summary>
Default = 0,
/// <summary>
/// Mixed DPI hosting behavior. This enables the creation and re-parenting of child windows with different DPI_AWARENESS_CONTEXT. These child windows will be independently scaled by the OS.
/// </summary>
Mixed = 1
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,28 +0,0 @@
// Copyright (c) Dapplo and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace GreenshotPlugin.Core.Enums
{
/// <summary>
/// If a system parameter is being set, specifies whether the user profile is to be updated, and if so, whether the
/// WM_SETTINGCHANGE message is to be broadcast to all top-level windows to notify them of the change.
/// This parameter can be zero if you do not want to update the user profile or broadcast the WM_SETTINGCHANGE message,
/// or it can be one or more of the following values.
/// </summary>
public enum SystemParametersInfoBehaviors : uint
{
/// <summary>
/// Do nothing
/// </summary>
None = 0x00,
/// <summary>Writes the new system-wide parameter setting to the user profile.</summary>
UpdateIniFile = 0x01,
/// <summary>Broadcasts the WM_SETTINGCHANGE message after updating the user profile.</summary>
SendChange = 0x02,
/// <summary>Same as SPIF_SENDCHANGE.</summary>
SendWinIniChange = SendChange
}
}

View file

@ -355,16 +355,7 @@ namespace GreenshotPlugin.Core {
} }
} }
/// <summary> /// <summary>
/// Factory for creating a FastBitmap as a destination for the source
/// </summary>
/// <param name="source">Bitmap to clone</param>
/// <returns>IFastBitmap</returns>
public static IFastBitmap CreateCloneOf(Image source) {
return CreateCloneOf(source, source.PixelFormat, Rectangle.Empty);
}
/// <summary>
/// Factory for creating a FastBitmap as a destination for the source /// Factory for creating a FastBitmap as a destination for the source
/// </summary> /// </summary>
/// <param name="source">Bitmap to clone</param> /// <param name="source">Bitmap to clone</param>

View file

@ -19,7 +19,6 @@
using GreenshotPlugin.Core.Enums; using GreenshotPlugin.Core.Enums;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
namespace GreenshotPlugin.Core namespace GreenshotPlugin.Core
{ {
@ -29,7 +28,7 @@ namespace GreenshotPlugin.Core
public static class HResultExtensions public static class HResultExtensions
{ {
/// <summary> /// <summary>
/// Test if the HResult respresents a fail /// Test if the HResult represents a fail
/// </summary> /// </summary>
/// <param name="hResult">HResult</param> /// <param name="hResult">HResult</param>
/// <returns>bool</returns> /// <returns>bool</returns>
@ -40,7 +39,7 @@ namespace GreenshotPlugin.Core
} }
/// <summary> /// <summary>
/// Test if the HResult respresents a success /// Test if the HResult represents a success
/// </summary> /// </summary>
/// <param name="hResult">HResult</param> /// <param name="hResult">HResult</param>
/// <returns>bool</returns> /// <returns>bool</returns>
@ -49,17 +48,5 @@ namespace GreenshotPlugin.Core
{ {
return hResult >= HResult.S_OK; return hResult >= HResult.S_OK;
} }
/// <summary>
/// Throw an exception on Failure
/// </summary>
/// <param name="hResult">HResult</param>
public static void ThrowOnFailure(this HResult hResult)
{
if (hResult.Failed())
{
throw Marshal.GetExceptionForHR((int)hResult);
}
}
} }
} }

View file

@ -12,16 +12,6 @@ namespace GreenshotPlugin.Core
private readonly Image _image; private readonly Image _image;
private Image _imageClone; private Image _imageClone;
/// <summary>
/// Factory method
/// </summary>
/// <param name="image">Image</param>
/// <returns>IImage</returns>
public static IImage FromImage(Image image)
{
return image == null ? null : new ImageWrapper(image);
}
public ImageWrapper(Image image) public ImageWrapper(Image image)
{ {
// Make sure the orientation is set correctly so Greenshot can process the image correctly // Make sure the orientation is set correctly so Greenshot can process the image correctly

View file

@ -20,9 +20,7 @@
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Threading; using System.Threading;
using GreenshotPlugin.Interfaces;
using log4net; using log4net;
namespace GreenshotPlugin.Core { namespace GreenshotPlugin.Core {
@ -33,42 +31,28 @@ namespace GreenshotPlugin.Core {
private static readonly ILog LOG = LogManager.GetLogger(typeof(InterfaceUtils)); private static readonly ILog LOG = LogManager.GetLogger(typeof(InterfaceUtils));
public static List<Type> GetSubclassesOf(Type type, bool excludeSystemTypes) { public static List<Type> GetSubclassesOf(Type type, bool excludeSystemTypes) {
List<Type> list = new List<Type>(); var list = new List<Type>();
foreach(Assembly currentAssembly in Thread.GetDomain().GetAssemblies()) { foreach(var currentAssembly in Thread.GetDomain().GetAssemblies()) {
try { try {
Type[] types = currentAssembly.GetTypes(); Type[] types = currentAssembly.GetTypes();
if (!excludeSystemTypes || (excludeSystemTypes && !currentAssembly.FullName.StartsWith("System."))) { if (excludeSystemTypes && (!excludeSystemTypes || currentAssembly.FullName.StartsWith("System.")))
foreach(Type currentType in types) { {
if (type.IsInterface) { continue;
if (currentType.GetInterface(type.FullName) != null) { }
list.Add(currentType); foreach(var currentType in types) {
} if (type.IsInterface) {
} else if (currentType.IsSubclassOf(type)) { if (currentType.GetInterface(type.FullName) != null) {
list.Add(currentType); list.Add(currentType);
} }
} } else if (currentType.IsSubclassOf(type)) {
} list.Add(currentType);
} catch (Exception ex) { }
}
} catch (Exception ex) {
LOG.WarnFormat("Problem getting subclasses of type: {0}, message: {1}", type.FullName, ex.Message); LOG.WarnFormat("Problem getting subclasses of type: {0}, message: {1}", type.FullName, ex.Message);
} }
} }
return list; return list;
} }
}
public static List<IProcessor> GetProcessors() {
List<IProcessor> processors = new List<IProcessor>();
foreach(Type processorType in GetSubclassesOf(typeof(IProcessor), true)) {
if (!processorType.IsAbstract) {
IProcessor processor = (IProcessor)Activator.CreateInstance(processorType);
if (processor.isActive) {
LOG.DebugFormat("Found processor {0} with designation {1}", processorType.Name, processor.Designation);
processors.Add(processor);
} else {
LOG.DebugFormat("Ignoring processor {0} with designation {1}", processorType.Name, processor.Designation);
}
}
}
return processors;
}
}
} }

View file

@ -476,32 +476,7 @@ namespace GreenshotPlugin.Core {
} }
} }
/// <summary> /// <summary>
/// Check if a resource with prefix.key exists
/// </summary>
/// <param name="prefix"></param>
/// <param name="key"></param>
/// <returns>true if available</returns>
public static bool HasKey(string prefix, Enum key) {
if (key == null) {
return false;
}
return HasKey(prefix + "." + key);
}
/// <summary>
/// Check if a resource with key exists
/// </summary>
/// <param name="key"></param>
/// <returns>true if available</returns>
public static bool HasKey(Enum key) {
if (key == null) {
return false;
}
return HasKey(key.ToString());
}
/// <summary>
/// Check if a resource with prefix.key exists /// Check if a resource with prefix.key exists
/// </summary> /// </summary>
/// <param name="prefix"></param> /// <param name="prefix"></param>

View file

@ -40,9 +40,8 @@ namespace GreenshotPlugin.Core {
GET, GET,
POST, POST,
PUT, PUT,
DELETE, DELETE
HEAD };
};
/// <summary> /// <summary>
/// Description of NetworkHelper. /// Description of NetworkHelper.
@ -61,54 +60,21 @@ namespace GreenshotPlugin.Core {
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warn("An error has occured while allowing self-signed certificates:", ex); Log.Warn("An error has occurred while allowing self-signed certificates:", ex);
} }
} }
/// <summary>
/// Download a uri response as string
/// </summary>
/// <param name="uri">An Uri to specify the download location</param>
/// <returns>string with the file content</returns>
public static string GetAsString(Uri uri) {
return GetResponseAsString(CreateWebRequest(uri));
}
/// <summary> /// <summary>
/// Download the FavIcon as a Bitmap
/// </summary>
/// <param name="baseUri"></param>
/// <returns>Bitmap with the FavIcon</returns>
public static Bitmap DownloadFavIcon(Uri baseUri) {
Uri url = new Uri(baseUri, new Uri("favicon.ico"));
try {
HttpWebRequest request = CreateWebRequest(url);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (request.HaveResponse)
{
using Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
using Image image = ImageHelper.FromStream(responseStream);
return image.Height > 16 && image.Width > 16 ? new Bitmap(image, 16, 16) : new Bitmap(image);
}
}
} catch (Exception e) {
Log.Error("Problem downloading the FavIcon from: " + baseUri, e);
}
return null;
}
/// <summary>
/// Download the uri into a memory stream, without catching exceptions /// Download the uri into a memory stream, without catching exceptions
/// </summary> /// </summary>
/// <param name="url">Of an image</param> /// <param name="url">Of an image</param>
/// <returns>MemoryStream which is already seek-ed to 0</returns> /// <returns>MemoryStream which is already seek-ed to 0</returns>
public static MemoryStream GetAsMemoryStream(string url) { public static MemoryStream GetAsMemoryStream(string url) {
HttpWebRequest request = CreateWebRequest(url); var request = CreateWebRequest(url);
using HttpWebResponse response = (HttpWebResponse)request.GetResponse(); using var response = (HttpWebResponse)request.GetResponse();
MemoryStream memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
using (Stream responseStream = response.GetResponseStream()) { using (var responseStream = response.GetResponseStream()) {
responseStream?.CopyTo(memoryStream); responseStream?.CopyTo(memoryStream);
// Make sure it can be used directly // Make sure it can be used directly
memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.Seek(0, SeekOrigin.Begin);
@ -123,7 +89,7 @@ namespace GreenshotPlugin.Core {
/// <returns>Bitmap</returns> /// <returns>Bitmap</returns>
public static Image DownloadImage(string url) public static Image DownloadImage(string url)
{ {
StringBuilder extensions = new StringBuilder(); var extensions = new StringBuilder();
foreach (var extension in ImageHelper.StreamConverters.Keys) foreach (var extension in ImageHelper.StreamConverters.Keys)
{ {
if (string.IsNullOrEmpty(extension)) if (string.IsNullOrEmpty(extension))
@ -147,7 +113,7 @@ namespace GreenshotPlugin.Core {
{ {
// If we arrive here, the image loading didn't work, try to see if the response has a http(s) URL to an image and just take this instead. // If we arrive here, the image loading didn't work, try to see if the response has a http(s) URL to an image and just take this instead.
string content; string content;
using (StreamReader streamReader = new StreamReader(memoryStream, Encoding.UTF8, true)) using (var streamReader = new StreamReader(memoryStream, Encoding.UTF8, true))
{ {
content = streamReader.ReadLine(); content = streamReader.ReadLine();
} }
@ -198,7 +164,7 @@ namespace GreenshotPlugin.Core {
/// <param name="method">Method to use</param> /// <param name="method">Method to use</param>
/// <returns>WebRequest</returns> /// <returns>WebRequest</returns>
public static HttpWebRequest CreateWebRequest(Uri uri, HTTPMethod method) { public static HttpWebRequest CreateWebRequest(Uri uri, HTTPMethod method) {
HttpWebRequest webRequest = CreateWebRequest(uri); var webRequest = CreateWebRequest(uri);
webRequest.Method = method.ToString(); webRequest.Method = method.ToString();
return webRequest; return webRequest;
} }
@ -209,7 +175,7 @@ namespace GreenshotPlugin.Core {
/// <param name="uri">Uri with uri to connect to</param> /// <param name="uri">Uri with uri to connect to</param>
/// <returns>WebRequest</returns> /// <returns>WebRequest</returns>
public static HttpWebRequest CreateWebRequest(Uri uri) { public static HttpWebRequest CreateWebRequest(Uri uri) {
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Proxy = Config.UseProxy ? CreateProxy(uri) : null; webRequest.Proxy = Config.UseProxy ? CreateProxy(uri) : null;
// Make sure the default credentials are available // Make sure the default credentials are available
webRequest.Credentials = CredentialCache.DefaultCredentials; webRequest.Credentials = CredentialCache.DefaultCredentials;
@ -231,28 +197,32 @@ namespace GreenshotPlugin.Core {
/// <returns>IWebProxy filled with all the proxy details or null if none is set/wanted</returns> /// <returns>IWebProxy filled with all the proxy details or null if none is set/wanted</returns>
public static IWebProxy CreateProxy(Uri uri) { public static IWebProxy CreateProxy(Uri uri) {
IWebProxy proxyToUse = null; IWebProxy proxyToUse = null;
if (Config.UseProxy) { if (!Config.UseProxy)
proxyToUse = WebRequest.DefaultWebProxy; {
if (proxyToUse != null) { return proxyToUse;
proxyToUse.Credentials = CredentialCache.DefaultCredentials; }
if (Log.IsDebugEnabled) { proxyToUse = WebRequest.DefaultWebProxy;
// check the proxy for the Uri if (proxyToUse != null) {
if (!proxyToUse.IsBypassed(uri)) { proxyToUse.Credentials = CredentialCache.DefaultCredentials;
Uri proxyUri = proxyToUse.GetProxy(uri); if (!Log.IsDebugEnabled)
if (proxyUri != null) { {
Log.Debug("Using proxy: " + proxyUri + " for " + uri); return proxyToUse;
} else { }
Log.Debug("No proxy found!"); // check the proxy for the Uri
} if (!proxyToUse.IsBypassed(uri)) {
} else { var proxyUri = proxyToUse.GetProxy(uri);
Log.Debug("Proxy bypass for: " + uri); if (proxyUri != null) {
} Log.Debug("Using proxy: " + proxyUri + " for " + uri);
} } else {
} else { Log.Debug("No proxy found!");
Log.Debug("No proxy found!"); }
} } else {
} Log.Debug("Proxy bypass for: " + uri);
return proxyToUse; }
} else {
Log.Debug("No proxy found!");
}
return proxyToUse;
} }
/// <summary> /// <summary>
@ -263,7 +233,7 @@ namespace GreenshotPlugin.Core {
// [Obsolete("Use System.Uri.EscapeDataString instead")] // [Obsolete("Use System.Uri.EscapeDataString instead")]
public static string UrlEncode(string text) { public static string UrlEncode(string text) {
if (!string.IsNullOrEmpty(text)) { if (!string.IsNullOrEmpty(text)) {
// Sytem.Uri provides reliable parsing, but doesn't encode spaces. // System.Uri provides reliable parsing, but doesn't encode spaces.
return Uri.EscapeDataString(text).Replace("%20", "+"); return Uri.EscapeDataString(text).Replace("%20", "+");
} }
return null; return null;
@ -277,7 +247,7 @@ namespace GreenshotPlugin.Core {
/// <returns>escaped data string</returns> /// <returns>escaped data string</returns>
public static string EscapeDataString(string text) { public static string EscapeDataString(string text) {
if (!string.IsNullOrEmpty(text)) { if (!string.IsNullOrEmpty(text)) {
StringBuilder result = new StringBuilder(); var result = new StringBuilder();
int currentLocation = 0; int currentLocation = 0;
while (currentLocation < text.Length) { while (currentLocation < text.Length) {
string process = text.Substring(currentLocation, Math.Min(16384, text.Length - currentLocation)); string process = text.Substring(currentLocation, Math.Min(16384, text.Length - currentLocation));
@ -326,7 +296,7 @@ namespace GreenshotPlugin.Core {
} }
/// <summary> /// <summary>
/// Generate the query paramters /// Generate the query parameters
/// </summary> /// </summary>
/// <param name="queryParameters">the list of query parameters</param> /// <param name="queryParameters">the list of query parameters</param>
/// <returns>a string with the query parameters</returns> /// <returns>a string with the query parameters</returns>
@ -337,7 +307,7 @@ namespace GreenshotPlugin.Core {
queryParameters = new SortedDictionary<string, object>(queryParameters); queryParameters = new SortedDictionary<string, object>(queryParameters);
StringBuilder sb = new StringBuilder(); var sb = new StringBuilder();
foreach(string key in queryParameters.Keys) { foreach(string key in queryParameters.Keys) {
sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", key, UrlEncode($"{queryParameters[key]}")); sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", key, UrlEncode($"{queryParameters[key]}"));
} }
@ -358,18 +328,8 @@ namespace GreenshotPlugin.Core {
WriteMultipartFormData(formDataStream, boundary, postParameters); WriteMultipartFormData(formDataStream, boundary, postParameters);
} }
/// <summary>
/// Write Multipart Form Data to the HttpListenerResponse
/// </summary>
/// <param name="response">HttpListenerResponse</param>
/// <param name="postParameters">Parameters to include in the multipart form data</param>
public static void WriteMultipartFormData(HttpListenerResponse response, IDictionary<string, object> postParameters) {
string boundary = $"----------{Guid.NewGuid():N}";
response.ContentType = "multipart/form-data; boundary=" + boundary;
WriteMultipartFormData(response.OutputStream, boundary, postParameters);
}
/// <summary> /// <summary>
/// Write Multipart Form Data to a Stream, content-type should be set before this! /// Write Multipart Form Data to a Stream, content-type should be set before this!
/// </summary> /// </summary>
/// <param name="formDataStream">Stream to write the multipart form data to</param> /// <param name="formDataStream">Stream to write the multipart form data to</param>
@ -519,27 +479,7 @@ namespace GreenshotPlugin.Core {
} }
return responseData; return responseData;
} }
}
/// <summary>
/// Get LastModified for a URI
/// </summary>
/// <param name="uri">Uri</param>
/// <returns>DateTime</returns>
public static DateTime GetLastModified(Uri uri) {
try {
HttpWebRequest webRequest = CreateWebRequest(uri);
webRequest.Method = HTTPMethod.HEAD.ToString();
using HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
Log.DebugFormat("RSS feed was updated at {0}", webResponse.LastModified);
return webResponse.LastModified;
} catch (Exception wE) {
Log.WarnFormat("Problem requesting HTTP - HEAD on uri {0}", uri);
Log.Warn(wE.Message);
// Pretend it is old
return DateTime.MinValue;
}
}
}
/// <summary> /// <summary>
/// This interface can be used to pass binary information around, like byte[] or Image /// This interface can be used to pass binary information around, like byte[] or Image
@ -555,158 +495,7 @@ namespace GreenshotPlugin.Core {
string Filename { get; set; } string Filename { get; set; }
} }
/// <summary> /// <summary>
/// A container to supply files to a Multi-part form data upload
/// </summary>
public class ByteContainer : IBinaryContainer {
private readonly byte[] _file;
private readonly string _contentType;
private readonly int _fileSize;
public ByteContainer(byte[] file) : this(file, null) {
}
public ByteContainer(byte[] file, string filename) : this(file, filename, null) {
}
public ByteContainer(byte[] file, string filename, string contenttype) : this(file, filename, contenttype, 0) {
}
public ByteContainer(byte[] file, string filename, string contenttype, int filesize) {
_file = file;
Filename = filename;
_contentType = contenttype;
_fileSize = filesize == 0 ? file.Length : filesize;
}
/// <summary>
/// Create a Base64String from the byte[]
/// </summary>
/// <returns>string</returns>
public string ToBase64String(Base64FormattingOptions formattingOptions) {
return Convert.ToBase64String(_file, 0, _fileSize, formattingOptions);
}
/// <summary>
/// Returns the initial byte-array which was supplied when creating the FileParameter
/// </summary>
/// <returns>byte[]</returns>
public byte[] ToByteArray() {
return _file;
}
/// <summary>
/// Write Multipart Form Data directly to the HttpWebRequest response stream
/// </summary>
/// <param name="boundary">Separator</param>
/// <param name="name">name</param>
/// <param name="formDataStream">Stream to write to</param>
public void WriteFormDataToStream(string boundary, string name, Stream formDataStream) {
// Add just the first part of this param, since we will write the file data directly to the Stream
string header = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{name}\"; filename=\"{Filename ?? name}\";\r\nContent-Type: {_contentType ?? "application/octet-stream"}\r\n\r\n";
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
// Write the file data directly to the Stream, rather than serializing it to a string.
formDataStream.Write(_file, 0, _fileSize);
}
/// <summary>
/// A plain "write data to stream"
/// </summary>
/// <param name="dataStream">Stream to write to</param>
public void WriteToStream(Stream dataStream) {
// Write the file data directly to the Stream, rather than serializing it to a string.
dataStream.Write(_file, 0, _fileSize);
}
/// <summary>
/// Upload the file to the webrequest
/// </summary>
/// <param name="webRequest"></param>
public void Upload(HttpWebRequest webRequest) {
webRequest.ContentType = _contentType;
webRequest.ContentLength = _fileSize;
using var requestStream = webRequest.GetRequestStream();
WriteToStream(requestStream);
}
public string ContentType => _contentType;
public string Filename { get; set; }
}
/// <summary>
/// A container to supply images to a Multi-part form data upload
/// </summary>
public class BitmapContainer : IBinaryContainer {
private readonly Bitmap _bitmap;
private readonly SurfaceOutputSettings _outputSettings;
public BitmapContainer(Bitmap bitmap, SurfaceOutputSettings outputSettings, string filename) {
_bitmap = bitmap;
_outputSettings = outputSettings;
Filename = filename;
}
/// <summary>
/// Create a Base64String from the image by saving it to a memory stream and converting it.
/// Should be avoided if possible, as this uses a lot of memory.
/// </summary>
/// <returns>string</returns>
public string ToBase64String(Base64FormattingOptions formattingOptions)
{
using MemoryStream stream = new MemoryStream();
ImageOutput.SaveToStream(_bitmap, null, stream, _outputSettings);
return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions);
}
/// <summary>
/// Create a byte[] from the image by saving it to a memory stream.
/// Should be avoided if possible, as this uses a lot of memory.
/// </summary>
/// <returns>byte[]</returns>
public byte[] ToByteArray()
{
using MemoryStream stream = new MemoryStream();
ImageOutput.SaveToStream(_bitmap, null, stream, _outputSettings);
return stream.ToArray();
}
/// <summary>
/// Write Multipart Form Data directly to the HttpWebRequest response stream
/// </summary>
/// <param name="boundary">Separator</param>
/// <param name="name">Name of the thing/file</param>
/// <param name="formDataStream">Stream to write to</param>
public void WriteFormDataToStream(string boundary, string name, Stream formDataStream) {
// Add just the first part of this param, since we will write the file data directly to the Stream
string header = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{name}\"; filename=\"{Filename ?? name}\";\r\nContent-Type: {ContentType}\r\n\r\n";
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
ImageOutput.SaveToStream(_bitmap, null, formDataStream, _outputSettings);
}
/// <summary>
/// A plain "write data to stream"
/// </summary>
/// <param name="dataStream"></param>
public void WriteToStream(Stream dataStream) {
// Write the file data directly to the Stream, rather than serializing it to a string.
ImageOutput.SaveToStream(_bitmap, null, dataStream, _outputSettings);
}
/// <summary>
/// Upload the image to the webrequest
/// </summary>
/// <param name="webRequest"></param>
public void Upload(HttpWebRequest webRequest) {
webRequest.ContentType = "image/" + _outputSettings.Format;
using var requestStream = webRequest.GetRequestStream();
WriteToStream(requestStream);
}
public string ContentType => "image/" + _outputSettings.Format;
public string Filename { get; set; }
}
/// <summary>
/// A container to supply surfaces to a Multi-part form data upload /// A container to supply surfaces to a Multi-part form data upload
/// </summary> /// </summary>
public class SurfaceContainer : IBinaryContainer { public class SurfaceContainer : IBinaryContainer {

View file

@ -549,21 +549,7 @@ namespace GreenshotPlugin.Core {
return MakeOAuthRequest(method, requestUrl, requestUrl, null, parametersToSign, additionalParameters, postData); return MakeOAuthRequest(method, requestUrl, requestUrl, null, parametersToSign, additionalParameters, postData);
} }
/// <summary> /// <summary>
/// Submit a web request using oAuth.
/// </summary>
/// <param name="method">GET or POST</param>
/// <param name="requestUrl">The full url, including the querystring for the signing/request</param>
/// <param name="headers">Header values</param>
/// <param name="parametersToSign">Parameters for the request, which need to be signed</param>
/// <param name="additionalParameters">Parameters for the request, which do not need to be signed</param>
/// <param name="postData">Data to post (MemoryStream)</param>
/// <returns>The web server response.</returns>
public string MakeOAuthRequest(HTTPMethod method, string requestUrl, IDictionary<string, string> headers, IDictionary<string, object> parametersToSign, IDictionary<string, object> additionalParameters, IBinaryContainer postData) {
return MakeOAuthRequest(method, requestUrl, requestUrl, headers, parametersToSign, additionalParameters, postData);
}
/// <summary>
/// Submit a web request using oAuth. /// Submit a web request using oAuth.
/// </summary> /// </summary>
/// <param name="method">GET or POST</param> /// <param name="method">GET or POST</param>

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