Skip to content

Commit 6d99b47

Browse files
committed
Merge branch 'next' of https://github.com/rubberduck-vba/Rubberduck into extractMethodRefactoring_Testing
2 parents 3acfdd1 + 9aa4d9b commit 6d99b47

File tree

136 files changed

+12374
-8635
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+12374
-8635
lines changed

README.md

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,31 @@
88
[nextBuildStatus]:https://ci.appveyor.com/api/projects/status/we3pdnkeebo4nlck/branch/next?svg=true
99
[masterBuildStatus]:https://ci.appveyor.com/api/projects/status/we3pdnkeebo4nlck/branch/master?svg=true
1010

11-
Rubberduck is a COM Add-In for the VBA IDE that makes VBA development even more enjoyable, by extending the Visual Basic Editor (VBE) with menus, toolbars and toolwindows that enable things we didn't even think were possible when we first started this project.
11+
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/rubberduck-vba/rubberduck.svg)](http://isitmaintained.com/project/rubberduck-vba/rubberduck "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/rubberduck-vba/rubberduck.svg)](http://isitmaintained.com/project/rubberduck-vba/rubberduck "Percentage of issues still open")
1212

13-
If you're learning VBA, Rubberduck can help you avoid a few common beginner mistakes, and can probably show you a trick or two - even if you're only ever writing *macros*. If you're a more advanced programmer, you will appreciate the richness of [Rubberduck's feature set](https://github.com/retailcoder/Rubberduck/wiki/Features).
14-
15-
[**Follow us on Twitter!**](https://twitter.com/rubberduckvba)
16-
17-
[**Rubberduck Wiki**](https://github.com/retailcoder/Rubberduck/wiki)
13+
> **[rubberduckvba.com](http://rubberduckvba.com)** [Wiki](https://github.com/retailcoder/Rubberduck/wiki) [Rubberduck News](https://rubberduckvba.wordpress.com/)
14+
> contact@rubberduckvba.com
15+
> Follow [@rubberduckvba](https://twitter.com/rubberduckvba) on Twitter
1816
1917
---
2018

21-
#[Contributing](https://github.com/rubberduck-vba/Rubberduck/wiki/Contributing)
19+
##What is Rubberduck?
2220

23-
If you're a C# developer looking for a fun project to contribute to, feel free to fork the project and
24-
[come meet the devs in Code Review's "VBA Rubberducking" chatroom][chat] - we'll be happy to answer your questions and help you help us!
21+
It's an add-in for the VBA IDE, the glorious *Visual Basic Editor* (VBE) - which hasn't seen an update in this century, but that's still in use everywhere around the world. Rubberduck wants to give its users access to features you would find in the VBE if it had kept up with the features of Visual Studio and other IDE's in the past, oh, *decade* or so.
2522

26-
We follow a [development branch workflow][branch], so please submit any Pull Requests to the `next` branch.
23+
Rubberduck wants to help its users write better, cleaner, maintainable code. The many **code inspections** and **refactoring tools** help harmlessly making changes to the code, and **unit testing** helps writing a *safety net* that makes it easy to know exactly what broke when you made that *small little harmless modification*.
2724

28-
[chat]:http://chat.stackexchange.com/rooms/14929
29-
[helpwanted]:https://github.com/rubberduck-vba/Rubberduck/labels/help-wanted
30-
[branch]:https://github.com/rubberduck-vba/Rubberduck/issues/288
25+
Rubberduck wants to bring VBA into the 21st century, and wants to see more open-source VBA repositories on [GitHub](https://github.com/) - VBA code and **source control** don't traditionally exactly work hand in hand; unless you've automated it, exporting each module one by one to your local repository, fetching the remote changes, re-importing every module one by one back into the project, ...is *a little bit* tedious. Rubberduck integrates Git into the IDE, and handles all the file handling behind the scenes - a bit like Visual Studio's *Team Explorer*.
3126

3227
---
3328

34-
#[Installing](https://github.com/rubberduck-vba/Rubberduck/wiki/Installing)
29+
If you're learning VBA, Rubberduck can help you avoid a few common beginner mistakes, and can probably show you a trick or two - even if you're only ever writing *macros*. If you're a more advanced programmer, you will appreciate the richness of [Rubberduck's feature set](https://github.com/retailcoder/Rubberduck/wiki/Features). See the [Installing](https://github.com/rubberduck-vba/Rubberduck/wiki/Installing) wiki page.
3530

36-
This section was moved to a dedicated wiki page.
31+
If you're a C# developer looking for a fun project to contribute to, see the [Contributing](https://github.com/rubberduck-vba/Rubberduck/wiki/Contributing) wiki page.
3732

3833
---
3934

40-
#License
35+
##License
4136

4237
Rubberduck is a COM add-in for the VBA IDE (VBE).
4338

RetailCoder.VBE/API/ParserState.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using Rubberduck.Common;
77
using Rubberduck.Parsing.VBA;
88
using Rubberduck.UI.Command.MenuItems;
9+
using Rubberduck.Parsing.Preprocessing;
10+
using System.Globalization;
911

1012
namespace Rubberduck.API
1113
{
@@ -44,15 +46,13 @@ public sealed class ParserState : IParserState, IDisposable
4446
private const string ProgId = "Rubberduck.ParserState";
4547

4648
private readonly RubberduckParserState _state;
47-
private readonly AttributeParser _attributeParser;
48-
49+
private AttributeParser _attributeParser;
4950
private RubberduckParser _parser;
5051

5152
public ParserState()
5253
{
5354
UiDispatcher.Initialize();
5455
_state = new RubberduckParserState();
55-
_attributeParser = new AttributeParser(new ModuleExporter());
5656

5757
_state.StateChanged += _state_StateChanged;
5858
}
@@ -63,8 +63,9 @@ public void Initialize(VBE vbe)
6363
{
6464
throw new InvalidOperationException("ParserState is already initialized.");
6565
}
66-
67-
_parser = new RubberduckParser(vbe, _state, _attributeParser);
66+
Func<IVBAPreprocessor> preprocessorFactory = () => new VBAPreprocessor(double.Parse(vbe.Version, CultureInfo.InvariantCulture));
67+
_attributeParser = new AttributeParser(new ModuleExporter(), preprocessorFactory);
68+
_parser = new RubberduckParser(vbe, _state, _attributeParser, preprocessorFactory);
6869
}
6970

7071
/// <summary>

RetailCoder.VBE/App.cs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Rubberduck.Common;
55
using Rubberduck.Common.Dispatch;
66
using Rubberduck.Parsing;
7+
using Rubberduck.Parsing.Symbols;
78
using Rubberduck.Parsing.VBA;
89
using Rubberduck.Settings;
910
using Rubberduck.SmartIndenter;
@@ -17,7 +18,7 @@
1718
using System.Runtime.InteropServices.ComTypes;
1819
using System.Threading.Tasks;
1920
using System.Windows.Forms;
20-
using Rubberduck.Parsing.Symbols;
21+
using Rubberduck.Common.Hotkeys;
2122

2223
namespace Rubberduck
2324
{
@@ -132,40 +133,24 @@ private bool ShouldEvaluateCanExecute(Declaration selectedDeclaration, ParserSta
132133
private void _configService_SettingsChanged(object sender, EventArgs e)
133134
{
134135
_config = _configService.LoadConfiguration();
136+
_hooks.HookHotkeys();
135137
// also updates the ShortcutKey text
136138
_appMenus.Localize();
137-
_hooks.HookHotkeys();
138139
UpdateLoggingLevel();
139140
}
140141

141142
private void UpdateLoggingLevel()
142143
{
143-
var fileRule = LogManager.Configuration.LoggingRules.Where(rule => rule.Targets.Any(t => t.Name == FILE_TARGET_NAME)).FirstOrDefault();
144-
if (fileRule == null)
145-
{
146-
return;
147-
}
148-
if (_config.UserSettings.GeneralSettings.DetailedLoggingEnabled)
149-
{
150-
// "Enable" should have been called "Add" perhaps?
151-
fileRule.EnableLoggingForLevel(LogLevel.Trace);
152-
fileRule.EnableLoggingForLevel(LogLevel.Debug);
153-
}
154-
else
155-
{
156-
fileRule.DisableLoggingForLevel(LogLevel.Trace);
157-
fileRule.DisableLoggingForLevel(LogLevel.Debug);
158-
}
159-
LogManager.ReconfigExistingLoggers();
144+
LogLevelHelper.SetMinimumLogLevel(LogLevel.FromOrdinal(_config.UserSettings.GeneralSettings.MinimumLogLevel));
160145
}
161146

162147
public void Startup()
163148
{
164149
CleanReloadConfig();
165150
_appMenus.Initialize();
151+
_hooks.HookHotkeys(); // need to hook hotkeys before we localize menus, to correctly display ShortcutTexts
166152
_appMenus.Localize();
167153
Task.Delay(1000).ContinueWith(t => UiDispatcher.Invoke(() => _parser.State.OnParseRequested(this))).ConfigureAwait(false);
168-
_hooks.HookHotkeys();
169154
UpdateLoggingLevel();
170155
}
171156

@@ -191,6 +176,8 @@ async void sink_ProjectRemoved(object sender, DispatcherEventArgs<VBProject> e)
191176
}
192177

193178
var projectId = e.Item.HelpFile;
179+
Debug.Assert(projectId != null);
180+
194181
_componentsEventsSinks.Remove(projectId);
195182
_referencesEventsSinks.Remove(projectId);
196183
_parser.State.RemoveProject(e.Item);
@@ -347,7 +334,9 @@ async void sink_ProjectRenamed(object sender, DispatcherRenamedEventArgs<VBProje
347334
}
348335

349336
_logger.Debug("Project '{0}' (ID {1}) was renamed to '{2}'.", e.OldName, e.Item.HelpFile, e.Item.Name);
350-
_parser.State.RemoveProject(e.Item.HelpFile);
337+
338+
// note: if a bug is discovered with renaming a project, it may just need to be removed and readded.
339+
351340
_parser.State.OnParseRequested(sender);
352341
}
353342

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
using System.IO;
3+
4+
namespace Rubberduck.Common
5+
{
6+
public static class ApplicationConstants
7+
{
8+
public static readonly string LOG_FOLDER_PATH = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Rubberduck", "Logs");
9+
}
10+
}

RetailCoder.VBE/Common/Hotkeys/Hotkey.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Windows.Input;
66
using Rubberduck.Common.WinAPI;
77
using NLog;
8+
using Rubberduck.UI.Command;
89

910
namespace Rubberduck.Common.Hotkeys
1011
{
@@ -58,6 +59,7 @@ public void Attach()
5859
}
5960

6061
HookKey(key, shift);
62+
SetCommandShortcutText();
6163
}
6264

6365
public void Detach()
@@ -71,6 +73,7 @@ public void Detach()
7173
Kernel32.GlobalDeleteAtom(HotkeyInfo.HookId);
7274

7375
IsAttached = false;
76+
ClearCommandShortcutText();
7477
}
7578

7679
private void HookKey(Keys key, uint shift)
@@ -90,9 +93,29 @@ private void HookKey(Keys key, uint shift)
9093

9194
HotkeyInfo = new HotkeyInfo(hookId, Combo);
9295
IsAttached = true;
96+
9397
_logger.Debug("Hotkey '{0}' hooked successfully to command '{1}'", Key, Command.GetType()); //no translation needed for Debug.Writeline
9498
}
9599

100+
private void SetCommandShortcutText()
101+
{
102+
var command = Command as CommandBase;
103+
if (command != null)
104+
{
105+
command.ShortcutText = HotkeyInfo.ToString();
106+
}
107+
}
108+
109+
private void ClearCommandShortcutText()
110+
{
111+
var command = Command as CommandBase;
112+
if (command != null)
113+
{
114+
command.ShortcutText = string.Empty;
115+
}
116+
}
117+
118+
96119
private static readonly IDictionary<char,uint> Modifiers = new Dictionary<char, uint>
97120
{
98121
{ '+', (uint)KeyModifier.SHIFT },

RetailCoder.VBE/Common/Hotkeys/HotkeyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ public override string ToString()
2525
var builder = new StringBuilder();
2626
if (_keys.HasFlag(Keys.Alt))
2727
{
28-
builder.Append("Alt");
28+
builder.Append(Rubberduck.UI.RubberduckUI.GeneralSettings_HotkeyAlt);
2929
builder.Append('+');
3030
}
3131
if (_keys.HasFlag(Keys.Control))
3232
{
33-
builder.Append("Ctrl");
33+
builder.Append(Rubberduck.UI.RubberduckUI.GeneralSettings_HotkeyCtrl);
3434
builder.Append('+');
3535
}
3636
if (_keys.HasFlag(Keys.Shift))
3737
{
38-
builder.Append("Shift");
38+
builder.Append(Rubberduck.UI.RubberduckUI.GeneralSettings_HotkeyShift);
3939
builder.Append('+');
4040
}
4141
builder.Append(_keys & ~Modifiers);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Rubberduck.Common
2+
{
3+
public interface IOperatingSystem
4+
{
5+
void ShowFolder(string folderPath);
6+
}
7+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using NLog;
2+
using NLog.Config;
3+
using System;
4+
using System.Collections.Generic;
5+
6+
namespace Rubberduck.Common
7+
{
8+
public static class LogLevelHelper
9+
{
10+
private static readonly Lazy<IEnumerable<LogLevel>> _logLevels = new Lazy<IEnumerable<LogLevel>>(GetLogLevels);
11+
12+
public static IEnumerable<LogLevel> LogLevels
13+
{
14+
get
15+
{
16+
return _logLevels.Value;
17+
}
18+
}
19+
20+
private static IEnumerable<LogLevel> GetLogLevels()
21+
{
22+
var logLevels = new List<LogLevel>();
23+
logLevels.Add(LogLevel.Off);
24+
for (int logLevelOrdinal = 0; logLevelOrdinal <= 5; logLevelOrdinal++)
25+
{
26+
logLevels.Add(LogLevel.FromOrdinal(logLevelOrdinal));
27+
}
28+
return logLevels;
29+
}
30+
31+
public static void SetMinimumLogLevel(LogLevel minimumLogLevel)
32+
{
33+
var loggingRules = LogManager.Configuration.LoggingRules;
34+
foreach (var loggingRule in loggingRules)
35+
{
36+
ClearLogLevels(loggingRule);
37+
}
38+
if (minimumLogLevel == LogLevel.Off)
39+
{
40+
LogManager.DisableLogging();
41+
LogManager.ReconfigExistingLoggers();
42+
return;
43+
}
44+
LogManager.EnableLogging();
45+
foreach (var loggingRule in loggingRules)
46+
{
47+
foreach (var logLevel in LogLevels)
48+
{
49+
if (logLevel != LogLevel.Off && logLevel >= minimumLogLevel)
50+
{
51+
loggingRule.EnableLoggingForLevel(logLevel);
52+
}
53+
}
54+
}
55+
LogManager.ReconfigExistingLoggers();
56+
}
57+
58+
private static void ClearLogLevels(LoggingRule loggingRule)
59+
{
60+
foreach (var logLevel in LogLevels)
61+
{
62+
if (logLevel != LogLevel.Off && loggingRule.IsLoggingEnabledForLevel(logLevel))
63+
{
64+
loggingRule.DisableLoggingForLevel(logLevel);
65+
}
66+
}
67+
}
68+
}
69+
}

RetailCoder.VBE/Common/RubberduckHooks.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Linq;
66
using System.Runtime.InteropServices;
7+
using System.Windows.Forms;
78
using System.Windows.Input;
89
using Microsoft.Vbe.Interop;
910
using Rubberduck.Common.Hotkeys;
@@ -106,9 +107,16 @@ private void Mouse_RawMouseInputReceived(object sender, RawMouseEventArgs e)
106107
}
107108
}
108109

110+
// keys that change the current selection.
111+
private static readonly HashSet<Keys> NavKeys = new HashSet<Keys>
112+
{
113+
Keys.Up, Keys.Down, Keys.Left, Keys.Right, Keys.PageDown, Keys.PageUp, Keys.Enter
114+
};
115+
109116
private void Keyboard_RawKeyboardInputReceived(object sender, RawKeyEventArgs e)
110117
{
111-
if (e.Message == WM.KEYUP)
118+
// note: handling *all* keys causes annoying RTrim of current line, making editing code a PITA.
119+
if (e.Message == WM.KEYUP && NavKeys.Contains((Keys)e.VKey))
112120
{
113121
OnMessageReceived(this, HookEventArgs.Empty);
114122
}

RetailCoder.VBE/Common/WinAPI/RawKeyboard.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public RawKeyboard(IntPtr hwnd, bool captureOnlyInForeground)
1010
var rid = new RawInputDevice[1];
1111
rid[0].UsagePage = HidUsagePage.GENERIC;
1212
rid[0].Usage = HidUsage.Keyboard;
13-
rid[0].Flags = (captureOnlyInForeground ? RawInputDeviceFlags.NONE : RawInputDeviceFlags.INPUTSINK) | RawInputDeviceFlags.DEVNOTIFY;
13+
rid[0].Flags = (captureOnlyInForeground ? RawInputDeviceFlags.NONE : RawInputDeviceFlags.INPUTSINK);
1414
rid[0].Target = hwnd;
1515
if (!User32.RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0])))
1616
{

0 commit comments

Comments
 (0)