aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common/UI/BaseApplication.cs
blob: e22eed1583b328721cb8eae173501623a0e06989 (plain)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
using MediaBrowser.Common.Kernel;
using MediaBrowser.Common.Logging;
using MediaBrowser.Model.Progress;
using Microsoft.Shell;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;

namespace MediaBrowser.Common.UI
{
    /// <summary>
    /// Serves as a base Application class for both the UI and Server apps.
    /// </summary>
    public abstract class BaseApplication : Application, INotifyPropertyChanged, ISingleInstanceApp
    {
        private IKernel Kernel { get; set; }

        protected abstract IKernel InstantiateKernel();
        protected abstract Window InstantiateMainWindow();

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            // Without this the app will shutdown after the splash screen closes
            ShutdownMode = ShutdownMode.OnExplicitShutdown;

            LoadKernel();
        }

        private async void LoadKernel()
        {
            Kernel = InstantiateKernel();

            var progress = new Progress<TaskProgress>();

            progress.ProgressChanged += progress_ProgressChanged;
            
            var splash = new Splash(progress);

            splash.Show();

            try
            {
                DateTime now = DateTime.UtcNow;

                await Kernel.Init(progress);

                progress.ProgressChanged -= progress_ProgressChanged;
                
                Logger.LogInfo("Kernel.Init completed in {0} seconds.", (DateTime.UtcNow - now).TotalSeconds);
                splash.Close();

                ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose;

                OnKernelLoaded();

                InstantiateMainWindow().Show();
            }
            catch (Exception ex)
            {
                progress.ProgressChanged -= progress_ProgressChanged;
                
                if (Logger.LoggerInstance != null)
                {
                    Logger.LogException(ex);
                }

                MessageBox.Show("There was an error launching Media Browser: " + ex.Message);
                splash.Close();

                // Shutdown the app with an error code
                Shutdown(1);
            }
        }

        public async Task ReloadKernel()
        {
            var progress = new Progress<TaskProgress>();

            progress.ProgressChanged += progress_ProgressChanged;

            try
            {
                DateTime now = DateTime.UtcNow;

                await Kernel.Reload(progress);

                progress.ProgressChanged -= progress_ProgressChanged;

                Logger.LogInfo("Kernel.Reload completed in {0} seconds.", (DateTime.UtcNow - now).TotalSeconds);
            }
            catch (Exception ex)
            {
                progress.ProgressChanged -= progress_ProgressChanged;

                Logger.LogException(ex);

                // Shutdown the app with an error code
                Shutdown(1);
            }
        }

        void progress_ProgressChanged(object sender, TaskProgress e)
        {
            if (Logger.LoggerInstance != null)
            {
                Logger.LogInfo(e.Description);
            }
        }

        protected virtual void OnKernelLoaded()
        {

        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);

            Kernel.Dispose();
        }

        public bool SignalExternalCommandLineArgs(IList<string> args)
        {
            OnSecondInstanceLaunched(args);

            return true;
        }

        protected virtual void OnSecondInstanceLaunched(IList<string> args)
        {
            if (this.MainWindow.WindowState == WindowState.Minimized)
            {
                this.MainWindow.WindowState = WindowState.Maximized;
            }            
        }

        public static void RunApplication<TApplicationType>(string uniqueKey)
            where TApplicationType : BaseApplication, IApplication, new()
        {
            if (SingleInstance<TApplicationType>.InitializeAsFirstInstance(uniqueKey))
            {
                var application = new TApplicationType();
                application.InitializeComponent();

                application.Run();

                // Allow single instance code to perform cleanup operations
                SingleInstance<TApplicationType>.Cleanup();
            }
        }
    }

    public interface IApplication
    {
        void InitializeComponent();
    }
}