diff --git a/src/Greenshot.Addon.Jira/Greenshot.Addon.Jira.csproj b/src/Greenshot.Addon.Jira/Greenshot.Addon.Jira.csproj
index 3b49c76fa..6736783bb 100644
--- a/src/Greenshot.Addon.Jira/Greenshot.Addon.Jira.csproj
+++ b/src/Greenshot.Addon.Jira/Greenshot.Addon.Jira.csproj
@@ -190,6 +190,7 @@
+
Always
diff --git a/src/Greenshot.Addon.Jira/JiraDestination.cs b/src/Greenshot.Addon.Jira/JiraDestination.cs
index 07644d152..955783cba 100644
--- a/src/Greenshot.Addon.Jira/JiraDestination.cs
+++ b/src/Greenshot.Addon.Jira/JiraDestination.cs
@@ -126,7 +126,7 @@ namespace Greenshot.Addon.Jira
}
}
- IEnumerable DynamicDestinations()
+ public override IEnumerable DynamicDestinations()
{
if (_jiraConnector == null || !_jiraConnector.IsLoggedIn)
{
diff --git a/src/Greenshot.Addon.Jira/jira.svgz b/src/Greenshot.Addon.Jira/jira.svgz
new file mode 100644
index 000000000..4d817e9a4
Binary files /dev/null and b/src/Greenshot.Addon.Jira/jira.svgz differ
diff --git a/src/Greenshot.Addon.Tfs/Entities/WorkItemFields.cs b/src/Greenshot.Addon.Tfs/Entities/WorkItemFields.cs
index b4650ee70..74aedf0ce 100644
--- a/src/Greenshot.Addon.Tfs/Entities/WorkItemFields.cs
+++ b/src/Greenshot.Addon.Tfs/Entities/WorkItemFields.cs
@@ -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; }
}
}
diff --git a/src/Greenshot.Addon.Tfs/TfsClient.cs b/src/Greenshot.Addon.Tfs/TfsClient.cs
index ed3b7eb40..c9dd12112 100644
--- a/src/Greenshot.Addon.Tfs/TfsClient.cs
+++ b/src/Greenshot.Addon.Tfs/TfsClient.cs
@@ -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>(workitemsQueryUri, wiql);
+ var queryResult = await client.PostAsync>(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>(workItemsUri);
+ var result = await client.GetAsAsync>(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>(attachmentUri, content);
+ var createAttachmentresult = await client.PostAsync>(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>(linkAttachmentUri, content);
+ var result = await client.PatchAsync>(linkAttachmentUri, content).ConfigureAwait(false);
if (result.HasError)
{
throw new Exception(result.ErrorResponse);
diff --git a/src/Greenshot.Addon.Tfs/TfsDestination.cs b/src/Greenshot.Addon.Tfs/TfsDestination.cs
index 115ffac57..7f4dcd123 100644
--- a/src/Greenshot.Addon.Tfs/TfsDestination.cs
+++ b/src/Greenshot.Addon.Tfs/TfsDestination.cs
@@ -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 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 ExportCaptureAsync(bool manuallyInitiated, ISurface surface,
- ICaptureDetails captureDetails)
+ public override async Task 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();
diff --git a/src/Greenshot.Addon.Tfs/Views/TfsConfigView.xaml b/src/Greenshot.Addon.Tfs/Views/TfsConfigView.xaml
index b59065d63..c6f882101 100644
--- a/src/Greenshot.Addon.Tfs/Views/TfsConfigView.xaml
+++ b/src/Greenshot.Addon.Tfs/Views/TfsConfigView.xaml
@@ -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 @@
-
-
+
+
-
+
diff --git a/src/Greenshot.Addons/Core/AbstractDestination.cs b/src/Greenshot.Addons/Core/AbstractDestination.cs
index a1419b18c..deb465fff 100644
--- a/src/Greenshot.Addons/Core/AbstractDestination.cs
+++ b/src/Greenshot.Addons/Core/AbstractDestination.cs
@@ -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();
}
+ ///
public virtual string Designation { get; }
+ ///
public abstract string Description { get; }
+ ///
public virtual Bitmap DisplayIcon { get; set; }
+ ///
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;
+ ///
+ /// Give a destination a preparation possibility before showing the toolstrip items
+ ///
+ /// ToolStripMenuItem
+ /// Task
+ protected virtual Task PrepareDynamicDestinations(ToolStripMenuItem destinationToolStripMenuItem)
+ {
+ return Task.FromResult(true);
+ }
+
+ ///
+ /// Get the Dynamic destinations
+ ///
+ /// IEnumerable of IDestination
public virtual IEnumerable DynamicDestinations()
{
- yield break;
+ return Enumerable.Empty();
+ }
+
+ ///
+ /// Give a destination the possibility to clean up after showing the toolstrip item
+ ///
+ /// ToolStripMenuItem
+ /// Task
+ protected virtual Task AfterDynamicDestinations(ToolStripMenuItem destinationToolStripMenuItem)
+ {
+ return Task.FromResult(true);
}
public void Dispose()
@@ -91,12 +120,16 @@ namespace Greenshot.Addons.Core
Dispose(true);
}
+ ///
public virtual bool IsDynamic => false;
+ ///
public virtual bool UseDynamicsOnly => false;
+ ///
public virtual bool IsLinkable => false;
+ ///
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();
// 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();
}
};
}
diff --git a/src/Greenshot/Ui/Configuration/Views/ConfigView.xaml b/src/Greenshot/Ui/Configuration/Views/ConfigView.xaml
index 99a48a246..92fc4094f 100644
--- a/src/Greenshot/Ui/Configuration/Views/ConfigView.xaml
+++ b/src/Greenshot/Ui/Configuration/Views/ConfigView.xaml
@@ -29,28 +29,28 @@
-
-
-
+
+
+
+
+
+
+
@@ -61,7 +61,7 @@
-
+