mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 13:10:00 -07:00
Work in progress for the Jira backport. [skip ci]
This commit is contained in:
parent
798ca503a5
commit
a3f3c20d71
12 changed files with 402 additions and 4290 deletions
|
@ -22,14 +22,19 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Dapplo.Jira.Entities;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GreenshotJiraPlugin.Forms {
|
namespace GreenshotJiraPlugin.Forms {
|
||||||
public partial class JiraForm : Form {
|
public partial class JiraForm : Form {
|
||||||
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraForm));
|
||||||
private readonly JiraConnector _jiraConnector;
|
private readonly JiraConnector _jiraConnector;
|
||||||
private JiraIssue _selectedIssue;
|
private Issue _selectedIssue;
|
||||||
private readonly GreenshotColumnSorter _columnSorter;
|
private readonly GreenshotColumnSorter _columnSorter;
|
||||||
private readonly JiraConfiguration _config = IniConfig.GetIniSection<JiraConfiguration>();
|
private readonly JiraConfiguration _config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
|
|
||||||
|
@ -47,15 +52,46 @@ namespace GreenshotJiraPlugin.Forms {
|
||||||
_jiraConnector = jiraConnector;
|
_jiraConnector = jiraConnector;
|
||||||
|
|
||||||
ChangeModus(false);
|
ChangeModus(false);
|
||||||
try {
|
|
||||||
if (!jiraConnector.IsLoggedIn) {
|
uploadButton.Enabled = false;
|
||||||
jiraConnector.Login();
|
Load += OnLoad;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
|
private async void OnLoad(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_jiraConnector.IsLoggedIn)
|
||||||
|
{
|
||||||
|
await _jiraConnector.Login();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
MessageBox.Show(Language.GetFormattedString("jira", LangKey.login_error, e.Message));
|
MessageBox.Show(Language.GetFormattedString("jira", LangKey.login_error, e.Message));
|
||||||
}
|
}
|
||||||
uploadButton.Enabled = false;
|
if (_jiraConnector.IsLoggedIn)
|
||||||
UpdateForm();
|
{
|
||||||
|
var filters = await _jiraConnector.GetFavoriteFiltersAsync();
|
||||||
|
if (filters.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var filter in filters)
|
||||||
|
{
|
||||||
|
jiraFilterBox.Items.Add(filter);
|
||||||
|
}
|
||||||
|
jiraFilterBox.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
ChangeModus(true);
|
||||||
|
if (_config.LastUsedJira != null)
|
||||||
|
{
|
||||||
|
_selectedIssue = await _jiraConnector.GetIssueAsync(_config.LastUsedJira);
|
||||||
|
if (_selectedIssue != null)
|
||||||
|
{
|
||||||
|
jiraKey.Text = _config.LastUsedJira;
|
||||||
|
uploadButton.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponentText() {
|
private void InitializeComponentText() {
|
||||||
|
@ -64,26 +100,6 @@ namespace GreenshotJiraPlugin.Forms {
|
||||||
label_filename.Text = Language.GetString("jira", LangKey.label_filename);
|
label_filename.Text = Language.GetString("jira", LangKey.label_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateForm() {
|
|
||||||
if (_jiraConnector.IsLoggedIn) {
|
|
||||||
JiraFilter[] filters = _jiraConnector.GetFilters();
|
|
||||||
if (filters.Length > 0) {
|
|
||||||
foreach (JiraFilter filter in filters) {
|
|
||||||
jiraFilterBox.Items.Add(filter);
|
|
||||||
}
|
|
||||||
jiraFilterBox.SelectedIndex = 0;
|
|
||||||
}
|
|
||||||
ChangeModus(true);
|
|
||||||
if (_config.LastUsedJira != null) {
|
|
||||||
_selectedIssue = _jiraConnector.GetIssue(_config.LastUsedJira);
|
|
||||||
if (_selectedIssue != null) {
|
|
||||||
jiraKey.Text = _config.LastUsedJira;
|
|
||||||
uploadButton.Enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChangeModus(bool enabled) {
|
private void ChangeModus(bool enabled) {
|
||||||
jiraFilterBox.Enabled = enabled;
|
jiraFilterBox.Enabled = enabled;
|
||||||
jiraListView.Enabled = enabled;
|
jiraListView.Enabled = enabled;
|
||||||
|
@ -99,59 +115,67 @@ namespace GreenshotJiraPlugin.Forms {
|
||||||
jiraCommentBox.Text = comment;
|
jiraCommentBox.Text = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JiraIssue GetJiraIssue() {
|
public Issue GetJiraIssue() {
|
||||||
return _selectedIssue;
|
return _selectedIssue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Upload(IBinaryContainer attachment) {
|
public async Task UploadAsync(IBinaryContainer attachment) {
|
||||||
_config.LastUsedJira = _selectedIssue.Key;
|
_config.LastUsedJira = _selectedIssue.Key;
|
||||||
_jiraConnector.AddAttachment(_selectedIssue.Key, jiraFilenameBox.Text, attachment);
|
using (var memoryStream = new MemoryStream())
|
||||||
if (!string.IsNullOrEmpty(jiraCommentBox.Text)) {
|
{
|
||||||
_jiraConnector.AddComment(_selectedIssue.Key, jiraCommentBox.Text);
|
attachment.WriteToStream(memoryStream);
|
||||||
}
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
await _jiraConnector.AttachAsync(_selectedIssue.Key, memoryStream, jiraFilenameBox.Text, attachment.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Logout() {
|
if (!string.IsNullOrEmpty(jiraCommentBox.Text)) {
|
||||||
_jiraConnector.Logout();
|
await _jiraConnector.AddCommentAsync(_selectedIssue.Key, jiraCommentBox.Text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectJiraToolStripMenuItem_Click(object sender, EventArgs e) {
|
private void selectJiraToolStripMenuItem_Click(object sender, EventArgs e) {
|
||||||
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
|
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
|
||||||
_selectedIssue = (JiraIssue)clickedItem.Tag;
|
_selectedIssue = (Issue)clickedItem.Tag;
|
||||||
jiraKey.Text = _selectedIssue.Key;
|
jiraKey.Text = _selectedIssue.Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void jiraFilterBox_SelectedIndexChanged(object sender, EventArgs e) {
|
private async void jiraFilterBox_SelectedIndexChanged(object sender, EventArgs e) {
|
||||||
if (_jiraConnector.IsLoggedIn) {
|
if (_jiraConnector.IsLoggedIn) {
|
||||||
JiraIssue[] issues = null;
|
|
||||||
uploadButton.Enabled = false;
|
uploadButton.Enabled = false;
|
||||||
JiraFilter filter = (JiraFilter)jiraFilterBox.SelectedItem;
|
var filter = (Filter)jiraFilterBox.SelectedItem;
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Run upload in the background
|
IList<Issue> issues = null;
|
||||||
new PleaseWaitForm().ShowAndWait(JiraPlugin.Instance.JiraPluginAttributes.Name, Language.GetString("jira", LangKey.communication_wait),
|
try
|
||||||
delegate() {
|
{
|
||||||
issues = _jiraConnector.GetIssuesForFilter(filter.Id);
|
var searchResult = await _jiraConnector.SearchAsync(filter.Jql);
|
||||||
|
issues = searchResult.Issues;
|
||||||
}
|
}
|
||||||
);
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex);
|
||||||
|
MessageBox.Show(this, ex.Message, "Error in filter", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
jiraListView.BeginUpdate();
|
jiraListView.BeginUpdate();
|
||||||
jiraListView.Items.Clear();
|
jiraListView.Items.Clear();
|
||||||
if (issues.Length > 0) {
|
if (issues?.Count > 0) {
|
||||||
jiraListView.Columns.Clear();
|
jiraListView.Columns.Clear();
|
||||||
LangKey[] columns = { LangKey.column_id, LangKey.column_created, LangKey.column_assignee, LangKey.column_reporter, LangKey.column_summary };
|
LangKey[] columns = { LangKey.column_id, LangKey.column_created, LangKey.column_assignee, LangKey.column_reporter, LangKey.column_summary };
|
||||||
foreach (LangKey column in columns) {
|
foreach (LangKey column in columns) {
|
||||||
jiraListView.Columns.Add(Language.GetString("jira", column));
|
jiraListView.Columns.Add(Language.GetString("jira", column));
|
||||||
}
|
}
|
||||||
foreach (JiraIssue issue in issues) {
|
foreach (var issue in issues) {
|
||||||
ListViewItem item = new ListViewItem(issue.Key)
|
var item = new ListViewItem(issue.Key)
|
||||||
{
|
{
|
||||||
Tag = issue
|
Tag = issue
|
||||||
};
|
};
|
||||||
item.SubItems.Add(issue.Created.Value.ToString("d", DateTimeFormatInfo.InvariantInfo));
|
item.SubItems.Add(issue.Fields.Created.ToString("d", DateTimeFormatInfo.InvariantInfo));
|
||||||
item.SubItems.Add(issue.Assignee);
|
item.SubItems.Add(issue.Fields.Assignee?.DisplayName);
|
||||||
item.SubItems.Add(issue.Reporter);
|
item.SubItems.Add(issue.Fields.Reporter?.DisplayName);
|
||||||
item.SubItems.Add(issue.Summary);
|
item.SubItems.Add(issue.Fields.Summary);
|
||||||
jiraListView.Items.Add(item);
|
jiraListView.Items.Add(item);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < columns.Length; i++) {
|
for (int i = 0; i < columns.Length; i++) {
|
||||||
|
@ -164,8 +188,8 @@ namespace GreenshotJiraPlugin.Forms {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void jiraListView_SelectedIndexChanged(object sender, EventArgs e) {
|
private void jiraListView_SelectedIndexChanged(object sender, EventArgs e) {
|
||||||
if (jiraListView.SelectedItems != null && jiraListView.SelectedItems.Count > 0) {
|
if (jiraListView.SelectedItems.Count > 0) {
|
||||||
_selectedIssue = (JiraIssue)jiraListView.SelectedItems[0].Tag;
|
_selectedIssue = (Issue)jiraListView.SelectedItems[0].Tag;
|
||||||
jiraKey.Text = _selectedIssue.Key;
|
jiraKey.Text = _selectedIssue.Key;
|
||||||
uploadButton.Enabled = true;
|
uploadButton.Enabled = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -192,12 +216,12 @@ namespace GreenshotJiraPlugin.Forms {
|
||||||
jiraListView.Sort();
|
jiraListView.Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JiraKeyTextChanged(object sender, EventArgs e) {
|
private async void JiraKeyTextChanged(object sender, EventArgs e) {
|
||||||
string jiranumber = jiraKey.Text;
|
string jiranumber = jiraKey.Text;
|
||||||
uploadButton.Enabled = false;
|
uploadButton.Enabled = false;
|
||||||
int dashIndex = jiranumber.IndexOf('-');
|
int dashIndex = jiranumber.IndexOf('-');
|
||||||
if (dashIndex > 0 && jiranumber.Length > dashIndex+1) {
|
if (dashIndex > 0 && jiranumber.Length > dashIndex+1) {
|
||||||
_selectedIssue = _jiraConnector.GetIssue(jiraKey.Text);
|
_selectedIssue = await _jiraConnector.GetIssueAsync(jiraKey.Text);
|
||||||
if (_selectedIssue != null) {
|
if (_selectedIssue != null) {
|
||||||
uploadButton.Enabled = true;
|
uploadButton.Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>GreenshotJiraPlugin</RootNamespace>
|
<RootNamespace>GreenshotJiraPlugin</RootNamespace>
|
||||||
<AssemblyName>GreenshotJiraPlugin</AssemblyName>
|
<AssemblyName>GreenshotJiraPlugin</AssemblyName>
|
||||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
<NoStdLib>False</NoStdLib>
|
<NoStdLib>False</NoStdLib>
|
||||||
|
@ -20,8 +20,36 @@
|
||||||
<UpgradeBackupLocation>
|
<UpgradeBackupLocation>
|
||||||
</UpgradeBackupLocation>
|
</UpgradeBackupLocation>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Dapplo.HttpExtensions, Version=0.5.30.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapplo.HttpExtensions.0.5.30\lib\net45\Dapplo.HttpExtensions.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Dapplo.Jira, Version=0.1.56.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapplo.Jira.0.1.56\lib\net45\Dapplo.Jira.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Dapplo.Log.Facade, Version=0.5.4.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapplo.Log.Facade.0.5.4\lib\net45\Dapplo.Log.Facade.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Dapplo.Utils, Version=0.1.113.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Dapplo.Utils.0.1.113\lib\net45\Dapplo.Utils.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="log4net">
|
<Reference Include="log4net">
|
||||||
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
|
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
@ -47,18 +75,13 @@
|
||||||
<Compile Include="Forms\SettingsForm.Designer.cs">
|
<Compile Include="Forms\SettingsForm.Designer.cs">
|
||||||
<DependentUpon>SettingsForm.cs</DependentUpon>
|
<DependentUpon>SettingsForm.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Jira.cs" />
|
<Compile Include="JiraConnector.cs" />
|
||||||
<Compile Include="JiraConfiguration.cs" />
|
<Compile Include="JiraConfiguration.cs" />
|
||||||
<Compile Include="JiraDestination.cs" />
|
<Compile Include="JiraDestination.cs" />
|
||||||
<Compile Include="JiraPlugin.cs" />
|
<Compile Include="JiraPlugin.cs" />
|
||||||
<Compile Include="JiraUtils.cs" />
|
<Compile Include="JiraUtils.cs" />
|
||||||
<Compile Include="LanguageKeys.cs" />
|
<Compile Include="LanguageKeys.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Web References\JiraSoap\Reference.cs">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DesignTime>True</DesignTime>
|
|
||||||
<DependentUpon>Reference.map</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<None Include="Languages\language_jiraplugin-de-DE.xml">
|
<None Include="Languages\language_jiraplugin-de-DE.xml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
@ -72,23 +95,12 @@
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="Languages\language_jiraplugin-zh-CN.xml" />
|
<None Include="Languages\language_jiraplugin-zh-CN.xml" />
|
||||||
<None Include="Web References\JiraSoap\jirasoapservice-v2.wsdl" />
|
<None Include="packages.config" />
|
||||||
<None Include="Web References\JiraSoap\Reference.map">
|
|
||||||
<Generator>MSDiscoCodeGenerator</Generator>
|
|
||||||
<LastGenOutput>Reference.cs</LastGenOutput>
|
|
||||||
</None>
|
|
||||||
<EmbeddedResource Include="JiraPlugin.resx">
|
<EmbeddedResource Include="JiraPlugin.resx">
|
||||||
<DependentUpon>JiraPlugin.cs</DependentUpon>
|
<DependentUpon>JiraPlugin.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<WebReferences Include="Web References\" />
|
|
||||||
<WebReferenceUrl Include="http://jira/rpc/soap/jirasoapservice-v2%3fwsdl">
|
|
||||||
<UrlBehavior>Static</UrlBehavior>
|
|
||||||
<UpdateFromURL>http://jira/rpc/soap/jirasoapservice-v2%3fwsdl</UpdateFromURL>
|
|
||||||
<RelPath>Web References\JiraSoap</RelPath>
|
|
||||||
<Namespace>Jira</Namespace>
|
|
||||||
</WebReferenceUrl>
|
|
||||||
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
|
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
|
||||||
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
|
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
|
||||||
<Name>GreenshotPlugin</Name>
|
<Name>GreenshotPlugin</Name>
|
||||||
|
@ -97,6 +109,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>mkdir "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)"
|
<PostBuildEvent>mkdir "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)"
|
||||||
copy "$(ProjectDir)bin\$(Configuration)\$(TargetFileName)" "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp"
|
copy "$(ProjectDir)bin\$(Configuration)\$(TargetFileName)" "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp"
|
||||||
|
copy "$(ProjectDir)bin\$(Configuration)\Dapplo.*" "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)\"
|
||||||
copy "$(ProjectDir)bin\$(Configuration)\$(ProjectName).pdb" "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)\"
|
copy "$(ProjectDir)bin\$(Configuration)\$(ProjectName).pdb" "$(SolutionDir)Greenshot\bin\$(Configuration)\Plugins\$(ProjectName)\"
|
||||||
mkdir "$(SolutionDir)Greenshot\bin\$(Configuration)\Languages\Plugins\$(ProjectName)"
|
mkdir "$(SolutionDir)Greenshot\bin\$(Configuration)\Languages\Plugins\$(ProjectName)"
|
||||||
copy "$(ProjectDir)\Languages\*.xml" "$(SolutionDir)Greenshot\bin\$(Configuration)\Languages\Plugins\$(ProjectName)\"</PostBuildEvent>
|
copy "$(ProjectDir)\Languages\*.xml" "$(SolutionDir)Greenshot\bin\$(Configuration)\Languages\Plugins\$(ProjectName)\"</PostBuildEvent>
|
||||||
|
|
|
@ -1,413 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Greenshot - a free and open source screenshot tool
|
|
||||||
* Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
|
|
||||||
*
|
|
||||||
* For more information see: http://getgreenshot.org/
|
|
||||||
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 1 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using Greenshot.IniFile;
|
|
||||||
using GreenshotJiraPlugin.Web_References.JiraSoap;
|
|
||||||
using GreenshotPlugin.Controls;
|
|
||||||
using GreenshotPlugin.Core;
|
|
||||||
|
|
||||||
namespace GreenshotJiraPlugin {
|
|
||||||
#region transport classes
|
|
||||||
public class JiraFilter {
|
|
||||||
public JiraFilter(string name, string id) {
|
|
||||||
Name = name;
|
|
||||||
Id = id;
|
|
||||||
}
|
|
||||||
public string Name {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
public string Id {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class JiraIssue {
|
|
||||||
public JiraIssue(string key, DateTime? created, string reporter, string assignee, string project, string summary, string description, string environment, string [] attachmentNames) {
|
|
||||||
Key = key;
|
|
||||||
Created = created;
|
|
||||||
Reporter = reporter;
|
|
||||||
Assignee = assignee;
|
|
||||||
Project = project;
|
|
||||||
Summary = summary;
|
|
||||||
Description = description;
|
|
||||||
Environment = environment;
|
|
||||||
AttachmentNames = attachmentNames;
|
|
||||||
}
|
|
||||||
public string Key {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
public DateTime? Created {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string Reporter {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string Assignee {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string Project {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string Summary {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string Description {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string Environment {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
public string[] AttachmentNames {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public class JiraConnector : IDisposable {
|
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraConnector));
|
|
||||||
private const string AuthFailedExceptionName = "com.atlassian.jira.rpc.exception.RemoteAuthenticationException";
|
|
||||||
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
|
||||||
public const string DefaultPostfix = "/rpc/soap/jirasoapservice-v2?wsdl";
|
|
||||||
private string _credentials;
|
|
||||||
private DateTime _loggedInTime = DateTime.Now;
|
|
||||||
private bool _loggedIn;
|
|
||||||
private JiraSoapServiceService _jira;
|
|
||||||
private readonly int _timeout;
|
|
||||||
private string _url;
|
|
||||||
private readonly Cache<string, JiraIssue> _jiraCache = new Cache<string, JiraIssue>(60 * Config.Timeout);
|
|
||||||
private readonly Cache<string, RemoteUser> _userCache = new Cache<string, RemoteUser>(60 * Config.Timeout);
|
|
||||||
private readonly bool _suppressBackgroundForm;
|
|
||||||
|
|
||||||
public void Dispose() {
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
|
||||||
if (_jira != null) {
|
|
||||||
Logout();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disposing) {
|
|
||||||
if (_jira != null) {
|
|
||||||
_jira.Dispose();
|
|
||||||
_jira = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JiraConnector() : this(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public JiraConnector(bool suppressBackgroundForm) {
|
|
||||||
_url = Config.Url;
|
|
||||||
_timeout = Config.Timeout;
|
|
||||||
_suppressBackgroundForm = suppressBackgroundForm;
|
|
||||||
CreateService();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateService() {
|
|
||||||
if (!_suppressBackgroundForm) {
|
|
||||||
new PleaseWaitForm().ShowAndWait(JiraPlugin.Instance.JiraPluginAttributes.Name, Language.GetString("jira", LangKey.communication_wait),
|
|
||||||
delegate {
|
|
||||||
_jira = new JiraSoapServiceService();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_jira = new JiraSoapServiceService();
|
|
||||||
}
|
|
||||||
_jira.Url = _url;
|
|
||||||
_jira.Proxy = NetworkHelper.CreateProxy(new Uri(_url));
|
|
||||||
// Do not use:
|
|
||||||
//jira.AllowAutoRedirect = true;
|
|
||||||
_jira.UserAgent = "Greenshot";
|
|
||||||
}
|
|
||||||
|
|
||||||
~JiraConnector() {
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Internal login which catches the exceptions
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>true if login was done sucessfully</returns>
|
|
||||||
private bool DoLogin(string user, string password, bool suppressBackgroundForm) {
|
|
||||||
|
|
||||||
// This is what needs to be done
|
|
||||||
ThreadStart jiraLogin = delegate {
|
|
||||||
Log.DebugFormat("Loggin in");
|
|
||||||
try {
|
|
||||||
_credentials = _jira.login(user, password);
|
|
||||||
} catch (Exception) {
|
|
||||||
if (!_url.EndsWith("wsdl")) {
|
|
||||||
_url = _url + "/rpc/soap/jirasoapservice-v2?wsdl";
|
|
||||||
// recreate the service with the new url
|
|
||||||
CreateService();
|
|
||||||
_credentials = _jira.login(user, password);
|
|
||||||
// Worked, store the url in the configuration
|
|
||||||
Config.Url = _url;
|
|
||||||
IniConfig.Save();
|
|
||||||
} else {
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.DebugFormat("Logged in");
|
|
||||||
_loggedInTime = DateTime.Now;
|
|
||||||
_loggedIn = true;
|
|
||||||
|
|
||||||
};
|
|
||||||
// Here we do it
|
|
||||||
try {
|
|
||||||
if (!suppressBackgroundForm) {
|
|
||||||
new PleaseWaitForm().ShowAndWait(JiraPlugin.Instance.JiraPluginAttributes.Name, Language.GetString("jira", LangKey.communication_wait), jiraLogin);
|
|
||||||
} else {
|
|
||||||
jiraLogin.Invoke();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// check if auth failed
|
|
||||||
if (e.Message.Contains(AuthFailedExceptionName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Not an authentication issue
|
|
||||||
_loggedIn = false;
|
|
||||||
_credentials = null;
|
|
||||||
e.Data.Add("user", user);
|
|
||||||
e.Data.Add("url", _url);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Login() {
|
|
||||||
Login(false);
|
|
||||||
}
|
|
||||||
public void Login(bool suppressBackgroundForm) {
|
|
||||||
Logout();
|
|
||||||
try {
|
|
||||||
// Get the system name, so the user knows where to login to
|
|
||||||
string systemName = _url.Replace(DefaultPostfix,"");
|
|
||||||
CredentialsDialog dialog = new CredentialsDialog(systemName)
|
|
||||||
{
|
|
||||||
Name = null
|
|
||||||
};
|
|
||||||
while (dialog.Show(dialog.Name) == DialogResult.OK) {
|
|
||||||
if (DoLogin(dialog.Name, dialog.Password, suppressBackgroundForm)) {
|
|
||||||
if (dialog.SaveChecked) {
|
|
||||||
dialog.Confirm(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
dialog.Confirm(false);
|
|
||||||
} catch (ApplicationException e) {
|
|
||||||
// exception handling ...
|
|
||||||
Log.Error("Problem using the credentials dialog", e);
|
|
||||||
}
|
|
||||||
// For every windows version after XP show an incorrect password baloon
|
|
||||||
dialog.IncorrectPassword = true;
|
|
||||||
// Make sure the dialog is display, the password was false!
|
|
||||||
dialog.AlwaysDisplay = true;
|
|
||||||
}
|
|
||||||
} catch (ApplicationException e) {
|
|
||||||
// exception handling ...
|
|
||||||
Log.Error("Problem using the credentials dialog", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Logout() {
|
|
||||||
if (_credentials != null) {
|
|
||||||
_jira.logout(_credentials);
|
|
||||||
_credentials = null;
|
|
||||||
_loggedIn = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckCredentials() {
|
|
||||||
if (_loggedIn) {
|
|
||||||
if (_loggedInTime.AddMinutes(_timeout-1).CompareTo(DateTime.Now) < 0) {
|
|
||||||
Logout();
|
|
||||||
Login();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Login();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsLoggedIn {
|
|
||||||
get {
|
|
||||||
return _loggedIn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JiraFilter[] GetFilters() {
|
|
||||||
List<JiraFilter> filters = new List<JiraFilter>();
|
|
||||||
CheckCredentials();
|
|
||||||
RemoteFilter[] remoteFilters = _jira.getSavedFilters(_credentials);
|
|
||||||
foreach (RemoteFilter remoteFilter in remoteFilters) {
|
|
||||||
filters.Add(new JiraFilter(remoteFilter.name, remoteFilter.id));
|
|
||||||
}
|
|
||||||
return filters.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
private JiraIssue CreateDummyErrorIssue(Exception e) {
|
|
||||||
// Creating bogus jira to indicate a problem
|
|
||||||
return new JiraIssue("error", DateTime.Now, "error", "error", "error", e.Message, "error", "error", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JiraIssue GetIssue(string key) {
|
|
||||||
JiraIssue jiraIssue = null;
|
|
||||||
if (_jiraCache.Contains(key)) {
|
|
||||||
jiraIssue = _jiraCache[key];
|
|
||||||
}
|
|
||||||
if (jiraIssue == null) {
|
|
||||||
CheckCredentials();
|
|
||||||
try {
|
|
||||||
RemoteIssue issue = _jira.getIssue(_credentials, key);
|
|
||||||
jiraIssue = new JiraIssue(issue.key, issue.created, GetUserFullName(issue.reporter), GetUserFullName(issue.assignee), issue.project, issue.summary, issue.description, issue.environment, issue.attachmentNames);
|
|
||||||
_jiraCache.Add(key, jiraIssue);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.Error("Problem retrieving Jira: " + key, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return jiraIssue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JiraIssue[] GetIssuesForFilter(string filterId) {
|
|
||||||
List<JiraIssue> issuesToReturn = new List<JiraIssue>();
|
|
||||||
CheckCredentials();
|
|
||||||
try {
|
|
||||||
RemoteIssue[] issues = _jira.getIssuesFromFilter(_credentials, filterId);
|
|
||||||
|
|
||||||
#region Username cache update
|
|
||||||
List<string> users = new List<string>();
|
|
||||||
foreach (RemoteIssue issue in issues) {
|
|
||||||
if (issue.reporter != null && !HasUser(issue.reporter) && !users.Contains(issue.reporter)) {
|
|
||||||
users.Add(issue.reporter);
|
|
||||||
}
|
|
||||||
if (issue.assignee != null && !HasUser(issue.assignee) && !users.Contains(issue.assignee)) {
|
|
||||||
users.Add(issue.assignee);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int taskCount = users.Count;
|
|
||||||
if (taskCount > 0) {
|
|
||||||
ManualResetEvent doneEvent = new ManualResetEvent(false);
|
|
||||||
for (int i = 0; i < users.Count; i++) {
|
|
||||||
ThreadPool.QueueUserWorkItem(delegate(object name) {
|
|
||||||
Log.InfoFormat("Retrieving {0}", name);
|
|
||||||
GetUserFullName((string)name);
|
|
||||||
if (Interlocked.Decrement(ref taskCount) == 0) {
|
|
||||||
doneEvent.Set();
|
|
||||||
}
|
|
||||||
}, users[i]);
|
|
||||||
}
|
|
||||||
doneEvent.WaitOne();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
foreach (RemoteIssue issue in issues) {
|
|
||||||
try {
|
|
||||||
JiraIssue jiraIssue = new JiraIssue(issue.key, issue.created, GetUserFullName(issue.reporter), GetUserFullName(issue.assignee), issue.project, issue.summary, issue.description, "", issue.attachmentNames);
|
|
||||||
issuesToReturn.Add(jiraIssue);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.Error("Problem retrieving Jira: " + issue.key, e);
|
|
||||||
JiraIssue jiraIssue = CreateDummyErrorIssue(e);
|
|
||||||
jiraIssue.Key = issue.key;
|
|
||||||
issuesToReturn.Add(jiraIssue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.Error("Problem retrieving Jiras for Filter: " + filterId, e);
|
|
||||||
issuesToReturn.Add(CreateDummyErrorIssue(e));
|
|
||||||
}
|
|
||||||
return issuesToReturn.ToArray(); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetUrl(string issueKey) {
|
|
||||||
return _url.Replace(DefaultPostfix,"") + "/browse/" + issueKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddAttachment(string issueKey, string filename, IBinaryContainer attachment) {
|
|
||||||
CheckCredentials();
|
|
||||||
try {
|
|
||||||
_jira.addBase64EncodedAttachmentsToIssue(_credentials, issueKey, new[] { filename }, new[] { attachment.ToBase64String(Base64FormattingOptions.InsertLineBreaks) });
|
|
||||||
} catch (Exception ex1) {
|
|
||||||
Log.WarnFormat("Failed to upload by using method addBase64EncodedAttachmentsToIssue, error was {0}", ex1.Message);
|
|
||||||
try {
|
|
||||||
Log.Warn("Trying addAttachmentsToIssue instead");
|
|
||||||
_jira.addAttachmentsToIssue(_credentials, issueKey, new[] { filename }, (sbyte[])(Array)attachment.ToByteArray());
|
|
||||||
} catch (Exception ex2) {
|
|
||||||
Log.WarnFormat("Failed to use alternative method, error was: {0}", ex2.Message);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddComment(string issueKey, string commentString) {
|
|
||||||
RemoteComment comment = new RemoteComment
|
|
||||||
{
|
|
||||||
body = commentString
|
|
||||||
};
|
|
||||||
CheckCredentials();
|
|
||||||
_jira.addComment(_credentials, issueKey, comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasUser(string user) {
|
|
||||||
if (user != null) {
|
|
||||||
return _userCache.Contains(user);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetUserFullName(string user) {
|
|
||||||
string fullname;
|
|
||||||
if (user != null) {
|
|
||||||
if (_userCache.Contains(user)) {
|
|
||||||
fullname = _userCache[user].fullname;
|
|
||||||
} else {
|
|
||||||
CheckCredentials();
|
|
||||||
RemoteUser remoteUser = _jira.getUser(_credentials, user);
|
|
||||||
_userCache.Add(user, remoteUser);
|
|
||||||
fullname = remoteUser.fullname;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fullname = "Not assigned";
|
|
||||||
}
|
|
||||||
return fullname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,10 +29,11 @@ namespace GreenshotJiraPlugin {
|
||||||
[IniSection("Jira", Description="Greenshot Jira Plugin configuration")]
|
[IniSection("Jira", Description="Greenshot Jira Plugin configuration")]
|
||||||
public class JiraConfiguration : IniSection {
|
public class JiraConfiguration : IniSection {
|
||||||
public const string DefaultPrefix = "http://";
|
public const string DefaultPrefix = "http://";
|
||||||
private const string DefaultUrl = DefaultPrefix + "jira" + JiraConnector.DefaultPostfix;
|
private const string DefaultUrl = DefaultPrefix + "jira";
|
||||||
|
|
||||||
[IniProperty("Url", Description="Url to Jira system, including wsdl.", 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("Timeout", Description="Session timeout in minutes", DefaultValue="30")]
|
||||||
public int Timeout { get; set; }
|
public int Timeout { get; set; }
|
||||||
|
|
||||||
|
|
181
GreenshotJiraPlugin/JiraConnector.cs
Normal file
181
GreenshotJiraPlugin/JiraConnector.cs
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Greenshot - a free and open source screenshot tool
|
||||||
|
* Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
*
|
||||||
|
* For more information see: http://getgreenshot.org/
|
||||||
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Dapplo.Jira;
|
||||||
|
using Dapplo.Jira.Entities;
|
||||||
|
using Greenshot.IniFile;
|
||||||
|
using GreenshotPlugin.Core;
|
||||||
|
|
||||||
|
namespace GreenshotJiraPlugin {
|
||||||
|
public class JiraConnector : IDisposable {
|
||||||
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraConnector));
|
||||||
|
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
|
public const string DefaultPostfix = "/rpc/soap/jirasoapservice-v2?wsdl";
|
||||||
|
private DateTime _loggedInTime = DateTime.Now;
|
||||||
|
private bool _loggedIn;
|
||||||
|
private readonly int _timeout;
|
||||||
|
private string _url;
|
||||||
|
private JiraApi _jiraApi;
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Dispose(bool disposing) {
|
||||||
|
if (_jiraApi != null)
|
||||||
|
{
|
||||||
|
Task.Run(async () => await Logout()).Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JiraConnector() {
|
||||||
|
_url = Config.Url.Replace(DefaultPostfix, "");
|
||||||
|
_timeout = Config.Timeout;
|
||||||
|
_jiraApi = new JiraApi(new Uri(_url));
|
||||||
|
}
|
||||||
|
|
||||||
|
~JiraConnector() {
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal login which catches the exceptions
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if login was done sucessfully</returns>
|
||||||
|
private async Task<bool> DoLogin(string user, string password)
|
||||||
|
{
|
||||||
|
if (_url.EndsWith("wsdl"))
|
||||||
|
{
|
||||||
|
_url = _url.Replace(DefaultPostfix, "");
|
||||||
|
// recreate the service with the new url
|
||||||
|
_jiraApi = new JiraApi(new Uri(_url));
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginInfo loginInfo;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
loginInfo = await _jiraApi.StartSessionAsync(user, password);
|
||||||
|
// Worked, store the url in the configuration
|
||||||
|
Config.Url = _url;
|
||||||
|
IniConfig.Save();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return loginInfo != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Login() {
|
||||||
|
await Logout();
|
||||||
|
try {
|
||||||
|
// Get the system name, so the user knows where to login to
|
||||||
|
string systemName = _url.Replace(DefaultPostfix,"");
|
||||||
|
var credentialsDialog = new CredentialsDialog(systemName)
|
||||||
|
{
|
||||||
|
Name = null
|
||||||
|
};
|
||||||
|
while (credentialsDialog.Show(credentialsDialog.Name) == DialogResult.OK) {
|
||||||
|
if (await DoLogin(credentialsDialog.Name, credentialsDialog.Password)) {
|
||||||
|
if (credentialsDialog.SaveChecked) {
|
||||||
|
credentialsDialog.Confirm(true);
|
||||||
|
}
|
||||||
|
_loggedIn = true;
|
||||||
|
_loggedInTime = DateTime.Now;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
credentialsDialog.Confirm(false);
|
||||||
|
} catch (ApplicationException e) {
|
||||||
|
// exception handling ...
|
||||||
|
Log.Error("Problem using the credentials dialog", e);
|
||||||
|
}
|
||||||
|
// For every windows version after XP show an incorrect password baloon
|
||||||
|
credentialsDialog.IncorrectPassword = true;
|
||||||
|
// Make sure the dialog is display, the password was false!
|
||||||
|
credentialsDialog.AlwaysDisplay = true;
|
||||||
|
}
|
||||||
|
} catch (ApplicationException e) {
|
||||||
|
// exception handling ...
|
||||||
|
Log.Error("Problem using the credentials dialog", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Logout() {
|
||||||
|
if (_jiraApi != null)
|
||||||
|
{
|
||||||
|
await _jiraApi.EndSessionAsync();
|
||||||
|
_loggedIn = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CheckCredentials() {
|
||||||
|
if (_loggedIn) {
|
||||||
|
if (_loggedInTime.AddMinutes(_timeout-1).CompareTo(DateTime.Now) < 0) {
|
||||||
|
await Logout();
|
||||||
|
await Login();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await Login();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IList<Filter>> GetFavoriteFiltersAsync()
|
||||||
|
{
|
||||||
|
await CheckCredentials();
|
||||||
|
return await _jiraApi.GetFavoriteFiltersAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Issue> GetIssueAsync(string issueKey)
|
||||||
|
{
|
||||||
|
await CheckCredentials();
|
||||||
|
return await _jiraApi.GetIssueAsync(issueKey);
|
||||||
|
}
|
||||||
|
public async Task<Attachment> AttachAsync<TContent>(string issueKey, TContent content, string filename, string contentType = null, CancellationToken cancellationToken = default(CancellationToken)) where TContent : class
|
||||||
|
{
|
||||||
|
await CheckCredentials();
|
||||||
|
return await _jiraApi.AttachAsync(issueKey, content, filename, contentType, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddCommentAsync(string issueKey, string body, string visibility = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
await CheckCredentials();
|
||||||
|
await _jiraApi.AddCommentAsync(issueKey, body, visibility, cancellationToken);
|
||||||
|
}
|
||||||
|
public async Task<SearchResult> SearchAsync(string jql, int maxResults = 20, IList<string> fields = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
await CheckCredentials();
|
||||||
|
return await _jiraApi.SearchAsync(jql, maxResults, fields, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri JiraBaseUri => _jiraApi.JiraBaseUri;
|
||||||
|
|
||||||
|
public bool IsLoggedIn => _loggedIn;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,8 @@ using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Dapplo.HttpExtensions;
|
||||||
|
using Dapplo.Jira.Entities;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using Greenshot.Plugin;
|
using Greenshot.Plugin;
|
||||||
using GreenshotJiraPlugin.Forms;
|
using GreenshotJiraPlugin.Forms;
|
||||||
|
@ -39,13 +41,13 @@ namespace GreenshotJiraPlugin {
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination));
|
||||||
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
private readonly JiraPlugin _jiraPlugin;
|
private readonly JiraPlugin _jiraPlugin;
|
||||||
private readonly JiraIssue _jira;
|
private readonly Issue _jira;
|
||||||
|
|
||||||
public JiraDestination(JiraPlugin jiraPlugin) {
|
public JiraDestination(JiraPlugin jiraPlugin) {
|
||||||
_jiraPlugin = jiraPlugin;
|
_jiraPlugin = jiraPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JiraDestination(JiraPlugin jiraPlugin, JiraIssue jira) {
|
public JiraDestination(JiraPlugin jiraPlugin, Issue jira) {
|
||||||
_jiraPlugin = jiraPlugin;
|
_jiraPlugin = jiraPlugin;
|
||||||
_jira = jira;
|
_jira = jira;
|
||||||
}
|
}
|
||||||
|
@ -56,8 +58,8 @@ namespace GreenshotJiraPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FormatUpload(JiraIssue jira) {
|
private string FormatUpload(Issue jira) {
|
||||||
return Designation + " - " + jira.Key + ": " + jira.Summary.Substring(0, Math.Min(20, jira.Summary.Length));
|
return Designation + " - " + jira.Key + ": " + jira.Fields.Summary.Substring(0, Math.Min(20, jira.Fields.Summary.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Description {
|
public override string Description {
|
||||||
|
@ -92,7 +94,7 @@ namespace GreenshotJiraPlugin {
|
||||||
if (JiraPlugin.Instance.CurrentJiraConnector == null || !JiraPlugin.Instance.CurrentJiraConnector.IsLoggedIn) {
|
if (JiraPlugin.Instance.CurrentJiraConnector == null || !JiraPlugin.Instance.CurrentJiraConnector.IsLoggedIn) {
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
List<JiraIssue> issues = JiraUtils.GetCurrentJiras();
|
var issues = JiraUtils.GetCurrentJirasAsync().Result;
|
||||||
if (issues != null) {
|
if (issues != null) {
|
||||||
foreach(var jiraIssue in issues) {
|
foreach(var jiraIssue in issues) {
|
||||||
yield return new JiraDestination(_jiraPlugin, jiraIssue);
|
yield return new JiraDestination(_jiraPlugin, jiraIssue);
|
||||||
|
@ -108,40 +110,46 @@ namespace GreenshotJiraPlugin {
|
||||||
try {
|
try {
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
||||||
delegate {
|
async () =>
|
||||||
_jiraPlugin.JiraConnector.AddAttachment(_jira.Key, filename, new SurfaceContainer(surfaceToUpload, outputSettings, filename));
|
{
|
||||||
|
var surfaceContainer = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
surfaceContainer.WriteToStream(memoryStream);
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
await _jiraPlugin.JiraConnector.AttachAsync(_jira.Key, memoryStream, filename, surfaceContainer.ContentType);
|
||||||
|
}
|
||||||
|
surfaceToUpload.UploadURL = _jiraPlugin.JiraConnector.JiraBaseUri.AppendSegments("browse", _jira.Key).AbsoluteUri;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
Log.Debug("Uploaded to Jira.");
|
Log.DebugFormat("Uploaded to Jira {0}", _jira.Key);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
// TODO: This can't work:
|
|
||||||
exportInformation.Uri = surfaceToUpload.UploadURL;
|
exportInformation.Uri = surfaceToUpload.UploadURL;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
JiraForm jiraForm = new JiraForm(_jiraPlugin.JiraConnector);
|
var jiraForm = new JiraForm(_jiraPlugin.JiraConnector);
|
||||||
if (_jiraPlugin.JiraConnector.IsLoggedIn) {
|
|
||||||
jiraForm.SetFilename(filename);
|
jiraForm.SetFilename(filename);
|
||||||
DialogResult result = jiraForm.ShowDialog();
|
var dialogResult = jiraForm.ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (dialogResult == DialogResult.OK) {
|
||||||
try {
|
try {
|
||||||
|
surfaceToUpload.UploadURL = _jiraPlugin.JiraConnector.JiraBaseUri.AppendSegments("browse", jiraForm.GetJiraIssue().Key).AbsoluteUri;
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
||||||
delegate {
|
async () =>
|
||||||
jiraForm.Upload(new SurfaceContainer(surfaceToUpload, outputSettings, filename));
|
{
|
||||||
|
await jiraForm.UploadAsync(new SurfaceContainer(surfaceToUpload, outputSettings, filename));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
Log.Debug("Uploaded to Jira.");
|
Log.DebugFormat("Uploaded to Jira {0}", jiraForm.GetJiraIssue().Key);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
// TODO: This can't work:
|
|
||||||
exportInformation.Uri = surfaceToUpload.UploadURL;
|
exportInformation.Uri = surfaceToUpload.UploadURL;
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ProcessExport(exportInformation, surfaceToUpload);
|
ProcessExport(exportInformation, surfaceToUpload);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
* 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using Greenshot.Plugin;
|
using Greenshot.Plugin;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using GreenshotJiraPlugin.Forms;
|
using GreenshotJiraPlugin.Forms;
|
||||||
|
|
||||||
namespace GreenshotJiraPlugin {
|
namespace GreenshotJiraPlugin {
|
||||||
|
@ -42,7 +42,7 @@ namespace GreenshotJiraPlugin {
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing) {
|
protected void Dispose(bool disposing) {
|
||||||
if (disposing) {
|
if (disposing) {
|
||||||
if (_jiraConnector != null) {
|
if (_jiraConnector != null) {
|
||||||
_jiraConnector.Dispose();
|
_jiraConnector.Dispose();
|
||||||
|
@ -85,7 +85,7 @@ namespace GreenshotJiraPlugin {
|
||||||
public JiraConnector JiraConnector {
|
public JiraConnector JiraConnector {
|
||||||
get {
|
get {
|
||||||
if (_jiraConnector == null) {
|
if (_jiraConnector == null) {
|
||||||
_jiraConnector = new JiraConnector(true);
|
_jiraConnector = new JiraConnector();
|
||||||
}
|
}
|
||||||
return _jiraConnector;
|
return _jiraConnector;
|
||||||
}
|
}
|
||||||
|
@ -97,33 +97,36 @@ namespace GreenshotJiraPlugin {
|
||||||
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
|
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
|
||||||
/// <param name="myAttributes">My own attributes</param>
|
/// <param name="myAttributes">My own attributes</param>
|
||||||
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
||||||
public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
|
public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) {
|
||||||
_jiraPluginAttributes = myAttributes;
|
_jiraPluginAttributes = myAttributes;
|
||||||
|
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<JiraConfiguration>();
|
_config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
new ComponentResourceManager(typeof(JiraPlugin));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Shutdown() {
|
public void Shutdown() {
|
||||||
Log.Debug("Jira Plugin shutdown.");
|
Log.Debug("Jira Plugin shutdown.");
|
||||||
if (_jiraConnector != null) {
|
if (_jiraConnector != null)
|
||||||
_jiraConnector.Logout();
|
{
|
||||||
|
Task.Run(async () => await _jiraConnector.Logout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Configure() {
|
public void Configure() {
|
||||||
string url = _config.Url;
|
string url = _config.Url;
|
||||||
if (ShowConfigDialog()) {
|
if (ShowConfigDialog()) {
|
||||||
// check for re-login
|
// check for re-login
|
||||||
if (_jiraConnector != null && _jiraConnector.IsLoggedIn && !string.IsNullOrEmpty(url)) {
|
if (_jiraConnector != null && _jiraConnector.IsLoggedIn && !string.IsNullOrEmpty(url)) {
|
||||||
if (!url.Equals(_config.Url)) {
|
if (!url.Equals(_config.Url)) {
|
||||||
_jiraConnector.Logout();
|
Task.Run(async () =>
|
||||||
_jiraConnector.Login();
|
{
|
||||||
|
await _jiraConnector.Logout();
|
||||||
|
await _jiraConnector.Login();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,15 +146,5 @@ namespace GreenshotJiraPlugin {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This will be called when Greenshot is shutting down
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender"></param>
|
|
||||||
/// <param name="e"></param>
|
|
||||||
public void Closing(object sender, FormClosingEventArgs e) {
|
|
||||||
Log.Debug("Application closing, calling logout of jira!");
|
|
||||||
Shutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,12 @@
|
||||||
* 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Dapplo.Jira.Entities;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
|
||||||
|
@ -30,15 +34,16 @@ namespace GreenshotJiraPlugin {
|
||||||
public static class JiraUtils {
|
public static class JiraUtils {
|
||||||
private static readonly Regex JiraKeyRegex = new Regex(@"/browse/([A-Z0-9]+\-[0-9]+)");
|
private static readonly Regex JiraKeyRegex = new Regex(@"/browse/([A-Z0-9]+\-[0-9]+)");
|
||||||
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraUtils));
|
||||||
|
|
||||||
public static List<JiraIssue> GetCurrentJiras() {
|
public static async Task<IList<Issue>> GetCurrentJirasAsync() {
|
||||||
// Make sure we suppress the login
|
// Make sure we suppress the login
|
||||||
List<string> jirakeys = new List<string>();
|
var jirakeys = new List<string>();
|
||||||
foreach(string url in IEHelper.GetIEUrls()) {
|
foreach(string url in IEHelper.GetIEUrls()) {
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MatchCollection jiraKeyMatch = JiraKeyRegex.Matches(url);
|
var jiraKeyMatch = JiraKeyRegex.Matches(url);
|
||||||
if (jiraKeyMatch.Count > 0) {
|
if (jiraKeyMatch.Count > 0) {
|
||||||
string jiraKey = jiraKeyMatch[0].Groups[1].Value;
|
string jiraKey = jiraKeyMatch[0].Groups[1].Value;
|
||||||
jirakeys.Add(jiraKey);
|
jirakeys.Add(jiraKey);
|
||||||
|
@ -48,19 +53,19 @@ namespace GreenshotJiraPlugin {
|
||||||
jirakeys.Add(Config.LastUsedJira);
|
jirakeys.Add(Config.LastUsedJira);
|
||||||
}
|
}
|
||||||
if (jirakeys.Count > 0) {
|
if (jirakeys.Count > 0) {
|
||||||
List<JiraIssue> jiraIssues = new List<JiraIssue>();
|
var jiraIssues = new List<Issue>();
|
||||||
foreach(string jiraKey in jirakeys) {
|
foreach(string jiraKey in jirakeys) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
JiraIssue issue = JiraPlugin.Instance.JiraConnector.GetIssue(jiraKey);
|
var issue = await JiraPlugin.Instance.JiraConnector.GetIssueAsync(jiraKey);
|
||||||
if (issue != null)
|
if (issue != null)
|
||||||
{
|
{
|
||||||
jiraIssues.Add(issue);
|
jiraIssues.Add(issue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Log.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jiraIssues.Count > 0) {
|
if (jiraIssues.Count > 0) {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
7
GreenshotJiraPlugin/packages.config
Normal file
7
GreenshotJiraPlugin/packages.config
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Dapplo.HttpExtensions" version="0.5.30" targetFramework="net45" />
|
||||||
|
<package id="Dapplo.Jira" version="0.1.56" targetFramework="net45" />
|
||||||
|
<package id="Dapplo.Log.Facade" version="0.5.4" targetFramework="net45" />
|
||||||
|
<package id="Dapplo.Utils" version="0.1.113" targetFramework="net45" />
|
||||||
|
</packages>
|
|
@ -30,8 +30,8 @@ namespace GreenshotPlugin.Controls {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class PleaseWaitForm : Form {
|
public partial class PleaseWaitForm : Form {
|
||||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(PleaseWaitForm));
|
private static readonly ILog LOG = LogManager.GetLogger(typeof(PleaseWaitForm));
|
||||||
private Thread waitFor;
|
private Thread _waitFor;
|
||||||
private string title;
|
private string _title;
|
||||||
public PleaseWaitForm() {
|
public PleaseWaitForm() {
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
|
@ -60,7 +60,7 @@ namespace GreenshotPlugin.Controls {
|
||||||
/// <param name="text">The text in the form</param>
|
/// <param name="text">The text in the form</param>
|
||||||
/// <param name="waitDelegate">delegate { with your code }</param>
|
/// <param name="waitDelegate">delegate { with your code }</param>
|
||||||
public void ShowAndWait(string title, string text, ThreadStart waitDelegate) {
|
public void ShowAndWait(string title, string text, ThreadStart waitDelegate) {
|
||||||
this.title = title;
|
_title = title;
|
||||||
Text = title;
|
Text = title;
|
||||||
label_pleasewait.Text = text;
|
label_pleasewait.Text = text;
|
||||||
cancelButton.Text = Language.GetString("CANCEL");
|
cancelButton.Text = Language.GetString("CANCEL");
|
||||||
|
@ -72,23 +72,29 @@ namespace GreenshotPlugin.Controls {
|
||||||
Exception threadException = null;
|
Exception threadException = null;
|
||||||
try {
|
try {
|
||||||
// Wrap the passed delegate in a try/catch which makes it possible to save the exception
|
// Wrap the passed delegate in a try/catch which makes it possible to save the exception
|
||||||
waitFor = new Thread(new ThreadStart(
|
_waitFor = new Thread(new ThreadStart(
|
||||||
delegate {
|
delegate
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
waitDelegate.Invoke();
|
waitDelegate.Invoke();
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.Error("invoke error:", ex);
|
LOG.Error("invoke error:", ex);
|
||||||
threadException = ex;
|
threadException = ex;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
waitFor.Name = title;
|
{
|
||||||
waitFor.IsBackground = true;
|
Name = title,
|
||||||
waitFor.SetApartmentState(ApartmentState.STA);
|
IsBackground = true
|
||||||
waitFor.Start();
|
};
|
||||||
|
_waitFor.SetApartmentState(ApartmentState.STA);
|
||||||
|
_waitFor.Start();
|
||||||
|
|
||||||
// Wait until finished
|
// Wait until finished
|
||||||
while (!waitFor.Join(TimeSpan.FromMilliseconds(100))) {
|
while (!_waitFor.Join(TimeSpan.FromMilliseconds(100))) {
|
||||||
Application.DoEvents();
|
Application.DoEvents();
|
||||||
}
|
}
|
||||||
LOG.DebugFormat("Finished {0}", title);
|
LOG.DebugFormat("Finished {0}", title);
|
||||||
|
@ -110,9 +116,9 @@ namespace GreenshotPlugin.Controls {
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
void CancelButtonClick(object sender, EventArgs e) {
|
void CancelButtonClick(object sender, EventArgs e) {
|
||||||
LOG.DebugFormat("Cancel clicked on {0}", title);
|
LOG.DebugFormat("Cancel clicked on {0}", _title);
|
||||||
cancelButton.Enabled = false;
|
cancelButton.Enabled = false;
|
||||||
waitFor.Abort();
|
_waitFor.Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -555,6 +555,8 @@ namespace GreenshotPlugin.Core {
|
||||||
string ToBase64String(Base64FormattingOptions formattingOptions);
|
string ToBase64String(Base64FormattingOptions formattingOptions);
|
||||||
byte[] ToByteArray();
|
byte[] ToByteArray();
|
||||||
void Upload(HttpWebRequest webRequest);
|
void Upload(HttpWebRequest webRequest);
|
||||||
|
|
||||||
|
string ContentType { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -634,6 +636,8 @@ namespace GreenshotPlugin.Core {
|
||||||
WriteToStream(requestStream);
|
WriteToStream(requestStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ContentType => _contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -686,7 +690,7 @@ namespace GreenshotPlugin.Core {
|
||||||
boundary,
|
boundary,
|
||||||
name,
|
name,
|
||||||
_fileName ?? name,
|
_fileName ?? name,
|
||||||
"image/" + _outputSettings.Format);
|
ContentType);
|
||||||
|
|
||||||
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
||||||
ImageOutput.SaveToStream(_bitmap, null, formDataStream, _outputSettings);
|
ImageOutput.SaveToStream(_bitmap, null, formDataStream, _outputSettings);
|
||||||
|
@ -711,6 +715,8 @@ namespace GreenshotPlugin.Core {
|
||||||
WriteToStream(requestStream);
|
WriteToStream(requestStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ContentType => "image/" + _outputSettings.Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -763,7 +769,7 @@ namespace GreenshotPlugin.Core {
|
||||||
boundary,
|
boundary,
|
||||||
name,
|
name,
|
||||||
_fileName ?? name,
|
_fileName ?? name,
|
||||||
"image/" + _outputSettings.Format);
|
ContentType);
|
||||||
|
|
||||||
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
||||||
ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings);
|
ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings);
|
||||||
|
@ -783,10 +789,12 @@ namespace GreenshotPlugin.Core {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="webRequest"></param>
|
/// <param name="webRequest"></param>
|
||||||
public void Upload(HttpWebRequest webRequest) {
|
public void Upload(HttpWebRequest webRequest) {
|
||||||
webRequest.ContentType = "image/" + _outputSettings.Format.ToString();
|
webRequest.ContentType = ContentType;
|
||||||
using (var requestStream = webRequest.GetRequestStream()) {
|
using (var requestStream = webRequest.GetRequestStream()) {
|
||||||
WriteToStream(requestStream);
|
WriteToStream(requestStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ContentType => "image/" + _outputSettings.Format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue