Browse Source

Windows.Forms designer: Implemented support for PropertyReflection localization model, and set this as default. Localization model can be changed on new options panel, with the option to keep the localization model of existing forms unchanged.

Moved common code from all CodeDOM designer loaders to new base class AbstractCodeDomDesignerLoader.
Fixed field change detection for types with type arguments.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3273 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Christian Hornung 17 years ago
parent
commit
61268e9dc4
  1. BIN
      data/resources/StringResources.de.resources
  2. BIN
      data/resources/StringResources.es-mx.resources
  3. BIN
      data/resources/StringResources.es.resources
  4. 157
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerLoader.cs
  5. 63
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs
  6. 3
      src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.addin
  7. 5
      src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj
  8. 4
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs
  9. 117
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/AbstractCodeDomDesignerLoader.cs
  10. 154
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs
  11. 167
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Gui/OptionPanels/LocalizationModelOptionsPanel.cs
  12. 123
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Gui/OptionPanels/LocalizationModelOptionsPanel.resx
  13. BIN
      src/Main/StartUp/Project/Resources/StringResources.resources

BIN
data/resources/StringResources.de.resources

Binary file not shown.

BIN
data/resources/StringResources.es-mx.resources

Binary file not shown.

BIN
data/resources/StringResources.es.resources

Binary file not shown.

157
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerLoader.cs

@ -8,9 +8,8 @@ @@ -8,9 +8,8 @@
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -24,13 +23,8 @@ using ICSharpCode.TextEditor; @@ -24,13 +23,8 @@ using ICSharpCode.TextEditor;
namespace Grunwald.BooBinding.Designer
{
public class BooDesignerLoader : CodeDomDesignerLoader
public class BooDesignerLoader : AbstractCodeDomDesignerLoader
{
bool loading = true;
IDesignerLoaderHost designerLoaderHost = null;
IDesignerGenerator generator;
ITypeResolutionService typeResolutionService = null;
TextEditorControl textEditorControl;
public string TextContent {
@ -39,64 +33,19 @@ namespace Grunwald.BooBinding.Designer @@ -39,64 +33,19 @@ namespace Grunwald.BooBinding.Designer
}
}
public override bool Loading {
get {
return loading;
}
}
public IDesignerLoaderHost DesignerLoaderHost {
get {
return designerLoaderHost;
}
}
protected override CodeDomProvider CodeDomProvider {
get {
return generator.CodeDomProvider;
}
}
protected override ITypeResolutionService TypeResolutionService {
get {
return typeResolutionService;
}
}
protected override bool IsReloadNeeded()
{
return base.IsReloadNeeded() || TextContent != lastTextContent;
}
public BooDesignerLoader(TextEditorControl textEditorControl, IDesignerGenerator generator)
: base(generator)
{
this.textEditorControl = textEditorControl;
this.generator = generator;
}
public override void BeginLoad(IDesignerLoaderHost host)
{
this.loading = true;
typeResolutionService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService));
this.designerLoaderHost = host;
base.BeginLoad(host);
}
protected override void Initialize()
{
CodeDomLocalizationProvider localizationProvider = new CodeDomLocalizationProvider(designerLoaderHost, CodeDomLocalizationModel.PropertyAssignment);
IDesignerSerializationManager manager = (IDesignerSerializationManager)designerLoaderHost.GetService(typeof(IDesignerSerializationManager));
manager.AddSerializationProvider(localizationProvider);
base.Initialize();
}
protected override void OnEndLoad(bool successful, System.Collections.ICollection errors)
{
this.loading = false;
base.OnEndLoad(successful, errors);
}
string lastTextContent;
Module parsedModule;
protected override CodeCompileUnit Parse()
{
@ -104,6 +53,8 @@ namespace Grunwald.BooBinding.Designer @@ -104,6 +53,8 @@ namespace Grunwald.BooBinding.Designer
try {
CodeCompileUnit ccu = ParseForm();
LoggingService.Debug("BooDesignerLoader.Parse() finished");
// Clear the cached module after loading has finished
this.parsedModule = null;
return ccu;
} catch (Boo.Lang.Compiler.CompilerError ex) {
throw new FormsDesignerLoadException(ex.ToString(true));
@ -112,6 +63,36 @@ namespace Grunwald.BooBinding.Designer @@ -112,6 +63,36 @@ namespace Grunwald.BooBinding.Designer
CodeCompileUnit ParseForm()
{
ParseInformation parseInfo = ParserService.ParseFile(textEditorControl.FileName, textEditorControl.Text, false);
Module module = ParseFormAsModule();
#if DEBUG
Console.WriteLine(module.ToCodeString());
#endif
CodeDomVisitor visitor = new CodeDomVisitor(parseInfo.MostRecentCompilationUnit.ProjectContent);
module.Accept(visitor);
#if DEBUG
// output generated CodeDOM to the console :
ICSharpCode.NRefactory.Visitors.CodeDomVerboseOutputGenerator outputGenerator = new ICSharpCode.NRefactory.Visitors.CodeDomVerboseOutputGenerator();
outputGenerator.GenerateCodeFromMember(visitor.OutputCompileUnit.Namespaces[0].Types[0], Console.Out, null);
CodeDomProvider cSharpProvider = new Microsoft.CSharp.CSharpCodeProvider();
cSharpProvider.GenerateCodeFromCompileUnit(visitor.OutputCompileUnit, Console.Out, null);
#endif
return visitor.OutputCompileUnit;
}
Module ParseFormAsModule()
{
// The module is cached while loading so that
// determining the localization model and generating the CodeDOM
// does not require the code to be parsed twice.
if (this.parsedModule != null && lastTextContent == TextContent) {
return this.parsedModule;
}
lastTextContent = TextContent;
ParseInformation parseInfo = ParserService.ParseFile(textEditorControl.FileName, textEditorControl.Text, false);
@ -169,23 +150,8 @@ namespace Grunwald.BooBinding.Designer @@ -169,23 +150,8 @@ namespace Grunwald.BooBinding.Designer
&& method.Parameters.Count == 0)
{
cld.Members.Add(method);
#if DEBUG
Console.WriteLine(module.ToCodeString());
#endif
CodeDomVisitor visitor = new CodeDomVisitor(parseInfo.MostRecentCompilationUnit.ProjectContent);
module.Accept(visitor);
#if DEBUG
// output generated CodeDOM to the console :
ICSharpCode.NRefactory.Visitors.CodeDomVerboseOutputGenerator outputGenerator = new ICSharpCode.NRefactory.Visitors.CodeDomVerboseOutputGenerator();
outputGenerator.GenerateCodeFromMember(visitor.OutputCompileUnit.Namespaces[0].Types[0], Console.Out, null);
CodeDomProvider cSharpProvider = new Microsoft.CSharp.CSharpCodeProvider();
cSharpProvider.GenerateCodeFromCompileUnit(visitor.OutputCompileUnit, Console.Out, null);
#endif
return visitor.OutputCompileUnit;
this.parsedModule = module;
return module;
}
}
}
@ -213,10 +179,55 @@ namespace Grunwald.BooBinding.Designer @@ -213,10 +179,55 @@ namespace Grunwald.BooBinding.Designer
{
LoggingService.Info("BooDesignerLoader.Write called");
try {
generator.MergeFormChanges(unit);
this.Generator.MergeFormChanges(unit);
} catch (Exception ex) {
MessageService.ShowError(ex);
}
}
protected override CodeDomLocalizationModel GetCurrentLocalizationModelFromDesignedFile()
{
Module m = ParseFormAsModule();
FindLocalizationModelVisitor visitor = new FindLocalizationModelVisitor();
m.Accept(visitor);
return visitor.Model;
}
sealed class FindLocalizationModelVisitor : DepthFirstVisitor
{
CodeDomLocalizationModel model = CodeDomLocalizationModel.None;
public CodeDomLocalizationModel Model {
get { return this.model; }
}
public override bool EnterMethod(Method node)
{
return node.Name == "InitializeComponent" || node.Name == "InitializeComponents";
}
public override bool EnterBinaryExpression(BinaryExpression node)
{
return this.model == CodeDomLocalizationModel.None && node.Operator == BinaryOperatorType.Assign;
}
public override bool EnterMethodInvocationExpression(MethodInvocationExpression node)
{
if (this.model != CodeDomLocalizationModel.None) return false;
MemberReferenceExpression member = node.Target as MemberReferenceExpression;
if (member != null) {
ReferenceExpression refex = member.Target as ReferenceExpression;
if (refex != null && refex.Name.Equals("resources", StringComparison.InvariantCulture)) {
if (member.Name.Equals("ApplyResources", StringComparison.InvariantCulture)) {
this.model = CodeDomLocalizationModel.PropertyReflection;
} else if (member.Name.Equals("GetString", StringComparison.InvariantCulture)) {
this.model = CodeDomLocalizationModel.PropertyAssignment;
}
}
}
return false;
}
}
}
}

63
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs

@ -7,14 +7,10 @@ @@ -7,14 +7,10 @@
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.IO;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.FormsDesigner;
using IronPython.CodeDom;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.PythonBinding
{
@ -22,54 +18,20 @@ namespace ICSharpCode.PythonBinding @@ -22,54 +18,20 @@ namespace ICSharpCode.PythonBinding
/// Loads the form or control's code so the forms designer can
/// display it.
/// </summary>
public class PythonDesignerLoader : CodeDomDesignerLoader
public class PythonDesignerLoader : AbstractCodeDomDesignerLoader
{
IDocument document;
IDesignerGenerator generator;
bool loading;
ITypeResolutionService typeResolutionService;
PythonProvider codeDomProvider = new PythonProvider();
IDesignerLoaderHost designerLoaderHost;
public PythonDesignerLoader(IDocument document, IDesignerGenerator generator)
: base(generator)
{
if (document == null) {
throw new ArgumentException("Document cannot be null", "document");
}
if (generator == null) {
throw new ArgumentException("Generator cannot be null", "generator");
}
this.document = document;
this.generator = generator;
}
public override void BeginLoad(IDesignerLoaderHost host)
{
loading = true;
designerLoaderHost = host;
typeResolutionService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService));
base.BeginLoad(host);
}
public override bool Loading {
get { return loading; }
}
protected override CodeDomProvider CodeDomProvider {
get { return codeDomProvider; }
}
protected override ITypeResolutionService TypeResolutionService {
get { return typeResolutionService; }
}
protected override void OnEndLoad(bool successful, System.Collections.ICollection errors)
{
base.OnEndLoad(successful, errors);
loading = false;
}
/// <summary>
/// Gets the form or user control's code from the document and
/// parses it using the PythonProvider class.
@ -81,15 +43,20 @@ namespace ICSharpCode.PythonBinding @@ -81,15 +43,20 @@ namespace ICSharpCode.PythonBinding
protected override void Write(CodeCompileUnit unit)
{
generator.MergeFormChanges(unit);
this.Generator.MergeFormChanges(unit);
}
protected override void Initialize()
protected override CodeDomLocalizationModel GetCurrentLocalizationModelFromDesignedFile()
{
CodeDomLocalizationProvider localizationProvider = new CodeDomLocalizationProvider(designerLoaderHost, CodeDomLocalizationModel.PropertyAssignment);
IDesignerSerializationManager manager = (IDesignerSerializationManager)designerLoaderHost.GetService(typeof(IDesignerSerializationManager));
manager.AddSerializationProvider(localizationProvider);
base.Initialize();
}
string content = this.document.TextContent;
if (content.Contains(@"resources.GetObject('$this.AutoScroll')")) {
return CodeDomLocalizationModel.PropertyAssignment;
} else if (content.Contains(@"resources.ApplyResources(")) {
return CodeDomLocalizationModel.PropertyReflection;
}
return CodeDomLocalizationModel.None;
}
}
}

3
src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.addin

@ -313,6 +313,9 @@ @@ -313,6 +313,9 @@
<DialogPanel id = "GridOptions"
label = "${res:ICSharpCode.SharpDevelop.FormDesigner.Gui.OptionPanels.GridOptionsPanel.PanelName}"
class = "ICSharpCode.FormsDesigner.Gui.OptionPanels.GridOptionsPanel"/>
<DialogPanel id = "LocalizationModelOptions"
label = "${res:ICSharpCode.SharpDevelop.FormDesigner.Gui.OptionPanels.LocalizationModelOptionsPanel.PanelName}"
class = "ICSharpCode.FormsDesigner.Gui.OptionPanels.LocalizationModelOptionsPanel"/>
</DialogPanel>
</Path>

5
src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj

@ -56,8 +56,10 @@ @@ -56,8 +56,10 @@
<Compile Include="Src\DesignerGenerator\CSharpDesignerGenerator.cs" />
<Compile Include="Src\DesignerGenerator\IDesignerGenerator.cs" />
<Compile Include="Src\DesignerGenerator\XmlDesignerGenerator.cs" />
<Compile Include="Src\DesignerLoader\AbstractCodeDomDesignerLoader.cs" />
<Compile Include="Src\DesignerLoader\NRefactoryDesignerLoader.cs" />
<Compile Include="Src\DesignerLoader\XmlDesignerLoader.cs" />
<Compile Include="Src\Gui\OptionPanels\LocalizationModelOptionsPanel.cs" />
<Compile Include="Src\SecondaryDisplayBinding.cs" />
<Compile Include="Src\DesignerViewContent.cs" />
<Compile Include="Src\FormKeyHandler.cs" />
@ -104,6 +106,9 @@ @@ -104,6 +106,9 @@
</Compile>
<Compile Include="Src\Gui\OptionPanels\GeneralOptions.cs" />
<EmbeddedResource Include="Resources\WindowsFormsGeneralOptions.xfrm" />
<EmbeddedResource Include="Src\Gui\OptionPanels\LocalizationModelOptionsPanel.resx">
<DependentUpon>LocalizationModelOptionsPanel.cs</DependentUpon>
</EmbeddedResource>
<Compile Include="Src\Services\DesignerSerializationService.cs" />
</ItemGroup>
<ItemGroup>

4
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerGenerator/AbstractDesignerGenerator.cs

@ -232,8 +232,8 @@ namespace ICSharpCode.FormsDesigner @@ -232,8 +232,8 @@ namespace ICSharpCode.FormsDesigner
bool FieldChanged(IField oldField, CodeMemberField newField)
{
// compare types
if (oldField.ReturnType != null) { // ignore type changes to untyped VB fields
if (oldField.ReturnType.FullyQualifiedName != newField.Type.BaseType) {
if (oldField.ReturnType != null && oldField.ReturnType.GetUnderlyingClass() != null) { // ignore type changes to untyped VB fields
if (oldField.ReturnType.GetUnderlyingClass().DotNetName != newField.Type.BaseType) {
LoggingService.Debug("FieldChanged: "+oldField.Name+", "+oldField.ReturnType.FullyQualifiedName+" -> "+newField.Type.BaseType);
return true;
}

117
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/AbstractCodeDomDesignerLoader.cs

@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using ICSharpCode.Core;
namespace ICSharpCode.FormsDesigner
{
/// <summary>
/// An abstract base class for CodeDOM designer loaders.
/// </summary>
public abstract class AbstractCodeDomDesignerLoader : CodeDomDesignerLoader
{
bool loading = true;
IDesignerLoaderHost designerLoaderHost = null;
ITypeResolutionService typeResolutionService = null;
readonly IDesignerGenerator generator;
public override bool Loading {
get { return base.Loading || loading; }
}
protected override ITypeResolutionService TypeResolutionService {
get { return this.typeResolutionService; }
}
protected IDesignerLoaderHost DesignerLoaderHost {
get { return this.designerLoaderHost; }
}
protected override CodeDomProvider CodeDomProvider {
get { return this.generator.CodeDomProvider; }
}
protected IDesignerGenerator Generator {
get { return this.generator; }
}
protected AbstractCodeDomDesignerLoader(IDesignerGenerator generator)
{
if (generator == null) {
throw new ArgumentNullException("generator", "Generator cannot be null");
}
this.generator = generator;
}
public override void BeginLoad(IDesignerLoaderHost host)
{
this.loading = true;
this.typeResolutionService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService));
this.designerLoaderHost = host;
base.BeginLoad(host);
}
protected override void Initialize()
{
CodeDomLocalizationModel model = FormsDesigner.Gui.OptionPanels.LocalizationModelOptionsPanel.DefaultLocalizationModel;
if (FormsDesigner.Gui.OptionPanels.LocalizationModelOptionsPanel.KeepLocalizationModel) {
// Try to find out the current localization model of the designed form
CodeDomLocalizationModel existingModel = this.GetCurrentLocalizationModelFromDesignedFile();
if (existingModel != CodeDomLocalizationModel.None) {
LoggingService.Debug("Determined existing localization model, using that: " + existingModel.ToString());
model = existingModel;
} else {
LoggingService.Debug("Could not determine existing localization model, using default: " + model.ToString());
}
} else {
LoggingService.Debug("Using default localization model: " + model.ToString());
}
CodeDomLocalizationProvider localizationProvider = new CodeDomLocalizationProvider(designerLoaderHost, model);
IDesignerSerializationManager manager = (IDesignerSerializationManager)designerLoaderHost.GetService(typeof(IDesignerSerializationManager));
manager.AddSerializationProvider(localizationProvider);
base.Initialize();
}
/// <summary>
/// When overridden in derived classes, this method should return the current
/// localization model of the designed file or None, if it cannot be determined.
/// </summary>
/// <returns>The default implementation always returns None.</returns>
protected virtual CodeDomLocalizationModel GetCurrentLocalizationModelFromDesignedFile()
{
return CodeDomLocalizationModel.None;
}
protected override void OnEndLoad(bool successful, ICollection errors)
{
this.loading = false;
//when control's Dispose() has a exception and on loading also raised exception
//then this is only place where this error can be logged, because after errors is
//catched internally in .net
try {
base.OnEndLoad(successful, errors);
} catch(ExceptionCollection e) {
LoggingService.Error("DesignerLoader.OnEndLoad error" + e.Message);
foreach(Exception ine in e.Exceptions) {
LoggingService.Error("DesignerLoader.OnEndLoad error" + ine.Message);
}
throw;
} catch(Exception e) {
LoggingService.Error("DesignerLoader.OnEndLoad error" + e.Message);
throw;
}
}
}
}

154
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs

@ -7,12 +7,10 @@ @@ -7,12 +7,10 @@
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using ICSharpCode.Core;
@ -37,12 +35,8 @@ namespace ICSharpCode.FormsDesigner @@ -37,12 +35,8 @@ namespace ICSharpCode.FormsDesigner
}
}
public class NRefactoryDesignerLoader : CodeDomDesignerLoader
public class NRefactoryDesignerLoader : AbstractCodeDomDesignerLoader
{
bool loading = true;
IDesignerLoaderHost designerLoaderHost = null;
ITypeResolutionService typeResolutionService = null;
IDesignerGenerator generator;
SupportedLanguage language;
TextEditorControl textEditorControl;
@ -53,76 +47,16 @@ namespace ICSharpCode.FormsDesigner @@ -53,76 +47,16 @@ namespace ICSharpCode.FormsDesigner
}
}
public override bool Loading {
get {
return loading;
}
}
public IDesignerLoaderHost DesignerLoaderHost {
get {
return designerLoaderHost;
}
}
protected override CodeDomProvider CodeDomProvider {
get {
return generator.CodeDomProvider;
}
}
protected override ITypeResolutionService TypeResolutionService {
get {
return typeResolutionService;
}
}
protected override bool IsReloadNeeded()
{
return base.IsReloadNeeded() || TextContent != lastTextContent;
}
public NRefactoryDesignerLoader(SupportedLanguage language, TextEditorControl textEditorControl, IDesignerGenerator generator)
: base(generator)
{
this.language = language;
this.textEditorControl = textEditorControl;
this.generator = generator;
}
public override void BeginLoad(IDesignerLoaderHost host)
{
this.loading = true;
typeResolutionService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService));
this.designerLoaderHost = host;
base.BeginLoad(host);
}
protected override void Initialize()
{
CodeDomLocalizationProvider localizationProvider = new CodeDomLocalizationProvider(designerLoaderHost, CodeDomLocalizationModel.PropertyAssignment);
IDesignerSerializationManager manager = (IDesignerSerializationManager)designerLoaderHost.GetService(typeof(IDesignerSerializationManager));
manager.AddSerializationProvider(localizationProvider);
base.Initialize();
}
protected override void OnEndLoad(bool successful, ICollection errors)
{
this.loading = false;
//when control's Dispose() has a exception and on loading also raised exception
//then this is only place where this error can be logged, because after errors is
//catched internally in .net
try {
base.OnEndLoad(successful, errors);
} catch(ExceptionCollection e) {
LoggingService.Error("DesignerLoader.OnEndLoad error" + e.Message);
foreach(Exception ine in e.Exceptions) {
LoggingService.Error("DesignerLoader.OnEndLoad error" + ine.Message);
}
throw;
} catch(Exception e) {
LoggingService.Error("DesignerLoader.OnEndLoad error" + e.Message);
throw;
}
}
string lastTextContent;
@ -358,30 +292,78 @@ namespace ICSharpCode.FormsDesigner @@ -358,30 +292,78 @@ namespace ICSharpCode.FormsDesigner
}
#endif
try {
generator.MergeFormChanges(unit);
this.Generator.MergeFormChanges(unit);
} catch (Exception ex) {
MessageService.ShowError(ex);
}
}
// public void Reload()
// {
// base.Reload(BasicDesignerLoader.ReloadFlags.Default);
// }
// public override void Flush()
// {
// base.Flush();
// }
// void InitializeExtendersForProject(IDesignerHost host)
// {
// IExtenderProviderService elsi = (IExtenderProviderService)host.GetService(typeof(IExtenderProviderService));
// elsi.AddExtenderProvider(new ICSharpCode.FormDesigner.Util.NameExtender());
// }
protected override CodeDomLocalizationModel GetCurrentLocalizationModelFromDesignedFile()
{
ParseInformation parseInfo = ParserService.GetParseInformation(this.textEditorControl.FileName);
IClass formClass;
bool isFirstClassInFile;
IList<IClass> parts = FindFormClassParts(parseInfo, out formClass, out isFirstClassInFile);
foreach (string fileName in
parts.Select(p => p.CompilationUnit.FileName)
.Where(n => n != null)
.Distinct(StringComparer.InvariantCultureIgnoreCase)) {
ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(language, new StringReader(ParserService.GetParseableFileContent(fileName)));
p.Parse();
if (p.Errors.Count > 0) {
throw new FormsDesignerLoadException("Syntax errors in " + fileName + ":\r\n" + p.Errors.ErrorOutput);
}
FindLocalizationModelVisitor visitor = new FindLocalizationModelVisitor();
p.CompilationUnit.AcceptVisitor(visitor, null);
if (visitor.Model != CodeDomLocalizationModel.None) {
return visitor.Model;
}
}
return CodeDomLocalizationModel.None;
}
public override void Dispose()
sealed class FindLocalizationModelVisitor : AbstractAstVisitor
{
base.Dispose();
bool inInitMethod;
CodeDomLocalizationModel model = CodeDomLocalizationModel.None;
public CodeDomLocalizationModel Model {
get { return this.model; }
}
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
{
if (methodDeclaration.Name == "InitializeComponents" || methodDeclaration.Name == "InitializeComponent") {
this.inInitMethod = true;
try {
return base.VisitMethodDeclaration(methodDeclaration, data);
} finally {
this.inInitMethod = false;
}
}
return null;
}
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
if (this.model == CodeDomLocalizationModel.None && this.inInitMethod) {
IdentifierExpression iex = memberReferenceExpression.TargetObject as IdentifierExpression;
if (iex != null && iex.Identifier == "resources") {
if (memberReferenceExpression.MemberName == "ApplyResources") {
this.model = CodeDomLocalizationModel.PropertyReflection;
} else if (memberReferenceExpression.MemberName == "GetString") {
this.model = CodeDomLocalizationModel.PropertyAssignment;
}
}
}
return null;
}
}
}
}

167
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Gui/OptionPanels/LocalizationModelOptionsPanel.cs

@ -0,0 +1,167 @@ @@ -0,0 +1,167 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Christian Hornung" email="chhornung@googlemail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows.Forms;
using System.ComponentModel.Design.Serialization;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.FormsDesigner.Gui.OptionPanels
{
/// <summary>
/// Options panel for localization model options.
/// </summary>
public class LocalizationModelOptionsPanel : AbstractOptionPanel
{
public LocalizationModelOptionsPanel()
{
}
#region Windows Forms Designer code
void InitializeComponent()
{
System.Windows.Forms.GroupBox modelGroupBox;
this.assignmentRadioButton = new System.Windows.Forms.RadioButton();
this.reflectionRadioButton = new System.Windows.Forms.RadioButton();
this.keepModelCheckBox = new System.Windows.Forms.CheckBox();
modelGroupBox = new System.Windows.Forms.GroupBox();
modelGroupBox.SuspendLayout();
this.SuspendLayout();
//
// modelGroupBox
//
modelGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
modelGroupBox.Controls.Add(this.assignmentRadioButton);
modelGroupBox.Controls.Add(this.reflectionRadioButton);
modelGroupBox.Location = new System.Drawing.Point(3, 3);
modelGroupBox.Name = "modelGroupBox";
modelGroupBox.Size = new System.Drawing.Size(385, 166);
modelGroupBox.TabIndex = 0;
modelGroupBox.TabStop = false;
modelGroupBox.Text = "${res:ICSharpCode.SharpDevelop.FormDesigner.Gui.OptionPanels.LocalizationModelOpt" +
"ionsPanel.DefaultLocalizationModel}";
//
// assignmentRadioButton
//
this.assignmentRadioButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.assignmentRadioButton.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.assignmentRadioButton.Location = new System.Drawing.Point(6, 91);
this.assignmentRadioButton.Name = "assignmentRadioButton";
this.assignmentRadioButton.Size = new System.Drawing.Size(373, 69);
this.assignmentRadioButton.TabIndex = 1;
this.assignmentRadioButton.TabStop = true;
this.assignmentRadioButton.Text = "${res:ICSharpCode.SharpDevelop.FormDesigner.Gui.OptionPanels.LocalizationModelOpt" +
"ionsPanel.AssignmentRadioButton}";
this.assignmentRadioButton.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.assignmentRadioButton.UseVisualStyleBackColor = true;
//
// reflectionRadioButton
//
this.reflectionRadioButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.reflectionRadioButton.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.reflectionRadioButton.Location = new System.Drawing.Point(6, 19);
this.reflectionRadioButton.Name = "reflectionRadioButton";
this.reflectionRadioButton.Size = new System.Drawing.Size(373, 66);
this.reflectionRadioButton.TabIndex = 0;
this.reflectionRadioButton.TabStop = true;
this.reflectionRadioButton.Text = "${res:ICSharpCode.SharpDevelop.FormDesigner.Gui.OptionPanels.LocalizationModelOpt" +
"ionsPanel.ReflectionRadioButton}";
this.reflectionRadioButton.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.reflectionRadioButton.UseVisualStyleBackColor = true;
//
// keepModelCheckBox
//
this.keepModelCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.keepModelCheckBox.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.keepModelCheckBox.Location = new System.Drawing.Point(9, 175);
this.keepModelCheckBox.Name = "keepModelCheckBox";
this.keepModelCheckBox.Size = new System.Drawing.Size(373, 95);
this.keepModelCheckBox.TabIndex = 1;
this.keepModelCheckBox.Text = "${res:ICSharpCode.SharpDevelop.FormDesigner.Gui.OptionPanels.LocalizationModelOpt" +
"ionsPanel.KeepModelCheckBox}";
this.keepModelCheckBox.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.keepModelCheckBox.UseVisualStyleBackColor = true;
//
// LocalizationModelOptionsPanel
//
this.Controls.Add(this.keepModelCheckBox);
this.Controls.Add(modelGroupBox);
this.Name = "LocalizationModelOptionsPanel";
this.Size = new System.Drawing.Size(391, 300);
modelGroupBox.ResumeLayout(false);
this.ResumeLayout(false);
}
private System.Windows.Forms.CheckBox keepModelCheckBox;
private System.Windows.Forms.RadioButton reflectionRadioButton;
private System.Windows.Forms.RadioButton assignmentRadioButton;
#endregion
public override void LoadPanelContents()
{
base.LoadPanelContents();
if (this.Controls.Count == 0) {
this.InitializeComponent();
Translate(this);
}
this.reflectionRadioButton.Checked = (DefaultLocalizationModel == CodeDomLocalizationModel.PropertyReflection);
this.assignmentRadioButton.Checked = !this.reflectionRadioButton.Checked;
this.keepModelCheckBox.Checked = KeepLocalizationModel;
}
static void Translate(Control container) {
container.Text = StringParser.Parse(container.Text);
foreach (Control c in container.Controls) {
Translate(c);
}
}
public override bool StorePanelContents()
{
if (this.reflectionRadioButton.Checked) {
DefaultLocalizationModel = CodeDomLocalizationModel.PropertyReflection;
} else if (this.assignmentRadioButton.Checked) {
DefaultLocalizationModel = CodeDomLocalizationModel.PropertyAssignment;
} else {
MessageService.ShowError("One localization model must be selected!");
return false;
}
KeepLocalizationModel = this.keepModelCheckBox.Checked;
return true;
}
public const string DefaultLocalizationModelPropertyName = "FormsDesigner.DesignerOptions.DefaultLocalizationModel";
public const string KeepLocalizationModelPropertyName = "FormsDesigner.DesignerOptions.KeepLocalizationModel";
/// <summary>
/// Gets or sets the default localization model to be used by the Windows Forms designer.
/// </summary>
public static CodeDomLocalizationModel DefaultLocalizationModel {
get { return PropertyService.Get<CodeDomLocalizationModel>(DefaultLocalizationModelPropertyName, CodeDomLocalizationModel.PropertyReflection); }
set { PropertyService.Set(DefaultLocalizationModelPropertyName, value); }
}
/// <summary>
/// Gets or sets whether the Windows Forms designer should keep the localization model of existing files.
/// </summary>
public static bool KeepLocalizationModel {
get { return PropertyService.Get<bool>(KeepLocalizationModelPropertyName, false); }
set { PropertyService.Set(KeepLocalizationModelPropertyName, value); }
}
}
}

123
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Gui/OptionPanels/LocalizationModelOptionsPanel.resx

@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="modelGroupBox.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

BIN
src/Main/StartUp/Project/Resources/StringResources.resources

Binary file not shown.
Loading…
Cancel
Save