diff --git a/Source/Terminals.Plugins.Vnc/VNCConnection.cs b/Source/Terminals.Plugins.Vnc/VNCConnection.cs index ce9274b5..5bd34150 100644 --- a/Source/Terminals.Plugins.Vnc/VNCConnection.cs +++ b/Source/Terminals.Plugins.Vnc/VNCConnection.cs @@ -14,11 +14,35 @@ internal class VNCConnection : Connection private string vncPassword = string.Empty; + private bool viewOnly; + + /// + /// Gets whether the live session currently ignores local mouse and keyboard input. + /// + public bool ViewOnly + { + get { return this.viewOnly; } + } + public void SendSpecialKeys(VncSharp.SpecialKeys Keys) { rd.SendSpecialKeys(Keys); } + /// + /// Toggles the View Only mode of the running session and returns the new state. + /// In View Only mode local mouse and keyboard events are not sent to the host. + /// + public bool ToggleViewOnly() + { + if (rd == null) + return this.viewOnly; + + this.viewOnly = !this.viewOnly; + rd.SetInputMode(this.viewOnly); + return this.viewOnly; + } + public override bool Connect() { try @@ -42,6 +66,7 @@ public override bool Connect() Text = "Connecting to VNC Server..."; VncOptions options = this.Favorite.ProtocolProperties as VncOptions; + this.viewOnly = options.ViewOnly; rd.Connect(Favorite.ServerName, options.DisplayNumber, options.ViewOnly, options.AutoScale); rd.BringToFront(); diff --git a/Source/Terminals.Plugins.Vnc/VncMenuVisitor.cs b/Source/Terminals.Plugins.Vnc/VncMenuVisitor.cs index d74fa740..4f6938c8 100644 --- a/Source/Terminals.Plugins.Vnc/VncMenuVisitor.cs +++ b/Source/Terminals.Plugins.Vnc/VncMenuVisitor.cs @@ -12,6 +12,8 @@ internal class VncMenuVisitor : IToolbarExtender private readonly ICurrenctConnectionProvider connectionProvider; private ToolStripDropDownButton vncActionButton; + private ToolStripMenuItem viewOnlyToolStripMenuItem; + private ToolStripMenuItem sendALTKeyToolStripMenuItem; private ToolStripMenuItem sendALTF4KeyToolStripMenuItem; @@ -31,8 +33,13 @@ public void Visit(ToolStrip standardToolbar) { this.EnusereMenuCreated(standardToolbar); - bool commandsAvailable = this.connectionProvider.CurrentConnection is VNCConnection; + var vnc = this.connectionProvider.CurrentConnection as VNCConnection; + bool commandsAvailable = vnc != null; this.vncActionButton.Visible = commandsAvailable; + + // Reflect the actual state of the current session, so switching tabs keeps the toggle in sync. + if (commandsAvailable) + this.viewOnlyToolStripMenuItem.Checked = vnc.ViewOnly; } private void EnusereMenuCreated(ToolStrip standardToolbar) @@ -43,6 +50,7 @@ private void EnusereMenuCreated(ToolStrip standardToolbar) private void CreateViewOnlyButton(ToolStrip standardToolbar) { + this.CreateViewOnlyMenuItem(); this.CreateAltKeyMenuItem(); this.CreateAltF4MenuItem(); this.CreateCtrlKeyMenuItem(); @@ -58,6 +66,7 @@ private void CreateActionButton() this.vncActionButton.DisplayStyle = ToolStripItemDisplayStyle.Image; this.vncActionButton.DropDownItems.AddRange(new ToolStripItem[] { + this.viewOnlyToolStripMenuItem, this.sendALTKeyToolStripMenuItem, this.sendALTF4KeyToolStripMenuItem, this.sendCTRLKeyToolStripMenuItem, @@ -72,6 +81,22 @@ private void CreateActionButton() this.vncActionButton.Visible = false; } + private void CreateViewOnlyMenuItem() + { + this.viewOnlyToolStripMenuItem = new ToolStripMenuItem(); + this.viewOnlyToolStripMenuItem.Name = "viewOnlyToolStripMenuItem"; + this.viewOnlyToolStripMenuItem.Size = new Size(202, 22); + this.viewOnlyToolStripMenuItem.Text = "View Only"; + this.viewOnlyToolStripMenuItem.Click += new EventHandler(this.ViewOnlyToolStripMenuItem_Click); + } + + private void ViewOnlyToolStripMenuItem_Click(object sender, EventArgs e) + { + var vnc = this.connectionProvider.CurrentConnection as VNCConnection; + if (vnc != null) + this.viewOnlyToolStripMenuItem.Checked = vnc.ToggleViewOnly(); + } + private void CreateAltKeyMenuItem() { this.sendALTKeyToolStripMenuItem = new ToolStripMenuItem(); diff --git a/Source/Tests/UserInterface/VncMenuVisitorTests.cs b/Source/Tests/UserInterface/VncMenuVisitorTests.cs index 8b73df06..a662e3db 100644 --- a/Source/Tests/UserInterface/VncMenuVisitorTests.cs +++ b/Source/Tests/UserInterface/VncMenuVisitorTests.cs @@ -14,7 +14,19 @@ public void EmptyToolBar_UpdateMenu_CreatesNewButtons() var menuVisitor = new VncMenuVisitor(sut.MockProvider.Object); menuVisitor.Visit(sut.Toolbar); int itemsCount = ((ToolStripDropDownButton)sut.Toolbar.Items[0]).DropDownItems.Count; - Assert.AreEqual(5, itemsCount, "First visit should update the menu by add its own drop donw menu items"); + Assert.AreEqual(6, itemsCount, "First visit should update the menu by add its own drop donw menu items"); + } + + [TestMethod] + public void UpdateMenu_AddsViewOnlyToggle() + { + var sut = new MenuVisitorSut(); + var menuVisitor = new VncMenuVisitor(sut.MockProvider.Object); + menuVisitor.Visit(sut.Toolbar); + var dropDown = (ToolStripDropDownButton)sut.Toolbar.Items[0]; + ToolStripItem viewOnly = dropDown.DropDownItems["viewOnlyToolStripMenuItem"]; + Assert.IsNotNull(viewOnly, "VNC actions menu has to offer a View Only toggle (issue #202)."); + Assert.AreEqual("View Only", viewOnly.Text, "The toggle has to be labelled View Only."); } } }