mirror of
https://github.com/greenshot/greenshot
synced 2025-08-24 07:06:23 -07:00
Merge remote-tracking branch 'origin/release/1.3' into bug/overflow-exception-on-scale
# Conflicts: # Greenshot/Helpers/ScaleHelper.cs
This commit is contained in:
commit
20096720e8
237 changed files with 6533 additions and 13029 deletions
78
.editorconfig
Normal file
78
.editorconfig
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
# EditorConfig is awesome:http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Don't use tabs for indentation.
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
# (Please don't specify an indent_size here; that has too many unintended consequences.)
|
||||||
|
|
||||||
|
# Code files
|
||||||
|
[*.{cs,csx,vb,vbx}]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# Xml project files
|
||||||
|
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# Xml config files
|
||||||
|
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# JSON files
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# Dotnet code style settings:
|
||||||
|
[*.{cs,vb}]
|
||||||
|
# Sort using and Import directives with System.* appearing first
|
||||||
|
dotnet_sort_system_directives_first = true
|
||||||
|
# Avoid "this." and "Me." if not necessary
|
||||||
|
dotnet_style_qualification_for_field = false:suggestion
|
||||||
|
dotnet_style_qualification_for_property = false:suggestion
|
||||||
|
dotnet_style_qualification_for_method = false:suggestion
|
||||||
|
dotnet_style_qualification_for_event = false:suggestion
|
||||||
|
|
||||||
|
# Use language keywords instead of framework type names for type references
|
||||||
|
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||||
|
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||||
|
|
||||||
|
# Suggest more modern language features when available
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
|
||||||
|
# CSharp code style settings:
|
||||||
|
[*.cs]
|
||||||
|
# Prefer "var" everywhere
|
||||||
|
csharp_style_var_for_built_in_types = true:suggestion
|
||||||
|
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||||
|
csharp_style_var_elsewhere = true:suggestion
|
||||||
|
|
||||||
|
# Prefer method-like constructs to have a block body
|
||||||
|
csharp_style_expression_bodied_methods = false:none
|
||||||
|
csharp_style_expression_bodied_constructors = false:none
|
||||||
|
csharp_style_expression_bodied_operators = false:none
|
||||||
|
|
||||||
|
# Prefer property-like constructs to have an expression-body
|
||||||
|
csharp_style_expression_bodied_properties = true:none
|
||||||
|
csharp_style_expression_bodied_indexers = true:none
|
||||||
|
csharp_style_expression_bodied_accessors = true:none
|
||||||
|
|
||||||
|
# Suggest more modern language features when available
|
||||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
|
csharp_style_throw_expression = true:suggestion
|
||||||
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
|
||||||
|
# Newline settings
|
||||||
|
csharp_new_line_before_open_brace = all
|
||||||
|
csharp_new_line_before_else = true
|
||||||
|
csharp_new_line_before_catch = true
|
||||||
|
csharp_new_line_before_finally = true
|
||||||
|
csharp_new_line_before_members_in_object_initializers = true
|
||||||
|
csharp_new_line_before_members_in_anonymous_types = true
|
46
CODE_OF_CONDUCT.md
Normal file
46
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at getgreenshot@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/4/
|
18
CONTRIBUTING.md
Normal file
18
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
The general rule we follow is "use Visual Studio defaults".
|
||||||
|
|
||||||
|
1. We use [Allman style](http://en.wikipedia.org/wiki/Indent_style#Allman_style) braces, where each brace begins on a new line. A single line statement block can go without braces but the block must be properly indented on its own line and it must not be nested in other statement blocks that use braces (See issue [381](https://github.com/dotnet/corefx/issues/381) for examples).
|
||||||
|
2. We use four spaces of indentation (no tabs).
|
||||||
|
3. We use `_camelCase` for internal and private fields and use `readonly` where possible. Prefix instance fields with `_`, static fields with `s_` and thread static fields with `t_`. When used on static fields, `readonly` should come after `static` (e.g. `static readonly` not `readonly static`).
|
||||||
|
4. We avoid `this.` unless absolutely necessary.
|
||||||
|
5. We always specify the visibility, even if it's the default (e.g. `private string _foo` not `string _foo`). Visibility should be the first modifier (e.g. `public abstract` not `abstract public`).
|
||||||
|
6. Namespace imports should be specified at the top of the file, *outside* of `namespace` declarations and should be sorted alphabetically.
|
||||||
|
7. Avoid more than one empty line at any time. For example, do not have two blank lines between members of a type.
|
||||||
|
8. Avoid spurious free spaces. For example avoid `if (someVar == 0)...`, where the dots mark the spurious free spaces. Consider enabling "View White Space (Ctrl+E, S)" if using Visual Studio, to aid detection.
|
||||||
|
9. If a file happens to differ in style from these guidelines (e.g. private members are named `m_member` rather than `_member`), the existing style in that file takes precedence.
|
||||||
|
10. We only use `var` when it's obvious what the variable type is (e.g. `var stream = new FileStream(...)` not `var stream = OpenStandardInput()`).
|
||||||
|
11. We use language keywords instead of BCL types (e.g. `int, string, float` instead of `Int32, String, Single`, etc) for both type references as well as method calls (e.g. `int.Parse` instead of `Int32.Parse`). See issue [391](https://github.com/dotnet/corefx/issues/391) for examples.
|
||||||
|
12. We use PascalCasing to name all our constant local variables and fields. The only exception is for interop code where the constant value should exactly match the name and value of the code you are calling via interop.
|
||||||
|
13. We use ```nameof(...)``` instead of ```"..."``` whenever possible and relevant.
|
||||||
|
14. Fields should be specified at the top within type declarations.
|
||||||
|
15. When including non-ASCII characters in the source code use Unicode escape sequences (\uXXXX) instead of literal characters. Literal non-ASCII characters occasionally get garbled by a tool or editor.
|
||||||
|
16. Do not use labels (e.g. for goto).
|
|
@ -65,17 +65,17 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Tokens Include="Box_ClientId">
|
<Tokens Include="Box13_ClientId">
|
||||||
<ReplacementValue>$(Box_ClientId)</ReplacementValue>
|
<ReplacementValue>$(Box13_ClientId)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="Box_ClientSecret">
|
<Tokens Include="Box13_ClientSecret">
|
||||||
<ReplacementValue>$(Box_ClientSecret)</ReplacementValue>
|
<ReplacementValue>$(Box13_ClientSecret)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="DropBox_ClientId">
|
<Tokens Include="DropBox13_ClientId">
|
||||||
<ReplacementValue>$(DropBox_ClientId)</ReplacementValue>
|
<ReplacementValue>$(DropBox13_ClientId)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="DropBox_ClientSecret">
|
<Tokens Include="DropBox13_ClientSecret">
|
||||||
<ReplacementValue>$(DropBox_ClientSecret)</ReplacementValue>
|
<ReplacementValue>$(DropBox13_ClientSecret)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="Flickr_ClientId">
|
<Tokens Include="Flickr_ClientId">
|
||||||
<ReplacementValue>$(Flickr_ClientId)</ReplacementValue>
|
<ReplacementValue>$(Flickr_ClientId)</ReplacementValue>
|
||||||
|
@ -83,11 +83,11 @@
|
||||||
<Tokens Include="Flickr_ClientSecret">
|
<Tokens Include="Flickr_ClientSecret">
|
||||||
<ReplacementValue>$(Flickr_ClientSecret)</ReplacementValue>
|
<ReplacementValue>$(Flickr_ClientSecret)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="Imgur_ClientId">
|
<Tokens Include="Imgur13_ClientId">
|
||||||
<ReplacementValue>$(Imgur_ClientId)</ReplacementValue>
|
<ReplacementValue>$(Imgur13_ClientId)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="Imgur_ClientSecret">
|
<Tokens Include="Imgur13_ClientSecret">
|
||||||
<ReplacementValue>$(Imgur_ClientSecret)</ReplacementValue>
|
<ReplacementValue>$(Imgur13_ClientSecret)</ReplacementValue>
|
||||||
</Tokens>
|
</Tokens>
|
||||||
<Tokens Include="Photobucket_ClientId">
|
<Tokens Include="Photobucket_ClientId">
|
||||||
<ReplacementValue>$(Photobucket_ClientId)</ReplacementValue>
|
<ReplacementValue>$(Photobucket_ClientId)</ReplacementValue>
|
||||||
|
|
|
@ -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,20 +28,13 @@ 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}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotFlickrPlugin", "GreenshotFlickrPlugin\GreenshotFlickrPlugin.csproj", "{7EC72A5A-D73A-4B4B-9CA1-2216C7D92D5E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotFlickrPlugin", "GreenshotFlickrPlugin\GreenshotFlickrPlugin.csproj", "{7EC72A5A-D73A-4B4B-9CA1-2216C7D92D5E}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotPicasaPlugin", "GreenshotPicasaPlugin\GreenshotPicasaPlugin.csproj", "{1893A2E4-A78A-4713-A8E7-E70058DABEE0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotGooglePhotosPlugin", "GreenshotGooglePhotosPlugin\GreenshotGooglePhotosPlugin.csproj", "{1893A2E4-A78A-4713-A8E7-E70058DABEE0}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotOfficePlugin", "GreenshotOfficePlugin\GreenshotOfficePlugin.csproj", "{92599C09-FF29-4ABD-B6E6-C48ECD781BAB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenshotOfficePlugin", "GreenshotOfficePlugin\GreenshotOfficePlugin.csproj", "{92599C09-FF29-4ABD-B6E6-C48ECD781BAB}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -40,10 +40,12 @@ namespace Greenshot.Destinations {
|
||||||
private readonly IImageEditor editor;
|
private readonly IImageEditor editor;
|
||||||
private static readonly Image greenshotIcon = GreenshotResources.GetGreenshotIcon().ToBitmap();
|
private static readonly Image greenshotIcon = GreenshotResources.GetGreenshotIcon().ToBitmap();
|
||||||
|
|
||||||
public EditorDestination() {
|
public EditorDestination()
|
||||||
}
|
{
|
||||||
|
// Do not remove, is needed for the framework
|
||||||
public EditorDestination(IImageEditor editor) {
|
}
|
||||||
|
|
||||||
|
public EditorDestination(IImageEditor editor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,10 +105,6 @@ namespace Greenshot.Drawing {
|
||||||
cursor.DrawStretched(graphics, Bounds);
|
cursor.DrawStretched(graphics, Bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Size DefaultSize {
|
public override Size DefaultSize => cursor?.Size ?? new Size(16, 16);
|
||||||
get {
|
|
||||||
return cursor.Size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,23 +548,11 @@ namespace Greenshot.Drawing
|
||||||
return ScaleHelper.ShapeAngleRoundBehavior.Instance;
|
return ScaleHelper.ShapeAngleRoundBehavior.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool HasContextMenu {
|
public virtual bool HasContextMenu => true;
|
||||||
get {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool HasDefaultSize {
|
public virtual bool HasDefaultSize => false;
|
||||||
get {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Size DefaultSize {
|
public virtual Size DefaultSize => throw new NotSupportedException("Object doesn't have a default size");
|
||||||
get {
|
|
||||||
throw new NotSupportedException("Object doesn't have a default size");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows to override the initializing of the fields, so we can actually have our own defaults
|
/// Allows to override the initializing of the fields, so we can actually have our own defaults
|
||||||
|
|
|
@ -30,17 +30,13 @@ namespace Greenshot.Drawing {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// empty container for filter-only elements
|
/// empty container for filter-only elements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable()]
|
[Serializable]
|
||||||
public abstract class FilterContainer : DrawableContainer {
|
public abstract class FilterContainer : DrawableContainer {
|
||||||
|
|
||||||
public enum PreparedFilterMode {OBFUSCATE, HIGHLIGHT};
|
public enum PreparedFilterMode {OBFUSCATE, HIGHLIGHT};
|
||||||
public enum PreparedFilter {BLUR, PIXELIZE, TEXT_HIGHTLIGHT, AREA_HIGHLIGHT, GRAYSCALE, MAGNIFICATION};
|
public enum PreparedFilter {BLUR, PIXELIZE, TEXT_HIGHTLIGHT, AREA_HIGHLIGHT, GRAYSCALE, MAGNIFICATION};
|
||||||
|
|
||||||
public PreparedFilter Filter {
|
public FilterContainer(Surface parent) : base(parent) {
|
||||||
get { return (PreparedFilter)GetFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterContainer(Surface parent) : base(parent) {
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace Greenshot.Drawing {
|
||||||
Width = value.Width;
|
Width = value.Width;
|
||||||
Height = value.Height;
|
Height = value.Height;
|
||||||
}
|
}
|
||||||
get { return icon; }
|
get => icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,27 +78,32 @@ namespace Greenshot.Drawing {
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load(string filename) {
|
public void Load(string filename)
|
||||||
if (File.Exists(filename))
|
{
|
||||||
{
|
if (!File.Exists(filename))
|
||||||
using Icon fileIcon = new Icon(filename);
|
{
|
||||||
Icon = fileIcon;
|
return;
|
||||||
Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
|
}
|
||||||
}
|
using Icon fileIcon = new Icon(filename);
|
||||||
|
Icon = fileIcon;
|
||||||
|
Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm)
|
||||||
if (icon != null) {
|
{
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
if (icon == null)
|
||||||
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
{
|
||||||
graphics.CompositingQuality = CompositingQuality.Default;
|
return;
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
||||||
graphics.DrawIcon(icon, Bounds);
|
|
||||||
}
|
}
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.Default;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
graphics.DrawIcon(icon, Bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HasDefaultSize => true;
|
public override bool HasDefaultSize => true;
|
||||||
|
|
||||||
public override Size DefaultSize => icon.Size;
|
public override Size DefaultSize => icon?.Size ?? new Size(16,16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,11 +77,14 @@ namespace Greenshot.Drawing {
|
||||||
AddField(GetType(), FieldType.SHADOW, false);
|
AddField(GetType(), FieldType.SHADOW, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void BitmapContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) {
|
protected void BitmapContainer_OnFieldChanged(object sender, FieldChangedEventArgs e)
|
||||||
if (sender.Equals(this)) {
|
{
|
||||||
if (FieldType.SHADOW.Equals(e.Field.FieldType)) {
|
if (!sender.Equals(this))
|
||||||
ChangeShadowField();
|
{
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
if (FieldType.SHADOW.Equals(e.Field.FieldType)) {
|
||||||
|
ChangeShadowField();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,12 +192,14 @@ namespace Greenshot.Drawing {
|
||||||
/// This checks if a shadow is already generated
|
/// This checks if a shadow is already generated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="shadow"></param>
|
/// <param name="shadow"></param>
|
||||||
private void CheckShadow(bool shadow) {
|
private void CheckShadow(bool shadow)
|
||||||
if (shadow && _shadowBitmap == null)
|
{
|
||||||
{
|
if (!shadow || _shadowBitmap != null)
|
||||||
using var matrix = new Matrix();
|
{
|
||||||
_shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), matrix);
|
return;
|
||||||
}
|
}
|
||||||
|
using var matrix = new Matrix();
|
||||||
|
_shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -202,25 +207,28 @@ namespace Greenshot.Drawing {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="graphics"></param>
|
/// <param name="graphics"></param>
|
||||||
/// <param name="rm"></param>
|
/// <param name="rm"></param>
|
||||||
public override void Draw(Graphics graphics, RenderMode rm) {
|
public override void Draw(Graphics graphics, RenderMode rm)
|
||||||
if (image != null) {
|
{
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
if (image == null)
|
||||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
{
|
||||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
return;
|
||||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
}
|
||||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
CheckShadow(true);
|
CheckShadow(true);
|
||||||
graphics.DrawImage(_shadowBitmap, Bounds);
|
graphics.DrawImage(_shadowBitmap, Bounds);
|
||||||
} else {
|
} else {
|
||||||
graphics.DrawImage(image, Bounds);
|
graphics.DrawImage(image, Bounds);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HasDefaultSize => true;
|
public override bool HasDefaultSize => true;
|
||||||
|
|
||||||
public override Size DefaultSize => image.Size;
|
public override Size DefaultSize => image?.Size ?? new Size(32, 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,135 +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.Drawing;
|
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
|
|
||||||
namespace Greenshot.Drawing {
|
|
||||||
/// <summary>
|
|
||||||
/// TODO: currently this is only used in the capture form, we might move this code directly to there!
|
|
||||||
/// </summary>
|
|
||||||
public abstract class RoundedRectangle {
|
|
||||||
[Flags]
|
|
||||||
public enum RectangleCorners {
|
|
||||||
None = 0, TopLeft = 1, TopRight = 2,
|
|
||||||
BottomLeft = 4, BottomRight = 8,
|
|
||||||
All = TopLeft | TopRight | BottomLeft | BottomRight
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GraphicsPath Create2(int x, int y, int width, int height, int radius) {
|
|
||||||
GraphicsPath gp = new GraphicsPath();
|
|
||||||
gp.AddLine(x + radius, y, x + width - radius * 2, y); // Line
|
|
||||||
gp.AddArc(x + width - radius * 2, y, radius * 2, radius * 2, 270, 90); // Corner
|
|
||||||
gp.AddLine(x + width, y + radius, x + width, y + height - radius * 2); // Line
|
|
||||||
gp.AddArc(x + width - radius * 2, y + height - radius * 2, radius * 2, radius * 2, 0, 90); // Corner
|
|
||||||
gp.AddLine(x + width - radius * 2, y + height, x + radius, y + height); // Line
|
|
||||||
gp.AddArc(x, y + height - radius * 2, radius * 2, radius * 2, 90, 90); // Corner
|
|
||||||
gp.AddLine(x, y + height - radius * 2, x, y + radius); // Line
|
|
||||||
gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner
|
|
||||||
gp.CloseFigure();
|
|
||||||
|
|
||||||
return gp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GraphicsPath Create(int x, int y, int width, int height, int radius, RectangleCorners corners) {
|
|
||||||
int xw = x + width;
|
|
||||||
int yh = y + height;
|
|
||||||
int xwr = xw - radius;
|
|
||||||
int yhr = yh - radius;
|
|
||||||
int xr = x + radius;
|
|
||||||
int yr = y + radius;
|
|
||||||
int r2 = radius * 2;
|
|
||||||
int xwr2 = xw - r2;
|
|
||||||
int yhr2 = yh - r2;
|
|
||||||
|
|
||||||
GraphicsPath p = new GraphicsPath();
|
|
||||||
p.StartFigure();
|
|
||||||
|
|
||||||
//Top Left Corner
|
|
||||||
if ((RectangleCorners.TopLeft & corners) == RectangleCorners.TopLeft) {
|
|
||||||
p.AddArc(x, y, r2, r2, 180, 90);
|
|
||||||
} else {
|
|
||||||
p.AddLine(x, yr, x, y);
|
|
||||||
p.AddLine(x, y, xr, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Top Edge
|
|
||||||
p.AddLine(xr, y, xwr, y);
|
|
||||||
|
|
||||||
//Top Right Corner
|
|
||||||
if ((RectangleCorners.TopRight & corners) == RectangleCorners.TopRight) {
|
|
||||||
p.AddArc(xwr2, y, r2, r2, 270, 90);
|
|
||||||
} else {
|
|
||||||
p.AddLine(xwr, y, xw, y);
|
|
||||||
p.AddLine(xw, y, xw, yr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Right Edge
|
|
||||||
p.AddLine(xw, yr, xw, yhr);
|
|
||||||
|
|
||||||
//Bottom Right Corner
|
|
||||||
if ((RectangleCorners.BottomRight & corners) == RectangleCorners.BottomRight) {
|
|
||||||
p.AddArc(xwr2, yhr2, r2, r2, 0, 90);
|
|
||||||
} else {
|
|
||||||
p.AddLine(xw, yhr, xw, yh);
|
|
||||||
p.AddLine(xw, yh, xwr, yh);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Bottom Edge
|
|
||||||
p.AddLine(xwr, yh, xr, yh);
|
|
||||||
|
|
||||||
//Bottom Left Corner
|
|
||||||
if ((RectangleCorners.BottomLeft & corners) == RectangleCorners.BottomLeft) {
|
|
||||||
p.AddArc(x, yhr2, r2, r2, 90, 90);
|
|
||||||
} else {
|
|
||||||
p.AddLine(xr, yh, x, yh);
|
|
||||||
p.AddLine(x, yh, x, yhr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Left Edge
|
|
||||||
p.AddLine(x, yhr, x, yr);
|
|
||||||
|
|
||||||
p.CloseFigure();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners corners) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GraphicsPath Create(Rectangle rect, int radius) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GraphicsPath Create(Rectangle rect) {
|
|
||||||
return Create(rect.X, rect.Y, rect.Width, rect.Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -598,9 +598,15 @@ namespace Greenshot.Drawing
|
||||||
DrawText(graphics, rect, lineThickness, lineColor, drawShadow, _stringFormat, text, _font);
|
DrawText(graphics, rect, lineThickness, lineColor, drawShadow, _stringFormat, text, _font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert the StringFormat information into a TextFormatFlags
|
||||||
|
/// This is important for the rending to work, have it aligned to the correct place
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stringFormat">StringFormat</param>
|
||||||
|
/// <returns>TextFormatFlags</returns>
|
||||||
private static TextFormatFlags ConvertStringFormat(StringFormat stringFormat)
|
private static TextFormatFlags ConvertStringFormat(StringFormat stringFormat)
|
||||||
{
|
{
|
||||||
TextFormatFlags flags = TextFormatFlags.Default;
|
var flags = TextFormatFlags.TextBoxControl | TextFormatFlags.WordBreak;
|
||||||
if (stringFormat == null)
|
if (stringFormat == null)
|
||||||
{
|
{
|
||||||
return flags;
|
return flags;
|
||||||
|
@ -683,14 +689,7 @@ namespace Greenshot.Drawing
|
||||||
drawingRectange.Inflate(-textOffset, -textOffset);
|
drawingRectange.Inflate(-textOffset, -textOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stringFormat != null)
|
TextRenderer.DrawText(graphics, text, font, drawingRectange, fontColor, ConvertStringFormat(stringFormat));
|
||||||
{
|
|
||||||
TextRenderer.DrawText(graphics, text, font, drawingRectange, fontColor, ConvertStringFormat(stringFormat));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TextRenderer.DrawText(graphics, text, font, drawingRectange, fontColor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ClickableAt(int x, int y)
|
public override bool ClickableAt(int x, int y)
|
||||||
|
|
1
Greenshot/Forms/AboutForm.Designer.cs
generated
1
Greenshot/Forms/AboutForm.Designer.cs
generated
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
|
using GreenshotPlugin.Core;
|
||||||
|
|
||||||
namespace Greenshot.Forms {
|
namespace Greenshot.Forms {
|
||||||
partial class AboutForm {
|
partial class AboutForm {
|
||||||
|
|
|
@ -905,7 +905,7 @@ namespace Greenshot.Forms {
|
||||||
// horizontal ruler
|
// horizontal ruler
|
||||||
if (fixedRect.Width > hSpace + 3)
|
if (fixedRect.Width > hSpace + 3)
|
||||||
{
|
{
|
||||||
using GraphicsPath p = RoundedRectangle.Create2(
|
using GraphicsPath p = CreateRoundedRectangle(
|
||||||
fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3,
|
fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3,
|
||||||
fixedRect.Y - dist - 7,
|
fixedRect.Y - dist - 7,
|
||||||
measureWidth.Width - 3,
|
measureWidth.Width - 3,
|
||||||
|
@ -923,7 +923,7 @@ namespace Greenshot.Forms {
|
||||||
// vertical ruler
|
// vertical ruler
|
||||||
if (fixedRect.Height > vSpace + 3)
|
if (fixedRect.Height > vSpace + 3)
|
||||||
{
|
{
|
||||||
using GraphicsPath p = RoundedRectangle.Create2(
|
using GraphicsPath p = CreateRoundedRectangle(
|
||||||
fixedRect.X - measureHeight.Width + 1,
|
fixedRect.X - measureHeight.Width + 1,
|
||||||
fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2,
|
fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2,
|
||||||
measureHeight.Width - 3,
|
measureHeight.Width - 3,
|
||||||
|
@ -990,7 +990,7 @@ namespace Greenshot.Forms {
|
||||||
string xy = _cursorPos.X + " x " + _cursorPos.Y;
|
string xy = _cursorPos.X + " x " + _cursorPos.Y;
|
||||||
using Font f = new Font(FontFamily.GenericSansSerif, 8);
|
using Font f = new Font(FontFamily.GenericSansSerif, 8);
|
||||||
Size xySize = TextRenderer.MeasureText(xy, f);
|
Size xySize = TextRenderer.MeasureText(xy, f);
|
||||||
using GraphicsPath gp = RoundedRectangle.Create2(_cursorPos.X + 5, _cursorPos.Y + 5, xySize.Width - 3, xySize.Height, 3);
|
using GraphicsPath gp = CreateRoundedRectangle(_cursorPos.X + 5, _cursorPos.Y + 5, xySize.Width - 3, xySize.Height, 3);
|
||||||
using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227))) {
|
using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227))) {
|
||||||
graphics.FillPath(bgBrush, gp);
|
graphics.FillPath(bgBrush, gp);
|
||||||
}
|
}
|
||||||
|
@ -1014,5 +1014,21 @@ namespace Greenshot.Forms {
|
||||||
DrawZoom(graphics, sourceRectangle, destinationRectangle);
|
DrawZoom(graphics, sourceRectangle, destinationRectangle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static GraphicsPath CreateRoundedRectangle(int x, int y, int width, int height, int radius)
|
||||||
|
{
|
||||||
|
var gp = new GraphicsPath();
|
||||||
|
gp.AddLine(x + radius, y, x + width - radius * 2, y); // Line
|
||||||
|
gp.AddArc(x + width - radius * 2, y, radius * 2, radius * 2, 270, 90); // Corner
|
||||||
|
gp.AddLine(x + width, y + radius, x + width, y + height - radius * 2); // Line
|
||||||
|
gp.AddArc(x + width - radius * 2, y + height - radius * 2, radius * 2, radius * 2, 0, 90); // Corner
|
||||||
|
gp.AddLine(x + width - radius * 2, y + height, x + radius, y + height); // Line
|
||||||
|
gp.AddArc(x, y + height - radius * 2, radius * 2, radius * 2, 90, 90); // Corner
|
||||||
|
gp.AddLine(x, y + height - radius * 2, x, y + radius); // Line
|
||||||
|
gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner
|
||||||
|
gp.CloseFigure();
|
||||||
|
|
||||||
|
return gp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,6 @@ namespace Greenshot.Forms {
|
||||||
set { PreviewColor(value, this); }
|
set { PreviewColor(value, this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Color> RecentColors => EditorConfig.RecentColors;
|
|
||||||
|
|
||||||
private void CreateColorPalette(int x, int y, int w, int h) {
|
private void CreateColorPalette(int x, int y, int w, int h) {
|
||||||
CreateColorButtonColumn(255, 0, 0, x, y, w, h, 11);
|
CreateColorButtonColumn(255, 0, 0, x, y, w, h, 11);
|
||||||
x += w;
|
x += w;
|
||||||
|
|
|
@ -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));
|
||||||
|
@ -517,14 +512,6 @@ namespace Greenshot.Forms {
|
||||||
|
|
||||||
public ICaptureDetails CaptureDetails => _surface.CaptureDetails;
|
public ICaptureDetails CaptureDetails => _surface.CaptureDetails;
|
||||||
|
|
||||||
public ToolStripMenuItem GetPluginMenuItem() {
|
|
||||||
return pluginToolStripMenuItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ToolStripMenuItem GetFileMenuItem() {
|
|
||||||
return fileStripMenuItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BtnSaveClick(object sender, EventArgs e) {
|
private void BtnSaveClick(object sender, EventArgs e) {
|
||||||
string destinationDesignation = FileDestination.DESIGNATION;
|
string destinationDesignation = FileDestination.DESIGNATION;
|
||||||
if (_surface.LastSaveFullPath == null) {
|
if (_surface.LastSaveFullPath == null) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -923,7 +918,7 @@ namespace Greenshot.Forms {
|
||||||
|
|
||||||
private void ShowThumbnailOnEnter(object sender, EventArgs e) {
|
private void ShowThumbnailOnEnter(object sender, EventArgs e) {
|
||||||
if (sender is not ToolStripMenuItem captureWindowItem) return;
|
if (sender is not ToolStripMenuItem captureWindowItem) return;
|
||||||
WindowDetails window = captureWindowItem.Tag as WindowDetails;
|
var window = captureWindowItem.Tag as WindowDetails;
|
||||||
if (_thumbnailForm == null) {
|
if (_thumbnailForm == null) {
|
||||||
_thumbnailForm = new ThumbnailForm();
|
_thumbnailForm = new ThumbnailForm();
|
||||||
}
|
}
|
||||||
|
@ -944,29 +939,39 @@ namespace Greenshot.Forms {
|
||||||
_thumbnailForm = null;
|
_thumbnailForm = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create the "capture window from list" list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="menuItem">ToolStripMenuItem</param>
|
||||||
|
/// <param name="eventHandler">EventHandler</param>
|
||||||
public void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler) {
|
public void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler) {
|
||||||
menuItem.DropDownItems.Clear();
|
menuItem.DropDownItems.Clear();
|
||||||
// check if thumbnailPreview is enabled and DWM is enabled
|
// check if thumbnailPreview is enabled and DWM is enabled
|
||||||
bool thumbnailPreview = _conf.ThumnailPreview && DWM.IsDwmEnabled;
|
bool thumbnailPreview = _conf.ThumnailPreview && DWM.IsDwmEnabled;
|
||||||
|
|
||||||
foreach(WindowDetails window in WindowDetails.GetTopLevelWindows()) {
|
foreach(var window in WindowDetails.GetTopLevelWindows()) {
|
||||||
|
if (LOG.IsDebugEnabled)
|
||||||
|
{
|
||||||
|
LOG.Debug(window.ToString());
|
||||||
|
}
|
||||||
string title = window.Text;
|
string title = window.Text;
|
||||||
if (title != null) {
|
if (string.IsNullOrEmpty(title))
|
||||||
if (title.Length > _conf.MaxMenuItemLength) {
|
{
|
||||||
title = title.Substring(0, Math.Min(title.Length, _conf.MaxMenuItemLength));
|
continue;
|
||||||
}
|
}
|
||||||
ToolStripItem captureWindowItem = menuItem.DropDownItems.Add(title);
|
if (title.Length > _conf.MaxMenuItemLength) {
|
||||||
captureWindowItem.Tag = window;
|
title = title.Substring(0, Math.Min(title.Length, _conf.MaxMenuItemLength));
|
||||||
captureWindowItem.Image = window.DisplayIcon;
|
}
|
||||||
captureWindowItem.Click += eventHandler;
|
ToolStripItem captureWindowItem = menuItem.DropDownItems.Add(title);
|
||||||
// Only show preview when enabled
|
captureWindowItem.Tag = window;
|
||||||
if (thumbnailPreview) {
|
captureWindowItem.Image = window.DisplayIcon;
|
||||||
captureWindowItem.MouseEnter += ShowThumbnailOnEnter;
|
captureWindowItem.Click += eventHandler;
|
||||||
captureWindowItem.MouseLeave += HideThumbnailOnLeave;
|
// Only show preview when enabled
|
||||||
}
|
if (thumbnailPreview) {
|
||||||
}
|
captureWindowItem.MouseEnter += ShowThumbnailOnEnter;
|
||||||
}
|
captureWindowItem.MouseLeave += HideThumbnailOnLeave;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureAreaToolStripMenuItemClick(object sender, EventArgs e) {
|
private void CaptureAreaToolStripMenuItemClick(object sender, EventArgs e) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -970,7 +970,7 @@ namespace Greenshot.Helpers {
|
||||||
// The following, to be precise the HideApp, causes the app to close as described in BUG-1620
|
// The following, to be precise the HideApp, causes the app to close as described in BUG-1620
|
||||||
// Added check for metro (Modern UI) apps, which might be maximized and cover the screen.
|
// Added check for metro (Modern UI) apps, which might be maximized and cover the screen.
|
||||||
|
|
||||||
//foreach(WindowDetails app in WindowDetails.GetMetroApps()) {
|
//foreach(WindowDetails app in WindowDetails.GetAppWindows()) {
|
||||||
// if (app.Maximised) {
|
// if (app.Maximised) {
|
||||||
// app.HideApp();
|
// app.HideApp();
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -1,855 +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.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using GreenshotPlugin.Core;
|
|
||||||
using GreenshotPlugin.IniFile;
|
|
||||||
using GreenshotPlugin.UnmanagedHelpers;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace Greenshot.Helpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Description of EnvironmentInfo.
|
|
||||||
/// </summary>
|
|
||||||
public static class EnvironmentInfo
|
|
||||||
{
|
|
||||||
private static bool? _isWindows;
|
|
||||||
|
|
||||||
public static bool IsWindows
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_isWindows.HasValue)
|
|
||||||
{
|
|
||||||
return _isWindows.Value;
|
|
||||||
}
|
|
||||||
_isWindows = Environment.OSVersion.Platform.ToString().StartsWith("Win");
|
|
||||||
return _isWindows.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsNet45OrNewer()
|
|
||||||
{
|
|
||||||
// Class "ReflectionContext" exists from .NET 4.5 onwards.
|
|
||||||
return Type.GetType("System.Reflection.ReflectionContext", false) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetGreenshotVersion(bool shortVersion = false)
|
|
||||||
{
|
|
||||||
var executingAssembly = Assembly.GetExecutingAssembly();
|
|
||||||
|
|
||||||
// Use assembly version
|
|
||||||
string greenshotVersion = executingAssembly.GetName().Version.ToString();
|
|
||||||
|
|
||||||
// Use AssemblyFileVersion if available
|
|
||||||
var assemblyFileVersionAttribute = executingAssembly.GetCustomAttribute<AssemblyFileVersionAttribute>();
|
|
||||||
if (!string.IsNullOrEmpty(assemblyFileVersionAttribute?.Version))
|
|
||||||
{
|
|
||||||
var assemblyFileVersion = new Version(assemblyFileVersionAttribute.Version);
|
|
||||||
greenshotVersion = assemblyFileVersion.ToString(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shortVersion)
|
|
||||||
{
|
|
||||||
// Use AssemblyInformationalVersion if available
|
|
||||||
var informationalVersionAttribute = executingAssembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
|
|
||||||
if (!string.IsNullOrEmpty(informationalVersionAttribute?.InformationalVersion))
|
|
||||||
{
|
|
||||||
greenshotVersion = informationalVersionAttribute.InformationalVersion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return greenshotVersion.Replace("+", " - ");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string EnvironmentToString(bool newline)
|
|
||||||
{
|
|
||||||
StringBuilder environment = new StringBuilder();
|
|
||||||
environment.Append("Software version: " + GetGreenshotVersion());
|
|
||||||
if (IniConfig.IsPortable) {
|
|
||||||
environment.Append(" Portable");
|
|
||||||
}
|
|
||||||
environment.Append(" (" + OsInfo.Bits + " bit)");
|
|
||||||
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
environment.Append(".NET runtime version: " + Environment.Version);
|
|
||||||
if (IsNet45OrNewer())
|
|
||||||
{
|
|
||||||
environment.Append("+");
|
|
||||||
|
|
||||||
}
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
environment.Append("Time: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss zzz"));
|
|
||||||
|
|
||||||
if (IsWindows)
|
|
||||||
{
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
environment.Append($"OS: {OsInfo.Name}");
|
|
||||||
if (!string.IsNullOrEmpty(OsInfo.Edition))
|
|
||||||
{
|
|
||||||
environment.Append($" {OsInfo.Edition}");
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(OsInfo.ServicePack))
|
|
||||||
{
|
|
||||||
environment.Append($" {OsInfo.ServicePack}");
|
|
||||||
|
|
||||||
}
|
|
||||||
environment.Append($" x{OsInfo.Bits}");
|
|
||||||
environment.Append($" {OsInfo.VersionString}");
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
// Get some important information for fixing GDI related Problems
|
|
||||||
environment.AppendFormat("GDI object count: {0}", User32.GetGuiResourcesGDICount());
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
environment.AppendFormat("User object count: {0}", User32.GetGuiResourcesUserCount());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
environment.AppendFormat("OS: {0}", Environment.OSVersion.Platform);
|
|
||||||
}
|
|
||||||
if (newline)
|
|
||||||
{
|
|
||||||
environment.AppendLine();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
environment.Append(", ");
|
|
||||||
}
|
|
||||||
// TODO: Is this needed?
|
|
||||||
// environment.AppendFormat("Surface count: {0}", Surface.Count);
|
|
||||||
|
|
||||||
return environment.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ExceptionToString(Exception ex)
|
|
||||||
{
|
|
||||||
if (ex == null)
|
|
||||||
return "null\r\n";
|
|
||||||
|
|
||||||
StringBuilder report = new StringBuilder();
|
|
||||||
|
|
||||||
report.AppendLine("Exception: " + ex.GetType());
|
|
||||||
report.AppendLine("Message: " + ex.Message);
|
|
||||||
if (ex.Data.Count > 0)
|
|
||||||
{
|
|
||||||
report.AppendLine();
|
|
||||||
report.AppendLine("Additional Information:");
|
|
||||||
foreach (object key in ex.Data.Keys)
|
|
||||||
{
|
|
||||||
object data = ex.Data[key];
|
|
||||||
if (data != null)
|
|
||||||
{
|
|
||||||
report.AppendLine(key + " : " + data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ex is ExternalException externalException)
|
|
||||||
{
|
|
||||||
// e.g. COMException
|
|
||||||
report.AppendLine().AppendLine("ErrorCode: 0x" + externalException.ErrorCode.ToString("X"));
|
|
||||||
}
|
|
||||||
|
|
||||||
report.AppendLine().AppendLine("Stack:").AppendLine(ex.StackTrace);
|
|
||||||
|
|
||||||
if (ex is ReflectionTypeLoadException reflectionTypeLoadException)
|
|
||||||
{
|
|
||||||
report.AppendLine().AppendLine("LoaderExceptions: ");
|
|
||||||
foreach (Exception cbE in reflectionTypeLoadException.LoaderExceptions)
|
|
||||||
{
|
|
||||||
report.AppendLine(cbE.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ex.InnerException != null)
|
|
||||||
{
|
|
||||||
report.AppendLine("--- InnerException: ---");
|
|
||||||
report.AppendLine(ExceptionToString(ex.InnerException));
|
|
||||||
}
|
|
||||||
return report.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string BuildReport(Exception exception)
|
|
||||||
{
|
|
||||||
StringBuilder exceptionText = new StringBuilder();
|
|
||||||
exceptionText.AppendLine(EnvironmentToString(true));
|
|
||||||
exceptionText.AppendLine(ExceptionToString(exception));
|
|
||||||
exceptionText.AppendLine("Configuration dump:");
|
|
||||||
|
|
||||||
return exceptionText.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides detailed information about the host operating system.
|
|
||||||
/// Code is available at: http://www.csharp411.com/determine-windows-version-and-edition-with-c/
|
|
||||||
/// </summary>
|
|
||||||
public static class OsInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Determines if the current application is 32 or 64-bit.
|
|
||||||
/// </summary>
|
|
||||||
public static int Bits => IntPtr.Size * 8;
|
|
||||||
|
|
||||||
private static string _sEdition;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the edition of the operating system running on this computer.
|
|
||||||
/// </summary>
|
|
||||||
public static string Edition
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_sEdition != null)
|
|
||||||
{
|
|
||||||
return _sEdition; //***** RETURN *****//
|
|
||||||
}
|
|
||||||
|
|
||||||
string edition = string.Empty;
|
|
||||||
|
|
||||||
OperatingSystem osVersion = Environment.OSVersion;
|
|
||||||
OSVERSIONINFOEX osVersionInfo = OSVERSIONINFOEX.Create();
|
|
||||||
|
|
||||||
if (GetVersionEx(ref osVersionInfo))
|
|
||||||
{
|
|
||||||
int majorVersion = osVersion.Version.Major;
|
|
||||||
int minorVersion = osVersion.Version.Minor;
|
|
||||||
byte productType = osVersionInfo.ProductType;
|
|
||||||
ushort suiteMask = osVersionInfo.SuiteMask;
|
|
||||||
|
|
||||||
if (majorVersion == 4)
|
|
||||||
{
|
|
||||||
if (productType == VER_NT_WORKSTATION)
|
|
||||||
{
|
|
||||||
// Windows NT 4.0 Workstation
|
|
||||||
edition = "Workstation";
|
|
||||||
}
|
|
||||||
else if (productType == VER_NT_SERVER)
|
|
||||||
{
|
|
||||||
edition = (suiteMask & VER_SUITE_ENTERPRISE) != 0 ? "Enterprise Server" : "Standard Server";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (majorVersion == 5)
|
|
||||||
{
|
|
||||||
if (productType == VER_NT_WORKSTATION)
|
|
||||||
{
|
|
||||||
if ((suiteMask & VER_SUITE_PERSONAL) != 0)
|
|
||||||
{
|
|
||||||
// Windows XP Home Edition
|
|
||||||
edition = "Home";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Windows XP / Windows 2000 Professional
|
|
||||||
edition = "Professional";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (productType == VER_NT_SERVER)
|
|
||||||
{
|
|
||||||
if (minorVersion == 0)
|
|
||||||
{
|
|
||||||
if ((suiteMask & VER_SUITE_DATACENTER) != 0)
|
|
||||||
{
|
|
||||||
// Windows 2000 Datacenter Server
|
|
||||||
edition = "Datacenter Server";
|
|
||||||
}
|
|
||||||
else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
|
|
||||||
{
|
|
||||||
// Windows 2000 Advanced Server
|
|
||||||
edition = "Advanced Server";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Windows 2000 Server
|
|
||||||
edition = "Server";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((suiteMask & VER_SUITE_DATACENTER) != 0)
|
|
||||||
{
|
|
||||||
// Windows Server 2003 Datacenter Edition
|
|
||||||
edition = "Datacenter";
|
|
||||||
}
|
|
||||||
else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
|
|
||||||
{
|
|
||||||
// Windows Server 2003 Enterprise Edition
|
|
||||||
edition = "Enterprise";
|
|
||||||
}
|
|
||||||
else if ((suiteMask & VER_SUITE_BLADE) != 0)
|
|
||||||
{
|
|
||||||
// Windows Server 2003 Web Edition
|
|
||||||
edition = "Web Edition";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Windows Server 2003 Standard Edition
|
|
||||||
edition = "Standard";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (majorVersion == 6)
|
|
||||||
{
|
|
||||||
if (GetProductInfo(majorVersion, minorVersion, osVersionInfo.ServicePackMajor, osVersionInfo.ServicePackMinor, out var ed))
|
|
||||||
{
|
|
||||||
switch (ed)
|
|
||||||
{
|
|
||||||
case PRODUCT_BUSINESS:
|
|
||||||
edition = "Business";
|
|
||||||
break;
|
|
||||||
case PRODUCT_BUSINESS_N:
|
|
||||||
edition = "Business N";
|
|
||||||
break;
|
|
||||||
case PRODUCT_CLUSTER_SERVER:
|
|
||||||
edition = "HPC Edition";
|
|
||||||
break;
|
|
||||||
case PRODUCT_DATACENTER_SERVER:
|
|
||||||
edition = "Datacenter Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_DATACENTER_SERVER_CORE:
|
|
||||||
edition = "Datacenter Server (core installation)";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE:
|
|
||||||
edition = "Enterprise";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE_N:
|
|
||||||
edition = "Enterprise N";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE_SERVER:
|
|
||||||
edition = "Enterprise Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE_SERVER_CORE:
|
|
||||||
edition = "Enterprise Server (core installation)";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE_SERVER_CORE_V:
|
|
||||||
edition = "Enterprise Server without Hyper-V (core installation)";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE_SERVER_IA64:
|
|
||||||
edition = "Enterprise Server for Itanium-based Systems";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ENTERPRISE_SERVER_V:
|
|
||||||
edition = "Enterprise Server without Hyper-V";
|
|
||||||
break;
|
|
||||||
case PRODUCT_HOME_BASIC:
|
|
||||||
edition = "Home Basic";
|
|
||||||
break;
|
|
||||||
case PRODUCT_HOME_BASIC_N:
|
|
||||||
edition = "Home Basic N";
|
|
||||||
break;
|
|
||||||
case PRODUCT_HOME_PREMIUM:
|
|
||||||
edition = "Home Premium";
|
|
||||||
break;
|
|
||||||
case PRODUCT_HOME_PREMIUM_N:
|
|
||||||
edition = "Home Premium N";
|
|
||||||
break;
|
|
||||||
case PRODUCT_HYPERV:
|
|
||||||
edition = "Microsoft Hyper-V Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
|
|
||||||
edition = "Windows Essential Business Management Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
|
|
||||||
edition = "Windows Essential Business Messaging Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
|
|
||||||
edition = "Windows Essential Business Security Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_SERVER_FOR_SMALLBUSINESS:
|
|
||||||
edition = "Windows Essential Server Solutions";
|
|
||||||
break;
|
|
||||||
case PRODUCT_SERVER_FOR_SMALLBUSINESS_V:
|
|
||||||
edition = "Windows Essential Server Solutions without Hyper-V";
|
|
||||||
break;
|
|
||||||
case PRODUCT_SMALLBUSINESS_SERVER:
|
|
||||||
edition = "Windows Small Business Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STANDARD_SERVER:
|
|
||||||
edition = "Standard Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STANDARD_SERVER_CORE:
|
|
||||||
edition = "Standard Server (core installation)";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STANDARD_SERVER_CORE_V:
|
|
||||||
edition = "Standard Server without Hyper-V (core installation)";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STANDARD_SERVER_V:
|
|
||||||
edition = "Standard Server without Hyper-V";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STARTER:
|
|
||||||
edition = "Starter";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STORAGE_ENTERPRISE_SERVER:
|
|
||||||
edition = "Enterprise Storage Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STORAGE_EXPRESS_SERVER:
|
|
||||||
edition = "Express Storage Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STORAGE_STANDARD_SERVER:
|
|
||||||
edition = "Standard Storage Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_STORAGE_WORKGROUP_SERVER:
|
|
||||||
edition = "Workgroup Storage Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_UNDEFINED:
|
|
||||||
edition = "Unknown product";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ULTIMATE:
|
|
||||||
edition = "Ultimate";
|
|
||||||
break;
|
|
||||||
case PRODUCT_ULTIMATE_N:
|
|
||||||
edition = "Ultimate N";
|
|
||||||
break;
|
|
||||||
case PRODUCT_WEB_SERVER:
|
|
||||||
edition = "Web Server";
|
|
||||||
break;
|
|
||||||
case PRODUCT_WEB_SERVER_CORE:
|
|
||||||
edition = "Web Server (core installation)";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_sEdition = edition;
|
|
||||||
return edition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string _name;
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of the operating system running on this computer.
|
|
||||||
/// </summary>
|
|
||||||
public static string Name
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_name != null)
|
|
||||||
{
|
|
||||||
return _name; //***** RETURN *****//
|
|
||||||
}
|
|
||||||
|
|
||||||
string name = "unknown";
|
|
||||||
|
|
||||||
OperatingSystem osVersion = Environment.OSVersion;
|
|
||||||
OSVERSIONINFOEX osVersionInfo = OSVERSIONINFOEX.Create();
|
|
||||||
if (GetVersionEx(ref osVersionInfo))
|
|
||||||
{
|
|
||||||
int majorVersion = osVersion.Version.Major;
|
|
||||||
int minorVersion = osVersion.Version.Minor;
|
|
||||||
byte productType = osVersionInfo.ProductType;
|
|
||||||
ushort suiteMask = osVersionInfo.SuiteMask;
|
|
||||||
switch (osVersion.Platform)
|
|
||||||
{
|
|
||||||
case PlatformID.Win32Windows:
|
|
||||||
if (majorVersion == 4)
|
|
||||||
{
|
|
||||||
string csdVersion = osVersionInfo.ServicePackVersion;
|
|
||||||
switch (minorVersion)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if (csdVersion == "B" || csdVersion == "C")
|
|
||||||
{
|
|
||||||
name = "Windows 95 OSR2";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name = "Windows 95";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
name = csdVersion == "A" ? "Windows 98 Second Edition" : "Windows 98";
|
|
||||||
break;
|
|
||||||
case 90:
|
|
||||||
name = "Windows Me";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PlatformID.Win32NT:
|
|
||||||
switch (majorVersion)
|
|
||||||
{
|
|
||||||
case 3:
|
|
||||||
name = "Windows NT 3.51";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
switch (productType)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
name = "Windows NT 4.0";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
name = "Windows NT 4.0 Server";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
switch (minorVersion)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
name = "Windows 2000";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
name = suiteMask switch
|
|
||||||
{
|
|
||||||
0x0200 => "Windows XP Professional",
|
|
||||||
_ => "Windows XP"
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
name = suiteMask switch
|
|
||||||
{
|
|
||||||
0x0200 => "Windows XP Professional x64",
|
|
||||||
0x0002 => "Windows Server 2003 Enterprise",
|
|
||||||
0x0080 => "Windows Server 2003 Data Center",
|
|
||||||
0x0400 => "Windows Server 2003 Web Edition",
|
|
||||||
0x8000 => "Windows Home Server",
|
|
||||||
_ => "Windows Server 2003"
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
switch (minorVersion)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
name = productType switch
|
|
||||||
{
|
|
||||||
3 => "Windows Server 2008",
|
|
||||||
_ => "Windows Vista"
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
name = productType switch
|
|
||||||
{
|
|
||||||
3 => "Windows Server 2008 R2",
|
|
||||||
_ => "Windows 7"
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
name = "Windows 8";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
name = "Windows 8.1";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
string releaseId = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ReleaseId", "").ToString();
|
|
||||||
name = $"Windows 10 {releaseId}";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_name = name;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("Kernel32.dll")]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
internal static extern bool GetProductInfo(
|
|
||||||
int osMajorVersion,
|
|
||||||
int osMinorVersion,
|
|
||||||
int spMajorVersion,
|
|
||||||
int spMinorVersion,
|
|
||||||
out int edition);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
private static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo);
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
||||||
private unsafe struct OSVERSIONINFOEX
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The size of this data structure, in bytes. Set this member to sizeof(OSVERSIONINFOEX).
|
|
||||||
/// </summary>
|
|
||||||
private int _dwOSVersionInfoSize;
|
|
||||||
|
|
||||||
private readonly int _dwMajorVersion;
|
|
||||||
private readonly int _dwMinorVersion;
|
|
||||||
private readonly int _dwBuildNumber;
|
|
||||||
private readonly int _dwPlatformId;
|
|
||||||
private fixed char _szCSDVersion[128];
|
|
||||||
private readonly short _wServicePackMajor;
|
|
||||||
private readonly short _wServicePackMinor;
|
|
||||||
private readonly ushort _wSuiteMask;
|
|
||||||
private readonly byte _wProductType;
|
|
||||||
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>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
public string ServicePackVersion
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
fixed (char* servicePackVersion = _szCSDVersion)
|
|
||||||
{
|
|
||||||
return new string(servicePackVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The major version number of the latest Service Pack installed on the system. For example, for Service Pack 3, the
|
|
||||||
/// major version number is 3.
|
|
||||||
/// If no Service Pack has been installed, the value is zero.
|
|
||||||
/// </summary>
|
|
||||||
public short ServicePackMajor => _wServicePackMajor;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The minor version number of the latest Service Pack installed on the system. For example, for Service Pack 3, the
|
|
||||||
/// minor version number is 0.
|
|
||||||
/// </summary>
|
|
||||||
public short ServicePackMinor => _wServicePackMinor;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A bit mask that identifies the product suites available on the system. This member can be a combination of the
|
|
||||||
/// following values.
|
|
||||||
/// </summary>
|
|
||||||
public ushort SuiteMask => _wSuiteMask;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Any additional information about the system.
|
|
||||||
/// </summary>
|
|
||||||
public byte ProductType => _wProductType;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Factory for an empty OsVersionInfoEx
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>OSVERSIONINFOEX</returns>
|
|
||||||
public static OSVERSIONINFOEX Create()
|
|
||||||
{
|
|
||||||
return new OSVERSIONINFOEX
|
|
||||||
{
|
|
||||||
_dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private const int PRODUCT_UNDEFINED = 0x00000000;
|
|
||||||
private const int PRODUCT_ULTIMATE = 0x00000001;
|
|
||||||
private const int PRODUCT_HOME_BASIC = 0x00000002;
|
|
||||||
private const int PRODUCT_HOME_PREMIUM = 0x00000003;
|
|
||||||
private const int PRODUCT_ENTERPRISE = 0x00000004;
|
|
||||||
private const int PRODUCT_HOME_BASIC_N = 0x00000005;
|
|
||||||
private const int PRODUCT_BUSINESS = 0x00000006;
|
|
||||||
private const int PRODUCT_STANDARD_SERVER = 0x00000007;
|
|
||||||
private const int PRODUCT_DATACENTER_SERVER = 0x00000008;
|
|
||||||
private const int PRODUCT_SMALLBUSINESS_SERVER = 0x00000009;
|
|
||||||
private const int PRODUCT_ENTERPRISE_SERVER = 0x0000000A;
|
|
||||||
private const int PRODUCT_STARTER = 0x0000000B;
|
|
||||||
private const int PRODUCT_DATACENTER_SERVER_CORE = 0x0000000C;
|
|
||||||
private const int PRODUCT_STANDARD_SERVER_CORE = 0x0000000D;
|
|
||||||
private const int PRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E;
|
|
||||||
private const int PRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F;
|
|
||||||
private const int PRODUCT_BUSINESS_N = 0x00000010;
|
|
||||||
private const int PRODUCT_WEB_SERVER = 0x00000011;
|
|
||||||
private const int PRODUCT_CLUSTER_SERVER = 0x00000012;
|
|
||||||
private const int PRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014;
|
|
||||||
private const int PRODUCT_STORAGE_STANDARD_SERVER = 0x00000015;
|
|
||||||
private const int PRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016;
|
|
||||||
private const int PRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017;
|
|
||||||
private const int PRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018;
|
|
||||||
private const int PRODUCT_HOME_PREMIUM_N = 0x0000001A;
|
|
||||||
private const int PRODUCT_ENTERPRISE_N = 0x0000001B;
|
|
||||||
private const int PRODUCT_ULTIMATE_N = 0x0000001C;
|
|
||||||
private const int PRODUCT_WEB_SERVER_CORE = 0x0000001D;
|
|
||||||
private const int PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E;
|
|
||||||
private const int PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F;
|
|
||||||
private const int PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020;
|
|
||||||
private const int PRODUCT_SERVER_FOR_SMALLBUSINESS_V = 0x00000023;
|
|
||||||
private const int PRODUCT_STANDARD_SERVER_V = 0x00000024;
|
|
||||||
private const int PRODUCT_ENTERPRISE_SERVER_V = 0x00000026;
|
|
||||||
private const int PRODUCT_STANDARD_SERVER_CORE_V = 0x00000028;
|
|
||||||
private const int PRODUCT_ENTERPRISE_SERVER_CORE_V = 0x00000029;
|
|
||||||
private const int PRODUCT_HYPERV = 0x0000002A;
|
|
||||||
|
|
||||||
private const int VER_NT_WORKSTATION = 1;
|
|
||||||
private const int VER_NT_SERVER = 3;
|
|
||||||
private const int VER_SUITE_ENTERPRISE = 2;
|
|
||||||
private const int VER_SUITE_DATACENTER = 128;
|
|
||||||
private const int VER_SUITE_PERSONAL = 512;
|
|
||||||
private const int VER_SUITE_BLADE = 1024;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the service pack information of the operating system running on this computer.
|
|
||||||
/// </summary>
|
|
||||||
public static string ServicePack
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string servicePack = string.Empty;
|
|
||||||
OSVERSIONINFOEX osVersionInfo = OSVERSIONINFOEX.Create();
|
|
||||||
|
|
||||||
if (GetVersionEx(ref osVersionInfo))
|
|
||||||
{
|
|
||||||
servicePack = osVersionInfo.ServicePackVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
return servicePack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the build version number of the operating system running on this computer.
|
|
||||||
/// </summary>
|
|
||||||
public static int BuildVersion => Environment.OSVersion.Version.Build;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the full version string of the operating system running on this computer.
|
|
||||||
/// </summary>
|
|
||||||
public static string VersionString
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (WindowsVersion.IsWindows10OrLater)
|
|
||||||
{
|
|
||||||
return $"build {Environment.OSVersion.Version.Build}";
|
|
||||||
}
|
|
||||||
if (Environment.OSVersion.Version.Revision != 0)
|
|
||||||
{
|
|
||||||
return $"{Environment.OSVersion.Version.Major}.{Environment.OSVersion.Version.Minor} build {Environment.OSVersion.Version.Build} revision {Environment.OSVersion.Version.Revision:X}";
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,27 +60,7 @@ namespace Greenshot.Helpers {
|
||||||
ieAccessible.ActivateIETab(tabIndex);
|
ieAccessible.ActivateIETab(tabIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return true if the supplied window has a sub-window which covers more than the supplied percentage
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="someWindow">WindowDetails to check</param>
|
|
||||||
/// <param name="minimumPercentage">min percentage</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool IsMostlyIeWindow(WindowDetails someWindow, int minimumPercentage) {
|
|
||||||
WindowDetails ieWindow = someWindow.GetChild("Internet Explorer_Server");
|
|
||||||
if (ieWindow == null) return false;
|
|
||||||
|
|
||||||
Rectangle wholeClient = someWindow.ClientRectangle;
|
|
||||||
Rectangle partClient = ieWindow.ClientRectangle;
|
|
||||||
int percentage = (int)(100*(float)(partClient.Width * partClient.Height) / (wholeClient.Width * wholeClient.Height));
|
|
||||||
Log.InfoFormat("Window {0}, ie part {1}, percentage {2}", wholeClient, partClient, percentage);
|
|
||||||
if (percentage > minimumPercentage) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Does the supplied window have a IE part?
|
/// Does the supplied window have a IE part?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="someWindow"></param>
|
/// <param name="someWindow"></param>
|
||||||
|
@ -321,15 +301,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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,374 +1,339 @@
|
||||||
/*
|
/*
|
||||||
* Greenshot - a free and open source screenshot tool
|
* Greenshot - a free and open source screenshot tool
|
||||||
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
|
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Drawing;
|
using Greenshot.Drawing;
|
||||||
|
|
||||||
namespace Greenshot.Helpers {
|
namespace Greenshot.Helpers {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Offers a few helper functions for scaling/aligning an element with another element
|
/// Offers a few helper functions for scaling/aligning an element with another element
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ScaleHelper {
|
public static class ScaleHelper {
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ScaleOptions {
|
public enum ScaleOptions {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default scale behavior.
|
/// Default scale behavior.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Default = 0x00,
|
Default = 0x00,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scale a rectangle in two our four directions, mirrored at it's center coordinates
|
/// Scale a rectangle in two our four directions, mirrored at it's center coordinates
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Centered = 0x01,
|
Centered = 0x01,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scale a rectangle maintaining it's aspect ratio
|
/// Scale a rectangle maintaining it's aspect ratio
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Rational = 0x02
|
Rational = 0x02
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// calculates the Size an element must be resized to, in order to fit another element, keeping aspect ratio
|
/// calculates the Size an element must be resized to, in order to fit another element, keeping aspect ratio
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="currentSize">the size of the element to be resized</param>
|
/// <param name="currentSize">the size of the element to be resized</param>
|
||||||
/// <param name="targetSize">the target size of the element</param>
|
/// <param name="targetSize">the target size 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="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>
|
||||||
/// <returns>a new SizeF object indicating the width and height the element should be scaled to</returns>
|
/// <returns>a new SizeF object indicating the width and height the element should be scaled to</returns>
|
||||||
public static SizeF GetScaledSize(SizeF currentSize, SizeF targetSize, bool crop) {
|
public static SizeF GetScaledSize(SizeF currentSize, SizeF targetSize, bool crop) {
|
||||||
float wFactor = targetSize.Width/currentSize.Width;
|
float wFactor = targetSize.Width/currentSize.Width;
|
||||||
float hFactor = targetSize.Height/currentSize.Height;
|
float hFactor = targetSize.Height/currentSize.Height;
|
||||||
|
|
||||||
float factor = crop ? Math.Max(wFactor, hFactor) : Math.Min(wFactor, hFactor);
|
float factor = crop ? Math.Max(wFactor, hFactor) : Math.Min(wFactor, hFactor);
|
||||||
return new SizeF(currentSize.Width * factor, currentSize.Height * factor);
|
return new SizeF(currentSize.Width * factor, currentSize.Height * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// calculates the position of an element depending on the desired alignment within a RectangleF
|
/// calculates the position of an element depending on the desired alignment within a RectangleF
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="currentRect">the bounds of the element to be aligned</param>
|
/// <param name="currentRect">the bounds of the element to be aligned</param>
|
||||||
/// <param name="targetRect">the rectangle reference for alignment of the element</param>
|
/// <param name="targetRect">the rectangle reference for alignment of the element</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>
|
/// <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 with Location aligned aligned to targetRect</returns>
|
/// <returns>a new RectangleF object with Location aligned aligned to targetRect</returns>
|
||||||
public static RectangleF GetAlignedRectangle(RectangleF currentRect, RectangleF targetRect, ContentAlignment alignment) {
|
public static RectangleF GetAlignedRectangle(RectangleF currentRect, RectangleF targetRect, ContentAlignment alignment) {
|
||||||
RectangleF newRect = new RectangleF(targetRect.Location, currentRect.Size);
|
RectangleF newRect = new RectangleF(targetRect.Location, currentRect.Size);
|
||||||
switch(alignment) {
|
switch(alignment) {
|
||||||
case ContentAlignment.TopCenter:
|
case ContentAlignment.TopCenter:
|
||||||
newRect.X = (targetRect.Width - currentRect.Width) / 2;
|
newRect.X = (targetRect.Width - currentRect.Width) / 2;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.TopRight:
|
case ContentAlignment.TopRight:
|
||||||
newRect.X = targetRect.Width - currentRect.Width;
|
newRect.X = targetRect.Width - currentRect.Width;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.MiddleLeft:
|
case ContentAlignment.MiddleLeft:
|
||||||
newRect.Y = (targetRect.Height - currentRect.Height) / 2;
|
newRect.Y = (targetRect.Height - currentRect.Height) / 2;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.MiddleCenter:
|
case ContentAlignment.MiddleCenter:
|
||||||
newRect.Y = (targetRect.Height - currentRect.Height) / 2;
|
newRect.Y = (targetRect.Height - currentRect.Height) / 2;
|
||||||
newRect.X = (targetRect.Width - currentRect.Width) / 2;
|
newRect.X = (targetRect.Width - currentRect.Width) / 2;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.MiddleRight:
|
case ContentAlignment.MiddleRight:
|
||||||
newRect.Y = (targetRect.Height - currentRect.Height) / 2;
|
newRect.Y = (targetRect.Height - currentRect.Height) / 2;
|
||||||
newRect.X = targetRect.Width - currentRect.Width;
|
newRect.X = targetRect.Width - currentRect.Width;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.BottomLeft:
|
case ContentAlignment.BottomLeft:
|
||||||
newRect.Y = targetRect.Height - currentRect.Height;
|
newRect.Y = targetRect.Height - currentRect.Height;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.BottomCenter:
|
case ContentAlignment.BottomCenter:
|
||||||
newRect.Y = targetRect.Height - currentRect.Height;
|
newRect.Y = targetRect.Height - currentRect.Height;
|
||||||
newRect.X = (targetRect.Width - currentRect.Width) / 2;
|
newRect.X = (targetRect.Width - currentRect.Width) / 2;
|
||||||
break;
|
break;
|
||||||
case ContentAlignment.BottomRight:
|
case ContentAlignment.BottomRight:
|
||||||
newRect.Y = targetRect.Height - currentRect.Height;
|
newRect.Y = targetRect.Height - currentRect.Height;
|
||||||
newRect.X = targetRect.Width - currentRect.Width;
|
newRect.X = targetRect.Width - currentRect.Width;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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
|
/// Calculates target size of a given rectangle scaled by dragging one of its handles (corners)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="currentRect">the rectangle of the element to be resized/repositioned</param>
|
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
|
||||||
/// <param name="targetRect">the target size/position of the element</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="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="resizeHandleCoords">coordinates of the used handle/gripper</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>
|
/// <param name="options">ScaleOptions to use when scaling</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 void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords, ScaleOptions? options) {
|
||||||
public static RectangleF GetScaledRectangle(RectangleF currentRect, RectangleF targetRect, bool crop, ContentAlignment alignment) {
|
options ??= GetScaleOptions();
|
||||||
SizeF newSize = GetScaledSize(currentRect.Size, targetRect.Size, crop);
|
|
||||||
RectangleF newRect = new RectangleF(new Point(0,0), newSize);
|
if ((options & ScaleOptions.Rational) == ScaleOptions.Rational) {
|
||||||
return GetAlignedRectangle(newRect, targetRect, alignment);
|
AdjustCoordsForRationalScale(originalRectangle, resizeHandlePosition, ref resizeHandleCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RationalScale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
if ((options & ScaleOptions.Centered) == ScaleOptions.Centered) {
|
||||||
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Rational);
|
// store center coordinates of rectangle
|
||||||
}
|
float rectCenterX = originalRectangle.Left + originalRectangle.Width / 2;
|
||||||
|
float rectCenterY = originalRectangle.Top + originalRectangle.Height / 2;
|
||||||
public static void CenteredScale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
// scale rectangle using handle coordinates
|
||||||
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, ScaleOptions.Centered);
|
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
||||||
}
|
// mirror handle coordinates via rectangle center coordinates
|
||||||
|
resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX);
|
||||||
public static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY);
|
||||||
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords, null);
|
// scale again with opposing handle and mirrored coordinates
|
||||||
}
|
resizeHandlePosition = (Positions)((((int)resizeHandlePosition) + 4) % 8);
|
||||||
|
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
||||||
/// <summary>
|
} else {
|
||||||
/// Calculates target size of a given rectangle scaled by dragging one of its handles (corners)
|
Scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
||||||
/// </summary>
|
}
|
||||||
/// <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="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
|
||||||
/// <param name="options">ScaleOptions to use when scaling</param>
|
/// <summary>
|
||||||
public static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords, ScaleOptions? options) {
|
/// Calculates target size of a given rectangle scaled by dragging one of its handles (corners)
|
||||||
options ??= GetScaleOptions();
|
/// </summary>
|
||||||
|
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
|
||||||
if ((options & ScaleOptions.Rational) == ScaleOptions.Rational) {
|
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
||||||
adjustCoordsForRationalScale(originalRectangle, resizeHandlePosition, ref resizeHandleCoords);
|
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
||||||
}
|
private static void Scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
||||||
|
switch(resizeHandlePosition) {
|
||||||
if ((options & ScaleOptions.Centered) == ScaleOptions.Centered) {
|
|
||||||
// store center coordinates of rectangle
|
case Positions.TopLeft:
|
||||||
float rectCenterX = originalRectangle.Left + originalRectangle.Width / 2;
|
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
||||||
float rectCenterY = originalRectangle.Top + originalRectangle.Height / 2;
|
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
||||||
// scale rectangle using handle coordinates
|
originalRectangle.X = resizeHandleCoords.X;
|
||||||
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
originalRectangle.Y = resizeHandleCoords.Y;
|
||||||
// mirror handle coordinates via rectangle center coordinates
|
break;
|
||||||
resizeHandleCoords.X -= 2 * (resizeHandleCoords.X - rectCenterX);
|
|
||||||
resizeHandleCoords.Y -= 2 * (resizeHandleCoords.Y - rectCenterY);
|
case Positions.TopCenter:
|
||||||
// scale again with opposing handle and mirrored coordinates
|
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
||||||
resizeHandlePosition = (Positions)((((int)resizeHandlePosition) + 4) % 8);
|
originalRectangle.Y = resizeHandleCoords.Y;
|
||||||
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
break;
|
||||||
} else {
|
|
||||||
scale(ref originalRectangle, resizeHandlePosition, resizeHandleCoords);
|
case Positions.TopRight:
|
||||||
}
|
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
|
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
||||||
}
|
originalRectangle.Y = resizeHandleCoords.Y;
|
||||||
|
break;
|
||||||
/// <summary>
|
|
||||||
/// Calculates target size of a given rectangle scaled by dragging one of its handles (corners)
|
case Positions.MiddleLeft:
|
||||||
/// </summary>
|
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
||||||
/// <param name="originalRectangle">bounds of the current rectangle, scaled values will be written to this reference</param>
|
originalRectangle.X = resizeHandleCoords.X;
|
||||||
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see constants in Gripper.cs, e.g. Gripper.POSITION_TOP_LEFT</param>
|
break;
|
||||||
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper</param>
|
|
||||||
private static void scale(ref RectangleF originalRectangle, Positions resizeHandlePosition, PointF resizeHandleCoords) {
|
case Positions.MiddleRight:
|
||||||
switch(resizeHandlePosition) {
|
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
|
break;
|
||||||
case Positions.TopLeft:
|
|
||||||
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
case Positions.BottomLeft:
|
||||||
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
||||||
originalRectangle.X = resizeHandleCoords.X;
|
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
originalRectangle.Y = resizeHandleCoords.Y;
|
originalRectangle.X = resizeHandleCoords.X;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Positions.TopCenter:
|
case Positions.BottomCenter:
|
||||||
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
originalRectangle.Y = resizeHandleCoords.Y;
|
break;
|
||||||
break;
|
|
||||||
|
case Positions.BottomRight:
|
||||||
case Positions.TopRight:
|
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
||||||
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
||||||
originalRectangle.Height = originalRectangle.Top + originalRectangle.Height - resizeHandleCoords.Y;
|
break;
|
||||||
originalRectangle.Y = resizeHandleCoords.Y;
|
|
||||||
break;
|
default:
|
||||||
|
throw new ArgumentException("Position cannot be handled: "+resizeHandlePosition);
|
||||||
case Positions.MiddleLeft:
|
|
||||||
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
}
|
||||||
originalRectangle.X = resizeHandleCoords.X;
|
}
|
||||||
break;
|
|
||||||
|
/// <summary>
|
||||||
case Positions.MiddleRight:
|
/// Adjusts resizeHandleCoords so that aspect ratio is kept after resizing a given rectangle with provided arguments.
|
||||||
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
/// An adjustment can always be done in two ways, e.g. *in*crease width until fit or *de*crease height until fit.
|
||||||
break;
|
/// To avoid objects growing near infinity unexpectedly in certain combinations, the adjustment will choose the
|
||||||
|
/// option resulting in the smaller rectangle.
|
||||||
case Positions.BottomLeft:
|
/// </summary>
|
||||||
originalRectangle.Width = originalRectangle.Left + originalRectangle.Width - resizeHandleCoords.X;
|
/// <param name="originalRectangle">bounds of the current rectangle</param>
|
||||||
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see Position</param>
|
||||||
originalRectangle.X = resizeHandleCoords.X;
|
/// <param name="resizeHandleCoords">coordinates of the used handle/gripper, adjusted coordinates will be written to this reference</param>
|
||||||
break;
|
private static void AdjustCoordsForRationalScale(RectangleF originalRectangle, Positions resizeHandlePosition, ref PointF resizeHandleCoords) {
|
||||||
|
SizeF selectedRectangle, newSize;
|
||||||
case Positions.BottomCenter:
|
|
||||||
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
switch(resizeHandlePosition) {
|
||||||
break;
|
|
||||||
|
case Positions.TopLeft:
|
||||||
case Positions.BottomRight:
|
selectedRectangle = new SizeF(originalRectangle.Right - resizeHandleCoords.X, originalRectangle.Bottom - resizeHandleCoords.Y);
|
||||||
originalRectangle.Width = resizeHandleCoords.X - originalRectangle.Left;
|
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
||||||
originalRectangle.Height = resizeHandleCoords.Y - originalRectangle.Top;
|
resizeHandleCoords.X = originalRectangle.Right - newSize.Width;
|
||||||
break;
|
resizeHandleCoords.Y = originalRectangle.Bottom - newSize.Height;
|
||||||
|
break;
|
||||||
default:
|
|
||||||
throw new ArgumentException("Position cannot be handled: "+resizeHandlePosition);
|
case Positions.TopRight:
|
||||||
|
selectedRectangle = new SizeF(resizeHandleCoords.X - originalRectangle.Left, originalRectangle.Bottom - resizeHandleCoords.Y);
|
||||||
}
|
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
||||||
}
|
resizeHandleCoords.X = originalRectangle.Left + newSize.Width;
|
||||||
|
resizeHandleCoords.Y = originalRectangle.Bottom - newSize.Height;
|
||||||
/// <summary>
|
break;
|
||||||
/// Adjusts resizeHandleCoords so that aspect ratio is kept after resizing a given rectangle with provided arguments.
|
|
||||||
/// An adjustment can always be done in two ways, e.g. *in*crease width until fit or *de*crease height until fit.
|
case Positions.BottomLeft:
|
||||||
/// To avoid objects growing near infinity unexpectedly in certain combinations, the adjustment will choose the
|
selectedRectangle = new SizeF(originalRectangle.Right - resizeHandleCoords.X, resizeHandleCoords.Y - originalRectangle.Top);
|
||||||
/// option resulting in the smaller rectangle.
|
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
||||||
/// </summary>
|
resizeHandleCoords.X = originalRectangle.Right - newSize.Width;
|
||||||
/// <param name="originalRectangle">bounds of the current rectangle</param>
|
resizeHandleCoords.Y = originalRectangle.Top + newSize.Height;
|
||||||
/// <param name="resizeHandlePosition">position of the handle/gripper being used for resized, see Position</param>
|
break;
|
||||||
/// <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) {
|
case Positions.BottomRight:
|
||||||
SizeF selectedRectangle, newSize;
|
selectedRectangle = new SizeF(resizeHandleCoords.X - originalRectangle.Left, resizeHandleCoords.Y - originalRectangle.Top);
|
||||||
|
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
||||||
switch(resizeHandlePosition) {
|
resizeHandleCoords.X = originalRectangle.Left + newSize.Width;
|
||||||
|
resizeHandleCoords.Y = originalRectangle.Top + newSize.Height;
|
||||||
case Positions.TopLeft:
|
break;
|
||||||
selectedRectangle = new SizeF(originalRectangle.Right - resizeHandleCoords.X, originalRectangle.Bottom - resizeHandleCoords.Y);
|
}
|
||||||
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
}
|
||||||
resizeHandleCoords.X = originalRectangle.Right - newSize.Width;
|
|
||||||
resizeHandleCoords.Y = originalRectangle.Bottom - newSize.Height;
|
/// <summary>
|
||||||
break;
|
/// For an original size, and a selected size, returns the the largest possible size that
|
||||||
|
/// * has the same aspect ratio as the original
|
||||||
case Positions.TopRight:
|
/// * fits into selected size
|
||||||
selectedRectangle = new SizeF(resizeHandleCoords.X - originalRectangle.Left, originalRectangle.Bottom - resizeHandleCoords.Y);
|
/// </summary>
|
||||||
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
/// <param name="originalSize">size to be considered for keeping aspect ratio</param>
|
||||||
resizeHandleCoords.X = originalRectangle.Left + newSize.Width;
|
/// <param name="selectedSize">selection size (i.e. the size we'd produce if we wouldn't keep aspect ratio)</param>
|
||||||
resizeHandleCoords.Y = originalRectangle.Bottom - newSize.Height;
|
/// <returns></returns>
|
||||||
break;
|
private static SizeF getNewSizeForRationalScale(SizeF originalSize, SizeF selectedSize)
|
||||||
|
{
|
||||||
case Positions.BottomLeft:
|
SizeF newSize = selectedSize;
|
||||||
selectedRectangle = new SizeF(originalRectangle.Right - resizeHandleCoords.X, resizeHandleCoords.Y - originalRectangle.Top);
|
float originalRatio = originalSize.Width / originalSize.Height;
|
||||||
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
float selectedRatio = selectedSize.Width / selectedSize.Height;
|
||||||
resizeHandleCoords.X = originalRectangle.Right - newSize.Width;
|
// will fix orientation if the scaling causes size to be flipped in any direction
|
||||||
resizeHandleCoords.Y = originalRectangle.Top + newSize.Height;
|
int flippedRatioSign = Math.Sign(selectedRatio) * Math.Sign(originalRatio);
|
||||||
break;
|
if (Math.Abs(selectedRatio) > Math.Abs(originalRatio))
|
||||||
|
{
|
||||||
case Positions.BottomRight:
|
// scaled rectangle (ratio) would be wider than original
|
||||||
selectedRectangle = new SizeF(resizeHandleCoords.X - originalRectangle.Left, resizeHandleCoords.Y - originalRectangle.Top);
|
// keep height and tweak width to maintain aspect ratio
|
||||||
newSize = getNewSizeForRationalScale(originalRectangle.Size, selectedRectangle);
|
newSize.Width = selectedSize.Height * originalRatio * flippedRatioSign;
|
||||||
resizeHandleCoords.X = originalRectangle.Left + newSize.Width;
|
}
|
||||||
resizeHandleCoords.Y = originalRectangle.Top + newSize.Height;
|
else if (Math.Abs(selectedRatio) < Math.Abs(originalRatio))
|
||||||
break;
|
{
|
||||||
}
|
// scaled rectangle (ratio) would be taller than original
|
||||||
}
|
// keep width and tweak height to maintain aspect ratio
|
||||||
|
newSize.Height = selectedSize.Width / originalRatio * flippedRatioSign;
|
||||||
/// <summary>
|
}
|
||||||
/// For an original size, and a selected size, returns the the largest possible size that
|
return newSize;
|
||||||
/// * has the same aspect ratio as the original
|
}
|
||||||
/// * fits into selected size
|
|
||||||
/// </summary>
|
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize) {
|
||||||
/// <param name="originalSize">size to be considered for keeping aspect ratio</param>
|
Scale(boundsBeforeResize, cursorX, cursorY, ref boundsAfterResize, null);
|
||||||
/// <param name="selectedSize">selection size (i.e. the size we'd produce if we wouldn't keep aspect ratio)</param>
|
}
|
||||||
/// <returns></returns>
|
|
||||||
private static SizeF getNewSizeForRationalScale(SizeF originalSize, SizeF selectedSize)
|
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
||||||
{
|
|
||||||
SizeF newSize = selectedSize;
|
Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior);
|
||||||
float originalRatio = originalSize.Width / originalSize.Height;
|
}
|
||||||
float selectedRatio = selectedSize.Width / selectedSize.Height;
|
|
||||||
// will fix orientation if the scaling causes size to be flipped in any direction
|
public static void Scale(Rectangle boundsBeforeResize, Positions gripperPosition, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
||||||
int flippedRatioSign = Math.Sign(selectedRatio) * Math.Sign(originalRatio);
|
|
||||||
if (Math.Abs(selectedRatio) > Math.Abs(originalRatio))
|
ScaleOptions opts = GetScaleOptions();
|
||||||
{
|
|
||||||
// scaled rectangle (ratio) would be wider than original
|
bool rationalScale = (opts & ScaleOptions.Rational) == ScaleOptions.Rational;
|
||||||
// keep height and tweak width to maintain aspect ratio
|
bool centeredScale = (opts & ScaleOptions.Centered) == ScaleOptions.Centered;
|
||||||
newSize.Width = selectedSize.Height * originalRatio * flippedRatioSign;
|
|
||||||
}
|
if(rationalScale) {
|
||||||
else if (Math.Abs(selectedRatio) < Math.Abs(originalRatio))
|
double angle = GeometryHelper.Angle2D(boundsBeforeResize.X, boundsBeforeResize.Y, cursorX, cursorY);
|
||||||
{
|
|
||||||
// scaled rectangle (ratio) would be taller than original
|
if(angleRoundBehavior != null) {
|
||||||
// keep width and tweak height to maintain aspect ratio
|
angle = angleRoundBehavior.Process(angle);
|
||||||
newSize.Height = selectedSize.Width / originalRatio * flippedRatioSign;
|
}
|
||||||
}
|
|
||||||
return newSize;
|
int dist = GeometryHelper.Distance2D(boundsBeforeResize.X, boundsBeforeResize.Y, cursorX, cursorY);
|
||||||
}
|
|
||||||
|
boundsAfterResize.Width = (int)Math.Round(dist * Math.Cos(angle / 180 * Math.PI));
|
||||||
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize) {
|
boundsAfterResize.Height = (int)Math.Round(dist * Math.Sin(angle / 180 * Math.PI));
|
||||||
Scale(boundsBeforeResize, cursorX, cursorY, ref boundsAfterResize, null);
|
}
|
||||||
}
|
|
||||||
|
if(centeredScale) {
|
||||||
public static void Scale(Rectangle boundsBeforeResize, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
float wdiff = boundsAfterResize.Width - boundsBeforeResize.Width;
|
||||||
|
float hdiff = boundsAfterResize.Height - boundsBeforeResize.Height;
|
||||||
Scale(boundsBeforeResize, Positions.TopLeft, cursorX, cursorY, ref boundsAfterResize, angleRoundBehavior);
|
boundsAfterResize.Width += wdiff;
|
||||||
}
|
boundsAfterResize.Height += hdiff;
|
||||||
|
boundsAfterResize.X -= wdiff;
|
||||||
public static void Scale(Rectangle boundsBeforeResize, Positions gripperPosition, int cursorX, int cursorY, ref RectangleF boundsAfterResize, IDoubleProcessor angleRoundBehavior) {
|
boundsAfterResize.Y -= hdiff;
|
||||||
|
}
|
||||||
ScaleOptions opts = GetScaleOptions();
|
|
||||||
|
|
||||||
bool rationalScale = (opts & ScaleOptions.Rational) == ScaleOptions.Rational;
|
}
|
||||||
bool centeredScale = (opts & ScaleOptions.Centered) == ScaleOptions.Centered;
|
|
||||||
|
/// <returns>the current ScaleOptions depending on modifier keys held down</returns>
|
||||||
if(rationalScale) {
|
public static ScaleOptions GetScaleOptions() {
|
||||||
double angle = GeometryHelper.Angle2D(boundsBeforeResize.X, boundsBeforeResize.Y, cursorX, cursorY);
|
bool anchorAtCenter = (Control.ModifierKeys & Keys.Control) != 0;
|
||||||
|
bool maintainAspectRatio = (Control.ModifierKeys & Keys.Shift) != 0;
|
||||||
if(angleRoundBehavior != null) {
|
ScaleOptions opts = ScaleOptions.Default;
|
||||||
angle = angleRoundBehavior.Process(angle);
|
if(anchorAtCenter) opts |= ScaleOptions.Centered;
|
||||||
}
|
if(maintainAspectRatio) opts |= ScaleOptions.Rational;
|
||||||
|
return opts;
|
||||||
int dist = GeometryHelper.Distance2D(boundsBeforeResize.X, boundsBeforeResize.Y, cursorX, cursorY);
|
}
|
||||||
|
|
||||||
boundsAfterResize.Width = (int)Math.Round(dist * Math.Cos(angle / 180 * Math.PI));
|
public interface IDoubleProcessor {
|
||||||
boundsAfterResize.Height = (int)Math.Round(dist * Math.Sin(angle / 180 * Math.PI));
|
double Process(double d);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(centeredScale) {
|
public class ShapeAngleRoundBehavior : IDoubleProcessor {
|
||||||
float wdiff = boundsAfterResize.Width - boundsBeforeResize.Width;
|
public static ShapeAngleRoundBehavior Instance = new();
|
||||||
float hdiff = boundsAfterResize.Height - boundsBeforeResize.Height;
|
private ShapeAngleRoundBehavior() {}
|
||||||
boundsAfterResize.Width += wdiff;
|
public double Process(double angle) {
|
||||||
boundsAfterResize.Height += hdiff;
|
return Math.Round((angle+45)/90)*90 - 45;
|
||||||
boundsAfterResize.X -= wdiff;
|
}
|
||||||
boundsAfterResize.Y -= hdiff;
|
}
|
||||||
}
|
public class LineAngleRoundBehavior : IDoubleProcessor {
|
||||||
|
public static LineAngleRoundBehavior Instance = new();
|
||||||
|
private LineAngleRoundBehavior() {}
|
||||||
}
|
public double Process(double angle) {
|
||||||
|
return Math.Round(angle/15)*15;
|
||||||
/// <returns>the current ScaleOptions depending on modifier keys held down</returns>
|
}
|
||||||
public static ScaleOptions GetScaleOptions() {
|
}
|
||||||
bool anchorAtCenter = (Control.ModifierKeys & Keys.Control) != 0;
|
}
|
||||||
bool maintainAspectRatio = (Control.ModifierKeys & Keys.Shift) != 0;
|
}
|
||||||
ScaleOptions opts = ScaleOptions.Default;
|
|
||||||
if(anchorAtCenter) opts |= ScaleOptions.Centered;
|
|
||||||
if(maintainAspectRatio) opts |= ScaleOptions.Rational;
|
|
||||||
return opts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IDoubleProcessor {
|
|
||||||
double Process(double d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ShapeAngleRoundBehavior : IDoubleProcessor {
|
|
||||||
public static ShapeAngleRoundBehavior Instance = new();
|
|
||||||
private ShapeAngleRoundBehavior() {}
|
|
||||||
public double Process(double angle) {
|
|
||||||
return Math.Round((angle+45)/90)*90 - 45;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class LineAngleRoundBehavior : IDoubleProcessor {
|
|
||||||
public static LineAngleRoundBehavior Instance = new();
|
|
||||||
private LineAngleRoundBehavior() {}
|
|
||||||
public double Process(double angle) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -103,8 +99,8 @@ Source: {#BaseDir}\GreenshotFlickrPlugin\Languages\language_flickr*.xml; DestDir
|
||||||
Source: {#BaseDir}\GreenshotPhotobucketPlugin\{#BinDir}\GreenshotPhotobucketPlugin.dll; DestDir: {app}\Plugins\GreenshotPhotobucketPlugin; Components: plugins\photobucket; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
Source: {#BaseDir}\GreenshotPhotobucketPlugin\{#BinDir}\GreenshotPhotobucketPlugin.dll; DestDir: {app}\Plugins\GreenshotPhotobucketPlugin; Components: plugins\photobucket; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
||||||
Source: {#BaseDir}\GreenshotPhotobucketPlugin\Languages\language_photo*.xml; DestDir: {app}\Languages\Plugins\GreenshotPhotobucketPlugin; Components: plugins\photobucket; Flags: overwritereadonly ignoreversion replacesameversion;
|
Source: {#BaseDir}\GreenshotPhotobucketPlugin\Languages\language_photo*.xml; DestDir: {app}\Languages\Plugins\GreenshotPhotobucketPlugin; Components: plugins\photobucket; Flags: overwritereadonly ignoreversion replacesameversion;
|
||||||
;Picasa Plugin
|
;Picasa Plugin
|
||||||
Source: {#BaseDir}\GreenshotPicasaPlugin\{#BinDir}\GreenshotPicasaPlugin.dll; DestDir: {app}\Plugins\GreenshotPicasaPlugin; Components: plugins\picasa; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
;Source: {#BaseDir}\GreenshotPicasaPlugin\{#BinDir}\GreenshotPicasaPlugin.dll; DestDir: {app}\Plugins\GreenshotPicasaPlugin; Components: plugins\picasa; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
||||||
Source: {#BaseDir}\GreenshotPicasaPlugin\Languages\language_picasa*.xml; DestDir: {app}\Languages\Plugins\GreenshotPicasaPlugin; Components: plugins\picasa; Flags: overwritereadonly ignoreversion replacesameversion;
|
;Source: {#BaseDir}\GreenshotPicasaPlugin\Languages\language_picasa*.xml; DestDir: {app}\Languages\Plugins\GreenshotPicasaPlugin; Components: plugins\picasa; Flags: overwritereadonly ignoreversion replacesameversion;
|
||||||
;Confluence Plugin
|
;Confluence Plugin
|
||||||
Source: {#BaseDir}\GreenshotConfluencePlugin\{#BinDir}\GreenshotConfluencePlugin.dll; DestDir: {app}\Plugins\GreenshotConfluencePlugin; Components: plugins\confluence; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
Source: {#BaseDir}\GreenshotConfluencePlugin\{#BinDir}\GreenshotConfluencePlugin.dll; DestDir: {app}\Plugins\GreenshotConfluencePlugin; Components: plugins\confluence; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
||||||
Source: {#BaseDir}\GreenshotConfluencePlugin\Languages\language_confluence*.xml; DestDir: {app}\Languages\Plugins\GreenshotConfluencePlugin; Components: plugins\confluence; Flags: overwritereadonly ignoreversion replacesameversion;
|
Source: {#BaseDir}\GreenshotConfluencePlugin\Languages\language_confluence*.xml; DestDir: {app}\Languages\Plugins\GreenshotConfluencePlugin; Components: plugins\confluence; Flags: overwritereadonly ignoreversion replacesameversion;
|
||||||
|
@ -113,6 +109,8 @@ Source: {#BaseDir}\GreenshotExternalCommandPlugin\{#BinDir}\GreenshotExternalCom
|
||||||
Source: {#BaseDir}\GreenshotExternalCommandPlugin\Languages\language_externalcommand*.xml; DestDir: {app}\Languages\Plugins\GreenshotExternalCommandPlugin; Components: plugins\externalcommand; Flags: overwritereadonly ignoreversion replacesameversion;
|
Source: {#BaseDir}\GreenshotExternalCommandPlugin\Languages\language_externalcommand*.xml; DestDir: {app}\Languages\Plugins\GreenshotExternalCommandPlugin; Components: plugins\externalcommand; Flags: overwritereadonly ignoreversion replacesameversion;
|
||||||
;Win 10 Plugin
|
;Win 10 Plugin
|
||||||
Source: {#BaseDir}\GreenshotWin10Plugin\{#BinDir}\GreenshotWin10Plugin.dll; DestDir: {app}\Plugins\GreenshotWin10Plugin; Components: plugins\win10; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
Source: {#BaseDir}\GreenshotWin10Plugin\{#BinDir}\GreenshotWin10Plugin.dll; DestDir: {app}\Plugins\GreenshotWin10Plugin; Components: plugins\win10; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
||||||
|
Source: {#BaseDir}\GreenshotWin10Plugin\{#BinDir}\Microsoft.Toolkit.Uwp.Notifications; DestDir: {app}\Plugins\GreenshotWin10Plugin; Components: plugins\win10; Flags: overwritereadonly recursesubdirs ignoreversion replacesameversion;
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
; changes associations is used when the installer installs new extensions, it clears the explorer icon cache
|
; changes associations is used when the installer installs new extensions, it clears the explorer icon cache
|
||||||
ChangesAssociations=yes
|
ChangesAssociations=yes
|
||||||
|
@ -260,7 +258,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 +275,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 +287,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 +298,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 +310,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 +325,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 +378,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 +390,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 +402,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 +414,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 +426,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 +438,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 +448,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 +459,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 +470,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,10 +491,9 @@ 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
|
||||||
Name: "plugins\win10"; Description: {cm:win10}; Types: default full custom; Flags: disablenouninstallwarning; Check: IsWindows10OrNewer()
|
Name: "plugins\win10"; Description: {cm:win10}; Types: default full custom; Flags: disablenouninstallwarning; Check: IsWindows10OrNewer()
|
||||||
Name: "languages"; Description: {cm:language}; Types: full custom; Flags: disablenouninstallwarning
|
Name: "languages"; Description: {cm:language}; Types: full custom; Flags: disablenouninstallwarning
|
||||||
Name: "languages\arSY"; Description: {cm:arSY}; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('d')
|
Name: "languages\arSY"; Description: {cm:arSY}; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('d')
|
||||||
|
|
|
@ -30,17 +30,9 @@ namespace GreenshotBoxPlugin {
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation {
|
public override string Designation => "Box";
|
||||||
get {
|
|
||||||
return "Box";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Description {
|
public override string Description => Language.GetString("box", LangKey.upload_menu_item);
|
||||||
get {
|
|
||||||
return Language.GetString("box", LangKey.upload_menu_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon {
|
||||||
get {
|
get {
|
||||||
|
|
|
@ -21,18 +21,18 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization.Json;
|
using System.Runtime.Serialization.Json;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using GreenshotPlugin.Core.OAuth;
|
||||||
using GreenshotPlugin.IniFile;
|
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";
|
||||||
|
@ -73,9 +73,8 @@ namespace GreenshotBoxPlugin {
|
||||||
CloudServiceName = "Box",
|
CloudServiceName = "Box",
|
||||||
ClientId = BoxCredentials.ClientId,
|
ClientId = BoxCredentials.ClientId,
|
||||||
ClientSecret = BoxCredentials.ClientSecret,
|
ClientSecret = BoxCredentials.ClientSecret,
|
||||||
RedirectUrl = "https://www.box.com/home/",
|
RedirectUrl = "https://getgreenshot.org/authorize/box",
|
||||||
BrowserSize = new Size(1060, 600),
|
AuthorizeMode = OAuth2AuthorizeMode.JsonReceiver,
|
||||||
AuthorizeMode = OAuth2AuthorizeMode.EmbeddedBrowser,
|
|
||||||
RefreshToken = Config.RefreshToken,
|
RefreshToken = Config.RefreshToken,
|
||||||
AccessToken = Config.AccessToken,
|
AccessToken = Config.AccessToken,
|
||||||
AccessTokenExpires = Config.AccessTokenExpires
|
AccessTokenExpires = Config.AccessTokenExpires
|
||||||
|
@ -121,19 +120,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 +128,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);
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace GreenshotBoxPlugin {
|
||||||
/// You can set your own values here
|
/// You can set your own values here
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class BoxCredentials {
|
public static class BoxCredentials {
|
||||||
public static string ClientId = "${Box_ClientId}";
|
public static string ClientId = "${Box13_ClientId}";
|
||||||
public static string ClientSecret = "${Box_ClientSecret}";
|
public static string ClientSecret = "${Box13_ClientSecret}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,15 +33,8 @@ namespace GreenshotConfluencePlugin {
|
||||||
private Type _type;
|
private Type _type;
|
||||||
private IDictionary _displayValues;
|
private IDictionary _displayValues;
|
||||||
private IDictionary _reverseValues;
|
private IDictionary _reverseValues;
|
||||||
|
|
||||||
public EnumDisplayer() {
|
public Type Type {
|
||||||
}
|
|
||||||
|
|
||||||
public EnumDisplayer(Type type) {
|
|
||||||
Type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type Type {
|
|
||||||
get { return _type; }
|
get { return _type; }
|
||||||
set {
|
set {
|
||||||
if (!value.IsEnum) {
|
if (!value.IsEnum) {
|
||||||
|
|
|
@ -1,113 +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;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace GreenshotConfluencePlugin.Forms
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class is an implementation of the 'IComparer' interface.
|
|
||||||
/// </summary>
|
|
||||||
public class ListViewColumnSorter : IComparer {
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the column to be sorted
|
|
||||||
/// </summary>
|
|
||||||
private int _columnToSort;
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the order in which to sort (i.e. 'Ascending').
|
|
||||||
/// </summary>
|
|
||||||
private SortOrder _orderOfSort;
|
|
||||||
/// <summary>
|
|
||||||
/// Case insensitive comparer object
|
|
||||||
/// </summary>
|
|
||||||
private readonly CaseInsensitiveComparer _objectCompare;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Class constructor. Initializes various elements
|
|
||||||
/// </summary>
|
|
||||||
public ListViewColumnSorter() {
|
|
||||||
// Initialize the column to '0'
|
|
||||||
_columnToSort = 0;
|
|
||||||
|
|
||||||
// Initialize the sort order to 'none'
|
|
||||||
_orderOfSort = SortOrder.None;
|
|
||||||
|
|
||||||
// Initialize the CaseInsensitiveComparer object
|
|
||||||
_objectCompare = new CaseInsensitiveComparer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive comparison.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">First object to be compared</param>
|
|
||||||
/// <param name="y">Second object to be compared</param>
|
|
||||||
/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
|
|
||||||
public int Compare(object x, object y) {
|
|
||||||
int compareResult;
|
|
||||||
ListViewItem listviewX, listviewY;
|
|
||||||
|
|
||||||
// Cast the objects to be compared to ListViewItem objects
|
|
||||||
listviewX = (ListViewItem)x;
|
|
||||||
listviewY = (ListViewItem)y;
|
|
||||||
|
|
||||||
// Compare the two items
|
|
||||||
compareResult = _objectCompare.Compare(listviewX.SubItems[_columnToSort].Text, listviewY.SubItems[_columnToSort].Text);
|
|
||||||
|
|
||||||
// Calculate correct return value based on object comparison
|
|
||||||
if (_orderOfSort == SortOrder.Ascending) {
|
|
||||||
// Ascending sort is selected, return normal result of compare operation
|
|
||||||
return compareResult;
|
|
||||||
} else if (_orderOfSort == SortOrder.Descending) {
|
|
||||||
// Descending sort is selected, return negative result of compare operation
|
|
||||||
return (-compareResult);
|
|
||||||
} else {
|
|
||||||
// Return '0' to indicate they are equal
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
|
|
||||||
/// </summary>
|
|
||||||
public int SortColumn {
|
|
||||||
set {
|
|
||||||
_columnToSort = value;
|
|
||||||
}
|
|
||||||
get {
|
|
||||||
return _columnToSort;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
|
|
||||||
/// </summary>
|
|
||||||
public SortOrder Order {
|
|
||||||
set {
|
|
||||||
_orderOfSort = value;
|
|
||||||
}
|
|
||||||
get {
|
|
||||||
return _orderOfSort;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
/*
|
/*
|
||||||
* Greenshot - a free and open source screenshot tool
|
* Greenshot - a free and open source screenshot tool
|
||||||
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
@ -32,7 +32,7 @@ namespace GreenshotDropboxPlugin {
|
||||||
public DropboxDestination(DropboxPlugin plugin) {
|
public DropboxDestination(DropboxPlugin plugin) {
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation => "Dropbox";
|
public override string Designation => "Dropbox";
|
||||||
|
|
||||||
public override string Description => Language.GetString("dropbox", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("dropbox", LangKey.upload_menu_item);
|
||||||
|
@ -43,10 +43,10 @@ namespace GreenshotDropboxPlugin {
|
||||||
return (Image)resources.GetObject("Dropbox");
|
return (Image)resources.GetObject("Dropbox");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ExportInformation ExportCapture(bool manually, ISurface surface, ICaptureDetails captureDetails) {
|
public override ExportInformation ExportCapture(bool manually, ISurface surface, ICaptureDetails captureDetails) {
|
||||||
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
||||||
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
||||||
if (uploaded) {
|
if (uploaded) {
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
|
|
|
@ -1,27 +1,26 @@
|
||||||
/*
|
/*
|
||||||
* Greenshot - a free and open source screenshot tool
|
* Greenshot - a free and open source screenshot tool
|
||||||
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
@ -45,13 +44,12 @@ namespace GreenshotDropboxPlugin {
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
private void Dispose(bool disposing)
|
||||||
if (disposing) {
|
{
|
||||||
if (_itemPlugInConfig != null) {
|
if (!disposing) return;
|
||||||
_itemPlugInConfig.Dispose();
|
if (_itemPlugInConfig == null) return;
|
||||||
_itemPlugInConfig = null;
|
_itemPlugInConfig.Dispose();
|
||||||
}
|
_itemPlugInConfig = null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -102,20 +100,16 @@ namespace GreenshotDropboxPlugin {
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
||||||
try {
|
try
|
||||||
string dropboxUrl = null;
|
{
|
||||||
new PleaseWaitForm().ShowAndWait("Dropbox", Language.GetString("dropbox", LangKey.communication_wait),
|
bool result = false;
|
||||||
|
new PleaseWaitForm().ShowAndWait("Dropbox", Language.GetString("dropbox", LangKey.communication_wait),
|
||||||
delegate
|
delegate
|
||||||
{
|
{
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
result = DropboxUtils.UploadToDropbox(surfaceToUpload, outputSettings, captureDetails);
|
||||||
dropboxUrl = DropboxUtils.UploadToDropbox(surfaceToUpload, outputSettings, filename);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (dropboxUrl == null) {
|
return result;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uploadUrl = dropboxUrl;
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.Error(e);
|
Log.Error(e);
|
||||||
MessageBox.Show(Language.GetString("dropbox", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("dropbox", LangKey.upload_failure) + " " + e.Message);
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
/*
|
/*
|
||||||
* Greenshot - a free and open source screenshot tool
|
* Greenshot - a free and open source screenshot tool
|
||||||
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using GreenshotDropboxPlugin.Forms;
|
using GreenshotDropboxPlugin.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
@ -39,10 +41,18 @@ namespace GreenshotDropboxPlugin {
|
||||||
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send Dropbox link to clipboard.", DefaultValue = "true")]
|
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send Dropbox link to clipboard.", DefaultValue = "true")]
|
||||||
public bool AfterUploadLinkToClipBoard { get; set; }
|
public bool AfterUploadLinkToClipBoard { get; set; }
|
||||||
|
|
||||||
[IniProperty("DropboxToken", Description = "The Dropbox token", Encrypted = true, ExcludeIfNull = true)]
|
[IniProperty("RefreshToken", Description = "Dropbox refresh Token", Encrypted = true, ExcludeIfNull = true)]
|
||||||
public string DropboxToken { get; set; }
|
public string RefreshToken { get; set; }
|
||||||
[IniProperty("DropboxTokenSecret", Description = "The Dropbox token secret", Encrypted = true, ExcludeIfNull = true)]
|
|
||||||
public string DropboxTokenSecret { get; set; }
|
/// <summary>
|
||||||
|
/// AccessToken, not stored
|
||||||
|
/// </summary>
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AccessTokenExpires, not stored
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset AccessTokenExpires { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A form for token
|
/// A form for token
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
/*
|
/*
|
||||||
* Greenshot - a free and open source screenshot tool
|
* Greenshot - a free and open source screenshot tool
|
||||||
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom, Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.IO;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
using GreenshotPlugin.Core.OAuth;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace GreenshotDropboxPlugin {
|
namespace GreenshotDropboxPlugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -37,49 +39,54 @@ namespace GreenshotDropboxPlugin {
|
||||||
private DropboxUtils() {
|
private DropboxUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string filename) {
|
public static bool UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, ICaptureDetails captureDetails)
|
||||||
var oAuth = new OAuthSession(DropBoxCredentials.CONSUMER_KEY, DropBoxCredentials.CONSUMER_SECRET)
|
{
|
||||||
{
|
var oauth2Settings = new OAuth2Settings
|
||||||
BrowserSize = new Size(1080, 650),
|
{
|
||||||
CheckVerifier = false,
|
AuthUrlPattern = "https://api.dropbox.com/oauth2/authorize?response_type=token&client_id={ClientId}&state={State}&redirect_uri={RedirectUrl}",
|
||||||
AccessTokenUrl = "https://api.dropbox.com/1/oauth/access_token",
|
TokenUrl = "https://api.dropbox.com/oauth2/token",
|
||||||
AuthorizeUrl = "https://api.dropbox.com/1/oauth/authorize",
|
RedirectUrl = "https://getgreenshot.org/authorize/dropbox",
|
||||||
RequestTokenUrl = "https://api.dropbox.com/1/oauth/request_token",
|
CloudServiceName = "Dropbox",
|
||||||
LoginTitle = "Dropbox authorization",
|
ClientId = DropBoxCredentials.CONSUMER_KEY,
|
||||||
Token = DropboxConfig.DropboxToken,
|
ClientSecret = DropBoxCredentials.CONSUMER_SECRET,
|
||||||
TokenSecret = DropboxConfig.DropboxTokenSecret
|
AuthorizeMode = OAuth2AuthorizeMode.JsonReceiver,
|
||||||
|
RefreshToken = DropboxConfig.RefreshToken,
|
||||||
|
AccessToken = DropboxConfig.AccessToken,
|
||||||
|
AccessTokenExpires = DropboxConfig.AccessTokenExpires
|
||||||
};
|
};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(DropboxConfig.UploadFormat, captureDetails));
|
||||||
|
SurfaceContainer image = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
||||||
|
|
||||||
try {
|
IDictionary<string, object> arguments = new Dictionary<string, object>
|
||||||
SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
{
|
||||||
string uploadResponse = oAuth.MakeOAuthRequest(HTTPMethod.POST, "https://api-content.dropbox.com/1/files_put/sandbox/" + OAuthSession.UrlEncode3986(filename), null, null, imageToUpload);
|
{ "autorename", true },
|
||||||
Log.DebugFormat("Upload response: {0}", uploadResponse);
|
{ "mute", true },
|
||||||
} catch (Exception ex) {
|
{ "path", "/" + filename.Replace(Path.DirectorySeparatorChar, '\\')}
|
||||||
|
};
|
||||||
|
IDictionary<string, object> headers = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "Dropbox-API-Arg", JsonConvert.SerializeObject(arguments)}
|
||||||
|
};
|
||||||
|
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, "https://content.dropboxapi.com/2/files/upload", oauth2Settings);
|
||||||
|
|
||||||
|
NetworkHelper.Post(webRequest, headers, image);
|
||||||
|
var responseString = NetworkHelper.GetResponseAsString(webRequest);
|
||||||
|
Log.DebugFormat("Upload response: {0}", responseString);
|
||||||
|
var response = JsonConvert.DeserializeObject<IDictionary<string, string>>(responseString);
|
||||||
|
return response.ContainsKey("id");
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
Log.Error("Upload error: ", ex);
|
Log.Error("Upload error: ", ex);
|
||||||
throw;
|
throw;
|
||||||
} finally {
|
} finally {
|
||||||
if (!string.IsNullOrEmpty(oAuth.Token)) {
|
DropboxConfig.RefreshToken = oauth2Settings.RefreshToken;
|
||||||
DropboxConfig.DropboxToken = oAuth.Token;
|
DropboxConfig.AccessToken = oauth2Settings.AccessToken;
|
||||||
}
|
DropboxConfig.AccessTokenExpires = oauth2Settings.AccessTokenExpires;
|
||||||
if (!string.IsNullOrEmpty(oAuth.TokenSecret)) {
|
DropboxConfig.IsDirty = true;
|
||||||
DropboxConfig.DropboxTokenSecret = oAuth.TokenSecret;
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Try to get a URL to the uploaded image
|
|
||||||
try {
|
|
||||||
string responseString = oAuth.MakeOAuthRequest(HTTPMethod.GET, "https://api.dropbox.com/1/shares/sandbox/" + OAuthSession.UrlEncode3986(filename), null, null, null);
|
|
||||||
if (responseString != null) {
|
|
||||||
Log.DebugFormat("Parsing output: {0}", responseString);
|
|
||||||
IDictionary<string, object> returnValues = JSONHelper.JsonDecode(responseString);
|
|
||||||
if (returnValues.ContainsKey("url")) {
|
|
||||||
return returnValues["url"] as string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.Error("Can't parse response.", ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace GreenshotDropboxPlugin {
|
||||||
/// You can set your own values here
|
/// You can set your own values here
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class DropBoxCredentials {
|
public static class DropBoxCredentials {
|
||||||
public static string CONSUMER_KEY = "${DropBox_ClientId}";
|
public static string CONSUMER_KEY = "${DropBox13_ClientId}";
|
||||||
public static string CONSUMER_SECRET = "${DropBox_ClientSecret}";
|
public static string CONSUMER_SECRET = "${DropBox13_ClientSecret}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,134 +29,158 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace GreenshotExternalCommandPlugin {
|
namespace GreenshotExternalCommandPlugin
|
||||||
/// <summary>
|
{
|
||||||
/// An Plugin to run commands after an image was written
|
/// <summary>
|
||||||
/// </summary>
|
/// An Plugin to run commands after an image was written
|
||||||
|
/// </summary>
|
||||||
[Plugin("ExternalCommand", true)]
|
[Plugin("ExternalCommand", true)]
|
||||||
public class ExternalCommandPlugin : IGreenshotPlugin {
|
public class ExternalCommandPlugin : IGreenshotPlugin
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ExternalCommandPlugin));
|
{
|
||||||
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ExternalCommandPlugin));
|
||||||
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
private ToolStripMenuItem _itemPlugInRoot;
|
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
||||||
|
private ToolStripMenuItem _itemPlugInRoot;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
Dispose(true);
|
{
|
||||||
GC.SuppressFinalize(this);
|
Dispose(true);
|
||||||
}
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!disposing) return;
|
if (!disposing) return;
|
||||||
if (_itemPlugInRoot == null) return;
|
if (_itemPlugInRoot == null) return;
|
||||||
_itemPlugInRoot.Dispose();
|
_itemPlugInRoot.Dispose();
|
||||||
_itemPlugInRoot = null;
|
_itemPlugInRoot = null;
|
||||||
}
|
}
|
||||||
private IEnumerable<IDestination> Destinations() {
|
private IEnumerable<IDestination> Destinations()
|
||||||
foreach(string command in ExternalCommandConfig.Commands) {
|
{
|
||||||
yield return new ExternalCommandDestination(command);
|
foreach (string command in ExternalCommandConfig.Commands)
|
||||||
}
|
{
|
||||||
}
|
yield return new ExternalCommandDestination(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check and eventually fix the command settings
|
/// Check and eventually fix the command settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command"></param>
|
/// <param name="command"></param>
|
||||||
/// <returns>false if the command is not correctly configured</returns>
|
/// <returns>false if the command is not correctly configured</returns>
|
||||||
private bool IsCommandValid(string command) {
|
private bool IsCommandValid(string command)
|
||||||
if (!ExternalCommandConfig.RunInbackground.ContainsKey(command)) {
|
{
|
||||||
Log.WarnFormat("Found missing runInbackground for {0}", command);
|
if (!ExternalCommandConfig.RunInbackground.ContainsKey(command))
|
||||||
// Fix it
|
{
|
||||||
ExternalCommandConfig.RunInbackground.Add(command, true);
|
Log.WarnFormat("Found missing runInbackground for {0}", command);
|
||||||
}
|
// Fix it
|
||||||
if (!ExternalCommandConfig.Argument.ContainsKey(command)) {
|
ExternalCommandConfig.RunInbackground.Add(command, true);
|
||||||
Log.WarnFormat("Found missing argument for {0}", command);
|
}
|
||||||
// Fix it
|
if (!ExternalCommandConfig.Argument.ContainsKey(command))
|
||||||
ExternalCommandConfig.Argument.Add(command, "{0}");
|
{
|
||||||
}
|
Log.WarnFormat("Found missing argument for {0}", command);
|
||||||
if (!ExternalCommandConfig.Commandline.ContainsKey(command)) {
|
// Fix it
|
||||||
Log.WarnFormat("Found missing commandline for {0}", command);
|
ExternalCommandConfig.Argument.Add(command, "{0}");
|
||||||
return false;
|
}
|
||||||
}
|
if (!ExternalCommandConfig.Commandline.ContainsKey(command))
|
||||||
string commandline = FilenameHelper.FillVariables(ExternalCommandConfig.Commandline[command], true);
|
{
|
||||||
commandline = FilenameHelper.FillCmdVariables(commandline, true);
|
Log.WarnFormat("Found missing commandline for {0}", command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
string commandline = FilenameHelper.FillVariables(ExternalCommandConfig.Commandline[command], true);
|
||||||
|
commandline = FilenameHelper.FillCmdVariables(commandline, true);
|
||||||
|
|
||||||
if (!File.Exists(commandline)) {
|
if (!File.Exists(commandline))
|
||||||
Log.WarnFormat("Found 'invalid' commandline {0} for command {1}", ExternalCommandConfig.Commandline[command], command);
|
{
|
||||||
return false;
|
Log.WarnFormat("Found 'invalid' commandline {0} for command {1}", ExternalCommandConfig.Commandline[command], command);
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool Initialize()
|
||||||
|
{
|
||||||
|
Log.DebugFormat("Initialize called");
|
||||||
|
|
||||||
|
var commandsToDelete = new List<string>();
|
||||||
|
// Check configuration
|
||||||
|
foreach (string command in ExternalCommandConfig.Commands)
|
||||||
|
{
|
||||||
|
if (!IsCommandValid(command))
|
||||||
|
{
|
||||||
|
commandsToDelete.Add(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cleanup
|
||||||
|
foreach (string command in commandsToDelete)
|
||||||
|
{
|
||||||
|
ExternalCommandConfig.Delete(command);
|
||||||
|
}
|
||||||
SimpleServiceProvider.Current.AddService(Destinations());
|
SimpleServiceProvider.Current.AddService(Destinations());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
|
||||||
/// </summary>
|
|
||||||
public virtual bool Initialize() {
|
|
||||||
Log.DebugFormat("Initialize called");
|
|
||||||
|
|
||||||
List<string> commandsToDelete = new List<string>();
|
_itemPlugInRoot = new ToolStripMenuItem();
|
||||||
// Check configuration
|
|
||||||
foreach(string command in ExternalCommandConfig.Commands) {
|
|
||||||
if (!IsCommandValid(command)) {
|
|
||||||
commandsToDelete.Add(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
foreach (string command in commandsToDelete) {
|
|
||||||
ExternalCommandConfig.Delete(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
_itemPlugInRoot = new ToolStripMenuItem();
|
|
||||||
_itemPlugInRoot.Click += ConfigMenuClick;
|
_itemPlugInRoot.Click += ConfigMenuClick;
|
||||||
OnIconSizeChanged(this, new PropertyChangedEventArgs("IconSize"));
|
OnIconSizeChanged(this, new PropertyChangedEventArgs("IconSize"));
|
||||||
OnLanguageChanged(this, null);
|
OnLanguageChanged(this, null);
|
||||||
|
|
||||||
PluginUtils.AddToContextMenu(_itemPlugInRoot);
|
PluginUtils.AddToContextMenu(_itemPlugInRoot);
|
||||||
Language.LanguageChanged += OnLanguageChanged;
|
Language.LanguageChanged += OnLanguageChanged;
|
||||||
CoreConfig.PropertyChanged += OnIconSizeChanged;
|
CoreConfig.PropertyChanged += OnIconSizeChanged;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fix icon reference
|
/// Fix icon reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private void OnIconSizeChanged(object sender, PropertyChangedEventArgs e) {
|
private void OnIconSizeChanged(object sender, PropertyChangedEventArgs e)
|
||||||
if (e.PropertyName == "IconSize") {
|
{
|
||||||
try {
|
if (e.PropertyName == "IconSize")
|
||||||
string exePath = PluginUtils.GetExePath("cmd.exe");
|
{
|
||||||
if (exePath != null && File.Exists(exePath)) {
|
try
|
||||||
_itemPlugInRoot.Image = PluginUtils.GetCachedExeIcon(exePath, 0);
|
{
|
||||||
}
|
string exePath = PluginUtils.GetExePath("cmd.exe");
|
||||||
} catch (Exception ex) {
|
if (exePath != null && File.Exists(exePath))
|
||||||
Log.Warn("Couldn't get the cmd.exe image", ex);
|
{
|
||||||
}
|
_itemPlugInRoot.Image = PluginUtils.GetCachedExeIcon(exePath, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warn("Couldn't get the cmd.exe image", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnLanguageChanged(object sender, EventArgs e) {
|
private void OnLanguageChanged(object sender, EventArgs e)
|
||||||
if (_itemPlugInRoot != null) {
|
{
|
||||||
_itemPlugInRoot.Text = Language.GetString("externalcommand", "contextmenu_configure");
|
if (_itemPlugInRoot != null)
|
||||||
}
|
{
|
||||||
}
|
_itemPlugInRoot.Text = Language.GetString("externalcommand", "contextmenu_configure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Shutdown() {
|
public virtual void Shutdown()
|
||||||
Log.Debug("Shutdown");
|
{
|
||||||
}
|
Log.Debug("Shutdown");
|
||||||
|
}
|
||||||
|
|
||||||
private void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
private void ConfigMenuClick(object sender, EventArgs eventArgs)
|
||||||
Configure();
|
{
|
||||||
}
|
Configure();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Configure() {
|
public virtual void Configure()
|
||||||
Log.Debug("Configure called");
|
{
|
||||||
new SettingsForm().ShowDialog();
|
Log.Debug("Configure called");
|
||||||
}
|
new SettingsForm().ShowDialog();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,7 @@ using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
using GreenshotPlugin.Core.OAuth;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin.Forms {
|
namespace GreenshotGooglePhotosPlugin.Forms {
|
||||||
public class PicasaForm : GreenshotForm {
|
public class GooglePhotosForm : GreenshotForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,147 +1,147 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
namespace GreenshotPicasaPlugin.Forms {
|
namespace GreenshotGooglePhotosPlugin.Forms {
|
||||||
partial class SettingsForm {
|
partial class SettingsForm {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Designer variable used to keep track of non-visual components.
|
/// Designer variable used to keep track of non-visual components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private System.ComponentModel.IContainer components = null;
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disposes resources used by the form.
|
/// Disposes resources used by the form.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing) {
|
if (disposing) {
|
||||||
if (components != null) {
|
if (components != null) {
|
||||||
components.Dispose();
|
components.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method is required for Windows Forms designer support.
|
/// This method is required for Windows Forms designer support.
|
||||||
/// Do not change the method contents inside the source code editor. The Forms designer might
|
/// 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.
|
/// not be able to load this method if it was changed manually.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.buttonOK = new GreenshotPlugin.Controls.GreenshotButton();
|
this.buttonOK = new GreenshotPlugin.Controls.GreenshotButton();
|
||||||
this.buttonCancel = new GreenshotPlugin.Controls.GreenshotButton();
|
this.buttonCancel = new GreenshotPlugin.Controls.GreenshotButton();
|
||||||
this.combobox_uploadimageformat = new GreenshotPlugin.Controls.GreenshotComboBox();
|
this.combobox_uploadimageformat = new GreenshotPlugin.Controls.GreenshotComboBox();
|
||||||
this.label_upload_format = new GreenshotPlugin.Controls.GreenshotLabel();
|
this.label_upload_format = new GreenshotPlugin.Controls.GreenshotLabel();
|
||||||
this.label_AfterUpload = new GreenshotPlugin.Controls.GreenshotLabel();
|
this.label_AfterUpload = new GreenshotPlugin.Controls.GreenshotLabel();
|
||||||
this.checkboxAfterUploadLinkToClipBoard = new GreenshotPlugin.Controls.GreenshotCheckBox();
|
this.checkboxAfterUploadLinkToClipBoard = new GreenshotPlugin.Controls.GreenshotCheckBox();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// buttonOK
|
// buttonOK
|
||||||
//
|
//
|
||||||
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||||
this.buttonOK.LanguageKey = "OK";
|
this.buttonOK.LanguageKey = "OK";
|
||||||
this.buttonOK.Location = new System.Drawing.Point(267, 78);
|
this.buttonOK.Location = new System.Drawing.Point(267, 78);
|
||||||
this.buttonOK.Name = "buttonOK";
|
this.buttonOK.Name = "buttonOK";
|
||||||
this.buttonOK.Size = new System.Drawing.Size(75, 23);
|
this.buttonOK.Size = new System.Drawing.Size(75, 23);
|
||||||
this.buttonOK.TabIndex = 10;
|
this.buttonOK.TabIndex = 10;
|
||||||
this.buttonOK.UseVisualStyleBackColor = true;
|
this.buttonOK.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// buttonCancel
|
// buttonCancel
|
||||||
//
|
//
|
||||||
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
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.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||||
this.buttonCancel.LanguageKey = "CANCEL";
|
this.buttonCancel.LanguageKey = "CANCEL";
|
||||||
this.buttonCancel.Location = new System.Drawing.Point(348, 78);
|
this.buttonCancel.Location = new System.Drawing.Point(348, 78);
|
||||||
this.buttonCancel.Name = "buttonCancel";
|
this.buttonCancel.Name = "buttonCancel";
|
||||||
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
|
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
|
||||||
this.buttonCancel.TabIndex = 11;
|
this.buttonCancel.TabIndex = 11;
|
||||||
this.buttonCancel.UseVisualStyleBackColor = true;
|
this.buttonCancel.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// combobox_uploadimageformat
|
// combobox_uploadimageformat
|
||||||
//
|
//
|
||||||
this.combobox_uploadimageformat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
this.combobox_uploadimageformat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.combobox_uploadimageformat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.combobox_uploadimageformat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(197, 12);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(197, 12);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
||||||
this.combobox_uploadimageformat.SectionName = "Picasa";
|
this.combobox_uploadimageformat.SectionName = "GooglePhotos";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(225, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(225, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 1;
|
this.combobox_uploadimageformat.TabIndex = 1;
|
||||||
//
|
//
|
||||||
// label_upload_format
|
// label_upload_format
|
||||||
//
|
//
|
||||||
this.label_upload_format.LanguageKey = "picasa.label_upload_format";
|
this.label_upload_format.LanguageKey = "googlephotos.label_upload_format";
|
||||||
this.label_upload_format.Location = new System.Drawing.Point(10, 18);
|
this.label_upload_format.Location = new System.Drawing.Point(10, 18);
|
||||||
this.label_upload_format.Name = "label_upload_format";
|
this.label_upload_format.Name = "label_upload_format";
|
||||||
this.label_upload_format.Size = new System.Drawing.Size(181, 33);
|
this.label_upload_format.Size = new System.Drawing.Size(181, 33);
|
||||||
this.label_upload_format.TabIndex = 4;
|
this.label_upload_format.TabIndex = 4;
|
||||||
//
|
//
|
||||||
// label_AfterUpload
|
// label_AfterUpload
|
||||||
//
|
//
|
||||||
this.label_AfterUpload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
this.label_AfterUpload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
this.label_AfterUpload.LanguageKey = "picasa.label_AfterUpload";
|
this.label_AfterUpload.LanguageKey = "googlephotos.label_AfterUpload";
|
||||||
this.label_AfterUpload.Location = new System.Drawing.Point(10, 51);
|
this.label_AfterUpload.Location = new System.Drawing.Point(10, 51);
|
||||||
this.label_AfterUpload.Name = "label_AfterUpload";
|
this.label_AfterUpload.Name = "label_AfterUpload";
|
||||||
this.label_AfterUpload.Size = new System.Drawing.Size(181, 29);
|
this.label_AfterUpload.Size = new System.Drawing.Size(181, 29);
|
||||||
this.label_AfterUpload.TabIndex = 8;
|
this.label_AfterUpload.TabIndex = 8;
|
||||||
//
|
//
|
||||||
// checkboxAfterUploadLinkToClipBoard
|
// checkboxAfterUploadLinkToClipBoard
|
||||||
//
|
//
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
this.checkboxAfterUploadLinkToClipBoard.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "picasa.label_AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "googlephotos.label_AfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(197, 50);
|
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(197, 50);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.PropertyName = "AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.PropertyName = "AfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Picasa";
|
this.checkboxAfterUploadLinkToClipBoard.SectionName = "GooglePhotos";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 2;
|
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 2;
|
||||||
this.checkboxAfterUploadLinkToClipBoard.UseVisualStyleBackColor = true;
|
this.checkboxAfterUploadLinkToClipBoard.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// SettingsForm
|
// SettingsForm
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||||
this.ClientSize = new System.Drawing.Size(432, 110);
|
this.ClientSize = new System.Drawing.Size(432, 110);
|
||||||
this.Controls.Add(this.checkboxAfterUploadLinkToClipBoard);
|
this.Controls.Add(this.checkboxAfterUploadLinkToClipBoard);
|
||||||
this.Controls.Add(this.label_AfterUpload);
|
this.Controls.Add(this.label_AfterUpload);
|
||||||
this.Controls.Add(this.label_upload_format);
|
this.Controls.Add(this.label_upload_format);
|
||||||
this.Controls.Add(this.combobox_uploadimageformat);
|
this.Controls.Add(this.combobox_uploadimageformat);
|
||||||
this.Controls.Add(this.buttonCancel);
|
this.Controls.Add(this.buttonCancel);
|
||||||
this.Controls.Add(this.buttonOK);
|
this.Controls.Add(this.buttonOK);
|
||||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||||
this.LanguageKey = "picasa.settings_title";
|
this.LanguageKey = "googlephotos.settings_title";
|
||||||
this.MaximizeBox = false;
|
this.MaximizeBox = false;
|
||||||
this.MinimizeBox = false;
|
this.MinimizeBox = false;
|
||||||
this.Name = "SettingsForm";
|
this.Name = "SettingsForm";
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
}
|
}
|
||||||
private GreenshotPlugin.Controls.GreenshotComboBox combobox_uploadimageformat;
|
private GreenshotPlugin.Controls.GreenshotComboBox combobox_uploadimageformat;
|
||||||
private GreenshotPlugin.Controls.GreenshotLabel label_upload_format;
|
private GreenshotPlugin.Controls.GreenshotLabel label_upload_format;
|
||||||
private GreenshotPlugin.Controls.GreenshotButton buttonCancel;
|
private GreenshotPlugin.Controls.GreenshotButton buttonCancel;
|
||||||
private GreenshotPlugin.Controls.GreenshotButton buttonOK;
|
private GreenshotPlugin.Controls.GreenshotButton buttonOK;
|
||||||
private GreenshotPlugin.Controls.GreenshotLabel label_AfterUpload;
|
private GreenshotPlugin.Controls.GreenshotLabel label_AfterUpload;
|
||||||
private GreenshotPlugin.Controls.GreenshotCheckBox checkboxAfterUploadLinkToClipBoard;
|
private GreenshotPlugin.Controls.GreenshotCheckBox checkboxAfterUploadLinkToClipBoard;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,38 +1,38 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin.Forms {
|
namespace GreenshotGooglePhotosPlugin.Forms {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : PicasaForm {
|
public partial class SettingsForm : GooglePhotosForm {
|
||||||
|
|
||||||
public SettingsForm()
|
public SettingsForm()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
//
|
//
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
CancelButton = buttonCancel;
|
CancelButton = buttonCancel;
|
||||||
AcceptButton = buttonOK;
|
AcceptButton = buttonOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
GreenshotGooglePhotosPlugin/GooglePhotos.png
Normal file
BIN
GreenshotGooglePhotosPlugin/GooglePhotos.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -1,93 +1,93 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using System;
|
using System;
|
||||||
using GreenshotPicasaPlugin.Forms;
|
using GreenshotGooglePhotosPlugin.Forms;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin {
|
namespace GreenshotGooglePhotosPlugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PicasaConfiguration.
|
/// Description of GooglePhotosConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Picasa", Description = "Greenshot Picasa Plugin configuration")]
|
[IniSection("GooglePhotos", Description = "Greenshot GooglePhotos Plugin configuration")]
|
||||||
public class PicasaConfiguration : IniSection {
|
public class GooglePhotosConfiguration : IniSection {
|
||||||
[IniProperty("UploadFormat", Description="What file type to use for uploading", DefaultValue="png")]
|
[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")]
|
||||||
public int UploadJpegQuality { get; set; }
|
public int UploadJpegQuality { get; set; }
|
||||||
|
|
||||||
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send Picasa link to clipboard.", DefaultValue = "true")]
|
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send GooglePhotos link to clipboard.", DefaultValue = "true")]
|
||||||
public bool AfterUploadLinkToClipBoard { get; set; }
|
public bool AfterUploadLinkToClipBoard { get; set; }
|
||||||
[IniProperty("AddFilename", Description = "Is the filename passed on to Picasa", DefaultValue = "False")]
|
[IniProperty("AddFilename", Description = "Is the filename passed on to GooglePhotos", DefaultValue = "False")]
|
||||||
public bool AddFilename {
|
public bool AddFilename {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[IniProperty("UploadUser", Description = "The Picasa user to upload to", DefaultValue = "default")]
|
[IniProperty("UploadUser", Description = "The GooglePhotos user to upload to", DefaultValue = "default")]
|
||||||
public string UploadUser {
|
public string UploadUser {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[IniProperty("UploadAlbum", Description = "The Picasa album to upload to", DefaultValue = "default")]
|
[IniProperty("UploadAlbum", Description = "The GooglePhotos album to upload to", DefaultValue = "default")]
|
||||||
public string UploadAlbum {
|
public string UploadAlbum {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[IniProperty("RefreshToken", Description = "Picasa authorization refresh Token", Encrypted = true)]
|
[IniProperty("RefreshToken", Description = "GooglePhotos authorization refresh Token", Encrypted = true)]
|
||||||
public string RefreshToken {
|
public string RefreshToken {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not stored
|
/// Not stored
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AccessToken {
|
public string AccessToken {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not stored
|
/// Not stored
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset AccessTokenExpires {
|
public DateTimeOffset AccessTokenExpires {
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A form for token
|
/// A form for token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog() {
|
||||||
DialogResult result = new SettingsForm().ShowDialog();
|
DialogResult result = new SettingsForm().ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,54 +1,54 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin {
|
namespace GreenshotGooglePhotosPlugin {
|
||||||
public class PicasaDestination : AbstractDestination {
|
public class GooglePhotosDestination : AbstractDestination {
|
||||||
private readonly PicasaPlugin _plugin;
|
private readonly GooglePhotosPlugin _plugin;
|
||||||
public PicasaDestination(PicasaPlugin plugin) {
|
public GooglePhotosDestination(GooglePhotosPlugin plugin) {
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation => "Picasa";
|
public override string Designation => "GooglePhotos";
|
||||||
|
|
||||||
public override string Description => Language.GetString("picasa", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("googlephotos", LangKey.upload_menu_item);
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon {
|
||||||
get {
|
get {
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(PicasaPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(GooglePhotosPlugin));
|
||||||
return (Image)resources.GetObject("Picasa");
|
return (Image)resources.GetObject("GooglePhotos");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
|
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
|
||||||
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
||||||
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
||||||
if (uploaded) {
|
if (uploaded) {
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
}
|
}
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,125 +1,124 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin {
|
namespace GreenshotGooglePhotosPlugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the Picasa base code
|
/// This is the GooglePhotos base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Picasa", true)]
|
[Plugin("GooglePhotos", true)]
|
||||||
public class PicasaPlugin : IGreenshotPlugin {
|
public class GooglePhotosPlugin : IGreenshotPlugin {
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PicasaPlugin));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(GooglePhotosPlugin));
|
||||||
private static PicasaConfiguration _config;
|
private static GooglePhotosConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _itemPlugInRoot;
|
private ToolStripMenuItem _itemPlugInRoot;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
private void Dispose(bool disposing)
|
||||||
if (disposing) {
|
{
|
||||||
if (_itemPlugInRoot != null) {
|
if (!disposing) return;
|
||||||
_itemPlugInRoot.Dispose();
|
if (_itemPlugInRoot == null) return;
|
||||||
_itemPlugInRoot = null;
|
_itemPlugInRoot.Dispose();
|
||||||
}
|
_itemPlugInRoot = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// </summary>
|
||||||
/// </summary>
|
public bool Initialize() {
|
||||||
public bool Initialize() {
|
SimpleServiceProvider.Current.AddService<IDestination>(new GooglePhotosDestination(this));
|
||||||
SimpleServiceProvider.Current.AddService<IDestination>(new PicasaDestination(this));
|
|
||||||
|
// Get configuration
|
||||||
// Get configuration
|
_config = IniConfig.GetIniSection<GooglePhotosConfiguration>();
|
||||||
_config = IniConfig.GetIniSection<PicasaConfiguration>();
|
_resources = new ComponentResourceManager(typeof(GooglePhotosPlugin));
|
||||||
_resources = new ComponentResourceManager(typeof(PicasaPlugin));
|
|
||||||
|
_itemPlugInRoot = new ToolStripMenuItem
|
||||||
_itemPlugInRoot = new ToolStripMenuItem
|
{
|
||||||
{
|
Text = Language.GetString("googlephotos", LangKey.Configure),
|
||||||
Text = Language.GetString("picasa", LangKey.Configure),
|
Image = (Image) _resources.GetObject("GooglePhotos")
|
||||||
Image = (Image) _resources.GetObject("Picasa")
|
};
|
||||||
};
|
_itemPlugInRoot.Click += ConfigMenuClick;
|
||||||
_itemPlugInRoot.Click += ConfigMenuClick;
|
PluginUtils.AddToContextMenu(_itemPlugInRoot);
|
||||||
PluginUtils.AddToContextMenu(_itemPlugInRoot);
|
Language.LanguageChanged += OnLanguageChanged;
|
||||||
Language.LanguageChanged += OnLanguageChanged;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
public void OnLanguageChanged(object sender, EventArgs e) {
|
||||||
public void OnLanguageChanged(object sender, EventArgs e) {
|
if (_itemPlugInRoot != null) {
|
||||||
if (_itemPlugInRoot != null) {
|
_itemPlugInRoot.Text = Language.GetString("googlephotos", LangKey.Configure);
|
||||||
_itemPlugInRoot.Text = Language.GetString("picasa", LangKey.Configure);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void Shutdown() {
|
||||||
public void Shutdown() {
|
Log.Debug("GooglePhotos Plugin shutdown.");
|
||||||
Log.Debug("Picasa Plugin shutdown.");
|
Language.LanguageChanged -= OnLanguageChanged;
|
||||||
Language.LanguageChanged -= OnLanguageChanged;
|
//host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened);
|
||||||
//host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened);
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
/// Implementation of the IPlugin.Configure
|
||||||
/// Implementation of the IPlugin.Configure
|
/// </summary>
|
||||||
/// </summary>
|
public void Configure() {
|
||||||
public void Configure() {
|
_config.ShowConfigDialog();
|
||||||
_config.ShowConfigDialog();
|
}
|
||||||
}
|
|
||||||
|
public void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
||||||
public void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
Configure();
|
||||||
Configure();
|
}
|
||||||
}
|
|
||||||
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality);
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality);
|
try {
|
||||||
try {
|
string url = null;
|
||||||
string url = null;
|
new PleaseWaitForm().ShowAndWait("GooglePhotos", Language.GetString("googlephotos", LangKey.communication_wait),
|
||||||
new PleaseWaitForm().ShowAndWait("Picasa", Language.GetString("picasa", LangKey.communication_wait),
|
delegate
|
||||||
delegate
|
{
|
||||||
{
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
url = GooglePhotosUtils.UploadToGooglePhotos(surfaceToUpload, outputSettings, captureDetails.Title, filename);
|
||||||
url = PicasaUtils.UploadToPicasa(surfaceToUpload, outputSettings, captureDetails.Title, filename);
|
}
|
||||||
}
|
);
|
||||||
);
|
uploadUrl = url;
|
||||||
uploadUrl = url;
|
|
||||||
|
if (uploadUrl != null && _config.AfterUploadLinkToClipBoard) {
|
||||||
if (uploadUrl != null && _config.AfterUploadLinkToClipBoard) {
|
ClipboardHelper.SetClipboardData(uploadUrl);
|
||||||
ClipboardHelper.SetClipboardData(uploadUrl);
|
}
|
||||||
}
|
return true;
|
||||||
return true;
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
Log.Error("Error uploading.", e);
|
||||||
Log.Error("Error uploading.", e);
|
MessageBox.Show(Language.GetString("googlephotos", LangKey.upload_failure) + " " + e.Message);
|
||||||
MessageBox.Show(Language.GetString("picasa", LangKey.upload_failure) + " " + e.Message);
|
}
|
||||||
}
|
uploadUrl = null;
|
||||||
uploadUrl = null;
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -118,7 +118,7 @@
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
<data name="Picasa" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="GooglePhotos" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>picasa.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>GooglePhotos.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -1,119 +1,120 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using System;
|
using System;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.Core.OAuth;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
namespace GreenshotPicasaPlugin {
|
|
||||||
/// <summary>
|
namespace GreenshotGooglePhotosPlugin {
|
||||||
/// Description of PicasaUtils.
|
/// <summary>
|
||||||
/// </summary>
|
/// Description of GooglePhotosUtils.
|
||||||
public static class PicasaUtils {
|
/// </summary>
|
||||||
private const string PicasaScope = "https://picasaweb.google.com/data/";
|
public static class GooglePhotosUtils {
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PicasaUtils));
|
private const string GooglePhotosScope = "https://picasaweb.google.com/data/";
|
||||||
private static readonly PicasaConfiguration Config = IniConfig.GetIniSection<PicasaConfiguration>();
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(GooglePhotosUtils));
|
||||||
private const string AuthUrl = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={ClientId}&redirect_uri={RedirectUrl}&state={State}&scope=" + PicasaScope;
|
private static readonly GooglePhotosConfiguration Config = IniConfig.GetIniSection<GooglePhotosConfiguration>();
|
||||||
private const string TokenUrl = "https://www.googleapis.com/oauth2/v3/token";
|
private const string AuthUrl = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={ClientId}&redirect_uri={RedirectUrl}&state={State}&scope=" + GooglePhotosScope;
|
||||||
private const string UploadUrl = "https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}";
|
private const string TokenUrl = "https://www.googleapis.com/oauth2/v3/token";
|
||||||
|
private const string UploadUrl = "https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}";
|
||||||
/// <summary>
|
|
||||||
/// Do the actual upload to Picasa
|
/// <summary>
|
||||||
/// </summary>
|
/// Do the actual upload to GooglePhotos
|
||||||
/// <param name="surfaceToUpload">Image to upload</param>
|
/// </summary>
|
||||||
/// <param name="outputSettings"></param>
|
/// <param name="surfaceToUpload">Image to upload</param>
|
||||||
/// <param name="title"></param>
|
/// <param name="outputSettings">SurfaceOutputSettings</param>
|
||||||
/// <param name="filename"></param>
|
/// <param name="title">string</param>
|
||||||
/// <returns>PicasaResponse</returns>
|
/// <param name="filename">string</param>
|
||||||
public static string UploadToPicasa(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
/// <returns>GooglePhotosResponse</returns>
|
||||||
// Fill the OAuth2Settings
|
public static string UploadToGooglePhotos(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
||||||
var settings = new OAuth2Settings
|
// Fill the OAuth2Settings
|
||||||
{
|
var settings = new OAuth2Settings
|
||||||
AuthUrlPattern = AuthUrl,
|
{
|
||||||
TokenUrl = TokenUrl,
|
AuthUrlPattern = AuthUrl,
|
||||||
CloudServiceName = "Picasa",
|
TokenUrl = TokenUrl,
|
||||||
ClientId = PicasaCredentials.ClientId,
|
CloudServiceName = "GooglePhotos",
|
||||||
ClientSecret = PicasaCredentials.ClientSecret,
|
ClientId = GooglePhotosCredentials.ClientId,
|
||||||
AuthorizeMode = OAuth2AuthorizeMode.LocalServer,
|
ClientSecret = GooglePhotosCredentials.ClientSecret,
|
||||||
RefreshToken = Config.RefreshToken,
|
AuthorizeMode = OAuth2AuthorizeMode.JsonReceiver,
|
||||||
AccessToken = Config.AccessToken,
|
RefreshToken = Config.RefreshToken,
|
||||||
AccessTokenExpires = Config.AccessTokenExpires
|
AccessToken = Config.AccessToken,
|
||||||
};
|
AccessTokenExpires = Config.AccessTokenExpires
|
||||||
|
};
|
||||||
// Copy the settings from the config, which is kept in memory and on the disk
|
|
||||||
|
// Copy the settings from the config, which is kept in memory and on the disk
|
||||||
try {
|
|
||||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, string.Format(UploadUrl, Config.UploadUser, Config.UploadAlbum), settings);
|
try {
|
||||||
if (Config.AddFilename) {
|
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, string.Format(UploadUrl, Config.UploadUser, Config.UploadAlbum), settings);
|
||||||
webRequest.Headers.Add("Slug", NetworkHelper.EscapeDataString(filename));
|
if (Config.AddFilename) {
|
||||||
}
|
webRequest.Headers.Add("Slug", NetworkHelper.EscapeDataString(filename));
|
||||||
SurfaceContainer container = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
}
|
||||||
container.Upload(webRequest);
|
SurfaceContainer container = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
||||||
|
container.Upload(webRequest);
|
||||||
string response = NetworkHelper.GetResponseAsString(webRequest);
|
|
||||||
|
string response = NetworkHelper.GetResponseAsString(webRequest);
|
||||||
return ParseResponse(response);
|
|
||||||
} finally {
|
return ParseResponse(response);
|
||||||
// Copy the settings back to the config, so they are stored.
|
} finally {
|
||||||
Config.RefreshToken = settings.RefreshToken;
|
// Copy the settings back to the config, so they are stored.
|
||||||
Config.AccessToken = settings.AccessToken;
|
Config.RefreshToken = settings.RefreshToken;
|
||||||
Config.AccessTokenExpires = settings.AccessTokenExpires;
|
Config.AccessToken = settings.AccessToken;
|
||||||
Config.IsDirty = true;
|
Config.AccessTokenExpires = settings.AccessTokenExpires;
|
||||||
IniConfig.Save();
|
Config.IsDirty = true;
|
||||||
}
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
|
||||||
/// Parse the upload URL from the response
|
/// <summary>
|
||||||
/// </summary>
|
/// Parse the upload URL from the response
|
||||||
/// <param name="response"></param>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <param name="response"></param>
|
||||||
public static string ParseResponse(string response) {
|
/// <returns></returns>
|
||||||
if (response == null) {
|
public static string ParseResponse(string response) {
|
||||||
return null;
|
if (response == null) {
|
||||||
}
|
return null;
|
||||||
try {
|
}
|
||||||
XmlDocument doc = new XmlDocument();
|
try {
|
||||||
doc.LoadXml(response);
|
XmlDocument doc = new XmlDocument();
|
||||||
XmlNodeList nodes = doc.GetElementsByTagName("link", "*");
|
doc.LoadXml(response);
|
||||||
if(nodes.Count > 0) {
|
XmlNodeList nodes = doc.GetElementsByTagName("link", "*");
|
||||||
string url = null;
|
if(nodes.Count > 0) {
|
||||||
foreach(XmlNode node in nodes) {
|
string url = null;
|
||||||
if (node.Attributes != null) {
|
foreach(XmlNode node in nodes) {
|
||||||
url = node.Attributes["href"].Value;
|
if (node.Attributes != null) {
|
||||||
string rel = node.Attributes["rel"].Value;
|
url = node.Attributes["href"].Value;
|
||||||
// Pictures with rel="http://schemas.google.com/photos/2007#canonical" are the direct link
|
string rel = node.Attributes["rel"].Value;
|
||||||
if (rel != null && rel.EndsWith("canonical")) {
|
// Pictures with rel="http://schemas.google.com/photos/2007#canonical" are the direct link
|
||||||
break;
|
if (rel != null && rel.EndsWith("canonical")) {
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return url;
|
}
|
||||||
}
|
return url;
|
||||||
} catch(Exception e) {
|
}
|
||||||
Log.ErrorFormat("Could not parse Picasa response due to error {0}, response was: {1}", e.Message, response);
|
} catch(Exception e) {
|
||||||
}
|
Log.ErrorFormat("Could not parse GooglePhotos response due to error {0}, response was: {1}", e.Message, response);
|
||||||
return null;
|
}
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -19,13 +19,13 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin {
|
namespace GreenshotGooglePhotosPlugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class is merely a placeholder for the file keeping the API key and secret for dropbox integration.
|
/// This class is merely a placeholder for the file keeping the API key and secret for dropbox integration.
|
||||||
/// You can set your own values here
|
/// You can set your own values here
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class PicasaCredentials {
|
public static class GooglePhotosCredentials {
|
||||||
public static string ClientId = "${Picasa_ClientId}";
|
public static string ClientId = "${GooglePhotos_ClientId}";
|
||||||
public static string ClientSecret = "${Picasa_ClientSecret}";
|
public static string ClientSecret = "${GooglePhotos_ClientSecret}";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,16 +1,15 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
<ItemGroup>
|
||||||
<PropertyGroup>
|
<None Include="Languages\language*.xml">
|
||||||
<RootNamespace>GreenshotOCRPlugin</RootNamespace>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<AssemblyName>GreenshotOCRPlugin</AssemblyName>
|
</None>
|
||||||
</PropertyGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Languages\language*.xml">
|
<EmbeddedResource Include="GooglePhotos.png" />
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
</ItemGroup>
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
<ItemGroup>
|
||||||
<ItemGroup>
|
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj" />
|
||||||
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj" />
|
</ItemGroup>
|
||||||
</ItemGroup>
|
</Project>
|
||||||
</Project>
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* A Picasa Plugin for Greenshot
|
* A GooglePhotos Plugin for Greenshot
|
||||||
* Copyright (C) 2011 Francis Noel
|
* Copyright (C) 2011 Francis Noel
|
||||||
*
|
*
|
||||||
* For more information see: http://getgreenshot.org/
|
* For more information see: http://getgreenshot.org/
|
||||||
|
@ -16,19 +16,14 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace GreenshotPicasaPlugin {
|
namespace GreenshotGooglePhotosPlugin {
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,29 +1,29 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Czech" ietf="cs-CZ" version="1.1.0.2411" languagegroup="">
|
<language description="Czech" ietf="cs-CZ" version="1.1.0.2411" languagegroup="">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="CANCEL">Zrušit</resource>
|
<resource name="CANCEL">Zrušit</resource>
|
||||||
<resource name="communication_wait">Probíhá komunikace s Picasem. Prosím počkejte ...</resource>
|
<resource name="communication_wait">Probíhá komunikace s Picasem. Prosím počkejte ...</resource>
|
||||||
<resource name="Configure">Konfigurace</resource>
|
<resource name="Configure">Konfigurace</resource>
|
||||||
<resource name="delete_question">Opravdu chcete odstranit obrázek {0} z Picasa?</resource>
|
<resource name="delete_question">Opravdu chcete odstranit obrázek {0} z GooglePhotos?</resource>
|
||||||
<resource name="delete_title">Odstranit Picasa {0}</resource>
|
<resource name="delete_title">Odstranit GooglePhotos {0}</resource>
|
||||||
<resource name="History">Historie</resource>
|
<resource name="History">Historie</resource>
|
||||||
<resource name="InvalidCredentials">Neplatná oprávnění. Otevřít nastavení pro provedené změn.</resource>
|
<resource name="InvalidCredentials">Neplatná oprávnění. Otevřít nastavení pro provedené změn.</resource>
|
||||||
<resource name="label_AfterUpload">Po odeslání</resource>
|
<resource name="label_AfterUpload">Po odeslání</resource>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Kopírovat odkaz do schránky</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Kopírovat odkaz do schránky</resource>
|
||||||
<resource name="label_AfterUploadOpenHistory">Zobrazit historii</resource>
|
<resource name="label_AfterUploadOpenHistory">Zobrazit historii</resource>
|
||||||
<resource name="label_DefaultSize">Výchozí velikost</resource>
|
<resource name="label_DefaultSize">Výchozí velikost</resource>
|
||||||
<resource name="label_Password">Heslo</resource>
|
<resource name="label_Password">Heslo</resource>
|
||||||
<resource name="label_upload_format">Formát obrázku</resource>
|
<resource name="label_upload_format">Formát obrázku</resource>
|
||||||
<resource name="label_Username">Jméno</resource>
|
<resource name="label_Username">Jméno</resource>
|
||||||
<resource name="OK">OK</resource>
|
<resource name="OK">OK</resource>
|
||||||
<resource name="PictureDisplaySize.OriginalUrl">Originál URL</resource>
|
<resource name="PictureDisplaySize.OriginalUrl">Originál URL</resource>
|
||||||
<resource name="PictureDisplaySize.SquareThumbnailUrl">Čtvercové náhledy URL ???</resource>
|
<resource name="PictureDisplaySize.SquareThumbnailUrl">Čtvercové náhledy URL ???</resource>
|
||||||
<resource name="PictureDisplaySize.WebUrl">Webová adresa URL</resource>
|
<resource name="PictureDisplaySize.WebUrl">Webová adresa URL</resource>
|
||||||
<resource name="settings_title">Nastavení Picasa</resource>
|
<resource name="settings_title">Nastavení GooglePhotos</resource>
|
||||||
<resource name="Upload">Nahrát</resource>
|
<resource name="Upload">Nahrát</resource>
|
||||||
<resource name="upload_failure">Nahrání obrázku do Picasa se nezdařilo:</resource>
|
<resource name="upload_failure">Nahrání obrázku do GooglePhotos se nezdařilo:</resource>
|
||||||
<resource name="upload_menu_item">Nahrát do Picasa</resource>
|
<resource name="upload_menu_item">Nahrát do GooglePhotos</resource>
|
||||||
<resource name="upload_success">Úspěšně odeslaný obrázek do Picasa!</resource>
|
<resource name="upload_success">Úspěšně odeslaný obrázek do GooglePhotos!</resource>
|
||||||
<resource name="UsernameNotSet">Prosím ověřit aplikaci Picasa. Otevřít nastavení obrazovky. ???</resource>
|
<resource name="UsernameNotSet">Prosím ověřit aplikaci GooglePhotos. Otevřít nastavení obrazovky. ???</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -8,25 +8,25 @@
|
||||||
Anschliessend
|
Anschliessend
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Picasa konfigurieren
|
GooglePhotos konfigurieren
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
Hochladen zu Picasa
|
Hochladen zu GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Picasa Einstellungen
|
GooglePhotos Einstellungen
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Hochladen zu Picasa war erfolgreich !
|
Hochladen zu GooglePhotos war erfolgreich !
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
Fehler beim Hochladen zu Picasa:
|
Fehler beim Hochladen zu GooglePhotos:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
Grafikformat
|
Grafikformat
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
Übermittle Daten zu Picasa. Bitte warten...
|
Übermittle Daten zu GooglePhotos. Bitte warten...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -8,25 +8,25 @@
|
||||||
After upload
|
After upload
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Configure Picasa
|
Configure GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
Upload to Picasa
|
Upload to GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Picasa settings
|
GooglePhotos settings
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Successfully uploaded image to Picasa!
|
Successfully uploaded image to GooglePhotos!
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
An error occured while uploading to Picasa:
|
An error occured while uploading to GooglePhotos:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
Image format
|
Image format
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
Communicating with Picasa. Please wait...
|
Communicating with GooglePhotos. Please wait...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Français" ietf="fr-FR" version="1.0.0" languagegroup="">
|
<language description="Français" ietf="fr-FR" version="1.0.0" languagegroup="">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="communication_wait">Communication en cours avec Picasa. Veuillez patientez...</resource>
|
<resource name="communication_wait">Communication en cours avec GooglePhotos. Veuillez patientez...</resource>
|
||||||
<resource name="Configure">Configurer Picasa</resource>
|
<resource name="Configure">Configurer GooglePhotos</resource>
|
||||||
<resource name="label_AfterUpload">Après téléversement</resource>
|
<resource name="label_AfterUpload">Après téléversement</resource>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Copier le lien dans le presse-papier</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Copier le lien dans le presse-papier</resource>
|
||||||
<resource name="label_upload_format">Format image</resource>
|
<resource name="label_upload_format">Format image</resource>
|
||||||
<resource name="settings_title">Paramètres Picasa</resource>
|
<resource name="settings_title">Paramètres GooglePhotos</resource>
|
||||||
<resource name="upload_failure">Une erreur s'est produite lors du téléversement vers Picasa :</resource>
|
<resource name="upload_failure">Une erreur s'est produite lors du téléversement vers GooglePhotos :</resource>
|
||||||
<resource name="upload_menu_item">Téléverser vers Picasa</resource>
|
<resource name="upload_menu_item">Téléverser vers GooglePhotos</resource>
|
||||||
<resource name="upload_success">Image téléversée avec succès vers Picasa !</resource>
|
<resource name="upload_success">Image téléversée avec succès vers GooglePhotos !</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Bahasa Indonesia" ietf="id-ID" version="1.0.0.0" languagegroup="">
|
<language description="Bahasa Indonesia" ietf="id-ID" version="1.0.0.0" languagegroup="">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="communication_wait">Menyambungkan ke Picasa. Tunggu sebentar...</resource>
|
<resource name="communication_wait">Menyambungkan ke GooglePhotos. Tunggu sebentar...</resource>
|
||||||
<resource name="Configure">Konfigurasi Picasa</resource>
|
<resource name="Configure">Konfigurasi GooglePhotos</resource>
|
||||||
<resource name="label_AfterUpload">Sesudah mengunggah</resource>
|
<resource name="label_AfterUpload">Sesudah mengunggah</resource>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Sambung ke papanklip</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Sambung ke papanklip</resource>
|
||||||
<resource name="label_upload_format">Format gambar</resource>
|
<resource name="label_upload_format">Format gambar</resource>
|
||||||
<resource name="settings_title">Pengaturan Picasa</resource>
|
<resource name="settings_title">Pengaturan GooglePhotos</resource>
|
||||||
<resource name="upload_failure">Kesalahan terjadi ketika mengunggah ke Picasa:</resource>
|
<resource name="upload_failure">Kesalahan terjadi ketika mengunggah ke GooglePhotos:</resource>
|
||||||
<resource name="upload_menu_item">Unggah ke Picasa</resource>
|
<resource name="upload_menu_item">Unggah ke GooglePhotos</resource>
|
||||||
<resource name="upload_success">Berhasil mengunggah gambar ke Picasa!</resource>
|
<resource name="upload_success">Berhasil mengunggah gambar ke GooglePhotos!</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -1,32 +1,32 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Italiano" ietf="it-IT" version="1.1.5">
|
<language description="Italiano" ietf="it-IT" version="1.1.5">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">
|
<resource name="label_AfterUploadLinkToClipBoard">
|
||||||
Collegamento agli Appunti
|
Collegamento agli Appunti
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_AfterUpload">
|
<resource name="label_AfterUpload">
|
||||||
Dopo il caricamento
|
Dopo il caricamento
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Impostazioni Picasa
|
Impostazioni GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
Carica su Picasa
|
Carica su GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Impostazioni Picasa
|
Impostazioni GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Caricamento immagine su Picasa completato!
|
Caricamento immagine su GooglePhotos completato!
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
Si è verificato un errore durante il caricamento su Picasa:
|
Si è verificato un errore durante il caricamento su GooglePhotos:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
Formato immagine
|
Formato immagine
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
Comunicazione con Picasa...
|
Comunicazione con GooglePhotos...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<language description="日本語" ietf="ja-JP" version="1.0.0">
|
||||||
|
<resources>
|
||||||
|
<resource name="label_AfterUploadLinkToClipBoard">リンクをクリップボードへコピー</resource>
|
||||||
|
<resource name="label_AfterUpload">アップロード後</resource>
|
||||||
|
<resource name="Configure">GooglePhotos の設定</resource>
|
||||||
|
<resource name="upload_menu_item">GooglePhotos にアップロード</resource>
|
||||||
|
<resource name="settings_title">GooglePhotos の設定</resource>
|
||||||
|
<resource name="upload_success">GooglePhotos へのアップロードに成功しました!</resource>
|
||||||
|
<resource name="upload_failure">GooglePhotos へのアップロード中にエラーが発生しました:</resource>
|
||||||
|
<resource name="label_upload_format">画像フォーマット</resource>
|
||||||
|
<resource name="communication_wait">GooglePhotos に接続中です。しばらくお待ち下さい...</resource>
|
||||||
|
</resources>
|
||||||
|
</language>
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
|
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="communication_wait">S tidett tebɣiḍ ad tekkseḍ amazray adigan n Picasa ?...</resource>
|
<resource name="communication_wait">S tidett tebɣiḍ ad tekkseḍ amazray adigan n GooglePhotos ?...</resource>
|
||||||
<resource name="Configure">Swel Picasa</resource>
|
<resource name="Configure">Swel GooglePhotos</resource>
|
||||||
<resource name="label_AfterUpload">Ticki yemmed usali</resource>
|
<resource name="label_AfterUpload">Ticki yemmed usali</resource>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Nɣel aseɣwen ɣef afus</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Nɣel aseɣwen ɣef afus</resource>
|
||||||
<resource name="label_upload_format">Amsal n tugna</resource>
|
<resource name="label_upload_format">Amsal n tugna</resource>
|
||||||
<resource name="settings_title">Iɣewwaṛen Picasa</resource>
|
<resource name="settings_title">Iɣewwaṛen GooglePhotos</resource>
|
||||||
<resource name="upload_failure">Teḍra-d tuccḍa deg usali ɣer Picasa :</resource>
|
<resource name="upload_failure">Teḍra-d tuccḍa deg usali ɣer GooglePhotos :</resource>
|
||||||
<resource name="upload_menu_item">Sali ɣer Picasa</resource>
|
<resource name="upload_menu_item">Sali ɣer GooglePhotos</resource>
|
||||||
<resource name="upload_success">Tugna tuli ɣer Picasa !</resource>
|
<resource name="upload_success">Tugna tuli ɣer GooglePhotos !</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -8,25 +8,25 @@
|
||||||
얼로드 후
|
얼로드 후
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Picasa 설정
|
GooglePhotos 설정
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
Picasa로 업로드
|
GooglePhotos로 업로드
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Picasa 설정
|
GooglePhotos 설정
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Picasa로 이미지 업로드 성공!
|
GooglePhotos로 이미지 업로드 성공!
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
Picasa로 업로드시 오류 발생:
|
GooglePhotos로 업로드시 오류 발생:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
이미지 형식
|
이미지 형식
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
Picasa와 연결 중 잠시 기다리세요...
|
GooglePhotos와 연결 중 잠시 기다리세요...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -9,25 +9,25 @@
|
||||||
Pēc augšupielādes
|
Pēc augšupielādes
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Picasa iestatījumi
|
GooglePhotos iestatījumi
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
Augšupieladēt uz Picasa
|
Augšupieladēt uz GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Picasa iestatījumi
|
GooglePhotos iestatījumi
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Attēls veiksmīgi augšupielādēts uz Picasa!
|
Attēls veiksmīgi augšupielādēts uz GooglePhotos!
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
Kļūda augšuplādējot uz Picasa:
|
Kļūda augšuplādējot uz GooglePhotos:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
Attēla formāts
|
Attēla formāts
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
Savienojos ar Picasa. Lūdzu uzgaidiet...
|
Savienojos ar GooglePhotos. Lūdzu uzgaidiet...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<language description="Polski" ietf="pl-PL" version="1.1.4" languagegroup="2">
|
||||||
|
<resources>
|
||||||
|
<resource name="communication_wait">Trwa komunikacja z GooglePhotos. Proszę czekać...</resource>
|
||||||
|
<resource name="Configure">Konfiguruj GooglePhotos</resource>
|
||||||
|
<resource name="label_AfterUpload">Po wysłaniu</resource>
|
||||||
|
<resource name="label_AfterUploadLinkToClipBoard">Link do schowka</resource>
|
||||||
|
<resource name="label_upload_format">Format obrazów</resource>
|
||||||
|
<resource name="settings_title">Ustawienia GooglePhotos</resource>
|
||||||
|
<resource name="upload_failure">Wystąpił błąd przy wysyłaniu do GooglePhotos:</resource>
|
||||||
|
<resource name="upload_menu_item">Wyślij do GooglePhotos</resource>
|
||||||
|
<resource name="upload_success">Wysyłanie obrazu do GooglePhotos powiodło się!</resource>
|
||||||
|
</resources>
|
||||||
|
</language>
|
|
@ -8,25 +8,25 @@
|
||||||
Após enviar
|
Após enviar
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Configurar o Picasa
|
Configurar o GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
enviar para o Picasa
|
enviar para o GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Definições Picasa
|
Definições GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Imagem enviada com êxito para o Picasa!
|
Imagem enviada com êxito para o GooglePhotos!
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
Ocorreu um erro ao enviar para o Picasa:
|
Ocorreu um erro ao enviar para o GooglePhotos:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
Formato da imagem
|
Formato da imagem
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
A comunicar com o Picasa. Por favor aguarde...
|
A comunicar com o GooglePhotos. Por favor aguarde...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Русский" ietf="ru-RU" version="1.1.0.2515" languagegroup="5">
|
<language description="Русский" ietf="ru-RU" version="1.1.0.2515" languagegroup="5">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="communication_wait">Обмен данными с Picasa. Подождите...</resource>
|
<resource name="communication_wait">Обмен данными с GooglePhotos. Подождите...</resource>
|
||||||
<resource name="Configure">Настройка Picasa</resource>
|
<resource name="Configure">Настройка GooglePhotos</resource>
|
||||||
<resource name="label_AfterUpload">После загрузки</resource>
|
<resource name="label_AfterUpload">После загрузки</resource>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Ссылки в буфер обмена</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Ссылки в буфер обмена</resource>
|
||||||
<resource name="label_upload_format">Формат изображения</resource>
|
<resource name="label_upload_format">Формат изображения</resource>
|
||||||
<resource name="settings_title">Настройки Picasa</resource>
|
<resource name="settings_title">Настройки GooglePhotos</resource>
|
||||||
<resource name="upload_failure">Произошла ошибка при загрузке на Picasa:</resource>
|
<resource name="upload_failure">Произошла ошибка при загрузке на GooglePhotos:</resource>
|
||||||
<resource name="upload_menu_item">Загрузить на Picasa</resource>
|
<resource name="upload_menu_item">Загрузить на GooglePhotos</resource>
|
||||||
<resource name="upload_success">Изображение успешно загружено на Picasa!</resource>
|
<resource name="upload_success">Изображение успешно загружено на GooglePhotos!</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Српски" ietf="sr-RS" version="1.0.5" languagegroup="">
|
<language description="Српски" ietf="sr-RS" version="1.0.5" languagegroup="">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="communication_wait">Комуницирам с Пикасом. Сачекајте…</resource>
|
<resource name="communication_wait">Комуницирам с Пикасом. Сачекајте…</resource>
|
||||||
<resource name="Configure">Поставке Пикасе</resource>
|
<resource name="Configure">Поставке Пикасе</resource>
|
||||||
<resource name="label_AfterUpload">Након отпремања:</resource>
|
<resource name="label_AfterUpload">Након отпремања:</resource>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Веза ка остави</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Веза ка остави</resource>
|
||||||
<resource name="label_upload_format">Формат слике:</resource>
|
<resource name="label_upload_format">Формат слике:</resource>
|
||||||
<resource name="settings_title">Поставке Пикасе</resource>
|
<resource name="settings_title">Поставке Пикасе</resource>
|
||||||
<resource name="upload_failure">Дошло је до грешке при отпремању на Пикасу:</resource>
|
<resource name="upload_failure">Дошло је до грешке при отпремању на Пикасу:</resource>
|
||||||
<resource name="upload_menu_item">Отпреми на Пикасу</resource>
|
<resource name="upload_menu_item">Отпреми на Пикасу</resource>
|
||||||
<resource name="upload_success">Слика је успешно отпремљена на Пикасу.</resource>
|
<resource name="upload_success">Слика је успешно отпремљена на Пикасу.</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -8,25 +8,25 @@
|
||||||
Vid uppladdning
|
Vid uppladdning
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="Configure">
|
<resource name="Configure">
|
||||||
Konfigurera Picasa
|
Konfigurera GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_menu_item">
|
<resource name="upload_menu_item">
|
||||||
Ladda upp till Picasa
|
Ladda upp till GooglePhotos
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="settings_title">
|
<resource name="settings_title">
|
||||||
Picasa-inställningar
|
GooglePhotos-inställningar
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_success">
|
<resource name="upload_success">
|
||||||
Skärmdumpen laddades upp till Picasa!
|
Skärmdumpen laddades upp till GooglePhotos!
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="upload_failure">
|
<resource name="upload_failure">
|
||||||
Ett fel uppstod vid uppladdning till Picasa:
|
Ett fel uppstod vid uppladdning till GooglePhotos:
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="label_upload_format">
|
<resource name="label_upload_format">
|
||||||
Bildformat
|
Bildformat
|
||||||
</resource>
|
</resource>
|
||||||
<resource name="communication_wait">
|
<resource name="communication_wait">
|
||||||
Kommunicerar med Picasa. Vänta...
|
Kommunicerar med GooglePhotos. Vänta...
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<language description="Українська" ietf="uk-UA" version="1.0.0">
|
<language description="Українська" ietf="uk-UA" version="1.0.0">
|
||||||
<resources>
|
<resources>
|
||||||
<resource name="label_AfterUploadLinkToClipBoard">Посилання в буфер обміну</resource>
|
<resource name="label_AfterUploadLinkToClipBoard">Посилання в буфер обміну</resource>
|
||||||
<resource name="label_AfterUpload">Після вивантаження</resource>
|
<resource name="label_AfterUpload">Після вивантаження</resource>
|
||||||
<resource name="Configure">Налаштувати Picasa</resource>
|
<resource name="Configure">Налаштувати GooglePhotos</resource>
|
||||||
<resource name="upload_menu_item">Вивантажити на Picasa</resource>
|
<resource name="upload_menu_item">Вивантажити на GooglePhotos</resource>
|
||||||
<resource name="settings_title">Параметри Picasa</resource>
|
<resource name="settings_title">Параметри GooglePhotos</resource>
|
||||||
<resource name="upload_success">Зображення вдало вивантажено на Picasa!</resource>
|
<resource name="upload_success">Зображення вдало вивантажено на GooglePhotos!</resource>
|
||||||
<resource name="upload_failure">Відбулась помилка під час вивантаження на Picasa:</resource>
|
<resource name="upload_failure">Відбулась помилка під час вивантаження на GooglePhotos:</resource>
|
||||||
<resource name="label_upload_format">Формат зображення</resource>
|
<resource name="label_upload_format">Формат зображення</resource>
|
||||||
<resource name="communication_wait">З’єднання з Picasa. Будь ласка, зачекайте...</resource>
|
<resource name="communication_wait">З’єднання з GooglePhotos. Будь ласка, зачекайте...</resource>
|
||||||
</resources>
|
</resources>
|
||||||
</language>
|
</language>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<language description="简体中文" ietf="zh-CN" version="1.0.3" languagegroup="a">
|
||||||
|
<resources>
|
||||||
|
<resource name="communication_wait">正在连接到GooglePhotos。请稍后...</resource>
|
||||||
|
<resource name="Configure">配置 GooglePhotos</resource>
|
||||||
|
<resource name="label_AfterUpload">上传之后</resource>
|
||||||
|
<resource name="label_AfterUploadLinkToClipBoard">复制链接到剪贴板</resource>
|
||||||
|
<resource name="label_upload_format">图片格式</resource>
|
||||||
|
<resource name="settings_title">GooglePhotos设置</resource>
|
||||||
|
<resource name="upload_failure">上传到GooglePhotos时发生错误:</resource>
|
||||||
|
<resource name="upload_menu_item">上传到GooglePhotos</resource>
|
||||||
|
<resource name="upload_success">图片已成功上传到了GooglePhotos!</resource>
|
||||||
|
</resources>
|
||||||
|
</language>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<language description="正體中文" ietf="zh-TW" version="1.0.0" languagegroup="9">
|
||||||
|
<resources>
|
||||||
|
<resource name="communication_wait">正在與 GooglePhotos 通訊,請稍候...</resource>
|
||||||
|
<resource name="Configure">組態 GooglePhotos</resource>
|
||||||
|
<resource name="label_AfterUpload">上傳後</resource>
|
||||||
|
<resource name="label_AfterUploadLinkToClipBoard">連結到剪貼簿</resource>
|
||||||
|
<resource name="label_upload_format">圖片格式</resource>
|
||||||
|
<resource name="settings_title">GooglePhotos 設定</resource>
|
||||||
|
<resource name="upload_failure">上傳到 GooglePhotos 時發生錯誤:</resource>
|
||||||
|
<resource name="upload_menu_item">上傳到 GooglePhotos</resource>
|
||||||
|
<resource name="upload_success">上傳圖片到 GooglePhotos 成功!</resource>
|
||||||
|
</resources>
|
||||||
|
</language>
|
|
@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyDescription("A plugin to upload images to Picasa")]
|
[assembly: AssemblyDescription("A plugin to upload images to GooglePhotos")]
|
||||||
|
|
||||||
// This sets the default COM visibility of types in the assembly to invisible.
|
// This sets the default COM visibility of types in the assembly to invisible.
|
||||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
|
@ -25,7 +25,7 @@ namespace GreenshotImgurPlugin {
|
||||||
/// You can set your own values here
|
/// You can set your own values here
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ImgurCredentials {
|
public static class ImgurCredentials {
|
||||||
public static string CONSUMER_KEY = "${Imgur_ClientId}";
|
public static string CONSUMER_KEY = "${Imgur13_ClientId}";
|
||||||
public static string CONSUMER_SECRET = "${Imgur_ClientSecret}";
|
public static string CONSUMER_SECRET = "${Imgur13_ClientSecret}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
using GreenshotPlugin.Core.OAuth;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
@ -37,10 +37,8 @@ namespace GreenshotImgurPlugin {
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurUtils));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurUtils));
|
||||||
private const string SmallUrlPattern = "http://i.imgur.com/{0}s.jpg";
|
private const string SmallUrlPattern = "http://i.imgur.com/{0}s.jpg";
|
||||||
private static readonly ImgurConfiguration Config = IniConfig.GetIniSection<ImgurConfiguration>();
|
private static readonly ImgurConfiguration Config = IniConfig.GetIniSection<ImgurConfiguration>();
|
||||||
private const string AuthUrlPattern = "https://api.imgur.com/oauth2/authorize?response_type=token&client_id={ClientId}&state={State}";
|
|
||||||
private const string TokenUrl = "https://api.imgur.com/oauth2/token";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if we need to load the history
|
/// Check if we need to load the history
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
@ -162,20 +160,20 @@ namespace GreenshotImgurPlugin {
|
||||||
responseString = reader.ReadToEnd();
|
responseString = reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.Error("Upload to imgur gave an exeption: ", ex);
|
Log.Error("Upload to imgur gave an exception: ", ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
var oauth2Settings = new OAuth2Settings
|
var oauth2Settings = new OAuth2Settings
|
||||||
{
|
{
|
||||||
AuthUrlPattern = AuthUrlPattern,
|
AuthUrlPattern = "https://api.imgur.com/oauth2/authorize?response_type=token&client_id={ClientId}&state={State}",
|
||||||
TokenUrl = TokenUrl,
|
TokenUrl = "https://api.imgur.com/oauth2/token",
|
||||||
RedirectUrl = "https://getgreenshot.org/oauth/imgur",
|
RedirectUrl = "https://getgreenshot.org/authorize/imgur",
|
||||||
CloudServiceName = "Imgur",
|
CloudServiceName = "Imgur",
|
||||||
ClientId = ImgurCredentials.CONSUMER_KEY,
|
ClientId = ImgurCredentials.CONSUMER_KEY,
|
||||||
ClientSecret = ImgurCredentials.CONSUMER_SECRET,
|
ClientSecret = ImgurCredentials.CONSUMER_SECRET,
|
||||||
AuthorizeMode = OAuth2AuthorizeMode.OutOfBoundAuto,
|
AuthorizeMode = OAuth2AuthorizeMode.JsonReceiver,
|
||||||
RefreshToken = Config.RefreshToken,
|
RefreshToken = Config.RefreshToken,
|
||||||
AccessToken = Config.AccessToken,
|
AccessToken = Config.AccessToken,
|
||||||
AccessTokenExpires = Config.AccessTokenExpires
|
AccessTokenExpires = Config.AccessTokenExpires
|
||||||
|
@ -221,7 +219,7 @@ namespace GreenshotImgurPlugin {
|
||||||
Log.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo.SmallSquare);
|
Log.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo.SmallSquare);
|
||||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(string.Format(SmallUrlPattern, imgurInfo.Hash), HTTPMethod.GET);
|
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(string.Format(SmallUrlPattern, imgurInfo.Hash), HTTPMethod.GET);
|
||||||
webRequest.ServicePoint.Expect100Continue = false;
|
webRequest.ServicePoint.Expect100Continue = false;
|
||||||
// Not for getting the thumbnail, in anonymous modus
|
// Not for getting the thumbnail, in anonymous mode
|
||||||
//SetClientId(webRequest);
|
//SetClientId(webRequest);
|
||||||
using WebResponse response = webRequest.GetResponse();
|
using WebResponse response = webRequest.GetResponse();
|
||||||
LogRateLimitInfo(response);
|
LogRateLimitInfo(response);
|
||||||
|
@ -304,7 +302,7 @@ namespace GreenshotImgurPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make sure we remove it from the history, if no error occured
|
// Make sure we remove it from the history, if no error occurred
|
||||||
Config.runtimeImgurHistory.Remove(imgurInfo.Hash);
|
Config.runtimeImgurHistory.Remove(imgurInfo.Hash);
|
||||||
Config.ImgurUploadHistory.Remove(imgurInfo.Hash);
|
Config.ImgurUploadHistory.Remove(imgurInfo.Hash);
|
||||||
imgurInfo.Image = null;
|
imgurInfo.Image = null;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 "$(TargetDir)*.exe" "$(SolutionDir)$(SolutionName)\$(OutDir)"" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue