Skip to content

Commit c92d7f5

Browse files
committed
Wire AddRemoveReferences to command.
1 parent bea26bb commit c92d7f5

File tree

12 files changed

+291
-80
lines changed

12 files changed

+291
-80
lines changed

Rubberduck.Core/AddRemoveReferences/IReferenceInfo.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.

Rubberduck.Core/AddRemoveReferences/ReferenceModel.cs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
using System.ComponentModel;
33
using System.IO;
44
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
56
using System.Runtime.InteropServices.ComTypes;
7+
using Rubberduck.Parsing.ComReflection;
8+
using Rubberduck.VBEditor;
69
using Rubberduck.VBEditor.SafeComWrappers;
710
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
11+
using Rubberduck.VBEditor.Utility;
812

913
namespace Rubberduck.AddRemoveReferences
1014
{
@@ -34,7 +38,7 @@ public ReferenceModel(RegisteredLibraryInfo info)
3438
LocaleName = info.LocaleName;
3539
IsBuiltIn = false;
3640
Type = ReferenceKind.TypeLibrary;
37-
Flags = info.Flags;
41+
Flags = (TypeLibTypeFlags)info.Flags;
3842
IsRegistered = true;
3943
}
4044

@@ -61,6 +65,30 @@ public ReferenceModel(IReference reference, int priority)
6165
Type = reference.Type;
6266
}
6367

68+
public ReferenceModel(ITypeLib reference)
69+
{
70+
var documentation = new ComDocumentation(reference, -1);
71+
Name = documentation.Name;
72+
Description = documentation.DocString;
73+
74+
reference.GetLibAttr(out var attributes);
75+
using (DisposalActionContainer.Create(attributes, reference.ReleaseTLibAttr))
76+
{
77+
var typeAttr = Marshal.PtrToStructure<System.Runtime.InteropServices.ComTypes.TYPELIBATTR>(attributes);
78+
79+
Major = typeAttr.wMajorVerNum;
80+
Minor = typeAttr.wMinorVerNum;
81+
Flags = (TypeLibTypeFlags)typeAttr.wLibFlags;
82+
Guid = typeAttr.guid;
83+
}
84+
}
85+
86+
public ReferenceModel(string path)
87+
{
88+
FullPath = path;
89+
Name = Path.GetFileName(path);
90+
}
91+
6492
private bool _pinned;
6593
public bool IsPinned
6694
{
@@ -73,9 +101,9 @@ public bool IsPinned
73101
}
74102

75103
public bool IsRecent { get; set; }
76-
77104
public bool IsRegistered { get; set; }
78105
public bool IsReferenced { get; set; }
106+
79107
public int? Priority { get; set; }
80108

81109
public string Name { get; }
@@ -86,7 +114,7 @@ public bool IsPinned
86114

87115
public bool IsBuiltIn { get; }
88116
public bool IsBroken { get; }
89-
public LIBFLAGS Flags { get; }
117+
public TypeLibTypeFlags Flags { get; set; }
90118
public ReferenceKind Type { get; }
91119

92120
private string FullPath32 { get; }
@@ -119,6 +147,11 @@ public ReferenceStatus Status
119147
}
120148
}
121149

150+
public ReferenceInfo ToReferenceInfo()
151+
{
152+
return new ReferenceInfo(Guid, Name, FullPath, Major, Minor);
153+
}
154+
122155
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
123156
{
124157
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Rubberduck.Interaction;
8+
using Rubberduck.Parsing.ComReflection;
9+
using Rubberduck.Parsing.Symbols;
10+
using Rubberduck.Resources;
11+
using Rubberduck.Settings;
12+
using Rubberduck.SettingsProvider;
13+
using Rubberduck.UI.AddRemoveReferences;
14+
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
15+
using Rubberduck.VBEditor.Utility;
16+
17+
namespace Rubberduck.AddRemoveReferences
18+
{
19+
public interface IReferenceReconciler
20+
{
21+
void ReconcileReferences(IAddRemoveReferencesModel model);
22+
List<ReferenceModel> ReconcileReferences(IAddRemoveReferencesModel model, List<ReferenceModel> allReferences);
23+
ReferenceModel TryAddReference(IVBProject project, string path);
24+
ReferenceModel TryAddReference(IVBProject project, ReferenceModel reference);
25+
ReferenceModel GetLibraryInfoFromPath(string path);
26+
}
27+
28+
public class ReferenceReconciler : IReferenceReconciler
29+
{
30+
private readonly IMessageBox _messageBox;
31+
private readonly IConfigProvider<GeneralSettings> _settings;
32+
private readonly IComLibraryProvider _tlbProvider;
33+
34+
public ReferenceReconciler(IMessageBox messageBox, IConfigProvider<GeneralSettings> settings, IComLibraryProvider tlbProvider)
35+
{
36+
_messageBox = messageBox;
37+
_settings = settings;
38+
_tlbProvider = tlbProvider;
39+
}
40+
41+
public void ReconcileReferences(IAddRemoveReferencesModel model)
42+
{
43+
ReconcileReferences(model, model.NewReferences.ToList());
44+
}
45+
46+
public List<ReferenceModel> ReconcileReferences(IAddRemoveReferencesModel model, List<ReferenceModel> allReferences)
47+
{
48+
var selected = allReferences.Where(reference => !reference.IsBuiltIn && reference.Priority.HasValue)
49+
.ToDictionary(reference => reference.FullPath);
50+
51+
var output = selected.Values.Where(reference => reference.IsBuiltIn).ToList();
52+
53+
var project = model.Project.Project;
54+
using (var references = project.References)
55+
{
56+
foreach (var reference in references)
57+
{
58+
try
59+
{
60+
if (!reference.IsBuiltIn)
61+
{
62+
references.Remove(reference);
63+
}
64+
}
65+
finally
66+
{
67+
reference.Dispose();
68+
}
69+
}
70+
71+
output.AddRange(selected.Values.OrderBy(selection => selection.Priority)
72+
.Select(reference => TryAddReference(project, reference)).Where(added => added != null));
73+
}
74+
75+
return output;
76+
}
77+
78+
public ReferenceModel GetLibraryInfoFromPath(string path)
79+
{
80+
try
81+
{
82+
return new ReferenceModel(_tlbProvider.LoadTypeLibrary(path));
83+
}
84+
catch
85+
{
86+
// Most likely this is a project. If not, it we can't fail here because it could have come from the Apply
87+
// button in the AddRemoveReferencesDialog. Wait for it... :-P
88+
return new ReferenceModel(path);
89+
}
90+
}
91+
92+
public ReferenceModel TryAddReference(IVBProject project, string path)
93+
{
94+
using (var references = project.References)
95+
{
96+
try
97+
{
98+
using (var reference = references.AddFromFile(path))
99+
{
100+
return reference is null ? null : new ReferenceModel(reference, references.Count);
101+
}
102+
}
103+
catch (COMException ex)
104+
{
105+
_messageBox.NotifyWarn(ex.Message, RubberduckUI.References_AddFailedCaption);
106+
}
107+
return null;
108+
}
109+
}
110+
111+
public ReferenceModel TryAddReference(IVBProject project, ReferenceModel reference)
112+
{
113+
using (var references = project.References)
114+
{
115+
try
116+
{
117+
using (references.AddFromFile(reference.FullPath))
118+
{
119+
reference.Priority = references.Count;
120+
return reference;
121+
}
122+
}
123+
catch (COMException ex)
124+
{
125+
_messageBox.NotifyWarn(ex.Message, RubberduckUI.References_AddFailedCaption);
126+
}
127+
return null;
128+
}
129+
}
130+
}
131+
}

Rubberduck.Core/AddRemoveReferences/RegisteredLibraryInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public RegisteredLibraryKey(Guid guid, int major, int minor)
2020
}
2121
}
2222

23-
public class RegisteredLibraryInfo : IReferenceInfo
23+
public class RegisteredLibraryInfo
2424
{
2525
private static readonly Dictionary<int, string> NativeLocaleNames = new Dictionary<int, string>
2626
{

Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesDialog.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@ public partial class AddRemoveReferencesDialog : Form, IRefactoringDialog<AddRem
99

1010
public AddRemoveReferencesDialog()
1111
{
12-
InitializeComponent();
12+
InitializeComponent();
1313
}
1414

1515
public AddRemoveReferencesDialog(AddRemoveReferencesViewModel viewModel) : this()
1616
{
1717
ViewModel = viewModel;
18+
ViewModel.OnWindowClosed += ViewModel_OnWindowClosed;
1819
addRemoveReferencesWindow1.DataContext = viewModel;
1920
}
21+
22+
private void ViewModel_OnWindowClosed(object sender, DialogResult result)
23+
{
24+
DialogResult = result;
25+
Close();
26+
}
2027
}
2128
}

Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesPresenter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
1+
using System.Linq;
32
using System.Windows.Forms;
43
using Rubberduck.AddRemoveReferences;
54
using Rubberduck.Parsing.Symbols;
@@ -40,6 +39,10 @@ public IAddRemoveReferencesModel Show(ProjectDeclaration project)
4039
_view.ViewModel.Model = Model;
4140

4241
_view.ShowDialog();
42+
if (_view.DialogResult != DialogResult.OK)
43+
{
44+
return null;
45+
}
4346

4447
Model.NewReferences = _view.ViewModel.ProjectReferences.SourceCollection.OfType<ReferenceModel>().ToList();
4548
return Model;

Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesPresenterFactory.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Linq;
44
using NLog;
55
using Rubberduck.AddRemoveReferences;
6-
using Rubberduck.Interaction;
76
using Rubberduck.Parsing.Symbols;
87
using Rubberduck.Parsing.VBA;
98
using Rubberduck.Refactorings;
@@ -27,19 +26,19 @@ public class AddRemoveReferencesPresenterFactory : IAddRemoveReferencesPresenter
2726
private readonly RubberduckParserState _state;
2827
private readonly IConfigProvider<GeneralSettings> _settings;
2928
private readonly IRegisteredLibraryFinderService _finder;
30-
private readonly IMessageBox _messageBox;
29+
private readonly IReferenceReconciler _reconciler;
3130

3231
public AddRemoveReferencesPresenterFactory(IVBE vbe,
3332
RubberduckParserState state,
3433
IConfigProvider<GeneralSettings> generalSettingsProvider,
3534
IRegisteredLibraryFinderService finder,
36-
IMessageBox messageBox)
35+
IReferenceReconciler reconciler)
3736
{
3837
_vbe = vbe;
3938
_state = state;
4039
_settings = generalSettingsProvider;
4140
_finder = finder;
42-
_messageBox = messageBox;
41+
_reconciler = reconciler;
4342
}
4443

4544
public AddRemoveReferencesPresenter Create(ProjectDeclaration project)
@@ -95,7 +94,7 @@ public AddRemoveReferencesPresenter Create(ProjectDeclaration project)
9594
var settings = _settings.Create();
9695
var model = new AddRemoveReferencesModel(project, models.Values, settings);
9796

98-
return new AddRemoveReferencesPresenter(new AddRemoveReferencesDialog(new AddRemoveReferencesViewModel(model, _messageBox)));
97+
return new AddRemoveReferencesPresenter(new AddRemoveReferencesDialog(new AddRemoveReferencesViewModel(model, _reconciler)));
9998
}
10099

101100
public AddRemoveReferencesPresenter Create()

0 commit comments

Comments
 (0)