From 62811016cec13953c686dd21b747568d4302335f Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 26 Apr 2018 16:00:40 +0200 Subject: [PATCH] Small fixes, mainly to make the TfsDestination work better. --- .../Greenshot.Addon.Jira.csproj | 1 + src/Greenshot.Addon.Jira/JiraDestination.cs | 2 +- src/Greenshot.Addon.Jira/jira.svgz | Bin 0 -> 1784 bytes .../Entities/WorkItemFields.cs | 3 ++ src/Greenshot.Addon.Tfs/TfsClient.cs | 17 ++++--- src/Greenshot.Addon.Tfs/TfsDestination.cs | 29 +++++++++--- .../Views/TfsConfigView.xaml | 8 ++-- .../Core/AbstractDestination.cs | 43 ++++++++++++++++-- .../Ui/Configuration/Views/ConfigView.xaml | 22 ++++----- 9 files changed, 94 insertions(+), 31 deletions(-) create mode 100644 src/Greenshot.Addon.Jira/jira.svgz 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 0000000000000000000000000000000000000000..4d817e9a4b79418cbfc7ee09b326021d5f6798b2 GIT binary patch literal 1784 zcmVNu4HY-_ACR*=oCK&L^AgaP?ugDvFEwv{^Ol zX4CGcMw{tmRG*LPbMe0X*vz-<^>(u_mYe;pZ?(QR^FMO%Yr#7wzTw1WILl*(@(ETYT>K%f4!*F*PC_fIb<@rkvvxK{JxJmZIZ!`)@%YIhzWMy@&35;G^e76mx7!bZ z6%fl_E{WS)B4!4xefI-<^bSCX?w%JSE=aaHrp_pz{RcFuI z1~%!=WCU?F``qlzdQ*WwX>NJtYpJ+M67dVH6;@) z)=tM@V`X%t=*_ToxR_5)trTJHopoN#v1Xl3Vj!YJVv1GJmME&am8$n7*R&Hlja0#S&ZPsVSA5RZup$(9{QO#iP~6 zxCAo-tzsAuH~91mEZym_OkR`aYz0f)%X zMTgqVrEGi_gq^qG83=>wlq%zlDUTyGzzRhnCL{Yqojtu*fzfXcekP!6BnH*b40@cYDGI8+s$@bwi<}e0ygQkTk!p8yTq=7#g;crkXR_ zTJT+1FpinL5Z_3ML3Ax5GdT*dNhibXI%SW9Ib*FP1>i{!N{*e26>`enQ0nwpBlei( zOyNlKoyhqZ(6TYvl0BNLz^6-<1t8$7Lqs@SCvUp}gIhSj4R9gx+M8%>!;uW8EF(l3Ik{wp45J72-6+HZ5hOL3I6%}Ml@-hx z0+bcb>@m$GX+m--`=cU%A>0XU={jZtFc5XcJ^KxD?fggGI@0P&$83FU;&I0+5p$Nh2Ugp)Fd z44@R|Fah0&Xlw()1jWlkvX8)#u>@^zr7*H&1*k?a4uidn3uCj9+2!!g z$Pp!982Yp1$C?++k@WJ`VE7DKB$SX)agDKW!Au9RJ^Cq3C1popj3*rH7G0k`gBLlW zZZNRR(=@vz-DqrO4oyoCBQy?U(KpK@&;v0Iw98$kI!lv;#QF{~3LsOJ0GNT!&l2jU zxW)VsRLWy5MNwpjJi=krF){PdzR}Ux2SFImvqICrY)w8$jw5=);qIe0@~#h6js_J? z-Q*Tn9CN8W<4{TRP>x^+8hE$hFiLu55Uc+xr0FgFx1!zx=XW;fk44LdSPg1wP#-1T z`Q?dvaNfr?3VP+^h@Nnsvpnxo&VK;Z{so|R1k|Miprhz_fcg=>L4A}A=l?UH>4a0) zS&g=bXI&0a1_t6E0gVShx#}Z70P06ce_{ShKzRg|2SCFBU-${oa0F0406GeK<>P?< amtk~&dVxjvb02?w!OvHO=J%RE6aWChB5!>F literal 0 HcmV?d00001 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 @@ - +