OSDN Git Service

ITwitterCredentialとアクセス手段ごとの具象クラスを追加
[opentween/open-tween.git] / OpenTween / ApplicationEvents.cs
index a17cbbe..04d5a69 100644 (file)
 //           (c) 2012      Egtra (@egtra) <http://dev.activebasic.com/egtra/>
 //           (c) 2012      kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
 // All rights reserved.
-// 
+//
 // This file is part of OpenTween.
-// 
+//
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General public License as published by the Free
 // Software Foundation; either version 3 of the License, or (at your option)
 // any later version.
-// 
+//
 // This program is distributed in the hope that it will be useful, but
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
 // for more details.
-// 
+//
 // You should have received a copy of the GNU General public License along
 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
 // Boston, MA 02110-1301, USA.
 
+#nullable enable
+
 using System;
-using System.IO;
-using System.Diagnostics;
 using System.Windows.Forms;
-using System.Threading;
-using System.Globalization;
-using System.Reflection;
+using OpenTween.Connection;
+using OpenTween.Setting;
 
 namespace OpenTween
 {
-    internal class MyApplication
+    internal class ApplicationEvents
     {
         /// <summary>
+        /// 起動時に指定されたオプションを取得します
+        /// </summary>
+        public static CommandLineArgs StartupOptions { get; private set; } = null!;
+
+        /// <summary>
         /// アプリケーションのメイン エントリ ポイントです。
         /// </summary>
         [STAThread]
-        static int Main()
+        public static int Main(string[] args)
         {
-            CheckSettingFilePath();
-            InitCulture();
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
 
-            string pt = Application.ExecutablePath.Replace("\\", "/") + "/" + Application.ProductName;
-            using (Mutex mt = new Mutex(false, pt))
-            {
-                if (!mt.WaitOne(0, false))
-                {
-                    ShowPreviousWindow();
-                    return 1;
-                }
+            using var errorReportHandler = new ErrorReportHandler();
 
-                Application.ThreadException += MyApplication_UnhandledException;
+            StartupOptions = new(args);
+            InitializeTraceFrag();
 
-                Application.EnableVisualStyles();
-                Application.SetCompatibleTextRenderingDefault(false);
-                Application.Run(new TweenMain());
+            if (!ApplicationPreconditions.CheckAll())
+                return 1;
 
-                mt.ReleaseMutex();
+            var settingsPath = SettingManager.DetermineSettingsPath(StartupOptions);
+            if (MyCommon.IsNullOrEmpty(settingsPath))
+                return 1;
 
-                return 0;
-            }
-        }
+            var settings = new SettingManager(settingsPath);
+            settings.LoadAll();
 
-        private static void ShowPreviousWindow()
-        {
-            // 実行中の同じアプリケーションのウィンドウ・ハンドルの取得
-            var prevProcess = Win32Api.GetPreviousProcess();
-            if (prevProcess != null && prevProcess.MainWindowHandle == IntPtr.Zero)
-            {
-                // 起動中のアプリケーションを最前面に表示
-                Win32Api.WakeupWindow(prevProcess.MainWindowHandle);
-            }
-            else
+            using var container = new ApplicationContainer(settings);
+
+            settings.Common.Validate();
+
+            ThemeManager.ApplyGlobalUIFont(settings.Local);
+            container.CultureService.Initialize();
+
+            Networking.Initialize();
+            settings.ApplySettings();
+
+            // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する
+            using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, settings.SettingsPath);
+
+            if (mutex.InstanceExists)
             {
-                if (prevProcess != null)
-                {
-                    //プロセス特定は出来たが、ウィンドウハンドルが取得できなかった(アイコン化されている)
-                    //タスクトレイアイコンのクリックをエミュレート
-                    //注:アイコン特定はTooltipの文字列で行うため、多重起動時は先に見つけた物がアクティブになる
-                    var rslt = Win32Api.ClickTasktrayIcon(Application.ProductName);
-                    if (!rslt)
-                    {
-                        // 警告を表示(見つからない、またはその他の原因で失敗)
-                        MessageBox.Show(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
-                    }
-                }
-                else
-                {
-                    // 警告を表示(プロセス見つからない場合)
-                    MessageBox.Show(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
-                }
+                var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), ApplicationSettings.AssemblyName);
+                MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
+
+                mutex.TryActivatePreviousInstance();
+                return 1;
             }
-        }
 
-        private static void MyApplication_UnhandledException(object sender, ThreadExceptionEventArgs e)
-        {
-            //GDI+のエラー原因を特定したい
-            if (e.Exception.Message != "A generic error occurred in GDI+." &&
-               e.Exception.Message != "GDI+ で汎用エラーが発生しました。")
+            if (settings.IsIncomplete)
             {
-                if (MyCommon.ExceptionOut(e.Exception))
-                {
-                    Application.Exit();
-                }
+                var completed = ShowSettingsDialog(settings, container.IconAssetsManager);
+                if (!completed)
+                    return 1; // 設定が完了しなかったため終了
             }
-        }
 
-        private static bool IsEqualCurrentCulture(string CultureName)
-        {
-            return Thread.CurrentThread.CurrentUICulture.Name.StartsWith(CultureName);
-        }
+            SetupTwitter(container.Twitter, settings);
 
-        public static string CultureCode
-        {
-            get
-            {
-                if (MyCommon.cultureStr == null)
-                {
-                    var cfgCommon = SettingCommon.Load();
-                    MyCommon.cultureStr = cfgCommon.Language;
-                    if (MyCommon.cultureStr == "OS")
-                    {
-                        if (!IsEqualCurrentCulture("ja") &&
-                           !IsEqualCurrentCulture("en") &&
-                           !IsEqualCurrentCulture("zh-CN"))
-                        {
-                            MyCommon.cultureStr = "en";
-                        }
-                    }
-                }
-                return MyCommon.cultureStr;
-            }
+            Application.Run(container.MainForm);
+
+            return 0;
         }
 
-        public static void InitCulture(string code)
+        private static void InitializeTraceFrag()
         {
-            try
-            {
-                Thread.CurrentThread.CurrentUICulture = new CultureInfo(code);
-            }
-            catch (Exception)
-            {
-            }
+            var traceFlag = false;
+
+#if DEBUG
+            traceFlag = true;
+#endif
+
+            if (StartupOptions.ContainsKey("d"))
+                traceFlag = true;
+
+            var version = Version.Parse(MyCommon.FileVersion);
+            if (version.Build != 0)
+                traceFlag = true;
+
+            MyCommon.TraceFlag = traceFlag;
         }
-        public static void InitCulture()
+
+        private static bool ShowSettingsDialog(SettingManager settings, IconAssetsManager iconAssets)
         {
-            try
-            {
-                if (CultureCode != "OS") Thread.CurrentThread.CurrentUICulture = new CultureInfo(CultureCode);
-            }
-            catch (Exception)
-            {
-            }
+            using var settingDialog = new AppendSettingDialog();
+            settingDialog.Icon = iconAssets.IconMain;
+            settingDialog.ShowInTaskbar = true; // この時点では TweenMain が表示されていないため代わりに表示する
+            settingDialog.LoadConfig(settings.Common, settings.Local);
+
+            var ret = settingDialog.ShowDialog();
+            if (ret != DialogResult.OK)
+                return false;
+
+            settingDialog.SaveConfig(settings.Common, settings.Local);
+
+            if (settings.IsIncomplete)
+                return false;
+
+            settings.SaveAll();
+            return true;
         }
 
-        private static void CheckSettingFilePath()
+        private static void SetupTwitter(Twitter tw, SettingManager settings)
         {
-            if (File.Exists(Path.Combine(Application.StartupPath, "roaming")))
+            var account = settings.Common.SelectedAccount;
+            if (account != null)
+                tw.Initialize(account.GetTwitterCredential(), account.Username, account.UserId);
+            else
+                tw.Initialize(new TwitterCredentialNone(), "", 0L);
+
+            tw.RestrictFavCheck = settings.Common.RestrictFavCheck;
+            tw.ReadOwnPost = settings.Common.ReadOwnPost;
+
+            // アクセストークンが有効であるか確認する
+            // ここが Twitter API への最初のアクセスになるようにすること
+            try
             {
-                MyCommon.settingPath = MySpecialPath.UserAppDataPath();
+                tw.VerifyCredentials();
             }
-            else
+            catch (WebApiException ex)
             {
-                MyCommon.settingPath = Application.StartupPath;
+                MessageBox.Show(
+                    string.Format(Properties.Resources.StartupAuthError_Text, ex.Message),
+                    ApplicationSettings.ApplicationName,
+                    MessageBoxButtons.OK,
+                    MessageBoxIcon.Warning
+                );
             }
         }
     }