diff --git a/DomainModel/Setting/AppAutoStart.cs b/DomainModel/Setting/AppAutoStart.cs index 5bd0328..98cfa06 100644 --- a/DomainModel/Setting/AppAutoStart.cs +++ b/DomainModel/Setting/AppAutoStart.cs @@ -144,7 +144,7 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting private static string GetFilePath() { var filePathMsStore = Environment.ExpandEnvironmentVariables("%LocalAppData%") + @"\Packages\Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalCache\"; - var filePathSteam = Environment.ExpandEnvironmentVariables("%AppData%") + @"\Microsoft Flight Simulator\LocalCache\"; + var filePathSteam = Environment.ExpandEnvironmentVariables("%AppData%") + @"\Microsoft Flight Simulator\"; if (Directory.Exists(filePathMsStore)) return filePathMsStore + "exe.xml"; @@ -187,5 +187,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting [XmlElement(ElementName = "Path")] public string Path { get; set; } + + [XmlElement(ElementName = "CommandLine")] + public string CommandLine { get; set; } } } diff --git a/DomainModel/Setting/DynamicLodSetting.cs b/DomainModel/Setting/DynamicLodSetting.cs index 95de666..f5545d1 100644 --- a/DomainModel/Setting/DynamicLodSetting.cs +++ b/DomainModel/Setting/DynamicLodSetting.cs @@ -23,7 +23,7 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting public int TargetedFps { get; set; } = 60; - public int FpsTolerance { get; set; } = 5; + public int FpsTolerance { get; set; } = 4; public bool TlodMinOnGround { get; set; } = true; @@ -31,13 +31,13 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting public int TlodMin { get; set; } = 50; - public int TlodMax { get; set; } = 400; + public int TlodMax { get; set; } = 200; public int CloudRecoveryTlod { get; set; } = 100; - public bool DecreaseCloudQuality { get; set; } = true; + public bool DecreaseCloudQuality { get; set; } = false; - public int OlodTop { get; set; } = 20; + public int OlodTop { get; set; } = 50; public int OlodBase { get; set; } = 200; diff --git a/DomainModel/Setting/GeneralSetting.cs b/DomainModel/Setting/GeneralSetting.cs index 7f7487d..8f036ef 100644 --- a/DomainModel/Setting/GeneralSetting.cs +++ b/DomainModel/Setting/GeneralSetting.cs @@ -1,4 +1,5 @@ -using MSFSPopoutPanelManager.Shared; +using System; +using MSFSPopoutPanelManager.Shared; using Newtonsoft.Json; namespace MSFSPopoutPanelManager.DomainModel.Setting @@ -8,6 +9,17 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting public GeneralSetting() { InitializeChildPropertyChangeBinding(); + + PropertyChanged += (_, e) => + { + if (e.PropertyName == "UseApplicationDataPath") + { + OnApplicationDataPathUpdated?.Invoke(this, UseApplicationDataPath); + ApplicationDataPath = FileIo.GetUserDataFilePath(UseApplicationDataPath); + } + }; + + ApplicationDataPath = FileIo.GetUserDataFilePath(UseApplicationDataPath); } public bool AlwaysOnTop { get; set; } = true; @@ -22,6 +34,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting public bool TurboMode { get; set; } = false; + public bool UseApplicationDataPath { get; set; } = false; + [JsonIgnore, IgnorePropertyChanged] public bool AutoStart { @@ -34,5 +48,10 @@ namespace MSFSPopoutPanelManager.DomainModel.Setting AppAutoStart.Deactivate(); } } + + [JsonIgnore] + public string ApplicationDataPath { get; set; } + + public event EventHandler OnApplicationDataPathUpdated; } } diff --git a/MainApp/App.xaml.cs b/MainApp/App.xaml.cs index 15c9509..6604a77 100644 --- a/MainApp/App.xaml.cs +++ b/MainApp/App.xaml.cs @@ -43,8 +43,10 @@ namespace MSFSPopoutPanelManager.MainApp // Setup all data storage objects SharedStorage = new SharedStorage(); SharedStorage.AppSettingData.ReadSettings(); + SharedStorage.ProfileData.AppSettingDataRef = SharedStorage.AppSettingData; SharedStorage.ProfileData.ReadProfiles(); - + FileLogger.UseApplicationDataPath = SharedStorage.AppSettingData.ApplicationSetting.GeneralSetting.UseApplicationDataPath; + // Setup dependency injections AppHost = Host.CreateDefaultBuilder() .ConfigureServices((_, services) => diff --git a/MainApp/AppUserControl/HelpDrawer.xaml b/MainApp/AppUserControl/HelpDrawer.xaml index 0c81733..9582219 100644 --- a/MainApp/AppUserControl/HelpDrawer.xaml +++ b/MainApp/AppUserControl/HelpDrawer.xaml @@ -247,14 +247,6 @@ Stroke="Gray" X2="1" /> - - - - - - diff --git a/MainApp/AppUserControl/PreferenceDrawer.xaml b/MainApp/AppUserControl/PreferenceDrawer.xaml index 56ab59e..2e18583 100644 --- a/MainApp/AppUserControl/PreferenceDrawer.xaml +++ b/MainApp/AppUserControl/PreferenceDrawer.xaml @@ -180,6 +180,40 @@ Automatically close the application when exiting MSFS. + + Folder Path to Store POPM Configuration and Profiles + + + + + + + + + + + + + Turbo Mode - - - - - - (Unsupported Feature) - - Dynamically adjust Terrain and Object Level of Details - - - - - - Enable automatic adjustments of TLOD and OLOD to get the desired targeted frame rate (FPS). - - - - - + + + + + (Unsupported Feature) + + Dynamically adjust Terrain and Object Level of Details + + + + + + Enable automatic adjustments of TLOD and OLOD to get the desired targeted frame rate (FPS). + + + + diff --git a/MainApp/AppUserControl/PreferenceDrawer.xaml.cs b/MainApp/AppUserControl/PreferenceDrawer.xaml.cs index f84f2fa..f79be60 100644 --- a/MainApp/AppUserControl/PreferenceDrawer.xaml.cs +++ b/MainApp/AppUserControl/PreferenceDrawer.xaml.cs @@ -1,7 +1,10 @@ using Microsoft.Extensions.DependencyInjection; using MSFSPopoutPanelManager.MainApp.ViewModel; +using System; using System.ComponentModel; +using System.Diagnostics; using System.Windows; +using System.Windows.Navigation; namespace MSFSPopoutPanelManager.MainApp.AppUserControl { @@ -22,5 +25,11 @@ namespace MSFSPopoutPanelManager.MainApp.AppUserControl InitializeComponent(); }; } + + private void Hyperlink_OpenDataFolder(object sender, RequestNavigateEventArgs e) + { + // ToDo: check for folder existence + Process.Start("explorer.exe",e.Uri.ToString()); + } } } \ No newline at end of file diff --git a/MainApp/AppWindow/NumPad.xaml b/MainApp/AppWindow/NumPad.xaml index 7cc9de0..05fd0ad 100644 --- a/MainApp/AppWindow/NumPad.xaml +++ b/MainApp/AppWindow/NumPad.xaml @@ -14,14 +14,27 @@ mc:Ignorable="d"> diff --git a/MainApp/AppWindow/NumPad.xaml.cs b/MainApp/AppWindow/NumPad.xaml.cs index 2665337..e618274 100644 --- a/MainApp/AppWindow/NumPad.xaml.cs +++ b/MainApp/AppWindow/NumPad.xaml.cs @@ -13,7 +13,7 @@ namespace MSFSPopoutPanelManager.MainApp.AppWindow { private readonly NumPadViewModel _viewModel; - public NumPad(Guid panelId) + public NumPad(Guid panelId, int initialWidth, int initialHeight) { InitializeComponent(); if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) @@ -30,8 +30,19 @@ namespace MSFSPopoutPanelManager.MainApp.AppWindow throw new ApplicationException("Unable to instantiate NumPad window"); _viewModel.PanelConfig.PanelHandle = new WindowInteropHelper(window).Handle; - _viewModel.PanelConfig.Width = Convert.ToInt32(Width); - _viewModel.PanelConfig.Height = Convert.ToInt32(Height); + + if (initialWidth == 0 && initialHeight == 0) + { + this.Width = 300; + this.Height = 400; + _viewModel.PanelConfig.Width = Convert.ToInt16(this.Width); + _viewModel.PanelConfig.Height = Convert.ToInt32(this.Height); + } + else + { + this.Width = initialWidth; + this.Height = initialHeight; + } }; this.MouseLeftButtonDown += NumPad_MouseLeftButtonDown; diff --git a/MainApp/ViewModel/BaseViewModel.cs b/MainApp/ViewModel/BaseViewModel.cs index 8182f63..9b86958 100644 --- a/MainApp/ViewModel/BaseViewModel.cs +++ b/MainApp/ViewModel/BaseViewModel.cs @@ -41,18 +41,5 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel get => SharedStorage.ApplicationWindow; set => SharedStorage.ApplicationWindow = value; } - - public bool LocalCompileOnly - { - get - { - #if LOCAL - return true; - #endif - - return false; - - } - } } } diff --git a/MainApp/ViewModel/HelpViewModel.cs b/MainApp/ViewModel/HelpViewModel.cs index 2e8f62f..3e4ce6d 100644 --- a/MainApp/ViewModel/HelpViewModel.cs +++ b/MainApp/ViewModel/HelpViewModel.cs @@ -16,8 +16,6 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel public ICommand DeleteAppCacheCommand { get; private set; } - public ICommand RollBackCommand { get; private set; } - public string ApplicationVersion { get; private set; } public bool IsRollBackCommandVisible { get; private set; } @@ -30,7 +28,6 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel HyperLinkCommand = new DelegateCommand(OnHyperLinkActivated); DeleteAppCacheCommand = new DelegateCommand(OnDeleteAppCache); - RollBackCommand = new DelegateCommand(OnRollBack); #if DEBUG var buildConfig = " (Debug)"; @@ -41,8 +38,6 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel #endif ApplicationVersion = $"{WindowProcessManager.GetApplicationVersion()}{buildConfig}"; - - IsRollBackCommandVisible = _helpOrchestrator.IsRollBackUpdateEnabled(); HasOrphanAppCache = _helpOrchestrator.HasOrphanAppCache(); } @@ -68,9 +63,6 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel case "Version Info": _helpOrchestrator.OpenVersionInfo(); break; - case "Open Data Folder": - _helpOrchestrator.OpenDataFolder(); - break; case "Download VCC Library": _helpOrchestrator.DownloadVccLibrary(); break; @@ -82,15 +74,5 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel _helpOrchestrator.DeleteAppCache(); HasOrphanAppCache = _helpOrchestrator.HasOrphanAppCache(); } - - private async void OnRollBack() - { - var result = await DialogHost.Show(new ConfirmationDialog($"WARNING!{Environment.NewLine}Are you sure you want to rollback to previous version of Pop Out Panel Manager (v3.4.6.0321)? All your changes since updated to v4.0.0 will be lost. Backups of user profile and application settings file from previous version of the application will be restored.", "Rollback"), "RootDialog"); - - if (result != null && result.Equals("CONFIRM")) - { - _helpOrchestrator.RollBackUpdate(); - } - } } } diff --git a/MainApp/ViewModel/OrchestratorUIHelper.cs b/MainApp/ViewModel/OrchestratorUIHelper.cs index 33e129c..bd0bc66 100644 --- a/MainApp/ViewModel/OrchestratorUIHelper.cs +++ b/MainApp/ViewModel/OrchestratorUIHelper.cs @@ -87,7 +87,7 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel { Application.Current.Dispatcher.Invoke(async () => { - var numPad = new NumPad(panelConfig.Id); + var numPad = new NumPad(panelConfig.Id, panelConfig.Width, panelConfig.Height); numPad.Show(); await Task.Run(() => diff --git a/MainApp/ViewModel/ProfileCardViewModel.cs b/MainApp/ViewModel/ProfileCardViewModel.cs index 3910d53..c93c74f 100644 --- a/MainApp/ViewModel/ProfileCardViewModel.cs +++ b/MainApp/ViewModel/ProfileCardViewModel.cs @@ -228,8 +228,8 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel PanelType = PanelType.NumPadWindow, Left = 0, Top = 0, - Width = 1920, - Height = 40, + Width = 0, + Height = 0, AutoGameRefocus = false }); } diff --git a/Orchestration/AppOrchestrator.cs b/Orchestration/AppOrchestrator.cs index 81a1b4c..67ccd1d 100644 --- a/Orchestration/AppOrchestrator.cs +++ b/Orchestration/AppOrchestrator.cs @@ -41,6 +41,25 @@ namespace MSFSPopoutPanelManager.Orchestration Task.Run(() => _flightSimOrchestrator.StartSimConnectServer()); // Start the SimConnect server _keyboardOrchestrator.Initialize(); + + AppSettingData.ApplicationSetting.GeneralSetting.OnApplicationDataPathUpdated += (_, e) => + { + AppSettingDataManager.MoveAppSettings(AppSettingData.ApplicationSetting); + ProfileDataManager.MoveProfiles(ProfileData.Profiles, e); + + FileLogger.UseApplicationDataPath = e; + + try + { + FileLogger.CloseFileLogger(); + if (Directory.Exists(FileIo.GetUserDataFilePath(!e))) + Directory.Delete(FileIo.GetUserDataFilePath(!e), true); + } + catch + { + FileLogger.WriteLog($"Unable to remove old POPM data folder. {FileIo.GetUserDataFilePath(!e)}", StatusMessageType.Error); + } + }; } public void ApplicationClose() @@ -56,7 +75,7 @@ namespace MSFSPopoutPanelManager.Orchestration private void CheckForAutoUpdate() { - var jsonPath = Path.Combine(Path.Combine(FileIo.GetUserDataFilePath(), "autoupdate.json")); + var jsonPath = Path.Combine(Path.Combine(FileIo.GetUserDataFilePath(AppSettingData.ApplicationSetting.GeneralSetting.UseApplicationDataPath), "autoupdate.json")); AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath); AutoUpdater.Synchronous = true; AutoUpdater.AppTitle = "MSFS Pop Out Panel Manager"; diff --git a/Orchestration/AppSettingData.cs b/Orchestration/AppSettingData.cs index 0d219a0..9b2123f 100644 --- a/Orchestration/AppSettingData.cs +++ b/Orchestration/AppSettingData.cs @@ -21,7 +21,7 @@ namespace MSFSPopoutPanelManager.Orchestration ApplicationSetting = new ApplicationSetting(); AppSettingDataManager.WriteAppSetting(ApplicationSetting); } - + // Auto Save data ApplicationSetting.PropertyChanged += (_, e) => { diff --git a/Orchestration/AppSettingDataManager.cs b/Orchestration/AppSettingDataManager.cs index 5dd52cb..7a1d4f9 100644 --- a/Orchestration/AppSettingDataManager.cs +++ b/Orchestration/AppSettingDataManager.cs @@ -1,8 +1,8 @@ -using System; -using MSFSPopoutPanelManager.DomainModel.DataFile; +using MSFSPopoutPanelManager.DomainModel.DataFile; using MSFSPopoutPanelManager.DomainModel.Setting; using MSFSPopoutPanelManager.Shared; using Newtonsoft.Json; +using System; using System.Diagnostics; using System.IO; @@ -18,10 +18,30 @@ namespace MSFSPopoutPanelManager.Orchestration { Debug.WriteLine("Reading application settings data file..."); - using var reader = new StreamReader(Path.Combine(FileIo.GetUserDataFilePath(), APP_SETTING_DATA_FILENAME)); + // Try to read folder path from both locations + var documentsFolderPath = Path.Combine(FileIo.GetUserDataFilePath(false), APP_SETTING_DATA_FILENAME); + var applicationDataFolderPath = Path.Combine(FileIo.GetUserDataFilePath(true), APP_SETTING_DATA_FILENAME); + string folderPath; + + if (File.Exists(applicationDataFolderPath)) + { + folderPath = applicationDataFolderPath; + FileLogger.UseApplicationDataPath = true; + } + else + { + folderPath = documentsFolderPath; + FileLogger.UseApplicationDataPath = false; + } + + using var reader = new StreamReader(folderPath); var fileContent = reader.ReadToEnd(); - return JsonConvert.DeserializeObject(fileContent).ApplicationSetting; + var appSetting = JsonConvert.DeserializeObject(fileContent).ApplicationSetting; + + appSetting.GeneralSetting.UseApplicationDataPath = folderPath.IndexOf("Roaming", StringComparison.Ordinal) > -1; + + return appSetting; } catch { @@ -33,24 +53,44 @@ namespace MSFSPopoutPanelManager.Orchestration { try { - Debug.WriteLine("Saving application settings data file..."); - - var dataFilePath = FileIo.GetUserDataFilePath(); - - if (string.IsNullOrEmpty(dataFilePath)) - throw new Exception("Unable to get app setting data file path."); - - if (!Directory.Exists(dataFilePath)) - Directory.CreateDirectory(dataFilePath); - - using var file = File.CreateText(Path.Combine(dataFilePath, APP_SETTING_DATA_FILENAME)); - var serializer = new JsonSerializer(); - serializer.Serialize(file, new AppSettingFile { ApplicationSetting = appSetting }); + CreateAppSettings(appSetting); } catch { FileLogger.WriteLog($"Unable to write app setting data file: {APP_SETTING_DATA_FILENAME}", StatusMessageType.Error); } } + + public static void MoveAppSettings(ApplicationSetting appSetting) + { + try + { + CreateAppSettings(appSetting); + + // Remove file in old path + var oldPath = FileIo.GetUserDataFilePath(!appSetting.GeneralSetting.UseApplicationDataPath); + if (File.Exists(oldPath)) + File.Delete(oldPath); + } + catch + { + FileLogger.WriteLog($"Unable to remove old app setting data folder:", StatusMessageType.Error); + } + } + + private static void CreateAppSettings(ApplicationSetting appSetting) + { + var dataFilePath = FileIo.GetUserDataFilePath(appSetting.GeneralSetting.UseApplicationDataPath); + + if (string.IsNullOrEmpty(dataFilePath)) + throw new Exception("Unable to get app setting data file path."); + + if (!Directory.Exists(dataFilePath)) + Directory.CreateDirectory(dataFilePath); + + using var file = File.CreateText(Path.Combine(dataFilePath, APP_SETTING_DATA_FILENAME)); + var serializer = new JsonSerializer(); + serializer.Serialize(file, new AppSettingFile { ApplicationSetting = appSetting }); + } } } diff --git a/Orchestration/DynamicLodOrchestrator.cs b/Orchestration/DynamicLodOrchestrator.cs index 75b2d92..ff0c937 100644 --- a/Orchestration/DynamicLodOrchestrator.cs +++ b/Orchestration/DynamicLodOrchestrator.cs @@ -3,10 +3,8 @@ using MSFSPopoutPanelManager.DomainModel.Setting; using MSFSPopoutPanelManager.Shared; using MSFSPopoutPanelManager.SimConnectAgent; using MSFSPopoutPanelManager.WindowsAgent; -using Newtonsoft.Json.Linq; using System; using System.Diagnostics; -using System.Dynamic; using System.Runtime.InteropServices; namespace MSFSPopoutPanelManager.Orchestration diff --git a/Orchestration/HelpOrchestrator.cs b/Orchestration/HelpOrchestrator.cs index c11701f..8a480ea 100644 --- a/Orchestration/HelpOrchestrator.cs +++ b/Orchestration/HelpOrchestrator.cs @@ -39,11 +39,6 @@ namespace MSFSPopoutPanelManager.Orchestration Process.Start("notepad.exe", "VERSION.md"); } - public void OpenDataFolder() - { - Process.Start("explorer.exe", Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MSFS Pop Out Panel Manager")); - } - public bool HasOrphanAppCache() { var appLocal = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); @@ -104,35 +99,5 @@ namespace MSFSPopoutPanelManager.Orchestration FileLogger.WriteLog("Delete app cache exception: " + ex.Message, StatusMessageType.Error); } } - - public void RollBackUpdate() - { - var userProfileBackupPath = Path.Combine(FileIo.GetUserDataFilePath(), "Backup-previous-version", "userprofiledata.json"); - var appSettingBackupPath = Path.Combine(FileIo.GetUserDataFilePath(), "Backup-previous-version", "appsettingdata.json"); - - var userProfilePath = Path.Combine(FileIo.GetUserDataFilePath(), "userprofiledata.json"); - var appSettingPath = Path.Combine(FileIo.GetUserDataFilePath(), "appsettingdata.json"); - - if (File.Exists(userProfileBackupPath)) - File.Copy(userProfileBackupPath, userProfilePath, true); - - if (File.Exists(appSettingBackupPath)) - File.Copy(appSettingBackupPath, appSettingPath, true); - - AutoUpdater.InstalledVersion = new Version("1.0.0.0"); - AutoUpdater.Synchronous = true; - AutoUpdater.AppTitle = "MSFS Pop Out Panel Manager"; - AutoUpdater.RunUpdateAsAdmin = false; - AutoUpdater.UpdateFormSize = new System.Drawing.Size(1024, 660); - AutoUpdater.UpdateMode = Mode.ForcedDownload; - AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/rollback.xml"); - } - - public bool IsRollBackUpdateEnabled() - { - var appSettingBackupPath = Path.Combine(FileIo.GetUserDataFilePath(), "Backup-previous-version", "appsettingdata.json"); - - return File.Exists(appSettingBackupPath); - } } } diff --git a/Orchestration/KeyboardOrchestrator.cs b/Orchestration/KeyboardOrchestrator.cs index 5994f67..1a72272 100644 --- a/Orchestration/KeyboardOrchestrator.cs +++ b/Orchestration/KeyboardOrchestrator.cs @@ -69,9 +69,13 @@ namespace MSFSPopoutPanelManager.Orchestration { Debug.WriteLine("Ends Global Keyboard Hook (Forced)"); _keyPressCaptureList = new List(); - _globalKeyboardHook.OnKeyboardPressed -= HandleGlobalKeyboardHookOnKeyboardPressed; - _globalKeyboardHook?.Dispose(); - _globalKeyboardHook = null; + + if (_globalKeyboardHook != null) + { + _globalKeyboardHook.OnKeyboardPressed -= HandleGlobalKeyboardHookOnKeyboardPressed; + _globalKeyboardHook?.Dispose(); + _globalKeyboardHook = null; + } } private void HandleGlobalKeyboardHookOnKeyboardPressed(object sender, GlobalKeyboardHookEventArgs e) diff --git a/Orchestration/PanelConfigurationOrchestrator.cs b/Orchestration/PanelConfigurationOrchestrator.cs index 86c0073..7589b03 100644 --- a/Orchestration/PanelConfigurationOrchestrator.cs +++ b/Orchestration/PanelConfigurationOrchestrator.cs @@ -209,7 +209,7 @@ namespace MSFSPopoutPanelManager.Orchestration foreach (var panel in panels) { - if (!panel.FloatingPanel.IsEnabled || panel.FullScreen) + if (!panel.FloatingPanel.IsEnabled) return; if (panel.PanelType is not (PanelType.CustomPopout or PanelType.BuiltInPopout)) diff --git a/Orchestration/ProfileData.cs b/Orchestration/ProfileData.cs index bdd911e..bd26408 100644 --- a/Orchestration/ProfileData.cs +++ b/Orchestration/ProfileData.cs @@ -19,7 +19,7 @@ namespace MSFSPopoutPanelManager.Orchestration internal FlightSimData FlightSimDataRef { private get; set; } [IgnorePropertyChanged] - internal AppSettingData AppSettingDataRef { private get; set; } + public AppSettingData AppSettingDataRef { private get; set; } public void AddProfile(string profileName) { @@ -29,7 +29,7 @@ namespace MSFSPopoutPanelManager.Orchestration Profiles.Add(newProfile); SetActiveProfile(newProfile.Id); - ProfileDataManager.WriteProfiles(Profiles); + ProfileDataManager.WriteProfiles(Profiles, AppSettingDataRef.ApplicationSetting.GeneralSetting.UseApplicationDataPath); AppSettingDataRef.ApplicationSetting.SystemSetting.LastUsedProfileId = newProfile.Id; } @@ -64,7 +64,7 @@ namespace MSFSPopoutPanelManager.Orchestration Profiles.Add(newProfile); SetActiveProfile(newProfile.Id); - ProfileDataManager.WriteProfiles(Profiles); + ProfileDataManager.WriteProfiles(Profiles, AppSettingDataRef.ApplicationSetting.GeneralSetting.UseApplicationDataPath); AppSettingDataRef.ApplicationSetting.SystemSetting.LastUsedProfileId = newProfile.Id; } @@ -99,7 +99,7 @@ namespace MSFSPopoutPanelManager.Orchestration ActiveProfile.AircraftBindings.Add(aircraft); - ProfileDataManager.WriteProfiles(Profiles); + ProfileDataManager.WriteProfiles(Profiles, AppSettingDataRef.ApplicationSetting.GeneralSetting.UseApplicationDataPath); RefreshProfile(); } @@ -110,13 +110,13 @@ namespace MSFSPopoutPanelManager.Orchestration ActiveProfile.AircraftBindings.Remove(aircraft); - ProfileDataManager.WriteProfiles(Profiles); + ProfileDataManager.WriteProfiles(Profiles, AppSettingDataRef.ApplicationSetting.GeneralSetting.UseApplicationDataPath); RefreshProfile(); } public void ReadProfiles() { - Profiles = new SortedObservableCollection(ProfileDataManager.ReadProfiles()); + Profiles = new SortedObservableCollection(ProfileDataManager.ReadProfiles(AppSettingDataRef.ApplicationSetting.GeneralSetting.UseApplicationDataPath)); Profiles.ToList().ForEach(p => p.OnProfileChanged += (_, _) => WriteProfiles()); // Detect profiles collection changes @@ -135,7 +135,7 @@ namespace MSFSPopoutPanelManager.Orchestration public void WriteProfiles() { Debug.WriteLine("Saving Data ... "); - ProfileDataManager.WriteProfiles(Profiles); + ProfileDataManager.WriteProfiles(Profiles, AppSettingDataRef.ApplicationSetting.GeneralSetting.UseApplicationDataPath); } public void SetActiveProfile(Guid id) diff --git a/Orchestration/ProfileDataManager.cs b/Orchestration/ProfileDataManager.cs index b5aed52..8f7257c 100644 --- a/Orchestration/ProfileDataManager.cs +++ b/Orchestration/ProfileDataManager.cs @@ -13,13 +13,13 @@ namespace MSFSPopoutPanelManager.Orchestration { private const string USER_PROFILE_DATA_FILENAME = "userprofiledata.json"; - public static IList ReadProfiles() + public static IList ReadProfiles(bool isRoamingPath) { try { Debug.WriteLine("Reading user profile data file..."); - using var reader = new StreamReader(Path.Combine(FileIo.GetUserDataFilePath(), USER_PROFILE_DATA_FILENAME)); + using var reader = new StreamReader(Path.Combine(FileIo.GetUserDataFilePath(isRoamingPath), USER_PROFILE_DATA_FILENAME)); var fileContent = reader.ReadToEnd(); return JsonConvert.DeserializeObject(fileContent).Profiles; @@ -30,7 +30,7 @@ namespace MSFSPopoutPanelManager.Orchestration } } - public static void WriteProfiles(IList profiles) + public static void WriteProfiles(IList profiles, bool isRoamingPath) { if (profiles == null) { @@ -40,22 +40,44 @@ namespace MSFSPopoutPanelManager.Orchestration try { - var dataFilePath = FileIo.GetUserDataFilePath(); - - if (string.IsNullOrEmpty(dataFilePath)) - throw new Exception("Unable to get user profile dat file path."); - - if (!Directory.Exists(dataFilePath)) - Directory.CreateDirectory(dataFilePath); - - using var file = File.CreateText(Path.Combine(dataFilePath, USER_PROFILE_DATA_FILENAME)); - var serializer = new JsonSerializer(); - serializer.Serialize(file, new UserProfileFile { Profiles = profiles }); + CreateProfiles(profiles, isRoamingPath); } catch { FileLogger.WriteLog($"Unable to write user data file: {USER_PROFILE_DATA_FILENAME}", StatusMessageType.Error); } } + + public static void MoveProfiles(IList profiles, bool isRoamingPath) + { + try + { + CreateProfiles(profiles, isRoamingPath); + + // Remove file in old path + var oldPath = FileIo.GetUserDataFilePath(!isRoamingPath); + if (File.Exists(oldPath)) + File.Delete(oldPath); + } + catch + { + FileLogger.WriteLog($"Unable to move user data file: {USER_PROFILE_DATA_FILENAME}", StatusMessageType.Error); + } + } + + private static void CreateProfiles(IList profiles, bool isRoamingPath) + { + var dataFilePath = FileIo.GetUserDataFilePath(isRoamingPath); + + if (string.IsNullOrEmpty(dataFilePath)) + throw new Exception("Unable to get user profile data file path."); + + if (!Directory.Exists(dataFilePath)) + Directory.CreateDirectory(dataFilePath); + + using var file = File.CreateText(Path.Combine(dataFilePath, USER_PROFILE_DATA_FILENAME)); + var serializer = new JsonSerializer(); + serializer.Serialize(file, new UserProfileFile { Profiles = profiles }); + } } } diff --git a/README.md b/README.md index 4a66f3b..7f1ca8c 100644 --- a/README.md +++ b/README.md @@ -170,4 +170,6 @@ Thank you for your super kind support of this app! [WPF CalcBinding](https://github.com/Alex141/CalcBinding) by Alexander Zinchenko -[AutoUpdater.NET](https://github.com/ravibpatel/AutoUpdater.NET) by Ravi Patel \ No newline at end of file +[AutoUpdater.NET](https://github.com/ravibpatel/AutoUpdater.NET) by Ravi Patel + +[DynamicLOD](https://github.com/Fragtality/DynamicLOD_ by Fragtality (idea and MSFS memory access code) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 101aecc..5ad2bc7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,19 +1,15 @@ -## Version 4.1.0 +## Version 4.1.1 -* Added new method to select panel source for an aircraft profile using fixed camera view instead of relying saved custom camera view. Previous method of using saved custom camera view is still available to use if desire. +* Added option to store POPM profiles and configuration files in your user's AppData Roaming folder instead of Documents folder. Hopefully, this solved the issue where OneDrive users are having issue with POPM files. -Video showing how to create a new aircraft profile using the new panel selection method: https://vimeo.com/917361559 +* Fixed POPM inability to close correctly when Keyboard Shortcuts preference is disabled. -Video showing how to update existing aircraft profile to use the new panel selection method: https://vimeo.com/917364912 +* Fixed issue where auto start option failed to retain CommandLine arguments in exe.xml file. -* Added new virtual number pad to be used for touch enabled screen. This number pad will first focus the game window before sending num pad keystroke to the game. +* Fixed issue where auto start does not work correctly for Steam version of MSFS since exe.xml file location has been moved by Steam installation. -* Added new feature to allow pop up panel as floating window. You can assign hotkeys (Ctrl-0 to Ctrl-9) to have the pop out to toggle either showing on screen or minimize. +* Added ability for full screen panel to work as floating panel. An example use case is to show and hide EFB as full screen using keyboard shortcut. -Video showing how to manage floating panel: https://vimeo.com/918153200 +* Added dynamic LOD (my own implementation of AutoFPS) - this is totally experimental and unsupported. If you decide to use this version of dynamic LOD, you don't have to run multiple apps. -* Added a new button to easily close all Pop Out Panel Manager's managed pop outs. - -* Updated keyboard shortcut feature in preference setting to allow usage of custom keyboard shortcut instead of predefined set of keyboard shortcuts. - -* Fixed few reported bugs in the application. \ No newline at end of file +* Fixed various smaller bugs. diff --git a/Shared/FileIO.cs b/Shared/FileIO.cs index d4bd46b..d4a1ee4 100644 --- a/Shared/FileIO.cs +++ b/Shared/FileIO.cs @@ -5,47 +5,38 @@ namespace MSFSPopoutPanelManager.Shared { public class FileIo { - public static string GetUserDataFilePath() + public static string GetUserDataFilePath(bool isRoamingPath) { -#if DEBUG - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MSFS Pop Out Panel Manager Debug"); -#elif LOCAL - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MSFS Pop Out Panel Manager Local"); -#else - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MSFS Pop Out Panel Manager"); -#endif + var specialFolder = isRoamingPath ? Environment.SpecialFolder.ApplicationData : Environment.SpecialFolder.MyDocuments; + return Path.Combine(Environment.GetFolderPath(specialFolder), GetBuildConfigPath()); } - public static string GetErrorLogFilePath() + public static string GetErrorLogFilePath(bool isRoamingPath) { -#if DEBUG - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager Debug\LogFiles\error.log"); -#elif LOCAL - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager Local\LogFiles\error.log"); -#else - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager\LogFiles\error.log"); -#endif + var specialFolder = isRoamingPath ? Environment.SpecialFolder.ApplicationData : Environment.SpecialFolder.MyDocuments; + return Path.Combine(Environment.GetFolderPath(specialFolder), GetBuildConfigPath(), @"LogFiles\error.log"); } - public static string GetDebugLogFilePath() + public static string GetDebugLogFilePath(bool isRoamingPath) { -#if DEBUG - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager Debug\LogFiles\debug.log"); -#elif LOCAL - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager Local\LogFiles\debug.log"); -#else - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager\LogFiles\debug.log"); -#endif + var specialFolder = isRoamingPath ? Environment.SpecialFolder.ApplicationData : Environment.SpecialFolder.MyDocuments; + return Path.Combine(Environment.GetFolderPath(specialFolder), GetBuildConfigPath(), @"LogFiles\debug.log"); } - public static string GetInfoLogFilePath() + public static string GetInfoLogFilePath(bool isRoamingPath) + { + var specialFolder = isRoamingPath ? Environment.SpecialFolder.ApplicationData : Environment.SpecialFolder.MyDocuments; + return Path.Combine(Environment.GetFolderPath(specialFolder), GetBuildConfigPath(), @"LogFiles\info.log"); + } + + private static string GetBuildConfigPath() { #if DEBUG - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager Debug\LogFiles\info.log"); + return "MSFS Pop Out Panel Manager Debug"; #elif LOCAL - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager Local\LogFiles\info.log"); + return "MSFS Pop Out Panel Manager Local"; #else - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"MSFS Pop Out Panel Manager\LogFiles\info.log"); + return "MSFS Pop Out Panel Manager"; #endif } } diff --git a/Shared/FileLogger.cs b/Shared/FileLogger.cs index 9fb058c..cf99a76 100644 --- a/Shared/FileLogger.cs +++ b/Shared/FileLogger.cs @@ -11,7 +11,7 @@ namespace MSFSPopoutPanelManager.Shared public class FileLogger { private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType); - + static FileLogger() { // Setup log4Net @@ -24,18 +24,12 @@ namespace MSFSPopoutPanelManager.Shared if (LogManager.GetRepository(Assembly.GetEntryAssembly()).GetAppenders().First() is not RollingFileAppender errorLogAppender) return; - errorLogAppender.File = FileIo.GetErrorLogFilePath(); + errorLogAppender.File = FileIo.GetErrorLogFilePath(UseApplicationDataPath); errorLogAppender.ActivateOptions(); - - //var infoLogAppender = LogManager.GetRepository(Assembly.GetEntryAssembly()).GetAppenders().Skip(1).First() as RollingFileAppender; - //infoLogAppender.File = FileIo.GetInfoLogFilePath(); - //infoLogAppender.ActivateOptions(); - - //var debugLogAppender = LogManager.GetRepository(Assembly.GetEntryAssembly()).GetAppenders().Skip(2).First() as RollingFileAppender; - //debugLogAppender.File = FileIo.GetDebugLogFilePath(); - //debugLogAppender.ActivateOptions(); } + public static bool UseApplicationDataPath { get; set; } = false; + public static void WriteLog(string message, StatusMessageType messageType) { switch (messageType) @@ -43,12 +37,12 @@ namespace MSFSPopoutPanelManager.Shared case StatusMessageType.Error: Log.Error(message); break; - //case StatusMessageType.Info: - // Log.Info(message); - // break; - //case StatusMessageType.Debug: - // Log.Debug(message); - // break; + //case StatusMessageType.Info: + // Log.Info(message); + // break; + //case StatusMessageType.Debug: + // Log.Debug(message); + // break; } } @@ -56,5 +50,10 @@ namespace MSFSPopoutPanelManager.Shared { Log.Error(message, exception); } + + public static void CloseFileLogger() + { + LogManager.ShutdownRepository(); + } } } diff --git a/SimconnectAgent/Resources/SimConnect/Managed/Microsoft.FlightSimulator.SimConnect.dll b/SimconnectAgent/Resources/SimConnect/Managed/Microsoft.FlightSimulator.SimConnect.dll index b9264d5..8ffed1c 100644 Binary files a/SimconnectAgent/Resources/SimConnect/Managed/Microsoft.FlightSimulator.SimConnect.dll and b/SimconnectAgent/Resources/SimConnect/Managed/Microsoft.FlightSimulator.SimConnect.dll differ diff --git a/SimconnectAgent/Resources/SimConnect/SimConnect.dll b/SimconnectAgent/Resources/SimConnect/SimConnect.dll index f04d61c..f6b7678 100644 Binary files a/SimconnectAgent/Resources/SimConnect/SimConnect.dll and b/SimconnectAgent/Resources/SimConnect/SimConnect.dll differ diff --git a/VERSION.md b/VERSION.md index 154c1e7..1eabd21 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1,6 +1,22 @@ # Version History
+## Version 4.1.1 + +* Added option to store POPM profiles and configuration files in your user's AppData Roaming folder instead of Documents folder. Hopefully, this solved the issue where OneDrive users are having issue with POPM files. + +* Fixed POPM inability to close correctly when Keyboard Shortcuts preference is disabled. + +* Fixed issue where auto start option failed to retain CommandLine arguments in exe.xml file. + +* Fixed issue where auto start does not work correctly for Steam version of MSFS since exe.xml file location has been moved by Steam installation. + +* Added ability for full screen panel to work as floating panel. An example use case is to show and hide EFB as full screen using keyboard shortcut. + +* Added dynamic LOD (my own implementation of AutoFPS) - this is totally experimental and unsupported. If you decide to use this version of dynamic LOD, you don't have to run multiple apps. + +* Fixed various smaller bugs. + ## Version 4.1.0 * Added new method to select panel source for an aircraft profile using fixed camera view instead of relying saved custom camera view. Previous method of using saved custom camera view is still available to use if desire.