-
Notifications
You must be signed in to change notification settings - Fork 295
/
AppMenu.cs
108 lines (93 loc) · 3.36 KB
/
AppMenu.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using Rubberduck.Parsing;
using Rubberduck.Parsing.VBA;
using Rubberduck.UI;
using Rubberduck.UI.Command.MenuItems;
using Rubberduck.UI.Command.MenuItems.CommandBars;
using Rubberduck.UI.Command.MenuItems.ParentMenus;
namespace Rubberduck
{
public class AppMenu : IAppMenu, IDisposable
{
private readonly IReadOnlyList<IParentMenuItem> _menus;
private readonly IParseCoordinator _parser;
private readonly ISelectionChangeService _selectionService;
private readonly RubberduckCommandBar _stateBar;
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
public AppMenu(IEnumerable<IParentMenuItem> menus, IParseCoordinator parser, ISelectionChangeService selectionService, RubberduckCommandBar stateBar)
{
_menus = menus.ToList();
_parser = parser;
_selectionService = selectionService;
_stateBar = stateBar;
_parser.State.StateChanged += OnParserStateChanged;
_selectionService.SelectedDeclarationChanged += OnSelectedDeclarationChange;
}
public void Initialize()
{
_stateBar.Initialize();
foreach (var menu in _menus)
{
menu.Initialize();
}
EvaluateCanExecute(_parser.State);
}
public void OnSelectedDeclarationChange(object sender, DeclarationChangedEventArgs e)
{
EvaluateCanExecute(_parser.State);
}
private void OnParserStateChanged(object sender, EventArgs e)
{
EvaluateCanExecute(_parser.State);
}
public void EvaluateCanExecute(RubberduckParserState state)
{
foreach (var menu in _menus)
{
menu.EvaluateCanExecute(state);
}
}
public void Localize()
{
_stateBar.Localize();
_stateBar.SetStatusLabelCaption(_parser.State.Status);
foreach (var menu in _menus)
{
menu.Localize();
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool _isDisposed;
protected virtual void Dispose(bool disposing)
{
if (_isDisposed || !disposing)
{
return;
}
_isDisposed = true;
_parser.State.StateChanged -= OnParserStateChanged;
_selectionService.SelectedDeclarationChanged -= OnSelectedDeclarationChange;
RemoveMenus();
}
private void RemoveMenus()
{
foreach (var menu in _menus.Where(menu => menu.Item != null))
{
_logger.Debug($"Starting removal of top-level menu {menu.GetType()}.");
menu.RemoveMenu();
//We do this here and not in the menu items because we only want to dispose of/release the parents of the top level parent menus.
//The parents further down get disposed of/released as part of the remove chain.
_logger.Trace($"Removing parent menu of top-level menu {menu.GetType()}.");
menu.Parent.Dispose();
menu.Parent = null;
}
}
}
}