Skip to content

Commit f997f89

Browse files
committed
Merge pull request #57 from rubberduck-vba/next
sync with main repo
2 parents 6c1136c + d195ced commit f997f89

File tree

373 files changed

+48714
-18588
lines changed

Some content is hidden

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

373 files changed

+48714
-18588
lines changed

RetailCoder.VBE/App.cs

Lines changed: 167 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
24
using System.Globalization;
35
using System.Linq;
6+
using System.Runtime.InteropServices.ComTypes;
47
using System.Threading.Tasks;
58
using System.Windows.Forms;
69
using Microsoft.Vbe.Interop;
710
using NLog;
8-
using Rubberduck.AutoSave;
911
using Rubberduck.Common;
10-
using Rubberduck.Inspections;
1112
using Rubberduck.Parsing;
1213
using Rubberduck.Parsing.VBA;
1314
using Rubberduck.Settings;
1415
using Rubberduck.SmartIndenter;
1516
using Rubberduck.UI;
1617
using Rubberduck.UI.Command.MenuItems;
17-
using Rubberduck.UI.ParserErrors;
18-
using Rubberduck.VBEditor.Extensions;
1918
using Infralution.Localization.Wpf;
19+
using Rubberduck.Common.Dispatch;
2020

2121
namespace Rubberduck
2222
{
@@ -36,6 +36,12 @@ public class App : IDisposable
3636

3737
private Configuration _config;
3838

39+
private readonly IConnectionPoint _projectsEventsConnectionPoint;
40+
private readonly int _projectsEventsCookie;
41+
42+
private readonly IDictionary<VBComponents, Tuple<IConnectionPoint, int>> _componentsEventsConnectionPoints =
43+
new Dictionary<VBComponents, Tuple<IConnectionPoint, int>>();
44+
3945
public App(VBE vbe, IMessageBox messageBox,
4046
IRubberduckParser parser,
4147
IGeneralConfigService configService,
@@ -60,9 +66,156 @@ public App(VBE vbe, IMessageBox messageBox,
6066
_parser.State.StateChanged += Parser_StateChanged;
6167
_stateBar.Refresh += _stateBar_Refresh;
6268

69+
var sink = new VBProjectsEventsSink();
70+
var connectionPointContainer = (IConnectionPointContainer)_vbe.VBProjects;
71+
var interfaceId = typeof (_dispVBProjectsEvents).GUID;
72+
connectionPointContainer.FindConnectionPoint(ref interfaceId, out _projectsEventsConnectionPoint);
73+
74+
sink.ProjectAdded += sink_ProjectAdded;
75+
sink.ProjectRemoved += sink_ProjectRemoved;
76+
sink.ProjectActivated += sink_ProjectActivated;
77+
sink.ProjectRenamed += sink_ProjectRenamed;
78+
79+
_projectsEventsConnectionPoint.Advise(sink, out _projectsEventsCookie);
80+
6381
UiDispatcher.Initialize();
6482
}
6583

84+
async void sink_ProjectRemoved(object sender, DispatcherEventArgs<VBProject> e)
85+
{
86+
Debug.WriteLine(string.Format("Project '{0}' was removed.", e.Item.Name));
87+
Tuple<IConnectionPoint, int> value;
88+
if (_componentsEventsConnectionPoints.TryGetValue(e.Item.VBComponents, out value))
89+
{
90+
value.Item1.Unadvise(value.Item2);
91+
_componentsEventsConnectionPoints.Remove(e.Item.VBComponents);
92+
93+
_parser.State.ClearDeclarations(e.Item);
94+
}
95+
}
96+
97+
async void sink_ProjectAdded(object sender, DispatcherEventArgs<VBProject> e)
98+
{
99+
if (!_parser.State.AllDeclarations.Any())
100+
{
101+
// forces menus to evaluate their CanExecute state:
102+
Parser_StateChanged(this, new ParserStateEventArgs(ParserState.Pending));
103+
_stateBar.SetStatusText();
104+
return;
105+
}
106+
107+
Debug.WriteLine(string.Format("Project '{0}' was added.", e.Item.Name));
108+
var connectionPointContainer = (IConnectionPointContainer)e.Item.VBComponents;
109+
var interfaceId = typeof(_dispVBComponentsEvents).GUID;
110+
111+
IConnectionPoint connectionPoint;
112+
connectionPointContainer.FindConnectionPoint(ref interfaceId, out connectionPoint);
113+
114+
var sink = new VBComponentsEventsSink();
115+
sink.ComponentActivated += sink_ComponentActivated;
116+
sink.ComponentAdded += sink_ComponentAdded;
117+
sink.ComponentReloaded += sink_ComponentReloaded;
118+
sink.ComponentRemoved += sink_ComponentRemoved;
119+
sink.ComponentRenamed += sink_ComponentRenamed;
120+
sink.ComponentSelected += sink_ComponentSelected;
121+
122+
int cookie;
123+
connectionPoint.Advise(sink, out cookie);
124+
125+
_componentsEventsConnectionPoints.Add(e.Item.VBComponents, Tuple.Create(connectionPoint, cookie));
126+
_parser.State.OnParseRequested(sender);
127+
}
128+
129+
async void sink_ComponentSelected(object sender, DispatcherEventArgs<VBComponent> e)
130+
{
131+
if (!_parser.State.AllDeclarations.Any())
132+
{
133+
return;
134+
}
135+
136+
Debug.WriteLine(string.Format("Component '{0}' was selected.", e.Item.Name));
137+
// do something?
138+
}
139+
140+
async void sink_ComponentRenamed(object sender, DispatcherRenamedEventArgs<VBComponent> e)
141+
{
142+
if (!_parser.State.AllDeclarations.Any())
143+
{
144+
return;
145+
}
146+
147+
Debug.WriteLine(string.Format("Component '{0}' was renamed.", e.Item.Name));
148+
149+
_parser.State.OnParseRequested(sender, e.Item);
150+
}
151+
152+
async void sink_ComponentRemoved(object sender, DispatcherEventArgs<VBComponent> e)
153+
{
154+
if (!_parser.State.AllDeclarations.Any())
155+
{
156+
return;
157+
}
158+
159+
Debug.WriteLine(string.Format("Component '{0}' was removed.", e.Item.Name));
160+
_parser.State.ClearDeclarations(e.Item);
161+
}
162+
163+
async void sink_ComponentReloaded(object sender, DispatcherEventArgs<VBComponent> e)
164+
{
165+
if (!_parser.State.AllDeclarations.Any())
166+
{
167+
return;
168+
}
169+
170+
Debug.WriteLine(string.Format("Component '{0}' was reloaded.", e.Item.Name));
171+
_parser.State.OnParseRequested(sender, e.Item);
172+
}
173+
174+
async void sink_ComponentAdded(object sender, DispatcherEventArgs<VBComponent> e)
175+
{
176+
if (!_parser.State.AllDeclarations.Any())
177+
{
178+
return;
179+
}
180+
181+
Debug.WriteLine(string.Format("Component '{0}' was added.", e.Item.Name));
182+
_parser.State.OnParseRequested(sender, e.Item);
183+
}
184+
185+
async void sink_ComponentActivated(object sender, DispatcherEventArgs<VBComponent> e)
186+
{
187+
if (!_parser.State.AllDeclarations.Any())
188+
{
189+
return;
190+
}
191+
192+
Debug.WriteLine(string.Format("Component '{0}' was activated.", e.Item.Name));
193+
// do something?
194+
}
195+
196+
async void sink_ProjectRenamed(object sender, DispatcherRenamedEventArgs<VBProject> e)
197+
{
198+
if (!_parser.State.AllDeclarations.Any())
199+
{
200+
return;
201+
}
202+
203+
Debug.WriteLine(string.Format("Project '{0}' was renamed.", e.Item.Name));
204+
_parser.State.ClearDeclarations(e.Item);
205+
_parser.State.OnParseRequested(sender);
206+
}
207+
208+
async void sink_ProjectActivated(object sender, DispatcherEventArgs<VBProject> e)
209+
{
210+
if (!_parser.State.AllDeclarations.Any())
211+
{
212+
return;
213+
}
214+
215+
Debug.WriteLine(string.Format("Project '{0}' was activated.", e.Item.Name));
216+
// do something?
217+
}
218+
66219
private Keys _firstStepHotKey;
67220
private bool _isAwaitingTwoStepKey;
68221
private bool _skipKeyUp;
@@ -137,11 +290,12 @@ private async void hooks_MessageReceived(object sender, HookEventArgs e)
137290

138291
private void _stateBar_Refresh(object sender, EventArgs e)
139292
{
140-
_parser.State.OnParseRequested();
293+
_parser.State.OnParseRequested(sender);
141294
}
142295

143-
private void Parser_StateChanged(object sender, ParserStateEventArgs e)
296+
private void Parser_StateChanged(object sender, EventArgs e)
144297
{
298+
Debug.WriteLine("App handles StateChanged ({0}), evaluating menu states...", _parser.State.Status);
145299
_appMenus.EvaluateCanExecute(_parser.State);
146300
}
147301

@@ -152,13 +306,6 @@ public void Startup()
152306
_appMenus.Initialize();
153307
_appMenus.Localize();
154308

155-
// delay to allow the VBE to properly load. HostApplication is null until then.
156-
Task.Delay(1000).ContinueWith(t =>
157-
{
158-
_parser.State.AddBuiltInDeclarations(_vbe.HostApplication());
159-
_parser.State.OnParseRequested();
160-
});
161-
162309
//_hooks.AddHook(new LowLevelKeyboardHook(_vbe));
163310
//_hooks.AddHook(new HotKey((IntPtr)_vbe.MainWindow.HWnd, "%^R", Keys.R));
164311
//_hooks.AddHook(new HotKey((IntPtr)_vbe.MainWindow.HWnd, "%^I", Keys.I));
@@ -197,11 +344,17 @@ private void LoadConfig()
197344

198345
public void Dispose()
199346
{
200-
//_hooks.MessageReceived -= hooks_MessageReceived;
201347
_configService.LanguageChanged -= ConfigServiceLanguageChanged;
202348
_parser.State.StateChanged -= Parser_StateChanged;
203349
_autoSave.Dispose();
204350

351+
_projectsEventsConnectionPoint.Unadvise(_projectsEventsCookie);
352+
foreach (var item in _componentsEventsConnectionPoints)
353+
{
354+
item.Value.Item1.Unadvise(item.Value.Item2);
355+
}
356+
357+
//_hooks.MessageReceived -= hooks_MessageReceived;
205358
//_hooks.Dispose();
206359
}
207360
}

RetailCoder.VBE/Common/ClipboardWriter.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,36 @@ namespace Rubberduck.Common
1010
public interface IClipboardWriter
1111
{
1212
void Write(string text);
13+
void AppendData(string format, object data);
14+
void Flush();
1315
}
1416

1517
public class ClipboardWriter : IClipboardWriter
1618
{
19+
private DataObject _data;
20+
1721
public void Write(string text)
1822
{
19-
Clipboard.SetText(text);
23+
this.AppendData(DataFormats.UnicodeText, text);
24+
this.Flush();
25+
}
26+
27+
public void AppendData(string format, object data)
28+
{
29+
if (_data == null)
30+
{
31+
_data = new DataObject();
32+
}
33+
_data.SetData(format, data);
34+
}
35+
36+
public void Flush()
37+
{
38+
if (_data != null)
39+
{
40+
Clipboard.SetDataObject(_data, true);
41+
_data = null;
42+
}
2043
}
2144
}
2245
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
3+
namespace Rubberduck.Common.Dispatch
4+
{
5+
public class DispatcherEventArgs<T> : EventArgs
6+
where T : class
7+
{
8+
private readonly T _item;
9+
10+
public DispatcherEventArgs(T item)
11+
{
12+
_item = item;
13+
}
14+
15+
public T Item { get { return _item; } }
16+
}
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace Rubberduck.Common.Dispatch
2+
{
3+
public class DispatcherRenamedEventArgs<T> : DispatcherEventArgs<T>
4+
where T : class
5+
{
6+
private readonly string _oldName;
7+
8+
public DispatcherRenamedEventArgs(T item, string oldName)
9+
: base(item)
10+
{
11+
_oldName = oldName;
12+
}
13+
14+
public string OldName { get { return _oldName; } }
15+
}
16+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using Microsoft.Vbe.Interop;
3+
4+
namespace Rubberduck.Common.Dispatch
5+
{
6+
public class ReferencesEventsSink : _dispReferencesEvents
7+
{
8+
public event EventHandler<DispatcherEventArgs<Reference>> ReferenceAdded;
9+
public void ItemAdded(Reference Reference)
10+
{
11+
OnDispatch(ReferenceAdded, Reference);
12+
}
13+
14+
public event EventHandler<DispatcherEventArgs<Reference>> ReferenceRemoved;
15+
public void ItemRemoved(Reference Reference)
16+
{
17+
OnDispatch(ReferenceRemoved, Reference);
18+
}
19+
20+
private void OnDispatch(EventHandler<DispatcherEventArgs<Reference>> dispatched, Reference reference)
21+
{
22+
var handler = dispatched;
23+
if (handler != null)
24+
{
25+
handler.Invoke(this, new DispatcherEventArgs<Reference>(reference));
26+
}
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)