From 4acc73ac19b62a10005035db87787ea085855097 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sun, 12 Nov 2017 11:32:19 -0600 Subject: [PATCH] did some refactoring to consolidate connection loading into a single service --- .../App/Initialization/CredsAndConsSetup.cs | 2 +- mRemoteV1/App/Runtime.cs | 36 ++--- .../Connections/ConnectionsLoadedEventArgs.cs | 57 ++++++++ .../Config/Connections/ConnectionsLoader.cs | 25 ++-- .../Multiuser/RemoteConnectionsSyncronizer.cs | 4 +- mRemoteV1/Connection/ConnectionsService.cs | 137 ++++++++++++------ mRemoteV1/UI/Forms/frmMain.cs | 16 +- mRemoteV1/UI/Menu/MainFileMenu.cs | 2 +- mRemoteV1/mRemoteV1.csproj | 3 +- 9 files changed, 195 insertions(+), 87 deletions(-) create mode 100644 mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs diff --git a/mRemoteV1/App/Initialization/CredsAndConsSetup.cs b/mRemoteV1/App/Initialization/CredsAndConsSetup.cs index 04bff55c..a9f08c9f 100644 --- a/mRemoteV1/App/Initialization/CredsAndConsSetup.cs +++ b/mRemoteV1/App/Initialization/CredsAndConsSetup.cs @@ -7,7 +7,7 @@ namespace mRemoteNG.App.Initialization public void LoadCredsAndCons() { if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(Runtime.ConnectionsService.GetStartupConnectionFileName())) - Runtime.ConnectionsService.NewConnections(Runtime.ConnectionsService.GetStartupConnectionFileName()); + Runtime.ConnectionsService.NewConnectionsFile(Runtime.ConnectionsService.GetStartupConnectionFileName()); Runtime.LoadConnections(); } diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index d7449c4b..70878db2 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -7,6 +7,7 @@ using mRemoteNG.App.Info; using mRemoteNG.Config.Connections; using mRemoteNG.Config.Connections.Multiuser; using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Putty; using mRemoteNG.Connection; using mRemoteNG.Credential; using mRemoteNG.Credential.Repositories; @@ -44,7 +45,7 @@ namespace mRemoteNG.App public static ExternalToolsService ExternalToolsService { get; } = new ExternalToolsService(); public static SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString(); public static ICredentialRepositoryList CredentialProviderCatalog { get; } = new CredentialRepositoryList(); - public static ConnectionsService ConnectionsService { get; } = new ConnectionsService(); + public static ConnectionsService ConnectionsService { get; } = new ConnectionsService(PuttySessionsManager.Instance); #region Connections Loading/Saving public static void LoadConnectionsAsync() @@ -64,7 +65,8 @@ namespace mRemoteNG.App public static void LoadConnections(bool withDialog = false) { - var connectionsLoader = new ConnectionsLoader(); + var connectionFileName = ""; + try { // disable sql update checking while we are loading updates @@ -76,22 +78,21 @@ namespace mRemoteNG.App { var loadDialog = DialogFactory.BuildLoadConnectionsDialog(); if (loadDialog.ShowDialog() != DialogResult.OK) return; - connectionsLoader.ConnectionFileName = loadDialog.FileName; + connectionFileName = loadDialog.FileName; } else { - connectionsLoader.ConnectionFileName = ConnectionsService.GetStartupConnectionFileName(); + connectionFileName = ConnectionsService.GetStartupConnectionFileName(); } var backupFileCreator = new FileBackupCreator(); - backupFileCreator.CreateBackupFile(connectionsLoader.ConnectionFileName); + backupFileCreator.CreateBackupFile(connectionFileName); var backupPruner = new FileBackupPruner(); - backupPruner.PruneBackupFiles(connectionsLoader.ConnectionFileName); + backupPruner.PruneBackupFiles(connectionFileName); } - connectionsLoader.UseDatabase = Settings.Default.UseSQLServer; - ConnectionsService.ConnectionTreeModel = connectionsLoader.LoadConnections(false); + ConnectionsService.ConnectionTreeModel = ConnectionsService.LoadConnections(Settings.Default.UseSQLServer, false, connectionFileName); Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionsService.ConnectionTreeModel; if (Settings.Default.UseSQLServer) @@ -100,14 +101,14 @@ namespace mRemoteNG.App } else { - if (connectionsLoader.ConnectionFileName == ConnectionsService.GetDefaultStartupConnectionFileName()) + if (connectionFileName == ConnectionsService.GetDefaultStartupConnectionFileName()) { Settings.Default.LoadConsFromCustomLocation = false; } else { Settings.Default.LoadConsFromCustomLocation = true; - Settings.Default.CustomConsPath = connectionsLoader.ConnectionFileName; + Settings.Default.CustomConsPath = connectionFileName; } } @@ -137,7 +138,7 @@ namespace mRemoteNG.App } if (ex is FileNotFoundException && !withDialog) { - MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoader.ConnectionFileName), ex, MessageClass.InformationMsg); + MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), ex, MessageClass.InformationMsg); string[] commandButtons = { @@ -147,7 +148,7 @@ namespace mRemoteNG.App Language.strMenuExit }; - bool answered = false; + var answered = false; while (!answered) { try @@ -157,7 +158,7 @@ namespace mRemoteNG.App switch (CTaskDialog.CommandButtonResult) { case 0: - ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName); + ConnectionsService.NewConnectionsFile(connectionFileName); answered = true; break; case 1: @@ -165,7 +166,7 @@ namespace mRemoteNG.App answered = true; break; case 2: - ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName); + ConnectionsService.NewConnectionsFile(connectionFileName); Import.ImportFromFile(ConnectionsService.ConnectionTreeModel.RootNodes[0]); answered = true; break; @@ -177,15 +178,14 @@ namespace mRemoteNG.App } catch (Exception exc) { - MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoader.ConnectionFileName), exc, MessageClass.InformationMsg); + MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), exc, MessageClass.InformationMsg); } - } return; } - MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoaded, connectionsLoader.ConnectionFileName), ex); - if (connectionsLoader.ConnectionFileName != ConnectionsService.GetStartupConnectionFileName()) + MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoaded, connectionFileName), ex); + if (connectionFileName != ConnectionsService.GetStartupConnectionFileName()) { LoadConnections(withDialog); } diff --git a/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs b/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs new file mode 100644 index 00000000..4e3e082d --- /dev/null +++ b/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs @@ -0,0 +1,57 @@ +using System; +using mRemoteNG.Tree; + +namespace mRemoteNG.Config.Connections +{ + public class ConnectionsLoadedEventArgs : EventArgs + { + /// + /// The previous that is being + /// unloaded. + /// + public ConnectionTreeModel PreviousConnectionTreeModel { get; } + + /// + /// True if the previous was loaded from + /// a database. + /// + public bool PreviousSourceWasDatabase { get; } + + /// + /// The new that is being loaded. + /// + public ConnectionTreeModel NewConnectionTreeModel { get; } + + /// + /// True if the new was loaded from + /// a database. + /// + public bool NewSourceIsDatabase { get; } + + /// + /// The path to the new connections source. + /// If is True, this will be the server and database name. + /// If False, it will be a file path to the connection file. + /// + public string NewSourcePath { get; } + + public ConnectionsLoadedEventArgs( + ConnectionTreeModel previousTreeModelModel, ConnectionTreeModel newTreeModelModel, + bool previousSourceWasDatabase, bool newSourceIsDatabase, + string newSourcePath) + { + if (previousTreeModelModel == null) + throw new ArgumentNullException(nameof(previousTreeModelModel)); + if (newTreeModelModel == null) + throw new ArgumentNullException(nameof(newTreeModelModel)); + if (newSourcePath == null) + throw new ArgumentNullException(nameof(newSourcePath)); + + PreviousConnectionTreeModel = previousTreeModelModel; + PreviousSourceWasDatabase = previousSourceWasDatabase; + NewConnectionTreeModel = newTreeModelModel; + NewSourceIsDatabase = newSourceIsDatabase; + NewSourcePath = newSourcePath; + } + } +} diff --git a/mRemoteV1/Config/Connections/ConnectionsLoader.cs b/mRemoteV1/Config/Connections/ConnectionsLoader.cs index 409062a4..def8af09 100644 --- a/mRemoteV1/Config/Connections/ConnectionsLoader.cs +++ b/mRemoteV1/Config/Connections/ConnectionsLoader.cs @@ -1,34 +1,33 @@ using mRemoteNG.Config.Putty; using mRemoteNG.Tree; -using mRemoteNG.UI.Forms; - namespace mRemoteNG.Config.Connections { public class ConnectionsLoader - { - public bool UseDatabase { get; set; } - public string ConnectionFileName { get; set; } - - - public ConnectionTreeModel LoadConnections(bool import) + { + /// + /// Load connections from a source. is ignored if + /// is true. + /// + /// + /// + /// + public ConnectionTreeModel LoadConnections(bool useDatabase, bool import, string connectionFileName) { ConnectionTreeModel connectionTreeModel; - if (UseDatabase) + if (useDatabase) { var sqlLoader = new SqlConnectionsLoader(); connectionTreeModel = sqlLoader.Load(); } else { - var xmlLoader = new XmlConnectionsLoader(ConnectionFileName); + var xmlLoader = new XmlConnectionsLoader(connectionFileName); connectionTreeModel = xmlLoader.Load(); } - if (connectionTreeModel != null) - FrmMain.Default.ConnectionsFileName = ConnectionFileName; - else + if (connectionTreeModel == null) connectionTreeModel = new ConnectionTreeModel(); if (!import) diff --git a/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs b/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs index d50691ed..d5e67cff 100644 --- a/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs +++ b/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs @@ -9,7 +9,6 @@ namespace mRemoteNG.Config.Connections.Multiuser { private readonly Timer _updateTimer; private readonly IConnectionsUpdateChecker _updateChecker; - private readonly ConnectionsLoader _connectionsLoader; private readonly ConnectionsSaver _connectionsSaver; public double TimerIntervalInMilliseconds @@ -21,7 +20,6 @@ namespace mRemoteNG.Config.Connections.Multiuser { _updateChecker = updateChecker; _updateTimer = new Timer(3000); - _connectionsLoader = new ConnectionsLoader { UseDatabase = mRemoteNG.Settings.Default.UseSQLServer }; _connectionsSaver = new ConnectionsSaver { SaveFormat = ConnectionsSaver.Format.SQL }; SetEventListeners(); } @@ -37,7 +35,7 @@ namespace mRemoteNG.Config.Connections.Multiuser public void Load() { - Runtime.ConnectionsService.ConnectionTreeModel = _connectionsLoader.LoadConnections(false); + Runtime.ConnectionsService.ConnectionTreeModel = Runtime.ConnectionsService.LoadConnections(mRemoteNG.Settings.Default.UseSQLServer, false, ""); } private void Load(object sender, ConnectionsUpdateAvailableEventArgs args) diff --git a/mRemoteV1/Connection/ConnectionsService.cs b/mRemoteV1/Connection/ConnectionsService.cs index 28b6fe99..0dedb6c7 100644 --- a/mRemoteV1/Connection/ConnectionsService.cs +++ b/mRemoteV1/Connection/ConnectionsService.cs @@ -4,16 +4,22 @@ using System.Windows.Forms; using mRemoteNG.App; using mRemoteNG.App.Info; using mRemoteNG.Config.Connections; +using mRemoteNG.Config.Putty; using mRemoteNG.Connection.Protocol; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; -using mRemoteNG.UI.Forms; namespace mRemoteNG.Connection { public class ConnectionsService { + private readonly PuttySessionsManager _puttySessionsManager; + private readonly ConnectionsLoader _connectionsLoader; + public bool IsConnectionsFileLoaded { get; set; } + public bool UsingDatabase { get; private set; } + public string ConnectionFileName { get; private set; } + public static DateTime LastSqlUpdate { get; private set; } public ConnectionTreeModel ConnectionTreeModel { @@ -21,7 +27,15 @@ namespace mRemoteNG.Connection set { Windows.TreeForm.ConnectionTree.ConnectionTreeModel = value; } } - public void NewConnections(string filename) + public ConnectionsService(PuttySessionsManager puttySessionsManager) + { + if (puttySessionsManager == null) + throw new ArgumentNullException(nameof(puttySessionsManager)); + _puttySessionsManager = puttySessionsManager; + _connectionsLoader = new ConnectionsLoader(); + } + + public void NewConnectionsFile(string filename) { try { @@ -32,18 +46,12 @@ namespace mRemoteNG.Connection var connectionSaver = new ConnectionsSaver { ConnectionTreeModel = newConnectionsModel, - ConnectionFileName = filename + ConnectionFileName = filename, + SaveFilter = new Security.SaveFilter() }; - connectionSaver.SaveFilter = new Security.SaveFilter(); connectionSaver.SaveConnections(); - // Load config - var connectionsLoader = new ConnectionsLoader { ConnectionFileName = filename }; - ConnectionTreeModel = connectionsLoader.LoadConnections(false); - Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel; - IsConnectionsFileLoaded = true; - // TODO - the connection service should not know about the ui. UI should update via events from service - FrmMain.Default.UpdateWindowTitle(); + LoadConnections(false, false, filename); } catch (Exception ex) { @@ -51,40 +59,6 @@ namespace mRemoteNG.Connection } } - private void UpdateCustomConsPathSetting(string filename) - { - if (filename == GetDefaultStartupConnectionFileName()) - { - Settings.Default.LoadConsFromCustomLocation = false; - } - else - { - Settings.Default.LoadConsFromCustomLocation = true; - Settings.Default.CustomConsPath = filename; - } - } - - public string GetStartupConnectionFileName() - { - return Settings.Default.LoadConsFromCustomLocation == false ? GetDefaultStartupConnectionFileName() : Settings.Default.CustomConsPath; - } - - public string GetDefaultStartupConnectionFileName() - { - return Runtime.IsPortableEdition ? GetDefaultStartupConnectionFileNamePortableEdition() : GetDefaultStartupConnectionFileNameNormalEdition(); - } - - private string GetDefaultStartupConnectionFileNameNormalEdition() - { - var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\" + Application.ProductName + "\\" + ConnectionsFileInfo.DefaultConnectionsFile; - return File.Exists(appDataPath) ? appDataPath : GetDefaultStartupConnectionFileNamePortableEdition(); - } - - private string GetDefaultStartupConnectionFileNamePortableEdition() - { - return ConnectionsFileInfo.DefaultConnectionsPath + "\\" + ConnectionsFileInfo.DefaultConnectionsFile; - } - public ConnectionInfo CreateQuickConnect(string connectionString, ProtocolType protocol) { try @@ -117,5 +91,78 @@ namespace mRemoteNG.Connection return null; } } + + /// + /// Load connections from a source. is ignored if + /// is true. + /// + /// + /// + /// + public ConnectionTreeModel LoadConnections(bool useDatabase, bool import, string connectionFileName) + { + var oldConnectionTreeModel = ConnectionTreeModel; + var oldIsUsingDatabaseValue = UsingDatabase; + var newConnectionTreeModel = _connectionsLoader.LoadConnections(useDatabase, import, connectionFileName); + IsConnectionsFileLoaded = true; + ConnectionFileName = connectionFileName; + UsingDatabase = useDatabase; + ConnectionTreeModel = newConnectionTreeModel; + RaiseConnectionsLoadedEvent(oldConnectionTreeModel, newConnectionTreeModel, oldIsUsingDatabaseValue, useDatabase, connectionFileName); + return newConnectionTreeModel; + } + + private void UpdateCustomConsPathSetting(string filename) + { + if (filename == GetDefaultStartupConnectionFileName()) + { + Settings.Default.LoadConsFromCustomLocation = false; + } + else + { + Settings.Default.LoadConsFromCustomLocation = true; + Settings.Default.CustomConsPath = filename; + } + } + + public string GetStartupConnectionFileName() + { + return Settings.Default.LoadConsFromCustomLocation == false ? GetDefaultStartupConnectionFileName() : Settings.Default.CustomConsPath; + } + + public string GetDefaultStartupConnectionFileName() + { + return Runtime.IsPortableEdition ? GetDefaultStartupConnectionFileNamePortableEdition() : GetDefaultStartupConnectionFileNameNormalEdition(); + } + + private string GetDefaultStartupConnectionFileNameNormalEdition() + { + var appDataPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + Application.ProductName, + ConnectionsFileInfo.DefaultConnectionsFile); + return File.Exists(appDataPath) ? appDataPath : GetDefaultStartupConnectionFileNamePortableEdition(); + } + + private string GetDefaultStartupConnectionFileNamePortableEdition() + { + return Path.Combine(ConnectionsFileInfo.DefaultConnectionsPath, ConnectionsFileInfo.DefaultConnectionsFile); + } + + #region Events + public event EventHandler ConnectionsLoaded; + + protected virtual void RaiseConnectionsLoadedEvent(ConnectionTreeModel previousTreeModel, ConnectionTreeModel newTreeModel, + bool previousSourceWasDatabase, bool newSourceIsDatabase, + string newSourcePath) + { + ConnectionsLoaded?.Invoke(this, new ConnectionsLoadedEventArgs( + previousTreeModel, + newTreeModel, + previousSourceWasDatabase, + newSourceIsDatabase, + newSourcePath)); + } + #endregion } } \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 3909e817..fbf9c8aa 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -12,6 +12,7 @@ using mRemoteNG.App; using mRemoteNG.App.Info; using mRemoteNG.App.Initialization; using mRemoteNG.Config; +using mRemoteNG.Config.Connections; using mRemoteNG.Config.Putty; using mRemoteNG.Config.Settings; using mRemoteNG.Connection; @@ -42,7 +43,7 @@ namespace mRemoteNG.UI.Forms private readonly ScreenSelectionSystemMenu _screenSystemMenu; private ConnectionInfo _selectedConnection; private readonly IList _messageWriters = new List(); - private ThemeManager _themeManager; + private readonly ThemeManager _themeManager; internal FullscreenHandler Fullscreen { get; set; } @@ -65,7 +66,6 @@ namespace mRemoteNG.UI.Forms static FrmMain() { - } #region Properties @@ -156,6 +156,7 @@ namespace mRemoteNG.UI.Forms if (Settings.Default.ResetPanels) SetDefaultLayout(); + Runtime.ConnectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded; var credsAndConsSetup = new CredsAndConsSetup(); credsAndConsSetup.LoadCredsAndCons(); @@ -173,6 +174,11 @@ namespace mRemoteNG.UI.Forms Opacity = 1; } + private void ConnectionsServiceOnConnectionsLoaded(object sender, ConnectionsLoadedEventArgs connectionsLoadedEventArgs) + { + UpdateWindowTitle(); + } + private void SetMenuDependencies() { var connectionInitiator = new ConnectionInitiator(); @@ -450,12 +456,12 @@ namespace mRemoteNG.UI.Forms } else { - if (!string.IsNullOrEmpty(ConnectionsFileName)) + if (!string.IsNullOrEmpty(Runtime.ConnectionsService.ConnectionFileName)) { titleBuilder.Append(separator); titleBuilder.Append(Settings.Default.ShowCompleteConsPathInTitle - ? ConnectionsFileName - : Path.GetFileName(ConnectionsFileName)); + ? Runtime.ConnectionsService.ConnectionFileName + : Path.GetFileName(Runtime.ConnectionsService.ConnectionFileName)); } } } diff --git a/mRemoteV1/UI/Menu/MainFileMenu.cs b/mRemoteV1/UI/Menu/MainFileMenu.cs index f6d41f5c..dc81220d 100644 --- a/mRemoteV1/UI/Menu/MainFileMenu.cs +++ b/mRemoteV1/UI/Menu/MainFileMenu.cs @@ -346,7 +346,7 @@ namespace mRemoteNG.UI.Menu return; } - Runtime.ConnectionsService.NewConnections(saveFileDialog.FileName); + Runtime.ConnectionsService.NewConnectionsFile(saveFileDialog.FileName); } private void mMenFileLoad_Click(object sender, EventArgs e) diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 850c981a..f248378f 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -133,6 +133,7 @@ + @@ -1598,4 +1599,4 @@ powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_mremo - + \ No newline at end of file