Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2020 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
26 changed files with 874 additions and 118 deletions
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using System.Resources; |
||||
using System.Resources.Tools; |
||||
using System.IO; |
||||
|
||||
namespace ResourceEditor |
||||
{ |
||||
public class ResourceCodeGeneratorTool : ICustomTool |
||||
{ |
||||
public void GenerateCode(FileProjectItem item, CustomToolContext context) |
||||
{ |
||||
/*context.GenerateCodeDomAsync(item, context.GetOutputFileName(item, ".Designer"), |
||||
delegate { |
||||
return GenerateCodeDom(); |
||||
});*/ |
||||
string inputFilePath = item.FileName; |
||||
|
||||
IResourceReader reader; |
||||
if (Path.GetExtension(inputFilePath) == ".resx") { |
||||
reader = new ResXResourceReader(inputFilePath); |
||||
} else { |
||||
reader = new ResourceReader(inputFilePath); |
||||
} |
||||
|
||||
Hashtable resources = new Hashtable(); |
||||
foreach (DictionaryEntry de in reader) { |
||||
resources.Add(de.Key, de.Value); |
||||
} |
||||
|
||||
string[] unmatchable = null; |
||||
|
||||
context.WriteCodeDomToFile( |
||||
item, |
||||
context.GetOutputFileName(item, ".Designer"), |
||||
StronglyTypedResourceBuilder.Create( |
||||
resources, // resourceList
|
||||
"Resources", // baseName
|
||||
context.OutputNamespace, // generatedCodeNamespace
|
||||
context.OutputNamespace, // resourcesNamespace
|
||||
context.Project.LanguageProperties.CodeDomProvider, // codeProvider
|
||||
true, // internal class
|
||||
out unmatchable |
||||
)); |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Xml; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.SettingsEditor |
||||
{ |
||||
public class SettingsDocument |
||||
{ |
||||
string generatedClassNamespace = ""; |
||||
string generatedClassName = ""; |
||||
List<SettingsEntry> entries = new List<SettingsEntry>(); |
||||
|
||||
public string GeneratedClassNamespace { |
||||
get { return generatedClassNamespace; } |
||||
set { generatedClassNamespace = value ?? ""; } |
||||
} |
||||
|
||||
public string GeneratedClassName { |
||||
get { return generatedClassName; } |
||||
set { generatedClassName = value ?? ""; } |
||||
} |
||||
|
||||
public List<SettingsEntry> Entries { |
||||
get { return entries; } |
||||
} |
||||
|
||||
public SettingsDocument() |
||||
{ |
||||
} |
||||
|
||||
const string XmlNamespace = "http://schemas.microsoft.com/VisualStudio/2004/01/settings"; |
||||
|
||||
public SettingsDocument(XmlElement settingsFile, ISettingsEntryHost host) |
||||
{ |
||||
generatedClassNamespace = settingsFile.GetAttribute("GeneratedClassNamespace"); |
||||
generatedClassName = settingsFile.GetAttribute("GeneratedClassName"); |
||||
|
||||
XmlElement settings = settingsFile["Settings"]; |
||||
|
||||
foreach (XmlNode node in settings.ChildNodes) { |
||||
if (node is XmlElement) { |
||||
entries.Add(new SettingsEntry(host, node as XmlElement)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void Save(XmlWriter writer) |
||||
{ |
||||
writer.WriteStartElement("SettingsFile", XmlNamespace); |
||||
writer.WriteAttributeString("CurrentProfile", "(Default)"); |
||||
writer.WriteAttributeString("GeneratedClassNamespace", generatedClassNamespace); |
||||
writer.WriteAttributeString("GeneratedClassName", generatedClassName); |
||||
|
||||
writer.WriteStartElement("Profiles"); |
||||
writer.WriteStartElement("Profile"); |
||||
writer.WriteAttributeString("Name", "(Default)"); |
||||
writer.WriteEndElement(); // Profile
|
||||
writer.WriteEndElement(); // Profiles
|
||||
|
||||
writer.WriteStartElement("Settings"); |
||||
foreach (SettingsEntry e in entries) { |
||||
e.WriteTo(writer); |
||||
} |
||||
writer.WriteEndElement(); // Settings
|
||||
|
||||
writer.WriteEndElement(); // SettingsFile
|
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,496 @@
@@ -0,0 +1,496 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.CodeDom; |
||||
using System.CodeDom.Compiler; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Text.RegularExpressions; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Project |
||||
{ |
||||
/// <summary>
|
||||
/// Registered in /SharpDevelop/CustomTools/
|
||||
/// </summary>
|
||||
public interface ICustomTool |
||||
{ |
||||
void GenerateCode(FileProjectItem item, CustomToolContext context); |
||||
} |
||||
|
||||
#region CustomToolContext
|
||||
/// <summary>
|
||||
/// Provides ProgressMonitor and MessageView to custom tools.
|
||||
/// Also provides helper methods that are useful for custom tools.
|
||||
/// </summary>
|
||||
public sealed class CustomToolContext |
||||
{ |
||||
IProject project; |
||||
IProgressMonitor progressMonitor; |
||||
string outputNamespace; |
||||
internal bool RunningSeparateThread; |
||||
|
||||
public CustomToolContext(IProject project) |
||||
: this(project, new DummyProgressMonitor()) |
||||
{ |
||||
} |
||||
|
||||
public CustomToolContext(IProject project, IProgressMonitor progressMonitor) |
||||
{ |
||||
if (project == null) |
||||
throw new ArgumentNullException("project"); |
||||
this.project = project; |
||||
this.ProgressMonitor = progressMonitor; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the project the custom tool is being run for. The IProject interface
|
||||
/// is not thread-safe!
|
||||
/// </summary>
|
||||
public IProject Project { |
||||
get { return project; } |
||||
} |
||||
|
||||
public string OutputNamespace { |
||||
get { return outputNamespace; } |
||||
set { outputNamespace = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs a method asynchronously. Prevents another CustomTool invocation
|
||||
/// on the same file while action is running.
|
||||
/// </summary>
|
||||
public void RunAsync(Action action) |
||||
{ |
||||
RunningSeparateThread = true; |
||||
System.Threading.ThreadPool.QueueUserWorkItem( |
||||
delegate { |
||||
try { |
||||
action(); |
||||
} catch (Exception ex) { |
||||
MessageService.ShowError(ex); |
||||
} finally { |
||||
CustomToolsService.NotifyAsyncFinish(this); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
static object lockObject = new object(); |
||||
static volatile MessageViewCategory customToolMessageView; |
||||
|
||||
internal static MessageViewCategory StaticMessageView { |
||||
get { |
||||
if (customToolMessageView == null) { |
||||
lock (lockObject) { |
||||
if (customToolMessageView == null) { |
||||
customToolMessageView = new MessageViewCategory("Custom Tool"); |
||||
CompilerMessageView.Instance.AddCategory(customToolMessageView); |
||||
} |
||||
} |
||||
} |
||||
return customToolMessageView; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the message view where custom tools can write to. This member is thread-safe.
|
||||
/// </summary>
|
||||
public MessageViewCategory MessageView { |
||||
get { |
||||
return StaticMessageView; |
||||
} |
||||
} |
||||
|
||||
public string GetOutputFileName(FileProjectItem baseItem, string additionalExtension) |
||||
{ |
||||
if (baseItem == null) |
||||
throw new ArgumentNullException("baseItem"); |
||||
if (baseItem.Project != project) |
||||
throw new ArgumentException("baseItem is not from project this CustomToolContext belongs to"); |
||||
|
||||
string newExtension = null; |
||||
if (project.LanguageProperties.CodeDomProvider != null) { |
||||
newExtension = project.LanguageProperties.CodeDomProvider.FileExtension; |
||||
} |
||||
if (string.IsNullOrEmpty(newExtension)) { |
||||
if (string.IsNullOrEmpty(additionalExtension)) { |
||||
newExtension = ".unknown"; |
||||
} else { |
||||
newExtension = additionalExtension; |
||||
additionalExtension = ""; |
||||
} |
||||
} |
||||
if (!newExtension.StartsWith(".")) { |
||||
newExtension = "." + newExtension; |
||||
} |
||||
|
||||
return Path.ChangeExtension(baseItem.FileName, additionalExtension + newExtension); |
||||
} |
||||
|
||||
public FileProjectItem EnsureOutputFileIsInProject(FileProjectItem baseItem, string outputFileName) |
||||
{ |
||||
WorkbenchSingleton.AssertMainThread(); |
||||
FileProjectItem outputItem = CustomToolsService.FindProjectItem(project, outputFileName); |
||||
if (outputItem == null) { |
||||
outputItem = new FileProjectItem(project, ItemType.Compile); |
||||
outputItem.FileName = outputFileName; |
||||
outputItem.DependentUpon = Path.GetFileName(baseItem.FileName); |
||||
ProjectService.AddProjectItem(project, outputItem); |
||||
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView(); |
||||
} |
||||
return outputItem; |
||||
} |
||||
|
||||
public void WriteCodeDomToFile(FileProjectItem baseItem, string outputFileName, CodeCompileUnit ccu) |
||||
{ |
||||
WorkbenchSingleton.AssertMainThread(); |
||||
CodeDomProvider provider = project.LanguageProperties.CodeDomProvider; |
||||
CodeGeneratorOptions options = new CodeDOMGeneratorUtility().CreateCodeGeneratorOptions; |
||||
|
||||
NamedFileOperationDelegate method = delegate(string fileName) { |
||||
using (StreamWriter writer = new StreamWriter(fileName, false, System.Text.Encoding.UTF8)) { |
||||
if (provider == null) { |
||||
writer.WriteLine("No CodeDom provider was found for this language."); |
||||
} else { |
||||
provider.GenerateCodeFromCompileUnit(ccu, writer, options); |
||||
} |
||||
} |
||||
}; |
||||
FileUtility.ObservedSave(method, outputFileName, FileErrorPolicy.Inform); |
||||
EnsureOutputFileIsInProject(baseItem, outputFileName); |
||||
} |
||||
|
||||
public void GenerateCodeDomAsync(FileProjectItem baseItem, string outputFileName, Func<CodeCompileUnit> func) |
||||
{ |
||||
RunAsync(delegate { |
||||
CodeCompileUnit ccu = func(); |
||||
WorkbenchSingleton.SafeThreadAsyncCall(WriteCodeDomToFile, baseItem, outputFileName, ccu); |
||||
}); |
||||
} |
||||
|
||||
public IProgressMonitor ProgressMonitor { |
||||
get { return progressMonitor; } |
||||
set { |
||||
if (value == null) |
||||
throw new ArgumentNullException("value"); |
||||
progressMonitor = value; |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region CustomToolDescriptor
|
||||
sealed class CustomToolDescriptor |
||||
{ |
||||
string name; |
||||
string fileNamePattern; |
||||
string className; |
||||
ICustomTool tool; |
||||
AddIn addIn; |
||||
|
||||
public string Name { |
||||
get { return name; } |
||||
} |
||||
|
||||
public ICustomTool Tool { |
||||
get { |
||||
if (tool == null) { |
||||
tool = (ICustomTool)addIn.CreateObject(className); |
||||
} |
||||
return tool; |
||||
} |
||||
} |
||||
|
||||
public bool CanRunOnFile(string fileName) |
||||
{ |
||||
if (string.IsNullOrEmpty(fileNamePattern)) // no regex specified
|
||||
return true; |
||||
return Regex.IsMatch(fileName, fileNamePattern, RegexOptions.IgnoreCase); |
||||
} |
||||
|
||||
public CustomToolDescriptor(string name, string fileNamePattern, string className, AddIn addIn) |
||||
{ |
||||
this.name = name; |
||||
this.fileNamePattern = fileNamePattern; |
||||
this.className = className; |
||||
this.addIn = addIn; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region CustomToolDoozer
|
||||
/// <summary>
|
||||
/// Creates CustomToolDescriptor objects.
|
||||
/// </summary>
|
||||
/// <attribute name="id" use="required">
|
||||
/// ID used to identify the custom tool.
|
||||
/// </attribute>
|
||||
/// <attribute name="class" use="required">
|
||||
/// Name of the ICustomTool class.
|
||||
/// </attribute>
|
||||
/// <attribute name="fileNamePattern" use="optional">
|
||||
/// Regular expression that specifies the file names for which the custom tool
|
||||
/// can be used. Example: "\.res(x|ources)$"
|
||||
/// </attribute>
|
||||
/// <usage>Only in /SharpDevelop/CustomTools</usage>
|
||||
/// <returns>
|
||||
/// An CustomToolDescriptor object that wraps a ICustomTool object.
|
||||
/// </returns>
|
||||
/// <example title="Strongly typed resource generator">
|
||||
/// <Path name = "/SharpDevelop/CustomTools">
|
||||
/// <CustomTool id = "ResXFileCodeGenerator"
|
||||
/// class = "ResourceEditor.ResourceCodeGeneratorTool"
|
||||
/// fileNamePattern = "\.res(x|ources)$"/>
|
||||
/// </Path>
|
||||
/// </example>
|
||||
public sealed class CustomToolDoozer : IDoozer |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if the doozer handles codon conditions on its own.
|
||||
/// If this property return false, the item is excluded when the condition is not met.
|
||||
/// </summary>
|
||||
public bool HandleConditions { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates an item with the specified sub items. And the current
|
||||
/// Condition status for this item.
|
||||
/// </summary>
|
||||
public object BuildItem(object caller, Codon codon, ArrayList subItems) |
||||
{ |
||||
return new CustomToolDescriptor(codon.Id, codon.Properties["fileNamePattern"], |
||||
codon.Properties["class"], codon.AddIn); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region CustomToolsService
|
||||
public static class CustomToolsService |
||||
{ |
||||
class CustomToolRun { |
||||
internal CustomToolContext context; |
||||
internal string file; |
||||
internal FileProjectItem baseItem; |
||||
internal ICustomTool customTool; |
||||
internal bool showMessageBoxOnErrors; |
||||
|
||||
public CustomToolRun(CustomToolContext context, string file, FileProjectItem baseItem, ICustomTool customTool, bool showMessageBoxOnErrors) |
||||
{ |
||||
this.context = context; |
||||
this.file = file; |
||||
this.baseItem = baseItem; |
||||
this.customTool = customTool; |
||||
this.showMessageBoxOnErrors = showMessageBoxOnErrors; |
||||
} |
||||
} |
||||
|
||||
static bool initialized; |
||||
static List<CustomToolRun> toolRuns = new List<CustomToolRun>(); |
||||
static Dictionary<string, CustomToolDescriptor> toolDict; |
||||
static List<CustomToolDescriptor> customToolList; |
||||
static CustomToolRun activeToolRun; |
||||
|
||||
internal static void Initialize() |
||||
{ |
||||
customToolList = AddInTree.BuildItems<CustomToolDescriptor>("/SharpDevelop/CustomTools", null, false); |
||||
toolDict = new Dictionary<string, CustomToolDescriptor>(StringComparer.OrdinalIgnoreCase); |
||||
foreach (CustomToolDescriptor desc in customToolList) { |
||||
toolDict[desc.Name] = desc; |
||||
} |
||||
|
||||
if (!initialized) { |
||||
initialized = true; |
||||
FileUtility.FileSaved += OnFileSaved; |
||||
} |
||||
} |
||||
|
||||
static void OnFileSaved(object sender, FileNameEventArgs e) |
||||
{ |
||||
Solution solution = ProjectService.OpenSolution; |
||||
if (solution == null) return; |
||||
IProject project = solution.FindProjectContainingFile(e.FileName); |
||||
if (project == null) return; |
||||
FileProjectItem item = FindProjectItem(project, e.FileName); |
||||
if (item == null) return; |
||||
if (!string.IsNullOrEmpty(item.CustomTool)) { |
||||
RunCustomTool(item, false); |
||||
} |
||||
} |
||||
|
||||
internal static FileProjectItem FindProjectItem(IProject project, string fileName) |
||||
{ |
||||
return Linq.Find(Linq.OfType<FileProjectItem>(project.Items), |
||||
delegate(FileProjectItem item) { |
||||
return FileUtility.IsEqualFileName(item.FileName, fileName); |
||||
}); |
||||
// return project.Items.OfType<FileProjectItem>().Find(
|
||||
// item => FileUtility.IsEqualFileName(item.FileName, outputFileName));
|
||||
} |
||||
|
||||
public static IEnumerable<string> GetCustomToolNames() |
||||
{ |
||||
return customToolList.ConvertAll<string>(delegate(CustomToolDescriptor desc) { |
||||
return desc.Name; |
||||
}); |
||||
} |
||||
|
||||
public static IEnumerable<string> GetCompatibleCustomToolNames(FileProjectItem item) |
||||
{ |
||||
string fileName = item.FileName; |
||||
foreach (CustomToolDescriptor desc in customToolList) { |
||||
if (desc.CanRunOnFile(fileName)) { |
||||
yield return desc.Name; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static ICustomTool GetCustomTool(string name) |
||||
{ |
||||
lock (toolDict) { |
||||
CustomToolDescriptor tool; |
||||
if (toolDict.TryGetValue(name, out tool)) |
||||
return tool.Tool; |
||||
else |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the custom tool specified by the base items' CustomTool property on the base item.
|
||||
/// </summary>
|
||||
public static void RunCustomTool(FileProjectItem baseItem, bool showMessageBoxOnErrors) |
||||
{ |
||||
if (baseItem == null) |
||||
throw new ArgumentNullException("baseItem"); |
||||
|
||||
if (string.IsNullOrEmpty(baseItem.CustomTool)) |
||||
return; |
||||
|
||||
ICustomTool customTool = GetCustomTool(baseItem.CustomTool); |
||||
if (customTool == null) { |
||||
string message = "Cannot find custom tool '" + baseItem.CustomTool + "'."; |
||||
CustomToolContext.StaticMessageView.AppendLine(message); |
||||
if (showMessageBoxOnErrors) { |
||||
MessageService.ShowError(message); |
||||
} |
||||
} else { |
||||
RunCustomTool(baseItem, customTool, showMessageBoxOnErrors); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the specified custom tool on the base item.
|
||||
/// </summary>
|
||||
public static void RunCustomTool(FileProjectItem baseItem, ICustomTool customTool, bool showMessageBoxOnErrors) |
||||
{ |
||||
if (baseItem == null) |
||||
throw new ArgumentNullException("baseItem"); |
||||
if (customTool == null) |
||||
throw new ArgumentNullException("customTool"); |
||||
WorkbenchSingleton.AssertMainThread(); |
||||
|
||||
string fileName = baseItem.FileName; |
||||
if (toolRuns.Exists(delegate(CustomToolRun run) { |
||||
return FileUtility.IsEqualFileName(run.file, fileName); |
||||
})) |
||||
{ |
||||
// file already in queue, do not enqueue it again
|
||||
return; |
||||
} |
||||
CustomToolContext context = new CustomToolContext(baseItem.Project); |
||||
if (string.IsNullOrEmpty(baseItem.CustomToolNamespace)) { |
||||
context.OutputNamespace = GetDefaultNamespace(baseItem.Project, baseItem.FileName); |
||||
} else { |
||||
context.OutputNamespace = baseItem.CustomToolNamespace; |
||||
} |
||||
RunCustomTool(new CustomToolRun(context, fileName, baseItem, customTool, showMessageBoxOnErrors)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace the file should have in the specified project.
|
||||
/// </summary>
|
||||
public static string GetDefaultNamespace(IProject project, string fileName) |
||||
{ |
||||
if (project == null) |
||||
throw new ArgumentNullException("project"); |
||||
if (fileName == null) |
||||
throw new ArgumentNullException("fileName"); |
||||
|
||||
string relPath = FileUtility.GetRelativePath(project.Directory, Path.GetDirectoryName(fileName)); |
||||
string[] subdirs = relPath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); |
||||
StringBuilder standardNameSpace = new StringBuilder(project.RootNamespace); |
||||
foreach(string subdir in subdirs) { |
||||
if (subdir == "." || subdir == ".." || subdir.Length == 0) |
||||
continue; |
||||
if (subdir.Equals("src", StringComparison.OrdinalIgnoreCase)) |
||||
continue; |
||||
if (subdir.Equals("source", StringComparison.OrdinalIgnoreCase)) |
||||
continue; |
||||
standardNameSpace.Append('.'); |
||||
standardNameSpace.Append(NewFileDialog.GenerateValidClassName(subdir)); |
||||
} |
||||
return standardNameSpace.ToString(); |
||||
} |
||||
|
||||
static void RunCustomTool(CustomToolRun run) |
||||
{ |
||||
if (activeToolRun != null) { |
||||
toolRuns.Add(run); |
||||
} else { |
||||
try { |
||||
run.customTool.GenerateCode(run.baseItem, run.context); |
||||
} catch (Exception ex) { |
||||
LoggingService.Error(ex); |
||||
run.context.MessageView.AppendLine("Custom tool '" + run.baseItem.CustomTool + "' failed."); |
||||
if (run.showMessageBoxOnErrors) { |
||||
MessageService.ShowError("Custom tool '" + run.baseItem.CustomTool |
||||
+ "'failed:" + Environment.NewLine + ex.ToString()); |
||||
} |
||||
} |
||||
if (run.context.RunningSeparateThread) { |
||||
activeToolRun = run; |
||||
} |
||||
} |
||||
} |
||||
|
||||
internal static void NotifyAsyncFinish(CustomToolContext context) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall( |
||||
delegate { |
||||
activeToolRun = null; |
||||
CustomToolRun nextRun = toolRuns[0]; |
||||
toolRuns.RemoveAt(0); |
||||
RunCustomTool(nextRun); |
||||
}); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region ExecuteCustomToolCommand
|
||||
public sealed class ExecuteCustomToolCommand : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
FileNode node = Owner as FileNode; |
||||
if (node != null) { |
||||
FileProjectItem item = node.ProjectItem as FileProjectItem; |
||||
if (item != null) { |
||||
CustomToolsService.RunCustomTool(item, true); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
using System.Drawing.Design; |
||||
using System.Windows.Forms; |
||||
using System.Windows.Forms.Design; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Widgets.DesignTimeSupport |
||||
{ |
||||
public abstract class DropDownEditor : UITypeEditor |
||||
{ |
||||
/// <summary>
|
||||
/// Returns the drop down style.
|
||||
/// </summary>
|
||||
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) |
||||
{ |
||||
return UITypeEditorEditStyle.DropDown; |
||||
} |
||||
|
||||
public override bool IsDropDownResizable { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Shows the drop down editor control in the drop down so the user
|
||||
/// can change the value.
|
||||
/// </summary>
|
||||
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) |
||||
{ |
||||
IWindowsFormsEditorService editorService = null; |
||||
|
||||
if (provider != null) { |
||||
editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); |
||||
} |
||||
|
||||
if (editorService != null) { |
||||
using (Control control = CreateDropDownControl(context, editorService)) { |
||||
SetValue(control, value); |
||||
editorService.DropDownControl(control); |
||||
value = GetValue(control); |
||||
} |
||||
} |
||||
|
||||
return value; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates the drop down control.
|
||||
/// </summary>
|
||||
protected abstract Control CreateDropDownControl(ITypeDescriptorContext context, IWindowsFormsEditorService editorService); |
||||
|
||||
/// <summary>
|
||||
/// Sets the current value in the drop down control.
|
||||
/// </summary>
|
||||
protected virtual void SetValue(Control control, object value) |
||||
{ |
||||
DropDownEditorListBox listBox = (DropDownEditorListBox)control; |
||||
listBox.Value = (string)value; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the current value from the drop down control.
|
||||
/// </summary>
|
||||
protected virtual object GetValue(Control control) |
||||
{ |
||||
DropDownEditorListBox listBox = (DropDownEditorListBox)control; |
||||
return listBox.Value; |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue