diff options
author | Miguel Costa <miguel.costa@qt.io> | 2022-01-13 18:45:15 +0100 |
---|---|---|
committer | Miguel Costa <miguel.costa@qt.io> | 2022-01-19 11:33:33 +0000 |
commit | cbb58e226c27bcb3fbe7b8f0fdc8d4774fdf4088 (patch) | |
tree | d8ae2f3b17442b3f7d54757581d12d4a25fc079c | |
parent | c1179b4720ac88c54034f237c18cf417eeaac9fd (diff) |
Add access to InfoBar extensibility
Change-Id: I5591ed5e3aa9fa94a110168f07a93391620dd931
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
-rw-r--r-- | QtVsTools.Package/QtVsTools.Package.csproj | 1 | ||||
-rw-r--r-- | QtVsTools.Package/VisualStudio/InfoBar.cs | 146 | ||||
-rw-r--r-- | QtVsTools.Package/VisualStudio/VsShell.cs | 15 |
3 files changed, 162 insertions, 0 deletions
diff --git a/QtVsTools.Package/QtVsTools.Package.csproj b/QtVsTools.Package/QtVsTools.Package.csproj index 31898e9a..20247c84 100644 --- a/QtVsTools.Package/QtVsTools.Package.csproj +++ b/QtVsTools.Package/QtVsTools.Package.csproj @@ -451,6 +451,7 @@ <Compile Include="Package\SR.cs" /> <Compile Include="Package\Translation.cs" /> <Compile Include="Package\TranslationItem.cs" /> + <Compile Include="VisualStudio\InfoBar.cs" /> <Compile Include="VisualStudio\VsShell.cs" /> <Compile Include="Common\VsToolsDialogWindow.cs" /> <Content Include="..\Changelog"> diff --git a/QtVsTools.Package/VisualStudio/InfoBar.cs b/QtVsTools.Package/VisualStudio/InfoBar.cs new file mode 100644 index 00000000..082dd635 --- /dev/null +++ b/QtVsTools.Package/VisualStudio/InfoBar.cs @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt VS Tools. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +using System; +using System.Diagnostics; +using System.Linq; +using Microsoft.VisualStudio.Imaging.Interop; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; + +namespace QtVsTools.VisualStudio +{ + internal static class InfoBar + { + public interface IMessage + { + void Show(); + void Close(); + bool IsOpen { get; } + } + + public class TextSpan + { + public string Text { get; set; } + public bool Bold { get; set; } + public bool Italic { get; set; } + public bool Underline { get; set; } + public static implicit operator TextSpan(string text) => new TextSpan { Text = text }; + } + + public class TextSpacer : TextSpan + { + public TextSpacer(int spaces) + { + Text = new string(' ', spaces); + } + } + + public class Hyperlink + { + public string Text { get; set; } + public bool CloseInfoBar { get; set; } + public Action OnClicked { get; set; } + } + + public class Message : IMessage, IVsInfoBarUIEvents + { + public ImageMoniker Icon { get; set; } + public TextSpan[] Text { get; set; } + public Hyperlink[] Hyperlinks { get; set; } + + static IVsInfoBarUIFactory _Factory = null; + static IVsInfoBarUIFactory Factory => _Factory ?? (_Factory = + VsServiceProvider.GetService<SVsInfoBarUIFactory, IVsInfoBarUIFactory>()); + + public IVsInfoBarUIElement UIElement { get; private set; } + private uint cookie; + + public bool IsOpen => UIElement != null; + + public void Show() + { + ThreadHelper.ThrowIfNotOnUIThread(); + if (Factory == null) + return; + if (UIElement != null) // Message already shown + return; + var textSpans = Enumerable.Empty<InfoBarTextSpan>(); + if (Text != null) { + textSpans = Text + .Select(x => new InfoBarTextSpan(x.Text, x.Bold, x.Italic, x.Underline)); + } + var hyperlinks = Enumerable.Empty<InfoBarHyperlink>(); + if (Hyperlinks != null) { + hyperlinks = Hyperlinks + .Select(x => new InfoBarHyperlink(x.Text, x)); + } + var model = new InfoBarModel(textSpans, hyperlinks, Icon, true); + UIElement = Factory.CreateInfoBar(model); + if (UIElement != null) { + UIElement.Advise(this, out cookie); + VsShell.InfoBarHost?.AddInfoBar(UIElement); + } + } + + public void Close() + { + if (UIElement == null) + return; + + ThreadHelper.ThrowIfNotOnUIThread(); + UIElement?.Close(); + } + + public void OnActionItemClicked( + IVsInfoBarUIElement infoBarUIElement, + IVsInfoBarActionItem actionItem) + { + Debug.Assert(infoBarUIElement == UIElement); + ThreadHelper.ThrowIfNotOnUIThread(); + var hyperlink = actionItem.ActionContext as Hyperlink; + if (hyperlink == null) + return; + if (hyperlink.CloseInfoBar) + Close(); + hyperlink.OnClicked?.Invoke(); + } + + public void OnClosed(IVsInfoBarUIElement infoBarUIElement) + { + Debug.Assert(infoBarUIElement == UIElement); + ThreadHelper.ThrowIfNotOnUIThread(); + if (UIElement != null) { + UIElement.Unadvise(cookie); + UIElement = null; + cookie = 0; + } + } + } + } +} diff --git a/QtVsTools.Package/VisualStudio/VsShell.cs b/QtVsTools.Package/VisualStudio/VsShell.cs index 964e17e5..1aa2b467 100644 --- a/QtVsTools.Package/VisualStudio/VsShell.cs +++ b/QtVsTools.Package/VisualStudio/VsShell.cs @@ -84,5 +84,20 @@ namespace QtVsTools.VisualStudio { return GetProjectItem(context, itemid)?.Document; } + + private static IVsInfoBarHost _InfoBarHost = null; + public static IVsInfoBarHost InfoBarHost + { + get + { + ThreadHelper.ThrowIfNotOnUIThread(); + if (_InfoBarHost != null) + return _InfoBarHost; + Initialize(); + object host = null; + vsShell?.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out host); + return _InfoBarHost = host as IVsInfoBarHost; + } + } } } |