/// <summary> /// Selects designer file for this (culture-specific) item from the list of culture-neutral ResX files /// </summary> private ProjectItem GetNeutralDesignerItem(List <ResXProjectItem> neutralItems) { string cultureNeutralName = GetCultureNeutralName(); // get name of culture-neutral ResX string thisDir = Path.GetFullPath(Path.GetDirectoryName(InternalProjectItem.GetFullPath())); // get full path of this item's directory ResXProjectItem neutralItem = null; foreach (ResXProjectItem item in neutralItems) { if (item.IsCultureSpecific()) { continue; // we are looking for culture-neutral file } // directory of tested item string neutralDir = Path.GetFullPath(Path.GetDirectoryName(item.InternalProjectItem.GetFullPath())); // we need the item to be located in the same directory and have proper name if (neutralDir == thisDir && item.InternalProjectItem.Name.ToLowerInvariant() == cultureNeutralName.ToLowerInvariant()) { neutralItem = item; break; } } if (neutralItem != null) // we found culture-neutral item { return(neutralItem.DesignerItem); } else { return(null); } }
/// <summary> /// Compares internal representations of the resource files /// </summary> public override bool Equals(object obj) { if (obj == null) { return(false); } ResXProjectItem copy = obj as ResXProjectItem; if (copy == null) { return(false); } return(InternalProjectItem.Equals(copy.InternalProjectItem)); }
/// <summary> /// Creates new ResXProjectItem instance /// </summary> /// <param name="projectItem">Corresponding ProjectItem in file hierarchy</param> /// <param name="displayName">Display name for this item</param> /// <param name="internalInReferenced">True if this item should be marked as "internal in referenced project"</param> private ResXProjectItem(ProjectItem projectItem, string displayName, bool internalInReferenced) { if (projectItem == null) { throw new ArgumentNullException("projectItem"); } if (displayName == null) { throw new ArgumentNullException("displayName"); } this.DisplayName = displayName; this.InternalProjectItem = projectItem; string customToolOutput = InternalProjectItem.GetCustomToolOutput(); this.DesignerItem = InternalProjectItem.ProjectItems.GetItem(customToolOutput); this.MarkedInternalInReferencedProject = internalInReferenced; }
/// <summary> /// Flushes current Data. If the file is closed, it means write data to disk; otherwise corresponding file buffer is modified. /// </summary> public void Flush() { if (!dataChangedInBatchMode && IsInBatchMode) { return; } string path = InternalProjectItem.GetFullPath(); if (RDTManager.IsFileOpen(path)) { VLDocumentViewsManager.SaveDataToBuffer(data, path); // modify in-memory buffer of this file } else { // write data to disk ResXResourceWriter writer = null; try { writer = new ResXResourceWriter(path); writer.BasePath = Path.GetDirectoryName(path); foreach (var pair in data) { writer.AddResource(pair.Value); } writer.Generate(); } finally { if (writer != null) { writer.Close(); } } } // regenerate designer item if (DesignerItem != null) { RDTManager.SilentlyModifyFile(DesignerItem.GetFullPath(), (string p) => { RunCustomTool(); }); } }
/// <summary> /// Loads file's content into memory /// </summary> public void Load() { if (IsLoaded) { return; } string path = InternalProjectItem.GetFullPath(); if (RDTManager.IsFileOpen(path)) // file is open - read from VS buffer { VLDocumentViewsManager.LoadDataFromBuffer(ref data, path); } else // file is closed - read from disk { ResXResourceReader reader = null; try { data = new Dictionary <string, ResXDataNode>(); reader = new ResXResourceReader(path); reader.BasePath = Path.GetDirectoryName(path); reader.UseResXDataNodes = true; foreach (DictionaryEntry entry in reader) { data.Add(entry.Key.ToString().ToLower(), entry.Value as ResXDataNode); } } finally { if (reader != null) { reader.Close(); } } } IsLoaded = true; }
/// <summary> /// If ResX file is culture specific, returns its culture neutral name (strips language info). Otherwise returns its name unchanged. /// </summary> public string GetCultureNeutralName() { return(InternalProjectItem.GetResXCultureNeutralName()); }
/// <summary> /// Returns true if ResX file is culture specific /// </summary> public bool IsCultureSpecific() { return(InternalProjectItem.IsCultureSpecificResX()); }
/// <summary> /// Returns a hash code for this instance. /// </summary> /// <returns> /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// </returns> public override int GetHashCode() { return(InternalProjectItem.GetHashCode()); }
/// <summary> /// Attempts to obtain class and namespace name of the designer file (if it exists) /// </summary> /// <param name="neutralItems">List of relevant culture-neutral ResX files</param> public void ResolveNamespaceClass(List <ResXProjectItem> neutralItems) { if (neutralItems == null) { throw new ArgumentNullException("neutralItems"); } Class = null; Namespace = null; // if this file is culture-specific it's designer file is empty - we need to find designer item if corresponding culture-neutral file if (IsCultureSpecific()) { DesignerItem = GetNeutralDesignerItem(neutralItems); } if (DesignerItem != null) // designer file is set { if (!File.Exists(DesignerItem.GetFullPath())) { RunCustomTool(); } // select first namespace in the designer file CodeElement nmspcElemet = null; bool fileOpened; var rootCodeElements = DesignerItem.GetCodeModel(true, false, out fileOpened).CodeElements; foreach (CodeElement element in rootCodeElements) { if (element.Kind == vsCMElement.vsCMElementNamespace) { Namespace = element.FullName; nmspcElemet = element; break; } } var nestedCodeElements = nmspcElemet == null ? rootCodeElements : nmspcElemet.Children; // select first class/module in the namespace if (nestedCodeElements != null) { foreach (CodeElement child in nestedCodeElements) { if (child.Kind == vsCMElement.vsCMElementClass || child.Kind == vsCMElement.vsCMElementModule) { Class = child.Name; break; } } } if (Namespace == null && DesignerLanguage == LANGUAGE.VB) { Namespace = InternalProjectItem.ContainingProject.GetRootNamespace(); } } else // designer file doesn't exist // if ResX files is contained in ASP .NET website project, designer files are implicit { if (InternalProjectItem.ContainingProject != null && InternalProjectItem.ContainingProject.Kind.ToUpper() == StringConstants.WebSiteProject) { string relative = InternalProjectItem.GetRelativeURL(); // file must be located in App_GlobalResources folder if (!string.IsNullOrEmpty(relative) && relative.StartsWith(StringConstants.GlobalWebSiteResourcesFolder)) { Class = Path.GetFileNameWithoutExtension(InternalProjectItem.GetFullPath()); // take file name as a class name if (IsCultureSpecific()) // strip culture-specific info { Class = GetCultureNeutralName(); Class = Class.Substring(0, Class.IndexOf('.')); } Namespace = StringConstants.GlobalWebSiteResourcesNamespace; // namespace is hard-coded as "Resources" } else { Class = null; Namespace = null; } } } }