Commit 251d981

mokhan <mokhan@ce5e1baf-6525-42e4-a1b2-857ea38da20a>
2009-03-25 02:59:42
got rid of the_application_context
git-svn-id: https://svn.xp-dev.com/svn/mokhan-mo.money@104 ce5e1baf-6525-42e4-a1b2-857ea38da20a
1 parent 5deb1be
trunk/product/MyMoney/boot/container/registration/wire_up_the_presentation_modules.cs
@@ -1,6 +1,9 @@
 using System.Reflection;
 using MoMoney.Infrastructure.Container.Windsor;
 using MoMoney.Presentation.Core;
+using MoMoney.Presentation.Model.Menu.File;
+using MoMoney.Presentation.Model.Menu.Help;
+using MoMoney.Presentation.Model.Menu.window;
 using MoMoney.Presentation.Presenters.Commands;
 using MoMoney.Utility.Core;
 using MoMoney.Utility.Extensions;
@@ -19,6 +22,10 @@ namespace MoMoney.boot.container.registration
         public void run()
         {
             registry.transient(typeof (IRunThe<>), typeof (RunThe<>));
+            registry.transient<IFileMenu, FileMenu>();
+            registry.transient<IWindowMenu, WindowMenu>();
+            registry.transient<IHelpMenu, HelpMenu>();
+
             Assembly
                 .GetExecutingAssembly()
                 .GetTypes()
trunk/product/MyMoney/boot/container/registration/wire_up_the_services_in_to_the.cs
@@ -4,7 +4,6 @@ using MoMoney.Domain.repositories;
 using MoMoney.Infrastructure.Container.Windsor;
 using MoMoney.Infrastructure.interceptors;
 using MoMoney.Infrastructure.proxies;
-using MoMoney.Presentation.Context;
 using MoMoney.Tasks.application;
 using MoMoney.Utility.Core;
 
@@ -21,7 +20,6 @@ namespace MoMoney.boot.container.registration
 
         public void run()
         {
-            registry.singleton<the_application_context, the_application_context>();
             registry.proxy(new ServiceLayerConfiguration<IBillingTasks>(
                                x =>
                                    {
trunk/product/MyMoney/boot/container/registration/wire_up_the_views_in_to_the.cs
@@ -2,7 +2,6 @@ using System.ComponentModel;
 using MoMoney.Infrastructure.Container.Windsor;
 using MoMoney.Infrastructure.interceptors;
 using MoMoney.Infrastructure.proxies;
-using MoMoney.Presentation.Context;
 using MoMoney.Presentation.Views;
 using MoMoney.Presentation.Views.billing;
 using MoMoney.Presentation.Views.dialogs;
@@ -27,9 +26,10 @@ namespace MoMoney.boot.container.registration
 
         public void run()
         {
-            register.singleton<IShell, ApplicationShell>();
+            var shell = new ApplicationShell();
+            register.singleton<IShell>(shell);
+            register.singleton(shell);
             //register.proxy(new SynchronizedViewProxyConfiguration<IShell>(), () => new ApplicationShell());
-            register.singleton<the_application_context, the_application_context>();
             register.transient<IAboutApplicationView, AboutTheApplicationView>();
             register.transient<ISplashScreenView, SplashScreenView>();
             register.transient<INavigationView, NavigationView>();
trunk/product/MyMoney/boot/global_error_handling.cs
@@ -19,7 +19,7 @@ namespace MoMoney.boot
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.ThreadException += (sender, e) => handle_error(e.Exception);
-            AppDomain.CurrentDomain.UnhandledException += ((sender, e) => handle_error(e.ExceptionObject.downcast_to<Exception>()));
+            AppDomain.CurrentDomain.UnhandledException += (sender, e) => handle_error(e.ExceptionObject.downcast_to<Exception>());
         }
 
         static void handle_error(Exception e)
trunk/product/MyMoney/boot/start_the_application.cs
@@ -3,19 +3,33 @@ using System.Windows.Forms;
 using MoMoney.Infrastructure.Container;
 using MoMoney.Infrastructure.eventing;
 using MoMoney.Infrastructure.Extensions;
-using MoMoney.Presentation.Context;
+using MoMoney.Infrastructure.interceptors;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Presentation.Presenters.Commands;
+using MoMoney.Presentation.Views.Shell;
 using MoMoney.Utility.Core;
 
 namespace MoMoney.boot
 {
     internal class start_the_application : ICommand
     {
+        ILoadPresentationModulesCommand command;
+
+        public start_the_application() : this(Lazy.load<ILoadPresentationModulesCommand>())
+        {
+        }
+
+        public start_the_application(ILoadPresentationModulesCommand command)
+        {
+            this.command = command;
+        }
+
         public void run()
         {
             try
             {
-                Application.Run(resolve.dependency_for<the_application_context>());
+                command.run();
+                Application.Run(resolve.dependency_for<ApplicationShell>());
             }
             catch (Exception e)
             {
trunk/product/MyMoney/Presentation/Context/the_application_context.cs
@@ -1,20 +0,0 @@
-using System.Windows.Forms;
-using MoMoney.Presentation.Model.Menu.File.Commands;
-using MoMoney.Presentation.Presenters.Commands;
-using MoMoney.Presentation.Views.Shell;
-using MoMoney.Utility.Extensions;
-
-namespace MoMoney.Presentation.Context
-{
-    public class the_application_context : ApplicationContext
-    {
-        public the_application_context(IShell shell_view,
-                                       IExitCommand exit_command,
-                                       ILoadPresentationModulesCommand command)
-        {
-            shell_view.downcast_to<Form>().Closed += ((sender, args) => exit_command.run());
-            MainForm = shell_view.downcast_to<Form>();
-            command.run();
-        }
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Context/the_application_context_specs.cs
@@ -1,51 +0,0 @@
-using System;
-using System.Windows.Forms;
-using developwithpassion.bdd.contexts;
-using MoMoney.Presentation.Model.Menu.File.Commands;
-using MoMoney.Presentation.Presenters.Commands;
-using MoMoney.Presentation.Views.Shell;
-using MoMoney.Testing.MetaData;
-using MoMoney.Testing.spechelpers.contexts;
-using MoMoney.Testing.spechelpers.core;
-using Rhino.Mocks;
-
-namespace MoMoney.Presentation.Context
-{
-    [Concern(typeof (the_application_context))]
-    public abstract class behaves_like_an_application_context : concerns_for<ApplicationContext, the_application_context>
-    {
-        public override ApplicationContext create_sut()
-        {
-            return new the_application_context(shell_view, exit_command, load_application);
-        }
-
-        context c = () =>
-                        {
-                            shell_view = dependency<ApplicationShell>();
-                            exit_command = the_dependency<IExitCommand>();
-                            load_application = the_dependency<ILoadPresentationModulesCommand>();
-                        };
-
-        static protected ApplicationShell shell_view;
-        static protected IExitCommand exit_command;
-        static protected ILoadPresentationModulesCommand load_application;
-    }
-
-    public class when_starting_the_application : behaves_like_an_application_context
-    {
-        it should_specify_the_main_shell_view_as_the_main_form = () => result.should_be_equal_to(shell_view);
-
-        it should_run_the_main_shell_presenter = () => load_application.was_told_to(x => x.run());
-
-        because b = () => { result = sut.MainForm; };
-
-        static Form result;
-    }
-
-    public class when_the_application_shell_is_closed : behaves_like_an_application_context
-    {
-        it should_shut_the_application_down = () => exit_command.was_told_to(x => x.run());
-
-        because b = () => shell_view.Raise(x => x.Closed += null, shell_view, EventArgs.Empty);
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/keyboard/shortcut_keys.cs โ†’ trunk/product/MyMoney/Presentation/Model/keyboard/ShortcutKeys.cs
@@ -2,7 +2,7 @@ using System.Windows.Forms;
 
 namespace MoMoney.Presentation.Model.keyboard
 {
-    public static class shortcut_keys
+    public static class ShortcutKeys
     {
         public static readonly ShortcutKey control = new ShortcutKey(Keys.Control);
         public static readonly ShortcutKey alt = new ShortcutKey(Keys.Alt);
trunk/product/MyMoney/Presentation/Model/Menu/File/FileMenu.cs
@@ -3,6 +3,7 @@ using MoMoney.Presentation.Model.keyboard;
 using MoMoney.Presentation.Model.Menu.File.Commands;
 using MoMoney.Presentation.Model.Projects;
 using MoMoney.Presentation.Resources;
+using MoMoney.Presentation.Views.Menu.Mappers;
 
 namespace MoMoney.Presentation.Model.Menu.File
 {
@@ -10,23 +11,28 @@ namespace MoMoney.Presentation.Model.Menu.File
     {
     }
 
-    public class FileMenu : IFileMenu
+    public class FileMenu : SubMenu, IFileMenu
     {
         readonly IProject project;
 
-        public FileMenu(IProject project)
+        public FileMenu(IProject project, ISubMenuToToolStripMenuItemMapper mapper) : base(mapper)
         {
             this.project = project;
         }
 
-        public IEnumerable<IMenuItem> all_menu_items()
+        public override string name
+        {
+            get { return "&File"; }
+        }
+
+        public override IEnumerable<IMenuItem> all_menu_items()
         {
             yield return Create
                 .a_menu_item()
                 .named("&New")
                 .that_executes<INewCommand>()
                 .represented_by(ApplicationIcons.NewProject)
-                .can_be_accessed_with(shortcut_keys.control.and(shortcut_keys.N))
+                .can_be_accessed_with(ShortcutKeys.control.and(ShortcutKeys.N))
                 .build();
 
             yield return Create
@@ -34,7 +40,7 @@ namespace MoMoney.Presentation.Model.Menu.File
                 .named("&Open")
                 .that_executes<IOpenCommand>()
                 .represented_by(ApplicationIcons.OpenProject)
-                .can_be_accessed_with(shortcut_keys.control.and(shortcut_keys.O))
+                .can_be_accessed_with(ShortcutKeys.control.and(ShortcutKeys.O))
                 .build();
 
             yield return Create
@@ -43,7 +49,7 @@ namespace MoMoney.Presentation.Model.Menu.File
                 .that_executes<ISaveCommand>()
                 .represented_by(ApplicationIcons.SaveProject)
                 //.can_be_clicked_when(() => project.has_unsaved_changes())
-                .can_be_accessed_with(shortcut_keys.control.and(shortcut_keys.S))
+                .can_be_accessed_with(ShortcutKeys.control.and(ShortcutKeys.S))
                 .build();
 
             yield return Create
@@ -70,10 +76,5 @@ namespace MoMoney.Presentation.Model.Menu.File
                 .represented_by(ApplicationIcons.ExitApplication)
                 .build();
         }
-
-        public string name
-        {
-            get { return "&File"; }
-        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/File/SubMenu.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using System.Windows.Forms;
+using MoMoney.Presentation.Views.Menu.Mappers;
+
+namespace MoMoney.Presentation.Model.Menu.File
+{
+    public abstract class SubMenu : ISubMenu
+    {
+        readonly ISubMenuToToolStripMenuItemMapper mapper;
+
+        protected SubMenu(ISubMenuToToolStripMenuItemMapper mapper)
+        {
+            this.mapper = mapper;
+        }
+
+        public abstract string name { get; }
+
+        public abstract IEnumerable<IMenuItem> all_menu_items();
+
+        public void add_to(MenuStrip strip)
+        {
+            strip.Items.Add(mapper.map_from(this));
+        }
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/Help/HelpMenu.cs
@@ -1,9 +1,11 @@
 using System.Collections.Generic;
+using MoMoney.Presentation.Model.Menu.File;
 using MoMoney.Presentation.Model.Menu.Help.commands;
 using MoMoney.Presentation.Presenters.Commands;
 using MoMoney.Presentation.Presenters.Shell;
 using MoMoney.Presentation.Presenters.updates;
 using MoMoney.Presentation.Resources;
+using MoMoney.Presentation.Views.Menu.Mappers;
 
 namespace MoMoney.Presentation.Model.Menu.Help
 {
@@ -11,16 +13,21 @@ namespace MoMoney.Presentation.Model.Menu.Help
     {
     }
 
-    public class HelpMenu : IHelpMenu
+    public class HelpMenu : SubMenu, IHelpMenu
     {
         readonly IRunPresenterCommand command;
 
-        public HelpMenu(IRunPresenterCommand command)
+        public HelpMenu(IRunPresenterCommand command, ISubMenuToToolStripMenuItemMapper mapper) : base(mapper)
         {
             this.command = command;
         }
 
-        public IEnumerable<IMenuItem> all_menu_items()
+        public override string name
+        {
+            get { return "&Help"; }
+        }
+
+        public override IEnumerable<IMenuItem> all_menu_items()
         {
             yield return Create
                 .a_menu_item()
@@ -43,10 +50,5 @@ namespace MoMoney.Presentation.Model.Menu.Help
                 .that_executes(() => command.run<ILogFilePresenter>())
                 .build();
         }
-
-        public string name
-        {
-            get { return "&Help"; }
-        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/window/WindowMenu.cs
@@ -1,5 +1,7 @@
 using System.Collections.Generic;
+using MoMoney.Presentation.Model.Menu.File;
 using MoMoney.Presentation.Model.Menu.File.Commands;
+using MoMoney.Presentation.Views.Menu.Mappers;
 
 namespace MoMoney.Presentation.Model.Menu.window
 {
@@ -7,14 +9,18 @@ namespace MoMoney.Presentation.Model.Menu.window
     {
     }
 
-    public class WindowMenu : IWindowMenu
+    public class WindowMenu : SubMenu, IWindowMenu
     {
-        public string name
+        public WindowMenu(ISubMenuToToolStripMenuItemMapper mapper) : base(mapper)
+        {
+        }
+
+        public override string name
         {
             get { return "&Window"; }
         }
 
-        public IEnumerable<IMenuItem> all_menu_items()
+        public override IEnumerable<IMenuItem> all_menu_items()
         {
             yield return Create
                 .a_menu_item()
trunk/product/MyMoney/Presentation/Model/Menu/ISubMenu.cs
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Windows.Forms;
 
 namespace MoMoney.Presentation.Model.Menu
 {
@@ -6,5 +7,6 @@ namespace MoMoney.Presentation.Model.Menu
     {
         string name { get; }
         IEnumerable<IMenuItem> all_menu_items();
+        void add_to(MenuStrip strip);
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/MenuItem.cs
@@ -1,6 +1,6 @@
 using System;
 using System.Windows.Forms;
-using MoMoney.Infrastructure.eventing;
+using MoMoney.Infrastructure.Extensions;
 using MoMoney.Presentation.Model.keyboard;
 using MoMoney.Presentation.Resources;
 
@@ -14,7 +14,8 @@ namespace MoMoney.Presentation.Model.Menu
 
     public class MenuItem : IMenuItem
     {
-        public MenuItem(string name, Action command, HybridIcon underlying_icon, ShortcutKey key, Func<bool> can_be_clicked)
+        public MenuItem(string name, Action command, HybridIcon underlying_icon, ShortcutKey key,
+                        Func<bool> can_be_clicked)
         {
             this.name = name;
             this.command = command;
@@ -23,31 +24,30 @@ namespace MoMoney.Presentation.Model.Menu
             this.can_be_clicked = can_be_clicked;
         }
 
-        public string name { get; private set; }
+        string name { get; set; }
         Action command { get; set; }
         HybridIcon underlying_icon { get; set; }
         ShortcutKey key { get; set; }
         readonly Func<bool> can_be_clicked;
-        ToolStripMenuItem tool_strip_menu_item;
-        System.Windows.Forms.MenuItem menu_item;
 
         public ToolStripItem build()
         {
-            tool_strip_menu_item = new ToolStripMenuItem(name);
-            tool_strip_menu_item.Click += ((o, e) => command());
-            tool_strip_menu_item.Image = underlying_icon;
-            tool_strip_menu_item.ShortcutKeys = key;
-            tool_strip_menu_item.Enabled = can_be_clicked();
-            return tool_strip_menu_item;
+            var item = new ToolStripMenuItem(name)
+                           {
+                               Image = underlying_icon,
+                               ShortcutKeys = key,
+                               Enabled = can_be_clicked()
+                           };
+            item.Click += (o, e) => command();
+            return item;
         }
 
         public System.Windows.Forms.MenuItem build_menu_item()
         {
-            menu_item = new System.Windows.Forms.MenuItem(name);
-            menu_item.Click += ((sender, e) => command());
-            menu_item.ShowShortcut = true;
-            menu_item.Enabled = can_be_clicked();
-            return menu_item;
+            var item = new System.Windows.Forms.MenuItem(name) {ShowShortcut = true, Enabled = can_be_clicked()};
+            item.Click += (sender, e) => command();
+            this.log().debug("{0} can be clicked? {1}", name, can_be_clicked());
+            return item;
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Model/Menu/MenuItemBuilder.cs
@@ -27,7 +27,7 @@ namespace MoMoney.Presentation.Model.Menu
             command_to_execute = () => { };
             this.registry = registry;
             icon = ApplicationIcons.Empty;
-            key = shortcut_keys.none;
+            key = ShortcutKeys.none;
         }
 
         public string name_of_the_menu { get; private set; }
trunk/product/MyMoney/Presentation/Model/Projects/CurrentProject.cs
@@ -16,6 +16,7 @@ namespace MoMoney.Presentation.Model.Projects
         void close_project();
         bool has_been_saved_at_least_once();
         bool has_unsaved_changes();
+        bool is_open();
     }
 
     public class CurrentProject : IProject
@@ -95,6 +96,11 @@ namespace MoMoney.Presentation.Model.Projects
             return registry.has_changes_to_commit();
         }
 
+        public bool is_open()
+        {
+            return is_project_open;
+        }
+
         void ensure_that_a_path_to_save_to_has_been_specified()
         {
             if (!has_been_saved_at_least_once())
trunk/product/MyMoney/Presentation/Presenters/Menu/ApplicationMenuModule.cs
@@ -0,0 +1,56 @@
+using MoMoney.Infrastructure.eventing;
+using MoMoney.Presentation.Core;
+using MoMoney.Presentation.Model.messages;
+using MoMoney.Presentation.Presenters.Commands;
+
+namespace MoMoney.Presentation.Presenters.Menu
+{
+    public interface IApplicationMenuModule : IPresentationModule,
+                                       IEventSubscriber<NewProjectOpened>,
+                                       IEventSubscriber<ClosingProjectEvent>,
+                                       IEventSubscriber<SavedChangesEvent>,
+                                       IEventSubscriber<UnsavedChangesEvent>
+    {
+    }
+
+    public class ApplicationMenuModule : IApplicationMenuModule
+    {
+        readonly IEventAggregator broker;
+        readonly IRunPresenterCommand command;
+
+        public ApplicationMenuModule(IEventAggregator broker, IRunPresenterCommand command)
+        {
+            this.broker = broker;
+            this.command = command;
+        }
+
+        public void run()
+        {
+            broker.subscribe_to<NewProjectOpened>(this);
+            broker.subscribe_to<ClosingProjectEvent>(this);
+            broker.subscribe_to<SavedChangesEvent>(this);
+            broker.subscribe_to<UnsavedChangesEvent>(this);
+            command.run<IApplicationMenuPresenter>();
+        }
+
+        public void notify(NewProjectOpened message)
+        {
+            command.run<IApplicationMenuPresenter>();
+        }
+
+        public void notify(ClosingProjectEvent message)
+        {
+            command.run<IApplicationMenuPresenter>();
+        }
+
+        public void notify(SavedChangesEvent message)
+        {
+            command.run<IApplicationMenuPresenter>();
+        }
+
+        public void notify(UnsavedChangesEvent message)
+        {
+            command.run<IApplicationMenuPresenter>();
+        }
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Presenters/Menu/ApplicationMenuPresenter.cs
@@ -0,0 +1,33 @@
+using System.Windows.Forms;
+using MoMoney.Presentation.Core;
+using MoMoney.Presentation.Model.Menu;
+using MoMoney.Presentation.Views.Shell;
+using MoMoney.Utility.Extensions;
+
+namespace MoMoney.Presentation.Presenters.Menu
+{
+    public interface IApplicationMenuPresenter : IPresenter
+    {
+    }
+
+    public class ApplicationMenuPresenter : IApplicationMenuPresenter
+    {
+        readonly ISubMenuRegistry registry;
+        readonly IShell shell;
+
+        public ApplicationMenuPresenter(ISubMenuRegistry registry, IShell shell)
+        {
+            this.registry = registry;
+            this.shell = shell;
+        }
+
+        public void run()
+        {
+            shell.region<MenuStrip>(x =>
+                                        {
+                                            x.Items.Clear();
+                                            registry.all().each(y => y.add_to(x));
+                                        });
+        }
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Presenters/Menu/MainMenuPresenter.cs
@@ -1,28 +0,0 @@
-using MoMoney.Presentation.Core;
-using MoMoney.Presentation.Model.Menu;
-using MoMoney.Presentation.Views.Menu;
-using MoMoney.Utility.Extensions;
-
-namespace MoMoney.Presentation.Presenters.Menu
-{
-    public interface IMainMenuPresenter : IPresentationModule
-    {
-    }
-
-    public class MainMenuPresenter : IMainMenuPresenter
-    {
-        readonly IMenuView main_menu;
-        readonly ISubMenuRegistry registry;
-
-        public MainMenuPresenter(IMenuView main_menu, ISubMenuRegistry registry)
-        {
-            this.main_menu = main_menu;
-            this.registry = registry;
-        }
-
-        public void run()
-        {
-            registry.all().each(x => main_menu.add(x));
-        }
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Presenters/Menu/MainMenuPresenterSpecs.cs
@@ -1,37 +0,0 @@
-using developwithpassion.bdd.contexts;
-using MoMoney.Presentation.Model.Menu;
-using MoMoney.Presentation.Views.Menu;
-using MoMoney.Testing.MetaData;
-using MoMoney.Testing.spechelpers.contexts;
-using MoMoney.Testing.spechelpers.core;
-
-namespace MoMoney.Presentation.Presenters.Menu
-{
-    [Concern(typeof (MainMenuPresenter))]
-    public abstract class behaves_like_the_main_menu_presenter : concerns_for<IMainMenuPresenter, MainMenuPresenter>
-    {
-        context c = () =>
-                        {
-                            main_menu = the_dependency<IMenuView>();
-                            repository = the_dependency<ISubMenuRegistry>();
-                        };
-
-        static protected ISubMenuRegistry repository;
-        static protected IMenuView main_menu;
-    }
-
-    public class when_initializing_the_main_menu_presenter : behaves_like_the_main_menu_presenter
-    {
-        context c = () =>
-                        {
-                            file_menu = an<ISubMenu>();
-                            when_the(repository).is_asked_for(x => x.all()).it_will_return(file_menu);
-                        };
-
-        because b = () => sut.run();
-
-        it should_add_each_of_the_sub_menus_to_the_main_menu = () => main_menu.was_told_to(x => x.add(file_menu));
-
-        static ISubMenu file_menu;
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Presenters/Shell/ApplicationShellPresenter.cs
@@ -1,23 +1,28 @@
 using MoMoney.Infrastructure.eventing;
 using MoMoney.Presentation.Core;
+using MoMoney.Presentation.Model.Menu.File.Commands;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Views.Shell;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
-    public interface IApplicationShellPresenter : IPresentationModule, IEventSubscriber<NewProjectOpened>,
+    public interface IApplicationShellPresenter : IPresentationModule,
+                                                  IEventSubscriber<NewProjectOpened>,
                                                   IEventSubscriber<ClosingProjectEvent>
     {
+        void shut_down();
     }
 
     public class ApplicationShellPresenter : IApplicationShellPresenter
     {
         readonly IShell shell;
         readonly IEventAggregator broker;
+        readonly IExitCommand command;
 
-        public ApplicationShellPresenter(IEventAggregator broker, IShell shell)
+        public ApplicationShellPresenter(IEventAggregator broker, IShell shell, IExitCommand command)
         {
             this.broker = broker;
+            this.command = command;
             this.shell = shell;
         }
 
@@ -25,6 +30,7 @@ namespace MoMoney.Presentation.Presenters.Shell
         {
             broker.subscribe_to<NewProjectOpened>(this);
             broker.subscribe_to<ClosingProjectEvent>(this);
+            shell.attach_to(this);
         }
 
         public void notify(NewProjectOpened message)
@@ -37,5 +43,10 @@ namespace MoMoney.Presentation.Presenters.Shell
         {
             shell.close_all_windows();
         }
+
+        public void shut_down()
+        {
+            command.run();
+        }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Views/Menu/ApplicationMenuHost.cs
@@ -1,30 +0,0 @@
-using System.Windows.Forms;
-using MoMoney.Presentation.Model.Menu;
-using MoMoney.Presentation.Views.Menu.Mappers;
-using MoMoney.Presentation.Views.Shell;
-
-namespace MoMoney.Presentation.Views.Menu
-{
-    public interface IMenuView
-    {
-        void add(ISubMenu menu_to_add);
-    }
-
-    public class ApplicationMenuHost : IMenuView
-    {
-        readonly ISubMenuToToolStripMenuItemMapper mapper;
-        readonly IShell shell;
-
-        public ApplicationMenuHost(IShell application_shell, ISubMenuToToolStripMenuItemMapper mapper)
-        {
-            this.mapper = mapper;
-            shell = application_shell;
-        }
-
-        public void add(ISubMenu menu_to_add)
-        {
-            //shell.add_to_main_menu(mapper.map_from(menu_to_add));
-            shell.region<MenuStrip>(x => x.Items.Add(mapper.map_from(menu_to_add)));
-        }
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Views/Menu/ApplicationMenuHostSpecs.cs
@@ -1,45 +0,0 @@
-using System.Windows.Forms;
-using developwithpassion.bdd.contexts;
-using MbUnit.Framework;
-using MoMoney.Presentation.Model.Menu;
-using MoMoney.Presentation.Views.Menu.Mappers;
-using MoMoney.Presentation.Views.Shell;
-using MoMoney.Testing.MetaData;
-using MoMoney.Testing.spechelpers.contexts;
-using MoMoney.Testing.spechelpers.core;
-
-namespace MoMoney.Presentation.Views.Menu
-{
-    [Concern(typeof (ApplicationMenuHost))]
-    public class behaves_like_application_menu_host : concerns_for<IMenuView, ApplicationMenuHost>
-    {
-        context c = () =>
-                        {
-                            mapper = the_dependency<ISubMenuToToolStripMenuItemMapper>();
-                            main_shell = the_dependency<IShell>();
-                        };
-
-        static protected ISubMenuToToolStripMenuItemMapper mapper;
-        static protected IShell main_shell;
-    }
-
-    [Ignore]
-    public class when_adding_sub_menus_to_the_main_menu : behaves_like_application_menu_host
-    {
-        //it should_add_the_mapped_menu_strip_item_to_the_main_menu_strip = () => main_shell.was_told_to(x => x.region<MenuStrip>((m)=>tool_strip_menu_item));
-
-        context c = () =>
-                        {
-                            mapper = the_dependency<ISubMenuToToolStripMenuItemMapper>();
-                            main_shell = the_dependency<IShell>();
-                            sub_menu = an<ISubMenu>();
-                            tool_strip_menu_item = new ToolStripMenuItem();
-                            mapper.is_told_to(x => x.map_from(sub_menu)).it_will_return(tool_strip_menu_item);
-                        };
-
-        because b = () => sut.add(sub_menu);
-
-        static ISubMenu sub_menu;
-        static ToolStripMenuItem tool_strip_menu_item;
-    }
-}
\ No newline at end of file
trunk/product/MyMoney/Presentation/Views/Shell/ApplicationShell.cs
@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.ComponentModel.Composition;
-using System.Windows.Forms;
+using MoMoney.Presentation.Presenters.Shell;
 using MoMoney.Presentation.Views.core;
 using MoMoney.Utility.Extensions;
 
@@ -12,17 +12,10 @@ namespace MoMoney.Presentation.Views.Shell
     public partial class ApplicationShell : ApplicationWindow, IShell
     {
         readonly IDictionary<string, IComponent> regions;
-        readonly NotifyIcon ux_notification_icon;
 
         public ApplicationShell()
         {
             InitializeComponent();
-            ux_notification_icon = new NotifyIcon
-                                       {
-                                           BalloonTipIcon = ToolTipIcon.Info,
-                                           BalloonTipText = "Thanks for trying out this sample application",
-                                           Visible = true,
-                                       };
             regions = new Dictionary<string, IComponent>
                           {
                               {GetType().FullName, this},
@@ -30,7 +23,7 @@ namespace MoMoney.Presentation.Views.Shell
                               {ux_dock_panel.GetType().FullName, ux_dock_panel},
                               {ux_tool_bar_strip.GetType().FullName, ux_tool_bar_strip},
                               {ux_status_bar.GetType().FullName, ux_status_bar},
-                              {ux_notification_icon.GetType().FullName, ux_notification_icon},
+                              {notification_icon.GetType().FullName, notification_icon},
                           };
         }
 
@@ -43,6 +36,11 @@ namespace MoMoney.Presentation.Views.Shell
             BringToFront();
         }
 
+        public void attach_to(IApplicationShellPresenter presenter)
+        {
+            Closed += (sender, args) => presenter.shut_down(); 
+        }
+
         public void add(IDockedContentView view)
         {
             on_ui_thread(() => view.add_to(ux_dock_panel));
trunk/product/MyMoney/Presentation/Views/Shell/ApplicationShell.Designer.cs
@@ -27,10 +27,12 @@ namespace MoMoney.Presentation.Views.Shell {
         /// </summary>
         private void InitializeComponent()
         {
+            this.components = new System.ComponentModel.Container();
             this.ux_main_menu_strip = new System.Windows.Forms.MenuStrip();
             this.ux_status_bar = new System.Windows.Forms.StatusStrip();
             this.ux_dock_panel = new WeifenLuo.WinFormsUI.Docking.DockPanel();
             this.ux_tool_bar_strip = new System.Windows.Forms.ToolStrip();
+            this.notification_icon = new System.Windows.Forms.NotifyIcon(this.components);
             this.SuspendLayout();
             // 
             // ux_main_menu_strip
@@ -38,16 +40,18 @@ namespace MoMoney.Presentation.Views.Shell {
             this.ux_main_menu_strip.Font = new System.Drawing.Font("Segoe UI", 8.25F);
             this.ux_main_menu_strip.Location = new System.Drawing.Point(0, 0);
             this.ux_main_menu_strip.Name = "ux_main_menu_strip";
-            this.ux_main_menu_strip.Size = new System.Drawing.Size(756, 24);
+            this.ux_main_menu_strip.Padding = new System.Windows.Forms.Padding(8, 2, 0, 2);
+            this.ux_main_menu_strip.Size = new System.Drawing.Size(1008, 24);
             this.ux_main_menu_strip.TabIndex = 0;
             this.ux_main_menu_strip.Text = "menuStrip1";
             // 
             // ux_status_bar
             // 
-            this.ux_status_bar.Location = new System.Drawing.Point(0, 485);
+            this.ux_status_bar.Location = new System.Drawing.Point(0, 602);
             this.ux_status_bar.Name = "ux_status_bar";
+            this.ux_status_bar.Padding = new System.Windows.Forms.Padding(1, 0, 19, 0);
             this.ux_status_bar.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
-            this.ux_status_bar.Size = new System.Drawing.Size(756, 22);
+            this.ux_status_bar.Size = new System.Drawing.Size(1008, 22);
             this.ux_status_bar.TabIndex = 2;
             this.ux_status_bar.Text = "statusStrip1";
             // 
@@ -64,10 +68,11 @@ namespace MoMoney.Presentation.Views.Shell {
             this.ux_dock_panel.DockRightPortion = 200;
             this.ux_dock_panel.DockTopPortion = 150;
             this.ux_dock_panel.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(0)));
-            this.ux_dock_panel.Location = new System.Drawing.Point(0, 52);
+            this.ux_dock_panel.Location = new System.Drawing.Point(0, 64);
+            this.ux_dock_panel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.ux_dock_panel.Name = "ux_dock_panel";
             this.ux_dock_panel.RightToLeftLayout = true;
-            this.ux_dock_panel.Size = new System.Drawing.Size(756, 433);
+            this.ux_dock_panel.Size = new System.Drawing.Size(1008, 533);
             this.ux_dock_panel.TabIndex = 3;
             // 
             // ux_tool_bar_strip
@@ -75,22 +80,31 @@ namespace MoMoney.Presentation.Views.Shell {
             this.ux_tool_bar_strip.Font = new System.Drawing.Font("Segoe UI", 8.25F);
             this.ux_tool_bar_strip.Location = new System.Drawing.Point(0, 24);
             this.ux_tool_bar_strip.Name = "ux_tool_bar_strip";
-            this.ux_tool_bar_strip.Size = new System.Drawing.Size(756, 25);
+            this.ux_tool_bar_strip.Size = new System.Drawing.Size(1008, 25);
             this.ux_tool_bar_strip.TabIndex = 6;
             this.ux_tool_bar_strip.Text = "toolStrip1";
             // 
-            // window_shell
+            // notification_icon
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.notification_icon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
+            this.notification_icon.BalloonTipText = "Thanks for trying out this sample application";
+            this.notification_icon.BalloonTipTitle = "Welcome!";
+            this.notification_icon.Text = "Thanks for trying out this sample application";
+            this.notification_icon.Visible = true;
+            // 
+            // ApplicationShell
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(756, 507);
+            this.ClientSize = new System.Drawing.Size(1008, 624);
             this.Controls.Add(this.ux_tool_bar_strip);
             this.Controls.Add(this.ux_dock_panel);
             this.Controls.Add(this.ux_status_bar);
             this.Controls.Add(this.ux_main_menu_strip);
             this.IsMdiContainer = true;
             this.MainMenuStrip = this.ux_main_menu_strip;
-            this.Name = "window_shell";
+            this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
+            this.Name = "ApplicationShell";
             this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
             this.Text = "MoMoney";
             this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
@@ -105,5 +119,6 @@ namespace MoMoney.Presentation.Views.Shell {
         private System.Windows.Forms.StatusStrip ux_status_bar;
         private WeifenLuo.WinFormsUI.Docking.DockPanel ux_dock_panel;
         private System.Windows.Forms.ToolStrip ux_tool_bar_strip;
+        private System.Windows.Forms.NotifyIcon notification_icon;
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Presentation/Views/Shell/ApplicationShell.resx
@@ -126,4 +126,7 @@
   <metadata name="ux_tool_bar_strip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
+  <metadata name="notification_icon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>467, 16</value>
+  </metadata>
 </root>
\ No newline at end of file
trunk/product/MyMoney/Presentation/Views/Shell/IShell.cs
@@ -1,12 +1,14 @@
 using System;
 using System.ComponentModel;
 using System.Windows.Forms;
+using MoMoney.Presentation.Presenters.Shell;
 using MoMoney.Presentation.Views.core;
 
 namespace MoMoney.Presentation.Views.Shell
 {
     public interface IShell : IWin32Window, ISynchronizeInvoke, IContainerControl, IBindableComponent, IDropTarget
     {
+        void attach_to(IApplicationShellPresenter presenter);
         string Text { get; set; }
         void add(IDockedContentView view);
         void region<T>(Action<T> action) where T : IComponent;
trunk/product/MyMoney/MyMoney.csproj
@@ -303,7 +303,7 @@
     <Compile Include="Presentation\Model\file_system\folder.cs" />
     <Compile Include="Presentation\Model\interaction\INotification.cs" />
     <Compile Include="Presentation\Model\interaction\notification_message.cs" />
-    <Compile Include="Presentation\Model\keyboard\shortcut_keys.cs" />
+    <Compile Include="Presentation\Model\keyboard\ShortcutKeys.cs" />
     <Compile Include="Presentation\Model\keyboard\ShortcutKey.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\CloseProjectCommand.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\close_window_command.cs" />
@@ -311,6 +311,7 @@
     <Compile Include="Presentation\Model\Menu\File\Commands\SaveChangesCommand.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\save_as_command_specs.cs" />
     <Compile Include="Presentation\Model\Menu\File\Commands\save_command_specs.cs" />
+    <Compile Include="Presentation\Model\Menu\File\SubMenu.cs" />
     <Compile Include="Presentation\Model\Menu\IToolbarButton.cs" />
     <Compile Include="Presentation\Model\Menu\IToolbarItemBuilder.cs" />
     <Compile Include="Presentation\Model\Menu\MenuItemSeparator.cs" />
@@ -377,7 +378,8 @@
     <Compile Include="Presentation\Presenters\income\dto\monthly_summary_dto.cs" />
     <Compile Include="Presentation\Presenters\income\ViewIncomeHistoryPresenter.cs" />
     <Compile Include="Presentation\Presenters\Menu\Help\about_the_application_presenter.cs" />
-    <Compile Include="Presentation\Presenters\Menu\MainMenuPresenter.cs" />
+    <Compile Include="Presentation\Presenters\Menu\ApplicationMenuModule.cs" />
+    <Compile Include="Presentation\Presenters\Menu\ApplicationMenuPresenter.cs" />
     <Compile Include="Presentation\Model\messages\new_project_opened.cs" />
     <Compile Include="Presentation\Model\messages\saved_changes_event.cs" />
     <Compile Include="Presentation\Model\messages\unsaved_changes_event.cs" />
@@ -479,7 +481,6 @@
       <DependentUpon>ViewAllIncome.cs</DependentUpon>
     </Compile>
     <Compile Include="Presentation\Databindings\listbox_extensions.cs" />
-    <Compile Include="Presentation\Views\Menu\ApplicationMenuHost.cs" />
     <Compile Include="Presentation\Views\Navigation\IMainMenuView.cs" />
     <Compile Include="Presentation\Views\Navigation\MainMenuView.cs">
       <SubType>Form</SubType>
@@ -654,8 +655,6 @@
       <DependentUpon>ApplicationShell.cs</DependentUpon>
     </Compile>
     <Compile Include="Presentation\Views\Menu\Mappers\SubMenuToToolStripMenuItemMapper.cs" />
-    <Compile Include="Presentation\Context\the_application_context_specs.cs" />
-    <Compile Include="Presentation\Context\the_application_context.cs" />
     <Compile Include="Presentation\Views\Startup\ISplashScreenView.cs" />
     <Compile Include="Presentation\Views\Startup\SplashScreenView.cs">
       <SubType>Form</SubType>
@@ -685,9 +684,7 @@
     <Compile Include="Presentation\Core\ApplicationController.cs" />
     <Compile Include="Presentation\Core\IPresenter.cs" />
     <Compile Include="Infrastructure\Container\IDependencyRegistry.cs" />
-    <Compile Include="Presentation\Presenters\Menu\MainMenuPresenterSpecs.cs" />
     <Compile Include="Presentation\Presenters\Commands\LoadPresentationModulesCommand.cs" />
-    <Compile Include="Presentation\Views\Menu\ApplicationMenuHostSpecs.cs" />
     <Compile Include="boot\bootstrap.cs" />
     <EmbeddedResource Include="Presentation\Views\AddCompanyView.resx">
       <DependentUpon>AddCompanyView.cs</DependentUpon>