Skip to content

Commit 14a5535

Browse files
committed
Clean up IntelliSenseDisplay file
Fix Automation event threading
1 parent 4af572a commit 14a5535

File tree

2 files changed

+66
-113
lines changed

2 files changed

+66
-113
lines changed

Source/ExcelDna.IntelliSense/IntelliSenseDisplay.cs

Lines changed: 57 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public IntelliSenseDisplay(SynchronizationContext syncContextMain, UIMonitor uiM
5757
_uiMonitor.StateUpdate += StateUpdate;
5858
}
5959

60+
#region Update Preview Filtering
6061
// This runs on the UIMonitor's automation thread
6162
// Allows us to enable the update to be raised on main thread
6263
// Might be raised on the main thread even if we don't enable it (other listeners might enable)
@@ -82,6 +83,36 @@ void StateUpdatePreview(object sender, UIStateUpdate update)
8283
update.EnableUpdateEvent();
8384
}
8485

86+
// Runs on the UIMonitor's automation thread - return true if we might want to process
87+
bool ShouldProcessFunctionListSelectedItemChange(string selectedItemText)
88+
{
89+
if (_descriptionToolTip?.Visible == true)
90+
return true;
91+
92+
return _functionInfoMap.ContainsKey(selectedItemText);
93+
}
94+
95+
// Runs on the UIMonitor's automation thread - return true if we might want to process
96+
bool ShouldProcessFormulaEditTextChange(string formulaPrefix)
97+
{
98+
// CAREFUL: Because of threading, this might run before FormulaEditStart!
99+
100+
if (_argumentsToolTip?.Visible == true)
101+
return true;
102+
103+
// TODO: Consolidate the check here with the FormulaMonitor
104+
var match = Regex.Match(formulaPrefix, @"^=(?<functionName>\w*)\(");
105+
if (match.Success)
106+
{
107+
string functionName = match.Groups["functionName"].Value;
108+
return _functionInfoMap.ContainsKey(functionName);
109+
}
110+
// Not interested...
111+
Debug.Print($"Not processing formula {formulaPrefix}");
112+
return false;
113+
}
114+
#endregion
115+
85116
// This runs on the main thread
86117
void StateUpdate(object sender, UIStateUpdate update)
87118
{
@@ -94,20 +125,24 @@ void StateUpdate(object sender, UIStateUpdate update)
94125
FormulaEditStart();
95126
break;
96127
case UIStateUpdate.UpdateType.FormulaEditMove:
128+
var fem = (UIState.FormulaEdit)update.NewState;
129+
FormulaEditMove(fem.EditWindowBounds, fem.ExcelTooltipBounds);
97130
break;
98131
case UIStateUpdate.UpdateType.FormulaEditMainWindowChange:
99132
UpdateMainWindow((update.NewState as UIState.FormulaEdit).MainWindow);
100133
break;
101134
case UIStateUpdate.UpdateType.FormulaEditTextChange:
102-
var fe = (UIState.FormulaEdit)update.NewState;
103-
FormulaEditTextChange(fe.FormulaPrefix, fe.EditWindowBounds, fe.ExcelTooltipBounds);
135+
var fetc = (UIState.FormulaEdit)update.NewState;
136+
FormulaEditTextChange(fetc.FormulaPrefix, fetc.EditWindowBounds, fetc.ExcelTooltipBounds);
104137
break;
105138
case UIStateUpdate.UpdateType.FunctionListShow:
106139
FunctionListShow();
107140
var fls = (UIState.FunctionList)update.NewState;
108141
FunctionListSelectedItemChange(fls.SelectedItemText, fls.SelectedItemBounds);
109142
break;
110143
case UIStateUpdate.UpdateType.FunctionListMove:
144+
var flm = (UIState.FunctionList)update.NewState;
145+
FunctionListMove(flm.SelectedItemBounds);
111146
break;
112147
case UIStateUpdate.UpdateType.FunctionListSelectedItemChange:
113148
var fl = (UIState.FunctionList)update.NewState;
@@ -151,23 +186,22 @@ void UpdateMainWindow(IntPtr mainWindow)
151186
}
152187

153188
// Runs on the main thread
154-
void FunctionListShow()
189+
void FormulaEditStart()
155190
{
156-
if (_descriptionToolTip == null)
157-
_descriptionToolTip = new ToolTipForm(_mainWindow);
191+
if (_argumentsToolTip == null)
192+
_argumentsToolTip = new ToolTipForm(_mainWindow);
158193
}
159194

160195
// Runs on the main thread
161-
void FunctionListHide()
196+
void FormulaEditEnd()
162197
{
163-
_descriptionToolTip.Hide();
198+
_argumentsToolTip.Hide();
164199
}
165200

166201
// Runs on the main thread
167-
void FormulaEditStart()
202+
void FormulaEditMove(Rect editWindowBounds, Rect excelTooltipBounds)
168203
{
169-
if (_argumentsToolTip == null)
170-
_argumentsToolTip = new ToolTipForm(_mainWindow);
204+
_argumentsToolTip.MoveToolTip((int)editWindowBounds.Left, (int)editWindowBounds.Bottom + 5);
171205
}
172206

173207
// Runs on the main thread
@@ -195,41 +229,20 @@ void FormulaEditTextChange(string formulaPrefix, Rect editWindowBounds, Rect exc
195229
_argumentsToolTip.Hide();
196230
}
197231

232+
198233
// Runs on the main thread
199-
void FormulaEditEnd()
234+
void FunctionListShow()
200235
{
201-
_argumentsToolTip.Hide();
236+
if (_descriptionToolTip == null)
237+
_descriptionToolTip = new ToolTipForm(_mainWindow);
202238
}
203239

204-
// Runs on the UIMonitor's automation thread - return true if we might want to process
205-
bool ShouldProcessFunctionListSelectedItemChange(string selectedItemText)
240+
// Runs on the main thread
241+
void FunctionListHide()
206242
{
207-
if (_descriptionToolTip?.Visible == true)
208-
return true;
209-
210-
return _functionInfoMap.ContainsKey(selectedItemText);
243+
_descriptionToolTip.Hide();
211244
}
212245

213-
// Runs on the UIMonitor's automation thread - return true if we might want to process
214-
bool ShouldProcessFormulaEditTextChange(string formulaPrefix)
215-
{
216-
// CAREFUL: Because of threading, this might run before FormulaEditStart!
217-
218-
if (_argumentsToolTip?.Visible == true)
219-
return true;
220-
221-
// TODO: Consolidate the check here with the FormulaMonitor
222-
var match = Regex.Match(formulaPrefix, @"^=(?<functionName>\w*)\(");
223-
if (match.Success)
224-
{
225-
string functionName = match.Groups["functionName"].Value;
226-
return _functionInfoMap.ContainsKey(functionName);
227-
}
228-
// Not interested...
229-
Debug.Print($"Not processing formula {formulaPrefix}");
230-
return false;
231-
}
232-
233246
// Runs on the main thread
234247
void FunctionListSelectedItemChange(string selectedItemText, Rect selectedItemBounds)
235248
{
@@ -249,58 +262,11 @@ void FunctionListSelectedItemChange(string selectedItemText, Rect selectedItemBo
249262
FunctionListHide();
250263
}
251264
}
252-
253-
//// Runs on the main thread
254-
//// TODO: Need better formula parsing story here
255-
//// Here are some ideas: http://fastexcel.wordpress.com/2013/10/27/parsing-functions-from-excel-formulas-using-vba-is-mid-or-a-byte-array-the-best-method/
256-
//void FormulaEditStateChanged(object stateChangeTypeObj)
257-
//{
258-
// var stateChangeType = (FormulaEditWatcher.StateChangeType)stateChangeTypeObj;
259-
// // Check for watcher already disposed
260-
// // CONSIDER: How to manage threading with disposal...?
261-
// if (_formulaEditWatcher == null)
262-
// return;
263-
264-
// if (stateChangeType == FormulaEditWatcher.StateChangeType.Move && _argumentsToolTip != null)
265-
// {
266-
// _argumentsToolTip.MoveToolTip(
267-
// (int)_formulaEditWatcher.EditWindowBounds.Left, (int)_formulaEditWatcher.EditWindowBounds.Bottom + 5);
268-
// return;
269-
// }
270-
271-
// Debug.Print($"^^^ FormulaEditStateChanged. CurrentPrefix: {_formulaEditWatcher.CurrentPrefix}, Thread {Thread.CurrentThread.ManagedThreadId}");
272-
// if (_formulaEditWatcher.IsEditingFormula && _formulaEditWatcher.CurrentPrefix != null)
273-
// {
274-
// string prefix = _formulaEditWatcher.CurrentPrefix;
275-
// var match = Regex.Match(prefix, @"^=(?<functionName>\w*)\(");
276-
// if (match.Success)
277-
// {
278-
// string functionName = match.Groups["functionName"].Value;
279-
280-
// IntelliSenseFunctionInfo functionInfo;
281-
// if (_functionInfoMap.TryGetValue(functionName, out functionInfo))
282-
// {
283-
// // It's ours!
284-
// if (_argumentsToolTip == null)
285-
// {
286-
// _argumentsToolTip = new ToolTipForm(_windowWatcher.MainWindow);
287-
// }
288-
289-
// // TODO: Fix this: Need to consider subformulae
290-
// int currentArgIndex = _formulaEditWatcher.CurrentPrefix.Count(c => c == ',');
291-
// _argumentsToolTip.ShowToolTip(
292-
// GetFunctionIntelliSense(functionInfo, currentArgIndex),
293-
// (int)_formulaEditWatcher.EditWindowBounds.Left, (int)_formulaEditWatcher.EditWindowBounds.Bottom + 5);
294-
// return;
295-
// }
296-
// }
297-
// }
298-
299-
// // All other paths, we just clear the box
300-
// if (_argumentsToolTip != null)
301-
// _argumentsToolTip.Hide();
302-
//}
303-
265+
266+
void FunctionListMove(Rect selectedItemBounds)
267+
{
268+
_descriptionToolTip.MoveToolTip((int)selectedItemBounds.Right + 25, (int)selectedItemBounds.Top);
269+
}
304270

305271
// TODO: Performance / efficiency - cache these somehow
306272
// TODO: Probably not a good place for LINQ !?
@@ -382,26 +348,9 @@ TextLine GetArgumentDescription(IntelliSenseFunctionInfo.ArgumentInfo argumentIn
382348
};
383349
}
384350

385-
//public void Shutdown()
386-
//{
387-
// Debug.Print("Shutdown!");
388-
// if (_current != null)
389-
// {
390-
// try
391-
// {
392-
// _current.Dispose();
393-
// }
394-
// catch (Exception ex)
395-
// {
396-
// Debug.Print("!!! Error during Shutdown: " + ex);
397-
// }
398-
399-
// _current = null;
400-
// }
401-
//}
402-
403351
public void Dispose()
404352
{
353+
// TODO: How to interact with the pending event callbacks?
405354
_syncContextMain.Send(delegate
406355
{
407356
if (_descriptionToolTip != null)

Source/ExcelDna.IntelliSense/Watchers.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,11 @@ void PopupListStructureChangedHandler(object sender, StructureChangedEventArgs e
670670
var selPat = listElement.GetCurrentPattern(SelectionPattern.Pattern) as SelectionPattern;
671671
Debug.Assert(selPat != null);
672672

673-
// TODO: Fix again to run this on our automation thread
674-
Automation.AddAutomationEventHandler(
675-
SelectionItemPattern.ElementSelectedEvent, _popupListList, TreeScope.Descendants /* was .Children */, PopupListElementSelectedHandler);
673+
_syncContextAuto.Send( _ =>
674+
{
675+
Automation.AddAutomationEventHandler(
676+
SelectionItemPattern.ElementSelectedEvent, _popupListList, TreeScope.Descendants /* was .Children */, PopupListElementSelectedHandler);
677+
}, null);
676678

677679
// Update the current selection, if any
678680
var curSel = selPat.Current.GetSelection();
@@ -698,8 +700,10 @@ void PopupListStructureChangedHandler(object sender, StructureChangedEventArgs e
698700
{
699701
if (_popupListList != null)
700702
{
701-
// TODO: Fix again to run this on our automation thread
702-
Automation.RemoveAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent, _popupListList, PopupListElementSelectedHandler);
703+
_syncContextAuto.Send( _ =>
704+
{
705+
Automation.RemoveAutomationEventHandler(SelectionItemPattern.ElementSelectedEvent, _popupListList, PopupListElementSelectedHandler);
706+
}, null);
703707
_popupListList = null;
704708
}
705709
_selectedItem = null;

0 commit comments

Comments
 (0)