From 33addc93531eabe55e7900569f806185b3f703dc Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Tue, 23 Jul 2013 00:59:31 +0200 Subject: [PATCH] Adding of custom assemblies to ClassBrowser from GAC through OpenFromGacDialog. --- .../SharpDevelop/Dom/ClassBrowser/Commands.cs | 11 +- .../Dom/ClassBrowser/OpenFromGacDialog.xaml | 46 +++++ .../ClassBrowser/OpenFromGacDialog.xaml.cs | 188 ++++++++++++++++++ src/Main/SharpDevelop/SharpDevelop.csproj | 5 + 4 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml create mode 100644 src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs index 3287d4e4f9..7496f03f0b 100644 --- a/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs @@ -36,7 +36,16 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser { public override void Execute(object parameter) { -// throw new NotImplementedException(); + var classBrowser = SD.GetService(); + if (classBrowser != null) { + OpenFromGacDialog gacDialog = new OpenFromGacDialog(); + if (gacDialog.ShowDialog() ?? false) + { + foreach (string assemblyFile in gacDialog.SelectedFileNames) { + classBrowser.AssemblyList.Assemblies.Add(ClassBrowserPad.CreateAssemblyModelFromFile(assemblyFile)); + } + } + } } } diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml new file mode 100644 index 0000000000..ae78f0982f --- /dev/null +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs new file mode 100644 index 0000000000..a13572bcf2 --- /dev/null +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs @@ -0,0 +1,188 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; +using ICSharpCode.Core.Presentation; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Parser; + +namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser +{ + /// + /// Interaction logic for OpenFromGacDialog.xaml + /// + public partial class OpenFromGacDialog : Window + { + ObservableCollection gacEntries = new ObservableCollection(); + ObservableCollection filteredEntries = new ObservableCollection(); + Predicate filterMethod = _ => true; + volatile bool cancelFetchThread; + + public OpenFromGacDialog() + { + InitializeComponent(); + FormLocationHelper.ApplyWindow(this, "ICSharpCode.SharpDevelop.Dom.OpenFromGacDialog.Bounds", true); + listView.ItemsSource = filteredEntries; + SortableGridViewColumn.SetCurrentSortColumn(listView, nameColumn); + SortableGridViewColumn.SetSortDirection(listView, ColumnSortDirection.Ascending); + + new Thread(new ThreadStart(FetchGacContents)).Start(); + } + + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + cancelFetchThread = true; + } + + #region Fetch Gac Contents + sealed class GacEntry + { + readonly DomAssemblyName r; + readonly string fileName; + string formattedVersion; + + public GacEntry(DomAssemblyName r, string fileName) + { + this.r = r; + this.fileName = fileName; + } + + public string FullName { + get { return r.FullName; } + } + + public string ShortName { + get { return r.ShortName; } + } + + public string FileName { + get { return fileName; } + } + + public Version Version { + get { return r.Version; } + } + + public string FormattedVersion { + get { + if (formattedVersion == null) + formattedVersion = Version.ToString(); + return formattedVersion; + } + } + + public string Culture { + get { return r.Culture; } + } + + public string PublicKeyToken { + get { + StringBuilder s = new StringBuilder(); + foreach (byte b in r.PublicKeyToken) + s.Append(b.ToString("x2")); + return s.ToString(); + } + } + + public override string ToString() + { + return r.FullName; + } + } + + void FetchGacContents() + { + IGlobalAssemblyCacheService gacService = SD.GetService(); + HashSet fullNames = new HashSet(); + UpdateProgressBar(pg => { pg.Visibility = System.Windows.Visibility.Visible; pg.IsIndeterminate = true; }); + var list = gacService.Assemblies.TakeWhile(_ => !cancelFetchThread).ToList(); + UpdateProgressBar(pg => { pg.IsIndeterminate = false; pg.Maximum = list.Count; }); + foreach (var r in list) { + if (cancelFetchThread) + break; + if (fullNames.Add(r.FullName)) { // filter duplicates + var file = gacService.FindAssemblyInNetGac(r); + if (file != null) { + var entry = new GacEntry(r, file); + UpdateProgressBar(pg => { pg.Value = pg.Value + 1; AddNewEntry(entry); }); + } + } + } + UpdateProgressBar(pg => { pg.Visibility = System.Windows.Visibility.Hidden; }); + } + + void UpdateProgressBar(Action updateAction) + { + Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => updateAction(gacReadingProgressBar))); + } + + void AddNewEntry(GacEntry entry) + { + gacEntries.Add(entry); + if (filterMethod(entry)) + filteredEntries.Add(entry); + } + #endregion + + void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + string filterString = filterTextBox.Text.Trim(); + if (filterString.Length == 0) + filterMethod = _ => true; + else { + var elements = filterString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + filterMethod = entry => elements.All(el => Contains(entry.FullName, el) || Contains(entry.FormattedVersion, el)); + } + + filteredEntries.Clear(); + filteredEntries.AddRange(gacEntries.Where(entry => filterMethod(entry))); + } + + static bool Contains(string s, string subString) + { + return s.IndexOf(subString, StringComparison.OrdinalIgnoreCase) >= 0; + } + + void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + okButton.IsEnabled = listView.SelectedItems.Count > 0; + } + + void OKButton_Click(object sender, RoutedEventArgs e) + { + this.DialogResult = true; + Close(); + } + + public string[] SelectedFileNames { + get { + return listView.SelectedItems.OfType().Select(e => e.FileName).ToArray(); + } + } + } +} \ No newline at end of file diff --git a/src/Main/SharpDevelop/SharpDevelop.csproj b/src/Main/SharpDevelop/SharpDevelop.csproj index 20ff169f9d..8eed81e197 100644 --- a/src/Main/SharpDevelop/SharpDevelop.csproj +++ b/src/Main/SharpDevelop/SharpDevelop.csproj @@ -109,6 +109,10 @@ + + OpenFromGacDialog.xaml + Code + @@ -331,6 +335,7 @@ +