Skip to content

Commit d7db16f

Browse files
committed
Finalized FindAllReferences feature - implemented double-click navigation, fixed (worked around) COMException and skipped showing the toolwindow when there's only 1 reference for the target identifier
1 parent a8286a9 commit d7db16f

File tree

6 files changed

+97
-4
lines changed

6 files changed

+97
-4
lines changed

RetailCoder.VBE/UI/IdentifierReferences/IdentifierReferenceListItem.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ public IdentifierReferenceListItem(IdentifierReference reference)
1212
_reference = reference;
1313
}
1414

15+
public IdentifierReference GetReferenceItem()
16+
{
17+
return _reference;
18+
}
19+
1520
public QualifiedSelection Selection { get { return new QualifiedSelection(_reference.QualifiedModuleName, _reference.Selection); } }
1621
public string IdentifierName { get { return _reference.IdentifierName; } }
1722

RetailCoder.VBE/UI/IdentifierReferences/IdentifierReferencesListControl.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Windows.Forms;
1+
using System;
2+
using System.Windows.Forms;
23
using Rubberduck.Parsing.Symbols;
34

45
namespace Rubberduck.UI.IdentifierReferences
@@ -9,6 +10,26 @@ public IdentifierReferencesListControl(Declaration target)
910
{
1011
InitializeComponent();
1112
Target = target;
13+
ResultBox.DoubleClick += ResultBox_DoubleClick;
14+
}
15+
16+
public event EventHandler<NavigateCodeEventArgs> NavigateIdentifierReference;
17+
private void ResultBox_DoubleClick(object sender, System.EventArgs e)
18+
{
19+
var handler = NavigateIdentifierReference;
20+
if (handler == null || ResultBox.SelectedItem == null)
21+
{
22+
return;
23+
}
24+
25+
var selectedItem = ResultBox.SelectedItem as IdentifierReferenceListItem;
26+
if (selectedItem == null)
27+
{
28+
return;
29+
}
30+
31+
var arg = new NavigateCodeEventArgs(selectedItem.GetReferenceItem());
32+
handler(this, arg);
1233
}
1334

1435
public Declaration Target { get; private set; }

RetailCoder.VBE/UI/IdentifierReferences/IdentifierReferencesListDockablePresenter.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using System.Linq;
1+
using System;
2+
using System.Linq;
23
using Microsoft.Vbe.Interop;
4+
using Rubberduck.Extensions;
5+
using Rubberduck.Parsing;
36
using Rubberduck.Parsing.Symbols;
47

58
namespace Rubberduck.UI.IdentifierReferences
@@ -18,6 +21,17 @@ private void BindTarget(Declaration target)
1821
listBox.DataSource = target.References.Select(reference => new IdentifierReferenceListItem(reference)).ToList();
1922
listBox.DisplayMember = "DisplayString";
2023
listBox.ValueMember = "Selection";
24+
Control.NavigateIdentifierReference += Control_NavigateIdentifierReference;
25+
}
26+
27+
public static void OnNavigateIdentifierReference(VBE vbe, IdentifierReference reference)
28+
{
29+
vbe.SetSelection(new QualifiedSelection(reference.QualifiedModuleName, reference.Selection));
30+
}
31+
32+
private void Control_NavigateIdentifierReference(object sender, NavigateCodeEventArgs e)
33+
{
34+
OnNavigateIdentifierReference(VBE, e.Reference);
2135
}
2236

2337
IdentifierReferencesListControl Control { get { return UserControl as IdentifierReferencesListControl; } }

RetailCoder.VBE/UI/NavigateCodeEventArgs.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,26 @@ public NavigateCodeEventArgs(Declaration declaration)
3131
_selection = declaration.Selection;
3232
}
3333

34-
public NavigateCodeEventArgs(QualifiedSelection qualifiedSelection)
34+
public NavigateCodeEventArgs(IdentifierReference reference)
35+
{
36+
if (reference == null)
37+
{
38+
return;
39+
}
40+
41+
_reference = reference;
42+
_qualifiedName = reference.QualifiedModuleName;
43+
_selection = reference.Selection;
44+
}
45+
46+
public NavigateCodeEventArgs(QualifiedSelection qualifiedSelection)
3547
:this(qualifiedSelection.QualifiedName, qualifiedSelection.Selection)
3648
{
3749
}
3850

51+
private readonly IdentifierReference _reference;
52+
public IdentifierReference Reference { get { return _reference; } }
53+
3954
private readonly Declaration _declaration;
4055
public Declaration Declaration { get { return _declaration; } }
4156

RetailCoder.VBE/UI/RefactorMenu.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using System.Drawing;
1+
using System;
2+
using System.Drawing;
23
using System.Linq;
4+
using System.Runtime.InteropServices;
35
using Microsoft.Office.Core;
46
using Microsoft.Vbe.Interop;
57
using Rubberduck.Extensions;
@@ -78,6 +80,38 @@ private void _findAllReferencesContextMenu_Click(CommandBarButton Ctrl, ref bool
7880
.FirstOrDefault(item => IsSelectedDeclaration(selection, item)
7981
|| IsSelectedReference(selection, item));
8082

83+
if (target == null)
84+
{
85+
return;
86+
}
87+
88+
var referenceCount = target.References.Count();
89+
90+
if (referenceCount == 1)
91+
{
92+
// if there's only 1 reference, just jump to it:
93+
IdentifierReferencesListDockablePresenter.OnNavigateIdentifierReference(IDE, target.References.First());
94+
95+
}
96+
else if (referenceCount > 1)
97+
{
98+
// if there's more than one reference, show the dockable reference navigation window:
99+
try
100+
{
101+
ShowReferencesToolwindow(target);
102+
}
103+
catch (COMException)
104+
{
105+
// the exception is related to the docked control host instance,
106+
// trying again will work (I know, that's bad bad bad code)
107+
ShowReferencesToolwindow(target);
108+
}
109+
}
110+
}
111+
112+
private void ShowReferencesToolwindow(Declaration target)
113+
{
114+
// throws a COMException if toolwindow was already closed
81115
var window = new IdentifierReferencesListControl(target);
82116
var presenter = new IdentifierReferencesListDockablePresenter(IDE, AddIn, window, target);
83117
presenter.Show();

Rubberduck.Parsing/Symbols/IdentifierReferenceListener.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ private Declaration GetClosestScope(IEnumerable<Declaration> declarations, Parse
481481
if (matchingParent != null)
482482
{
483483
var parentType = matches.FirstOrDefault(p => p.ComponentName == matchingParent.AsTypeName);
484+
if (parentType == null)
485+
{
486+
return null;
487+
}
484488
return matches.FirstOrDefault(m => m.ParentScope == parentType.ParentScope);
485489
}
486490
}

0 commit comments

Comments
 (0)