Skip to content

Commit eb79c9c

Browse files
committed
Merge pull request #1323 from retailcoder/next
added "current selection" to Rubberduck command bar
2 parents 1b68ce2 + 922f1d9 commit eb79c9c

File tree

9 files changed

+112
-35
lines changed

9 files changed

+112
-35
lines changed

RetailCoder.VBE/App.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public App(VBE vbe, IMessageBox messageBox,
8585
_hookActions = new Dictionary<Type, Action>
8686
{
8787
{ typeof(MouseHook), HandleMouseMessage },
88-
//{ typeof(KeyboardHook), HandleKeyboardMessage },
88+
{ typeof(KeyboardHook), HandleKeyboardMessage },
8989
};
9090

9191

@@ -104,17 +104,18 @@ private void _hooks_MessageReceived(object sender, HookEventArgs e)
104104

105105
private void HandleMouseMessage()
106106
{
107-
_appMenus.EvaluateCanExecute(_parser.State);
107+
RefreshSelection();
108108
}
109109

110110
private void HandleKeyboardMessage()
111111
{
112-
var pane = _vbe.ActiveCodePane;
113-
if (pane == null)
114-
{
115-
return;
116-
}
117-
_parser.State.OnParseRequested(this, pane.CodeModule.Parent);
112+
RefreshSelection();
113+
}
114+
115+
private void RefreshSelection()
116+
{
117+
_stateBar.SetSelectionText(_parser.State.FindSelectedDeclaration(_vbe.ActiveCodePane));
118+
_appMenus.EvaluateCanExecute(_parser.State);
118119
}
119120

120121
private void _configService_SettingsChanged(object sender, EventArgs e)

RetailCoder.VBE/Common/KeyboardHook.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.ComponentModel;
34
using System.Diagnostics;
5+
using System.Linq;
6+
using System.Runtime.InteropServices;
7+
using System.Windows.Forms;
48
using Microsoft.Vbe.Interop;
59
using Rubberduck.Common.WinAPI;
610

@@ -19,13 +23,29 @@ public KeyboardHook(VBE vbe)
1923
_callback = HookCallback;
2024
}
2125

26+
// keys that don't modify anything in the code pane but the current selection
27+
private static readonly IReadOnlyList<Keys> NavigationKeys = new[]
28+
{
29+
Keys.Down,
30+
Keys.Up,
31+
Keys.Left,
32+
Keys.Right,
33+
Keys.PageDown,
34+
Keys.PageUp,
35+
Keys.Home,
36+
Keys.End,
37+
};
38+
2239
private int _lastLineIndex;
2340
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
2441
{
2542
try
2643
{
2744
var pane = _vbe.ActiveCodePane;
28-
if (User32.IsVbeWindowActive((IntPtr)_vbe.MainWindow.HWnd) && pane != null && (WM)wParam == WM.KEYUP)
45+
if ((WM)wParam == WM.KEYDOWN
46+
&& pane != null
47+
&& NavigationKeys.Contains((Keys)Marshal.ReadInt32(lParam))
48+
&& User32.IsVbeWindowActive((IntPtr)_vbe.MainWindow.HWnd))
2949
{
3050
int startLine;
3151
int endLine;
@@ -36,11 +56,9 @@ private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
3656
pane.GetSelection(out startLine, out startColumn, out endLine, out endColumn);
3757
if (startLine != _lastLineIndex)
3858
{
39-
// if the current line has changed, let the KEYDOWN be written to the IDE, and notify on KEYUP:
4059
_lastLineIndex = startLine;
4160
if (nCode >= 0)
4261
{
43-
//var key = (Keys)Marshal.ReadInt32(lParam);
4462
OnMessageReceived();
4563
}
4664
}

RetailCoder.VBE/Common/MouseHook.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
4141
Debug.WriteLine(exception);
4242
}
4343

44-
return IntPtr.Zero;
44+
return User32.CallNextHookEx(_hookId, nCode, wParam, lParam);
4545
}
4646

4747
private void OnMessageReceived()
@@ -85,12 +85,14 @@ public void Detach()
8585
return;
8686
}
8787

88+
IsAttached = false;
8889
if (!User32.UnhookWindowsHookEx(_hookId))
8990
{
91+
_hookId = IntPtr.Zero;
9092
throw new Win32Exception();
9193
}
9294

93-
IsAttached = false;
95+
_hookId = IntPtr.Zero;
9496
Debug.WriteLine("{0}: {1}", GetType().Name, IsAttached ? "Attached" : "Detached");
9597
}
9698
}

RetailCoder.VBE/Common/RubberduckHooks.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.ComponentModel;
34
using System.Diagnostics;
45
using System.Linq;
56
using System.Runtime.InteropServices;
@@ -44,7 +45,7 @@ public void HookHotkeys()
4445
var config = _config.LoadConfiguration();
4546
var settings = config.UserSettings.GeneralSettings.HotkeySettings;
4647

47-
//AddHook(new KeyboardHook(_vbe));
48+
AddHook(new KeyboardHook(_vbe));
4849
AddHook(new MouseHook(_vbe));
4950
foreach (var hotkey in settings.Where(hotkey => hotkey.IsEnabled))
5051
{
@@ -91,7 +92,7 @@ public void Attach()
9192

9293
IsAttached = true;
9394
}
94-
catch (Exception exception)
95+
catch (Win32Exception exception)
9596
{
9697
Debug.WriteLine(exception);
9798
}
@@ -111,13 +112,12 @@ public void Detach()
111112
hook.Detach();
112113
hook.MessageReceived -= hook_MessageReceived;
113114
}
114-
115-
IsAttached = false;
116115
}
117-
catch (Exception exception)
116+
catch (Win32Exception exception)
118117
{
119118
Debug.WriteLine(exception);
120119
}
120+
IsAttached = false;
121121
}
122122

123123
private void hook_MessageReceived(object sender, HookEventArgs e)
@@ -166,9 +166,9 @@ private IntPtr WindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
166166
suppress = HandleHotkeyMessage(wParam);
167167
break;
168168

169-
//case WM.ACTIVATEAPP:
170-
// HandleActivateAppMessage(wParam);
171-
// break;
169+
case WM.ACTIVATEAPP:
170+
HandleActivateAppMessage(wParam);
171+
break;
172172
}
173173
}
174174

RetailCoder.VBE/UI/Command/MenuItems/RubberduckCommandBar.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
using System.Diagnostics;
33
using Microsoft.Office.Core;
44
using Microsoft.Vbe.Interop;
5+
using Rubberduck.Parsing.Symbols;
56
using Rubberduck.Parsing.VBA;
67
using Rubberduck.Properties;
78
using Rubberduck.UI.Command.MenuItems.ParentMenus;
9+
using Rubberduck.VBEditor;
10+
using Rubberduck.VBEditor.VBEInterfaces.RubberduckCodePane;
11+
using ParserState = Rubberduck.Parsing.VBA.ParserState;
812

913
namespace Rubberduck.UI.Command.MenuItems
1014
{
@@ -16,6 +20,7 @@ public class RubberduckCommandBar
1620

1721
private CommandBarButton _refreshButton;
1822
private CommandBarButton _statusButton;
23+
private CommandBarButton _selectionButton;
1924

2025
public RubberduckCommandBar(RubberduckParserState state, VBE vbe, IShowParserErrorsCommand command)
2126
{
@@ -36,13 +41,38 @@ private void _statusButton_Click(CommandBarButton Ctrl, ref bool CancelDefault)
3641

3742
public void SetStatusText(string value = null)
3843
{
39-
_statusButton.Caption = value ?? RubberduckUI.ResourceManager.GetString("ParserState_" + _state.Status);
44+
UiDispatcher.Invoke(() => _statusButton.Caption = value ?? RubberduckUI.ResourceManager.GetString("ParserState_" + _state.Status));
45+
}
46+
47+
public void SetSelectionText(Declaration declaration)
48+
{
49+
UiDispatcher.Invoke(() =>
50+
{
51+
if (declaration == null && _vbe.ActiveCodePane != null)
52+
{
53+
var selection = _vbe.ActiveCodePane.GetSelection();
54+
SetSelectionText(selection);
55+
}
56+
else if (declaration != null)
57+
{
58+
_selectionButton.Caption = string.Format("{0} ({1}): {2} ({3})",
59+
declaration.QualifiedName.QualifiedModuleName,
60+
declaration.QualifiedSelection.Selection,
61+
declaration.IdentifierName,
62+
RubberduckUI.ResourceManager.GetString("DeclarationType_" + declaration.DeclarationType));
63+
}
64+
});
65+
}
66+
67+
private void SetSelectionText(QualifiedSelection selection)
68+
{
69+
UiDispatcher.Invoke(() => _selectionButton.Caption = selection.ToString());
4070
}
4171

4272
private void State_StateChanged(object sender, EventArgs e)
4373
{
4474
Debug.WriteLine("RubberduckCommandBar handles StateChanged...");
45-
UiDispatcher.Invoke(() => SetStatusText(RubberduckUI.ResourceManager.GetString("ParserState_" + _state.Status)));
75+
SetStatusText(RubberduckUI.ResourceManager.GetString("ParserState_" + _state.Status));
4676
}
4777

4878
public event EventHandler Refresh;
@@ -72,6 +102,11 @@ public void Initialize()
72102
_statusButton.Tag = "Status";
73103
_statusButton.Click += _statusButton_Click;
74104

105+
_selectionButton = (CommandBarButton)commandbar.Controls.Add(MsoControlType.msoControlButton);
106+
_selectionButton.Style = MsoButtonStyle.msoButtonCaption;
107+
_selectionButton.BeginGroup = true;
108+
_selectionButton.Enabled = false;
109+
75110
commandbar.Visible = true;
76111
}
77112

RetailCoder.VBE/UI/Command/Refactorings/CodePaneRefactorRenameCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public override bool CanExecute(object parameter)
3333
}
3434

3535
var target = _state.FindSelectedDeclaration(Vbe.ActiveCodePane);
36-
return _state.Status == ParserState.Ready && target != null;
36+
return _state.Status == ParserState.Ready && target != null && !target.IsBuiltIn;
3737
}
3838

3939
public override void Execute(object parameter)

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,18 @@ public void Resolve(CancellationToken token)
279279

280280
private void ResolveInternal(CancellationToken token)
281281
{
282-
if (!_state.HasAllParseTrees)
282+
var components = _state.Projects
283+
.Where(project => project.Protection == vbext_ProjectProtection.vbext_pp_none)
284+
.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
285+
if (!_state.HasAllParseTrees(components))
283286
{
284287
return;
285288
}
286289

287290
foreach (var kvp in _state.ParseTrees)
288291
{
289292
var qualifiedName = kvp.Key;
290-
if (_force || _state.IsModified(qualifiedName))
293+
if (/*_force || _state.IsModified(qualifiedName)*/ true)
291294
{
292295
Debug.WriteLine(string.Format("Module '{0}' is new or was modified since last parse. Walking parse tree for declarations...", kvp.Key.ComponentName));
293296
// modified module; walk parse tree and re-acquire all declarations

Rubberduck.Parsing/VBA/RubberduckParserState.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,16 @@ public IParseTree GetParseTree(VBComponent component)
415415

416416
public IEnumerable<KeyValuePair<QualifiedModuleName, IParseTree>> ParseTrees { get { return _parseTrees; } }
417417

418-
public bool HasAllParseTrees { get { return _moduleStates.Count == _parseTrees.Count; } }
418+
public bool HasAllParseTrees(IReadOnlyList<VBComponent> expected)
419+
{
420+
var expectedModules = expected.Select(module => new QualifiedModuleName(module));
421+
foreach (var module in _moduleStates.Keys.Where(item => !expectedModules.Contains(item)))
422+
{
423+
ClearDeclarations(module.Component);
424+
}
425+
426+
return _parseTrees.Count == expected.Count;
427+
}
419428

420429
public TokenStreamRewriter GetRewriter(VBComponent component)
421430
{
@@ -487,11 +496,19 @@ public Declaration FindSelectedDeclaration(CodePane activeCodePane)
487496

488497
if (!selection.Equals(default(QualifiedSelection)))
489498
{
490-
_selectedDeclaration = AllDeclarations
491-
.SingleOrDefault(item => item.DeclarationType != DeclarationType.Project &&
492-
item.DeclarationType != DeclarationType.ModuleOption &&
493-
(IsSelectedDeclaration(selection, item) ||
494-
item.References.Any(reference => IsSelectedReference(selection, reference))));
499+
var matches = AllDeclarations
500+
.Where(item => item.DeclarationType != DeclarationType.Project &&
501+
item.DeclarationType != DeclarationType.ModuleOption &&
502+
(IsSelectedDeclaration(selection, item) ||
503+
item.References.Any(reference => IsSelectedReference(selection, reference))));
504+
try
505+
{
506+
_selectedDeclaration = matches.SingleOrDefault();
507+
}
508+
catch (InvalidOperationException exception)
509+
{
510+
Debug.WriteLine(exception);
511+
}
495512
}
496513

497514
if (_selectedDeclaration != null)

RubberduckTests/Inspections/ImplicitPublicMemberInspectionTests.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ public class ImplicitPublicMemberInspectionTests
1616
[TestMethod]
1717
public void ImplicitPublicMember_ReturnsResult_Sub()
1818
{
19-
const string inputCode =
20-
@"Sub Foo()
21-
End Sub";
19+
const string inputCode = @"
20+
Sub Foo()
21+
End Sub
22+
";
2223

2324
//Arrange
2425
var builder = new MockVbeBuilder();

0 commit comments

Comments
 (0)