Merge branch 'develop' into sql_test_connection

# Conflicts:
#	mRemoteV1/Resources/Language/Language.Designer.cs
#	mRemoteV1/Resources/Language/Language.resx
#	mRemoteV1/mRemoteV1.csproj
This commit is contained in:
David Sparer
2017-11-11 21:16:39 -06:00
23 changed files with 4280 additions and 4063 deletions

View File

@@ -77,6 +77,10 @@ IP TextBox
Copyright <20> 2005 mawnkay
http://www.codeproject.com/Articles/11576/IP-TextBox
PortableSettingsProvider
Copyright <20> 2014 crdx
https://github.com/crdx/PortableSettingsProvider
Included Components
===================

View File

@@ -0,0 +1,21 @@
using mRemoteNG.Config.Connections;
using mRemoteNGTests.TestHelpers;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace mRemoteNGTests.Config.Connections
{
class XmlConnectionsLoaderTests
{
[Test]
public void ThrowsFileNotFound()
{
Assert.Throws<FileNotFoundException>(() => (new XmlConnectionsLoader(FileTestHelpers.NewTempFilePath())).Load());
}
}
}

View File

@@ -3,6 +3,7 @@ using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Tools;
using mRemoteNG.Tools.CustomCollections;
using mRemoteNG.UI.Window;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
@@ -44,7 +45,7 @@ namespace mRemoteNGTests.Connection.Protocol
private void SetExternalToolList(ExternalTool externalTool)
{
Runtime.ExternalToolsService.ExternalTools = new ObservableCollection<ExternalTool> {externalTool};
Runtime.ExternalToolsService.ExternalTools = new FullyObservableCollection<ExternalTool> {externalTool};
}
private InterfaceControl BuildInterfaceControl(string extAppName, ProtocolBase sut)

View File

@@ -138,7 +138,49 @@ namespace mRemoteNG.App
if (ex is FileNotFoundException && !withDialog)
{
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoader.ConnectionFileName), ex, MessageClass.InformationMsg);
ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName);
string[] commandButtons =
{
Language.ConfigurationCreateNew,
Language.ConfigurationCustomPath,
Language.ConfigurationImportFile,
Language.strMenuExit
};
bool answered = false;
while (!answered)
{
try
{
CTaskDialog.ShowTaskDialogBox(GeneralAppInfo.ProductName, Language.ConfigurationFileNotFound, "", "", "", "", "", string.Join(" | ", commandButtons), ETaskDialogButtons.None, ESysIcons.Question, ESysIcons.Question);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName);
answered = true;
break;
case 1:
LoadConnections(true);
answered = true;
break;
case 2:
ConnectionsService.NewConnections(connectionsLoader.ConnectionFileName);
Import.ImportFromFile(ConnectionsService.ConnectionTreeModel.RootNodes[0]);
answered = true;
break;
case 3:
Application.Exit();
answered = true;
break;
}
}
catch (Exception exc)
{
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionsLoader.ConnectionFileName), exc, MessageClass.InformationMsg);
}
}
return;
}

View File

@@ -4,6 +4,7 @@ using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using System.IO;
namespace mRemoteNG.Config.Connections
{
@@ -16,6 +17,9 @@ namespace mRemoteNG.Config.Connections
if (string.IsNullOrEmpty(connectionFilePath))
throw new ArgumentException($"{nameof(connectionFilePath)} cannot be null or empty");
if (!File.Exists(connectionFilePath))
throw new FileNotFoundException($"{connectionFilePath} does not exist");
_connectionFilePath = connectionFilePath;
}

View File

@@ -72,6 +72,12 @@ namespace mRemoteNG.Config.Settings
Arguments = xEl.Attributes["Arguments"].Value
};
// check before, since old save files won't have this set
if (xEl.HasAttribute("WorkingDir"))
extA.WorkingDir = xEl.Attributes["WorkingDir"].Value;
if (xEl.HasAttribute("RunElevated"))
extA.RunElevated = bool.Parse(xEl.Attributes["RunElevated"].Value);
if (xEl.HasAttribute("WaitForExit"))
{
extA.WaitForExit = bool.Parse(xEl.Attributes["WaitForExit"].Value);
@@ -82,6 +88,11 @@ namespace mRemoteNG.Config.Settings
extA.TryIntegrate = bool.Parse(xEl.Attributes["TryToIntegrate"].Value);
}
if (xEl.HasAttribute("ShowOnToolbar"))
{
extA.ShowOnToolbar = bool.Parse(xEl.Attributes["ShowOnToolbar"].Value);
}
_messageCollector.AddMessage(MessageClass.InformationMsg, $"Adding External App: {extA.DisplayName} {extA.FileName} {extA.Arguments}", true);
Runtime.ExternalToolsService.ExternalTools.Add(extA);
}

View File

@@ -37,8 +37,11 @@ namespace mRemoteNG.Config.Settings
xmlTextWriter.WriteAttributeString("DisplayName", "", extA.DisplayName);
xmlTextWriter.WriteAttributeString("FileName", "", extA.FileName);
xmlTextWriter.WriteAttributeString("Arguments", "", extA.Arguments);
xmlTextWriter.WriteAttributeString("WorkingDir", "", extA.WorkingDir);
xmlTextWriter.WriteAttributeString("WaitForExit", "", Convert.ToString(extA.WaitForExit));
xmlTextWriter.WriteAttributeString("TryToIntegrate", "", Convert.ToString(extA.TryIntegrate));
xmlTextWriter.WriteAttributeString("RunElevated", "", Convert.ToString(extA.RunElevated));
xmlTextWriter.WriteAttributeString("ShowOnToolbar", "", Convert.ToString(extA.ShowOnToolbar));
xmlTextWriter.WriteEndElement();
}

View File

@@ -1,241 +0,0 @@
#if false
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace mRemoteNG.Config.Settings.Providers
{
public class AppSettingsProvider : SettingsProvider
{
const string SETTINGSROOT = "Settings"; //XML Root Node
public override void Initialize(string name, NameValueCollection col)
{
if (Application.ProductName.Trim().Length > 0)
{
_applicationName = Application.ProductName;
}
else
{
_applicationName = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
}
base.Initialize(ApplicationName, col);
/*
if (!File.Exists(GetDotSettingsFile()))
{
// do something smart.
}
*/
}
private string _applicationName;
public override string ApplicationName
{
get { return _applicationName; }
set { }
}
public virtual string GetDotSettingsFile()
{
return Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename());
}
public virtual string GetAppSettingsPath()
{
//Used to determine where to store the settings
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Application.ProductName);
}
public virtual string GetAppSettingsFilename()
{
//Used to determine the filename to store the settings
return Application.ProductName + ".settings";
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
//Iterate through the settings to be stored
//Only dirty settings are included in propvals, and only ones relevant to this provider
foreach (SettingsPropertyValue propval in propvals)
{
SetValue(propval);
}
try
{
SettingsXml.Save(GetDotSettingsFile());
}
catch (Exception)
{
//Ignore if cant save, device been ejected
}
}
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
{
//Create new collection of values
var values = new SettingsPropertyValueCollection();
//Iterate through the settings to be retrieved
foreach (SettingsProperty setting in props)
{
var value = new SettingsPropertyValue(setting)
{
IsDirty = false,
SerializedValue = GetValue(setting)
};
values.Add(value);
}
return values;
}
private XmlDocument _SettingsXml;
private XmlDocument SettingsXml
{
get
{
//If we dont hold an xml document, try opening one.
//If it doesnt exist then create a new one ready.
if (_SettingsXml == null)
{
_SettingsXml = new XmlDocument();
try
{
_SettingsXml.Load(GetDotSettingsFile());
}
catch (Exception)
{
//Create new document
var dec = _SettingsXml.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
_SettingsXml.AppendChild(dec);
var nodeRoot = _SettingsXml.CreateNode(XmlNodeType.Element, SETTINGSROOT, "");
_SettingsXml.AppendChild(nodeRoot);
}
}
return _SettingsXml;
}
}
private string GetValue(SettingsProperty setting)
{
var ret = string.Empty;
try
{
if (IsRoaming(setting))
{
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + setting.Name).InnerText;
}
else
{
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName + "/" + setting.Name).InnerText;
}
}
catch (Exception)
{
ret = setting.DefaultValue?.ToString() ?? "";
}
return ret;
}
private void SetValue(SettingsPropertyValue propVal)
{
System.Xml.XmlElement MachineNode = default(System.Xml.XmlElement);
System.Xml.XmlElement SettingNode = default(System.Xml.XmlElement);
//Determine if the setting is roaming.
//If roaming then the value is stored as an element under the root
//Otherwise it is stored under a machine name node
try
{
if (IsRoaming(propVal.Property))
{
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + propVal.Name));
}
else
{
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name + "/" + propVal.Name));
}
}
catch (Exception)
{
SettingNode = null;
}
//Check to see if the node exists, if so then set its new value
if (SettingNode != null)
{
if (propVal.SerializedValue != null)
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
}
else
{
if (IsRoaming(propVal.Property))
{
//Store the value as an element of the Settings Root Node
SettingNode = SettingsXml.CreateElement(propVal.Name);
if (propVal.SerializedValue != null)
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(SettingNode);
}
else
{
//Its machine specific, store as an element of the machine name node,
//creating a new machine name node if one doesnt exist.
try
{
MachineNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name));
}
catch (Exception)
{
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
}
if (MachineNode == null)
{
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
}
SettingNode = SettingsXml.CreateElement(propVal.Name);
if (propVal.SerializedValue != null)
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
MachineNode.AppendChild(SettingNode);
}
}
}
private bool IsRoaming(SettingsProperty prop)
{
//Determine if the setting is marked as Roaming
//For Each d As DictionaryEntry In prop.Attributes
// Dim a As Attribute = DirectCast(d.Value, Attribute)
// If TypeOf a Is System.Configuration.SettingsManageabilityAttribute Then
// Return True
// End If
//Next
//Return False
return true;
}
}
}
#endif

View File

@@ -1,12 +1,11 @@
namespace mRemoteNG.Config.Settings.Providers
using System.Configuration;
namespace mRemoteNG.Config.Settings.Providers
{
#if false
#if PORTABLE
public class ChooseProvider : PortableSettingsProvider
#else
public class ChooseProvider : AppSettingsProvider
#endif
{
}
public class ChooseProvider : LocalFileSettingsProvider
#endif
{ }
}

View File

@@ -1,234 +1,245 @@
#if false
/// The MIT License (MIT)
///
/// Copyright(c) crdx
///
/// Permission is hereby granted, free of charge, to any person obtaining
/// a copy of this software and associated documentation files (the
/// "Software"), to deal in the Software without restriction, including
/// without limitation the rights to use, copy, modify, merge, publish,
/// distribute, sublicense, and/or sell copies of the Software, and to
/// permit persons to whom the Software is furnished to do so, subject to
/// the following conditions:
///
/// The above copyright notice and this permission notice shall be
/// included in all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
/// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
/// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
/// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
/// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///
/// https://raw.githubusercontent.com/crdx/PortableSettingsProvider
///
using System.Linq;
using System;
using System.Collections.Specialized;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Xml;
using System.IO;
namespace mRemoteNG.Config.Settings.Providers
{
public class PortableSettingsProvider : SettingsProvider
{
const string SETTINGSROOT = "Settings"; //XML Root Node
public class PortableSettingsProvider : SettingsProvider, IApplicationSettingsProvider
{
private const string _rootNodeName = "settings";
private const string _localSettingsNodeName = "localSettings";
private const string _globalSettingsNodeName = "globalSettings";
private const string _className = "PortableSettingsProvider";
private XmlDocument _xmlDocument;
public override void Initialize(string name, NameValueCollection col)
{
if (Application.ProductName.Trim().Length > 0)
private string _filePath
{
get
{
_applicationName = Application.ProductName;
return Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),
string.Format("{0}.settings", ApplicationName));
}
}
private XmlNode _localSettingsNode
{
get
{
XmlNode settingsNode = GetSettingsNode(_localSettingsNodeName);
XmlNode machineNode = settingsNode.SelectSingleNode(Environment.MachineName.ToLowerInvariant());
if (machineNode == null)
{
machineNode = _rootDocument.CreateElement(Environment.MachineName.ToLowerInvariant());
settingsNode.AppendChild(machineNode);
}
return machineNode;
}
}
private XmlNode _globalSettingsNode
{
get { return GetSettingsNode(_globalSettingsNodeName); }
}
private XmlNode _rootNode
{
get { return _rootDocument.SelectSingleNode(_rootNodeName); }
}
private XmlDocument _rootDocument
{
get
{
if (_xmlDocument == null)
{
try
{
_xmlDocument = new XmlDocument();
_xmlDocument.Load(_filePath);
}
catch (Exception)
{
}
if (_xmlDocument.SelectSingleNode(_rootNodeName) != null)
return _xmlDocument;
_xmlDocument = GetBlankXmlDocument();
}
return _xmlDocument;
}
else
{
_applicationName = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
}
base.Initialize(ApplicationName, col);
}
private string _applicationName;
public override string ApplicationName
{
get { return _applicationName; }
get { return Path.GetFileNameWithoutExtension(Application.ExecutablePath); }
set { }
}
public virtual string GetDotSettingsFile()
public override string Name
{
return Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename());
get { return _className; }
}
public virtual string GetAppSettingsPath()
{
//Used to determine where to store the settings
System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
return fi.DirectoryName;
}
public virtual string GetAppSettingsFilename()
{
//Used to determine the filename to store the settings
return "portable.settings.";
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
//Iterate through the settings to be stored
//Only dirty settings are included in propvals, and only ones relevant to this provider
foreach (SettingsPropertyValue propval in propvals)
{
SetValue(propval);
}
try
{
SettingsXml.Save(GetDotSettingsFile());
}
catch (Exception)
{
//Ignore if cant save, device been ejected
}
}
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
{
//Create new collection of values
var values = new SettingsPropertyValueCollection();
//Iterate through the settings to be retrieved
foreach (SettingsProperty setting in props)
{
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(Name, config);
}
var value = new SettingsPropertyValue(setting)
{
IsDirty = false,
SerializedValue = GetValue(setting)
};
values.Add(value);
}
return values;
}
private XmlDocument _SettingsXml;
private XmlDocument SettingsXml
{
get
{
//If we dont hold an xml document, try opening one.
//If it doesnt exist then create a new one ready.
if (_SettingsXml == null)
{
_SettingsXml = new XmlDocument();
try
{
_SettingsXml.Load(GetDotSettingsFile());
}
catch (Exception)
{
//Create new document
var dec = _SettingsXml.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
_SettingsXml.AppendChild(dec);
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
{
foreach (SettingsPropertyValue propertyValue in collection)
SetValue(propertyValue);
var nodeRoot = _SettingsXml.CreateNode(XmlNodeType.Element, SETTINGSROOT, "");
_SettingsXml.AppendChild(nodeRoot);
}
}
return _SettingsXml;
}
}
private string GetValue(SettingsProperty setting)
{
var ret = string.Empty;
try
{
if (IsRoaming(setting))
{
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + setting.Name).InnerText;
}
else
{
ret = SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName + "/" + setting.Name).InnerText;
}
}
catch (Exception)
{
ret = setting.DefaultValue?.ToString() ?? "";
}
return ret;
}
private void SetValue(SettingsPropertyValue propVal)
{
System.Xml.XmlElement MachineNode = default(System.Xml.XmlElement);
System.Xml.XmlElement SettingNode = default(System.Xml.XmlElement);
//Determine if the setting is roaming.
//If roaming then the value is stored as an element under the root
//Otherwise it is stored under a machine name node
try
{
if (IsRoaming(propVal.Property))
{
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + propVal.Name));
}
else
{
SettingNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name + "/" + propVal.Name));
}
}
catch (Exception)
{
SettingNode = null;
}
//Check to see if the node exists, if so then set its new value
if (SettingNode != null)
{
if (propVal.SerializedValue != null)
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
}
else
{
if (IsRoaming(propVal.Property))
{
//Store the value as an element of the Settings Root Node
SettingNode = SettingsXml.CreateElement(propVal.Name);
if (propVal.SerializedValue != null)
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(SettingNode);
}
else
{
//Its machine specific, store as an element of the machine name node,
//creating a new machine name node if one doesnt exist.
try
{
MachineNode = (XmlElement) (SettingsXml.SelectSingleNode(SETTINGSROOT + "/" + (new Microsoft.VisualBasic.Devices.Computer()).Name));
}
catch (Exception)
{
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
}
if (MachineNode == null)
{
MachineNode = SettingsXml.CreateElement((new Microsoft.VisualBasic.Devices.Computer()).Name);
SettingsXml.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
}
SettingNode = SettingsXml.CreateElement(propVal.Name);
if (propVal.SerializedValue != null)
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
MachineNode.AppendChild(SettingNode);
}
}
}
private bool IsRoaming(SettingsProperty prop)
{
//Determine if the setting is marked as Roaming
//For Each d As DictionaryEntry In prop.Attributes
// Dim a As Attribute = DirectCast(d.Value, Attribute)
// If TypeOf a Is System.Configuration.SettingsManageabilityAttribute Then
// Return True
// End If
//Next
//Return False
return true;
}
}
}
#endif
try
{
_rootDocument.Save(_filePath);
}
catch (Exception)
{
/*
* If this is a portable application and the device has been
* removed then this will fail, so don't do anything. It's
* probably better for the application to stop saving settings
* rather than just crashing outright. Probably.
*/
}
}
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
{
SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
foreach (SettingsProperty property in collection)
{
values.Add(new SettingsPropertyValue(property)
{
SerializedValue = GetValue(property)
});
}
return values;
}
private void SetValue(SettingsPropertyValue propertyValue)
{
XmlNode targetNode = IsGlobal(propertyValue.Property)
? _globalSettingsNode
: _localSettingsNode;
XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", propertyValue.Name));
if (settingNode != null)
settingNode.InnerText = propertyValue.SerializedValue.ToString();
else
{
settingNode = _rootDocument.CreateElement("setting");
XmlAttribute nameAttribute = _rootDocument.CreateAttribute("name");
nameAttribute.Value = propertyValue.Name;
settingNode.Attributes.Append(nameAttribute);
settingNode.InnerText = propertyValue.SerializedValue.ToString();
targetNode.AppendChild(settingNode);
}
}
private string GetValue(SettingsProperty property)
{
XmlNode targetNode = IsGlobal(property) ? _globalSettingsNode : _localSettingsNode;
XmlNode settingNode = targetNode.SelectSingleNode(string.Format("setting[@name='{0}']", property.Name));
if (settingNode == null)
return property.DefaultValue != null ? property.DefaultValue.ToString() : string.Empty;
return settingNode.InnerText;
}
private bool IsGlobal(SettingsProperty property)
{
foreach (DictionaryEntry attribute in property.Attributes)
{
if ((Attribute)attribute.Value is SettingsManageabilityAttribute)
return true;
}
return false;
}
private XmlNode GetSettingsNode(string name)
{
XmlNode settingsNode = _rootNode.SelectSingleNode(name);
if (settingsNode == null)
{
settingsNode = _rootDocument.CreateElement(name);
_rootNode.AppendChild(settingsNode);
}
return settingsNode;
}
public XmlDocument GetBlankXmlDocument()
{
XmlDocument blankXmlDocument = new XmlDocument();
blankXmlDocument.AppendChild(blankXmlDocument.CreateXmlDeclaration("1.0", "utf-8", string.Empty));
blankXmlDocument.AppendChild(blankXmlDocument.CreateElement(_rootNodeName));
return blankXmlDocument;
}
public void Reset(SettingsContext context)
{
_localSettingsNode.RemoveAll();
_globalSettingsNode.RemoveAll();
_xmlDocument.Save(_filePath);
}
public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property)
{
// do nothing
return new SettingsPropertyValue(property);
}
public void Upgrade(SettingsContext context, SettingsPropertyCollection properties)
{
}
}
}

View File

@@ -33,6 +33,7 @@ namespace mRemoteNG.Connection
ConnectionTreeModel = newConnectionsModel,
ConnectionFileName = filename
};
connectionSaver.SaveFilter = new Security.SaveFilter();
connectionSaver.SaveConnections();
// Load config

File diff suppressed because it is too large Load Diff

View File

@@ -60,6 +60,42 @@ namespace mRemoteNG {
}
}
/// <summary>
/// Looks up a localized string similar to Create a New Configuration File.
/// </summary>
internal static string ConfigurationCreateNew {
get {
return ResourceManager.GetString("ConfigurationCreateNew", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use a Custom File Path.
/// </summary>
internal static string ConfigurationCustomPath {
get {
return ResourceManager.GetString("ConfigurationCustomPath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The Configuration File is Missing..
/// </summary>
internal static string ConfigurationFileNotFound {
get {
return ResourceManager.GetString("ConfigurationFileNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Import an Existing File.
/// </summary>
internal static string ConfigurationImportFile {
get {
return ResourceManager.GetString("ConfigurationImportFile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connection successful.
/// </summary>
@@ -7037,7 +7073,16 @@ namespace mRemoteNG {
return ResourceManager.GetString("strTryIntegrate", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Try to integrate.
/// </summary>
internal static string strShowOnToolbar {
get {
return ResourceManager.GetString("strShowOnToolbar", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Type.
/// </summary>

View File

@@ -2240,6 +2240,9 @@ Message:
<data name="strTryIntegrate" xml:space="preserve">
<value>Try to integrate</value>
</data>
<data name="strShowOnToolbar" xml:space="preserve">
<value>Show On Toolbar</value>
</data>
<data name="strType" xml:space="preserve">
<value>Type</value>
</data>
@@ -2595,6 +2598,18 @@ This page will walk you through the process of upgrading your connections file o
<data name="CouldNotFindExternalTool" xml:space="preserve">
<value>Could not find external tool with name "{0}"</value>
</data>
<data name="ConfigurationCreateNew" xml:space="preserve">
<value>Create a New Configuration File</value>
</data>
<data name="ConfigurationFileNotFound" xml:space="preserve">
<value>The Configuration File is Missing.</value>
</data>
<data name="ConfigurationImportFile" xml:space="preserve">
<value>Import an Existing File</value>
</data>
<data name="ConfigurationCustomPath" xml:space="preserve">
<value>Use a Custom File Path</value>
</data>
<data name="TestingConnection" xml:space="preserve">
<value>Testing connection</value>
</data>
@@ -2610,4 +2625,4 @@ This page will walk you through the process of upgrading your connections file o
<data name="DatabaseNotAvailable" xml:space="preserve">
<value>Database '{0}' not available.</value>
</data>
</root>
</root>

32
mRemoteV1/Settings.cs Normal file
View File

@@ -0,0 +1,32 @@
using System.Configuration;
namespace mRemoteNG
{
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
[global::System.Configuration.SettingsProviderAttribute(typeof(mRemoteNG.Config.Settings.Providers.ChooseProvider))]
internal sealed partial class Settings {
public Settings() {
// // To add event handlers for saving and changing settings, uncomment the lines below:
//
// this.SettingChanging += this.SettingChangingEventHandler;
//
// this.SettingsSaving += this.SettingsSavingEventHandler;
//
}
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
// Add code to handle the SettingChangingEvent event here.
}
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
// Add code to handle the SettingsSaving event here.
}
}
}

View File

@@ -10,6 +10,7 @@ namespace mRemoteNG.Tools.CustomCollections
where T : INotifyPropertyChanged
{
private readonly IList<T> _list = new List<T>();
private bool _eventsAllowed;
public int Count => _list.Count;
public bool IsReadOnly => _list.IsReadOnly;
@@ -26,30 +27,48 @@ namespace mRemoteNG.Tools.CustomCollections
public FullyObservableCollection(IEnumerable<T> items)
{
foreach (var item in items)
Add(item);
AddRange(items);
}
public void Add(T item)
{
_list.Add(item);
SubscribeToChildEvents(item);
RaiseCredentialChangedEvent(ActionType.Added, new[] {item});
if (_eventsAllowed)
RaiseCollectionChangedEvent(ActionType.Added, new[] {item});
}
/// <summary>
/// Adds a range of items to the collection.
/// Only raises a single <see cref="CollectionUpdated"/> event
/// after all new items are added.
/// </summary>
/// <param name="items"></param>
public void AddRange(IEnumerable<T> items)
{
var itemsAsList = items.ToList();
_eventsAllowed = false;
foreach (var item in itemsAsList)
Add(item);
_eventsAllowed = true;
RaiseCollectionChangedEvent(ActionType.Added, itemsAsList);
}
public void Insert(int index, T item)
{
_list.Insert(index, item);
SubscribeToChildEvents(item);
RaiseCredentialChangedEvent(ActionType.Added, new[] { item });
RaiseCollectionChangedEvent(ActionType.Added, new[] { item });
}
public bool Remove(T item)
{
var worked = _list.Remove(item);
if (!worked) return worked;
RaiseCredentialChangedEvent(ActionType.Removed, new[] {item});
UnsubscribeFromChildEvents(item);
RaiseCollectionChangedEvent(ActionType.Removed, new[] {item});
return worked;
}
@@ -58,7 +77,7 @@ namespace mRemoteNG.Tools.CustomCollections
var item = _list[index];
_list.RemoveAt(index);
UnsubscribeFromChildEvents(item);
RaiseCredentialChangedEvent(ActionType.Removed, new[] { item });
RaiseCollectionChangedEvent(ActionType.Removed, new[] { item });
}
public void Clear()
@@ -67,7 +86,7 @@ namespace mRemoteNG.Tools.CustomCollections
_list.Clear();
foreach (var item in oldItems)
UnsubscribeFromChildEvents(item);
RaiseCredentialChangedEvent(ActionType.Removed, oldItems);
RaiseCollectionChangedEvent(ActionType.Removed, oldItems);
}
private void SubscribeToChildEvents(INotifyPropertyChanged item)
@@ -83,12 +102,12 @@ namespace mRemoteNG.Tools.CustomCollections
private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
if (sender is T)
RaiseCredentialChangedEvent(ActionType.Updated, new []{ (T)sender });
RaiseCollectionChangedEvent(ActionType.Updated, new []{ (T)sender });
}
public event EventHandler<CollectionUpdatedEventArgs<T>> CollectionUpdated;
private void RaiseCredentialChangedEvent(ActionType action, IEnumerable<T> changedItems)
private void RaiseCollectionChangedEvent(ActionType action, IEnumerable<T> changedItems)
{
CollectionUpdated?.Invoke(this, new CollectionUpdatedEventArgs<T>(action, changedItems));
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
@@ -10,16 +12,81 @@ using mRemoteNG.Messages;
namespace mRemoteNG.Tools
{
public class ExternalTool
public class ExternalTool : INotifyPropertyChanged
{
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
#region Public Properties
public string DisplayName { get; set; }
public string FileName { get; set; }
public bool WaitForExit { get; set; }
public string Arguments { get; set; }
public bool TryIntegrate { get; set; }
public ConnectionInfo ConnectionInfo { get; set; }
private string _displayName;
private string _fileName;
private bool _waitForExit;
private string _arguments;
private string _workingDir;
private bool _tryIntegrate;
private bool _showOnToolbar = true;
private bool _runElevated;
#region Public Properties
public string DisplayName
{
get { return _displayName; }
set { SetField(ref _displayName, value, nameof(DisplayName)); }
}
public string FileName
{
get { return _fileName; }
set { SetField(ref _fileName, value, nameof(FileName)); }
}
public bool WaitForExit
{
get { return _waitForExit; }
set
{
// WaitForExit cannot be turned on when TryIntegrate is true
if (TryIntegrate)
return;
SetField(ref _waitForExit, value, nameof(WaitForExit));
}
}
public string Arguments
{
get { return _arguments; }
set { SetField(ref _arguments, value, nameof(Arguments)); }
}
public string WorkingDir
{
get { return _workingDir; }
set { SetField(ref _workingDir, value, nameof(WorkingDir)); }
}
public bool TryIntegrate
{
get { return _tryIntegrate; }
set
{
// WaitForExit cannot be turned on when TryIntegrate is true
if (value)
WaitForExit = false;
SetField(ref _tryIntegrate, value, nameof(TryIntegrate));
}
}
public bool ShowOnToolbar
{
get { return _showOnToolbar; }
set { SetField(ref _showOnToolbar, value, nameof(ShowOnToolbar)); }
}
public bool RunElevated
{
get { return _runElevated; }
set { SetField(ref _runElevated, value, nameof(RunElevated)); }
}
public ConnectionInfo ConnectionInfo { get; set; }
public Icon Icon
{
@@ -33,11 +100,13 @@ namespace mRemoteNG.Tools
#endregion
public ExternalTool(string displayName = "", string fileName = "", string arguments = "")
public ExternalTool(string displayName = "", string fileName = "", string arguments = "", string workingDir = "", bool runElevated = false)
{
DisplayName = displayName;
FileName = fileName;
Arguments = arguments;
WorkingDir = workingDir;
RunElevated = runElevated;
}
public void Start(ConnectionInfo startConnectionInfo = null)
@@ -81,6 +150,8 @@ namespace mRemoteNG.Tools
process.StartInfo.UseShellExecute = true;
process.StartInfo.FileName = argParser.ParseArguments(FileName);
process.StartInfo.Arguments = argParser.ParseArguments(Arguments);
if (WorkingDir != "") process.StartInfo.WorkingDirectory = argParser.ParseArguments(WorkingDir);
if (RunElevated) process.StartInfo.Verb = "runas";
}
private void StartIntegrated()
@@ -116,5 +187,20 @@ namespace mRemoteNG.Tools
newConnectionInfo.Name = DisplayName;
newConnectionInfo.Panel = Language.strMenuExternalTools;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChangedEvent(object sender, string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
RaisePropertyChangedEvent(this, propertyName);
return true;
}
}
}

View File

@@ -1,11 +1,11 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq;
using mRemoteNG.Tools.CustomCollections;
namespace mRemoteNG.Tools
{
public class ExternalToolsService
{
public ObservableCollection<ExternalTool> ExternalTools { get; set; } = new ObservableCollection<ExternalTool>();
public FullyObservableCollection<ExternalTool> ExternalTools { get; set; } = new FullyObservableCollection<ExternalTool>();
public ExternalTool GetExtAppByName(string name)
{

View File

@@ -17,7 +17,7 @@ namespace mRemoteNG.UI.Controls
public ExternalToolsToolStrip()
{
Initialize();
Runtime.ExternalToolsService.ExternalTools.CollectionChanged += (sender, args) => AddExternalToolsToToolBar();
Runtime.ExternalToolsService.ExternalTools.CollectionUpdated += (sender, args) => AddExternalToolsToToolBar();
}
private void Initialize()
@@ -53,9 +53,6 @@ namespace mRemoteNG.UI.Controls
CMenToolbarShowText.Click += cMenToolbarShowText_Click;
}
#region Ext Apps Toolbar
private void cMenToolbarShowText_Click(object sender, EventArgs e)
{
@@ -66,25 +63,34 @@ namespace mRemoteNG.UI.Controls
{
try
{
SuspendLayout();
for (var index = Items.Count - 1; index >= 0; index--)
Items[index].Dispose();
Items.Clear();
foreach (var tool in Runtime.ExternalToolsService.ExternalTools)
{
var button = (ToolStripButton)Items.Add(tool.DisplayName, tool.Image, tsExtAppEntry_Click);
if (CMenToolbarShowText.Checked)
button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
else
button.DisplayStyle = button.Image != null ? ToolStripItemDisplayStyle.Image : ToolStripItemDisplayStyle.ImageAndText;
if (tool.ShowOnToolbar)
{
var button = (ToolStripButton)Items.Add(tool.DisplayName, tool.Image, tsExtAppEntry_Click);
if (CMenToolbarShowText.Checked)
button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
else
button.DisplayStyle = button.Image != null ? ToolStripItemDisplayStyle.Image : ToolStripItemDisplayStyle.ImageAndText;
button.Tag = tool;
button.Tag = tool;
}
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddExternalToolsToToolBarFailed, ex);
}
finally
{
ResumeLayout(true);
}
}
private static void tsExtAppEntry_Click(object sender, EventArgs e)

View File

@@ -11,8 +11,10 @@ namespace mRemoteNG.UI.Window
internal BrightIdeasSoftware.OLVColumn ArgumentsColumnHeader;
internal BrightIdeasSoftware.OLVColumn WaitForExitColumnHeader;
internal BrightIdeasSoftware.OLVColumn TryToIntegrateColumnHeader;
internal System.Windows.Forms.GroupBox PropertiesGroupBox;
internal BrightIdeasSoftware.OLVColumn WorkingDirColumnHeader;
internal BrightIdeasSoftware.OLVColumn RunElevateHeader;
internal Controls.Base.NGTextBox DisplayNameTextBox;
internal BrightIdeasSoftware.OLVColumn ShowOnToolbarColumnHeader;
internal Controls.Base.NGLabel DisplayNameLabel;
internal Controls.Base.NGTextBox ArgumentsCheckBox;
internal Controls.Base.NGTextBox FilenameTextBox;
@@ -27,29 +29,41 @@ namespace mRemoteNG.UI.Window
internal Controls.Base.NGCheckBox WaitForExitCheckBox;
internal Controls.Base.NGLabel OptionsLabel;
internal Controls.Base.NGCheckBox TryToIntegrateCheckBox;
internal Controls.Base.NGListView ToolsListObjView;
private void InitializeComponent()
internal Controls.Base.NGCheckBox ShowOnToolbarCheckBox;
internal Controls.Base.NGListView ToolsListObjView;
internal Controls.Base.NGLabel WorkingDirLabel;
internal Controls.Base.NGTextBox WorkingDirTextBox;
internal Controls.Base.NGButton BrowseWorkingDir;
internal Controls.Base.NGCheckBox RunElevatedCheckBox;
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExternalToolsWindow));
this.ToolsListObjView = new Controls.Base.NGListView();
this.ToolsListObjView = new mRemoteNG.UI.Controls.Base.NGListView();
this.DisplayNameColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.FilenameColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.ArgumentsColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.WorkingDirColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.WaitForExitColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.TryToIntegrateColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.RunElevateHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.ShowOnToolbarColumnHeader = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.ToolsContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.NewToolMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.DeleteToolMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.LaunchToolMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.PropertiesGroupBox = new mRemoteNG.UI.Controls.Base.NGGroupBox();
this.ShowOnToolbarCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
this.RunElevatedCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
this.BrowseWorkingDir = new mRemoteNG.UI.Controls.Base.NGButton();
this.WorkingDirLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
this.WorkingDirTextBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
this.TryToIntegrateCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
this.OptionsLabel = new mRemoteNG.UI.Controls.Base.NGLabel();
this.WaitForExitCheckBox = new mRemoteNG.UI.Controls.Base.NGCheckBox();
this.BrowseButton = new Controls.Base.NGButton();
this.BrowseButton = new mRemoteNG.UI.Controls.Base.NGButton();
this.ArgumentsCheckBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
this.FilenameTextBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
this.DisplayNameTextBox = new mRemoteNG.UI.Controls.Base.NGTextBox();
@@ -74,64 +88,118 @@ namespace mRemoteNG.UI.Window
//
// ToolsListObjView
//
this.ToolsListObjView.AllColumns.Add(this.DisplayNameColumnHeader);
this.ToolsListObjView.AllColumns.Add(this.FilenameColumnHeader);
this.ToolsListObjView.AllColumns.Add(this.ArgumentsColumnHeader);
this.ToolsListObjView.AllColumns.Add(this.WorkingDirColumnHeader);
this.ToolsListObjView.AllColumns.Add(this.WaitForExitColumnHeader);
this.ToolsListObjView.AllColumns.Add(this.TryToIntegrateColumnHeader);
this.ToolsListObjView.AllColumns.Add(this.RunElevateHeader);
this.ToolsListObjView.AllColumns.Add(this.ShowOnToolbarColumnHeader);
this.ToolsListObjView.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.ToolsListObjView.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.ToolsListObjView.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.F2Only;
this.ToolsListObjView.CellEditUseWholeCell = false;
this.ToolsListObjView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.DisplayNameColumnHeader,
this.FilenameColumnHeader,
this.ArgumentsColumnHeader,
this.WorkingDirColumnHeader,
this.WaitForExitColumnHeader,
this.TryToIntegrateColumnHeader});
this.TryToIntegrateColumnHeader,
this.RunElevateHeader,
this.ShowOnToolbarColumnHeader});
this.ToolsListObjView.ContextMenuStrip = this.ToolsContextMenuStrip;
this.ToolsListObjView.Cursor = System.Windows.Forms.Cursors.Default;
this.ToolsListObjView.DecorateLines = true;
this.ToolsListObjView.FullRowSelect = true;
this.ToolsListObjView.GridLines = true;
this.ToolsListObjView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.ToolsListObjView.HideSelection = false;
this.ToolsListObjView.Location = new System.Drawing.Point(0, 0);
this.ToolsListObjView.Name = "ToolsListObjView";
this.ToolsListObjView.Size = new System.Drawing.Size(684, 157);
this.ToolsListObjView.RenderNonEditableCheckboxesAsDisabled = true;
this.ToolsListObjView.ShowCommandMenuOnRightClick = true;
this.ToolsListObjView.ShowGroups = false;
this.ToolsListObjView.Size = new System.Drawing.Size(827, 186);
this.ToolsListObjView.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.ToolsListObjView.TabIndex = 0;
this.ToolsListObjView.UseCompatibleStateImageBehavior = false;
this.ToolsListObjView.UseNotifyPropertyChanged = true;
this.ToolsListObjView.View = System.Windows.Forms.View.Details;
this.ToolsListObjView.CellToolTipShowing += new System.EventHandler<BrightIdeasSoftware.ToolTipShowingEventArgs>(this.ToolsListObjView_CellToolTipShowing);
this.ToolsListObjView.SelectedIndexChanged += new System.EventHandler(this.ToolsListObjView_SelectedIndexChanged);
this.ToolsListObjView.DoubleClick += new System.EventHandler(this.ToolsListObjView_DoubleClick);
//
// DisplayNameColumnHeader
//
this.DisplayNameColumnHeader.AspectName = "DisplayName";
this.DisplayNameColumnHeader.AutoCompleteEditor = false;
this.DisplayNameColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
this.DisplayNameColumnHeader.Text = "Display Name";
this.DisplayNameColumnHeader.Width = 130;
this.DisplayNameColumnHeader.UseInitialLetterForGroup = true;
this.DisplayNameColumnHeader.Width = 100;
//
// FilenameColumnHeader
//
this.FilenameColumnHeader.AspectName = "FileName";
this.FilenameColumnHeader.AutoCompleteEditor = false;
this.FilenameColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
this.FilenameColumnHeader.Groupable = false;
this.FilenameColumnHeader.Text = "Filename";
this.FilenameColumnHeader.Width = 200;
this.FilenameColumnHeader.Width = 100;
//
// ArgumentsColumnHeader
//
this.ArgumentsColumnHeader.AspectName = "Arguments";
this.ArgumentsColumnHeader.FillsFreeSpace = true;
this.ArgumentsColumnHeader.AutoCompleteEditor = false;
this.ArgumentsColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
this.ArgumentsColumnHeader.Groupable = false;
this.ArgumentsColumnHeader.Text = "Arguments";
this.ArgumentsColumnHeader.Width = 160;
this.ArgumentsColumnHeader.Width = 100;
//
// WorkingDirColumnHeader
//
this.WorkingDirColumnHeader.AspectName = "WorkingDir";
this.WorkingDirColumnHeader.AutoCompleteEditor = false;
this.WorkingDirColumnHeader.AutoCompleteEditorMode = System.Windows.Forms.AutoCompleteMode.None;
this.WorkingDirColumnHeader.Groupable = false;
this.WorkingDirColumnHeader.Text = "Working Directory";
this.WorkingDirColumnHeader.Width = 120;
//
// WaitForExitColumnHeader
//
this.WaitForExitColumnHeader.AspectName = "WaitForExit";
this.WaitForExitColumnHeader.CheckBoxes = true;
this.WaitForExitColumnHeader.Groupable = false;
this.WaitForExitColumnHeader.Text = "Wait for exit";
this.WaitForExitColumnHeader.Width = 95;
this.WaitForExitColumnHeader.Width = 75;
//
// TryToIntegrateColumnHeader
//
this.TryToIntegrateColumnHeader.AspectName = "TryIntegrate";
this.TryToIntegrateColumnHeader.CheckBoxes = true;
this.TryToIntegrateColumnHeader.Groupable = false;
this.TryToIntegrateColumnHeader.Text = "Try To Integrate";
this.TryToIntegrateColumnHeader.Width = 95;
//
// RunElevateHeader
//
this.RunElevateHeader.AspectName = "RunElevated";
this.RunElevateHeader.CheckBoxes = true;
this.RunElevateHeader.Groupable = false;
this.RunElevateHeader.Text = "Run Elevated";
this.RunElevateHeader.Width = 95;
//
// ShowOnToolbarColumnHeader
//
this.ShowOnToolbarColumnHeader.AspectName = "ShowOnToolbar";
this.ShowOnToolbarColumnHeader.CheckBoxes = true;
this.ShowOnToolbarColumnHeader.Groupable = false;
this.ShowOnToolbarColumnHeader.Text = "Show On Toolbar";
this.ShowOnToolbarColumnHeader.Width = 120;
//
// ToolsContextMenuStrip
//
this.ToolsContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -153,6 +221,7 @@ namespace mRemoteNG.UI.Window
//
// DeleteToolMenuItem
//
this.DeleteToolMenuItem.Enabled = false;
this.DeleteToolMenuItem.Image = global::mRemoteNG.Resources.ExtApp_Delete;
this.DeleteToolMenuItem.Name = "DeleteToolMenuItem";
this.DeleteToolMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;
@@ -167,6 +236,7 @@ namespace mRemoteNG.UI.Window
//
// LaunchToolMenuItem
//
this.LaunchToolMenuItem.Enabled = false;
this.LaunchToolMenuItem.Image = global::mRemoteNG.Resources.ExtApp_Start;
this.LaunchToolMenuItem.Name = "LaunchToolMenuItem";
this.LaunchToolMenuItem.Size = new System.Drawing.Size(219, 22);
@@ -177,6 +247,11 @@ namespace mRemoteNG.UI.Window
//
this.PropertiesGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.PropertiesGroupBox.Controls.Add(this.ShowOnToolbarCheckBox);
this.PropertiesGroupBox.Controls.Add(this.RunElevatedCheckBox);
this.PropertiesGroupBox.Controls.Add(this.BrowseWorkingDir);
this.PropertiesGroupBox.Controls.Add(this.WorkingDirLabel);
this.PropertiesGroupBox.Controls.Add(this.WorkingDirTextBox);
this.PropertiesGroupBox.Controls.Add(this.TryToIntegrateCheckBox);
this.PropertiesGroupBox.Controls.Add(this.OptionsLabel);
this.PropertiesGroupBox.Controls.Add(this.WaitForExitCheckBox);
@@ -188,30 +263,85 @@ namespace mRemoteNG.UI.Window
this.PropertiesGroupBox.Controls.Add(this.FilenameLabel);
this.PropertiesGroupBox.Controls.Add(this.DisplayNameLabel);
this.PropertiesGroupBox.Enabled = false;
this.PropertiesGroupBox.Location = new System.Drawing.Point(0, 153);
this.PropertiesGroupBox.Location = new System.Drawing.Point(0, 192);
this.PropertiesGroupBox.Name = "PropertiesGroupBox";
this.PropertiesGroupBox.Size = new System.Drawing.Size(684, 145);
this.PropertiesGroupBox.Size = new System.Drawing.Size(827, 184);
this.PropertiesGroupBox.TabIndex = 1;
this.PropertiesGroupBox.TabStop = false;
this.PropertiesGroupBox.Text = "External Tool Properties";
//
// ShowOnToolbarCheckBox
//
this.ShowOnToolbarCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
this.ShowOnToolbarCheckBox.AutoSize = true;
this.ShowOnToolbarCheckBox.Location = new System.Drawing.Point(306, 158);
this.ShowOnToolbarCheckBox.Name = "ShowOnToolbarCheckBox";
this.ShowOnToolbarCheckBox.Size = new System.Drawing.Size(113, 17);
this.ShowOnToolbarCheckBox.TabIndex = 10;
this.ShowOnToolbarCheckBox.Text = "Show on toolbar";
this.ShowOnToolbarCheckBox.UseVisualStyleBackColor = true;
this.ShowOnToolbarCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// RunElevatedCheckBox
//
this.RunElevatedCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
this.RunElevatedCheckBox.AutoSize = true;
this.RunElevatedCheckBox.Location = new System.Drawing.Point(126, 158);
this.RunElevatedCheckBox.Name = "RunElevatedCheckBox";
this.RunElevatedCheckBox.Size = new System.Drawing.Size(93, 17);
this.RunElevatedCheckBox.TabIndex = 9;
this.RunElevatedCheckBox.Text = "Run Elevated";
this.RunElevatedCheckBox.UseVisualStyleBackColor = true;
this.RunElevatedCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// BrowseWorkingDir
//
this.BrowseWorkingDir._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
this.BrowseWorkingDir.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.BrowseWorkingDir.Location = new System.Drawing.Point(723, 103);
this.BrowseWorkingDir.Name = "BrowseWorkingDir";
this.BrowseWorkingDir.Size = new System.Drawing.Size(95, 23);
this.BrowseWorkingDir.TabIndex = 6;
this.BrowseWorkingDir.Text = "Browse...";
this.BrowseWorkingDir.UseVisualStyleBackColor = true;
this.BrowseWorkingDir.Click += new System.EventHandler(this.BrowseWorkingDir_Click);
//
// WorkingDirLabel
//
this.WorkingDirLabel.AutoSize = true;
this.WorkingDirLabel.Location = new System.Drawing.Point(6, 108);
this.WorkingDirLabel.Name = "WorkingDirLabel";
this.WorkingDirLabel.Size = new System.Drawing.Size(104, 13);
this.WorkingDirLabel.TabIndex = 11;
this.WorkingDirLabel.Text = "Working Directory:";
this.WorkingDirLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// WorkingDirTextBox
//
this.WorkingDirTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.WorkingDirTextBox.Location = new System.Drawing.Point(126, 104);
this.WorkingDirTextBox.Name = "WorkingDirTextBox";
this.WorkingDirTextBox.Size = new System.Drawing.Size(591, 22);
this.WorkingDirTextBox.TabIndex = 5;
this.WorkingDirTextBox.Leave += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// TryToIntegrateCheckBox
//
this.TryToIntegrateCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
this.TryToIntegrateCheckBox.AutoSize = true;
this.TryToIntegrateCheckBox.Location = new System.Drawing.Point(280, 106);
this.TryToIntegrateCheckBox.Location = new System.Drawing.Point(306, 135);
this.TryToIntegrateCheckBox.Name = "TryToIntegrateCheckBox";
this.TryToIntegrateCheckBox.Size = new System.Drawing.Size(103, 17);
this.TryToIntegrateCheckBox.TabIndex = 9;
this.TryToIntegrateCheckBox.TabIndex = 8;
this.TryToIntegrateCheckBox.Text = "Try to integrate";
this.TryToIntegrateCheckBox.UseVisualStyleBackColor = true;
this.TryToIntegrateCheckBox.CheckedChanged += new System.EventHandler(this.TryToIntegrateCheckBox_CheckedChanged);
this.TryToIntegrateCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// OptionsLabel
//
this.OptionsLabel.AutoSize = true;
this.OptionsLabel.Location = new System.Drawing.Point(51, 107);
this.OptionsLabel.Location = new System.Drawing.Point(6, 135);
this.OptionsLabel.Name = "OptionsLabel";
this.OptionsLabel.Size = new System.Drawing.Size(52, 13);
this.OptionsLabel.TabIndex = 7;
@@ -222,10 +352,10 @@ namespace mRemoteNG.UI.Window
//
this.WaitForExitCheckBox._mice = mRemoteNG.UI.Controls.Base.NGCheckBox.MouseState.HOVER;
this.WaitForExitCheckBox.AutoSize = true;
this.WaitForExitCheckBox.Location = new System.Drawing.Point(110, 106);
this.WaitForExitCheckBox.Location = new System.Drawing.Point(126, 135);
this.WaitForExitCheckBox.Name = "WaitForExitCheckBox";
this.WaitForExitCheckBox.Size = new System.Drawing.Size(89, 17);
this.WaitForExitCheckBox.TabIndex = 8;
this.WaitForExitCheckBox.TabIndex = 7;
this.WaitForExitCheckBox.Text = "Wait for exit";
this.WaitForExitCheckBox.UseVisualStyleBackColor = true;
this.WaitForExitCheckBox.Click += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
@@ -233,11 +363,12 @@ namespace mRemoteNG.UI.Window
//
// BrowseButton
//
this.BrowseButton._mice = mRemoteNG.UI.Controls.Base.NGButton.MouseState.HOVER;
this.BrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.BrowseButton.Location = new System.Drawing.Point(580, 45);
this.BrowseButton.Location = new System.Drawing.Point(723, 46);
this.BrowseButton.Name = "BrowseButton";
this.BrowseButton.Size = new System.Drawing.Size(95, 23);
this.BrowseButton.TabIndex = 4;
this.BrowseButton.TabIndex = 3;
this.BrowseButton.Text = "Browse...";
this.BrowseButton.UseVisualStyleBackColor = true;
this.BrowseButton.Click += new System.EventHandler(this.BrowseButton_Click);
@@ -248,10 +379,10 @@ namespace mRemoteNG.UI.Window
this.ArgumentsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ArgumentsCheckBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ArgumentsCheckBox.Location = new System.Drawing.Point(110, 76);
this.ArgumentsCheckBox.Location = new System.Drawing.Point(126, 76);
this.ArgumentsCheckBox.Name = "ArgumentsCheckBox";
this.ArgumentsCheckBox.Size = new System.Drawing.Size(565, 22);
this.ArgumentsCheckBox.TabIndex = 6;
this.ArgumentsCheckBox.Size = new System.Drawing.Size(591, 22);
this.ArgumentsCheckBox.TabIndex = 4;
this.ArgumentsCheckBox.LostFocus += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// FilenameTextBox
@@ -259,10 +390,10 @@ namespace mRemoteNG.UI.Window
this.FilenameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.FilenameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.FilenameTextBox.Location = new System.Drawing.Point(110, 47);
this.FilenameTextBox.Location = new System.Drawing.Point(126, 47);
this.FilenameTextBox.Name = "FilenameTextBox";
this.FilenameTextBox.Size = new System.Drawing.Size(464, 22);
this.FilenameTextBox.TabIndex = 3;
this.FilenameTextBox.Size = new System.Drawing.Size(591, 22);
this.FilenameTextBox.TabIndex = 2;
this.FilenameTextBox.LostFocus += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// DisplayNameTextBox
@@ -270,16 +401,16 @@ namespace mRemoteNG.UI.Window
this.DisplayNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.DisplayNameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.DisplayNameTextBox.Location = new System.Drawing.Point(110, 19);
this.DisplayNameTextBox.Location = new System.Drawing.Point(126, 19);
this.DisplayNameTextBox.Name = "DisplayNameTextBox";
this.DisplayNameTextBox.Size = new System.Drawing.Size(565, 22);
this.DisplayNameTextBox.Size = new System.Drawing.Size(591, 22);
this.DisplayNameTextBox.TabIndex = 1;
this.DisplayNameTextBox.LostFocus += new System.EventHandler(this.PropertyControl_ChangedOrLostFocus);
//
// ArgumentsLabel
//
this.ArgumentsLabel.AutoSize = true;
this.ArgumentsLabel.Location = new System.Drawing.Point(33, 79);
this.ArgumentsLabel.Location = new System.Drawing.Point(6, 78);
this.ArgumentsLabel.Name = "ArgumentsLabel";
this.ArgumentsLabel.Size = new System.Drawing.Size(66, 13);
this.ArgumentsLabel.TabIndex = 5;
@@ -289,7 +420,7 @@ namespace mRemoteNG.UI.Window
// FilenameLabel
//
this.FilenameLabel.AutoSize = true;
this.FilenameLabel.Location = new System.Drawing.Point(44, 50);
this.FilenameLabel.Location = new System.Drawing.Point(6, 50);
this.FilenameLabel.Name = "FilenameLabel";
this.FilenameLabel.Size = new System.Drawing.Size(56, 13);
this.FilenameLabel.TabIndex = 2;
@@ -299,7 +430,7 @@ namespace mRemoteNG.UI.Window
// DisplayNameLabel
//
this.DisplayNameLabel.AutoSize = true;
this.DisplayNameLabel.Location = new System.Drawing.Point(21, 22);
this.DisplayNameLabel.Location = new System.Drawing.Point(6, 21);
this.DisplayNameLabel.Name = "DisplayNameLabel";
this.DisplayNameLabel.Size = new System.Drawing.Size(79, 13);
this.DisplayNameLabel.TabIndex = 0;
@@ -313,11 +444,11 @@ namespace mRemoteNG.UI.Window
//
this.ToolStripContainer.ContentPanel.Controls.Add(this.PropertiesGroupBox);
this.ToolStripContainer.ContentPanel.Controls.Add(this.ToolsListObjView);
this.ToolStripContainer.ContentPanel.Size = new System.Drawing.Size(684, 298);
this.ToolStripContainer.ContentPanel.Size = new System.Drawing.Size(827, 376);
this.ToolStripContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ToolStripContainer.Location = new System.Drawing.Point(0, 0);
this.ToolStripContainer.Name = "ToolStripContainer";
this.ToolStripContainer.Size = new System.Drawing.Size(684, 323);
this.ToolStripContainer.Size = new System.Drawing.Size(827, 401);
this.ToolStripContainer.TabIndex = 0;
this.ToolStripContainer.Text = "ToolStripContainer";
//
@@ -351,6 +482,7 @@ namespace mRemoteNG.UI.Window
//
// DeleteToolToolstripButton
//
this.DeleteToolToolstripButton.Enabled = false;
this.DeleteToolToolstripButton.Image = global::mRemoteNG.Resources.ExtApp_Delete;
this.DeleteToolToolstripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.DeleteToolToolstripButton.Name = "DeleteToolToolstripButton";
@@ -365,6 +497,7 @@ namespace mRemoteNG.UI.Window
//
// LaunchToolToolstripButton
//
this.LaunchToolToolstripButton.Enabled = false;
this.LaunchToolToolstripButton.Image = global::mRemoteNG.Resources.ExtApp_Start;
this.LaunchToolToolstripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.LaunchToolToolstripButton.Name = "LaunchToolToolstripButton";
@@ -378,7 +511,7 @@ namespace mRemoteNG.UI.Window
//
// ExternalToolsWindow
//
this.ClientSize = new System.Drawing.Size(684, 323);
this.ClientSize = new System.Drawing.Size(827, 401);
this.Controls.Add(this.ToolStripContainer);
this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
@@ -411,5 +544,6 @@ namespace mRemoteNG.UI.Window
#endregion
private System.ComponentModel.IContainer components;
internal Controls.Base.NGGroupBox PropertiesGroupBox;
}
}

View File

@@ -1,20 +1,22 @@
using System.Collections.Generic;
using System;
using System.Linq;
using System.Windows.Forms;
using BrightIdeasSoftware;
using mRemoteNG.App;
using mRemoteNG.Config.Settings;
using mRemoteNG.Tools;
using WeifenLuo.WinFormsUI.Docking;
using mRemoteNG.UI.Forms;
using mRemoteNG.Themes;
using mRemoteNG.Tools.CustomCollections;
namespace mRemoteNG.UI.Window
{
public partial class ExternalToolsWindow
{
private readonly ExternalAppsSaver _externalAppsSaver;
private ExternalTool _selectedTool;
private ThemeManager _themeManager;
private readonly ThemeManager _themeManager;
private readonly FullyObservableCollection<ExternalTool> _currentlySelectedExternalTools;
public ExternalToolsWindow()
{
@@ -24,23 +26,120 @@ namespace mRemoteNG.UI.Window
_themeManager = ThemeManager.getInstance();
_themeManager.ThemeChanged += ApplyTheme;
_externalAppsSaver = new ExternalAppsSaver();
_currentlySelectedExternalTools = new FullyObservableCollection<ExternalTool>();
_currentlySelectedExternalTools.CollectionUpdated += CurrentlySelectedExternalToolsOnCollectionUpdated;
}
#region Private Methods
#region Private Methods
private void ExternalTools_Load(object sender, EventArgs e)
{
ApplyLanguage();
ApplyTheme();
UpdateToolsListObjView();
}
private void ApplyLanguage()
{
Text = Language.strMenuExternalTools;
TabText = Language.strMenuExternalTools;
NewToolToolstripButton.Text = Language.strButtonNew;
DeleteToolToolstripButton.Text = Language.strOptionsKeyboardButtonDelete;
LaunchToolToolstripButton.Text = Language.strButtonLaunch;
DisplayNameColumnHeader.Text = Language.strColumnDisplayName;
FilenameColumnHeader.Text = Language.strColumnFilename;
ArgumentsColumnHeader.Text = Language.strColumnArguments;
WaitForExitColumnHeader.Text = Language.strColumnWaitForExit;
TryToIntegrateCheckBox.Text = Language.strTryIntegrate;
ShowOnToolbarCheckBox.Text = Language.strShowOnToolbar;
PropertiesGroupBox.Text = Language.strGroupboxExternalToolProperties;
DisplayNameLabel.Text = Language.strLabelDisplayName;
FilenameLabel.Text = Language.strLabelFilename;
ArgumentsLabel.Text = Language.strLabelArguments;
OptionsLabel.Text = Language.strLabelOptions;
WaitForExitCheckBox.Text = Language.strCheckboxWaitForExit;
BrowseButton.Text = Language.strButtonBrowse;
NewToolMenuItem.Text = Language.strMenuNewExternalTool;
DeleteToolMenuItem.Text = Language.strMenuDeleteExternalTool;
LaunchToolMenuItem.Text = Language.strMenuLaunchExternalTool;
}
private new void ApplyTheme()
{
if (!_themeManager.ThemingActive) return;
vsToolStripExtender.SetStyle(ToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
vsToolStripExtender.SetStyle(ToolsContextMenuStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
//Apply the extended palette
ToolStripContainer.TopToolStripPanel.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
ToolStripContainer.TopToolStripPanel.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
PropertiesGroupBox.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
PropertiesGroupBox.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
}
private void UpdateToolsListObjView()
{
try
{
ToolsListObjView.BeginUpdate();
ToolsListObjView.SetObjects(Runtime.ExternalToolsService.ExternalTools, true);
ToolsListObjView.AutoResizeColumns();
ToolsListObjView.EndUpdate();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.PopulateToolsListObjView()", ex);
}
}
private void LaunchTool()
{
try
{
foreach (var externalTool in _currentlySelectedExternalTools)
{
externalTool.Start();
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.LaunchTool() failed.", ex);
}
}
private void UpdateEditorControls()
{
var selectedTool = _currentlySelectedExternalTools.FirstOrDefault();
DisplayNameTextBox.Text = selectedTool?.DisplayName;
FilenameTextBox.Text = selectedTool?.FileName;
ArgumentsCheckBox.Text = selectedTool?.Arguments;
WorkingDirTextBox.Text = selectedTool?.WorkingDir;
WaitForExitCheckBox.Checked = selectedTool?.WaitForExit ?? false;
TryToIntegrateCheckBox.Checked = selectedTool?.TryIntegrate ?? false;
ShowOnToolbarCheckBox.Checked = selectedTool?.ShowOnToolbar ?? false;
RunElevatedCheckBox.Checked = selectedTool?.RunElevated ?? false;
WaitForExitCheckBox.Enabled = !TryToIntegrateCheckBox.Checked;
}
#endregion
#region Event Handlers
private void ExternalTools_Load(object sender, EventArgs e)
{
ApplyLanguage();
ApplyTheme();
UpdateToolsListObjView();
}
private void CurrentlySelectedExternalToolsOnCollectionUpdated(object sender, CollectionUpdatedEventArgs<ExternalTool> collectionUpdatedEventArgs)
{
UpdateEditorControls();
}
private void ExternalTools_FormClosed(object sender, FormClosedEventArgs e)
{
_externalAppsSaver.Save(Runtime.ExternalToolsService.ExternalTools);
}
_themeManager.ThemeChanged -= ApplyTheme;
_currentlySelectedExternalTools.CollectionUpdated -= CurrentlySelectedExternalToolsOnCollectionUpdated;
}
private void NewTool_Click(object sender, EventArgs e)
{
@@ -48,7 +147,8 @@ namespace mRemoteNG.UI.Window
{
var externalTool = new ExternalTool(Language.strExternalToolDefaultName);
Runtime.ExternalToolsService.ExternalTools.Add(externalTool);
UpdateToolsListObjView(externalTool);
UpdateToolsListObjView();
ToolsListObjView.SelectedObject = externalTool;
DisplayNameTextBox.Focus();
}
catch (Exception ex)
@@ -62,31 +162,29 @@ namespace mRemoteNG.UI.Window
try
{
string message;
if (ToolsListObjView.SelectedItems.Count == 1)
{
message = string.Format(Language.strConfirmDeleteExternalTool, ToolsListObjView.SelectedItems[0].Text);
}
else if (ToolsListObjView.SelectedItems.Count > 1)
{
message = string.Format(Language.strConfirmDeleteExternalToolMultiple, ToolsListObjView.SelectedItems.Count);
}
if (_currentlySelectedExternalTools.Count == 1)
message = string.Format(Language.strConfirmDeleteExternalTool, _currentlySelectedExternalTools[0].DisplayName);
else if (_currentlySelectedExternalTools.Count > 1)
message = string.Format(Language.strConfirmDeleteExternalToolMultiple, _currentlySelectedExternalTools.Count);
else
{
return;
}
if (MessageBox.Show(FrmMain.Default, message, "Question?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
foreach (Object toDeleteObj in ToolsListObjView.SelectedObjects)
foreach (var externalTool in _currentlySelectedExternalTools)
{
var externalTool = toDeleteObj as ExternalTool;
if (externalTool == null) continue;
Runtime.ExternalToolsService.ExternalTools.Remove(externalTool);
}
var firstDeletedNode = _currentlySelectedExternalTools.FirstOrDefault();
var oldSelectedIndex = ToolsListObjView.IndexOf(firstDeletedNode);
_currentlySelectedExternalTools.Clear();
UpdateToolsListObjView();
var maxIndex = ToolsListObjView.GetItemCount() - 1;
ToolsListObjView.SelectedIndex = oldSelectedIndex <= maxIndex
? oldSelectedIndex
: maxIndex;
}
catch (Exception ex)
{
@@ -103,25 +201,15 @@ namespace mRemoteNG.UI.Window
{
try
{
if (ToolsListObjView.SelectedItems.Count == 1)
{
PropertiesGroupBox.Enabled = true;
_selectedTool = ToolsListObjView.SelectedObjects[0] as ExternalTool;
if (_selectedTool == null)
{
return;
}
DisplayNameTextBox.Text = _selectedTool.DisplayName;
FilenameTextBox.Text = _selectedTool.FileName;
ArgumentsCheckBox.Text = _selectedTool.Arguments;
WaitForExitCheckBox.Checked = _selectedTool.WaitForExit;
TryToIntegrateCheckBox.Checked = _selectedTool.TryIntegrate;
}
else
{
PropertiesGroupBox.Enabled = false;
}
_currentlySelectedExternalTools.Clear();
_currentlySelectedExternalTools.AddRange(ToolsListObjView.SelectedObjects.OfType<ExternalTool>());
PropertiesGroupBox.Enabled = _currentlySelectedExternalTools.Count == 1;
var atleastOneToolSelected = _currentlySelectedExternalTools.Count > 0;
DeleteToolMenuItem.Enabled = atleastOneToolSelected;
DeleteToolToolstripButton.Enabled = atleastOneToolSelected;
LaunchToolMenuItem.Enabled = atleastOneToolSelected;
LaunchToolToolstripButton.Enabled = atleastOneToolSelected;
}
catch (Exception ex)
{
@@ -139,20 +227,22 @@ namespace mRemoteNG.UI.Window
private void PropertyControl_ChangedOrLostFocus(object sender, EventArgs e)
{
if (_selectedTool == null)
{
var selectedTool = _currentlySelectedExternalTools.FirstOrDefault();
if (selectedTool == null)
return;
}
try
{
_selectedTool.DisplayName = DisplayNameTextBox.Text;
_selectedTool.FileName = FilenameTextBox.Text;
_selectedTool.Arguments = ArgumentsCheckBox.Text;
_selectedTool.WaitForExit = WaitForExitCheckBox.Checked;
_selectedTool.TryIntegrate = TryToIntegrateCheckBox.Checked;
UpdateToolsListObjView();
selectedTool.DisplayName = DisplayNameTextBox.Text;
selectedTool.FileName = FilenameTextBox.Text;
selectedTool.Arguments = ArgumentsCheckBox.Text;
selectedTool.WorkingDir = WorkingDirTextBox.Text;
selectedTool.WaitForExit = WaitForExitCheckBox.Checked;
selectedTool.TryIntegrate = TryToIntegrateCheckBox.Checked;
selectedTool.ShowOnToolbar = ShowOnToolbarCheckBox.Checked;
selectedTool.RunElevated = RunElevatedCheckBox.Checked;
UpdateToolsListObjView();
}
catch (Exception ex)
{
@@ -166,128 +256,53 @@ namespace mRemoteNG.UI.Window
{
using (var browseDialog = new OpenFileDialog())
{
browseDialog.Filter = string.Join("|", new string[] {Language.strFilterApplication, "*.exe", Language.strFilterAll, "*.*"});
if (browseDialog.ShowDialog() == DialogResult.OK)
{
FilenameTextBox.Text = browseDialog.FileName;
}
browseDialog.Filter = string.Join("|", Language.strFilterApplication, "*.exe", Language.strFilterAll, "*.*");
if (browseDialog.ShowDialog() != DialogResult.OK)
return;
var selectedItem = _currentlySelectedExternalTools.FirstOrDefault();
if (selectedItem == null)
return;
selectedItem.FileName = browseDialog.FileName;
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.BrowseButton_Click() failed.", ex);
}
}
private void TryToIntegrateCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (TryToIntegrateCheckBox.Checked)
{
WaitForExitCheckBox.Enabled = false;
WaitForExitCheckBox.Checked = false;
}
else
{
WaitForExitCheckBox.Enabled = true;
}
}
#endregion
private void ApplyLanguage()
{
Text = Language.strMenuExternalTools;
TabText = Language.strMenuExternalTools;
NewToolToolstripButton.Text = Language.strButtonNew;
DeleteToolToolstripButton.Text = Language.strOptionsKeyboardButtonDelete;
LaunchToolToolstripButton.Text = Language.strButtonLaunch;
DisplayNameColumnHeader.Text = Language.strColumnDisplayName;
FilenameColumnHeader.Text = Language.strColumnFilename;
ArgumentsColumnHeader.Text = Language.strColumnArguments;
WaitForExitColumnHeader.Text = Language.strColumnWaitForExit;
TryToIntegrateCheckBox.Text = Language.strTryIntegrate;
PropertiesGroupBox.Text = Language.strGroupboxExternalToolProperties;
DisplayNameLabel.Text = Language.strLabelDisplayName;
FilenameLabel.Text = Language.strLabelFilename;
ArgumentsLabel.Text = Language.strLabelArguments;
OptionsLabel.Text = Language.strLabelOptions;
WaitForExitCheckBox.Text = Language.strCheckboxWaitForExit;
BrowseButton.Text = Language.strButtonBrowse;
NewToolMenuItem.Text = Language.strMenuNewExternalTool;
DeleteToolMenuItem.Text = Language.strMenuDeleteExternalTool;
LaunchToolMenuItem.Text = Language.strMenuLaunchExternalTool;
}
private new void ApplyTheme()
{
if (!_themeManager.ThemingActive) return;
vsToolStripExtender.SetStyle(ToolStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
vsToolStripExtender.SetStyle(ToolsContextMenuStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
//Apply the extended palette
ToolStripContainer.TopToolStripPanel.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
ToolStripContainer.TopToolStripPanel.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
PropertiesGroupBox.BackColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Background;
PropertiesGroupBox.ForeColor = _themeManager.ActiveTheme.Theme.ColorPalette.CommandBarMenuDefault.Text;
//Toollist grouping
ToolsListObjView.AlwaysGroupByColumn = this.FilenameColumnHeader;
}
private void UpdateToolsListObjView(ExternalTool selectTool = null)
private void BrowseWorkingDir_Click(object sender, EventArgs e)
{
var selectedTools = new List<ExternalTool>();
try
{
if (selectTool == null)
{
foreach (var listViewItem in ToolsListObjView.SelectedObjects)
{
var externalTool = listViewItem as ExternalTool;
if (externalTool != null)
{
selectedTools.Add(externalTool);
}
}
}
else
{
selectedTools.Add(selectTool);
}
ToolsListObjView.BeginUpdate();
ToolsListObjView.Items.Clear();
ToolsListObjView.SetObjects(Runtime.ExternalToolsService.ExternalTools);
ToolsListObjView.EndUpdate();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.PopulateToolsListObjView()", ex);
}
}
private void LaunchTool()
{
try
{
foreach (Object listViewObject in ToolsListObjView.SelectedObjects)
{
((ExternalTool)listViewObject).Start();
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.LaunchTool() failed.", ex);
}
}
using (var browseDialog = new FolderBrowserDialog())
{
if (browseDialog.ShowDialog() != DialogResult.OK)
return;
var selectedItem = _currentlySelectedExternalTools.FirstOrDefault();
if (selectedItem == null)
return;
selectedItem.WorkingDir = browseDialog.SelectedPath;
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage("UI.Window.ExternalTools.BrowseButton_Click() failed.", ex);
}
}
private void ToolsListObjView_CellToolTipShowing(object sender, ToolTipShowingEventArgs e)
{
if (e.Column != WaitForExitColumnHeader)
return;
var rowItemAsExternalTool = e.Model as ExternalTool;
if (rowItemAsExternalTool == null || !rowItemAsExternalTool.TryIntegrate)
return;
e.Text = string.Format("'{0}' cannot be enabled if '{1}' is enabled", Language.strCheckboxWaitForExit, Language.strTryIntegrate);
}
#endregion
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -75,6 +75,7 @@
<HintPath>..\packages\SSH.NET.2016.0.0\lib\net40\Renci.SshNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.DirectoryServices" />
<Reference Include="System.Drawing" />
@@ -107,7 +108,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Credential\Records\" />
<Folder Include="Properties\DataSources\" />
</ItemGroup>
<ItemGroup>
<Compile Include="App\CompatibilityChecker.cs" />
@@ -198,7 +198,6 @@
<Compile Include="Config\Settings\ExternalAppsSaver.cs" />
<Compile Include="Config\Settings\DockPanelLayoutLoader.cs" />
<Compile Include="Config\Settings\DockPanelLayoutSaver.cs" />
<Compile Include="Config\Settings\Providers\AppSettingsProvider.cs" />
<Compile Include="Config\Settings\Providers\ChooseProvider.cs" />
<Compile Include="Config\Settings\SettingsLoader.cs" />
<Compile Include="Config\Settings\Providers\PortableSettingsProvider.cs" />
@@ -307,6 +306,7 @@
<Compile Include="Tools\Cmdline\StartupArgumentsInterpreter.cs" />
<Compile Include="Tools\CustomCollections\CollectionUpdatedEventArgs.cs" />
<Compile Include="Tools\DesignModeTest.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Tools\Extensions.cs" />
<Compile Include="Tools\ExternalToolArgumentParser.cs" />
<Compile Include="Tools\Cmdline\CmdArgumentsInterpreter.cs" />
@@ -1598,4 +1598,4 @@ powershell.exe -ExecutionPolicy Bypass -File "%25psScriptsDir%25\postbuild_mremo
</PropertyGroup>
<Error Condition="!Exists('..\packages\Geckofx45.45.0.32\build\Geckofx45.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Geckofx45.45.0.32\build\Geckofx45.targets'))" />
</Target>
</Project>
</Project>