From 44ee3ceec873286df653fa96c411daeb78e342b0 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 2 Dec 2016 14:57:49 -0500 Subject: [PATCH 001/106] User Selectable Release Channels Final = Final Beta = Beta & RC Pre-Release = Alpha, Beta & RC --- mRemoteV1/App/Info/UpdateChannelInfo.cs | 32 +- mRemoteV1/Properties/Settings.Designer.cs | 5 +- mRemoteV1/Properties/Settings.settings | 2 +- .../OptionsPages/UpdatesPage.Designer.cs | 530 ++++++++++-------- .../UI/Forms/OptionsPages/UpdatesPage.cs | 21 + .../UI/Forms/OptionsPages/UpdatesPage.resx | 6 +- mRemoteV1/app.config | 6 +- 7 files changed, 345 insertions(+), 257 deletions(-) diff --git a/mRemoteV1/App/Info/UpdateChannelInfo.cs b/mRemoteV1/App/Info/UpdateChannelInfo.cs index 1dac711c6..b199d5a8c 100644 --- a/mRemoteV1/App/Info/UpdateChannelInfo.cs +++ b/mRemoteV1/App/Info/UpdateChannelInfo.cs @@ -10,11 +10,17 @@ /* */ /* return PORTABLE update files here */ /* */ -#if DEBUG - return "update-portable-debug.txt"; -#else - return Settings.Default.UpdateChannel.ToLowerInvariant() == "debug" ? "update-portable-debug.txt" : "update-portable.txt"; -#endif + switch (Settings.Default.UpdateChannel) + { + case "Final": + return "update-portable.txt"; + case "Beta": + return "beta-update-portable.txt"; + case "Pre-Release": + return "prere-update-portable.txt"; + default: + return "update-portable.txt"; + } } #else //NOT portable get @@ -22,11 +28,17 @@ /* */ /* return INSTALLER update files here */ /* */ -#if DEBUG - return "update-debug.txt"; -#else - return Settings.Default.UpdateChannel.ToLowerInvariant() == "debug" ? "update-debug.txt" : "update.txt"; -#endif + switch (Settings.Default.UpdateChannel) + { + case "Final": + return "update.txt"; + case "Beta": + return "beta-update.txt"; + case "Pre-Release": + return "prere-update.txt"; + default: + return "update.txt"; + } } #endif //endif for PORTABLE } diff --git a/mRemoteV1/Properties/Settings.Designer.cs b/mRemoteV1/Properties/Settings.Designer.cs index 78a7bb2a8..ed31fe7c8 100644 --- a/mRemoteV1/Properties/Settings.Designer.cs +++ b/mRemoteV1/Properties/Settings.Designer.cs @@ -2099,13 +2099,16 @@ namespace mRemoteNG { } } - [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("release")] public string UpdateChannel { get { return ((string)(this["UpdateChannel"])); } + set { + this["UpdateChannel"] = value; + } } [global::System.Configuration.UserScopedSettingAttribute()] diff --git a/mRemoteV1/Properties/Settings.settings b/mRemoteV1/Properties/Settings.settings index 4d0fa8ea3..477a07aed 100644 --- a/mRemoteV1/Properties/Settings.settings +++ b/mRemoteV1/Properties/Settings.settings @@ -521,7 +521,7 @@ False - + release diff --git a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs index 78e3ce2ac..bc77664a7 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs @@ -29,243 +29,293 @@ namespace mRemoteNG.UI.Forms.OptionsPages //Do not modify it using the code editor. [System.Diagnostics.DebuggerStepThrough()]private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdatesPage)); - this.lblUpdatesExplanation = new System.Windows.Forms.Label(); - this.pnlUpdateCheck = new System.Windows.Forms.Panel(); - this.btnUpdateCheckNow = new System.Windows.Forms.Button(); - this.btnUpdateCheckNow.Click += new System.EventHandler(this.btnUpdateCheckNow_Click); - this.chkCheckForUpdatesOnStartup = new System.Windows.Forms.CheckBox(); - this.chkCheckForUpdatesOnStartup.CheckedChanged += new System.EventHandler(this.chkCheckForUpdatesOnStartup_CheckedChanged); - this.cboUpdateCheckFrequency = new System.Windows.Forms.ComboBox(); - this.pnlProxy = new System.Windows.Forms.Panel(); - this.pnlProxyBasic = new System.Windows.Forms.Panel(); - this.lblProxyAddress = new System.Windows.Forms.Label(); - this.txtProxyAddress = new System.Windows.Forms.TextBox(); - this.lblProxyPort = new System.Windows.Forms.Label(); - this.numProxyPort = new System.Windows.Forms.NumericUpDown(); - this.chkUseProxyForAutomaticUpdates = new System.Windows.Forms.CheckBox(); - this.chkUseProxyForAutomaticUpdates.CheckedChanged += new System.EventHandler(this.chkUseProxyForAutomaticUpdates_CheckedChanged); - this.chkUseProxyAuthentication = new System.Windows.Forms.CheckBox(); - this.chkUseProxyAuthentication.CheckedChanged += new System.EventHandler(this.chkUseProxyAuthentication_CheckedChanged); - this.pnlProxyAuthentication = new System.Windows.Forms.Panel(); - this.lblProxyUsername = new System.Windows.Forms.Label(); - this.txtProxyUsername = new System.Windows.Forms.TextBox(); - this.lblProxyPassword = new System.Windows.Forms.Label(); - this.txtProxyPassword = new System.Windows.Forms.TextBox(); - this.btnTestProxy = new System.Windows.Forms.Button(); - this.btnTestProxy.Click += new System.EventHandler(this.btnTestProxy_Click); - this.pnlUpdateCheck.SuspendLayout(); - this.pnlProxy.SuspendLayout(); - this.pnlProxyBasic.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize) this.numProxyPort).BeginInit(); - this.pnlProxyAuthentication.SuspendLayout(); - this.SuspendLayout(); - // - //lblUpdatesExplanation - // - this.lblUpdatesExplanation.Location = new System.Drawing.Point(3, 0); - this.lblUpdatesExplanation.Name = "lblUpdatesExplanation"; - this.lblUpdatesExplanation.Size = new System.Drawing.Size(536, 40); - this.lblUpdatesExplanation.TabIndex = 3; - this.lblUpdatesExplanation.Text = "mRemoteNG can periodically connect to the mRemoteNG website to check for updates."; - // - //pnlUpdateCheck - // - this.pnlUpdateCheck.Controls.Add(this.btnUpdateCheckNow); - this.pnlUpdateCheck.Controls.Add(this.chkCheckForUpdatesOnStartup); - this.pnlUpdateCheck.Controls.Add(this.cboUpdateCheckFrequency); - this.pnlUpdateCheck.Location = new System.Drawing.Point(0, 48); - this.pnlUpdateCheck.Name = "pnlUpdateCheck"; - this.pnlUpdateCheck.Size = new System.Drawing.Size(610, 120); - this.pnlUpdateCheck.TabIndex = 4; - // - //btnUpdateCheckNow - // - this.btnUpdateCheckNow.Location = new System.Drawing.Point(3, 80); - this.btnUpdateCheckNow.Name = "btnUpdateCheckNow"; - this.btnUpdateCheckNow.Size = new System.Drawing.Size(120, 32); - this.btnUpdateCheckNow.TabIndex = 2; - this.btnUpdateCheckNow.Text = "Check Now"; - this.btnUpdateCheckNow.UseVisualStyleBackColor = true; - // - //chkCheckForUpdatesOnStartup - // - this.chkCheckForUpdatesOnStartup.AutoSize = true; - this.chkCheckForUpdatesOnStartup.Location = new System.Drawing.Point(3, 8); - this.chkCheckForUpdatesOnStartup.Name = "chkCheckForUpdatesOnStartup"; - this.chkCheckForUpdatesOnStartup.Size = new System.Drawing.Size(213, 17); - this.chkCheckForUpdatesOnStartup.TabIndex = 0; - this.chkCheckForUpdatesOnStartup.Text = "Check for updates"; - this.chkCheckForUpdatesOnStartup.UseVisualStyleBackColor = true; - // - //cboUpdateCheckFrequency - // - this.cboUpdateCheckFrequency.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboUpdateCheckFrequency.FormattingEnabled = true; - this.cboUpdateCheckFrequency.Location = new System.Drawing.Point(48, 40); - this.cboUpdateCheckFrequency.Name = "cboUpdateCheckFrequency"; - this.cboUpdateCheckFrequency.Size = new System.Drawing.Size(128, 21); - this.cboUpdateCheckFrequency.TabIndex = 1; - // - //pnlProxy - // - this.pnlProxy.Controls.Add(this.pnlProxyBasic); - this.pnlProxy.Controls.Add(this.chkUseProxyForAutomaticUpdates); - this.pnlProxy.Controls.Add(this.chkUseProxyAuthentication); - this.pnlProxy.Controls.Add(this.pnlProxyAuthentication); - this.pnlProxy.Controls.Add(this.btnTestProxy); - this.pnlProxy.Location = new System.Drawing.Point(0, 200); - this.pnlProxy.Name = "pnlProxy"; - this.pnlProxy.Size = new System.Drawing.Size(610, 224); - this.pnlProxy.TabIndex = 5; - // - //pnlProxyBasic - // - this.pnlProxyBasic.Controls.Add(this.lblProxyAddress); - this.pnlProxyBasic.Controls.Add(this.txtProxyAddress); - this.pnlProxyBasic.Controls.Add(this.lblProxyPort); - this.pnlProxyBasic.Controls.Add(this.numProxyPort); - this.pnlProxyBasic.Enabled = false; - this.pnlProxyBasic.Location = new System.Drawing.Point(3, 32); - this.pnlProxyBasic.Name = "pnlProxyBasic"; - this.pnlProxyBasic.Size = new System.Drawing.Size(604, 40); - this.pnlProxyBasic.TabIndex = 1; - // - //lblProxyAddress - // - this.lblProxyAddress.Location = new System.Drawing.Point(8, 4); - this.lblProxyAddress.Name = "lblProxyAddress"; - this.lblProxyAddress.Size = new System.Drawing.Size(96, 24); - this.lblProxyAddress.TabIndex = 0; - this.lblProxyAddress.Text = "Address:"; - this.lblProxyAddress.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - //txtProxyAddress - // - this.txtProxyAddress.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.txtProxyAddress.Location = new System.Drawing.Point(104, 8); - this.txtProxyAddress.Name = "txtProxyAddress"; - this.txtProxyAddress.Size = new System.Drawing.Size(240, 20); - this.txtProxyAddress.TabIndex = 1; - // - //lblProxyPort - // - this.lblProxyPort.Location = new System.Drawing.Point(350, 5); - this.lblProxyPort.Name = "lblProxyPort"; - this.lblProxyPort.Size = new System.Drawing.Size(64, 23); - this.lblProxyPort.TabIndex = 2; - this.lblProxyPort.Text = "Port:"; - this.lblProxyPort.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - //numProxyPort - // - this.numProxyPort.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.numProxyPort.Location = new System.Drawing.Point(420, 8); - this.numProxyPort.Maximum = new decimal(new int[] {65535, 0, 0, 0}); - this.numProxyPort.Minimum = new decimal(new int[] {1, 0, 0, 0}); - this.numProxyPort.Name = "numProxyPort"; - this.numProxyPort.Size = new System.Drawing.Size(64, 20); - this.numProxyPort.TabIndex = 3; - this.numProxyPort.Value = new decimal(new int[] {80, 0, 0, 0}); - // - //chkUseProxyForAutomaticUpdates - // - this.chkUseProxyForAutomaticUpdates.AutoSize = true; - this.chkUseProxyForAutomaticUpdates.Location = new System.Drawing.Point(3, 8); - this.chkUseProxyForAutomaticUpdates.Name = "chkUseProxyForAutomaticUpdates"; - this.chkUseProxyForAutomaticUpdates.Size = new System.Drawing.Size(168, 17); - this.chkUseProxyForAutomaticUpdates.TabIndex = 0; - this.chkUseProxyForAutomaticUpdates.Text = "Use a proxy server to connect"; - this.chkUseProxyForAutomaticUpdates.UseVisualStyleBackColor = true; - // - //chkUseProxyAuthentication - // - this.chkUseProxyAuthentication.AutoSize = true; - this.chkUseProxyAuthentication.Enabled = false; - this.chkUseProxyAuthentication.Location = new System.Drawing.Point(27, 80); - this.chkUseProxyAuthentication.Name = "chkUseProxyAuthentication"; - this.chkUseProxyAuthentication.Size = new System.Drawing.Size(216, 17); - this.chkUseProxyAuthentication.TabIndex = 2; - this.chkUseProxyAuthentication.Text = "This proxy server requires authentication"; - this.chkUseProxyAuthentication.UseVisualStyleBackColor = true; - // - //pnlProxyAuthentication - // - this.pnlProxyAuthentication.Controls.Add(this.lblProxyUsername); - this.pnlProxyAuthentication.Controls.Add(this.txtProxyUsername); - this.pnlProxyAuthentication.Controls.Add(this.lblProxyPassword); - this.pnlProxyAuthentication.Controls.Add(this.txtProxyPassword); - this.pnlProxyAuthentication.Enabled = false; - this.pnlProxyAuthentication.Location = new System.Drawing.Point(3, 104); - this.pnlProxyAuthentication.Name = "pnlProxyAuthentication"; - this.pnlProxyAuthentication.Size = new System.Drawing.Size(604, 72); - this.pnlProxyAuthentication.TabIndex = 3; - // - //lblProxyUsername - // - this.lblProxyUsername.Location = new System.Drawing.Point(8, 4); - this.lblProxyUsername.Name = "lblProxyUsername"; - this.lblProxyUsername.Size = new System.Drawing.Size(96, 24); - this.lblProxyUsername.TabIndex = 0; - this.lblProxyUsername.Text = "Username:"; - this.lblProxyUsername.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - //txtProxyUsername - // - this.txtProxyUsername.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.txtProxyUsername.Location = new System.Drawing.Point(104, 8); - this.txtProxyUsername.Name = "txtProxyUsername"; - this.txtProxyUsername.Size = new System.Drawing.Size(240, 20); - this.txtProxyUsername.TabIndex = 1; - // - //lblProxyPassword - // - this.lblProxyPassword.Location = new System.Drawing.Point(8, 36); - this.lblProxyPassword.Name = "lblProxyPassword"; - this.lblProxyPassword.Size = new System.Drawing.Size(96, 24); - this.lblProxyPassword.TabIndex = 2; - this.lblProxyPassword.Text = "Password:"; - this.lblProxyPassword.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - //txtProxyPassword - // - this.txtProxyPassword.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.txtProxyPassword.Location = new System.Drawing.Point(104, 40); - this.txtProxyPassword.Name = "txtProxyPassword"; - this.txtProxyPassword.Size = new System.Drawing.Size(240, 20); - this.txtProxyPassword.TabIndex = 3; - this.txtProxyPassword.UseSystemPasswordChar = true; - // - //btnTestProxy - // - this.btnTestProxy.Location = new System.Drawing.Point(3, 184); - this.btnTestProxy.Name = "btnTestProxy"; - this.btnTestProxy.Size = new System.Drawing.Size(120, 32); - this.btnTestProxy.TabIndex = 4; - this.btnTestProxy.Text = "Test Proxy"; - this.btnTestProxy.UseVisualStyleBackColor = true; - // - //UpdatesPage - // - this.AutoScaleDimensions = new System.Drawing.SizeF((float) (6.0F), (float) (13.0F)); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.lblUpdatesExplanation); - this.Controls.Add(this.pnlUpdateCheck); - this.Controls.Add(this.pnlProxy); - this.Name = "UpdatesPage"; - this.PageIcon = (System.Drawing.Icon) (resources.GetObject("$this.PageIcon")); - this.Size = new System.Drawing.Size(610, 489); - this.pnlUpdateCheck.ResumeLayout(false); - this.pnlUpdateCheck.PerformLayout(); - this.pnlProxy.ResumeLayout(false); - this.pnlProxy.PerformLayout(); - this.pnlProxyBasic.ResumeLayout(false); - this.pnlProxyBasic.PerformLayout(); - ((System.ComponentModel.ISupportInitialize) this.numProxyPort).EndInit(); - this.pnlProxyAuthentication.ResumeLayout(false); - this.pnlProxyAuthentication.PerformLayout(); - this.ResumeLayout(false); - + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdatesPage)); + this.lblUpdatesExplanation = new System.Windows.Forms.Label(); + this.pnlUpdateCheck = new System.Windows.Forms.Panel(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.lblReleaseChannel = new System.Windows.Forms.Label(); + this.cboReleaseChannel = new System.Windows.Forms.ComboBox(); + this.btnUpdateCheckNow = new System.Windows.Forms.Button(); + this.chkCheckForUpdatesOnStartup = new System.Windows.Forms.CheckBox(); + this.cboUpdateCheckFrequency = new System.Windows.Forms.ComboBox(); + this.pnlProxy = new System.Windows.Forms.Panel(); + this.pnlProxyBasic = new System.Windows.Forms.Panel(); + this.lblProxyAddress = new System.Windows.Forms.Label(); + this.txtProxyAddress = new System.Windows.Forms.TextBox(); + this.lblProxyPort = new System.Windows.Forms.Label(); + this.numProxyPort = new System.Windows.Forms.NumericUpDown(); + this.chkUseProxyForAutomaticUpdates = new System.Windows.Forms.CheckBox(); + this.chkUseProxyAuthentication = new System.Windows.Forms.CheckBox(); + this.pnlProxyAuthentication = new System.Windows.Forms.Panel(); + this.lblProxyUsername = new System.Windows.Forms.Label(); + this.txtProxyUsername = new System.Windows.Forms.TextBox(); + this.lblProxyPassword = new System.Windows.Forms.Label(); + this.txtProxyPassword = new System.Windows.Forms.TextBox(); + this.btnTestProxy = new System.Windows.Forms.Button(); + this.pnlUpdateCheck.SuspendLayout(); + this.pnlProxy.SuspendLayout(); + this.pnlProxyBasic.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).BeginInit(); + this.pnlProxyAuthentication.SuspendLayout(); + this.SuspendLayout(); + // + // lblUpdatesExplanation + // + this.lblUpdatesExplanation.Location = new System.Drawing.Point(3, 0); + this.lblUpdatesExplanation.Name = "lblUpdatesExplanation"; + this.lblUpdatesExplanation.Size = new System.Drawing.Size(536, 40); + this.lblUpdatesExplanation.TabIndex = 3; + this.lblUpdatesExplanation.Text = "mRemoteNG can periodically connect to the mRemoteNG website to check for updates." + + ""; + // + // pnlUpdateCheck + // + this.pnlUpdateCheck.Controls.Add(this.textBox1); + this.pnlUpdateCheck.Controls.Add(this.lblReleaseChannel); + this.pnlUpdateCheck.Controls.Add(this.cboReleaseChannel); + this.pnlUpdateCheck.Controls.Add(this.btnUpdateCheckNow); + this.pnlUpdateCheck.Controls.Add(this.chkCheckForUpdatesOnStartup); + this.pnlUpdateCheck.Controls.Add(this.cboUpdateCheckFrequency); + this.pnlUpdateCheck.Location = new System.Drawing.Point(0, 48); + this.pnlUpdateCheck.Name = "pnlUpdateCheck"; + this.pnlUpdateCheck.Size = new System.Drawing.Size(610, 120); + this.pnlUpdateCheck.TabIndex = 4; + // + // textBox1 + // + this.textBox1.BackColor = System.Drawing.SystemColors.Control; + this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox1.Location = new System.Drawing.Point(226, 78); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.ReadOnly = true; + this.textBox1.Size = new System.Drawing.Size(366, 34); + this.textBox1.TabIndex = 5; + this.textBox1.Text = "Beta channel includes Release Candidates.\r\nPre-Release Channel includes Alphas an" + + "d Beta Channel releases."; + // + // lblReleaseChannel + // + this.lblReleaseChannel.AutoSize = true; + this.lblReleaseChannel.Location = new System.Drawing.Point(223, 12); + this.lblReleaseChannel.Name = "lblReleaseChannel"; + this.lblReleaseChannel.Size = new System.Drawing.Size(91, 13); + this.lblReleaseChannel.TabIndex = 4; + this.lblReleaseChannel.Text = "Release Channel:"; + // + // cboReleaseChannel + // + this.cboReleaseChannel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboReleaseChannel.FormattingEnabled = true; + this.cboReleaseChannel.Location = new System.Drawing.Point(226, 41); + this.cboReleaseChannel.Name = "cboReleaseChannel"; + this.cboReleaseChannel.Size = new System.Drawing.Size(121, 21); + this.cboReleaseChannel.TabIndex = 3; + // + // btnUpdateCheckNow + // + this.btnUpdateCheckNow.Location = new System.Drawing.Point(3, 80); + this.btnUpdateCheckNow.Name = "btnUpdateCheckNow"; + this.btnUpdateCheckNow.Size = new System.Drawing.Size(120, 32); + this.btnUpdateCheckNow.TabIndex = 2; + this.btnUpdateCheckNow.Text = "Check Now"; + this.btnUpdateCheckNow.UseVisualStyleBackColor = true; + this.btnUpdateCheckNow.Click += new System.EventHandler(this.btnUpdateCheckNow_Click); + // + // chkCheckForUpdatesOnStartup + // + this.chkCheckForUpdatesOnStartup.AutoSize = true; + this.chkCheckForUpdatesOnStartup.Location = new System.Drawing.Point(3, 8); + this.chkCheckForUpdatesOnStartup.Name = "chkCheckForUpdatesOnStartup"; + this.chkCheckForUpdatesOnStartup.Size = new System.Drawing.Size(113, 17); + this.chkCheckForUpdatesOnStartup.TabIndex = 0; + this.chkCheckForUpdatesOnStartup.Text = "Check for updates"; + this.chkCheckForUpdatesOnStartup.UseVisualStyleBackColor = true; + this.chkCheckForUpdatesOnStartup.CheckedChanged += new System.EventHandler(this.chkCheckForUpdatesOnStartup_CheckedChanged); + // + // cboUpdateCheckFrequency + // + this.cboUpdateCheckFrequency.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboUpdateCheckFrequency.FormattingEnabled = true; + this.cboUpdateCheckFrequency.Location = new System.Drawing.Point(3, 41); + this.cboUpdateCheckFrequency.Name = "cboUpdateCheckFrequency"; + this.cboUpdateCheckFrequency.Size = new System.Drawing.Size(128, 21); + this.cboUpdateCheckFrequency.TabIndex = 1; + // + // pnlProxy + // + this.pnlProxy.Controls.Add(this.pnlProxyBasic); + this.pnlProxy.Controls.Add(this.chkUseProxyForAutomaticUpdates); + this.pnlProxy.Controls.Add(this.chkUseProxyAuthentication); + this.pnlProxy.Controls.Add(this.pnlProxyAuthentication); + this.pnlProxy.Controls.Add(this.btnTestProxy); + this.pnlProxy.Location = new System.Drawing.Point(0, 200); + this.pnlProxy.Name = "pnlProxy"; + this.pnlProxy.Size = new System.Drawing.Size(610, 224); + this.pnlProxy.TabIndex = 5; + // + // pnlProxyBasic + // + this.pnlProxyBasic.Controls.Add(this.lblProxyAddress); + this.pnlProxyBasic.Controls.Add(this.txtProxyAddress); + this.pnlProxyBasic.Controls.Add(this.lblProxyPort); + this.pnlProxyBasic.Controls.Add(this.numProxyPort); + this.pnlProxyBasic.Enabled = false; + this.pnlProxyBasic.Location = new System.Drawing.Point(3, 32); + this.pnlProxyBasic.Name = "pnlProxyBasic"; + this.pnlProxyBasic.Size = new System.Drawing.Size(604, 40); + this.pnlProxyBasic.TabIndex = 1; + // + // lblProxyAddress + // + this.lblProxyAddress.Location = new System.Drawing.Point(8, 4); + this.lblProxyAddress.Name = "lblProxyAddress"; + this.lblProxyAddress.Size = new System.Drawing.Size(96, 24); + this.lblProxyAddress.TabIndex = 0; + this.lblProxyAddress.Text = "Address:"; + this.lblProxyAddress.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // txtProxyAddress + // + this.txtProxyAddress.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtProxyAddress.Location = new System.Drawing.Point(104, 8); + this.txtProxyAddress.Name = "txtProxyAddress"; + this.txtProxyAddress.Size = new System.Drawing.Size(240, 20); + this.txtProxyAddress.TabIndex = 1; + // + // lblProxyPort + // + this.lblProxyPort.Location = new System.Drawing.Point(350, 5); + this.lblProxyPort.Name = "lblProxyPort"; + this.lblProxyPort.Size = new System.Drawing.Size(64, 23); + this.lblProxyPort.TabIndex = 2; + this.lblProxyPort.Text = "Port:"; + this.lblProxyPort.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // numProxyPort + // + this.numProxyPort.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.numProxyPort.Location = new System.Drawing.Point(420, 8); + this.numProxyPort.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numProxyPort.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numProxyPort.Name = "numProxyPort"; + this.numProxyPort.Size = new System.Drawing.Size(64, 20); + this.numProxyPort.TabIndex = 3; + this.numProxyPort.Value = new decimal(new int[] { + 80, + 0, + 0, + 0}); + // + // chkUseProxyForAutomaticUpdates + // + this.chkUseProxyForAutomaticUpdates.AutoSize = true; + this.chkUseProxyForAutomaticUpdates.Location = new System.Drawing.Point(3, 8); + this.chkUseProxyForAutomaticUpdates.Name = "chkUseProxyForAutomaticUpdates"; + this.chkUseProxyForAutomaticUpdates.Size = new System.Drawing.Size(168, 17); + this.chkUseProxyForAutomaticUpdates.TabIndex = 0; + this.chkUseProxyForAutomaticUpdates.Text = "Use a proxy server to connect"; + this.chkUseProxyForAutomaticUpdates.UseVisualStyleBackColor = true; + this.chkUseProxyForAutomaticUpdates.CheckedChanged += new System.EventHandler(this.chkUseProxyForAutomaticUpdates_CheckedChanged); + // + // chkUseProxyAuthentication + // + this.chkUseProxyAuthentication.AutoSize = true; + this.chkUseProxyAuthentication.Enabled = false; + this.chkUseProxyAuthentication.Location = new System.Drawing.Point(27, 80); + this.chkUseProxyAuthentication.Name = "chkUseProxyAuthentication"; + this.chkUseProxyAuthentication.Size = new System.Drawing.Size(216, 17); + this.chkUseProxyAuthentication.TabIndex = 2; + this.chkUseProxyAuthentication.Text = "This proxy server requires authentication"; + this.chkUseProxyAuthentication.UseVisualStyleBackColor = true; + this.chkUseProxyAuthentication.CheckedChanged += new System.EventHandler(this.chkUseProxyAuthentication_CheckedChanged); + // + // pnlProxyAuthentication + // + this.pnlProxyAuthentication.Controls.Add(this.lblProxyUsername); + this.pnlProxyAuthentication.Controls.Add(this.txtProxyUsername); + this.pnlProxyAuthentication.Controls.Add(this.lblProxyPassword); + this.pnlProxyAuthentication.Controls.Add(this.txtProxyPassword); + this.pnlProxyAuthentication.Enabled = false; + this.pnlProxyAuthentication.Location = new System.Drawing.Point(3, 104); + this.pnlProxyAuthentication.Name = "pnlProxyAuthentication"; + this.pnlProxyAuthentication.Size = new System.Drawing.Size(604, 72); + this.pnlProxyAuthentication.TabIndex = 3; + // + // lblProxyUsername + // + this.lblProxyUsername.Location = new System.Drawing.Point(8, 4); + this.lblProxyUsername.Name = "lblProxyUsername"; + this.lblProxyUsername.Size = new System.Drawing.Size(96, 24); + this.lblProxyUsername.TabIndex = 0; + this.lblProxyUsername.Text = "Username:"; + this.lblProxyUsername.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // txtProxyUsername + // + this.txtProxyUsername.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtProxyUsername.Location = new System.Drawing.Point(104, 8); + this.txtProxyUsername.Name = "txtProxyUsername"; + this.txtProxyUsername.Size = new System.Drawing.Size(240, 20); + this.txtProxyUsername.TabIndex = 1; + // + // lblProxyPassword + // + this.lblProxyPassword.Location = new System.Drawing.Point(8, 36); + this.lblProxyPassword.Name = "lblProxyPassword"; + this.lblProxyPassword.Size = new System.Drawing.Size(96, 24); + this.lblProxyPassword.TabIndex = 2; + this.lblProxyPassword.Text = "Password:"; + this.lblProxyPassword.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // txtProxyPassword + // + this.txtProxyPassword.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtProxyPassword.Location = new System.Drawing.Point(104, 40); + this.txtProxyPassword.Name = "txtProxyPassword"; + this.txtProxyPassword.Size = new System.Drawing.Size(240, 20); + this.txtProxyPassword.TabIndex = 3; + this.txtProxyPassword.UseSystemPasswordChar = true; + // + // btnTestProxy + // + this.btnTestProxy.Location = new System.Drawing.Point(3, 184); + this.btnTestProxy.Name = "btnTestProxy"; + this.btnTestProxy.Size = new System.Drawing.Size(120, 32); + this.btnTestProxy.TabIndex = 4; + this.btnTestProxy.Text = "Test Proxy"; + this.btnTestProxy.UseVisualStyleBackColor = true; + this.btnTestProxy.Click += new System.EventHandler(this.btnTestProxy_Click); + // + // UpdatesPage + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lblUpdatesExplanation); + this.Controls.Add(this.pnlUpdateCheck); + this.Controls.Add(this.pnlProxy); + this.Name = "UpdatesPage"; + this.PageIcon = ((System.Drawing.Icon)(resources.GetObject("$this.PageIcon"))); + this.Size = new System.Drawing.Size(610, 489); + this.pnlUpdateCheck.ResumeLayout(false); + this.pnlUpdateCheck.PerformLayout(); + this.pnlProxy.ResumeLayout(false); + this.pnlProxy.PerformLayout(); + this.pnlProxyBasic.ResumeLayout(false); + this.pnlProxyBasic.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).EndInit(); + this.pnlProxyAuthentication.ResumeLayout(false); + this.pnlProxyAuthentication.PerformLayout(); + this.ResumeLayout(false); + } internal System.Windows.Forms.Label lblUpdatesExplanation; internal System.Windows.Forms.Panel pnlUpdateCheck; @@ -286,6 +336,8 @@ namespace mRemoteNG.UI.Forms.OptionsPages internal System.Windows.Forms.Label lblProxyPassword; internal System.Windows.Forms.TextBox txtProxyPassword; internal System.Windows.Forms.Button btnTestProxy; - - } + private System.Windows.Forms.Label lblReleaseChannel; + private System.Windows.Forms.ComboBox cboReleaseChannel; + private System.Windows.Forms.TextBox textBox1; + } } \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs index b1d49f2b0..44243a0ac 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs @@ -84,6 +84,25 @@ namespace mRemoteNG.UI.Forms.OptionsPages break; } + var fin = cboReleaseChannel.Items.Add("Final"); + var beta = cboReleaseChannel.Items.Add("Beta"); + var prere = cboReleaseChannel.Items.Add("Pre-Release"); + switch (Settings.Default.UpdateChannel) + { + case "Final": + cboReleaseChannel.SelectedIndex = fin; + break; + case "Beta": + cboReleaseChannel.SelectedIndex = beta; + break; + case "Pre-Release": + cboReleaseChannel.SelectedIndex = prere; + break; + default: + cboReleaseChannel.SelectedIndex = fin; + break; + } + chkUseProxyForAutomaticUpdates.Checked = Convert.ToBoolean(Settings.Default.UpdateUseProxy); pnlProxyBasic.Enabled = Convert.ToBoolean(Settings.Default.UpdateUseProxy); txtProxyAddress.Text = Convert.ToString(Settings.Default.UpdateProxyAddress); @@ -116,6 +135,8 @@ namespace mRemoteNG.UI.Forms.OptionsPages Settings.Default.CheckForUpdatesFrequencyDays = 31; } + Settings.Default.UpdateChannel = cboReleaseChannel.Text; + Settings.Default.UpdateUseProxy = chkUseProxyForAutomaticUpdates.Checked; Settings.Default.UpdateProxyAddress = txtProxyAddress.Text; Settings.Default.UpdateProxyPort = (int) numProxyPort.Value; diff --git a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.resx b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.resx index 90e6d05ef..cef4dd5fc 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.resx +++ b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.resx @@ -112,12 +112,12 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/mRemoteV1/app.config b/mRemoteV1/app.config index 9f5783443..8fb7debe4 100644 --- a/mRemoteV1/app.config +++ b/mRemoteV1/app.config @@ -544,6 +544,9 @@ False + + release + @@ -608,9 +611,6 @@ de,el,en,en-US,es-AR,es,fr,hu,it,ja-JP,nb-NO,nl,pt,pt-BR,pl,ru,uk,tr-TR,zh-CN,zh-TW - - release - https://mremoteng.org/ From 27f8f2542e96dbcd9e07c9ac1607a2d91e281479 Mon Sep 17 00:00:00 2001 From: Tony M Lambert Date: Fri, 2 Dec 2016 15:25:05 -0600 Subject: [PATCH 002/106] Added screenshots for Quickconnect documentation --- .../Help/Screenshots/Quickconnect/01.png | Bin 0 -> 2300 bytes .../Help/Screenshots/Quickconnect/02.png | Bin 0 -> 4232 bytes .../Help/Screenshots/Quickconnect/03.png | Bin 0 -> 3924 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mRemoteV1/Resources/Help/Screenshots/Quickconnect/01.png create mode 100644 mRemoteV1/Resources/Help/Screenshots/Quickconnect/02.png create mode 100644 mRemoteV1/Resources/Help/Screenshots/Quickconnect/03.png diff --git a/mRemoteV1/Resources/Help/Screenshots/Quickconnect/01.png b/mRemoteV1/Resources/Help/Screenshots/Quickconnect/01.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa15b94dbfc2e867c4113cf3a18100d910f6e2d GIT binary patch literal 2300 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D01|XXSaefwW^{L9 za%BKVa%E+1b7*gLUR4MM000PcNklWm}HuU=z{Sh0RusoLIGX7AUpg} ziUkyGSIUQ^2dzK{9(8Sge zuLra+T2G7|*RNk!#mJ!j2r_8WaK+XUuLra+S|6;qdavTs((`zJ;|a`Na~QJ{4`9xk z0<7LwgNE}R+-r<-_3Bksj11b3AcH0iS8N^edO!=K^&(A|nz`{nq`Jk0$aP1tz2I9k zeecBA4HvO3uO7)+^;q~pE&dgkg^cVn?zKkf>FH6$g4dwSJm)Fmxg^HaW|PE6qK2V( z4rI`z;fk#zUJqztv|eO$(e|J)>8#@}Ji6>4vP){*^Lz6a;J5+o`R4!FezXH`<+LCo zy%LYbY(?6x9PSu;>F(}U#k?4_4dzf2Or}0U&9HIn{2#UmMX}>OF5#dRI3fIy8npDB z9q+LW$C3V+OROiC8saDKMI)MBBy#m!|>bPU+ zp|i7772_MU&5TfCG6p8m6EjQCe^=OxrvHUvi%=9h7Ll5xdp9c>rkGnS?0i+bUtiTo zAcH3PQfwXZdO!=K^&)A7AELaiOs7dJ`qdI87;O|RyqsvrQ5MPhK;C8!9hJ@E#mg=v zW}L!9@yC%O^z;GSFDP&M2~`dtwH!#y`4Jymo!E55fvJflm=yB~X2xv5;<*3fd}|wb z%)xLt9I6<{pglWhnK}C%zBg!Q^Eh% zv5FJs$@PCcQGJy0mXp7L9`p9RQ1W|H{CYBI63MfUq-(!_BO^hYSJo@hGU(*}Z(+;V zJKW~{`u>$z_E9XtH_k_kqeXVThrZqy>A!s;=9Gr3ZO}ux#UcIOMR;{mb{wq2xXH^g ze)>v`TXY!XmLA9Kk1k<#K^Io%cOdM&I*gA!2GfFUM802wg35DT?4(0M9t@-9Lqaw5sG5RB2sfy8mY=?eOV)c44ULi zv2~G-1JZIh08s^MU_PVsEdA-aGT8y#0#237IlNY?r0gv3` zQ@DM~GK`-r5WW+)zfyufL|gHX#A2PAtnjgGq7OnDyFDB&6*_cx(#(GW{j& z%`KIUrT4Mx>ePQ=G=2|y#0;7<@uO+b7Qsj*=PW0F`=bBYS2cY(F-8VW@|D;+;`M-* zIcU|3Xc_d&8OwE=Geh35Y!|G$^(pOTS>GG$b#Lf3XGYDrb}Wuh!=I+Vf+gz@VRAwN zOyRk>H|{G`G+f3nH-AM|xgC?1Y=%iN@q1=QtssL2g~tpWsKe}4mWJ~+ou!4v9zw=SbbF^iIG8*d?mJy zcs-zn(Rz`{txI*9Gh?vcSLUSNqs)&UxyS67wlEQ&K->on)F&6$QyJUC}L{v0v`Pep7* zY-$ZM%Wk0f^v`&6Pdg%$^YQ5XRS1dLikikQ?ihNhtgKYU$e{fQGHB9p#nut82edF+ zFA@yqeC0|nn!dk`P1y|yS-1@or?0`i|H;9u*V?c!r2}EF*5i(+_v8MTbCH(Uf(xDM z|D|Dsii!$VEa(iHL<(e$mO%##-A)%y+Pjce@Ex8{uft;r$M9fGJ|;&OVp@C&UNF~S zbN&U?GyzNMz8y=ZBsvIPd5|RYNz9)Lw$c+KwE7;_42Z zYUsj+b|;)d4eweb6c-n(Vr0-HQUHkzdhAkISg4ATL6b-UBr@o+OI}`{Dn9W(|_5Ck7y&k&=_wQJY7aT7}r1VIqLA3SqrjMxs^VzCeeK@da6g5Ll+ Wc+9H8*K{~t9nh?tTaV~cE|d!w-%$2!Pfma$#Q5*HUkb~U%MWr!MkCX|_MF_!FI z(G)RbOU#WM7o#ze-B|h_eSg2->%M+}oO7P%d7aPmS>Er@`+1#{YG-3Ez$eBBfj|T- z&?XKL2v-0&#=wq&_eaw2so;Yv!ol1KQZtBH1Se2`z#4!+>N5HFyt%loN~;F7>nm`N~QU$@)U)7xqAY>akVMB#e4VG*N|XL zH3D_jPLe;pyPkOsfMtq!bH%(=$xNyHu*%vWcwel&_1APqg#Xsp!Th+c>3?#H;|5zY zJK|{mgGDXsg<3JIa$FF|&nIAF5XfYPvmAdU9#9?u%(X@A?? zF;Mfmt#?(i{)VltK>nUu$IES>$;R4@sp$jl0hgB<^6x*HHS1II6Ey?X28y~Y-8H4~ zQYf$vj`T{0{+uP>r}rscu1d>k$osz^hYjbiT$0=1y097?y0%m=>Lat*62w^S`y4v7 zCu03>ZI|s@`k^+(FKNXq_S>gF)&tm*VtNVs9#=U>t`0sIX%>E1W}cZgCy5JrmNvy} zDL1@cL-eaF-XYD*QYnmTp19NxuBa>8&-?eHqpX|MmXMy*Thhh6Ud9emD`%%Skt)nz zD3UP6MKR?%{p@GuZ`x{Zno?-39puu98WtvMIkc>w+C1{{OL0RK!#fbQrke2WlKpF$ zQiZAgG^gM6t^1prMh4~tMnm`XICCXmE3Bo0MVdwK7$*y+&V>M)&UT@!>(_0sJ+CtI zP*dD9=RZhx==D#}3VZv&oI?1S-Ktylpf+e-+)11pCdR8CFJO`IDm|XTxS|&G_`{Ny zh}|$IsamPd#LeiEL$T^V*wgKlkv&$ia4E?+Xfxhg z9Fy8NE|gKZpM5YvHya@|4U5b=+0llbnXSWQES1z{-#@iKgNzuOoKz+R;cPOBB*KyS z6>c`1EI;`(gJeiY=lu^u0>8Uh$H4c)cDgMK#`Z9V7FO`4+`FAc2x$(lUi9>`;>JKV zc7m?lx-!3rwTcwCCZnus6VMH->Xlu{qNiLVZi`>uF-QwN@|>}KD>C&(E{W!mIa14W zpU7=Bp2B$FJJk`_8(u+_P@w*?4r3%ve2#CqR@}~)c<=Io>GI-E*5_sA^LxE1?# zMc_9ob}BM+C`MDy0@azM?xD*T%J7IHhzSZ=yKbEGxaiGOjG8~n`I@ptqTNXv$|5h* zv%aY_7rLY_)113hL)1mvZuT$GR0F1Sg_Hol@}g6f3Ed8n`MC-;xfc^72T{LTPLWX$ zBWx@~P5`p#FJcb0`|l0Sfa-AuE1Ea9yU2X8Wy{O5Z|AnQug0E~?2W%in(2=}=;JpW z%Xd4i{W#q50wa=rukXlxQh{HxE|GBzXbp<4Hz7^0e~wnvR@jw7!GHouxP`UgBCzqHMsE&S!FO zDaE$MKI=vIzNb8PqdeCYj?)SgcTO9A2tXI1I6(bbK5y4fY44&9Nkij4gS-T+JyTW$8y>cc(XT8Y`aYF zPF=PE#$C={CA187?w(!KszNU6v>nHpb@TlIIr|UiIPnX>wEo)Et#H4h{YU11){t!* zFX(a-5)(dU62tup473ez-Y1tYZ*?T!vxzB;&G5LKdYhj)W4~;_zv;6+(EPouB`C^{ z_JropoxN>3os8BVhwin*n0Al9Hs&xkJh$#VZCEouymY- zOl9zO&kq##hBp)Q%cCjA5y=pVNKXY%ugyvdeJeM=VkT-LeD?&kZ1ZxPAm60PzeIg% z{zD(YHTRyG;8koDwHdmVF!(jHEyv!r-3Y~sI4_`5jDGzFWxQow{gfQ4L0{J#ADUIq zwR^X{z`Up1&+HB|qu=70J_YJ(hPYBt)
jX6DP-$;{!z zt>F`~?p8^NJ&g>N(9-8uy@pm#d^bKZU|?u0uTpwGG#{;htjo|^H#3C+>*H*&djH=! zG$k(>ZV)yj$DX`-|JlH_jebZWu&|YIN9`a&)dLla`h;AR-e?IG-(Pv7jeYltpA`OC zlCz$*=OG4=YimXOea;0yQ^Q-W=wY7&+;oHg3cI5$nq<~&J8kKl;bEOiP%HJ6CD6xw zoakQX3z!q8B@QDsve+v2otGKJD)+_q-PgzddvXevT)>wQ2_I$~ym##}tvf%DX&{K0 z^tnPohuKZp^~KxBK*}VVHUD~bt{+T73^)siwMM(vUr%)r1RLMv2q1caUsUZ>zYG`< zTADfYw8`nfV9^CUyrpF~&d@uG3=%LZ{&4p*zLr*2Tt7~5?1k*S;MVI<4@XCzgM+tK!^Ooz3bjL66$LRL4)*$DK3y)GLOb0mhNZU-w732Zo!t=M~CdFs$wI#vatWV`>zEN`d~QGzU~BtG#c>9|ACf&+O;z zd>m!tW{%;IB_HubR|7#{jWnX%uR>v#+lPK+Yq(RN{w-A1nIK*po-U2stX$JY+Qoy8 zjsg|A=j<(H-@ITfZZ}R4c^@+@!#9*^&UEdP9z*-1K;a2!v8Nh|=o-Hm%~xdpHxA+2 zib%MA{t?4B)&yAl<%TT`@Z!ET1HmDsU^*S{cEI`H#XXuV^q|4BjgK*sSm?ll8A8dJ z{@}>r88u#yc znyNG!_2Cy%Ss;OwD=iU0cM@-uNJlDNs|{y`*#K){PZ?=043QG3q5Y8`mITVJCDPg9 z9`Qik#G;UHdvl6T>#s4|Cw;pT=Q?ptndA8S&genIA@FTm3_atDeym1@6FCH%s;M}P z=ewIrOovmj4axt+|?rxGH3 zAo0%pi#P|42-V0dU(f%3=7#xQ+yx^j@YikPfWqnK2^rXoAjm8Nal>s%Cu-qd8t9n| zkWE2=*6_%=GIFcEu*!7H(Cr%nBB1RNoSBd|7z!*D9<`JK94;B1#_B&h2fyM};@Lo{ zP2;%D@jgouVOxo|!Nc1)^;q#Yk#>Qb_E(eUUb6b@S?4&8k2;Rl6^&n=ET_~yM{PLs zb>Q#zk42%s@qiF+72c7E_pvjbw0}b9E{5BkdE|;JR=a+~pL<@le1&mUX|D5ZLr)>u zs;}!khG7${>p6ED%D$wU#wKEYh_&(PTC8X3{^xJ|EfZ(N=WKv`qBWV~xp8Wt!I^QL{=9 zOC*HVF@qIwGcWbc3%|6&t9%-bucKHh(+G93p%H36}ZY3!7j^mqsJF|9Iw#I_U4+1pxE?lo8!Hk92p-; zjJGDDRmh4WS8AJNjlBqaA0q#zH-K=kE99r!w9n3Z=ZFnN3hD6Gt1w(m<;P8t9UmLJ*K-?Ze-M|X*h zw#RioM2>$$DZLHB)NXB~b>NHOZa%!2-R=XM15FXLAFLTTa*>64UjF4DpW&HpITRBmE!zvqSUkcJL5>Mvcg5d?fGu`*64!LDpRsvHm=OlUJZMXF7s9Ii zfB~IQRt9>hNk4qa>}yPPbR>>?I8|L4akehL!^nvBibfIij>bIyg(x+O)J( z{KP*8(XD6CvEFxX>|3#vzo7)>ln+&9SKj+rylZw{9dxN^ z{A=3E+v%hlM5-BB>^d|0WFhXCmh>{M9I-Pu=a>X@n#Xs!TX{lYq$?f>7<>f8Qx+!X z2o94ErLp~lP6SV~4bQa7Ls0Rg1E3EMBP*TUnA;l?2aZCnmm3^?FSB|x3<5E%gYRha zazThL!r$k{nClJZtH$RgUe4J}3PT{b_Fnz#L%I%Ho#2|ys=@C)h=M{O(kOQ?!oxjJ kCM;o890Ezp5#yi=ma4mEcmP_9#Fwji-HdEPUV|C?9_ZFXSOzFC-GebSYwK4CnB;wt zIsNpovV^ThAS*AM{-dfJhmUG=YO`nsaCGmE1uZR2sLw9F^Ix6`+uB?6o`EjxXM1C^ z9&P&fjAYqk);1T%*rSd@u-srgop9R;GVPJ*dI>Pfy3(KTfREt7(zK$vTp1x{u-F&C zwXH?+Eo$u-9C@-e_hJC=u;Ig#PlO9v_e+%>+i@3072j2a9)!4$pVFCGWsoZ?+&wat z4Z}o$VfUqum^qKHa~TIyba~a4r6_sD`iJTSntjsCa?oDL_@h+w;=aTWk?KL4E{u?A z$a<`#5%z4x?U}v7?7BxE=L@WcI94ZP;TmHOU%qW6GUjUizO+VWDmGNHn4eLLoVt3v zdW(ZnVq0J3`3FhDdoL>}{CKgfhMk?=v%?>Ey3i)c=We|3Lgb#g-%!)SpBAn6{-*h4 z2}7#V*P2}}dpwp?9@F+?!~W%ZALpZB)&dW9;gER+oYKXXXETQ5SMr3PfSRN1_rGC^ zcFQb-N=2$_Ytermv$C${L}5)a2gt{XQ>;Q`p7eT1N?059wp6C%=dyqu&^$g7tN(48 z@ocqF(U)yyRF_j}ZFdH%u9^!0w3)`+-;_|$t&eE}^rSS62S%I7r8EfYaG{;TI^ zCoSSK?G`jlCcq7AEM+?(7Sy_^stm;yfN ziott0c1(|KcV3LjTj*4&+M?Y=qYIUnbbEk&S`fEU({7RMT2A1W<435I!t`op8Dste zW&5)1-A#$1+VBjw)d+;My6O8=OQ+&&yaz|9&z9e41LFGbjzE^u7sD*|6}v2@h1*%r zn+1l|*Uv7Mj>PVsTh^E^M`fv_B-bz{Z86V~1+LqyjQli4c%g^ZToxN~_j^;#o-e}6 z%8HpbUbw5j-^9js-=LRn@qqiqhV*NV{ncDhpwArd;(U^u@m}M%W?sEnW;9GDwv8Nt zM5#ruFIhxEZw@okutN@h6KNJ}`s_D9>~rsv&AyI?UXSMNEOqQoCvLB{jIB~$eWNr^ zm&%eSF00Ho1yU?gReL?-Iv`hYtVrpLE@svcxQX*vK}^bFd3-{y8@ZSfzxpK1{~n@W z@Vvsyqk&p{U)wxA@-Xcfp=+L}*UhV69CS-1J99RF$>`r6F>B}H_q&+!yB5p{8PPs= z{r9#LvkHyyc25JO|ETL0K+h7Xpwa+tywcE&{(97R&IZIWzGAo5=UP%P9X*c-uHvM3Lv&4w{9u?Cnf~j(x`E7O ztJb&bZSu5~=Y;##)L!9Drp1#mY;j(90L36Ym}dj z+IPdfvdO`1`U+VQbyIw%0W z+3Oagna_>8D|6@S6$|el**Te=;LU#h@$myv-{^{4dmnKqakFG&yMJT-fr$@KT%ii1 za&tViMjCEzp8w|^VH5} zee81>S78#yO%7s9G8Nopw=2S@8J#?i1+Mw_l3 zTP@laAf7XLb}pgE8mu}Oo<5S02z`MY<_o;PvpMGBxxL~bXc8fDC16FQ>DP>)pr?mP zuUOxHufl{@%Da25hdC?=cn*(5Eu8BWCg-*%ma%g9&~<~Tf%NaQ7Xd1pL9yx}Y# z->ZUxOEiEHLrNsQ@?5UbD;jimV=cd%pTO5P_Nm;-{iSFcSU*Nr7Hrbt>z>%)VnZ^l zt?d%)j_>HZU)!%4K<(`%cf|6Zd`7gXAA?vq#cWgjHl)H=l)a|)+7WRy7&6V!P{xtR zSsI1^Y6peG3+Q|{pbgidBAO||*xXtggiuu+7QDfK>-ajtYFMm(;M&~;*rXCx?k2^w z)Yp9}Ne%+-0KQeri^{7fkUGn0$?p;2EdXchKfxh_7Vy#5(^=F&cOmY{G%@y0ut;Av zPC}adjufOrnv2#=ORe*Pap0($Vnl$4Jq@r7QdIYq(Ti7|!GL@*mBz-=6O zn6nJ^ADDQ4xaaC?bG2kzN0_hO z<@=o$GjmvQg|7eR_p`l{(8cpqwP0Y;qmIBms?q~!HLw^M#^cngak}S>^bAYi01zlE zfR(uQ2M|}8dc~Q*56CX;4t6ic0T`&>X!j})fh1M1}YF#t!gB~Rbz=ds)zl)?a`2dB4NMH| zX&)oW!TYQS1BH7lm69=3pJ^m7_$qy9Um?t#%7Bf5gZJ3Tz?&?l@3elK4CBnh3h2`H3}E>+)}eP5{ZrUayNt6Q2LcAV69iYmeS--zG=zDbkrK+CG zLWiD)mzHp-{!+!s;qDS=3!jsTcF-aqHnc`li2(bSfmBV; z#1q*?NTW8Onbj!0rp>oA#}$vhhaJCTbTA<%5k|2psFBP$GA#+;5ul_B zV`x;Eb@JYa4fL(l&`*bTGS{xaYc(d&6TSh8Mg(8k3TgEXeRl|U;HX}MpHbyniOToO z^BdJ|2`>RGumJO}9yy%7F(}z;cW~O>QbmL438{=mZXV76kNE5q!RqDi?mqJOp3?&8 zNe6}+GBRwz%206I|ECLw7?`J*=)omJ)tP5yp`WGAL|^v+@Zif*B2yBbFJ}3+9g<=C z;U%f<*B>Q{NgtFe*A`5#rrXf-gncp-@PHEkjGoE#r*OKI_$yg~N=I;O)$cpG@9;z+ zd;L3S!YUxM)pcn$!5XtaJDAUxF=xk6W24Lye3KBl0hdP%T^i4%r{OnA`6z7A1n)3d zKT$zH%g+GxI1ngCn}y4u;S!NjmCBd|lVgpq6z|NxY0<+|e7knQ-0)&(Bgn3>)3!(O zanD1rf+@;Nx>};ENXbOSi~=vFoAWLGh8eJEA%GkA@DcwA1#Q#}G4>iJHyn}W3Nkd^ z8yz4!aFI%#jv^4K<@rHEmk$|9XaS&(A&mBuR9eihgi|U<-=_{M;d7q9r!Tms5P4H= z6XVQ7e|>Pk*m6^UE_(1mu*eFUg5%$7=C9)U+a#)+7IJ?8Js3E}a-LZ8;GzvS1>aa| zo+$vQ+#K%}swi>FU{{D@!{K?bCDlo9IOQQwagcrd@QyA$g69c>GM@qKrO=9cyoHaw z3GH%E|3a&BTFY#A!a9}ae&wS8!MlZ@ECr|XAC|+Ke|w_0GUB8NV+y6Y5GXp-^%&Q$ z%FPog?^(nC!%P25V}DuNxbagz+k#!PN)DCvfBa#*SEw114u<>xST4!p4IU4j!(BN_ zNj-4MRCy(>AtZ6_;Kz<}yBgl_?!%9BuesZ>{I1Rg_#`9hStt^P&HI_sLE2?r07c3l zDm&-6ac1T{jf9G88jw@bsUeO$I+5y{vWFC2#3;|(litMR0k%ya8Km8v7u#;cvBu3v z;t)3;#%%!-{TtMfKUAS#yWk)v5I^8+YHIqTsOUswWaRm4evq~G^~Eq)9XBRI+#dh@ z`EzDdplf21GGY12xh?vExX>?3(c8Bbm2i%;`~vZv##UC8h!bB44GlsE?EQjzwnq>) SKbfE2L;5;~+9jIz!v6&u&wncb literal 0 HcmV?d00001 From 24508abe7a0241a0379bef7dbaf5e11fb3529b1d Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 2 Dec 2016 16:41:37 -0500 Subject: [PATCH 003/106] rename channels --- mRemoteV1/App/Info/UpdateChannelInfo.cs | 20 +++++++++++-------- .../OptionsPages/UpdatesPage.Designer.cs | 9 +++++---- .../UI/Forms/OptionsPages/UpdatesPage.cs | 19 +++++++++--------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/mRemoteV1/App/Info/UpdateChannelInfo.cs b/mRemoteV1/App/Info/UpdateChannelInfo.cs index b199d5a8c..6954e4cc2 100644 --- a/mRemoteV1/App/Info/UpdateChannelInfo.cs +++ b/mRemoteV1/App/Info/UpdateChannelInfo.cs @@ -2,6 +2,10 @@ { public static class UpdateChannelInfo { + internal const string STABLE = "Stable"; + internal const string BETA = "Beta"; + internal const string DEV = "Development"; + public static string FileName { #if PORTABLE @@ -12,12 +16,12 @@ /* */ switch (Settings.Default.UpdateChannel) { - case "Final": + case STABLE: return "update-portable.txt"; - case "Beta": + case BETA: return "beta-update-portable.txt"; - case "Pre-Release": - return "prere-update-portable.txt"; + case DEV: + return "dev-update-portable.txt"; default: return "update-portable.txt"; } @@ -30,12 +34,12 @@ /* */ switch (Settings.Default.UpdateChannel) { - case "Final": + case STABLE: return "update.txt"; - case "Beta": + case BETA: return "beta-update.txt"; - case "Pre-Release": - return "prere-update.txt"; + case DEV: + return "dev-update.txt"; default: return "update.txt"; } diff --git a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs index bc77664a7..06617d63a 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.Designer.cs @@ -85,14 +85,15 @@ namespace mRemoteNG.UI.Forms.OptionsPages // this.textBox1.BackColor = System.Drawing.SystemColors.Control; this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.textBox1.Location = new System.Drawing.Point(226, 78); + this.textBox1.Location = new System.Drawing.Point(226, 68); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(366, 34); + this.textBox1.Size = new System.Drawing.Size(366, 44); this.textBox1.TabIndex = 5; - this.textBox1.Text = "Beta channel includes Release Candidates.\r\nPre-Release Channel includes Alphas an" + - "d Beta Channel releases."; + this.textBox1.Text = "Stable channel includes final releases only.\r\nBeta channel includes Betas & Relea" + + "se Candidates.\r\nDevelopment Channel includes Alphas, Betas & Release Candidates." + + ""; // // lblReleaseChannel // diff --git a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs index 44243a0ac..2ea1fea1e 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; using System.Windows.Forms; using mRemoteNG.App; +using mRemoteNG.App.Info; using mRemoteNG.App.Update; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tools; @@ -84,22 +85,22 @@ namespace mRemoteNG.UI.Forms.OptionsPages break; } - var fin = cboReleaseChannel.Items.Add("Final"); - var beta = cboReleaseChannel.Items.Add("Beta"); - var prere = cboReleaseChannel.Items.Add("Pre-Release"); + var stable = cboReleaseChannel.Items.Add(UpdateChannelInfo.STABLE); + var beta = cboReleaseChannel.Items.Add(UpdateChannelInfo.BETA); + var dev = cboReleaseChannel.Items.Add(UpdateChannelInfo.DEV); switch (Settings.Default.UpdateChannel) { - case "Final": - cboReleaseChannel.SelectedIndex = fin; + case UpdateChannelInfo.STABLE: + cboReleaseChannel.SelectedIndex = stable; break; - case "Beta": + case UpdateChannelInfo.BETA: cboReleaseChannel.SelectedIndex = beta; break; - case "Pre-Release": - cboReleaseChannel.SelectedIndex = prere; + case UpdateChannelInfo.DEV: + cboReleaseChannel.SelectedIndex = dev; break; default: - cboReleaseChannel.SelectedIndex = fin; + cboReleaseChannel.SelectedIndex = stable; break; } From 3dbcbae61f0ef82102f3b23a369d39ec2e8bef1b Mon Sep 17 00:00:00 2001 From: Tony M Lambert Date: Fri, 2 Dec 2016 15:49:04 -0600 Subject: [PATCH 004/106] Added code for Quick Connect documentation Added HTML code to document Quick Connect functionality --- mRemoteV1/Resources/Help/QuickConnect.htm | 71 +++++++++++++++++++---- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/mRemoteV1/Resources/Help/QuickConnect.htm b/mRemoteV1/Resources/Help/QuickConnect.htm index 943e82e9a..3a76ebc8b 100644 --- a/mRemoteV1/Resources/Help/QuickConnect.htm +++ b/mRemoteV1/Resources/Help/QuickConnect.htm @@ -1,13 +1,60 @@ - - - - Quick Connect - - - - -

- Sorry, not yet...

- - + + + + Quick Connect + + + + +

+ The Quick Connect functionality of mRemoteNG allows you to quickly connect to a remote host using a variety of network protocols. +

+ +

+ Use Cases +

+ +

+ The primary use case for Quick Connect is to connect to remote hosts when you already remember the DNS hostname/IP address and the appropriate protocol for the connection. +
+
+ An additional use case is to connect to remote hosts saved as a connection quickly. +

+ +

+ Prerequisites +

+ +
    +
  • Knowledge of a DNS host name or IP address
  • +
  • Knowledge of an appropriate protocol to communicate with remote host
  • +
+

OR

+
    +
  • A predefined mRemoteNG connection
  • +
+ +

+ Using QuickConnect +

+ +

+ To use Quick Connect, ensure the Quick Connect toolbar is enabled by selecting View and then Quick Connect Toolbar. +
+ Next, input a DNS host name or IP address into the box labeled "Connect". This box will also save previous entries during your session. +
+ Quick Connect Toolbar +
+
+ Quick Connect Toolbar +
+
+ Select the appropriate network protocol by clicking the arrow next to the Connect box. +
+ Quick Connect Toolbar +
+
+ If you wish to use an existing connection, select the globe icon next to the protocol button and select the appropriate connection. +

+ \ No newline at end of file From f7787c748ae1f7044856db17a5d4d105e52391df Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 3 Dec 2016 11:17:41 -0700 Subject: [PATCH 005/106] Added multiple build badges based on update channel to readme.md --- README.MD | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.MD b/README.MD index ecad8f95e..f2ce96154 100644 --- a/README.MD +++ b/README.MD @@ -4,12 +4,17 @@ [![Join the chat at https://gitter.im/mRemoteNG/PublicChat/](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mRemoteNG/PublicChat) [![PayPal](https://img.shields.io/badge/%24-PayPal-blue.svg)](https://www.paypal.me/DavidSparer) -[![Build Status](https://jenkins.mremoteng.org/buildStatus/icon?job=mRemoteNG/mRemoteNG/develop)](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/develop/) -[![Issues In Progress](https://badge.waffle.io/mRemoteNG/mRemoteNG.png?label=In%20Progress&title=In%20Progress)](https://waffle.io/mRemoteNG/mRemoteNG) -[![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.74/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.74) - [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/529/badge)](https://bestpractices.coreinfrastructure.org/projects/529) +[![Issues In Progress](https://badge.waffle.io/mRemoteNG/mRemoteNG.png?label=In%20Progress&title=In%20Progress)](https://waffle.io/mRemoteNG/mRemoteNG) + +| Update Channel | Build Status | Downloads | +| ---------------|--------------|-----------| +| Stable | [![Build Status](https://jenkins.mremoteng.org/buildStatus/icon?job=mRemoteNG/mRemoteNG/master)](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/master/) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.74/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.74) | +| Beta | [![Build Status](https://jenkins.mremoteng.org/buildStatus/icon?job=mRemoteNG/mRemoteNG/beta_channel)](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/beta_channel/) | [![Github Releases (by Release)](https://img.shields.io/github/downloads/mRemoteNG/mRemoteNG/v1.75Beta3/total.svg)](https://github.com/mRemoteNG/mRemoteNG/releases/tag/v1.75Beta3) | +| Development | [![Build Status](https://jenkins.mremoteng.org/buildStatus/icon?job=mRemoteNG/mRemoteNG/develop)](https://jenkins.mremoteng.org/job/mRemoteNG/job/mRemoteNG/job/develop/) | - | + + mRemoteNG is the next generation of mRemote, a full-featured, multi-tab remote connections manager. From 002e41f418de2e12558ea2e7b07f7b44b1c1d131 Mon Sep 17 00:00:00 2001 From: ForensicITGuy Date: Tue, 6 Dec 2016 01:04:52 -0600 Subject: [PATCH 006/106] Added Quick Connect screenshots into project. Modified folder name and HTML code to include spaces as observed in the other screenshot folders. Set to track content and copy if newer in output. --- mRemoteV1/Resources/Help/QuickConnect.htm | 6 +++--- .../Help/Screenshots/Quick Connect/01.png | Bin 0 -> 2300 bytes .../Help/Screenshots/Quick Connect/02.png | Bin 0 -> 4232 bytes .../Help/Screenshots/Quick Connect/03.png | Bin 0 -> 3924 bytes mRemoteV1/mRemoteV1.csproj | 9 +++++++++ 5 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 mRemoteV1/Resources/Help/Screenshots/Quick Connect/01.png create mode 100644 mRemoteV1/Resources/Help/Screenshots/Quick Connect/02.png create mode 100644 mRemoteV1/Resources/Help/Screenshots/Quick Connect/03.png diff --git a/mRemoteV1/Resources/Help/QuickConnect.htm b/mRemoteV1/Resources/Help/QuickConnect.htm index 3a76ebc8b..3f784d495 100644 --- a/mRemoteV1/Resources/Help/QuickConnect.htm +++ b/mRemoteV1/Resources/Help/QuickConnect.htm @@ -43,15 +43,15 @@
Next, input a DNS host name or IP address into the box labeled "Connect". This box will also save previous entries during your session.
- Quick Connect Toolbar + Quick Connect Toolbar

- Quick Connect Toolbar + Quick Connect Toolbar

Select the appropriate network protocol by clicking the arrow next to the Connect box.
- Quick Connect Toolbar + Quick Connect Toolbar

If you wish to use an existing connection, select the globe icon next to the protocol button and select the appropriate connection. diff --git a/mRemoteV1/Resources/Help/Screenshots/Quick Connect/01.png b/mRemoteV1/Resources/Help/Screenshots/Quick Connect/01.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa15b94dbfc2e867c4113cf3a18100d910f6e2d GIT binary patch literal 2300 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D01|XXSaefwW^{L9 za%BKVa%E+1b7*gLUR4MM000PcNklWm}HuU=z{Sh0RusoLIGX7AUpg} ziUkyGSIUQ^2dzK{9(8Sge zuLra+T2G7|*RNk!#mJ!j2r_8WaK+XUuLra+S|6;qdavTs((`zJ;|a`Na~QJ{4`9xk z0<7LwgNE}R+-r<-_3Bksj11b3AcH0iS8N^edO!=K^&(A|nz`{nq`Jk0$aP1tz2I9k zeecBA4HvO3uO7)+^;q~pE&dgkg^cVn?zKkf>FH6$g4dwSJm)Fmxg^HaW|PE6qK2V( z4rI`z;fk#zUJqztv|eO$(e|J)>8#@}Ji6>4vP){*^Lz6a;J5+o`R4!FezXH`<+LCo zy%LYbY(?6x9PSu;>F(}U#k?4_4dzf2Or}0U&9HIn{2#UmMX}>OF5#dRI3fIy8npDB z9q+LW$C3V+OROiC8saDKMI)MBBy#m!|>bPU+ zp|i7772_MU&5TfCG6p8m6EjQCe^=OxrvHUvi%=9h7Ll5xdp9c>rkGnS?0i+bUtiTo zAcH3PQfwXZdO!=K^&)A7AELaiOs7dJ`qdI87;O|RyqsvrQ5MPhK;C8!9hJ@E#mg=v zW}L!9@yC%O^z;GSFDP&M2~`dtwH!#y`4Jymo!E55fvJflm=yB~X2xv5;<*3fd}|wb z%)xLt9I6<{pglWhnK}C%zBg!Q^Eh% zv5FJs$@PCcQGJy0mXp7L9`p9RQ1W|H{CYBI63MfUq-(!_BO^hYSJo@hGU(*}Z(+;V zJKW~{`u>$z_E9XtH_k_kqeXVThrZqy>A!s;=9Gr3ZO}ux#UcIOMR;{mb{wq2xXH^g ze)>v`TXY!XmLA9Kk1k<#K^Io%cOdM&I*gA!2GfFUM802wg35DT?4(0M9t@-9Lqaw5sG5RB2sfy8mY=?eOV)c44ULi zv2~G-1JZIh08s^MU_PVsEdA-aGT8y#0#237IlNY?r0gv3` zQ@DM~GK`-r5WW+)zfyufL|gHX#A2PAtnjgGq7OnDyFDB&6*_cx(#(GW{j& z%`KIUrT4Mx>ePQ=G=2|y#0;7<@uO+b7Qsj*=PW0F`=bBYS2cY(F-8VW@|D;+;`M-* zIcU|3Xc_d&8OwE=Geh35Y!|G$^(pOTS>GG$b#Lf3XGYDrb}Wuh!=I+Vf+gz@VRAwN zOyRk>H|{G`G+f3nH-AM|xgC?1Y=%iN@q1=QtssL2g~tpWsKe}4mWJ~+ou!4v9zw=SbbF^iIG8*d?mJy zcs-zn(Rz`{txI*9Gh?vcSLUSNqs)&UxyS67wlEQ&K->on)F&6$QyJUC}L{v0v`Pep7* zY-$ZM%Wk0f^v`&6Pdg%$^YQ5XRS1dLikikQ?ihNhtgKYU$e{fQGHB9p#nut82edF+ zFA@yqeC0|nn!dk`P1y|yS-1@or?0`i|H;9u*V?c!r2}EF*5i(+_v8MTbCH(Uf(xDM z|D|Dsii!$VEa(iHL<(e$mO%##-A)%y+Pjce@Ex8{uft;r$M9fGJ|;&OVp@C&UNF~S zbN&U?GyzNMz8y=ZBsvIPd5|RYNz9)Lw$c+KwE7;_42Z zYUsj+b|;)d4eweb6c-n(Vr0-HQUHkzdhAkISg4ATL6b-UBr@o+OI}`{Dn9W(|_5Ck7y&k&=_wQJY7aT7}r1VIqLA3SqrjMxs^VzCeeK@da6g5Ll+ Wc+9H8*K{~t9nh?tTaV~cE|d!w-%$2!Pfma$#Q5*HUkb~U%MWr!MkCX|_MF_!FI z(G)RbOU#WM7o#ze-B|h_eSg2->%M+}oO7P%d7aPmS>Er@`+1#{YG-3Ez$eBBfj|T- z&?XKL2v-0&#=wq&_eaw2so;Yv!ol1KQZtBH1Se2`z#4!+>N5HFyt%loN~;F7>nm`N~QU$@)U)7xqAY>akVMB#e4VG*N|XL zH3D_jPLe;pyPkOsfMtq!bH%(=$xNyHu*%vWcwel&_1APqg#Xsp!Th+c>3?#H;|5zY zJK|{mgGDXsg<3JIa$FF|&nIAF5XfYPvmAdU9#9?u%(X@A?? zF;Mfmt#?(i{)VltK>nUu$IES>$;R4@sp$jl0hgB<^6x*HHS1II6Ey?X28y~Y-8H4~ zQYf$vj`T{0{+uP>r}rscu1d>k$osz^hYjbiT$0=1y097?y0%m=>Lat*62w^S`y4v7 zCu03>ZI|s@`k^+(FKNXq_S>gF)&tm*VtNVs9#=U>t`0sIX%>E1W}cZgCy5JrmNvy} zDL1@cL-eaF-XYD*QYnmTp19NxuBa>8&-?eHqpX|MmXMy*Thhh6Ud9emD`%%Skt)nz zD3UP6MKR?%{p@GuZ`x{Zno?-39puu98WtvMIkc>w+C1{{OL0RK!#fbQrke2WlKpF$ zQiZAgG^gM6t^1prMh4~tMnm`XICCXmE3Bo0MVdwK7$*y+&V>M)&UT@!>(_0sJ+CtI zP*dD9=RZhx==D#}3VZv&oI?1S-Ktylpf+e-+)11pCdR8CFJO`IDm|XTxS|&G_`{Ny zh}|$IsamPd#LeiEL$T^V*wgKlkv&$ia4E?+Xfxhg z9Fy8NE|gKZpM5YvHya@|4U5b=+0llbnXSWQES1z{-#@iKgNzuOoKz+R;cPOBB*KyS z6>c`1EI;`(gJeiY=lu^u0>8Uh$H4c)cDgMK#`Z9V7FO`4+`FAc2x$(lUi9>`;>JKV zc7m?lx-!3rwTcwCCZnus6VMH->Xlu{qNiLVZi`>uF-QwN@|>}KD>C&(E{W!mIa14W zpU7=Bp2B$FJJk`_8(u+_P@w*?4r3%ve2#CqR@}~)c<=Io>GI-E*5_sA^LxE1?# zMc_9ob}BM+C`MDy0@azM?xD*T%J7IHhzSZ=yKbEGxaiGOjG8~n`I@ptqTNXv$|5h* zv%aY_7rLY_)113hL)1mvZuT$GR0F1Sg_Hol@}g6f3Ed8n`MC-;xfc^72T{LTPLWX$ zBWx@~P5`p#FJcb0`|l0Sfa-AuE1Ea9yU2X8Wy{O5Z|AnQug0E~?2W%in(2=}=;JpW z%Xd4i{W#q50wa=rukXlxQh{HxE|GBzXbp<4Hz7^0e~wnvR@jw7!GHouxP`UgBCzqHMsE&S!FO zDaE$MKI=vIzNb8PqdeCYj?)SgcTO9A2tXI1I6(bbK5y4fY44&9Nkij4gS-T+JyTW$8y>cc(XT8Y`aYF zPF=PE#$C={CA187?w(!KszNU6v>nHpb@TlIIr|UiIPnX>wEo)Et#H4h{YU11){t!* zFX(a-5)(dU62tup473ez-Y1tYZ*?T!vxzB;&G5LKdYhj)W4~;_zv;6+(EPouB`C^{ z_JropoxN>3os8BVhwin*n0Al9Hs&xkJh$#VZCEouymY- zOl9zO&kq##hBp)Q%cCjA5y=pVNKXY%ugyvdeJeM=VkT-LeD?&kZ1ZxPAm60PzeIg% z{zD(YHTRyG;8koDwHdmVF!(jHEyv!r-3Y~sI4_`5jDGzFWxQow{gfQ4L0{J#ADUIq zwR^X{z`Up1&+HB|qu=70J_YJ(hPYBt)
jX6DP-$;{!z zt>F`~?p8^NJ&g>N(9-8uy@pm#d^bKZU|?u0uTpwGG#{;htjo|^H#3C+>*H*&djH=! zG$k(>ZV)yj$DX`-|JlH_jebZWu&|YIN9`a&)dLla`h;AR-e?IG-(Pv7jeYltpA`OC zlCz$*=OG4=YimXOea;0yQ^Q-W=wY7&+;oHg3cI5$nq<~&J8kKl;bEOiP%HJ6CD6xw zoakQX3z!q8B@QDsve+v2otGKJD)+_q-PgzddvXevT)>wQ2_I$~ym##}tvf%DX&{K0 z^tnPohuKZp^~KxBK*}VVHUD~bt{+T73^)siwMM(vUr%)r1RLMv2q1caUsUZ>zYG`< zTADfYw8`nfV9^CUyrpF~&d@uG3=%LZ{&4p*zLr*2Tt7~5?1k*S;MVI<4@XCzgM+tK!^Ooz3bjL66$LRL4)*$DK3y)GLOb0mhNZU-w732Zo!t=M~CdFs$wI#vatWV`>zEN`d~QGzU~BtG#c>9|ACf&+O;z zd>m!tW{%;IB_HubR|7#{jWnX%uR>v#+lPK+Yq(RN{w-A1nIK*po-U2stX$JY+Qoy8 zjsg|A=j<(H-@ITfZZ}R4c^@+@!#9*^&UEdP9z*-1K;a2!v8Nh|=o-Hm%~xdpHxA+2 zib%MA{t?4B)&yAl<%TT`@Z!ET1HmDsU^*S{cEI`H#XXuV^q|4BjgK*sSm?ll8A8dJ z{@}>r88u#yc znyNG!_2Cy%Ss;OwD=iU0cM@-uNJlDNs|{y`*#K){PZ?=043QG3q5Y8`mITVJCDPg9 z9`Qik#G;UHdvl6T>#s4|Cw;pT=Q?ptndA8S&genIA@FTm3_atDeym1@6FCH%s;M}P z=ewIrOovmj4axt+|?rxGH3 zAo0%pi#P|42-V0dU(f%3=7#xQ+yx^j@YikPfWqnK2^rXoAjm8Nal>s%Cu-qd8t9n| zkWE2=*6_%=GIFcEu*!7H(Cr%nBB1RNoSBd|7z!*D9<`JK94;B1#_B&h2fyM};@Lo{ zP2;%D@jgouVOxo|!Nc1)^;q#Yk#>Qb_E(eUUb6b@S?4&8k2;Rl6^&n=ET_~yM{PLs zb>Q#zk42%s@qiF+72c7E_pvjbw0}b9E{5BkdE|;JR=a+~pL<@le1&mUX|D5ZLr)>u zs;}!khG7${>p6ED%D$wU#wKEYh_&(PTC8X3{^xJ|EfZ(N=WKv`qBWV~xp8Wt!I^QL{=9 zOC*HVF@qIwGcWbc3%|6&t9%-bucKHh(+G93p%H36}ZY3!7j^mqsJF|9Iw#I_U4+1pxE?lo8!Hk92p-; zjJGDDRmh4WS8AJNjlBqaA0q#zH-K=kE99r!w9n3Z=ZFnN3hD6Gt1w(m<;P8t9UmLJ*K-?Ze-M|X*h zw#RioM2>$$DZLHB)NXB~b>NHOZa%!2-R=XM15FXLAFLTTa*>64UjF4DpW&HpITRBmE!zvqSUkcJL5>Mvcg5d?fGu`*64!LDpRsvHm=OlUJZMXF7s9Ii zfB~IQRt9>hNk4qa>}yPPbR>>?I8|L4akehL!^nvBibfIij>bIyg(x+O)J( z{KP*8(XD6CvEFxX>|3#vzo7)>ln+&9SKj+rylZw{9dxN^ z{A=3E+v%hlM5-BB>^d|0WFhXCmh>{M9I-Pu=a>X@n#Xs!TX{lYq$?f>7<>f8Qx+!X z2o94ErLp~lP6SV~4bQa7Ls0Rg1E3EMBP*TUnA;l?2aZCnmm3^?FSB|x3<5E%gYRha zazThL!r$k{nClJZtH$RgUe4J}3PT{b_Fnz#L%I%Ho#2|ys=@C)h=M{O(kOQ?!oxjJ kCM;o890Ezp5#yi=ma4mEcmP_9#Fwji-HdEPUV|C?9_ZFXSOzFC-GebSYwK4CnB;wt zIsNpovV^ThAS*AM{-dfJhmUG=YO`nsaCGmE1uZR2sLw9F^Ix6`+uB?6o`EjxXM1C^ z9&P&fjAYqk);1T%*rSd@u-srgop9R;GVPJ*dI>Pfy3(KTfREt7(zK$vTp1x{u-F&C zwXH?+Eo$u-9C@-e_hJC=u;Ig#PlO9v_e+%>+i@3072j2a9)!4$pVFCGWsoZ?+&wat z4Z}o$VfUqum^qKHa~TIyba~a4r6_sD`iJTSntjsCa?oDL_@h+w;=aTWk?KL4E{u?A z$a<`#5%z4x?U}v7?7BxE=L@WcI94ZP;TmHOU%qW6GUjUizO+VWDmGNHn4eLLoVt3v zdW(ZnVq0J3`3FhDdoL>}{CKgfhMk?=v%?>Ey3i)c=We|3Lgb#g-%!)SpBAn6{-*h4 z2}7#V*P2}}dpwp?9@F+?!~W%ZALpZB)&dW9;gER+oYKXXXETQ5SMr3PfSRN1_rGC^ zcFQb-N=2$_Ytermv$C${L}5)a2gt{XQ>;Q`p7eT1N?059wp6C%=dyqu&^$g7tN(48 z@ocqF(U)yyRF_j}ZFdH%u9^!0w3)`+-;_|$t&eE}^rSS62S%I7r8EfYaG{;TI^ zCoSSK?G`jlCcq7AEM+?(7Sy_^stm;yfN ziott0c1(|KcV3LjTj*4&+M?Y=qYIUnbbEk&S`fEU({7RMT2A1W<435I!t`op8Dste zW&5)1-A#$1+VBjw)d+;My6O8=OQ+&&yaz|9&z9e41LFGbjzE^u7sD*|6}v2@h1*%r zn+1l|*Uv7Mj>PVsTh^E^M`fv_B-bz{Z86V~1+LqyjQli4c%g^ZToxN~_j^;#o-e}6 z%8HpbUbw5j-^9js-=LRn@qqiqhV*NV{ncDhpwArd;(U^u@m}M%W?sEnW;9GDwv8Nt zM5#ruFIhxEZw@okutN@h6KNJ}`s_D9>~rsv&AyI?UXSMNEOqQoCvLB{jIB~$eWNr^ zm&%eSF00Ho1yU?gReL?-Iv`hYtVrpLE@svcxQX*vK}^bFd3-{y8@ZSfzxpK1{~n@W z@Vvsyqk&p{U)wxA@-Xcfp=+L}*UhV69CS-1J99RF$>`r6F>B}H_q&+!yB5p{8PPs= z{r9#LvkHyyc25JO|ETL0K+h7Xpwa+tywcE&{(97R&IZIWzGAo5=UP%P9X*c-uHvM3Lv&4w{9u?Cnf~j(x`E7O ztJb&bZSu5~=Y;##)L!9Drp1#mY;j(90L36Ym}dj z+IPdfvdO`1`U+VQbyIw%0W z+3Oagna_>8D|6@S6$|el**Te=;LU#h@$myv-{^{4dmnKqakFG&yMJT-fr$@KT%ii1 za&tViMjCEzp8w|^VH5} zee81>S78#yO%7s9G8Nopw=2S@8J#?i1+Mw_l3 zTP@laAf7XLb}pgE8mu}Oo<5S02z`MY<_o;PvpMGBxxL~bXc8fDC16FQ>DP>)pr?mP zuUOxHufl{@%Da25hdC?=cn*(5Eu8BWCg-*%ma%g9&~<~Tf%NaQ7Xd1pL9yx}Y# z->ZUxOEiEHLrNsQ@?5UbD;jimV=cd%pTO5P_Nm;-{iSFcSU*Nr7Hrbt>z>%)VnZ^l zt?d%)j_>HZU)!%4K<(`%cf|6Zd`7gXAA?vq#cWgjHl)H=l)a|)+7WRy7&6V!P{xtR zSsI1^Y6peG3+Q|{pbgidBAO||*xXtggiuu+7QDfK>-ajtYFMm(;M&~;*rXCx?k2^w z)Yp9}Ne%+-0KQeri^{7fkUGn0$?p;2EdXchKfxh_7Vy#5(^=F&cOmY{G%@y0ut;Av zPC}adjufOrnv2#=ORe*Pap0($Vnl$4Jq@r7QdIYq(Ti7|!GL@*mBz-=6O zn6nJ^ADDQ4xaaC?bG2kzN0_hO z<@=o$GjmvQg|7eR_p`l{(8cpqwP0Y;qmIBms?q~!HLw^M#^cngak}S>^bAYi01zlE zfR(uQ2M|}8dc~Q*56CX;4t6ic0T`&>X!j})fh1M1}YF#t!gB~Rbz=ds)zl)?a`2dB4NMH| zX&)oW!TYQS1BH7lm69=3pJ^m7_$qy9Um?t#%7Bf5gZJ3Tz?&?l@3elK4CBnh3h2`H3}E>+)}eP5{ZrUayNt6Q2LcAV69iYmeS--zG=zDbkrK+CG zLWiD)mzHp-{!+!s;qDS=3!jsTcF-aqHnc`li2(bSfmBV; z#1q*?NTW8Onbj!0rp>oA#}$vhhaJCTbTA<%5k|2psFBP$GA#+;5ul_B zV`x;Eb@JYa4fL(l&`*bTGS{xaYc(d&6TSh8Mg(8k3TgEXeRl|U;HX}MpHbyniOToO z^BdJ|2`>RGumJO}9yy%7F(}z;cW~O>QbmL438{=mZXV76kNE5q!RqDi?mqJOp3?&8 zNe6}+GBRwz%206I|ECLw7?`J*=)omJ)tP5yp`WGAL|^v+@Zif*B2yBbFJ}3+9g<=C z;U%f<*B>Q{NgtFe*A`5#rrXf-gncp-@PHEkjGoE#r*OKI_$yg~N=I;O)$cpG@9;z+ zd;L3S!YUxM)pcn$!5XtaJDAUxF=xk6W24Lye3KBl0hdP%T^i4%r{OnA`6z7A1n)3d zKT$zH%g+GxI1ngCn}y4u;S!NjmCBd|lVgpq6z|NxY0<+|e7knQ-0)&(Bgn3>)3!(O zanD1rf+@;Nx>};ENXbOSi~=vFoAWLGh8eJEA%GkA@DcwA1#Q#}G4>iJHyn}W3Nkd^ z8yz4!aFI%#jv^4K<@rHEmk$|9XaS&(A&mBuR9eihgi|U<-=_{M;d7q9r!Tms5P4H= z6XVQ7e|>Pk*m6^UE_(1mu*eFUg5%$7=C9)U+a#)+7IJ?8Js3E}a-LZ8;GzvS1>aa| zo+$vQ+#K%}swi>FU{{D@!{K?bCDlo9IOQQwagcrd@QyA$g69c>GM@qKrO=9cyoHaw z3GH%E|3a&BTFY#A!a9}ae&wS8!MlZ@ECr|XAC|+Ke|w_0GUB8NV+y6Y5GXp-^%&Q$ z%FPog?^(nC!%P25V}DuNxbagz+k#!PN)DCvfBa#*SEw114u<>xST4!p4IU4j!(BN_ zNj-4MRCy(>AtZ6_;Kz<}yBgl_?!%9BuesZ>{I1Rg_#`9hStt^P&HI_sLE2?r07c3l zDm&-6ac1T{jf9G88jw@bsUeO$I+5y{vWFC2#3;|(litMR0k%ya8Km8v7u#;cvBu3v z;t)3;#%%!-{TtMfKUAS#yWk)v5I^8+YHIqTsOUswWaRm4evq~G^~Eq)9XBRI+#dh@ z`EzDdplf21GGY12xh?vExX>?3(c8Bbm2i%;`~vZv##UC8h!bB44GlsE?EQjzwnq>) SKbfE2L;5;~+9jIz!v6&u&wncb literal 0 HcmV?d00001 diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 10e50f4ec..d3975c74d 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -762,6 +762,15 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest From 6367b589941c1d938f922e39f159a98a9c954f86 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 6 Dec 2016 15:28:56 -0700 Subject: [PATCH 007/106] began adding unit tests for the connectiontree ui --- .../UI/Window/ConnectionTreeWindowTests.cs | 54 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + 2 files changed, 55 insertions(+) create mode 100644 mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs diff --git a/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs b/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs new file mode 100644 index 000000000..1c1fcaecd --- /dev/null +++ b/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs @@ -0,0 +1,54 @@ +using System.Threading; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using mRemoteNG.UI.Window; +using NUnit.Framework; +using WeifenLuo.WinFormsUI.Docking; + + +namespace mRemoteNGTests.UI.Window +{ + public class ConnectionTreeWindowTests + { + private ConnectionTreeWindow _connectionTreeWindow; + + [SetUp] + public void Setup() + { + _connectionTreeWindow = new ConnectionTreeWindow(new DockContent()); + } + + [TearDown] + public void Teardown() + { + _connectionTreeWindow.Close(); + } + + [Test, Apartment(ApartmentState.STA)] + public void CanSetTheConnectionTreeModel() + { + var treeModel = CreateConnectionTreeModel(); + _connectionTreeWindow.ConnectionTreeModel = treeModel; + _connectionTreeWindow.Show(); + Assert.That(_connectionTreeWindow.ConnectionTreeModel, Is.EqualTo(treeModel)); + } + + [Test, Apartment(ApartmentState.STA)] + public void CanDeleteLastFolderInTheTree() + { + var treeModel = CreateConnectionTreeModel(); + treeModel.RootNodes[0].AddChild(new ContainerInfo()); + _connectionTreeWindow.ConnectionTreeModel = treeModel; + _connectionTreeWindow.Show(); + Assert.That(_connectionTreeWindow.ConnectionTreeModel, Is.EqualTo(treeModel)); + } + + private ConnectionTreeModel CreateConnectionTreeModel() + { + var connectionTreeModel = new ConnectionTreeModel(); + connectionTreeModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection)); + return connectionTreeModel; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index b1343dc61..a8010efee 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -157,6 +157,7 @@ + From e38f7c880e2180a31f14c5498cc92435245bbf9d Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 6 Dec 2016 19:13:09 -0500 Subject: [PATCH 008/106] code clean up Added some log messages for #298 --- mRemoteV1/App/CompatibilityChecker.cs | 35 +++++++------- mRemoteV1/App/Startup.cs | 66 +++++++++++++-------------- 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/mRemoteV1/App/CompatibilityChecker.cs b/mRemoteV1/App/CompatibilityChecker.cs index a7e29265c..c69da026d 100644 --- a/mRemoteV1/App/CompatibilityChecker.cs +++ b/mRemoteV1/App/CompatibilityChecker.cs @@ -8,24 +8,23 @@ using System.Windows.Forms; namespace mRemoteNG.App { - public class CompatibilityChecker + public static class CompatibilityChecker { - public void CheckCompatibility() + public static void CheckCompatibility() { CheckFipsPolicy(); CheckLenovoAutoScrollUtility(); } - private void CheckFipsPolicy() + private static void CheckFipsPolicy() { - if (FipsPolicyEnabledForServer2003() || FipsPolicyEnabledForServer2008AndNewer()) - { - MessageBox.Show(frmMain.Default, string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName, GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)); - Environment.Exit(1); - } + Logger.Instance.InfoFormat("Checking FIPS Policy..."); + if (!FipsPolicyEnabledForServer2003() && !FipsPolicyEnabledForServer2008AndNewer()) return; + MessageBox.Show(frmMain.Default, string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName, GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)); + Environment.Exit(1); } - private bool FipsPolicyEnabledForServer2003() + private static bool FipsPolicyEnabledForServer2003() { var regKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Lsa"); var fipsPolicy = regKey?.GetValue("FIPSAlgorithmPolicy"); @@ -34,7 +33,7 @@ namespace mRemoteNG.App return (int)fipsPolicy != 0; } - private bool FipsPolicyEnabledForServer2008AndNewer() + private static bool FipsPolicyEnabledForServer2008AndNewer() { var regKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Lsa\\FIPSAlgorithmPolicy"); var fipsPolicy = regKey?.GetValue("Enabled"); @@ -43,12 +42,14 @@ namespace mRemoteNG.App return (int)fipsPolicy != 0; } - private void CheckLenovoAutoScrollUtility() + private static void CheckLenovoAutoScrollUtility() { + Logger.Instance.InfoFormat("Checking Lenovo AutoScroll Utility..."); + if (!Settings.Default.CompatibilityWarnLenovoAutoScrollUtility) return; - Process[] proccesses = new Process[] { }; + var proccesses = new Process[] { }; try { proccesses = Process.GetProcessesByName("virtscrl"); @@ -58,12 +59,10 @@ namespace mRemoteNG.App Runtime.MessageCollector.AddExceptionMessage("Error in CheckLenovoAutoScrollUtility", ex); } - if (proccesses.Length > 0) - { - CTaskDialog.MessageBox(Application.ProductName, Language.strCompatibilityProblemDetected, string.Format(Language.strCompatibilityLenovoAutoScrollUtilityDetected, Application.ProductName), "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.Ok, ESysIcons.Warning, ESysIcons.Warning); - if (CTaskDialog.VerificationChecked) - Settings.Default.CompatibilityWarnLenovoAutoScrollUtility = false; - } + if (proccesses.Length <= 0) return; + CTaskDialog.MessageBox(Application.ProductName, Language.strCompatibilityProblemDetected, string.Format(Language.strCompatibilityLenovoAutoScrollUtilityDetected, Application.ProductName), "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.Ok, ESysIcons.Warning, ESysIcons.Warning); + if (CTaskDialog.VerificationChecked) + Settings.Default.CompatibilityWarnLenovoAutoScrollUtility = false; } } } diff --git a/mRemoteV1/App/Startup.cs b/mRemoteV1/App/Startup.cs index cd067324a..163669376 100644 --- a/mRemoteV1/App/Startup.cs +++ b/mRemoteV1/App/Startup.cs @@ -22,14 +22,12 @@ namespace mRemoteNG.App { public class Startup { - private CompatibilityChecker _compatibilityChecker; private AppUpdater _appUpdate; public static Startup Instance { get; } = new Startup(); private Startup() { - _compatibilityChecker = new CompatibilityChecker(); _appUpdate = new AppUpdater(); } @@ -41,12 +39,12 @@ namespace mRemoteNG.App { Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture)); LogStartupData(); - _compatibilityChecker.CheckCompatibility(); + CompatibilityChecker.CheckCompatibility(); ParseCommandLineArgs(); IeBrowserEmulation.Register(); GetConnectionIcons(); - DefaultConnectionInfo.Instance.LoadFrom(Settings.Default, (a)=>"ConDefault"+a); - DefaultConnectionInheritance.Instance.LoadFrom(Settings.Default, (a)=>"InhDefault"+a); + DefaultConnectionInfo.Instance.LoadFrom(Settings.Default, a=>"ConDefault"+a); + DefaultConnectionInheritance.Instance.LoadFrom(Settings.Default, a=>"InhDefault"+a); } public void SetDefaultLayout() @@ -67,23 +65,23 @@ namespace mRemoteNG.App frmMain.Default.pnlDock.Visible = true; } - private void GetConnectionIcons() + private static void GetConnectionIcons() { - string iPath = GeneralAppInfo.HomePath + "\\Icons\\"; + var iPath = GeneralAppInfo.HomePath + "\\Icons\\"; if (Directory.Exists(iPath) == false) { return; } - foreach (string f in Directory.GetFiles(iPath, "*.ico", SearchOption.AllDirectories)) + foreach (var f in Directory.GetFiles(iPath, "*.ico", SearchOption.AllDirectories)) { - FileInfo fInfo = new FileInfo(f); + var fInfo = new FileInfo(f); Array.Resize(ref ConnectionIcon.Icons, ConnectionIcon.Icons.Length + 1); ConnectionIcon.Icons.SetValue(fInfo.Name.Replace(".ico", ""), ConnectionIcon.Icons.Length - 1); } } - private void LogStartupData() + private static void LogStartupData() { if (!Settings.Default.WriteLogFile) return; LogApplicationData(); @@ -93,17 +91,17 @@ namespace mRemoteNG.App LogCultureData(); } - private void LogSystemData() + private static void LogSystemData() { - string osData = GetOperatingSystemData(); - string architecture = GetArchitectureData(); + var osData = GetOperatingSystemData(); + var architecture = GetArchitectureData(); Logger.Instance.InfoFormat(string.Join(" ", Array.FindAll(new[] { osData, architecture }, s => !string.IsNullOrEmpty(Convert.ToString(s))))); } - private string GetOperatingSystemData() + private static string GetOperatingSystemData() { - string osVersion = string.Empty; - string servicePack = string.Empty; + var osVersion = string.Empty; + var servicePack = string.Empty; try { @@ -118,13 +116,13 @@ namespace mRemoteNG.App { Logger.Instance.WarnFormat($"Error retrieving operating system information from WMI. {ex.Message}"); } - string osData = string.Join(" ", new string[] { osVersion, servicePack }); + var osData = string.Join(" ", new string[] { osVersion, servicePack }); return osData; } - private string GetOSServicePack(string servicePack, ManagementObject managementObject) + private static string GetOSServicePack(string servicePack, ManagementObject managementObject) { - int servicePackNumber = Convert.ToInt32(managementObject.GetPropertyValue("ServicePackMajorVersion")); + var servicePackNumber = Convert.ToInt32(managementObject.GetPropertyValue("ServicePackMajorVersion")); if (servicePackNumber != 0) { servicePack = $"Service Pack {servicePackNumber}"; @@ -132,15 +130,15 @@ namespace mRemoteNG.App return servicePack; } - private string GetArchitectureData() + private static string GetArchitectureData() { - string architecture = string.Empty; + var architecture = string.Empty; try { foreach (var o in new ManagementObjectSearcher("SELECT * FROM Win32_Processor WHERE DeviceID=\'CPU0\'").Get()) { var managementObject = (ManagementObject) o; - int addressWidth = Convert.ToInt32(managementObject.GetPropertyValue("AddressWidth")); + var addressWidth = Convert.ToInt32(managementObject.GetPropertyValue("AddressWidth")); architecture = $"{addressWidth}-bit"; } } @@ -151,7 +149,7 @@ namespace mRemoteNG.App return architecture; } - private void LogApplicationData() + private static void LogApplicationData() { #if !PORTABLE Logger.Instance.InfoFormat($"{Application.ProductName} {Application.ProductVersion} starting."); @@ -161,17 +159,17 @@ namespace mRemoteNG.App #endif } - private void LogCmdLineArgs() + private static void LogCmdLineArgs() { Logger.Instance.InfoFormat($"Command Line: {Environment.GetCommandLineArgs()}"); } - private void LogCLRData() + private static void LogCLRData() { Logger.Instance.InfoFormat($"Microsoft .NET CLR {Environment.Version}"); } - private void LogCultureData() + private static void LogCultureData() { Logger.Instance.InfoFormat( $"System Culture: {Thread.CurrentThread.CurrentUICulture.Name}/{Thread.CurrentThread.CurrentUICulture.NativeName}"); @@ -197,7 +195,7 @@ namespace mRemoteNG.App return; } - DateTime nextUpdateCheck = Convert.ToDateTime(Settings.Default.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(Convert.ToDouble(Settings.Default.CheckForUpdatesFrequencyDays)))); + var nextUpdateCheck = Convert.ToDateTime(Settings.Default.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(Convert.ToDouble(Settings.Default.CheckForUpdatesFrequencyDays)))); if (!Settings.Default.UpdatePending && DateTime.UtcNow < nextUpdateCheck) { return; @@ -240,13 +238,13 @@ namespace mRemoteNG.App } - private void ParseCommandLineArgs() + private static void ParseCommandLineArgs() { try { - CmdArgumentsInterpreter cmd = new CmdArgumentsInterpreter(Environment.GetCommandLineArgs()); + var cmd = new CmdArgumentsInterpreter(Environment.GetCommandLineArgs()); - string ConsParam = ""; + var ConsParam = ""; if (cmd["cons"] != null) { ConsParam = "cons"; @@ -256,7 +254,7 @@ namespace mRemoteNG.App ConsParam = "c"; } - string ResetPosParam = ""; + var ResetPosParam = ""; if (cmd["resetpos"] != null) { ResetPosParam = "resetpos"; @@ -266,7 +264,7 @@ namespace mRemoteNG.App ResetPosParam = "rp"; } - string ResetPanelsParam = ""; + var ResetPanelsParam = ""; if (cmd["resetpanels"] != null) { ResetPanelsParam = "resetpanels"; @@ -276,7 +274,7 @@ namespace mRemoteNG.App ResetPanelsParam = "rpnl"; } - string ResetToolbarsParam = ""; + var ResetToolbarsParam = ""; if (cmd["resettoolbar"] != null) { ResetToolbarsParam = "resettoolbar"; @@ -293,7 +291,7 @@ namespace mRemoteNG.App ResetToolbarsParam = "rtbr"; } - string NoReconnectParam = ""; + var NoReconnectParam = ""; if (cmd["noreconnect"] != null) { NoReconnectParam = "noreconnect"; From 88b5b9d1e7b404a675323c626d23fe69e8e72698 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 7 Dec 2016 15:07:15 -0700 Subject: [PATCH 009/106] began moving connectiontree functions out of the code for the window and into its own class. this will improve testability and reduce class complexity --- .../UI/Controls/ConnectionTree.Designer.cs | 36 +++++++++++++++ mRemoteV1/UI/Controls/ConnectionTree.cs | 44 +++++++++++++++++++ .../Window/ConnectionTreeWindow.Designer.cs | 4 +- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 42 +++++------------- mRemoteV1/mRemoteV1.csproj | 6 +++ 5 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 mRemoteV1/UI/Controls/ConnectionTree.Designer.cs create mode 100644 mRemoteV1/UI/Controls/ConnectionTree.cs diff --git a/mRemoteV1/UI/Controls/ConnectionTree.Designer.cs b/mRemoteV1/UI/Controls/ConnectionTree.Designer.cs new file mode 100644 index 000000000..2c3c0b1c5 --- /dev/null +++ b/mRemoteV1/UI/Controls/ConnectionTree.Designer.cs @@ -0,0 +1,36 @@ +namespace mRemoteNG.UI.Controls +{ + partial class ConnectionTree + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs new file mode 100644 index 000000000..a94326f37 --- /dev/null +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using System.Linq; +using BrightIdeasSoftware; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.UI.Controls +{ + public partial class ConnectionTree : TreeListView + { + public ConnectionInfo SelectedNode => (ConnectionInfo)SelectedObject; + + + public ConnectionTree() + { + InitializeComponent(); + } + + public RootNodeInfo GetRootConnectionNode() + { + return (RootNodeInfo)Roots.Cast().First(item => item is RootNodeInfo); + } + + public IEnumerable GetRootPuttyNodes() + { + return Objects.OfType(); + } + + public void DuplicateSelectedNode() + { + var newNode = SelectedNode.Clone(); + newNode.Parent.SetChildBelow(newNode, SelectedNode); + Runtime.SaveConnectionsAsync(); + } + + public void RenameSelectedNode() + { + SelectedItem.BeginEdit(); + Runtime.SaveConnectionsAsync(); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs index 82865b44a..18666dda8 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs @@ -17,11 +17,11 @@ namespace mRemoteNG.UI.Window internal System.Windows.Forms.ToolStripMenuItem mMenAddConnection; internal System.Windows.Forms.ToolStripMenuItem mMenAddFolder; public System.Windows.Forms.TreeView tvConnections; - public BrightIdeasSoftware.TreeListView olvConnections; + public mRemoteNG.UI.Controls.ConnectionTree olvConnections; private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.olvConnections = new BrightIdeasSoftware.TreeListView(); + this.olvConnections = new mRemoteNG.UI.Controls.ConnectionTree(); this.olvNameColumn = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.imgListTree = new System.Windows.Forms.ImageList(this.components); this.pnlConnections = new System.Windows.Forms.Panel(); diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index c3d8ad3bc..c111169e9 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -4,7 +4,6 @@ using mRemoteNG.Container; using mRemoteNG.Tree; using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; @@ -28,7 +27,7 @@ namespace mRemoteNG.UI.Window private readonly ConnectionContextMenu _contextMenu = new ConnectionContextMenu(); private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; - public ConnectionInfo SelectedNode => (ConnectionInfo) olvConnections.SelectedObject; + public ConnectionInfo SelectedNode => olvConnections.SelectedNode; public ConnectionTreeModel ConnectionTreeModel { @@ -214,9 +213,9 @@ namespace mRemoteNG.UI.Window mMenViewCollapseAllFolders.Click += (sender, args) => { olvConnections.CollapseAll(); - olvConnections.Expand(GetRootConnectionNode()); + olvConnections.Expand(olvConnections.GetRootConnectionNode()); }; - mMenSortAscending.Click += (sender, args) => SortNodesRecursive(GetRootConnectionNode(), ListSortDirection.Ascending); + mMenSortAscending.Click += (sender, args) => SortNodesRecursive(olvConnections.GetRootConnectionNode(), ListSortDirection.Ascending); } private void PopulateTreeView() @@ -246,7 +245,7 @@ namespace mRemoteNG.UI.Window private void OnPuttySessionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { - RefreshTreeObjects(GetRootPuttyNodes().ToList()); + RefreshTreeObjects(olvConnections.GetRootPuttyNodes().ToList()); } private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) @@ -261,20 +260,10 @@ namespace mRemoteNG.UI.Window private void ExpandRootConnectionNode() { - var rootConnectionNode = GetRootConnectionNode(); + var rootConnectionNode = olvConnections.GetRootConnectionNode(); olvConnections.InvokeExpand(rootConnectionNode); } - private RootNodeInfo GetRootConnectionNode() - { - return (RootNodeInfo)olvConnections.Roots.Cast().First(item => item is RootNodeInfo); - } - - private IEnumerable GetRootPuttyNodes() - { - return olvConnections.Objects.OfType(); - } - #region Form Stuff private void Tree_Load(object sender, EventArgs e) { @@ -318,7 +307,7 @@ namespace mRemoteNG.UI.Window private void ExpandPreviouslyOpenedFolders() { - var containerList = ConnectionTreeModel.GetRecursiveChildList(GetRootConnectionNode()).OfType(); + var containerList = ConnectionTreeModel.GetRecursiveChildList(olvConnections.GetRootConnectionNode()).OfType(); var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); olvConnections.ExpandedObjects = previouslyExpandedNodes; olvConnections.InvokeRebuildAll(true); @@ -327,7 +316,7 @@ namespace mRemoteNG.UI.Window private void OpenConnectionsFromLastSession() { if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; - var connectionInfoList = GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); + var connectionInfoList = olvConnections.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); foreach (var connectionInfo in previouslyOpenedConnections) { @@ -337,21 +326,12 @@ namespace mRemoteNG.UI.Window public void EnsureRootNodeVisible() { - olvConnections.EnsureModelVisible(GetRootConnectionNode()); + olvConnections.EnsureModelVisible(olvConnections.GetRootConnectionNode()); } - public void DuplicateSelectedNode() - { - var newNode = SelectedNode.Clone(); - newNode.Parent.SetChildBelow(newNode, SelectedNode); - Runtime.SaveConnectionsAsync(); - } + public void DuplicateSelectedNode() => olvConnections.DuplicateSelectedNode(); - public void RenameSelectedNode() - { - olvConnections.SelectedItem.BeginEdit(); - Runtime.SaveConnectionsAsync(); - } + public void RenameSelectedNode() => olvConnections.RenameSelectedNode(); public void DeleteSelectedNode() { @@ -535,7 +515,7 @@ namespace mRemoteNG.UI.Window private void SortNodesRecursive(ConnectionInfo sortTarget, ListSortDirection sortDirection) { if (sortTarget == null) - sortTarget = GetRootConnectionNode(); + sortTarget = olvConnections.GetRootConnectionNode(); var sortTargetAsContainer = sortTarget as ContainerInfo; if (sortTargetAsContainer != null) diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 66c7866f5..1c2130235 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -220,6 +220,12 @@ Component + + Component + + + ConnectionTree.cs + Component From a22758f5cdaf5e0e09648d63f369eaaf36b2cb85 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 9 Dec 2016 12:57:26 -0700 Subject: [PATCH 010/106] organized code into regions to help prepare for later refactoring --- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 864 ++++++++++---------- 1 file changed, 435 insertions(+), 429 deletions(-) diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index c111169e9..484e3742d 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -44,12 +44,58 @@ namespace mRemoteNG.UI.Window WindowType = WindowType.Tree; DockPnl = panel; InitializeComponent(); + SetupConnectionTreeView(); + } + #region Form Stuff + private void Tree_Load(object sender, EventArgs e) + { + ApplyLanguage(); + Themes.ThemeManager.ThemeChanged += ApplyTheme; + ApplyTheme(); + + txtSearch.Multiline = true; + txtSearch.MinimumSize = new Size(0, 14); + txtSearch.Size = new Size(txtSearch.Size.Width, 14); + txtSearch.Multiline = false; + } + + private void ApplyLanguage() + { + Text = Language.strConnections; + TabText = Language.strConnections; + + mMenAddConnection.ToolTipText = Language.strAddConnection; + mMenAddFolder.ToolTipText = Language.strAddFolder; + mMenView.ToolTipText = Language.strMenuView.Replace("&", ""); + mMenViewExpandAllFolders.Text = Language.strExpandAllFolders; + mMenViewCollapseAllFolders.Text = Language.strCollapseAllFolders; + mMenSortAscending.ToolTipText = Language.strSortAsc; + + txtSearch.Text = Language.strSearchPrompt; + } + + private void ApplyTheme() + { + msMain.BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; + msMain.ForeColor = Themes.ThemeManager.ActiveTheme.ToolbarTextColor; + olvConnections.BackColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelBackgroundColor; + olvConnections.ForeColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTextColor; + //tvConnections.LineColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTreeLineColor; + BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; + txtSearch.BackColor = Themes.ThemeManager.ActiveTheme.SearchBoxBackgroundColor; + txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor; + } + #endregion + + #region ConnectionTree Setup + private void SetupConnectionTreeView() + { FillImageList(); LinkModelToView(); - SetupDropSink(); + SetupDropSink(); SetEventHandlers(); - } + } private void FillImageList() { @@ -73,9 +119,9 @@ namespace mRemoteNG.UI.Window } private void LinkModelToView() - { + { olvNameColumn.AspectGetter = item => ((ConnectionInfo)item).Name; - olvNameColumn.ImageGetter = ConnectionImageGetter; + olvNameColumn.ImageGetter = ConnectionImageGetter; olvConnections.CanExpandGetter = item => { var itemAsContainer = item as ContainerInfo; @@ -83,39 +129,39 @@ namespace mRemoteNG.UI.Window }; olvConnections.ChildrenGetter = item => ((ContainerInfo)item).Children; olvConnections.ContextMenuStrip = _contextMenu; - } + } - private void SetupDropSink() - { - var dropSink = (SimpleDropSink)olvConnections.DropSink; - dropSink.CanDropBetween = true; - } - - private static object ConnectionImageGetter(object rowObject) - { + private static object ConnectionImageGetter(object rowObject) + { if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; if (rowObject is RootNodeInfo) return "Root"; - if (rowObject is ContainerInfo) return "Folder"; - var connection = rowObject as ConnectionInfo; - if (connection == null) return ""; - return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; - } + if (rowObject is ContainerInfo) return "Folder"; + var connection = rowObject as ConnectionInfo; + if (connection == null) return ""; + return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; + } - private void SetEventHandlers() - { - SetTreeEventHandlers(); - SetContextMenuEventHandlers(); + private void SetupDropSink() + { + var dropSink = (SimpleDropSink)olvConnections.DropSink; + dropSink.CanDropBetween = true; + } + + private void SetEventHandlers() + { + SetTreeEventHandlers(); + SetContextMenuEventHandlers(); SetMenuEventHandlers(); - } + } - private void SetTreeEventHandlers() - { - olvConnections.Collapsed += (sender, args) => - { - var container = args.Model as ContainerInfo; + private void SetTreeEventHandlers() + { + olvConnections.Collapsed += (sender, args) => + { + var container = args.Model as ContainerInfo; if (container != null) container.IsExpanded = false; - }; + }; olvConnections.Expanded += (sender, args) => { var container = args.Model as ContainerInfo; @@ -130,23 +176,354 @@ namespace mRemoteNG.UI.Window olvConnections.CellToolTipShowing += tvConnections_CellToolTipShowing; olvConnections.ModelCanDrop += _dragAndDropHandler.HandleEvent_ModelCanDrop; olvConnections.ModelDropped += _dragAndDropHandler.HandleEvent_ModelDropped; - olvConnections.KeyDown += tvConnections_KeyDown; - olvConnections.KeyPress += tvConnections_KeyPress; - } + olvConnections.KeyDown += tvConnections_KeyDown; + olvConnections.KeyPress += tvConnections_KeyPress; + } - private void SetContextMenuEventHandlers() - { - _contextMenu.Opening += (sender, args) => _contextMenu.ShowHideTreeContextMenuItems(SelectedNode); - _contextMenu.ConnectClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; + private void PopulateTreeView() + { + UnregisterModelUpdateHandlers(); + olvConnections.SetObjects(ConnectionTreeModel.RootNodes); + RegisterModelUpdateHandlers(); + _nodeSearcher = new NodeSearcher(ConnectionTreeModel); + ExpandPreviouslyOpenedFolders(); + ExpandRootConnectionNode(); + OpenConnectionsFromLastSession(); + } + + private void RegisterModelUpdateHandlers() + { + _puttySessionsManager.PuttySessionsCollectionChanged += OnPuttySessionsCollectionChanged; + ConnectionTreeModel.CollectionChanged += HandleCollectionChanged; + ConnectionTreeModel.PropertyChanged += HandleCollectionPropertyChanged; + } + + private void UnregisterModelUpdateHandlers() + { + _puttySessionsManager.PuttySessionsCollectionChanged -= OnPuttySessionsCollectionChanged; + ConnectionTreeModel.CollectionChanged -= HandleCollectionChanged; + ConnectionTreeModel.PropertyChanged -= HandleCollectionPropertyChanged; + } + + private void OnPuttySessionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + RefreshTreeObjects(olvConnections.GetRootPuttyNodes().ToList()); + } + + private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + { + //TODO for some reason property changed events are getting triggered twice for each changed property. should be just once. cant find source of duplication + var property = propertyChangedEventArgs.PropertyName; + if (property != "Name" && property != "OpenConnections") return; + var senderAsConnectionInfo = sender as ConnectionInfo; + if (senderAsConnectionInfo != null) + RefreshTreeObject(senderAsConnectionInfo); + } + + private void ExpandPreviouslyOpenedFolders() + { + var containerList = ConnectionTreeModel.GetRecursiveChildList(olvConnections.GetRootConnectionNode()).OfType(); + var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); + olvConnections.ExpandedObjects = previouslyExpandedNodes; + olvConnections.InvokeRebuildAll(true); + } + + private void OpenConnectionsFromLastSession() + { + if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; + var connectionInfoList = olvConnections.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); + var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); + foreach (var connectionInfo in previouslyOpenedConnections) + { + ConnectionInitiator.OpenConnection(connectionInfo); + } + } + #endregion + + #region ConnectionTree + public void DuplicateSelectedNode() => olvConnections.DuplicateSelectedNode(); + + public void RenameSelectedNode() => olvConnections.RenameSelectedNode(); + + public void DeleteSelectedNode() + { + if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; + if (!UserConfirmsDeletion()) return; + ConnectionTreeModel.DeleteNode(SelectedNode); + Runtime.SaveConnectionsAsync(); + } + + private bool UserConfirmsDeletion() + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + return selectedNodeAsContainer.HasChildren() + ? UserConfirmsNonEmptyFolderDeletion() + : UserConfirmsEmptyFolderDeletion(); + return UserConfirmsConnectionDeletion(); + } + + private bool UserConfirmsEmptyFolderDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool UserConfirmsNonEmptyFolderDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool UserConfirmsConnectionDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private static bool PromptUser(string promptMessage) + { + var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + return (msgBoxResponse == DialogResult.Yes); + } + + private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + var senderAsContainerInfo = sender as ContainerInfo; + // ReSharper disable once SwitchStatementMissingSomeCases + switch (args?.Action) + { + case NotifyCollectionChangedAction.Add: + var childList = senderAsContainerInfo?.Children; + ConnectionInfo otherChild = null; + if (childList?.Count > 1) + otherChild = childList.First(child => !args.NewItems.Contains(child)); + RefreshTreeObject(otherChild ?? senderAsContainerInfo); + break; + case NotifyCollectionChangedAction.Remove: + RefreshTreeObjects(args.OldItems); + break; + case NotifyCollectionChangedAction.Move: + RefreshTreeObjects(args.OldItems); + break; + case NotifyCollectionChangedAction.Reset: + RefreshTreeObject(senderAsContainerInfo); + break; + case NotifyCollectionChangedAction.Replace: + break; + case null: + break; + } + } + + private void RefreshTreeObject(ConnectionInfo modelObject) + { + olvConnections.RefreshObject(modelObject); + } + + private void RefreshTreeObjects(IList modelObjects) + { + olvConnections.RefreshObjects(modelObjects); + } + + public void AddConnection() + { + try + { + AddNode(new ConnectionInfo()); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); + } + } + + public void AddFolder() + { + try + { + AddNode(new ContainerInfo()); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); + } + } + + private void AddNode(ConnectionInfo newNode) + { + if (SelectedNode == null) return; + DefaultConnectionInfo.Instance.SaveTo(newNode); + DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); + var selectedContainer = SelectedNode as ContainerInfo; + var parent = selectedContainer ?? SelectedNode?.Parent; + newNode.SetParent(parent); + olvConnections.Expand(parent); + olvConnections.SelectObject(newNode); + olvConnections.EnsureModelVisible(newNode); + } + + private void DisconnectConnection(ConnectionInfo connectionInfo) + { + try + { + if (connectionInfo == null) return; + var nodeAsContainer = connectionInfo as ContainerInfo; + if (nodeAsContainer != null) + { + foreach (var child in nodeAsContainer.Children) + { + for (var i = 0; i <= child.OpenConnections.Count - 1; i++) + { + child.OpenConnections[i].Disconnect(); + } + } + } + else + { + for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) + { + connectionInfo.OpenConnections[i].Disconnect(); + } + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void SshTransferFile() + { + try + { + Windows.Show(WindowType.SSHTransfer); + Windows.SshtransferForm.Hostname = SelectedNode.Hostname; + Windows.SshtransferForm.Username = SelectedNode.Username; + Windows.SshtransferForm.Password = SelectedNode.Password; + Windows.SshtransferForm.Port = Convert.ToString(SelectedNode.Port); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void StartExternalApp(ExternalTool externalTool) + { + try + { + if (SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) + externalTool.Start(SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeToolsExternalAppsEntry_Click failed (UI.Window.ConnectionTreeWindow)", ex); + } + } + + private void ExpandRootConnectionNode() + { + var rootConnectionNode = olvConnections.GetRootConnectionNode(); + olvConnections.InvokeExpand(rootConnectionNode); + } + + public void EnsureRootNodeVisible() + { + olvConnections.EnsureModelVisible(olvConnections.GetRootConnectionNode()); + } + + private void tvConnections_AfterSelect(object sender, EventArgs e) + { + try + { + Windows.ConfigForm.SelectedTreeNode = SelectedNode; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) + { + try + { + if (e.ClickCount > 1) return; + var clickedNode = e.Model as ConnectionInfo; + + if (clickedNode == null) return; + if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; + if (Settings.Default.SingleClickOnConnectionOpensIt) + ConnectionInitiator.OpenConnection(SelectedNode); + + if (Settings.Default.SingleClickSwitchesToOpenConnection) + ConnectionInitiator.SwitchToOpenConnection(SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) + { + if (e.ClickCount < 2) return; + var clickedNodeAsContainer = e.Model as ContainerInfo; + if (clickedNodeAsContainer != null) + { + olvConnections.ToggleExpansion(clickedNodeAsContainer); + } + + var clickedNode = e.Model as ConnectionInfo; + if (clickedNode?.GetTreeNodeType() == TreeNodeType.Connection | + clickedNode?.GetTreeNodeType() == TreeNodeType.PuttySession) + { + ConnectionInitiator.OpenConnection(SelectedNode); + } + } + + private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) + { + try + { + var nodeProducingTooltip = (ConnectionInfo)e.Model; + e.Text = nodeProducingTooltip.Description; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_MouseMove (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + #endregion + + #region Top Menu + private void SetMenuEventHandlers() + { + mMenViewExpandAllFolders.Click += (sender, args) => olvConnections.ExpandAll(); + mMenViewCollapseAllFolders.Click += (sender, args) => + { + olvConnections.CollapseAll(); + olvConnections.Expand(olvConnections.GetRootConnectionNode()); + }; + mMenSortAscending.Click += (sender, args) => SortNodesRecursive(olvConnections.GetRootConnectionNode(), ListSortDirection.Ascending); + } + #endregion + + #region Tree Context Menu + private void SetContextMenuEventHandlers() + { + _contextMenu.Opening += (sender, args) => _contextMenu.ShowHideTreeContextMenuItems(SelectedNode); + _contextMenu.ConnectClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DoNotJump); else ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.DoNotJump); - }; - _contextMenu.ConnectToConsoleSessionClicked += (sender, args) => - { + }; + _contextMenu.ConnectToConsoleSessionClicked += (sender, args) => + { var selectedNodeAsContainer = SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); @@ -205,301 +582,8 @@ namespace mRemoteNG.UI.Window _contextMenu.MoveUpClicked += cMenTreeMoveUp_Click; _contextMenu.MoveDownClicked += cMenTreeMoveDown_Click; _contextMenu.ExternalToolClicked += (sender, args) => StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); - } - - private void SetMenuEventHandlers() - { - mMenViewExpandAllFolders.Click += (sender, args) => olvConnections.ExpandAll(); - mMenViewCollapseAllFolders.Click += (sender, args) => - { - olvConnections.CollapseAll(); - olvConnections.Expand(olvConnections.GetRootConnectionNode()); - }; - mMenSortAscending.Click += (sender, args) => SortNodesRecursive(olvConnections.GetRootConnectionNode(), ListSortDirection.Ascending); - } - - private void PopulateTreeView() - { - UnregisterModelUpdateHandlers(); - olvConnections.SetObjects(ConnectionTreeModel.RootNodes); - RegisterModelUpdateHandlers(); - _nodeSearcher = new NodeSearcher(ConnectionTreeModel); - ExpandPreviouslyOpenedFolders(); - ExpandRootConnectionNode(); - OpenConnectionsFromLastSession(); - } - - private void RegisterModelUpdateHandlers() - { - _puttySessionsManager.PuttySessionsCollectionChanged += OnPuttySessionsCollectionChanged; - ConnectionTreeModel.CollectionChanged += HandleCollectionChanged; - ConnectionTreeModel.PropertyChanged += HandleCollectionPropertyChanged; } - private void UnregisterModelUpdateHandlers() - { - _puttySessionsManager.PuttySessionsCollectionChanged -= OnPuttySessionsCollectionChanged; - ConnectionTreeModel.CollectionChanged -= HandleCollectionChanged; - ConnectionTreeModel.PropertyChanged -= HandleCollectionPropertyChanged; - } - - private void OnPuttySessionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) - { - RefreshTreeObjects(olvConnections.GetRootPuttyNodes().ToList()); - } - - private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) - { - //TODO for some reason property changed events are getting triggered twice for each changed property. should be just once. cant find source of duplication - var property = propertyChangedEventArgs.PropertyName; - if (property != "Name" && property != "OpenConnections") return; - var senderAsConnectionInfo = sender as ConnectionInfo; - if (senderAsConnectionInfo != null) - RefreshTreeObject(senderAsConnectionInfo); - } - - private void ExpandRootConnectionNode() - { - var rootConnectionNode = olvConnections.GetRootConnectionNode(); - olvConnections.InvokeExpand(rootConnectionNode); - } - - #region Form Stuff - private void Tree_Load(object sender, EventArgs e) - { - ApplyLanguage(); - Themes.ThemeManager.ThemeChanged += ApplyTheme; - ApplyTheme(); - - txtSearch.Multiline = true; - txtSearch.MinimumSize = new Size(0, 14); - txtSearch.Size = new Size(txtSearch.Size.Width, 14); - txtSearch.Multiline = false; - } - - private void ApplyLanguage() - { - Text = Language.strConnections; - TabText = Language.strConnections; - - mMenAddConnection.ToolTipText = Language.strAddConnection; - mMenAddFolder.ToolTipText = Language.strAddFolder; - mMenView.ToolTipText = Language.strMenuView.Replace("&", ""); - mMenViewExpandAllFolders.Text = Language.strExpandAllFolders; - mMenViewCollapseAllFolders.Text = Language.strCollapseAllFolders; - mMenSortAscending.ToolTipText = Language.strSortAsc; - - txtSearch.Text = Language.strSearchPrompt; - } - - private void ApplyTheme() - { - msMain.BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; - msMain.ForeColor = Themes.ThemeManager.ActiveTheme.ToolbarTextColor; - olvConnections.BackColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelBackgroundColor; - olvConnections.ForeColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTextColor; - //tvConnections.LineColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTreeLineColor; - BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; - txtSearch.BackColor = Themes.ThemeManager.ActiveTheme.SearchBoxBackgroundColor; - txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor; - } - #endregion - - private void ExpandPreviouslyOpenedFolders() - { - var containerList = ConnectionTreeModel.GetRecursiveChildList(olvConnections.GetRootConnectionNode()).OfType(); - var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); - olvConnections.ExpandedObjects = previouslyExpandedNodes; - olvConnections.InvokeRebuildAll(true); - } - - private void OpenConnectionsFromLastSession() - { - if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; - var connectionInfoList = olvConnections.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); - var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); - foreach (var connectionInfo in previouslyOpenedConnections) - { - ConnectionInitiator.OpenConnection(connectionInfo); - } - } - - public void EnsureRootNodeVisible() - { - olvConnections.EnsureModelVisible(olvConnections.GetRootConnectionNode()); - } - - public void DuplicateSelectedNode() => olvConnections.DuplicateSelectedNode(); - - public void RenameSelectedNode() => olvConnections.RenameSelectedNode(); - - public void DeleteSelectedNode() - { - if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; - if (!UserConfirmsDeletion()) return; - ConnectionTreeModel.DeleteNode(SelectedNode); - Runtime.SaveConnectionsAsync(); - } - - private bool UserConfirmsDeletion() - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - return selectedNodeAsContainer.HasChildren() - ? UserConfirmsNonEmptyFolderDeletion() - : UserConfirmsEmptyFolderDeletion(); - return UserConfirmsConnectionDeletion(); - } - - private bool UserConfirmsEmptyFolderDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private bool UserConfirmsNonEmptyFolderDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private bool UserConfirmsConnectionDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private static bool PromptUser(string promptMessage) - { - var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - return (msgBoxResponse == DialogResult.Yes); - } - - #region Private Methods - private void tvConnections_BeforeLabelEdit(object sender, LabelEditEventArgs e) - { - _contextMenu.DisableShortcutKeys(); - } - - private void tvConnections_AfterLabelEdit(object sender, LabelEditEventArgs e) - { - try - { - _contextMenu.EnableShortcutKeys(); - ConnectionTreeModel.RenameNode(SelectedNode, e.Label); - Windows.ConfigForm.SelectedTreeNode = SelectedNode; - Runtime.SaveConnectionsAsync(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterLabelEdit (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_AfterSelect(object sender, EventArgs e) - { - try - { - Windows.ConfigForm.SelectedTreeNode = SelectedNode; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) - { - try - { - if (e.ClickCount > 1) return; - var clickedNode = e.Model as ConnectionInfo; - - if (clickedNode == null) return; - if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; - if (Settings.Default.SingleClickOnConnectionOpensIt) - ConnectionInitiator.OpenConnection(SelectedNode); - - if (Settings.Default.SingleClickSwitchesToOpenConnection) - ConnectionInitiator.SwitchToOpenConnection(SelectedNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) - { - if (e.ClickCount < 2) return; - var clickedNodeAsContainer = e.Model as ContainerInfo; - if (clickedNodeAsContainer != null) - { - olvConnections.ToggleExpansion(clickedNodeAsContainer); - } - - var clickedNode = e.Model as ConnectionInfo; - if (clickedNode?.GetTreeNodeType() == TreeNodeType.Connection | - clickedNode?.GetTreeNodeType() == TreeNodeType.PuttySession) - { - ConnectionInitiator.OpenConnection(SelectedNode); - } - } - - private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) - { - try - { - var nodeProducingTooltip = (ConnectionInfo) e.Model; - e.Text = nodeProducingTooltip.Description; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_MouseMove (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) - { - var senderAsContainerInfo = sender as ContainerInfo; - // ReSharper disable once SwitchStatementMissingSomeCases - switch (args?.Action) - { - case NotifyCollectionChangedAction.Add: - var childList = senderAsContainerInfo?.Children; - ConnectionInfo otherChild = null; - if (childList?.Count > 1) - otherChild = childList.First(child => !args.NewItems.Contains(child)); - RefreshTreeObject(otherChild ?? senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Remove: - RefreshTreeObjects(args.OldItems); - break; - case NotifyCollectionChangedAction.Move: - RefreshTreeObjects(args.OldItems); - break; - case NotifyCollectionChangedAction.Reset: - RefreshTreeObject(senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Replace: - break; - case null: - break; - } - } - - private void RefreshTreeObject(ConnectionInfo modelObject) - { - olvConnections.RefreshObject(modelObject); - } - - private void RefreshTreeObjects(IList modelObjects) - { - olvConnections.RefreshObjects(modelObjects); - } - #endregion - - #region Tree Context Menu private void cMenTreeAddConnection_Click(object sender, EventArgs e) { AddConnection(); @@ -537,104 +621,26 @@ namespace mRemoteNG.UI.Window SelectedNode.Parent.DemoteChild(SelectedNode); Runtime.SaveConnectionsAsync(); } - #endregion - #region Context Menu Actions - public void AddConnection() - { - try - { - AddNode(new ConnectionInfo()); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); - } - } - - public void AddFolder() - { - try - { - AddNode(new ContainerInfo()); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); - } - } - - private void AddNode(ConnectionInfo newNode) - { - if (SelectedNode == null) return; - DefaultConnectionInfo.Instance.SaveTo(newNode); - DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); - var selectedContainer = SelectedNode as ContainerInfo; - var parent = selectedContainer ?? SelectedNode?.Parent; - newNode.SetParent(parent); - olvConnections.Expand(parent); - olvConnections.SelectObject(newNode); - olvConnections.EnsureModelVisible(newNode); + private void tvConnections_BeforeLabelEdit(object sender, LabelEditEventArgs e) + { + _contextMenu.DisableShortcutKeys(); } - private void DisconnectConnection(ConnectionInfo connectionInfo) - { - try - { - if (connectionInfo == null) return; - var nodeAsContainer = connectionInfo as ContainerInfo; - if (nodeAsContainer != null) - { - foreach (var child in nodeAsContainer.Children) - { - for (var i = 0; i <= child.OpenConnections.Count - 1; i++) - { - child.OpenConnections[i].Disconnect(); - } - } - } - else - { - for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) - { - connectionInfo.OpenConnections[i].Disconnect(); - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void SshTransferFile() - { - try - { - Windows.Show(WindowType.SSHTransfer); - Windows.SshtransferForm.Hostname = SelectedNode.Hostname; - Windows.SshtransferForm.Username = SelectedNode.Username; - Windows.SshtransferForm.Password = SelectedNode.Password; - Windows.SshtransferForm.Port = Convert.ToString(SelectedNode.Port); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void StartExternalApp(ExternalTool externalTool) - { - try - { - if (SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) - externalTool.Start(SelectedNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeToolsExternalAppsEntry_Click failed (UI.Window.ConnectionTreeWindow)", ex); - } - } + private void tvConnections_AfterLabelEdit(object sender, LabelEditEventArgs e) + { + try + { + _contextMenu.EnableShortcutKeys(); + ConnectionTreeModel.RenameNode(SelectedNode, e.Label); + Windows.ConfigForm.SelectedTreeNode = SelectedNode; + Runtime.SaveConnectionsAsync(); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterLabelEdit (UI.Window.ConnectionTreeWindow) failed", ex); + } + } #endregion #region Search From 3f65e1bfa073ef0a908f95b71458f853eb750971 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 13 Dec 2016 10:31:16 -0500 Subject: [PATCH 011/106] add tests for update channels Some code clean up as well... --- mRemoteNGTests/App/UpdaterTests.cs | 45 ++++++++++++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + mRemoteV1/App/Info/GeneralAppInfo.cs | 10 +++---- mRemoteV1/App/Update/UpdateInfo.cs | 2 +- mRemoteV1/UI/Window/UpdateWindow.cs | 18 +++++------ 5 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 mRemoteNGTests/App/UpdaterTests.cs diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs new file mode 100644 index 000000000..083616c36 --- /dev/null +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -0,0 +1,45 @@ +using System; +using System.ComponentModel; +using mRemoteNG.App.Info; +using mRemoteNG.App.Update; +using NUnit.Framework; + +namespace mRemoteNGTests.App +{ + [TestFixture] + public class UpdaterTests + { + private AppUpdater _appUpdate; + + [SetUp] + public void Setup() + { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + _appUpdate = new AppUpdater(); + _appUpdate.GetUpdateInfoCompletedEvent += TestGetUpdateInfoCompleted; + + } + + [Test] + public void TestStableChannel() + { + } + + private void TestGetUpdateInfoCompleted(object sender, AsyncCompletedEventArgs e) + { + try + { + _appUpdate.GetUpdateInfoCompletedEvent -= TestGetUpdateInfoCompleted; + + if (_appUpdate.IsUpdateAvailable()) + { + + } + } + catch (Exception ex) + { + + } + } + } +} diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index b1343dc61..4b0192ce6 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -107,6 +107,7 @@ + diff --git a/mRemoteV1/App/Info/GeneralAppInfo.cs b/mRemoteV1/App/Info/GeneralAppInfo.cs index 304fcd652..5e3506beb 100644 --- a/mRemoteV1/App/Info/GeneralAppInfo.cs +++ b/mRemoteV1/App/Info/GeneralAppInfo.cs @@ -11,11 +11,11 @@ namespace mRemoteNG.App.Info { public static class GeneralAppInfo { - public static readonly string UrlHome = "http://www.mremoteng.org/"; - public static readonly string UrlDonate = "http://donate.mremoteng.org/"; - public static readonly string UrlForum = "http://forum.mremoteng.org/"; - public static readonly string UrlBugs = "http://bugs.mremoteng.org/"; - public static readonly string ApplicationVersion = Application.ProductVersion; + public const string UrlHome = "http://www.mremoteng.org/"; + public const string UrlDonate = "http://donate.mremoteng.org/"; + public const string UrlForum = "http://forum.mremoteng.org/"; + public const string UrlBugs = "http://bugs.mremoteng.org/"; + public static string ApplicationVersion = Application.ProductVersion; public static readonly string ProductName = Application.ProductName; public static readonly string Copyright = ((AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCopyrightAttribute), false)).Copyright; public static readonly string HomePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location); diff --git a/mRemoteV1/App/Update/UpdateInfo.cs b/mRemoteV1/App/Update/UpdateInfo.cs index 2deee4040..0bf0b3578 100644 --- a/mRemoteV1/App/Update/UpdateInfo.cs +++ b/mRemoteV1/App/Update/UpdateInfo.cs @@ -14,7 +14,7 @@ namespace mRemoteNG.App.Update #if !PORTABLE public string CertificateThumbprint { get; private set; } #endif - public string FileName { get; private set; } + private string FileName { get; set; } public string Checksum { get; private set; } public static UpdateInfo FromString(string input) diff --git a/mRemoteV1/UI/Window/UpdateWindow.cs b/mRemoteV1/UI/Window/UpdateWindow.cs index 55489483b..efdfecbc6 100644 --- a/mRemoteV1/UI/Window/UpdateWindow.cs +++ b/mRemoteV1/UI/Window/UpdateWindow.cs @@ -163,17 +163,13 @@ namespace mRemoteNG.UI.Window { lblStatus.Text = Language.strNoUpdateAvailable; lblStatus.ForeColor = Color.ForestGreen; - - if (_appUpdate.CurrentUpdateInfo != null) - { - var updateInfo = _appUpdate.CurrentUpdateInfo; - if (updateInfo.IsValid && updateInfo.Version != null) - { - lblLatestVersion.Text = updateInfo.Version.ToString(); - lblLatestVersionLabel.Visible = true; - lblLatestVersion.Visible = true; - } - } + + if (_appUpdate.CurrentUpdateInfo == null) return; + var updateInfo = _appUpdate.CurrentUpdateInfo; + if (!updateInfo.IsValid || updateInfo.Version == null) return; + lblLatestVersion.Text = updateInfo.Version.ToString(); + lblLatestVersionLabel.Visible = true; + lblLatestVersion.Visible = true; } } catch (Exception ex) From d4681073115e98b99ea62c91253f2fb69cba9193 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 13 Dec 2016 10:50:36 -0500 Subject: [PATCH 012/106] Load users default/current domain Fixes #311 Caused by 97a0e2413e702e04afbb0c3acf620637e9653a7a Some code clean up as well... --- .../ActiveDirectoryImportWindow.Designer.cs | 4 +- .../UI/Window/ActiveDirectoryImportWindow.cs | 128 ++++++++++-------- 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.Designer.cs b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.Designer.cs index 1713a9584..b842e70c6 100644 --- a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.Designer.cs @@ -64,9 +64,9 @@ namespace mRemoteNG.UI.Window | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.ActiveDirectoryTree.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.ActiveDirectoryTree.Domain = "tant-a01"; + this.ActiveDirectoryTree.Domain = "DOMAIN"; this.ActiveDirectoryTree.Location = new System.Drawing.Point(12, 52); - this.ActiveDirectoryTree.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.ActiveDirectoryTree.Margin = new System.Windows.Forms.Padding(4); this.ActiveDirectoryTree.Name = "ActiveDirectoryTree"; this.ActiveDirectoryTree.SelectedNode = null; this.ActiveDirectoryTree.Size = new System.Drawing.Size(506, 280); diff --git a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs index f97dc9534..0e1039906 100644 --- a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs +++ b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs @@ -8,81 +8,93 @@ using mRemoteNG.Container; namespace mRemoteNG.UI.Window { - public partial class ActiveDirectoryImportWindow - { + public partial class ActiveDirectoryImportWindow + { + private string CurrentDomain; + #region Constructors - public ActiveDirectoryImportWindow(DockContent panel) - { - InitializeComponent(); - Runtime.FontOverride(this); - WindowType = WindowType.ActiveDirectoryImport; - DockPnl = panel; - } + + public ActiveDirectoryImportWindow(DockContent panel) + { + InitializeComponent(); + Runtime.FontOverride(this); + WindowType = WindowType.ActiveDirectoryImport; + DockPnl = panel; + CurrentDomain = Environment.UserDomainName; + } + #endregion - + #region Private Methods + #region Event Handlers - private void ADImport_Load(object sender, EventArgs e) - { - ApplyLanguage(); - txtDomain.Text = ActiveDirectoryTree.Domain; - EnableDisableImportButton(); - } + private void ADImport_Load(object sender, EventArgs e) + { + ApplyLanguage(); + txtDomain.Text = CurrentDomain; + ActiveDirectoryTree.Domain = CurrentDomain; + EnableDisableImportButton(); + } - private void btnImport_Click(object sender, EventArgs e) - { - var selectedNode = Windows.TreeForm.SelectedNode; - ContainerInfo importDestination; - if (selectedNode != null) - importDestination = selectedNode as ContainerInfo ?? selectedNode.Parent; - else - importDestination = Runtime.ConnectionTreeModel.RootNodes.First(); + private void btnImport_Click(object sender, EventArgs e) + { + var selectedNode = Windows.TreeForm.SelectedNode; + ContainerInfo importDestination; + if (selectedNode != null) + importDestination = selectedNode as ContainerInfo ?? selectedNode.Parent; + else + importDestination = Runtime.ConnectionTreeModel.RootNodes.First(); - Import.ImportFromActiveDirectory(ActiveDirectoryTree.ADPath, importDestination, chkSubOU.Checked); - } + Import.ImportFromActiveDirectory(ActiveDirectoryTree.ADPath, importDestination, chkSubOU.Checked); + } + /* private static void txtDomain_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (e.KeyCode == Keys.Enter) e.IsInputKey = true; } + */ - private void txtDomain_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode != Keys.Enter) return; - ChangeDomain(); - e.SuppressKeyPress = true; - } + private void txtDomain_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode != Keys.Enter) return; + ChangeDomain(); + e.SuppressKeyPress = true; + } - private void btnChangeDomain_Click(object sender, EventArgs e) - { - ChangeDomain(); - } + private void btnChangeDomain_Click(object sender, EventArgs e) + { + ChangeDomain(); + } + + private void ActiveDirectoryTree_ADPathChanged(object sender) + { + EnableDisableImportButton(); + } - private void ActiveDirectoryTree_ADPathChanged(object sender) - { - EnableDisableImportButton(); - } #endregion - - private void ApplyLanguage() - { - btnImport.Text = Language.strButtonImport; - lblDomain.Text = Language.strLabelDomain; - btnChangeDomain.Text = Language.strButtonChange; - } - - private void ChangeDomain() - { - ActiveDirectoryTree.Domain = txtDomain.Text; - ActiveDirectoryTree.Refresh(); - } - - private void EnableDisableImportButton() - { - btnImport.Enabled = !string.IsNullOrEmpty(ActiveDirectoryTree.ADPath); - } + + private void ApplyLanguage() + { + btnImport.Text = Language.strButtonImport; + lblDomain.Text = Language.strLabelDomain; + btnChangeDomain.Text = Language.strButtonChange; + } + + private void ChangeDomain() + { + CurrentDomain = txtDomain.Text; + ActiveDirectoryTree.Domain = CurrentDomain; + ActiveDirectoryTree.Refresh(); + } + + private void EnableDisableImportButton() + { + btnImport.Enabled = !string.IsNullOrEmpty(ActiveDirectoryTree.ADPath); + } + #endregion private void btnClose_Click(object sender, EventArgs e) From d5360c6568b6ec95c24a1d195e18e8ea7ca93c23 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 09:00:38 -0700 Subject: [PATCH 013/106] Completed splitting the connection tree from the connection tree window --- mRemoteNGTests/Tree/ConnectionTreeTests.cs | 29 ++ mRemoteNGTests/mRemoteNGTests.csproj | 5 +- mRemoteV1/App/Runtime.cs | 8 +- mRemoteV1/UI/Controls/ConnectionTree.cs | 451 ++++++++++++++++- mRemoteV1/UI/Forms/frmMain.cs | 10 +- .../Window/ConnectionTreeWindow.Designer.cs | 22 +- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 454 +----------------- mRemoteV1/UI/Window/ConnectionTreeWindow.resx | 3 - 8 files changed, 515 insertions(+), 467 deletions(-) create mode 100644 mRemoteNGTests/Tree/ConnectionTreeTests.cs diff --git a/mRemoteNGTests/Tree/ConnectionTreeTests.cs b/mRemoteNGTests/Tree/ConnectionTreeTests.cs new file mode 100644 index 000000000..e27710091 --- /dev/null +++ b/mRemoteNGTests/Tree/ConnectionTreeTests.cs @@ -0,0 +1,29 @@ +using mRemoteNG.UI.Controls; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class ConnectionTreeTests + { + private ConnectionTree _connectionTree; + + [SetUp] + public void Setup() + { + _connectionTree = new ConnectionTree(); + } + + [TearDown] + public void Teardown() + { + _connectionTree.Dispose(); + } + + + [Test] + public void test() + { + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index a8010efee..63e3ce761 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -101,7 +101,9 @@ - + + False + @@ -146,6 +148,7 @@ + diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index d99b8e5ed..319f570bc 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -42,8 +42,8 @@ namespace mRemoteNG.App public static SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString(); public static ConnectionTreeModel ConnectionTreeModel { - get { return Windows.TreeForm.ConnectionTreeModel; } - set { Windows.TreeForm.ConnectionTreeModel = value; } + get { return Windows.TreeForm.ConnectionTree.ConnectionTreeModel; } + set { Windows.TreeForm.ConnectionTree.ConnectionTreeModel = value; } } #endregion @@ -237,7 +237,7 @@ namespace mRemoteNG.App // Load config connectionsLoader.ConnectionFileName = filename; ConnectionTreeModel = connectionsLoader.LoadConnections(false); - Windows.TreeForm.ConnectionTreeModel = ConnectionTreeModel; + Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel; } catch (Exception ex) { @@ -288,7 +288,7 @@ namespace mRemoteNG.App connectionsLoader.UseDatabase = Settings.Default.UseSQLServer; ConnectionTreeModel = connectionsLoader.LoadConnections(false); - Windows.TreeForm.ConnectionTreeModel = ConnectionTreeModel; + Windows.TreeForm.ConnectionTree.ConnectionTreeModel = ConnectionTreeModel; if (Settings.Default.UseSQLServer) { diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index a94326f37..e3895eb7e 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -1,8 +1,17 @@ -using System.Collections.Generic; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; using System.Linq; +using System.Windows.Forms; using BrightIdeasSoftware; using mRemoteNG.App; +using mRemoteNG.Config.Putty; using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tools; +using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -10,12 +19,451 @@ namespace mRemoteNG.UI.Controls { public partial class ConnectionTree : TreeListView { + private ConnectionTreeModel _connectionTreeModel; + private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); + private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; + private OLVColumn _olvNameColumn; + private ImageList imgListTree; + + public ConnectionInfo SelectedNode => (ConnectionInfo)SelectedObject; + public NodeSearcher NodeSearcher { get; private set; } + + public ConnectionTreeModel ConnectionTreeModel + { + get { return _connectionTreeModel; } + set + { + _connectionTreeModel = value; + PopulateTreeView(); + } + } + public ConnectionTree() { InitializeComponent(); + SetupConnectionTreeView(); + } + + #region ConnectionTree Setup + private void SetupConnectionTreeView() + { + CreateNameColumn(); + CreateImageList(); + FillImageList(); + LinkModelToView(); + SetupDropSink(); + SetEventHandlers(); + } + + private void CreateNameColumn() + { + _olvNameColumn = new OLVColumn + { + AspectName = "Name", + FillsFreeSpace = true, + IsButton = true, + AspectGetter = item => ((ConnectionInfo)item).Name, + ImageGetter = ConnectionImageGetter + }; + Columns.Add(_olvNameColumn); + AllColumns.Add(_olvNameColumn); + } + + private void CreateImageList() + { + imgListTree = new ImageList(this.components) + { + ColorDepth = ColorDepth.Depth32Bit, + ImageSize = new System.Drawing.Size(16, 16), + TransparentColor = System.Drawing.Color.Transparent + }; + SmallImageList = imgListTree; + } + + private void FillImageList() + { + try + { + imgListTree.Images.Add(Resources.Root); + imgListTree.Images.SetKeyName(0, "Root"); + imgListTree.Images.Add(Resources.Folder); + imgListTree.Images.SetKeyName(1, "Folder"); + imgListTree.Images.Add(Resources.Play); + imgListTree.Images.SetKeyName(2, "Play"); + imgListTree.Images.Add(Resources.Pause); + imgListTree.Images.SetKeyName(3, "Pause"); + imgListTree.Images.Add(Resources.PuttySessions); + imgListTree.Images.SetKeyName(4, "PuttySessions"); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("FillImageList (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void LinkModelToView() + { + CanExpandGetter = item => + { + var itemAsContainer = item as ContainerInfo; + return itemAsContainer?.Children.Count > 0; + }; + ChildrenGetter = item => ((ContainerInfo)item).Children; + //ContextMenuStrip = _contextMenu; + } + + private static object ConnectionImageGetter(object rowObject) + { + if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; + if (rowObject is RootNodeInfo) return "Root"; + if (rowObject is ContainerInfo) return "Folder"; + var connection = rowObject as ConnectionInfo; + if (connection == null) return ""; + return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; + } + + private void SetupDropSink() + { + DropSink = new SimpleDropSink(); + var dropSink = (SimpleDropSink)DropSink; + dropSink.CanDropBetween = true; + } + + private void SetEventHandlers() + { + Collapsed += (sender, args) => + { + var container = args.Model as ContainerInfo; + if (container != null) + container.IsExpanded = false; + }; + Expanded += (sender, args) => + { + var container = args.Model as ContainerInfo; + if (container != null) + container.IsExpanded = true; + }; + SelectionChanged += tvConnections_AfterSelect; + CellClick += tvConnections_NodeMouseSingleClick; + CellClick += tvConnections_NodeMouseDoubleClick; + CellToolTipShowing += tvConnections_CellToolTipShowing; + ModelCanDrop += _dragAndDropHandler.HandleEvent_ModelCanDrop; + ModelDropped += _dragAndDropHandler.HandleEvent_ModelDropped; + } + + private void PopulateTreeView() + { + UnregisterModelUpdateHandlers(); + SetObjects(ConnectionTreeModel.RootNodes); + RegisterModelUpdateHandlers(); + NodeSearcher = new NodeSearcher(ConnectionTreeModel); + ExpandPreviouslyOpenedFolders(); + ExpandRootConnectionNode(); + OpenConnectionsFromLastSession(); + } + + private void RegisterModelUpdateHandlers() + { + _puttySessionsManager.PuttySessionsCollectionChanged += OnPuttySessionsCollectionChanged; + ConnectionTreeModel.CollectionChanged += HandleCollectionChanged; + ConnectionTreeModel.PropertyChanged += HandleCollectionPropertyChanged; + } + + private void UnregisterModelUpdateHandlers() + { + _puttySessionsManager.PuttySessionsCollectionChanged -= OnPuttySessionsCollectionChanged; + ConnectionTreeModel.CollectionChanged -= HandleCollectionChanged; + ConnectionTreeModel.PropertyChanged -= HandleCollectionPropertyChanged; + } + + private void OnPuttySessionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + RefreshTreeObjects(GetRootPuttyNodes().ToList()); + } + + private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + { + //TODO for some reason property changed events are getting triggered twice for each changed property. should be just once. cant find source of duplication + var property = propertyChangedEventArgs.PropertyName; + if (property != "Name" && property != "OpenConnections") return; + var senderAsConnectionInfo = sender as ConnectionInfo; + if (senderAsConnectionInfo != null) + RefreshTreeObject(senderAsConnectionInfo); + } + + private void ExpandPreviouslyOpenedFolders() + { + var containerList = ConnectionTreeModel.GetRecursiveChildList(GetRootConnectionNode()).OfType(); + var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); + ExpandedObjects = previouslyExpandedNodes; + this.InvokeRebuildAll(true); + } + + private void OpenConnectionsFromLastSession() + { + if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; + var connectionInfoList = GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); + var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); + foreach (var connectionInfo in previouslyOpenedConnections) + { + ConnectionInitiator.OpenConnection(connectionInfo); + } + } + #endregion + + #region ConnectionTree + public void DeleteSelectedNode() + { + if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; + if (!UserConfirmsDeletion()) return; + ConnectionTreeModel.DeleteNode(SelectedNode); + Runtime.SaveConnectionsAsync(); + } + + private bool UserConfirmsDeletion() + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + return selectedNodeAsContainer.HasChildren() + ? UserConfirmsNonEmptyFolderDeletion() + : UserConfirmsEmptyFolderDeletion(); + return UserConfirmsConnectionDeletion(); + } + + private bool UserConfirmsEmptyFolderDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool UserConfirmsNonEmptyFolderDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool UserConfirmsConnectionDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private static bool PromptUser(string promptMessage) + { + var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + return (msgBoxResponse == DialogResult.Yes); + } + + private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + var senderAsContainerInfo = sender as ContainerInfo; + // ReSharper disable once SwitchStatementMissingSomeCases + switch (args?.Action) + { + case NotifyCollectionChangedAction.Add: + var childList = senderAsContainerInfo?.Children; + ConnectionInfo otherChild = null; + if (childList?.Count > 1) + otherChild = childList.First(child => !args.NewItems.Contains(child)); + RefreshTreeObject(otherChild ?? senderAsContainerInfo); + break; + case NotifyCollectionChangedAction.Remove: + RefreshTreeObjects(args.OldItems); + break; + case NotifyCollectionChangedAction.Move: + RefreshTreeObjects(args.OldItems); + break; + case NotifyCollectionChangedAction.Reset: + RefreshTreeObject(senderAsContainerInfo); + break; + case NotifyCollectionChangedAction.Replace: + break; + case null: + break; + } + } + + private void RefreshTreeObject(ConnectionInfo modelObject) + { + RefreshObject(modelObject); + } + + private void RefreshTreeObjects(IList modelObjects) + { + RefreshObjects(modelObjects); + } + + public void AddConnection() + { + try + { + AddNode(new ConnectionInfo()); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); + } + } + + public void AddFolder() + { + try + { + AddNode(new ContainerInfo()); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); + } + } + + private void AddNode(ConnectionInfo newNode) + { + if (SelectedNode == null) return; + DefaultConnectionInfo.Instance.SaveTo(newNode); + DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); + var selectedContainer = SelectedNode as ContainerInfo; + var parent = selectedContainer ?? SelectedNode?.Parent; + newNode.SetParent(parent); + Expand(parent); + SelectObject(newNode); + EnsureModelVisible(newNode); + } + + public void DisconnectConnection(ConnectionInfo connectionInfo) + { + try + { + if (connectionInfo == null) return; + var nodeAsContainer = connectionInfo as ContainerInfo; + if (nodeAsContainer != null) + { + foreach (var child in nodeAsContainer.Children) + { + for (var i = 0; i <= child.OpenConnections.Count - 1; i++) + { + child.OpenConnections[i].Disconnect(); + } + } + } + else + { + for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) + { + connectionInfo.OpenConnections[i].Disconnect(); + } + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + public void SshTransferFile() + { + try + { + Windows.Show(WindowType.SSHTransfer); + Windows.SshtransferForm.Hostname = SelectedNode.Hostname; + Windows.SshtransferForm.Username = SelectedNode.Username; + Windows.SshtransferForm.Password = SelectedNode.Password; + Windows.SshtransferForm.Port = Convert.ToString(SelectedNode.Port); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + public void StartExternalApp(ExternalTool externalTool) + { + try + { + if (SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) + externalTool.Start(SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeToolsExternalAppsEntry_Click failed (UI.Window.ConnectionTreeWindow)", ex); + } + } + + private void ExpandRootConnectionNode() + { + var rootConnectionNode = GetRootConnectionNode(); + this.InvokeExpand(rootConnectionNode); + } + + public void EnsureRootNodeVisible() + { + EnsureModelVisible(GetRootConnectionNode()); + } + + private void tvConnections_AfterSelect(object sender, EventArgs e) + { + try + { + Windows.ConfigForm.SelectedTreeNode = SelectedNode; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) + { + try + { + if (e.ClickCount > 1) return; + var clickedNode = e.Model as ConnectionInfo; + + if (clickedNode == null) return; + if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; + if (Settings.Default.SingleClickOnConnectionOpensIt) + ConnectionInitiator.OpenConnection(SelectedNode); + + if (Settings.Default.SingleClickSwitchesToOpenConnection) + ConnectionInitiator.SwitchToOpenConnection(SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) + { + if (e.ClickCount < 2) return; + var clickedNodeAsContainer = e.Model as ContainerInfo; + if (clickedNodeAsContainer != null) + { + ToggleExpansion(clickedNodeAsContainer); + } + + var clickedNode = e.Model as ConnectionInfo; + if (clickedNode?.GetTreeNodeType() == TreeNodeType.Connection | + clickedNode?.GetTreeNodeType() == TreeNodeType.PuttySession) + { + ConnectionInitiator.OpenConnection(SelectedNode); + } + } + + private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) + { + try + { + var nodeProducingTooltip = (ConnectionInfo)e.Model; + e.Text = nodeProducingTooltip.Description; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_MouseMove (UI.Window.ConnectionTreeWindow) failed", ex); + } } public RootNodeInfo GetRootConnectionNode() @@ -40,5 +488,6 @@ namespace mRemoteNG.UI.Controls SelectedItem.BeginEdit(); Runtime.SaveConnectionsAsync(); } + #endregion } } \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 5d632e74f..20a7f3f19 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -494,13 +494,13 @@ namespace mRemoteNG.UI.Forms private void mMenFileNewConnection_Click(object sender, EventArgs e) { - ConnectionTreeWindow.AddConnection(); + ConnectionTreeWindow.ConnectionTree.AddConnection(); Runtime.SaveConnectionsAsync(); } private void mMenFileNewFolder_Click(object sender, EventArgs e) { - ConnectionTreeWindow.AddFolder(); + ConnectionTreeWindow.ConnectionTree.AddFolder(); Runtime.SaveConnectionsAsync(); } @@ -546,19 +546,19 @@ namespace mRemoteNG.UI.Forms private void mMenFileDelete_Click(object sender, EventArgs e) { - ConnectionTreeWindow.DeleteSelectedNode(); + ConnectionTreeWindow.ConnectionTree.DeleteSelectedNode(); Runtime.SaveConnectionsAsync(); } private void mMenFileRename_Click(object sender, EventArgs e) { - ConnectionTreeWindow.RenameSelectedNode(); + ConnectionTreeWindow.ConnectionTree.RenameSelectedNode(); Runtime.SaveConnectionsAsync(); } private void mMenFileDuplicate_Click(object sender, EventArgs e) { - ConnectionTreeWindow.DuplicateSelectedNode(); + ConnectionTreeWindow.ConnectionTree.DuplicateSelectedNode(); Runtime.SaveConnectionsAsync(); } diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs index 18666dda8..abb971af0 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs @@ -7,7 +7,6 @@ namespace mRemoteNG.UI.Window #region Windows Form Designer generated code internal System.Windows.Forms.TextBox txtSearch; internal System.Windows.Forms.Panel pnlConnections; - internal System.Windows.Forms.ImageList imgListTree; internal System.Windows.Forms.MenuStrip msMain; internal System.Windows.Forms.ToolStripMenuItem mMenView; internal System.Windows.Forms.ToolStripMenuItem mMenViewExpandAllFolders; @@ -17,13 +16,10 @@ namespace mRemoteNG.UI.Window internal System.Windows.Forms.ToolStripMenuItem mMenAddConnection; internal System.Windows.Forms.ToolStripMenuItem mMenAddFolder; public System.Windows.Forms.TreeView tvConnections; - public mRemoteNG.UI.Controls.ConnectionTree olvConnections; private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.olvConnections = new mRemoteNG.UI.Controls.ConnectionTree(); - this.olvNameColumn = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); - this.imgListTree = new System.Windows.Forms.ImageList(this.components); this.pnlConnections = new System.Windows.Forms.Panel(); this.PictureBox1 = new System.Windows.Forms.PictureBox(); this.txtSearch = new System.Windows.Forms.TextBox(); @@ -42,15 +38,12 @@ namespace mRemoteNG.UI.Window // // olvConnections // - this.olvConnections.AllColumns.Add(this.olvNameColumn); this.olvConnections.AllowDrop = true; this.olvConnections.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.olvConnections.BorderStyle = System.Windows.Forms.BorderStyle.None; this.olvConnections.CellEditUseWholeCell = false; - this.olvConnections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.olvNameColumn}); this.olvConnections.Cursor = System.Windows.Forms.Cursors.Default; this.olvConnections.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; this.olvConnections.HideSelection = false; @@ -64,7 +57,6 @@ namespace mRemoteNG.UI.Window this.olvConnections.SelectedForeColor = System.Drawing.SystemColors.HighlightText; this.olvConnections.ShowGroups = false; this.olvConnections.Size = new System.Drawing.Size(192, 410); - this.olvConnections.SmallImageList = this.imgListTree; this.olvConnections.TabIndex = 20; this.olvConnections.UnfocusedSelectedBackColor = System.Drawing.SystemColors.Highlight; this.olvConnections.UnfocusedSelectedForeColor = System.Drawing.SystemColors.HighlightText; @@ -72,18 +64,6 @@ namespace mRemoteNG.UI.Window this.olvConnections.View = System.Windows.Forms.View.Details; this.olvConnections.VirtualMode = true; // - // olvNameColumn - // - this.olvNameColumn.AspectName = "Name"; - this.olvNameColumn.FillsFreeSpace = true; - this.olvNameColumn.IsButton = true; - // - // imgListTree - // - this.imgListTree.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; - this.imgListTree.ImageSize = new System.Drawing.Size(16, 16); - this.imgListTree.TransparentColor = System.Drawing.Color.Transparent; - // // pnlConnections // this.pnlConnections.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -214,6 +194,6 @@ namespace mRemoteNG.UI.Window #endregion private System.ComponentModel.IContainer components; - private BrightIdeasSoftware.OLVColumn olvNameColumn; + private Controls.ConnectionTree olvConnections; } } diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 484e3742d..0056b9bb1 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -3,16 +3,10 @@ using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Tree; using System; -using System.Collections; -using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; -using System.Linq; using System.Windows.Forms; -using BrightIdeasSoftware; -using mRemoteNG.Config.Putty; using mRemoteNG.Tools; -using mRemoteNG.Tree.Root; using mRemoteNG.UI.Controls; using WeifenLuo.WinFormsUI.Docking; @@ -21,22 +15,14 @@ namespace mRemoteNG.UI.Window { public partial class ConnectionTreeWindow { - private ConnectionTreeModel _connectionTreeModel; - private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); - private NodeSearcher _nodeSearcher; private readonly ConnectionContextMenu _contextMenu = new ConnectionContextMenu(); - private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; public ConnectionInfo SelectedNode => olvConnections.SelectedNode; - public ConnectionTreeModel ConnectionTreeModel + public ConnectionTree ConnectionTree { - get { return _connectionTreeModel; } - set - { - _connectionTreeModel = value; - PopulateTreeView(); - } + get { return olvConnections; } + set { olvConnections = value; } } public ConnectionTreeWindow(DockContent panel) @@ -44,7 +30,10 @@ namespace mRemoteNG.UI.Window WindowType = WindowType.Tree; DockPnl = panel; InitializeComponent(); - SetupConnectionTreeView(); + olvConnections.ContextMenuStrip = _contextMenu; + SetMenuEventHandlers(); + SetContextMenuEventHandlers(); + SetConnectionTreeEventHandlers(); } #region Form Stuff @@ -88,413 +77,14 @@ namespace mRemoteNG.UI.Window } #endregion - #region ConnectionTree Setup - private void SetupConnectionTreeView() + #region ConnectionTree + private void SetConnectionTreeEventHandlers() { - FillImageList(); - LinkModelToView(); - SetupDropSink(); - SetEventHandlers(); - } - - private void FillImageList() - { - try - { - imgListTree.Images.Add(Resources.Root); - imgListTree.Images.SetKeyName(0, "Root"); - imgListTree.Images.Add(Resources.Folder); - imgListTree.Images.SetKeyName(1, "Folder"); - imgListTree.Images.Add(Resources.Play); - imgListTree.Images.SetKeyName(2, "Play"); - imgListTree.Images.Add(Resources.Pause); - imgListTree.Images.SetKeyName(3, "Pause"); - imgListTree.Images.Add(Resources.PuttySessions); - imgListTree.Images.SetKeyName(4, "PuttySessions"); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("FillImageList (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void LinkModelToView() - { - olvNameColumn.AspectGetter = item => ((ConnectionInfo)item).Name; - olvNameColumn.ImageGetter = ConnectionImageGetter; - olvConnections.CanExpandGetter = item => - { - var itemAsContainer = item as ContainerInfo; - return itemAsContainer?.Children.Count > 0; - }; - olvConnections.ChildrenGetter = item => ((ContainerInfo)item).Children; - olvConnections.ContextMenuStrip = _contextMenu; - } - - private static object ConnectionImageGetter(object rowObject) - { - if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; - if (rowObject is RootNodeInfo) return "Root"; - if (rowObject is ContainerInfo) return "Folder"; - var connection = rowObject as ConnectionInfo; - if (connection == null) return ""; - return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; - } - - private void SetupDropSink() - { - var dropSink = (SimpleDropSink)olvConnections.DropSink; - dropSink.CanDropBetween = true; - } - - private void SetEventHandlers() - { - SetTreeEventHandlers(); - SetContextMenuEventHandlers(); - SetMenuEventHandlers(); - } - - private void SetTreeEventHandlers() - { - olvConnections.Collapsed += (sender, args) => - { - var container = args.Model as ContainerInfo; - if (container != null) - container.IsExpanded = false; - }; - olvConnections.Expanded += (sender, args) => - { - var container = args.Model as ContainerInfo; - if (container != null) - container.IsExpanded = true; - }; olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; - olvConnections.SelectionChanged += tvConnections_AfterSelect; - olvConnections.CellClick += tvConnections_NodeMouseSingleClick; - olvConnections.CellClick += tvConnections_NodeMouseDoubleClick; - olvConnections.CellToolTipShowing += tvConnections_CellToolTipShowing; - olvConnections.ModelCanDrop += _dragAndDropHandler.HandleEvent_ModelCanDrop; - olvConnections.ModelDropped += _dragAndDropHandler.HandleEvent_ModelDropped; olvConnections.KeyDown += tvConnections_KeyDown; olvConnections.KeyPress += tvConnections_KeyPress; } - - private void PopulateTreeView() - { - UnregisterModelUpdateHandlers(); - olvConnections.SetObjects(ConnectionTreeModel.RootNodes); - RegisterModelUpdateHandlers(); - _nodeSearcher = new NodeSearcher(ConnectionTreeModel); - ExpandPreviouslyOpenedFolders(); - ExpandRootConnectionNode(); - OpenConnectionsFromLastSession(); - } - - private void RegisterModelUpdateHandlers() - { - _puttySessionsManager.PuttySessionsCollectionChanged += OnPuttySessionsCollectionChanged; - ConnectionTreeModel.CollectionChanged += HandleCollectionChanged; - ConnectionTreeModel.PropertyChanged += HandleCollectionPropertyChanged; - } - - private void UnregisterModelUpdateHandlers() - { - _puttySessionsManager.PuttySessionsCollectionChanged -= OnPuttySessionsCollectionChanged; - ConnectionTreeModel.CollectionChanged -= HandleCollectionChanged; - ConnectionTreeModel.PropertyChanged -= HandleCollectionPropertyChanged; - } - - private void OnPuttySessionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) - { - RefreshTreeObjects(olvConnections.GetRootPuttyNodes().ToList()); - } - - private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) - { - //TODO for some reason property changed events are getting triggered twice for each changed property. should be just once. cant find source of duplication - var property = propertyChangedEventArgs.PropertyName; - if (property != "Name" && property != "OpenConnections") return; - var senderAsConnectionInfo = sender as ConnectionInfo; - if (senderAsConnectionInfo != null) - RefreshTreeObject(senderAsConnectionInfo); - } - - private void ExpandPreviouslyOpenedFolders() - { - var containerList = ConnectionTreeModel.GetRecursiveChildList(olvConnections.GetRootConnectionNode()).OfType(); - var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); - olvConnections.ExpandedObjects = previouslyExpandedNodes; - olvConnections.InvokeRebuildAll(true); - } - - private void OpenConnectionsFromLastSession() - { - if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; - var connectionInfoList = olvConnections.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); - var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); - foreach (var connectionInfo in previouslyOpenedConnections) - { - ConnectionInitiator.OpenConnection(connectionInfo); - } - } - #endregion - - #region ConnectionTree - public void DuplicateSelectedNode() => olvConnections.DuplicateSelectedNode(); - - public void RenameSelectedNode() => olvConnections.RenameSelectedNode(); - - public void DeleteSelectedNode() - { - if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; - if (!UserConfirmsDeletion()) return; - ConnectionTreeModel.DeleteNode(SelectedNode); - Runtime.SaveConnectionsAsync(); - } - - private bool UserConfirmsDeletion() - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - return selectedNodeAsContainer.HasChildren() - ? UserConfirmsNonEmptyFolderDeletion() - : UserConfirmsEmptyFolderDeletion(); - return UserConfirmsConnectionDeletion(); - } - - private bool UserConfirmsEmptyFolderDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private bool UserConfirmsNonEmptyFolderDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private bool UserConfirmsConnectionDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private static bool PromptUser(string promptMessage) - { - var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - return (msgBoxResponse == DialogResult.Yes); - } - - private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) - { - var senderAsContainerInfo = sender as ContainerInfo; - // ReSharper disable once SwitchStatementMissingSomeCases - switch (args?.Action) - { - case NotifyCollectionChangedAction.Add: - var childList = senderAsContainerInfo?.Children; - ConnectionInfo otherChild = null; - if (childList?.Count > 1) - otherChild = childList.First(child => !args.NewItems.Contains(child)); - RefreshTreeObject(otherChild ?? senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Remove: - RefreshTreeObjects(args.OldItems); - break; - case NotifyCollectionChangedAction.Move: - RefreshTreeObjects(args.OldItems); - break; - case NotifyCollectionChangedAction.Reset: - RefreshTreeObject(senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Replace: - break; - case null: - break; - } - } - - private void RefreshTreeObject(ConnectionInfo modelObject) - { - olvConnections.RefreshObject(modelObject); - } - - private void RefreshTreeObjects(IList modelObjects) - { - olvConnections.RefreshObjects(modelObjects); - } - - public void AddConnection() - { - try - { - AddNode(new ConnectionInfo()); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); - } - } - - public void AddFolder() - { - try - { - AddNode(new ContainerInfo()); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); - } - } - - private void AddNode(ConnectionInfo newNode) - { - if (SelectedNode == null) return; - DefaultConnectionInfo.Instance.SaveTo(newNode); - DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); - var selectedContainer = SelectedNode as ContainerInfo; - var parent = selectedContainer ?? SelectedNode?.Parent; - newNode.SetParent(parent); - olvConnections.Expand(parent); - olvConnections.SelectObject(newNode); - olvConnections.EnsureModelVisible(newNode); - } - - private void DisconnectConnection(ConnectionInfo connectionInfo) - { - try - { - if (connectionInfo == null) return; - var nodeAsContainer = connectionInfo as ContainerInfo; - if (nodeAsContainer != null) - { - foreach (var child in nodeAsContainer.Children) - { - for (var i = 0; i <= child.OpenConnections.Count - 1; i++) - { - child.OpenConnections[i].Disconnect(); - } - } - } - else - { - for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) - { - connectionInfo.OpenConnections[i].Disconnect(); - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void SshTransferFile() - { - try - { - Windows.Show(WindowType.SSHTransfer); - Windows.SshtransferForm.Hostname = SelectedNode.Hostname; - Windows.SshtransferForm.Username = SelectedNode.Username; - Windows.SshtransferForm.Password = SelectedNode.Password; - Windows.SshtransferForm.Port = Convert.ToString(SelectedNode.Port); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void StartExternalApp(ExternalTool externalTool) - { - try - { - if (SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) - externalTool.Start(SelectedNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeToolsExternalAppsEntry_Click failed (UI.Window.ConnectionTreeWindow)", ex); - } - } - - private void ExpandRootConnectionNode() - { - var rootConnectionNode = olvConnections.GetRootConnectionNode(); - olvConnections.InvokeExpand(rootConnectionNode); - } - - public void EnsureRootNodeVisible() - { - olvConnections.EnsureModelVisible(olvConnections.GetRootConnectionNode()); - } - - private void tvConnections_AfterSelect(object sender, EventArgs e) - { - try - { - Windows.ConfigForm.SelectedTreeNode = SelectedNode; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) - { - try - { - if (e.ClickCount > 1) return; - var clickedNode = e.Model as ConnectionInfo; - - if (clickedNode == null) return; - if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; - if (Settings.Default.SingleClickOnConnectionOpensIt) - ConnectionInitiator.OpenConnection(SelectedNode); - - if (Settings.Default.SingleClickSwitchesToOpenConnection) - ConnectionInitiator.SwitchToOpenConnection(SelectedNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) - { - if (e.ClickCount < 2) return; - var clickedNodeAsContainer = e.Model as ContainerInfo; - if (clickedNodeAsContainer != null) - { - olvConnections.ToggleExpansion(clickedNodeAsContainer); - } - - var clickedNode = e.Model as ConnectionInfo; - if (clickedNode?.GetTreeNodeType() == TreeNodeType.Connection | - clickedNode?.GetTreeNodeType() == TreeNodeType.PuttySession) - { - ConnectionInitiator.OpenConnection(SelectedNode); - } - } - - private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) - { - try - { - var nodeProducingTooltip = (ConnectionInfo)e.Model; - e.Text = nodeProducingTooltip.Description; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_MouseMove (UI.Window.ConnectionTreeWindow) failed", ex); - } - } #endregion #region Top Menu @@ -562,11 +152,11 @@ namespace mRemoteNG.UI.Window else ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); }; - _contextMenu.DisconnectClicked += (sender, args) => DisconnectConnection(SelectedNode); - _contextMenu.TransferFileClicked += (sender, args) => SshTransferFile(); - _contextMenu.DuplicateClicked += (sender, args) => DuplicateSelectedNode(); - _contextMenu.RenameClicked += (sender, args) => RenameSelectedNode(); - _contextMenu.DeleteClicked += (sender, args) => DeleteSelectedNode(); + _contextMenu.DisconnectClicked += (sender, args) => olvConnections.DisconnectConnection(SelectedNode); + _contextMenu.TransferFileClicked += (sender, args) => olvConnections.SshTransferFile(); + _contextMenu.DuplicateClicked += (sender, args) => olvConnections.DuplicateSelectedNode(); + _contextMenu.RenameClicked += (sender, args) => olvConnections.RenameSelectedNode(); + _contextMenu.DeleteClicked += (sender, args) => olvConnections.DeleteSelectedNode(); _contextMenu.ImportFileClicked += (sender, args) => { var selectedNodeAsContainer = SelectedNode as ContainerInfo ?? SelectedNode.Parent; @@ -581,18 +171,18 @@ namespace mRemoteNG.UI.Window _contextMenu.SortDescendingClicked += (sender, args) => SortNodesRecursive(SelectedNode, ListSortDirection.Descending); _contextMenu.MoveUpClicked += cMenTreeMoveUp_Click; _contextMenu.MoveDownClicked += cMenTreeMoveDown_Click; - _contextMenu.ExternalToolClicked += (sender, args) => StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); + _contextMenu.ExternalToolClicked += (sender, args) => olvConnections.StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); } private void cMenTreeAddConnection_Click(object sender, EventArgs e) { - AddConnection(); + olvConnections.AddConnection(); Runtime.SaveConnectionsAsync(); } private void cMenTreeAddFolder_Click(object sender, EventArgs e) { - AddFolder(); + olvConnections.AddFolder(); Runtime.SaveConnectionsAsync(); } @@ -632,7 +222,7 @@ namespace mRemoteNG.UI.Window try { _contextMenu.EnableShortcutKeys(); - ConnectionTreeModel.RenameNode(SelectedNode, e.Label); + ConnectionTree.ConnectionTreeModel.RenameNode(SelectedNode, e.Label); Windows.ConfigForm.SelectedTreeNode = SelectedNode; Runtime.SaveConnectionsAsync(); } @@ -669,13 +259,13 @@ namespace mRemoteNG.UI.Window } else if (e.KeyCode == Keys.Up) { - var match = _nodeSearcher.PreviousMatch(); + var match = olvConnections.NodeSearcher.PreviousMatch(); JumpToNode(match); e.Handled = true; } else if (e.KeyCode == Keys.Down) { - var match = _nodeSearcher.NextMatch(); + var match = olvConnections.NodeSearcher.NextMatch(); JumpToNode(match); e.Handled = true; } @@ -693,8 +283,8 @@ namespace mRemoteNG.UI.Window private void txtSearch_TextChanged(object sender, EventArgs e) { if (txtSearch.Text == "") return; - _nodeSearcher?.SearchByName(txtSearch.Text); - JumpToNode(_nodeSearcher?.CurrentMatch); + olvConnections.NodeSearcher?.SearchByName(txtSearch.Text); + JumpToNode(olvConnections.NodeSearcher?.CurrentMatch); } private void JumpToNode(ConnectionInfo connectionInfo) diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.resx b/mRemoteV1/UI/Window/ConnectionTreeWindow.resx index dfeabba7a..584bd6853 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.resx +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.resx @@ -117,9 +117,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 17, 17 - 119, 19 From a518d41c78c28e51aca466560d9ff4bec58b2c11 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 09:07:21 -0700 Subject: [PATCH 014/106] updated connection tree window tests --- .../UI/Window/ConnectionTreeWindowTests.cs | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs b/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs index 1c1fcaecd..abbf20af3 100644 --- a/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs +++ b/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs @@ -1,7 +1,4 @@ using System.Threading; -using mRemoteNG.Container; -using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; using mRemoteNG.UI.Window; using NUnit.Framework; using WeifenLuo.WinFormsUI.Docking; @@ -25,30 +22,11 @@ namespace mRemoteNGTests.UI.Window _connectionTreeWindow.Close(); } - [Test, Apartment(ApartmentState.STA)] - public void CanSetTheConnectionTreeModel() - { - var treeModel = CreateConnectionTreeModel(); - _connectionTreeWindow.ConnectionTreeModel = treeModel; - _connectionTreeWindow.Show(); - Assert.That(_connectionTreeWindow.ConnectionTreeModel, Is.EqualTo(treeModel)); - } - [Test, Apartment(ApartmentState.STA)] public void CanDeleteLastFolderInTheTree() { - var treeModel = CreateConnectionTreeModel(); - treeModel.RootNodes[0].AddChild(new ContainerInfo()); - _connectionTreeWindow.ConnectionTreeModel = treeModel; _connectionTreeWindow.Show(); - Assert.That(_connectionTreeWindow.ConnectionTreeModel, Is.EqualTo(treeModel)); - } - - private ConnectionTreeModel CreateConnectionTreeModel() - { - var connectionTreeModel = new ConnectionTreeModel(); - connectionTreeModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection)); - return connectionTreeModel; + Assert.That(_connectionTreeWindow.Visible); } } } \ No newline at end of file From a44a33d5089fca9ca88b8573a34b80bc1abdab96 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 09:16:05 -0700 Subject: [PATCH 015/106] minor cleanup --- mRemoteV1/UI/Controls/ConnectionTree.cs | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index e3895eb7e..817f4d45e 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -23,7 +23,7 @@ namespace mRemoteNG.UI.Controls private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; private OLVColumn _olvNameColumn; - private ImageList imgListTree; + private ImageList _imgListTree; public ConnectionInfo SelectedNode => (ConnectionInfo)SelectedObject; @@ -74,29 +74,29 @@ namespace mRemoteNG.UI.Controls private void CreateImageList() { - imgListTree = new ImageList(this.components) + _imgListTree = new ImageList(components) { ColorDepth = ColorDepth.Depth32Bit, ImageSize = new System.Drawing.Size(16, 16), TransparentColor = System.Drawing.Color.Transparent }; - SmallImageList = imgListTree; + SmallImageList = _imgListTree; } private void FillImageList() { try { - imgListTree.Images.Add(Resources.Root); - imgListTree.Images.SetKeyName(0, "Root"); - imgListTree.Images.Add(Resources.Folder); - imgListTree.Images.SetKeyName(1, "Folder"); - imgListTree.Images.Add(Resources.Play); - imgListTree.Images.SetKeyName(2, "Play"); - imgListTree.Images.Add(Resources.Pause); - imgListTree.Images.SetKeyName(3, "Pause"); - imgListTree.Images.Add(Resources.PuttySessions); - imgListTree.Images.SetKeyName(4, "PuttySessions"); + _imgListTree.Images.Add(Resources.Root); + _imgListTree.Images.SetKeyName(0, "Root"); + _imgListTree.Images.Add(Resources.Folder); + _imgListTree.Images.SetKeyName(1, "Folder"); + _imgListTree.Images.Add(Resources.Play); + _imgListTree.Images.SetKeyName(2, "Play"); + _imgListTree.Images.Add(Resources.Pause); + _imgListTree.Images.SetKeyName(3, "Pause"); + _imgListTree.Images.Add(Resources.PuttySessions); + _imgListTree.Images.SetKeyName(4, "PuttySessions"); } catch (Exception ex) { From 737db469ba8707f262cd9958c328082f4f5b1b53 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 09:27:32 -0700 Subject: [PATCH 016/106] Fixed test name --- mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs b/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs index abbf20af3..1ea17109f 100644 --- a/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs +++ b/mRemoteNGTests/UI/Window/ConnectionTreeWindowTests.cs @@ -23,7 +23,7 @@ namespace mRemoteNGTests.UI.Window } [Test, Apartment(ApartmentState.STA)] - public void CanDeleteLastFolderInTheTree() + public void CanShowWindow() { _connectionTreeWindow.Show(); Assert.That(_connectionTreeWindow.Visible); From d469fa1d4055b7ed2fa08a52a16661d841ae7617 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 09:51:18 -0700 Subject: [PATCH 017/106] Made the deletion confirmation functionality plugable to make testing easier --- mRemoteV1/Tree/ConnectionDeletionConfirmer.cs | 44 +++++++++++++++++++ mRemoteV1/UI/Controls/ConnectionTree.cs | 38 ++-------------- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 1 + mRemoteV1/mRemoteV1.csproj | 1 + 4 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 mRemoteV1/Tree/ConnectionDeletionConfirmer.cs diff --git a/mRemoteV1/Tree/ConnectionDeletionConfirmer.cs b/mRemoteV1/Tree/ConnectionDeletionConfirmer.cs new file mode 100644 index 000000000..43844646f --- /dev/null +++ b/mRemoteV1/Tree/ConnectionDeletionConfirmer.cs @@ -0,0 +1,44 @@ +using System.Windows.Forms; +using mRemoteNG.Connection; +using mRemoteNG.Container; + + +namespace mRemoteNG.Tree +{ + public class ConnectionDeletionConfirmer + { + public static bool UserConfirmsDeletion(ConnectionInfo deletionTarget) + { + var deletionTargetAsContainer = deletionTarget as ContainerInfo; + if (deletionTargetAsContainer != null) + return deletionTargetAsContainer.HasChildren() + ? UserConfirmsNonEmptyFolderDeletion(deletionTargetAsContainer) + : UserConfirmsEmptyFolderDeletion(deletionTargetAsContainer); + return UserConfirmsConnectionDeletion(deletionTarget); + } + + private static bool UserConfirmsEmptyFolderDeletion(AbstractConnectionInfoData deletionTarget) + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, deletionTarget.Name); + return PromptUser(messagePrompt); + } + + private static bool UserConfirmsNonEmptyFolderDeletion(AbstractConnectionInfoData deletionTarget) + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, deletionTarget.Name); + return PromptUser(messagePrompt); + } + + private static bool UserConfirmsConnectionDeletion(AbstractConnectionInfoData deletionTarget) + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, deletionTarget.Name); + return PromptUser(messagePrompt); + } + + private static bool PromptUser(string promptMessage) + { + var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + return (msgBoxResponse == DialogResult.Yes); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 817f4d45e..29c8e139d 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -40,6 +40,8 @@ namespace mRemoteNG.UI.Controls } } + public Func DeletionConfirmer { get; set; } = connectionInfo => true; + public ConnectionTree() { @@ -218,45 +220,11 @@ namespace mRemoteNG.UI.Controls public void DeleteSelectedNode() { if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; - if (!UserConfirmsDeletion()) return; + if (!DeletionConfirmer(SelectedNode)) return; ConnectionTreeModel.DeleteNode(SelectedNode); Runtime.SaveConnectionsAsync(); } - private bool UserConfirmsDeletion() - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - return selectedNodeAsContainer.HasChildren() - ? UserConfirmsNonEmptyFolderDeletion() - : UserConfirmsEmptyFolderDeletion(); - return UserConfirmsConnectionDeletion(); - } - - private bool UserConfirmsEmptyFolderDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private bool UserConfirmsNonEmptyFolderDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private bool UserConfirmsConnectionDeletion() - { - var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Name); - return PromptUser(messagePrompt); - } - - private static bool PromptUser(string promptMessage) - { - var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - return (msgBoxResponse == DialogResult.Yes); - } - private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { var senderAsContainerInfo = sender as ContainerInfo; diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 0056b9bb1..d726bf43d 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -80,6 +80,7 @@ namespace mRemoteNG.UI.Window #region ConnectionTree private void SetConnectionTreeEventHandlers() { + olvConnections.DeletionConfirmer = ConnectionDeletionConfirmer.UserConfirmsDeletion; olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; olvConnections.KeyDown += tvConnections_KeyDown; diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 1c2130235..41f9efd32 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -211,6 +211,7 @@ + From 1e213dfff7b0b3467dd0eb84d427274223518949 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 09:58:24 -0700 Subject: [PATCH 018/106] resolved issue with deleting the last folder in the tree --- mRemoteNGTests/Tree/ConnectionTreeTests.cs | 25 +++++++++++++++++++--- mRemoteV1/UI/Controls/ConnectionTree.cs | 7 ++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/mRemoteNGTests/Tree/ConnectionTreeTests.cs b/mRemoteNGTests/Tree/ConnectionTreeTests.cs index e27710091..ecf8818a5 100644 --- a/mRemoteNGTests/Tree/ConnectionTreeTests.cs +++ b/mRemoteNGTests/Tree/ConnectionTreeTests.cs @@ -1,4 +1,8 @@ -using mRemoteNG.UI.Controls; +using System.Threading; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using mRemoteNG.UI.Controls; using NUnit.Framework; @@ -7,10 +11,12 @@ namespace mRemoteNGTests.Tree public class ConnectionTreeTests { private ConnectionTree _connectionTree; + private ConnectionTreeModel _connectionTreeModel; [SetUp] public void Setup() { + _connectionTreeModel = CreateConnectionTreeModel(); _connectionTree = new ConnectionTree(); } @@ -21,9 +27,22 @@ namespace mRemoteNGTests.Tree } - [Test] - public void test() + [Test, Apartment(ApartmentState.STA)] + public void CanDeleteLastFolderInTheTree() { + var lastFolder = new ContainerInfo(); + _connectionTreeModel.RootNodes[0].AddChild(lastFolder); + _connectionTree.ConnectionTreeModel = _connectionTreeModel; + _connectionTree.SelectObject(lastFolder); + _connectionTree.DeleteSelectedNode(); + Assert.That(_connectionTree.GetRootConnectionNode().HasChildren, Is.False); + } + + private ConnectionTreeModel CreateConnectionTreeModel() + { + var connectionTreeModel = new ConnectionTreeModel(); + connectionTreeModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection)); + return connectionTreeModel; } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 29c8e139d..f4daee50d 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -26,7 +26,7 @@ namespace mRemoteNG.UI.Controls private ImageList _imgListTree; - public ConnectionInfo SelectedNode => (ConnectionInfo)SelectedObject; + public ConnectionInfo SelectedNode => (ConnectionInfo) SelectedObject; public NodeSearcher NodeSearcher { get; private set; } @@ -239,7 +239,10 @@ namespace mRemoteNG.UI.Controls RefreshTreeObject(otherChild ?? senderAsContainerInfo); break; case NotifyCollectionChangedAction.Remove: - RefreshTreeObjects(args.OldItems); + if (senderAsContainerInfo?.Children.Count > 0) + RefreshTreeObjects(args.OldItems); + else + RefreshTreeObject(senderAsContainerInfo); break; case NotifyCollectionChangedAction.Move: RefreshTreeObjects(args.OldItems); From adccb9110652fef6b836a42e5c41bd25291e74ae Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 10:06:50 -0700 Subject: [PATCH 019/106] removed unnecessary code --- mRemoteV1/UI/Controls/ConnectionTree.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index f4daee50d..c53558e0b 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -193,7 +193,7 @@ namespace mRemoteNG.UI.Controls if (property != "Name" && property != "OpenConnections") return; var senderAsConnectionInfo = sender as ConnectionInfo; if (senderAsConnectionInfo != null) - RefreshTreeObject(senderAsConnectionInfo); + RefreshObject(senderAsConnectionInfo); } private void ExpandPreviouslyOpenedFolders() @@ -236,19 +236,19 @@ namespace mRemoteNG.UI.Controls ConnectionInfo otherChild = null; if (childList?.Count > 1) otherChild = childList.First(child => !args.NewItems.Contains(child)); - RefreshTreeObject(otherChild ?? senderAsContainerInfo); + RefreshObject(otherChild ?? senderAsContainerInfo); break; case NotifyCollectionChangedAction.Remove: if (senderAsContainerInfo?.Children.Count > 0) RefreshTreeObjects(args.OldItems); else - RefreshTreeObject(senderAsContainerInfo); + RefreshObject(senderAsContainerInfo); break; case NotifyCollectionChangedAction.Move: RefreshTreeObjects(args.OldItems); break; case NotifyCollectionChangedAction.Reset: - RefreshTreeObject(senderAsContainerInfo); + RefreshObject(senderAsContainerInfo); break; case NotifyCollectionChangedAction.Replace: break; @@ -257,11 +257,6 @@ namespace mRemoteNG.UI.Controls } } - private void RefreshTreeObject(ConnectionInfo modelObject) - { - RefreshObject(modelObject); - } - private void RefreshTreeObjects(IList modelObjects) { RefreshObjects(modelObjects); From 78c1f6b8e36cbcbdf4cb5c12158d55b419f1cb3b Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 10:28:38 -0700 Subject: [PATCH 020/106] Fixed bug where we could not drop between items (rearrange) --- mRemoteV1/UI/Controls/ConnectionTree.cs | 7 ++++--- mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index c53558e0b..f5f9a6025 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -129,9 +129,10 @@ namespace mRemoteNG.UI.Controls private void SetupDropSink() { - DropSink = new SimpleDropSink(); - var dropSink = (SimpleDropSink)DropSink; - dropSink.CanDropBetween = true; + DropSink = new SimpleDropSink + { + CanDropBetween = true + }; } private void SetEventHandlers() diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs index abb971af0..ed23b42f3 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs @@ -48,7 +48,6 @@ namespace mRemoteNG.UI.Window this.olvConnections.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; this.olvConnections.HideSelection = false; this.olvConnections.IsSimpleDragSource = true; - this.olvConnections.IsSimpleDropSink = true; this.olvConnections.LabelEdit = true; this.olvConnections.Location = new System.Drawing.Point(0, 0); this.olvConnections.MultiSelect = false; From 34fa6b158b69445f2abac236436d70185175d151 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 13 Dec 2016 13:34:44 -0500 Subject: [PATCH 021/106] load the default domain when opening the form Related to #311 --- mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs index 0e1039906..373806c54 100644 --- a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs +++ b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs @@ -35,6 +35,9 @@ namespace mRemoteNG.UI.Window txtDomain.Text = CurrentDomain; ActiveDirectoryTree.Domain = CurrentDomain; EnableDisableImportButton(); + + // Domain doesn't refresh on load, so it defaults to DOMAIN without this... + ChangeDomain(); } private void btnImport_Click(object sender, EventArgs e) From 8d5a76504029e35afa42a0598bbe712617a903ff Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 13 Dec 2016 14:22:39 -0500 Subject: [PATCH 022/106] pass importSubOU option in to recursive calls Fixes remaining problems reported in #211 --- mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs b/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs index f98beb5f2..c8835c92d 100644 --- a/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs +++ b/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs @@ -66,7 +66,7 @@ namespace mRemoteNG.Config.Serializers // check/continue here so we don't create empty connection objects if(!_importSubOU) continue; - ActiveDirectoryImporter.Import(ldapResult.Path, parentContainer); + ActiveDirectoryImporter.Import(ldapResult.Path, parentContainer, _importSubOU); continue; } From 715f92f3d5093820211c99dd5dee6c333a4ec8ae Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 13:07:52 -0700 Subject: [PATCH 023/106] removed unnecessary code --- mRemoteV1/UI/Controls/ConnectionTree.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index f5f9a6025..e56a685ac 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; @@ -184,7 +183,7 @@ namespace mRemoteNG.UI.Controls private void OnPuttySessionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { - RefreshTreeObjects(GetRootPuttyNodes().ToList()); + RefreshObjects(GetRootPuttyNodes().ToList()); } private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) @@ -241,12 +240,12 @@ namespace mRemoteNG.UI.Controls break; case NotifyCollectionChangedAction.Remove: if (senderAsContainerInfo?.Children.Count > 0) - RefreshTreeObjects(args.OldItems); + RefreshObjects(args.OldItems); else RefreshObject(senderAsContainerInfo); break; case NotifyCollectionChangedAction.Move: - RefreshTreeObjects(args.OldItems); + RefreshObjects(args.OldItems); break; case NotifyCollectionChangedAction.Reset: RefreshObject(senderAsContainerInfo); @@ -258,11 +257,6 @@ namespace mRemoteNG.UI.Controls } } - private void RefreshTreeObjects(IList modelObjects) - { - RefreshObjects(modelObjects); - } - public void AddConnection() { try From 45dfaa1b21ed262c5e1b771ec571f0fffe8fa904 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 13 Dec 2016 13:11:50 -0700 Subject: [PATCH 024/106] removed unused code --- mRemoteV1/UI/Controls/ConnectionTree.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index e56a685ac..c8722787d 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -359,11 +359,6 @@ namespace mRemoteNG.UI.Controls this.InvokeExpand(rootConnectionNode); } - public void EnsureRootNodeVisible() - { - EnsureModelVisible(GetRootConnectionNode()); - } - private void tvConnections_AfterSelect(object sender, EventArgs e) { try From 975a3086470c833975c6dc19c27271963c5316cb Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Thu, 15 Dec 2016 17:44:55 -0500 Subject: [PATCH 025/106] reworking code to better test & code cleanup --- mRemoteNGTests/App/UpdaterTests.cs | 22 -- mRemoteV1/App/Info/GeneralAppInfo.cs | 12 +- mRemoteV1/App/Info/UpdateChannelInfo.cs | 59 ++- mRemoteV1/App/Startup.cs | 2 +- mRemoteV1/App/Update/AppUpdater.cs | 457 ++++++++++++------------ 5 files changed, 293 insertions(+), 259 deletions(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index 083616c36..1889b5df9 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -9,37 +9,15 @@ namespace mRemoteNGTests.App [TestFixture] public class UpdaterTests { - private AppUpdater _appUpdate; - [SetUp] public void Setup() { GeneralAppInfo.ApplicationVersion = "1.0.0.0"; - _appUpdate = new AppUpdater(); - _appUpdate.GetUpdateInfoCompletedEvent += TestGetUpdateInfoCompleted; - } [Test] public void TestStableChannel() { } - - private void TestGetUpdateInfoCompleted(object sender, AsyncCompletedEventArgs e) - { - try - { - _appUpdate.GetUpdateInfoCompletedEvent -= TestGetUpdateInfoCompleted; - - if (_appUpdate.IsUpdateAvailable()) - { - - } - } - catch (Exception ex) - { - - } - } } } diff --git a/mRemoteV1/App/Info/GeneralAppInfo.cs b/mRemoteV1/App/Info/GeneralAppInfo.cs index 5e3506beb..ff98ea5b7 100644 --- a/mRemoteV1/App/Info/GeneralAppInfo.cs +++ b/mRemoteV1/App/Info/GeneralAppInfo.cs @@ -19,15 +19,19 @@ namespace mRemoteNG.App.Info public static readonly string ProductName = Application.ProductName; public static readonly string Copyright = ((AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCopyrightAttribute), false)).Copyright; public static readonly string HomePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location); - public static string ReportingFilePath = ""; + //public static string ReportingFilePath = ""; public static readonly string PuttyPath = HomePath + "\\PuTTYNG.exe"; public static string UserAgent { get { - var details = new List(); - details.Add("compatible"); - details.Add(OSVersion.Platform == PlatformID.Win32NT ? $"Windows NT {OSVersion.Version.Major}.{OSVersion.Version.Minor}": OSVersion.VersionString); + var details = new List + { + "compatible", + OSVersion.Platform == PlatformID.Win32NT + ? $"Windows NT {OSVersion.Version.Major}.{OSVersion.Version.Minor}" + : OSVersion.VersionString + }; if (Is64BitProcess) { details.Add("WOW64"); diff --git a/mRemoteV1/App/Info/UpdateChannelInfo.cs b/mRemoteV1/App/Info/UpdateChannelInfo.cs index 6954e4cc2..8a347671e 100644 --- a/mRemoteV1/App/Info/UpdateChannelInfo.cs +++ b/mRemoteV1/App/Info/UpdateChannelInfo.cs @@ -1,12 +1,35 @@ -namespace mRemoteNG.App.Info +using System; + +namespace mRemoteNG.App.Info { - public static class UpdateChannelInfo + public class UpdateChannelInfo { internal const string STABLE = "Stable"; internal const string BETA = "Beta"; internal const string DEV = "Development"; - public static string FileName + /* no #if here since they are used for unit tests as well */ + public const string STABLE_PORTABLE = "update-portable.txt"; + public const string BETA_PORTABLE = "beta-update-portable.txt"; + public const string DEV_PORTABLE = "dev-update-portable.txt"; + + public const string STABLE_MSI = "update.txt"; + public const string BETA_MSI = "beta-update.txt"; + public const string DEV_MSI = "dev-update.txt"; + + private readonly string channel; + + public UpdateChannelInfo() + { + channel = IsValidChannel(Settings.Default.UpdateChannel) ? Settings.Default.UpdateChannel : STABLE; + } + + public UpdateChannelInfo(string s) + { + channel = IsValidChannel(s) ? s : STABLE; + } + + private string FileName { #if PORTABLE get @@ -14,16 +37,16 @@ /* */ /* return PORTABLE update files here */ /* */ - switch (Settings.Default.UpdateChannel) + switch (channel) { case STABLE: - return "update-portable.txt"; + return STABLE_PORTABLE; case BETA: - return "beta-update-portable.txt"; + return BETA_PORTABLE; case DEV: - return "dev-update-portable.txt"; + return DEV_PORTABLE; default: - return "update-portable.txt"; + return STABLE_PORTABLE; } } #else //NOT portable @@ -32,19 +55,29 @@ /* */ /* return INSTALLER update files here */ /* */ - switch (Settings.Default.UpdateChannel) + switch (channel) { case STABLE: - return "update.txt"; + return STABLE_MSI; case BETA: - return "beta-update.txt"; + return BETA_MSI; case DEV: - return "dev-update.txt"; + return DEV_MSI; default: - return "update.txt"; + return STABLE_MSI; } } #endif //endif for PORTABLE } + + public Uri GetUpdateTxtUri() + { + return new Uri(new Uri(Settings.Default.UpdateAddress), new Uri(FileName, UriKind.Relative)); + } + + private static bool IsValidChannel(string s) + { + return s.Equals(STABLE) || s.Equals(BETA) || s.Equals(DEV); + } } } \ No newline at end of file diff --git a/mRemoteV1/App/Startup.cs b/mRemoteV1/App/Startup.cs index 163669376..95390a9f2 100644 --- a/mRemoteV1/App/Startup.cs +++ b/mRemoteV1/App/Startup.cs @@ -223,7 +223,7 @@ namespace mRemoteNG.App } if (e.Error != null) { - throw (e.Error); + throw e.Error; } if (_appUpdate.IsUpdateAvailable()) diff --git a/mRemoteV1/App/Update/AppUpdater.cs b/mRemoteV1/App/Update/AppUpdater.cs index 7f406f07f..2cee01c99 100644 --- a/mRemoteV1/App/Update/AppUpdater.cs +++ b/mRemoteV1/App/Update/AppUpdater.cs @@ -9,116 +9,122 @@ using mRemoteNG.Security.SymmetricEncryption; using System.Security.Cryptography; #if !PORTABLE using mRemoteNG.Tools; + #else using System.Windows.Forms; #endif namespace mRemoteNG.App.Update { - public class AppUpdater - { - private WebProxy _webProxy; + public class AppUpdater + { + private WebProxy _webProxy; private Thread _getUpdateInfoThread; private Thread _getChangeLogThread; -#region Public Properties + private UpdateChannelInfo updChannel; + + #region Public Properties + public UpdateInfo CurrentUpdateInfo { get; private set; } - public string ChangeLog { get; private set; } + public string ChangeLog { get; private set; } - public bool IsGetUpdateInfoRunning => _getUpdateInfoThread != null && _getUpdateInfoThread.IsAlive; + public bool IsGetUpdateInfoRunning => _getUpdateInfoThread != null && _getUpdateInfoThread.IsAlive; - private bool IsGetChangeLogRunning => _getChangeLogThread != null && _getChangeLogThread.IsAlive; + private bool IsGetChangeLogRunning => _getChangeLogThread != null && _getChangeLogThread.IsAlive; - public bool IsDownloadUpdateRunning => _downloadUpdateWebClient != null; + public bool IsDownloadUpdateRunning => _downloadUpdateWebClient != null; -#endregion - -#region Public Methods - public AppUpdater() - { - SetProxySettings(); - } + #endregion - private void SetProxySettings() - { - var shouldWeUseProxy = Settings.Default.UpdateUseProxy; - var proxyAddress = Settings.Default.UpdateProxyAddress; - var port = Settings.Default.UpdateProxyPort; - var useAuthentication = Settings.Default.UpdateProxyUseAuthentication; - var username = Settings.Default.UpdateProxyAuthUser; + #region Public Methods + + public AppUpdater() + { + SetProxySettings(); + } + + private void SetProxySettings() + { + var shouldWeUseProxy = Settings.Default.UpdateUseProxy; + var proxyAddress = Settings.Default.UpdateProxyAddress; + var port = Settings.Default.UpdateProxyPort; + var useAuthentication = Settings.Default.UpdateProxyUseAuthentication; + var username = Settings.Default.UpdateProxyAuthUser; var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey); + var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey); SetProxySettings(shouldWeUseProxy, proxyAddress, port, useAuthentication, username, password); - } - - public void SetProxySettings(bool useProxy, string address, int port, bool useAuthentication, string username, string password) - { - if (useProxy && !string.IsNullOrEmpty(address)) - { - _webProxy = port != 0 ? new WebProxy(address, port) : new WebProxy(address); + } - _webProxy.Credentials = useAuthentication ? new NetworkCredential(username, password) : null; - } - else - { - _webProxy = null; - } - } - - public bool IsUpdateAvailable() - { - if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid) - { - return false; - } - - return CurrentUpdateInfo.Version > GeneralAppInfo.GetApplicationVersion(); - } - - public void GetUpdateInfoAsync() - { - if (IsGetUpdateInfoRunning) - { - _getUpdateInfoThread.Abort(); - } - - _getUpdateInfoThread = new Thread(GetUpdateInfo); - _getUpdateInfoThread.SetApartmentState(ApartmentState.STA); - _getUpdateInfoThread.IsBackground = true; - _getUpdateInfoThread.Start(); - } - - public void GetChangeLogAsync() - { - if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid) - { - throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling GetChangeLogAsync()."); - } - - if (IsGetChangeLogRunning) - { - _getChangeLogThread.Abort(); - } - - _getChangeLogThread = new Thread(GetChangeLog); - _getChangeLogThread.SetApartmentState(ApartmentState.STA); - _getChangeLogThread.IsBackground = true; - _getChangeLogThread.Start(); - } - - public void DownloadUpdateAsync() - { - if (_downloadUpdateWebClient != null) - { - throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress."); - } - - if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid) - { - throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync()."); - } + public void SetProxySettings(bool useProxy, string address, int port, bool useAuthentication, string username, string password) + { + if (useProxy && !string.IsNullOrEmpty(address)) + { + _webProxy = port != 0 ? new WebProxy(address, port) : new WebProxy(address); + + _webProxy.Credentials = useAuthentication ? new NetworkCredential(username, password) : null; + } + else + { + _webProxy = null; + } + } + + public bool IsUpdateAvailable() + { + if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid) + { + return false; + } + + return CurrentUpdateInfo.Version > GeneralAppInfo.GetApplicationVersion(); + } + + public void GetUpdateInfoAsync() + { + if (IsGetUpdateInfoRunning) + { + _getUpdateInfoThread.Abort(); + } + + _getUpdateInfoThread = new Thread(GetUpdateInfo); + _getUpdateInfoThread.SetApartmentState(ApartmentState.STA); + _getUpdateInfoThread.IsBackground = true; + _getUpdateInfoThread.Start(); + } + + public void GetChangeLogAsync() + { + if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid) + { + throw new InvalidOperationException("CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling GetChangeLogAsync()."); + } + + if (IsGetChangeLogRunning) + { + _getChangeLogThread.Abort(); + } + + _getChangeLogThread = new Thread(GetChangeLog); + _getChangeLogThread.SetApartmentState(ApartmentState.STA); + _getChangeLogThread.IsBackground = true; + _getChangeLogThread.Start(); + } + + public void DownloadUpdateAsync() + { + if (_downloadUpdateWebClient != null) + { + throw new InvalidOperationException("A previous call to DownloadUpdateAsync() is still in progress."); + } + + if (CurrentUpdateInfo == null || !CurrentUpdateInfo.IsValid) + { + throw new InvalidOperationException( + "CurrentUpdateInfo is not valid. GetUpdateInfoAsync() must be called before calling DownloadUpdateAsync()."); + } #if !PORTABLE CurrentUpdateInfo.UpdateFilePath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "msi")); #else @@ -138,133 +144,139 @@ namespace mRemoteNG.App.Update } #endif DownloadUpdateWebClient.DownloadFileAsync(CurrentUpdateInfo.DownloadAddress, CurrentUpdateInfo.UpdateFilePath); - } -#endregion - -#region Private Properties - private WebClient _downloadUpdateWebClient; - private WebClient DownloadUpdateWebClient - { - get - { - if (_downloadUpdateWebClient != null) - { - return _downloadUpdateWebClient; - } - - _downloadUpdateWebClient = CreateWebClient(); - - _downloadUpdateWebClient.DownloadProgressChanged += DownloadUpdateProgressChanged; - _downloadUpdateWebClient.DownloadFileCompleted += DownloadUpdateCompleted; - - return _downloadUpdateWebClient; - } - } -#endregion - -#region Private Methods - private WebClient CreateWebClient() - { - var webClient = new WebClient(); - webClient.Headers.Add("user-agent", GeneralAppInfo.UserAgent); - webClient.Proxy = _webProxy; - return webClient; - } - - private static DownloadStringCompletedEventArgs NewDownloadStringCompletedEventArgs(string result, Exception exception, bool cancelled, object userToken) - { - var type = typeof(DownloadStringCompletedEventArgs); - const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; - Type[] argumentTypes = {typeof(string), typeof(Exception), typeof(bool), typeof(object)}; - var constructor = type.GetConstructor(bindingFlags, null, argumentTypes, null); - object[] arguments = {result, exception, cancelled, userToken}; + } - return (DownloadStringCompletedEventArgs)constructor.Invoke(arguments); - } - - private DownloadStringCompletedEventArgs DownloadString(Uri address) - { - var webClient = CreateWebClient(); - var result = string.Empty; - Exception exception = null; - var cancelled = false; - - try - { - result = webClient.DownloadString(address); - } - catch (ThreadAbortException) - { - cancelled = true; - } - catch (Exception ex) - { - exception = ex; - } - - return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null); - } - - private void GetUpdateInfo() - { - var updateFileUri = new Uri(new Uri(Convert.ToString(Settings.Default.UpdateAddress)), new Uri(UpdateChannelInfo.FileName, UriKind.Relative)); - var e = DownloadString(updateFileUri); - - if (!e.Cancelled && e.Error == null) - { - CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + #endregion + + #region Private Properties + + private WebClient _downloadUpdateWebClient; + + private WebClient DownloadUpdateWebClient + { + get + { + if (_downloadUpdateWebClient != null) + { + return _downloadUpdateWebClient; + } + + _downloadUpdateWebClient = CreateWebClient(); + + _downloadUpdateWebClient.DownloadProgressChanged += DownloadUpdateProgressChanged; + _downloadUpdateWebClient.DownloadFileCompleted += DownloadUpdateCompleted; + + return _downloadUpdateWebClient; + } + } + + #endregion + + #region Private Methods + + private WebClient CreateWebClient() + { + var webClient = new WebClient(); + webClient.Headers.Add("user-agent", GeneralAppInfo.UserAgent); + webClient.Proxy = _webProxy; + return webClient; + } + + private static DownloadStringCompletedEventArgs NewDownloadStringCompletedEventArgs(string result, + Exception exception, bool cancelled, object userToken) + { + var type = typeof(DownloadStringCompletedEventArgs); + const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; + Type[] argumentTypes = {typeof(string), typeof(Exception), typeof(bool), typeof(object)}; + var constructor = type.GetConstructor(bindingFlags, null, argumentTypes, null); + object[] arguments = {result, exception, cancelled, userToken}; + + return (DownloadStringCompletedEventArgs) constructor.Invoke(arguments); + } + + private DownloadStringCompletedEventArgs DownloadString(Uri address) + { + var webClient = CreateWebClient(); + var result = string.Empty; + Exception exception = null; + var cancelled = false; + + try + { + result = webClient.DownloadString(address); + } + catch (ThreadAbortException) + { + cancelled = true; + } + catch (Exception ex) + { + exception = ex; + } + + return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null); + } + + public void GetUpdateInfo() + { + updChannel = new UpdateChannelInfo(); + var e = DownloadString(updChannel.GetUpdateTxtUri()); + + if (!e.Cancelled && e.Error == null) + { + CurrentUpdateInfo = UpdateInfo.FromString(e.Result); Settings.Default.CheckForUpdatesLastCheck = DateTime.UtcNow; - if (!Settings.Default.UpdatePending) - { + if (!Settings.Default.UpdatePending) + { Settings.Default.UpdatePending = IsUpdateAvailable(); - } - } + } + } GetUpdateInfoCompletedEventEvent?.Invoke(this, e); } - - private void GetChangeLog() - { - var e = DownloadString(CurrentUpdateInfo.ChangeLogAddress); - - if (!e.Cancelled && e.Error == null) - { - ChangeLog = e.Result; - } + + private void GetChangeLog() + { + var e = DownloadString(CurrentUpdateInfo.ChangeLogAddress); + + if (!e.Cancelled && e.Error == null) + { + ChangeLog = e.Result; + } GetChangeLogCompletedEventEvent?.Invoke(this, e); } - - private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e) - { + + private void DownloadUpdateProgressChanged(object sender, DownloadProgressChangedEventArgs e) + { DownloadUpdateProgressChangedEventEvent?.Invoke(sender, e); } - - private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e) - { - var raiseEventArgs = e; - - if (!e.Cancelled && e.Error == null) - { - try - { + + private void DownloadUpdateCompleted(object sender, AsyncCompletedEventArgs e) + { + var raiseEventArgs = e; + + if (!e.Cancelled && e.Error == null) + { + try + { #if !PORTABLE var updateAuthenticode = new Authenticode(CurrentUpdateInfo.UpdateFilePath) - { - RequireThumbprintMatch = true, - ThumbprintToMatch = CurrentUpdateInfo.CertificateThumbprint - }; + { + RequireThumbprintMatch = true, + ThumbprintToMatch = CurrentUpdateInfo.CertificateThumbprint + }; - if (updateAuthenticode.Verify() != Authenticode.StatusValue.Verified) - { - if (updateAuthenticode.Status == Authenticode.StatusValue.UnhandledException) - { - throw (updateAuthenticode.Exception); - } + if (updateAuthenticode.Verify() != Authenticode.StatusValue.Verified) + { + if (updateAuthenticode.Status == Authenticode.StatusValue.UnhandledException) + { + throw updateAuthenticode.Exception; + } - throw (new Exception(updateAuthenticode.StatusMessage)); - } + throw new Exception(updateAuthenticode.StatusMessage); + } #endif using (var md5 = MD5.Create()) @@ -278,26 +290,29 @@ namespace mRemoteNG.App.Update } } } - catch (Exception ex) - { - raiseEventArgs = new AsyncCompletedEventArgs(ex, false, null); - } - } - - if (raiseEventArgs.Cancelled || raiseEventArgs.Error != null) - { - File.Delete(CurrentUpdateInfo.UpdateFilePath); - } + catch (Exception ex) + { + raiseEventArgs = new AsyncCompletedEventArgs(ex, false, null); + } + } + + if (raiseEventArgs.Cancelled || raiseEventArgs.Error != null) + { + File.Delete(CurrentUpdateInfo.UpdateFilePath); + } DownloadUpdateCompletedEventEvent?.Invoke(this, raiseEventArgs); _downloadUpdateWebClient.Dispose(); - _downloadUpdateWebClient = null; - } -#endregion - -#region Events + _downloadUpdateWebClient = null; + } + + #endregion + + #region Events + private AsyncCompletedEventHandler GetUpdateInfoCompletedEventEvent; + public event AsyncCompletedEventHandler GetUpdateInfoCompletedEvent { add @@ -311,6 +326,7 @@ namespace mRemoteNG.App.Update } private AsyncCompletedEventHandler GetChangeLogCompletedEventEvent; + public event AsyncCompletedEventHandler GetChangeLogCompletedEvent { add @@ -323,7 +339,8 @@ namespace mRemoteNG.App.Update } } - private DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEventEvent; + private DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEventEvent; + public event DownloadProgressChangedEventHandler DownloadUpdateProgressChangedEvent { add @@ -337,6 +354,7 @@ namespace mRemoteNG.App.Update } private AsyncCompletedEventHandler DownloadUpdateCompletedEventEvent; + public event AsyncCompletedEventHandler DownloadUpdateCompletedEvent { add @@ -348,6 +366,7 @@ namespace mRemoteNG.App.Update DownloadUpdateCompletedEventEvent = (AsyncCompletedEventHandler)Delegate.Remove(DownloadUpdateCompletedEventEvent, value); } } -#endregion - } + + #endregion + } } \ No newline at end of file From d1a6526c22e9f7a7ea4ba0023a43de594411c2e4 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 16 Dec 2016 17:27:57 -0500 Subject: [PATCH 026/106] Added functional UpdateStableChannel test It's working! It's working! --- mRemoteNGTests/App/UpdaterTests.cs | 16 +++++++++++-- mRemoteV1/App/Info/UpdateChannelInfo.cs | 31 +++++++++++-------------- mRemoteV1/App/Update/AppUpdater.cs | 9 +++---- mRemoteV1/App/Update/UpdateInfo.cs | 31 ++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index 1889b5df9..e35b30d27 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using mRemoteNG.App.Info; using mRemoteNG.App.Update; using NUnit.Framework; @@ -9,15 +8,28 @@ namespace mRemoteNGTests.App [TestFixture] public class UpdaterTests { + /* [SetUp] public void Setup() { GeneralAppInfo.ApplicationVersion = "1.0.0.0"; } + */ [Test] - public void TestStableChannel() + public void UpdateStableChannel() { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + var _upd = new AppUpdater(); + var e = _upd.DownloadString(UpdateChannelInfo.GetUpdateChannelInfo(UpdateChannelInfo.STABLE)); + Assert.That(e.Cancelled, Is.False); + Assert.That(e.Error, Is.Null); + var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + Assert.That(CurrentUpdateInfo.IsValid, Is.False); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); } } } diff --git a/mRemoteV1/App/Info/UpdateChannelInfo.cs b/mRemoteV1/App/Info/UpdateChannelInfo.cs index 8a347671e..624116ae3 100644 --- a/mRemoteV1/App/Info/UpdateChannelInfo.cs +++ b/mRemoteV1/App/Info/UpdateChannelInfo.cs @@ -2,11 +2,11 @@ namespace mRemoteNG.App.Info { - public class UpdateChannelInfo + public static class UpdateChannelInfo { - internal const string STABLE = "Stable"; - internal const string BETA = "Beta"; - internal const string DEV = "Development"; + public const string STABLE = "Stable"; + public const string BETA = "Beta"; + public const string DEV = "Development"; /* no #if here since they are used for unit tests as well */ public const string STABLE_PORTABLE = "update-portable.txt"; @@ -17,23 +17,22 @@ namespace mRemoteNG.App.Info public const string BETA_MSI = "beta-update.txt"; public const string DEV_MSI = "dev-update.txt"; - private readonly string channel; - public UpdateChannelInfo() + public static Uri GetUpdateChannelInfo() { - channel = IsValidChannel(Settings.Default.UpdateChannel) ? Settings.Default.UpdateChannel : STABLE; + var channel = IsValidChannel(Settings.Default.UpdateChannel) ? Settings.Default.UpdateChannel : STABLE; + return GetUpdateTxtUri(channel); } - public UpdateChannelInfo(string s) + public static Uri GetUpdateChannelInfo(string s) { - channel = IsValidChannel(s) ? s : STABLE; + var channel = IsValidChannel(s) ? s : STABLE; + return GetUpdateTxtUri(channel); } - private string FileName + private static string GetChannelFileName(string channel) { #if PORTABLE - get - { /* */ /* return PORTABLE update files here */ /* */ @@ -48,10 +47,7 @@ namespace mRemoteNG.App.Info default: return STABLE_PORTABLE; } - } #else //NOT portable - get - { /* */ /* return INSTALLER update files here */ /* */ @@ -66,13 +62,12 @@ namespace mRemoteNG.App.Info default: return STABLE_MSI; } - } #endif //endif for PORTABLE } - public Uri GetUpdateTxtUri() + private static Uri GetUpdateTxtUri(string channel) { - return new Uri(new Uri(Settings.Default.UpdateAddress), new Uri(FileName, UriKind.Relative)); + return new Uri(new Uri(Settings.Default.UpdateAddress), new Uri(GetChannelFileName(channel), UriKind.Relative)); } private static bool IsValidChannel(string s) diff --git a/mRemoteV1/App/Update/AppUpdater.cs b/mRemoteV1/App/Update/AppUpdater.cs index 2cee01c99..9b4780c56 100644 --- a/mRemoteV1/App/Update/AppUpdater.cs +++ b/mRemoteV1/App/Update/AppUpdater.cs @@ -22,8 +22,6 @@ namespace mRemoteNG.App.Update private Thread _getUpdateInfoThread; private Thread _getChangeLogThread; - private UpdateChannelInfo updChannel; - #region Public Properties public UpdateInfo CurrentUpdateInfo { get; private set; } @@ -194,7 +192,7 @@ namespace mRemoteNG.App.Update return (DownloadStringCompletedEventArgs) constructor.Invoke(arguments); } - private DownloadStringCompletedEventArgs DownloadString(Uri address) + public DownloadStringCompletedEventArgs DownloadString(Uri address) { var webClient = CreateWebClient(); var result = string.Empty; @@ -217,10 +215,9 @@ namespace mRemoteNG.App.Update return NewDownloadStringCompletedEventArgs(result, exception, cancelled, null); } - public void GetUpdateInfo() + private void GetUpdateInfo() { - updChannel = new UpdateChannelInfo(); - var e = DownloadString(updChannel.GetUpdateTxtUri()); + var e = DownloadString(UpdateChannelInfo.GetUpdateChannelInfo()); if (!e.Cancelled && e.Error == null) { diff --git a/mRemoteV1/App/Update/UpdateInfo.cs b/mRemoteV1/App/Update/UpdateInfo.cs index 0bf0b3578..f48813257 100644 --- a/mRemoteV1/App/Update/UpdateInfo.cs +++ b/mRemoteV1/App/Update/UpdateInfo.cs @@ -30,16 +30,45 @@ namespace mRemoteNG.App.Update newInfo.Version = updateFile.GetVersion(); newInfo.DownloadAddress = updateFile.GetUri("dURL"); newInfo.ChangeLogAddress = updateFile.GetUri("clURL"); +#if false newInfo.ImageAddress = updateFile.GetUri("imgURL"); newInfo.ImageLinkAddress = updateFile.GetUri("imgURLLink"); +#endif #if !PORTABLE newInfo.CertificateThumbprint = updateFile.GetThumbprint(); #endif newInfo.FileName = updateFile.GetFileName(); newInfo.Checksum = updateFile.GetChecksum(); - newInfo.IsValid = true; + newInfo.IsValid = newInfo.CheckIfValid(); } return newInfo; } + + private bool CheckIfValid() + { + if (string.IsNullOrEmpty(Version.ToString())) + return false; + if(string.IsNullOrEmpty(DownloadAddress.AbsoluteUri)) + return false; + if (string.IsNullOrEmpty(ChangeLogAddress.AbsoluteUri)) + return false; +#if false + if (string.IsNullOrEmpty(ImageAddress.AbsoluteUri)) + return false; + if (string.IsNullOrEmpty(ImageLinkAddress.AbsoluteUri)) + return false; +#endif +#if !PORTABLE + if (string.IsNullOrEmpty(CertificateThumbprint)) + return false; +#endif + if (string.IsNullOrEmpty(FileName)) + return false; + // ReSharper disable once ConvertIfStatementToReturnStatement + if (string.IsNullOrEmpty(Checksum)) + return false; + + return true; + } } } \ No newline at end of file From 355f48b6baf720d466ef3419b2161465e15afa5a Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 16 Dec 2016 17:29:03 -0500 Subject: [PATCH 027/106] We want only Valid info! --- mRemoteNGTests/App/UpdaterTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index e35b30d27..d2244e946 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -25,7 +25,7 @@ namespace mRemoteNGTests.App Assert.That(e.Cancelled, Is.False); Assert.That(e.Error, Is.Null); var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); - Assert.That(CurrentUpdateInfo.IsValid, Is.False); + Assert.That(CurrentUpdateInfo.IsValid, Is.True); Version v; Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); var IsNewer = CurrentUpdateInfo.Version > v; From 94a6e9a886d05c968182c108f6a67debd181ff5c Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Thu, 22 Dec 2016 10:01:20 -0500 Subject: [PATCH 028/106] code clean up around startup / frmMain Slightly related to #298 --- mRemoteV1/App/Startup.cs | 43 ++++++------------- .../Config/Settings/LayoutSettingsLoader.cs | 2 +- mRemoteV1/UI/Forms/frmMain.cs | 23 +++++++++- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/mRemoteV1/App/Startup.cs b/mRemoteV1/App/Startup.cs index 163669376..e78376c9e 100644 --- a/mRemoteV1/App/Startup.cs +++ b/mRemoteV1/App/Startup.cs @@ -1,11 +1,4 @@ -using mRemoteNG.App.Info; -using mRemoteNG.App.Update; -using mRemoteNG.Config.Connections; -using mRemoteNG.Connection; -using mRemoteNG.Messages; -using mRemoteNG.Tools; -using mRemoteNG.UI.Forms; -using System; +using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; @@ -14,9 +7,15 @@ using System.IO; using System.Management; using System.Threading; using System.Windows.Forms; +using mRemoteNG.App.Info; +using mRemoteNG.App.Update; +using mRemoteNG.Config.Connections; using mRemoteNG.Config.Connections.Multiuser; +using mRemoteNG.Connection; +using mRemoteNG.Messages; +using mRemoteNG.Tools; using mRemoteNG.UI; -using WeifenLuo.WinFormsUI.Docking; +using mRemoteNG.UI.Forms; namespace mRemoteNG.App { @@ -47,24 +46,6 @@ namespace mRemoteNG.App DefaultConnectionInheritance.Instance.LoadFrom(Settings.Default, a=>"InhDefault"+a); } - public void SetDefaultLayout() - { - frmMain.Default.pnlDock.Visible = false; - - frmMain.Default.pnlDock.DockLeftPortion = frmMain.Default.pnlDock.Width * 0.2; - frmMain.Default.pnlDock.DockRightPortion = frmMain.Default.pnlDock.Width * 0.2; - frmMain.Default.pnlDock.DockTopPortion = frmMain.Default.pnlDock.Height * 0.25; - frmMain.Default.pnlDock.DockBottomPortion = frmMain.Default.pnlDock.Height * 0.25; - - Windows.TreePanel.Show(frmMain.Default.pnlDock, DockState.DockLeft); - Windows.ConfigPanel.Show(frmMain.Default.pnlDock); - Windows.ConfigPanel.DockTo(Windows.TreePanel.Pane, DockStyle.Bottom, -1); - - Windows.ScreenshotForm.Hide(); - - frmMain.Default.pnlDock.Visible = true; - } - private static void GetConnectionIcons() { var iPath = GeneralAppInfo.HomePath + "\\Icons\\"; @@ -116,7 +97,7 @@ namespace mRemoteNG.App { Logger.Instance.WarnFormat($"Error retrieving operating system information from WMI. {ex.Message}"); } - var osData = string.Join(" ", new string[] { osVersion, servicePack }); + var osData = string.Join(" ", osVersion, servicePack); return osData; } @@ -209,7 +190,7 @@ namespace mRemoteNG.App { if (frmMain.Default.InvokeRequired) { - frmMain.Default.Invoke(new AsyncCompletedEventHandler(GetUpdateInfoCompleted), new object[] { sender, e }); + frmMain.Default.Invoke(new AsyncCompletedEventHandler(GetUpdateInfoCompleted), sender, e); return; } @@ -223,7 +204,7 @@ namespace mRemoteNG.App } if (e.Error != null) { - throw (e.Error); + throw e.Error; } if (_appUpdate.IsUpdateAvailable()) @@ -311,7 +292,7 @@ namespace mRemoteNG.App Settings.Default.CustomConsPath = GeneralAppInfo.HomePath + "\\" + cmd[ConsParam]; return; } - else if (File.Exists(ConnectionsFileInfo.DefaultConnectionsPath + "\\" + cmd[ConsParam])) + if (File.Exists(ConnectionsFileInfo.DefaultConnectionsPath + "\\" + cmd[ConsParam])) { Settings.Default.LoadConsFromCustomLocation = true; Settings.Default.CustomConsPath = ConnectionsFileInfo.DefaultConnectionsPath + "\\" + cmd[ConsParam]; diff --git a/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs b/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs index 027cfb896..1728e8b97 100644 --- a/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs +++ b/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs @@ -48,7 +48,7 @@ namespace mRemoteNG.Config.Settings } else { - Startup.Instance.SetDefaultLayout(); + frmMain.Default.SetDefaultLayout(); } } catch (Exception ex) diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 5d632e74f..2be6e1fac 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -164,7 +164,7 @@ namespace mRemoteNG.UI.Forms ConnectionTreeWindow = Windows.TreeForm; } - private void ApplyLanguage() + private void ApplyLanguage() { mMenFile.Text = Language.strMenuFile; mMenFileNew.Text = Language.strMenuNewConnectionFile; @@ -426,6 +426,7 @@ namespace mRemoteNG.UI.Forms private void mMenFile_DropDownOpening(object sender, EventArgs e) { var selectedNodeType = ConnectionTreeWindow.SelectedNode?.GetTreeNodeType(); + // ReSharper disable once SwitchStatementMissingSomeCases switch (selectedNodeType) { case TreeNodeType.Root: @@ -733,7 +734,7 @@ namespace mRemoteNG.UI.Forms MessageBoxIcon.Question); if (msgBoxResult == DialogResult.Yes) { - Startup.Instance.SetDefaultLayout(); + Default.SetDefaultLayout(); } } @@ -1201,6 +1202,24 @@ namespace mRemoteNG.UI.Forms _systemMenu.InsertMenuItem(_systemMenu.SystemMenuHandle, 0, SystemMenu.Flags.MF_POPUP | SystemMenu.Flags.MF_BYPOSITION, popMen, Language.strSendTo); _systemMenu.InsertMenuItem(_systemMenu.SystemMenuHandle, 1, SystemMenu.Flags.MF_BYPOSITION | SystemMenu.Flags.MF_SEPARATOR, IntPtr.Zero, null); } + + public void SetDefaultLayout() + { + Default.pnlDock.Visible = false; + + Default.pnlDock.DockLeftPortion = Default.pnlDock.Width * 0.2; + Default.pnlDock.DockRightPortion = Default.pnlDock.Width * 0.2; + Default.pnlDock.DockTopPortion = Default.pnlDock.Height * 0.25; + Default.pnlDock.DockBottomPortion = Default.pnlDock.Height * 0.25; + + Windows.TreePanel.Show(Default.pnlDock, DockState.DockLeft); + Windows.ConfigPanel.Show(Default.pnlDock); + Windows.ConfigPanel.DockTo(Windows.TreePanel.Pane, DockStyle.Bottom, -1); + + Windows.ScreenshotForm.Hide(); + + Default.pnlDock.Visible = true; + } #endregion #region Events From 0aed66df471338c42f7f3a065b194069b10e5759 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 3 Jan 2017 18:17:03 -0500 Subject: [PATCH 029/106] fix build & test failure --- mRemoteNGTests/App/UpdaterTests.cs | 12 ++++++------ mRemoteV1/App/Update/UpdateInfo.cs | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index d2244e946..2967524f8 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -1,4 +1,4 @@ -using System; +//using System; using mRemoteNG.App.Info; using mRemoteNG.App.Update; using NUnit.Framework; @@ -25,11 +25,11 @@ namespace mRemoteNGTests.App Assert.That(e.Cancelled, Is.False); Assert.That(e.Error, Is.Null); var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); - Assert.That(CurrentUpdateInfo.IsValid, Is.True); - Version v; - Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); - var IsNewer = CurrentUpdateInfo.Version > v; - Assert.That(IsNewer, Is.True); + Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); + //Version v; + //Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + //var IsNewer = CurrentUpdateInfo.Version > v; + //Assert.That(IsNewer, Is.True); } } } diff --git a/mRemoteV1/App/Update/UpdateInfo.cs b/mRemoteV1/App/Update/UpdateInfo.cs index f48813257..9255ef16e 100644 --- a/mRemoteV1/App/Update/UpdateInfo.cs +++ b/mRemoteV1/App/Update/UpdateInfo.cs @@ -1,4 +1,5 @@ using System; +// ReSharper disable UnusedAutoPropertyAccessor.Local namespace mRemoteNG.App.Update { @@ -14,7 +15,8 @@ namespace mRemoteNG.App.Update #if !PORTABLE public string CertificateThumbprint { get; private set; } #endif - private string FileName { get; set; } + // ReSharper disable once MemberCanBePrivate.Global + public string FileName { get; set; } public string Checksum { get; private set; } public static UpdateInfo FromString(string input) @@ -44,7 +46,7 @@ namespace mRemoteNG.App.Update return newInfo; } - private bool CheckIfValid() + public bool CheckIfValid() { if (string.IsNullOrEmpty(Version.ToString())) return false; From 17ccf40082c9c0d45876183ee9a12c694476ad2b Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 4 Jan 2017 10:47:23 -0500 Subject: [PATCH 030/106] re-add version check & adjust CPU target for tests fixed compliler warning regarding architecture mismatch. --- mRemoteNGTests/App/UpdaterTests.cs | 10 +++++----- mRemoteNGTests/mRemoteNGTests.csproj | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index 2967524f8..4b1eb8c9c 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -1,4 +1,4 @@ -//using System; +using System; using mRemoteNG.App.Info; using mRemoteNG.App.Update; using NUnit.Framework; @@ -26,10 +26,10 @@ namespace mRemoteNGTests.App Assert.That(e.Error, Is.Null); var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); - //Version v; - //Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); - //var IsNewer = CurrentUpdateInfo.Version > v; - //Assert.That(IsNewer, Is.True); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); } } } diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 4b0192ce6..d317f3538 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -22,7 +22,7 @@ bin\Debug\ DEBUG;TRACE full - AnyCPU + x86 prompt MinimumRecommendedRules.ruleset @@ -31,7 +31,7 @@ TRACE true pdbonly - AnyCPU + x86 prompt MinimumRecommendedRules.ruleset @@ -40,7 +40,7 @@ bin\x86\Debug Portable\ TRACE;DEBUG;PORTABLE full - AnyCPU + x86 prompt MinimumRecommendedRules.ruleset @@ -49,7 +49,7 @@ TRACE;PORTABLE true pdbonly - AnyCPU + x86 prompt MinimumRecommendedRules.ruleset From 051dd2e5674dd2c4e03533ea9b0c22d1bc137947 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 4 Jan 2017 11:15:51 -0500 Subject: [PATCH 031/106] Add Beta and Dev tests --- mRemoteNGTests/App/UpdaterTests.cs | 40 ++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index 4b1eb8c9c..a4b8d5355 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -8,14 +8,6 @@ namespace mRemoteNGTests.App [TestFixture] public class UpdaterTests { - /* - [SetUp] - public void Setup() - { - GeneralAppInfo.ApplicationVersion = "1.0.0.0"; - } - */ - [Test] public void UpdateStableChannel() { @@ -31,5 +23,37 @@ namespace mRemoteNGTests.App var IsNewer = CurrentUpdateInfo.Version > v; Assert.That(IsNewer, Is.True); } + + [Test] + public void UpdateBetaChannel() + { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + var _upd = new AppUpdater(); + var e = _upd.DownloadString(UpdateChannelInfo.GetUpdateChannelInfo(UpdateChannelInfo.BETA)); + Assert.That(e.Cancelled, Is.False); + Assert.That(e.Error, Is.Null); + var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); + } + + [Test] + public void UpdateDevChannel() + { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + var _upd = new AppUpdater(); + var e = _upd.DownloadString(UpdateChannelInfo.GetUpdateChannelInfo(UpdateChannelInfo.DEV)); + Assert.That(e.Cancelled, Is.False); + Assert.That(e.Error, Is.Null); + var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); + } } } From 46dd58d26e320f594969e9583a645c8670827f75 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Thu, 5 Jan 2017 11:05:59 -0500 Subject: [PATCH 032/106] External Tool/Connection - code clean up & logging Relates to #325 --- mRemoteV1/Connection/ConnectionInitiator.cs | 26 +++++---- .../Connection/Protocol/IntegratedProgram.cs | 50 +++++++++-------- mRemoteV1/Connection/Protocol/ProtocolBase.cs | 56 +++++++++---------- mRemoteV1/Tools/ExternalTool.cs | 10 ++-- mRemoteV1/UI/Forms/frmMain.cs | 5 +- 5 files changed, 79 insertions(+), 68 deletions(-) diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs index e6cd952a4..058f22de9 100644 --- a/mRemoteV1/Connection/ConnectionInitiator.cs +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -41,7 +41,7 @@ namespace mRemoteNG.Connection } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex); } } @@ -53,7 +53,7 @@ namespace mRemoteNG.Connection } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex); } } @@ -104,7 +104,7 @@ namespace mRemoteNG.Connection } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex); } } @@ -185,11 +185,15 @@ namespace mRemoteNG.Connection { Control connectionContainer = ((ConnectionWindow)connectionForm).AddConnectionTab(connectionInfo); - if (connectionInfo.Protocol == ProtocolType.IntApp) - { - if (Runtime.GetExtAppByName(connectionInfo.ExtApp).Icon != null) - ((TabPage)connectionContainer).Icon = Runtime.GetExtAppByName(connectionInfo.ExtApp).Icon; - } + if (connectionInfo.Protocol != ProtocolType.IntApp) return connectionContainer; + + var extT = Runtime.GetExtAppByName(connectionInfo.ExtApp); + + if(extT == null) return connectionContainer; + + if (extT.Icon != null) + ((TabPage)connectionContainer).Icon = extT.Icon; + return connectionContainer; } @@ -230,7 +234,7 @@ namespace mRemoteNG.Connection } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strProtocolEventDisconnectFailed, ex.Message), true); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strProtocolEventDisconnectFailed, ex); } } @@ -249,7 +253,7 @@ namespace mRemoteNG.Connection } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnenctionCloseEventFailed + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnenctionCloseEventFailed, ex); } } @@ -273,7 +277,7 @@ namespace mRemoteNG.Connection } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionEventConnectionFailed + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionEventConnectionFailed, ex); } } } diff --git a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs index 81013aeaa..55bbde660 100644 --- a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs +++ b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs @@ -20,13 +20,12 @@ namespace mRemoteNG.Connection.Protocol #region Public Methods public override bool Initialize() { - if (InterfaceControl.Info != null) - { - _externalTool = Runtime.GetExtAppByName(Convert.ToString(InterfaceControl.Info.ExtApp)); - _externalTool.ConnectionInfo = InterfaceControl.Info; - } - - return base.Initialize(); + if (InterfaceControl.Info == null) return base.Initialize(); + + _externalTool = Runtime.GetExtAppByName(Convert.ToString(InterfaceControl.Info.ExtApp)); + _externalTool.ConnectionInfo = InterfaceControl.Info; + + return base.Initialize(); } public override bool Connect() @@ -40,20 +39,25 @@ namespace mRemoteNG.Connection.Protocol return false; } - ExternalToolArgumentParser argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo); - _process = new Process(); - - _process.StartInfo.UseShellExecute = true; - _process.StartInfo.FileName = argParser.ParseArguments(_externalTool.FileName); - _process.StartInfo.Arguments = argParser.ParseArguments(_externalTool.Arguments); - - _process.EnableRaisingEvents = true; - _process.Exited += ProcessExited; + var argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo); + _process = new Process + { + StartInfo = + { + UseShellExecute = true, + FileName = argParser.ParseArguments(_externalTool.FileName), + Arguments = argParser.ParseArguments(_externalTool.Arguments) + }, + EnableRaisingEvents = true + }; + + + _process.Exited += ProcessExited; _process.Start(); _process.WaitForInputIdle(Convert.ToInt32(Settings.Default.MaxPuttyWaitTime * 1000)); - int startTicks = Environment.TickCount; + var startTicks = Environment.TickCount; while (_handle.ToInt32() == 0 & Environment.TickCount < startTicks + (Settings.Default.MaxPuttyWaitTime * 1000)) { _process.Refresh(); @@ -69,9 +73,9 @@ namespace mRemoteNG.Connection.Protocol NativeMethods.SetParent(_handle, InterfaceControl.Handle); Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, Language.strIntAppStuff, true); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppHandle, _handle.ToString()), true); + Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppHandle, _handle), true); Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppTitle, _process.MainWindowTitle), true); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppParentHandle, InterfaceControl.Parent.Handle.ToString()), true); + Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppParentHandle, InterfaceControl.Parent.Handle), true); Resize(this, new EventArgs()); base.Connect(); @@ -96,7 +100,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppFocusFailed, ex: ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppFocusFailed, ex, logOnly: true); } } @@ -112,7 +116,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppResizeFailed, ex: ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppResizeFailed, ex, logOnly: true); } } @@ -127,7 +131,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppKillFailed, ex: ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppKillFailed, ex, logOnly: true); } try @@ -139,7 +143,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(message: Language.strIntAppDisposeFailed, ex: ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppDisposeFailed, ex, logOnly: true); } base.Close(); diff --git a/mRemoteV1/Connection/Protocol/ProtocolBase.cs b/mRemoteV1/Connection/Protocol/ProtocolBase.cs index dfb80df60..76a6cf326 100644 --- a/mRemoteV1/Connection/Protocol/ProtocolBase.cs +++ b/mRemoteV1/Connection/Protocol/ProtocolBase.cs @@ -23,12 +23,12 @@ namespace mRemoteNG.Connection.Protocol #region Public Properties #region Control - public string Name { get; set; } + private string Name { get; } protected UI.Window.ConnectionWindow ConnectionWindow { get { return _connectionWindow; } - set + private set { _connectionWindow = value; _connectionWindow.ResizeBegin += ResizeBegin; @@ -61,7 +61,7 @@ namespace mRemoteNG.Connection.Protocol Name = name; } - public ProtocolBase() + protected ProtocolBase() { } @@ -78,7 +78,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t focus Control (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Couldn't focus Control (Connection.Protocol.Base)", ex); } } @@ -112,7 +112,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t SetProps (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Couldn't SetProps (Connection.Protocol.Base)", ex); return false; } } @@ -132,7 +132,7 @@ namespace mRemoteNG.Connection.Protocol public virtual void Close() { - Thread t = new Thread(CloseBG); + var t = new Thread(CloseBG); t.SetApartmentState(ApartmentState.STA); t.IsBackground = true; t.Start(); @@ -153,31 +153,31 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, "Could not dispose control, probably form is already closed (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Couldn't dispose control, probably form is already closed (Connection.Protocol.Base)", ex); } } - - if (_interfaceControl != null) - { - try - { - if (_interfaceControl.Parent == null) return; - if (_interfaceControl.Parent.Tag != null) - { - SetTagToNothing(); - } + + if (_interfaceControl == null) return; + + try + { + if (_interfaceControl.Parent == null) return; + + if (_interfaceControl.Parent.Tag != null) + { + SetTagToNothing(); + } - DisposeInterface(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.WarningMsg, "Could not set InterfaceControl.Parent.Tag or Dispose Interface, probably form is already closed (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true); - } - } + DisposeInterface(); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("Couldn't set InterfaceControl.Parent.Tag or Dispose Interface, probably form is already closed (Connection.Protocol.Base)", ex); + } } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t Close InterfaceControl BG (Connection.Protocol.Base)" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Couldn't Close InterfaceControl BG (Connection.Protocol.Base)", ex); } } @@ -186,7 +186,7 @@ namespace mRemoteNG.Connection.Protocol { if (_interfaceControl.InvokeRequired) { - DisposeInterfaceCB s = new DisposeInterfaceCB(DisposeInterface); + var s = new DisposeInterfaceCB(DisposeInterface); _interfaceControl.Invoke(s); } else @@ -200,7 +200,7 @@ namespace mRemoteNG.Connection.Protocol { if (_interfaceControl.Parent.InvokeRequired) { - SetTagToNothingCB s = new SetTagToNothingCB(SetTagToNothing); + var s = new SetTagToNothingCB(SetTagToNothing); _interfaceControl.Parent.Invoke(s); } else @@ -214,7 +214,7 @@ namespace mRemoteNG.Connection.Protocol { if (Control.InvokeRequired) { - DisposeControlCB s = new DisposeControlCB(DisposeControl); + var s = new DisposeControlCB(DisposeControl); Control.Invoke(s); } else diff --git a/mRemoteV1/Tools/ExternalTool.cs b/mRemoteV1/Tools/ExternalTool.cs index 9e25ae3c1..5002d6cc9 100644 --- a/mRemoteV1/Tools/ExternalTool.cs +++ b/mRemoteV1/Tools/ExternalTool.cs @@ -57,7 +57,7 @@ namespace mRemoteNG.Tools private void StartExternalProcess() { - Process process = new Process(); + var process = new Process(); SetProcessProperties(process, ConnectionInfo); process.Start(); @@ -69,7 +69,7 @@ namespace mRemoteNG.Tools private void SetProcessProperties(Process process, ConnectionInfo startConnectionInfo) { - ExternalToolArgumentParser argParser = new ExternalToolArgumentParser(startConnectionInfo); + var argParser = new ExternalToolArgumentParser(startConnectionInfo); process.StartInfo.UseShellExecute = true; process.StartInfo.FileName = argParser.ParseArguments(FileName); process.StartInfo.Arguments = argParser.ParseArguments(Arguments); @@ -79,18 +79,18 @@ namespace mRemoteNG.Tools { try { - ConnectionInfo newConnectionInfo = BuildConnectionInfoForIntegratedApp(); + var newConnectionInfo = BuildConnectionInfoForIntegratedApp(); ConnectionInitiator.OpenConnection(newConnectionInfo); } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(message: "ExternalApp.StartIntegrated() failed.", ex: ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage("ExternalApp.StartIntegrated() failed.", ex, logOnly: true); } } private ConnectionInfo BuildConnectionInfoForIntegratedApp() { - ConnectionInfo newConnectionInfo = GetAppropriateInstanceOfConnectionInfo(); + var newConnectionInfo = GetAppropriateInstanceOfConnectionInfo(); SetConnectionInfoFields(newConnectionInfo); return newConnectionInfo; } diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 2be6e1fac..acf65ec96 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -384,7 +384,7 @@ namespace mRemoteNG.UI.Forms } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strErrorAddExternalToolsToToolBarFailed, ex.Message), true); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddExternalToolsToToolBarFailed, ex); } } @@ -1069,6 +1069,9 @@ namespace mRemoteNG.UI.Forms if (w?.TabController.SelectedTab == null) return; var tab = w.TabController.SelectedTab; var ifc = (InterfaceControl)tab.Tag; + + if (ifc == null) return; + ifc.Protocol.Focus(); ((ConnectionWindow) ifc.FindForm())?.RefreshInterfaceController(); } From 3c9cfbdf92b7c041750ab4fc314461f90a0f3753 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Thu, 5 Jan 2017 11:13:43 -0500 Subject: [PATCH 033/106] log exception messages only --- mRemoteV1/Messages/MessageCollector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mRemoteV1/Messages/MessageCollector.cs b/mRemoteV1/Messages/MessageCollector.cs index 5168e7810..993b4e9c0 100644 --- a/mRemoteV1/Messages/MessageCollector.cs +++ b/mRemoteV1/Messages/MessageCollector.cs @@ -116,7 +116,7 @@ namespace mRemoteNG.Messages return lvItem; } - public void AddExceptionMessage(string message, Exception ex, MessageClass msgClass = MessageClass.ErrorMsg, bool logOnly = false) + public void AddExceptionMessage(string message, Exception ex, MessageClass msgClass = MessageClass.ErrorMsg, bool logOnly = true) { AddMessage(msgClass, message + Environment.NewLine + Tools.MiscTools.GetExceptionMessageRecursive(ex), logOnly); } @@ -186,7 +186,7 @@ namespace mRemoteNG.Messages } } - delegate void AddToListCB(ListViewItem lvItem); + private delegate void AddToListCB(ListViewItem lvItem); private void AddToList(ListViewItem lvItem) { if (MCForm.lvErrorCollector.InvokeRequired) From 244d27427d937b19c582c0f762b632133cb44560 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Thu, 5 Jan 2017 14:30:24 -0500 Subject: [PATCH 034/106] update some log messages --- mRemoteV1/UI/Forms/frmMain.cs | 6 +++--- mRemoteV1/UI/Window/UpdateWindow.cs | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index acf65ec96..4219036de 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -835,7 +835,7 @@ namespace mRemoteNG.UI.Forms } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage("PopulateQuickConnectProtocolMenu() failed.", ex, MessageClass.ErrorMsg, true); + Runtime.MessageCollector.AddExceptionStackTrace("PopulateQuickConnectProtocolMenu() failed.", ex); } } @@ -864,7 +864,7 @@ namespace mRemoteNG.UI.Forms } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage("btnQuickConnect_ButtonClick() failed.", ex, MessageClass.ErrorMsg, true); + Runtime.MessageCollector.AddExceptionStackTrace("btnQuickConnect_ButtonClick() failed.", ex); } } @@ -1057,7 +1057,7 @@ namespace mRemoteNG.UI.Forms } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage("frmMain WndProc failed", ex, MessageClass.ErrorMsg, true); + Runtime.MessageCollector.AddExceptionStackTrace("frmMain WndProc failed", ex); } base.WndProc(ref m); diff --git a/mRemoteV1/UI/Window/UpdateWindow.cs b/mRemoteV1/UI/Window/UpdateWindow.cs index efdfecbc6..31027bc18 100644 --- a/mRemoteV1/UI/Window/UpdateWindow.cs +++ b/mRemoteV1/UI/Window/UpdateWindow.cs @@ -6,6 +6,7 @@ using System.Net; using System.Windows.Forms; using mRemoteNG.App; using mRemoteNG.App.Update; +using mRemoteNG.Messages; using WeifenLuo.WinFormsUI.Docking; #if !PORTABLE @@ -177,7 +178,7 @@ namespace mRemoteNG.UI.Window lblStatus.Text = Language.strUpdateCheckFailedLabel; lblStatus.ForeColor = Color.OrangeRed; - Runtime.MessageCollector.AddExceptionMessage(Language.strUpdateCheckCompleteFailed, ex); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strUpdateCheckCompleteFailed, ex); } } @@ -203,7 +204,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strUpdateGetChangeLogFailed, ex); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strUpdateGetChangeLogFailed, ex); } } @@ -226,7 +227,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strUpdateDownloadFailed, ex); + Runtime.MessageCollector.AddExceptionStackTrace(Language.strUpdateDownloadFailed, ex); } } #endregion @@ -263,8 +264,9 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strUpdateDownloadCompleteFailed, ex); - } + Runtime.MessageCollector.AddExceptionStackTrace(Language.strUpdateDownloadCompleteFailed, ex); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, ex.Message); + } } #endregion } From fd5e3e24df8754595b7778ff0a44596e2b56609a Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 6 Jan 2017 11:16:02 -0500 Subject: [PATCH 035/106] Run tests from local resources --- mRemoteNGTests/App/UpdaterTests.cs | 58 ++++++++++---- .../Properties/Resources.Designer.cs | 77 +++++++++++++++++++ mRemoteNGTests/Properties/Resources.resx | 18 +++++ .../Resources/beta-update-portable.txt | 4 + mRemoteNGTests/Resources/beta-update.txt | 5 ++ .../Resources/dev-update-portable.txt | 4 + mRemoteNGTests/Resources/dev-update.txt | 5 ++ mRemoteNGTests/Resources/update-portable.txt | 4 + mRemoteNGTests/Resources/update.txt | 5 ++ mRemoteNGTests/mRemoteNGTests.csproj | 8 ++ mRemoteV1/App/Info/UpdateChannelInfo.cs | 6 -- 11 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 mRemoteNGTests/Resources/beta-update-portable.txt create mode 100644 mRemoteNGTests/Resources/beta-update.txt create mode 100644 mRemoteNGTests/Resources/dev-update-portable.txt create mode 100644 mRemoteNGTests/Resources/dev-update.txt create mode 100644 mRemoteNGTests/Resources/update-portable.txt create mode 100644 mRemoteNGTests/Resources/update.txt diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index a4b8d5355..46febb63c 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -1,6 +1,7 @@ using System; using mRemoteNG.App.Info; using mRemoteNG.App.Update; +using mRemoteNGTests.Properties; using NUnit.Framework; namespace mRemoteNGTests.App @@ -8,15 +9,12 @@ namespace mRemoteNGTests.App [TestFixture] public class UpdaterTests { +#if !PORTABLE [Test] public void UpdateStableChannel() { GeneralAppInfo.ApplicationVersion = "1.0.0.0"; - var _upd = new AppUpdater(); - var e = _upd.DownloadString(UpdateChannelInfo.GetUpdateChannelInfo(UpdateChannelInfo.STABLE)); - Assert.That(e.Cancelled, Is.False); - Assert.That(e.Error, Is.Null); - var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + var CurrentUpdateInfo = UpdateInfo.FromString(Resources.update); Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); Version v; Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); @@ -28,11 +26,7 @@ namespace mRemoteNGTests.App public void UpdateBetaChannel() { GeneralAppInfo.ApplicationVersion = "1.0.0.0"; - var _upd = new AppUpdater(); - var e = _upd.DownloadString(UpdateChannelInfo.GetUpdateChannelInfo(UpdateChannelInfo.BETA)); - Assert.That(e.Cancelled, Is.False); - Assert.That(e.Error, Is.Null); - var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + var CurrentUpdateInfo = UpdateInfo.FromString(Resources.beta_update); Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); Version v; Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); @@ -44,16 +38,50 @@ namespace mRemoteNGTests.App public void UpdateDevChannel() { GeneralAppInfo.ApplicationVersion = "1.0.0.0"; - var _upd = new AppUpdater(); - var e = _upd.DownloadString(UpdateChannelInfo.GetUpdateChannelInfo(UpdateChannelInfo.DEV)); - Assert.That(e.Cancelled, Is.False); - Assert.That(e.Error, Is.Null); - var CurrentUpdateInfo = UpdateInfo.FromString(e.Result); + var CurrentUpdateInfo = UpdateInfo.FromString(Resources.dev_update); Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); Version v; Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); var IsNewer = CurrentUpdateInfo.Version > v; Assert.That(IsNewer, Is.True); } + +#else + [Test] + public void UpdateStablePortableChannel() + { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + var CurrentUpdateInfo = UpdateInfo.FromString(Resources.update_portable); + Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); + } + + [Test] + public void UpdateBetaPortableChannel() + { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + var CurrentUpdateInfo = UpdateInfo.FromString(Resources.beta_update_portable); + Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); + } + + [Test] + public void UpdateDevPortableChannel() + { + GeneralAppInfo.ApplicationVersion = "1.0.0.0"; + var CurrentUpdateInfo = UpdateInfo.FromString(Resources.dev_update_portable); + Assert.That(CurrentUpdateInfo.CheckIfValid(), Is.True); + Version v; + Version.TryParse(GeneralAppInfo.ApplicationVersion, out v); + var IsNewer = CurrentUpdateInfo.Version > v; + Assert.That(IsNewer, Is.True); + } +#endif } } diff --git a/mRemoteNGTests/Properties/Resources.Designer.cs b/mRemoteNGTests/Properties/Resources.Designer.cs index b47fce602..ebc09adb6 100644 --- a/mRemoteNGTests/Properties/Resources.Designer.cs +++ b/mRemoteNGTests/Properties/Resources.Designer.cs @@ -60,6 +60,32 @@ namespace mRemoteNGTests.Properties { } } + /// + /// Looks up a localized string similar to Version: 1.75.6164.27544 + ///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi + ///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT + ///CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA + ///Checksum: A1E50ACAC4CB8023527E1E7A0E682459 + ///. + /// + internal static string beta_update { + get { + return ResourceManager.GetString("beta_update", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Version: 1.75.6170.27478 + ///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip + ///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT + ///Checksum: 1C35EA199F58001BC4EBB164D8B3D11C. + /// + internal static string beta_update_portable { + get { + return ResourceManager.GetString("beta_update_portable", resourceCulture); + } + } + /// /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> ///<Connections Name="Connections" Export="False" Protected="95syzRuZ4mRxpNkZQzoyX8SDpQXLyMq3GncO8o4SyTBoYvn3TAWgn05ZEU2DrjkM" ConfVersion="2.5"> @@ -142,6 +168,32 @@ namespace mRemoteNGTests.Properties { } } + /// + /// Looks up a localized string similar to Version: 1.75.6164.27544 + ///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi + ///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT + ///CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA + ///Checksum: A1E50ACAC4CB8023527E1E7A0E682459 + ///. + /// + internal static string dev_update { + get { + return ResourceManager.GetString("dev_update", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Version: 1.75.6170.27478 + ///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip + ///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT + ///Checksum: 1C35EA199F58001BC4EBB164D8B3D11C. + /// + internal static string dev_update_portable { + get { + return ResourceManager.GetString("dev_update_portable", resourceCulture); + } + } + /// /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-16"?> ///<!-- ****************************************************************--> @@ -276,5 +328,30 @@ namespace mRemoteNGTests.Properties { return ResourceManager.GetString("test_remotedesktopconnection_rdp", resourceCulture); } } + + /// + /// Looks up a localized string similar to Version: 1.72.5065.32737 + ///dURL: http://downloads.mremoteng.org/mRemoteNG-Installer-1.72.exe + ///clURL: http://update.mremoteng.org/changes-1.72.txt + ///CertificateThumbprint: 1cbd910dbd6e77f26506e7f600736972f700673f + ///. + /// + internal static string update { + get { + return ResourceManager.GetString("update", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Version: 1.75.6170.27478 + ///dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip + ///clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT + ///Checksum: 1C35EA199F58001BC4EBB164D8B3D11C. + /// + internal static string update_portable { + get { + return ResourceManager.GetString("update_portable", resourceCulture); + } + } } } diff --git a/mRemoteNGTests/Properties/Resources.resx b/mRemoteNGTests/Properties/Resources.resx index 0fe45ee4d..902712d20 100644 --- a/mRemoteNGTests/Properties/Resources.resx +++ b/mRemoteNGTests/Properties/Resources.resx @@ -118,6 +118,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\beta-update.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\beta-update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\confCons_v2_5.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 @@ -142,6 +148,12 @@ ..\Resources\confCons_v2_6_passwordis_Password_fullencryption.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\dev-update.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\dev-update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\test_puttyConnectionManager_database.dat;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16 @@ -163,4 +175,10 @@ ..\Resources\test_remotedesktopconnection.rdp;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16 + + ..\Resources\update.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/beta-update-portable.txt b/mRemoteNGTests/Resources/beta-update-portable.txt new file mode 100644 index 000000000..86a8e3626 --- /dev/null +++ b/mRemoteNGTests/Resources/beta-update-portable.txt @@ -0,0 +1,4 @@ +Version: 1.75.6170.27478 +dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip +clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +Checksum: 1C35EA199F58001BC4EBB164D8B3D11C \ No newline at end of file diff --git a/mRemoteNGTests/Resources/beta-update.txt b/mRemoteNGTests/Resources/beta-update.txt new file mode 100644 index 000000000..1e6beeb0d --- /dev/null +++ b/mRemoteNGTests/Resources/beta-update.txt @@ -0,0 +1,5 @@ +Version: 1.75.6164.27544 +dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi +clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA +Checksum: A1E50ACAC4CB8023527E1E7A0E682459 \ No newline at end of file diff --git a/mRemoteNGTests/Resources/dev-update-portable.txt b/mRemoteNGTests/Resources/dev-update-portable.txt new file mode 100644 index 000000000..86a8e3626 --- /dev/null +++ b/mRemoteNGTests/Resources/dev-update-portable.txt @@ -0,0 +1,4 @@ +Version: 1.75.6170.27478 +dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip +clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +Checksum: 1C35EA199F58001BC4EBB164D8B3D11C \ No newline at end of file diff --git a/mRemoteNGTests/Resources/dev-update.txt b/mRemoteNGTests/Resources/dev-update.txt new file mode 100644 index 000000000..1e6beeb0d --- /dev/null +++ b/mRemoteNGTests/Resources/dev-update.txt @@ -0,0 +1,5 @@ +Version: 1.75.6164.27544 +dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi +clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA +Checksum: A1E50ACAC4CB8023527E1E7A0E682459 \ No newline at end of file diff --git a/mRemoteNGTests/Resources/update-portable.txt b/mRemoteNGTests/Resources/update-portable.txt new file mode 100644 index 000000000..86a8e3626 --- /dev/null +++ b/mRemoteNGTests/Resources/update-portable.txt @@ -0,0 +1,4 @@ +Version: 1.75.6170.27478 +dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip +clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +Checksum: 1C35EA199F58001BC4EBB164D8B3D11C \ No newline at end of file diff --git a/mRemoteNGTests/Resources/update.txt b/mRemoteNGTests/Resources/update.txt new file mode 100644 index 000000000..1e6beeb0d --- /dev/null +++ b/mRemoteNGTests/Resources/update.txt @@ -0,0 +1,5 @@ +Version: 1.75.6164.27544 +dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Installer-1.75.6179.28160.msi +clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA +Checksum: A1E50ACAC4CB8023527E1E7A0E682459 \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index d317f3538..ca6f77c02 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -208,6 +208,14 @@ + + + + + + + + diff --git a/mRemoteV1/App/Info/UpdateChannelInfo.cs b/mRemoteV1/App/Info/UpdateChannelInfo.cs index 624116ae3..1ec19d9fb 100644 --- a/mRemoteV1/App/Info/UpdateChannelInfo.cs +++ b/mRemoteV1/App/Info/UpdateChannelInfo.cs @@ -24,12 +24,6 @@ namespace mRemoteNG.App.Info return GetUpdateTxtUri(channel); } - public static Uri GetUpdateChannelInfo(string s) - { - var channel = IsValidChannel(s) ? s : STABLE; - return GetUpdateTxtUri(channel); - } - private static string GetChannelFileName(string channel) { #if PORTABLE From a88fdddecb16780e961b843974f2e6ff9d8cb5a1 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 6 Jan 2017 11:58:00 -0500 Subject: [PATCH 036/106] allow all tests to pass regardless of build type --- mRemoteNGTests/App/UpdaterTests.cs | 3 --- mRemoteNGTests/Resources/beta-update-portable.txt | 1 + mRemoteNGTests/Resources/dev-update-portable.txt | 1 + mRemoteNGTests/Resources/update-portable.txt | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mRemoteNGTests/App/UpdaterTests.cs b/mRemoteNGTests/App/UpdaterTests.cs index 46febb63c..ab81bf6ff 100644 --- a/mRemoteNGTests/App/UpdaterTests.cs +++ b/mRemoteNGTests/App/UpdaterTests.cs @@ -9,7 +9,6 @@ namespace mRemoteNGTests.App [TestFixture] public class UpdaterTests { -#if !PORTABLE [Test] public void UpdateStableChannel() { @@ -46,7 +45,6 @@ namespace mRemoteNGTests.App Assert.That(IsNewer, Is.True); } -#else [Test] public void UpdateStablePortableChannel() { @@ -82,6 +80,5 @@ namespace mRemoteNGTests.App var IsNewer = CurrentUpdateInfo.Version > v; Assert.That(IsNewer, Is.True); } -#endif } } diff --git a/mRemoteNGTests/Resources/beta-update-portable.txt b/mRemoteNGTests/Resources/beta-update-portable.txt index 86a8e3626..5d4e02f26 100644 --- a/mRemoteNGTests/Resources/beta-update-portable.txt +++ b/mRemoteNGTests/Resources/beta-update-portable.txt @@ -1,4 +1,5 @@ Version: 1.75.6170.27478 dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA Checksum: 1C35EA199F58001BC4EBB164D8B3D11C \ No newline at end of file diff --git a/mRemoteNGTests/Resources/dev-update-portable.txt b/mRemoteNGTests/Resources/dev-update-portable.txt index 86a8e3626..5d4e02f26 100644 --- a/mRemoteNGTests/Resources/dev-update-portable.txt +++ b/mRemoteNGTests/Resources/dev-update-portable.txt @@ -1,4 +1,5 @@ Version: 1.75.6170.27478 dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA Checksum: 1C35EA199F58001BC4EBB164D8B3D11C \ No newline at end of file diff --git a/mRemoteNGTests/Resources/update-portable.txt b/mRemoteNGTests/Resources/update-portable.txt index 86a8e3626..5d4e02f26 100644 --- a/mRemoteNGTests/Resources/update-portable.txt +++ b/mRemoteNGTests/Resources/update-portable.txt @@ -1,4 +1,5 @@ Version: 1.75.6170.27478 dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/v1.75Beta3/mRemoteNG-Portable-1.75.6179.28241.zip clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/v1.75Beta3/CHANGELOG.TXT +CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA Checksum: 1C35EA199F58001BC4EBB164D8B3D11C \ No newline at end of file From 256f6d8fdd5d22743516d65568d3f649a1dd2b56 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 6 Jan 2017 10:15:33 -0700 Subject: [PATCH 037/106] extracted and renamed some methods --- .../UI/Controls/ConnectionContextMenu.cs | 163 ++++++++++-------- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 2 +- 2 files changed, 95 insertions(+), 70 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index 3816d08ae..a000fd47a 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -384,7 +384,7 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveDown.Text = Language.strMoveDown; } - internal void ShowHideTreeContextMenuItems(ConnectionInfo connectionInfo) + internal void ShowHideMenuItems(ConnectionInfo connectionInfo) { if (connectionInfo == null) return; @@ -395,93 +395,118 @@ namespace mRemoteNG.UI.Controls EnableMenuItemsRecursive(Items); if (connectionInfo is RootPuttySessionsNodeInfo) { - _cMenTreeAddConnection.Enabled = false; - _cMenTreeAddFolder.Enabled = false; - _cMenTreeConnect.Enabled = false; - _cMenTreeConnectWithOptions.Enabled = false; - _cMenTreeDisconnect.Enabled = false; - _cMenTreeToolsTransferFile.Enabled = false; - _cMenTreeConnectWithOptions.Enabled = false; - _cMenTreeToolsSort.Enabled = false; - _cMenTreeToolsExternalApps.Enabled = false; - _cMenTreeDuplicate.Enabled = false; - _cMenTreeRename.Enabled = true; - _cMenTreeDelete.Enabled = false; - _cMenTreeMoveUp.Enabled = false; - _cMenTreeMoveDown.Enabled = false; + ShowHideMenuItemsForRootPuttyNode(); } else if (connectionInfo is RootNodeInfo) { - _cMenTreeConnect.Enabled = false; - _cMenTreeConnectWithOptions.Enabled = false; - _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Enabled = false; - _cMenTreeDisconnect.Enabled = false; - _cMenTreeToolsTransferFile.Enabled = false; - _cMenTreeToolsExternalApps.Enabled = false; - _cMenTreeDuplicate.Enabled = false; - _cMenTreeDelete.Enabled = false; - _cMenTreeMoveUp.Enabled = false; - _cMenTreeMoveDown.Enabled = false; + ShowHideMenuItemsForRootConnectionNode(); } else if (connectionInfo is ContainerInfo) { - _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - _cMenTreeDisconnect.Enabled = false; - - var openConnections = ((ContainerInfo)connectionInfo).Children.Sum(child => child.OpenConnections.Count); - if (openConnections > 0) - _cMenTreeDisconnect.Enabled = true; - - _cMenTreeToolsTransferFile.Enabled = false; - _cMenTreeToolsExternalApps.Enabled = false; + ShowHideMenuItemsForContainer(connectionInfo); } else if (connectionInfo is PuttySessionInfo) { - _cMenTreeAddConnection.Enabled = false; - _cMenTreeAddFolder.Enabled = false; - - if (connectionInfo.OpenConnections.Count == 0) - _cMenTreeDisconnect.Enabled = false; - - if (!(connectionInfo.Protocol == ProtocolType.SSH1 | connectionInfo.Protocol == ProtocolType.SSH2)) - _cMenTreeToolsTransferFile.Enabled = false; - - _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - _cMenTreeToolsSort.Enabled = false; - _cMenTreeDuplicate.Enabled = false; - _cMenTreeRename.Enabled = false; - _cMenTreeDelete.Enabled = false; - _cMenTreeMoveUp.Enabled = false; - _cMenTreeMoveDown.Enabled = false; + ShowHideMenuItemsForPuttyNode(connectionInfo); } else { - if (connectionInfo.OpenConnections.Count == 0) - _cMenTreeDisconnect.Enabled = false; - - if (!(connectionInfo.Protocol == ProtocolType.SSH1 | connectionInfo.Protocol == ProtocolType.SSH2)) - _cMenTreeToolsTransferFile.Enabled = false; - - if (!(connectionInfo.Protocol == ProtocolType.RDP | connectionInfo.Protocol == ProtocolType.ICA)) - { - _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - } - - if (connectionInfo.Protocol == ProtocolType.IntApp) - _cMenTreeConnectWithOptionsNoCredentials.Enabled = false; + ShowHideMenuItemsForConnectionNode(connectionInfo); } } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionStackTrace("ShowHideTreeContextMenuItems (UI.Window.ConnectionTreeWindow) failed", ex); + Runtime.MessageCollector.AddExceptionStackTrace("ShowHideMenuItems (UI.Controls.ConnectionContextMenu) failed", ex); } } + internal void ShowHideMenuItemsForRootPuttyNode() + { + _cMenTreeAddConnection.Enabled = false; + _cMenTreeAddFolder.Enabled = false; + _cMenTreeConnect.Enabled = false; + _cMenTreeConnectWithOptions.Enabled = false; + _cMenTreeDisconnect.Enabled = false; + _cMenTreeToolsTransferFile.Enabled = false; + _cMenTreeConnectWithOptions.Enabled = false; + _cMenTreeToolsSort.Enabled = false; + _cMenTreeToolsExternalApps.Enabled = false; + _cMenTreeDuplicate.Enabled = false; + _cMenTreeRename.Enabled = true; + _cMenTreeDelete.Enabled = false; + _cMenTreeMoveUp.Enabled = false; + _cMenTreeMoveDown.Enabled = false; + } + + internal void ShowHideMenuItemsForRootConnectionNode() + { + _cMenTreeConnect.Enabled = false; + _cMenTreeConnectWithOptions.Enabled = false; + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Enabled = false; + _cMenTreeDisconnect.Enabled = false; + _cMenTreeToolsTransferFile.Enabled = false; + _cMenTreeToolsExternalApps.Enabled = false; + _cMenTreeDuplicate.Enabled = false; + _cMenTreeDelete.Enabled = false; + _cMenTreeMoveUp.Enabled = false; + _cMenTreeMoveDown.Enabled = false; + } + + internal void ShowHideMenuItemsForContainer(ConnectionInfo connectionInfo) + { + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + _cMenTreeDisconnect.Enabled = false; + + var openConnections = ((ContainerInfo)connectionInfo).Children.Sum(child => child.OpenConnections.Count); + if (openConnections > 0) + _cMenTreeDisconnect.Enabled = true; + + _cMenTreeToolsTransferFile.Enabled = false; + _cMenTreeToolsExternalApps.Enabled = false; + } + + internal void ShowHideMenuItemsForPuttyNode(ConnectionInfo connectionInfo) + { + _cMenTreeAddConnection.Enabled = false; + _cMenTreeAddFolder.Enabled = false; + + if (connectionInfo.OpenConnections.Count == 0) + _cMenTreeDisconnect.Enabled = false; + + if (!(connectionInfo.Protocol == ProtocolType.SSH1 | connectionInfo.Protocol == ProtocolType.SSH2)) + _cMenTreeToolsTransferFile.Enabled = false; + + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + _cMenTreeToolsSort.Enabled = false; + _cMenTreeDuplicate.Enabled = false; + _cMenTreeRename.Enabled = false; + _cMenTreeDelete.Enabled = false; + _cMenTreeMoveUp.Enabled = false; + _cMenTreeMoveDown.Enabled = false; + } + + internal void ShowHideMenuItemsForConnectionNode(ConnectionInfo connectionInfo) + { + if (connectionInfo.OpenConnections.Count == 0) + _cMenTreeDisconnect.Enabled = false; + + if (!(connectionInfo.Protocol == ProtocolType.SSH1 | connectionInfo.Protocol == ProtocolType.SSH2)) + _cMenTreeToolsTransferFile.Enabled = false; + + if (!(connectionInfo.Protocol == ProtocolType.RDP | connectionInfo.Protocol == ProtocolType.ICA)) + { + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + } + + if (connectionInfo.Protocol == ProtocolType.IntApp) + _cMenTreeConnectWithOptionsNoCredentials.Enabled = false; + } + internal void DisableShortcutKeys() { _cMenTreeConnect.ShortcutKeys = Keys.None; diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index d726bf43d..d98216921 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -104,7 +104,7 @@ namespace mRemoteNG.UI.Window #region Tree Context Menu private void SetContextMenuEventHandlers() { - _contextMenu.Opening += (sender, args) => _contextMenu.ShowHideTreeContextMenuItems(SelectedNode); + _contextMenu.Opening += (sender, args) => _contextMenu.ShowHideMenuItems(SelectedNode); _contextMenu.ConnectClicked += (sender, args) => { var selectedNodeAsContainer = SelectedNode as ContainerInfo; From dd65c9c588e1a7c10a80e4c5824c0b9367294764 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 6 Jan 2017 12:53:56 -0500 Subject: [PATCH 038/106] update changelog --- CHANGELOG.TXT | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 05ea38240..362a81d2c 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,14 +1,40 @@ -1.75 Beta 3 (2016-12-01): - -Fixes: ------- -#289: Install fails during update process (only affects v1.75 beta 1 - v1.75 beta 2) +1.75 Beta 4 (2017-01-XX): Known Issue: ------------ Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versions. +Features/Enhancements: +---------------------- +Added Release Channels to the update check functionality allowing users to select one of 3 release channels for updates: Stable, Beta, Dev + + +Fixes: +------ +#311: Import from Active Directory does not use machine's domain by default +#211, #267: Recursive AD Import wasn't fully functional + + +General Changes: +---------------- +#325: Code clean up and additional logging for External Tools based connections +#298: Code clean up and additional logging around application startup +#291, #236: External Tools code clean up and additional logging + + + +1.75 Beta 3 (2016-12-01): + +Known Issue: +------------ +Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versions. + +Fixes: +------ +#289: Install fails during update process (only affects v1.75 beta 1 - v1.75 beta 2) + + 1.75 Beta 2 (2016-12-01): Features/Enhancements: From 6f29183b45516c448a380765a94fbff72bb20412 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Mon, 9 Jan 2017 11:32:04 -0500 Subject: [PATCH 039/106] code clean up and logging / exception handling --- mRemoteV1/App/NativeMethods.cs | 6 +++ mRemoteV1/UI/Window/ConnectionWindow.cs | 57 ++++++++++++------------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/mRemoteV1/App/NativeMethods.cs b/mRemoteV1/App/NativeMethods.cs index 6b3ed452a..41127e1ee 100644 --- a/mRemoteV1/App/NativeMethods.cs +++ b/mRemoteV1/App/NativeMethods.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; using System.Runtime.InteropServices; +#pragma warning disable 169 namespace mRemoteNG.App { @@ -326,6 +327,11 @@ namespace mRemoteNG.App /// public const int WM_ACTIVATEAPP = 0x1C; + /// + /// Sent to a window if the mouse causes the cursor to move within a window and mouse input is not captured. + /// + public const int WM_SETCURSOR = 0x20; + /// /// Sent when the cursor is in an inactive window and the user presses a mouse button. The parent window receives this message only if the child window passes it to the DefWindowProc function. /// diff --git a/mRemoteV1/UI/Window/ConnectionWindow.cs b/mRemoteV1/UI/Window/ConnectionWindow.cs index 4c8c12b3d..41972d41f 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.cs @@ -15,7 +15,6 @@ using mRemoteNG.UI.Forms; using mRemoteNG.UI.TaskDialog; using mRemoteNG.App.Info; using mRemoteNG.Container; -using mRemoteNG.Messages; using mRemoteNG.Tools; using mRemoteNG.UI.Forms.Input; using Message = System.Windows.Forms.Message; @@ -144,7 +143,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "AddConnectionTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("AddConnectionTab (UI.Window.ConnectionWindow) failed", ex); } return null; @@ -223,8 +222,8 @@ namespace mRemoteNG.UI.Window private void Connection_FormClosing(object sender, FormClosingEventArgs e) { if (!frmMain.Default.IsClosing && - ((Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.All & TabController.TabPages.Count > 0) || - (Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.Multiple & TabController.TabPages.Count > 1))) + (Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.All & TabController.TabPages.Count > 0 || + Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.Multiple & TabController.TabPages.Count > 1)) { var result = CTaskDialog.MessageBox(this, GeneralAppInfo.ProductName, string.Format(Language.strConfirmCloseConnectionPanelMainInstruction, Text), "", "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.YesNo, ESysIcons.Question, ESysIcons.Question); if (CTaskDialog.VerificationChecked) @@ -249,7 +248,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "UI.Window.Connection.Connection_FormClosing() failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("UI.Window.Connection.Connection_FormClosing() failed", ex); } } @@ -308,7 +307,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "UI.Window.Connection.CloseConnectionTab() failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("UI.Window.Connection.CloseConnectionTab() failed", ex); } UpdateSelectedConnection(); @@ -413,7 +412,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ShowHideMenuButtons (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("ShowHideMenuButtons (UI.Window.ConnectionWindow) failed", ex); } } #endregion @@ -440,7 +439,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ToggleSmartSize (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("ToggleSmartSize (UI.Window.ConnectionWindow) failed", ex); } } @@ -458,7 +457,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "TransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("TransferFile (UI.Window.ConnectionWindow) failed", ex); } } @@ -479,7 +478,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SSHTransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("SSHTransferFile (UI.Window.ConnectionWindow) failed", ex); } } @@ -493,7 +492,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "VNCTransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("VNCTransferFile (UI.Window.ConnectionWindow) failed", ex); } } @@ -509,7 +508,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ToggleViewOnly (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("ToggleViewOnly (UI.Window.ConnectionWindow) failed", ex); } } @@ -523,7 +522,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "StartChat (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("StartChat (UI.Window.ConnectionWindow) failed", ex); } } @@ -537,7 +536,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "RefreshScreen (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("RefreshScreen (UI.Window.ConnectionWindow) failed", ex); } } @@ -551,7 +550,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SendSpecialKeys (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("SendSpecialKeys (UI.Window.ConnectionWindow) failed", ex); } } @@ -565,7 +564,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ToggleFullscreen (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("ToggleFullscreen (UI.Window.ConnectionWindow) failed", ex); } } @@ -579,7 +578,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ShowPuttySettingsDialog (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("ShowPuttySettingsDialog (UI.Window.ConnectionWindow) failed", ex); } } @@ -627,7 +626,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "cmenTabExternalAppsEntry_Click failed (UI.Window.ConnectionWindow)" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("cmenTabExternalAppsEntry_Click failed (UI.Window.ConnectionWindow)", ex); } } @@ -640,7 +639,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "CloseTabMenu (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("CloseTabMenu (UI.Window.ConnectionWindow) failed", ex); } } @@ -655,7 +654,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "DuplicateTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("DuplicateTab (UI.Window.ConnectionWindow) failed", ex); } } @@ -670,7 +669,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Reconnect (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("Reconnect (UI.Window.ConnectionWindow) failed", ex); } } @@ -684,7 +683,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "RenameTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("RenameTab (UI.Window.ConnectionWindow) failed", ex); } } @@ -724,7 +723,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Couldn\'t close tab" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("Couldn't close tab", ex); } } else @@ -740,7 +739,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Couldn\'t close tab" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("Couldn't close tab", ex); } if (TabController.TabPages.Count == 0) @@ -784,7 +783,7 @@ namespace mRemoteNG.UI.Window if (elapsedTicks > SystemInformation.DoubleClickTime || !_doubleClickRectangle.Contains(MousePosition)) { _firstClickTicks = currentTicks; - _doubleClickRectangle = new Rectangle(MousePosition.X - (SystemInformation.DoubleClickSize.Width / 2), MousePosition.Y - (SystemInformation.DoubleClickSize.Height / 2), SystemInformation.DoubleClickSize.Width, SystemInformation.DoubleClickSize.Height); + _doubleClickRectangle = new Rectangle(MousePosition.X - SystemInformation.DoubleClickSize.Width / 2, MousePosition.Y - SystemInformation.DoubleClickSize.Height / 2, SystemInformation.DoubleClickSize.Width, SystemInformation.DoubleClickSize.Height); FocusInterfaceController(); } else @@ -805,7 +804,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "TabController_MouseUp (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("TabController_MouseUp (UI.Window.ConnectionWindow) failed", ex); } } @@ -818,7 +817,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "FocusIC (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("FocusIC (UI.Window.ConnectionWindow) failed", ex); } } @@ -832,7 +831,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "RefreshIC (UI.Window.Connection) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionMessage("RefreshIC (UI.Window.Connection) failed", ex); } } #endregion @@ -862,7 +861,7 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(message: "UI.Window.Connection.WndProc() failed.", ex: ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage("UI.Window.Connection.WndProc() failed.", ex); } base.WndProc(ref m); From 4c2b3738c2bf47a3a9cddd15c9cedb92705b33ac Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 10 Jan 2017 10:46:34 -0500 Subject: [PATCH 040/106] Don't attempt to connect to folders Fixes #334 --- mRemoteV1/UI/Forms/frmMain.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 4219036de..1c6176626 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -939,6 +939,7 @@ namespace mRemoteNG.UI.Forms private static void ConnectionsMenuItem_MouseUp(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; + if (((ToolStripMenuItem) sender).Tag is ContainerInfo) return; var tag = ((ToolStripMenuItem)sender).Tag as ConnectionInfo; if (tag != null) { From ac9d5dfa9554901d161abce6efb2868070a4933f Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 10 Jan 2017 10:51:34 -0500 Subject: [PATCH 041/106] code clean up --- mRemoteV1/UI/Controls/QuickConnectComboBox.cs | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/mRemoteV1/UI/Controls/QuickConnectComboBox.cs b/mRemoteV1/UI/Controls/QuickConnectComboBox.cs index 0ea734364..2161a1e67 100644 --- a/mRemoteV1/UI/Controls/QuickConnectComboBox.cs +++ b/mRemoteV1/UI/Controls/QuickConnectComboBox.cs @@ -9,7 +9,7 @@ namespace mRemoteNG.UI.Controls { public class QuickConnectComboBox : ToolStripComboBox { - private ComboBox _comboBox; + private readonly ComboBox _comboBox; private bool _ignoreEnter; public QuickConnectComboBox() @@ -53,7 +53,7 @@ namespace mRemoteNG.UI.Controls // Items can't be removed from the ComboBox while it is dropped down without possibly causing // an exception so we must close it, delete the item, and then drop it down again. When we // close it programmatically, the SelectedItem may revert to Nothing, so we must save it first. - object item = _comboBox.SelectedItem; + var item = _comboBox.SelectedItem; _comboBox.DroppedDown = false; _comboBox.Items.Remove(item); _comboBox.SelectedIndex = -1; @@ -66,29 +66,29 @@ namespace mRemoteNG.UI.Controls } } - private void ComboBox_SelectedIndexChanged(Object sender, EventArgs e) + private void ComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (!(_comboBox.SelectedItem is HistoryItem)) { - return ; + return; } - HistoryItem historyItem = (HistoryItem) _comboBox.SelectedItem; + var historyItem = (HistoryItem) _comboBox.SelectedItem; OnProtocolChanged(new ProtocolChangedEventArgs(historyItem.ConnectionInfo.Protocol)); } private static void ComboBox_DrawItem(object sender, DrawItemEventArgs e) { - ComboBox comboBox = sender as ComboBox; + var comboBox = sender as ComboBox; if (comboBox == null) { - return ; + return; } - object drawItem = comboBox.Items[e.Index]; + var drawItem = comboBox.Items[e.Index]; string drawString; if (drawItem is HistoryItem) { - HistoryItem historyItem = (HistoryItem) drawItem; + var historyItem = (HistoryItem) drawItem; drawString = historyItem.ToString(true); } else @@ -116,11 +116,8 @@ namespace mRemoteNG.UI.Controls { return false; } - if (ConnectionInfo.Protocol != other.ConnectionInfo.Protocol) - { - return false; - } - return true; + + return ConnectionInfo.Protocol == other.ConnectionInfo.Protocol; } public override string ToString() @@ -130,31 +127,25 @@ namespace mRemoteNG.UI.Controls public string ToString(bool includeProtocol) { - string port = string.Empty; + var port = string.Empty; if (ConnectionInfo.Port != ConnectionInfo.GetDefaultPort()) { port = $":{ConnectionInfo.Port}"; } - if (includeProtocol) - { - return $"{ConnectionInfo.Hostname}{port} ({ConnectionInfo.Protocol})"; - } - else - { - return $"{ConnectionInfo.Hostname}{port}"; - } + + return includeProtocol ? $"{ConnectionInfo.Hostname}{port} ({ConnectionInfo.Protocol})" : $"{ConnectionInfo.Hostname}{port}"; } } private bool Exists(HistoryItem searchItem) { - foreach (object item in _comboBox.Items) + foreach (var item in _comboBox.Items) { if (!(item is HistoryItem)) { continue; } - HistoryItem historyItem = (HistoryItem) item; + var historyItem = (HistoryItem) item; if (historyItem.Equals(searchItem)) { return true; @@ -167,7 +158,7 @@ namespace mRemoteNG.UI.Controls { try { - HistoryItem historyItem = new HistoryItem {ConnectionInfo = connectionInfo}; + var historyItem = new HistoryItem {ConnectionInfo = connectionInfo}; if (!Exists(historyItem)) { _comboBox.Items.Insert(0, historyItem); @@ -175,7 +166,7 @@ namespace mRemoteNG.UI.Controls } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strQuickConnectAddFailed, ex, Messages.MessageClass.ErrorMsg, true); + Runtime.MessageCollector.AddExceptionMessage(Language.strQuickConnectAddFailed, ex); } } @@ -209,7 +200,8 @@ namespace mRemoteNG.UI.Controls private void OnConnectRequested(ConnectRequestedEventArgs e) { - ConnectRequestedEvent?.Invoke(this, new ConnectRequestedEventArgs(e.ConnectionString)); + // TODO: Any reason to not jsut pass "e"? + ConnectRequestedEvent?.Invoke(this, new ConnectRequestedEventArgs(e.ConnectionString)); } public class ProtocolChangedEventArgs : EventArgs @@ -241,6 +233,7 @@ namespace mRemoteNG.UI.Controls private void OnProtocolChanged(ProtocolChangedEventArgs e) { + // TODO: Any reason to not jsut pass "e"? ProtocolChangedEvent?.Invoke(this, new ProtocolChangedEventArgs(e.Protocol)); } #endregion From eec17f10d5c225cf5d2e2085693d9413ff92a981 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 10 Jan 2017 10:54:03 -0500 Subject: [PATCH 042/106] update changelog --- CHANGELOG.TXT | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 362a81d2c..7648e6054 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -12,6 +12,7 @@ Added Release Channels to the update check functionality allowing users to selec Fixes: ------ +#334: Quick Connect displays warning when clicking on a folder #311: Import from Active Directory does not use machine's domain by default #211, #267: Recursive AD Import wasn't fully functional From 7e4b0635b25b657ef8bac9370bb8ede0e829859c Mon Sep 17 00:00:00 2001 From: countchappy Date: Wed, 11 Jan 2017 15:23:43 -0500 Subject: [PATCH 043/106] RDP Minutes To Idle Timeout Allows users to configure a number of minutes until the session will automatically disconnect if left idle. --- .../Serializers/DataTableDeserializer.cs | 2 ++ .../Config/Serializers/DataTableSerializer.cs | 5 +++ .../XmlConnectionNodeSerializer.cs | 3 ++ .../Serializers/XmlConnectionsDeserializer.cs | 2 ++ .../Connection/AbstractConnectionInfoData.cs | 10 ++++++ mRemoteV1/Connection/ConnectionInfo.cs | 1 + .../Connection/ConnectionInfoInheritance.cs | 11 +++++-- .../Protocol/RDP/Connection.Protocol.RDP.cs | 31 +++++++++++++---- mRemoteV1/Properties/Settings.Designer.cs | 24 ++++++++++++++ mRemoteV1/Properties/Settings.settings | 6 ++++ .../Resources/Language/Language.Designer.cs | 18 ++++++++++ mRemoteV1/Resources/Language/Language.resx | 6 ++++ mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd | 2 ++ mRemoteV1/UI/Window/ConfigWindow.cs | 33 +++++++++++++------ mRemoteV1/app.config | 6 ++++ 15 files changed, 140 insertions(+), 20 deletions(-) diff --git a/mRemoteV1/Config/Serializers/DataTableDeserializer.cs b/mRemoteV1/Config/Serializers/DataTableDeserializer.cs index 1b06134e7..bc05007e1 100644 --- a/mRemoteV1/Config/Serializers/DataTableDeserializer.cs +++ b/mRemoteV1/Config/Serializers/DataTableDeserializer.cs @@ -84,6 +84,7 @@ namespace mRemoteNG.Config.Serializers connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), (string)dataRow["RenderingEngine"]); connectionInfo.ICAEncryptionStrength = (ProtocolICA.EncryptionStrength)Enum.Parse(typeof(ProtocolICA.EncryptionStrength), (string)dataRow["ICAEncryptionStrength"]); connectionInfo.RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel)Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]); + connectionInfo.RDPMinutesToIdleTimeout = (int)dataRow["RDPMinutesToIdleTimeout"]; connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"]; connectionInfo.Colors = (ProtocolRDP.RDPColors)Enum.Parse(typeof(ProtocolRDP.RDPColors) ,(string)dataRow["Colors"]); connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Enum.Parse(typeof(ProtocolRDP.RDPResolutions), (string)dataRow["Resolution"]); @@ -153,6 +154,7 @@ namespace mRemoteNG.Config.Serializers connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"]; connectionInfo.Inheritance.ICAEncryptionStrength = (bool)dataRow["InheritICAEncryptionStrength"]; connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"]; + connectionInfo.Inheritance.RDPMinutesToIdleTimeout = (bool)dataRow["RDPMinutesToIdleTimeout"]; connectionInfo.Inheritance.LoadBalanceInfo = (bool)dataRow["InheritLoadBalanceInfo"]; connectionInfo.Inheritance.PreExtApp = (bool)dataRow["InheritPreExtApp"]; connectionInfo.Inheritance.PostExtApp = (bool)dataRow["InheritPostExtApp"]; diff --git a/mRemoteV1/Config/Serializers/DataTableSerializer.cs b/mRemoteV1/Config/Serializers/DataTableSerializer.cs index 50974069a..abc27493e 100644 --- a/mRemoteV1/Config/Serializers/DataTableSerializer.cs +++ b/mRemoteV1/Config/Serializers/DataTableSerializer.cs @@ -65,6 +65,7 @@ namespace mRemoteNG.Config.Serializers _dataTable.Columns.Add("RenderingEngine", typeof(string)); _dataTable.Columns.Add("ICAEncryptionStrength", typeof(string)); _dataTable.Columns.Add("RDPAuthenticationLevel", typeof(string)); + _dataTable.Columns.Add("RDPMinutesToIdleTimeout", typeof(int)); _dataTable.Columns.Add("Colors", typeof(string)); _dataTable.Columns.Add("Resolution", typeof(string)); _dataTable.Columns.Add("DisplayWallpaper", typeof(bool)); @@ -128,6 +129,7 @@ namespace mRemoteNG.Config.Serializers _dataTable.Columns.Add("InheritRenderingEngine", typeof(bool)); _dataTable.Columns.Add("InheritICAEncryptionStrength", typeof(bool)); _dataTable.Columns.Add("InheritRDPAuthenticationLevel", typeof(bool)); + _dataTable.Columns.Add("InheritRDPMinutesToIdleTimeout", typeof(bool)); _dataTable.Columns.Add("InheritUsername", typeof(bool)); _dataTable.Columns.Add("InheritPreExtApp", typeof(bool)); _dataTable.Columns.Add("InheritPostExtApp", typeof(bool)); @@ -200,6 +202,7 @@ namespace mRemoteNG.Config.Serializers dataRow["RenderingEngine"] = connectionInfo.RenderingEngine; dataRow["ICAEncryptionStrength"] = connectionInfo.ICAEncryptionStrength; dataRow["RDPAuthenticationLevel"] = connectionInfo.RDPAuthenticationLevel; + //dataRow["RDPMinutesToIdleTimeout"] = connectionInfo.RDPMinutesToIdleTimeout; dataRow["LoadBalanceInfo"] = connectionInfo.LoadBalanceInfo; dataRow["Colors"] = connectionInfo.Colors; dataRow["Resolution"] = connectionInfo.Resolution; @@ -270,6 +273,7 @@ namespace mRemoteNG.Config.Serializers dataRow["InheritUsername"] = connectionInfo.Inheritance.Username; dataRow["InheritICAEncryptionStrength"] = connectionInfo.Inheritance.ICAEncryptionStrength; dataRow["InheritRDPAuthenticationLevel"] = connectionInfo.Inheritance.RDPAuthenticationLevel; + //dataRow["InheritRDPMinutesToIdleTimeout"] = connectionInfo.Inheritance.RDPMinutesToIdleTimeout; dataRow["InheritLoadBalanceInfo"] = connectionInfo.Inheritance.LoadBalanceInfo; dataRow["InheritPreExtApp"] = connectionInfo.Inheritance.PreExtApp; dataRow["InheritPostExtApp"] = connectionInfo.Inheritance.PostExtApp; @@ -325,6 +329,7 @@ namespace mRemoteNG.Config.Serializers dataRow["InheritUsername"] = false; dataRow["InheritICAEncryptionStrength"] = false; dataRow["InheritRDPAuthenticationLevel"] = false; + //dataRow["InheritRDPMinutesToIdleTimeout"] = false; dataRow["InheritLoadBalanceInfo"] = false; dataRow["InheritPreExtApp"] = false; dataRow["InheritPostExtApp"] = false; diff --git a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs index fd75bad05..4cf1030a4 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs @@ -67,6 +67,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("RenderingEngine", connectionInfo.RenderingEngine)); element.Add(new XAttribute("ICAEncryptionStrength", connectionInfo.ICAEncryptionStrength)); element.Add(new XAttribute("RDPAuthenticationLevel", connectionInfo.RDPAuthenticationLevel)); + element.Add(new XAttribute("RDPMinutesToIdleTimeout", connectionInfo.RDPMinutesToIdleTimeout)); element.Add(new XAttribute("LoadBalanceInfo", connectionInfo.LoadBalanceInfo)); element.Add(new XAttribute("Colors", connectionInfo.Colors)); element.Add(new XAttribute("Resolution", connectionInfo.Resolution)); @@ -159,6 +160,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritUsername", connectionInfo.Inheritance.Username.ToString())); element.Add(new XAttribute("InheritICAEncryptionStrength", connectionInfo.Inheritance.ICAEncryptionStrength.ToString())); element.Add(new XAttribute("InheritRDPAuthenticationLevel", connectionInfo.Inheritance.RDPAuthenticationLevel.ToString())); + element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", connectionInfo.Inheritance.RDPMinutesToIdleTimeout.ToString())); element.Add(new XAttribute("InheritLoadBalanceInfo", connectionInfo.Inheritance.LoadBalanceInfo.ToString())); element.Add(new XAttribute("InheritPreExtApp", connectionInfo.Inheritance.PreExtApp.ToString())); element.Add(new XAttribute("InheritPostExtApp", connectionInfo.Inheritance.PostExtApp.ToString())); @@ -214,6 +216,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritUsername", false.ToString())); element.Add(new XAttribute("InheritICAEncryptionStrength", false.ToString())); element.Add(new XAttribute("InheritRDPAuthenticationLevel", false.ToString())); + element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", false.ToString())); element.Add(new XAttribute("InheritLoadBalanceInfo", false.ToString())); element.Add(new XAttribute("InheritPreExtApp", false.ToString())); element.Add(new XAttribute("InheritPostExtApp", false.ToString())); diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index 3fd113c93..8b7965ee1 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -487,6 +487,8 @@ namespace mRemoteNG.Config.Serializers { connectionInfo.SoundQuality = (ProtocolRDP.RDPSoundQuality)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPSoundQuality), Convert.ToString(xmlnode.Attributes["SoundQuality"].Value)); connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); + connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"].Value); + connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"].Value); } } catch (Exception ex) diff --git a/mRemoteV1/Connection/AbstractConnectionInfoData.cs b/mRemoteV1/Connection/AbstractConnectionInfoData.cs index a10a9d8e1..83197c815 100644 --- a/mRemoteV1/Connection/AbstractConnectionInfoData.cs +++ b/mRemoteV1/Connection/AbstractConnectionInfoData.cs @@ -30,6 +30,7 @@ namespace mRemoteNG.Connection private ProtocolICA.EncryptionStrength _icaEncryption; private bool _useConsoleSession; private ProtocolRDP.AuthenticationLevel _rdpAuthenticationLevel; + private int _rdpMinutesToIdleTimeout; private string _loadBalanceInfo; private HTTPBase.RenderingEngine _renderingEngine; private bool _useCredSsp; @@ -225,6 +226,15 @@ namespace mRemoteNG.Connection set { SetField(ref _rdpAuthenticationLevel, value, "RDPAuthenticationLevel"); } } + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameMinutesToIdleTimeout"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionMinutesToIdleTimeout")] + public virtual int RDPMinutesToIdleTimeout + { + get { return GetPropertyValue("RDPMinutesToIdleTimeout", _rdpMinutesToIdleTimeout); } + set { SetField(ref _rdpMinutesToIdleTimeout, value, "RDPMinutesToIdleTimeout"); } + } + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), LocalizedAttributes.LocalizedDisplayName("strPropertyNameLoadBalanceInfo"), LocalizedAttributes.LocalizedDescription("strPropertyDescriptionLoadBalanceInfo")] diff --git a/mRemoteV1/Connection/ConnectionInfo.cs b/mRemoteV1/Connection/ConnectionInfo.cs index 19b388e8c..acc3baf67 100644 --- a/mRemoteV1/Connection/ConnectionInfo.cs +++ b/mRemoteV1/Connection/ConnectionInfo.cs @@ -248,6 +248,7 @@ namespace mRemoteNG.Connection ICAEncryptionStrength = (ProtocolICA.EncryptionStrength) Enum.Parse(typeof(ProtocolICA.EncryptionStrength), Settings.Default.ConDefaultICAEncryptionStrength); UseConsoleSession = Settings.Default.ConDefaultUseConsoleSession; RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel) Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), Settings.Default.ConDefaultRDPAuthenticationLevel); + RDPMinutesToIdleTimeout = Settings.Default.ConDefaultRDPMinutesToIdleTimeout; LoadBalanceInfo = Settings.Default.ConDefaultLoadBalanceInfo; RenderingEngine = (HTTPBase.RenderingEngine) Enum.Parse(typeof(HTTPBase.RenderingEngine), Settings.Default.ConDefaultRenderingEngine); UseCredSsp = Settings.Default.ConDefaultUseCredSsp; diff --git a/mRemoteV1/Connection/ConnectionInfoInheritance.cs b/mRemoteV1/Connection/ConnectionInfoInheritance.cs index fb1862238..3ed97778c 100644 --- a/mRemoteV1/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteV1/Connection/ConnectionInfoInheritance.cs @@ -83,9 +83,14 @@ namespace mRemoteNG.Connection [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameAuthenticationLevel"), LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionAuthenticationLevel"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPAuthenticationLevel {get; set;} - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPAuthenticationLevel {get; set; } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), + LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyName"), + LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescription"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPMinutesToIdleTimeout { get; set; } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameLoadBalanceInfo"), LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionLoadBalanceInfo"), TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool LoadBalanceInfo {get; set;} diff --git a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs index ebdc551c9..72e3c1a6b 100644 --- a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs +++ b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs @@ -129,9 +129,19 @@ namespace mRemoteNG.Connection.Protocol.RDP SetCredentials(); SetResolution(); _rdpClient.FullScreenTitle = _connectionInfo.Name; - - //not user changeable - _rdpClient.AdvancedSettings2.GrabFocusOnConnect = true; + + // Set the timeout to the default (zero) if it is out of bounds. + if (_connectionInfo.RDPMinutesToIdleTimeout < 0 || _connectionInfo.RDPMinutesToIdleTimeout > 240) + { + _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = Settings.Default.ConDefaultRDPMinutesToIdleTimeout; + } + else + { + _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = _connectionInfo.RDPMinutesToIdleTimeout; + } + + //not user changeable + _rdpClient.AdvancedSettings2.GrabFocusOnConnect = true; _rdpClient.AdvancedSettings3.EnableAutoReconnect = true; _rdpClient.AdvancedSettings3.MaxReconnectAttempts = Settings.Default.RdpReconnectionCount; _rdpClient.AdvancedSettings2.keepAliveInterval = 60000; //in milliseconds (10,000 = 10 seconds) @@ -176,8 +186,8 @@ namespace mRemoteNG.Connection.Protocol.RDP { _loginComplete = false; SetEventHandlers(); - - try + + try { _rdpClient.Connect(); base.Connect(); @@ -616,7 +626,8 @@ namespace mRemoteNG.Connection.Protocol.RDP _rdpClient.OnFatalError += RDPEvent_OnFatalError; _rdpClient.OnDisconnected += RDPEvent_OnDisconnected; _rdpClient.OnLeaveFullScreenMode += RDPEvent_OnLeaveFullscreenMode; - } + _rdpClient.OnIdleTimeoutNotification += RDPEvent_OnIdleTimeoutNotification; + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace(Language.strRdpSetEventHandlersFailed, ex); @@ -625,7 +636,13 @@ namespace mRemoteNG.Connection.Protocol.RDP #endregion #region Private Events & Handlers - private void RDPEvent_OnFatalError(int errorCode) + private void RDPEvent_OnIdleTimeoutNotification() + { + Close(); //Simply close the RDP Session if the idle timeout has been triggered. + } + + + private void RDPEvent_OnFatalError(int errorCode) { Event_ErrorOccured(this, Convert.ToString(errorCode)); } diff --git a/mRemoteV1/Properties/Settings.Designer.cs b/mRemoteV1/Properties/Settings.Designer.cs index ed31fe7c8..e73bb2477 100644 --- a/mRemoteV1/Properties/Settings.Designer.cs +++ b/mRemoteV1/Properties/Settings.Designer.cs @@ -2350,5 +2350,29 @@ namespace mRemoteNG { this["InhDefaultSoundQuality"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public int ConDefaultRDPMinutesToIdleTimeout { + get { + return ((int)(this["ConDefaultRDPMinutesToIdleTimeout"])); + } + set { + this["ConDefaultRDPMinutesToIdleTimeout"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool InhDefaultRDPMinutesToIdleTimeout { + get { + return ((bool)(this["InhDefaultRDPMinutesToIdleTimeout"])); + } + set { + this["InhDefaultRDPMinutesToIdleTimeout"] = value; + } + } } } diff --git a/mRemoteV1/Properties/Settings.settings b/mRemoteV1/Properties/Settings.settings index 477a07aed..6be7293a7 100644 --- a/mRemoteV1/Properties/Settings.settings +++ b/mRemoteV1/Properties/Settings.settings @@ -584,5 +584,11 @@ False + + 0 + + + False + \ No newline at end of file diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 899f6bc5e..2ef6ba792 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -4018,6 +4018,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to The number of minutes for the RDP session to sit idle before automatically disconnecting. + /// + internal static string strPropertyDescriptionMinutesToIdleTimeout { + get { + return ResourceManager.GetString("strPropertyDescriptionMinutesToIdleTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to This is the name that will be displayed in the connections tree.. /// @@ -4495,6 +4504,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Minutes to Idle. + /// + internal static string strPropertyNameMinutesToIdleTimeout { + get { + return ResourceManager.GetString("strPropertyNameMinutesToIdleTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Name. /// diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index 34cff4195..6de521f45 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2421,4 +2421,10 @@ mRemoteNG will now quit and begin with the installation. Download + + The number of minutes for the RDP session to sit idle before automatically disconnecting + + + Minutes to Idle + \ No newline at end of file diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd index a3fbb4c83..876a72856 100644 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd +++ b/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd @@ -46,6 +46,7 @@ + @@ -114,6 +115,7 @@ + diff --git a/mRemoteV1/UI/Window/ConfigWindow.cs b/mRemoteV1/UI/Window/ConfigWindow.cs index ff947b279..8f685a5fd 100644 --- a/mRemoteV1/UI/Window/ConfigWindow.cs +++ b/mRemoteV1/UI/Window/ConfigWindow.cs @@ -812,6 +812,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); + strHide.Add("RDPMinutesToIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -910,7 +911,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -953,7 +955,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -995,7 +998,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1038,7 +1042,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1082,7 +1087,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1126,7 +1132,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1170,7 +1177,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1212,7 +1220,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1250,7 +1259,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1291,7 +1301,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUseConnectionCredentials"); strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); - strHide.Add("LoadBalanceInfo"); + strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); strHide.Add("RedirectPorts"); @@ -1372,6 +1383,8 @@ namespace mRemoteNG.UI.Window strHide.Add("ICAEncryptionStrength"); if (conI.Inheritance.RDPAuthenticationLevel) strHide.Add("RDPAuthenticationLevel"); + if (conI.Inheritance.RDPMinutesToIdleTimeout) + strHide.Add("RDPMinutesToIdleTimeout"); if (conI.Inheritance.LoadBalanceInfo) strHide.Add("LoadBalanceInfo"); if (conI.Inheritance.Username) diff --git a/mRemoteV1/app.config b/mRemoteV1/app.config index 8fb7debe4..7a30d0434 100644 --- a/mRemoteV1/app.config +++ b/mRemoteV1/app.config @@ -604,6 +604,12 @@ False + + 0 + + + False + From 10d152342f7eb2efd1e2f1ae94205a0cb55b68c1 Mon Sep 17 00:00:00 2001 From: countchappy Date: Wed, 11 Jan 2017 16:44:53 -0500 Subject: [PATCH 044/106] RDP Minutes to Idle Timeout - Update 1 Fixed some language file stuff. --- mRemoteV1/Connection/ConnectionInfoInheritance.cs | 4 ++-- mRemoteV1/Resources/Language/Language.Designer.cs | 2 +- mRemoteV1/Resources/Language/Language.resx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mRemoteV1/Connection/ConnectionInfoInheritance.cs b/mRemoteV1/Connection/ConnectionInfoInheritance.cs index 3ed97778c..49ab3c3cd 100644 --- a/mRemoteV1/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteV1/Connection/ConnectionInfoInheritance.cs @@ -86,8 +86,8 @@ namespace mRemoteNG.Connection TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPAuthenticationLevel {get; set; } [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), - LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyName"), - LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescription"), + LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameRDPMinutesToIdleTimeout"), + LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionRDPMinutesToIdleTimeout"), TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPMinutesToIdleTimeout { get; set; } [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 2ef6ba792..9d48fdb97 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -4019,7 +4019,7 @@ namespace mRemoteNG { } /// - /// Looks up a localized string similar to The number of minutes for the RDP session to sit idle before automatically disconnecting. + /// Looks up a localized string similar to The number of minutes for the RDP session to sit idle before automatically disconnecting (for no limit use 0). /// internal static string strPropertyDescriptionMinutesToIdleTimeout { get { diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index 6de521f45..43c27f006 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2422,7 +2422,7 @@ mRemoteNG will now quit and begin with the installation. Download - The number of minutes for the RDP session to sit idle before automatically disconnecting + The number of minutes for the RDP session to sit idle before automatically disconnecting (for no limit use 0) Minutes to Idle From e92a76f95b731c8cfa7e27b09adc35a552923418 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 11 Jan 2017 16:56:14 -0500 Subject: [PATCH 045/106] "return ;" annoyed me... And I did a find and replace in the solution instead of the one file I was working on... So I'm going with it... --- mRemoteV1/App/Export.cs | 2 +- .../Config/Connections/ConnectionsSaver.cs | 2 +- .../Putty/PuttySessionsXmingProvider.cs | 8 ++--- .../Http/Connection.Protocol.HTTPBase.cs | 2 +- .../Protocol/ICA/Connection.Protocol.ICA.cs | 2 +- mRemoteV1/Connection/PuttySessionInfo.cs | 2 +- mRemoteV1/Themes/ThemeInfo.cs | 36 +++++++++---------- mRemoteV1/Themes/ThemeManager.cs | 2 +- mRemoteV1/Tools/MiscTools.cs | 2 +- mRemoteV1/Tools/ProcessController.cs | 2 +- mRemoteV1/UI/Controls/ToolStripSplitButton.cs | 2 +- mRemoteV1/UI/Forms/ExportForm.cs | 2 +- mRemoteV1/UI/Window/PortScanWindow.cs | 4 +-- 13 files changed, 34 insertions(+), 34 deletions(-) diff --git a/mRemoteV1/App/Export.cs b/mRemoteV1/App/Export.cs index 15af5ac03..ef3fbfa33 100644 --- a/mRemoteV1/App/Export.cs +++ b/mRemoteV1/App/Export.cs @@ -34,7 +34,7 @@ namespace mRemoteNG.App } if (exportForm.ShowDialog(frmMain.Default) != DialogResult.OK) - return ; + return; ConnectionInfo exportTarget; switch (exportForm.Scope) diff --git a/mRemoteV1/Config/Connections/ConnectionsSaver.cs b/mRemoteV1/Config/Connections/ConnectionsSaver.cs index 6b4339e62..0059ca1b4 100644 --- a/mRemoteV1/Config/Connections/ConnectionsSaver.cs +++ b/mRemoteV1/Config/Connections/ConnectionsSaver.cs @@ -89,7 +89,7 @@ namespace mRemoteNG.Config.Connections if (!VerifyDatabaseVersion(sqlConnector)) { Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorConnectionListSaveFailed); - return ; + return; } var rootTreeNode = Runtime.ConnectionTreeModel.RootNodes.OfType().First(); diff --git a/mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs b/mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs index 98366a945..5801a57bf 100644 --- a/mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs +++ b/mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs @@ -130,7 +130,7 @@ namespace mRemoteNG.Config.Putty if (_eventWatcher != null) { - return ; + return; } try @@ -158,7 +158,7 @@ namespace mRemoteNG.Config.Putty if (_eventWatcher == null) { - return ; + return; } _eventWatcher.EnableRaisingEvents = false; _eventWatcher.Dispose(); @@ -231,7 +231,7 @@ namespace mRemoteNG.Config.Putty { if (!File.Exists(_puttyConfFile)) { - return ; + return; } using (var streamReader = new StreamReader(_puttyConfFile)) { @@ -299,7 +299,7 @@ namespace mRemoteNG.Config.Putty { if (!File.Exists(_sessionFile)) { - return ; + return; } using (var streamReader = new StreamReader(_sessionFile)) { diff --git a/mRemoteV1/Connection/Protocol/Http/Connection.Protocol.HTTPBase.cs b/mRemoteV1/Connection/Protocol/Http/Connection.Protocol.HTTPBase.cs index 429b96d03..f66f94445 100644 --- a/mRemoteV1/Connection/Protocol/Http/Connection.Protocol.HTTPBase.cs +++ b/mRemoteV1/Connection/Protocol/Http/Connection.Protocol.HTTPBase.cs @@ -172,7 +172,7 @@ namespace mRemoteNG.Connection.Protocol.Http WebBrowser objWebBrowser = wBrowser as WebBrowser; if (objWebBrowser == null) { - return ; + return; } // This can only be set once the WebBrowser control is shown, it will throw a COM exception otherwise. diff --git a/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs b/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs index 568d8e4fb..00f918b68 100644 --- a/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs +++ b/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs @@ -137,7 +137,7 @@ namespace mRemoteNG.Connection.Protocol.ICA { if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) == (int)ConnectionInfo.Force.NoCredentials) { - return ; + return; } string _user = _Info.Username; diff --git a/mRemoteV1/Connection/PuttySessionInfo.cs b/mRemoteV1/Connection/PuttySessionInfo.cs index ce0470fe6..8edce2a38 100644 --- a/mRemoteV1/Connection/PuttySessionInfo.cs +++ b/mRemoteV1/Connection/PuttySessionInfo.cs @@ -75,7 +75,7 @@ namespace mRemoteNG.Connection var puttyProcess = new PuttyProcessController(); if (!puttyProcess.Start()) { - return ; + return; } if (puttyProcess.SelectListBoxItem(PuttySession)) { diff --git a/mRemoteV1/Themes/ThemeInfo.cs b/mRemoteV1/Themes/ThemeInfo.cs index 41ae1f189..fc72f5801 100644 --- a/mRemoteV1/Themes/ThemeInfo.cs +++ b/mRemoteV1/Themes/ThemeInfo.cs @@ -117,7 +117,7 @@ namespace mRemoteNG.Themes { if (_name == value) { - return ; + return; } _name = value; NotifyPropertyChanged("Name"); @@ -135,7 +135,7 @@ namespace mRemoteNG.Themes { if (_windowBackgroundColor == value) { - return ; + return; } _windowBackgroundColor = value; NotifyPropertyChanged("WindowBackgroundColor"); @@ -152,7 +152,7 @@ namespace mRemoteNG.Themes { if (_menuBackgroundColor == value) { - return ; + return; } _menuBackgroundColor = value; NotifyPropertyChanged("MenuBackgroundColor"); @@ -169,7 +169,7 @@ namespace mRemoteNG.Themes { if (_menuTextColor == value) { - return ; + return; } _menuTextColor = value; NotifyPropertyChanged("MenuTextColor"); @@ -187,7 +187,7 @@ namespace mRemoteNG.Themes { if (_toolbarBackgroundColor == value || value.A < 255) { - return ; + return; } _toolbarBackgroundColor = value; NotifyPropertyChanged("ToolbarBackgroundColor"); @@ -204,7 +204,7 @@ namespace mRemoteNG.Themes { if (_toolbarTextColor == value) { - return ; + return; } _toolbarTextColor = value; NotifyPropertyChanged("ToolbarTextColor"); @@ -223,7 +223,7 @@ namespace mRemoteNG.Themes { if (_connectionsPanelBackgroundColor == value || value.A < 255) { - return ; + return; } _connectionsPanelBackgroundColor = value; NotifyPropertyChanged("ConnectionsPanelBackgroundColor"); @@ -240,7 +240,7 @@ namespace mRemoteNG.Themes { if (_connectionsPanelTextColor == value) { - return ; + return; } _connectionsPanelTextColor = value; NotifyPropertyChanged("ConnectionsPanelTextColor"); @@ -260,7 +260,7 @@ namespace mRemoteNG.Themes { if (_connectionsPanelTreeLineColor == value) { - return ; + return; } _connectionsPanelTreeLineColor = value; NotifyPropertyChanged("ConnectionsPanelTreeLineColor"); @@ -280,7 +280,7 @@ namespace mRemoteNG.Themes { if (_searchBoxBackgroundColor == value || value.A < 255) { - return ; + return; } _searchBoxBackgroundColor = value; NotifyPropertyChanged("SearchBoxBackgroundColor"); @@ -300,7 +300,7 @@ namespace mRemoteNG.Themes { if (_searchBoxTextPromptColor == value) { - return ; + return; } _searchBoxTextPromptColor = value; NotifyPropertyChanged("SearchBoxTextPromptColor"); @@ -320,7 +320,7 @@ namespace mRemoteNG.Themes { if (_searchBoxTextColor == value) { - return ; + return; } _searchBoxTextColor = value; NotifyPropertyChanged("SearchBoxTextColor"); @@ -342,7 +342,7 @@ namespace mRemoteNG.Themes { if (_configPanelBackgroundColor == value || value.A < 255) { - return ; + return; } _configPanelBackgroundColor = value; NotifyPropertyChanged("ConfigPanelBackgroundColor"); @@ -362,7 +362,7 @@ namespace mRemoteNG.Themes { if (_configPanelTextColor == value) { - return ; + return; } _configPanelTextColor = value; NotifyPropertyChanged("ConfigPanelTextColor"); @@ -382,7 +382,7 @@ namespace mRemoteNG.Themes { if (_configPanelCategoryTextColor == value) { - return ; + return; } _configPanelCategoryTextColor = value; NotifyPropertyChanged("ConfigPanelCategoryTextColor"); @@ -402,7 +402,7 @@ namespace mRemoteNG.Themes { if (_configPanelHelpBackgroundColor == value || value.A < 255) { - return ; + return; } _configPanelHelpBackgroundColor = value; NotifyPropertyChanged("ConfigPanelHelpBackgroundColor"); @@ -422,7 +422,7 @@ namespace mRemoteNG.Themes { if (_configPanelHelpTextColor == value) { - return ; + return; } _configPanelHelpTextColor = value; NotifyPropertyChanged("ConfigPanelHelpTextColor"); @@ -442,7 +442,7 @@ namespace mRemoteNG.Themes { if (_configPanelGridLineColor == value) { - return ; + return; } _configPanelGridLineColor = value; NotifyPropertyChanged("ConfigPanelGridLineColor"); diff --git a/mRemoteV1/Themes/ThemeManager.cs b/mRemoteV1/Themes/ThemeManager.cs index 4516c8874..6584f67f8 100644 --- a/mRemoteV1/Themes/ThemeManager.cs +++ b/mRemoteV1/Themes/ThemeManager.cs @@ -81,7 +81,7 @@ namespace mRemoteNG.Themes { if (e.PropertyName == "Name") { - return ; + return; } ThemeChangedEvent?.Invoke(); } diff --git a/mRemoteV1/Tools/MiscTools.cs b/mRemoteV1/Tools/MiscTools.cs index c67b67e33..2c286596b 100644 --- a/mRemoteV1/Tools/MiscTools.cs +++ b/mRemoteV1/Tools/MiscTools.cs @@ -244,7 +244,7 @@ namespace mRemoteNG.Tools { if (_value == value) { - return ; + return; } if (!_value) { diff --git a/mRemoteV1/Tools/ProcessController.cs b/mRemoteV1/Tools/ProcessController.cs index 13c11145b..625b73fe0 100644 --- a/mRemoteV1/Tools/ProcessController.cs +++ b/mRemoteV1/Tools/ProcessController.cs @@ -83,7 +83,7 @@ namespace mRemoteNG.Tools public void WaitForExit() { if (Process == null || Process.HasExited) - return ; + return; Process.WaitForExit(); } #endregion diff --git a/mRemoteV1/UI/Controls/ToolStripSplitButton.cs b/mRemoteV1/UI/Controls/ToolStripSplitButton.cs index 033b448f9..ed7090851 100644 --- a/mRemoteV1/UI/Controls/ToolStripSplitButton.cs +++ b/mRemoteV1/UI/Controls/ToolStripSplitButton.cs @@ -22,7 +22,7 @@ namespace mRemoteNG.UI.Controls { if (e.CloseReason != ToolStripDropDownCloseReason.AppClicked) { - return ; + return; } Rectangle dropDownButtonBoundsClient = DropDownButtonBounds; // Relative to the ToolStripSplitButton diff --git a/mRemoteV1/UI/Forms/ExportForm.cs b/mRemoteV1/UI/Forms/ExportForm.cs index 652124597..a7a74c3b2 100644 --- a/mRemoteV1/UI/Forms/ExportForm.cs +++ b/mRemoteV1/UI/Forms/ExportForm.cs @@ -205,7 +205,7 @@ namespace mRemoteNG.UI.Forms SelectFileTypeBasedOnSaveFormat(saveFileDialog); if (saveFileDialog.ShowDialog(this) != DialogResult.OK) - return ; + return; txtFileName.Text = saveFileDialog.FileName; } diff --git a/mRemoteV1/UI/Window/PortScanWindow.cs b/mRemoteV1/UI/Window/PortScanWindow.cs index 073bebb5c..10ea61c4d 100644 --- a/mRemoteV1/UI/Window/PortScanWindow.cs +++ b/mRemoteV1/UI/Window/PortScanWindow.cs @@ -211,7 +211,7 @@ namespace mRemoteNG.UI.Window if (InvokeRequired) { Invoke(new PortScannerHostScannedDelegate(PortScanner_HostScanned), new object[] {host, scannedCount, totalCount}); - return ; + return; } Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Host scanned " + host.HostIp, true); @@ -233,7 +233,7 @@ namespace mRemoteNG.UI.Window if (InvokeRequired) { Invoke(new PortScannerScanComplete(PortScanner_ScanComplete), new object[] {hosts}); - return ; + return; } Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strPortScanComplete); From b9cdd0996dfdcf0bde47b3d7a8c0d7b1612e853a Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 11 Jan 2017 14:58:29 -0700 Subject: [PATCH 046/106] moved click handling responsibility out of the connectiontreewindow and into the context menu class --- .../UI/Controls/ConnectionContextMenu.cs | 187 ++++++++---------- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 92 +-------- 2 files changed, 88 insertions(+), 191 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index a000fd47a..726ef1e90 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Linq; using System.Windows.Forms; using mRemoteNG.App; @@ -12,7 +13,7 @@ using mRemoteNG.Tree.Root; namespace mRemoteNG.UI.Controls { - internal sealed class ConnectionContextMenu : ContextMenuStrip + public sealed class ConnectionContextMenu : ContextMenuStrip { private ToolStripMenuItem _cMenTreeAddConnection; private ToolStripMenuItem _cMenTreeAddFolder; @@ -44,14 +45,20 @@ namespace mRemoteNG.UI.Controls private ToolStripMenuItem _cMenTreeImportFile; private ToolStripMenuItem _cMenTreeImportActiveDirectory; private ToolStripMenuItem _cMenTreeImportPortScan; + private readonly ConnectionTree _connectionTree; - public ConnectionContextMenu() + public ConnectionContextMenu(ConnectionTree connectionTree) { + _connectionTree = connectionTree; InitializeComponent(); ApplyLanguage(); EnableShortcutKeys(); - Opening += (sender, args) => AddExternalApps(); + Opening += (sender, args) => + { + AddExternalApps(); + ShowHideMenuItems(); + }; } private void InitializeComponent() @@ -384,34 +391,34 @@ namespace mRemoteNG.UI.Controls _cMenTreeMoveDown.Text = Language.strMoveDown; } - internal void ShowHideMenuItems(ConnectionInfo connectionInfo) + internal void ShowHideMenuItems() { - if (connectionInfo == null) + if (_connectionTree.SelectedNode == null) return; try { Enabled = true; EnableMenuItemsRecursive(Items); - if (connectionInfo is RootPuttySessionsNodeInfo) + if (_connectionTree.SelectedNode is RootPuttySessionsNodeInfo) { ShowHideMenuItemsForRootPuttyNode(); } - else if (connectionInfo is RootNodeInfo) + else if (_connectionTree.SelectedNode is RootNodeInfo) { ShowHideMenuItemsForRootConnectionNode(); } - else if (connectionInfo is ContainerInfo) + else if (_connectionTree.SelectedNode is ContainerInfo) { - ShowHideMenuItemsForContainer(connectionInfo); + ShowHideMenuItemsForContainer(_connectionTree.SelectedNode); } - else if (connectionInfo is PuttySessionInfo) + else if (_connectionTree.SelectedNode is PuttySessionInfo) { - ShowHideMenuItemsForPuttyNode(connectionInfo); + ShowHideMenuItemsForPuttyNode(_connectionTree.SelectedNode); } else { - ShowHideMenuItemsForConnectionNode(connectionInfo); + ShowHideMenuItemsForConnectionNode(_connectionTree.SelectedNode); } } catch (Exception ex) @@ -578,183 +585,159 @@ namespace mRemoteNG.UI.Controls _cMenTreeToolsExternalApps.DropDownItems.Clear(); } - #region Events - public event EventHandler ConnectClicked; - + #region Click handlers private void OnConnectClicked(object sender, EventArgs e) { - var handler = ConnectClicked; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.DoNotJump); } - public event EventHandler ConnectToConsoleSessionClicked; - private void OnConnectToConsoleSessionClicked(object sender, EventArgs e) { - var handler = ConnectToConsoleSessionClicked; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); } - - public event EventHandler DontConnectToConsoleSessionClicked; private void OnDontConnectToConsoleSessionClicked(object sender, EventArgs e) { - var handler = DontConnectToConsoleSessionClicked; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); } - public event EventHandler ConnectInFullscreenClicked; - private void OnConnectInFullscreenClicked(object sender, EventArgs e) { - var handler = ConnectInFullscreenClicked; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); } - public event EventHandler ConnectWithNoCredentialsClick; - private void OnConnectWithNoCredentialsClick(object sender, EventArgs e) { - var handler = ConnectWithNoCredentialsClick; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.NoCredentials); + else + ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.NoCredentials); } - public event EventHandler ChoosePanelBeforeConnectingClicked; - private void OnChoosePanelBeforeConnectingClicked(object sender, EventArgs e) { - var handler = ChoosePanelBeforeConnectingClicked; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); } - - public event EventHandler DisconnectClicked; - private void OnDisconnectClicked(object sender, EventArgs e) { - var handler = DisconnectClicked; - handler?.Invoke(this, e); + _connectionTree.DisconnectConnection(_connectionTree.SelectedNode); } - public event EventHandler TransferFileClicked; - private void OnTransferFileClicked(object sender, EventArgs e) { - var handler = TransferFileClicked; - handler?.Invoke(this, e); + _connectionTree.SshTransferFile(); } - public event EventHandler DuplicateClicked; - private void OnDuplicateClicked(object sender, EventArgs e) { - var handler = DuplicateClicked; - handler?.Invoke(this, e); + _connectionTree.DuplicateSelectedNode(); } - public event EventHandler RenameClicked; - private void OnRenameClicked(object sender, EventArgs e) { - var handler = RenameClicked; - handler?.Invoke(this, e); + _connectionTree.RenameSelectedNode(); } - public event EventHandler DeleteClicked; - private void OnDeleteClicked(object sender, EventArgs e) { - var handler = DeleteClicked; - handler?.Invoke(this, e); + _connectionTree.DeleteSelectedNode(); } - public event EventHandler ImportFileClicked; - private void OnImportFileClicked(object sender, EventArgs e) { - var handler = ImportFileClicked; - handler?.Invoke(this, e); + var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo ?? _connectionTree.SelectedNode.Parent; + Import.ImportFromFile(selectedNodeAsContainer); } - public event EventHandler ImportActiveDirectoryClicked; - private void OnImportActiveDirectoryClicked(object sender, EventArgs e) { - var handler = ImportActiveDirectoryClicked; - handler?.Invoke(this, e); + Windows.Show(WindowType.ActiveDirectoryImport); } - public event EventHandler ImportPortScanClicked; - private void OnImportPortScanClicked(object sender, EventArgs e) { - var handler = ImportPortScanClicked; - handler?.Invoke(this, e); + Windows.Show(WindowType.PortScan); } - public event EventHandler ExportFileClicked; - private void OnExportFileClicked(object sender, EventArgs e) { - var handler = ExportFileClicked; - handler?.Invoke(this, e); + Export.ExportToFile(_connectionTree.SelectedNode, Runtime.ConnectionTreeModel); } - public event EventHandler AddConnectionClicked; - private void OnAddConnectionClicked(object sender, EventArgs e) { - var handler = AddConnectionClicked; - handler?.Invoke(this, e); + _connectionTree.AddConnection(); + Runtime.SaveConnectionsAsync(); } - public event EventHandler AddFolderClicked; - private void OnAddFolderClicked(object sender, EventArgs e) { - var handler = AddFolderClicked; - handler?.Invoke(this, e); + _connectionTree.AddFolder(); + Runtime.SaveConnectionsAsync(); } - public event EventHandler SortAscendingClicked; - private void OnSortAscendingClicked(object sender, EventArgs e) { - var handler = SortAscendingClicked; - handler?.Invoke(this, e); + SortNodesRecursive(_connectionTree.SelectedNode, ListSortDirection.Ascending); } - public event EventHandler SortDescendingClicked; - private void OnSortDescendingClicked(object sender, EventArgs e) { - var handler = SortDescendingClicked; - handler?.Invoke(this, e); + SortNodesRecursive(_connectionTree.SelectedNode, ListSortDirection.Descending); } - public event EventHandler MoveUpClicked; - private void OnMoveUpClicked(object sender, EventArgs e) { - var handler = MoveUpClicked; - handler?.Invoke(this, e); + _connectionTree.SelectedNode.Parent.PromoteChild(_connectionTree.SelectedNode); + Runtime.SaveConnectionsAsync(); } - public event EventHandler MoveDownClicked; - private void OnMoveDownClicked(object sender, EventArgs e) { - var handler = MoveDownClicked; - handler?.Invoke(this, e); + _connectionTree.SelectedNode.Parent.DemoteChild(_connectionTree.SelectedNode); + Runtime.SaveConnectionsAsync(); } - public event EventHandler ExternalToolClicked; - private void OnExternalToolClicked(object sender, EventArgs e) { - var handler = ExternalToolClicked; - handler?.Invoke(sender, e); + _connectionTree.StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); } #endregion + + private void SortNodesRecursive(ConnectionInfo sortTarget, ListSortDirection sortDirection) + { + if (sortTarget == null) + sortTarget = _connectionTree.GetRootConnectionNode(); + + var sortTargetAsContainer = sortTarget as ContainerInfo; + if (sortTargetAsContainer != null) + sortTargetAsContainer.SortRecursive(sortDirection); + else + _connectionTree.SelectedNode.Parent.SortRecursive(sortDirection); + + Runtime.SaveConnectionsAsync(); + } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index d98216921..19d671757 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; -using mRemoteNG.Tools; using mRemoteNG.UI.Controls; using WeifenLuo.WinFormsUI.Docking; @@ -15,9 +14,9 @@ namespace mRemoteNG.UI.Window { public partial class ConnectionTreeWindow { - private readonly ConnectionContextMenu _contextMenu = new ConnectionContextMenu(); + private readonly ConnectionContextMenu _contextMenu; - public ConnectionInfo SelectedNode => olvConnections.SelectedNode; + public ConnectionInfo SelectedNode => olvConnections.SelectedNode; public ConnectionTree ConnectionTree { @@ -30,9 +29,9 @@ namespace mRemoteNG.UI.Window WindowType = WindowType.Tree; DockPnl = panel; InitializeComponent(); + _contextMenu = new ConnectionContextMenu(olvConnections); olvConnections.ContextMenuStrip = _contextMenu; SetMenuEventHandlers(); - SetContextMenuEventHandlers(); SetConnectionTreeEventHandlers(); } @@ -102,79 +101,6 @@ namespace mRemoteNG.UI.Window #endregion #region Tree Context Menu - private void SetContextMenuEventHandlers() - { - _contextMenu.Opening += (sender, args) => _contextMenu.ShowHideMenuItems(SelectedNode); - _contextMenu.ConnectClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DoNotJump); - else - ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.DoNotJump); - }; - _contextMenu.ConnectToConsoleSessionClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); - else - ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); - }; - _contextMenu.DontConnectToConsoleSessionClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); - else - ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); - }; - _contextMenu.ConnectInFullscreenClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); - else - ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); - }; - _contextMenu.ConnectWithNoCredentialsClick += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.NoCredentials); - else - ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.NoCredentials); - }; - _contextMenu.ChoosePanelBeforeConnectingClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo; - if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); - else - ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); - }; - _contextMenu.DisconnectClicked += (sender, args) => olvConnections.DisconnectConnection(SelectedNode); - _contextMenu.TransferFileClicked += (sender, args) => olvConnections.SshTransferFile(); - _contextMenu.DuplicateClicked += (sender, args) => olvConnections.DuplicateSelectedNode(); - _contextMenu.RenameClicked += (sender, args) => olvConnections.RenameSelectedNode(); - _contextMenu.DeleteClicked += (sender, args) => olvConnections.DeleteSelectedNode(); - _contextMenu.ImportFileClicked += (sender, args) => - { - var selectedNodeAsContainer = SelectedNode as ContainerInfo ?? SelectedNode.Parent; - Import.ImportFromFile(selectedNodeAsContainer); - }; - _contextMenu.ImportActiveDirectoryClicked += (sender, args) => Windows.Show(WindowType.ActiveDirectoryImport); - _contextMenu.ImportPortScanClicked += (sender, args) => Windows.Show(WindowType.PortScan); - _contextMenu.ExportFileClicked += (sender, args) => Export.ExportToFile(SelectedNode, Runtime.ConnectionTreeModel); - _contextMenu.AddConnectionClicked += cMenTreeAddConnection_Click; - _contextMenu.AddFolderClicked += cMenTreeAddFolder_Click; - _contextMenu.SortAscendingClicked += (sender, args) => SortNodesRecursive(SelectedNode, ListSortDirection.Ascending); - _contextMenu.SortDescendingClicked += (sender, args) => SortNodesRecursive(SelectedNode, ListSortDirection.Descending); - _contextMenu.MoveUpClicked += cMenTreeMoveUp_Click; - _contextMenu.MoveDownClicked += cMenTreeMoveDown_Click; - _contextMenu.ExternalToolClicked += (sender, args) => olvConnections.StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); - } - private void cMenTreeAddConnection_Click(object sender, EventArgs e) { olvConnections.AddConnection(); @@ -201,18 +127,6 @@ namespace mRemoteNG.UI.Window Runtime.SaveConnectionsAsync(); } - private void cMenTreeMoveUp_Click(object sender, EventArgs e) - { - SelectedNode.Parent.PromoteChild(SelectedNode); - Runtime.SaveConnectionsAsync(); - } - - private void cMenTreeMoveDown_Click(object sender, EventArgs e) - { - SelectedNode.Parent.DemoteChild(SelectedNode); - Runtime.SaveConnectionsAsync(); - } - private void tvConnections_BeforeLabelEdit(object sender, LabelEditEventArgs e) { _contextMenu.DisableShortcutKeys(); From 99e7072e27a7d427a540144023711c9b884fc6cb Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 11 Jan 2017 17:01:08 -0500 Subject: [PATCH 047/106] code clean up relates to #325 --- .../Connection/Protocol/IntegratedProgram.cs | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs index 55bbde660..2911fb271 100644 --- a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs +++ b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs @@ -22,7 +22,7 @@ namespace mRemoteNG.Connection.Protocol { if (InterfaceControl.Info == null) return base.Initialize(); - _externalTool = Runtime.GetExtAppByName(Convert.ToString(InterfaceControl.Info.ExtApp)); + _externalTool = Runtime.GetExtAppByName(InterfaceControl.Info.ExtApp); _externalTool.ConnectionInfo = InterfaceControl.Info; return base.Initialize(); @@ -55,10 +55,10 @@ namespace mRemoteNG.Connection.Protocol _process.Exited += ProcessExited; _process.Start(); - _process.WaitForInputIdle(Convert.ToInt32(Settings.Default.MaxPuttyWaitTime * 1000)); + _process.WaitForInputIdle(Settings.Default.MaxPuttyWaitTime * 1000); var startTicks = Environment.TickCount; - while (_handle.ToInt32() == 0 & Environment.TickCount < startTicks + (Settings.Default.MaxPuttyWaitTime * 1000)) + while (_handle.ToInt32() == 0 & Environment.TickCount < startTicks + Settings.Default.MaxPuttyWaitTime * 1000) { _process.Refresh(); if (_process.MainWindowTitle != "Default IME") @@ -92,15 +92,12 @@ namespace mRemoteNG.Connection.Protocol { try { - if (ConnectionWindow.InTabDrag) - { - return ; - } + if (ConnectionWindow.InTabDrag) return; NativeMethods.SetForegroundWindow(_handle); } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppFocusFailed, ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppFocusFailed, ex); } } @@ -108,15 +105,12 @@ namespace mRemoteNG.Connection.Protocol { try { - if (InterfaceControl.Size == Size.Empty) - { - return ; - } - NativeMethods.MoveWindow(_handle, Convert.ToInt32(-SystemInformation.FrameBorderSize.Width), Convert.ToInt32(-(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height)), InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width * 2), InterfaceControl.Height + SystemInformation.CaptionHeight + (SystemInformation.FrameBorderSize.Height * 2), true); + if (InterfaceControl.Size == Size.Empty) return; + NativeMethods.MoveWindow(_handle, -SystemInformation.FrameBorderSize.Width, -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height), InterfaceControl.Width + SystemInformation.FrameBorderSize.Width * 2, InterfaceControl.Height + SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height * 2, true); } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppResizeFailed, ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppResizeFailed, ex); } } @@ -131,7 +125,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppKillFailed, ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppKillFailed, ex); } try @@ -143,7 +137,7 @@ namespace mRemoteNG.Connection.Protocol } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppDisposeFailed, ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppDisposeFailed, ex); } base.Close(); From ea657824c2f18b50ccece678c56489fe0500f8a2 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 11 Jan 2017 17:49:37 -0500 Subject: [PATCH 048/106] Streamlined non-integrated IntApp connections This seems to fix #325 --- mRemoteV1/Connection/ConnectionInitiator.cs | 10 ++- .../Connection/Protocol/IntegratedProgram.cs | 79 +++++++++++-------- mRemoteV1/Tools/ExternalTool.cs | 2 +- 3 files changed, 57 insertions(+), 34 deletions(-) diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs index 058f22de9..a28c39073 100644 --- a/mRemoteV1/Connection/ConnectionInitiator.cs +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -244,7 +244,15 @@ namespace mRemoteNG.Connection { var Prot = (ProtocolBase)sender; Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnenctionCloseEvent, true); - Runtime.MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnenctionClosedByUser, Prot.InterfaceControl.Info.Hostname, Prot.InterfaceControl.Info.Protocol.ToString(), Environment.UserName)); + string connDetail; + if (Prot.InterfaceControl.Info.Hostname == "" && Prot.InterfaceControl.Info.Protocol == ProtocolType.IntApp) + connDetail = Prot.InterfaceControl.Info.ExtApp; + else if (Prot.InterfaceControl.Info.Hostname != "") + connDetail = Prot.InterfaceControl.Info.Hostname; + else + connDetail = "UNKNOWN"; + + Runtime.MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnenctionClosedByUser, connDetail, Prot.InterfaceControl.Info.Protocol, Environment.UserName)); Prot.InterfaceControl.Info.OpenConnections.Remove(Prot); if (Prot.InterfaceControl.Info.PostExtApp == "") return; diff --git a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs index 2911fb271..c87d6da76 100644 --- a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs +++ b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Drawing; using System.Threading; using System.Windows.Forms; +using mRemoteNG.Messages; namespace mRemoteNG.Connection.Protocol @@ -32,11 +33,18 @@ namespace mRemoteNG.Connection.Protocol { try { - if (_externalTool.TryIntegrate == false) + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Attempting to start: {_externalTool.DisplayName}", true); + + if (_externalTool.TryIntegrate == false) { _externalTool.Start(InterfaceControl.Info); - Close(); - return false; + /* Don't call close here... There's nothing for the override to do in this case since + * _process is not created in this scenario. When returning false, ProtocolBase.Close() + * will be called - which is just going to call IntegratedProgram.Close() again anyway... + * Close(); + */ + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Assuming no other errors/exceptions occurred immediately before this message regarding {_externalTool.DisplayName}, the next \"closed by user\" message can be ignored", true); + return false; } var argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo); @@ -72,10 +80,10 @@ namespace mRemoteNG.Connection.Protocol } NativeMethods.SetParent(_handle, InterfaceControl.Handle); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, Language.strIntAppStuff, true); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppHandle, _handle), true); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppTitle, _process.MainWindowTitle), true); - Runtime.MessageCollector.AddMessage(Messages.MessageClass.InformationMsg, string.Format(Language.strIntAppParentHandle, InterfaceControl.Parent.Handle), true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strIntAppStuff, true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strIntAppHandle, _handle), true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strIntAppTitle, _process.MainWindowTitle), true); + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strIntAppParentHandle, InterfaceControl.Parent.Handle), true); Resize(this, new EventArgs()); base.Connect(); @@ -116,31 +124,38 @@ namespace mRemoteNG.Connection.Protocol public override void Close() { - try - { - if (!_process.HasExited) - { - _process.Kill(); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppKillFailed, ex); - } - - try - { - if (!_process.HasExited) - { - _process.Dispose(); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppDisposeFailed, ex); - } - - base.Close(); + /* only attempt this if we have a valid process object + * Non-integated tools will still call base.Close() and don't have a valid process object. + * See Connect() above... This just muddies up the log. + */ + if (_process != null) + { + try + { + if (!_process.HasExited) + { + _process.Kill(); + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppKillFailed, ex); + } + + try + { + if (!_process.HasExited) + { + _process.Dispose(); + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionMessage(Language.strIntAppDisposeFailed, ex); + } + } + + base.Close(); } #endregion diff --git a/mRemoteV1/Tools/ExternalTool.cs b/mRemoteV1/Tools/ExternalTool.cs index 5002d6cc9..9cbc2a50f 100644 --- a/mRemoteV1/Tools/ExternalTool.cs +++ b/mRemoteV1/Tools/ExternalTool.cs @@ -84,7 +84,7 @@ namespace mRemoteNG.Tools } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage("ExternalApp.StartIntegrated() failed.", ex, logOnly: true); + Runtime.MessageCollector.AddExceptionMessage("ExternalApp.StartIntegrated() failed.", ex); } } From ca592fac77d62c8413984558de50682ce3fa9b0e Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 11 Jan 2017 17:56:37 -0500 Subject: [PATCH 049/106] update change log --- CHANGELOG.TXT | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 7648e6054..19cd54adf 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -13,6 +13,7 @@ Added Release Channels to the update check functionality allowing users to selec Fixes: ------ #334: Quick Connect displays warning when clicking on a folder +#325: When using a connection with an external app, results in opening the same external app continuously #311: Import from Active Directory does not use machine's domain by default #211, #267: Recursive AD Import wasn't fully functional @@ -48,7 +49,7 @@ Fixes: ------ #254: Component check window position issues and uncaught exception #260: Crash when attempting to load fully encrypted confCons v2.5 -#261: Double clicking folder in treeview doesnt expand it in 1.75 beta1 +#261: Double clicking folder in treeview doesn't expand it in 1.75 beta1 #271: Install package is not using the last installation path #278: Silent installs not detecting prerequisites @@ -92,7 +93,7 @@ Fixes: MR-965, MR-871, MR-629: Error 264 on RDP Connect attempt - Added timeout value to Tools -> Options -> Connections MR-946: Remove old/insecure SharpSSH and related components. Replace with SSH.NET for File Transfer Functionality MR-896: Added prerequisite installer check for KB2574819. Prevents "Class not registered" errors when opening RDP connections. -PR-130: Fix Scan button width to fit russian translation +PR-130: Fix Scan button width to fit Russian translation @@ -100,7 +101,7 @@ PR-130: Fix Scan button width to fit russian translation General Changes: ---------------- -Updated GeckoFx pacakge +Updated GeckoFx package Updated DockPanelSuite library to 2.10 Final Japanese translation updated MR-942: Refactored code relating to loading the connections file @@ -175,7 +176,7 @@ Port Scan is now Asynchronous (and is significantly faster) Fixes: ------ MR-874: Added work-around to installer to ignore installation prerequisites -MR-884: Slow startup in some scnearios checking authenticode certificate +MR-884: Slow startup in some scenarios checking authenticode certificate MR-872: Crash in External Tools when arguments aren't quoted MR-854: crashes when right clicking on connection tab MR-852: Option "Allow only a single instance of the application" non-functional @@ -316,7 +317,7 @@ Fixed issue MR-398 - Full Screen mode doesn't correctly make use of available sp Fixed issue MR-402 - scrollbar touch moves putty window Fixed issue MR-406 - Items disappear from External Tools toolbar when accessing External Tools panel Fixed issue MR-410 - Unhandled exception when clicking New button under Theme -Fixed issue MR-413 - Can't use aplication +Fixed issue MR-413 - Can't use application Fixed new connections having a globe icon. Fixed the category names in the themes tab of the options dialog on Windows XP not showing correctly. Fixed PuTTY saved sessions with spaces or special characters not being listed. From 9132592fd7a097d547604911dfa05dc3359edb99 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 08:58:52 -0700 Subject: [PATCH 050/106] moved the setup of the name column to its own class --- mRemoteV1/UI/Controls/ConnectionTree.cs | 19 +--------------- mRemoteV1/UI/Controls/NameColumn.cs | 30 +++++++++++++++++++++++++ mRemoteV1/mRemoteV1.csproj | 3 +++ 3 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 mRemoteV1/UI/Controls/NameColumn.cs diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index c8722787d..df06414e6 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -61,14 +61,7 @@ namespace mRemoteNG.UI.Controls private void CreateNameColumn() { - _olvNameColumn = new OLVColumn - { - AspectName = "Name", - FillsFreeSpace = true, - IsButton = true, - AspectGetter = item => ((ConnectionInfo)item).Name, - ImageGetter = ConnectionImageGetter - }; + _olvNameColumn = new NameColumn(); Columns.Add(_olvNameColumn); AllColumns.Add(_olvNameColumn); } @@ -116,16 +109,6 @@ namespace mRemoteNG.UI.Controls //ContextMenuStrip = _contextMenu; } - private static object ConnectionImageGetter(object rowObject) - { - if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; - if (rowObject is RootNodeInfo) return "Root"; - if (rowObject is ContainerInfo) return "Folder"; - var connection = rowObject as ConnectionInfo; - if (connection == null) return ""; - return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; - } - private void SetupDropSink() { DropSink = new SimpleDropSink diff --git a/mRemoteV1/UI/Controls/NameColumn.cs b/mRemoteV1/UI/Controls/NameColumn.cs new file mode 100644 index 000000000..ed81d16d0 --- /dev/null +++ b/mRemoteV1/UI/Controls/NameColumn.cs @@ -0,0 +1,30 @@ +using BrightIdeasSoftware; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.UI.Controls +{ + public class NameColumn : OLVColumn + { + public NameColumn() + { + AspectName = "Name"; + FillsFreeSpace = true; + IsButton = true; + AspectGetter = item => ((ConnectionInfo) item).Name; + ImageGetter = ConnectionImageGetter; + } + + private static object ConnectionImageGetter(object rowObject) + { + if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; + if (rowObject is RootNodeInfo) return "Root"; + if (rowObject is ContainerInfo) return "Folder"; + var connection = rowObject as ConnectionInfo; + if (connection == null) return ""; + return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 41f9efd32..38570f53c 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -237,6 +237,9 @@ UserControl + + Component + Component From 5bcb59f876b20332d6943652f50672488fed4d7e Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 08:59:34 -0700 Subject: [PATCH 051/106] moved the setup of the tree image list to its own class --- mRemoteV1/UI/Controls/ConnectionTree.cs | 30 +---------------- mRemoteV1/UI/Controls/StatusImageList.cs | 43 ++++++++++++++++++++++++ mRemoteV1/mRemoteV1.csproj | 1 + 3 files changed, 45 insertions(+), 29 deletions(-) create mode 100644 mRemoteV1/UI/Controls/StatusImageList.cs diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index df06414e6..36d39e328 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -53,7 +53,6 @@ namespace mRemoteNG.UI.Controls { CreateNameColumn(); CreateImageList(); - FillImageList(); LinkModelToView(); SetupDropSink(); SetEventHandlers(); @@ -68,34 +67,7 @@ namespace mRemoteNG.UI.Controls private void CreateImageList() { - _imgListTree = new ImageList(components) - { - ColorDepth = ColorDepth.Depth32Bit, - ImageSize = new System.Drawing.Size(16, 16), - TransparentColor = System.Drawing.Color.Transparent - }; - SmallImageList = _imgListTree; - } - - private void FillImageList() - { - try - { - _imgListTree.Images.Add(Resources.Root); - _imgListTree.Images.SetKeyName(0, "Root"); - _imgListTree.Images.Add(Resources.Folder); - _imgListTree.Images.SetKeyName(1, "Folder"); - _imgListTree.Images.Add(Resources.Play); - _imgListTree.Images.SetKeyName(2, "Play"); - _imgListTree.Images.Add(Resources.Pause); - _imgListTree.Images.SetKeyName(3, "Pause"); - _imgListTree.Images.Add(Resources.PuttySessions); - _imgListTree.Images.SetKeyName(4, "PuttySessions"); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("FillImageList (UI.Window.ConnectionTreeWindow) failed", ex); - } + SmallImageList = StatusImageList.GetImageList(); } private void LinkModelToView() diff --git a/mRemoteV1/UI/Controls/StatusImageList.cs b/mRemoteV1/UI/Controls/StatusImageList.cs new file mode 100644 index 000000000..987952aa0 --- /dev/null +++ b/mRemoteV1/UI/Controls/StatusImageList.cs @@ -0,0 +1,43 @@ +using System; +using System.Windows.Forms; +using mRemoteNG.App; + + +namespace mRemoteNG.UI.Controls +{ + public class StatusImageList + { + public static ImageList GetImageList() + { + var imageList = new ImageList + { + ColorDepth = ColorDepth.Depth32Bit, + ImageSize = new System.Drawing.Size(16, 16), + TransparentColor = System.Drawing.Color.Transparent + }; + FillImageList(imageList); + return imageList; + } + + private static void FillImageList(ImageList imageList) + { + try + { + imageList.Images.Add(Resources.Root); + imageList.Images.SetKeyName(0, "Root"); + imageList.Images.Add(Resources.Folder); + imageList.Images.SetKeyName(1, "Folder"); + imageList.Images.Add(Resources.Play); + imageList.Images.SetKeyName(2, "Play"); + imageList.Images.Add(Resources.Pause); + imageList.Images.SetKeyName(3, "Pause"); + imageList.Images.Add(Resources.PuttySessions); + imageList.Images.SetKeyName(4, "PuttySessions"); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace($"Unable to fill the image list of type {nameof(StatusImageList)}", ex); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 38570f53c..6a7c9a0dc 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -243,6 +243,7 @@ Component + Component From dae339f4942b6f5b00bac4a6a5219df1392c711f Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 09:17:34 -0700 Subject: [PATCH 052/106] moved the image getter delegate code into its imagelist since the img names have to match up. seems like a better division of responsibility --- mRemoteV1/UI/Controls/ConnectionTree.cs | 16 +++++----------- mRemoteV1/UI/Controls/NameColumn.cs | 16 ++-------------- mRemoteV1/UI/Controls/StatusImageList.cs | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 36d39e328..8c5bd336f 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -22,8 +22,6 @@ namespace mRemoteNG.UI.Controls private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; private OLVColumn _olvNameColumn; - private ImageList _imgListTree; - public ConnectionInfo SelectedNode => (ConnectionInfo) SelectedObject; @@ -51,25 +49,21 @@ namespace mRemoteNG.UI.Controls #region ConnectionTree Setup private void SetupConnectionTreeView() { - CreateNameColumn(); - CreateImageList(); + var imageList = new StatusImageList(); + SmallImageList = imageList.GetImageList(); + CreateNameColumn(imageList.ImageGetter); LinkModelToView(); SetupDropSink(); SetEventHandlers(); } - private void CreateNameColumn() + private void CreateNameColumn(ImageGetterDelegate imageGetterDelegate) { - _olvNameColumn = new NameColumn(); + _olvNameColumn = new NameColumn(imageGetterDelegate); Columns.Add(_olvNameColumn); AllColumns.Add(_olvNameColumn); } - private void CreateImageList() - { - SmallImageList = StatusImageList.GetImageList(); - } - private void LinkModelToView() { CanExpandGetter = item => diff --git a/mRemoteV1/UI/Controls/NameColumn.cs b/mRemoteV1/UI/Controls/NameColumn.cs index ed81d16d0..8903f1839 100644 --- a/mRemoteV1/UI/Controls/NameColumn.cs +++ b/mRemoteV1/UI/Controls/NameColumn.cs @@ -1,30 +1,18 @@ using BrightIdeasSoftware; using mRemoteNG.Connection; -using mRemoteNG.Container; -using mRemoteNG.Tree.Root; namespace mRemoteNG.UI.Controls { public class NameColumn : OLVColumn { - public NameColumn() + public NameColumn(ImageGetterDelegate imageGetterDelegate) { AspectName = "Name"; FillsFreeSpace = true; IsButton = true; AspectGetter = item => ((ConnectionInfo) item).Name; - ImageGetter = ConnectionImageGetter; - } - - private static object ConnectionImageGetter(object rowObject) - { - if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; - if (rowObject is RootNodeInfo) return "Root"; - if (rowObject is ContainerInfo) return "Folder"; - var connection = rowObject as ConnectionInfo; - if (connection == null) return ""; - return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; + ImageGetter = imageGetterDelegate; } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/StatusImageList.cs b/mRemoteV1/UI/Controls/StatusImageList.cs index 987952aa0..24feb1a57 100644 --- a/mRemoteV1/UI/Controls/StatusImageList.cs +++ b/mRemoteV1/UI/Controls/StatusImageList.cs @@ -1,13 +1,16 @@ using System; using System.Windows.Forms; using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree.Root; namespace mRemoteNG.UI.Controls { public class StatusImageList { - public static ImageList GetImageList() + public ImageList GetImageList() { var imageList = new ImageList { @@ -19,7 +22,17 @@ namespace mRemoteNG.UI.Controls return imageList; } - private static void FillImageList(ImageList imageList) + public object ImageGetter(object rowObject) + { + if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; + if (rowObject is RootNodeInfo) return "Root"; + if (rowObject is ContainerInfo) return "Folder"; + var connection = rowObject as ConnectionInfo; + if (connection == null) return ""; + return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; + } + + private void FillImageList(ImageList imageList) { try { From aa954cbea9514b5bb0f3c599eb97873258e30e08 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 09:24:59 -0700 Subject: [PATCH 053/106] minor cleanup --- mRemoteV1/UI/Controls/ConnectionTree.cs | 17 ++++++----------- mRemoteV1/UI/Controls/StatusImageList.cs | 5 +++-- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 8c5bd336f..a80e50b65 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; -using System.Windows.Forms; using BrightIdeasSoftware; using mRemoteNG.App; using mRemoteNG.Config.Putty; @@ -21,12 +20,13 @@ namespace mRemoteNG.UI.Controls private ConnectionTreeModel _connectionTreeModel; private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; - private OLVColumn _olvNameColumn; public ConnectionInfo SelectedNode => (ConnectionInfo) SelectedObject; public NodeSearcher NodeSearcher { get; private set; } + public Func DeletionConfirmer { get; set; } = connectionInfo => true; + public ConnectionTreeModel ConnectionTreeModel { get { return _connectionTreeModel; } @@ -37,8 +37,6 @@ namespace mRemoteNG.UI.Controls } } - public Func DeletionConfirmer { get; set; } = connectionInfo => true; - public ConnectionTree() { @@ -51,17 +49,15 @@ namespace mRemoteNG.UI.Controls { var imageList = new StatusImageList(); SmallImageList = imageList.GetImageList(); - CreateNameColumn(imageList.ImageGetter); + AddColumns(imageList.ImageGetter); LinkModelToView(); SetupDropSink(); SetEventHandlers(); } - private void CreateNameColumn(ImageGetterDelegate imageGetterDelegate) + private void AddColumns(ImageGetterDelegate imageGetterDelegate) { - _olvNameColumn = new NameColumn(imageGetterDelegate); - Columns.Add(_olvNameColumn); - AllColumns.Add(_olvNameColumn); + Columns.Add(new NameColumn(imageGetterDelegate)); } private void LinkModelToView() @@ -72,7 +68,6 @@ namespace mRemoteNG.UI.Controls return itemAsContainer?.Children.Count > 0; }; ChildrenGetter = item => ((ContainerInfo)item).Children; - //ContextMenuStrip = _contextMenu; } private void SetupDropSink() @@ -165,7 +160,7 @@ namespace mRemoteNG.UI.Controls } #endregion - #region ConnectionTree + #region ConnectionTree Behavior public void DeleteSelectedNode() { if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; diff --git a/mRemoteV1/UI/Controls/StatusImageList.cs b/mRemoteV1/UI/Controls/StatusImageList.cs index 24feb1a57..b5a2413d2 100644 --- a/mRemoteV1/UI/Controls/StatusImageList.cs +++ b/mRemoteV1/UI/Controls/StatusImageList.cs @@ -1,4 +1,5 @@ using System; +using System.Drawing; using System.Windows.Forms; using mRemoteNG.App; using mRemoteNG.Connection; @@ -15,8 +16,8 @@ namespace mRemoteNG.UI.Controls var imageList = new ImageList { ColorDepth = ColorDepth.Depth32Bit, - ImageSize = new System.Drawing.Size(16, 16), - TransparentColor = System.Drawing.Color.Transparent + ImageSize = new Size(16, 16), + TransparentColor = Color.Transparent }; FillImageList(imageList); return imageList; From 28728fe29f8cae5ab55d88e93c4a69159c8ef7fe Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 10:29:30 -0700 Subject: [PATCH 054/106] moved some connectiontree post setup actions into their own classes. post setup actions are now managed by a composite --- mRemoteV1/Tree/PreviousSessionOpener.cs | 22 +++++++++++++++++++ .../Tree/PreviouslyOpenedFolderExpander.cs | 18 +++++++++++++++ mRemoteV1/Tree/RootNodeExpander.cs | 14 ++++++++++++ mRemoteV1/UI/Controls/ConnectionTree.cs | 14 +++++++++--- .../UI/Controls/IConnectionTreeDelegate.cs | 8 +++++++ mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 6 +++++ mRemoteV1/mRemoteV1.csproj | 4 ++++ 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 mRemoteV1/Tree/PreviousSessionOpener.cs create mode 100644 mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs create mode 100644 mRemoteV1/Tree/RootNodeExpander.cs create mode 100644 mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs diff --git a/mRemoteV1/Tree/PreviousSessionOpener.cs b/mRemoteV1/Tree/PreviousSessionOpener.cs new file mode 100644 index 000000000..6d5170c25 --- /dev/null +++ b/mRemoteV1/Tree/PreviousSessionOpener.cs @@ -0,0 +1,22 @@ +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.UI.Controls; + + +namespace mRemoteNG.Tree +{ + public class PreviousSessionOpener : IConnectionTreeDelegate + { + public void Execute(ConnectionTree connectionTree) + { + if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; + var connectionInfoList = connectionTree.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); + var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); + foreach (var connectionInfo in previouslyOpenedConnections) + { + ConnectionInitiator.OpenConnection(connectionInfo); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs b/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs new file mode 100644 index 000000000..b276da702 --- /dev/null +++ b/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs @@ -0,0 +1,18 @@ +using System.Linq; +using mRemoteNG.Container; +using mRemoteNG.UI.Controls; + + +namespace mRemoteNG.Tree +{ + public class PreviouslyOpenedFolderExpander : IConnectionTreeDelegate + { + public void Execute(ConnectionTree connectionTree) + { + var containerList = connectionTree.ConnectionTreeModel.GetRecursiveChildList(connectionTree.GetRootConnectionNode()).OfType(); + var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); + connectionTree.ExpandedObjects = previouslyExpandedNodes; + connectionTree.InvokeRebuildAll(true); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/RootNodeExpander.cs b/mRemoteV1/Tree/RootNodeExpander.cs new file mode 100644 index 000000000..a092ebbdf --- /dev/null +++ b/mRemoteV1/Tree/RootNodeExpander.cs @@ -0,0 +1,14 @@ +using mRemoteNG.UI.Controls; + + +namespace mRemoteNG.Tree +{ + public class RootNodeExpander : IConnectionTreeDelegate + { + public void Execute(ConnectionTree connectionTree) + { + var rootConnectionNode = connectionTree.GetRootConnectionNode(); + connectionTree.InvokeExpand(rootConnectionNode); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index a80e50b65..0b8fd6f2e 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -27,6 +27,8 @@ namespace mRemoteNG.UI.Controls public Func DeletionConfirmer { get; set; } = connectionInfo => true; + public IEnumerable PostSetupActions { get; set; } = new IConnectionTreeDelegate[0]; + public ConnectionTreeModel ConnectionTreeModel { get { return _connectionTreeModel; } @@ -106,9 +108,7 @@ namespace mRemoteNG.UI.Controls SetObjects(ConnectionTreeModel.RootNodes); RegisterModelUpdateHandlers(); NodeSearcher = new NodeSearcher(ConnectionTreeModel); - ExpandPreviouslyOpenedFolders(); - ExpandRootConnectionNode(); - OpenConnectionsFromLastSession(); + ExecutePostSetupActions(); } private void RegisterModelUpdateHandlers() @@ -158,6 +158,14 @@ namespace mRemoteNG.UI.Controls ConnectionInitiator.OpenConnection(connectionInfo); } } + + private void ExecutePostSetupActions() + { + foreach (var action in PostSetupActions) + { + action.Execute(this); + } + } #endregion #region ConnectionTree Behavior diff --git a/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs b/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs new file mode 100644 index 000000000..07b1b73e6 --- /dev/null +++ b/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs @@ -0,0 +1,8 @@ + +namespace mRemoteNG.UI.Controls +{ + public interface IConnectionTreeDelegate + { + void Execute(ConnectionTree connectionTree); + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 19d671757..6714379bb 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -84,6 +84,12 @@ namespace mRemoteNG.UI.Window olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; olvConnections.KeyDown += tvConnections_KeyDown; olvConnections.KeyPress += tvConnections_KeyPress; + olvConnections.PostSetupActions = new IConnectionTreeDelegate[] + { + new PreviouslyOpenedFolderExpander(), + new RootNodeExpander(), + new PreviousSessionOpener() + }; } #endregion diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 6a7c9a0dc..c8e26f1fd 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -217,6 +217,9 @@ + + + Component @@ -237,6 +240,7 @@ UserControl + Component From 6631a13d20098976cf47fc9e3b24d9217ea39d83 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 10:31:50 -0700 Subject: [PATCH 055/106] cleanup --- mRemoteV1/UI/Controls/ConnectionTree.cs | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 0b8fd6f2e..fb2967365 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -140,25 +140,6 @@ namespace mRemoteNG.UI.Controls RefreshObject(senderAsConnectionInfo); } - private void ExpandPreviouslyOpenedFolders() - { - var containerList = ConnectionTreeModel.GetRecursiveChildList(GetRootConnectionNode()).OfType(); - var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); - ExpandedObjects = previouslyExpandedNodes; - this.InvokeRebuildAll(true); - } - - private void OpenConnectionsFromLastSession() - { - if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; - var connectionInfoList = GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); - var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); - foreach (var connectionInfo in previouslyOpenedConnections) - { - ConnectionInitiator.OpenConnection(connectionInfo); - } - } - private void ExecutePostSetupActions() { foreach (var action in PostSetupActions) @@ -305,12 +286,6 @@ namespace mRemoteNG.UI.Controls } } - private void ExpandRootConnectionNode() - { - var rootConnectionNode = GetRootConnectionNode(); - this.InvokeExpand(rootConnectionNode); - } - private void tvConnections_AfterSelect(object sender, EventArgs e) { try From 875888a34182866092056b331838bc885de39f7b Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 10:51:05 -0700 Subject: [PATCH 056/106] moved a method closer to its call site --- mRemoteV1/UI/Controls/ConnectionContextMenu.cs | 16 +++++++++++++++- mRemoteV1/UI/Controls/ConnectionTree.cs | 14 -------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index 726ef1e90..f0f765c79 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -7,6 +7,7 @@ using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; using mRemoteNG.Container; using mRemoteNG.Tools; +using mRemoteNG.Tree; using mRemoteNG.Tree.Root; // ReSharper disable UnusedParameter.Local @@ -722,7 +723,20 @@ namespace mRemoteNG.UI.Controls private void OnExternalToolClicked(object sender, EventArgs e) { - _connectionTree.StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); + StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); + } + + private void StartExternalApp(ExternalTool externalTool) + { + try + { + if (_connectionTree.SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | _connectionTree.SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) + externalTool.Start(_connectionTree.SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeToolsExternalAppsEntry_Click failed (UI.Window.ConnectionTreeWindow)", ex); + } } #endregion diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index fb2967365..2f829581e 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -8,7 +8,6 @@ using mRemoteNG.App; using mRemoteNG.Config.Putty; using mRemoteNG.Connection; using mRemoteNG.Container; -using mRemoteNG.Tools; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -273,19 +272,6 @@ namespace mRemoteNG.UI.Controls } } - public void StartExternalApp(ExternalTool externalTool) - { - try - { - if (SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) - externalTool.Start(SelectedNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeToolsExternalAppsEntry_Click failed (UI.Window.ConnectionTreeWindow)", ex); - } - } - private void tvConnections_AfterSelect(object sender, EventArgs e) { try From b195d89b76f1565324086de4770f9240c72b4cfa Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 11:02:11 -0700 Subject: [PATCH 057/106] moved a few more functions closer to their call site --- .../UI/Controls/ConnectionContextMenu.cs | 50 ++++++++++++++++++- mRemoteV1/UI/Controls/ConnectionTree.cs | 46 ----------------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index f0f765c79..dc48173b1 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -643,12 +643,58 @@ namespace mRemoteNG.UI.Controls private void OnDisconnectClicked(object sender, EventArgs e) { - _connectionTree.DisconnectConnection(_connectionTree.SelectedNode); + DisconnectConnection(_connectionTree.SelectedNode); + } + + public void DisconnectConnection(ConnectionInfo connectionInfo) + { + try + { + if (connectionInfo == null) return; + var nodeAsContainer = connectionInfo as ContainerInfo; + if (nodeAsContainer != null) + { + foreach (var child in nodeAsContainer.Children) + { + for (var i = 0; i <= child.OpenConnections.Count - 1; i++) + { + child.OpenConnections[i].Disconnect(); + } + } + } + else + { + for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) + { + connectionInfo.OpenConnections[i].Disconnect(); + } + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); + } } private void OnTransferFileClicked(object sender, EventArgs e) { - _connectionTree.SshTransferFile(); + SshTransferFile(); + } + + public void SshTransferFile() + { + try + { + Windows.Show(WindowType.SSHTransfer); + Windows.SshtransferForm.Hostname = _connectionTree.SelectedNode.Hostname; + Windows.SshtransferForm.Username = _connectionTree.SelectedNode.Username; + Windows.SshtransferForm.Password = _connectionTree.SelectedNode.Password; + Windows.SshtransferForm.Port = Convert.ToString(_connectionTree.SelectedNode.Port); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); + } } private void OnDuplicateClicked(object sender, EventArgs e) diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 2f829581e..fb65257ee 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -226,52 +226,6 @@ namespace mRemoteNG.UI.Controls EnsureModelVisible(newNode); } - public void DisconnectConnection(ConnectionInfo connectionInfo) - { - try - { - if (connectionInfo == null) return; - var nodeAsContainer = connectionInfo as ContainerInfo; - if (nodeAsContainer != null) - { - foreach (var child in nodeAsContainer.Children) - { - for (var i = 0; i <= child.OpenConnections.Count - 1; i++) - { - child.OpenConnections[i].Disconnect(); - } - } - } - else - { - for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) - { - connectionInfo.OpenConnections[i].Disconnect(); - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - public void SshTransferFile() - { - try - { - Windows.Show(WindowType.SSHTransfer); - Windows.SshtransferForm.Hostname = SelectedNode.Hostname; - Windows.SshtransferForm.Username = SelectedNode.Username; - Windows.SshtransferForm.Password = SelectedNode.Password; - Windows.SshtransferForm.Port = Convert.ToString(SelectedNode.Port); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - private void tvConnections_AfterSelect(object sender, EventArgs e) { try From 978d94a2cd2edb06cccf6fcec910040dade9425c Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 11:12:18 -0700 Subject: [PATCH 058/106] resolved issue with unit test. we could not select a tree object without that object being visible --- mRemoteNGTests/Tree/ConnectionTreeTests.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mRemoteNGTests/Tree/ConnectionTreeTests.cs b/mRemoteNGTests/Tree/ConnectionTreeTests.cs index ecf8818a5..be6f30204 100644 --- a/mRemoteNGTests/Tree/ConnectionTreeTests.cs +++ b/mRemoteNGTests/Tree/ConnectionTreeTests.cs @@ -17,7 +17,10 @@ namespace mRemoteNGTests.Tree public void Setup() { _connectionTreeModel = CreateConnectionTreeModel(); - _connectionTree = new ConnectionTree(); + _connectionTree = new ConnectionTree + { + PostSetupActions = new IConnectionTreeDelegate[] {new RootNodeExpander()} + }; } [TearDown] From 4c792308bbdb55a5e384f7024c1a83073c2a0e63 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 12:47:23 -0700 Subject: [PATCH 059/106] moved all click-actions for the tree to separate classes to make them easily composable this has the nice effect of also pushing any calls to the settings class outside the classes that are actualy doing work, making them much easier to test in isolation --- mRemoteV1/Tree/ExpandNodeClickHandler.cs | 28 ++++ mRemoteV1/Tree/ITreeNodeClickHandler.cs | 10 ++ mRemoteV1/Tree/OpenConnectionClickHandler.cs | 15 ++ .../Tree/SwitchToConnectionClickHandler.cs | 15 ++ mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs | 20 +++ mRemoteV1/Tree/TreeNodeSingleClickHandler.cs | 20 +++ mRemoteV1/UI/Controls/ConnectionTree.cs | 157 ++++++++---------- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 24 +++ mRemoteV1/mRemoteV1.csproj | 6 + 9 files changed, 207 insertions(+), 88 deletions(-) create mode 100644 mRemoteV1/Tree/ExpandNodeClickHandler.cs create mode 100644 mRemoteV1/Tree/ITreeNodeClickHandler.cs create mode 100644 mRemoteV1/Tree/OpenConnectionClickHandler.cs create mode 100644 mRemoteV1/Tree/SwitchToConnectionClickHandler.cs create mode 100644 mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs create mode 100644 mRemoteV1/Tree/TreeNodeSingleClickHandler.cs diff --git a/mRemoteV1/Tree/ExpandNodeClickHandler.cs b/mRemoteV1/Tree/ExpandNodeClickHandler.cs new file mode 100644 index 000000000..5376d731c --- /dev/null +++ b/mRemoteV1/Tree/ExpandNodeClickHandler.cs @@ -0,0 +1,28 @@ +using System; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.UI.Controls; + + +namespace mRemoteNG.Tree +{ + public class ExpandNodeClickHandler : ITreeNodeClickHandler + { + private readonly ConnectionTree _connectionTree; + + public ExpandNodeClickHandler(ConnectionTree connectionTree) + { + if (connectionTree == null) + throw new ArgumentNullException(nameof(connectionTree)); + + _connectionTree = connectionTree; + } + + public void Execute(ConnectionInfo clickedNode) + { + var clickedNodeAsContainer = clickedNode as ContainerInfo; + if (clickedNodeAsContainer == null) return; + _connectionTree.ToggleExpansion(clickedNodeAsContainer); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/ITreeNodeClickHandler.cs b/mRemoteV1/Tree/ITreeNodeClickHandler.cs new file mode 100644 index 000000000..40b2852a7 --- /dev/null +++ b/mRemoteV1/Tree/ITreeNodeClickHandler.cs @@ -0,0 +1,10 @@ +using mRemoteNG.Connection; + + +namespace mRemoteNG.Tree +{ + public interface ITreeNodeClickHandler + { + void Execute(ConnectionInfo clickedNode); + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/OpenConnectionClickHandler.cs b/mRemoteV1/Tree/OpenConnectionClickHandler.cs new file mode 100644 index 000000000..22c1794e4 --- /dev/null +++ b/mRemoteV1/Tree/OpenConnectionClickHandler.cs @@ -0,0 +1,15 @@ +using mRemoteNG.Connection; + + +namespace mRemoteNG.Tree +{ + public class OpenConnectionClickHandler : ITreeNodeClickHandler + { + public void Execute(ConnectionInfo clickedNode) + { + if (clickedNode == null) return; + if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; + ConnectionInitiator.OpenConnection(clickedNode); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs b/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs new file mode 100644 index 000000000..fbb24eb39 --- /dev/null +++ b/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs @@ -0,0 +1,15 @@ +using mRemoteNG.Connection; + + +namespace mRemoteNG.Tree +{ + public class SwitchToConnectionClickHandler : ITreeNodeClickHandler + { + public void Execute(ConnectionInfo clickedNode) + { + if (clickedNode == null) return; + if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; + ConnectionInitiator.SwitchToOpenConnection(clickedNode); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs b/mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs new file mode 100644 index 000000000..333ae08a8 --- /dev/null +++ b/mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using mRemoteNG.Connection; + + +namespace mRemoteNG.Tree +{ + public class TreeNodeDoubleClickHandler : ITreeNodeClickHandler + { + public IEnumerable ClickHandlers { get; set; } = new ITreeNodeClickHandler[0]; + + public void Execute(ConnectionInfo clickedNode) + { + if (clickedNode == null) return; + foreach (var handler in ClickHandlers) + { + handler.Execute(clickedNode); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/TreeNodeSingleClickHandler.cs b/mRemoteV1/Tree/TreeNodeSingleClickHandler.cs new file mode 100644 index 000000000..5ce6f847b --- /dev/null +++ b/mRemoteV1/Tree/TreeNodeSingleClickHandler.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using mRemoteNG.Connection; + + +namespace mRemoteNG.Tree +{ + public class TreeNodeSingleClickHandler : ITreeNodeClickHandler + { + public IEnumerable ClickHandlers { get; set; } = new ITreeNodeClickHandler[0]; + + public void Execute(ConnectionInfo clickedNode) + { + if (clickedNode == null) return; + foreach (var handler in ClickHandlers) + { + handler.Execute(clickedNode); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index fb65257ee..01ca2a5f9 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -28,6 +28,11 @@ namespace mRemoteNG.UI.Controls public IEnumerable PostSetupActions { get; set; } = new IConnectionTreeDelegate[0]; + public TreeNodeDoubleClickHandler DoubleClickHandler { get; set; } = new TreeNodeDoubleClickHandler(); + + public TreeNodeSingleClickHandler SingleClickHandler { get; set; } = new TreeNodeSingleClickHandler(); + + public ConnectionTreeModel ConnectionTreeModel { get { return _connectionTreeModel; } @@ -149,6 +154,66 @@ namespace mRemoteNG.UI.Controls #endregion #region ConnectionTree Behavior + public RootNodeInfo GetRootConnectionNode() + { + return (RootNodeInfo)Roots.Cast().First(item => item is RootNodeInfo); + } + + public IEnumerable GetRootPuttyNodes() + { + return Objects.OfType(); + } + + public void AddConnection() + { + try + { + AddNode(new ConnectionInfo()); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); + } + } + + public void AddFolder() + { + try + { + AddNode(new ContainerInfo()); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); + } + } + + private void AddNode(ConnectionInfo newNode) + { + if (SelectedNode == null) return; + DefaultConnectionInfo.Instance.SaveTo(newNode); + DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); + var selectedContainer = SelectedNode as ContainerInfo; + var parent = selectedContainer ?? SelectedNode?.Parent; + newNode.SetParent(parent); + Expand(parent); + SelectObject(newNode); + EnsureModelVisible(newNode); + } + + public void DuplicateSelectedNode() + { + var newNode = SelectedNode.Clone(); + newNode.Parent.SetChildBelow(newNode, SelectedNode); + Runtime.SaveConnectionsAsync(); + } + + public void RenameSelectedNode() + { + SelectedItem.BeginEdit(); + Runtime.SaveConnectionsAsync(); + } + public void DeleteSelectedNode() { if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; @@ -189,43 +254,6 @@ namespace mRemoteNG.UI.Controls } } - public void AddConnection() - { - try - { - AddNode(new ConnectionInfo()); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); - } - } - - public void AddFolder() - { - try - { - AddNode(new ContainerInfo()); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); - } - } - - private void AddNode(ConnectionInfo newNode) - { - if (SelectedNode == null) return; - DefaultConnectionInfo.Instance.SaveTo(newNode); - DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); - var selectedContainer = SelectedNode as ContainerInfo; - var parent = selectedContainer ?? SelectedNode?.Parent; - newNode.SetParent(parent); - Expand(parent); - SelectObject(newNode); - EnsureModelVisible(newNode); - } - private void tvConnections_AfterSelect(object sender, EventArgs e) { try @@ -240,40 +268,16 @@ namespace mRemoteNG.UI.Controls private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) { - try - { - if (e.ClickCount > 1) return; - var clickedNode = e.Model as ConnectionInfo; - - if (clickedNode == null) return; - if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; - if (Settings.Default.SingleClickOnConnectionOpensIt) - ConnectionInitiator.OpenConnection(SelectedNode); - - if (Settings.Default.SingleClickSwitchesToOpenConnection) - ConnectionInitiator.SwitchToOpenConnection(SelectedNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); - } + if (e.ClickCount > 1) return; + var clickedNode = e.Model as ConnectionInfo; + SingleClickHandler.Execute(clickedNode); } private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) { if (e.ClickCount < 2) return; - var clickedNodeAsContainer = e.Model as ContainerInfo; - if (clickedNodeAsContainer != null) - { - ToggleExpansion(clickedNodeAsContainer); - } - var clickedNode = e.Model as ConnectionInfo; - if (clickedNode?.GetTreeNodeType() == TreeNodeType.Connection | - clickedNode?.GetTreeNodeType() == TreeNodeType.PuttySession) - { - ConnectionInitiator.OpenConnection(SelectedNode); - } + DoubleClickHandler.Execute(clickedNode); } private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) @@ -288,29 +292,6 @@ namespace mRemoteNG.UI.Controls Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_MouseMove (UI.Window.ConnectionTreeWindow) failed", ex); } } - - public RootNodeInfo GetRootConnectionNode() - { - return (RootNodeInfo)Roots.Cast().First(item => item is RootNodeInfo); - } - - public IEnumerable GetRootPuttyNodes() - { - return Objects.OfType(); - } - - public void DuplicateSelectedNode() - { - var newNode = SelectedNode.Clone(); - newNode.Parent.SetChildBelow(newNode, SelectedNode); - Runtime.SaveConnectionsAsync(); - } - - public void RenameSelectedNode() - { - SelectedItem.BeginEdit(); - Runtime.SaveConnectionsAsync(); - } #endregion } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 6714379bb..1a2ae6e44 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -3,6 +3,7 @@ using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Tree; using System; +using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; @@ -33,6 +34,7 @@ namespace mRemoteNG.UI.Window olvConnections.ContextMenuStrip = _contextMenu; SetMenuEventHandlers(); SetConnectionTreeEventHandlers(); + Settings.Default.PropertyChanged += (sender, args) => SetConnectionTreeEventHandlers(); } #region Form Stuff @@ -90,6 +92,28 @@ namespace mRemoteNG.UI.Window new RootNodeExpander(), new PreviousSessionOpener() }; + SetConnectionTreeDoubleClickHandlers(); + SetConnectionTreeSingleClickHandlers(); + } + + private void SetConnectionTreeDoubleClickHandlers() + { + olvConnections.DoubleClickHandler.ClickHandlers = new ITreeNodeClickHandler[] + { + new ExpandNodeClickHandler(olvConnections), + new OpenConnectionClickHandler() + }; + } + + private void SetConnectionTreeSingleClickHandlers() + { + + var singleClickHandlers = new List(); + if (Settings.Default.SingleClickOnConnectionOpensIt) + singleClickHandlers.Add(new OpenConnectionClickHandler()); + if (Settings.Default.SingleClickSwitchesToOpenConnection) + singleClickHandlers.Add(new SwitchToConnectionClickHandler()); + olvConnections.SingleClickHandler.ClickHandlers = singleClickHandlers; } #endregion diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index c8e26f1fd..5c1f3aed2 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -214,13 +214,19 @@ + + + + + + Component From 82217478d97ff1ed16ee7aca7d00595875aabd19 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 13:31:29 -0700 Subject: [PATCH 060/106] made one of the methods for the connectioninitiator non-static (they should eventually all be non-static). This change was made to making testing easier (make connectioninitiator mockable) --- mRemoteV1/Connection/ConnectionInitiator.cs | 4 ++-- mRemoteV1/Connection/IConnectionInitiator.cs | 7 +++++++ mRemoteV1/Tools/ExternalTool.cs | 3 ++- mRemoteV1/Tools/Tools.Controls.cs | 6 ++++-- mRemoteV1/Tree/PreviousSessionOpener.cs | 5 ++++- mRemoteV1/UI/Forms/frmMain.cs | 6 ++++-- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 4 +++- mRemoteV1/UI/Window/ConnectionWindow.cs | 5 +++-- mRemoteV1/mRemoteV1.csproj | 1 + 9 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 mRemoteV1/Connection/IConnectionInitiator.cs diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs index 058f22de9..af392bea4 100644 --- a/mRemoteV1/Connection/ConnectionInitiator.cs +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -12,7 +12,7 @@ using TabPage = Crownwood.Magic.Controls.TabPage; namespace mRemoteNG.Connection { - public static class ConnectionInitiator + public class ConnectionInitiator : IConnectionInitiator { public static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None) { @@ -33,7 +33,7 @@ namespace mRemoteNG.Connection } } - public static void OpenConnection(ConnectionInfo connectionInfo) + public void OpenConnection(ConnectionInfo connectionInfo) { try { diff --git a/mRemoteV1/Connection/IConnectionInitiator.cs b/mRemoteV1/Connection/IConnectionInitiator.cs new file mode 100644 index 000000000..99e8732f8 --- /dev/null +++ b/mRemoteV1/Connection/IConnectionInitiator.cs @@ -0,0 +1,7 @@ +namespace mRemoteNG.Connection +{ + public interface IConnectionInitiator + { + void OpenConnection(ConnectionInfo connectionInfo); + } +} \ No newline at end of file diff --git a/mRemoteV1/Tools/ExternalTool.cs b/mRemoteV1/Tools/ExternalTool.cs index 5002d6cc9..8ddd0193f 100644 --- a/mRemoteV1/Tools/ExternalTool.cs +++ b/mRemoteV1/Tools/ExternalTool.cs @@ -11,6 +11,7 @@ namespace mRemoteNG.Tools { public class ExternalTool { + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); #region Public Properties public string DisplayName { get; set; } public string FileName { get; set; } @@ -80,7 +81,7 @@ namespace mRemoteNG.Tools try { var newConnectionInfo = BuildConnectionInfoForIntegratedApp(); - ConnectionInitiator.OpenConnection(newConnectionInfo); + _connectionInitiator.OpenConnection(newConnectionInfo); } catch (Exception ex) { diff --git a/mRemoteV1/Tools/Tools.Controls.cs b/mRemoteV1/Tools/Tools.Controls.cs index 1e92b03a2..8f4516400 100644 --- a/mRemoteV1/Tools/Tools.Controls.cs +++ b/mRemoteV1/Tools/Tools.Controls.cs @@ -15,8 +15,10 @@ namespace mRemoteNG.Tools private NotifyIcon _nI; private ContextMenuStrip _cMen; private ToolStripMenuItem _cMenCons; + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); - public bool Disposed { get; set; } + + public bool Disposed { get; set; } public NotificationAreaIcon() { @@ -124,7 +126,7 @@ namespace mRemoteNG.Tools { ShowForm(); } - ConnectionInitiator.OpenConnection((ConnectionInfo)((Control)sender).Tag); + _connectionInitiator.OpenConnection((ConnectionInfo)((Control)sender).Tag); } private void cMenExit_Click(Object sender, EventArgs e) diff --git a/mRemoteV1/Tree/PreviousSessionOpener.cs b/mRemoteV1/Tree/PreviousSessionOpener.cs index 6d5170c25..8d2a3a461 100644 --- a/mRemoteV1/Tree/PreviousSessionOpener.cs +++ b/mRemoteV1/Tree/PreviousSessionOpener.cs @@ -8,6 +8,9 @@ namespace mRemoteNG.Tree { public class PreviousSessionOpener : IConnectionTreeDelegate { + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + + public void Execute(ConnectionTree connectionTree) { if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; @@ -15,7 +18,7 @@ namespace mRemoteNG.Tree var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); foreach (var connectionInfo in previouslyOpenedConnections) { - ConnectionInitiator.OpenConnection(connectionInfo); + _connectionInitiator.OpenConnection(connectionInfo); } } } diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index d85be23ea..7d008ca5b 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -44,6 +44,8 @@ namespace mRemoteNG.UI.Forms private ConnectionInfo _selectedConnection; private SystemMenu _systemMenu; private ConnectionTreeWindow ConnectionTreeWindow { get; set; } + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + @@ -936,14 +938,14 @@ namespace mRemoteNG.UI.Forms btnConnections.DropDownItems.AddRange(rootMenuItems); } - private static void ConnectionsMenuItem_MouseUp(object sender, MouseEventArgs e) + private void ConnectionsMenuItem_MouseUp(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; if (((ToolStripMenuItem) sender).Tag is ContainerInfo) return; var tag = ((ToolStripMenuItem)sender).Tag as ConnectionInfo; if (tag != null) { - ConnectionInitiator.OpenConnection(tag); + _connectionInitiator.OpenConnection(tag); } } #endregion diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 1a2ae6e44..259eed7ae 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -16,6 +16,8 @@ namespace mRemoteNG.UI.Window public partial class ConnectionTreeWindow { private readonly ConnectionContextMenu _contextMenu; + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + public ConnectionInfo SelectedNode => olvConnections.SelectedNode; @@ -276,7 +278,7 @@ namespace mRemoteNG.UI.Window if (e.KeyCode == Keys.Enter) { e.Handled = true; - ConnectionInitiator.OpenConnection(SelectedNode); + _connectionInitiator.OpenConnection(SelectedNode); } else if (e.Control && e.KeyCode == Keys.F) { diff --git a/mRemoteV1/UI/Window/ConnectionWindow.cs b/mRemoteV1/UI/Window/ConnectionWindow.cs index 41972d41f..ed367b818 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.cs @@ -27,7 +27,8 @@ namespace mRemoteNG.UI.Window public partial class ConnectionWindow : BaseWindow { public TabControl TabController; - + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + #region Public Methods public ConnectionWindow(DockContent panel, string formText = "") @@ -335,7 +336,7 @@ namespace mRemoteNG.UI.Window if (modelAsContainer != null) ConnectionInitiator.OpenConnection(modelAsContainer); else if (modelAsConnection != null) - ConnectionInitiator.OpenConnection(modelAsConnection); + _connectionInitiator.OpenConnection(modelAsConnection); } } diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 5c1f3aed2..e93b5009a 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -187,6 +187,7 @@ + From 8970a15d4ed995fd141f5a52c97b19b993b148e6 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 13:33:12 -0700 Subject: [PATCH 061/106] added tests for one of the click handlers --- .../Tree/OpenConnectionClickHandlerTests.cs | 29 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + mRemoteV1/Tree/OpenConnectionClickHandler.cs | 9 +++++- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 4 +-- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs diff --git a/mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs b/mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs new file mode 100644 index 000000000..5e0f2dcbc --- /dev/null +++ b/mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs @@ -0,0 +1,29 @@ +using mRemoteNG.Connection; +using mRemoteNG.Tree; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class OpenConnectionClickHandlerTests + { + private OpenConnectionClickHandler _clickHandler; + private IConnectionInitiator _connectionInitiator; + + [SetUp] + public void Setup() + { + _connectionInitiator = Substitute.For(); + _clickHandler = new OpenConnectionClickHandler(_connectionInitiator); + } + + [Test] + public void ConnectionOpened() + { + var connectionInfo = new ConnectionInfo(); + _clickHandler.Execute(connectionInfo); + _connectionInitiator.Received().OpenConnection(connectionInfo); + } + } +} diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 7c0054d09..a1f737a7f 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -151,6 +151,7 @@ + Form diff --git a/mRemoteV1/Tree/OpenConnectionClickHandler.cs b/mRemoteV1/Tree/OpenConnectionClickHandler.cs index 22c1794e4..786e70bcf 100644 --- a/mRemoteV1/Tree/OpenConnectionClickHandler.cs +++ b/mRemoteV1/Tree/OpenConnectionClickHandler.cs @@ -5,11 +5,18 @@ namespace mRemoteNG.Tree { public class OpenConnectionClickHandler : ITreeNodeClickHandler { + private readonly IConnectionInitiator _connectionInitiator; + + public OpenConnectionClickHandler(IConnectionInitiator connectionInitiator) + { + _connectionInitiator = connectionInitiator; + } + public void Execute(ConnectionInfo clickedNode) { if (clickedNode == null) return; if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; - ConnectionInitiator.OpenConnection(clickedNode); + _connectionInitiator.OpenConnection(clickedNode); } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 259eed7ae..55164ef4b 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -103,7 +103,7 @@ namespace mRemoteNG.UI.Window olvConnections.DoubleClickHandler.ClickHandlers = new ITreeNodeClickHandler[] { new ExpandNodeClickHandler(olvConnections), - new OpenConnectionClickHandler() + new OpenConnectionClickHandler(_connectionInitiator) }; } @@ -112,7 +112,7 @@ namespace mRemoteNG.UI.Window var singleClickHandlers = new List(); if (Settings.Default.SingleClickOnConnectionOpensIt) - singleClickHandlers.Add(new OpenConnectionClickHandler()); + singleClickHandlers.Add(new OpenConnectionClickHandler(_connectionInitiator)); if (Settings.Default.SingleClickSwitchesToOpenConnection) singleClickHandlers.Add(new SwitchToConnectionClickHandler()); olvConnections.SingleClickHandler.ClickHandlers = singleClickHandlers; From 12da35f8756d062f5ba475424ce3f77e5848396e Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 13:57:15 -0700 Subject: [PATCH 062/106] made the rest of the connectioninitiator functions non-static --- mRemoteV1/App/Runtime.cs | 3 +- mRemoteV1/Connection/ConnectionInitiator.cs | 67 ++++++++++--------- mRemoteV1/Connection/IConnectionInitiator.cs | 8 +++ .../UI/Controls/ConnectionContextMenu.cs | 26 +++---- mRemoteV1/UI/Forms/frmMain.cs | 4 +- mRemoteV1/UI/Window/ConnectionWindow.cs | 6 +- 6 files changed, 63 insertions(+), 51 deletions(-) diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index 319f570bc..f052d06bd 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -593,7 +593,8 @@ namespace mRemoteNG.App connectionInfo.Protocol = url.StartsWith("https:") ? ProtocolType.HTTPS : ProtocolType.HTTP; connectionInfo.SetDefaultPort(); connectionInfo.IsQuickConnect = true; - ConnectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); + var connectionInitiator = new ConnectionInitiator(); + connectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); } public static void GoToWebsite() diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs index af392bea4..c8c19882d 100644 --- a/mRemoteV1/Connection/ConnectionInitiator.cs +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -14,25 +14,11 @@ namespace mRemoteNG.Connection { public class ConnectionInitiator : IConnectionInitiator { - public static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None) + public void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None) { OpenConnection(containerInfo, force, null); } - private static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force, Form conForm) - { - var children = containerInfo.Children; - if (children.Count == 0) return; - foreach (var child in children) - { - var childAsContainer = child as ContainerInfo; - if (childAsContainer != null) - OpenConnection(childAsContainer, force, conForm); - else - OpenConnection(child, force, conForm); - } - } - public void OpenConnection(ConnectionInfo connectionInfo) { try @@ -45,7 +31,7 @@ namespace mRemoteNG.Connection } } - public static void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force) + public void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force) { try { @@ -57,7 +43,35 @@ namespace mRemoteNG.Connection } } - private static void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force, Form conForm) + public bool SwitchToOpenConnection(ConnectionInfo connectionInfo) + { + var interfaceControl = FindConnectionContainer(connectionInfo); + if (interfaceControl == null) return false; + var connectionWindow = (ConnectionWindow)interfaceControl.FindForm(); + connectionWindow?.Focus(); + var findForm = (ConnectionWindow)interfaceControl.FindForm(); + findForm?.Show(frmMain.Default.pnlDock); + var tabPage = (TabPage)interfaceControl.Parent; + tabPage.Selected = true; + return true; + } + + #region Private + private void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force, Form conForm) + { + var children = containerInfo.Children; + if (children.Count == 0) return; + foreach (var child in children) + { + var childAsContainer = child as ContainerInfo; + if (childAsContainer != null) + OpenConnection(childAsContainer, force, conForm); + else + OpenConnection(child, force, conForm); + } + } + + private void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force, Form conForm) { try { @@ -115,19 +129,6 @@ namespace mRemoteNG.Connection extA?.Start(connectionInfo); } - public static bool SwitchToOpenConnection(ConnectionInfo nCi) - { - var IC = FindConnectionContainer(nCi); - if (IC == null) return false; - var connectionWindow = (ConnectionWindow)IC.FindForm(); - connectionWindow?.Focus(); - var findForm = (ConnectionWindow)IC.FindForm(); - findForm?.Show(frmMain.Default.pnlDock); - var tabPage = (TabPage)IC.Parent; - tabPage.Selected = true; - return true; - } - private static InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo) { if (connectionInfo.OpenConnections.Count <= 0) return null; @@ -214,10 +215,9 @@ namespace mRemoteNG.Connection { newProtocol.InterfaceControl = new InterfaceControl(connectionContainer, newProtocol, connectionInfo); } + #endregion - - - + #region Event handlers private static void Prot_Event_Disconnected(object sender, string disconnectedMessage) { try @@ -280,5 +280,6 @@ namespace mRemoteNG.Connection Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionEventConnectionFailed, ex); } } + #endregion } } \ No newline at end of file diff --git a/mRemoteV1/Connection/IConnectionInitiator.cs b/mRemoteV1/Connection/IConnectionInitiator.cs index 99e8732f8..5a0ff1d32 100644 --- a/mRemoteV1/Connection/IConnectionInitiator.cs +++ b/mRemoteV1/Connection/IConnectionInitiator.cs @@ -1,7 +1,15 @@ +using mRemoteNG.Container; + namespace mRemoteNG.Connection { public interface IConnectionInitiator { void OpenConnection(ConnectionInfo connectionInfo); + + void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None); + + void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force); + + bool SwitchToOpenConnection(ConnectionInfo connectionInfo); } } \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index dc48173b1..e4baf4c82 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -47,11 +47,13 @@ namespace mRemoteNG.UI.Controls private ToolStripMenuItem _cMenTreeImportActiveDirectory; private ToolStripMenuItem _cMenTreeImportPortScan; private readonly ConnectionTree _connectionTree; + private readonly IConnectionInitiator _connectionInitiator; public ConnectionContextMenu(ConnectionTree connectionTree) { _connectionTree = connectionTree; + _connectionInitiator = new ConnectionInitiator(); InitializeComponent(); ApplyLanguage(); EnableShortcutKeys(); @@ -591,54 +593,54 @@ namespace mRemoteNG.UI.Controls { var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DoNotJump); else - ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.DoNotJump); } private void OnConnectToConsoleSessionClicked(object sender, EventArgs e) { var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); else - ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); } private void OnDontConnectToConsoleSessionClicked(object sender, EventArgs e) { var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); else - ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); } private void OnConnectInFullscreenClicked(object sender, EventArgs e) { var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); else - ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); } private void OnConnectWithNoCredentialsClick(object sender, EventArgs e) { var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.NoCredentials); + _connectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.NoCredentials); else - ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.NoCredentials); + _connectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.NoCredentials); } private void OnChoosePanelBeforeConnectingClicked(object sender, EventArgs e) { var selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo; if (selectedNodeAsContainer != null) - ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); else - ConnectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(_connectionTree.SelectedNode, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); } private void OnDisconnectClicked(object sender, EventArgs e) diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 7d008ca5b..b886f1655 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -587,7 +587,7 @@ namespace mRemoteNG.UI.Forms foreach (var i in ICList) { i.Protocol.Close(); - ConnectionInitiator.OpenConnection(i.Info, ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(i.Info, ConnectionInfo.Force.DoNotJump); } // throw it on the garbage collector @@ -862,7 +862,7 @@ namespace mRemoteNG.UI.Forms return; } cmbQuickConnect.Add(connectionInfo); - ConnectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); } catch (Exception ex) { diff --git a/mRemoteV1/UI/Window/ConnectionWindow.cs b/mRemoteV1/UI/Window/ConnectionWindow.cs index ed367b818..c4f7ca62a 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.cs @@ -334,7 +334,7 @@ namespace mRemoteNG.UI.Window var modelAsContainer = model as ContainerInfo; var modelAsConnection = model as ConnectionInfo; if (modelAsContainer != null) - ConnectionInitiator.OpenConnection(modelAsContainer); + _connectionInitiator.OpenConnection(modelAsContainer); else if (modelAsConnection != null) _connectionInitiator.OpenConnection(modelAsConnection); } @@ -650,7 +650,7 @@ namespace mRemoteNG.UI.Window { var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; if (interfaceControl == null) return; - ConnectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); _ignoreChangeSelectedTabClick = false; } catch (Exception ex) @@ -666,7 +666,7 @@ namespace mRemoteNG.UI.Window var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; if (interfaceControl == null) return; interfaceControl.Protocol.Close(); - ConnectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); + _connectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); } catch (Exception ex) { From 1d46c44c213a71b7095611cb60f0686f65ae5d46 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 13:57:44 -0700 Subject: [PATCH 063/106] added tests for another click handler --- .../SwitchToConnectionClickHandlerTests.cs | 29 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + .../Tree/SwitchToConnectionClickHandler.cs | 9 +++++- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 2 +- 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs diff --git a/mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs b/mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs new file mode 100644 index 000000000..4fd60ede5 --- /dev/null +++ b/mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs @@ -0,0 +1,29 @@ +using mRemoteNG.Connection; +using mRemoteNG.Tree; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class SwitchToConnectionClickHandlerTests + { + private SwitchToConnectionClickHandler _clickHandler; + private IConnectionInitiator _connectionInitiator; + + [SetUp] + public void Setup() + { + _connectionInitiator = Substitute.For(); + _clickHandler = new SwitchToConnectionClickHandler(_connectionInitiator); + } + + [Test] + public void SwitchesToConnection() + { + var connectionInfo = new ConnectionInfo(); + _clickHandler.Execute(connectionInfo); + _connectionInitiator.Received().SwitchToOpenConnection(connectionInfo); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index a1f737a7f..b852759e3 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -153,6 +153,7 @@ + Form diff --git a/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs b/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs index fbb24eb39..23ec32c04 100644 --- a/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs +++ b/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs @@ -5,11 +5,18 @@ namespace mRemoteNG.Tree { public class SwitchToConnectionClickHandler : ITreeNodeClickHandler { + private readonly IConnectionInitiator _connectionInitiator; + + public SwitchToConnectionClickHandler(IConnectionInitiator connectionInitiator) + { + _connectionInitiator = connectionInitiator; + } + public void Execute(ConnectionInfo clickedNode) { if (clickedNode == null) return; if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; - ConnectionInitiator.SwitchToOpenConnection(clickedNode); + _connectionInitiator.SwitchToOpenConnection(clickedNode); } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 55164ef4b..1266a4a9f 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -114,7 +114,7 @@ namespace mRemoteNG.UI.Window if (Settings.Default.SingleClickOnConnectionOpensIt) singleClickHandlers.Add(new OpenConnectionClickHandler(_connectionInitiator)); if (Settings.Default.SingleClickSwitchesToOpenConnection) - singleClickHandlers.Add(new SwitchToConnectionClickHandler()); + singleClickHandlers.Add(new SwitchToConnectionClickHandler(_connectionInitiator)); olvConnections.SingleClickHandler.ClickHandlers = singleClickHandlers; } #endregion From b4f8ab0a49ce27fed9f99f42bb0fa5c5231bb4c9 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 14:13:35 -0700 Subject: [PATCH 064/106] moved a call to settings further up in the abstraction level to make testing easier --- mRemoteV1/Tree/PreviousSessionOpener.cs | 1 - mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 23 ++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/mRemoteV1/Tree/PreviousSessionOpener.cs b/mRemoteV1/Tree/PreviousSessionOpener.cs index 8d2a3a461..1e7c6e00e 100644 --- a/mRemoteV1/Tree/PreviousSessionOpener.cs +++ b/mRemoteV1/Tree/PreviousSessionOpener.cs @@ -13,7 +13,6 @@ namespace mRemoteNG.Tree public void Execute(ConnectionTree connectionTree) { - if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; var connectionInfoList = connectionTree.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); foreach (var connectionInfo in previouslyOpenedConnections) diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 1266a4a9f..720e796eb 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -88,16 +88,25 @@ namespace mRemoteNG.UI.Window olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; olvConnections.KeyDown += tvConnections_KeyDown; olvConnections.KeyPress += tvConnections_KeyPress; - olvConnections.PostSetupActions = new IConnectionTreeDelegate[] - { - new PreviouslyOpenedFolderExpander(), - new RootNodeExpander(), - new PreviousSessionOpener() - }; - SetConnectionTreeDoubleClickHandlers(); + SetTreePostSetupActions(); + SetConnectionTreeDoubleClickHandlers(); SetConnectionTreeSingleClickHandlers(); } + private void SetTreePostSetupActions() + { + var actions = new List + { + new PreviouslyOpenedFolderExpander(), + new RootNodeExpander() + }; + + if (Settings.Default.OpenConsFromLastSession && !Settings.Default.NoReconnect) + actions.Add(new PreviousSessionOpener()); + + olvConnections.PostSetupActions = actions; + } + private void SetConnectionTreeDoubleClickHandlers() { olvConnections.DoubleClickHandler.ClickHandlers = new ITreeNodeClickHandler[] From 77add0b39d25fd18e0384c99c2358607088dd682 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 15:08:12 -0700 Subject: [PATCH 065/106] added an interface for iconnectiontree. this kind of hacky and really just exists to make the tests work. this indicates we have some coupling on ConnectionTree that shouldn't be there.. --- mRemoteV1/UI/Controls/IConnectionTree.cs | 20 ++++++++++++++++++++ mRemoteV1/mRemoteV1.csproj | 1 + 2 files changed, 21 insertions(+) create mode 100644 mRemoteV1/UI/Controls/IConnectionTree.cs diff --git a/mRemoteV1/UI/Controls/IConnectionTree.cs b/mRemoteV1/UI/Controls/IConnectionTree.cs new file mode 100644 index 000000000..b1514039e --- /dev/null +++ b/mRemoteV1/UI/Controls/IConnectionTree.cs @@ -0,0 +1,20 @@ +using System.Collections; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.UI.Controls +{ + public interface IConnectionTree + { + ConnectionTreeModel ConnectionTreeModel { get; set; } + + IEnumerable ExpandedObjects { get; set; } + + RootNodeInfo GetRootConnectionNode(); + + void InvokeExpand(object model); + + void InvokeRebuildAll(bool preserveState); + } +} \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index e93b5009a..a79233871 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -244,6 +244,7 @@ FilteredPropertyGrid.cs + UserControl From 893d5d92f3206bdc87c99607d54bd5356c3fa6b6 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 15:09:05 -0700 Subject: [PATCH 066/106] made all relevant classes use IConnectionTree --- mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs | 2 +- mRemoteV1/Tree/RootNodeExpander.cs | 2 +- mRemoteV1/UI/Controls/ConnectionTree.cs | 13 +++++++++++-- mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs b/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs index b276da702..1c52d7165 100644 --- a/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs +++ b/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs @@ -7,7 +7,7 @@ namespace mRemoteNG.Tree { public class PreviouslyOpenedFolderExpander : IConnectionTreeDelegate { - public void Execute(ConnectionTree connectionTree) + public void Execute(IConnectionTree connectionTree) { var containerList = connectionTree.ConnectionTreeModel.GetRecursiveChildList(connectionTree.GetRootConnectionNode()).OfType(); var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); diff --git a/mRemoteV1/Tree/RootNodeExpander.cs b/mRemoteV1/Tree/RootNodeExpander.cs index a092ebbdf..bc02f0ae8 100644 --- a/mRemoteV1/Tree/RootNodeExpander.cs +++ b/mRemoteV1/Tree/RootNodeExpander.cs @@ -5,7 +5,7 @@ namespace mRemoteNG.Tree { public class RootNodeExpander : IConnectionTreeDelegate { - public void Execute(ConnectionTree connectionTree) + public void Execute(IConnectionTree connectionTree) { var rootConnectionNode = connectionTree.GetRootConnectionNode(); connectionTree.InvokeExpand(rootConnectionNode); diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 01ca2a5f9..41b3d0cf5 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -14,7 +14,7 @@ using mRemoteNG.Tree.Root; namespace mRemoteNG.UI.Controls { - public partial class ConnectionTree : TreeListView + public partial class ConnectionTree : TreeListView, IConnectionTree { private ConnectionTreeModel _connectionTreeModel; private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); @@ -32,7 +32,6 @@ namespace mRemoteNG.UI.Controls public TreeNodeSingleClickHandler SingleClickHandler { get; set; } = new TreeNodeSingleClickHandler(); - public ConnectionTreeModel ConnectionTreeModel { get { return _connectionTreeModel; } @@ -159,6 +158,16 @@ namespace mRemoteNG.UI.Controls return (RootNodeInfo)Roots.Cast().First(item => item is RootNodeInfo); } + void IConnectionTree.InvokeExpand(object model) + { + this.InvokeExpand(model); + } + + void IConnectionTree.InvokeRebuildAll(bool preserveState) + { + this.InvokeRebuildAll(preserveState); + } + public IEnumerable GetRootPuttyNodes() { return Objects.OfType(); diff --git a/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs b/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs index 07b1b73e6..77643a1e5 100644 --- a/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs +++ b/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs @@ -3,6 +3,6 @@ namespace mRemoteNG.UI.Controls { public interface IConnectionTreeDelegate { - void Execute(ConnectionTree connectionTree); + void Execute(IConnectionTree connectionTree); } } \ No newline at end of file From b3e6fd7b9619b2a5e764e29269427ac48ac718d2 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 15:09:24 -0700 Subject: [PATCH 067/106] created test for another tree handler --- .../Tree/PreviousSessionOpenerTests.cs | 42 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + mRemoteV1/Tree/PreviousSessionOpener.cs | 13 ++++-- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 2 +- 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs diff --git a/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs b/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs new file mode 100644 index 000000000..e8d0f2e6b --- /dev/null +++ b/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs @@ -0,0 +1,42 @@ +using mRemoteNG.Connection; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using mRemoteNG.UI.Controls; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class PreviousSessionOpenerTests + { + private PreviousSessionOpener _previousSessionOpener; + private IConnectionInitiator _connectionInitiator; + private IConnectionTree _connectionTree; + + [SetUp] + public void Setup() + { + _connectionInitiator = Substitute.For(); + _previousSessionOpener = new PreviousSessionOpener(_connectionInitiator); + _connectionTree = Substitute.For(); + _connectionTree.GetRootConnectionNode().Returns(BuildTree()); + } + + [Test] + public void AllRequestedSessionsAreReopened() + { + _previousSessionOpener.Execute(_connectionTree); + _connectionInitiator.ReceivedWithAnyArgs(2).OpenConnection(new ConnectionInfo()); + } + + private RootNodeInfo BuildTree() + { + var root = new RootNodeInfo(RootNodeType.Connection); + root.AddChild(new ConnectionInfo { PleaseConnect = true }); + root.AddChild(new ConnectionInfo()); + root.AddChild(new ConnectionInfo { PleaseConnect = true }); + return root; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index b852759e3..451abdd53 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -152,6 +152,7 @@ + diff --git a/mRemoteV1/Tree/PreviousSessionOpener.cs b/mRemoteV1/Tree/PreviousSessionOpener.cs index 1e7c6e00e..5df20c8ac 100644 --- a/mRemoteV1/Tree/PreviousSessionOpener.cs +++ b/mRemoteV1/Tree/PreviousSessionOpener.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.UI.Controls; @@ -8,10 +9,16 @@ namespace mRemoteNG.Tree { public class PreviousSessionOpener : IConnectionTreeDelegate { - private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + private readonly IConnectionInitiator _connectionInitiator; + public PreviousSessionOpener(IConnectionInitiator connectionInitiator) + { + if (connectionInitiator == null) + throw new ArgumentNullException(nameof(connectionInitiator)); + _connectionInitiator = connectionInitiator; + } - public void Execute(ConnectionTree connectionTree) + public void Execute(IConnectionTree connectionTree) { var connectionInfoList = connectionTree.GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 720e796eb..68b1dea04 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -102,7 +102,7 @@ namespace mRemoteNG.UI.Window }; if (Settings.Default.OpenConsFromLastSession && !Settings.Default.NoReconnect) - actions.Add(new PreviousSessionOpener()); + actions.Add(new PreviousSessionOpener(_connectionInitiator)); olvConnections.PostSetupActions = actions; } From 16b094be449fc21e6fab2a85affd3a47d718e307 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 15:16:55 -0700 Subject: [PATCH 068/106] we no longer need the extensions now that we are subclassing TreeListView --- mRemoteV1/Tree/ObjectListViewExtensions.cs | 24 ---------------------- mRemoteV1/UI/Controls/ConnectionTree.cs | 9 ++++---- mRemoteV1/mRemoteV1.csproj | 1 - 3 files changed, 5 insertions(+), 29 deletions(-) delete mode 100644 mRemoteV1/Tree/ObjectListViewExtensions.cs diff --git a/mRemoteV1/Tree/ObjectListViewExtensions.cs b/mRemoteV1/Tree/ObjectListViewExtensions.cs deleted file mode 100644 index 2e7c1b554..000000000 --- a/mRemoteV1/Tree/ObjectListViewExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Windows.Forms; -using BrightIdeasSoftware; - - -namespace mRemoteNG.Tree -{ - public static class ObjectListViewExtensions - { - public static void Invoke(this Control control, MethodInvoker action) - { - control.Invoke(action); - } - - public static void InvokeExpand(this TreeListView control, object model) - { - control.Invoke(() => control.Expand(model)); - } - - public static void InvokeRebuildAll(this TreeListView control, bool preserveState) - { - control.Invoke(() => control.RebuildAll(preserveState)); - } - } -} \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree.cs index 41b3d0cf5..51e5085f6 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; +using System.Windows.Forms; using BrightIdeasSoftware; using mRemoteNG.App; using mRemoteNG.Config.Putty; @@ -158,14 +159,14 @@ namespace mRemoteNG.UI.Controls return (RootNodeInfo)Roots.Cast().First(item => item is RootNodeInfo); } - void IConnectionTree.InvokeExpand(object model) + public void InvokeExpand(object model) { - this.InvokeExpand(model); + Invoke((MethodInvoker)(() => Expand(model))); } - void IConnectionTree.InvokeRebuildAll(bool preserveState) + public void InvokeRebuildAll(bool preserveState) { - this.InvokeRebuildAll(preserveState); + Invoke((MethodInvoker)(() => RebuildAll(preserveState))); } public IEnumerable GetRootPuttyNodes() diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index a79233871..b5649435d 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -219,7 +219,6 @@ - From ac0aa8daf48a94ffe0adcb816fbd6c098f5e324b Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 15:20:32 -0700 Subject: [PATCH 069/106] added a method to the IConnectionTree interface to make testing another class possible --- mRemoteV1/Tree/ExpandNodeClickHandler.cs | 4 ++-- mRemoteV1/UI/Controls/IConnectionTree.cs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mRemoteV1/Tree/ExpandNodeClickHandler.cs b/mRemoteV1/Tree/ExpandNodeClickHandler.cs index 5376d731c..63ae56e6e 100644 --- a/mRemoteV1/Tree/ExpandNodeClickHandler.cs +++ b/mRemoteV1/Tree/ExpandNodeClickHandler.cs @@ -8,9 +8,9 @@ namespace mRemoteNG.Tree { public class ExpandNodeClickHandler : ITreeNodeClickHandler { - private readonly ConnectionTree _connectionTree; + private readonly IConnectionTree _connectionTree; - public ExpandNodeClickHandler(ConnectionTree connectionTree) + public ExpandNodeClickHandler(IConnectionTree connectionTree) { if (connectionTree == null) throw new ArgumentNullException(nameof(connectionTree)); diff --git a/mRemoteV1/UI/Controls/IConnectionTree.cs b/mRemoteV1/UI/Controls/IConnectionTree.cs index b1514039e..9f69a0d9c 100644 --- a/mRemoteV1/UI/Controls/IConnectionTree.cs +++ b/mRemoteV1/UI/Controls/IConnectionTree.cs @@ -16,5 +16,7 @@ namespace mRemoteNG.UI.Controls void InvokeExpand(object model); void InvokeRebuildAll(bool preserveState); + + void ToggleExpansion(object model); } } \ No newline at end of file From 6cc668fe83846f6078ed32803c88aa0095f859ff Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 12 Jan 2017 15:30:30 -0700 Subject: [PATCH 070/106] added more tests for connectiontree delegates --- .../Tree/ExpandNodeClickHandlerTests.cs | 39 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + 2 files changed, 40 insertions(+) create mode 100644 mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs diff --git a/mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs b/mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs new file mode 100644 index 000000000..be1d74927 --- /dev/null +++ b/mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs @@ -0,0 +1,39 @@ +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using mRemoteNG.UI.Controls; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class ExpandNodeClickHandlerTests + { + private ExpandNodeClickHandler _clickHandler; + private IConnectionTree _connectionTree; + + [SetUp] + public void Setup() + { + _connectionTree = Substitute.For(); + _clickHandler = new ExpandNodeClickHandler(_connectionTree); + } + + [Test] + public void TargetedNodeIsExpanded() + { + var folder = new ContainerInfo(); + _clickHandler.Execute(folder); + _connectionTree.Received().ToggleExpansion(folder); + } + + [Test] + public void NothingHappensWhenConnectionInfoProvided() + { + _clickHandler.Execute(new ConnectionInfo()); + _connectionTree.DidNotReceiveWithAnyArgs().ToggleExpansion(new ConnectionInfo()); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 451abdd53..fdf827b63 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -150,6 +150,7 @@ + From ce5d0cefe375c12bbb2f2d5d564d3a2de9c36fa0 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 13 Jan 2017 10:41:28 -0700 Subject: [PATCH 071/106] organized some files --- .../{ => ConnectionTree}/ConnectionTree.Designer.cs | 0 .../UI/Controls/{ => ConnectionTree}/ConnectionTree.cs | 0 .../Controls/{ => ConnectionTree}/IConnectionTree.cs | 0 .../{ => ConnectionTree}/IConnectionTreeDelegate.cs | 0 .../UI/Controls/{ => ConnectionTree}/NameColumn.cs | 0 mRemoteV1/mRemoteV1.csproj | 10 +++++----- mRemoteV1/mRemoteV1.csproj.DotSettings | 2 ++ 7 files changed, 7 insertions(+), 5 deletions(-) rename mRemoteV1/UI/Controls/{ => ConnectionTree}/ConnectionTree.Designer.cs (100%) rename mRemoteV1/UI/Controls/{ => ConnectionTree}/ConnectionTree.cs (100%) rename mRemoteV1/UI/Controls/{ => ConnectionTree}/IConnectionTree.cs (100%) rename mRemoteV1/UI/Controls/{ => ConnectionTree}/IConnectionTreeDelegate.cs (100%) rename mRemoteV1/UI/Controls/{ => ConnectionTree}/NameColumn.cs (100%) create mode 100644 mRemoteV1/mRemoteV1.csproj.DotSettings diff --git a/mRemoteV1/UI/Controls/ConnectionTree.Designer.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.Designer.cs similarity index 100% rename from mRemoteV1/UI/Controls/ConnectionTree.Designer.cs rename to mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.Designer.cs diff --git a/mRemoteV1/UI/Controls/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs similarity index 100% rename from mRemoteV1/UI/Controls/ConnectionTree.cs rename to mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs diff --git a/mRemoteV1/UI/Controls/IConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/IConnectionTree.cs similarity index 100% rename from mRemoteV1/UI/Controls/IConnectionTree.cs rename to mRemoteV1/UI/Controls/ConnectionTree/IConnectionTree.cs diff --git a/mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs b/mRemoteV1/UI/Controls/ConnectionTree/IConnectionTreeDelegate.cs similarity index 100% rename from mRemoteV1/UI/Controls/IConnectionTreeDelegate.cs rename to mRemoteV1/UI/Controls/ConnectionTree/IConnectionTreeDelegate.cs diff --git a/mRemoteV1/UI/Controls/NameColumn.cs b/mRemoteV1/UI/Controls/ConnectionTree/NameColumn.cs similarity index 100% rename from mRemoteV1/UI/Controls/NameColumn.cs rename to mRemoteV1/UI/Controls/ConnectionTree/NameColumn.cs diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index b5649435d..2514dd25a 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -230,10 +230,10 @@ Component - + Component - + ConnectionTree.cs @@ -243,12 +243,12 @@ FilteredPropertyGrid.cs - + UserControl - - + + Component diff --git a/mRemoteV1/mRemoteV1.csproj.DotSettings b/mRemoteV1/mRemoteV1.csproj.DotSettings new file mode 100644 index 000000000..294c0624e --- /dev/null +++ b/mRemoteV1/mRemoteV1.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file From 2ce31f35cc287c75a61c53cea89ab7b3a0d05f28 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 13 Jan 2017 10:54:39 -0700 Subject: [PATCH 072/106] more file organizing --- .../{ => ClickHandlers}/ExpandNodeClickHandler.cs | 0 .../{ => ClickHandlers}/ITreeNodeClickHandler.cs | 0 .../OpenConnectionClickHandler.cs | 0 .../SwitchToConnectionClickHandler.cs | 0 .../TreeNodeDoubleClickHandler.cs | 0 .../TreeNodeSingleClickHandler.cs | 0 mRemoteV1/mRemoteV1.csproj | 12 ++++++------ mRemoteV1/mRemoteV1.csproj.DotSettings | 1 + 8 files changed, 7 insertions(+), 6 deletions(-) rename mRemoteV1/Tree/{ => ClickHandlers}/ExpandNodeClickHandler.cs (100%) rename mRemoteV1/Tree/{ => ClickHandlers}/ITreeNodeClickHandler.cs (100%) rename mRemoteV1/Tree/{ => ClickHandlers}/OpenConnectionClickHandler.cs (100%) rename mRemoteV1/Tree/{ => ClickHandlers}/SwitchToConnectionClickHandler.cs (100%) rename mRemoteV1/Tree/{ => ClickHandlers}/TreeNodeDoubleClickHandler.cs (100%) rename mRemoteV1/Tree/{ => ClickHandlers}/TreeNodeSingleClickHandler.cs (100%) diff --git a/mRemoteV1/Tree/ExpandNodeClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/ExpandNodeClickHandler.cs similarity index 100% rename from mRemoteV1/Tree/ExpandNodeClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/ExpandNodeClickHandler.cs diff --git a/mRemoteV1/Tree/ITreeNodeClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/ITreeNodeClickHandler.cs similarity index 100% rename from mRemoteV1/Tree/ITreeNodeClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/ITreeNodeClickHandler.cs diff --git a/mRemoteV1/Tree/OpenConnectionClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs similarity index 100% rename from mRemoteV1/Tree/OpenConnectionClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs diff --git a/mRemoteV1/Tree/SwitchToConnectionClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs similarity index 100% rename from mRemoteV1/Tree/SwitchToConnectionClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs diff --git a/mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/TreeNodeDoubleClickHandler.cs similarity index 100% rename from mRemoteV1/Tree/TreeNodeDoubleClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/TreeNodeDoubleClickHandler.cs diff --git a/mRemoteV1/Tree/TreeNodeSingleClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/TreeNodeSingleClickHandler.cs similarity index 100% rename from mRemoteV1/Tree/TreeNodeSingleClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/TreeNodeSingleClickHandler.cs diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 2514dd25a..b59da048d 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -215,18 +215,18 @@ - - + + - + - - - + + + Component diff --git a/mRemoteV1/mRemoteV1.csproj.DotSettings b/mRemoteV1/mRemoteV1.csproj.DotSettings index 294c0624e..07f70d627 100644 --- a/mRemoteV1/mRemoteV1.csproj.DotSettings +++ b/mRemoteV1/mRemoteV1.csproj.DotSettings @@ -1,2 +1,3 @@  + True True \ No newline at end of file From 166d9f7133b1171ca6fb555fe19320d4ca9f42de Mon Sep 17 00:00:00 2001 From: countchappy Date: Fri, 13 Jan 2017 13:41:19 -0500 Subject: [PATCH 073/106] RDP Minutes to Idle Timeout - Update 2 Added null conditional operator to prevent throwing a null reference error for beta users. --- mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index 8b7965ee1..22a90eeac 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -487,8 +487,8 @@ namespace mRemoteNG.Config.Serializers { connectionInfo.SoundQuality = (ProtocolRDP.RDPSoundQuality)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPSoundQuality), Convert.ToString(xmlnode.Attributes["SoundQuality"].Value)); connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); - connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"].Value); - connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"].Value); + connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"].Value ?? "0"); + connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"].Value ?? "False"); } } catch (Exception ex) From 05d8b7983a3df70c98d12dfdbc17d24d1d38e0fd Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 13 Jan 2017 12:12:22 -0700 Subject: [PATCH 074/106] reorganized some test files and added tests for null args --- .../ExpandNodeClickHandlerTests.cs | 11 +++++++++-- .../OpenConnectionClickHandlerTests.cs | 10 +++++++++- .../SwitchToConnectionClickHandlerTests.cs | 10 +++++++++- mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs | 10 +++++++++- mRemoteNGTests/mRemoteNGTests.csproj | 6 +++--- mRemoteNGTests/mRemoteNGTests.csproj.DotSettings | 2 ++ .../Tree/ClickHandlers/OpenConnectionClickHandler.cs | 5 ++++- .../ClickHandlers/SwitchToConnectionClickHandler.cs | 5 ++++- 8 files changed, 49 insertions(+), 10 deletions(-) rename mRemoteNGTests/Tree/{ => ClickHandlers}/ExpandNodeClickHandlerTests.cs (77%) rename mRemoteNGTests/Tree/{ => ClickHandlers}/OpenConnectionClickHandlerTests.cs (71%) rename mRemoteNGTests/Tree/{ => ClickHandlers}/SwitchToConnectionClickHandlerTests.cs (71%) create mode 100644 mRemoteNGTests/mRemoteNGTests.csproj.DotSettings diff --git a/mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/ExpandNodeClickHandlerTests.cs similarity index 77% rename from mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs rename to mRemoteNGTests/Tree/ClickHandlers/ExpandNodeClickHandlerTests.cs index be1d74927..e4ffcb641 100644 --- a/mRemoteNGTests/Tree/ExpandNodeClickHandlerTests.cs +++ b/mRemoteNGTests/Tree/ClickHandlers/ExpandNodeClickHandlerTests.cs @@ -1,7 +1,7 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; using mRemoteNG.UI.Controls; using NSubstitute; using NUnit.Framework; @@ -35,5 +35,12 @@ namespace mRemoteNGTests.Tree _clickHandler.Execute(new ConnectionInfo()); _connectionTree.DidNotReceiveWithAnyArgs().ToggleExpansion(new ConnectionInfo()); } + + [Test] + public void ExceptionThrownOnConstructorNullArg() + { + // ReSharper disable once ObjectCreationAsStatement + Assert.Throws(() => new ExpandNodeClickHandler(null)); + } } } \ No newline at end of file diff --git a/mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs similarity index 71% rename from mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs rename to mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs index 5e0f2dcbc..5ceda527d 100644 --- a/mRemoteNGTests/Tree/OpenConnectionClickHandlerTests.cs +++ b/mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs @@ -1,4 +1,5 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; using mRemoteNG.Tree; using NSubstitute; using NUnit.Framework; @@ -25,5 +26,12 @@ namespace mRemoteNGTests.Tree _clickHandler.Execute(connectionInfo); _connectionInitiator.Received().OpenConnection(connectionInfo); } + + [Test] + public void ExceptionThrownWhenConstructorGivenNullArg() + { + // ReSharper disable once ObjectCreationAsStatement + Assert.Throws(() => new OpenConnectionClickHandler(null)); + } } } diff --git a/mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs similarity index 71% rename from mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs rename to mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs index 4fd60ede5..d58bf9e9a 100644 --- a/mRemoteNGTests/Tree/SwitchToConnectionClickHandlerTests.cs +++ b/mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs @@ -1,4 +1,5 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; using mRemoteNG.Tree; using NSubstitute; using NUnit.Framework; @@ -25,5 +26,12 @@ namespace mRemoteNGTests.Tree _clickHandler.Execute(connectionInfo); _connectionInitiator.Received().SwitchToOpenConnection(connectionInfo); } + + [Test] + public void ExceptionThrownWhenConstructorGivenNullArg() + { + // ReSharper disable once ObjectCreationAsStatement + Assert.Throws(() => new SwitchToConnectionClickHandler(null)); + } } } \ No newline at end of file diff --git a/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs b/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs index e8d0f2e6b..372296fad 100644 --- a/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs +++ b/mRemoteNGTests/Tree/PreviousSessionOpenerTests.cs @@ -1,4 +1,5 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using mRemoteNG.UI.Controls; @@ -30,6 +31,13 @@ namespace mRemoteNGTests.Tree _connectionInitiator.ReceivedWithAnyArgs(2).OpenConnection(new ConnectionInfo()); } + [Test] + public void ExceptionThrownWhenConstructorGivenNullArg() + { + // ReSharper disable once ObjectCreationAsStatement + Assert.Throws(() => new PreviousSessionOpener(null)); + } + private RootNodeInfo BuildTree() { var root = new RootNodeInfo(RootNodeType.Connection); diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index fdf827b63..4652c0ae3 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -150,12 +150,12 @@ - + - + - + Form diff --git a/mRemoteNGTests/mRemoteNGTests.csproj.DotSettings b/mRemoteNGTests/mRemoteNGTests.csproj.DotSettings new file mode 100644 index 000000000..1b5bada58 --- /dev/null +++ b/mRemoteNGTests/mRemoteNGTests.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs index 786e70bcf..75d3f1972 100644 --- a/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs +++ b/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs @@ -1,4 +1,5 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; namespace mRemoteNG.Tree @@ -9,6 +10,8 @@ namespace mRemoteNG.Tree public OpenConnectionClickHandler(IConnectionInitiator connectionInitiator) { + if (connectionInitiator == null) + throw new ArgumentNullException(nameof(connectionInitiator)); _connectionInitiator = connectionInitiator; } diff --git a/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs index 23ec32c04..7c950e130 100644 --- a/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs +++ b/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs @@ -1,4 +1,5 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; namespace mRemoteNG.Tree @@ -9,6 +10,8 @@ namespace mRemoteNG.Tree public SwitchToConnectionClickHandler(IConnectionInitiator connectionInitiator) { + if (connectionInitiator == null) + throw new ArgumentNullException(nameof(connectionInitiator)); _connectionInitiator = connectionInitiator; } From c33095cd0e93703d5b8aedeb1042fb249dc03c99 Mon Sep 17 00:00:00 2001 From: countchappy Date: Fri, 13 Jan 2017 17:11:07 -0500 Subject: [PATCH 075/106] RDP Minutes to Idle Timeout - Update 2.1 Fixed my goof! --- mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index 22a90eeac..2ad45255c 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -487,8 +487,8 @@ namespace mRemoteNG.Config.Serializers { connectionInfo.SoundQuality = (ProtocolRDP.RDPSoundQuality)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPSoundQuality), Convert.ToString(xmlnode.Attributes["SoundQuality"].Value)); connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); - connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"].Value ?? "0"); - connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"].Value ?? "False"); + connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0"); + connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False"); } } catch (Exception ex) From c897eae04e3c341960e0018ecf8d9567cdf843dc Mon Sep 17 00:00:00 2001 From: countchappy Date: Fri, 13 Jan 2017 18:08:36 -0500 Subject: [PATCH 076/106] RDP Minutes to Idle Timeout - Update 3 Fixed name and description not showing up in the config window. --- .../Resources/Language/Language.Designer.cs | 36 +++++++++---------- mRemoteV1/Resources/Language/Language.resx | 4 +-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 9d48fdb97..21ee69f1a 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -4018,15 +4018,6 @@ namespace mRemoteNG { } } - /// - /// Looks up a localized string similar to The number of minutes for the RDP session to sit idle before automatically disconnecting (for no limit use 0). - /// - internal static string strPropertyDescriptionMinutesToIdleTimeout { - get { - return ResourceManager.GetString("strPropertyDescriptionMinutesToIdleTimeout", resourceCulture); - } - } - /// /// Looks up a localized string similar to This is the name that will be displayed in the connections tree.. /// @@ -4126,6 +4117,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to The number of minutes for the RDP session to sit idle before automatically disconnecting (for no limit use 0). + /// + internal static string strPropertyDescriptionRDPMinutesToIdleTimeout { + get { + return ResourceManager.GetString("strPropertyDescriptionRDPMinutesToIdleTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Select whether local disk drives should be shown on the remote host.. /// @@ -4504,15 +4504,6 @@ namespace mRemoteNG { } } - /// - /// Looks up a localized string similar to Minutes to Idle. - /// - internal static string strPropertyNameMinutesToIdleTimeout { - get { - return ResourceManager.GetString("strPropertyNameMinutesToIdleTimeout", resourceCulture); - } - } - /// /// Looks up a localized string similar to Name. /// @@ -4621,6 +4612,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Minutes to Idle. + /// + internal static string strPropertyNameRDPMinutesToIdleTimeout { + get { + return ResourceManager.GetString("strPropertyNameRDPMinutesToIdleTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Disk Drives. /// diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index 43c27f006..cc0a13971 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2421,10 +2421,10 @@ mRemoteNG will now quit and begin with the installation. Download - + The number of minutes for the RDP session to sit idle before automatically disconnecting (for no limit use 0) - + Minutes to Idle \ No newline at end of file From 5a61c6b7dffc2e124b14b26f5f3f9f7d55e137b4 Mon Sep 17 00:00:00 2001 From: countchappy Date: Fri, 13 Jan 2017 18:49:39 -0500 Subject: [PATCH 077/106] RDP Minutes to Idle Timeout - Update 3.1 --- mRemoteV1/Connection/AbstractConnectionInfoData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mRemoteV1/Connection/AbstractConnectionInfoData.cs b/mRemoteV1/Connection/AbstractConnectionInfoData.cs index 83197c815..d3166cdb2 100644 --- a/mRemoteV1/Connection/AbstractConnectionInfoData.cs +++ b/mRemoteV1/Connection/AbstractConnectionInfoData.cs @@ -227,8 +227,8 @@ namespace mRemoteNG.Connection } [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameMinutesToIdleTimeout"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionMinutesToIdleTimeout")] + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPMinutesToIdleTimeout"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPMinutesToIdleTimeout")] public virtual int RDPMinutesToIdleTimeout { get { return GetPropertyValue("RDPMinutesToIdleTimeout", _rdpMinutesToIdleTimeout); } From fd7adf3c64942cab644f1a7192b2178aebc383b2 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 13 Jan 2017 17:43:06 -0700 Subject: [PATCH 078/106] added some more tests --- .../OpenConnectionClickHandlerTests.cs | 14 ++++++++++++++ .../SwitchToConnectionClickHandlerTests.cs | 14 ++++++++++++++ .../ClickHandlers/OpenConnectionClickHandler.cs | 3 ++- .../SwitchToConnectionClickHandler.cs | 3 ++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs index 5ceda527d..a6f19f96a 100644 --- a/mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs +++ b/mRemoteNGTests/Tree/ClickHandlers/OpenConnectionClickHandlerTests.cs @@ -1,5 +1,6 @@ using System; using mRemoteNG.Connection; +using mRemoteNG.Container; using mRemoteNG.Tree; using NSubstitute; using NUnit.Framework; @@ -27,11 +28,24 @@ namespace mRemoteNGTests.Tree _connectionInitiator.Received().OpenConnection(connectionInfo); } + [Test] + public void DoesNothingWhenGivenContainerInfo() + { + _clickHandler.Execute(new ContainerInfo()); + _connectionInitiator.DidNotReceiveWithAnyArgs().OpenConnection(new ConnectionInfo()); + } + [Test] public void ExceptionThrownWhenConstructorGivenNullArg() { // ReSharper disable once ObjectCreationAsStatement Assert.Throws(() => new OpenConnectionClickHandler(null)); } + + [Test] + public void ThrowWhenExecuteGivenNullArg() + { + Assert.Throws(() => _clickHandler.Execute(null)); + } } } diff --git a/mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs index d58bf9e9a..5cbdcd89c 100644 --- a/mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs +++ b/mRemoteNGTests/Tree/ClickHandlers/SwitchToConnectionClickHandlerTests.cs @@ -1,5 +1,6 @@ using System; using mRemoteNG.Connection; +using mRemoteNG.Container; using mRemoteNG.Tree; using NSubstitute; using NUnit.Framework; @@ -27,11 +28,24 @@ namespace mRemoteNGTests.Tree _connectionInitiator.Received().SwitchToOpenConnection(connectionInfo); } + [Test] + public void DoesNothingWhenGivenContainerInfo() + { + _clickHandler.Execute(new ContainerInfo()); + _connectionInitiator.DidNotReceiveWithAnyArgs().SwitchToOpenConnection(new ConnectionInfo()); + } + [Test] public void ExceptionThrownWhenConstructorGivenNullArg() { // ReSharper disable once ObjectCreationAsStatement Assert.Throws(() => new SwitchToConnectionClickHandler(null)); } + + [Test] + public void ThrowWhenExecuteGivenNullArg() + { + Assert.Throws(() => _clickHandler.Execute(null)); + } } } \ No newline at end of file diff --git a/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs index 75d3f1972..078d94e81 100644 --- a/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs +++ b/mRemoteV1/Tree/ClickHandlers/OpenConnectionClickHandler.cs @@ -17,7 +17,8 @@ namespace mRemoteNG.Tree public void Execute(ConnectionInfo clickedNode) { - if (clickedNode == null) return; + if (clickedNode == null) + throw new ArgumentNullException(nameof(clickedNode)); if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; _connectionInitiator.OpenConnection(clickedNode); } diff --git a/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs index 7c950e130..5ed5ddf95 100644 --- a/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs +++ b/mRemoteV1/Tree/ClickHandlers/SwitchToConnectionClickHandler.cs @@ -17,7 +17,8 @@ namespace mRemoteNG.Tree public void Execute(ConnectionInfo clickedNode) { - if (clickedNode == null) return; + if (clickedNode == null) + throw new ArgumentNullException(nameof(clickedNode)); if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; _connectionInitiator.SwitchToOpenConnection(clickedNode); } From 9b42dc9f10ac22cae5b8d5ddbb6a8a522a636d38 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 14 Jan 2017 10:11:22 -0700 Subject: [PATCH 079/106] Refactored some click handlers and created a test for it During testing I realized that the double and single click handlers were exactly the same thing, so i combined them into the composite click handler. --- .../TreeNodeCompositeClickHandlerTests.cs | 32 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + ...er.cs => TreeNodeCompositeClickHandler.cs} | 2 +- .../TreeNodeSingleClickHandler.cs | 20 ------------ .../Controls/ConnectionTree/ConnectionTree.cs | 4 +-- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 26 ++++++++------- mRemoteV1/mRemoteV1.csproj | 3 +- 7 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs rename mRemoteV1/Tree/ClickHandlers/{TreeNodeDoubleClickHandler.cs => TreeNodeCompositeClickHandler.cs} (86%) delete mode 100644 mRemoteV1/Tree/ClickHandlers/TreeNodeSingleClickHandler.cs diff --git a/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs new file mode 100644 index 000000000..ee80e8a55 --- /dev/null +++ b/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs @@ -0,0 +1,32 @@ +using mRemoteNG.Connection; +using mRemoteNG.Tree; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class TreeNodeCompositeClickHandlerTests + { + private TreeNodeCompositeClickHandler _clickHandler; + private ConnectionInfo _connectionInfo; + + [SetUp] + public void Setup() + { + _clickHandler = new TreeNodeCompositeClickHandler(); + _connectionInfo = new ConnectionInfo(); + } + + [Test] + public void ExecutesAllItsHandlers() + { + var handler1 = Substitute.For(); + var handler2 = Substitute.For(); + _clickHandler.ClickHandlers = new[] {handler1, handler2}; + _clickHandler.Execute(_connectionInfo); + handler1.Received().Execute(_connectionInfo); + handler2.Received().Execute(_connectionInfo); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 4652c0ae3..f716a47fe 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -130,6 +130,7 @@ + diff --git a/mRemoteV1/Tree/ClickHandlers/TreeNodeDoubleClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs similarity index 86% rename from mRemoteV1/Tree/ClickHandlers/TreeNodeDoubleClickHandler.cs rename to mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs index 333ae08a8..81581e30b 100644 --- a/mRemoteV1/Tree/ClickHandlers/TreeNodeDoubleClickHandler.cs +++ b/mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs @@ -4,7 +4,7 @@ using mRemoteNG.Connection; namespace mRemoteNG.Tree { - public class TreeNodeDoubleClickHandler : ITreeNodeClickHandler + public class TreeNodeCompositeClickHandler : ITreeNodeClickHandler { public IEnumerable ClickHandlers { get; set; } = new ITreeNodeClickHandler[0]; diff --git a/mRemoteV1/Tree/ClickHandlers/TreeNodeSingleClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/TreeNodeSingleClickHandler.cs deleted file mode 100644 index 5ce6f847b..000000000 --- a/mRemoteV1/Tree/ClickHandlers/TreeNodeSingleClickHandler.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using mRemoteNG.Connection; - - -namespace mRemoteNG.Tree -{ - public class TreeNodeSingleClickHandler : ITreeNodeClickHandler - { - public IEnumerable ClickHandlers { get; set; } = new ITreeNodeClickHandler[0]; - - public void Execute(ConnectionInfo clickedNode) - { - if (clickedNode == null) return; - foreach (var handler in ClickHandlers) - { - handler.Execute(clickedNode); - } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index 51e5085f6..d7a9a02da 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -29,9 +29,9 @@ namespace mRemoteNG.UI.Controls public IEnumerable PostSetupActions { get; set; } = new IConnectionTreeDelegate[0]; - public TreeNodeDoubleClickHandler DoubleClickHandler { get; set; } = new TreeNodeDoubleClickHandler(); + public ITreeNodeClickHandler DoubleClickHandler { get; set; } = new TreeNodeCompositeClickHandler(); - public TreeNodeSingleClickHandler SingleClickHandler { get; set; } = new TreeNodeSingleClickHandler(); + public ITreeNodeClickHandler SingleClickHandler { get; set; } = new TreeNodeCompositeClickHandler(); public ConnectionTreeModel ConnectionTreeModel { diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 68b1dea04..94da163fe 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -109,22 +109,26 @@ namespace mRemoteNG.UI.Window private void SetConnectionTreeDoubleClickHandlers() { - olvConnections.DoubleClickHandler.ClickHandlers = new ITreeNodeClickHandler[] - { - new ExpandNodeClickHandler(olvConnections), - new OpenConnectionClickHandler(_connectionInitiator) - }; - } + var doubleClickHandler = new TreeNodeCompositeClickHandler + { + ClickHandlers = new ITreeNodeClickHandler[] + { + new ExpandNodeClickHandler(olvConnections), + new OpenConnectionClickHandler(_connectionInitiator) + } + }; + olvConnections.DoubleClickHandler = doubleClickHandler; + } private void SetConnectionTreeSingleClickHandlers() { - - var singleClickHandlers = new List(); + var handlers = new List(); if (Settings.Default.SingleClickOnConnectionOpensIt) - singleClickHandlers.Add(new OpenConnectionClickHandler(_connectionInitiator)); + handlers.Add(new OpenConnectionClickHandler(_connectionInitiator)); if (Settings.Default.SingleClickSwitchesToOpenConnection) - singleClickHandlers.Add(new SwitchToConnectionClickHandler(_connectionInitiator)); - olvConnections.SingleClickHandler.ClickHandlers = singleClickHandlers; + handlers.Add(new SwitchToConnectionClickHandler(_connectionInitiator)); + var singleClickHandler = new TreeNodeCompositeClickHandler {ClickHandlers = handlers}; + olvConnections.SingleClickHandler = singleClickHandler; } #endregion diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index b59da048d..dbbee77ca 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -225,8 +225,7 @@ - - + Component From d03f830622cb074ee96b2fa8fb7e32bdd4d02823 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 14 Jan 2017 10:36:54 -0700 Subject: [PATCH 080/106] added null test for the composite click handler --- .../ClickHandlers/TreeNodeCompositeClickHandlerTests.cs | 9 ++++++++- .../Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs b/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs index ee80e8a55..d024bcebf 100644 --- a/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs +++ b/mRemoteNGTests/Tree/ClickHandlers/TreeNodeCompositeClickHandlerTests.cs @@ -1,4 +1,5 @@ -using mRemoteNG.Connection; +using System; +using mRemoteNG.Connection; using mRemoteNG.Tree; using NSubstitute; using NUnit.Framework; @@ -28,5 +29,11 @@ namespace mRemoteNGTests.Tree handler1.Received().Execute(_connectionInfo); handler2.Received().Execute(_connectionInfo); } + + [Test] + public void ThrowWhenExecuteGivenNullArg() + { + Assert.Throws(() => _clickHandler.Execute(null)); + } } } \ No newline at end of file diff --git a/mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs b/mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs index 81581e30b..39c7a7c25 100644 --- a/mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs +++ b/mRemoteV1/Tree/ClickHandlers/TreeNodeCompositeClickHandler.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using mRemoteNG.Connection; @@ -10,7 +11,8 @@ namespace mRemoteNG.Tree public void Execute(ConnectionInfo clickedNode) { - if (clickedNode == null) return; + if (clickedNode == null) + throw new ArgumentNullException(nameof(clickedNode)); foreach (var handler in ClickHandlers) { handler.Execute(clickedNode); From a03095ab8e8d80439164ca9fd4e031e59d1e9ddc Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 14 Jan 2017 10:38:11 -0700 Subject: [PATCH 081/106] refactored the node deletion confirmer to be interface-based. this will lead to improved testability --- mRemoteV1/Tree/AlwaysConfirmYes.cs | 11 +++++++++++ mRemoteV1/Tree/IConfirm.cs | 7 +++++++ ...er.cs => SelectedConnectionDeletionConfirmer.cs} | 13 +++++++++++-- .../UI/Controls/ConnectionTree/ConnectionTree.cs | 4 ++-- .../UI/Controls/ConnectionTree/IConnectionTree.cs | 3 +++ mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 2 +- mRemoteV1/mRemoteV1.csproj | 4 +++- 7 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 mRemoteV1/Tree/AlwaysConfirmYes.cs create mode 100644 mRemoteV1/Tree/IConfirm.cs rename mRemoteV1/Tree/{ConnectionDeletionConfirmer.cs => SelectedConnectionDeletionConfirmer.cs} (81%) diff --git a/mRemoteV1/Tree/AlwaysConfirmYes.cs b/mRemoteV1/Tree/AlwaysConfirmYes.cs new file mode 100644 index 000000000..40d0989ec --- /dev/null +++ b/mRemoteV1/Tree/AlwaysConfirmYes.cs @@ -0,0 +1,11 @@ + +namespace mRemoteNG.Tree +{ + public class AlwaysConfirmYes : IConfirm + { + public bool Confirm() + { + return true; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/IConfirm.cs b/mRemoteV1/Tree/IConfirm.cs new file mode 100644 index 000000000..e4434cb5b --- /dev/null +++ b/mRemoteV1/Tree/IConfirm.cs @@ -0,0 +1,7 @@ +namespace mRemoteNG.Tree +{ + public interface IConfirm + { + bool Confirm(); + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/ConnectionDeletionConfirmer.cs b/mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs similarity index 81% rename from mRemoteV1/Tree/ConnectionDeletionConfirmer.cs rename to mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs index 43844646f..b04907d80 100644 --- a/mRemoteV1/Tree/ConnectionDeletionConfirmer.cs +++ b/mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs @@ -1,14 +1,23 @@ using System.Windows.Forms; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.UI.Controls; namespace mRemoteNG.Tree { - public class ConnectionDeletionConfirmer + public class SelectedConnectionDeletionConfirmer : IConfirm { - public static bool UserConfirmsDeletion(ConnectionInfo deletionTarget) + private readonly IConnectionTree _connectionTree; + + public SelectedConnectionDeletionConfirmer(IConnectionTree connectionTree) { + _connectionTree = connectionTree; + } + + public bool Confirm() + { + var deletionTarget = _connectionTree.SelectedNode; var deletionTargetAsContainer = deletionTarget as ContainerInfo; if (deletionTargetAsContainer != null) return deletionTargetAsContainer.HasChildren() diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index d7a9a02da..047508df3 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -25,7 +25,7 @@ namespace mRemoteNG.UI.Controls public NodeSearcher NodeSearcher { get; private set; } - public Func DeletionConfirmer { get; set; } = connectionInfo => true; + public IConfirm NodeDeletionConfirmer { get; set; } = new AlwaysConfirmYes(); public IEnumerable PostSetupActions { get; set; } = new IConnectionTreeDelegate[0]; @@ -227,7 +227,7 @@ namespace mRemoteNG.UI.Controls public void DeleteSelectedNode() { if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; - if (!DeletionConfirmer(SelectedNode)) return; + if (!NodeDeletionConfirmer.Confirm()) return; ConnectionTreeModel.DeleteNode(SelectedNode); Runtime.SaveConnectionsAsync(); } diff --git a/mRemoteV1/UI/Controls/ConnectionTree/IConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/IConnectionTree.cs index 9f69a0d9c..3edc92875 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/IConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/IConnectionTree.cs @@ -1,4 +1,5 @@ using System.Collections; +using mRemoteNG.Connection; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -9,6 +10,8 @@ namespace mRemoteNG.UI.Controls { ConnectionTreeModel ConnectionTreeModel { get; set; } + ConnectionInfo SelectedNode { get; } + IEnumerable ExpandedObjects { get; set; } RootNodeInfo GetRootConnectionNode(); diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 94da163fe..7c742d3b7 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -83,7 +83,7 @@ namespace mRemoteNG.UI.Window #region ConnectionTree private void SetConnectionTreeEventHandlers() { - olvConnections.DeletionConfirmer = ConnectionDeletionConfirmer.UserConfirmsDeletion; + olvConnections.NodeDeletionConfirmer = new SelectedConnectionDeletionConfirmer(olvConnections); olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; olvConnections.KeyDown += tvConnections_KeyDown; diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index dbbee77ca..e0aa8fcbe 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -212,11 +212,13 @@ - + + + From 113e4035e5a0591176fe290262b6ecd486525486 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 14 Jan 2017 11:14:30 -0700 Subject: [PATCH 082/106] refactored the deletion confirmer to make it testable --- ...electedConnectionDeletionConfirmerTests.cs | 47 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + .../SelectedConnectionDeletionConfirmer.cs | 19 ++++---- mRemoteV1/UI/Window/ConnectionTreeWindow.cs | 2 +- 4 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 mRemoteNGTests/Tree/SelectedConnectionDeletionConfirmerTests.cs diff --git a/mRemoteNGTests/Tree/SelectedConnectionDeletionConfirmerTests.cs b/mRemoteNGTests/Tree/SelectedConnectionDeletionConfirmerTests.cs new file mode 100644 index 000000000..ffab4e6b2 --- /dev/null +++ b/mRemoteNGTests/Tree/SelectedConnectionDeletionConfirmerTests.cs @@ -0,0 +1,47 @@ +using System.Windows.Forms; +using mRemoteNG.Connection; +using mRemoteNG.Tree; +using mRemoteNG.UI.Controls; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class SelectedConnectionDeletionConfirmerTests + { + private SelectedConnectionDeletionConfirmer _deletionConfirmer; + private IConnectionTree _connectionTree; + + [SetUp] + public void Setup() + { + _connectionTree = Substitute.For(); + _connectionTree.SelectedNode.Returns(new ConnectionInfo()); + } + + [Test] + public void ClickingYesReturnsTrue() + { + _deletionConfirmer = new SelectedConnectionDeletionConfirmer(_connectionTree, MockClickYes); + Assert.That(_deletionConfirmer.Confirm(), Is.True); + } + + [Test] + public void ClickingNoReturnsFalse() + { + _deletionConfirmer = new SelectedConnectionDeletionConfirmer(_connectionTree, MockClickNo); + Assert.That(_deletionConfirmer.Confirm(), Is.False); + } + + private DialogResult MockClickYes(string promptMessage, string title, MessageBoxButtons buttons, MessageBoxIcon icon) + { + return DialogResult.Yes; + } + + private DialogResult MockClickNo(string promptMessage, string title, MessageBoxButtons buttons, MessageBoxIcon icon) + { + return DialogResult.No; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index f716a47fe..90b43f3d9 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -157,6 +157,7 @@ + Form diff --git a/mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs b/mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs index b04907d80..cb49f726d 100644 --- a/mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs +++ b/mRemoteV1/Tree/SelectedConnectionDeletionConfirmer.cs @@ -1,4 +1,5 @@ -using System.Windows.Forms; +using System; +using System.Windows.Forms; using mRemoteNG.Connection; using mRemoteNG.Container; using mRemoteNG.UI.Controls; @@ -9,10 +10,12 @@ namespace mRemoteNG.Tree public class SelectedConnectionDeletionConfirmer : IConfirm { private readonly IConnectionTree _connectionTree; + private readonly Func _confirmationFunc; - public SelectedConnectionDeletionConfirmer(IConnectionTree connectionTree) + public SelectedConnectionDeletionConfirmer(IConnectionTree connectionTree, Func confirmationFunc) { _connectionTree = connectionTree; + _confirmationFunc = confirmationFunc; } public bool Confirm() @@ -26,28 +29,28 @@ namespace mRemoteNG.Tree return UserConfirmsConnectionDeletion(deletionTarget); } - private static bool UserConfirmsEmptyFolderDeletion(AbstractConnectionInfoData deletionTarget) + private bool UserConfirmsEmptyFolderDeletion(AbstractConnectionInfoData deletionTarget) { var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, deletionTarget.Name); return PromptUser(messagePrompt); } - private static bool UserConfirmsNonEmptyFolderDeletion(AbstractConnectionInfoData deletionTarget) + private bool UserConfirmsNonEmptyFolderDeletion(AbstractConnectionInfoData deletionTarget) { var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, deletionTarget.Name); return PromptUser(messagePrompt); } - private static bool UserConfirmsConnectionDeletion(AbstractConnectionInfoData deletionTarget) + private bool UserConfirmsConnectionDeletion(AbstractConnectionInfoData deletionTarget) { var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, deletionTarget.Name); return PromptUser(messagePrompt); } - private static bool PromptUser(string promptMessage) + private bool PromptUser(string promptMessage) { - var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - return (msgBoxResponse == DialogResult.Yes); + var msgBoxResponse = _confirmationFunc.Invoke(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + return msgBoxResponse == DialogResult.Yes; } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 7c742d3b7..3ce13648c 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -83,7 +83,7 @@ namespace mRemoteNG.UI.Window #region ConnectionTree private void SetConnectionTreeEventHandlers() { - olvConnections.NodeDeletionConfirmer = new SelectedConnectionDeletionConfirmer(olvConnections); + olvConnections.NodeDeletionConfirmer = new SelectedConnectionDeletionConfirmer(olvConnections, MessageBox.Show); olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; olvConnections.KeyDown += tvConnections_KeyDown; From 1a776359c43abb9579dc9fd4195eadb343d411a1 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 14 Jan 2017 11:44:09 -0700 Subject: [PATCH 083/106] added test for folder expander --- .../PreviouslyOpenedFolderExpanderTests.cs | 49 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + .../Tree/PreviouslyOpenedFolderExpander.cs | 3 +- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 mRemoteNGTests/Tree/PreviouslyOpenedFolderExpanderTests.cs diff --git a/mRemoteNGTests/Tree/PreviouslyOpenedFolderExpanderTests.cs b/mRemoteNGTests/Tree/PreviouslyOpenedFolderExpanderTests.cs new file mode 100644 index 000000000..45df7c9d6 --- /dev/null +++ b/mRemoteNGTests/Tree/PreviouslyOpenedFolderExpanderTests.cs @@ -0,0 +1,49 @@ +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using mRemoteNG.UI.Controls; +using NSubstitute; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class PreviouslyOpenedFolderExpanderTests + { + private PreviouslyOpenedFolderExpander _folderExpander; + private IConnectionTree _connectionTree; + + [SetUp] + public void Setup() + { + _folderExpander = new PreviouslyOpenedFolderExpander(); + _connectionTree = Substitute.For(); + } + + [Test] + public void ExpandsAllFoldersThatAreMarkedForExpansion() + { + var connectionTreeModel = GenerateConnectionTreeModel(); + _connectionTree.ConnectionTreeModel.Returns(connectionTreeModel); + _connectionTree.GetRootConnectionNode().Returns(connectionTreeModel.RootNodes[0]); + _folderExpander.Execute(_connectionTree); + Assert.That(_connectionTree.ExpandedObjects, Is.EquivalentTo(connectionTreeModel.GetRecursiveChildList().OfType().Where(info => info.IsExpanded))); + } + + private ConnectionTreeModel GenerateConnectionTreeModel() + { + var connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection) { IsExpanded = true }; + var folder1 = new ContainerInfo { IsExpanded = true }; + var folder2 = new ContainerInfo(); + var con1 = new ConnectionInfo(); + root.AddChild(folder1); + folder1.AddChild(folder2); + root.AddChild(con1); + connectionTreeModel.AddRootNode(root); + return connectionTreeModel; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 90b43f3d9..b1d9ac8af 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -154,6 +154,7 @@ + diff --git a/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs b/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs index 1c52d7165..8b26236f7 100644 --- a/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs +++ b/mRemoteV1/Tree/PreviouslyOpenedFolderExpander.cs @@ -9,7 +9,8 @@ namespace mRemoteNG.Tree { public void Execute(IConnectionTree connectionTree) { - var containerList = connectionTree.ConnectionTreeModel.GetRecursiveChildList(connectionTree.GetRootConnectionNode()).OfType(); + var rootNode = connectionTree.GetRootConnectionNode(); + var containerList = connectionTree.ConnectionTreeModel.GetRecursiveChildList(rootNode).OfType(); var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); connectionTree.ExpandedObjects = previouslyExpandedNodes; connectionTree.InvokeRebuildAll(true); From 80c6ce81e10a0ef5f9de870861fc5fd9800ecbfd Mon Sep 17 00:00:00 2001 From: countchappy Date: Mon, 16 Jan 2017 15:14:27 -0500 Subject: [PATCH 084/106] RDP Minutes to Idle Timeout - Update 4 Added an option to alert if disconnected due to inactivity. --- .../Serializers/DataTableDeserializer.cs | 2 ++ .../Config/Serializers/DataTableSerializer.cs | 5 ++++ .../XmlConnectionNodeSerializer.cs | 3 +++ .../Serializers/XmlConnectionsDeserializer.cs | 2 ++ .../Connection/AbstractConnectionInfoData.cs | 9 +++++++ mRemoteV1/Connection/ConnectionInfo.cs | 1 + .../Connection/ConnectionInfoInheritance.cs | 5 ++++ .../Protocol/RDP/Connection.Protocol.RDP.cs | 16 ++++++++++++- mRemoteV1/Properties/Settings.Designer.cs | 24 +++++++++++++++++++ mRemoteV1/Properties/Settings.settings | 6 +++++ .../Resources/Language/Language.Designer.cs | 18 ++++++++++++++ mRemoteV1/Resources/Language/Language.resx | 6 +++++ mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd | 2 ++ mRemoteV1/UI/Window/ConfigWindow.cs | 17 +++++++++++++ mRemoteV1/app.config | 18 ++++++++++++++ 15 files changed, 133 insertions(+), 1 deletion(-) diff --git a/mRemoteV1/Config/Serializers/DataTableDeserializer.cs b/mRemoteV1/Config/Serializers/DataTableDeserializer.cs index bc05007e1..86098c628 100644 --- a/mRemoteV1/Config/Serializers/DataTableDeserializer.cs +++ b/mRemoteV1/Config/Serializers/DataTableDeserializer.cs @@ -85,6 +85,7 @@ namespace mRemoteNG.Config.Serializers connectionInfo.ICAEncryptionStrength = (ProtocolICA.EncryptionStrength)Enum.Parse(typeof(ProtocolICA.EncryptionStrength), (string)dataRow["ICAEncryptionStrength"]); connectionInfo.RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel)Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]); connectionInfo.RDPMinutesToIdleTimeout = (int)dataRow["RDPMinutesToIdleTimeout"]; + connectionInfo.RDPAlertIdleTimeout = (bool)dataRow["RDPAlertIdleTimeout"]; connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"]; connectionInfo.Colors = (ProtocolRDP.RDPColors)Enum.Parse(typeof(ProtocolRDP.RDPColors) ,(string)dataRow["Colors"]); connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Enum.Parse(typeof(ProtocolRDP.RDPResolutions), (string)dataRow["Resolution"]); @@ -154,6 +155,7 @@ namespace mRemoteNG.Config.Serializers connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"]; connectionInfo.Inheritance.ICAEncryptionStrength = (bool)dataRow["InheritICAEncryptionStrength"]; connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"]; + connectionInfo.Inheritance.RDPAlertIdleTimeout = (bool)dataRow["RDPAlertIdleTimeout"]; connectionInfo.Inheritance.RDPMinutesToIdleTimeout = (bool)dataRow["RDPMinutesToIdleTimeout"]; connectionInfo.Inheritance.LoadBalanceInfo = (bool)dataRow["InheritLoadBalanceInfo"]; connectionInfo.Inheritance.PreExtApp = (bool)dataRow["InheritPreExtApp"]; diff --git a/mRemoteV1/Config/Serializers/DataTableSerializer.cs b/mRemoteV1/Config/Serializers/DataTableSerializer.cs index abc27493e..0e2daefa0 100644 --- a/mRemoteV1/Config/Serializers/DataTableSerializer.cs +++ b/mRemoteV1/Config/Serializers/DataTableSerializer.cs @@ -66,6 +66,7 @@ namespace mRemoteNG.Config.Serializers _dataTable.Columns.Add("ICAEncryptionStrength", typeof(string)); _dataTable.Columns.Add("RDPAuthenticationLevel", typeof(string)); _dataTable.Columns.Add("RDPMinutesToIdleTimeout", typeof(int)); + _dataTable.Columns.Add("RDPAlertIdleTimeout", typeof(bool)); _dataTable.Columns.Add("Colors", typeof(string)); _dataTable.Columns.Add("Resolution", typeof(string)); _dataTable.Columns.Add("DisplayWallpaper", typeof(bool)); @@ -130,6 +131,7 @@ namespace mRemoteNG.Config.Serializers _dataTable.Columns.Add("InheritICAEncryptionStrength", typeof(bool)); _dataTable.Columns.Add("InheritRDPAuthenticationLevel", typeof(bool)); _dataTable.Columns.Add("InheritRDPMinutesToIdleTimeout", typeof(bool)); + _dataTable.Columns.Add("InheritRDPAlertIdleTimeout", typeof(bool)); _dataTable.Columns.Add("InheritUsername", typeof(bool)); _dataTable.Columns.Add("InheritPreExtApp", typeof(bool)); _dataTable.Columns.Add("InheritPostExtApp", typeof(bool)); @@ -203,6 +205,7 @@ namespace mRemoteNG.Config.Serializers dataRow["ICAEncryptionStrength"] = connectionInfo.ICAEncryptionStrength; dataRow["RDPAuthenticationLevel"] = connectionInfo.RDPAuthenticationLevel; //dataRow["RDPMinutesToIdleTimeout"] = connectionInfo.RDPMinutesToIdleTimeout; + //dataRow["RDPAlertIdleTimeout"] = connectionInfo.RDPAlertIdleTimeout; dataRow["LoadBalanceInfo"] = connectionInfo.LoadBalanceInfo; dataRow["Colors"] = connectionInfo.Colors; dataRow["Resolution"] = connectionInfo.Resolution; @@ -274,6 +277,7 @@ namespace mRemoteNG.Config.Serializers dataRow["InheritICAEncryptionStrength"] = connectionInfo.Inheritance.ICAEncryptionStrength; dataRow["InheritRDPAuthenticationLevel"] = connectionInfo.Inheritance.RDPAuthenticationLevel; //dataRow["InheritRDPMinutesToIdleTimeout"] = connectionInfo.Inheritance.RDPMinutesToIdleTimeout; + //dataRow["InheritRDPAlertIdleTimeout"] = connectionInfo.Inheritance.RDPAlertIdleTimeout; dataRow["InheritLoadBalanceInfo"] = connectionInfo.Inheritance.LoadBalanceInfo; dataRow["InheritPreExtApp"] = connectionInfo.Inheritance.PreExtApp; dataRow["InheritPostExtApp"] = connectionInfo.Inheritance.PostExtApp; @@ -330,6 +334,7 @@ namespace mRemoteNG.Config.Serializers dataRow["InheritICAEncryptionStrength"] = false; dataRow["InheritRDPAuthenticationLevel"] = false; //dataRow["InheritRDPMinutesToIdleTimeout"] = false; + //dataRow["InheritRDPAlertIdleTimeout"] = false; dataRow["InheritLoadBalanceInfo"] = false; dataRow["InheritPreExtApp"] = false; dataRow["InheritPostExtApp"] = false; diff --git a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs index 4cf1030a4..f38231d32 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs @@ -68,6 +68,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("ICAEncryptionStrength", connectionInfo.ICAEncryptionStrength)); element.Add(new XAttribute("RDPAuthenticationLevel", connectionInfo.RDPAuthenticationLevel)); element.Add(new XAttribute("RDPMinutesToIdleTimeout", connectionInfo.RDPMinutesToIdleTimeout)); + element.Add(new XAttribute("RDPAlertIdleTimeout", connectionInfo.RDPAlertIdleTimeout)); element.Add(new XAttribute("LoadBalanceInfo", connectionInfo.LoadBalanceInfo)); element.Add(new XAttribute("Colors", connectionInfo.Colors)); element.Add(new XAttribute("Resolution", connectionInfo.Resolution)); @@ -161,6 +162,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritICAEncryptionStrength", connectionInfo.Inheritance.ICAEncryptionStrength.ToString())); element.Add(new XAttribute("InheritRDPAuthenticationLevel", connectionInfo.Inheritance.RDPAuthenticationLevel.ToString())); element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", connectionInfo.Inheritance.RDPMinutesToIdleTimeout.ToString())); + element.Add(new XAttribute("InheritRDPAlertIdleTimeout", connectionInfo.Inheritance.RDPAlertIdleTimeout.ToString())); element.Add(new XAttribute("InheritLoadBalanceInfo", connectionInfo.Inheritance.LoadBalanceInfo.ToString())); element.Add(new XAttribute("InheritPreExtApp", connectionInfo.Inheritance.PreExtApp.ToString())); element.Add(new XAttribute("InheritPostExtApp", connectionInfo.Inheritance.PostExtApp.ToString())); @@ -217,6 +219,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("InheritICAEncryptionStrength", false.ToString())); element.Add(new XAttribute("InheritRDPAuthenticationLevel", false.ToString())); element.Add(new XAttribute("InheritRDPMinutesToIdleTimeout", false.ToString())); + element.Add(new XAttribute("InheritRDPAlertIdleTimeout", false.ToString())); element.Add(new XAttribute("InheritLoadBalanceInfo", false.ToString())); element.Add(new XAttribute("InheritPreExtApp", false.ToString())); element.Add(new XAttribute("InheritPostExtApp", false.ToString())); diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index 2ad45255c..fa0442977 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -489,6 +489,8 @@ namespace mRemoteNG.Config.Serializers connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0"); connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False"); + connectionInfo.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["RDPAlertIdleTimeout"]?.Value ?? "False"); + connectionInfo.Inheritance.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPAlertIdleTimeout"]?.Value ?? "False"); } } catch (Exception ex) diff --git a/mRemoteV1/Connection/AbstractConnectionInfoData.cs b/mRemoteV1/Connection/AbstractConnectionInfoData.cs index d3166cdb2..c6ee05043 100644 --- a/mRemoteV1/Connection/AbstractConnectionInfoData.cs +++ b/mRemoteV1/Connection/AbstractConnectionInfoData.cs @@ -31,6 +31,7 @@ namespace mRemoteNG.Connection private bool _useConsoleSession; private ProtocolRDP.AuthenticationLevel _rdpAuthenticationLevel; private int _rdpMinutesToIdleTimeout; + private bool _rdpAlertIdleTimeout; private string _loadBalanceInfo; private HTTPBase.RenderingEngine _renderingEngine; private bool _useCredSsp; @@ -234,6 +235,14 @@ namespace mRemoteNG.Connection get { return GetPropertyValue("RDPMinutesToIdleTimeout", _rdpMinutesToIdleTimeout); } set { SetField(ref _rdpMinutesToIdleTimeout, value, "RDPMinutesToIdleTimeout"); } } + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPAlertIdleTimeout"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDPAlertIdleTimeout")] + public bool RDPAlertIdleTimeout + { + get { return GetPropertyValue("RDPAlertIdleTimeout", _rdpAlertIdleTimeout); } + set { SetField(ref _rdpAlertIdleTimeout, value, "RDPAlertIdleTimeout"); } + } [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), LocalizedAttributes.LocalizedDisplayName("strPropertyNameLoadBalanceInfo"), diff --git a/mRemoteV1/Connection/ConnectionInfo.cs b/mRemoteV1/Connection/ConnectionInfo.cs index acc3baf67..8d00dec50 100644 --- a/mRemoteV1/Connection/ConnectionInfo.cs +++ b/mRemoteV1/Connection/ConnectionInfo.cs @@ -249,6 +249,7 @@ namespace mRemoteNG.Connection UseConsoleSession = Settings.Default.ConDefaultUseConsoleSession; RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel) Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), Settings.Default.ConDefaultRDPAuthenticationLevel); RDPMinutesToIdleTimeout = Settings.Default.ConDefaultRDPMinutesToIdleTimeout; + RDPAlertIdleTimeout = Settings.Default.ConDefaultRDPAlertIdleTimeout; LoadBalanceInfo = Settings.Default.ConDefaultLoadBalanceInfo; RenderingEngine = (HTTPBase.RenderingEngine) Enum.Parse(typeof(HTTPBase.RenderingEngine), Settings.Default.ConDefaultRenderingEngine); UseCredSsp = Settings.Default.ConDefaultUseCredSsp; diff --git a/mRemoteV1/Connection/ConnectionInfoInheritance.cs b/mRemoteV1/Connection/ConnectionInfoInheritance.cs index 49ab3c3cd..3d149c088 100644 --- a/mRemoteV1/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteV1/Connection/ConnectionInfoInheritance.cs @@ -90,6 +90,11 @@ namespace mRemoteNG.Connection LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionRDPMinutesToIdleTimeout"), TypeConverter(typeof(MiscTools.YesNoTypeConverter))]public bool RDPMinutesToIdleTimeout { get; set; } + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), + LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameRDPAlertIdleTimeout"), + LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionRDPAlertIdleTimeout"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] public bool RDPAlertIdleTimeout { get; set; } + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 4), LocalizedAttributes.LocalizedDisplayNameInheritAttribute("strPropertyNameLoadBalanceInfo"), LocalizedAttributes.LocalizedDescriptionInheritAttribute("strPropertyDescriptionLoadBalanceInfo"), diff --git a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs index 72e3c1a6b..435a2b16b 100644 --- a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs +++ b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs @@ -30,6 +30,7 @@ namespace mRemoteNG.Connection.Protocol.RDP private ConnectionInfo _connectionInfo; private bool _loginComplete; private bool _redirectKeys; + private bool _alertOnIdleDisconnect; #endregion #region Properties @@ -129,11 +130,17 @@ namespace mRemoteNG.Connection.Protocol.RDP SetCredentials(); SetResolution(); _rdpClient.FullScreenTitle = _connectionInfo.Name; + + _alertOnIdleDisconnect = _connectionInfo.RDPAlertIdleTimeout; // Set the timeout to the default (zero) if it is out of bounds. - if (_connectionInfo.RDPMinutesToIdleTimeout < 0 || _connectionInfo.RDPMinutesToIdleTimeout > 240) + if (_connectionInfo.RDPMinutesToIdleTimeout < 0) { _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = Settings.Default.ConDefaultRDPMinutesToIdleTimeout; + } // Set the timeout to the max (240) if it is out of bounds. + else if (_connectionInfo.RDPMinutesToIdleTimeout > 240) + { + _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = 240; } else { @@ -639,6 +646,13 @@ namespace mRemoteNG.Connection.Protocol.RDP private void RDPEvent_OnIdleTimeoutNotification() { Close(); //Simply close the RDP Session if the idle timeout has been triggered. + + if (_alertOnIdleDisconnect) + { + string message = "The " + _connectionInfo.Name + " session was disconnected due to inactivity"; + const string caption = "Session Disconnected"; + MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Information); + } } diff --git a/mRemoteV1/Properties/Settings.Designer.cs b/mRemoteV1/Properties/Settings.Designer.cs index e73bb2477..c8701775d 100644 --- a/mRemoteV1/Properties/Settings.Designer.cs +++ b/mRemoteV1/Properties/Settings.Designer.cs @@ -2374,5 +2374,29 @@ namespace mRemoteNG { this["InhDefaultRDPMinutesToIdleTimeout"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool ConDefaultRDPAlertIdleTimeout { + get { + return ((bool)(this["ConDefaultRDPAlertIdleTimeout"])); + } + set { + this["ConDefaultRDPAlertIdleTimeout"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool InhDefaultRDPAlertIdleTimeout { + get { + return ((bool)(this["InhDefaultRDPAlertIdleTimeout"])); + } + set { + this["InhDefaultRDPAlertIdleTimeout"] = value; + } + } } } diff --git a/mRemoteV1/Properties/Settings.settings b/mRemoteV1/Properties/Settings.settings index 6be7293a7..d25ee254f 100644 --- a/mRemoteV1/Properties/Settings.settings +++ b/mRemoteV1/Properties/Settings.settings @@ -590,5 +590,11 @@ False + + False + + + False + \ No newline at end of file diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 21ee69f1a..4b674afca 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -4117,6 +4117,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Select whether to receive an alert after the RDP session disconnects due to inactivity. + /// + internal static string strPropertyDescriptionRDPAlertIdleTimeout { + get { + return ResourceManager.GetString("strPropertyDescriptionRDPAlertIdleTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to The number of minutes for the RDP session to sit idle before automatically disconnecting (for no limit use 0). /// @@ -4612,6 +4621,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Alert on Idle Disconnect. + /// + internal static string strPropertyNameRDPAlertIdleTimeout { + get { + return ResourceManager.GetString("strPropertyNameRDPAlertIdleTimeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Minutes to Idle. /// diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index cc0a13971..a928e5068 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2427,4 +2427,10 @@ mRemoteNG will now quit and begin with the installation. Minutes to Idle + + Select whether to receive an alert after the RDP session disconnects due to inactivity + + + Alert on Idle Disconnect + \ No newline at end of file diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd index 876a72856..3756a83e7 100644 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd +++ b/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd @@ -47,6 +47,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/mRemoteV1/UI/Window/ConfigWindow.cs b/mRemoteV1/UI/Window/ConfigWindow.cs index 8f685a5fd..f529aab83 100644 --- a/mRemoteV1/UI/Window/ConfigWindow.cs +++ b/mRemoteV1/UI/Window/ConfigWindow.cs @@ -813,6 +813,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -871,6 +872,10 @@ namespace mRemoteNG.UI.Window strHide.Add("VNCProxyUsername"); strHide.Add("VNCSmartSizeMode"); strHide.Add("VNCViewOnly"); + if (conI.RDPMinutesToIdleTimeout <= 0) + { + strHide.Add("RDPAlertIdleTimeout"); + } if (conI.RDGatewayUsageMethod == ProtocolRDP.RDGatewayUsageMethod.Never) { strHide.Add("RDGatewayDomain"); @@ -912,6 +917,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -956,6 +962,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -999,6 +1006,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1043,6 +1051,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1088,6 +1097,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1133,6 +1143,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1178,6 +1189,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1221,6 +1233,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1260,6 +1273,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1302,6 +1316,7 @@ namespace mRemoteNG.UI.Window strHide.Add("RDGatewayUsername"); strHide.Add("RDPAuthenticationLevel"); strHide.Add("RDPMinutesToIdleTimeout"); + strHide.Add("RDPAlertIdleTimeout"); strHide.Add("LoadBalanceInfo"); strHide.Add("RedirectDiskDrives"); strHide.Add("RedirectKeys"); @@ -1385,6 +1400,8 @@ namespace mRemoteNG.UI.Window strHide.Add("RDPAuthenticationLevel"); if (conI.Inheritance.RDPMinutesToIdleTimeout) strHide.Add("RDPMinutesToIdleTimeout"); + if (conI.Inheritance.RDPAlertIdleTimeout) + strHide.Add("RDPAlertIdleTimeout"); if (conI.Inheritance.LoadBalanceInfo) strHide.Add("LoadBalanceInfo"); if (conI.Inheritance.Username) diff --git a/mRemoteV1/app.config b/mRemoteV1/app.config index 7a30d0434..41ac45650 100644 --- a/mRemoteV1/app.config +++ b/mRemoteV1/app.config @@ -415,6 +415,18 @@ False + + 0 + + + False + + + False + + + False + 5500 @@ -610,6 +622,12 @@ False + + False + + + False + From b43331dc273aa10955c024fa8ee7cf506058068b Mon Sep 17 00:00:00 2001 From: John Gleason Date: Mon, 16 Jan 2017 15:20:07 -0600 Subject: [PATCH 085/106] Fix typo in README.MD --- README.MD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.MD b/README.MD index f2ce96154..539b9861d 100644 --- a/README.MD +++ b/README.MD @@ -40,8 +40,8 @@ https://support.microsoft.com/en-us/kb/2923545 Windows 8+ support RDP version 8+ out of the box. -RDP versions are backwards compatible, so an mRemoteNG client running on Windows 10 can connection successfully to a Windows 2003 host (for example). +RDP versions are backwards compatible, so an mRemoteNG client running on Windows 10 can connect successfully to a Windows 2003 host (for example). -[![Developed with ReSharper](https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/develop/.github/icon_ReSharper.png)](https://www.jetbrains.com/resharper/) \ No newline at end of file +[![Developed with ReSharper](https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/develop/.github/icon_ReSharper.png)](https://www.jetbrains.com/resharper/) From 4e5a22a7e839c664716822516d9da09f1ebd0278 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 17 Jan 2017 09:47:00 -0700 Subject: [PATCH 086/106] resolved a minor bug where creating a new node would screw up the selected node in the tree We were trying to do multiselection when it is currently not supported by our implementation. --- mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index 047508df3..1c929f743 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -207,7 +207,7 @@ namespace mRemoteNG.UI.Controls var parent = selectedContainer ?? SelectedNode?.Parent; newNode.SetParent(parent); Expand(parent); - SelectObject(newNode); + SelectObject(newNode, true); EnsureModelVisible(newNode); } From cb708b321703775b59563cfef675ace9242fac0f Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 17 Jan 2017 13:45:25 -0700 Subject: [PATCH 087/106] resolved bug where some context menu hot keys would not work after opening the menu on the root node --- mRemoteV1/UI/Controls/ConnectionContextMenu.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs index e4baf4c82..9ff0f1457 100644 --- a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -62,6 +62,7 @@ namespace mRemoteNG.UI.Controls AddExternalApps(); ShowHideMenuItems(); }; + Closing += (sender, args) => EnableMenuItemsRecursive(Items); } private void InitializeComponent() From cbd9d16e4cea728ff2edb1b5c2f91175fe726f14 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 17 Jan 2017 15:31:40 -0700 Subject: [PATCH 088/106] simplified the connection tree refresh method. the complexity of trying to add refresh optimizations was causing bugs. i will need to find a new way of reducing flicker --- .../Controls/ConnectionTree/ConnectionTree.cs | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index 1c929f743..dc15ebbfc 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -234,34 +234,7 @@ namespace mRemoteNG.UI.Controls private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { - var senderAsContainerInfo = sender as ContainerInfo; - // ReSharper disable once SwitchStatementMissingSomeCases - switch (args?.Action) - { - case NotifyCollectionChangedAction.Add: - var childList = senderAsContainerInfo?.Children; - ConnectionInfo otherChild = null; - if (childList?.Count > 1) - otherChild = childList.First(child => !args.NewItems.Contains(child)); - RefreshObject(otherChild ?? senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Remove: - if (senderAsContainerInfo?.Children.Count > 0) - RefreshObjects(args.OldItems); - else - RefreshObject(senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Move: - RefreshObjects(args.OldItems); - break; - case NotifyCollectionChangedAction.Reset: - RefreshObject(senderAsContainerInfo); - break; - case NotifyCollectionChangedAction.Replace: - break; - case null: - break; - } + RefreshObject(sender); } private void tvConnections_AfterSelect(object sender, EventArgs e) From 04f6f4f9cf6167faa1b2af46131f55572c70acda Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Mon, 23 Jan 2017 12:59:29 -0500 Subject: [PATCH 089/106] Make version selectable/copyable fixes #360 Also update copyright year since it's 2017 now... --- mRemoteV1/Properties/AssemblyInfo.cs | 2 +- mRemoteV1/UI/Window/AboutWindow.cs | 74 ++++++++++++++++++---------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/mRemoteV1/Properties/AssemblyInfo.cs b/mRemoteV1/Properties/AssemblyInfo.cs index f28dff039..16ac88715 100644 --- a/mRemoteV1/Properties/AssemblyInfo.cs +++ b/mRemoteV1/Properties/AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyDescription("Multi-protocol remote connections manager")] [assembly: AssemblyCompany("")] [assembly:AssemblyProduct("mRemoteNG")] -[assembly: AssemblyCopyright("Copyright © 2016 mRemoteNG Dev Team; 2010-2013 Riley McArdle; 2007-2009 Felix Deimel")] +[assembly: AssemblyCopyright("Copyright © 2017 mRemoteNG Dev Team; 2010-2013 Riley McArdle; 2007-2009 Felix Deimel")] [assembly:AssemblyTrademark("")] [assembly:ComVisible(false)] diff --git a/mRemoteV1/UI/Window/AboutWindow.cs b/mRemoteV1/UI/Window/AboutWindow.cs index a97f17d12..0eb418789 100644 --- a/mRemoteV1/UI/Window/AboutWindow.cs +++ b/mRemoteV1/UI/Window/AboutWindow.cs @@ -5,6 +5,8 @@ using System.IO; using System.Text; using mRemoteNG.App; using mRemoteNG.App.Info; +// ReSharper disable ArrangeRedundantParentheses +// ReSharper disable RedundantCast namespace mRemoteNG.UI.Window { @@ -22,6 +24,7 @@ namespace mRemoteNG.UI.Window internal Label lblEdition; internal Label lblCredits; internal TextBox txtCredits; + private TextBox verText; internal Panel pnlTop; private void InitializeComponent() @@ -38,6 +41,7 @@ namespace mRemoteNG.UI.Window this.lblChangeLog = new System.Windows.Forms.Label(); this.lblLicense = new System.Windows.Forms.Label(); this.lblCopyright = new System.Windows.Forms.Label(); + this.verText = new System.Windows.Forms.TextBox(); this.pnlTop.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pbLogo)).BeginInit(); this.pnlBottom.SuspendLayout(); @@ -86,6 +90,7 @@ namespace mRemoteNG.UI.Window | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.pnlBottom.BackColor = System.Drawing.SystemColors.Control; + this.pnlBottom.Controls.Add(this.verText); this.pnlBottom.Controls.Add(this.lblCredits); this.pnlBottom.Controls.Add(this.txtCredits); this.pnlBottom.Controls.Add(this.txtChangeLog); @@ -206,6 +211,18 @@ namespace mRemoteNG.UI.Window this.lblCopyright.Text = "Copyright"; this.lblCopyright.UseCompatibleTextRendering = true; // + // verText + // + this.verText.BackColor = System.Drawing.SystemColors.Control; + this.verText.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.verText.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.verText.Location = new System.Drawing.Point(69, 51); + this.verText.Name = "verText"; + this.verText.Size = new System.Drawing.Size(147, 20); + this.verText.TabIndex = 12; + this.verText.TabStop = false; + this.verText.Text = "w.x.y.z"; + // // AboutWindow // this.BackColor = System.Drawing.SystemColors.Control; @@ -282,34 +299,37 @@ namespace mRemoteNG.UI.Window #endregion #region Form Stuff - private void About_Load(object sender, EventArgs e) - { - ApplyLanguage(); - ApplyEditions(); - - try - { - lblCopyright.Text = GeneralAppInfo.Copyright; - - lblVersion.Text = @"Version " + GeneralAppInfo.ApplicationVersion; - - if (File.Exists(GeneralAppInfo.HomePath + "\\CHANGELOG.TXT")) - { - using (var sR = new StreamReader(GeneralAppInfo.HomePath + "\\CHANGELOG.TXT")) - txtChangeLog.Text = sR.ReadToEnd(); - } - if (File.Exists(GeneralAppInfo.HomePath + "\\CREDITS.TXT")) - { - using (var sR = new StreamReader(GeneralAppInfo.HomePath + "\\CREDITS.TXT", Encoding.Default, true)) - txtCredits.Text = sR.ReadToEnd(); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Loading About failed" + Environment.NewLine + ex.Message, true); - } - } + private void About_Load(object sender, EventArgs e) + { + ApplyLanguage(); + ApplyEditions(); + + try + { + lblCopyright.Text = GeneralAppInfo.Copyright; + + lblVersion.Text = @"Version "; + verText.Text = GeneralAppInfo.ApplicationVersion; + + if (File.Exists(GeneralAppInfo.HomePath + "\\CHANGELOG.TXT")) + { + using (var sR = new StreamReader(GeneralAppInfo.HomePath + "\\CHANGELOG.TXT")) + txtChangeLog.Text = sR.ReadToEnd(); + } + + if (File.Exists(GeneralAppInfo.HomePath + "\\CREDITS.TXT")) + { + using (var sR = new StreamReader(GeneralAppInfo.HomePath + "\\CREDITS.TXT", Encoding.Default, true)) + txtCredits.Text = sR.ReadToEnd(); + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, + "Loading About failed" + Environment.NewLine + ex.Message, true); + } + } #if false private void llblFAMFAMFAM_LinkClicked(Object sender, LinkLabelLinkClickedEventArgs e) From e0fd81e9387109cf3d700ba00f1718e380320602 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Mon, 23 Jan 2017 15:32:06 -0700 Subject: [PATCH 090/106] resolved bug when clicking in blank space in the connection tree --- mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index dc15ebbfc..3f01fa547 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -253,6 +253,7 @@ namespace mRemoteNG.UI.Controls { if (e.ClickCount > 1) return; var clickedNode = e.Model as ConnectionInfo; + if (clickedNode == null) return; SingleClickHandler.Execute(clickedNode); } @@ -260,6 +261,7 @@ namespace mRemoteNG.UI.Controls { if (e.ClickCount < 2) return; var clickedNode = e.Model as ConnectionInfo; + if (clickedNode == null) return; DoubleClickHandler.Execute(clickedNode); } From 48d53cecce158a0fd837a8bdfbea522205bc8abb Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 24 Jan 2017 17:36:41 -0500 Subject: [PATCH 091/106] Rename Tab dialog - populate original name Fixes #258 --- mRemoteV1/UI/Window/ConnectionWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteV1/UI/Window/ConnectionWindow.cs b/mRemoteV1/UI/Window/ConnectionWindow.cs index c4f7ca62a..c4e04f289 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.cs @@ -678,7 +678,7 @@ namespace mRemoteNG.UI.Window { try { - var newTitle = ""; + var newTitle = TabController.SelectedTab.Title; if (input.InputBox(Language.strNewTitle, Language.strNewTitle + ":", ref newTitle) == DialogResult.OK && !string.IsNullOrEmpty(newTitle)) TabController.SelectedTab.Title = newTitle.Replace("&", "&&"); } From e00ba626068e68aa8606a47105e36d3c2ba05b6e Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 24 Jan 2017 17:52:15 -0500 Subject: [PATCH 092/106] Refactored Tools.Controls.cs Fixes #363 --- mRemoteV1/App/Runtime.cs | 14 ++++- mRemoteV1/Config/Settings/SettingsLoader.cs | 3 +- ...ls.Controls.cs => NotificationAreaIcon.cs} | 51 +++++-------------- .../UI/Forms/OptionsPages/AppearancePage.cs | 3 +- mRemoteV1/UI/Forms/frmMain.cs | 16 +++++- mRemoteV1/mRemoteV1.csproj | 3 +- 6 files changed, 43 insertions(+), 47 deletions(-) rename mRemoteV1/Tools/{Tools.Controls.cs => NotificationAreaIcon.cs} (70%) diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index f052d06bd..f17259b38 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -33,7 +33,7 @@ namespace mRemoteNG.App #region Public Properties public static WindowList WindowList { get; set; } public static MessageCollector MessageCollector { get; set; } - public static Controls.NotificationAreaIcon NotificationAreaIcon { get; set; } + public static NotificationAreaIcon NotificationAreaIcon { get; set; } public static bool IsConnectionsFileLoaded { get; set; } public static RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; } // ReSharper disable once UnusedAutoPropertyAccessor.Local @@ -274,7 +274,7 @@ namespace mRemoteNG.App { if (withDialog) { - var loadDialog = Controls.ConnectionsLoadDialog(); + var loadDialog = ConnectionsLoadDialog(); if (loadDialog.ShowDialog() != DialogResult.OK) return; connectionsLoader.ConnectionFileName = loadDialog.FileName; } @@ -353,6 +353,16 @@ namespace mRemoteNG.App } } + private static OpenFileDialog ConnectionsLoadDialog() + { + return new OpenFileDialog + { + CheckFileExists = true, + InitialDirectory = ConnectionsFileInfo.DefaultConnectionsPath, + Filter = Language.strFiltermRemoteXML + @"|*.xml|" + Language.strFilterAll + @"|*.*" + }; + } + private static void CreateBackupFile(string fileName) { // This intentionally doesn't prune any existing backup files. We just assume the user doesn't want any new ones created. diff --git a/mRemoteV1/Config/Settings/SettingsLoader.cs b/mRemoteV1/Config/Settings/SettingsLoader.cs index cd1d475c1..89f6741b0 100644 --- a/mRemoteV1/Config/Settings/SettingsLoader.cs +++ b/mRemoteV1/Config/Settings/SettingsLoader.cs @@ -9,6 +9,7 @@ using mRemoteNG.Themes; using mRemoteNG.Connection.Protocol; using mRemoteNG.App.Info; using mRemoteNG.Security.SymmetricEncryption; +using mRemoteNG.Tools; using mRemoteNG.UI.Forms; @@ -144,7 +145,7 @@ namespace mRemoteNG.Config.Settings private static void SetShowSystemTrayIcon() { if (mRemoteNG.Settings.Default.ShowSystemTrayIcon) - Runtime.NotificationAreaIcon = new Tools.Controls.NotificationAreaIcon(); + Runtime.NotificationAreaIcon = new NotificationAreaIcon(); } private static void SetPuttyPath() diff --git a/mRemoteV1/Tools/Tools.Controls.cs b/mRemoteV1/Tools/NotificationAreaIcon.cs similarity index 70% rename from mRemoteV1/Tools/Tools.Controls.cs rename to mRemoteV1/Tools/NotificationAreaIcon.cs index 8f4516400..c12ec880c 100644 --- a/mRemoteV1/Tools/Tools.Controls.cs +++ b/mRemoteV1/Tools/NotificationAreaIcon.cs @@ -8,17 +8,15 @@ using mRemoteNG.UI.Forms; namespace mRemoteNG.Tools { - public class Controls - { public class NotificationAreaIcon { - private NotifyIcon _nI; - private ContextMenuStrip _cMen; - private ToolStripMenuItem _cMenCons; + private readonly NotifyIcon _nI; + private readonly ContextMenuStrip _cMen; + private readonly ToolStripMenuItem _cMenCons; private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); - public bool Disposed { get; set; } + public bool Disposed { get; private set; } public NotificationAreaIcon() { @@ -46,8 +44,8 @@ namespace mRemoteNG.Tools _nI = new NotifyIcon { - Text = "mRemote", - BalloonTipText = "mRemote", + Text = @"mRemoteNG", + BalloonTipText = @"mRemoteNG", Icon = Resources.mRemote_Icon, ContextMenuStrip = _cMen, Visible = true @@ -86,11 +84,12 @@ namespace mRemoteNG.Tools MouseUpEventHandler = ConMenItem_MouseUp }; + // ReSharper disable once CoVariantArrayConversion ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionTreeModel).ToArray(); _cMenCons.DropDownItems.AddRange(rootMenuItems); } - private void nI_MouseDoubleClick(object sender, MouseEventArgs e) + private static void nI_MouseDoubleClick(object sender, MouseEventArgs e) { if (frmMain.Default.Visible) { @@ -102,7 +101,7 @@ namespace mRemoteNG.Tools } } - private void ShowForm() + private static void ShowForm() { frmMain.Default.Show(); frmMain.Default.WindowState = frmMain.Default.PreviousWindowState; @@ -112,13 +111,13 @@ namespace mRemoteNG.Tools Runtime.NotificationAreaIcon = null; } - private void HideForm() + private static void HideForm() { frmMain.Default.Hide(); frmMain.Default.PreviousWindowState = frmMain.Default.WindowState; } - private void ConMenItem_MouseUp(Object sender, MouseEventArgs e) + private void ConMenItem_MouseUp(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; if (!(((Control) sender).Tag is ConnectionInfo)) return; @@ -129,35 +128,9 @@ namespace mRemoteNG.Tools _connectionInitiator.OpenConnection((ConnectionInfo)((Control)sender).Tag); } - private void cMenExit_Click(Object sender, EventArgs e) + private static void cMenExit_Click(object sender, EventArgs e) { Shutdown.Quit(); } } - - public static SaveFileDialog ConnectionsSaveAsDialog() - { - var saveFileDialog = new SaveFileDialog(); - saveFileDialog.CheckPathExists = true; - saveFileDialog.InitialDirectory = App.Info.ConnectionsFileInfo.DefaultConnectionsPath; - saveFileDialog.FileName = App.Info.ConnectionsFileInfo.DefaultConnectionsFile; - saveFileDialog.OverwritePrompt = true; - - saveFileDialog.Filter = Language.strFiltermRemoteXML + "|*.xml|" + Language.strFilterAll + "|*.*"; - - return saveFileDialog; - } - - public static OpenFileDialog ConnectionsLoadDialog() - { - var lDlg = new OpenFileDialog - { - CheckFileExists = true, - InitialDirectory = App.Info.ConnectionsFileInfo.DefaultConnectionsPath, - Filter = Language.strFiltermRemoteXML + "|*.xml|" + Language.strFilterAll + "|*.*" - }; - - return lDlg; - } - } } \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/OptionsPages/AppearancePage.cs b/mRemoteV1/UI/Forms/OptionsPages/AppearancePage.cs index 3a9a229fd..fd5c2a34c 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/AppearancePage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/AppearancePage.cs @@ -1,6 +1,7 @@ using System; using System.Windows.Forms; using mRemoteNG.App; +using mRemoteNG.Tools; namespace mRemoteNG.UI.Forms.OptionsPages { @@ -79,7 +80,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages { if (Runtime.NotificationAreaIcon == null) { - Runtime.NotificationAreaIcon = new Tools.Controls.NotificationAreaIcon(); + Runtime.NotificationAreaIcon = new NotificationAreaIcon(); } } else diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index b886f1655..8c3471f10 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -509,7 +509,7 @@ namespace mRemoteNG.UI.Forms private void mMenFileNew_Click(object sender, EventArgs e) { - var saveFileDialog = Tools.Controls.ConnectionsSaveAsDialog(); + var saveFileDialog = ConnectionsSaveAsDialog(); if (saveFileDialog.ShowDialog() != DialogResult.OK) { return; @@ -626,6 +626,18 @@ namespace mRemoteNG.UI.Forms { Shutdown.Quit(); } + + public static SaveFileDialog ConnectionsSaveAsDialog() + { + return new SaveFileDialog + { + CheckPathExists = true, + InitialDirectory = ConnectionsFileInfo.DefaultConnectionsPath, + FileName = ConnectionsFileInfo.DefaultConnectionsFile, + OverwritePrompt = true, + Filter = Language.strFiltermRemoteXML + @"|*.xml|" + Language.strFilterAll + @"|*.*" + }; + } #endregion #region View @@ -963,7 +975,7 @@ namespace mRemoteNG.UI.Forms if (!Settings.Default.MinimizeToTray) return; if (Runtime.NotificationAreaIcon == null) { - Runtime.NotificationAreaIcon = new Tools.Controls.NotificationAreaIcon(); + Runtime.NotificationAreaIcon = new NotificationAreaIcon(); } Hide(); } diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index e0aa8fcbe..fb3569c37 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -210,6 +210,7 @@ + @@ -412,8 +413,6 @@ UserControl - - From 73f72e39d3f0ab61677e87f633457df480f05f90 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 24 Jan 2017 19:49:22 -0500 Subject: [PATCH 093/106] Fix incorrect cast & code clean up Fixes #362 --- mRemoteV1/Tools/NotificationAreaIcon.cs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/mRemoteV1/Tools/NotificationAreaIcon.cs b/mRemoteV1/Tools/NotificationAreaIcon.cs index c12ec880c..05b32c912 100644 --- a/mRemoteV1/Tools/NotificationAreaIcon.cs +++ b/mRemoteV1/Tools/NotificationAreaIcon.cs @@ -35,10 +35,9 @@ namespace mRemoteNG.Tools _cMen = new ContextMenuStrip { - Font = - new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, - System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)), - RenderMode = ToolStripRenderMode.Professional + Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, + System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)), + RenderMode = ToolStripRenderMode.Professional }; _cMen.Items.AddRange(new ToolStripItem[] {_cMenCons, cMenSep1, cMenExit}); @@ -56,7 +55,7 @@ namespace mRemoteNG.Tools } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Creating new SysTrayIcon failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Creating new SysTrayIcon failed", ex); } } @@ -71,7 +70,7 @@ namespace mRemoteNG.Tools } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Disposing SysTrayIcon failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Disposing SysTrayIcon failed", ex); } } @@ -92,13 +91,9 @@ namespace mRemoteNG.Tools private static void nI_MouseDoubleClick(object sender, MouseEventArgs e) { if (frmMain.Default.Visible) - { HideForm(); - } else - { ShowForm(); - } } private static void ShowForm() @@ -120,12 +115,10 @@ namespace mRemoteNG.Tools private void ConMenItem_MouseUp(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; - if (!(((Control) sender).Tag is ConnectionInfo)) return; + if (!(((ToolStripMenuItem)sender).Tag is ConnectionInfo)) return; if (frmMain.Default.Visible == false) - { ShowForm(); - } - _connectionInitiator.OpenConnection((ConnectionInfo)((Control)sender).Tag); + _connectionInitiator.OpenConnection((ConnectionInfo)((ToolStripMenuItem)sender).Tag); } private static void cMenExit_Click(object sender, EventArgs e) From 87c89a0de5cf53c8faf30dc41857aa1bab1c23ad Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 24 Jan 2017 19:55:18 -0500 Subject: [PATCH 094/106] reformat code --- mRemoteV1/Tools/NotificationAreaIcon.cs | 223 ++++++++++++------------ 1 file changed, 111 insertions(+), 112 deletions(-) diff --git a/mRemoteV1/Tools/NotificationAreaIcon.cs b/mRemoteV1/Tools/NotificationAreaIcon.cs index 05b32c912..cd66a8554 100644 --- a/mRemoteV1/Tools/NotificationAreaIcon.cs +++ b/mRemoteV1/Tools/NotificationAreaIcon.cs @@ -8,122 +8,121 @@ using mRemoteNG.UI.Forms; namespace mRemoteNG.Tools { - public class NotificationAreaIcon - { - private readonly NotifyIcon _nI; - private readonly ContextMenuStrip _cMen; - private readonly ToolStripMenuItem _cMenCons; - private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + public class NotificationAreaIcon + { + private readonly NotifyIcon _nI; + private readonly ContextMenuStrip _cMen; + private readonly ToolStripMenuItem _cMenCons; + private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator(); + public bool Disposed { get; private set; } - public bool Disposed { get; private set; } - - public NotificationAreaIcon() - { - try - { - _cMenCons = new ToolStripMenuItem - { - Text = Language.strConnections, - Image = Resources.Root - }; - - var cMenSep1 = new ToolStripSeparator(); - - var cMenExit = new ToolStripMenuItem {Text = Language.strMenuExit}; - cMenExit.Click += cMenExit_Click; - - _cMen = new ContextMenuStrip - { - Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, - System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)), - RenderMode = ToolStripRenderMode.Professional - }; - _cMen.Items.AddRange(new ToolStripItem[] {_cMenCons, cMenSep1, cMenExit}); - - _nI = new NotifyIcon - { - Text = @"mRemoteNG", - BalloonTipText = @"mRemoteNG", - Icon = Resources.mRemote_Icon, - ContextMenuStrip = _cMen, - Visible = true - }; - - _nI.MouseClick += nI_MouseClick; - _nI.MouseDoubleClick += nI_MouseDoubleClick; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("Creating new SysTrayIcon failed", ex); - } - } - - public void Dispose() - { - try - { - _nI.Visible = false; - _nI.Dispose(); - _cMen.Dispose(); - Disposed = true; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("Disposing SysTrayIcon failed", ex); - } - } - - private void nI_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button != MouseButtons.Right) return; - _cMenCons.DropDownItems.Clear(); - var menuItemsConverter = new ConnectionsTreeToMenuItemsConverter + public NotificationAreaIcon() + { + try + { + _cMenCons = new ToolStripMenuItem { - MouseUpEventHandler = ConMenItem_MouseUp + Text = Language.strConnections, + Image = Resources.Root }; - // ReSharper disable once CoVariantArrayConversion - ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionTreeModel).ToArray(); - _cMenCons.DropDownItems.AddRange(rootMenuItems); - } - - private static void nI_MouseDoubleClick(object sender, MouseEventArgs e) - { - if (frmMain.Default.Visible) - HideForm(); - else - ShowForm(); - } - - private static void ShowForm() - { - frmMain.Default.Show(); - frmMain.Default.WindowState = frmMain.Default.PreviousWindowState; + var cMenSep1 = new ToolStripSeparator(); - if (Settings.Default.ShowSystemTrayIcon) return; - Runtime.NotificationAreaIcon.Dispose(); - Runtime.NotificationAreaIcon = null; - } - - private static void HideForm() - { - frmMain.Default.Hide(); - frmMain.Default.PreviousWindowState = frmMain.Default.WindowState; - } - - private void ConMenItem_MouseUp(object sender, MouseEventArgs e) - { - if (e.Button != MouseButtons.Left) return; - if (!(((ToolStripMenuItem)sender).Tag is ConnectionInfo)) return; - if (frmMain.Default.Visible == false) - ShowForm(); - _connectionInitiator.OpenConnection((ConnectionInfo)((ToolStripMenuItem)sender).Tag); - } - - private static void cMenExit_Click(object sender, EventArgs e) - { - Shutdown.Quit(); - } - } + var cMenExit = new ToolStripMenuItem {Text = Language.strMenuExit}; + cMenExit.Click += cMenExit_Click; + + _cMen = new ContextMenuStrip + { + Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, + System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)), + RenderMode = ToolStripRenderMode.Professional + }; + _cMen.Items.AddRange(new ToolStripItem[] {_cMenCons, cMenSep1, cMenExit}); + + _nI = new NotifyIcon + { + Text = @"mRemoteNG", + BalloonTipText = @"mRemoteNG", + Icon = Resources.mRemote_Icon, + ContextMenuStrip = _cMen, + Visible = true + }; + + _nI.MouseClick += nI_MouseClick; + _nI.MouseDoubleClick += nI_MouseDoubleClick; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("Creating new SysTrayIcon failed", ex); + } + } + + public void Dispose() + { + try + { + _nI.Visible = false; + _nI.Dispose(); + _cMen.Dispose(); + Disposed = true; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("Disposing SysTrayIcon failed", ex); + } + } + + private void nI_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Right) return; + _cMenCons.DropDownItems.Clear(); + var menuItemsConverter = new ConnectionsTreeToMenuItemsConverter + { + MouseUpEventHandler = ConMenItem_MouseUp + }; + + // ReSharper disable once CoVariantArrayConversion + ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionTreeModel).ToArray(); + _cMenCons.DropDownItems.AddRange(rootMenuItems); + } + + private static void nI_MouseDoubleClick(object sender, MouseEventArgs e) + { + if (frmMain.Default.Visible) + HideForm(); + else + ShowForm(); + } + + private static void ShowForm() + { + frmMain.Default.Show(); + frmMain.Default.WindowState = frmMain.Default.PreviousWindowState; + + if (Settings.Default.ShowSystemTrayIcon) return; + Runtime.NotificationAreaIcon.Dispose(); + Runtime.NotificationAreaIcon = null; + } + + private static void HideForm() + { + frmMain.Default.Hide(); + frmMain.Default.PreviousWindowState = frmMain.Default.WindowState; + } + + private void ConMenItem_MouseUp(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left) return; + if (!(((ToolStripMenuItem) sender).Tag is ConnectionInfo)) return; + if (frmMain.Default.Visible == false) + ShowForm(); + _connectionInitiator.OpenConnection((ConnectionInfo) ((ToolStripMenuItem) sender).Tag); + } + + private static void cMenExit_Click(object sender, EventArgs e) + { + Shutdown.Quit(); + } + } } \ No newline at end of file From 29ca72d8ca6072d0f4e04f6b522715dc43fb77cd Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Tue, 24 Jan 2017 20:03:20 -0500 Subject: [PATCH 095/106] Change log update --- CHANGELOG.TXT | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 19cd54adf..92f2e6280 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -8,18 +8,22 @@ Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versi Features/Enhancements: ---------------------- Added Release Channels to the update check functionality allowing users to select one of 3 release channels for updates: Stable, Beta, Dev +#360: Help -> About, Version # is now selectable/copyable Fixes: ------ +#362: Invalid cast exception when using the Notification Area Icon minimize/restore #334: Quick Connect displays warning when clicking on a folder #325: When using a connection with an external app, results in opening the same external app continuously #311: Import from Active Directory does not use machine's domain by default +#258: Rename Tab dialog - populate original name in dialog (1.72 functionality) #211, #267: Recursive AD Import wasn't fully functional General Changes: ---------------- +The usual general code clean up and refactoring #325: Code clean up and additional logging for External Tools based connections #298: Code clean up and additional logging around application startup #291, #236: External Tools code clean up and additional logging @@ -32,6 +36,7 @@ Known Issue: ------------ Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versions. + Fixes: ------ #289: Install fails during update process (only affects v1.75 beta 1 - v1.75 beta 2) From 601951582d73ef9dea97546cf3ce43e4a69325c5 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 25 Jan 2017 09:54:54 -0700 Subject: [PATCH 096/106] resolved issue where saving default con properties would fail enum, int, bool -> string was throwing an exception. now using a simpler strategy for type conversion resolves #295 --- .../Connection/DefaultConnectionInfoTests.cs | 39 +++++++++++++++++++ mRemoteV1/Connection/DefaultConnectionInfo.cs | 21 +++++----- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/mRemoteNGTests/Connection/DefaultConnectionInfoTests.cs b/mRemoteNGTests/Connection/DefaultConnectionInfoTests.cs index 8b6f5a759..0d9cf4a37 100644 --- a/mRemoteNGTests/Connection/DefaultConnectionInfoTests.cs +++ b/mRemoteNGTests/Connection/DefaultConnectionInfoTests.cs @@ -1,4 +1,5 @@ using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; using NUnit.Framework; @@ -30,5 +31,43 @@ namespace mRemoteNGTests.Connection DefaultConnectionInfo.Instance.SaveTo(saveTarget); Assert.That(saveTarget.Domain, Is.EqualTo(_testDomain)); } + + [Test] + public void CanSaveEnumValuesToString() + { + const ProtocolType targetProtocol = ProtocolType.RAW; + var saveTarget = new AllStringPropertySaveTarget(); + DefaultConnectionInfo.Instance.Protocol = targetProtocol; + DefaultConnectionInfo.Instance.SaveTo(saveTarget); + Assert.That(saveTarget.Protocol, Is.EqualTo(targetProtocol.ToString())); + } + + [Test] + public void CanSaveIntegerValuesToString() + { + const int targetValue = 123; + var saveTarget = new AllStringPropertySaveTarget(); + DefaultConnectionInfo.Instance.RDPMinutesToIdleTimeout = targetValue; + DefaultConnectionInfo.Instance.SaveTo(saveTarget); + Assert.That(saveTarget.RDPMinutesToIdleTimeout, Is.EqualTo(targetValue.ToString())); + } + + [Test] + public void CanSaveStringValuesToString() + { + const string targetName = "hello"; + var saveTarget = new AllStringPropertySaveTarget(); + DefaultConnectionInfo.Instance.Username = targetName; + DefaultConnectionInfo.Instance.SaveTo(saveTarget); + Assert.That(saveTarget.Username, Is.EqualTo(targetName)); + } + + + private class AllStringPropertySaveTarget + { + public string Username { get; set; } + public string Protocol { get; set; } + public string RDPMinutesToIdleTimeout { get; set; } + } } } \ No newline at end of file diff --git a/mRemoteV1/Connection/DefaultConnectionInfo.cs b/mRemoteV1/Connection/DefaultConnectionInfo.cs index 8f7e3b742..156df57ad 100644 --- a/mRemoteV1/Connection/DefaultConnectionInfo.cs +++ b/mRemoteV1/Connection/DefaultConnectionInfo.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using mRemoteNG.App; namespace mRemoteNG.Connection @@ -39,15 +40,17 @@ namespace mRemoteNG.Connection var inheritanceProperties = GetProperties(_excludedProperties); foreach (var property in inheritanceProperties) { - var propertyFromDestination = typeof(TDestination).GetProperty(propertyNameMutator(property.Name)); - var localValue = property.GetValue(Instance, null); - - var descriptor = TypeDescriptor.GetProperties(Instance)[property.Name]; - var converter = descriptor.Converter; - if (converter != null && converter.CanConvertFrom(localValue.GetType())) - propertyFromDestination.SetValue(destinationInstance, converter.ConvertFrom(localValue), null); - else - propertyFromDestination.SetValue(destinationInstance, localValue, null); + try + { + var propertyFromDestination = typeof(TDestination).GetProperty(propertyNameMutator(property.Name)); + var localValue = property.GetValue(Instance, null); + var convertedValue = Convert.ChangeType(localValue, propertyFromDestination.PropertyType); + propertyFromDestination.SetValue(destinationInstance, convertedValue, null); + } + catch (Exception ex) + { + Runtime.MessageCollector?.AddExceptionStackTrace($"Error saving default connectioninfo property {property.Name}", ex); + } } } } From 6a07f4e731625145a6228b7809adb5a23ce3a5bd Mon Sep 17 00:00:00 2001 From: Joe Cefoli Date: Wed, 25 Jan 2017 14:02:16 -0500 Subject: [PATCH 097/106] Quick fix for #369 --- mRemoteV1/UI/Forms/frmMain.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 8c3471f10..730d2b28d 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -1233,7 +1233,9 @@ namespace mRemoteNG.UI.Forms Windows.TreePanel.Show(Default.pnlDock, DockState.DockLeft); Windows.ConfigPanel.Show(Default.pnlDock); Windows.ConfigPanel.DockTo(Windows.TreePanel.Pane, DockStyle.Bottom, -1); + Windows.ErrorsPanel.Show(Default.pnlDock, DockState.Document); + Windows.ErrorsForm.Hide(); Windows.ScreenshotForm.Hide(); Default.pnlDock.Visible = true; From 217693937fa02884e7adfa034f4e0b88b277659c Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 25 Jan 2017 14:02:20 -0700 Subject: [PATCH 098/106] connectioninfo id is now serialized to the confCons file --- mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs | 1 + mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs | 1 + mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd | 1 + 3 files changed, 3 insertions(+) diff --git a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs index 4cf1030a4..471053539 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionNodeSerializer.cs @@ -44,6 +44,7 @@ namespace mRemoteNG.Config.Serializers element.Add(new XAttribute("Descr", connectionInfo.Description)); element.Add(new XAttribute("Icon", connectionInfo.Icon)); element.Add(new XAttribute("Panel", connectionInfo.Panel)); + element.Add(new XAttribute("Id", connectionInfo.ConstantID)); element.Add(_saveFilter.SaveUsername ? new XAttribute("Username", connectionInfo.Username) diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index 2ad45255c..cc76c36ae 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -485,6 +485,7 @@ namespace mRemoteNG.Config.Serializers if (_confVersion >= 2.6) { + connectionInfo.ConstantID = xmlnode.Attributes["Id"]?.Value ?? connectionInfo.ConstantID; connectionInfo.SoundQuality = (ProtocolRDP.RDPSoundQuality)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPSoundQuality), Convert.ToString(xmlnode.Attributes["SoundQuality"].Value)); connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0"); diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd index 876a72856..5b815a806 100644 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd +++ b/mRemoteV1/Schemas/mremoteng_confcons_v2_6.xsd @@ -34,6 +34,7 @@ + From 2445c7463878d6c469efc82604540fd166028623 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 25 Jan 2017 17:50:10 -0500 Subject: [PATCH 099/106] code clean up and minor refactoring --- mRemoteV1/Config/Settings/SettingsLoader.cs | 2 +- mRemoteV1/Config/Settings/SettingsSaver.cs | 4 +- mRemoteV1/Tools/MiscTools.cs | 81 +++------------------ mRemoteV1/UI/Forms/frmMain.cs | 70 ++++++++++++++++-- 4 files changed, 76 insertions(+), 81 deletions(-) diff --git a/mRemoteV1/Config/Settings/SettingsLoader.cs b/mRemoteV1/Config/Settings/SettingsLoader.cs index 89f6741b0..0680e07dd 100644 --- a/mRemoteV1/Config/Settings/SettingsLoader.cs +++ b/mRemoteV1/Config/Settings/SettingsLoader.cs @@ -138,7 +138,7 @@ namespace mRemoteNG.Config.Settings private void SetKioskMode() { if (!mRemoteNG.Settings.Default.MainFormKiosk) return; - MainForm.Fullscreen.Value = true; + MainForm._fullscreen.Value = true; MainForm.mMenViewFullscreen.Checked = true; } diff --git a/mRemoteV1/Config/Settings/SettingsSaver.cs b/mRemoteV1/Config/Settings/SettingsSaver.cs index 53ebaa708..90be71668 100644 --- a/mRemoteV1/Config/Settings/SettingsSaver.cs +++ b/mRemoteV1/Config/Settings/SettingsSaver.cs @@ -36,9 +36,9 @@ namespace mRemoteNG.Config.Settings mRemoteNG.Settings.Default.MainFormState = with1.WindowState; - if (with1.Fullscreen != null) + if (with1._fullscreen != null) { - mRemoteNG.Settings.Default.MainFormKiosk = with1.Fullscreen.Value; + mRemoteNG.Settings.Default.MainFormKiosk = with1._fullscreen.Value; } mRemoteNG.Settings.Default.FirstStart = false; diff --git a/mRemoteV1/Tools/MiscTools.cs b/mRemoteV1/Tools/MiscTools.cs index 2c286596b..b09c86150 100644 --- a/mRemoteV1/Tools/MiscTools.cs +++ b/mRemoteV1/Tools/MiscTools.cs @@ -14,7 +14,7 @@ using static System.String; namespace mRemoteNG.Tools { - public class MiscTools + public static class MiscTools { public static Icon GetIconFromFile(string FileName) { @@ -112,7 +112,7 @@ namespace mRemoteNG.Tools } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Taking Screenshot failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddExceptionStackTrace("Taking Screenshot failed", ex); } return null; @@ -120,7 +120,7 @@ namespace mRemoteNG.Tools public class EnumTypeConverter : EnumConverter { - private Type _enumType; + private readonly Type _enumType; public EnumTypeConverter(Type type) : base(type) { @@ -135,8 +135,8 @@ namespace mRemoteNG.Tools public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType) { if (value == null) return null; - var fi = _enumType.GetField(Enum.GetName(_enumType, value: value)); - var dna = (DescriptionAttribute) (Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute))); + var fi = _enumType.GetField(Enum.GetName(_enumType, value)); + var dna = (DescriptionAttribute) Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute)); return dna != null ? dna.Description : value.ToString(); } @@ -150,9 +150,9 @@ namespace mRemoteNG.Tools { foreach (var fi in _enumType.GetFields()) { - var dna = (DescriptionAttribute) (Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute))); + var dna = (DescriptionAttribute) Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute)); - if ((dna != null) && ((string) value == dna.Description)) + if (dna != null && (string) value == dna.Description) { return Enum.Parse(_enumType, fi.Name); } @@ -167,12 +167,7 @@ namespace mRemoteNG.Tools public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { - if (sourceType == typeof(string)) - { - return true; - } - - return base.CanConvertFrom(context, sourceType); + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) @@ -193,7 +188,7 @@ namespace mRemoteNG.Tools return false; } - throw (new Exception("Values must be \"Yes\" or \"No\"")); + throw new Exception("Values must be \"Yes\" or \"No\""); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) @@ -220,63 +215,5 @@ namespace mRemoteNG.Tools return svc; } } - - public class Fullscreen - { - public Fullscreen(Form handledForm) - { - _handledForm = handledForm; - } - - private readonly Form _handledForm; - private FormWindowState _savedWindowState; - private FormBorderStyle _savedBorderStyle; - private Rectangle _savedBounds; - - private bool _value; - public bool Value - { - get - { - return _value; - } - set - { - if (_value == value) - { - return; - } - if (!_value) - { - EnterFullscreen(); - } - else - { - ExitFullscreen(); - } - _value = value; - } - } - - private void EnterFullscreen() - { - _savedBorderStyle = _handledForm.FormBorderStyle; - _savedWindowState = _handledForm.WindowState; - _savedBounds = _handledForm.Bounds; - - _handledForm.FormBorderStyle = FormBorderStyle.None; - if (_handledForm.WindowState == FormWindowState.Maximized) - { - _handledForm.WindowState = FormWindowState.Normal; - } - _handledForm.WindowState = FormWindowState.Maximized; - } - private void ExitFullscreen() - { - _handledForm.FormBorderStyle = _savedBorderStyle; - _handledForm.WindowState = _savedWindowState; - _handledForm.Bounds = _savedBounds; - } - } } } \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index 730d2b28d..d76d507b9 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -53,7 +53,7 @@ namespace mRemoteNG.UI.Forms { _showFullPathInTitle = Settings.Default.ShowCompleteConsPathInTitle; InitializeComponent(); - Fullscreen = new MiscTools.Fullscreen(this); + _fullscreen = new Fullscreen(this); pnlDock.Theme = new VS2012LightTheme(); } @@ -122,10 +122,68 @@ namespace mRemoteNG.UI.Forms } } - public MiscTools.Fullscreen Fullscreen { get; set; } + internal Fullscreen _fullscreen { get; set; } + + internal class Fullscreen + { + public Fullscreen(Form handledForm) + { + _handledForm = handledForm; + } + + private readonly Form _handledForm; + private FormWindowState _savedWindowState; + private FormBorderStyle _savedBorderStyle; + private Rectangle _savedBounds; + + private bool _value; + public bool Value + { + get + { + return _value; + } + set + { + if (_value == value) + { + return; + } + if (!_value) + { + EnterFullscreen(); + } + else + { + ExitFullscreen(); + } + _value = value; + } + } + + private void EnterFullscreen() + { + _savedBorderStyle = _handledForm.FormBorderStyle; + _savedWindowState = _handledForm.WindowState; + _savedBounds = _handledForm.Bounds; + + _handledForm.FormBorderStyle = FormBorderStyle.None; + if (_handledForm.WindowState == FormWindowState.Maximized) + { + _handledForm.WindowState = FormWindowState.Normal; + } + _handledForm.WindowState = FormWindowState.Maximized; + } + private void ExitFullscreen() + { + _handledForm.FormBorderStyle = _savedBorderStyle; + _handledForm.WindowState = _savedWindowState; + _handledForm.Bounds = _savedBounds; + } + } #endregion - + #region Startup & Shutdown private void frmMain_Load(object sender, EventArgs e) { @@ -390,7 +448,7 @@ namespace mRemoteNG.UI.Forms } } - private void tsExtAppEntry_Click(object sender, EventArgs e) + private static void tsExtAppEntry_Click(object sender, EventArgs e) { var extA = (ExternalTool)((ToolStripButton)sender).Tag; @@ -787,8 +845,8 @@ namespace mRemoteNG.UI.Forms private void mMenViewFullscreen_Click(object sender, EventArgs e) { - Fullscreen.Value = !Fullscreen.Value; - mMenViewFullscreen.Checked = Fullscreen.Value; + _fullscreen.Value = !_fullscreen.Value; + mMenViewFullscreen.Checked = _fullscreen.Value; } #endregion From 237cf037be828a7909265e228d85dcc866ca17bc Mon Sep 17 00:00:00 2001 From: countchappy Date: Fri, 27 Jan 2017 14:56:40 -0500 Subject: [PATCH 100/106] RDP Minutes to Idle Timeout - Update 5 Incorrect values entered in the Minutes to Idle Timout setting will be corrected to fit in the range of 0-240, rather than be truncated. --- .../Connection/AbstractConnectionInfoData.cs | 9 ++++++++- .../Protocol/RDP/Connection.Protocol.RDP.cs | 15 +-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/mRemoteV1/Connection/AbstractConnectionInfoData.cs b/mRemoteV1/Connection/AbstractConnectionInfoData.cs index c6ee05043..86e4fd7f2 100644 --- a/mRemoteV1/Connection/AbstractConnectionInfoData.cs +++ b/mRemoteV1/Connection/AbstractConnectionInfoData.cs @@ -233,7 +233,14 @@ namespace mRemoteNG.Connection public virtual int RDPMinutesToIdleTimeout { get { return GetPropertyValue("RDPMinutesToIdleTimeout", _rdpMinutesToIdleTimeout); } - set { SetField(ref _rdpMinutesToIdleTimeout, value, "RDPMinutesToIdleTimeout"); } + set { + if(value < 0) { + value = 0; + } else if(value > 240) { + value = 240; + } + SetField(ref _rdpMinutesToIdleTimeout, value, "RDPMinutesToIdleTimeout"); + } } [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDPAlertIdleTimeout"), diff --git a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs index 435a2b16b..a7d85433f 100644 --- a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs +++ b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs @@ -132,20 +132,7 @@ namespace mRemoteNG.Connection.Protocol.RDP _rdpClient.FullScreenTitle = _connectionInfo.Name; _alertOnIdleDisconnect = _connectionInfo.RDPAlertIdleTimeout; - - // Set the timeout to the default (zero) if it is out of bounds. - if (_connectionInfo.RDPMinutesToIdleTimeout < 0) - { - _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = Settings.Default.ConDefaultRDPMinutesToIdleTimeout; - } // Set the timeout to the max (240) if it is out of bounds. - else if (_connectionInfo.RDPMinutesToIdleTimeout > 240) - { - _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = 240; - } - else - { - _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = _connectionInfo.RDPMinutesToIdleTimeout; - } + _rdpClient.AdvancedSettings2.MinutesToIdleTimeout = _connectionInfo.RDPMinutesToIdleTimeout; //not user changeable _rdpClient.AdvancedSettings2.GrabFocusOnConnect = true; From afcdf96e5c84f0fd8387e3d855eedec2e4faaaba Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 27 Jan 2017 17:13:50 -0500 Subject: [PATCH 101/106] changelog / credits update --- CHANGELOG.TXT | 6 ++++-- CREDITS.TXT | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 92f2e6280..c9a069fc9 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,4 +1,4 @@ -1.75 Beta 4 (2017-01-XX): +1.75 RC1 (2017-01-XX): Known Issue: ------------ @@ -8,11 +8,13 @@ Portable build MD5 check will fail when updating from 1.75 Beta 1 to newer versi Features/Enhancements: ---------------------- Added Release Channels to the update check functionality allowing users to select one of 3 release channels for updates: Stable, Beta, Dev -#360: Help -> About, Version # is now selectable/copyable +#360: Help -> About, Version # is now selectable/copyable +#221: RDP: Optional disconnect after X number of minutes of inactivity Fixes: ------ +#369: Reset Layout Option Does Not Reset Notification Pane #362: Invalid cast exception when using the Notification Area Icon minimize/restore #334: Quick Connect displays warning when clicking on a folder #325: When using a connection with an external app, results in opening the same external app continuously diff --git a/CREDITS.TXT b/CREDITS.TXT index d5f858bc9..2b5922afd 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -8,9 +8,12 @@ Sean Kaim (github.com/kmscode) Thanks for the awesome new website! Bennett Blodinger (github.com/benwa) +Joe Cefoli (github.com/jcefoli) +countchappy (github.com/countchappy) Tony Lambert + Past Contributors ================= From 9b38308ad1207c2d98001dafde62a5f8883061b8 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Fri, 27 Jan 2017 15:28:36 -0700 Subject: [PATCH 102/106] set date for rc1 build in changelog --- CHANGELOG.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index c9a069fc9..859334377 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,4 +1,4 @@ -1.75 RC1 (2017-01-XX): +1.75 RC1 (2017-01-27): Known Issue: ------------ From 768fdcd0e455e2cf268014e75ef3d70c97beb292 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Mon, 30 Jan 2017 11:33:27 -0700 Subject: [PATCH 103/106] using MouseClick events rather than the OLV CellClick events. this should resolve #378 --- .../Controls/ConnectionTree/ConnectionTree.cs | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs index 3f01fa547..ea0769394 100644 --- a/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -99,8 +99,8 @@ namespace mRemoteNG.UI.Controls container.IsExpanded = true; }; SelectionChanged += tvConnections_AfterSelect; - CellClick += tvConnections_NodeMouseSingleClick; - CellClick += tvConnections_NodeMouseDoubleClick; + MouseDoubleClick += OnMouse_DoubleClick; + MouseClick += OnMouse_SingleClick; CellToolTipShowing += tvConnections_CellToolTipShowing; ModelCanDrop += _dragAndDropHandler.HandleEvent_ModelCanDrop; ModelDropped += _dragAndDropHandler.HandleEvent_ModelDropped; @@ -249,22 +249,26 @@ namespace mRemoteNG.UI.Controls } } - private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) + private void OnMouse_DoubleClick(object sender, MouseEventArgs mouseEventArgs) { - if (e.ClickCount > 1) return; - var clickedNode = e.Model as ConnectionInfo; - if (clickedNode == null) return; - SingleClickHandler.Execute(clickedNode); - } - - private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) - { - if (e.ClickCount < 2) return; - var clickedNode = e.Model as ConnectionInfo; + if (mouseEventArgs.Clicks < 2) return; + OLVColumn column; + var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column); + var clickedNode = listItem.RowObject as ConnectionInfo; if (clickedNode == null) return; DoubleClickHandler.Execute(clickedNode); } + private void OnMouse_SingleClick(object sender, MouseEventArgs mouseEventArgs) + { + if (mouseEventArgs.Clicks > 1) return; + OLVColumn column; + var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column); + var clickedNode = listItem.RowObject as ConnectionInfo; + if (clickedNode == null) return; + SingleClickHandler.Execute(clickedNode); + } + private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) { try From 69eec0135e3c04788464d5309b329becdb6d1afd Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 15 Feb 2017 15:21:18 -0500 Subject: [PATCH 104/106] Update to SHA512 file hashes --- CHANGELOG.TXT | 13 +++++++++++++ Tools/create_upg_chk_files.ps1 | 4 ++-- mRemoteV1/App/Update/AppUpdater.cs | 6 +++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 859334377..c11587eea 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,3 +1,16 @@ +1.75 (2017-02-13): + +Known Issue: +------------ +File hash check will fail when updating from 1.75 Beta 1 to newer versions. + Exception will be: "MD5 Hashes didn't match!" for 1.75 Beta 1 - 1.75 RC1 + + +Features/Enhancements: +---------------------- +#344 - Use SHA512 File Hashes to validate downloads (in the update mechanism & posted to the Downloads page) + + 1.75 RC1 (2017-01-27): Known Issue: diff --git a/Tools/create_upg_chk_files.ps1 b/Tools/create_upg_chk_files.ps1 index d81f992b9..28d539549 100644 --- a/Tools/create_upg_chk_files.ps1 +++ b/Tools/create_upg_chk_files.ps1 @@ -18,7 +18,7 @@ Write-Host Version: $version Write-Host dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/$tag/$filename Write-Host clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/$tag/CHANGELOG.TXT -$hash = Get-FileHash -Algorithm MD5 $file | % { $_.Hash } +$hash = Get-FileHash -Algorithm SHA512 $file | % { $_.Hash } Write-Host Checksum: $hash @@ -38,5 +38,5 @@ Write-Host dURL: https://github.com/mRemoteNG/mRemoteNG/releases/download/$tag/$ Write-Host clURL: https://raw.githubusercontent.com/mRemoteNG/mRemoteNG/$tag/CHANGELOG.TXT Write-Host CertificateThumbprint: 0CEA828E5C787EA8AA89268D83816C1EA03375BA -$hash = Get-FileHash -Algorithm MD5 $file | % { $_.Hash } +$hash = Get-FileHash -Algorithm SHA512 $file | % { $_.Hash } Write-Host Checksum: $hash \ No newline at end of file diff --git a/mRemoteV1/App/Update/AppUpdater.cs b/mRemoteV1/App/Update/AppUpdater.cs index 9b4780c56..94462bce4 100644 --- a/mRemoteV1/App/Update/AppUpdater.cs +++ b/mRemoteV1/App/Update/AppUpdater.cs @@ -276,14 +276,14 @@ namespace mRemoteNG.App.Update } #endif - using (var md5 = MD5.Create()) + using (var cksum = SHA512.Create()) { using (var stream = File.OpenRead(CurrentUpdateInfo.UpdateFilePath)) { - var hash = md5.ComputeHash(stream); + var hash = cksum.ComputeHash(stream); var hashString = BitConverter.ToString(hash).Replace("-", "").ToUpperInvariant(); if (!hashString.Equals(CurrentUpdateInfo.Checksum)) - throw new Exception("MD5 Hashes didn't match!"); + throw new Exception("SHA512 Hashes didn't match!"); } } } From f419bff5457658204df1ccc24bb8c057e3a0c571 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Thu, 16 Feb 2017 08:29:31 -0700 Subject: [PATCH 105/106] #394 resolved bug where export flag would not get set on the exported connections file --- mRemoteV1/App/Export.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mRemoteV1/App/Export.cs b/mRemoteV1/App/Export.cs index ef3fbfa33..bcbb52c92 100644 --- a/mRemoteV1/App/Export.cs +++ b/mRemoteV1/App/Export.cs @@ -76,12 +76,17 @@ namespace mRemoteNG.App var factory = new CryptographyProviderFactory(); var cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode); cryptographyProvider.KeyDerivationIterations = Settings.Default.EncryptionKeyDerivationIterations; - serializer = new XmlConnectionsSerializer(cryptographyProvider); - ((XmlConnectionsSerializer) serializer).SaveFilter = saveFilter; + serializer = new XmlConnectionsSerializer(cryptographyProvider) + { + Export = true, + SaveFilter = saveFilter + }; break; case ConnectionsSaver.Format.mRCSV: - serializer = new CsvConnectionsSerializerMremotengFormat(); - ((CsvConnectionsSerializerMremotengFormat)serializer).SaveFilter = saveFilter; + serializer = new CsvConnectionsSerializerMremotengFormat + { + SaveFilter = saveFilter + }; break; default: throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null); From 1034e434c44c9d70b2de0863bda0ca6476a02f5d Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 1 Mar 2017 16:23:40 -0700 Subject: [PATCH 106/106] updated changelog with release date --- CHANGELOG.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index c11587eea..8fa19fbea 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,4 +1,4 @@ -1.75 (2017-02-13): +1.75 (2017-03-01): Known Issue: ------------