From aaa93b1bcc5d922604ff2ec444f24ae010e3822d Mon Sep 17 00:00:00 2001 From: Faryan Rezagholi Date: Sun, 23 Dec 2018 00:56:09 +0100 Subject: [PATCH 1/4] external links to open in browser instead of mremote itself --- mRemoteV1/App/Info/GeneralAppInfo.cs | 6 ++--- mRemoteV1/UI/Menu/HelpMenu.cs | 37 +++++++--------------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/mRemoteV1/App/Info/GeneralAppInfo.cs b/mRemoteV1/App/Info/GeneralAppInfo.cs index 727a33463..179773898 100644 --- a/mRemoteV1/App/Info/GeneralAppInfo.cs +++ b/mRemoteV1/App/Info/GeneralAppInfo.cs @@ -11,10 +11,10 @@ namespace mRemoteNG.App.Info { public static class GeneralAppInfo { - public const string UrlHome = "http://www.mremoteng.org/"; - public const string UrlDonate = "http://donate.mremoteng.org/"; + public const string UrlHome = "https://www.mremoteng.org/"; + public const string UrlDonate = "https://mremoteng.org/contribute/"; public const string UrlForum = "https://www.reddit.com/r/mRemoteNG/"; - public const string UrlBugs = "http://bugs.mremoteng.org/"; + public const string UrlBugs = "https://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; diff --git a/mRemoteV1/UI/Menu/HelpMenu.cs b/mRemoteV1/UI/Menu/HelpMenu.cs index c343c08c7..e79257716 100644 --- a/mRemoteV1/UI/Menu/HelpMenu.cs +++ b/mRemoteV1/UI/Menu/HelpMenu.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Windows.Forms; using mRemoteNG.App; using mRemoteNG.App.Info; @@ -142,39 +143,19 @@ namespace mRemoteNG.UI.Menu } #region Info - private void mMenToolsUpdate_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.Update); - } - private void mMenInfoHelp_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.Help); - } + private void mMenToolsUpdate_Click(object sender, EventArgs e) => Windows.Show(WindowType.Update); - private void mMenInfoForum_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlForum); - } + private void mMenInfoHelp_Click(object sender, EventArgs e) => Windows.Show(WindowType.Help); - private void mMenInfoBugReport_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlBugs); - } + private void mMenInfoForum_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlForum); - private void mMenInfoWebsite_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlHome); - } + private void mMenInfoBugReport_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlBugs); - private void mMenInfoDonate_Click(object sender, EventArgs e) - { - WebHelper.GoToUrl(GeneralAppInfo.UrlDonate); - } + private void mMenInfoWebsite_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlHome); - private void mMenInfoAbout_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.About); - } + private void mMenInfoDonate_Click(object sender, EventArgs e) => Process.Start(GeneralAppInfo.UrlDonate); + + private void mMenInfoAbout_Click(object sender, EventArgs e) => Windows.Show(WindowType.About); #endregion } } \ No newline at end of file From ba1e8cc4482c84ce856fd21481faefd36dd45e39 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Mon, 24 Dec 2018 15:08:33 -0500 Subject: [PATCH 2/4] update changelog --- CHANGELOG.TXT | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index ae3acea76..4d28ed198 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -2,6 +2,7 @@ Features/Enhancements: ---------------------- +#1223: Open External Links in Default Web Browser #1186: Fixed several dialog boxes to use localized button text #1170: Prevent Options window from showing up in taskbar #1141: 'Copy Hostname' option added to connection tree context menu From 0b8bcafb721760ce3f063972c7a905783f64e17b Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 26 Dec 2018 10:31:02 -0600 Subject: [PATCH 3/4] added unit tests for the DisplayProperties utility class. made class more testable --- .../Properties/Resources.Designer.cs | 10 ++ mRemoteNGTests/Properties/Resources.resx | 3 + mRemoteNGTests/Resources/TestImage.bmp | Bin 0 -> 3382 bytes mRemoteNGTests/UI/DisplayPropertiesTests.cs | 123 ++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 2 + mRemoteV1/UI/DisplayProperties.cs | 43 ++++-- .../GdiPlusGraphicsProvider.cs | 22 ++++ .../UI/GraphicsUtilities/IGraphicsProvider.cs | 9 ++ mRemoteV1/mRemoteV1.csproj | 2 + 9 files changed, 201 insertions(+), 13 deletions(-) create mode 100644 mRemoteNGTests/Resources/TestImage.bmp create mode 100644 mRemoteNGTests/UI/DisplayPropertiesTests.cs create mode 100644 mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs create mode 100644 mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs diff --git a/mRemoteNGTests/Properties/Resources.Designer.cs b/mRemoteNGTests/Properties/Resources.Designer.cs index 2f7599682..48157bac3 100644 --- a/mRemoteNGTests/Properties/Resources.Designer.cs +++ b/mRemoteNGTests/Properties/Resources.Designer.cs @@ -329,6 +329,16 @@ namespace mRemoteNGTests.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap TestImage { + get { + object obj = ResourceManager.GetObject("TestImage", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// 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 diff --git a/mRemoteNGTests/Properties/Resources.resx b/mRemoteNGTests/Properties/Resources.resx index 902712d20..93d4db1fa 100644 --- a/mRemoteNGTests/Properties/Resources.resx +++ b/mRemoteNGTests/Properties/Resources.resx @@ -154,6 +154,9 @@ ..\Resources\dev-update-portable.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\TestImage.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\test_puttyConnectionManager_database.dat;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16 diff --git a/mRemoteNGTests/Resources/TestImage.bmp b/mRemoteNGTests/Resources/TestImage.bmp new file mode 100644 index 0000000000000000000000000000000000000000..745429ef29d69878b58e7ecd12c99f70a26d454d GIT binary patch literal 3382 zcmcK6JhM~YwLz5sukzpus)KC>9C^8HMjvAT; z35pCufun|+AVHB~C~(x!B1lkV7z!LU)CCEO3`2pVhE_p>BEwMNsO$Ysw2HjkdnvSz z8kPhJiVQ=6qlT#JR z0!Iz2f&@i|p}X}n?6qR zX7K)8_5S`OQ#AK&SbzGtMTZxR@;%twV=sd|V_y@4Io$Kds>l7M#w|a+?bTc0cEL4& z4P1{e`F-r`6zJh}AI|xo25Wxq;gmn0+Iu+6=$IeJ&yzmn?_=M4*ygb3A60J`?dP`q z^33##*LJ(0=eIYm$@RFOU-OU0-mhQp!;&AZdk^+@>0!?I&ibiwJEvOyx%iSJ|MJ*- zf6PJT+3M}0iT@hr&uXu*x19N3x4oysUK`Kgkv}9(yL?uEWWH@>+IpTpai@yMgL&Pb zzhBF`xBOE#czxdI{1X@SySn6GoWu6atoavu=+&2Bm3a~Nw~lMF>>s`(d;R~K^s&^Q ze>jJ2?5(py{=poM)zA6i1()xcWBt(_&ebpV+XdS<-@G)Zv0umEj?eY(-!td&TrN1Q yd#ly9TmI0)xvxk0Z4S4wkL&k2+{gYXKM!d%nBn+a6~fz(d^_H^`+VnflY9pd(11n& literal 0 HcmV?d00001 diff --git a/mRemoteNGTests/UI/DisplayPropertiesTests.cs b/mRemoteNGTests/UI/DisplayPropertiesTests.cs new file mode 100644 index 000000000..124fb0937 --- /dev/null +++ b/mRemoteNGTests/UI/DisplayPropertiesTests.cs @@ -0,0 +1,123 @@ +using System; +using System.Drawing; +using mRemoteNG.UI; +using mRemoteNG.UI.GraphicsUtilities; +using mRemoteNGTests.Properties; +using NSubstitute; +using NUnit.Framework; + +namespace mRemoteNGTests.UI +{ + public class DisplayPropertiesTests + { + [Test] + public void ScaleHeightReturnsValueScaledByHeightScalingFactor() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = 10; + var scaledValue = sut.ScaleHeight(initialValue); + + Assert.That(scaledValue, Is.EqualTo(sut.ResolutionScalingFactor.Height * initialValue)); + } + + [Test] + public void ScaleWidthReturnsValueScaledByWidthScalingFactor() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = 10; + var scaledValue = sut.ScaleWidth(initialValue); + + Assert.That(scaledValue, Is.EqualTo(sut.ResolutionScalingFactor.Width * initialValue)); + } + + [Test] + public void ScaleSizeReturnsNewSizeWithCorrectlyScaledHeight() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = new Size(12, 16); + var scaledValue = sut.ScaleSize(initialValue); + + Assert.That(scaledValue.Height, Is.EqualTo(sut.ResolutionScalingFactor.Height * initialValue.Height)); + } + + [Test] + public void ScaleSizeReturnsNewSizeWithCorrectlyScaledWidth() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = new Size(12, 16); + var scaledValue = sut.ScaleSize(initialValue); + + Assert.That(scaledValue.Width, Is.EqualTo(sut.ResolutionScalingFactor.Width * initialValue.Width)); + } + + [Test] + public void ScaleImageReturnsNewImageWithCorrectlyScaledHeight() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = Resources.TestImage; + var scaledValue = sut.ScaleImage(initialValue); + + Assert.That(scaledValue.Height, Is.EqualTo(sut.ResolutionScalingFactor.Height * initialValue.Height)); + } + + [Test] + public void ScaleImageReturnsNewImageWithCorrectlyScaledWidth() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 2)); + var sut = new DisplayProperties(graphics); + + var initialValue = Resources.TestImage; + var scaledValue = sut.ScaleImage(initialValue); + + Assert.That(scaledValue.Width, Is.EqualTo(sut.ResolutionScalingFactor.Width * initialValue.Width)); + } + + [Test] + public void ResolutionScalingFactorAlwaysReturnsMostUpdatedValue() + { + var graphics = Substitute.For(); + graphics.GetResolutionScalingFactor().Returns(new SizeF(4, 4)); + var sut = new DisplayProperties(graphics); + + graphics.GetResolutionScalingFactor().Returns(new SizeF(8, 8)); + Assert.That(sut.ResolutionScalingFactor.Width, Is.EqualTo(8)); + } + + [Test] + public void AttemptingToScaleANullImageWillThrowAnException() + { + var sut = new DisplayProperties(Substitute.For()); + Assert.Throws(() => sut.ScaleImage((Image)null)); + } + + [Test] + public void AttemptingToScaleANullIconWillThrowAnException() + { + var sut = new DisplayProperties(Substitute.For()); + Assert.Throws(() => sut.ScaleImage((Icon)null)); + } + + [Test] + public void AttemptingToCallConstructorWithNullGraphicsProviderWillThrow() + { + // ReSharper disable once ObjectCreationAsStatement + Assert.Throws(() => new DisplayProperties(null)); + } + } +} diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 614851942..845117450 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -231,6 +231,7 @@ TextBoxExtensionsTestForm.cs + @@ -295,6 +296,7 @@ + diff --git a/mRemoteV1/UI/DisplayProperties.cs b/mRemoteV1/UI/DisplayProperties.cs index 18cff4be2..dae5ee068 100644 --- a/mRemoteV1/UI/DisplayProperties.cs +++ b/mRemoteV1/UI/DisplayProperties.cs @@ -2,16 +2,35 @@ using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; -using System.Windows.Forms; +using mRemoteNG.Tools; +using mRemoteNG.UI.GraphicsUtilities; namespace mRemoteNG.UI { public class DisplayProperties { - // Dpi of a 'normal' definition screen - private const int BaselineDpi = 96; + private readonly IGraphicsProvider _graphicsProvider; - public SizeF ResolutionScalingFactor { get; } = GetResolutionScalingFactor(); + public SizeF ResolutionScalingFactor => _graphicsProvider.GetResolutionScalingFactor(); + + /// + /// Creates a new instance with the default + /// of type + /// + public DisplayProperties() + : this(new GdiPlusGraphicsProvider()) + { + } + + /// + /// Creates a new instance with the given + /// . + /// + /// + public DisplayProperties(IGraphicsProvider graphicsProvider) + { + _graphicsProvider = graphicsProvider.ThrowIfNull(nameof(graphicsProvider)); + } /// /// Scale the given nominal width value by the @@ -28,7 +47,7 @@ namespace mRemoteNG.UI /// public int ScaleHeight(float height) { - return CalculateScaledValue(height, ResolutionScalingFactor.Width); + return CalculateScaledValue(height, ResolutionScalingFactor.Height); } /// @@ -52,6 +71,9 @@ namespace mRemoteNG.UI /// public Bitmap ScaleImage(Image image) { + if (image == null) + throw new ArgumentNullException(nameof(image)); + var width = ScaleWidth(image.Width); var height = ScaleHeight(image.Height); var destRect = new Rectangle(0, 0, width, height); @@ -79,6 +101,9 @@ namespace mRemoteNG.UI public Bitmap ScaleImage(Icon icon) { + if (icon == null) + throw new ArgumentNullException(nameof(icon)); + return ScaleImage(icon.ToBitmap()); } @@ -90,13 +115,5 @@ namespace mRemoteNG.UI { return (int)Math.Round(value * scalingValue); } - - private static SizeF GetResolutionScalingFactor() - { - using (var g = new Form().CreateGraphics()) - { - return new SizeF(g.DpiX/BaselineDpi, g.DpiY / BaselineDpi); - } - } } } diff --git a/mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs b/mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs new file mode 100644 index 000000000..d6fdc4812 --- /dev/null +++ b/mRemoteV1/UI/GraphicsUtilities/GdiPlusGraphicsProvider.cs @@ -0,0 +1,22 @@ +using System.Drawing; +using System.Windows.Forms; + +namespace mRemoteNG.UI.GraphicsUtilities +{ + /// + /// Gets environment graphics information using the Windows GDI+ API. + /// + public class GdiPlusGraphicsProvider : IGraphicsProvider + { + // Dpi of a 'normal' definition screen + private const int BaselineDpi = 96; + + public SizeF GetResolutionScalingFactor() + { + using (var g = new Form().CreateGraphics()) + { + return new SizeF(g.DpiX / BaselineDpi, g.DpiY / BaselineDpi); + } + } + } +} diff --git a/mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs b/mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs new file mode 100644 index 000000000..918a5b7e4 --- /dev/null +++ b/mRemoteV1/UI/GraphicsUtilities/IGraphicsProvider.cs @@ -0,0 +1,9 @@ +using System.Drawing; + +namespace mRemoteNG.UI.GraphicsUtilities +{ + public interface IGraphicsProvider + { + SizeF GetResolutionScalingFactor(); + } +} diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index e12c42ab4..085f7eb86 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -664,6 +664,8 @@ UnhandledExceptionWindow.cs + + Component From bdb1812705cb79c49a555cbf4faaf03061d8081e Mon Sep 17 00:00:00 2001 From: David Sparer Date: Wed, 26 Dec 2018 10:33:49 -0600 Subject: [PATCH 4/4] return a default options page icon if no icon exists for page --- mRemoteV1/UI/Forms/frmOptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mRemoteV1/UI/Forms/frmOptions.cs b/mRemoteV1/UI/Forms/frmOptions.cs index 5eb407000..a0fca6c20 100644 --- a/mRemoteV1/UI/Forms/frmOptions.cs +++ b/mRemoteV1/UI/Forms/frmOptions.cs @@ -89,8 +89,8 @@ namespace mRemoteNG.UI.Forms private object ImageGetter(object rowobject) { var page = rowobject as OptionsPage; - if (page == null) - return Resources.Help; + if (page?.PageIcon == null) + return _display.ScaleImage(Resources.Help); return _display.ScaleImage(page.PageIcon); }