mirror of
https://github.com/greenshot/greenshot
synced 2025-08-25 23:56:12 -07:00
Small fixes, mainly to make the TfsDestination work better.
This commit is contained in:
parent
f27fcb4ab2
commit
62811016ce
9 changed files with 94 additions and 31 deletions
|
@ -190,6 +190,7 @@
|
|||
<Compile Include="ViewModels\JiraViewModel.cs" />
|
||||
<Compile Include="ViewModels\JiraConfigViewModel.cs" />
|
||||
<None Include="app.config" />
|
||||
<EmbeddedResource Include="jira.svgz" />
|
||||
<None Include="Languages\language_jiraplugin-de-DE.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace Greenshot.Addon.Jira
|
|||
}
|
||||
}
|
||||
|
||||
IEnumerable<IDestination> DynamicDestinations()
|
||||
public override IEnumerable<IDestination> DynamicDestinations()
|
||||
{
|
||||
if (_jiraConnector == null || !_jiraConnector.IsLoggedIn)
|
||||
{
|
||||
|
|
BIN
src/Greenshot.Addon.Jira/jira.svgz
Normal file
BIN
src/Greenshot.Addon.Jira/jira.svgz
Normal file
Binary file not shown.
|
@ -34,5 +34,8 @@ namespace Greenshot.Addon.Tfs.Entities
|
|||
|
||||
[JsonProperty("System.WorkItemType")]
|
||||
public string WorkItemType { get; set; }
|
||||
|
||||
[JsonProperty("System.State")]
|
||||
public string State { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Dapplo.HttpExtensions;
|
||||
using Dapplo.HttpExtensions.ContentConverter;
|
||||
using Dapplo.HttpExtensions.Factory;
|
||||
using Dapplo.HttpExtensions.JsonNet;
|
||||
using Greenshot.Addon.Tfs.Entities;
|
||||
|
@ -59,11 +59,16 @@ namespace Greenshot.Addon.Tfs
|
|||
_coreConfiguration = coreConfiguration;
|
||||
_tfsConfiguration = tfsConfiguration;
|
||||
|
||||
#if DEBUG
|
||||
// Set json log threshold high
|
||||
DefaultJsonHttpContentConverter.Instance.Value.LogThreshold = 0;
|
||||
#endif
|
||||
_tfsHttpBehaviour = new HttpBehaviour
|
||||
{
|
||||
HttpSettings = networkConfiguration,
|
||||
JsonSerializer = new JsonNetJsonSerializer()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public bool CanUpdate => _tfsConfiguration.TfsUri != null && !string.IsNullOrEmpty(_tfsConfiguration.ApiKey);
|
||||
|
@ -75,7 +80,7 @@ namespace Greenshot.Addon.Tfs
|
|||
{
|
||||
return;
|
||||
}
|
||||
var workItems = await GetOwnWorkitems();
|
||||
var workItems = await GetOwnWorkitems().ConfigureAwait(false);
|
||||
foreach (var workItem in workItems.Items)
|
||||
{
|
||||
WorkItems[workItem.Id] = workItem;
|
||||
|
@ -95,14 +100,14 @@ namespace Greenshot.Addon.Tfs
|
|||
|
||||
var wiql = new JObject { { "query", "Select [System.Id] FROM WorkItems WHERE [System.AssignedTo] = @me" } };
|
||||
|
||||
var queryResult = await client.PostAsync<HttpResponse<WorkItemQueryResult, string>>(workitemsQueryUri, wiql);
|
||||
var queryResult = await client.PostAsync<HttpResponse<WorkItemQueryResult, string>>(workitemsQueryUri, wiql).ConfigureAwait(false);
|
||||
if (queryResult.HasError)
|
||||
{
|
||||
throw new Exception(queryResult.ErrorResponse);
|
||||
}
|
||||
|
||||
var workItemsUri = apiUri.AppendSegments("wit", "workItems").ExtendQuery("ids", string.Join(",",queryResult.Response.Items.Select(item => item.Id)));
|
||||
var result = await client.GetAsAsync<HttpResponse<WorkItemList, string>>(workItemsUri);
|
||||
var result = await client.GetAsAsync<HttpResponse<WorkItemList, string>>(workItemsUri).ConfigureAwait(false);
|
||||
if (result.HasError)
|
||||
{
|
||||
throw new Exception(result.ErrorResponse);
|
||||
|
@ -132,7 +137,7 @@ namespace Greenshot.Addon.Tfs
|
|||
using (var content = new StreamContent(imageStream))
|
||||
{
|
||||
content.SetContentType("application/octet-stream");
|
||||
var createAttachmentresult = await client.PostAsync<HttpResponse<CreateAttachmentResult, string>>(attachmentUri, content);
|
||||
var createAttachmentresult = await client.PostAsync<HttpResponse<CreateAttachmentResult, string>>(attachmentUri, content).ConfigureAwait(false);
|
||||
if (createAttachmentresult.HasError)
|
||||
{
|
||||
throw new Exception(createAttachmentresult.ErrorResponse);
|
||||
|
@ -176,7 +181,7 @@ namespace Greenshot.Addon.Tfs
|
|||
|
||||
var content = HttpContentFactory.Create(linkAttachmentRequest);
|
||||
content.SetContentType("application/json-patch+json");
|
||||
var result = await client.PatchAsync<HttpResponse<string, string>>(linkAttachmentUri, content);
|
||||
var result = await client.PatchAsync<HttpResponse<string, string>>(linkAttachmentUri, content).ConfigureAwait(false);
|
||||
if (result.HasError)
|
||||
{
|
||||
throw new Exception(result.ErrorResponse);
|
||||
|
|
|
@ -65,20 +65,36 @@ namespace Greenshot.Addon.Tfs
|
|||
_tfsConfiguration = tfsConfiguration;
|
||||
_tfsLanguage = tfsLanguage;
|
||||
_tfsClient = tfsClient;
|
||||
var ignoreTask = _tfsClient.UpdateWorkItems();
|
||||
}
|
||||
|
||||
public TfsDestination(
|
||||
ITfsConfiguration tfsConfiguration,
|
||||
ITfsLanguage tfsLanguage,
|
||||
TfsClient tfsClient, WorkItem workItem) : this(tfsConfiguration, tfsLanguage, tfsClient)
|
||||
TfsClient tfsClient, WorkItem workItem)
|
||||
{
|
||||
_tfsConfiguration = tfsConfiguration;
|
||||
_tfsLanguage = tfsLanguage;
|
||||
_tfsClient = tfsClient;
|
||||
_workItem = workItem;
|
||||
}
|
||||
|
||||
public override bool IsActive => base.IsActive && _tfsClient.CanUpdate;
|
||||
|
||||
public override bool UseDynamicsOnly => true;
|
||||
|
||||
public override bool IsDynamic => true;
|
||||
|
||||
protected override async Task PrepareDynamicDestinations(ToolStripMenuItem destinationToolStripMenuItem)
|
||||
{
|
||||
if (!destinationToolStripMenuItem.HasDropDownItems)
|
||||
{
|
||||
var oldColor = destinationToolStripMenuItem.BackColor;
|
||||
destinationToolStripMenuItem.BackColor = Color.DarkGray;
|
||||
await _tfsClient.UpdateWorkItems();
|
||||
destinationToolStripMenuItem.BackColor = oldColor;
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<IDestination> DynamicDestinations()
|
||||
{
|
||||
var workitems = _tfsClient.WorkItems.Values;
|
||||
|
@ -96,7 +112,6 @@ namespace Greenshot.Addon.Tfs
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public override string Description
|
||||
{
|
||||
get
|
||||
|
@ -106,7 +121,8 @@ namespace Greenshot.Addon.Tfs
|
|||
return _tfsLanguage.UploadMenuItem;
|
||||
}
|
||||
// Format the title of this destination
|
||||
return _workItem.Id + ": " + _workItem.Fields.Title.Substring(0, Math.Min(20, _workItem.Fields.Title.Length));
|
||||
// TODO: substring?
|
||||
return $"{_workItem.Fields.WorkItemType} {_workItem.Id}: {_workItem.Fields.Title}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,8 +139,7 @@ namespace Greenshot.Addon.Tfs
|
|||
}
|
||||
}
|
||||
|
||||
public override async Task<ExportInformation> ExportCaptureAsync(bool manuallyInitiated, ISurface surface,
|
||||
ICaptureDetails captureDetails)
|
||||
public override async Task<ExportInformation> ExportCaptureAsync(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
|
||||
{
|
||||
if (_workItem == null)
|
||||
{
|
||||
|
@ -157,7 +172,7 @@ namespace Greenshot.Addon.Tfs
|
|||
Uri response;
|
||||
|
||||
var cancellationTokenSource = new CancellationTokenSource();
|
||||
using (var pleaseWaitForm = new PleaseWaitForm("OneDrive plug-in", _tfsLanguage.CommunicationWait,
|
||||
using (var pleaseWaitForm = new PleaseWaitForm("TFS plug-in", _tfsLanguage.CommunicationWait,
|
||||
cancellationTokenSource))
|
||||
{
|
||||
pleaseWaitForm.Show();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Greenshot.Addon.Tfs.ViewModels"
|
||||
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:behaviours="http://metro.mahapps.com/winfx/xaml/shared"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance viewModels:TfsConfigViewModel,IsDesignTimeCreatable=False}"
|
||||
>
|
||||
|
@ -13,12 +15,12 @@
|
|||
<ContentControl x:Name="FileConfigPartViewModel"/>
|
||||
<CheckBox IsChecked="{Binding TfsConfiguration.AfterUploadLinkToClipBoard}" Content="{Binding TfsLanguage.UsePageLink}"/>
|
||||
<DockPanel LastChildFill="True">
|
||||
<Label Content="{Binding TfsLanguage.LabelUrl}" Width="100" />
|
||||
<TextBox Text="{Binding TfsConfiguration.TfsUri}" />
|
||||
<Label Content="{Binding TfsLanguage.LabelUrl}" Width="100"/>
|
||||
<TextBox Text="{Binding TfsConfiguration.TfsUri}" mah:TextBoxHelper.ClearTextButton="True" mah:TextBoxHelper.Watermark="TFS Url"/>
|
||||
</DockPanel>
|
||||
<DockPanel LastChildFill="True">
|
||||
<Label Content="{Binding TfsLanguage.LabelApiKey}" Width="100" />
|
||||
<TextBox Text="{Binding TfsConfiguration.ApiKey}" />
|
||||
<PasswordBox behaviours:PasswordBoxBindingBehavior.Password="{Binding TfsConfiguration.ApiKey}" mah:PasswordBoxHelper.RevealButtonContent="{Binding TfsConfiguration.ApiKey}" />
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
|
|
@ -27,6 +27,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
@ -64,12 +65,16 @@ namespace Greenshot.Addons.Core
|
|||
Designation = GetType().GetDesignation();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual string Designation { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract string Description { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Bitmap DisplayIcon { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual BitmapSource DisplayIconWpf => DisplayIcon?.ToBitmapSource() ?? GetDisplayIcon(DpiHandler.DefaultScreenDpi).ToBitmapSource();
|
||||
|
||||
public virtual Bitmap GetDisplayIcon(double dpi)
|
||||
|
@ -81,9 +86,33 @@ namespace Greenshot.Addons.Core
|
|||
|
||||
public virtual Keys EditorShortcutKeys => Keys.None;
|
||||
|
||||
/// <summary>
|
||||
/// Give a destination a preparation possibility before showing the toolstrip items
|
||||
/// </summary>
|
||||
/// <param name="destinationToolStripMenuItem">ToolStripMenuItem</param>
|
||||
/// <returns>Task</returns>
|
||||
protected virtual Task PrepareDynamicDestinations(ToolStripMenuItem destinationToolStripMenuItem)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Dynamic destinations
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable of IDestination</returns>
|
||||
public virtual IEnumerable<IDestination> DynamicDestinations()
|
||||
{
|
||||
yield break;
|
||||
return Enumerable.Empty<IDestination>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Give a destination the possibility to clean up after showing the toolstrip item
|
||||
/// </summary>
|
||||
/// <param name="destinationToolStripMenuItem">ToolStripMenuItem</param>
|
||||
/// <returns>Task</returns>
|
||||
protected virtual Task AfterDynamicDestinations(ToolStripMenuItem destinationToolStripMenuItem)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -91,12 +120,16 @@ namespace Greenshot.Addons.Core
|
|||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsDynamic => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool UseDynamicsOnly => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsLinkable => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsActive => true;
|
||||
|
||||
protected virtual ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
|
||||
|
@ -140,13 +173,16 @@ namespace Greenshot.Addons.Core
|
|||
|
||||
if (IsDynamic && addDynamics)
|
||||
{
|
||||
basisMenuItem.DropDownOpening += (sender, args) =>
|
||||
basisMenuItem.DropDownOpening += async (sender, args) =>
|
||||
{
|
||||
if (basisMenuItem.DropDownItems.Count != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Give the destination a chance to prepare for the destinations
|
||||
await PrepareDynamicDestinations(basisMenuItem).ConfigureAwait(true);
|
||||
|
||||
var subDestinations = new List<IDestination>();
|
||||
// Fixing Bug #3536968 by catching the COMException (every exception) and not displaying the "subDestinations"
|
||||
try
|
||||
|
@ -157,7 +193,7 @@ namespace Greenshot.Addons.Core
|
|||
{
|
||||
Log.Error().WriteLine("Skipping {0}, due to the following error: {1}", Description, ex.Message);
|
||||
}
|
||||
|
||||
await AfterDynamicDestinations(basisMenuItem).ConfigureAwait(true);
|
||||
if (subDestinations.Count <= 0)
|
||||
{
|
||||
return;
|
||||
|
@ -184,6 +220,7 @@ namespace Greenshot.Addons.Core
|
|||
AddTagEvents(destinationMenuItem, menu, subDestination.Description);
|
||||
basisMenuItem.DropDownItems.Add(destinationMenuItem);
|
||||
}
|
||||
basisMenuItem.ShowDropDown();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,28 +29,28 @@
|
|||
<ColumnDefinition Width="200" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0">
|
||||
<TextBox x:Name="Filter" />
|
||||
<TreeView x:Name="TreeItems"
|
||||
cal:Message.Attach="[Event SelectedItemChanged] = [Action ActivateChildView($this.SelectedItem)]">
|
||||
<Grid Grid.Column="0" Grid.Row="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox x:Name="Filter" Grid.Row="0" mah:TextBoxHelper.ClearTextButton="True" />
|
||||
<TreeView x:Name="TreeItems" Grid.Row="1" cal:Message.Attach="[Event SelectedItemChanged] = [Action ActivateChildView($this.SelectedItem)]">
|
||||
<TreeView.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
|
||||
<Setter Property="IsEnabled" Value="{Binding IsEnabled}" />
|
||||
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibility}}" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Converter={StaticResource AuthenticationTargetPropertyConverter}}"
|
||||
Value="{x:Static security:AuthenticationTargetProperties.Visibility}">
|
||||
<DataTrigger Binding="{Binding Converter={StaticResource AuthenticationTargetPropertyConverter}}" Value="{x:Static security:AuthenticationTargetProperties.Visibility}">
|
||||
<Setter Property="security:AuthenticationVisibility.Permissions" Value="{Binding Permissions}" />
|
||||
<Setter Property="security:AuthenticationVisibility.WhenPermissions" Value="{Binding WhenPermission}" />
|
||||
<Setter Property="security:AuthenticationVisibility.WhenPermissionsMissing"
|
||||
Value="{Binding WhenPermissionMissing}" />
|
||||
<Setter Property="security:AuthenticationVisibility.WhenPermissionsMissing" Value="{Binding WhenPermissionMissing}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Converter={StaticResource AuthenticationTargetPropertyConverter}}"
|
||||
Value="{x:Static security:AuthenticationTargetProperties.IsEnabled}">
|
||||
<Setter Property="security:AuthenticationEnabled.Permissions" Value="{Binding Permissions}" />
|
||||
<Setter Property="security:AuthenticationEnabled.WhenPermissions" Value="{Binding WhenPermission}" />
|
||||
<Setter Property="security:AuthenticationEnabled.WhenPermissionsMissing"
|
||||
Value="{Binding WhenPermissionMissing}" />
|
||||
<Setter Property="security:AuthenticationEnabled.WhenPermissionsMissing" Value="{Binding WhenPermissionMissing}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
@ -61,7 +61,7 @@
|
|||
</HierarchicalDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<ContentControl x:Name="ActiveItem" Grid.Column="1" Grid.Row="0"/>
|
||||
<UniformGrid Grid.Column="1" Grid.Row="1" Rows="1" Columns="2">
|
||||
<Button x:Name="Cancel" Content="{Binding GreenshotLanguage.Cancel}" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue