Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVsevolod Kukol <sevoku@xamarin.com>2016-07-08 12:47:12 +0300
committerVsevolod Kukol <sevoku@xamarin.com>2016-07-08 17:07:29 +0300
commit0d4aa037f5c9dda81183328a51a56a323a086ab1 (patch)
tree17d5a48b54dc7ef75f7ec7926cd2391cf66e6f7c /main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools
parent66d0294724ca11a7958a8addfde530314b5031af (diff)
[Ide] Register ActionCommands for custom tools
Add custom tools to the global command system, which allows to assign key bindings to custom tools and makes them visible in the global search and key bindings option panel. (fixes bug #9222)
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs74
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs121
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolService.cs34
3 files changed, 220 insertions, 9 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs
index 3481572852..448318f114 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalTool.cs
@@ -28,9 +28,11 @@
using System;
using System.Diagnostics;
+using System.Threading.Tasks;
using System.Xml;
-
+using MonoDevelop.Components.Commands;
using MonoDevelop.Core;
+using MonoDevelop.Core.Execution;
namespace MonoDevelop.Ide.ExternalTools
{
@@ -40,6 +42,7 @@ namespace MonoDevelop.Ide.ExternalTools
string command;
string arguments;
string initialDirectory;
+ string accelKey;
bool promptForArguments;
bool useOutputPad = true;
bool saveCurrentFile;
@@ -80,6 +83,15 @@ namespace MonoDevelop.Ide.ExternalTools
}
}
+ public string AccelKey {
+ get {
+ return accelKey;
+ }
+ set {
+ accelKey = value;
+ }
+ }
+
public bool PromptForArguments {
get {
return promptForArguments;
@@ -111,6 +123,62 @@ namespace MonoDevelop.Ide.ExternalTools
{
this.menuCommand = GettextCatalog.GetString ("New Tool");
}
+
+ internal void Run ()
+ {
+ string argumentsTool = StringParserService.Parse (Arguments, IdeApp.Workbench.GetStringTagModel ());
+
+ //Save current file checkbox
+ if (SaveCurrentFile && IdeApp.Workbench.ActiveDocument != null)
+ IdeApp.Workbench.ActiveDocument.Save ();
+
+ if (PromptForArguments) {
+ string customerArguments = MessageService.GetTextResponse (GettextCatalog.GetString ("Enter any arguments you want to use while launching tool, {0}:", MenuCommand), GettextCatalog.GetString ("Command Arguments for {0}", MenuCommand), "");
+ if (customerArguments != String.Empty)
+ argumentsTool = StringParserService.Parse (customerArguments, IdeApp.Workbench.GetStringTagModel ());
+ }
+
+ Task.Run (delegate {
+ RunExternalTool (this, argumentsTool);
+ });
+ }
+
+ static void RunExternalTool (ExternalTools.ExternalTool tool, string argumentsTool)
+ {
+ string commandTool = StringParserService.Parse (tool.Command, IdeApp.Workbench.GetStringTagModel ());
+ string initialDirectoryTool = StringParserService.Parse (tool.InitialDirectory, IdeApp.Workbench.GetStringTagModel ());
+
+ //Execute tool
+ ProgressMonitor progressMonitor = IdeApp.Workbench.ProgressMonitors.GetRunProgressMonitor ();
+ try {
+ progressMonitor.Log.WriteLine (GettextCatalog.GetString ("Running: {0} {1}", (commandTool), (argumentsTool)));
+ progressMonitor.Log.WriteLine ();
+
+ ProcessWrapper processWrapper;
+ if (tool.UseOutputPad)
+ processWrapper = Runtime.ProcessService.StartProcess (commandTool, argumentsTool, initialDirectoryTool, progressMonitor.Log, progressMonitor.Log, null);
+ else
+ processWrapper = Runtime.ProcessService.StartProcess (commandTool, argumentsTool, initialDirectoryTool, null);
+
+ string processName = System.IO.Path.GetFileName (commandTool);
+ try {
+ processName = processWrapper.ProcessName;
+ } catch (SystemException) {
+ }
+
+ processWrapper.WaitForOutput ();
+
+ if (processWrapper.ExitCode == 0) {
+ progressMonitor.Log.WriteLine (GettextCatalog.GetString ("Process '{0}' has completed succesfully", processName));
+ } else {
+ progressMonitor.Log.WriteLine (GettextCatalog.GetString ("Process '{0}' has exited with error code {1}", processName, processWrapper.ExitCode));
+ }
+ } catch (Exception ex) {
+ progressMonitor.ReportError (GettextCatalog.GetString ("External program execution failed.\nError while starting:\n '{0} {1}'", commandTool, argumentsTool), ex);
+ } finally {
+ progressMonitor.Dispose ();
+ }
+ }
#region I/O
public const string Node = "ExternalTool";
@@ -119,6 +187,7 @@ namespace MonoDevelop.Ide.ExternalTools
const string commandAttribute = "command";
const string argumentsAttribute = "arguments";
const string initialDirectoryAttribute = "initialDirectory";
+ const string accelKeyAttribute = "accelKey";
const string promptForArgumentsAttribute = "promptForArguments";
const string useOutputPadAttribute = "useOutputPad";
const string saveCurrentFileAttribute = "saveCurrentFile";
@@ -130,6 +199,7 @@ namespace MonoDevelop.Ide.ExternalTools
writer.WriteAttributeString (commandAttribute, this.command);
writer.WriteAttributeString (argumentsAttribute, this.arguments);
writer.WriteAttributeString (initialDirectoryAttribute, this.initialDirectory);
+ writer.WriteAttributeString (accelKeyAttribute, this.accelKey);
writer.WriteAttributeString (promptForArgumentsAttribute, this.promptForArguments.ToString ());
writer.WriteAttributeString (useOutputPadAttribute, this.useOutputPad.ToString ());
writer.WriteAttributeString (saveCurrentFileAttribute, this.saveCurrentFile.ToString ());
@@ -145,7 +215,7 @@ namespace MonoDevelop.Ide.ExternalTools
result.command = reader.GetAttribute (commandAttribute);
result.arguments = reader.GetAttribute (argumentsAttribute);
result.initialDirectory = reader.GetAttribute (initialDirectoryAttribute);
- result.menuCommand = reader.GetAttribute (menuCommandAttribute);
+ result.accelKey = reader.GetAttribute (accelKeyAttribute);
if (!String.IsNullOrEmpty (reader.GetAttribute (promptForArgumentsAttribute)))
result.promptForArguments = Boolean.Parse (reader.GetAttribute (promptForArgumentsAttribute));
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs
index 2cbaa2c321..c53ad191ea 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolPanel.cs
@@ -35,6 +35,8 @@ using MonoDevelop.Components;
using MonoDevelop.Ide.ExternalTools;
using MonoDevelop.Core;
using MonoDevelop.Ide.Gui.Dialogs;
+using MonoDevelop.Components.Commands;
+using System.Linq;
#pragma warning disable 612
@@ -72,6 +74,9 @@ namespace MonoDevelop.Ide.ExternalTools
int toolListBoxItemCount = 0;
bool lockStoreValues = false;
+ EventBoxTooltip keyBindingInfoTooltip;
+ string defaultKeyBindingTooltipText;
+
public ExternalToolPanelWidget ()
{
Build ();
@@ -80,9 +85,10 @@ namespace MonoDevelop.Ide.ExternalTools
dependendControls = new Widget[] {
titleTextBox, argumentTextBox,
- workingDirTextBox, promptArgsCheckBox, useOutputPadCheckBox,
- titleLabel, argumentLabel, commandLabel,
- workingDirLabel, browseButton,
+ workingDirTextBox, promptArgsCheckBox, useOutputPadCheckBox,
+ titleLabel, argumentLabel, commandLabel, defaultKeyLabel,
+ defaultKeyTextBox, keyBindingInfoEventBox,
+ workingDirLabel, browseButton,
moveUpButton, moveDownButton,
saveCurrentFileCheckBox,
tagSelectorArgs, tagSelectorPath
@@ -107,6 +113,10 @@ namespace MonoDevelop.Ide.ExternalTools
tagSelectorPath.TagModel = IdeApp.Workbench.GetStringTagModelDescription ();
tagSelectorPath.TargetEntry = workingDirTextBox;
+ keyBindingInfoTooltip = new EventBoxTooltip (keyBindingInfoEventBox) {
+ Severity = Tasks.TaskSeverity.Warning
+ };
+
toolListBox.Selection.Changed += SelectionChanged;
removeButton.Clicked += RemoveButtonClicked;
addButton.Clicked += AddButtonClicked;
@@ -120,7 +130,10 @@ namespace MonoDevelop.Ide.ExternalTools
promptArgsCheckBox.Toggled += StoreValuesInSelectedTool;
useOutputPadCheckBox.Toggled += StoreValuesInSelectedTool;
saveCurrentFileCheckBox.Toggled += StoreValuesInSelectedTool;
-
+
+ defaultKeyTextBox.KeyPressEvent += OnDefaultKeyEntryKeyPress;
+ defaultKeyTextBox.KeyReleaseEvent += OnDefaultKeyEntryKeyRelease;
+
SelectionChanged (this, EventArgs.Empty);
}
@@ -154,6 +167,101 @@ namespace MonoDevelop.Ide.ExternalTools
((ListStore)ls).Swap (selectedItem, toSwap);
}
}
+
+ bool accelIncomplete = false;
+ bool accelComplete = false;
+ string chord;
+
+ string currentKey;
+ string CurrentKey {
+ get {
+ return currentKey ?? string.Empty;
+ }
+ set {
+ currentKey = value;
+ defaultKeyTextBox.Text = value == null ? "" : KeyBindingManager.BindingToDisplayLabel (value, false, true);
+
+ var cmdConflicts = new HashSet<string> ();
+ KeyBinding binding = null;
+ if (KeyBinding.TryParse (currentKey, out binding)) {
+ foreach (var cmd in IdeApp.CommandService.GetCommands (binding).Where (c => !((string)c.Id).StartsWith ("MonoDevelop.CustomCommands.Command", StringComparison.Ordinal))) {
+ cmdConflicts.Add (cmd.Category + " \u2013 " + cmd.DisplayName);
+ }
+ }
+
+ TreeIter iter;
+ if (toolListBoxStore.GetIterFirst (out iter)) {
+ do {
+ if (!iter.Equals (SelectedIter)) {
+ var tool = toolListBoxStore.GetValue (iter, 1) as ExternalTool;
+ if (tool?.AccelKey == value)
+ cmdConflicts.Add ("Tools \u2013 " + tool.MenuCommand);
+ }
+ } while (toolListBoxStore.IterNext (ref iter));
+ }
+
+ if (cmdConflicts.Count > 0) {
+ keyBindingInfoEventBox.Visible = true;
+ keyBindingInfoTooltip.Severity = Tasks.TaskSeverity.Warning;
+ var text = GettextCatalog.GetPluralString (
+ "This shortcut is assigned to another command:",
+ "This shortcut is assigned to other commands:",
+ cmdConflicts.Count) + "\n";
+ foreach (var cmd in cmdConflicts)
+ text += "\n\u2022 " + cmd;
+ keyBindingInfoTooltip.ToolTip = text;
+ } else {
+ keyBindingInfoEventBox.Visible = false;
+ }
+
+ if (lockStoreValues)
+ return;
+ ExternalTool selectedItem = SelectedTool;
+ if (selectedItem != null)
+ selectedItem.AccelKey = CurrentKey;
+ }
+ }
+
+ [GLib.ConnectBefore]
+ void OnDefaultKeyEntryKeyPress (object sender, KeyPressEventArgs e)
+ {
+ Gdk.Key key = e.Event.Key;
+ string accel;
+
+ e.RetVal = true;
+
+ if (accelComplete) {
+ CurrentKey = String.Empty;
+ accelIncomplete = false;
+ accelComplete = false;
+ chord = null;
+
+ if (key.Equals (Gdk.Key.BackSpace))
+ return;
+ }
+
+ accelComplete = false;
+ bool combinationComplete;
+ accel = KeyBindingManager.AccelLabelFromKey (e.Event, out combinationComplete);
+ if (combinationComplete) {
+ CurrentKey = KeyBindingManager.Binding (chord, accel);
+ accelIncomplete = false;
+ if (chord != null)
+ accelComplete = true;
+ else
+ chord = accel;
+ } else {
+ accel = (chord != null ? chord + "|" : string.Empty) + accel;
+ accelIncomplete = true;
+ CurrentKey = accel;
+ }
+ }
+
+ void OnDefaultKeyEntryKeyRelease (object sender, KeyReleaseEventArgs e)
+ {
+ if (accelIncomplete)
+ CurrentKey = chord != null ? chord : string.Empty;
+ }
void StoreValuesInSelectedTool (object sender, EventArgs e)
{
@@ -206,13 +314,16 @@ namespace MonoDevelop.Ide.ExternalTools
browseButton.Path = externalTool.Command ?? "";
argumentTextBox.Text = externalTool.Arguments ?? "";
workingDirTextBox.Text = externalTool.InitialDirectory ?? "";
+ CurrentKey = externalTool.AccelKey;
promptArgsCheckBox.Active = externalTool.PromptForArguments ;
useOutputPadCheckBox.Active = externalTool.UseOutputPad;
saveCurrentFileCheckBox.Active = externalTool.SaveCurrentFile;
} else {
- titleTextBox.Text = browseButton.Path = argumentTextBox.Text = workingDirTextBox.Text = "";
+ titleTextBox.Text = browseButton.Path = argumentTextBox.Text = workingDirTextBox.Text = CurrentKey = "";
promptArgsCheckBox.Active = useOutputPadCheckBox.Active = saveCurrentFileCheckBox.Active = false;
}
+ accelIncomplete = false;
+ accelComplete = true;
} finally {
lockStoreValues = false;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolService.cs
index aa55bad407..3a1c2bbf25 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.ExternalTools/ExternalToolService.cs
@@ -33,6 +33,8 @@ using System.Collections.Generic;
using System.Xml;
using MonoDevelop.Core;
+using MonoDevelop.Components.Commands;
+using MonoDevelop.Ide.Commands;
namespace MonoDevelop.Ide.ExternalTools
{
@@ -48,17 +50,45 @@ namespace MonoDevelop.Ide.ExternalTools
return tools;
}
set {
+ UnregisterCommands ();
tools = value;
+ RegisterCommands ();
+ }
+ }
+
+ static void UnregisterCommands ()
+ {
+ if (tools == null)
+ return;
+ for (int i = 0; i < tools.Count; i++) {
+ var cmd = IdeApp.CommandService.GetActionCommand ("MonoDevelop.CustomCommands.Command" + i);
+ if (cmd != null)
+ IdeApp.CommandService.UnregisterCommand (cmd);
+ }
+ }
+
+ static void RegisterCommands ()
+ {
+ if (tools == null)
+ return;
+ for (int i = 0; i < tools.Count; i++) {
+ var tool = tools [i];
+ ActionCommand cmd = new ActionCommand ("MonoDevelop.CustomCommands.Command" + i, tool.MenuCommand, null);
+ cmd.DefaultHandler = new RunCustomToolHandler (tool);
+ cmd.Category = GettextCatalog.GetString ("Tools (Custom)");
+ cmd.Description = GettextCatalog.GetString ("Start tool") + " " + string.Join (string.Empty, tool.MenuCommand.Split ('&'));
+ cmd.AccelKey = tool.AccelKey;
+ IdeApp.CommandService.RegisterCommand (cmd);
}
}
static ExternalToolService ()
{
try {
- tools = LoadTools ();
+ Tools = LoadTools ();
} catch (Exception e) {
LoggingService.LogError ("ExternalToolService: Exception while loading tools.", e);
- tools = new List<ExternalTool> ();
+ Tools = new List<ExternalTool> ();
}
}