Browse Source

Windows.Forms designer: Fixed saving of the resources of localizable forms (previously, saving in a non-default language resulted in the default resources being deleted). It seems that the designer always expects to read back the old values of the resources even if it has already written to a new ResourceWriter. So the content of the ResourceWriter stream is now only transferred to the internal storage buffer after serialization is complete.

Separated the resource storage management from the DesignerResourceService so that the ResourceStore is persistent for the lifetime of the view content, but the service can be deleted after unloading of the designer. Previously, the DesignerResourceService was automatically disposed on unloading, possibly deleting unsaved resources.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3332 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Christian Hornung 17 years ago
parent
commit
ce2ac2fd6e
  1. 1
      src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj
  2. 23
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs
  3. 314
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/DesignerResourceService.cs
  4. 341
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ResourceStore.cs

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

@ -86,6 +86,7 @@ @@ -86,6 +86,7 @@
<Compile Include="Src\Services\HelpService.cs" />
<Compile Include="Src\Services\MenuCommandService.cs" />
<Compile Include="Src\Services\PropertyValueUIService.cs" />
<Compile Include="Src\Services\ResourceStore.cs" />
<Compile Include="Src\Services\ToolboxService.cs" />
<Compile Include="Src\Services\TypeDescriptorFilterService.cs" />
<Compile Include="Src\Services\TypeResolutionService.cs" />

23
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerViewContent.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.FormsDesigner @@ -40,7 +40,7 @@ namespace ICSharpCode.FormsDesigner
IDesignerLoaderProvider loaderProvider;
IDesignerGenerator generator;
DesignerResourceService designerResourceService;
readonly ResourceStore resourceStore;
FormsDesignerUndoEngine undoEngine;
public override Control Control {
@ -97,6 +97,8 @@ namespace ICSharpCode.FormsDesigner @@ -97,6 +97,8 @@ namespace ICSharpCode.FormsDesigner
this.viewContent = viewContent;
this.textAreaControlProvider = viewContent as ITextEditorControlProvider;
this.resourceStore = new ResourceStore(this);
// null check is required to support running in unit test mode
if (WorkbenchSingleton.Workbench != null) {
this.IsActiveViewContentChanged += this.IsActiveViewContentChangedHandler;
@ -114,15 +116,7 @@ namespace ICSharpCode.FormsDesigner @@ -114,15 +116,7 @@ namespace ICSharpCode.FormsDesigner
serviceContainer.AddService(typeof(IHelpService), new HelpService());
serviceContainer.AddService(typeof(System.Drawing.Design.IPropertyValueUIService), new PropertyValueUIService());
// Do not re-initialize the resource service on every load
// because of SD2-1107.
// The service holds cached resource file contents which
// may not have been written to disk yet if the user switched
// between source and design view without saving.
if (designerResourceService == null) {
designerResourceService = new DesignerResourceService(this);
}
serviceContainer.AddService(typeof(System.ComponentModel.Design.IResourceService), designerResourceService);
serviceContainer.AddService(typeof(System.ComponentModel.Design.IResourceService), new DesignerResourceService(this.resourceStore));
AmbientProperties ambientProperties = new AmbientProperties();
serviceContainer.AddService(typeof(AmbientProperties), ambientProperties);
serviceContainer.AddService(typeof(ITypeResolutionService), new TypeResolutionService(viewContent.PrimaryFileName));
@ -177,7 +171,7 @@ namespace ICSharpCode.FormsDesigner @@ -177,7 +171,7 @@ namespace ICSharpCode.FormsDesigner
{
hasUnmergedChanges = true;
this.PrimaryFile.MakeDirty();
designerResourceService.MarkResourceFilesAsDirty();
this.resourceStore.MarkResourceFilesAsDirty();
}
public override void Load(OpenedFile file, System.IO.Stream stream)
@ -185,7 +179,7 @@ namespace ICSharpCode.FormsDesigner @@ -185,7 +179,7 @@ namespace ICSharpCode.FormsDesigner
if (file == PrimaryFile) {
base.Load(file, stream);
} else {
designerResourceService.Load(file, stream);
this.resourceStore.Load(file, stream);
}
}
@ -195,7 +189,7 @@ namespace ICSharpCode.FormsDesigner @@ -195,7 +189,7 @@ namespace ICSharpCode.FormsDesigner
base.Save(file, stream);
} else {
if (hasUnmergedChanges) SaveToPrimary();
designerResourceService.Save(file, stream);
this.resourceStore.Save(file, stream);
}
}
@ -315,6 +309,7 @@ namespace ICSharpCode.FormsDesigner @@ -315,6 +309,7 @@ namespace ICSharpCode.FormsDesigner
bool isDirty = this.PrimaryFile.IsDirty;
LoggingService.Info("Merging form changes...");
designSurface.Flush();
this.resourceStore.CommitAllResourceChanges();
LoggingService.Info("Finished merging form changes");
hasUnmergedChanges = false;
this.PrimaryFile.IsDirty = isDirty;
@ -373,6 +368,8 @@ namespace ICSharpCode.FormsDesigner @@ -373,6 +368,8 @@ namespace ICSharpCode.FormsDesigner
this.IsActiveViewContentChanged -= this.IsActiveViewContentChangedHandler;
}
this.resourceStore.Dispose();
p.Dispose();
p = null;

314
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/DesignerResourceService.cs

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.IO;
using System.Resources;
@ -20,13 +21,15 @@ using ICSharpCode.SharpDevelop.Project; @@ -20,13 +21,15 @@ using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.FormsDesigner.Services
{
sealed class DesignerResourceService : System.ComponentModel.Design.IResourceService , IDisposable
sealed class DesignerResourceService : System.ComponentModel.Design.IResourceService
{
FormsDesignerViewContent viewContent;
readonly ResourceStore store;
public DesignerResourceService(FormsDesignerViewContent viewContent)
public DesignerResourceService(ResourceStore store)
{
this.viewContent = viewContent;
if (store == null)
throw new ArgumentNullException("store");
this.store = store;
}
#region System.ComponentModel.Design.IResourceService interface implementation
@ -34,7 +37,7 @@ namespace ICSharpCode.FormsDesigner.Services @@ -34,7 +37,7 @@ namespace ICSharpCode.FormsDesigner.Services
{
try {
LoggingService.Debug("ResourceWriter requested for culture: " + info.ToString());
return GetResourceStorage(info).GetWriter(this);
return this.store.GetWriter(info);
} catch (Exception e) {
MessageService.ShowError(e);
return null;
@ -45,311 +48,12 @@ namespace ICSharpCode.FormsDesigner.Services @@ -45,311 +48,12 @@ namespace ICSharpCode.FormsDesigner.Services
{
try {
LoggingService.Debug("ResourceReader requested for culture: "+info.ToString());
return GetResourceStorage(info).GetReader();
return this.store.GetReader(info);
} catch (Exception e) {
MessageService.ShowError(e);
return null;
}
}
#endregion
// Culture name (or empty string) => Resources
readonly Dictionary<string, ResourceStorage> resources = new Dictionary<string, ResourceStorage>();
readonly Dictionary<OpenedFile, ResourceStorage> resourceByFile = new Dictionary<OpenedFile, ResourceStorage>();
ResourceStorage GetResourceStorage(CultureInfo culture)
{
ResourceStorage storage;
if (!resources.TryGetValue(culture.Name, out storage)) {
storage = resources[culture.Name] = new ResourceStorage(culture.Name);
string fileName = CalcResourceFileName(viewContent.PrimaryFileName, culture.Name);
CreateOpenedFileForStorage(storage, fileName, File.Exists(fileName));
}
return storage;
}
void CreateOpenedFileForStorage(ResourceStorage storage, string fileName, bool isExistingFile)
{
storage.OpenedFile = FileService.GetOrCreateOpenedFile(fileName);
storage.IsNewFile = !isExistingFile;
if (!isExistingFile && storage.OpenedFile.RegisteredViewContents.Count == 0) {
storage.OpenedFile.SetData(new byte[0]);
}
resourceByFile[storage.OpenedFile] = storage;
// adding the opened file to the view content will load the file content into ResourceStorage.buffer
viewContent.Files.Add(storage.OpenedFile);
}
#region ResourceStorage
sealed class ResourceStorage
{
MemoryStream stream;
IResourceWriter writer;
byte[] buffer;
readonly string cultureName;
internal OpenedFile OpenedFile;
internal bool IsNewFile;
public ResourceStorage(string cultureName)
{
this.cultureName = cultureName;
}
/// <summary>
/// true, if the currently stored resource is not empty.
/// Note that this property is only valid after at least one
/// of GetReader, GetWriter or Save has been called.
/// </summary>
public bool ContainsData {
get {
return this.buffer != null;
}
}
public void Dispose()
{
if (this.stream != null) {
this.writer.Dispose();
this.stream.Dispose();
this.writer = null;
this.stream = null;
}
this.buffer = null;
}
/// <summary>
/// Writes the byte array containing the most recent version of the resource
/// represented by this instance into the private field "buffer" and returns it.
/// Returns null, if this resource has not been written to yet.
/// </summary>
byte[] GetBuffer()
{
if (this.stream != null) {
this.writer.Close();
this.writer.Dispose();
this.buffer = this.stream.ToArray();
this.writer = null;
this.stream.Dispose();
this.stream = null;
}
return this.buffer;
}
// load from OpenedFile into memory
public void Load(Stream stream)
{
Dispose();
this.buffer = new byte[stream.Length];
int pos = 0;
while (pos < buffer.Length)
pos += stream.Read(buffer, pos, buffer.Length - pos);
}
/// <summary>
/// Returns a new resource reader for this resource based on the most recent
/// version available (either in memory or on disk).
/// </summary>
public IResourceReader GetReader()
{
if (this.GetBuffer() == null) {
if (OpenedFile != null) {
return CreateResourceReader(OpenFileContentAsMemoryStream(OpenedFile), GetResourceType(OpenedFile.FileName));
} else {
return null;
}
} else {
ResourceType type = (OpenedFile != null) ? GetResourceType(OpenedFile.FileName) : ResourceType.Resx;
return CreateResourceReader(new MemoryStream(this.buffer, false), type);
}
}
static MemoryStream OpenFileContentAsMemoryStream(OpenedFile file)
{
Stream stream = file.OpenRead();
MemoryStream ms = stream as MemoryStream;
if (ms == null) {
// copy stream content to memory
try {
ms = new MemoryStream();
byte[] buffer = new byte[4096];
int c;
do {
c = stream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, c);
} while (c > 0);
ms.Position = 0;
} finally {
stream.Dispose();
}
}
return ms;
}
/// <summary>
/// Returns a new resource writer for this resource.
/// According to the SDK documentation of IResourceService.GetResourceWriter,
/// a new writer needs to be returned every time one is requested, discarding any
/// data written by previously returned writers.
/// </summary>
public IResourceWriter GetWriter(DesignerResourceService resourceService)
{
this.stream = new MemoryStream();
this.writer = CreateResourceWriter(this.stream, GetResourceType(OpenedFile.FileName));
return this.writer;
}
public void Save(Stream stream, DesignerResourceService resourceService)
{
if (this.GetBuffer() != null) {
stream.Write(buffer, 0, buffer.Length);
if (IsNewFile) {
resourceService.AddFileToProject(this);
IsNewFile = false;
}
}
}
}
#endregion
public void Load(OpenedFile file, Stream stream)
{
resourceByFile[file].Load(stream);
}
public void Save(OpenedFile file, Stream stream)
{
resourceByFile[file].Save(stream, this);
}
public void MarkResourceFilesAsDirty()
{
foreach (ResourceStorage rs in resourceByFile.Values) {
rs.OpenedFile.MakeDirty();
}
}
enum ResourceType {
Resx = 0,
Resources = 1
};
static IProject GetProject(string formFileName)
{
if (ProjectService.OpenSolution != null && formFileName != null)
return ProjectService.OpenSolution.FindProjectContainingFile(formFileName);
else
return null;
}
void AddFileToProject(ResourceStorage storage)
{
string resourceFileName = storage.OpenedFile.FileName;
string formFileName = viewContent.PrimaryFileName;
IProject project = GetProject(formFileName);
// Add this resource file to the project
if (project != null && !project.IsFileInProject(resourceFileName)) {
FileProjectItem newFileProjectItem = new FileProjectItem(project, ItemType.EmbeddedResource);
newFileProjectItem.DependentUpon = Path.GetFileName(formFileName);
newFileProjectItem.Include = FileUtility.GetRelativePath(project.Directory, resourceFileName);
ProjectService.AddProjectItem(project, newFileProjectItem);
FileService.FireFileCreated(resourceFileName, false);
PadDescriptor pd = WorkbenchSingleton.Workbench.GetPad(typeof(ProjectBrowserPad));
FileNode formFileNode = ((ProjectBrowserPad)pd.PadContent).ProjectBrowserControl.FindFileNode(formFileName);
if (formFileNode != null) {
LoggingService.Info("FormFileNode found, adding subitem");
FileNode fileNode = new FileNode(resourceFileName, FileNodeStatus.BehindFile);
fileNode.AddTo(formFileNode);
fileNode.ProjectItem = newFileProjectItem;
}
project.Save();
}
}
static string CalcResourceFileName(string formFileName, string cultureName)
{
StringBuilder resourceFileName = null;
IProject project = GetProject(formFileName);
if (formFileName != null && formFileName != String.Empty) {
resourceFileName = new StringBuilder(Path.GetDirectoryName(formFileName));
} else if (project != null) {
resourceFileName = new StringBuilder(project.Directory);
} else {
// required for untitled files. Untitled files should NOT save their resources.
resourceFileName = new StringBuilder(Path.GetTempPath());
}
resourceFileName.Append(Path.DirectorySeparatorChar);
string sourceFileName = null;
if (project != null && formFileName != null) {
// Try to find the source file name by using the project dependencies first.
FileProjectItem sourceItem = project.FindFile(formFileName);
if (sourceItem != null && sourceItem.DependentUpon != null && sourceItem.DependentUpon.Length > 0) {
sourceFileName = Path.GetFileNameWithoutExtension(sourceItem.DependentUpon);
}
}
if (sourceFileName == null) {
// If the source file name cannot be found using the project dependencies,
// assume the resource file name to be equal to the current source file name.
// Remove the ".Designer" part if present.
sourceFileName = Path.GetFileNameWithoutExtension(formFileName);
if (sourceFileName != null && sourceFileName.ToLowerInvariant().EndsWith(".designer")) {
sourceFileName = sourceFileName.Substring(0, sourceFileName.Length - 9);
}
}
resourceFileName.Append(sourceFileName);
if (!string.IsNullOrEmpty(cultureName)) {
resourceFileName.Append('.');
resourceFileName.Append(cultureName);
}
// Use .resources filename if file exists.
if (File.Exists(resourceFileName.ToString() + ".resources")) {
resourceFileName.Append(".resources");
} else {
resourceFileName.Append(".resx");
}
return resourceFileName.ToString();
}
public void Dispose()
{
if (resources != null) {
foreach (ResourceStorage storage in resources.Values) {
storage.Dispose();
}
resources.Clear();
}
}
static ResourceType GetResourceType(string fileName)
{
if (Path.GetExtension(fileName).ToLowerInvariant() == ".resx") {
return ResourceType.Resx;
}
return ResourceType.Resources;
}
static IResourceReader CreateResourceReader(Stream stream, ResourceType type)
{
if (stream.Length == 0)
return null;
if (type == ResourceType.Resources) {
return new ResourceReader(stream);
}
return new ResXResourceReader(stream);
}
static IResourceWriter CreateResourceWriter(Stream stream, ResourceType type)
{
if (type == ResourceType.Resources) {
return new ResourceWriter(stream);
}
return new ResXResourceWriter(stream);
}
}
}

341
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ResourceStore.cs

@ -0,0 +1,341 @@ @@ -0,0 +1,341 @@
// <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.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Resources;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.FormsDesigner.Services
{
/// <summary>
/// Manages the resource files that belong to an open forms designer view.
/// </summary>
internal sealed class ResourceStore : IDisposable
{
readonly FormsDesignerViewContent viewContent;
public ResourceStore(FormsDesignerViewContent viewContent)
{
if (viewContent == null)
throw new ArgumentNullException("viewContent");
this.viewContent = viewContent;
}
// Culture name (or empty string) => Resources
readonly Dictionary<string, ResourceStorage> resources = new Dictionary<string, ResourceStorage>();
readonly Dictionary<OpenedFile, ResourceStorage> resourceByFile = new Dictionary<OpenedFile, ResourceStorage>();
ResourceStorage GetResourceStorage(CultureInfo culture)
{
ResourceStorage storage;
if (!resources.TryGetValue(culture.Name, out storage)) {
storage = resources[culture.Name] = new ResourceStorage(culture.Name);
string fileName = CalcResourceFileName(viewContent.PrimaryFileName, culture.Name);
CreateOpenedFileForStorage(storage, fileName, File.Exists(fileName));
}
return storage;
}
public IResourceReader GetReader(CultureInfo info)
{
return this.GetResourceStorage(info).GetReader();
}
public IResourceWriter GetWriter(CultureInfo info)
{
return this.GetResourceStorage(info).GetWriter();
}
void CreateOpenedFileForStorage(ResourceStorage storage, string fileName, bool isExistingFile)
{
storage.OpenedFile = FileService.GetOrCreateOpenedFile(fileName);
storage.IsNewFile = !isExistingFile;
if (!isExistingFile && storage.OpenedFile.RegisteredViewContents.Count == 0) {
storage.OpenedFile.SetData(new byte[0]);
}
resourceByFile[storage.OpenedFile] = storage;
// adding the opened file to the view content will load the file content into ResourceStorage.buffer
viewContent.Files.Add(storage.OpenedFile);
}
public void Dispose()
{
foreach (ResourceStorage rs in this.resources.Values) {
rs.Dispose();
}
this.resources.Clear();
this.resourceByFile.Clear();
}
public void Load(OpenedFile file, Stream stream)
{
resourceByFile[file].Load(stream);
}
public void Save(OpenedFile file, Stream stream)
{
resourceByFile[file].Save(stream, this);
}
public void MarkResourceFilesAsDirty()
{
foreach (ResourceStorage rs in resourceByFile.Values) {
if (rs.OpenedFile != null) {
rs.OpenedFile.MakeDirty();
}
}
}
public void CommitAllResourceChanges()
{
foreach (ResourceStorage rs in this.resources.Values) {
rs.WriteResourcesToBuffer();
}
}
#region ResourceStorage
sealed class ResourceStorage
{
MemoryStream stream;
IResourceWriter writer;
byte[] buffer;
readonly string cultureName;
internal OpenedFile OpenedFile;
internal bool IsNewFile;
public ResourceStorage(string cultureName)
{
this.cultureName = cultureName;
}
public void Dispose()
{
if (this.stream != null) {
this.writer.Dispose();
this.stream.Dispose();
this.writer = null;
this.stream = null;
}
this.buffer = null;
}
/// <summary>
/// Writes the byte array containing the most recent version of the resource
/// represented by this instance into the private field "buffer", if a
/// resource writer has previously been requested for this resource.
/// </summary>
public void WriteResourcesToBuffer()
{
if (this.stream != null) {
this.writer.Close();
this.writer.Dispose();
this.buffer = this.stream.ToArray();
this.writer = null;
this.stream.Dispose();
this.stream = null;
}
}
// load from OpenedFile into memory
public void Load(Stream stream)
{
Dispose();
this.buffer = new byte[stream.Length];
int pos = 0;
while (pos < buffer.Length)
pos += stream.Read(buffer, pos, buffer.Length - pos);
}
/// <summary>
/// Returns a new resource reader for this resource based on the most recent
/// version available (either in memory or on disk).
/// </summary>
public IResourceReader GetReader()
{
if (this.buffer == null) {
if (OpenedFile != null) {
return CreateResourceReader(OpenFileContentAsMemoryStream(OpenedFile), GetResourceType(OpenedFile.FileName));
} else {
return null;
}
} else {
ResourceType type = (OpenedFile != null) ? GetResourceType(OpenedFile.FileName) : ResourceType.Resx;
return CreateResourceReader(new MemoryStream(this.buffer, false), type);
}
}
static MemoryStream OpenFileContentAsMemoryStream(OpenedFile file)
{
Stream stream = file.OpenRead();
MemoryStream ms = stream as MemoryStream;
if (ms == null) {
// copy stream content to memory
try {
ms = new MemoryStream();
byte[] buffer = new byte[4096];
int c;
do {
c = stream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, c);
} while (c > 0);
ms.Position = 0;
} finally {
stream.Dispose();
}
}
return ms;
}
/// <summary>
/// Returns a new resource writer for this resource.
/// According to the SDK documentation of IResourceService.GetResourceWriter,
/// a new writer needs to be returned every time one is requested, discarding any
/// data written by previously returned writers.
/// </summary>
public IResourceWriter GetWriter()
{
this.stream = new MemoryStream();
this.writer = CreateResourceWriter(this.stream, GetResourceType(OpenedFile.FileName));
return this.writer;
}
public void Save(Stream stream, ResourceStore resourceStore)
{
this.WriteResourcesToBuffer();
if (buffer == null || buffer.Length == 0) return;
stream.Write(buffer, 0, buffer.Length);
if (IsNewFile) {
resourceStore.AddFileToProject(this);
IsNewFile = false;
}
}
}
#endregion
enum ResourceType {
Resx = 0,
Resources = 1
};
static IProject GetProject(string formFileName)
{
if (ProjectService.OpenSolution != null && formFileName != null)
return ProjectService.OpenSolution.FindProjectContainingFile(formFileName);
else
return null;
}
void AddFileToProject(ResourceStorage storage)
{
string resourceFileName = storage.OpenedFile.FileName;
string formFileName = viewContent.PrimaryFileName;
IProject project = GetProject(formFileName);
// Add this resource file to the project
if (project != null && !project.IsFileInProject(resourceFileName)) {
FileProjectItem newFileProjectItem = new FileProjectItem(project, ItemType.EmbeddedResource);
newFileProjectItem.DependentUpon = Path.GetFileName(formFileName);
newFileProjectItem.Include = FileUtility.GetRelativePath(project.Directory, resourceFileName);
ProjectService.AddProjectItem(project, newFileProjectItem);
FileService.FireFileCreated(resourceFileName, false);
PadDescriptor pd = WorkbenchSingleton.Workbench.GetPad(typeof(ProjectBrowserPad));
FileNode formFileNode = ((ProjectBrowserPad)pd.PadContent).ProjectBrowserControl.FindFileNode(formFileName);
if (formFileNode != null) {
LoggingService.Info("FormFileNode found, adding subitem");
FileNode fileNode = new FileNode(resourceFileName, FileNodeStatus.BehindFile);
fileNode.AddTo(formFileNode);
fileNode.ProjectItem = newFileProjectItem;
}
project.Save();
}
}
static string CalcResourceFileName(string formFileName, string cultureName)
{
StringBuilder resourceFileName = null;
IProject project = GetProject(formFileName);
if (formFileName != null && formFileName != String.Empty) {
resourceFileName = new StringBuilder(Path.GetDirectoryName(formFileName));
} else if (project != null) {
resourceFileName = new StringBuilder(project.Directory);
} else {
// required for untitled files. Untitled files should NOT save their resources.
resourceFileName = new StringBuilder(Path.GetTempPath());
}
resourceFileName.Append(Path.DirectorySeparatorChar);
string sourceFileName = null;
if (project != null && formFileName != null) {
// Try to find the source file name by using the project dependencies first.
FileProjectItem sourceItem = project.FindFile(formFileName);
if (sourceItem != null && sourceItem.DependentUpon != null && sourceItem.DependentUpon.Length > 0) {
sourceFileName = Path.GetFileNameWithoutExtension(sourceItem.DependentUpon);
}
}
if (sourceFileName == null) {
// If the source file name cannot be found using the project dependencies,
// assume the resource file name to be equal to the current source file name.
// Remove the ".Designer" part if present.
sourceFileName = Path.GetFileNameWithoutExtension(formFileName);
if (sourceFileName != null && sourceFileName.ToLowerInvariant().EndsWith(".designer")) {
sourceFileName = sourceFileName.Substring(0, sourceFileName.Length - 9);
}
}
resourceFileName.Append(sourceFileName);
if (!string.IsNullOrEmpty(cultureName)) {
resourceFileName.Append('.');
resourceFileName.Append(cultureName);
}
// Use .resources filename if file exists.
if (File.Exists(resourceFileName.ToString() + ".resources")) {
resourceFileName.Append(".resources");
} else {
resourceFileName.Append(".resx");
}
return resourceFileName.ToString();
}
static IResourceReader CreateResourceReader(Stream stream, ResourceType type)
{
if (stream.Length == 0)
return null;
if (type == ResourceType.Resources) {
return new ResourceReader(stream);
}
return new ResXResourceReader(stream);
}
static IResourceWriter CreateResourceWriter(Stream stream, ResourceType type)
{
if (type == ResourceType.Resources) {
return new ResourceWriter(stream);
}
return new ResXResourceWriter(stream);
}
static ResourceType GetResourceType(string fileName)
{
if (Path.GetExtension(fileName).ToLowerInvariant() == ".resx") {
return ResourceType.Resx;
}
return ResourceType.Resources;
}
}
}
Loading…
Cancel
Save